diff --git a/music/pt3_lib/Makefile b/music/pt3_lib/Makefile index ca78841d..8b4ca36c 100644 --- a/music/pt3_lib/Makefile +++ b/music/pt3_lib/Makefile @@ -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 diff --git a/music/pt3_lib/README.pt3_lib b/music/pt3_lib/README.pt3_lib index 73d898f3..59fec17c 100644 --- a/music/pt3_lib/README.pt3_lib +++ b/music/pt3_lib/README.pt3_lib @@ -1,10 +1,10 @@ -The PT3_player Library version 0.2 +The PT3_player Library version 0.3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ by Vince "Deater" Weaver 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. + diff --git a/music/pt3_lib/empty.dsk b/music/pt3_lib/empty.dsk deleted file mode 100644 index 0a2af35e..00000000 Binary files a/music/pt3_lib/empty.dsk and /dev/null differ diff --git a/music/pt3_lib/hello.bas b/music/pt3_lib/hello.bas index 744fa7b2..be32c545 100644 --- a/music/pt3_lib/hello.bas +++ b/music/pt3_lib/hello.bas @@ -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" diff --git a/music/pt3_lib/pt3_lib_mockingboard_detect.s b/music/pt3_lib/pt3_lib_mockingboard_detect.s index 706d9407..925be47f 100644 --- a/music/pt3_lib/pt3_lib_mockingboard_detect.s +++ b/music/pt3_lib/pt3_lib_mockingboard_detect.s @@ -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 diff --git a/music/pt3_lib/pt3_lib_mockingboard_setup.s b/music/pt3_lib/pt3_lib_mockingboard_setup.s index 9c7a6e1c..ff563546 100644 --- a/music/pt3_lib/pt3_lib_mockingboard_setup.s +++ b/music/pt3_lib/pt3_lib_mockingboard_setup.s @@ -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 $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 diff --git a/music/pt3_lib/pt3_test.s b/music/pt3_lib/pt3_test.s index 91d69c0b..11bac7b9 100644 --- a/music/pt3_lib/pt3_test.s +++ b/music/pt3_lib/pt3_test.s @@ -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" diff --git a/music/pt3_lib/zp.inc b/music/pt3_lib/zp.inc index 52ff3fb8..d3f6351d 100644 --- a/music/pt3_lib/zp.inc +++ b/music/pt3_lib/zp.inc @@ -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