From f9f16609f0eeeff0a4a15612c87fe614bec75aee Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 19 Nov 2018 13:06:19 -0500 Subject: [PATCH] dya: add files --- dya/Makefile | 88 ++++++ dya/chip_title.inc | 51 ++++ dya/chiptune_empty.dsk | Bin 0 -> 143360 bytes dya/chiptune_player.s | 610 ++++++++++++++++++++++++++++++++++++++++ dya/hello.bas | 5 + dya/interrupt_handler.s | 376 +++++++++++++++++++++++++ dya/rasterbars.s | 299 ++++++++++++++++++++ dya/text_print.s | 80 ++++++ dya/volume_bars.s | 226 +++++++++++++++ dya/zp.inc | 251 +++++++++++++++++ 10 files changed, 1986 insertions(+) create mode 100644 dya/Makefile create mode 100644 dya/chip_title.inc create mode 100644 dya/chiptune_empty.dsk create mode 100644 dya/chiptune_player.s create mode 100644 dya/hello.bas create mode 100644 dya/interrupt_handler.s create mode 100644 dya/rasterbars.s create mode 100644 dya/text_print.s create mode 100644 dya/volume_bars.s create mode 100644 dya/zp.inc diff --git a/dya/Makefile b/dya/Makefile new file mode 100644 index 00000000..65beb217 --- /dev/null +++ b/dya/Makefile @@ -0,0 +1,88 @@ +include ../Makefile.inc + +DOS33 = ../dos33fs-utils/dos33 +PNG2GR = ../gr-utils/png2gr + +all: chiptune_player.dsk chiptune_unrolled.dsk + +$(DOS33): + cd ../dos33fs-utils && make + +chiptune_player.dsk: CHIPTUNE_PLAYER ./krw/INTRO2.KRW HELLO + cp chiptune_empty.dsk chiptune_player.dsk + $(DOS33) -y chiptune_player.dsk SAVE A HELLO + $(DOS33) -y chiptune_player.dsk BSAVE -a 0x0C00 CHIPTUNE_PLAYER + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/CAMOUFLAGE.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/CHRISTMAS.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/CRMOROS.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/DEATH2.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/DEMO4.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/HARKONEN.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/INTRO2.KRW +# $(DOS33) -y chiptune_player.dsk SAVE B ./krw/KORO.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/LYRA2.KRW +# $(DOS33) -y chiptune_player.dsk SAVE B ./krw/MMCM.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/RANDOM.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/ROBOT.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/SDEMO.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/SPUTNIK.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/TECHNO.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/UNIVERSE.KRW + $(DOS33) -y chiptune_player.dsk SAVE B ./krw/WAVE.KRW +# $(DOS33) -y chiptune_player.dsk SAVE B OUT.LZ4 +# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x6000 OUT.0 + + +chiptune_unrolled.dsk: CHIPTUNE_UNROLLED ./krw/INTRO2.KRW + cp chiptune_empty.dsk chiptune_unrolled.dsk + $(DOS33) -y chiptune_unrolled.dsk BSAVE -a 0x0C00 CHIPTUNE_UNROLLED + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/CAMOUFLAGE.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/CHRISTMAS.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/CRMOROS.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/DEATH2.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/DEMO4.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/HARKONEN.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/INTRO2.KRW +# $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/KORO.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/LYRA2.KRW +# $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/MMCM.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/RANDOM.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/ROBOT.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/SDEMO.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/SPUTNIK.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/TECHNO.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/UNIVERSE.KRW + $(DOS33) -y chiptune_unrolled.dsk SAVE B ./krw/WAVE.KRW + +HELLO: hello.bas + ../asoft_basic-utils/tokenize_asoft < hello.bas > HELLO + +CHIPTUNE_PLAYER: chiptune_player.o + ld65 -o CHIPTUNE_PLAYER chiptune_player.o -C ../linker_scripts/apple2_c00.inc + +chiptune_player.o: chiptune_player.s \ + ../asm_routines/mockingboard.s \ + ../asm_routines/dos33_routines.s \ + ../asm_routines/lz4_decode.s \ + ../asm_routines/keypress_minimal.s \ + rasterbars.s volume_bars.s interrupt_handler.s \ + chip_title.inc zp.inc + ca65 -o chiptune_player.o chiptune_player.s -l chiptune_player.lst + +CHIPTUNE_UNROLLED: chiptune_unrolled.o + ld65 -o CHIPTUNE_UNROLLED chiptune_unrolled.o -C ../linker_scripts/apple2_c00.inc + +chiptune_unrolled.o: chiptune_player.s \ + ../asm_routines/mockingboard.s \ + ../asm_routines/dos33_routines.s \ + ../asm_routines/lz4_decode.s \ + ../asm_routines/keypress_minimal.s \ + rasterbars.s volume_bars.s interrupt_handler_unrolled.s \ + chip_title.inc zp.inc + ca65 -D UNROLLED=1 -o chiptune_unrolled.o chiptune_player.s -l chiptune_unrolled.lst + + +clean: + rm -f *~ TITLE.GR *.o *.lst \ + CHIPTUNE_PLAYER CHIPTUNE_UNROLLED + diff --git a/dya/chip_title.inc b/dya/chip_title.inc new file mode 100644 index 00000000..4f3a4d4f --- /dev/null +++ b/dya/chip_title.inc @@ -0,0 +1,51 @@ +chip_title: .byte $28 ; ysize=40 + .byte $AE,$00, $A3,$10, $40, $A3,$20, $40, $A3,$20, $A0,$14,$00 + .byte $A3,$10, $11, $A4,$91, $00, $A3,$11, $44, $A3,$22 + .byte $44, $A3,$22, $00, $A4,$91, $11, $A3,$10, $A8,$00 + .byte $10, $11, $91,$91, $99, $A3,$D9, $DD, $CD,$CD + .byte $C0, $00, $11, $A3,$44, $22, $A3,$44, $22 + .byte $00, $C0, $CD,$CD, $DD, $A3,$D9, $99, $A3,$91 + .byte $11, $10, $A3,$00, $10, $91, $D9,$D9, $DD + .byte $CD,$CD, $A3,$6C, $A3,$06, $00, $01, $A3,$04, $02 + .byte $A3,$04, $02, $00, $A3,$06, $A3,$6C, $A3,$CD, $DD + .byte $D9,$D9, $91, $10, $00,$00, $11, $A0,$24,$00, $11 + .byte $00,$00, $11, $00, $20, $22,$22, $00, $22 + .byte $00, $22, $00, $22, $00, $22,$22, $20 + .byte $00, $A3,$33, $00, $33, $00, $33, $00 + .byte $33, $00,$00, $33, $00, $A3,$33, $00, $A3,$33 + .byte $00, $11, $00,$00, $11, $00, $22, $A3,$00 + .byte $22, $20, $22, $00, $22, $00, $22 + .byte $00, $22, $00,$00, $33, $00,$00, $33, $00 + .byte $33, $00, $33,$33, $30, $33, $00, $33 + .byte $30, $00,$00, $33, $30,$30, $00, $11, $00,$00 + .byte $11, $00, $22, $A3,$00, $22, $02, $22 + .byte $00, $22, $00, $22,$22, $02, $00,$00, $33 + .byte $00,$00, $33, $00, $33, $00, $33, $00 + .byte $33,$33, $00, $33, $03, $00,$00, $03,$03, $33 + .byte $00, $11, $00,$00, $11, $00, $02, $22,$22 + .byte $00, $22, $00, $22, $00, $22, $00 + .byte $22, $A4,$00, $33, $00,$00, $A3,$33, $00, $33 + .byte $00,$00, $33, $00, $A3,$33, $00, $A3,$33, $00 + .byte $11, $00, $10, $11, $A0,$24,$00, $11, $10 + .byte $11, $A8,$00, $A0,$15,$40, $A9,$00, $11,$11, $A4,$00, $C0 + .byte $A3,$00, $44, $A3,$55, $44, $A5,$55, $44, $55 + .byte $45, $55, $44, $94, $44, $4E, $44 + .byte $4E, $44, $A6,$00, $C0, $00,$00, $11,$11, $00,$00 + .byte $C0, $CC, $C0,$C0, $00,$00, $44, $A3,$55, $44 + .byte $A5,$55, $44, $55, $54, $55, $44, $94 + .byte $44, $55, $44, $55, $44, $A4,$00, $C0 + .byte $CC, $C0,$C0, $00, $11,$11, $00, $A4,$9D, $A3,$00 + .byte $A0,$12,$44, $64, $44, $64, $44, $00,$00, $A4,$9D + .byte $00,$00, $11,$11, $00, $A5,$21, $00,$00, $44, $A3,$55 + .byte $44, $A5,$55, $44, $55, $45, $55, $44 + .byte $54,$54, $44, $66, $44, $66, $44, $00,$00 + .byte $A5,$21, $00, $11,$11, $00,$00, $A3,$06, $A3,$00, $44 + .byte $A3,$55, $44, $A5,$55, $44, $55, $54, $55 + .byte $44, $45,$45, $44, $46, $44, $46, $44 + .byte $A3,$00, $A3,$06, $00,$00, $11,$11, $A8,$00, $A0,$15,$44, $57 + .byte $A8,$00, $11,$11, $A8,$00, $05, $AB,$04, $C4, $D4 + .byte $C4, $D4, $C4, $D4, $C4, $D4, $04 + .byte $05, $A8,$00, $11,$11, $A0,$14,$00, $0C, $0D, $0C + .byte $0D, $0C, $0D, $0C, $0D, $AA,$00, $11,$11 + .byte $A0,$26,$10, $11 + .byte $A1 diff --git a/dya/chiptune_empty.dsk b/dya/chiptune_empty.dsk new file mode 100644 index 0000000000000000000000000000000000000000..9c9b5808b354b895b0f1a0700dab17603f089e1e GIT binary patch literal 143360 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�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 + sta OUTH + jsr move_and_print ; print it + + jsr mockingboard_detect_slot4 ; call detection routine + cpx #$1 + beq mockingboard_found + + lda #not_message + sta OUTH + inc CV + jsr move_and_print + +; jmp forever_loop ; and wait forever + +mockingboard_found: +; lda #found_message +; sta OUTH +; inc CV +; jsr move_and_print + + ;============================ + ; Init the Mockingboard + ;============================ + + jsr mockingboard_init + jsr reset_ay_both + jsr clear_ay_both + + ;========================= + ; Setup Interrupt Handler + ;========================= + ; Vector address goes to 0x3fe/0x3ff + ; FIXME: should chain any existing handler + + lda #interrupt_handler + sta $03ff + + ;============================ + ; Enable 50Hz clock on 6522 + ;============================ + + sei ; disable interrupts just in case + + lda #$40 ; Continuous interrupts, don't touch PB7 + sta $C40B ; ACR register + lda #$7F ; clear all interrupt flags + sta $C40E ; IER register (interrupt enable) + + lda #$C0 + sta $C40D ; IFR: 1100, enable interrupt on timer one oflow + sta $C40E ; IER: 1100, enable timer one interrupt + + lda #$E7 + sta $C404 ; write into low-order latch + lda #$4f + sta $C405 ; write into high-order latch, + ; load both values into counter + ; clear interrupt and start counting + + ; 4fe7 / 1e6 = .020s, 50Hz + + + ;============================ + ; Draw title screen + ;============================ + + jsr set_gr_page0 ; set page 0 + + lda #$4 ; draw page 1 + sta DRAW_PAGE + + jsr clear_screens ; clear both screens + + lda #chip_title + sta GBASH + + ; Load image ; load the image + lda #<$400 + sta BASL + lda #>$400 + sta BASH + + jsr load_rle_gr + + ;================== + ; load first song + ;================== + + jsr new_song + + ;============================ + ; Init Background + ;============================ + jsr set_gr_page0 + + lda #0 + sta DRAW_PAGE + sta SCREEN_Y + + ;============================ + ; Enable 6502 interrupts + ;============================ + + cli ; clear interrupt mask + + + ;============================ + ; Loop forever + ;============================ +main_loop: + lda DECODE_ERROR + beq check_copy + sei + brk + +check_copy: + lda COPY_TIME + beq check_decompress ; if zero, skip + + lda #0 + sta COPY_OFFSET +check_copy_loop: + jsr page_copy ;6+3621 + + inc COPY_OFFSET ; (opt: make subtract?) ; 5 + + lda #14 ; NOT HEX URGH! + cmp COPY_OFFSET + bne check_copy_loop + + lda #0 ; we are done + sta COPY_TIME + +check_decompress: + lda DECOMPRESS_TIME + beq check_done ; if zero, skip + + jsr setup_next_subsong ; decompress + + lda MB_CHUNK_OFFSET + sta TIME_TAKEN + + lda #0 + sta DECOMPRESS_TIME + + ;============================ + ; visualization + ;============================ +; jsr clear_top +; jsr draw_rasters +; jsr volume_bars +; jsr page_flip + +check_done: + lda #$ff + bit DONE_PLAYING + beq main_loop ; if was all zeros, loop + bmi main_loop ; if high bit set, paused + bvs minus_song ; if bit 6 set, then left pressed + + ; else, either song finished or + ; right pressed + +plus_song: + sei ; disable interrupts + jsr increment_file + jmp done_play + +minus_song: + sei ; disable interrupts + jsr decrement_file + +done_play: + + lda #0 + sta DONE_PLAYING + + lda #0 + sta CH + + jsr clear_bottoms + + jsr new_song + + cli ; re-enable interrupts + + jmp main_loop + +forever_loop: + jmp forever_loop + + + + ;================= + ; load a new song + ;================= + +new_song: + + ;========================= + ; Init Variables + ;========================= + + lda #$0 + sta FRAME_COUNT + sta A_VOLUME + sta B_VOLUME + sta C_VOLUME + sta COPY_OFFSET + sta DECOMPRESS_TIME + sta COPY_TIME + sta MB_CHUNK_OFFSET + lda #$20 + sta DECODER_STATE + lda #3 + sta CHUNKSIZE + + ;=========================== + ; Print loading message + ;=========================== + + jsr clear_bottoms ; clear bottom of page 0/1 + + lda #0 ; print LOADING message + sta CH + lda #21 + sta CV + + lda #loading_message + sta OUTH + jsr print_both_pages + + + ;=========================== + ; Load in KRW file + ;=========================== + + jsr get_filename + + lda #8 + sta CH + lda #21 + sta CV + + lda INL + sta OUTL + lda INH + sta OUTH + jsr print_both_pages + +disk_buff EQU LZ4_BUFFER +read_size EQU $4000 + + jsr read_file ; read KRW file from disk + + + ;========================= + ; Print Info + ;========================= + + jsr clear_bottoms ; clear bottom of page 0/1 + + lda #>LZ4_BUFFER ; point to LZ4 data + sta OUTH + lda #' + sta $777 + sta $B77 + + + + + + ; Point LZ4 src at proper place + + ldy #0 + lda #>(LZ4_BUFFER+3) + sta LZ4_SRC+1 + lda #<(LZ4_BUFFER+3) + sta LZ4_SRC + + lda (LZ4_SRC),Y ; get header skip + clc + adc LZ4_SRC + sta LZ4_SRC + lda LZ4_SRC+1 + adc #0 + sta LZ4_SRC+1 + + lda #UNPACK_BUFFER + sta INH + + ; Decompress first chunks + + lda #$0 + sta COPY_OFFSET + sta DECOMPRESS_TIME + lda #$3 + sta CHUNKSIZE + lda #$20 + sta DECODER_STATE + sta COPY_TIME + + jsr setup_next_subsong + + rts + + ;================= + ; next sub-song + ;================= +setup_next_subsong: + + ldy #0 + + lda (LZ4_SRC),Y ; get next size value + sta LZ4_END + iny + lda (LZ4_SRC),Y + sta LZ4_END+1 + + lda #2 ; increment pointer + clc + adc LZ4_SRC + sta LZ4_SRC + lda LZ4_SRC+1 + adc #0 + sta LZ4_SRC+1 + + jsr lz4_decode ; decode + + ; tail-call? + + rts + + + + ;=================== + ; print header info + ;=================== + ; shortcut to print header info + ; a = VTAB + +print_header_info: + + sta CV + + iny ; adjust pointer + tya + ldy #0 + clc + adc OUTL + sta OUTL + lda OUTH + adc #$0 + sta OUTH + + lda (OUTL),Y ; get HTAB value + sta CH + + inc OUTL ; increment 16-bits + bne bloop22 + inc OUTH +bloop22: + + jmp print_both_pages ; print, tail call + + + ;============================================== + ; plan: takes 256 50Hz to play a chunk + ; need to copy 14 256-byte blocks + ; PLAY A (copying C) + ; PLAY B (copying C) + ; PLAY D (decompressing A/B/C) + + + ;======================== + ; page copy + ;======================== + ; want to copy: + ; SRC: chunk_buffer+(2*256)+(COPY_OFFSET*3*256) + ; DST: chunk_buffer+$2A00+(COPY_OFFSET*256) +page_copy: + clc ; 2 + lda #>(UNPACK_BUFFER+512) ; 3 + adc COPY_OFFSET ; 3 + adc COPY_OFFSET ; 3 + adc COPY_OFFSET ; 3 + sta page_copy_loop+2 ; self modify ; 5 + + lda #>(UNPACK_BUFFER+$2A00) ; 2 + adc COPY_OFFSET ; 3 + sta page_copy_loop+5 ; self modify ; 5 + + ldx #$00 ; 2 +page_copy_loop: + lda $1000,x ; 4 + sta $1000,X ; 5 + inx ; 2 + bne page_copy_loop ; 2nt/3 + rts ; 6 + ;====================== + ; 2+14*256+6+29= 3621 + + + ;================== + ; Get filename + ;================== + ; WHICH_FILE holds number + ; MAX_FILES has max + ; Scroll through until find + ; point INH:INL to it +get_filename: + + ldy #0 + ldx WHICH_FILE + + lda #krw_file + sta INH + +get_filename_loop: + cpx #0 + beq filename_found + +inner_loop: + iny + lda (INL),Y + bne inner_loop + + iny + + dex + jmp get_filename_loop + +filename_found: + tya + clc + adc INL + sta INL + lda INH + adc #0 + sta INH + + rts + + ;=============================== + ; Increment file we want to load + ;=============================== +increment_file: + inc WHICH_FILE + lda WHICH_FILE + cmp #NUM_FILES + bne done_increment + lda #0 + sta WHICH_FILE +done_increment: + rts + + ;=============================== + ; Decrement file we want to load + ;=============================== +decrement_file: + dec WHICH_FILE + bpl done_decrement + lda #(NUM_FILES-1) + sta WHICH_FILE +done_decrement: + rts + +;========== +; filenames +;========== +krw_file: + .asciiz "CAMOUFLAGE.KRW" + .asciiz "CHRISTMAS.KRW" + .asciiz "CRMOROS.KRW" + .asciiz "DEATH2.KRW" + .asciiz "DEMO4.KRW" + .asciiz "HARKONEN.KRW" + .asciiz "INTRO2.KRW" + .asciiz "LYRA2.KRW" + .asciiz "RANDOM.KRW" + .asciiz "ROBOT.KRW" + .asciiz "SDEMO.KRW" + .asciiz "SPUTNIK.KRW" + .asciiz "TECHNO.KRW" + .asciiz "UNIVERSE.KRW" + .asciiz "WAVE.KRW" + + + + +;========= +;routines +;========= +.include "../asm_routines/gr_offsets.s" +.include "text_print.s" +.include "../asm_routines/mockingboard_a.s" +.include "../asm_routines/gr_fast_clear.s" +.include "../asm_routines/pageflip.s" +.include "../asm_routines/gr_unrle.s" +.include "../asm_routines/gr_setpage.s" +.include "../asm_routines/dos33_routines.s" +.include "../asm_routines/gr_hlin.s" +.include "../asm_routines/lz4_decode.s" +.include "../asm_routines/keypress_minimal.s" +.include "rasterbars.s" +.include "volume_bars.s" +.if .def(UNROLLED) +.include "interrupt_handler_unrolled.s" +.else +.include "interrupt_handler.s" +.endif +;========= +; strings +;========= +mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD IN SLOT #4" +not_message: .byte "NOT " +found_message: .asciiz "FOUND" +;done_message: .asciiz "DONE PLAYING" +loading_message: .asciiz "LOADING" + +;============ +; graphics +;============ +.include "chip_title.inc" diff --git a/dya/hello.bas b/dya/hello.bas new file mode 100644 index 00000000..d510efdf --- /dev/null +++ b/dya/hello.bas @@ -0,0 +1,5 @@ + 5 PRINT + 10 PRINT "LOADING VMW CHIPTUNE PLAYER" + 20 PRINT "DYA SPECIAL EDITION V1.0" + 50 PRINT + 100 PRINT CHR$ (4)"BRUN CHIPTUNE_PLAYER" diff --git a/dya/interrupt_handler.s b/dya/interrupt_handler.s new file mode 100644 index 00000000..05240ae9 --- /dev/null +++ b/dya/interrupt_handler.s @@ -0,0 +1,376 @@ + ;================================ + ;================================ + ; mockingboard interrupt handler + ;================================ + ;================================ + ; On Apple II/6502 the interrupt handler jumps to address in 0xfffe + ; This is in the ROM, which saves the registers + ; on older IIe it saved A to $45 (which could mess with DISK II) + ; newer IIe doesn't do that. + ; It then calculates if it is a BRK or not (which trashes A) + ; Then it sets up the stack like an interrupt and calls 0x3fe + +TIME_OFFSET EQU 13 + +interrupt_handler: +; pha ; save A ; 3 + ; A is saved in $45 by firmware + txa + pha ; save X + tya + pha ; save Y + + + +; inc $0404 ; debug (flashes char onscreen) + + bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4 + + + lda DONE_PLAYING ; 3 + beq mb_play_music ; if song done, don't play music ; 3/2nt + jmp check_keyboard ; 3 + ;============ + ; 13 + +mb_play_music: + + + ;====================================== + ; Write frames to Mockingboard + ;====================================== + ; actually plays frame loaded at end of + ; last interrupt, so 20ms behind? + +mb_write_frame: + + + ldx #0 ; set up reg count ; 2 + ;============ + ; 2 + + ;================================== + ; loop through the 14 registers + ; reading the value, then write out + ;================================== + ; inlined "write_ay_both" to save up to 156 (12*13) cycles + ; unrolled + +mb_write_loop: + lda REGISTER_DUMP,X ; load register value ; 4 + cmp REGISTER_OLD,X ; compare with old values ; 4 + beq mb_no_write ; 3/2nt + ;============= + ; typ 11 + + ; special case R13. If it is 0xff, then don't update + ; otherwise might spuriously reset the envelope settings + + cpx #13 ; 2 + bne mb_not_13 ; 3/2nt + cmp #$ff ; 2 + beq mb_skip_13 ; 3/2nt + ;============ + ; typ 5 +mb_not_13: + + + ; address + stx MOCK_6522_ORA1 ; put address on PA1 ; 4 + stx MOCK_6522_ORA2 ; put address on PA2 ; 4 + lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2 + sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4 + sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 4 + sta MOCK_6522_ORB2 ; 4 + + ; value + lda REGISTER_DUMP,X ; load register value ; 4 + sta MOCK_6522_ORA1 ; put value on PA1 ; 4 + sta MOCK_6522_ORA2 ; put value on PA2 ; 4 + lda #MOCK_AY_WRITE ; ; 2 + sta MOCK_6522_ORB1 ; write on PB1 ; 4 + sta MOCK_6522_ORB2 ; write on PB2 ; 4 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 4 + sta MOCK_6522_ORB2 ; 4 + ;=========== + ; 62 +mb_no_write: + inx ; point to next register ; 2 + cpx #14 ; if 14 we're done ; 2 + bmi mb_write_loop ; otherwise, loop ; 3/2nt + ;============ + ; 7 +mb_skip_13: + + + ;===================================== + ; Copy registers to old + ;===================================== + ldx #13 ; 2 +mb_reg_copy: + lda REGISTER_DUMP,X ; load register value ; 4 + sta REGISTER_OLD,X ; compare with old values ; 4 + dex ; 2 + bpl mb_reg_copy ; 2nt/3 + ;============= + ; 171 + + ;=================================== + ; Load all 14 registers in advance + ;=================================== + ; note, assuming not cross page boundary, not any slower + ; then loading from zero page? + +mb_load_values: + + ldx #0 ; set up reg count ; 2 + ldy MB_CHUNK_OFFSET ; get chunk offset ; 3 + ;============= + ; 5 + +mb_load_loop: + lda (INL),y ; load register value ; 5 + sta REGISTER_DUMP,X ; 4 + ;============ + ; 9 + ;==================== + ; point to next page + ;==================== + + clc ; point to next interleaved ; 2 + lda INH ; page by adding CHUNKSIZE (3/1); 3 + adc CHUNKSIZE ; 3 + sta INH ; 3 + + inx ; point to next register ; 2 + cpx #14 ; if 14 we're done ; 2 + bmi mb_load_loop ; otherwise, loop ; 3/2nt + ;============ + ; 18 + + ;========================================= + ; if A_COARSE_TONE is $ff then we are done + + lda A_COARSE_TONE ; 3 + bpl mb_not_done ; 3/2nt + + lda #1 ; set done playing ; 2 + + jmp quiet_exit ; 3 + ;=========== + ; typ 6 +mb_not_done: + + ;============================================== + ; incremement offset. If 0 move to next chunk + ;============================================== + +increment_offset: + + inc MB_CHUNK_OFFSET ; increment offset ; 5 + bne back_to_first_reg ; if not zero, done ; 3/2nt + + + ;===================== + ; move to next state + ;===================== + + clc + rol DECODER_STATE ; next state ; 5 + ; 20 -> 40 -> 80 -> c+00 + bcs wraparound_to_a ; 3/2nt + + bit DECODER_STATE ;bit7->N bit6->V + bvs back_to_first_reg ; do nothing on B ; 3/2nt + +start_c: + lda #1 + sta CHUNKSIZE + + ; setup next three chunks of song + + lda #1 ; start decompressing + sta DECOMPRESS_TIME ; outside of handler + + jmp back_to_first_reg + +wraparound_to_a: + lda #$3 + sta CHUNKSIZE + lda #$20 + sta DECODER_STATE + sta COPY_TIME ; start copying + + lda DECOMPRESS_TIME + beq blah + lda #1 + sta DECODE_ERROR +blah: + ;============================== + ; After 14th reg, reset back to + ; read R0 data + ;============================== + +back_to_first_reg: + lda #0 ; 2 + bit DECODER_STATE ; 3 + bmi back_to_first_reg_c ; 2nt/3 + bvc back_to_first_reg_a ; 2nt/3 + +back_to_first_reg_b: + lda #$1 ; offset by 1 + +back_to_first_reg_a: + clc ; 2 + adc #>UNPACK_BUFFER ; in proper chunk 1 or 2 ; 2 + + jmp update_r0_pointer ; 3 + +back_to_first_reg_c: + lda #>(UNPACK_BUFFER+$2A00) ; in linear C area ; 2 + +update_r0_pointer: + sta INH ; update r0 pointer ; 3 + + + + ;================================= + ; Finally done with this interrupt + ;================================= + +done_interrupt: + + + ;===================== + ; Update time counter + ;===================== +update_time: + inc FRAME_COUNT ; 5 + lda FRAME_COUNT ; 3 + cmp #50 ; 3 + bne done_time ; 3/2nt + + lda #$0 ; 2 + sta FRAME_COUNT ; 3 + +update_second_ones: + inc $7d0+TIME_OFFSET+3 ; 6 + inc $bd0+TIME_OFFSET+3 ; 6 + lda $bd0+TIME_OFFSET+3 ; 4 + cmp #$ba ; one past '9' ; 2 + bne done_time ; 3/2nt + lda #'0'+$80 ; 2 + sta $7d0+TIME_OFFSET+3 ; 4 + sta $bd0+TIME_OFFSET+3 ; 4 +update_second_tens: + inc $7d0+TIME_OFFSET+2 ; 6 + inc $bd0+TIME_OFFSET+2 ; 6 + lda $bd0+TIME_OFFSET+2 ; 4 + cmp #$b6 ; 6 (for 60 seconds) ; 2 + bne done_time ; 3/2nt + lda #'0'+$80 ; 2 + sta $7d0+TIME_OFFSET+2 ; 4 + sta $bd0+TIME_OFFSET+2 ; 4 +update_minutes: + inc $7d0+TIME_OFFSET ; 6 + inc $bd0+TIME_OFFSET ; 6 + ; we don't handle > 9:59 songs yet +done_time: + ;============= + ; 90 worst + + + ;================================= + ; Moved visualization here as a hack + ;================================= + + ;============================ + ; Visualization + ;============================ + + jsr clear_top + lda RASTERBARS_ON + beq skip_rasters + jsr draw_rasters +skip_rasters: + jsr volume_bars + jsr page_flip + + +check_keyboard: + + jsr get_key + lda LASTKEY + beq exit_interrupt + + cmp #(' '+$80) + bne key_R +key_space: + lda #$80 + eor DONE_PLAYING + jmp quiet_exit + +key_R: + cmp #'R' + bne key_left + + lda #$ff + eor RASTERBARS_ON + sta RASTERBARS_ON + jmp done_key + +key_left: + cmp #'A' + bne key_right + + lda #$40 + bne quiet_exit + +key_right: + cmp #'D' + bne done_key + + lda #$20 + bne quiet_exit + +done_key: + jmp exit_interrupt + +quiet_exit: + sta DONE_PLAYING + jsr clear_ay_both + + ;===================================== + ; clear register area + ;===================================== + ldx #13 ; 2 + lda #0 ; 2 +mb_clear_reg: + sta REGISTER_DUMP,X ; clear register value ; 4 + sta REGISTER_OLD,X ; clear old values ; 4 + dex ; 2 + bpl mb_clear_reg ; 2nt/3 + +exit_interrupt: + +; pla ; restore a ; 4 + + pla + tay ; restore Y + pla + tax ; restore X + lda $45 ; restore A + + + rti ; return from interrupt ; 6 + + ;============ + ; typical + ; ???? cycles + + +REGISTER_OLD: + .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/dya/rasterbars.s b/dya/rasterbars.s new file mode 100644 index 00000000..a8bcf73a --- /dev/null +++ b/dya/rasterbars.s @@ -0,0 +1,299 @@ +; Not quite a raster-bar, but why not + + +; OPTIMIZATION (as originally it was 16,200 instructions, a bit much +; for a max 20,000 cycle interrupt handler) + +; -120 : Unroll the zero loop, saved 120 cycles +; -5000 : Inline the vlin_double code + +;=========== +; CONSTANTS +;=========== + +ELEMENTS EQU 64 +NUM_ROWS EQU 20 + + ;===================== + ; Rasterbars + ;===================== + + ;=========================== + ;=========================== + ; Main Loop + ;=========================== + ;=========================== +draw_rasters: + + ; clear rows + +; ldy #(NUM_ROWS-1) ; 2 + lda #0 ; 2 +init_rows: + sta row_color+0 ; 4 + sta row_color+1 + sta row_color+2 + sta row_color+3 + sta row_color+4 + sta row_color+5 + sta row_color+6 + sta row_color+7 + sta row_color+8 + sta row_color+9 + sta row_color+10 + sta row_color+11 + sta row_color+12 + sta row_color+13 + sta row_color+14 + sta row_color+15 + sta row_color+16 + sta row_color+17 + sta row_color+18 + sta row_color+19 + + + + +; sta row_color,Y ; 5 +; dey ; 2 +; bpl init_rows ; 2nt/3 + ;============== + ; Originally 4+20*10 = 204 cyles / 10 bytes + ; now 2+4*20 = 82 cycles / 62 bytes + + ;================ + ; set colors + + ldy SCREEN_Y ; 3 + + lda #COLOR_BOTH_DARKBLUE ; d. blue ; 2 + jsr set_row_color ; 6+136 + + lda #COLOR_BOTH_MEDIUMBLUE ; m.blue ; 2 + jsr set_row_color ; 6+136 + + lda #COLOR_BOTH_AQUA ; aqua ; 2 + jsr set_row_color ; 6+136 + + lda #COLOR_BOTH_PINK ; pink ; 2 + jsr set_row_color ; 6+136 + + lda #COLOR_BOTH_RED ; red ; 2 + jsr set_row_color ; 6+136 + + ;============== + ; new = 5 * 142 = 710 + ; original = 1152 + + ;================= + ; draw rows + + ldy #(NUM_ROWS-1) ; 2 +draw_rows_loop: + lda row_color,Y ; 5 + beq draw_rows_skip ; skip if black ; 2nt/3 + + sta COLOR ; 3 + + sty TEMPY ; 3 + tya ; y*2 ; 2 + asl ; 2 + tay ; 2 + + ; hlin_setup inlined + + lda gr_offsets,Y ; lookup low-res memory address ; 4 + sta GBASL ; 3 + iny ; 2 + lda gr_offsets,Y ; 4 + clc ; 2 + adc DRAW_PAGE ; add in draw page offset ; 3 + sta GBASH ; 3 + + ldy #39 ; 2 + lda COLOR ; 3 +double_loop: + sta (GBASL),Y ; 6 + dey ; 2 + bpl double_loop ; 2nt/3 + + ldy TEMPY ; 3 + +draw_rows_skip: + dey ; 2 + bpl draw_rows_loop ; 3/2nt + + ;============================== + ; Original: 20 * 741 = 14,820 + ; new = 2+ 20*(53+11*40)=9862 + ; (note, worst case) + ;================== + ; update y pointer + ;================== + ldy SCREEN_Y ; 3 + iny ; 2 + cpy #ELEMENTS ; 2 + bne not_there ; 3/2nt + ldy #0 ; 2 +not_there: + sty SCREEN_Y ; 3 + + rts ; 6 + + ;=========== + ; 24 + + ;===================================== + ; original total= 16,200 + ; new total (worst case)= 10,678 + ; (realistic) = 5,748 + + ;=================== + ;=================== + ; set_row_color + ;=================== + ;=================== + ; color in A + ; Y=offset + ; Y incremented + ; A, X trashed + +set_row_color: + sta COLOR ; 3 + tya ; wrap y offset ; 2 + and #(ELEMENTS-1) ; 2 + tax ; 2 + + lda fine_sine,X ; lookup sine value ; 4 + ; pre-shifted right by 4, sign-extended + ; 18 added to center + +sin_no_more: + + pha ; save row value ; 3 + jsr put_color ; put color at row ; 6+44 + pla ; restore row value ; 4 + + clc ; increment row value ; 2 + adc #1 ; 2 + + jsr put_color ; put color at row ; 6+44 + + iny ; increment for next time ; 2 + + rts ; 6 + ;============= + ; 132 + + ;================== + ; put_color + ;================== + ; A = row to set color of + ; A trashed +put_color: + clc ; 2 + ror ; row/2, with even/odd in carry ; 2 + tax ; put row/2 in X ; 2 + + bcc even_line ; if even, skip to even ; 2nt/3 +odd_line: + lda #$f0 ; load mask for odd ; 2 + bcs finish_line ; 2nt/3 +even_line: + lda #$0f ; load mask for even ; 2 +finish_line: + sta MASK ; 3 + + and COLOR ; mask off color ; 3 + sta COLOR2 ; store for later ; 3 + + lda MASK ; 3 + eor #$ff ; invert mask ; 2 + and row_color,X ; load existing color ; 4 + + ora COLOR2 ; combine ; 3 + sta row_color,X ; store back ; 5 + + rts ; 6 + + ;=========== + ; 44 +;====================== +; some arrays +;====================== + +row_color: +.byte $00,$00,$00,$00,$00, $00,$00,$00,$00,$00 +.byte $00,$00,$00,$00,$00, $00,$00,$00,$00,$00 + +; arithmatically shifted right by 4, sign extended, added 18 to center + +; FIXME: exploit symmetry and get rid of 3/4 of this table +; possibly not worth the extra code +fine_sine: +.byte $00+18 ; 0.000000 +.byte $01+18 ; 0.098017 +.byte $03+18 ; 0.195090 +.byte $04+18 ; 0.290285 +.byte $06+18 ; 0.382683 +.byte $07+18 ; 0.471397 +.byte $08+18 ; 0.555570 +.byte $0A+18 ; 0.634393 +.byte $0B+18 ; 0.707107 +.byte $0C+18 ; 0.773010 +.byte $0D+18 ; 0.831470 +.byte $0E+18 ; 0.881921 +.byte $0E+18 ; 0.923880 +.byte $0F+18 ; 0.956940 +.byte $0F+18 ; 0.980785 +.byte $0F+18 ; 0.995185 +.byte $0F+18 ; 1.000000 +.byte $0F+18 ; 0.995185 +.byte $0F+18 ; 0.980785 +.byte $0F+18 ; 0.956940 +.byte $0E+18 ; 0.923880 +.byte $0E+18 ; 0.881921 +.byte $0D+18 ; 0.831470 +.byte $0C+18 ; 0.773010 +.byte $0B+18 ; 0.707107 +.byte $0A+18 ; 0.634393 +.byte $08+18 ; 0.555570 +.byte $07+18 ; 0.471397 +.byte $06+18 ; 0.382683 +.byte $04+18 ; 0.290285 +.byte $03+18 ; 0.195090 +.byte $01+18 ; 0.098017 +.byte $00+18 ; 0.000000 + +.byte ($FE+18)&$ff ; -0.098017 +.byte ($FC+18)&$ff ; -0.195090 +.byte ($FB+18)&$ff ; -0.290285 +.byte ($F9+18)&$ff ; -0.382683 +.byte ($F8+18)&$ff ; -0.471397 +.byte ($F7+18)&$ff ; -0.555570 +.byte ($F5+18)&$ff ; -0.634393 +.byte ($F4+18)&$ff ; -0.707107 +.byte ($F3+18)&$ff ; -0.773010 +.byte ($F2+18)&$ff ; -0.831470 +.byte ($F1+18)&$ff ; -0.881921 +.byte ($F1+18)&$ff ; -0.923880 +.byte ($F0+18)&$ff ; -0.956940 +.byte ($F0+18)&$ff ; -0.980785 +.byte ($F0+18)&$ff ; -0.995185 +.byte ($F0+18)&$ff ; -1.000000 +.byte ($F0+18)&$ff ; -0.995185 +.byte ($F0+18)&$ff ; -0.980785 +.byte ($F0+18)&$ff ; -0.956940 +.byte ($F1+18)&$ff ; -0.923880 +.byte ($F1+18)&$ff ; -0.881921 +.byte ($F2+18)&$ff ; -0.831470 +.byte ($F3+18)&$ff ; -0.773010 +.byte ($F4+18)&$ff ; -0.707107 +.byte ($F5+18)&$ff ; -0.634393 +.byte ($F7+18)&$ff ; -0.555570 +.byte ($F8+18)&$ff ; -0.471397 +.byte ($F9+18)&$ff ; -0.382683 +.byte ($FB+18)&$ff ; -0.290285 +.byte ($FC+18)&$ff ; -0.195090 +.byte ($FE+18)&$ff ; -0.098017 + diff --git a/dya/text_print.s b/dya/text_print.s new file mode 100644 index 00000000..a39506f7 --- /dev/null +++ b/dya/text_print.s @@ -0,0 +1,80 @@ + ;================================ + ; 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 + diff --git a/dya/volume_bars.s b/dya/volume_bars.s new file mode 100644 index 00000000..3a5e6732 --- /dev/null +++ b/dya/volume_bars.s @@ -0,0 +1,226 @@ +;============================== +;============================== +; Draw volume bars +;============================== +;============================== + +volume_bars: + ; hline Y,V2 at A + ; top line + + lda #COLOR_BOTH_GREY ; 2 + sta COLOR ; remove for crazy effect ; 3 + ldy #12 ; 2 + lda #26 ; 2 + sta V2 ; 3 + lda #6 ; 2 + jsr hlin_double ; 6 + ; 63+14*16=287 + ;===================== + ; 307 + ; middle + + lda #8 ; 2 +middle_loop: + pha ; 3 + + cmp #8 ; 2 + beq middle_black ; 2nt/3 + cmp #26 ; 2 + beq middle_black ; 2nt/3 + + cmp #10 ; 2 + bne not_top ; 2nt/3 + + ldx #$3B ; pink/purple ; 2 + stx A_COLOR ; 3 + ldx #$7E ; light-blue/aqua ; 2 + stx B_COLOR ; 3 + ldx #$CD ; light-green/yellow ; 2 + stx C_COLOR ; 3 + jmp calc_volume ; 3 + +not_top: + ldx #COLOR_BOTH_RED ; 2 + stx A_COLOR ; 3 + ldx #COLOR_BOTH_DARKBLUE ; 2 + stx B_COLOR ; 3 + ldx #COLOR_BOTH_DARKGREEN ; 2 + stx C_COLOR ; 3 + +calc_volume: + + ; 10 14/15 24-x = 14 PLUS=none, zero=bottom, neg=all + ; 12 12/13 12 + ; 14 10/11 10 + ; 16 8/9 8 + ; 18 6/7 6 + ; 20 4/5 4 + ; 22 2/3 2 + ; 24 0/1 0 + + ; FIXME: there must be a way to make this faster + +mod_a: + pha ; 3 + sec ; 2 + eor #$ff ; negate ; 2 + adc #24 ; 24-A ; 2 + sec ; 2 + sbc A_VOLUME ; 2 + bmi mod_b ; 2nt/3 + beq mod_a_bottom ; 2nt/3 +mod_a_zero: + lda #0 ; 2 + beq done_a ; 2nt/3 +mod_a_bottom: + lda A_COLOR ; 2 + and #$f0 ; 2 +done_a: + sta A_COLOR ; 2 + +mod_b: + pla ; 4 + pha ; 3 + sec ; 2 + eor #$ff ; negate ; 2 + adc #24 ; 24-A ; 2 + sec ; 2 + sbc B_VOLUME ; 2 + bmi mod_c ; 2nt/3 + beq mod_b_bottom ; 2nt/3 +mod_b_zero: + lda #0 ; 2 + beq done_b ; 2nt/3 +mod_b_bottom: + lda B_COLOR ; 3 + and #$f0 ; 2 +done_b: + sta B_COLOR ; 3 + +mod_c: + pla ; 4 + pha ; 3 + sec ; 2 + eor #$ff ; negate ; 2 + adc #24 ; 24-A ; 2 + sec ; 2 + sbc C_VOLUME ; 2 + bmi mod_d ; 2nt/3 + beq mod_c_bottom ; 2nt/3 +mod_c_zero: + lda #0 ; 2 + beq done_c ; 2nt/3 +mod_c_bottom: + lda C_COLOR ; 3 + and #$f0 ; 2 +done_c: + sta C_COLOR ; 3 + +mod_d: + pla ; 4 + + jmp middle_color_done ; 3 + +middle_black: + ldx #COLOR_BOTH_BLACK ; 2 + stx A_COLOR ; 3 + stx B_COLOR ; 3 + stx C_COLOR ; 3 + +middle_color_done: + + ; left border + ldy #COLOR_BOTH_GREY ; 2 + sty COLOR ; 3 + + ldy #12 ; 2 + sty V2 ; 3 + ldy #12 ; 2 + + jsr hlin_double ; 6 + ; 63+1*16=79 + ; border space + lda #COLOR_BOTH_BLACK ; 2 + sta COLOR ; 3 + + ldx #1 ; 2 + jsr hlin_double_continue ; 10+1*16=27 + + ; A volume + lda A_COLOR ; 3 + sta COLOR ; 3 + + ldx #3 ; 2 + jsr hlin_double_continue ; 10+3*16=58 + + ; A space + lda #COLOR_BOTH_BLACK ; 2 + sta COLOR ; 3 + + ldx #1 ; 2 + jsr hlin_double_continue ; 6 + ; 10+1*16=27 + ; B volume + lda B_COLOR ; 3 + sta COLOR ; 3 + + ldx #3 ; 2 + jsr hlin_double_continue ; 6 + ; 10+3*16=58 + ; B space + lda #COLOR_BOTH_BLACK ; 2 + sta COLOR ; 3 + + ldx #1 ; 2 + jsr hlin_double_continue ; 6 + ; 10+1*16=27 + + ; C volume + lda C_COLOR ; 3 + sta COLOR ; 3 + + ldx #3 ; 2 + jsr hlin_double_continue ; 6 + ; 10+3*16=58 + + ; C space + lda #COLOR_BOTH_BLACK ; 2 + sta COLOR ; 3 + + ldx #1 ; 2 + jsr hlin_double_continue ; 6 + ; 10+1*16=27 + ; Right border + + lda #COLOR_BOTH_GREY ; 2 + sta COLOR ; 3 + + ldx #1 ; 2 + jsr hlin_double_continue ; 6 + ; 10+1*16=27 + + pla ; 4 + clc ; 2 + adc #2 ; 2 + cmp #28 ; 2 + beq bottom_line ; 2nt/3 + jmp middle_loop ; 3 + +bottom_line: + ; bottom line + + lda #COLOR_BOTH_GREY ; 2 + sta COLOR ; 3 + ldy #12 ; 2 + lda #26 ; 2 + sta V2 ; 3 + lda #28 ; 2 + jsr hlin_double ; 6 + ; 63+14*16=287 + + rts ; 6 + + + +; 309+ 684*10 + 313 = roughly worst case 7462 diff --git a/dya/zp.inc b/dya/zp.inc new file mode 100644 index 00000000..fff64073 --- /dev/null +++ b/dya/zp.inc @@ -0,0 +1,251 @@ +.define EQU = + +LZ4_SRC EQU $00 +LZ4_DST EQU $02 +LZ4_END EQU $04 +COUNT EQU $06 +DELTA EQU $08 + +;; Zero page monitor routines addresses + +WNDLFT EQU $20 +WNDWDTH EQU $21 +WNDTOP EQU $22 +WNDBTM EQU $23 +CH EQU $24 +CV EQU $25 +GBASL EQU $26 +GBASH EQU $27 +BASL EQU $28 +BASH EQU $29 +H2 EQU $2C +V2 EQU $2D +MASK EQU $2E +COLOR EQU $30 + ;INVFLG EQU $32 + +; dos33 zero page = 26-2f, 35-38, 3e 3f 40-4d +; overlap applesoft 67-6a,6f,70,af,b0,ca-cd,d8 + + +; DOS33: Confirmed kills $68 + +RWTSL EQU $60 +RWTSH EQU $61 +DOSBUFL EQU $62 +DOSBUFH EQU $63 +FILEML EQU $64 +FILEMH EQU $65 + ;TURNING EQU $60 + ;SCREEN_X EQU $61 ; not used? + ;SCREEN_Y EQU $62 + + + ;ANGLE EQU $63 + ;HORIZ_SCALE_I EQU $64 + ;HORIZ_SCALE_F EQU $65 + ;FACTOR_I EQU $66 + ;FACTOR_F EQU $67 + ;DX_I EQU $68 + ;DX_F EQU $69 + ;SPACEX_I EQU $6A + ;SPACEX_F EQU $6B + ;CX_I EQU $6C + ;CX_F EQU $6D + ;DY_I EQU $6E + ;DY_F EQU $6F + +REGISTER_DUMP EQU $70 +A_FINE_TONE EQU $70 +A_COARSE_TONE EQU $71 +B_FINE_TONE EQU $72 +B_COARSE_TONE EQU $73 +C_FINE_TONE EQU $74 +C_COARSE_TONE EQU $75 +NOISE EQU $76 +ENABLE EQU $77 +A_VOLUME EQU $78 +B_VOLUME EQU $79 +C_VOLUME EQU $7A +ENVELOPE_FINE EQU $7B +ENVELOPE_COARSE EQU $7C +ENVELOPE_SHAPE EQU $7D +COPY_OFFSET EQU $7E +DECODER_STATE EQU $7F + ;SPACEY_I EQU $70 + ;SPACEY_F EQU $71 + ;CY_I EQU $72 + ;CY_F EQU $73 + ;TEMP_I EQU $74 + ;TEMP_F EQU $75 + ;DISTANCE_I EQU $76 + ;DISTANCE_F EQU $77 + ;SPACEZ_I EQU $78 + ;SPACEZ_F EQU $79 + ;DRAW_SPLASH EQU $7A + ;SPEED EQU $7B + ;SPLASH_COUNT EQU $7C + ;OVER_LAND EQU $7D + ;NUM1L EQU $7E + ;NUM1H EQU $7F +CHUNKSIZE EQU $80 +LZ4_DONE EQU $81 +DECODE_ERROR EQU $82 + +A_COLOR EQU $83 +B_COLOR EQU $84 +C_COLOR EQU $85 +COPY_TIME EQU $86 +DECOMPRESS_TIME EQU $87 +TIME_TAKEN EQU $88 +SCREEN_Y EQU $89 +WHICH_FILE EQU $8A + ;NUM2L EQU $80 + ;NUM2H EQU $81 + ;RESULT EQU $82 ; 83,84,85 + ;NEGATE EQU $86 ; UNUSED? + ;LAST_SPACEX_I EQU $87 + ;LAST_SPACEY_I EQU $88 + ;LAST_MAP_COLOR EQU $89 + ;DRAW_SKY EQU $8A +COLOR_MASK EQU $8B +RASTERBARS_ON EQU $8C + ;KEY_COUNT EQU $8C + ;KEY_OFFSET EQU $8D + ;DRAW_BLUE_SKY EQU $8E +RANDOM_POINTER EQU $8F +FRAME_COUNT EQU $90 +MB_VALUE EQU $91 +;MB_CHUNK EQU $92 +MB_ADDRL EQU $91 +MB_ADDRH EQU $92 +DONE_PLAYING EQU $93 +;MB_FRAME_DIFF EQU $94 +MB_CHUNK_OFFSET 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 + ;MB_FRAME_DIFF2 EQU $9F + +; More zero-page addresses +; we try not to conflict with anything DOS, MONITOR or BASIC related + + ;COLOR1 EQU $E0 +COLOR2 EQU $E1 + ;MATCH EQU $E2 +XX EQU $E3 + ;YY EQU $E4 + ;SHIPY EQU $E4 + ;YADD EQU $E5 + ;LOOP EQU $E6 + ;MEMPTRL EQU $E7 + ;MEMPTRH EQU $E8 + ;NAMEL EQU $E9 + ;NAMEH EQU $EA + ;NAMEX EQU $EB + ;CHAR EQU $EC +DISP_PAGE EQU $ED +DRAW_PAGE EQU $EE + + ;FIRST EQU $F0 +LASTKEY EQU $F1 + ;PADDLE_STATUS EQU $F2 +XPOS EQU $F3 +YPOS EQU $F4 +TEMP EQU $FA + ;RUN EQU $FA + ;TEMP2 EQU $FB +TEMPY EQU $FB +INL EQU $FC +INH EQU $FD +OUTL EQU $FE +OUTH EQU $FF + + + +KEYPRESS EQU $C000 +KEYRESET EQU $C010 + +;; SOFT SWITCHES +CLR80COL EQU $C000 ; PAGE0/PAGE1 normal +SET80COL EQU $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead +EIGHTYCOL EQU $C00D +SPEAKER EQU $C030 +SET_GR EQU $C050 +SET_TEXT EQU $C051 +FULLGR EQU $C052 +TEXTGR EQU $C053 +PAGE0 EQU $C054 +PAGE1 EQU $C055 +LORES EQU $C056 ; Enable LORES graphics +HIRES EQU $C057 ; Enable HIRES graphics +AN3 EQU $C05E ; Annunciator 3 + +PADDLE_BUTTON0 EQU $C061 +PADDL0 EQU $C064 +PTRIG EQU $C070 + +;; BASIC ROUTINES + +NORMAL EQU $F273 + +;; MONITOR ROUTINES + +HLINE EQU $F819 ;; HLINE Y,$2C at A +VLINE EQU $F828 ;; VLINE A,$2D at Y +CLRSCR EQU $F832 ;; Clear low-res screen +CLRTOP EQU $F836 ;; clear only top of low-res screen +SETCOL EQU $F864 ;; COLOR=A +TEXT EQU $FB36 +TABV EQU $FB5B ;; VTAB to A +BASCALC EQU $FBC1 ;; +VTAB EQU $FC22 ;; VTAB to CV +HOME EQU $FC58 ;; Clear the text screen +WAIT EQU $FCA8 ;; delay 1/2(26+27A+5A^2) us +SETINV EQU $FE80 ;; INVERSE +SETNORM EQU $FE84 ;; NORMAL +COUT EQU $FDED ;; output A to screen +COUT1 EQU $FDF0 ;; output A to screen + + + + + + +COLOR_BLACK EQU 0 +COLOR_RED EQU 1 +COLOR_DARKBLUE EQU 2 +COLOR_PURPLE EQU 3 +COLOR_DARKGREEN EQU 4 +COLOR_GREY EQU 5 +COLOR_MEDIUMBLUE EQU 6 +COLOR_LIGHTBLUE EQU 7 +COLOR_BROWN EQU 8 +COLOR_ORANGE EQU 9 +COLOR_GREY2 EQU 10 +COLOR_PINK EQU 11 +COLOR_LIGHTGREEN EQU 12 +COLOR_YELLOW EQU 13 +COLOR_AQUA EQU 14 +COLOR_WHITE EQU 15 + +COLOR_BOTH_BLACK EQU $00 +COLOR_BOTH_RED EQU $11 +COLOR_BOTH_DARKBLUE EQU $22 +COLOR_BOTH_DARKGREEN EQU $44 +COLOR_BOTH_GREY EQU $55 +COLOR_BOTH_MEDIUMBLUE EQU $66 +COLOR_BOTH_LIGHTBLUE EQU $77 +COLOR_BOTH_BROWN EQU $88 +COLOR_BOTH_ORANGE EQU $99 +COLOR_BOTH_PINK EQU $BB +COLOR_BOTH_LIGHTGREEN EQU $CC +COLOR_BOTH_YELLOW EQU $DD +COLOR_BOTH_AQUA EQU $EE +COLOR_BOTH_WHITE EQU $FF + +AUX_BOTH_MEDIUMBLUE EQU $33 ; 0011 0011 +AUX_BOTH_GREY EQU $AA ; 1010 1010