Here is a Forth word that I was converting to Z80 assembler. This is the original unmodified assembler.
; next ( -- ) ; Run time code for the single index loop. ; : next ( -- ) \ hilevel model ; r> r> dup if 1 - >r @ >r exit then drop cell+ >r ; $CODE COMPO+4,'next',DONXT DB 2Ah, 0Ch,0FEh ; LD HL, (RP) ;16t DB 7Eh ; LD A, (HL) ; 7t DB 0B7h ; OR A ; 4t DB 20h, 0Eh ; JR NZ, DECLOW;12/7t a fast dec is ok, only failed every 255 time ; ; low byte 0 DB 23h ; INC HL ; 6t DB 7Eh ; LD A, (HL) ; 7t DB 0B7h ; OR A ; 4t DB 20h, 0Ch ; JR NZ, DECHILO;12/7t Hi-byte no-zero, it is also a re-loop case ;zero bound now .. . DB 23h ; INC HL ; 6tdiscard the loop count on R-stack DB 22h, 0Ch,0FEh ; LD (RP), HL ;16t DB 03h ; INC BC ; 6t\ IP slip over the re-loop-addr DB 03h ; INC BC ; 6t DB 0C3h DW NextStep ; JP NextStep ;10t loop is over ; ; 98t==(10MHz)9.8usec DB 35h ;DECHILO:DEC (HL) ;11t hi-byte DB 2Bh ; DEC HL ; 6t back to low byte DB 35h ;DECLOW:DEC (HL) ;11t low byte non-zero, just dec it and re-loop DB 69h ; LD L, C ; 4t get loop-start-adr to IP and keep stepping DB 60h ; LD H, B ; 4t DB 4Eh ; LD C, (HL) ; 7t DB 23h ; INC HL ; 6t DB 46h ; LD B, (HL) ; 7t DB 0C3h DW NextStep ; JP NextStep ;10t ; low byte dec: 88t==(10MHz)8.8usec ; lo&Hi byte dec: 134t==(10MHz)13.4usec
Now if I calculate the destinations for the the two JRs from the offsets, they don't land where the assembler code claim they should.
From my understanding of the intention of the code, decrement a 16 bit value and leave the loop on 0, the assembler code in the comments is correct and the offsets in the DBs are wrong. So how did this this word ever work at all? I think the author never tested this word.
I'm going to go with the assembler code and note that a discrepancy with the distributed binary is expected here.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.