From 981c3235d515a9dbeef8ec55e4c9f702af50eb00 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 17 Jan 2024 20:11:31 -0500 Subject: [PATCH] pt3_lib: update to version 0.5 --- demos/second/pt3_lib_mockingboard_setup.s | 11 +++- music/pt3_lib/CHANGES | 14 +++++ music/pt3_lib/README.pt3_lib | 44 +++++++++++--- music/pt3_lib/hello.bas | 2 +- music/pt3_lib/interrupt_handler.s | 18 ++++++ music/pt3_lib/pt3_lib_detect_model.s | 67 ++++++++++++++++----- music/pt3_lib/pt3_lib_gs_interrupt.s | 15 +++++ music/pt3_lib/pt3_lib_mockingboard_detect.s | 24 +++++--- music/pt3_lib/pt3_lib_mockingboard_setup.s | 58 ++++++++++++++++-- music/pt3_lib/pt3_test.s | 5 ++ 10 files changed, 216 insertions(+), 42 deletions(-) create mode 100644 music/pt3_lib/pt3_lib_gs_interrupt.s diff --git a/demos/second/pt3_lib_mockingboard_setup.s b/demos/second/pt3_lib_mockingboard_setup.s index 7f925ad1..1289c1df 100644 --- a/demos/second/pt3_lib_mockingboard_setup.s +++ b/demos/second/pt3_lib_mockingboard_setup.s @@ -203,9 +203,14 @@ clear_ay_end: mockingboard_setup_interrupt: - ; for this game with things in language card including - ; irq handler, always force IIc mode (where RAM swapped in - ; and we put the irq handler address directly up at $FFFE) + ; for this demo we assume we are using the language card RAM + ; so we force things to be in "IIc" mode which means + ; we have ROM swapped out and can directly point the + ; interrupt vector at $FFFE to here + + ; we also nop out the load from $45 in the interrupt handler + ; because we aren't running the ROM handler that saves A + ; to there on IIe/II+ systems lda # http://www.deater.net/weave/vmwprod/pt3_lib/ - Last Update: 15 May 2023 + Last Update: 17 January 2024 Plays Vortex Tracker II .pt3 files on the Apple II @@ -73,6 +73,14 @@ To get a pt3 file playing: + If you want the music to Loop then set the LOOP value to 1. +Notes on having player code in Language Card +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +On IIgs interrupts reset language card settings. + +You'll have to call the gs_interrupt.s code or similar +to switch the language card back on before calling the irq handler. + + Notes on Using on a IIc ~~~~~~~~~~~~~~~~~~~~~~~ I usually test this code mostly on a II+ and IIe. @@ -86,18 +94,23 @@ which does increase the size a bit. Things that are different on IIc: + For the board to get detected you have to touch the slot4 - registers for some reason + registers, this will disable the mouse firmware + which normally lives in slot4 + + IRQ support is much more complex on the IIc. We support things by switching out the default ROM IRQ handler with language-card RAM and place our own handler where the stock handler would be. - This does mean if you use ROM routines they will break, + This does mean if you use ROM routines they will break. + + If you need these, enable PT3_IIC_COPY_ROM as well so the code also copies the $D000-$F000 ROM into the language card too. If your code doesn't use ROM routines you can skip this. The ROM copy hack uses $400 (text page 1) as a temporary buffer for the copy, feel free to use something - else if that's a problem. + else if that's a problem. (It might be a bad as it + over-writes the screen holes) Finally we patch out loading the A register from $45 at the end of the IRQ handler. @@ -107,8 +120,16 @@ Things that are different on IIc: Notes on Using on a IIgs ~~~~~~~~~~~~~~~~~~~~~~~~ -I have not tested this on a IIgs with Mockingboard, I'm guessing it probably -doesn't work. +The code in theory works on a IIgs though it's mostly tested on +MAME. For some reason detection doesn't work (I feel like someone +told me why but I forget) but if you force it to play in slot4 it +will work if you configure a mockingboard in that slot. + +Note that if your code uses text/gr PAGE2 and you enable the workaround +on ROM0 machines it can slow things down a lot. + +Also note the previous commentary on how to have the music player +in the language card area on a IIgs. Cycle-counted version (not finished): @@ -145,3 +166,12 @@ can be generated if you're willing to sacrifice 128+ zero page locations. +It Doesn't Work! +~~~~~~~~~~~~~~~~ + +There are a lot of places things can go wrong. + +One, if you're using the default fast patching code and by bad luck +the value $C4 appears smewhere and you aren't in slot4 this will patch +the value with disastrous results. I'm often lazy and just add nops +(it's usually a branch causing the problem) until it is fixed. diff --git a/music/pt3_lib/hello.bas b/music/pt3_lib/hello.bas index 8120e6b4..830fd1d9 100644 --- a/music/pt3_lib/hello.bas +++ b/music/pt3_lib/hello.bas @@ -1,2 +1,2 @@ - 10 PRINT "PT3 LIB TEST V0.4" + 10 PRINT "PT3 LIB TEST V0.5" 100 PRINT CHR$ (4)"BRUN PT3_TEST" diff --git a/music/pt3_lib/interrupt_handler.s b/music/pt3_lib/interrupt_handler.s index 2a766283..752be19d 100644 --- a/music/pt3_lib/interrupt_handler.s +++ b/music/pt3_lib/interrupt_handler.s @@ -67,3 +67,21 @@ interrupt_smc: ; typical ; ???? cycles + ;============================= + ; Disable Interrupt + ;============================= + ; disables all the 6522 timer interrupts + +mockingboard_disable_interrupt: + + sei ; disable interrupts just in case + + lda #$40 ; Continuous interrupts, don't touch PB7 +disable_irq_smc1: + sta MOCK_6522_ACR ; ACR register + lda #$7F ; clear all interrupt flags +disable_irq_smc2: + sta MOCK_6522_IER ; IER register (interrupt enable) + + rts + diff --git a/music/pt3_lib/pt3_lib_detect_model.s b/music/pt3_lib/pt3_lib_detect_model.s index 31c1b8dc..42d59e50 100644 --- a/music/pt3_lib/pt3_lib_detect_model.s +++ b/music/pt3_lib/pt3_lib_detect_model.s @@ -1,33 +1,60 @@ ;=========================== ; Check Apple II model ;=========================== - ; this is mostly for IIc support - ; as it does interrupts differently + ; this is mostly for IIc and IIgs support + ; as they do interrupts differently - ; ' ' ($20) = Apple II - ; '+' ($2B) = Apple II+ - ; 'E' ($45) = Apple IIe - ; 'C' ($43) = Apple IIc - ; 'G' ($47) = Apple IIgs + ; some of this info from the document: + ; Apple II Family Identification Routines 2.2 + ; + ; note the more obscure are not well tested + ; Returns one of the following in A + + ; ' ' = Apple II + ; '+' = Apple II+ + ; 'e' = Apple IIe + ; 'c' = Apple IIc + ; 'g' = Apple IIgs + ; 'm' = mac L/C with board + ; 'j' = jplus + ; '3' = Apple III detect_appleii_model: lda #' ' ldx $FBB3 + ; II is $38 ; J-plus is $C9 ; II+ is $EA (so is III) ; IIe and newer is $06 - cpx #$38 + cpx #$38 ; ii beq done_apple_detect - lda #'+' + + ; ii+ is EA FB1E=AD + ; iii is EA FB1E=8A 00 + cpx #$EA + bne not_ii_iii +ii_or_iii: + + lda #'+' ; ii+/iii + + ldx $FB1E + cpx #$AD + beq done_apple_detect ; ii+ + + lda #'3' + bne done_apple_detect ; bra iii + +not_ii_iii: + lda #'j' ; jplus + cpx #$C9 beq done_apple_detect - ; TODO: check for J-plus or III? cpx #$06 bne done_apple_detect @@ -44,19 +71,27 @@ apple_iie_or_newer: beq apple_iic - lda #'E' + lda #'e' cpx #$EA beq done_apple_detect - cpx #$E0 - beq done_apple_detect +; cpx #$E0 +; beq done_apple_detect - ; assume GS? + ; should do something if not $E0 - lda #'G' + ; GS and IIe enhanced are the same, need to check + + sec ; set carry + jsr $FE1F + bcs done_apple_detect ;If carry then IIe enhanced + + ; get here we're a IIgs? + + lda #'g' bne done_apple_detect apple_iic: - lda #'C' + lda #'c' done_apple_detect: sta APPLEII_MODEL diff --git a/music/pt3_lib/pt3_lib_gs_interrupt.s b/music/pt3_lib/pt3_lib_gs_interrupt.s new file mode 100644 index 00000000..26f6433e --- /dev/null +++ b/music/pt3_lib/pt3_lib_gs_interrupt.s @@ -0,0 +1,15 @@ + ; On Apple IIgs the interrupt handler clears the + ; Language Card settings + + ; If you have your player in the Language card area ($D000-$FFFF) + ; You will need to have this code elsewhere, and jump through + ; this to the actual handler + +gs_interrupt_handler: + ; swap back in language card + + ; read/write RAM, use $d000 bank1 + bit $C083 + bit $C083 + + jmp interrupt_handler diff --git a/music/pt3_lib/pt3_lib_mockingboard_detect.s b/music/pt3_lib/pt3_lib_mockingboard_detect.s index 8b0857c5..7aa3ca29 100644 --- a/music/pt3_lib/pt3_lib_mockingboard_detect.s +++ b/music/pt3_lib/pt3_lib_mockingboard_detect.s @@ -28,28 +28,34 @@ ; if card was found, X = #$Cn where n is the slot number of the card ; C clear if no Mockingboard found ; other flags clobbered -; zp $65-$67 clobbered ; A/Y clobbered ;------------------------------------------------------------------------------ mockingboard_detect: - ; activate IIc mockingboard? - ; this might only be necessary to allow detection - ; I get the impression the Mockingboard 4c activates - ; when you access any of the 6522 ports in Slot 4 + ; activate Mockingboard IIc + ; + the Mockingboard has to take over Slot#4 (IIc has no slots) + ; in theory any write to the firmware area in $C400 will + ; activate it, but that might not be fast enough when detecting + ; so writing $FF to $C403/$C404 is official way to enable + ; + Note this disables permanently the mouse firmware in $C400 + ; so "normal" interrupts are broken :( The hack to fix things + ; is to switch in RAM for $F000 and just replace the IRQ + ; vectors at $FFFE/$FFFF instead of $3FE/$3FF but that makes + ; it difficult if you actually wanted to use any + ; Applesoft/Monitor ROM routines .ifdef PT3_ENABLE_APPLE_IIC lda APPLEII_MODEL - cmp #'C' + cmp #'c' bne not_iic lda #$ff - ; don't bother patching these, IIc mockingboard always slot 4? + ; don't bother patching these, IIc mockingboard always slot 4 - sta MOCK_6522_DDRA1 - sta MOCK_6522_T1CL + sta MOCK_6522_DDRA1 ; $C403 + sta MOCK_6522_T1CL ; $C404 .endif not_iic: diff --git a/music/pt3_lib/pt3_lib_mockingboard_setup.s b/music/pt3_lib/pt3_lib_mockingboard_setup.s index 2f00bc4a..486b5d42 100644 --- a/music/pt3_lib/pt3_lib_mockingboard_setup.s +++ b/music/pt3_lib/pt3_lib_mockingboard_setup.s @@ -1,8 +1,8 @@ ; Mockingboad programming: ; + Has two 6522 I/O chips connected to two AY-3-8910 chips ; + Optionally has some speech chips controlled via the outport on the AY -; + Often in slot 4 -; TODO: how to auto-detect? +; + Often in slot 4. We autodetect and patch + ; References used: ; http://macgui.com/usenet/?group=2&id=8366 ; 6522 Data Sheet @@ -162,6 +162,36 @@ clear_ay_left_loop: ; -1 rts ; 6 + ;======================================= + ; mute AY -- just turn off all 3 channels + ; should silence the card + ; + ;======================================= +mute_ay_both: + ldx #7 ; + lda #$FF ; + sta MB_VALUE ; +mute_ay_left_loop: + jsr write_ay_both ; + + rts + + ;======================================= + ; unmute AY + ; restore to value we had before muting + ;======================================= +unmute_ay_both: + ldx #7 ; + lda ENABLE ; + sta MB_VALUE ; +unmute_ay_left_loop: + jsr write_ay_both ; + + rts ; + + + + clear_ay_end: ;.assert >clear_ay_both = >clear_ay_end, error, "clear_ay_both crosses page" @@ -172,17 +202,28 @@ mockingboard_setup_interrupt: .ifdef PT3_ENABLE_APPLE_IIC lda APPLEII_MODEL - cmp #'C' + cmp #'c' bne done_iic_hack - ; bypass the firmware interrupt handler - ; should we do this on IIe too? probably faster + ;================================================== + ; On IIc we use a hack and swap RAM into the langauge + ; card and replace the interrupt vectors + ; (should we do this on IIe too? probably faster) + ; This does mean you can't use any ROM routines when + ; playing music + + ;==================================================== + ; If we need the ROM routines we need to copy them ; first we have to copy the ROM to the language card + sei ; disable interrupts + lda $c08B ; read/write RAM1 + lda $c08B ; +.ifdef PT3_ENABLE_IIC_COPY_ROM copy_rom_loop: lda $c089 ; read ROM, write RAM1 @@ -199,6 +240,9 @@ read_rom_loop: lda $c08B ; read/write RAM1 lda $c08B ; + ; should probably use $800 instead of $400 + ; as we over-write screen holes here + write_rom_loop: lda $400,Y sta $D000,Y @@ -208,13 +252,15 @@ write_rom_loop: inc read_rom_loop+2 inc write_rom_loop+5 bne copy_rom_loop +.endif lda #interrupt_handler sta $ffff - lda #$EA ; nop out the "lda $45" in the irq handler + lda #$EA ; nop out the "lda $45" in the irq handler + ; as it's not needed on IIc (and maybe others?) sta interrupt_smc sta interrupt_smc+1 .endif diff --git a/music/pt3_lib/pt3_test.s b/music/pt3_lib/pt3_test.s index 79011e33..e3468c89 100644 --- a/music/pt3_lib/pt3_test.s +++ b/music/pt3_lib/pt3_test.s @@ -25,6 +25,11 @@ PT3_LOC = song PT3_ENABLE_APPLE_IIC = 1 +; Enable ROM copying on IIc + +;PT3_ENABLE_IIC_COPY_ROM = 1 + + ; The Vortex Tracker by default generates Atari-ST style pt3 files ; which assume there is a 1.77MHz clock frequency driving ; the AY-3-8910. Apple II Mockingboards run at 1MHz, so unless