ZX81 Machine Code demo: how to move a dot around

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
Post Reply
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

ZX81 Machine Code demo: how to move a dot around

Post by David G »

a sample program that shows how to move a dot around the screen using the arrow keys
MOVEDOT_4K.p
(1.17 KiB) Downloaded 148 times

Attached is the Assembly file for ZX-IDE
MOVEDOT_4K.ASM
(6.12 KiB) Downloaded 154 times
(get ZX-IDE for Windows at viewtopic.php?f=6&t=1064 -- download FASMW-ZX)

REQUIRES 4K OR MORE MEMORY AS IT USES A FULL SCREEN DISPLAY. Something similar can work for 1K but needs different code to handle a smaller display file.

Basically works like this.

Code: Select all

  MOVEDOT:   LD      HL,(D_FILE)          ;HL=DFILE (DISPLAY AREA OF MEMORY)
             INC     HL                   ;HL=1ST CHARACTER OF FIRST LINE OF DFILE
             LD      (D_CURSOR),HL
             LD      A,(HL)
             LD      (OLDSPACE),A         ;SAVE WHAT IS THERE ALREADY
             LD      (HL),DOT             ;PUT THE DOT THERE
   MDLOOP:   CALL    GETKEY
             OR      A                    ;A=0 (SPACE/BREAK)
             RET     Z                    ;' ' SPACE (BREAK), EXIT PROGRAM
             CP      ZX_R_ARROW
             CALL    Z,RIGHT
             CP      ZX_L_ARROW
             CALL    Z,LEFT
             CP      ZX_U_ARROW
             CALL    Z,UPDOWN
             CP      ZX_D_ARROW
             CALL    Z,UPDOWN
             JR      MDLOOP
The ASM file include the subroutines such as LEFT, RIGHT, etc. and the BASIC program to launch it

Code: Select all

  //ROM SUBROUTINES
  DECODE       EQU $07BD
  //KEYCODES
  ZX_U_ARROW EQU 70H  ;UP ARROW
  ZX_D_ARROW EQU 71H  ;DOWN ARROW
  ZX_L_ARROW EQU 72H  ;LEFT ARROW
  ZX_R_ARROW EQU 73H  ;RIGHT ARROW
  ZX_INV_SP  EQU 80H  ;'±' INVERSE SPACE

  DOT        EQU ZX_INV_SP

  //VARIABLES FOR THE PROGRAM
  OLDSPACE: db 00
  D_CURSOR: dw 0000

  MOVEDOT:   LD      HL,(D_FILE)          ;HL=DFILE (DISPLAY AREA OF MEMORY)
             INC     HL                   ;HL=1ST CHARACTER OF FIRST LINE OF DFILE
             LD      (D_CURSOR),HL
             LD      A,(HL)
             LD      (OLDSPACE),A         ;SAVE WHAT IS THERE ALREADY
             LD      (HL),DOT             ;PUT THE DOT THERE
   MDLOOP:   CALL    GETKEY
             OR      A                    ;A=0 (SPACE/BREAK)
             RET     Z                    ;' ' SPACE (BREAK), EXIT PROGRAM
             CP      ZX_R_ARROW
             CALL    Z,RIGHT
             CP      ZX_L_ARROW
             CALL    Z,LEFT
             CP      ZX_U_ARROW
             CALL    Z,UPDOWN
             CP      ZX_D_ARROW
             CALL    Z,UPDOWN
             JR      MDLOOP

    RIGHT:   PUSH    AF                      ;SAVE THE A REGISTER
             LD      HL,(D_CURSOR)
             INC     HL
             LD      A,(HL)
             CP      76H                     ; EOL MARKER
             JR      Z,R_FIN                 ; DONT GO PAST EOL
             DEC     HL
             LD      A,(OLDSPACE)
             LD      (HL),A
             INC     HL
             LD      (D_CURSOR),HL
             LD      A,(HL)
             LD      (OLDSPACE),A
             LD      (HL),DOT
       R_FIN:POP     AF                       ;RESTORE THE A REGISTER
             RET

    LEFT:    PUSH    AF
             LD      HL,(D_CURSOR)
             DEC     HL
             LD      A,(HL)
             CP      76H                     ; EOL MARKER
             JR      Z,L_FIN                 ; DONT GO PAST EOL
             INC     HL
             LD      A,(OLDSPACE)
             LD      (HL),A
             DEC     HL
             LD      (D_CURSOR),HL
             LD      A,(HL)
             LD      (OLDSPACE),A
             LD      (HL),DOT
       L_FIN:POP     AF
             RET

      UPDOWN:LD      DE,0021H             ;ONE ZX81 DISPLAY LINE = 32 CHAR + EOL (33d OR 21h)
             LD      HL,(D_CURSOR)
             CP      ZX_U_ARROW
             JR      Z,UP
        DOWN:ADD     HL,DE                ;BOUNDS CHECK , ADD ONE LINE
             EX      DE,HL                ;DE=ONE LINE DOWN
             LD      HL,VARS_ADDR         ;ADDRESS AFTER THE DFILE (DISPLAY AREA)
             DEC     HL
             OR      A
             SBC     HL,DE
             RET     C                    ;DO NOT GO BELOW DISPLAY AREA
             JR      UD_FIN
        UP:  OR      A                    ;BOUNDS CHECK
             SBC     HL,DE
             EX      DE,HL
             LD      HL,(D_FILE)
             OR      A
             SBC     HL,DE
             RET     NC                   ;DO NOT GO UP
     UD_FIN: PUSH    AF                   ;SAVE THE A REGISTER (WHICH CONTAINS THE KEYCODE)
             LD      A,(OLDSPACE)
             LD      HL,(D_CURSOR)
             LD      (HL),A
             LD      (D_CURSOR),DE
             LD      A,(DE)
             LD      (OLDSPACE),A
             LD      A,DOT
             LD      (DE),A
             POP     AF                   ;RETURN WITH A SAME AS BEFORE
             RET

   GETKEY:   ;RETURN WITH A=KEYPRESS
     SCANKEY:LD      A,(4025H);LAST_K
             INC     A
             JR      NZ,SCANKEY
     GOTKEY: LD      BC,(LAST_K)
             LD      A,C
             INC     A
             JR      Z,GOTKEY
             CALL    DECODE
             JR      NC,GOTKEY
             LD      A,(HL)
             RET
Post Reply