mode7: break out the utils into separate routines

This commit is contained in:
Vince Weaver 2017-12-16 13:52:00 -05:00
parent a4ad2010c2
commit ebd22ed243
8 changed files with 387 additions and 360 deletions

20
asm_routines/gr_setpage.s Normal file
View File

@ -0,0 +1,20 @@
;==========================================================
; set_text_page0
;==========================================================
;
set_text_page0:
bit PAGE0 ; set page0
bit TEXT ; set text mode
rts
;==========================================================
; set_gr_page0
;==========================================================
;
set_gr_page0:
bit PAGE0 ; set page 0
bit LORES ; Lo-res graphics
bit TEXTGR ; mixed gr/text mode
bit SET_GR ; set graphics
rts

View File

@ -0,0 +1,205 @@
;=====================================================================
;= 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
;================================
; 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

16
asm_routines/memset.s Normal file
View File

@ -0,0 +1,16 @@
;======================
; memset
;======================
; a=value
; x=length
; MEMPTRL/MEMPTRH is address
memset:
ldy #0
memset_loop:
sta MEMPTRL,Y
iny
dex
bne memset_loop
rts

24
asm_routines/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

115
asm_routines/unrle_gr.s Normal file
View File

@ -0,0 +1,115 @@
;=================
; load RLE image
;=================
; Output is BASH/BASL
; Input is in GBASH/GBASL
load_rle_gr:
lda #$0
tay ; init Y to 0
sta TEMP ; stores the xcoord
sta CV ; ycoord=0
jsr load_and_increment ; load xsize
sta CH
rle_loop:
jsr load_and_increment
cmp #$A1 ; if 0xa1
beq rle_done ; we are done
pha
and #$f0 ; mask
cmp #$a0 ; see if special AX
beq decompress_special
pla ; note, PLA sets flags!
ldx #$1 ; only want to print 1
bne decompress_run
decompress_special:
pla
and #$0f ; check if was A0
bne decompress_color ; if A0 need to read run, color
decompress_large:
jsr load_and_increment ; get run length
decompress_color:
tax ; put runlen into X
jsr load_and_increment ; get color
decompress_run:
rle_run_loop:
sta (BASL),y ; write out the value
inc BASL ; increment the pointer
bne rle_skip3 ; if wrapped
inc BASH ; then increment the high value
rle_skip3:
pha ; store colore for later
inc TEMP ; increment the X value
lda TEMP
cmp CH ; compare against the image width
bcc rle_not_eol ; if less then keep going
lda BASL ; cheat to avoid a 16-bit add
cmp #$a7 ; we are adding 0x58 to get
bcc rle_add_skip ; to the next line
inc BASH
rle_add_skip:
clc
adc #$58 ; actually do the 0x58 add
sta BASL ; and store it back
inc CV ; add 2 to ypos
inc CV ; each "line" is two high
lda CV ; load value
cmp #15 ; if it's greater than 14 it wraps
bcc rle_no_wrap ; Thanks Woz
lda #$0 ; we wrapped, so set to zero
sta CV
; when wrapping have to sub 0x3d8
sec ; this is a 16-bit subtract routine
lda BASL
sbc #$d8 ; LSB
sta BASL
lda BASH ; MSB
sbc #$3 ;
sta BASH
rle_no_wrap:
lda #$0 ; set X value back to zero
sta TEMP
rle_not_eol:
pla ; restore color
dex
bne rle_run_loop ; if not zero, keep looping
beq rle_loop ; and branch always
rle_done:
lda #$15 ; move the cursor somewhere sane
sta CV
rts
load_and_increment:
lda (GBASL),y ; load value ; 5?
inc GBASL ; 5?
bne lskip2 ; 2nt/3
inc GBASH ; 5?
lskip2:
rts ; 6

View File

@ -2,182 +2,6 @@
;= 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
;=================
; load RLE image
;=================
; Output is BASH/BASL
; Input is in GBASH/GBASL
load_rle_gr:
lda #$0
tay ; init Y to 0
sta TEMP ; stores the xcoord
sta CV ; ycoord=0
jsr load_and_increment ; load xsize
sta CH
rle_loop:
jsr load_and_increment
cmp #$A1 ; if 0xa1
beq rle_done ; we are done
pha
and #$f0 ; mask
cmp #$a0 ; see if special AX
beq decompress_special
pla ; note, PLA sets flags!
ldx #$1 ; only want to print 1
bne decompress_run
decompress_special:
pla
and #$0f ; check if was A0
bne decompress_color ; if A0 need to read run, color
decompress_large:
jsr load_and_increment ; get run length
decompress_color:
tax ; put runlen into X
jsr load_and_increment ; get color
decompress_run:
rle_run_loop:
sta (BASL),y ; write out the value
inc BASL ; increment the pointer
bne rle_skip3 ; if wrapped
inc BASH ; then increment the high value
rle_skip3:
pha ; store colore for later
inc TEMP ; increment the X value
lda TEMP
cmp CH ; compare against the image width
bcc rle_not_eol ; if less then keep going
lda BASL ; cheat to avoid a 16-bit add
cmp #$a7 ; we are adding 0x58 to get
bcc rle_add_skip ; to the next line
inc BASH
rle_add_skip:
clc
adc #$58 ; actually do the 0x58 add
sta BASL ; and store it back
inc CV ; add 2 to ypos
inc CV ; each "line" is two high
lda CV ; load value
cmp #15 ; if it's greater than 14 it wraps
bcc rle_no_wrap ; Thanks Woz
lda #$0 ; we wrapped, so set to zero
sta CV
; when wrapping have to sub 0x3d8
sec ; this is a 16-bit subtract routine
lda BASL
sbc #$d8 ; LSB
sta BASL
lda BASH ; MSB
sbc #$3 ;
sta BASH
rle_no_wrap:
lda #$0 ; set X value back to zero
sta TEMP
rle_not_eol:
pla ; restore color
dex
bne rle_run_loop ; if not zero, keep looping
beq rle_loop ; and branch always
rle_done:
lda #$15 ; move the cursor somewhere sane
sta CV
rts
load_and_increment:
lda (GBASL),y ; load value ; 5?
inc GBASL ; 5?
bne lskip2 ; 2nt/3
inc GBASH ; 5?
lskip2:
rts ; 6
;==========================================================
; set_text_page0
;==========================================================
@ -192,8 +16,6 @@ set_text_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
@ -594,183 +416,3 @@ vlin_too_slow:
rts ; return
;================================
; 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

View File

@ -19,7 +19,10 @@ mode7_demo.dsk: $(DOS33) MODE7_DEMO
MODE7_DEMO: mode7_demo.o
ld65 -o MODE7_DEMO mode7_demo.o -C ./apple2_1000.inc
mode7_demo.o: mode7_demo.s mode7_demo_backgrounds.inc utils.s
mode7_demo.o: mode7_demo.s mode7_demo_backgrounds.inc \
../asm_routines/unrle_gr.s \
../asm_routines/hlin_clearscreen.s \
../asm_routines/gr_setpage.s
ca65 -o mode7_demo.o mode7_demo.s -l mode7_demo.lst

View File

@ -27,6 +27,8 @@ loop_forever:
; External modules
;===============================================
.include "utils.s"
.include "../asm_routines/unrle_gr.s"
.include "../asm_routines/hlin_clearscreen.s"
.include "../asm_routines/gr_setpage.s"
.include "mode7_demo_backgrounds.inc"