2019-05-13 13:11:26 +00:00
|
|
|
;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.
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
;Install cc65 (on Ubuntu this is: sudo apt install cc65)
|
|
|
|
;Execute the following commands to generate the binary:
|
2020-12-01 02:38:13 +00:00
|
|
|
;ca65 Warning.asm -o warning.o
|
2020-12-01 02:36:10 +00:00
|
|
|
;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
|
2020-12-01 02:38:13 +00:00
|
|
|
;ld65 -t none warning.o slot1.o slot2.o slot3.o slot4.o slot5.o slot6.o slot7.o -o Firmware.bin
|
2019-05-13 13:11:26 +00:00
|
|
|
|
|
|
|
;Determine which slot we want by command-line define
|
2020-12-01 02:36:10 +00:00
|
|
|
.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
|
2019-05-13 13:11:26 +00:00
|
|
|
|
|
|
|
;Calculate I/O addresses for this slot
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
slotwh = $C081+slot*$10
|
|
|
|
slotwl = $C080+slot*$10
|
|
|
|
slotrd = $C080+slot*$10
|
|
|
|
sdrive = slot*$10
|
2019-05-13 13:11:26 +00:00
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
sram0 = $478+slot
|
|
|
|
sram1 = $4F8+slot
|
|
|
|
sram2 = $578+slot
|
|
|
|
sram3 = $5F8+slot
|
|
|
|
sram4 = $678+slot
|
|
|
|
sram5 = $6F8+slot
|
|
|
|
sram6 = $778+slot
|
|
|
|
sram7 = $7F8+slot
|
2019-05-13 13:11:26 +00:00
|
|
|
|
|
|
|
;ProDOS defines
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
command = $42 ;ProDOS command
|
|
|
|
unit = $43 ;7=drive 6-4=slot 3-0=not used
|
|
|
|
buflo = $44 ;low address of buffer
|
|
|
|
bufhi = $45 ;hi address of buffer
|
|
|
|
blklo = $46 ;low block
|
|
|
|
blkhi = $47 ;hi block
|
|
|
|
ioerr = $27 ;I/O error code
|
|
|
|
nodev = $28 ;no device connected
|
|
|
|
wperr = $2B ;write protect error
|
|
|
|
|
|
|
|
.org $C000+slot*$100
|
2019-05-13 13:11:26 +00:00
|
|
|
;code is non-relocatable
|
|
|
|
; but duplicated seven times,
|
|
|
|
; once for each slot
|
|
|
|
|
|
|
|
;ID bytes for booting and drive detection
|
|
|
|
cpx #$20 ;ID bytes for ProDOS and the
|
|
|
|
cpx #$00 ; Apple Autostart ROM
|
|
|
|
cpx #$03 ;
|
|
|
|
cpx #$3C ;this one for older II's
|
|
|
|
|
|
|
|
;display copyright message
|
|
|
|
ldy #$00
|
2020-12-01 02:36:10 +00:00
|
|
|
drawtxt: lda text,y
|
2019-05-13 13:11:26 +00:00
|
|
|
beq boot ;check for NULL
|
|
|
|
ora #$80 ;make it visible to the Apple
|
|
|
|
sta $07D0,y ;put text on last line
|
|
|
|
iny
|
|
|
|
bpl drawtxt
|
|
|
|
|
|
|
|
;load first two blocks and execute to boot
|
2020-12-01 02:36:10 +00:00
|
|
|
boot: lda #$01 ;set read command
|
2019-05-13 13:11:26 +00:00
|
|
|
sta command
|
|
|
|
lda #sdrive ;set slot and unit
|
|
|
|
sta unit
|
|
|
|
|
|
|
|
lda #$00 ;block 0
|
|
|
|
sta blklo
|
|
|
|
sta blkhi
|
|
|
|
sta buflo ;buffer at $800
|
|
|
|
lda #$08
|
|
|
|
sta bufhi
|
|
|
|
jsr entry ;get the block
|
|
|
|
|
|
|
|
ldx #sdrive ;set up for slot n
|
|
|
|
jmp $801 ;execute the block
|
|
|
|
|
|
|
|
;This is the ProDOS entry point for this card
|
2020-12-01 02:36:10 +00:00
|
|
|
entry: lda #sdrive ;unit number is $n0 - n = slot
|
2019-05-13 13:11:26 +00:00
|
|
|
cmp unit ;make sure same as ProDOS
|
|
|
|
beq docmd ;yep, do command
|
|
|
|
sec ;nope, set device not connected
|
|
|
|
lda #nodev
|
|
|
|
rts ;go back to ProDOS
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
docmd: lda command ;get ProDOS command
|
2019-05-13 13:11:26 +00:00
|
|
|
beq getstat ;command 0 is GetStatus
|
|
|
|
cmp #$01 ;
|
|
|
|
beq readblk ;command 1 is ReadBlock
|
|
|
|
sec ;Format/Write not permitted
|
|
|
|
lda #wperr ;write protect error
|
|
|
|
rts ;go back to ProDOS
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
getstat: clc ;send back status
|
2019-05-13 13:11:26 +00:00
|
|
|
lda #$00 ;good status
|
|
|
|
ldx #$00 ;1024 blocks
|
|
|
|
ldy #$04 ;
|
|
|
|
rts
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
readblk: lda blkhi ;get hi block
|
2019-05-13 13:11:26 +00:00
|
|
|
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
|
|
|
|
;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
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
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
|
2020-12-01 02:36:10 +00:00
|
|
|
get256: ldy #$00 ;clear buffer counter
|
2019-05-13 13:11:26 +00:00
|
|
|
lda sram0 ;get high latch value
|
|
|
|
sta slotwh ;set high latch for card
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
loop256: ldx #$00 ;clear port counter
|
2019-05-13 13:11:26 +00:00
|
|
|
lda sram1 ;get low latch value
|
|
|
|
sta slotwl ;set low latch
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
loop16: lda slotrd,x ;get a byte
|
2019-05-13 13:11:26 +00:00
|
|
|
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
|
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
text: .byte "ROM-Drive (c)1998-2019 Terence J. Boldt", 0
|
2019-05-13 13:11:26 +00:00
|
|
|
|
2020-12-01 02:36:10 +00:00
|
|
|
; These bytes need to be at the top of the 256 byte firmware as ProDOS
|
|
|
|
; uses these to find the entry point and drive capabilities
|
|
|
|
|
|
|
|
; In 1998, cc65 used to allow this but now with ld65 removes the padded bytes
|
|
|
|
; .org $C0FC+slot*$100
|
|
|
|
|
|
|
|
; CAUTION: These are padding bytes entered manually, add or remove
|
|
|
|
; to match if changing code. Firmware must be 256 bytes
|
|
|
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
|
|
|
|
|
|
.byte 0,0 ;0000 blocks = check status
|
|
|
|
.byte 3 ;bit 0=read 1=status
|
|
|
|
.byte entry&$00FF ;low byte of entry
|
2019-05-13 13:11:26 +00:00
|
|
|
|