diff --git a/asm_routines/gr_setpage.s b/asm_routines/gr_setpage.s new file mode 100644 index 00000000..c54bd570 --- /dev/null +++ b/asm_routines/gr_setpage.s @@ -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 + diff --git a/asm_routines/hlin_clearscreen.s b/asm_routines/hlin_clearscreen.s new file mode 100644 index 00000000..cce402d0 --- /dev/null +++ b/asm_routines/hlin_clearscreen.s @@ -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 diff --git a/asm_routines/memset.s b/asm_routines/memset.s new file mode 100644 index 00000000..70bf33e1 --- /dev/null +++ b/asm_routines/memset.s @@ -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 + diff --git a/asm_routines/pageflip.s b/asm_routines/pageflip.s new file mode 100644 index 00000000..f199f5be --- /dev/null +++ b/asm_routines/pageflip.s @@ -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 + diff --git a/asm_routines/unrle_gr.s b/asm_routines/unrle_gr.s new file mode 100644 index 00000000..51fbf6ce --- /dev/null +++ b/asm_routines/unrle_gr.s @@ -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 + + + diff --git a/mode7_demo/utils.s b/asm_routines/utils.s similarity index 61% rename from mode7_demo/utils.s rename to asm_routines/utils.s index 005dbff8..c3c60291 100644 --- a/mode7_demo/utils.s +++ b/asm_routines/utils.s @@ -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 - diff --git a/mode7_demo/Makefile b/mode7_demo/Makefile index 8f6c2557..4496164b 100644 --- a/mode7_demo/Makefile +++ b/mode7_demo/Makefile @@ -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 diff --git a/mode7_demo/mode7_demo.s b/mode7_demo/mode7_demo.s index 2991e8eb..fa81472b 100644 --- a/mode7_demo/mode7_demo.s +++ b/mode7_demo/mode7_demo.s @@ -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"