joystick: working on joystick code

This commit is contained in:
Vince Weaver 2020-09-05 00:36:07 -04:00
parent 28bd57c753
commit 4079f21cd6
13 changed files with 1884 additions and 0 deletions

27
joystick/Makefile Normal file
View File

@ -0,0 +1,27 @@
include ../Makefile.inc
DOS33 = ../dos33fs-utils/dos33
DOS33_RAW = ../dos33fs-utils/dos33_raw
PNG_TO_40x96 = ../gr-utils/png_to_40x96
PNG_TO_40x48D = ../gr-utils/png_to_40x48d
PNG2RLE = ../gr-utils/png2rle
B2D = ../bmp2dhr/b2d
all: js.dsk
js.dsk: JS
cp empty.dsk js.dsk
$(DOS33) -y js.dsk BSAVE -a 0x1000 JS
####
JS: js_test.o
ld65 -o JS js_test.o -C ../linker_scripts/apple2_1000.inc
js_test.o: js_test.s keyboard.s joystick.s
ca65 -o js_test.o js_test.s -l js_test.lst
####
clean:
rm -f *~ *.o *.lst JS

View File

@ -0,0 +1,88 @@
finger_point_sprite:
.byte 5,5
.byte $AA,$BB,$AA,$AA,$AA
.byte $AA,$BB,$AA,$AA,$AA
.byte $BA,$BB,$BB,$BB,$BB
.byte $AB,$BB,$BB,$BB,$BB
.byte $AA,$BB,$BB,$BB,$AA
finger_grab_sprite:
.byte 5,5
.byte $AA,$AA,$BB,$AA,$AA
.byte $BB,$AA,$BB,$AA,$BB
.byte $BB,$BA,$BB,$BA,$BB
.byte $AB,$BB,$BB,$BB,$BB
.byte $AA,$BB,$BB,$BB,$AA
finger_left_sprite:
.byte 6,4
.byte $AA,$AA,$AA,$AB,$BA,$AA
.byte $BB,$BB,$BB,$BB,$BB,$BB
.byte $AA,$AA,$BB,$BB,$BB,$BB
.byte $AA,$AA,$AB,$BB,$BB,$AB
finger_right_sprite:
.byte 6,4
.byte $AA,$BA,$AB,$AA,$AA,$AA
.byte $BB,$BB,$BB,$BB,$BB,$BB
.byte $BB,$BB,$BB,$BB,$AA,$AA
.byte $AB,$BB,$BB,$AB,$AA,$AA
finger_turn_left_sprite:
.byte 6,4
.byte $aa,$aa,$ba,$bb,$aa,$aa
.byte $ba,$bb,$bb,$bb,$bb,$ba
.byte $aa,$ab,$bb,$bb,$ab,$bb
.byte $aa,$aa,$aa,$ab,$aa,$ab
finger_turn_right_sprite:
.byte 6,4
.byte $aa,$aa,$bb,$ba,$aa,$aa
.byte $ba,$bb,$bb,$bb,$bb,$ba
.byte $bb,$ab,$bb,$bb,$ab,$aa
.byte $ab,$aa,$ab,$aa,$aa,$aa
finger_match_sprite:
.byte 6,4
.byte $aa,$aa,$aa,$aa,$ba,$ba
.byte $1a,$da,$da,$db,$db,$db
.byte $a1,$ad,$ad,$bd,$bd,$ad
.byte $aa,$aa,$aa,$aa,$ab,$bb
finger_match_lit_sprite:
.byte 6,4
.byte $9a,$a9,$aa,$aa,$ba,$ba
.byte $19,$da,$da,$db,$db,$db
.byte $a9,$ad,$ad,$bd,$bd,$ad
.byte $aa,$aa,$aa,$aa,$ab,$bb
finger_key_sprite:
.byte 6,4
.byte $aa,$aa,$aa,$aa,$aa,$bd
.byte $dd,$dd,$dd,$dd,$db,$bb
.byte $aa,$ad,$aa,$ab,$bd,$bb
.byte $aa,$aa,$aa,$aa,$ab,$ab
finger_red_page_sprite:
.byte 5,5
.byte $3a,$33,$33,$aa,$aa
.byte $33,$33,$33,$ba,$aa
.byte $33,$b3,$33,$bb,$ba
.byte $33,$3b,$bb,$bb,$bb
.byte $a3,$a3,$bb,$bb,$bb
finger_blue_page_sprite:
.byte 5,5
.byte $6a,$66,$66,$aa,$aa
.byte $66,$66,$66,$ba,$aa
.byte $66,$b6,$66,$bb,$ba
.byte $66,$6b,$bb,$bb,$bb
.byte $a6,$a6,$bb,$bb,$bb
finger_white_page_sprite:
.byte 5,5
.byte $fa,$ff,$ff,$aa,$aa
.byte $ff,$ff,$ff,$ba,$aa
.byte $ff,$bf,$ff,$bb,$ba
.byte $ff,$fb,$bb,$bb,$bb
.byte $af,$af,$bb,$bb,$bb

268
joystick/draw_pointer.s Normal file
View File

@ -0,0 +1,268 @@
;====================================
; draw pointer
;====================================
draw_pointer:
; point sprite to right location (X,Y)
lda CURSOR_X
sta XPOS
lda CURSOR_Y
sta YPOS
; see if inside special region
; ldy #LOCATION_SPECIAL_EXIT
; lda (LOCATION_STRUCT_L),Y
; cmp #$ff
; beq finger_not_special ; if $ff not special
; lda (LOCATION_STRUCT_L),Y
; cmp #DIRECTION_ANY
; beq was_any
; lda DIRECTION
; and #$f
; and (LOCATION_STRUCT_L),Y
; beq finger_not_special ; only special if facing right way
;was_any:
; see if X1 < X < X2
; lda CURSOR_X
; ldy #LOCATION_SPECIAL_X1
; cmp (LOCATION_STRUCT_L),Y
; bcc finger_not_special ; blt
; ldy #LOCATION_SPECIAL_X2
; cmp (LOCATION_STRUCT_L),Y
; bcs finger_not_special ; bge
; see if Y1 < Y < Y2
; lda CURSOR_Y
; ldy #LOCATION_SPECIAL_Y1
; cmp (LOCATION_STRUCT_L),Y
; bcc finger_not_special ; blt
; ldy #LOCATION_SPECIAL_Y2
; cmp (LOCATION_STRUCT_L),Y
; bcs finger_not_special ; bge
; we made it this far, we are special
;finger_grab:
; lda #1
; sta IN_SPECIAL
; lda CURSOR_VISIBLE ; if not visible skip
; bne really_draw_grab
; rts
;really_draw_grab:
; lda DIRECTION
; and #DIRECTION_ONLY_POINT
; bne special_but_point
; lda #<finger_grab_sprite
; sta INL
; lda #>finger_grab_sprite
; jmp finger_draw
;special_but_point:
; jmp finger_point
finger_not_special:
; lda CURSOR_VISIBLE ; if not visible skip
; bne really_not_special
; rts
really_not_special:
; check for left/right
lda CURSOR_X
cmp #7
bcc check_cursor_left ; blt
cmp #33
bcs check_cursor_right ; bge
; otherwise, finger_point
finger_point:
; holding item takes precednce
lda HOLDING_ITEM
cmp #HOLDING_MATCH
beq match_finger
cmp #HOLDING_LIT_MATCH
beq match_lit_finger
cmp #HOLDING_KEY
beq key_finger
lda HOLDING_PAGE
and #$c0
beq real_finger_point
cmp #HOLDING_BLUE_PAGE
beq blue_finger
cmp #HOLDING_WHITE_PAGE
beq white_finger
cmp #HOLDING_RED_PAGE
; beq red_finger
red_finger:
lda #<finger_red_page_sprite
sta INL
lda #>finger_red_page_sprite
jmp finger_draw
; all that's left is key
key_finger:
lda #<finger_key_sprite
sta INL
lda #>finger_key_sprite
jmp finger_draw
match_finger:
lda #<finger_match_sprite
sta INL
lda #>finger_match_sprite
jmp finger_draw
match_lit_finger:
lda #<finger_match_lit_sprite
sta INL
lda #>finger_match_lit_sprite
jmp finger_draw
blue_finger:
lda #<finger_blue_page_sprite
sta INL
lda #>finger_blue_page_sprite
jmp finger_draw
white_finger:
lda #<finger_white_page_sprite
sta INL
lda #>finger_white_page_sprite
jmp finger_draw
real_finger_point:
lda #<finger_point_sprite
sta INL
lda #>finger_point_sprite
jmp finger_draw
check_cursor_left:
jsr lookup_direction
and #$f
beq finger_point
cmp #$1
beq finger_left
bne finger_uturn_left
check_cursor_right:
jsr lookup_direction
and #$f0
beq finger_point
cmp #$10
beq finger_right
bne finger_uturn_right
log2_table:
; 0 1 2 3 4 5 6 7 8
.byte 0,0,1,1,2,2,2,2,3
lookup_direction:
; lda DIRECTION
; and #$f
; tay
; lda log2_table,Y
; asl
; asl
; asl
; asl
; clc
; ldy #LOCATION_BGS
; adc (LOCATION_STRUCT_L),Y
; tay
; lda direction_lookup,Y
rts
finger_left:
lda #1
sta IN_LEFT
lda #<finger_left_sprite
sta INL
lda #>finger_left_sprite
jmp finger_draw
finger_right:
lda #1
sta IN_RIGHT
lda #<finger_right_sprite
sta INL
lda #>finger_right_sprite
jmp finger_draw
finger_uturn_left:
lda #2
sta IN_LEFT
lda #<finger_turn_left_sprite
sta INL
lda #>finger_turn_left_sprite
jmp finger_draw
finger_uturn_right:
lda #2
sta IN_RIGHT
lda #<finger_turn_right_sprite
sta INL
lda #>finger_turn_right_sprite
jmp finger_draw
finger_draw:
sta INH
jsr put_sprite_crop
no_draw_pointer:
rts
; 0 = point
; 1 = left
; 2 = left u-turn
; R/L EWSN 0010
; 1010
direction_lookup:
direction_lookup_n:
.byte $00,$00,$22,$22,$01,$01,$21,$21,$10,$10,$12,$12,$11,$11,$11,$11
direction_lookup_s:
; N S SN W WN WS WSN
.byte $00, $22,$00,$22,$10,$12,$10,$12
; E EN ES ESN EW EWN EWS EWSN
.byte $01,$02,$01,$21,$11,$11,$11,$11
direction_lookup_e:
.byte $00,$01,$10,$11,$22,$21,$12,$11,$00,$01,$10,$11,$22,$21,$12,$11
direction_lookup_w:
.byte $00,$10,$01,$11,$00,$10,$01,$11,$22,$12,$21,$11,$22,$12,$21,$11

BIN
joystick/empty.dsk Normal file

Binary file not shown.

161
joystick/gr_copy.s Normal file
View File

@ -0,0 +1,161 @@
;=========================================================
; gr_copy_to_current, 40x48 version
;=========================================================
; copy 0xc00 to DRAW_PAGE
;
; 45 + 2 + 120*(8*9 + 5) -1 + 6 = 9292
;.align $100
gr_copy_to_current:
lda DRAW_PAGE ; 3
clc ; 2
adc #$4 ; 2
sta gr_copy_line+5 ; 4
sta gr_copy_line+11 ; 4
adc #$1 ; 2
sta gr_copy_line+17 ; 4
sta gr_copy_line+23 ; 4
adc #$1 ; 2
sta gr_copy_line+29 ; 4
sta gr_copy_line+35 ; 4
adc #$1 ; 2
sta gr_copy_line+41 ; 4
sta gr_copy_line+47 ; 4
;===========
; 45
ldy #119 ; for early ones, copy 120 bytes ; 2
gr_copy_line:
lda $C00,Y ; load a byte (self modified) ; 4
sta $400,Y ; store a byte (self modified) ; 5
lda $C80,Y ; load a byte (self modified) ; 4
sta $480,Y ; store a byte (self modified) ; 5
lda $D00,Y ; load a byte (self modified) ; 4
sta $500,Y ; store a byte (self modified) ; 5
lda $D80,Y ; load a byte (self modified) ; 4
sta $580,Y ; store a byte (self modified) ; 5
lda $E00,Y ; load a byte (self modified) ; 4
sta $600,Y ; store a byte (self modified) ; 5
lda $E80,Y ; load a byte (self modified) ; 4
sta $680,Y ; store a byte (self modified) ; 5
lda $F00,Y ; load a byte (self modified) ; 4
sta $700,Y ; store a byte (self modified) ; 5
lda $F80,Y ; load a byte (self modified) ; 4
sta $780,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line ; ; 2nt/3
rts ; 6
;=========================================================
; gr_copy_to_current, 40x48 version
;=========================================================
; copy 0x1000 to DRAW_PAGE
gr_copy_to_current_1000:
lda DRAW_PAGE ; 3
clc ; 2
adc #$4 ; 2
sta gr_copy_line_40+5 ; 4
sta gr_copy_line_40+11 ; 4
adc #$1 ; 2
sta gr_copy_line_40+17 ; 4
sta gr_copy_line_40+23 ; 4
adc #$1 ; 2
sta gr_copy_line_40+29 ; 4
sta gr_copy_line_40+35 ; 4
adc #$1 ; 2
sta gr_copy_line_40+41 ; 4
sta gr_copy_line_40+47 ; 4
;===========
; 45
ldy #119 ; for early ones, copy 120 bytes ; 2
gr_copy_line_40:
lda $1000,Y ; load a byte (self modified) ; 4
sta $400,Y ; store a byte (self modified) ; 5
lda $1080,Y ; load a byte (self modified) ; 4
sta $480,Y ; store a byte (self modified) ; 5
lda $1100,Y ; load a byte (self modified) ; 4
sta $500,Y ; store a byte (self modified) ; 5
lda $1180,Y ; load a byte (self modified) ; 4
sta $580,Y ; store a byte (self modified) ; 5
lda $1200,Y ; load a byte (self modified) ; 4
sta $600,Y ; store a byte (self modified) ; 5
lda $1280,Y ; load a byte (self modified) ; 4
sta $680,Y ; store a byte (self modified) ; 5
lda $1300,Y ; load a byte (self modified) ; 4
sta $700,Y ; store a byte (self modified) ; 5
lda $1380,Y ; load a byte (self modified) ; 4
sta $780,Y ; store a byte (self modified) ; 5
dey ; decrement pointer ; 2
bpl gr_copy_line_40 ; ; 2nt/3
rts ; 6
;=========================================================
; gr_copy_to_current_40x40
;=========================================================
; Take image in 0xc00
; Copy to DRAW_PAGE
; Actually copy lines 0..39
; Don't over-write bottom 4 lines of text
gr_copy_to_current_40x40:
ldx #0
gc_40x40_loop:
lda gr_offsets,x
sta OUTL
sta INL
lda gr_offsets+1,x
clc
adc DRAW_PAGE
sta OUTH
lda gr_offsets+1,x
clc
adc #$8
sta INH
ldy #39
gc_40x40_inner:
lda (INL),Y
sta (OUTL),Y
dey
bpl gc_40x40_inner
inx
inx
cpx #40
bne gc_40x40_loop
rts ; 6

5
joystick/gr_offsets.s Normal file
View File

@ -0,0 +1,5 @@
gr_offsets:
.word $400,$480,$500,$580,$600,$680,$700,$780
.word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8
.word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0

24
joystick/gr_pageflip.s Normal file
View File

@ -0,0 +1,24 @@
;==========
; page_flip
;==========
page_flip:
lda DISP_PAGE ; 3
beq page_flip_show_1 ; 2nt/3
page_flip_show_0:
bit PAGE0 ; 4
lda #4 ; 2
sta DRAW_PAGE ; DRAW_PAGE=1 ; 3
lda #0 ; 2
sta DISP_PAGE ; DISP_PAGE=0 ; 3
rts ; 6
page_flip_show_1:
bit PAGE1 ; 4
sta DRAW_PAGE ; DRAW_PAGE=0 ; 3
lda #1 ; 2
sta DISP_PAGE ; DISP_PAGE=1 ; 3
rts ; 6
;====================
; DISP_PAGE=0 26
; DISP_PAGE=1 24

View File

@ -0,0 +1,356 @@
;=============================================
; put_sprite_crop
;=============================================
; Sprite to display in INH,INL
; Location is XPOS,YPOS
; Note, only works if YPOS is multiple of two
; transparent color is $A (grey #2)
; this means we can have black ($0) in a sprite
; FIXME: force YPOS to be even?
put_sprite_crop:
ldy #0 ; byte 0 is xsize ; 2
lda (INL),Y ; 5
sta CH ; xsize is in CH ; 3
iny ; 2
clc
adc XPOS
sta XMAX
lda (INL),Y ; byte 1 is ysize ; 5
sta CV ; ysize is in CV ; 3
iny ; 2
lda YPOS ; make a copy of ypos ; 3
sta TEMPY ; as we modify it ; 3
;===========
; 28
put_sprite_crop_loop:
sty TEMP ; save sprite pointer ; 3
ldy TEMPY ; 3
bpl put_sprite_crop_pos ; if < 0, skip to next
clc ; skip line in sprite too
lda TEMP
adc CH
tay
bne crop_increment_y
put_sprite_crop_pos:
psc_smc1:
cpy #48 ; bge if >= 48, done sprite
bcs crop_sprite_done
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc XPOS ; add in xpos ; 3
sta OUTL ; store out low byte of addy ; 3
clc ; never wraps, handle negative
lda gr_offsets+1,Y ; look up high byte ; 4
adc DRAW_PAGE ; ; 3
sta OUTH ; and store it out ; 3
ldy TEMP ; restore sprite pointer ; 3
; OUTH:OUTL now points at right place
ldx XPOS ; load xposition into x ; 3
;===========
; 34
crop_put_sprite_pixel:
lda (INL),Y ; get sprite colors ; 5
iny ; increment sprite pointer ; 2
sty TEMP ; save sprite pointer ; 3
cpx #0 ; if off-screen left, skip draw
bmi skip_drawing
cpx #40
bcs skip_drawing ; if off-screen right, skip draw
ldy #$0 ; 2
; check if completely transparent
; if so, skip
cmp #$aa ; if all zero, transparent ; 2
beq crop_put_sprite_done_draw ; don't draw it ; 2nt/3
;==============
; 16/17
sta COLOR ; save color for later ; 3
; check if top pixel transparent
and #$f0 ; check if top nibble zero ; 2
cmp #$a0
bne crop_put_sprite_bottom ; if not skip ahead ; 2nt/3
;==============
; 7/8
lda COLOR
and #$0f
sta COLOR
lda #$f0 ; setup mask ; 2
sta MASK ; 3
bmi crop_put_sprite_mask ; always? ; 3
;=============
; 8
crop_put_sprite_bottom:
lda COLOR ; re-load color ; 3
and #$0f ; check if bottom nibble zero ; 2
cmp #$0a
bne crop_put_sprite_all ; if not, skip ahead ; 2nt/3
;=============
; 7/8
lda COLOR
and #$f0
sta COLOR
lda #$0f ; 2
sta MASK ; setup mask ; 3
;===========
; 5
crop_put_sprite_mask:
lda (OUTL),Y ; get color at output ; 5
and MASK ; mask off unneeded part ; 3
ora COLOR ; or the color in ; 3
sta (OUTL),Y ; store it back ; 6
jmp crop_put_sprite_done_draw ; we are done ; 3
;===========
; 20
crop_put_sprite_all:
lda COLOR ; load color ; 3
sta (OUTL),Y ; and write it out ; 6
;============
; 9
crop_put_sprite_done_draw:
skip_drawing:
ldy TEMP ; restore sprite pointer ; 3
inc OUTL ; increment output pointer ; 5
inx ; increment x counter ; 2
cpx XMAX
bne crop_put_sprite_pixel ; if not done, keep looping ; 2nt/3
;==============
; 12/13
crop_increment_y:
inc TEMPY ; each line has two y vars ; 5
inc TEMPY ; 5
dec CV ; decemenet total y count ; 5
bne put_sprite_crop_loop ; loop if not done ; 2nt/3
;==============
; 17/18
crop_sprite_done:
rts ; return ; 6
; 0,0 = 400+0
; -1,0 = 400+ff=4ff, inc=400
; sprite: 5x4
;
; -2,0 Xstart=0, sprite_offset=2, xsize=3
; -1,0, Xstart=0, sprite_offset=1, xsize=4
; 0,0, Xstrat=0, sprite_offset=0, xsize=5
; 1,0, Xstart=1, sprite_offset=0, xsize=5
;
; 39,0 Xstart=39, sprite_offset=0, xsize=1
;
;
;
;
;=============================================
; put_sprite_flipped_crop
;=============================================
; Sprite to display in INH,INL
; Location is XPOS,YPOS
; Note, only works if YPOS is multiple of two
; transparent color is $A (grey #2)
; this means we can have black ($0) in a sprite
put_sprite_flipped_crop:
ldy #0 ; byte 0 is xsize ; 2
lda (INL),Y ; 5
sta CH ; xsize is in CH ; 3
iny ; 2
lda (INL),Y ; byte 1 is ysize ; 5
sta CV ; ysize is in CV ; 3
dey ; make Y zero again ; 2
lda INH ; ???
sta ppfc_smc+2
clc
lda INL
adc #1 ; add one (not two) because X counts
; from CH to 1 (not CH-1 to 0)
sta ppfc_smc+1
bcc psfc16
inc ppfc_smc+2
psfc16:
lda YPOS ; make a copy of ypos ; 3
sta TEMPY ; as we modify it ; 3
;===========
; 28
put_spritefc_loop:
; sty TEMP ; save sprite pointer ; 3
ldy TEMPY ; 3
bmi fcrop_increment_y ; if < 0, skip to next
psc_smc2:
cpy #48 ; bge if >= 48, done sprite
bcs fcrop_sprite_done
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc XPOS ; add in xpos ; 3
sta OUTL ; store out low byte of addy ; 3
lda gr_offsets+1,Y ; look up high byte ; 4
clc
adc DRAW_PAGE ; ; 3
sta OUTH ; and store it out ; 3
; ldy TEMP ; restore sprite pointer ; 3
; OUTH:OUTL now points at right place
ldx CH ; load xsize into x ; 3
;===========
; 34
put_spritefc_pixel:
clc
txa ; want (CH-X-1)+XPOS
eor #$ff
adc CH
adc XPOS
bmi cskip_drawing
cmp #40
bcs cskip_drawing ; if off-screen right, skip draw
ppfc_smc:
lda $C000,X ; get sprite colors ; 5
; iny ; increment sprite pointer ; 2
; sty TEMP ; save sprite pointer ; 3
ldy #$0 ; 2
; check if completely transparent
; if so, skip
cmp #$aa ; if all zero, transparent ; 2
beq put_spritefc_done_draw ; don't draw it ; 2nt/3
;==============
; 16/17
sta COLOR ; save color for later ; 3
; check if top pixel transparent
and #$f0 ; check if top nibble zero ; 2
cmp #$a0
bne put_spritefc_bottom ; if not skip ahead ; 2nt/3
;==============
; 7/8
lda COLOR
and #$0f
sta COLOR
lda #$f0 ; setup mask ; 2
sta MASK ; 3
bmi put_spritefc_mask ; always? ; 3
;=============
; 8
put_spritefc_bottom:
lda COLOR ; re-load color ; 3
and #$0f ; check if bottom nibble zero ; 2
cmp #$0a
bne put_spritefc_all ; if not, skip ahead ; 2nt/3
;=============
; 7/8
lda COLOR
and #$f0
sta COLOR
lda #$0f ; 2
sta MASK ; setup mask ; 3
;===========
; 5
put_spritefc_mask:
lda (OUTL),Y ; get color at output ; 5
and MASK ; mask off unneeded part ; 3
ora COLOR ; or the color in ; 3
sta (OUTL),Y ; store it back ; 6
jmp put_spritefc_done_draw ; we are done ; 3
;===========
; 20
put_spritefc_all:
lda COLOR ; load color ; 3
sta (OUTL),Y ; and write it out ; 6
;============
; 9
put_spritefc_done_draw:
cskip_drawing:
; ldy TEMP ; restore sprite pointer ; 3
inc OUTL ; increment output pointer ; 5
dex ; decrement x counter ; 2
bne put_spritefc_pixel ; if not done, keep looping ; 2nt/3
;==============
; 12/13
fcrop_increment_y:
inc TEMPY ; each line has two y vars ; 5
inc TEMPY ; 5
lda CH
clc
adc ppfc_smc+1
sta ppfc_smc+1
bcc psfco
inc ppfc_smc+2
psfco:
dec CV ; decemenet total y count ; 5
beq fcrop_sprite_done ; loop if not done ; 2nt/3
jmp put_spritefc_loop
;==============
; 17/18
fcrop_sprite_done:
rts ; return ; 6

98
joystick/hardware.inc Normal file
View File

@ -0,0 +1,98 @@
;; HARDWARE LOCATIONS
KEYPRESS = $C000
KEYRESET = $C010
;; SOFT SWITCHES
CLR80COL = $C000 ; PAGE0/PAGE1 normal
SET80COL = $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead
EIGHTYCOLOFF = $C00C
EIGHTYCOLON = $C00D
TBCOLOR = $C022 ; IIgs text foreground / background colors
NEWVIDEO = $C029 ; IIgs graphics modes
SPEAKER = $C030
CLOCKCTL = $C034 ; bits 0-3 are IIgs border color
SET_GR = $C050
SET_TEXT = $C051
FULLGR = $C052
TEXTGR = $C053
PAGE0 = $C054
PAGE1 = $C055
LORES = $C056 ; Enable LORES graphics
HIRES = $C057 ; Enable HIRES graphics
AN3 = $C05E ; Annunciator 3
PADDLE_BUTTON0 = $C061
PADDL0 = $C064
PTRIG = $C070
;; BASIC ROUTINES
NORMAL = $F273
;; MONITOR ROUTINES
HLINE = $F819 ;; HLINE Y,$2C at A
VLINE = $F828 ;; VLINE A,$2D at Y
CLRSCR = $F832 ;; Clear low-res screen
CLRTOP = $F836 ;; clear only top of low-res screen
SETCOL = $F864 ;; COLOR=A
ROM_TEXT2COPY = $F962 ;; iigs
TEXT = $FB36
TABV = $FB5B ;; VTAB to A
ROM_MACHINEID = $FBB3 ;; iigs
BELL = $FBDD ;; ring the bell
BASCALC = $FBC1 ;;
VTAB = $FC22 ;; VTAB to CV
HOME = $FC58 ;; Clear the text screen
WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us
CROUT1 = $FD8B
SETINV = $FE80 ;; INVERSE
SETNORM = $FE84 ;; NORMAL
COUT = $FDED ;; output A to screen
COUT1 = $FDF0 ;; output A to screen
COLOR_BLACK = 0
COLOR_RED = 1
COLOR_DARKBLUE = 2
COLOR_PURPLE = 3
COLOR_DARKGREEN = 4
COLOR_GREY = 5
COLOR_MEDIUMBLUE = 6
COLOR_LIGHTBLUE = 7
COLOR_BROWN = 8
COLOR_ORANGE = 9
COLOR_GREY2 = 10
COLOR_PINK = 11
COLOR_LIGHTGREEN = 12
COLOR_YELLOW = 13
COLOR_AQUA = 14
COLOR_WHITE = 15
COLOR_BOTH_BLACK = $00
COLOR_BOTH_RED = $11
COLOR_BOTH_DARKBLUE = $22
COLOR_BOTH_DARKGREEN = $44
COLOR_BOTH_GREY = $55
COLOR_BOTH_MEDIUMBLUE = $66
COLOR_BOTH_LIGHTBLUE = $77
COLOR_BOTH_BROWN = $88
COLOR_BOTH_ORANGE = $99
COLOR_BOTH_PINK = $BB
COLOR_BOTH_LIGHTGREEN = $CC
COLOR_BOTH_YELLOW = $DD
COLOR_BOTH_AQUA = $EE
COLOR_BOTH_WHITE = $FF

43
joystick/joystick.s Normal file
View File

@ -0,0 +1,43 @@
; Oliver Schmidt
; comp.sys.apple2.programmer
; Call with joystick number (0 or 1) in A.
; Results are stored in value0 and value1.
; UPPER_THRESHOLD is the paddle value you want to consider as "right enough" /
; "down enough".
UPPER_THRESHOLD = 128
;PTRIG = $c070
PADDL1 = $C065
handle_joystick:
; Read both paddles simultaneously
asl ; Joystick number -> paddle number
tax
ldy #$00
sty value0
sty value1
lda PTRIG ; Trigger paddles
loop: lda PADDL0,x ; Read paddle (0 or 2)
bmi set0 ; Cycles: 2 3
nop ; Cycles: 2
bpl nop0 ; Cycles: 3
set0: sty value0 ; Cycles: 4
nop0: ; - -
; Cycles: 7 7
lda PADDL1,x ; Read paddle (1 or 3)
bmi set1 ; Cycles: 2 3
nop ; Cycles: 2
bpl nop1 ; Cycles: 3
set1: sty value1 ; Cycles: 4
nop1: ; - -
; Cycles: 7 7
iny
cpy #UPPER_THRESHOLD+1
bne loop
value0: .byte $00
value1: .byte $00

115
joystick/js_test.s Normal file
View File

@ -0,0 +1,115 @@
; Joystick Test
; by deater (Vince Weaver) <vince@deater.net>
; Zero Page
.include "zp.inc"
.include "hardware.inc"
; .include "common_defines.inc"
; .include "common_routines.inc"
js_test:
;===================
; init screen
;===================
jsr TEXT
jsr HOME
bit KEYRESET
bit SET_GR
bit LORES
bit FULLGR
lda #0
sta DRAW_PAGE
; init cursor
lda #20
sta CURSOR_X
sta CURSOR_Y
lda #0
sta LEVEL_OVER
;============================
; set up initial location
; lda #TITLE_BOOK_GROUND
; sta LOCATION ; start at first room
; lda #DIRECTION_N
; sta DIRECTION
; jsr change_location
lda #1
sta CURSOR_VISIBLE ; visible at first
sta JOYSTICK_ENABLED
game_loop:
;=================
; reset things
;=================
lda #0
sta IN_SPECIAL
sta IN_RIGHT
sta IN_LEFT
;====================================
; copy background to current page
;====================================
jsr gr_copy_to_current
;====================================
; draw pointer
;====================================
jsr draw_pointer
;====================================
; page flip
;====================================
jsr page_flip
;====================================
; handle keypress/joystick
;====================================
jsr handle_keypress
;====================================
; inc frame count
;====================================
inc FRAMEL
bne room_frame_no_oflo
inc FRAMEH
room_frame_no_oflo:
;====================================
; check level over
;====================================
; lda LEVEL_OVER
; bne really_exit
jmp game_loop
;really_exit:
; jmp really_exit
.include "common_sprites.inc"
.include "draw_pointer.s"
.include "gr_putsprite_crop.s"
.include "gr_offsets.s"
.include "keyboard.s"
.include "gr_copy.s"
.include "gr_pageflip.s"
.include "joystick.s"

341
joystick/keyboard.s Normal file
View File

@ -0,0 +1,341 @@
;==============================
; Handle Keypress
;==============================
handle_keypress:
lda KEYPRESS
bmi keypress
jmp no_keypress
keypress:
and #$7f ; clear high bit
cmp #' '
beq check_sound
and #$df ; convert uppercase to lower case
check_sound:
cmp #$14 ; control-T
bne check_joystick
lda SOUND_STATUS
eor #SOUND_DISABLED
sta SOUND_STATUS
jmp done_keypress
; can't be ^J as that's the same as down
check_joystick:
cmp #$10 ; control-P
bne check_load
lda JOYSTICK_ENABLED
eor #1
sta JOYSTICK_ENABLED
jmp done_keypress
check_load:
cmp #$C ; control-L
bne check_save
; jsr load_game
jmp done_keypress
check_save:
cmp #$13 ; control-S
bne check_left
; jsr save_game
jmp done_keypress
check_left:
cmp #'A'
beq left_pressed
cmp #8 ; left key
bne check_right
left_pressed:
dec CURSOR_X
jmp done_keypress
check_right:
cmp #'D'
beq right_pressed
cmp #$15 ; right key
bne check_up
right_pressed:
inc CURSOR_X
jmp done_keypress
check_up:
cmp #'W'
beq up_pressed
cmp #$0B ; up key
bne check_down
up_pressed:
dec CURSOR_Y
dec CURSOR_Y
jmp done_keypress
check_down:
cmp #'S'
beq down_pressed
cmp #$0A
bne check_return
down_pressed:
inc CURSOR_Y
inc CURSOR_Y
jmp done_keypress
check_return:
cmp #' '
beq return_pressed
cmp #13
bne done_keypress
return_pressed:
inc $c00
; lda IN_SPECIAL
; beq not_special_return
;special_return:
; jsr handle_special
; special case, don't make cursor visible
; jmp no_keypress
not_special_return:
lda IN_RIGHT
beq not_right_return
cmp #1
beq right_return
right_uturn:
jsr uturn
jmp no_keypress
right_return:
jsr turn_right
jmp no_keypress
not_right_return:
lda IN_LEFT
beq not_left_return
cmp #1
beq left_return
left_uturn:
jsr uturn
jmp no_keypress
left_return:
jsr turn_left
jmp no_keypress
not_left_return:
jsr go_forward
jmp no_keypress
done_keypress:
lda #1 ; make cursor visible
sta CURSOR_VISIBLE
no_keypress:
bit KEYRESET
rts
;============================
; handle_special
;===========================
; set up jump table fakery
handle_special:
; ldy #LOCATION_SPECIAL_FUNC+1
; lda (LOCATION_STRUCT_L),Y
; pha
; dey
; lda (LOCATION_STRUCT_L),Y
; pha
rts
;=============================
; change direction
;=============================
change_direction:
; load background
; lda DIRECTION
; bpl no_split
; split text/graphics
; bit TEXTGR
; also change sprite cutoff
; ldx #40
; stx psc_smc1+1
; stx psc_smc2+1
; jmp done_split
no_split:
; bit FULLGR
; also change sprite cutoff
; ldx #48
; stx psc_smc1+1
; stx psc_smc2+1
done_split:
; and #$f ; mask off special flags
; tay
; lda log2_table,Y
; asl
; clc
; adc #LOCATION_NORTH_BG
; tay
; lda (LOCATION_STRUCT_L),Y
; sta LZSA_SRC_LO
; iny
; lda (LOCATION_STRUCT_L),Y
; sta LZSA_SRC_HI
; lda #$c ; load to page $c00
; jsr decompress_lzsa2_fast
rts
;=============================
; change location
;=============================
change_location:
; reset graphics
bit SET_GR
; reset pointer to not visible, centered
lda #0
sta ANIMATE_FRAME
sta CURSOR_VISIBLE
lda #20
sta CURSOR_X
sta CURSOR_Y
; lda LOCATION
; asl
; tay
; lda (LOCATIONS_L),Y
; sta LOCATION_STRUCT_L
; iny
; lda (LOCATIONS_L),Y
; sta LOCATION_STRUCT_H
jsr change_direction
rts
;==========================
; go forward
;===========================
go_forward:
; update new location
; lda DIRECTION
; and #$f
; tay
; lda log2_table,Y
; clc
; adc #LOCATION_NORTH_EXIT
; tay
; lda (LOCATION_STRUCT_L),Y
; cmp #$ff
; beq cant_go_forward
; sta LOCATION
; update new direction
; lda DIRECTION
; and #$f
; tay
; lda log2_table,Y
; clc
; adc #LOCATION_NORTH_EXIT_DIR
; tay
; lda (LOCATION_STRUCT_L),Y
; sta DIRECTION
; jsr change_location
cant_go_forward:
rts
;==========================
; turn left
;===========================
turn_left:
lda DIRECTION
and #$f
cmp #DIRECTION_N
beq go_west
cmp #DIRECTION_W
beq go_south
cmp #DIRECTION_S
beq go_east
bne go_north
;==========================
; turn right
;===========================
turn_right:
lda DIRECTION
and #$f
cmp #DIRECTION_N
beq go_east
cmp #DIRECTION_E
beq go_south
cmp #DIRECTION_S
beq go_west
bne go_north
;==========================
; uturn
;===========================
uturn:
lda DIRECTION
and #$f
cmp #DIRECTION_N
beq go_south
cmp #DIRECTION_W
beq go_east
cmp #DIRECTION_S
beq go_north
bne go_west
go_north:
lda #DIRECTION_N
jmp done_turning
go_east:
lda #DIRECTION_E
jmp done_turning
go_south:
lda #DIRECTION_S
jmp done_turning
go_west:
lda #DIRECTION_W
jmp done_turning
done_turning:
sta DIRECTION
jsr change_direction
rts

358
joystick/zp.inc Normal file
View File

@ -0,0 +1,358 @@
;; Zero Page
;; LZSA addresses
NIBCOUNT = $00
;; Zero page monitor routines addresses
WNDLFT = $20
WNDWDTH = $21
WNDTOP = $22
WNDBTM = $23
CH = $24
CV = $25
GBASL = $26
GBASH = $27
BASL = $28
BASH = $29
H2 = $2C
X_LEFT = $2C
V2 = $2D
MASK = $2E
COLOR_MASK = $2F
COLOR = $30
SEEDL = $4e
SEEDH = $4f
XMAX = $50
; MIST zero page addresses
FRAMEL = $60
FRAMEH = $61
CURSOR_X = $62
CURSOR_Y = $63
XPOS = $64
YPOS = $65
LOCATION_STRUCT_L = $66
LOCATION_STRUCT_H = $67
IN_SPECIAL = $68
CURSOR_VISIBLE = $69
IN_LEFT = $6A
IN_RIGHT = $6B
BTC_L = $6C
BTC_H = $6D
; pt3 player registers
AY_REGISTERS = $70
A_FINE_TONE = $70
A_COARSE_TONE = $71
B_FINE_TONE = $72
B_COARSE_TONE = $73
C_FINE_TONE = $74
C_COARSE_TONE = $75
NOISE = $76
ENABLE = $77
PT3_MIXER_VAL = $77
A_VOLUME = $78
B_VOLUME = $79
C_VOLUME = $7A
ENVELOPE_FINE = $7B
ENVELOPE_COARSE = $7C
ENVELOPE_SHAPE = $7D
PATTERN_L = $7E
PATTERN_H = $7F
; note 70-7f also used by disk code
; note: rest are up at $f0
; We have to save/restore the following values
; when loading/storing from disk
WHICH_LOAD = $80 ; which file to load
DIRECTION = $81 ; direction we are pointing
DIRECTION_N = $1
DIRECTION_S = $2
DIRECTION_E = $4
DIRECTION_W = $8
DIRECTION_ANY=$f
DIRECTION_ONLY_POINT = $40 ; do not change pointer to grab
DIRECTION_SPLIT = $80 ; split text/graphics
LOCATION = $82 ; location on the map
RED_PAGES_TAKEN = $83 ; red pages that have been picked up
OCTAGON_PAGE = $01
MECHE_PAGE = $02
SELENA_PAGE = $04
STONEY_PAGE = $08
CHANNEL_PAGE = $10
FINAL_PAGE = $20
BLUE_PAGES_TAKEN= $84 ; blue pages that have been picked up
CLOCK_BRIDGE = $85 ; is the clock island bridge raised
GEAR_OPEN = $86 ; is the big gear open
MARKER_SWITCHES = $87 ; state of the marker switches
MARKER_DOCK = $01
MARKER_GEARS = $02
MARKER_SPACESHIP = $04
MARKER_GENERATOR = $08
MARKER_CLOCK = $10
MARKER_TREE = $20
MARKER_POOL = $40
MARKER_DENTIST = $80
CLOCK_HOUR = $88 ; hour on the mist clock
CLOCK_MINUTE = $89 ; minute on the mist clock
BOILER_LEVEL = $8A ; furnace in the cabin level
FIREPLACE_GRID0 = $8B ; fireplace grid puzzle state
FIREPLACE_GRID1 = $8C
FIREPLACE_GRID2 = $8D
FIREPLACE_GRID3 = $8E
FIREPLACE_GRID4 = $8F
FIREPLACE_GRID5 = $90
CLOCK_COUNT = $91 ; clock puzzle (turns taken)
CLOCK_TOP = $92 ; clock puzzle (top dial)
CLOCK_MIDDLE = $93 ; clock puzzle (middle dial)
CLOCK_BOTTOM = $94 ; clock puzzle (bottom dial)
CLOCK_LAST = $95 ; clock puzzle (last dial turned)
BREAKER_TRIPPED = $96 ; generator (circuit breakers status)
GENERATOR_VOLTS = $97 ; generator (total volts)
ROCKET_VOLTS = $98 ; generator (rocket volts)
SWITCH_TOP_ROW = $99 ; generator (switch top row)
SWITCH_BOTTOM_ROW = $9A ; generator (switch bottom row)
GENERATOR_VOLTS_DISP = $9B ; generator (total volts on display)
ROCKET_VOLTS_DISP = $9C ; generator (rocket volts on display)
ROCKET_HANDLE_STEP = $9D ; organ (which knob is lit) [why zp?]
ROCKET_NOTE1 = $9E ; organ (note slider 1)
ROCKET_NOTE2 = $9F ; organ (note slider 2)
ROCKET_NOTE3 = $A0 ; organ (note slider 3)
ROCKET_NOTE4 = $A1 ; organ (note slider 4)
MECHE_ELEVATOR = $A2 ; fortress elevator state
MECHE_ROTATION = $A3 ; fortress rotation state
; 0..3 = S
; 4..7 = E
; 8..11 = N
; 12..15 = W
MECHE_LEVERS = $A4 ; fortress rotation levers
LEFT_LEVER = 1
RIGHT_LEVER = 2
MECHE_LOCK1 = $A5 ; meche lock symbol1
MECHE_LOCK2 = $A6 ; meche lock symbol2
MECHE_LOCK3 = $A7 ; meche lock symbol3
MECHE_LOCK4 = $A8 ; meche lock symbol4
HOLDING_PAGE = $A9 ; which page in hand
HOLDING_RED_PAGE = $80
HOLDING_BLUE_PAGE = $40
HOLDING_WHITE_PAGE = $C0
;FINAL_PAGE = $20
;CHANNEL_PAGE = $10
;STONEY_PAGE = $08
;SELENA_PAGE = $04
;MECHE_PAGE = $02
;OCTAGON_PAGE = $01
RED_PAGE_COUNT = $AA ; # of red pages in book
BLUE_PAGE_COUNT = $AB ; # of blue pages in book
VIEWER_CHANNEL = $AC ; viewer: current channel
VIEWER_LATCHED = $AD ; viewer: latched channel
TOWER_ROTATION = $AE ; tower rotation: which
ROTATION_GEARS = 2
ROTATION_DOCK = 3
ROTATION_TREE = 4
ROTATION_SPACESHIP = 8
SHIP_RAISED = $AF ; ship raised or not
PUMP_STATE = $B0 ; stoneship pump state
DRAINED_EXIT = $01
DRAINED_TUNNELS = $02
DRAINED_LIGHTHOUSE=$04
BATTERY_CHARGE = $B1 ; stoneship battery charge
COMPASS_STATE = $B2 ; stoneship compass state
COMPASS_DEFAULT = 0 ; cabin lights off
COMPASS_LIGHT_ON= 1 ; proper angle selected
CRANK_ANGLE = $B3 ; stoneship crank angle
WHITE_PAGE_TAKEN= $B4 ; white page taken
CHANNEL_SWITCHES= $B5 ; channelwood switches
CHANNEL_SW_FAUCET = $80
CHANNEL_SW_WINDMILL = $40
CHANNEL_SW_GATE_BOTTOM = $20
CHANNEL_ELEVATOR1_UP = $10
CHANNEL_SW_GATE_TOP = $08
CHANNEL_BOOK_ELEVATOR_UP= $04
CHANNEL_PIPE_EXTENDED = $02
CHANNEL_BRIDGE_UP = $01
CHANNEL_VALVES = $B6 ; channelwood valves
CHANNEL_VALVE1 = $01 ; elevator2
CHANNEL_VALVE2 = $02 ; big tree
CHANNEL_VALVE3 = $04 ; broken
CHANNEL_VALVE4 = $08 ; elevator1
CHANNEL_VALVE5 = $10 ; entry
CHANNEL_VALVE6 = $20 ; bridge
DENTIST_LIGHT = $B7 ; dentist lightswitch
DENTIST_MONTH = $B8 ; dentist panel: month
DENTIST_DAY = $B9 ; dentist panel: day
DENTIST_CENTURY = $BA ; dentist panel: century
DENTIST_YEAR = $BB ; dentist panel: year
DENTIST_HOURS = $BC ; dentist panel: hours
DENTIST_MINUTES = $BD ; dentist panel: minutes
PILLAR_ON = $BE ; pillars: which on/off
PILLAR_EYE = $01
PILLAR_SNAKE = $02
PILLAR_BUG = $04
PILLAR_ANCHOR = $08
PILLAR_ARROW = $10
PILLAR_LEAF = $20
PILLAR_CROSS = $40
PILLAR_EMU = $80
GREEN_BOOK_PROGRESS = $BF ; green book: what's ben seen
DNI_PROGRESS = $C0 ; dni: atrus status
COMPARTMENT_OPEN = $C1 ; dock marker switch compartment
GAME_COMPLETE = $C2 ; game has been completed
SAFE_HUNDREDS = $C3 ; safe combination, hundreds
SAFE_TENS = $C4 ; safe combination, tens
SAFE_ONES = $C5 ; safe combination, ones
TREE_LEVEL = $C6 ; how high is the tree hole
HOLDING_ITEM = $C7
HOLDING_KEY = $04
HOLDING_LIT_MATCH = $02
HOLDING_MATCH = $01
BOILER_VALVE = $C8 ; how many turns of the boiler valve
TRUNK_STATE = $C9 ; trunk state in stonsehip
TRUNK_VALVE_OPEN = $01
TRUNK_WATER_DRAINED = $02
TRUNK_KEY_TAKEN = $04
TRUNK_LID_OPEN = $08
TRUNK_HATCH_OPEN = $10
TRUNK_KEY_ON_FLOOR = $20
SELENA_BUTTON_STATUS = $CA
SELENA_BUTTON1 = $01 ; POOL (water)
SELENA_BUTTON2 = $02 ; CHASM (fire)
SELENA_BUTTON3 = $04 ; CLOCK (ticking)
SELENA_BUTTON4 = $08 ; CRYSTALS (whistle)
SELENA_BUTTON5 = $10 ; TUNNEL (wind)
SELENA_LIGHTSWITCH= $80 ; light in the tunnel
SELENA_ANTENNA1 = $CB ; rotation angle for antenna1
SELENA_ANTENNA2 = $CC ; rotation angle for antenna1
SELENA_ANTENNA3 = $CD ; rotation angle for antenna1
SELENA_ANTENNA4 = $CE ; rotation angle for antenna1
SELENA_ANTENNA5 = $CF ; rotation angle for antenna1
SELENA_LOCK1 = $D0 ; antenna lock slider1
SELENA_LOCK2 = $D1 ; antenna lock slider2
SELENA_LOCK3 = $D2 ; antenna lock slider3
SELENA_LOCK4 = $D3 ; antenna lock slider4
SELENA_LOCK5 = $D4 ; antenna lock slider5
SELENA_ANTENNA_ACTIVE = $D5 ; which antenna currently selected
SUB_LOCATION = $D6
SUB_DIRECTION = $D7
NIBEL_PROJECTOR = $D8 ; which button on projector in nibel
END_OF_SAVE = $D9
; done game puzzle state
CURRENT_DISK = $DC
JOYSTICK_ENABLED= $DD
SOUND_STATUS = $DE
SOUND_DISABLED = $80
SOUND_IN_LC = $01 ; $01 sound effects in language card
SOUND_MOCKINGBOARD = $02 ; mockingboard detected
GRID_PAGE = $DF
ANIMATE_FRAME = $E0
LEVEL_OVER = $E1
LOCATIONS_L = $E2
LOCATIONS_H = $E3
; temp var per-world define
LONG_FRAME = $E4 ; nibel
CURRENT_DISPLAY = $E4 ; selena
LAST_PLAYED = $E4 ; selena
DISP_PAGE = $ED ; ALL
DRAW_PAGE = $EE ; ALL
; rest of pt3_player
PT3_TEMP = $EF
ORNAMENT_L = $F0
ORNAMENT_H = $F1
SAMPLE_L = $F2
SAMPLE_H = $F3
LOOP = $F4
MB_VALUE = $F5
MB_ADDR_L = $F6
MB_ADDR_H = $F7
DONE_PLAYING = $F8
DONE_SONG = $F9
;TINL = $F0
;TINH = $F1
;BINL = $F2
;BINH = $F3
;SCROLL_COUNT = $F9
TEMP = $FA
TEMPY = $FB
INL = $FC
INH = $FD
OUTL = $FE
OUTH = $FF
; read any file slot 6 version
; based on FASTLD6 and RTS copyright (c) Peter Ferrie 2011-2013,2018
; modified to assembled with ca64 -- vmw
; added code to patch it to run from current disk slot -- vmw
adrlo = $26 ; constant from boot prom
adrhi = $27 ; constant from boot prom
tmpsec = $3c ; constant from boot prom
reqsec = $3d ; constant from boot prom
sizelo = $44
sizehi = $45
secsize = $46
ldsizel = $70
ldsizeh = $71
namlo = $7b
namhi = $7c
step = $7d ; state for stepper motor
tmptrk = $7e ; temporary copy of current track
phase = $7f ; current phase for /seek