a2-liron/liron-if.asm

1483 lines
22 KiB
NASM
Raw Normal View History

2018-02-21 19:04:13 +00:00
; Apple II UniDisk 3.5 (Liron) disk interface card firmware
2018-02-11 22:12:00 +00:00
; Firmware P/N 341-????
2018-03-06 18:33:38 +00:00
; Copyright 1985 Apple Computer, Inc.
; Disassembly copyright 2018 Eric Smith <spacewar@gmail.com>
2018-02-11 22:12:00 +00:00
cpu 6502
fillto macro addr, val
while * < addr
size set addr-*
if size > 256
size set 256
endif
fcb [size] val
endm
endm
fcchz macro string
irpc char,string
fcb $80+'char'
endm
fcb $00
endm
2018-03-06 21:39:41 +00:00
; SmartPort error codes
stat_no_err equ $00
stat_bad_cmd equ $01
stat_bad_pcnt equ $04
stat_bus_err equ $06
stat_bad_unit equ $11
stat_no_int equ $1f
stat_bad_ctl equ $21
stat_bad_parm equ $22
stat_io_error equ $27 ; ProDOS protocol also
stat_no_drive equ $28 ; ProDOS protocol also
stat_no_write equ $2b ; ProDOS protocol also
stat_bad_block equ $2d
stat_disk_sw equ $2e
stat_offline equ $2f ; ProDOS protocol also
2018-03-06 18:49:24 +00:00
2018-02-15 21:24:01 +00:00
; SmartPort bus commands
sp_cmd_status equ $00
sp_cmd_readblk equ $01 ; block device only
sp_cmd_writeblk equ $02 ; block device only
sp_cmd_format equ $03 ; block device only
sp_cmd_control equ $04
sp_cmd_init equ $05 ; used to assign unit number
sp_cmd_open equ $06 ; character device only
sp_cmd_close equ $07 ; character device only
sp_cmd_read equ $08 ; character device only
sp_cmd_write equ $09 ; character device only
Z00 equ $00
Z01 equ $01
mon_ch equ $24
mon_cv equ $25
checksum equ $40
Z40 equ $40
Z41 equ $41
prodos_cmd_blk equ $42
prodos_command equ $42 ; Smartport command is also copied here
prodos_unit_num equ $43
prodos_buffer equ $44
prodos_block equ $46
Z48 equ $48
2018-03-06 18:33:38 +00:00
group_count equ $4b ; count of seven-byte groups
odd_byte_count equ $4c ; count of "odd bytes"
Z4d equ $4d ; rx packet data status byte
Z4e equ $4e ; rx packet aux type
Z4f equ $4f ; rx packet type
Z50 equ $50 ; rx packet source ID
Z51 equ $51 ; rx packet destination ID
Z52 equ $52
Z53 equ $53
2018-03-06 18:33:38 +00:00
Z54 equ $54
Z56 equ $56
2018-03-06 18:33:38 +00:00
slot equ $58
Z59 equ $59
2018-03-06 18:33:38 +00:00
Z5a equ $5a ; destination ID
Z5b equ $5b ; packet type
2018-02-11 22:12:00 +00:00
; per-slot screen holes (index by slot)
sh_prodos_flag equ $0478 ; MSB = 1 for ProDOS, 0 for SmartPort
2018-03-06 18:49:24 +00:00
sh_retry_cnt_l equ $04f8
2018-03-06 22:47:24 +00:00
sh_status_save1 equ $04f8
2018-03-06 18:49:24 +00:00
sh_retry_cnt_h equ $0578
2018-03-06 22:47:24 +00:00
sh_status_save2 equ $0578 ; save status flag during return sequence
2018-02-12 08:30:19 +00:00
sh_05f8 equ $05f8
sh_0678 equ $0678
sh_magic1 equ $06f8 ; $a5 if firmware initialized
sh_magic2 equ $0778 ; $5a if firmware initialized
2018-03-06 18:49:24 +00:00
sh_unit_count equ $07f8
2018-02-11 22:12:00 +00:00
2018-02-12 08:30:19 +00:00
; global screen holes - undocumented
; these seem to be used as temporaries
gh_06f8 equ $06f8
; note - 06f8 is used by Apple DOS RWTS for RECLBCNT (recal counter),
; not needed between RWTS calls
2018-02-11 22:12:00 +00:00
2018-02-12 08:30:19 +00:00
gh_0778 equ $0778
2018-02-11 22:12:00 +00:00
2018-02-12 08:30:19 +00:00
; global screen holes - documented
gh_shared_slot equ $07f8 ; $Cn if card in slot n $c800 ROM active
; needed for interrupt handling
D0800 equ $0800
L0801 equ $0801
2018-02-11 22:12:00 +00:00
basic_cold equ $e000
mon_sloop equ $faba
mon_vtab equ $fc22
mon_cout equ $fded
mon_setkbd equ $fe89
mon_setvid equ $fe93
iwm_ph_0_off equ $c080
iwm_ph_0_on equ $c081
iwm_ph_1_off equ $c082
iwm_ph_1_on equ $c083
iwm_ph_2_off equ $c084
iwm_ph_2_on equ $c085
iwm_ph_3_off equ $c086
iwm_ph_3_on equ $c087
iwm_motor_off equ $c088
iwm_motor_on equ $c089
iwm_sel_drive_1 equ $c08a
iwm_sel_drive_2 equ $c08b
iwm_q6l equ $c08c
iwm_q6h equ $c08d
iwm_q7l equ $c08e
iwm_q7h equ $c08f
rom_dis equ $cfff
org $c000
2018-02-21 19:04:13 +00:00
; $c000..$cfff is not visible in Apple II address space
fcchz "Firmware written by Michael Askins"
2018-02-11 22:12:00 +00:00
fillto $c100,$ff
; Cnxx slot ROM is replicated for all seven slots, and is identical
; other than slot number references and slot I/O references
irp slotnum, 1, 2, 3, 4, 5, 6, 7
org $c000 + (slotnum << 8)
; firmware boot entry point
ldx #$20
ldx #$00
ldx #$03
cmp #$00
bcs Lcn14
prodos_entry:
sec
bcs Lcn0e
smartport_entry:
clc
; combined ProDOS/SmartPort dispatch
; save ProDOS/SmartPort flag (1 = ProDOS) in MSB of sh_prodos_flag
Lcn0e: ldx #slotnum
ror sh_prodos_flag,x
clc
; combined ProDOS/SmartPort/boot dispatch
; carry = 1 for boot, 0 for ProDOS/SmartPort
Lcn14: ldx #$c0 + slotnum
2018-02-12 08:30:19 +00:00
stx gh_shared_slot
2018-02-11 22:12:00 +00:00
ldx #slotnum
lda rom_dis
jmp shared_rom_entry
2018-03-06 18:33:38 +00:00
; continuation of smartport_bus_read_packet subroutine (in shared ROM)
2018-02-11 22:12:00 +00:00
Lcn21: ldy #$00
2018-03-06 18:33:38 +00:00
lda group_count ; get group count
pha ; and save for later
2018-02-11 22:12:00 +00:00
bne Lcn2b
2018-03-06 18:33:38 +00:00
jmp Lcnb8 ; no groups, skip
2018-02-11 22:12:00 +00:00
2018-03-06 18:33:38 +00:00
; read seven-byte groups
2018-02-11 22:12:00 +00:00
Lcn2b: lda iwm_q6l + (slotnum << 4)
bpl Lcn2b
sta Z59
lsr
lsr
lsr
and #$0f
tax
lda Z59
and #$07
sta Z59
Lcn3e: lda iwm_q6l + (slotnum << 4)
bpl Lcn3e
eor Dca27,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
bne Lcn51
2018-03-06 18:33:38 +00:00
inc Z56+1
2018-02-11 22:12:00 +00:00
Lcn51: lda iwm_q6l + (slotnum << 4)
bpl Lcn51
eor Dca37,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
Lcn60: lda iwm_q6l + (slotnum << 4)
bpl Lcn60
eor Dca47,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
Lcn6f: lda iwm_q6l + (slotnum << 4)
bpl Lcn6f
eor Dca57,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
bne Lcn82
2018-03-06 18:33:38 +00:00
inc Z56+1
2018-02-11 22:12:00 +00:00
Lcn82: ldx Z59
Lcn84: lda iwm_q6l + (slotnum << 4)
bpl Lcn84
eor Dca37,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
Lcn93: lda iwm_q6l + (slotnum << 4)
bpl Lcn93
eor Dca47,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
Lcna2: lda iwm_q6l + (slotnum << 4)
bpl Lcna2
eor Dca57,x
sta (Z56),y
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
iny
2018-03-06 18:33:38 +00:00
dec group_count
2018-02-11 22:12:00 +00:00
beq Lcnb8
jmp Lcn2b
Lcnb8: lda iwm_q6l + (slotnum << 4)
bpl Lcnb8
sta Z59
2018-03-06 18:33:38 +00:00
pla ; restore group count
sta group_count
2018-02-11 22:12:00 +00:00
Lcnc2: lda iwm_q6l + (slotnum << 4)
bpl Lcnc2
sec
rol
and Z59
eor checksum
2018-02-11 22:12:00 +00:00
Lcncd: ldy iwm_q6l + (slotnum << 4)
bpl Lcncd
cpy #$c8
bne Lcnf2
2018-03-06 18:33:38 +00:00
ldx odd_byte_count
2018-02-11 22:12:00 +00:00
beq Lcne2
ldy #$00
Lcndc: eor (Z54),y
iny
dex
bne Lcndc
Lcne2: tax
bne Lcnf6
lda iwm_q6h + (slotnum << 4)
Lcne8: lda iwm_q7l + (slotnum << 4)
bmi Lcne8
lda iwm_ph_0_off + (slotnum << 4)
clc
rts
Lcnf2: lda #$20
bne Lcnf8 ; always taken
Lcnf6: lda #$10
Lcnf8: sec
rts
; fillto slot_fw + $fb, $ff
fcb $ff ; unused
fcb $00 ; SmartPort type
fdb $0000 ; ProDOS block count (status call required)
fcb $bf ; ProDOS characteristics
fcb prodos_entry & $0ff
endm
2018-02-15 23:27:30 +00:00
smartport_bus_write_packet:
jsr Scaee
2018-02-15 20:34:42 +00:00
jsr smartport_bus_enable
2018-02-15 23:27:30 +00:00
ldy #$07 ; bit 0 = 1: latch mode
; bit 1 = 1: asynchronous
; bit 2 = 1: timer disable
; bit 3 = 0: slow mode (4 us bit cell)
; bit 4 = 0: 7 MHz
; bit 5 = 0: normal mode (not test)
; bit 6 = 0: not reset
jsr iwm_write_mode_reg
2018-02-11 22:12:00 +00:00
lda iwm_sel_drive_2,x
lda iwm_motor_on,x
2018-02-15 23:27:30 +00:00
ldy #50
Lc813: lda iwm_q7l,x ; read status reg
bmi Lc81f ; wait for ACK/ deasserted (high)
2018-02-11 22:12:00 +00:00
dey
bne Lc813
sec
jmp Lc949
; send packet sync sequence
2018-02-15 23:27:30 +00:00
Lc81f: lda iwm_ph_0_on,x ; assert REQ
ldy #packet_sync_sequence_len - 1
2018-02-11 22:12:00 +00:00
lda #$ff
sta iwm_q7h,x ; set write mode
Lc829: lda packet_sync_sequence,y
2018-02-11 22:12:00 +00:00
Lc82c: asl iwm_q6l,x
bcc Lc82c
sta iwm_q6h,x
dey
bpl Lc829
lda Z5a ; destination ID
2018-02-11 22:12:00 +00:00
ora #$80
jsr send_nib7
jsr send_80 ; source address, always $80 (host)
lda Z5b ; packet type
jsr send_nib7
jsr send_80 ; aux type
2018-03-06 18:33:38 +00:00
jsr send_80 ; data status byte
2018-03-06 18:33:38 +00:00
lda odd_byte_count ; length of packet "odd bytes", 0-6
2018-02-11 22:12:00 +00:00
ora #$80
jsr send_nib7
2018-03-06 18:33:38 +00:00
lda group_count ; number of encoded 7-byte groups
2018-02-11 22:12:00 +00:00
ora #$80
jsr send_nib7
2018-03-06 18:33:38 +00:00
lda odd_byte_count ; any "odd bytes"?
beq Lc873 ; no, skip
; send "odd bytes"
2018-02-11 22:12:00 +00:00
ldy #$ff
lda Z59
Lc862: asl iwm_q6l,x
bcc Lc862
sta iwm_q6h,x
iny
lda (Z54),y
ora #$80
2018-03-06 18:33:38 +00:00
cpy odd_byte_count
2018-02-11 22:12:00 +00:00
bcc Lc862
; send groups
2018-03-06 18:33:38 +00:00
Lc873: lda group_count ; any groups to send?
bne Lc87a ; yes
jmp send_checksum ; no
2018-02-11 22:12:00 +00:00
Lc87a: nop
ldy #$00
; send a group
2018-02-11 22:12:00 +00:00
Lc87d: lda Z41
sta iwm_q6h,x
lda Z4d
ora #$80
sty Z59
Lc888: ldy iwm_q6l,x
bpl Lc888
sta iwm_q6h,x
ldy Z59
lda (Z56),y
sta Z4d
asl
rol Z41
iny
bne Lc8a1
2018-03-06 18:33:38 +00:00
inc Z56+1
2018-02-11 22:12:00 +00:00
jmp Lc8a3
2018-02-11 22:12:00 +00:00
Lc8a1: pha
pla
Lc8a3: lda #$02
ora Z41
sta Z41
lda Z4e
ora #$80
sta iwm_q6h,x
lda (Z56),y
sta Z4e
asl
rol Z41
iny
lda Z4f
ora #$80
sta iwm_q6h,x
lda (Z56),y
sta Z4f
asl
rol Z41
iny
lda Z50
ora #$80
sta iwm_q6h,x
lda (Z56),y
sta Z50
asl
rol Z41
iny
bne Lc8dd
2018-03-06 18:33:38 +00:00
inc Z56+1
2018-02-11 22:12:00 +00:00
jmp Lc8df
Lc8dd: pha
pla
Lc8df: lda Z51
ora #$80
sta iwm_q6h,x
lda (Z56),y
sta Z51
asl
rol Z41
iny
lda Z52
ora #$80
sta iwm_q6h,x
lda (Z56),y
sta Z52
asl
rol Z41
iny
lda Z53
ora #$80
sta iwm_q6h,x
lda (Z56),y
sta Z53
asl
rol Z41
iny
2018-03-06 18:33:38 +00:00
dec group_count ; sent last group?
beq send_checksum ; yes
jmp Lc87d ; no, send another group
; send checksum in FM
send_checksum:
; send checksum even bits (bit 6, 4, 2, 0)
lda checksum
2018-02-11 22:12:00 +00:00
ora #$aa
; can't call send_nib7 to send the first part of the checksum, because
; it would modify the checksum in the process
Lc917: ldy iwm_q6l,x ; wait for write buffer ready
2018-02-11 22:12:00 +00:00
bpl Lc917
sta iwm_q6h,x ; write data
; send checksum odd bits (bit 7, 5, 3, 1, shifted right one bit)
lda checksum
2018-02-11 22:12:00 +00:00
lsr
ora #$aa
jsr send_nib7
lda #$c8 ; send packet end mark
jsr send_nib7
; wait for write underrun; IWM write state will clear when
; done writing and no data presented
Lc92c: lda iwm_q6l,x ; read IWM handshake register
and #$40 ; in write state?
bne Lc92c ; yes, loop
sta iwm_q6h,x ; prepare to read status register
ldy #$0a ; counter to wait for ACK
Lc938: dey ; timeout?
bne Lc943 ; no, go check status
2018-02-11 22:12:00 +00:00
lda #$01
Sc93d: jsr get_slot_x
sec ; indicate error
bcs Lc949 ; always taken
2018-02-11 22:12:00 +00:00
Lc943: lda iwm_q7l,x ; read status
2018-02-15 23:27:30 +00:00
bmi Lc938 ; ACK asserted (low)? if not, keep waiting
clc ; yes, so no error
2018-02-15 23:27:30 +00:00
Lc949: lda iwm_ph_0_off,x ; deassert REQ
2018-02-11 22:12:00 +00:00
lda iwm_q6l,x
rts
; packet sync byte sequence, in reverse order
packet_sync_sequence:
fcb $c3,$ff,$fc,$f3,$cf,$3f
packet_sync_sequence_len equ *-packet_sync_sequence
2018-02-11 22:12:00 +00:00
2018-03-06 18:33:38 +00:00
; delay routine - unused?
2018-02-11 22:12:00 +00:00
jsr Sc95b
nop
nop
Sc95b: nop
rts
2018-03-06 18:33:38 +00:00
2018-02-11 22:12:00 +00:00
Lc95d: jmp Sc93d
2018-02-15 23:27:30 +00:00
2018-03-06 18:33:38 +00:00
; on entry, Z54
smartport_bus_read_packet: lda #$00
sta checksum
2018-03-06 18:33:38 +00:00
; copy buffer pointer to group pointer
2018-02-11 22:12:00 +00:00
lda Z54
sta Z56
2018-03-06 18:33:38 +00:00
lda Z54+1
sta Z56+1
2018-02-11 22:12:00 +00:00
2018-03-06 18:33:38 +00:00
; point Z52 at LCn21 for later continuation of execution
lda #$21
2018-02-11 22:12:00 +00:00
sta Z52
lda slot
clc
adc #$c0
sta Z53
2018-02-15 20:34:42 +00:00
jsr smartport_bus_enable
2018-02-11 22:12:00 +00:00
lda iwm_q6h,x
2018-02-15 23:27:30 +00:00
Lc97d: lda iwm_q7l,x ; read status
2018-02-11 22:12:00 +00:00
bpl Lc97d
lda iwm_ph_0_on,x
2018-02-15 23:27:30 +00:00
ldy #30 ; need a $c3 sync byte in first 30 nibbles
Lc987: lda iwm_q6l,x ; read a nibble
bpl Lc987 ; loop if don't have a nibble yet
dey ; too many attempts?
bmi Lc95d ; yes, report error
cmp #$c3 ; is it the sync byte?
bne Lc987 ; loop if not
2018-03-06 18:33:38 +00:00
ldy #$06 ; read first six nibbles of packet
2018-02-15 23:27:30 +00:00
Lc995: lda iwm_q6l,x ; read a nibble
bpl Lc995 ; loop if don't have a nibble yet
2018-02-11 22:12:00 +00:00
and #$7f
2018-03-06 18:33:38 +00:00
sta group_count,y ; store in reverse order
2018-02-11 22:12:00 +00:00
eor #$80
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
dey
bpl Lc995
2018-02-15 23:27:30 +00:00
2018-03-06 18:33:38 +00:00
lda odd_byte_count ; any odd bytes?
beq Lc9d3 ; no
clc ; advance group pointer by number of odd bytes
2018-02-11 22:12:00 +00:00
adc Z54
sta Z56
2018-03-06 18:33:38 +00:00
lda Z54+1
2018-02-11 22:12:00 +00:00
adc #$00
2018-03-06 18:33:38 +00:00
sta Z56+1
2018-02-15 23:27:30 +00:00
2018-03-06 18:33:38 +00:00
; receive "odd bytes"
2018-02-11 22:12:00 +00:00
ldy #$00
Lc9b9: lda iwm_q6l,x
bpl Lc9b9
asl
sta Z41
Lc9c1: lda iwm_q6l,x
bpl Lc9c1
asl Z41
bcs Lc9cc
eor #$80
Lc9cc: sta (Z54),y
iny
2018-03-06 18:33:38 +00:00
cpy odd_byte_count
2018-02-11 22:12:00 +00:00
bcc Lc9c1
2018-03-06 18:33:38 +00:00
2018-02-15 20:34:42 +00:00
Lc9d3: jmp (Z52) ; continue from slot ROM space
2018-02-11 22:12:00 +00:00
send_80:
lda #$80
send_nib7:
ldy iwm_q6l,x
bpl send_nib7
2018-02-11 22:12:00 +00:00
sta iwm_q6h,x
eor checksum
sta checksum
2018-02-11 22:12:00 +00:00
rts
2018-02-15 21:24:01 +00:00
reset_smartport_bus:
jsr smartport_bus_disable
2018-02-11 22:12:00 +00:00
lda iwm_ph_0_on,x
lda iwm_ph_2_on,x
2018-02-15 20:34:42 +00:00
2018-02-15 21:24:01 +00:00
ldy #80 ; delay 80ms
2018-02-15 20:34:42 +00:00
jsr delay_y_ms
jsr smartport_bus_disable
2018-02-15 21:24:01 +00:00
ldy #10 ; delay 10ms and return
2018-02-11 22:12:00 +00:00
2018-02-15 20:34:42 +00:00
delay_y_ms:
jsr delay_1ms
2018-02-11 22:12:00 +00:00
dey
2018-02-15 20:34:42 +00:00
bne delay_y_ms
2018-02-11 22:12:00 +00:00
rts
2018-02-15 20:34:42 +00:00
delay_1ms:
2018-02-15 21:24:01 +00:00
ldx #200
2018-02-15 20:34:42 +00:00
delay_1ms_loop:
dex
bne delay_1ms_loop
2018-02-11 22:12:00 +00:00
rts
2018-02-15 20:34:42 +00:00
smartport_bus_enable:
jsr get_slot_x
2018-02-11 22:12:00 +00:00
lda iwm_ph_1_on,x
lda iwm_ph_3_on,x
rts
2018-02-15 20:34:42 +00:00
smartport_bus_disable:
jsr get_slot_x
2018-02-11 22:12:00 +00:00
lda iwm_ph_0_off,x
lda iwm_ph_1_off,x
lda iwm_ph_2_off,x
lda iwm_ph_3_off,x
rts
get_slot_x:
lda slot
2018-02-11 22:12:00 +00:00
asl
asl
asl
asl
tax
rts
Dca27: fcb $80,$80,$80,$80,$80,$80,$80,$80
fcb $00,$00,$00,$00,$00,$00,$00,$00
Dca37: fcb $80,$80,$80,$80,$00,$00,$00,$00
fcb $80,$80,$80,$80,$00,$00,$00,$00
Dca47: fcb $80,$80,$00,$00,$80,$80,$00,$00
fcb $80,$80,$00,$00,$80,$80,$00,$00
Dca57: fcb $80,$00,$80,$00,$80,$00,$80,$00
fcb $80,$00,$80,$00,$80,$00,$80,$00
Sca67: lda #$05
ldy #$00
jsr Sca8a
bcc Lca75
lda #$80
jsr Scded
Lca75: rts
Sca76: jsr Sca8a
bcc Lca75
lda #$80
jsr Scded
2018-02-11 22:12:00 +00:00
lda gh_06f8
sta Z4d
lda gh_0778
sta Z4e
Sca8a: lda #3000 & $ff ; retry 3000 times!
ldy #3000 >> 8
2018-02-11 22:12:00 +00:00
ldx slot
2018-03-06 18:49:24 +00:00
sta sh_retry_cnt_l,x
2018-02-11 22:12:00 +00:00
tya
2018-03-06 18:49:24 +00:00
sta sh_retry_cnt_h,x
2018-02-11 22:12:00 +00:00
Lca97: lda Z4d
sta gh_06f8
lda Z4e
sta gh_0778
2018-02-15 23:27:30 +00:00
jsr smartport_bus_write_packet
2018-02-11 22:12:00 +00:00
lda gh_06f8
sta Z4d
lda gh_0778
sta Z4e
bcc Lcabc ; if no error, done
ldx slot ; decrement retry count
2018-03-06 18:49:24 +00:00
dec sh_retry_cnt_l,x
2018-02-11 22:12:00 +00:00
bne Lca97
2018-03-06 18:49:24 +00:00
dec sh_retry_cnt_h,x
2018-02-11 22:12:00 +00:00
bpl Lca97
2018-02-11 22:12:00 +00:00
Lcabc: rts
2018-03-06 18:49:24 +00:00
smartport_bus_read_packet_with_retries:
ldy slot
2018-02-11 22:12:00 +00:00
lda #$05
2018-03-06 18:49:24 +00:00
sta sh_retry_cnt_l,y
2018-03-06 18:33:38 +00:00
Lcac4: jsr smartport_bus_read_packet
2018-03-06 18:49:24 +00:00
bcc Lcad8 ; good?
2018-02-15 20:34:42 +00:00
2018-02-15 21:24:01 +00:00
ldy #1
2018-02-15 20:34:42 +00:00
jsr delay_y_ms
2018-02-11 22:12:00 +00:00
jsr Sc93d
ldx slot
2018-03-06 18:49:24 +00:00
dec sh_retry_cnt_l,x
2018-02-11 22:12:00 +00:00
bne Lcac4
2018-03-06 18:49:24 +00:00
2018-02-11 22:12:00 +00:00
Lcad8: rts
2018-02-15 23:27:30 +00:00
; Tables of quotients and remainders from dividing multiples of 256 (page size)
; by 7, from 0 to 2.
page_div_7_tab:
fcb $0000/7, $0100/7, $0200/7
page_rem_7_tab:
fcb $0000#7, $0100#7, $0200#7
; Tables of quotients and remainders from dividing powers of 2, from 3 to 7,
; by 7. Entry 0 not used
pow2_div_7:
fcb $00/7, $08/7, $10/7, $20/7, $40/7, $80/7 ; quotients
pow2_rem_7:
fcb $00#7, $08#7, $10#7, $20#7, $40#7, $80#7 ; remainder
2018-02-11 22:12:00 +00:00
Dcaeb: fcb $00,$7f,$ff
2018-02-15 23:27:30 +00:00
; prepare for transmitting a packet, including computing the
; number of 7-byte groups and the number of "odd bytes"
Scaee: ldx Z4e ; high byte of length
2018-02-11 22:12:00 +00:00
beq Lcb05
2018-03-06 18:33:38 +00:00
lda Z54+1
sta Z56+1
2018-02-11 22:12:00 +00:00
lda #$80
cpx #$01
beq Lcb00
2018-03-06 18:33:38 +00:00
inc Z56+1
2018-02-11 22:12:00 +00:00
lda #$00
Lcb00: clc
adc Z54
sta Z56
2018-02-15 23:27:30 +00:00
; divide high byte of length by 7 using table lookup
Lcb05: lda page_div_7_tab,x
2018-03-06 18:33:38 +00:00
sta group_count
2018-02-15 23:27:30 +00:00
lda page_rem_7_tab,x
2018-03-06 18:33:38 +00:00
sta odd_byte_count
2018-02-15 23:27:30 +00:00
ldx #$05 ; start table lookup at entry for 2^7
lda Z4d ; copy low byte of length
sta Z59 ; to temp
; convert and add low byte of lenght divided by 7, using table
; lookup for each bit position from 2^7 down to 2^3
2018-02-11 22:12:00 +00:00
and #$07
tay
Lcb18: asl Z59
bcc Lcb31
2018-02-15 23:27:30 +00:00
lda pow2_rem_7,x
2018-02-11 22:12:00 +00:00
Lcb1f: clc
2018-03-06 18:33:38 +00:00
adc odd_byte_count
2018-02-11 22:12:00 +00:00
cmp #$07
bcc Lcb28
sbc #$07
2018-03-06 18:33:38 +00:00
Lcb28: sta odd_byte_count
2018-02-15 23:27:30 +00:00
lda pow2_div_7,x
2018-03-06 18:33:38 +00:00
adc group_count
sta group_count
2018-02-15 23:27:30 +00:00
2018-02-11 22:12:00 +00:00
Lcb31: dex
bmi Lcb3a
bne Lcb18
tya
jmp Lcb1f
2018-02-15 23:27:30 +00:00
2018-03-06 18:33:38 +00:00
Lcb3a: lda Z54+1
2018-02-11 22:12:00 +00:00
pha
lda #$00
ldx Z4e
beq Lcb59
ldy Dcaeb,x
Lcb46: eor (Z54),y
eor (Z56),y
dey
bne Lcb46
eor (Z54),y
eor (Z56),y
cpx #$01
beq Lcb57
2018-03-06 18:33:38 +00:00
inc Z54+1
Lcb57: inc Z54+1
2018-02-11 22:12:00 +00:00
Lcb59: ldy Z4d
beq Lcb66
eor (Z54),y
Lcb5f: eor (Z54),y
dey
bne Lcb5f
eor (Z54),y
Lcb66: sta checksum
2018-02-11 22:12:00 +00:00
pla
2018-03-06 18:33:38 +00:00
sta Z54+1
ldy odd_byte_count
2018-02-11 22:12:00 +00:00
dey
lda #$00
sta Z59
Lcb72: lda (Z54),y
asl
ror Z59
dey
bpl Lcb72
sec
ror Z59
2018-03-06 18:33:38 +00:00
lda odd_byte_count
2018-02-11 22:12:00 +00:00
clc
adc Z54
sta Z56
2018-03-06 18:33:38 +00:00
lda Z54+1
2018-02-11 22:12:00 +00:00
adc #$00
2018-03-06 18:33:38 +00:00
sta Z56+1
2018-02-11 22:12:00 +00:00
ldy #$06
Lcb8c: sec
lda (Z56),y
sta Z4d,y
bmi Lcb95
clc
Lcb95: ror Z41
dey
bpl Lcb8c
sec
ror Z41
lda Z56
clc
adc #$07
sta Z56
bcc Lcba8
2018-03-06 18:33:38 +00:00
inc Z56+1
2018-02-11 22:12:00 +00:00
Lcba8: rts
2018-02-15 23:27:30 +00:00
; returns with q6h, q7l
iwm_write_mode_reg:
lda iwm_motor_off,x
2018-02-11 22:12:00 +00:00
lda iwm_q6h,x
jmp Lcbb6
2018-02-15 23:27:30 +00:00
2018-02-11 22:12:00 +00:00
Lcbb2: tya
2018-02-15 23:27:30 +00:00
sta iwm_q7h,x ; write mode reg
2018-02-11 22:12:00 +00:00
Lcbb6: tya
2018-02-15 23:27:30 +00:00
eor iwm_q7l,x ; compare to low 5 bits of status reg
2018-02-11 22:12:00 +00:00
and #$1f
bne Lcbb2
rts
2018-02-15 23:27:30 +00:00
2018-03-06 18:33:38 +00:00
Scbbf: lda group_count
2018-02-11 22:12:00 +00:00
tay
ldx #$00
2018-03-06 18:33:38 +00:00
stx group_count
2018-02-11 22:12:00 +00:00
ldx #$03
Lcbc8: asl
2018-03-06 18:33:38 +00:00
rol group_count
2018-02-11 22:12:00 +00:00
dex
bne Lcbc8
clc
2018-03-06 18:33:38 +00:00
adc odd_byte_count
2018-02-11 22:12:00 +00:00
bcc Lcbd5
2018-03-06 18:33:38 +00:00
inc group_count
Lcbd5: sty odd_byte_count
2018-02-11 22:12:00 +00:00
sec
2018-03-06 18:33:38 +00:00
sbc odd_byte_count
2018-02-11 22:12:00 +00:00
bcs Lcbde
2018-03-06 18:33:38 +00:00
dec group_count
Lcbde: ldy group_count
2018-02-11 22:12:00 +00:00
rts
shared_rom_entry:
bcc execute_command
jmp boot
execute_command:
cld
txa
tay
lda sh_prodos_flag,y ; ProDOS or SmartPort?
bmi Lcbff
2018-02-15 21:24:01 +00:00
; SmartPort only
2018-02-11 22:12:00 +00:00
pla ; save ptr to SmartPort cmd num (offset 1)
sta sh_05f8,y
clc ; advance past cmd num and parm list ptr (low byte)
adc #$03
tax
pla ; save ptr to SmartPort cmd num (offset 1)
sta sh_0678,y
adc #$00 ; advance past cmd num and parm list ptr (high byte)
pha ; push advanced return address back onto stack
txa
pha
2018-02-15 21:24:01 +00:00
; continue here whether SmartPort or ProDOS
2018-02-11 22:12:00 +00:00
Lcbff: php
sei
2018-02-15 21:24:01 +00:00
; save zero page $40..$5b onto stack
2018-02-11 22:12:00 +00:00
ldx #$1b
Lcc03: lda Z40,x
pha
dex
bpl Lcc03
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
sty slot
2018-02-12 08:30:19 +00:00
lda sh_magic1,y ; has card been initialized?
2018-02-11 22:12:00 +00:00
cmp #$a5
bne Lcc19
eor #$ff
2018-02-12 08:30:19 +00:00
eor sh_magic2,y
2018-02-11 22:12:00 +00:00
beq Lcc1e
2018-02-12 08:30:19 +00:00
2018-02-11 22:12:00 +00:00
Lcc19: lda #$00
jsr Scded
Lcc1e: lda prodos_unit_num
2018-02-11 22:12:00 +00:00
rol
php
rol
rol
plp
rol
and #$03
eor #$02
cpy #$04
bcs Lcc30
eor #$02
Lcc30: tax
inx
stx prodos_unit_num
2018-02-11 22:12:00 +00:00
lda sh_prodos_flag,y ; ProDOS or SmartPort?
bpl Lcc3c
jmp Lcccf
; SmartPort command, convert it into a ProDOS command
2018-02-11 22:12:00 +00:00
Lcc3c: lda sh_05f8,y ; set Z54 to point to cmd num -1
sta Z54
lda sh_0678,y
2018-03-06 18:33:38 +00:00
sta Z54+1
2018-02-11 22:12:00 +00:00
ldy #$01 ; copy SmartPort command
2018-02-11 22:12:00 +00:00
lda (Z54),y
sta prodos_command
2018-02-11 22:12:00 +00:00
iny
lda (Z54),y ; copy SmartPort arg list pointer to Z54
tax
iny
lda (Z54),y
2018-03-06 18:33:38 +00:00
sta Z54+1
2018-02-11 22:12:00 +00:00
stx Z54
2018-03-06 21:39:41 +00:00
lda #stat_bad_cmd
2018-02-11 22:12:00 +00:00
ldx prodos_command ; SmartPort command in range ($00 to $09)?
2018-02-11 22:12:00 +00:00
cpx #$0a
bcc Lcc62
Lcc5f: jmp Lcd9f
Lcc62: ldy #$00
lda (Z54),y
sta Z5a
2018-02-11 22:12:00 +00:00
ldy #$08
Lcc6a: lda (Z54),y
sta prodos_cmd_blk,y
2018-02-11 22:12:00 +00:00
dey
bne Lcc6a
lda prodos_unit_num
2018-02-11 22:12:00 +00:00
bne Lcccf
ldx prodos_command
2018-03-06 22:47:24 +00:00
lda expected_param_cnt_tbl,x
2018-02-11 22:12:00 +00:00
and #$7f
tay
2018-03-06 22:47:24 +00:00
lda #stat_bad_pcnt
2018-02-11 22:12:00 +00:00
cpy Z5a
bne Lcc5f
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
cpx #$05
bne Lcc92
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
lda #$00
jsr Scded
Lcc8d: lda #$00
jmp Lcdc1
2018-03-06 21:39:41 +00:00
2018-02-11 22:12:00 +00:00
Lcc92: txa
bne Lccb8
lda #$21
ldx prodos_block
2018-02-11 22:12:00 +00:00
bne Lcc5f
txa
ldx slot
ldy #$07
Lcca0: sta (prodos_buffer),y
2018-02-11 22:12:00 +00:00
dey
bne Lcca0
2018-03-06 18:49:24 +00:00
lda sh_unit_count,x
sta (prodos_buffer),y
2018-02-11 22:12:00 +00:00
iny
lda #$00
sta (prodos_buffer),y
2018-02-11 22:12:00 +00:00
lda #$08
dey
jsr Sce4f
jmp Lcc8d
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
Lccb8: cmp #$04
bne Lccc7
ldx prodos_block
2018-02-11 22:12:00 +00:00
beq Lcccb
dex
beq Lcccb
2018-03-06 21:39:41 +00:00
lda #stat_bad_ctl
2018-02-11 22:12:00 +00:00
Lccc5: bne Lcc5f
2018-03-06 21:39:41 +00:00
Lccc7: lda #stat_bad_unit
2018-02-11 22:12:00 +00:00
bne Lcc5f
2018-03-06 21:39:41 +00:00
Lcccb: lda #stat_no_int
2018-02-11 22:12:00 +00:00
bne Lcc5f
; ProDOS
2018-03-06 21:39:41 +00:00
Lcccf: lda #stat_no_drive
2018-02-11 22:12:00 +00:00
ldy slot
2018-03-06 18:49:24 +00:00
ldx sh_unit_count,y
cpx prodos_unit_num
2018-02-11 22:12:00 +00:00
bcc Lccc5
lda #$09
sta Z4d
lda #$00
sta Z4e
2018-03-06 18:33:38 +00:00
sta Z54+1
2018-02-11 22:12:00 +00:00
lda #$42
sta Z54
ldx slot
2018-02-11 22:12:00 +00:00
lda sh_prodos_flag,x ; ProDOS or SmartPort?
bpl Lcd02
ldx prodos_command
2018-03-06 22:47:24 +00:00
lda expected_param_cnt_tbl,x
2018-02-11 22:12:00 +00:00
and #$7f
sta Z5a
lda #$00
sta Z48
lda prodos_command
2018-02-11 22:12:00 +00:00
bne Lcd02
sta prodos_block
2018-02-11 22:12:00 +00:00
Lcd02: lda Z5a
ldx prodos_unit_num
2018-02-11 22:12:00 +00:00
stx Z5a
sta prodos_unit_num
2018-02-11 22:12:00 +00:00
lda #$80
sta Z5b
2018-02-15 20:34:42 +00:00
jsr smartport_bus_disable
2018-02-11 22:12:00 +00:00
jsr Sca76
2018-03-06 22:47:24 +00:00
bcs bus_err
lda prodos_buffer
2018-02-11 22:12:00 +00:00
sta Z54
lda prodos_buffer+1
2018-03-06 18:33:38 +00:00
sta Z54+1
ldx prodos_command
2018-03-06 22:47:24 +00:00
lda expected_param_cnt_tbl,x
2018-02-11 22:12:00 +00:00
bpl Lcd60
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
cpx #$04
bne Lcd41
ldy #$01
lda (Z54),y
tax
dey
lda (Z54),y
pha
clc
lda #$02
adc Z54
sta Z54
pla
bcc Lcd4f
2018-03-06 18:33:38 +00:00
inc Z54+1
2018-02-11 22:12:00 +00:00
jmp Lcd4f
Lcd41: cpx #$02
bne Lcd4b
lda #$00
ldx #$02
bne Lcd4f
Lcd4b: ldx prodos_block+1
lda prodos_block
2018-02-11 22:12:00 +00:00
Lcd4f: stx Z4e
sta Z4d
lda #$82
sta Z5b
jsr Sca67
bcc Lcd60
2018-03-06 21:39:41 +00:00
2018-03-06 22:47:24 +00:00
bus_err:
lda #stat_bus_err
2018-02-11 22:12:00 +00:00
bne Lcd9f
2018-02-11 22:12:00 +00:00
Lcd60: ldy slot
lda sh_prodos_flag,y ; ProDOS or SmartPort?
bpl Lcd73
lda prodos_command
2018-02-11 22:12:00 +00:00
bne Lcd73
2018-03-06 18:49:24 +00:00
2018-02-11 22:12:00 +00:00
lda #$45
ldx #$00
sta Z54
2018-03-06 18:33:38 +00:00
stx Z54+1
2018-03-06 18:49:24 +00:00
Lcd73: jsr smartport_bus_read_packet_with_retries
2018-03-06 22:47:24 +00:00
bcs bus_err
2018-03-06 18:49:24 +00:00
2018-02-11 22:12:00 +00:00
jsr Scbbf
jsr Sce4f
2018-03-06 18:49:24 +00:00
lda prodos_command
2018-02-11 22:12:00 +00:00
bne Lcd9d
2018-03-06 18:49:24 +00:00
2018-02-11 22:12:00 +00:00
ldx slot
lda sh_prodos_flag,x ; ProDOS or SmartPort?
bpl Lcd9d
; ProDOS
lda prodos_block
2018-02-11 22:12:00 +00:00
sta sh_05f8,x
lda prodos_block+1
2018-02-11 22:12:00 +00:00
sta sh_0678,x
2018-02-15 21:24:01 +00:00
lda prodos_buffer+1
2018-02-11 22:12:00 +00:00
and #$10
bne Lcd9d
2018-02-15 21:24:01 +00:00
2018-03-06 21:39:41 +00:00
lda #stat_offline
2018-02-11 22:12:00 +00:00
bne Lcd9f
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
Lcd9d: lda Z4d
Lcd9f: ldy slot
2018-03-06 22:47:24 +00:00
sta sh_status_save1,y
2018-02-11 22:12:00 +00:00
tax
beq Lcdc1
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
ldx sh_prodos_flag,y ; ProDOS or SmartPort?
bpl Lcdc1
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
ldx #$00
cmp #$40
bcs Lcdc0
2018-02-15 21:24:01 +00:00
2018-03-06 21:39:41 +00:00
ldx #stat_io_error ; default result
cmp #stat_no_write
2018-02-11 22:12:00 +00:00
beq Lcdc1
2018-02-15 21:24:01 +00:00
2018-03-06 21:39:41 +00:00
cmp #stat_no_drive
2018-02-11 22:12:00 +00:00
beq Lcdc1
2018-02-15 21:24:01 +00:00
2018-03-06 21:39:41 +00:00
cmp #stat_offline
2018-02-11 22:12:00 +00:00
beq Lcdc1
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
Lcdc0: txa
2018-03-06 21:39:41 +00:00
2018-02-11 22:12:00 +00:00
Lcdc1: ldy slot
2018-03-06 22:47:24 +00:00
sta sh_status_save2,y
2018-02-15 21:24:01 +00:00
; restore zero page $40..$5b from stack
2018-02-11 22:12:00 +00:00
ldx #$00
Lcdc8: pla
sta Z40,x
inx
cpx #$1c
bcc Lcdc8
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
plp
lda sh_05f8,y
tax
2018-03-06 22:47:24 +00:00
lda sh_status_save2,y
2018-02-11 22:12:00 +00:00
pha
lda sh_0678,y
tay
clc
pla
beq Lcde2
sec
Lcde2: rts
2018-03-06 22:47:24 +00:00
expected_param_cnt_tbl:
fcb $03 ; status
fcb $03 ; readblk
fcb $83 ; writeblk
fcb $01 ; format
fcb $83 ; control
fcb $01 ; init
fcb $01 ; open
fcb $01 ; close
fcb $03 ; read
fcb $83 ; write
2018-02-11 22:12:00 +00:00
Scded: pha
2018-02-15 21:24:01 +00:00
jsr reset_smartport_bus
2018-02-11 22:12:00 +00:00
pla
tax
2018-02-15 21:24:01 +00:00
lda prodos_command
2018-02-11 22:12:00 +00:00
pha
lda prodos_unit_num
2018-02-11 22:12:00 +00:00
pha
lda prodos_block
2018-02-11 22:12:00 +00:00
pha
2018-02-15 21:24:01 +00:00
stx prodos_block
2018-02-15 21:24:01 +00:00
lda #sp_cmd_init
sta prodos_command
2018-02-11 22:12:00 +00:00
lda #$00
sta Z5a
lda #$02
sta prodos_unit_num
2018-02-11 22:12:00 +00:00
lda #$42
sta Z54
lda #$00
2018-03-06 18:33:38 +00:00
sta Z54+1
2018-02-11 22:12:00 +00:00
lda #$80
sta Z5b
2018-02-15 20:34:42 +00:00
jsr smartport_bus_disable
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
Lce19: inc Z5a
lda #$09
sta Z4d
lda #$00
sta Z4e
2018-02-15 23:27:30 +00:00
jsr smartport_bus_write_packet ; send init command
2018-02-11 22:12:00 +00:00
bcc Lce2d
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
dec Z5a
jmp Lce34
2018-02-15 21:24:01 +00:00
2018-03-06 18:33:38 +00:00
Lce2d: jsr smartport_bus_read_packet
2018-02-11 22:12:00 +00:00
lda Z4d
beq Lce19
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
Lce34: lda Z5a
ldy slot
2018-03-06 18:49:24 +00:00
sta sh_unit_count,y
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
pla
sta prodos_block
2018-02-11 22:12:00 +00:00
pla
sta prodos_unit_num
2018-02-11 22:12:00 +00:00
pla
sta prodos_command
2018-02-12 08:30:19 +00:00
lda #$a5 ; mark firmware as initialized
sta sh_magic1,y
2018-02-11 22:12:00 +00:00
eor #$ff
2018-02-12 08:30:19 +00:00
sta sh_magic2,y
2018-02-11 22:12:00 +00:00
rts
2018-02-15 21:24:01 +00:00
2018-02-11 22:12:00 +00:00
Sce4f: ldx slot
sta sh_05f8,x
tya
sta sh_0678,x
rts
boot: stx slot
lda #$aa
sta sh_prodos_flag,x ; sets MSB, to indicate use of ProDOS protocol
2018-02-12 08:30:19 +00:00
sta sh_magic1,x ; mark firmware not initialized
2018-02-11 22:12:00 +00:00
; copy boot_prodos_command_block into zero page for use
ldy #boot_prodos_command_block_len - 1
Lce65: lda boot_prodos_command_block,y
sta prodos_cmd_blk,y
2018-02-11 22:12:00 +00:00
dey
bpl Lce65
lda slot
asl
asl
asl
asl
sta prodos_unit_num
2018-02-11 22:12:00 +00:00
jsr execute_command ; read the boot block
bcs boot_error
ldx D0800 ; first byte of boot block must be 1
dex
bne boot_error
ldx L0801 ; second byte of boot block must be non-zero
beq boot_error
lda slot ; jump to boot block entry point
asl ; with slot * 16 in X
asl
asl
asl
tax
jmp L0801
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
boot_error:
jsr mon_setvid
jsr mon_setkbd
ldx Z00
bne Lcea4
ldx Z01
2018-02-12 08:30:19 +00:00
cpx gh_shared_slot
2018-02-11 22:12:00 +00:00
bne Lcea4
jmp mon_sloop
Lcea4: ldx #23 ; bottom line of display
stx mon_cv
2018-02-11 22:12:00 +00:00
jsr mon_vtab
lda #$00
sta mon_ch
2018-02-11 22:12:00 +00:00
ldx #$00
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
ldy slot
2018-03-06 22:47:24 +00:00
lda sh_status_save1,y
2018-02-11 22:12:00 +00:00
bne Lceba
2018-03-06 22:47:24 +00:00
2018-02-11 22:12:00 +00:00
ldx #msg_not_bootable - msg_tab
2018-03-06 21:39:41 +00:00
Lceba: cmp #stat_no_drive
2018-02-11 22:12:00 +00:00
bne Lcec0
ldx #msg_no_dev - msg_tab
2018-03-06 22:47:24 +00:00
2018-03-06 21:39:41 +00:00
Lcec0: cmp #stat_offline
2018-02-11 22:12:00 +00:00
bne Lcec6
ldx #msg_no_disk - msg_tab
; output error message with starting index in X
Lcec6: lda msg_tab,x
beq Lced1
jsr mon_cout
inx
bne Lcec6
Lced1: jmp basic_cold
msg_tab:
fcchz "I/O ERROR"
msg_not_bootable:
fcchz "NOT A BOOTABLE DISK"
msg_no_dev:
fcchz "NO DEVICE CONNECTED"
msg_no_disk:
fcchz "NO DISK TO BOOT"
boot_prodos_command_block:
fcb $01 ; command
fcb $50 ; unit
fdb D0800 ; buffer
fdb 0 ; block number
boot_prodos_command_block_len equ *-boot_prodos_command_block
fillto $cfdb,$ff
2018-02-21 19:04:13 +00:00
fcchz "(C) 1985 Apple Computer, Inc. MSA"
fcb $10
2018-02-11 22:12:00 +00:00
fillto $d000,$ff