Close

Who to believe?

A project log for eForth/z80 modifications

A more hackable eForth/z80

ken-yapKen Yap 08/08/2019 at 12:460 Comments

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