Compare commits

...

4 Commits

Author SHA1 Message Date
Terence Boldt 90320b1ab5
Update README.md 2022-11-06 06:43:38 -05:00
Terence Boldt abe8b085cf
Merge pull request #15 from tjboldt/esc-skip
Add ESC to skip boot, menu 1 - 7 to boot specific slot
2022-11-06 06:23:57 -05:00
Terence Boldt 950338d29a Add boot slot 1 - 7 in startup menu 2022-11-06 05:48:15 -05:00
Terence Boldt d6691c6567 Add ESC to skip boot to next slot 2022-11-02 18:10:17 -04:00
6 changed files with 209 additions and 188 deletions

Binary file not shown.

View File

@ -22,6 +22,11 @@
highLatch = $FF
knownRts = $FF58
;autostart ROM next card
sloop = $FABA
keyboard = $C000
clearKeyboard = $C010
.org $C700
;code is relocatable
; but set to $c700 for
@ -33,7 +38,14 @@
cpx #$03 ;
cpx #$3C ;this one for older II's
;check for ESC key and if so, jump to next slot in autostart
lda keyboard
cmp #$9B
bne start
jmp sloop
;zero out block numbers and buffer address
start:
sty buflo
sty blklo
sty blkhi
@ -90,18 +102,13 @@ getstat:
rts
readblk:
lda ioAddressLo
pha
lda ioAddressHi
pha
lda tempY
pha
lda blockHalfCounter
pha
lda lowLatch
pha
lda highLatch
saveVars:
ldy #ioAddressLo
varLoop:
lda $00,y
pha
iny
bne varLoop
lda blkhi ;get hi block
asl a ;shift up to top 3 bits

Binary file not shown.

View File

@ -26,6 +26,11 @@ Current file: Firmware.asm
000000r 1 highLatch = $FF
000000r 1 knownRts = $FF58
000000r 1
000000r 1 ;autostart ROM next card
000000r 1 sloop = $FABA
000000r 1 keyboard = $C000
000000r 1 clearKeyboard = $C010
000000r 1
000000r 1 .org $C700
00C700 1 ;code is relocatable
00C700 1 ; but set to $c700 for
@ -37,185 +42,187 @@ Current file: Firmware.asm
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 20 58 FF jsr knownRts ;jump to known RTS to get our address from the stack
00C714 1 BA tsx
00C715 1 BD 00 01 lda $0100,x ;this for example would be $C7 in slot 7
00C718 1 85 45 sta bufhi ;keep the slot here
00C71A 1 0A asl
00C71B 1 0A asl
00C71C 1 0A asl
00C71D 1 0A asl
00C71E 1 85 43 sta unit
00C720 1
00C720 1 ;display copyright message
00C720 1 A0 CE ldy #<text
00C722 1 drawtxt:
00C722 1 B1 44 lda (buflo),y
00C724 1 F0 06 beq boot
00C726 1 99 02 07 sta $07D0-<text,y ;put text on last line
00C729 1 C8 iny
00C72A 1 D0 F6 bne drawtxt
00C72C 1
00C72C 1 ;load block 0000 at $0800
00C72C 1 boot:
00C72C 1 A9 08 lda #$08 ;push $0800 onto the stack so an RTS will run at $0801
00C72E 1 85 45 sta bufhi
00C730 1 48 pha
00C731 1 A9 00 lda #$00
00C733 1 48 pha
00C734 1 ;This is the ProDOS entry point for this card
00C734 1 entry:
00C734 1 A6 43 ldx unit ;make sure it's drive 1
00C736 1 10 04 bpl docmd ;yep, do command
00C738 1 38 sec ;nope, set device not connected
00C739 1 A9 28 lda #nodev
00C73B 1 60 rts ;go back to ProDOS
00C73C 1
00C73C 1 docmd:
00C73C 1 A5 42 lda command
00C73E 1 F0 08 beq getstat ;command 0 is GetStatus
00C740 1 C9 01 cmp #$01
00C742 1 F0 0C beq readblk ;command 1 is ReadBlock
00C744 1 38 sec ;Format/Write not permitted
00C745 1 A9 2B lda #wperr ;write protect error
00C747 1 60 rts ;go back to ProDOS
00C748 1
00C748 1 getstat:
00C748 1 18 clc ;send back status
00C749 1 A9 00 lda #$00 ;good status
00C74B 1 A2 00 ldx #$00 ;1024 blocks
00C74D 1 A0 04 ldy #$04 ;
00C74F 1 60 rts
00C750 1
00C750 1 readblk:
00C750 1 A5 FA lda ioAddressLo
00C752 1 48 pha
00C753 1 A5 FB lda ioAddressHi
00C755 1 48 pha
00C756 1 A5 FC lda tempY
00C758 1 48 pha
00C759 1 A5 FD lda blockHalfCounter
00C75B 1 48 pha
00C75C 1 A5 FE lda lowLatch
00C75E 1 48 pha
00C75F 1 A5 FF lda highLatch
00C761 1 48 pha
00C762 1
00C762 1 A5 47 lda blkhi ;get hi block
00C764 1 0A asl a ;shift up to top 3 bits
00C765 1 0A asl a ;since that's all the high
00C766 1 0A asl a ;blocks we can handle
00C767 1 0A asl a ;
00C708 1 ;check for ESC key and if so, jump to next slot in autostart
00C708 1 AD 00 C0 lda keyboard
00C70B 1 C9 9B cmp #$9B
00C70D 1 D0 03 bne start
00C70F 1 4C BA FA jmp sloop
00C712 1
00C712 1 ;zero out block numbers and buffer address
00C712 1 start:
00C712 1 84 44 sty buflo
00C714 1 84 46 sty blklo
00C716 1 84 47 sty blkhi
00C718 1 C8 iny ;set command = 1 for read block
00C719 1 84 42 sty command
00C71B 1 20 58 FF jsr knownRts ;jump to known RTS to get our address from the stack
00C71E 1 BA tsx
00C71F 1 BD 00 01 lda $0100,x ;this for example would be $C7 in slot 7
00C722 1 85 45 sta bufhi ;keep the slot here
00C724 1 0A asl
00C725 1 0A asl
00C726 1 0A asl
00C727 1 0A asl
00C728 1 85 43 sta unit
00C72A 1
00C72A 1 ;display copyright message
00C72A 1 A0 CF ldy #<text
00C72C 1 drawtxt:
00C72C 1 B1 44 lda (buflo),y
00C72E 1 F0 06 beq boot
00C730 1 99 01 07 sta $07D0-<text,y ;put text on last line
00C733 1 C8 iny
00C734 1 D0 F6 bne drawtxt
00C736 1
00C736 1 ;load block 0000 at $0800
00C736 1 boot:
00C736 1 A9 08 lda #$08 ;push $0800 onto the stack so an RTS will run at $0801
00C738 1 85 45 sta bufhi
00C73A 1 48 pha
00C73B 1 A9 00 lda #$00
00C73D 1 48 pha
00C73E 1 ;This is the ProDOS entry point for this card
00C73E 1 entry:
00C73E 1 A6 43 ldx unit ;make sure it's drive 1
00C740 1 10 04 bpl docmd ;yep, do command
00C742 1 38 sec ;nope, set device not connected
00C743 1 A9 28 lda #nodev
00C745 1 60 rts ;go back to ProDOS
00C746 1
00C746 1 docmd:
00C746 1 A5 42 lda command
00C748 1 F0 08 beq getstat ;command 0 is GetStatus
00C74A 1 C9 01 cmp #$01
00C74C 1 F0 0C beq readblk ;command 1 is ReadBlock
00C74E 1 38 sec ;Format/Write not permitted
00C74F 1 A9 2B lda #wperr ;write protect error
00C751 1 60 rts ;go back to ProDOS
00C752 1
00C752 1 getstat:
00C752 1 18 clc ;send back status
00C753 1 A9 00 lda #$00 ;good status
00C755 1 A2 00 ldx #$00 ;1024 blocks
00C757 1 A0 04 ldy #$04 ;
00C759 1 60 rts
00C75A 1
00C75A 1 readblk:
00C75A 1 saveVars:
00C75A 1 A0 FA ldy #ioAddressLo
00C75C 1 varLoop:
00C75C 1 B9 00 00 lda $00,y
00C75F 1 48 pha
00C760 1 C8 iny
00C761 1 D0 F9 bne varLoop
00C763 1
00C763 1 A5 47 lda blkhi ;get hi block
00C765 1 0A asl a ;shift up to top 3 bits
00C766 1 0A asl a ;since that's all the high
00C767 1 0A asl a ;blocks we can handle
00C768 1 0A asl a ;
00C769 1 85 FF sta highLatch
00C76B 1 A5 46 lda blklo ;get low block
00C76D 1 4A lsr a ;shift so we get the top 5
00C76E 1 4A lsr a ;bits - this also goes in
00C76F 1 4A lsr a ;the high latch
00C770 1 05 FF ora highLatch ;add it to those top 3 bits
00C772 1 85 FF sta highLatch ;save it back in scratch ram
00C774 1 9D 81 C0 sta writeLatchHigh,x ;set high latch for card
00C777 1 A5 46 lda blklo ;get low block
00C779 1 0A asl a ;shift it to top 3 bits
00C77A 1 0A asl a ;
00C769 1 0A asl a ;
00C76A 1 85 FF sta highLatch
00C76C 1 A5 46 lda blklo ;get low block
00C76E 1 4A lsr a ;shift so we get the top 5
00C76F 1 4A lsr a ;bits - this also goes in
00C770 1 4A lsr a ;the high latch
00C771 1 05 FF ora highLatch ;add it to those top 3 bits
00C773 1 85 FF sta highLatch ;save it back in scratch ram
00C775 1 9D 81 C0 sta writeLatchHigh,x ;set high latch for card
00C778 1 A5 46 lda blklo ;get low block
00C77A 1 0A asl a ;shift it to top 3 bits
00C77B 1 0A asl a ;
00C77C 1 0A asl a ;
00C77D 1 0A asl a ;
00C77E 1 85 FE sta lowLatch
00C780 1 A9 02 lda #$02
00C782 1 85 FD sta blockHalfCounter
00C784 1 A9 C0 lda #$C0
00C786 1 85 FB sta ioAddressHi
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 loop256:
00C78A 1 A5 FE lda lowLatch
00C78C 1 9D 80 C0 sta writeLatchLow,x
00C78F 1 8A txa
00C790 1 09 80 ora #$80
00C792 1 85 FA sta ioAddressLo
00C794 1
00C794 1 loop16:
00C794 1 84 FC sty tempY
00C796 1 A0 00 ldy #$00
00C798 1 B1 FA lda (ioAddressLo),y
00C79A 1 A4 FC ldy tempY
00C79C 1 91 44 sta (buflo),y
00C79E 1 C8 iny
00C79F 1 E6 FA inc ioAddressLo
00C7A1 1 A5 FA lda ioAddressLo
00C7A3 1 29 0F and #$0F
00C7A5 1 D0 ED bne loop16
00C7A7 1
00C7A7 1 continue256:
00C7A7 1 E6 FE inc lowLatch
00C7A9 1 C0 00 cpy #$00
00C7AB 1 D0 DD bne loop256
00C7AD 1 C6 FD dec blockHalfCounter
00C7AF 1 D0 18 bne readnext256
00C7B1 1
00C7B1 1 finish:
00C7B1 1 68 pla
00C7B2 1 85 FF sta highLatch
00C7B4 1 68 pla
00C7B5 1 85 FE sta lowLatch
00C7B7 1 68 pla
00C7B8 1 85 FD sta blockHalfCounter
00C7BA 1 68 pla
00C7BB 1 85 FC sta tempY
00C7BD 1 68 pla
00C7BE 1 85 FB sta ioAddressHi
00C7C0 1 68 pla
00C7C1 1 85 FA sta ioAddressLo
00C7C3 1
00C7C3 1 C6 45 dec bufhi
00C7C5 1 18 clc ;clear error code for success
00C7C6 1 A9 00 lda #$00
00C7C8 1 60 rts
00C7C9 1
00C7C9 1 readnext256:
00C7C9 1 E6 45 inc bufhi ; set buffer to receive next 256 bytes
00C7CB 1 18 clc ; effectively a branch always
00C7CC 1 90 BA bcc read256
00C7CE 1
00C7CE 1 ;macro for string with high-bit set
00C7CE 1 .macro aschi str
00C7CE 1 .repeat .strlen (str), c
00C7CE 1 .byte .strat (str, c) | $80
00C7CE 1 .endrep
00C7CE 1 .endmacro
00C7CE 1
00C7CE 1 D2 CF CD AD text: aschi "ROM-Drive (c)1998-2022 Terence J. Boldt"
00C7D2 1 C4 F2 E9 F6
00C7D6 1 E5 A0 A8 E3
00C7DA 1 A9 B1 B9 B9
00C7DE 1 B8 AD B2 B0
00C7E2 1 B2 B2 A0 D4
00C7E6 1 E5 F2 E5 EE
00C7EA 1 E3 E5 A0 CA
00C7EE 1 AE A0 C2 EF
00C7F2 1 EC E4 F4
00C7F5 1 end:
00C7F5 1 00 .byte 0
00C7F6 1
00C7F6 1 ; These bytes need to be at the top of the 256 byte firmware as ProDOS
00C7F6 1 ; uses these to find the entry point and drive capabilities
00C7F6 1
00C7F6 1 00 00 00 00 .repeat 251-<end
00C7FA 1 00 00
00C77E 1 0A asl a ;
00C77F 1 85 FE sta lowLatch
00C781 1 A9 02 lda #$02
00C783 1 85 FD sta blockHalfCounter
00C785 1 A9 C0 lda #$C0
00C787 1 85 FB sta ioAddressHi
00C789 1
00C789 1 ;This gets 256 bytes from the ROM card
00C789 1
00C789 1 read256:
00C789 1 A0 00 ldy #$00
00C78B 1 loop256:
00C78B 1 A5 FE lda lowLatch
00C78D 1 9D 80 C0 sta writeLatchLow,x
00C790 1 8A txa
00C791 1 09 80 ora #$80
00C793 1 85 FA sta ioAddressLo
00C795 1
00C795 1 loop16:
00C795 1 84 FC sty tempY
00C797 1 A0 00 ldy #$00
00C799 1 B1 FA lda (ioAddressLo),y
00C79B 1 A4 FC ldy tempY
00C79D 1 91 44 sta (buflo),y
00C79F 1 C8 iny
00C7A0 1 E6 FA inc ioAddressLo
00C7A2 1 A5 FA lda ioAddressLo
00C7A4 1 29 0F and #$0F
00C7A6 1 D0 ED bne loop16
00C7A8 1
00C7A8 1 continue256:
00C7A8 1 E6 FE inc lowLatch
00C7AA 1 C0 00 cpy #$00
00C7AC 1 D0 DD bne loop256
00C7AE 1 C6 FD dec blockHalfCounter
00C7B0 1 D0 18 bne readnext256
00C7B2 1
00C7B2 1 finish:
00C7B2 1 68 pla
00C7B3 1 85 FF sta highLatch
00C7B5 1 68 pla
00C7B6 1 85 FE sta lowLatch
00C7B8 1 68 pla
00C7B9 1 85 FD sta blockHalfCounter
00C7BB 1 68 pla
00C7BC 1 85 FC sta tempY
00C7BE 1 68 pla
00C7BF 1 85 FB sta ioAddressHi
00C7C1 1 68 pla
00C7C2 1 85 FA sta ioAddressLo
00C7C4 1
00C7C4 1 C6 45 dec bufhi
00C7C6 1 18 clc ;clear error code for success
00C7C7 1 A9 00 lda #$00
00C7C9 1 60 rts
00C7CA 1
00C7CA 1 readnext256:
00C7CA 1 E6 45 inc bufhi ; set buffer to receive next 256 bytes
00C7CC 1 18 clc ; effectively a branch always
00C7CD 1 90 BA bcc read256
00C7CF 1
00C7CF 1 ;macro for string with high-bit set
00C7CF 1 .macro aschi str
00C7CF 1 .repeat .strlen (str), c
00C7CF 1 .byte .strat (str, c) | $80
00C7CF 1 .endrep
00C7CF 1 .endmacro
00C7CF 1
00C7CF 1 D2 CF CD AD text: aschi "ROM-Drive (c)1998-2022 Terence J. Boldt"
00C7D3 1 C4 F2 E9 F6
00C7D7 1 E5 A0 A8 E3
00C7DB 1 A9 B1 B9 B9
00C7DF 1 B8 AD B2 B0
00C7E3 1 B2 B2 A0 D4
00C7E7 1 E5 F2 E5 EE
00C7EB 1 E3 E5 A0 CA
00C7EF 1 AE A0 C2 EF
00C7F3 1 EC E4 F4
00C7F6 1 end:
00C7F6 1 00 .byte 0
00C7F7 1
00C7F7 1 ; These bytes need to be at the top of the 256 byte firmware as ProDOS
00C7F7 1 ; uses these to find the entry point and drive capabilities
00C7F7 1
00C7F7 1 00 00 00 00 .repeat 251-<end
00C7FB 1 00
00C7FC 1 .byte 0
00C7FC 1 .endrepeat
00C7FC 1
00C7FC 1 00 00 .byte 0,0 ;0000 blocks = check status
00C7FE 1 03 .byte 3 ;bit 0=read 1=status
00C7FF 1 34 .byte <entry ;low byte of entry
00C7FF 1 3E .byte <entry ;low byte of entry
00C7FF 1

Binary file not shown.

View File

@ -22,15 +22,22 @@ By mid-May of 1999 I finally got around to building a third design. This time I
To build actual circuit boards, I tried making some by hand with marker, etching solution and copper on fibreglass boards but this proved to be far too difficult. I then learned the wonders of gerber files which can be created with a variety of PCB layout software. The files were emailed to a company in Alberta, Canada and three days later in July of 1999 I received a batch of 10 blank boards. These boards did not have the familiar green board look to them, nor were they pre-cut. I had to cut and file them to fit an Apple II slot by hand. Back then it was prohitively expensive for a young hobbiest to make less than 20 or 30 boards with the full solder-masking process due to the set-up fees.
In 2019, I decided to revisit the original design as I was disappointed that the original didn't have a solder mask and was rather large for what it was. I got the board much smaller but in the process of translating my two decade old hand written notes, I made a mistake on one control line. To actually call this project finished, I had to make another revision. I also noticed the revised board was slightly larger than a credit card so I worked for a couple weeks to optimize the lines and squeeze the two-layer board down to 3.375" x 2.125". The board here is that final revision 2.5 (note that references to first, second and third design are all the solderless breadboard prototypes leading up to the 1.0 circuit board printed in 1999, 2.0 was never made, 2.1 is the board with the error patched with a jumper wire and 2.2 through 2.4 were never made).
In 2019, I decided to revisit the original design as I was disappointed that the original didn't have a solder mask and was rather large for what it was. I got the board much smaller but in the process of translating my two decade old hand written notes, I made a mistake on one control line. To actually call this project finished, I had to make another revision. I also noticed the revised board was slightly larger than a credit card so I worked for a couple weeks to optimize the lines and squeeze the two-layer board down to 3.375" x 2.125". (Note that references above to first, second and third design are all the solderless breadboard prototypes leading up to the 1.0 circuit board printed in 1999, 2.0 was never made, 2.1 is the board with the error patched with a jumper wire and 2.2 through 2.4 were never made).
In 2021, the first and only issue was opened on the project requesting that the firmware be relocatable. I let that issue sit for a few months and then Ralle Palaveev supplied some relocatable firmware as a patch. I quickly realized that this could be placed into the second block on the drive normally reserved for SOS bootloader for the Apple ///, essentially allowing the full EPROM to be used for the drive. I disassembed Ralle's patch, merged it into the existing source code and made a few updates to save a few bytes and add clarity.
In 2021, the first ever issue was opened on the project requesting that the firmware be relocatable. I let that issue sit for a few months and then Ralle Palaveev supplied some relocatable firmware as a patch. I quickly realized that this could be placed into the second block on the drive normally reserved for SOS bootloader for the Apple ///, essentially allowing the full EPROM to be used for the drive. I disassembed Ralle's patch, merged it into the existing source code and made a few updates to save a few bytes and add clarity. This change required some differences in wiring for the firmware addressing on the card. The final revision 4.0 was made in 2022 to fix the data buffer wiring but was otherwise the same as 3.0.
## Notes
I usually use Ciderpress to copy files onto the drive image and then burn the file to a 27C801 EPROM with a GQ-4x4 USB Programmer. Do NOT overwrite block 0001 as it contains the firmware for the card.
I used to use Ciderpress to copy files onto the drive image but now use my own cross-platform command line tool [ProDOS-Utilities](https://github.com/tjboldt/ProDOS-Utilities) and sometimes make modifications to the image live via an Apple II emulator. I then burn the file to a 27C801 EPROM with a GQ-4x4 USB Programmer. Do NOT overwrite block 0001 in the image as it contains the firmware for the card.
If you're planning on designing you own card, I highly recommend reading "Interfacing & Digital Experiments with your Apple" by Charles J. Engelisher and Apple's "Apple II Reference Manual" as well as "ProDOS Technical Reference Manual" if you want to build a drive. You also need an EPROM programmer, some chips and a prototyping board. My designs used simple logic gates to decode addresses but if you want to reduce chip count, you'll also need a PAL/GAL logic programmer (which some EPROM programmers can do).
##
## Website
Official website is [apple2.ca](http://apple2.ca/).
## Purchasing a ProDOS ROM-Drive
I generally no longer sell these cards but you can buy them online from [Laser](https://www.laser.com/product_info.php/item/ProDOS_ROM_Drive-Apple_II_ProDOS_bootable_1MB_read-only_drive/cPath/288_292/products_id/1984) and other retailers.
## Other links
- [Thread about building the card](https://tinkerdifferent.com/threads/building-tjboldts-prodos-rom-drive-for-apple.1249/)
- [Article about the card](https://www.callapple.org/hardware/prodos-rom-drive-version-3/)
- [Alternate version with fewer chips](https://www.ebay.com/itm/374004896438)