dos33fsprogs/mode7/utils.s
2017-12-14 15:59:54 -05:00

553 lines
10 KiB
ArmAsm

;=====================================================================
;= ROUTINES
;=====================================================================
clear_screens:
;===================================
; Clear top/bottom of page 0
;===================================
lda #$0
sta DRAW_PAGE
jsr clear_top
jsr clear_bottom
;===================================
; Clear top/bottom of page 1
;===================================
lda #$4
sta DRAW_PAGE
jsr clear_top
jsr clear_bottom
rts
;==========
; 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
;======================
; memset
;======================
; a=value
; x=length
; MEMPTRL/MEMPTRH is address
memset:
ldy #0
memset_loop:
sta MEMPTRL,Y
iny
dex
bne memset_loop
rts
;==========================================================
; set_gr_page0
;==========================================================
;
set_gr_page0:
;lda #4
;sta GR_PAGE
bit PAGE0 ; set page 0
bit LORES ; Lo-res graphics
bit TEXTGR ; mixed gr/text mode
bit SET_GR ; set graphics
rts
;==========================================================
; Wait until keypressed
;==========================================================
;
wait_until_keypressed:
lda KEYPRESS ; check if keypressed
bpl wait_until_keypressed ; if not, loop
jmp figure_out_key
;==========================================================
; Get Key
;==========================================================
;
get_key:
check_paddle_button:
; check for paddle button
bit PADDLE_BUTTON0 ; 4
bpl no_button ; 2nt/3
lda #' '+128 ; 2
jmp save_key ; 3
no_button:
lda KEYPRESS ; 3
bpl no_key ; 2nt/3
figure_out_key:
cmp #' '+128 ; the mask destroys space ; 2
beq save_key ; so handle it specially ; 2nt/3
and #$5f ; mask, to make upper-case ; 2
check_right_arrow:
cmp #$15 ; 2
bne check_left_arrow ; 2nt/3
lda #'D' ; 2
check_left_arrow:
cmp #$08 ; 2
bne check_up_arrow ; 2nt/3
lda #'A' ; 2
check_up_arrow:
cmp #$0B ; 2
bne check_down_arrow ; 2nt/3
lda #'W' ; 2
check_down_arrow:
cmp #$0A ; 2
bne check_escape ; 2nt/3
lda #'S' ; 2
check_escape:
cmp #$1B ; 2
bne save_key ; 2nt/3
lda #'Q' ; 2
jmp save_key ; 3
no_key:
bit PADDLE_STATUS ; 3
bpl no_key_store ; 2nt/3
; check for paddle action
; code from http://web.pdx.edu/~heiss/technotes/aiie/tn.aiie.06.html
inc PADDLE_STATUS ; 5
lda PADDLE_STATUS ; 3
and #$03 ; 2
beq check_paddles ; 2nt/3
jmp no_key_store ; 3
check_paddles:
lda PADDLE_STATUS ; 3
and #$80 ; 2
sta PADDLE_STATUS ; 3
ldx #$0 ; 2
LDA PTRIG ;TRIGGER PADDLES ; 4
LDY #0 ;INIT COUNTER ; 2
NOP ;COMPENSATE FOR 1ST COUNT ; 2
NOP ; 2
PREAD2: LDA PADDL0,X ;COUNT EVERY 11 uSEC. ; 4
BPL RTS2D ;BRANCH WHEN TIMED OUT ; 2nt/3
INY ;INCREMENT COUNTER ; 2
BNE PREAD2 ;CONTINUE COUNTING ; 2nt/3
DEY ;COUNTER OVERFLOWED ; 2
RTS2D: ;RETURN W/VALUE 0-255
cpy #96 ; 2
bmi paddle_left ; 2nt/3
cpy #160 ; 2
bmi no_key_store ; 2nt/3
lda #'D' ; 2
jmp save_key ; 3
paddle_left:
lda #'A' ; 2
jmp save_key ; 3
no_key_store:
lda #0 ; no key, so save a zero ; 2
save_key:
sta LASTKEY ; save the key to our buffer ; 2
bit KEYRESET ; clear the keyboard buffer ; 4
rts ; 6
;============
; 33=nokey
; 48=worstkey
;=============================================
; put_sprite
;=============================================
; Sprite to display in INH,INL
; Location is XPOS,YPOS
; Note, only works if YPOS is multiple of two?
put_sprite:
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
iny ; 2
lda YPOS ; make a copy of ypos ; 3
sta TEMPY ; as we modify it ; 3
;===========
; 28
put_sprite_loop:
sty TEMP ; save sprite pointer ; 3
ldy TEMPY ; 3
lda gr_offsets,Y ; lookup low-res memory address ; 5
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 ; 5
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
;===========
; 36
put_sprite_pixel:
lda (INL),Y ; 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 #$0 ; if all zero, transparent ; 2
beq put_sprite_done_draw ; don't draw it ; 2nt/3
; FIXME: use BIT? ;==============
; 17
sta COLOR ; save color for later ; 3
; check if top pixel transparent
and #$f0 ; check if top nibble zero ; 2
bne put_sprite_bottom ; if not skip ahead ; 2nt/3
lda #$f0 ; setup mask ; 2
sta MASK ; 3
bmi put_sprite_mask ; 2nt/3
put_sprite_bottom:
lda COLOR ; re-load color ; 3
and #$0f ; check if bottom nibble zero ; 2
bne put_sprite_all ; if not, skip ahead ; 2nt/3
lda #$0f ; 2
sta MASK ; setup mask ; 3
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 ; 5
jmp put_sprite_done_draw ; we are done ; 3
put_sprite_all:
lda COLOR ; load color ; 3
sta (OUTL),Y ; and write it out ; 5
put_sprite_done_draw:
ldy TEMP ; restore sprite pointer ; 3
inc OUTL ; increment output pointer ; 5
dex ; decrement x counter ; 2
bne put_sprite_pixel ; if not done, keep looping ; 2nt/3
inc TEMPY ; each line has two y vars ; 5
inc TEMPY ; 5
dec CV ; decemenet total y count ; 5
bne put_sprite_loop ; loop if not done ; 2nt/3
rts ; return ; 6
;================================
; htab_vtab
;================================
; move to CH/CV
htab_vtab:
lda CV
asl
tay
lda gr_offsets,Y ; lookup low-res memory address
clc
adc CH ; add in xpos
sta BASL ; store out low byte of addy
lda gr_offsets+1,Y ; look up high byte
adc DRAW_PAGE ;
sta BASH ; and store it out
; BASH:BASL now points at right place
rts
;================================
; move_and_print
;================================
; move to CH/CV
move_and_print:
jsr htab_vtab
;================================
; print_string
;================================
print_string:
ldy #0
print_string_loop:
lda (OUTL),Y
beq done_print_string
ora #$80
sta (BASL),Y
iny
bne print_string_loop
done_print_string:
rts
;====================
; point_to_end_string
;====================
point_to_end_string:
iny
tya
clc
adc OUTL
sta OUTL
lda #0
adc OUTH
sta OUTH
rts
;================================
; print_both_pages
;================================
print_both_pages:
lda DRAW_PAGE
pha
lda #0
sta DRAW_PAGE
jsr move_and_print
lda #4
sta DRAW_PAGE
jsr move_and_print
pla
sta DRAW_PAGE
rts ; oops forgot this initially
; explains the weird vertical stripes on the screen
;================================
; hlin_setup
;================================
; put address in GBASL/GBASH
; Ycoord in A, Xcoord in Y
hlin_setup:
sty TEMPY ; 3
tay ; y=A ; 2
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc TEMPY ; 3
sta GBASL ; 3
iny ; 2
lda gr_offsets,Y ; 4
adc DRAW_PAGE ; add in draw page offset ; 3
sta GBASH ; 3
rts ; 6
;===========
; 35
;================================
; hlin_double:
;================================
; HLIN Y, V2 AT A
; Y, X, A trashed
; start at Y, draw up to and including X
hlin_double:
;int hlin_double(int page, int x1, int x2, int at) {
jsr hlin_setup ; 41
sec ; 2
lda V2 ; 3
sbc TEMPY ; 3
tax ; 2
inx ; 2
;===========
; 53
; fallthrough
;=================================
; hlin_double_continue: width
;=================================
; width in X
hlin_double_continue:
ldy #0 ; 2
lda COLOR ; 3
hlin_double_loop:
sta (GBASL),Y ; 6
inc GBASL ; 5
dex ; 2
bne hlin_double_loop ; 2nt/3
rts ; 6
;=============
; 53+5+X*16+5
;================================
; hlin_single:
;================================
; HLIN Y, V2 AT A
; Y, X, A trashed
hlin_single:
jsr hlin_setup
sec
lda V2
sbc TEMPY
tax
; fallthrough
;=================================
; hlin_single_continue: width
;=================================
; width in X
hlin_single_continue:
hlin_single_top:
lda COLOR
and #$f0
sta COLOR
hlin_single_top_loop:
ldy #0
lda (GBASL),Y
and #$0f
ora COLOR
sta (GBASL),Y
inc GBASL
dex
bne hlin_single_top_loop
rts
hlin_single_bottom:
lda COLOR
and #$0f
sta COLOR
hlin_single_bottom_loop:
ldy #0
lda (GBASL),Y
and #$f0
sta (GBASL),Y
inc GBASL
dex
bne hlin_single_bottom_loop
rts
;=============================
; clear_top
;=============================
clear_top:
lda #$00
;=============================
; clear_top_a
;=============================
clear_top_a:
sta COLOR
; VLIN Y, V2 AT A
lda #40
sta V2
lda #0
clear_top_loop:
ldy #0
pha
jsr hlin_double
pla
clc
adc #$2
cmp #40
bne clear_top_loop
rts
clear_bottom:
lda #$a0 ; NORMAL space
sta COLOR
lda #40
sta V2
clear_bottom_loop:
ldy #0
pha
jsr hlin_double
pla
clc
adc #$2
cmp #48
bne clear_bottom_loop
rts
; move these to zero page for slight speed increase?
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