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