; ram_sub.asm
; subtract two BCD numbers on the Intel 4004
init:
 FIM R0R1, 0  ; ram 1, bank 0, address 0
 FIM R2R3, 1  ; ram 1, bank 1, address 0
 FIM R4R5, 2  ; ram 1, bank 2, address 0
 LDM 1
 SRC 0        ; select register 0, address 0
 WRM          ; store 1
 INC R1
 LDM 2
 SRC 0        ; select register 0, address 1
 WRM          ; store 2
 INC R1
 LDM 3
 SRC 0        ; select register 0, address 2
 WRM          ; store 3
 WR0          ; store length 3
 LDM 1
 SRC 1        ; select register 1, address 0
 WRM          ; store 1
 INC R3
 LDM 1
 SRC 1        ; select register 1, address 1
 WRM          ; store 1
 INC R3
 LDM 7
 SRC 1        ; select register 1, address 2
 WRM          ; store 7
 INC R3
 LDM 4
 src 1        ; select register 1, address 3
 WRM          ; store 4
 WR0          ; store length 4
begin:
 SRC 1        ; number 2
 RD0          ; read length
 XCH R6      
 SRC 0        ; number 1
 RD0          ; read length
 SUB R6
 JCN NC, len2 ; number 2 > 1
 JCN NZ, go   ; number 1 > 2
 RD0          ; length number 1
 DAC
 XCH R6
check:
 CLC
 LD R6
 XCH R1
 LD R6
 XCH R3
 SRC 0
 RDM          ; read digit number 1
 SRC 1
 SBM          ; subtract digit number 1
 JCN NC, len2 ; number 2 > 1
 JCN NZ, go   ; number 1 > 2
 LD R6
 JCN Z, go    ; last digit checked
 DAC
 XCH R6
 JUN check
len2:
 LD R0
 XCH R2
 XCH R0
 LDM 1        ; store negativ sign
 XCH R8
 SRC 0
go:
 RD0  
 XCH R6       ; store length
 LDM 0        ; reset addresses
 XCH R1
 LDM 0
 XCH R3
doSub:
 JMS ldBorrow
 SRC 0
 RDM          ; read digit of number 1 
 SRC 1
 SBM          ; subtract digit of number 2
 JCN C, go2   ; carry not set when result<0
 STC          ; carry 0 after JCN
 DAA 
go2:
 SRC 2
 WRM          ; write digit of result
 TCC          ; store borrow
 XCH R7
 RDM
 JCN NZ, noZero
 INC R9       ; zeros in result
 JUN go3
noZero:
 LDM 0
 XCH R9
go3:
 LD R6        ; check length
 DAC
 JCN Z, endSub ; no digits left, ready
 XCH R6
 INC R1       ; next addresses
 INC R3
 INC R5
 JUN doSub    ; subtract next digits
endSub:
 LD R8        ; write sign
 SRC 2
 WR1
 LD R5        ; write lenght of result       
 IAC
 SUB R9
 WR0
done:
 JUN done     ; end
ldBorrow:
 LDM 15       ; restore carry
 ADD R7
 BBL 0 
 