diff --git a/asm_routines/lzss_decompress.s b/asm_routines/lzss_decompress.s new file mode 100644 index 00000000..fdd16955 --- /dev/null +++ b/asm_routines/lzss_decompress.s @@ -0,0 +1,219 @@ +;; Our Zero Page Allocations + +;; for the LZSS part of the code + +OUTPUTL EQU $FE +OUTPUTH EQU $FF +LOGOL EQU $28 +LOGOH EQU $29 +STORERL EQU $95 +STORERH EQU $96 +COUNT EQU $97 +;LZSS_MASK EQU $98 +LOGOENDL EQU $99 +LOGOENDH EQU $9A +LOADRL EQU $9B +LOADRH EQU $9C +EFFECTRL EQU $9D +EFFECTRH EQU $9E + + +;; LZSS Parameters + +N EQU 1024 +F EQU 64 +THRESHOLD EQU 2 +P_BITS EQU 10 +POSITION_MASK EQU 3 +FREQUENT_CHAR EQU 0 + +;R: .res (1024-64) ; N-F + +R EQU $4000 + + ; Init +lzss_init: + ldx #R + stx OUTH + + lda #FREQUENT_CHAR + ldx #$4 +lzss_init_outer: + ldy #$0 +lzss_init_inner: + sta (OUTL),Y + iny + bne lzss_init_inner + inc OUTH + dex + bpl lzss_init_inner + + rts + + ;================================ + ; Decomress + ; FIXME: optimize + ;================================ + +lzss_decompress: + + lda #>(N-F) ; load R value + sta STORERH + lda #<(N-F) + sta STORERL + + ldy #0 ; setup Y for indirect zero page + ; addressing, we always want +0 + +decompression_loop: + + lda #8 ; set mask counter + sta COUNT + + lda (LOGOL),Y ; load byte + + sta LZSS_MASK ; store it + + ldx #LOGOL + jsr inc16 ; increment pointer + +test_flags: + + lda LOGOH ; compare to see if we've reached end + cmp LOGOENDH + bne not_match + + lda LOGOL + cmp LOGOENDL + + beq done_logo ; if so, we are done + ; bcs one byte less than jmp + +not_match: + lsr LZSS_MASK ; shift byte mask into carry flag + + lda (LOGOL),Y ; load byte + + ldx #LOGOL ; 16-bit increrment + jsr inc16 + + bcs discrete_char ; if set we have discrete char + +offset_length: + + sta LOADRL ; bottom of R offset + + lda (LOGOL),Y ; load another byte + + ldx #LOGOL ; + jsr inc16 ; 16 bit increment + + sta LOADRH ; top of R offset + + lsr A + lsr A ; shift right by 10 (top byte by 2) + + clc + adc #3 ; add threshold+1 (3) + + tax ; store out count in X + +output_loop: + + clc ; calculate R+LOADR + lda LOADRL + adc #>8) ; Mask so mod N + sta LOADRH + + adc #>R + sta EFFECTRH + + lda (EFFECTRL),Y ; Load byte R[LOADR] + + inc LOADRL ; increment address + bne load_carry1 + inc LOADRH ; handle overflow +load_carry1: + +store_byte: + + sta (OUTPUTL),Y ; store byte to output + + inc OUTPUTL ; increment address + bne sb_carry + inc OUTPUTH ; handle overflow +sb_carry: + pha ; calculate R+STORER + clc + lda STORERL + adc #>8) ; mask so mod N + + sta STORERH + adc #>R + sta EFFECTRH + + pla ; restore from stack + + sta (EFFECTRL),Y ; store A there too + + inc STORERL ; increment address + bne store_carry2 + inc STORERH ; handle overflow +store_carry2: + + dex ; count down the out counter + bne output_loop ; loop to output_loop if not 0 + + dec COUNT ; count down the mask counter + bne test_flags ; loop to test_flags if not zero + + beq decompression_loop ; restart whole process + +discrete_char: + ldx #1 ; want to write a single byte + + bne store_byte ; go and store it (1 byte less than jmp) + +done_logo: + rts + + +;============================================ +; inc_pointer - increments the output pointer +;============================================ + +inc_pointer: + ldx #OUTPUTL + +;================================================== +; inc16 - increments a 16-bit pointer in zero page +;================================================== + +inc16: + inc 0,X ; increment address + bne no_carry + inx + inc 0,X ; handle overflow +no_carry: + rts + + +;; ********************* +;; BSS +;; ********************* +;.bss + +;R: .res (1024-64) ; N-F + + + diff --git a/mockingboard/Makefile b/mockingboard/Makefile index 720e7b16..8f7f8241 100644 --- a/mockingboard/Makefile +++ b/mockingboard/Makefile @@ -9,7 +9,7 @@ mock.dsk: KSP_THEME_UNCOMPRESSED KSP_THEME_COMPRESSED \ KSP_THEME_INTERRUPT INTERRUPT_TEST $(DOS33) -y mock_test.dsk BSAVE -a 0x1000 KSP_THEME_UNCOMPRESSED $(DOS33) -y mock_test.dsk BSAVE -a 0x1000 KSP_THEME_COMPRESSED - $(DOS33) -y mock_test.dsk BSAVE -a 0x1000 KSP_THEME_INTERRUPT + $(DOS33) -y mock_test.dsk BSAVE -a 0xc00 KSP_THEME_INTERRUPT $(DOS33) -y mock_test.dsk BSAVE -a 0x1000 INTERRUPT_TEST KSP_THEME_COMPRESSED: ksp_theme_compressed.o @@ -21,7 +21,7 @@ ksp_theme_compressed.o: ksp_theme_compressed.s \ ca65 -o ksp_theme_compressed.o ksp_theme_compressed.s -l ksp_theme_compressed.lst KSP_THEME_INTERRUPT: ksp_theme_interrupt.o - ld65 -o KSP_THEME_INTERRUPT ksp_theme_interrupt.o -C ./apple2_1000.inc + ld65 -o KSP_THEME_INTERRUPT ksp_theme_interrupt.o -C ./apple2_c00.inc ksp_theme_interrupt.o: ksp_theme_interrupt.s \ ../asm_routines/mockingboard.s \ diff --git a/mockingboard/ksp_theme_compressed.inc b/mockingboard/ksp_theme_compressed.inc index a1a744d4..2c90ba13 100644 --- a/mockingboard/ksp_theme_compressed.inc +++ b/mockingboard/ksp_theme_compressed.inc @@ -8,7 +8,7 @@ ksptheme: ; Comment: Tracked by Vince Weaver .byte $01,$80,$38,$00 ; 00000 -.byte $60,$35,$BD,$EE,$DD,$01,$07,$0D,$0D,$0D ; 00096 +.byte $01,$35,$BD,$EE,$DD,$01,$07,$0D,$0D,$0D ; 00096 .byte $01,$00,$07,$0E,$0E,$0E ; 00097 .byte $01,$00,$07,$0F,$0F,$0F ; 00098 .byte $01,$00,$07,$0E,$0E,$0E ; 00099 diff --git a/mockingboard/ksp_theme_interrupt.s b/mockingboard/ksp_theme_interrupt.s index 4f956ee9..13b7a54b 100644 --- a/mockingboard/ksp_theme_interrupt.s +++ b/mockingboard/ksp_theme_interrupt.s @@ -110,6 +110,35 @@ mockingboard_found: cli ; clear interrupt mask + bit SET_GR ; graphics mode + bit HIRES ; hires mode + bit TEXTGR ; mixed text/graphics + bit PAGE0 ; first graphics page + + ;========================== + ; Graphics + ;========================== +uncompress_graphics: + jsr lzss_init ; init R to zero + + lda #>ksp_title ; load logo pointer + sta BASH + lda #ksp_title_end ; load logo end pointer + sta LZSS_ENDH + lda #$2000 + sta OUTH + lda #<$2000 + sta OUTL + + jsr lzss_decompress + ;============================ ; Loop forever ;============================ @@ -129,7 +158,7 @@ done_play: lda #0 sta CH - lda #3 + lda #21 sta CV lda #>(8-(position_bits-8)))); + printf(";N EQU %i\n",ring_buffer_size); + printf(";F EQU %i\n",match_length_limit); + printf(";THRESHOLD EQU %i\n",position_length_threshold); + printf(";P_BITS EQU %i\n",position_bits); + printf(";POSITION_MASK EQU %i\n",(0xff>>(8-(position_bits-8)))); printf("logo:\n"); diff --git a/mockingboard/zp.inc b/mockingboard/zp.inc index 3b639039..f8266073 100644 --- a/mockingboard/zp.inc +++ b/mockingboard/zp.inc @@ -104,6 +104,13 @@ MB_ADDRL EQU $91 MB_ADDRH EQU $92 DONE_PLAYING EQU $93 MB_FRAME_DIFF EQU $94 +LZSS_RL EQU $95 +LZSS_RH EQU $96 +LZSS_COUNT EQU $97 +LZSS_MASK EQU $98 +LZSS_ENDL EQU $99 +LZSS_ENDH EQU $9A + SHIPY EQU $E4