diff --git a/Firmware/Firmware-RP-patch.bin b/Firmware/Firmware-RP-patch.bin deleted file mode 100644 index 3f71b70..0000000 Binary files a/Firmware/Firmware-RP-patch.bin and /dev/null differ diff --git a/Firmware/Firmware.asm b/Firmware/Firmware.asm index f60ab45..f36b279 100644 --- a/Firmware/Firmware.asm +++ b/Firmware/Firmware.asm @@ -1,61 +1,13 @@ -;Please note this code is assembled seven times, -;once for each slot in the Apple II. -;This allows the card to work in any slot without -;having to write space consuming relocatable code. + writeLatchHigh = $C081 + writeLatchLow = $C080 -;Install cc65 (on Ubuntu this is: sudo apt install cc65) -;Execute the following commands to generate the binary: -;ca65 Warning.asm -o warning.o -;ca65 Firmware.asm -D SLOT1 -o slot1.o -;ca65 Firmware.asm -D SLOT2 -o slot2.o -;ca65 Firmware.asm -D SLOT3 -o slot3.o -;ca65 Firmware.asm -D SLOT4 -o slot4.o -;ca65 Firmware.asm -D SLOT5 -o slot5.o -;ca65 Firmware.asm -D SLOT6 -o slot6.o -;ca65 Firmware.asm -D SLOT7 -o slot7.o -;ld65 -t none warning.o slot1.o slot2.o slot3.o slot4.o slot5.o slot6.o slot7.o -o Firmware.bin - -;Determine which slot we want by command-line define - .ifdef SLOT1 - slot = $01 - .endif - .ifdef SLOT2 - slot = $02 - .endif - .ifdef SLOT3 - slot = $03 - .endif - .ifdef SLOT4 - slot = $04 - .endif - .ifdef SLOT5 - slot = $05 - .endif - .ifdef SLOT6 - slot = $06 - .endif - .ifdef SLOT7 - slot = $07 - .endif - -;Calculate I/O addresses for this slot - - slotwh = $C081+slot*$10 - slotwl = $C080+slot*$10 - slotrd = $C080+slot*$10 - sdrive = slot*$10 - - sram0 = $478+slot - sram1 = $4F8+slot - sram2 = $578+slot - sram3 = $5F8+slot - sram4 = $678+slot - sram5 = $6F8+slot - sram6 = $778+slot - sram7 = $7F8+slot +;temp variables becasue 6502 only has 3 registers + highLatch = $F8 + lowLatch = $F9 + tempY = $FE + blockHalfCounter = $FF ;ProDOS defines - command = $42 ;ProDOS command unit = $43 ;7=drive 6-4=slot 3-0=not used buflo = $44 ;low address of buffer @@ -66,10 +18,17 @@ nodev = $28 ;no device connected wperr = $2B ;write protect error - .org $C000+slot*$100 - ;code is non-relocatable - ; but duplicated seven times, - ; once for each slot +;for relocatable code, address to jump to instead of JSR absolute + RTS + jumpAddressLo = $FA + jumpAddressHi = $FB + ioAddressLo = $FC + ioAddressHi = $FD + knownRts = $FF58 + + .org $C700 + ;code is relocatable + ; but set to $c700 for + ; readability ;ID bytes for booting and drive detection cpx #$20 ;ID bytes for ProDOS and the @@ -77,118 +36,147 @@ cpx #$03 ; cpx #$3C ;this one for older II's +;zero out block numbers and buffer address + sty buflo + sty blklo + sty blkhi + iny ;set command = 1 for read block + sty command + sty jumpAddressLo ;$01 of $0801 where boot code starts + jsr knownRts ;jump to known RTS to get our address from the stack + tsx + lda $0100,x ;this for example would be $C7 in slot 7 + sta bufhi ;keep the slot here + asl + asl + asl + asl + tax + ;display copyright message - ldy #$00 -drawtxt: lda text,y - beq boot ;check for NULL - ora #$80 ;make it visible to the Apple + ldy #knownRts + sta jumpAddressHi +start: + lda #$C0 + sta ioAddressHi + jsr knownRts + tsx + lda $0100,x + asl a + asl a + asl a + asl a + tax + cpx unit ;make sure same as ProDOS + beq docmd ;yep, do command + sec ;nope, set device not connected lda #nodev rts ;go back to ProDOS -docmd: lda command ;get ProDOS command +docmd: + lda command beq getstat ;command 0 is GetStatus - cmp #$01 ; + cmp #$01 beq readblk ;command 1 is ReadBlock sec ;Format/Write not permitted lda #wperr ;write protect error rts ;go back to ProDOS -getstat: clc ;send back status +getstat: + clc ;send back status lda #$00 ;good status ldx #$00 ;1024 blocks ldy #$04 ; rts -readblk: lda blkhi ;get hi block +readblk: + lda blkhi ;get hi block asl a ;shift up to top 3 bits asl a ;since that's all the high asl a ;blocks we can handle asl a ; asl a ; - sta sram0 ;save it in scratch ram 0 + sta highLatch ;save it in scratch ram 0 ;so we can stuff it in the ;high latch later lda blklo ;get low block lsr a ;shift so we get the top 5 lsr a ;bits - this also goes in lsr a ;the high latch - ora sram0 ;add it to those top 3 bits - sta sram0 ;save it back in scratch ram - + ora highLatch ;add it to those top 3 bits + sta highLatch ;save it back in scratch ram lda blklo ;get low block asl a ;shift it to top 3 bits asl a ; asl a ; asl a ; asl a ; - sta sram1 ;save it in scratch ram + sta lowLatch + lda #$02 + sta blockHalfCounter - jsr get256 ;get first half of block - - lda sram1 ;get low latch - and #$F0 ;clear bottom 4 bits - ora #$10 ;set bit 5 for second half - ;of 512 byte block - sta sram1 ;save it back in scratch - - inc bufhi ;write 2nd block up 256 bytes - jsr get256 ;get second half of block - dec bufhi ;put ProDOS buffer back +;This gets 256 bytes from the ROM card +read256: + ldy #$00 + lda highLatch ;get high latch value + sta writeLatchHigh,x ;set high latch for card +loop256: + lda lowLatch + sta writeLatchLow,x + txa + ora #$80 + sta ioAddressLo +loop16: + sty tempY + ldy #$00 + lda (ioAddressLo),y + ldy tempY + sta (buflo),y + iny + inc ioAddressLo + lda ioAddressLo + and #$0F + bne loop16 + inc lowLatch + cpy #$00 + bne loop256 + dec blockHalfCounter + bne readnext256 + dec bufhi clc ;clear error code for success lda #$00 rts ;return to ProDOS -;This gets 256 bytes from the ROM card -;assuming high latch value is in sram0 -;and low latch value is in sram1 -get256: ldy #$00 ;clear buffer counter - lda sram0 ;get high latch value - sta slotwh ;set high latch for card +readnext256: + inc bufhi + clc + bcc read256 -loop256: ldx #$00 ;clear port counter - lda sram1 ;get low latch value - sta slotwl ;set low latch +;macro for string with high-bit set +.macro aschi str +.repeat .strlen (str), c +.byte .strat (str, c) | $80 +.endrep +.endmacro -loop16: lda slotrd,x ;get a byte - sta (buflo),y ;write into the buffer - iny - inx - cpx #$10 - bne loop16 ;go until 16 bytes read - - inc sram1 ;next 16 bytes - cpy #$00 - bne loop256 ;go until 256 total - rts - -text: .byte "ROM-Drive (c)1998-2019 Terence J. Boldt" +text: aschi "ROM-Drive (c)1998-2021 Terence J. Boldt" end: .byte 0 diff --git a/Firmware/Firmware.bin b/Firmware/Firmware.bin index 56fc03f..b50118d 100644 Binary files a/Firmware/Firmware.bin and b/Firmware/Firmware.bin differ diff --git a/Firmware/Firmware.lst b/Firmware/Firmware.lst new file mode 100644 index 0000000..64d8555 --- /dev/null +++ b/Firmware/Firmware.lst @@ -0,0 +1,201 @@ +ca65 V2.18 - N/A +Main file : Firmware.asm +Current file: Firmware.asm + +000000r 1 writeLatchHigh = $C081 +000000r 1 writeLatchLow = $C080 +000000r 1 +000000r 1 ;temp variables becasue 6502 only has 3 registers +000000r 1 highLatch = $F8 +000000r 1 lowLatch = $F9 +000000r 1 tempY = $FE +000000r 1 blockHalfCounter = $FF +000000r 1 +000000r 1 ;ProDOS defines +000000r 1 command = $42 ;ProDOS command +000000r 1 unit = $43 ;7=drive 6-4=slot 3-0=not used +000000r 1 buflo = $44 ;low address of buffer +000000r 1 bufhi = $45 ;hi address of buffer +000000r 1 blklo = $46 ;low block +000000r 1 blkhi = $47 ;hi block +000000r 1 ioerr = $27 ;I/O error code +000000r 1 nodev = $28 ;no device connected +000000r 1 wperr = $2B ;write protect error +000000r 1 +000000r 1 ;for relocatable code, address to jump to instead of JSR absolute + RTS +000000r 1 jumpAddressLo = $FA +000000r 1 jumpAddressHi = $FB +000000r 1 ioAddressLo = $FC +000000r 1 ioAddressHi = $FD +000000r 1 knownRts = $FF58 +000000r 1 +000000r 1 .org $C700 +00C700 1 ;code is relocatable +00C700 1 ; but set to $c700 for +00C700 1 ; readability +00C700 1 +00C700 1 ;ID bytes for booting and drive detection +00C700 1 E0 20 cpx #$20 ;ID bytes for ProDOS and the +00C702 1 E0 00 cpx #$00 ; Apple Autostart ROM +00C704 1 E0 03 cpx #$03 ; +00C706 1 E0 3C cpx #$3C ;this one for older II's +00C708 1 +00C708 1 ;zero out block numbers and buffer address +00C708 1 84 44 sty buflo +00C70A 1 84 46 sty blklo +00C70C 1 84 47 sty blkhi +00C70E 1 C8 iny ;set command = 1 for read block +00C70F 1 84 42 sty command +00C711 1 84 FA sty jumpAddressLo ;$01 of $0801 where boot code starts +00C713 1 20 58 FF jsr knownRts ;jump to known RTS to get our address from the stack +00C716 1 BA tsx +00C717 1 BD 00 01 lda $0100,x ;this for example would be $C7 in slot 7 +00C71A 1 85 45 sta bufhi ;keep the slot here +00C71C 1 0A asl +00C71D 1 0A asl +00C71E 1 0A asl +00C71F 1 0A asl +00C720 1 AA tax +00C721 1 +00C721 1 ;display copyright message +00C721 1 A0 C1 ldy #knownRts +00C73B 1 85 FB sta jumpAddressHi +00C73D 1 start: +00C73D 1 A9 C0 lda #$C0 +00C73F 1 85 FD sta ioAddressHi +00C741 1 20 58 FF jsr knownRts +00C744 1 BA tsx +00C745 1 BD 00 01 lda $0100,x +00C748 1 0A asl a +00C749 1 0A asl a +00C74A 1 0A asl a +00C74B 1 0A asl a +00C74C 1 AA tax +00C74D 1 E4 43 cpx unit ;make sure same as ProDOS +00C74F 1 F0 04 beq docmd ;yep, do command +00C751 1 38 sec ;nope, set device not connected +00C752 1 A9 28 lda #nodev +00C754 1 60 rts ;go back to ProDOS +00C755 1 +00C755 1 docmd: +00C755 1 A5 42 lda command +00C757 1 F0 08 beq getstat ;command 0 is GetStatus +00C759 1 C9 01 cmp #$01 +00C75B 1 F0 0C beq readblk ;command 1 is ReadBlock +00C75D 1 38 sec ;Format/Write not permitted +00C75E 1 A9 2B lda #wperr ;write protect error +00C760 1 60 rts ;go back to ProDOS +00C761 1 +00C761 1 getstat: +00C761 1 18 clc ;send back status +00C762 1 A9 00 lda #$00 ;good status +00C764 1 A2 00 ldx #$00 ;1024 blocks +00C766 1 A0 04 ldy #$04 ; +00C768 1 60 rts +00C769 1 +00C769 1 readblk: +00C769 1 A5 47 lda blkhi ;get hi block +00C76B 1 0A asl a ;shift up to top 3 bits +00C76C 1 0A asl a ;since that's all the high +00C76D 1 0A asl a ;blocks we can handle +00C76E 1 0A asl a ; +00C76F 1 0A asl a ; +00C770 1 85 F8 sta highLatch ;save it in scratch ram 0 +00C772 1 ;so we can stuff it in the +00C772 1 ;high latch later +00C772 1 A5 46 lda blklo ;get low block +00C774 1 4A lsr a ;shift so we get the top 5 +00C775 1 4A lsr a ;bits - this also goes in +00C776 1 4A lsr a ;the high latch +00C777 1 05 F8 ora highLatch ;add it to those top 3 bits +00C779 1 85 F8 sta highLatch ;save it back in scratch ram +00C77B 1 A5 46 lda blklo ;get low block +00C77D 1 0A asl a ;shift it to top 3 bits +00C77E 1 0A asl a ; +00C77F 1 0A asl a ; +00C780 1 0A asl a ; +00C781 1 0A asl a ; +00C782 1 85 F9 sta lowLatch +00C784 1 A9 02 lda #$02 +00C786 1 85 FF sta blockHalfCounter +00C788 1 +00C788 1 ;This gets 256 bytes from the ROM card +00C788 1 +00C788 1 read256: +00C788 1 A0 00 ldy #$00 +00C78A 1 A5 F8 lda highLatch ;get high latch value +00C78C 1 9D 81 C0 sta writeLatchHigh,x ;set high latch for card +00C78F 1 loop256: +00C78F 1 A5 F9 lda lowLatch +00C791 1 9D 80 C0 sta writeLatchLow,x +00C794 1 8A txa +00C795 1 09 80 ora #$80 +00C797 1 85 FC sta ioAddressLo +00C799 1 loop16: +00C799 1 84 FE sty tempY +00C79B 1 A0 00 ldy #$00 +00C79D 1 B1 FC lda (ioAddressLo),y +00C79F 1 A4 FE ldy tempY +00C7A1 1 91 44 sta (buflo),y +00C7A3 1 C8 iny +00C7A4 1 E6 FC inc ioAddressLo +00C7A6 1 A5 FC lda ioAddressLo +00C7A8 1 29 0F and #$0F +00C7AA 1 D0 ED bne loop16 +00C7AC 1 E6 F9 inc lowLatch +00C7AE 1 C0 00 cpy #$00 +00C7B0 1 D0 DD bne loop256 +00C7B2 1 C6 FF dec blockHalfCounter +00C7B4 1 D0 06 bne readnext256 +00C7B6 1 C6 45 dec bufhi +00C7B8 1 18 clc ;clear error code for success +00C7B9 1 A9 00 lda #$00 +00C7BB 1 60 rts ;return to ProDOS +00C7BC 1 +00C7BC 1 readnext256: +00C7BC 1 E6 45 inc bufhi +00C7BE 1 18 clc +00C7BF 1 90 C7 bcc read256 +00C7C1 1 +00C7C1 1 ;macro for string with high-bit set +00C7C1 1 .macro aschi str +00C7C1 1 .repeat .strlen (str), c +00C7C1 1 .byte .strat (str, c) | $80 +00C7C1 1 .endrep +00C7C1 1 .endmacro +00C7C1 1 +00C7C1 1 D2 CF CD AD text: aschi "ROM-Drive (c)1998-2021 Terence J. Boldt" +00C7C5 1 C4 F2 E9 F6 +00C7C9 1 E5 A0 A8 E3 +00C7E8 1 end: +00C7E8 1 00 .byte 0 +00C7E9 1 +00C7E9 1 ; These bytes need to be at the top of the 256 byte firmware as ProDOS +00C7E9 1 ; uses these to find the entry point and drive capabilities +00C7E9 1 +00C7E9 1 00 00 00 00 .repeat 251-