pt3_lib: add Apple IIc support

This commit is contained in:
Vince Weaver 2021-05-30 01:49:41 -04:00
parent 9873a1da0e
commit e3f4822d77
8 changed files with 139 additions and 37 deletions

View File

@ -3,6 +3,7 @@ include ../../Makefile.inc
DOS33 = ../../utils/dos33fs-utils/dos33
PNG2GR = ../../utils/gr-utils/png2gr
TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft
EMPTY_DISK = ../../empty_disk
all: pt3_lib.dsk
@ -10,7 +11,7 @@ $(DOS33):
cd ../../utils/dos33fs-utils && make
pt3_lib.dsk: PT3_TEST HELLO
cp empty.dsk pt3_lib.dsk
cp $(EMPTY_DISK)/empty.dsk pt3_lib.dsk
$(DOS33) -y pt3_lib.dsk SAVE A HELLO
$(DOS33) -y pt3_lib.dsk BSAVE -a 0x1000 PT3_TEST
@ -23,6 +24,7 @@ PT3_TEST: pt3_test.o
ld65 -o PT3_TEST pt3_test.o -C ../../linker_scripts/apple2_1000.inc
pt3_test.o: pt3_test.s \
pt3_lib_detect_model.s \
pt3_lib_init.s pt3_lib_core.s pt3_lib_irq_handler.s \
pt3_lib_mockingboard_detect.s pt3_lib_mockingboard_setup.s \
interrupt_handler.s zp.inc

View File

@ -1,10 +1,10 @@
The PT3_player Library version 0.2
The PT3_player Library version 0.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
by Vince "Deater" Weaver <vince@deater.net>
http://www.deater.net/weave/vmwprod/pt3_lib/
Last Update: 28 December 2019
Last Update: 30 May 2021
Plays Vortex Tracker II .pt3 files on the Apple II
@ -73,8 +73,46 @@ To get a pt3 file playing:
+ If you want the music to Loop then set the LOOP value to 1.
Using the Code (cycle-counted):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Notes on Using on a IIc
~~~~~~~~~~~~~~~~~~~~~~~
I usually test this code mostly on a II+ and IIe.
Version 0.3 adds support for the IIc as well (having Mockingboards in a
IIc was rare due to the lack of expansion port, but you can get mockingboard
compatible cards that plug into the CPU socket)
This does involve adding some Apple II model detection code to the pt3 player
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
+ 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,
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.
Finally we patch out loading the A register from $45 at
the end of the IRQ handler.
Older Apple IIs needed to do this, but on a IIc this
will break things.
Notes on Using on a IIgs
~~~~~~~~~~~~~~~~~~~~~~~~
I have not tested this on a IIgs with Mockingboard, I'm guessing it probably
doesn't work.
Cycle-counted version (not finished):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I started work on a cycle-counted (deterministic cycle count) pt3
decoder, but it turned out to be large and complex enough to not be
@ -100,3 +138,4 @@ The player also uses 26 zero-page locations. More compact/faster code
can be generated if you're willing to sacrifice 128+ zero page locations.

Binary file not shown.

View File

@ -1,2 +1,2 @@
10 PRINT "PT3 LIB TEST V0.2"
10 PRINT "PT3 LIB TEST V0.3"
100 PRINT CHR$ (4)"BRUN PT3_TEST"

View File

@ -33,6 +33,24 @@
;------------------------------------------------------------------------------
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
lda APPLEII_MODEL
cmp #'C'
bne not_iic
lda #$ff
; don't bother patching these, IIc mockingboard always slot 4?
sta MOCK_6522_DDRA1
sta MOCK_6522_T1CL
not_iic:
lda #$00
sta MB_ADDR_L
ldx #$C7 ; start at slot #7

View File

@ -170,47 +170,54 @@ clear_ay_end:
;=============================
mockingboard_setup_interrupt:
;===========================
; Check for Apple IIc
;===========================
; it does interrupts differently
lda $FBB3 ; IIe and newer is $06
cmp #6
beq apple_iie_or_newer
jmp done_apple_detect
apple_iie_or_newer:
lda $FBC0 ; 0 on a IIc
bne done_apple_detect
apple_iic:
; 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
lda #$ff
; don't bother patching these, IIc mockingboard always slot 4?
sta MOCK_6522_DDRA1
sta MOCK_6522_T1CL
lda APPLEII_MODEL
cmp #'C'
bne done_iic_hack
; bypass the firmware interrupt handler
; should we do this on IIe too? probably faster
; first we have to copy the ROM to the language card
sei ; disable interrupts
lda $c08b ; disable ROM (enable language card)
lda $c08b
copy_rom_loop:
lda $c089 ; read ROM, write RAM1
lda $c089
ldy #0
read_rom_loop:
lda $D000,Y
sta $400,Y ; note this uses text page as
; temporary data store
iny
bne read_rom_loop
lda $c08B ; read/write RAM1
lda $c08B ;
write_rom_loop:
lda $400,Y
sta $D000,Y
iny
bne write_rom_loop
inc read_rom_loop+2
inc write_rom_loop+5
bne copy_rom_loop
lda #<interrupt_handler
sta $fffe
lda #>interrupt_handler
sta $ffff
lda #$EA ; nop out the "lda $45" in the irq hand
lda #$EA ; nop out the "lda $45" in the irq handler
sta interrupt_smc
sta interrupt_smc+1
done_apple_detect:
done_iic_hack:
;=========================
@ -228,10 +235,16 @@ done_apple_detect:
; Enable 50Hz clock on 6522
;============================
; 4fe7 / 1e6 = .020s, 50Hz
; 9c40 / 1e6 = .040s, 25Hz
; 411a / 1e6 = .016s, 60Hz
; Note, on Apple II the clock isn't 1MHz but is actually closer to
; roughly 1.023MHz, and every 65th clock is stretched (it's complicated)
; 4fe7 / 1.023e6 = .020s, 50Hz
; 9c40 / 1.023e6 = .040s, 25Hz
; 411a / 1.023e6 = .016s, 60Hz
; French Touch uses
; 4e20 / 1.000e6 = .020s, 50Hz, which assumes 1MHz clock freq
sei ; disable interrupts just in case
@ -249,9 +262,11 @@ setup_irq_smc4:
sta MOCK_6522_IER ; IER: 1100, enable timer one interrupt
lda #$E7
; lda #$20
setup_irq_smc5:
sta MOCK_6522_T1CL ; write into low-order latch
lda #$4f
; lda #$4E
setup_irq_smc6:
sta MOCK_6522_T1CH ; write into high-order latch,
; load both values into counter

View File

@ -36,6 +36,15 @@ pt3_setup:
; lda #1
sta LOOP ; change to 1 to loop forever
;=======================
; Detect Apple II Model
;========================
; IRQ setup is different on IIc
; You can possibly skip this if you only care about II+/IIe
jsr detect_appleii_model
;=======================
; Detect mockingboard
;========================
@ -124,6 +133,21 @@ forever_loop:
; as we disable ROM (COUT won't work?)
print_mockingboard_detect:
lda APPLEII_MODEL
sta apple_message+17
; print detection message for Apple II type
ldy #0
print_apple_message:
lda apple_message,Y ; load loading message
beq done_apple_message
ora #$80
jsr COUT
iny
jmp print_apple_message
done_apple_message:
jsr CROUT1
; print detection message
ldy #0
@ -168,6 +192,8 @@ done_found_message:
;=========
; strings
;=========
apple_message: .asciiz "DETECTED APPLE II "
mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD: "
not_message: .byte "NOT "
found_message: .asciiz "FOUND SLOT#4"
@ -182,6 +208,7 @@ found_message: .asciiz "FOUND SLOT#4"
;routines
;=========
.include "pt3_lib_detect_model.s"
.include "pt3_lib_core.s"
.include "pt3_lib_init.s"
.include "pt3_lib_mockingboard_setup.s"

View File

@ -12,6 +12,7 @@ MB_VALUE = $67
DONE_PLAYING = $68
DONE_SONG = $69
PT3_TEMP = $6A
APPLEII_MODEL = $6B
AY_REGISTERS = $70
A_FINE_TONE = $70