ZX81 Assembly Listing for pitfallsim.asm


ZX81 assembly listing for *PITFALL SIM**SLR/23*

*PITFALL SIM**SLR/23* (pitfallsim.asm)

A simulator for Activision's PITFALL! for the Atari 2600. I converted the LFSR from 6502 code that David Crain wrote to generate the maps.


ASSEMBLY PROGRAM LISTING

;
; PITFALL! Simulator
;
; A simulator for Activision's PITFALL! for the Atari 2600.
; I converted the LFSR from 6502 code that David Crain
; wrote to generate the maps. I used this article to help
; determine how the map worked:
; article: https://evoniuk.github.io/posts/pitfall.html
; However, I found that some of the descriptions weren't
; complete. Digging around, I found a more complete version
; here: https://meatfighter.com/pitfall/
; The map link provided in the original article also has some
; descrpancies. I ended up finding actual footage of the rooms
; to validate the routines. This program is mmeant as an easy
; way to traverse the map, but without all the game play.
; For testing, I used this long play to check the board was
; accurate: https://www.youtube.com/watch?v=pslbO6Fddhw
;
; 01/04/2023 - Steven Reid
;

; +++
; Header and startup
;
        org 16514               ; stored in REM at top (ZX81)
        jr start                ; jump to start

; Title and copyright (will show when listed)
copy:
        db _as,_p_,_i_,_t_,_f_,_a_,_l_,_l_,_sp,_s_
        db _i_,_m_,_as,_as,_s_,_l_,_r_,_sl,_2_,_3_
        db _as,$76,$76

; some data (since we are here)
room:   db $c4
player: db 0    ; player bits as follow:
        ; 0 - above/below
        ; 1 - player left/right
        ; 6 - no wall/wall
        ; 7 - wall left/right

start:
        call slow               ; SLOW is required.
        call cls                ; clear screen / exapnd screen

; end header
; ---

; +++
; Main Program
;
        call print_title        ; print title and legend
        call move_start         ; move to seed (start of game)
main_loop:
        call print_rooms        ; will print rooms on screen
        call get_move
        call check_move
        jr main_loop

;  end main
; ---

; +++
; Get Move
;
;       Routine won't return until a key is pressed.
;       Screen is upated until that happens.
;
; in:           none
; out:          a       = character code of pressed key
; destroys:     af, bc, hl, de
;
get_move:
        ; did the player make a move?
        ld bc,(last_k)          ; get key information
        inc c                   ; Test if NOKEY pressed
        jr z,get_move           ; not yet then loop
        dec c                   ; restore c

        call findchar           ; yep, grab character pressed
        ld a,(hl)

        ret                     ; return
; end get move
; ---

; +++
; Check Move
;
check_move:
        ; compare keys (only left or right moves)
        cp $70 ; (cursor up)
        jp z,move_up
        cp $71 ; (cursor down)
        jp z,move_down
        cp $72 ; (cursor left)
        jp z,move_left
        cp $73 ; (cursor right)
        jp z,move_right
        cp _5_ ; '5' (left)
        jp z,move_left
        cp _6_ ; '6' (down)
        jp z,move_down
        cp _7_ ; '7' (up)
        jp z,move_up
        cp _8_ ; '8' (right)
        jp z,move_right
        cp _a_ ; 'a' (left)
        jp z,move_left
        cp _d_ ; 'd' (right)
        jp z,move_right
        cp _r_ ; 'r' (reset)
        jp z,move_start
        cp _s_ ; 's' (down)
        jp z,move_down
        cp _w_ ; 'w' (up)
        jp z,move_up

        ret     ; do nothing!
; end check move
; ---

; +++
; Move right - LSFR
;       room' = room << 1 | (bit3 + bit4 + bit5 + bit7)
; input:        none
; uses:         room, a, hl, b
;
move_right:
        ld hl,player            ; get player information
        bit 0,(hl)              ; above ground?
        jr z,move_right_above   ; yes!

        ; check if player can move past wall
        bit 1,(hl)              ; player on left?
        jr nz,move_right_below  ; no, allow move
        bit 6,(hl)              ; is there a wall?
        ret nz                  ; yes, then return (no move)
move_right_below:
        ld b,3
        jr move_right_lsfr
move_right_above:
        ld b,1
move_right_lsfr:
        res 1,(hl)      ; move player to left (set bit 1 to 0)
        ld hl,room      ; set hl to room
mr_loop:
        ld a,(hl)       ; load a with room
        sla a           ; could also be add a,a
        xor (hl)        ; XOR with room
        sla a
        xor (hl)
        sla a
        sla a
        xor (hl)
        sla a
        rl (hl)         ; rotate carry into room
        djnz mr_loop

        ret
; end move right
; ---

; +++
; Move left - LFSR
;       room' = room >> 1 | ((bit4 + bit5 + bit6 + bit0) * 128)
; input:        none
; uses:         room, a, hl, b
;
move_left:
        ld hl,player            ; get player information
        bit 0,(hl)              ; above ground?
        jr z,move_left_above    ; yes!

        ; check if player can move past wall
        bit 1,(hl)              ; player on right?
        jr z,move_left_below    ; no, allow move
        bit 6,(hl)              ; is there a wall?
        ret nz                  ; yes, then return (no move)
move_left_below:
        ld b,3
        jr move_left_lsfr
move_left_above:
        ld b,1
move_left_lsfr:
        set 1,(hl)      ; move player to right (set bit 1 to 1)
        ld hl,room      ; set hl to room
ml_loop:
        ld a,(hl)       ; load a with room
        sla a
        xor (hl)
        sla a
        xor (hl)
        sla a
        sla a
        rl a
        xor (hl)
        srl a
        rr (hl)         ; rotate carry into room
        djnz ml_loop

        ret
; end move left
; ---

; +++
; Move up
;       Move player to above ground
move_up:
        ld hl,player            ; get player information
        bit 0,(hl)              ; below ground? (bit 0 is 1)
        ret z                   ; no, then return (already there)
        bit 6,(hl)              ; at ladder? (is wall bit 1?)
        ret z                   ; no, then return (no move)

        ; okay, see if can reach ladder
        bit 1,(hl)              ; on left (bit 1 is 0?)
        jr z,check_left         ; yes, then check left
; check right
        bit 7,(hl)              ; wall on right? (bit 7 is 1)
        ret nz                  ; yes, then return (no move)
        jr can_move_up
check_left:
        bit 7,(hl)              ; wall on left? (bit 7 is 0)
        ret z                   ; yes, then return (no move)

can_move_up:
        ; okay, player can move up!
        res 0,(hl)              ; move player up (bit 0 set to 0)

        ret
; end move up
; ---

; +++
; Move Down
;       Move player to above ground
move_down:
        ld hl,player            ; get player information
        bit 0,(hl)              ; above ground? (bit 0 is 0)
        ret nz                  ; no, then return (already there)
        bit 6,(hl)              ; at ladder? (is wall bit 1?)
        ret z                   ; no, then return (no move)

        ; okay, player can move down!
        set 0,(hl)              ; move player down (bit 0 set to 1)

        ; okay, move player to opposite side of wall
        bit 1,(hl)              ; player on left (bit 1 is 0?)
        jr z,check_wall_left    ; yes, then check left
; check wall right
        bit 7,(hl)              ; wall on right? (bit 7 is 1)
        ret z                   ; no, then return (all done)
        res 1,(hl)              ; yes, then move player to left
        ret

check_wall_left:
        bit 7,(hl)              ; wall on left? (bit 7 is 0)
        ret nz                  ; no, then return (all done)
        set 1,(hl)              ; yes, then move player to right
        ret
; end move down
; ---

; +++
; Move to start
;       Resest's player's location to seed value.
move_start:
        ld hl,room      ; set hl to room
        ld (hl),$c4     ; set to start of game
        inc hl
        ld (hl),$00     ; move player to left/above ground (0)

        ret
; end move to start
; ---

; +++
; Print Rooms
;
print_rooms:
        call print_borders      ; and print the intial room stuff
        call print_player       ; place player in room
        call print_room         ; print room

        ld hl,$0250             ; longer pause
        call delay

        ret
; end print rooms
; ---

; +++
; Print Player
;       Places player in room (left/right and up/down)
;
print_player:
        ld bc,12+9*256          ; left/top to start
        ld a,_p_                ; what to print
        ld hl,player            ; grab player

        bit 0,(hl)              ; above ground?
        jr z,above_ground       ; yes, skip ahead

; below ground
        ld a,$b5                ; inverted p
        ld b,11                 ; move to below ground

above_ground:
        bit 1,(hl)              ; on left?
        jr z,on_left            ; yes, skip ahead

; on right
        ld c,19                 ; move to right

on_left:
        push af                 ; save a
        call print_at
        pop af
        jp $10                  ; print player
; end print player
; ---

; +++
; Print Room
;       For now, will print the value of the room
;       In future, I want to print what the room decodes to.
print_room:
        ; print map number
        ; move cursor to room
        ld bc,17+15*256
        call printat

        ld a,(room)     ; load a with room
        ld d,a          ; put in d

        call print_binary
        ld a,_sp
        rst $10

        ; print trees first
        ld bc,12+7*256
        call print_at
        ld a,d          ; load a with room
        ld hl,trees
        rlca            ; rotate them to start
        rlca
        and %00000011   ; only need last two bits
        ld b,a
        xor a
        loop:
                add a,9
                djnz loop
        ld c,a          ; add them into bc
        ld b,0

        add hl,bc       ; move to message
        call print      ; and print it!

        ; now print hazard in room
        ld bc,13+9*256
        call print_at

        ld a,d          ; load a with room
        rrca            ; rotate them to start
        rrca
        rrca
        and %00000111   ; only need last three bits
        ld e,a          ; save hazard in e

        ; rest any wall information
        ld hl,player
        res 6,(hl)      ; assume no wall

        ; is this a hole location?
        cp %00000000    ; 1 hole?
        jr z,check_if_left_wall ; yes, jump to check which wall to print
        cp %00000001    ; 3 holes?
        jr nz,print_hazard      ; no, keep going

        ; print where wall is
check_if_left_wall:
        set 6,(hl)              ; there is a wall! (bit 6 is 1)
        res 7,(hl)              ; assume on left (bit 7 is 0)
        bit 7,d                 ; check if wall on left
        jr nz,print_wall_right
print_wall_left:
        ld bc,13+11*256         ; move position down
        call print_at
        ld a,$05
        jr print_wall

print_wall_right:
        set 7,(hl)              ; set wall on right (bit 7 is 1)
        ld bc,18+11*256         ; move position down
        call print_at
        ld a,$85

print_wall:
        rst $10

        ; now print ladder
        ld bc,15+11*256         ; move position down
        call print_at
        ld a,$ad
        rst $10

        ; now go print holes!
        ld bc,13+10*256          ; reset location
        call print_at

print_hazard:
        ld hl,pits
        ld b,e          ; get hazard
        xor a
        loop2:
                add a,6
                djnz loop2
        ld c,a          ; add them into bc
        ld b,0

        add hl,bc       ; move to message
        call print      ; and print it!

test_treasure:
        ld a,e          ; restore hazard
        cp %00000101    ; is treasure?
        jr nz,check_croc_vine   ; no
        ld a,_sp
        rst $10
        ld a,d          ; restore room
        and %00000011   ; only need last two bits
        ld hl,treasure
        ld b,0
        ld c,a
        add hl,bc
        ld a,(hl)
        jp $10

check_croc_vine:
        ld bc,15+7*256          ; reset to vine
        call print_at

        ld a,e          ; restore hazard
        cp %00000100    ; is croc?
        jr nz,test_vines
        bit 1,d         ; test bit 1 (vine)
        ld a,_sp        ; print space
        jr z,print_croc ; no vine
        ld a,_sl        ; print vine
print_croc:
        rst $10
        ld e,a
print_bottom_vine:
        ld bc,14+8*256          ; reset to vine
        call print_at
        ld a,e
        jp $10

test_vines:
        ld e,0          ; no vine printed
        cp %00000010    ; tar pit with vine
        jr z,print_vine
        cp %00000011    ; quicksand with vine
        jr z,print_vine
        cp %00000110    ; shifting tar pit with vine
        jr nz,print_object      ; skip ahead!

print_vine:
        ld a,_sl
        rst $10
        ld e,a          ; vine was printed!

print_object:
        ; print objects
        ld bc,13+8*256
        call print_at
        ld a,d          ; load a with room
        ld hl,objects
        and %000000111   ; only need last three bits
        ld b,a
        xor a
        loopo:
                add a,7
                djnz loopo
        ld c,a          ; add them into bc
        ld b,0

        add hl,bc       ; move to message
        call print      ; and print it!

        ld a,e          ; check if bottom vine
        and a
        jr nz,print_bottom_vine

all_done:
        ret
; ---

; +++
; Print Digit String and Copy Digit String
;
; in:           a (binary value)
;               h = 1 if no leading spaces, 0 if leading spaces
; destroys:     af,bc,hl
; preserves:    de
;

;       Prints a binary string to the text window.
print_binary:
        ld c,0
        ld b,1                  ; set skip flag
        ld h,256-100            ; hundreds
        call pb_num1
        ld h,256-10             ; tens
        call pb_num1
        ld b,0                  ; unset skip flag for last digit
        ld h,256-1              ; ones
pb_num1:
        ld l,$1c-1              ; reset l to zx81 0 -1
pb_num2:
        inc l                   ; next digit
        add a,h                 ; sub digit
        jr c,pb_num2            ; until we are too far
        sub h                   ; then add back
        push af                 ; save digit
        ld a,l                  ; set a to digit in l
        djnz printnum           ; is b==0? Then jump to printnum
        cp $1c                  ; at zero?
        jr nz,printnum          ; no, print number
        inc b                   ; reset skip flag
        ld a,c                  ; check if leading spaces
        and a                   ; check if zero
        jr nz,skipnum           ; no, then skip printing
                                ; if yes, a is 0 which is a space!
printnum:
        rst $10                 ; print digit (or leading space)
skipnum:
        pop af                  ; restore digit

        ret
; end print binary
; ---

; +++
; My Print At
; stops when reaches $ff
;
print_at:
        push hl
        push de
        push bc
;        call printat
        ; this is faster...
        ld hl,(d_file)
        inc hl
        ld de,33
pa_loop:
        add hl,de
        djnz pa_loop
        ld b,0
        add hl,bc
        ld (df_cc),hl
        pop bc
        pop de
        pop hl
        ret
; end my print at
; ---

; +++
; Print string at HL
; stops when reaches $ff
;
print:
        ld a,(hl)               ; load character
        inc hl                  ; increment memory
        cp $ff                  ; last character?
        ret z                   ; yep, return
        rst $10                 ; nope, print it!
        jr print                ; loop
; end print
; ---

; +++
; Delay
;
; set bc to speed
; uses check_break to exit
delay_count: dw $0000
delay:
        ld (delay_count),hl     ; save delay

        call check_break

        ; check if done
        ld hl,(delay_count)     ; grab what to test
        dec hl                  ; subtract 1
        ld a,h                  ; check if done
        or l
        jr nz,delay             ; not zero, keep going!

        ret                     ; pause is done!
; end delay
; ---

; +++
; Break
;
; preserves state, but will exit if SPACE is pushed
check_break:
        exx                     ; save register states

        ; did the player press break key (space)?
        call $0f46              ; was break pressed? (break-1 ROM routine)
        jr nc,break             ; no, exit as normal

        exx                     ; restore registers
        ret                     ; and return

        ; yes, exit the program as normal
break:
        rst $0008               ; call ERROR-1 reset
        db $ff                  ; with error code 0 (normal exit)
; end break
; ---

; +++
; Print Title
print_title:
        ; first, print title
        ld bc,10+2*256
        call printat
        ld hl,title
        call print

        ; priht left legend
        ld bc,0+4*256
        ld hl,left_legend
        call print_line_loop

        ; priht right legend
        ld bc,22+4*256
        ld hl,right_legend
        call print_line_loop

        ; print where at
        ld bc,12+15*256
        call printat
        ld hl,whereat
        call print

        ; priht treasure legend
        ld bc,12+17*256
        ld hl,treasures
        call print_line_loop

        ret
; end print titles
; ---

; +++
; Print Loop
;
print_line_loop:
        ; hl points to what to print at
        ld e,(hl)
        inc hl
        ld d,(hl)
        inc hl
        ld a,(hl)
        inc hl
        ld (loc_jump+1),de      ; save what to add each loop
        add a,b                 ; add b to a (new end)
        ld (loc_length+1),a     ; save end of loop
print_loop:
        call print_at
location:
        push hl
        call print
        pop hl
loc_jump:
        ld de,loc_jump
        add hl,de
        inc b
        ld a,b
loc_length:
        cp 14
        jr nz,print_loop
        ret 
; end print loop
; ---

; +++
; Print Borders
print_borders:
        ; then print each row of screen (clears previous room)
        ld bc,11+4*256
        ld hl,screen
        call print_line_loop

        ret
; end print borders
; ---

; +++
; Data!

; bits 0-2: Objects
objects:
db _sp,_sp,_sp,_sp,_sp,_0_,$ff          ; bit 000 - one rolling log
db _sp,_sp,_sp,_sp,_0_,_0_,$ff          ; bit 001 - two rolling logs together
db _sp,_sp,_sp,_0_,_sp,_0_,$ff          ; bit 010 - two rolling logs spread out
db _0_,_sp,_sp,_0_,_sp,_0_,$ff          ; bit 011 - three rolling logs
db _sp,_sp,_sp,_sp,_sp,_o_,$ff          ; bit 100 - one stationary log
db _o_,_sp,_sp,_o_,_sp,_o_,$ff          ; bit 101 - three stationay logs
db _sp,_sp,_sp,_sp,_sp,_f_,$ff          ; bit 110 - fire
db _sp,_sp,_sp,_sp,_sp,_s_,$ff          ; bit 111 - snake

; if bit 1 and bits 3-5 are 100 (crocodiles), add vine
db _v_,_i_,_n_,_e_,_sp                  ; add vine

; bits 0-1 determine treasure type if bits 3-5 are 101 (treasure)
treasure:
db _m_,_s_,_g_,_r_
; bit 000 - money
; bit 001 - silver
; bit 010 - gold
; bit 011 - ring

; bits 3-5: Pit Type
pits:
db $88,$88,$89,$88,$88,$ff              ; bit 000 - hole with ladder
db $89,$88,$89,$88,$89,$ff              ; bit 001 - hole with ladder with 2 holes
db _mi,_lp,_eq,_rp,_mi,$ff              ; bit 010 - tar pit with vine
db _mi,_lt,_eq,_gt,_mi,$ff              ; bit 011 - quicksand with vine
db _mi,_c_,_c_,_c_,_mi,$ff              ; bit 100 - crocodiles in the water
db _sp,_lp,_eq,_rp,$ff,$ff              ; bit 101 - shifting tar pit with treasure
db _sp,_lp,_eq,_rp,_sp,$ff              ; bit 110 - shifting tar pit with vine
db _sp,_lt,_eq,_gt,_sp,$ff              ; bit 111 - shifting quicksand

; bits 6&7: Trees
trees:
db _y_,_sp,_t_,_sp,_sp,_t_,_sp,_y_,$ff  ; bit 00 - trees | |  | |
db _y_,_sp,_y_,_sp,_y_,_sp,_y_,_sp,$ff  ; bit 01 - trees | | | |
db _t_,_sp,_t_,_sp,_t_,_sp,_t_,_sp,$ff  ; bit 10 - trees  | | | |
db _y_,_sp,_t_,_sp,_t_,_sp,_y_,_sp,$ff  ; bit 11 - trees |  ||  | 

; bits 7: Underground Wall
; if a ladder in scene, wall is is either left or right
; bit 0 - wall left
; bit 1 - wall right

; screen
title:
db _p_,_i_,_t_,_f_,_a_,_l_,_l_,_sl,_sp,_s_,_i_,_m_,$ff
screen:
dw 11    ; increment amount
db 10   ; and number
db $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ff
db $80,$0a,$09,$0a,$09,$0a,$09,$0a,$09,$80,$ff
db $80,$0a,$09,$0a,$09,$0a,$09,$0a,$09,$80,$ff
db $80,$00,$00,$00,$00,$00,$00,$00,$00,$80,$ff
db $80,$00,$00,$00,$00,$00,$00,$00,$00,$80,$ff
db $80,$00,$00,$00,$00,$00,$00,$00,$00,$80,$ff
db $80,$88,$88,$88,$88,$88,$88,$88,$88,$80,$ff
db $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ff
db $80,$8a,$8a,$8a,$8a,$8a,$8a,$8a,$8a,$80,$ff
db $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ff
whereat:
db _r_,_o_,_o_,_m_,_sp,$ff

;
; legends
;
left_legend:
dw 10   ; increment amount
db 12    ; and number
db _sl,_sp,_v_,_i_,_n_,_e_,$ff,$ff,$ff,$ff
db _o_,_sp,_l_,_o_,_g_,$ff,$ff,$ff,$ff,$ff
db _0_,_sp,_r_,_o_,_l_,_l_,_i_,_n_,_g_,$ff
db _c_,_sp,_c_,_r_,_o_,_c_,_s_,$ff,$ff,$ff
db _s_,_sp,_s_,_n_,_a_,_k_,_e_,$ff,$ff,$ff
db _f_,_sp,_f_,_i_,_r_,_e_,$ff,$ff,$ff,$ff
db $89,_sp,_h_,_o_,_l_,_e_,$ff,$ff,$ff,$ff
db $ad,_sp,_l_,_a_,_d_,_d_,_e_,_r_,$ff,$ff
db $85,_sp,_r_,_i_,_g_,_h_,_t_,$ff,$ff,$ff
db _sp,_sp,_w_,_a_,_l_,_l_,$ff,$ff,$ff,$ff
db $05,_sp,_l_,_e_,_f_,_t_,$ff,$ff,$ff,$ff
db _sp,_sp,_w_,_a_,_l_,_l_,$ff,$ff,$ff,$ff

right_legend:
dw 11   ; increment amount
db 10   ; and number
db _mi,_lp,_rp,_mi,_sp,_t_,_a_,_r_,$ff,$ff,$ff
db _sp,_p_,_i_,_t_,$ff,$ff,$ff,$ff,$ff,$ff,$ff
db _mi,_lt,_gt,_mi,_sp,_q_,_u_,_i_,_c_,_k_,$ff
db _sp,_s_,_a_,_n_,_d_,$ff,$ff,$ff,$ff,$ff,$ff
db _sp,_lp,_rp,_sp,_s_,_h_,_i_,_f_,_t_,_mi,$ff
db _sp,_i_,_n_,_g_,_sp,_t_,_a_,_r_,$ff,$ff,$ff
db _sp,_p_,_i_,_t_,$ff,$ff,$ff,$ff,$ff,$ff,$ff
db _sp,_lt,_gt,_sp,_s_,_h_,_i_,_f_,_t_,_mi,$ff
db _sp,_i_,_n_,_g_,_sp,_q_,_u_,_i_,_c_,_k_,$ff
db _sp,_s_,_a_,_n_,_d_,$ff,$ff,$ff,$ff,$ff,$ff

treasures:
dw 9    ; increment amount
db 4    ; and number
db _m_,_sp,_m_,_o_,_n_,_e_,_y_,$ff,$ff
db _g_,_sp,_g_,_o_,_l_,_d_,$ff,$ff,$ff
db _s_,_sp,_s_,_i_,_l_,_v_,_e_,_r_,$ff
db _r_,_sp,_r_,_i_,_n_,_g_,$ff,$ff,$ff

; ---

; +++
;
; Data and Defines
;

; ZX81 system vars
d_file:         equ $400c
df_cc:          equ 16398
last_k:         equ 16421
margin:         equ 16424
s_posn:         equ 16441
frames:         equ 16436

; ZX81 ROM functions
kscan:          equ $02bb
findchar:       equ $07bd
stop:           equ $0cdc
slow:           equ $0f2b
fast:           equ $02e7
save:           equ $02f9
printat:        equ $08f5
pause:          equ $0f35
cls:            equ $0a2a

; ZX81 Characters (not ASCII)
_sp:            equ $00
_qu:            equ $0b
_lb:            equ $0c
_dl:            equ $0d
_cl:            equ $0e
_lp:            equ $10
_rp:            equ $11
_gt:            equ $12
_lt:            equ $13
_eq:            equ $14
_pl:            equ $15
_mi:            equ $16
_as:            equ $17
_sl:            equ $18
_sc:            equ $19
_cm:            equ $1a
_pr:            equ $1b
_0_:            equ $1c
_1_:            equ $1d
_2_:            equ $1e
_3_:            equ $1f
_4_:            equ $20
_5_:            equ $21
_6_:            equ $22
_7_:            equ $23
_8_:            equ $24
_9_:            equ $25
_a_:            equ $26
_b_:            equ $27
_c_:            equ $28
_d_:            equ $29
_e_:            equ $2a
_f_:            equ $2b
_g_:            equ $2c
_h_:            equ $2d
_i_:            equ $2e
_j_:            equ $2f
_k_:            equ $30
_l_:            equ $31
_m_:            equ $32
_n_:            equ $33
_o_:            equ $34
_p_:            equ $35
_q_:            equ $36
_r_:            equ $37
_s_:            equ $38
_t_:            equ $39
_u_:            equ $3a
_v_:            equ $3b
_w_:            equ $3c
_x_:            equ $3d
_y_:            equ $3e
_z_:            equ $3f

; end defines
; ---