ibancg / zxcircle

A fast circle algorithm for ZX Spectrum
GNU General Public License v3.0
14 stars 3 forks source link

Screen address finding. #4

Open Sarah-C opened 2 years ago

Sarah-C commented 2 years ago

https://retrocomputing.stackexchange.com/questions/20425/zx-spectrum-coordinates-to-bitmap-conversion-subroutine-acting-strange

Looking at the Y calculation code, I think it's a few bytes less/quicker than the look up algorithm you're using? I don't know how many T-States it is though.


  ld      hl,tabpow2
    ld      a,(x)
    and     7       ; x mod 8
    ld      b,0
    ld      c,a
    add     hl,bc
    ld      a,(hl)
    ld      e,a     ; e contains one bit set

    ld      hl,tablinidx
    ld      a,(y)
    ld      b,0
    ld      c,a
    add     hl,bc
    ld      a,(hl)      ; table lookup

    ld      h,0
    ld      l,a
    add     hl,hl
    add     hl,hl
    add     hl,hl
    add     hl,hl
    add     hl,hl       ; x32 (16 bits)

    set     6,h         ; adds the screen start address (16384)

Vs


000A            convert_xy:    ; convert (x,y) in BC to memory address in HL
000A                           ; assuming arguments are always in valid range

000A   79             LD   a,c       ; getting Y position bits [5:3] ...
000B   07             RLCA           ; adjust it for the address lower byte's
000C   07             RLCA           ; bits [7:5]
000D   E6 E0          AND  $e0       ; mask out the garbage
000F   B0             OR   b         ; mix in the X coordinate
0010   6F             LD   l,a       ; this is final result for address low byte

0011   79             LD   a,c       ; back to Y
0012   E6 07          AND  $7        ; bits Y[2:0] are already in place
0014   F6 40          OR   $40       ; make it $4000 base
0016   67             LD   h,a       ; intermediate state is set to H
0017   79             LD   a,c   
0018   0F             RRCA           ; moving bits Y[7:6] to close the gap
0019   0F             RRCA           ; that was taken by bits Y[5:3] before
001A   0F             RRCA      
001B   E6 18          AND  $18       ; mask out the garbage
001D   B4             OR   h         ; join with temporary in H
001E   67             LD   h,a       ; this is final address high byte
001F   C9             RET     
chupocro commented 12 months ago

The code from Stack Overflow expects x coordinate in the range of characters (0 - 31) so B should be divided by 8 for using with that routine which is at least three slow shift operations more.

The whole routine could be improved by using registers instead of memory locations for the coordinates, by avoiding pushing so many registers on the stack (which is not easy to do) and by replacing:

        scf
        ccf

with

        or a