pt3_lib: update to version 0.5
This commit is contained in:
parent
cb0546ede7
commit
981c3235d5
|
@ -203,9 +203,14 @@ clear_ay_end:
|
||||||
mockingboard_setup_interrupt:
|
mockingboard_setup_interrupt:
|
||||||
|
|
||||||
|
|
||||||
; for this game with things in language card including
|
; for this demo we assume we are using the language card RAM
|
||||||
; irq handler, always force IIc mode (where RAM swapped in
|
; so we force things to be in "IIc" mode which means
|
||||||
; and we put the irq handler address directly up at $FFFE)
|
; 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 #<interrupt_handler
|
lda #<interrupt_handler
|
||||||
sta $fffe
|
sta $fffe
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
V0.5 (17 January 2024)
|
||||||
|
+ Fixes problem when pt3 file has more than 42 patterns.
|
||||||
|
Apparently this is a common failure mode, the Demosplash people also
|
||||||
|
hit it on their 6809 player but for different reasons.
|
||||||
|
+ Changes the value return by processor detect to lowercase.
|
||||||
|
(so Apple IIe returns 'e' instead of 'E')
|
||||||
|
Yes, I shouldn't make a change like this but it simplifies a lot
|
||||||
|
of my use cases and it was a pain carrying around the diff
|
||||||
|
+ add mute/unmute functions. Just disables/re-enables the channels
|
||||||
|
This is less destructive than using the clear function which
|
||||||
|
zeros all registers and is harder/slower to recover from
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
V0.4 (15 May 2023)
|
V0.4 (15 May 2023)
|
||||||
+ Changed so that you can disable the 1.77MHz frequency adjustment at compile
|
+ Changed so that you can disable the 1.77MHz frequency adjustment at compile
|
||||||
time. This saves a few hundred cycles and also some binary size.
|
time. This saves a few hundred cycles and also some binary size.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
The PT3_player Library version 0.4
|
The PT3_player Library version 0.5
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
by Vince "Deater" Weaver <vince@deater.net>
|
by Vince "Deater" Weaver <vince@deater.net>
|
||||||
http://www.deater.net/weave/vmwprod/pt3_lib/
|
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
|
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.
|
+ 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
|
Notes on Using on a IIc
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
I usually test this code mostly on a II+ and IIe.
|
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:
|
Things that are different on IIc:
|
||||||
+ For the board to get detected you have to touch the slot4
|
+ 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
|
+ IRQ support is much more complex on the IIc. We support things
|
||||||
by switching out the default ROM IRQ handler with
|
by switching out the default ROM IRQ handler with
|
||||||
language-card RAM and place our own handler where the
|
language-card RAM and place our own handler where the
|
||||||
stock handler would be.
|
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
|
so the code also copies the $D000-$F000 ROM into the
|
||||||
language card too. If your code doesn't use ROM routines
|
language card too. If your code doesn't use ROM routines
|
||||||
you can skip this. The ROM copy hack uses $400 (text page 1)
|
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
|
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
|
Finally we patch out loading the A register from $45 at
|
||||||
the end of the IRQ handler.
|
the end of the IRQ handler.
|
||||||
|
@ -107,8 +120,16 @@ Things that are different on IIc:
|
||||||
|
|
||||||
Notes on Using on a IIgs
|
Notes on Using on a IIgs
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
I have not tested this on a IIgs with Mockingboard, I'm guessing it probably
|
The code in theory works on a IIgs though it's mostly tested on
|
||||||
doesn't work.
|
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):
|
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.
|
||||||
|
|
|
@ -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"
|
100 PRINT CHR$ (4)"BRUN PT3_TEST"
|
||||||
|
|
|
@ -67,3 +67,21 @@ interrupt_smc:
|
||||||
; typical
|
; typical
|
||||||
; ???? cycles
|
; ???? 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
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,60 @@
|
||||||
;===========================
|
;===========================
|
||||||
; Check Apple II model
|
; Check Apple II model
|
||||||
;===========================
|
;===========================
|
||||||
; this is mostly for IIc support
|
; this is mostly for IIc and IIgs support
|
||||||
; as it does interrupts differently
|
; as they do interrupts differently
|
||||||
|
|
||||||
; ' ' ($20) = Apple II
|
; some of this info from the document:
|
||||||
; '+' ($2B) = Apple II+
|
; Apple II Family Identification Routines 2.2
|
||||||
; 'E' ($45) = Apple IIe
|
;
|
||||||
; 'C' ($43) = Apple IIc
|
; note the more obscure are not well tested
|
||||||
; 'G' ($47) = Apple IIgs
|
|
||||||
|
|
||||||
|
; 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:
|
detect_appleii_model:
|
||||||
lda #' '
|
lda #' '
|
||||||
|
|
||||||
ldx $FBB3
|
ldx $FBB3
|
||||||
|
|
||||||
; II is $38
|
; II is $38
|
||||||
; J-plus is $C9
|
; J-plus is $C9
|
||||||
; II+ is $EA (so is III)
|
; II+ is $EA (so is III)
|
||||||
; IIe and newer is $06
|
; IIe and newer is $06
|
||||||
|
|
||||||
cpx #$38
|
cpx #$38 ; ii
|
||||||
beq done_apple_detect
|
beq done_apple_detect
|
||||||
|
|
||||||
lda #'+'
|
|
||||||
|
; ii+ is EA FB1E=AD
|
||||||
|
; iii is EA FB1E=8A 00
|
||||||
|
|
||||||
cpx #$EA
|
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
|
beq done_apple_detect
|
||||||
|
|
||||||
; TODO: check for J-plus or III?
|
|
||||||
|
|
||||||
cpx #$06
|
cpx #$06
|
||||||
bne done_apple_detect
|
bne done_apple_detect
|
||||||
|
@ -44,19 +71,27 @@ apple_iie_or_newer:
|
||||||
|
|
||||||
beq apple_iic
|
beq apple_iic
|
||||||
|
|
||||||
lda #'E'
|
lda #'e'
|
||||||
cpx #$EA
|
cpx #$EA
|
||||||
beq done_apple_detect
|
beq done_apple_detect
|
||||||
cpx #$E0
|
; cpx #$E0
|
||||||
beq done_apple_detect
|
; 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
|
bne done_apple_detect
|
||||||
|
|
||||||
apple_iic:
|
apple_iic:
|
||||||
lda #'C'
|
lda #'c'
|
||||||
|
|
||||||
done_apple_detect:
|
done_apple_detect:
|
||||||
sta APPLEII_MODEL
|
sta APPLEII_MODEL
|
||||||
|
|
|
@ -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
|
|
@ -28,28 +28,34 @@
|
||||||
; if card was found, X = #$Cn where n is the slot number of the card
|
; if card was found, X = #$Cn where n is the slot number of the card
|
||||||
; C clear if no Mockingboard found
|
; C clear if no Mockingboard found
|
||||||
; other flags clobbered
|
; other flags clobbered
|
||||||
; zp $65-$67 clobbered
|
|
||||||
; A/Y clobbered
|
; A/Y clobbered
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
mockingboard_detect:
|
mockingboard_detect:
|
||||||
|
|
||||||
; activate IIc mockingboard?
|
; activate Mockingboard IIc
|
||||||
; this might only be necessary to allow detection
|
; + the Mockingboard has to take over Slot#4 (IIc has no slots)
|
||||||
; I get the impression the Mockingboard 4c activates
|
; in theory any write to the firmware area in $C400 will
|
||||||
; when you access any of the 6522 ports in Slot 4
|
; 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
|
.ifdef PT3_ENABLE_APPLE_IIC
|
||||||
lda APPLEII_MODEL
|
lda APPLEII_MODEL
|
||||||
cmp #'C'
|
cmp #'c'
|
||||||
bne not_iic
|
bne not_iic
|
||||||
|
|
||||||
lda #$ff
|
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_DDRA1 ; $C403
|
||||||
sta MOCK_6522_T1CL
|
sta MOCK_6522_T1CL ; $C404
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
not_iic:
|
not_iic:
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
; Mockingboad programming:
|
; Mockingboad programming:
|
||||||
; + Has two 6522 I/O chips connected to two AY-3-8910 chips
|
; + 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
|
; + Optionally has some speech chips controlled via the outport on the AY
|
||||||
; + Often in slot 4
|
; + Often in slot 4. We autodetect and patch
|
||||||
; TODO: how to auto-detect?
|
|
||||||
; References used:
|
; References used:
|
||||||
; http://macgui.com/usenet/?group=2&id=8366
|
; http://macgui.com/usenet/?group=2&id=8366
|
||||||
; 6522 Data Sheet
|
; 6522 Data Sheet
|
||||||
|
@ -162,6 +162,36 @@ clear_ay_left_loop:
|
||||||
; -1
|
; -1
|
||||||
rts ; 6
|
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:
|
clear_ay_end:
|
||||||
;.assert >clear_ay_both = >clear_ay_end, error, "clear_ay_both crosses page"
|
;.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
|
.ifdef PT3_ENABLE_APPLE_IIC
|
||||||
lda APPLEII_MODEL
|
lda APPLEII_MODEL
|
||||||
cmp #'C'
|
cmp #'c'
|
||||||
bne done_iic_hack
|
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
|
; first we have to copy the ROM to the language card
|
||||||
|
|
||||||
|
|
||||||
sei ; disable interrupts
|
sei ; disable interrupts
|
||||||
|
|
||||||
|
lda $c08B ; read/write RAM1
|
||||||
|
lda $c08B ;
|
||||||
|
|
||||||
|
.ifdef PT3_ENABLE_IIC_COPY_ROM
|
||||||
|
|
||||||
copy_rom_loop:
|
copy_rom_loop:
|
||||||
lda $c089 ; read ROM, write RAM1
|
lda $c089 ; read ROM, write RAM1
|
||||||
|
@ -199,6 +240,9 @@ read_rom_loop:
|
||||||
lda $c08B ; read/write RAM1
|
lda $c08B ; read/write RAM1
|
||||||
lda $c08B ;
|
lda $c08B ;
|
||||||
|
|
||||||
|
; should probably use $800 instead of $400
|
||||||
|
; as we over-write screen holes here
|
||||||
|
|
||||||
write_rom_loop:
|
write_rom_loop:
|
||||||
lda $400,Y
|
lda $400,Y
|
||||||
sta $D000,Y
|
sta $D000,Y
|
||||||
|
@ -208,13 +252,15 @@ write_rom_loop:
|
||||||
inc read_rom_loop+2
|
inc read_rom_loop+2
|
||||||
inc write_rom_loop+5
|
inc write_rom_loop+5
|
||||||
bne copy_rom_loop
|
bne copy_rom_loop
|
||||||
|
.endif
|
||||||
|
|
||||||
lda #<interrupt_handler
|
lda #<interrupt_handler
|
||||||
sta $fffe
|
sta $fffe
|
||||||
lda #>interrupt_handler
|
lda #>interrupt_handler
|
||||||
sta $ffff
|
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
|
||||||
sta interrupt_smc+1
|
sta interrupt_smc+1
|
||||||
.endif
|
.endif
|
||||||
|
|
|
@ -25,6 +25,11 @@ PT3_LOC = song
|
||||||
|
|
||||||
PT3_ENABLE_APPLE_IIC = 1
|
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
|
; The Vortex Tracker by default generates Atari-ST style pt3 files
|
||||||
; which assume there is a 1.77MHz clock frequency driving
|
; which assume there is a 1.77MHz clock frequency driving
|
||||||
; the AY-3-8910. Apple II Mockingboards run at 1MHz, so unless
|
; the AY-3-8910. Apple II Mockingboards run at 1MHz, so unless
|
||||||
|
|
Loading…
Reference in New Issue