Z80 Assembly for ZX Spectrum how to use a variable as PRINT AT coordinates

183 views Asked by At

I've been messing around with the ZX Spin emulator and Assembly language. I used to write BASIC games back in the 80s, and always wanted to learn machine code, but too stupid as a 12 year old kid. I've been putting this simple code together that simply creates a series of UDGs that make up an image, and should print the image onto the screen. I'm a little stuck though on how to get it to use my TIT_X_POS and TIT_Y_POS variables, which I have stored and initialised into memory locations. It seems to be tied to the "_AT" coordinates in the DEFB statements, and you cannot seem to pass in variables into those. Does anyone have any quick tips? Here is the code:

ORG 30000

    _MAIN 

        CALL SUB_STARTUP
        CALL SUB_PRINT_TIT                                  ;Print TIT sprite
    RET                                                 ;Return to BASIC

    _SUBS 

    SUB_STARTUP

        CALL CLS

        LD A, 0
        LD (TIT_Y_POS), A
        LD A, 25
        LD (TIT_X_POS), A

    RET

    SUB_PRINT_TIT               

        LD HL, TIT_UDGS                                         ;Get location of UDG data.
        LD (UDGPOINTER), HL                                     ;Set UDG SYSVAR pointer.
        LD A, 2                                                 ;Set output channel 2 (upper screen).
        CALL OUTCHAN                                            ;Activate output channel.
        LD DE, TIT_STR                                          ;Start of string.
        LD BC, TIT_STR_END-TIT_STR                              ;Length of string.
    
        ;;;;;;;;;;STUCK HERE - How do I get it to use TIT_Y_POS and TIT_X_POS instead of the _AT values in DEFB?
    
        CALL PRINTSTRING                                    ;Print string.

    RET                                                 ; Return from SUB_PRINT_TIT

    _SYSVARS 

    UDGPOINTER          EQU 23675                           ;UDG pointer.
    TIT_X_POS           EQU 23700                           ;Memory location for X coordinate
    TIT_Y_POS           EQU 23701                           ;Memory location for Y coordinate

    _ROM 

    BORDER              EQU 8859                            ;Set border color.
    CLS                 EQU 3503                            ;Clear screen using attributes in ATTR-P (23693)
    OUTCHAN             EQU 5633                            ;Activate output channel.
    PRINTNUMSMALL           EQU 6683                            ;Print number in BC (9999 max).
    PRINTNUMBIG1            EQU 11563                           ;(1 of 2) to print number in BC (65535 max).
    PRINTNUMBIG2            EQU 11747                           ;(2 of 2) to print number in BC (65535 max).
    PRINTSTRING             EQU 8252                            ;Print string (DE start, BC length).

    _VALUES 

    ;Store values into memory here.

    _STRINGS 

    TIT_STR                                             ;TIT sprite string.

        DEFB _AT, 0, 0, ink, blk, paper, wht, flash, off, bright, off, ua, ub, ue, uf           ;TIT - top
        DEFB _AT, 1, 0,ink, blk, paper, wht, flash, off, bright, off, uc, ud, ug, uh            ;TIT - bottom

    TIT_STR_END EQU $                                       ;Marker for end of string data.

    _CODES EQU $ 

    cr  equ 13                                              ;carriage return.
    ink  equ 16                                             ;INK control code.
    paper  equ 17                                           ;PAPER control code.
    flash  equ 18                                           ;FLASH control code.
    bright  equ 19                                          ;BRIGHT control code.
    inverse equ 20                                          ;INVERSE control code.
    off equ 0                                           ;OFF control code.
    on equ 1                                            ;ON control code.
    _at  equ 22                                             ;AT control code.
    _tab  equ 23                                            ;TAB
    blk  equ 0                                              ;Blk.
    blu  equ 1                                              ;Blue.
    red  equ 2                                              ;Red.
    mag  equ 3                                              ;Magenta.
    grn  equ 4                                              ;Green.
    cyn  equ 5                                              ;Cyan.
    yel  equ 6                                              ;Yellow.
    wht  equ 7                                              ;White.
    ua  equ 144                                             ;UDG "A".
    ub  equ 145                                             ;UDG "B".
    uc  equ 146                                             ;UDG "C".
    ud  equ 147                                             ;UDG "D".
    ue  equ 148                                             ;UDG "E".
    uf  equ 149                                             ;UDG "F".
    ug  equ 150                                             ;UDG "G".
    uh  equ 151                                             ;UDG "H".
    ui  equ 152                                             ;UDG "I".
    uj  equ 153                                             ;UDG "J".
    uk  equ 154                                             ;UDG "K".
    ul  equ 155                                             ;UDG "L".
    um  equ 156                                             ;UDG "M".
    un  equ 157                                             ;UDG "N".
    uo  equ 158                                             ;UDG "O".
    up  equ 159                                             ;UDG "P".
    uq  equ 160                                             ;UDG "Q".
    ur  equ 161                                             ;UDG "R".
    us  equ 162                                             ;UDG "S".
    ut  equ 163                                             ;UDG "Y".
    uu  equ 164                                             ;UDG "U".

    _UDGS ;********************************* UDGS ********************************

    TIT_UDGS                                            ;UDGs.
        ; (A,B)Top-left TIT sprite
        DEFB 15,18,33,41,41,41,33,17, 255,2,1,0,32,16,16,32
        ; (C,D)Bot-left TIT sprite
        DEFB 18,13,0,0,0,1,0,0, 0,255,64,64,64,255,0,0
        ; (E,F)Top-right TIT sprite
        DEFB 255,32,144,72,72,48,0,0, 255,1,2,2,4,8,16,16
        ; (G,H)Bot-right TIT sprite
        DEFB 0,255,2,2,2,255,0,0, 32,192,0,0,0,128,0,0

Many thanks in advance.

1

There are 1 answers

0
Davy C On

I discovered that the easiest solution is to just dynamically adjust the bytes stored in the "TIT_STR" itself with the values of the X/Y coordinates in there relevant places according to the DEFBs:

SUB_PRINT_TIT               

    LD HL, TIT_UDGS                                     
    LD (UDGPOINTER), HL                                     
    LD A, 2                                         
    CALL OUTCHAN

    LD A, (TIT_Y_POS)
    LD (TIT_STR+1), A
    INC A
    LD (TIT_STR+16), A

    LD A, (TIT_X_POS)
    LD (TIT_STR+2), A
    LD (TIT_STR+17), A
                                
    LD DE, TIT_STR                                      
    LD BC, TIT_STR_END-TIT_STR                              

    CALL PRINTSTRING                                    

RET

enter image description here

Therefore, as long as "TIT_Y_POS" and "TIT_X_POS" are updated prior, simply calling "SUB_TIT_PRINT" will always honour the locations according to the coordinates.