From 757f9d9c3dbf0f8418f490ec88b3430c844cde31 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 6 Oct 2018 20:35:28 -0400 Subject: [PATCH] space_bars: some initial cycle-counting it would help if I could subtract --- space_bars/Makefile | 12 +- space_bars/delay_a.s | 25 +++++ space_bars/game.s | 236 ++++++++++++++++++++++++++++++++++++++-- space_bars/lz4_decode.s | 213 ++++++++++++++++++++++++++++++++++++ space_bars/space_bars.s | 17 +++ space_bars/title.s | 50 +-------- space_bars/vapor_lock.s | 216 ++++++++++++++++++++++++++++++++++++ 7 files changed, 710 insertions(+), 59 deletions(-) create mode 100644 space_bars/delay_a.s create mode 100644 space_bars/lz4_decode.s create mode 100644 space_bars/vapor_lock.s diff --git a/space_bars/Makefile b/space_bars/Makefile index 85971cdd..41b9481c 100644 --- a/space_bars/Makefile +++ b/space_bars/Makefile @@ -2,6 +2,7 @@ include ../Makefile.inc DOS33 = ../dos33fs-utils/dos33 PNG_TO_40x48D = ../gr-utils/png_to_40x48d +B2D = ../bmp2dhr/b2d all: space_bars.dsk @@ -16,7 +17,8 @@ SPACE_BARS: space_bars.o space_bars.o: space_bars.s instructions.s game.s \ game_over.s gr_copy.s text_print.s title.s \ - spacebars_title.inc + spacebars_title.inc \ + vapor_lock.s delay_a.s lz4_decode.s SB_BACKGROUNDC.BIN.lz4 ca65 -o space_bars.o space_bars.s -l space_bars.lst #### @@ -24,6 +26,14 @@ space_bars.o: space_bars.s instructions.s game.s \ spacebars_title.inc: ./images/spacebars_title_scaled.png $(PNG_TO_40x48D) asm ./images/spacebars_title_scaled.png spacebars_title > spacebars_title.inc +#### + +SB_BACKGROUNDC.BIN.lz4: SB_BACKGROUNDC.BIN + lz4 -f -16 SB_BACKGROUNDC.BIN + +SB_BACKGROUNDC.BIN: sb_background.bmp + $(B2D) sb_background.bmp HGR -d + ### clean: diff --git a/space_bars/delay_a.s b/space_bars/delay_a.s new file mode 100644 index 00000000..2d0802da --- /dev/null +++ b/space_bars/delay_a.s @@ -0,0 +1,25 @@ +; From http://6502org.wikidot.com/software-delay + +; 25+A cycles (including JSR), 19 bytes (excluding JSR) +; +; The branches must not cross page boundaries! +; + + ; Cycles Accumulator Carry flag + ; 0 1 2 3 4 5 6 (hex) 0 1 2 3 4 5 6 + +; jsr delay_a ; 6 6 6 6 6 6 6 00 01 02 03 04 05 06 + +dly0: sbc #7 +delay_a:cmp #7 ; 2 2 2 2 2 2 2 00 01 02 03 04 05 06 0 0 0 0 0 0 0 + bcs dly0 ; 2 2 2 2 2 2 2 00 01 02 03 04 05 06 0 0 0 0 0 0 0 + lsr ; 2 2 2 2 2 2 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0 + bcs dly1 ; 2 3 2 3 2 3 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0 +dly1: beq dly2 ; 3 3 2 2 2 2 2 00 00 01 01 02 02 03 0 1 0 1 0 1 0 + lsr ; 2 2 2 2 2 00 00 01 01 01 1 1 0 0 1 + beq dly3 ; 3 3 2 2 2 00 00 01 01 01 1 1 0 0 1 + bcc dly3 ; 3 3 2 01 01 01 0 0 1 +dly2: bne dly3 ; 2 2 3 00 00 01 0 1 0 +dly3: rts ; 6 6 6 6 6 6 6 00 00 00 00 01 01 01 0 1 1 1 0 0 1 + ; + ; Total cycles: 25 26 27 28 29 30 31 diff --git a/space_bars/game.s b/space_bars/game.s index 498ce6ef..85ec1873 100644 --- a/space_bars/game.s +++ b/space_bars/game.s @@ -1,14 +1,10 @@ ;================================ - ; Show some instructions - ; return when a key is pressed + ; spacebars gameplay ;================================ - game: + ;=================== ; init screen - bit LORES - bit SET_GR - bit FULLGR bit KEYRESET ;=================== @@ -17,11 +13,233 @@ game: lda #0 sta DRAW_PAGE + + ;============================= + ; Load graphic hgr + + lda #background_hgr + sta LZ4_SRC+1 + + lda #<(background_hgr_end-8) ; skip checksum at end + sta LZ4_END + lda #>(background_hgr_end-8) ; skip checksum at end + sta LZ4_END+1 + + lda #<$2000 + sta LZ4_DST + lda #>$2000 + sta LZ4_DST+1 + + jsr lz4_decode + + + ;============================= + ; Load graphic page0 + + lda #$0c + sta BASH + lda #$00 + sta BASL ; load image to $c00 + + +; lda #fs +; sta GBASH +; jsr load_rle_gr + + lda #4 + sta DRAW_PAGE + + jsr gr_copy_to_current ; copy to page1 + + ; GR part + bit PAGE1 + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + + ;============================= + ; Load graphic page1 + + lda #$0c + sta BASH + lda #$00 + sta BASL ; load image to $c00 + +; lda #fs +; sta GBASH +; jsr load_rle_gr + + + ;=================== + ; copy to page3 + lda #0 - jsr clear_gr + sta DRAW_PAGE + + jsr gr_copy_to_current + + ; GR part + bit PAGE0 - jsr wait_until_keypressed ; tail call? + ;============================== + ; setup graphics for vapor lock + ;============================== - rts + jsr vapor_lock ; 6 + + ; vapor lock returns with us at beginning of hsync in line + ; 114 (7410 cycles), so with 5070 lines to go + + ; so we have 5070 + 4550 = 9620 to kill + + jsr gr_copy_to_current ; 6+ 9292 + + ; now we have 322 left + + ; GR part + bit LORES ; 4 + bit SET_GR ; 4 + bit FULLGR ; 4 + + ; 322 - 12 = 310 + ; - 3 for jmp + ; 307 + + ; Try X=9 Y=6 cycles=307 + + ldy #6 ; 2 +sbloopA:ldx #9 ; 2 +sbloopB:dex ; 2 + bne sbloopB ; 2nt/3 + dey ; 2 + bne sbloopA ; 2nt/3 + + jmp sb_begin_loop +.align $100 + + + ;================================================ + ; Spacebars Loop + ;================================================ + ; each scan line 65 cycles + ; 1 cycle each byte (40cycles) + 25 for horizontal + ; Total of 12480 cycles to draw screen + ; Vertical blank = 4550 cycles (70 scan lines) + ; Total of 17030 cycles to get back to where was + +sb_begin_loop: + +sb_display_loop: + + ; 0-7 = text mode +; 1 2 3 +;0123456789012345678901234567890123456789 +;LEVEL: 6 LIVES: 2 SCORE: 01978 HI: 02018 + + ; 8-47 = hgr + ; 48 - 191 = split .. 144 = 36grlins + ; 6 4 25+16+8+16 NNNNNNNN + ; 7 6 25+15+10+15 LNNNNNN + ; 8 8 25+14+12+14 NNNNNNN + ; 9 10 25+13+14+13 LNNNNN + ; 10 12 25+12+16+12 + ; 11 14 25+11+18+11 + ; 12 16 25+10+20+10 + ; 13 18 25+09+22+09 + ; 14 20 25+08+24+08 + ; 15 22 25+07+26+07 + ; 16 24 25+06+28+06 + ; 17 26 25+05+30+05 + ; 18 28 25+04+32+04 + ; 19 30 25+03+34+03 + ; 20 32 25+02+36+02 + ; 21 34 25+01+38+01 + ; 22 36 25+00 + ; 23 38 25+12 + ; 24 40 25+12 + + + ; 8 lines of text mode + + + ldy #8 ; 2 + +sb_text_loop: + bit SET_TEXT ; 4 + lda #29 ; 2 + jsr delay_a ; 25+29 + + dey ; 2 + bne sb_text_loop ; 3 + ;================ + ; 65 + + + ; -1 + + +sb_hgr_loop: + ; delay 184*65 = 11960 + ; -2 + ; +1 + ; -8 + ;========================= + ; 11951 + + bit SET_GR ; 4 + bit HIRES ; 4 + + ; Try X=22 Y=103 cycles=11949 R2 + + nop + + ldy #103 ; 2 +sbloopC:ldx #22 ; 2 +sbloopD:dex ; 2 + bne sbloopD ; 2nt/3 + dey ; 2 + bne sbloopC ; 2nt/3 + + + ;====================================================== + ; We have 4550 cycles in the vblank, use them wisely + ;====================================================== + + ; do_nothing should be 4550 + ; -10 keypress + ; =========== + ; 4540 + + ; Try X=9 Y=89 cycles=4540 + + ldy #89 ; 2 +sbloop1:ldx #9 ; 2 +sbloop2:dex ; 2 + bne sbloop2 ; 2nt/3 + dey ; 2 + bne sbloop1 ; 2nt/3 + + lda KEYPRESS ; 4 + bpl sb_no_keypress ; 3 + jmp sb_start_over +sb_no_keypress: + + jmp sb_display_loop ; 3 + +sb_start_over: + bit KEYRESET ; clear keypress ; 4 + rts ; 6 + + +;.include "deater.inc" +background_hgr: +.incbin "SB_BACKGROUNDC.BIN.lz4",11 +background_hgr_end: diff --git a/space_bars/lz4_decode.s b/space_bars/lz4_decode.s new file mode 100644 index 00000000..4355da11 --- /dev/null +++ b/space_bars/lz4_decode.s @@ -0,0 +1,213 @@ +; LZ4 data decompressor for Apple II + +; Code by Peter Ferrie (qkumba) (peter.ferrie@gmail.com) +; "LZ4 unpacker in 143 bytes (6502 version) (2013)" +; http://pferrie.host22.com/misc/appleii.htm +; This is that code, but with comments and labels added for clarity. +; I also found a bug when decoding with runs of multiples of 256 +; which has since been fixed upstream. + +; For LZ4 reference see +; https://github.com/lz4/lz4/wiki/lz4_Frame_format.md + +; LZ4 summary: +; +; HEADER: +; Should: check for magic number 04 22 4d 18 +; FLG: 64 in our case (01=version, block.index=1, block.checksum=0 +; size=0, checksum=1, reserved +; MAX Blocksize: 40 (64kB) +; HEADER CHECKSUM: a7 +; BLOCK HEADER: 4 bytes (le) length If highest bit set, uncompressed! +; data (see below), followed by checksum? +; BLOCKS: +; Token byte. High 4-bits literal length, low 4-bits copy length +; + If literal length==15, then following byte gets added to length +; If that byte was 255, then keep adding bytes until not 255 +; + The literal bytes follow. There may be zero of them +; + Next is block copy info. little-endian 2-byte offset to +; be subtracted from current read position indicating source +; + The low 4-bits of the token are the copy length, which needs +; 4 added to it. As with the literal length, if it is 15 then +; you read a byte and add (and if that byte is 255, keep adding) + +; At end you have 4 byte end-of-block marker (all zeros?) then +; 4 bytes of checksum (if marked in flags) +; our code does that, so be sure to set end -8 + + +;LZ4_SRC EQU $00 +;LZ4_DST EQU $02 +;LZ4_END EQU $04 +;COUNT EQU $06 +;DELTA EQU $08 + +;UNPACK_BUFFER EQU $5E00 ; offset of first unpacked byte + + + ;====================== + ; LZ4 decode + ;====================== + ; input buffer in LZ4_SRC + ; output buffer hardcoded still + ; size in ENDH:ENDL + +lz4_decode: +; lda LZ4_SRC ; packed data offset +; clc +; adc LZ4_END +; sta LZ4_END +; lda LZ4_SRC+1 +; adc LZ4_END+1 +; sta LZ4_END+1 + +; lda #>UNPACK_BUFFER ; original unpacked data offset +; sta LZ4_DST+1 +; lda #