From a4699be60418d8765f9f24d31f96434671bc527b Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 6 May 2019 20:31:10 -0400 Subject: [PATCH] pt3: compiles at least --- pt3_player/EA.PT3 | Bin 0 -> 4024 bytes pt3_player/Makefile | 6 +- pt3_player/interrupt_handler.s | 376 +++++++++++++++++++++++++++++++++ 3 files changed, 379 insertions(+), 3 deletions(-) create mode 100644 pt3_player/EA.PT3 create mode 100644 pt3_player/interrupt_handler.s diff --git a/pt3_player/EA.PT3 b/pt3_player/EA.PT3 new file mode 100644 index 0000000000000000000000000000000000000000..7874415b3b7a2d1f12ab739ff68029a261082df3 GIT binary patch literal 4024 zcmcInU2GIp6uvV%JIt2dPK)KoP{=fp@MEM!{-TgTEsfd&DiDbT6(k}Aq^6VvgCyhT zX2x;0El<8+qKPpvzTkb}Nu%;3+qz3&4=GUe5lKM3Qm@#Bo?t@#@Jh# z{h3plZ!$k;e#_j*nAMA_+pA%&_&ZkpOZ6^uze$b<%|qr9w2qm+dEETiJYjxjegXX} zQ%|MMY13!Tezx`b_DwHu-L~@SHEZWKEStamwVk^cEN*&o&%Og4orjMcWusS>Kb3lQ zp8Q*&ZdA9Z$JEc&UsWT~oj8#g0NUi~QA1NtY@eoER4(tcCgSEtGUXqx=LMSHJ)3+(~DE<^Su z8L~f@8LA1yx-K?c6$ph7gcrhMSO|X#`@_C4AD$0?49|sU!!zOOP%Qm{4Lt+rFPT^u zvLUS~RG+(?$hEocIy~!T9ZAyexeiOgRc9g*4r%#H?m}@VM$I8|&iC9&qUxbOG_6k< zu7{|e&|IN96W|Ih99D(O&j9^7RB;~F^o2|)5fZ0_eDWM6D2ktViahTZ-8_eMi@ucO zI@xX5dESQP@Ux4K)SY4$x|h#Fda#jn?$UkO%j0`8AB}O@u-carHC$hBXInTEMmSVQ z)9$&d&~wT{c6}6@&@l_HFdWpI<&G+j)dx zS87-(jYfAAlNh|B8~8;pP;<&mY-rp}X$~NoC+hBR0j^Izb>l0>{?cd}+Y8yYfb#;E ztR1WD7Qz73M!kiwJ!+%1A>eHV4qkGGhXQ*b`=m1>NxwqKZc_AY!49(7LRPXn+>r)- zNCEfuAZk?xVk13y+oj-9-2Wu_1=QUiUI4XSKq>v<15eLJIX&Q$OwYz>E@i#&!1Ty% z;Lnu06NZcV_{5IiCOEq|=va>;$M?v^ zDIW87@U~IKoylSpuyb4wt}>UtXBxj(Hu#BI{Dy{Si<~Q3pnE`$wwRCfC^kmtp$yz^ zbhXGA(p?*qZk~#FQku)-K7K&)Xu3u_(8Yr$kPP4d0IwcgYHr{`y13lX5i`6P(1Z1k zde}AjCd3B9LnmT*#RR03qzj$%5~DN@VvqsvER3h*P>=$7iIoGuqog7LK&6XVvL2bd zCn!n64gfKm3_#i)nug0BFH0P9x$e;>gHhuS%m%Jm`9Q{WF;JeKH*!dBvLUo3%3sus zDXbU&yiBvfiC9le-H=4Nn0!d0k7Dv5i9U?Ug(OngamKV{gUJ-7m#LrxNTYFDa;dc1 zN<%eMYpZRQtO-q-gJCg6e#&e_iZdy*qPC_ZP872TF?*QyK{rb(-AreOtfBYzDC@li zB8f4*DoB%3OGg%1h&(SWVMbYE57@S)$gowa4Z%Hk}A) zOEj~du@XIw_8d?H@GqFk*b|_oRg5hItpcqEeGjr4{;%k35nVwk70HH^N?xZyAq7h3NVDK$Dk4X1_08L=U3IG5A literal 0 HcmV?d00001 diff --git a/pt3_player/Makefile b/pt3_player/Makefile index d8bc8a13..f1753d16 100644 --- a/pt3_player/Makefile +++ b/pt3_player/Makefile @@ -10,9 +10,9 @@ $(DOS33): pt3_player.dsk: PT3_PLAYER HELLO cp empty.dsk pt3_player.dsk - $(DOS33) -y chiptune_player.dsk SAVE A HELLO - $(DOS33) -y chiptune_player.dsk BSAVE -a 0x0800 PT3_PLAYER -# $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/CAMOUFLAGE.KRW + $(DOS33) -y pt3_player.dsk SAVE A HELLO + $(DOS33) -y pt3_player.dsk BSAVE -a 0x0800 PT3_PLAYER + $(DOS33) -y pt3_player.dsk BSAVE -a 0x2000 EA.PT3 # $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/CHRISTMAS.KRW # $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/CRMOROS.KRW # $(DOS33) -y chiptune_player.dsk BSAVE -a 0x1c00 ./krw/DEATH2.KRW diff --git a/pt3_player/interrupt_handler.s b/pt3_player/interrupt_handler.s new file mode 100644 index 00000000..05240ae9 --- /dev/null +++ b/pt3_player/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