I replaced my //sub above with one that is technically more the way the i4004 does it, but first I created some test code that would run through all possible 16*16*2 combinations of the sub command (acc, reg, carry set or clear). It then outputs the carry output and the acc after the SUB instruction.
R0 = current acc to test
R1 = current value to sub to test
R2 = current value of carry to test
Code:
PGM:000 A2 LD 2 ;is r2 clear or set carry
PGM:001 14 06 JCN 4(JZ) 006
PGM:003 FA STC ;it is non-zero set carry
PGM:004 40 06 JUN 006
PGM:006 F1 CLC ;it is zery clear carry
PGM:007 A0 LD 0 ;load acc from r0
PGM:008 91 SUB 1 ;sub r1 from it
PGM:009 B3 XCH 3 ;store acc result in r3 for later
PGM:00A 12 14 JCN 2(JC) 014 ;output carry bit
PGM:00C D3 LDM 3 ;tx char
PGM:00D FE EMU
PGM:00E D3 LDM 3 ;send 0x30 (0)
PGM:00F FE EMU
PGM:010 D0 LDM 0
PGM:011 FE EMU
PGM:012 40 1A JUN 01A
PGM:014 D3 LDM 3 ;output carry bit
PGM:015 FE EMU
PGM:016 D3 LDM 3 ;tx char
PGM:017 FE EMU
PGM:018 D1 LDM 1 ;send 0x31 (1)
PGM:019 FE EMU
PGM:01A D3 LDM 3 ;tx char
PGM:01B FE EMU
PGM:01C D4 LDM 4 ;0x4X (@ABCDEFGHIJKLMNO represented for 0123456789ABCDEF)
PGM:01D FE EMU
PGM:01E A3 LD 3 ;retrieve result from r3
PGM:01F FE EMU
PGM:020 60 INC 0 ;loop through all r0 values (acc)
PGM:021 A0 LD 0
PGM:022 1C 00 JCN C(JNZ) 000
PGM:024 61 INC 1 ;loop through all r1 values (sub)
PGM:025 A1 LD 1
PGM:026 1C 00 JCN C(JNZ) 000
PGM:028 62 INC 2 ;loop through non-carry and then carry
PGM:029 A1 LD 1
PGM:02A F8 DAC
PGM:02B 14 00 JCN 4(JZ) 000
PGM:02D D0 LDM 0 ;halt command
PGM:02E FE EMU
Output with my original SUB:
1@1A1B1C1D1E1F1G1H1I1J1K1L1M1N1O0O1@1A1B1C1D1E1F1G1H1I1J1K1L1M1N0N0O1@1A1B1C1D1E1F1G1H1I1J1K1L1M0M0N0O1@1A1B1C1D1E1F1G1H1I1J1K1L0L0M0N0O1@1A1B1C1D1E1F1G1H1I1J1K0K0L0M0N0O1@1A1B1C1D1E1F1G1H1I1J0J0K0L0M0N0O1@1A1B1C1D1E1F1G1H1I0I0J0K0L0M0N0O1@1A1B1C1D1E1F1G1H0H0I0J0K0L0M0N0O1@1A1B1C1D1E1F1G0G0H0I0J0K0L0M0N0O1@1A1B1C1D1E1F0F0G0H0I0J0K0L0M0N0O1@1A1B1C1D1E0E0F0G0H0I0J0K0L0M0N0O1@1A1B1C1D0D0E0F0G0H0I0J0K0L0M0N0O1@1A1B1C0C0D0E0F0G0H0I0J0K0L0M0N0O1@1A1B0B0C0D0E0F0G0H0I0J0K0L0M0N0O1@1A0A0B0C0D0E0F0G0H0I0J0K0L0M0N0O1@
Output with a SUB that doesn't use subtraction, but instead adds the complement of the carry and acc:
APtr->acc+=(unsigned char)(((~APtr->carry)&1)+((~APtr->reg[c1&0xf])&0xf));
APtr->carry=(unsigned char)((APtr->acc>>4)&1);
1@1A1B1C1D1E1F1G1H1I1J1K1L1M1N1O0O1@1A1B1C1D1E1F1G1H1I1J1K1L1M1N0N0O1@1A1B1C1D1E1F1G1H1I1J1K1L1M0M0N0O1@1A1B1C1D1E1F1G1H1I1J1K1L0L0M0N0O1@1A1B1C1D1E1F1G1H1I1J1K0K0L0M0N0O1@1A1B1C1D1E1F1G1H1I1J0J0K0L0M0N0O1@1A1B1C1D1E1F1G1H1I0I0J0K0L0M0N0O1@1A1B1C1D1E1F1G1H0H0I0J0K0L0M0N0O1@1A1B1C1D1E1F1G0G0H0I0J0K0L0M0N0O1@1A1B1C1D1E1F0F0G0H0I0J0K0L0M0N0O1@1A1B1C1D1E0E0F0G0H0I0J0K0L0M0N0O1@1A1B1C1D0D0E0F0G0H0I0J0K0L0M0N0O1@1A1B1C0C0D0E0F0G0H0I0J0K0L0M0N0O1@1A1B0B0C0D0E0F0G0H0I0J0K0L0M0N0O1@1A0A0B0C0D0E0F0G0H0I0J0K0L0M0N0O1@
I'm going to keep my original sub code however because it is less complicated for CPU's which have a subtract opcode (which is all of them).