a2-3.5cont/apple35cont.asm
2018-02-19 12:00:00 -07:00

8567 lines
101 KiB
NASM

; Apple II 3.5 Disk Controller Card
; Firmware P/N 341-0438A
; Copyright (C) Apple Computer Inc. 1991
; Disassembly Copyright 2014, 2018 Eric Smith <spacewar@gmail.com>
fillto macro addr
while * < addr
size set addr-*
if size > 256
size set 256
endif
fcb [size] $00
endm
endm
fcchz macro string
irpc char,string
fcb $80+'char'
endm
fcb $00
endm
cpu 65c02
D0100 equ $0100
D01ab equ $01ab
D01af equ $01af
D01b1 equ $01b1
D01b2 equ $01b2
D0200 equ $0200
slot_1_rom_copy equ $03ee ; first 16 bytes of host slot 1 ROM copied here
D03fe equ $03fe
D03ff equ $03ff
D0400 equ $0400
D0403 equ $0403
D0500 equ $0500
D0503 equ $0503
D05ff equ $05ff
D0600 equ $0600
D0601 equ $0601
D0602 equ $0602
D0603 equ $0603
D0620 equ $0620
D0640 equ $0640
D06eb equ $06eb
D06ef equ $06ef
D0741 equ $0741
D07eb equ $07eb
D07ef equ $07ef
D0803 equ $0803
D09ff equ $09ff
; SWIM chip - IWM registers
iwm_ph0_off equ $0a00 ; phase 0 off data/corr (r/w)
iwm_ph0_on equ $0a01 ; phase 0 on header (r/w)
iwm_ph1_off equ $0a02 ; phase 1 off error (r)/CRC (w)
iwm_ph1_on equ $0a03 ; phase 1 on param data (r/w)
iwm_ph2_off equ $0a04 ; phase 2 off phase (r/w)
iwm_ph2_on equ $0a05 ; phase 2 on setup (r/w)
iwm_ph3_off equ $0a06 ; phase 3 off status (r)/write zeros (w)
iwm_ph3_on equ $0a07 ; phase 3 on handshake (r)/write ones (w)
iwm_motor_off equ $0a08 ; motor off
iwm_motor_on equ $0a09 ; motor on
iwm_sel_drive_1 equ $0a0a ; enable drive 1
iwm_sel_drive_2 equ $0a0b ; enable drive 2
iwm_q6l equ $0a0c ; Q6 low
iwm_q6h equ $0a0d ; Q6 high
iwm_q7l equ $0a0e ; Q7 low
iwm_q7h equ $0a0f ; Q7 high
; IWM registers and states
; from IWM Design Spec 343-0041-B
; Q7 Q6 Motor-On register operation selected state name
; -- -- -------- --------------------------- ----------
; 0 0 0 read all ones
; 0 0 1 read data reg
; 0 1 x read status register write protect sense
; 1 0 x read write-handshake reg write
; 1 1 0 write mode reg mode set
; 1 1 1 write data reg write load
; SWIM chip - ISM registers
; Note: there are probably some references in the code to ISM registers
; that are currently misidentified as IWM registers
ism_w_data equ $0a00
ism_r_data equ $0a08
ism_w_mark equ $0a01
ism_r_mark equ $0a09
ism_w_crc equ $0a02
ism_r_error equ $0a0a
ism_w_param equ $0a03
ism_r_param equ $0a0b
ism_w_phase equ $0a04
ism_r_phase equ $0a0c
ism_w_setup equ $0a05
ism_r_setup equ $0a0d
ism_w_zeros equ $0a06
ism_r_status equ $0a0e
ism_w_ones equ $0a07
ism_r_handshake equ $0a0f
D0a40 equ $0a40
D0a41 equ $0a41
D0a80 equ $0a80
D0a81 equ $0a81
D0aff equ $0aff
D0b00 equ $0b00
D0b1f equ $0b1f
D0b20 equ $0b20
D0b3f equ $0b3f
D0b40 equ $0b40
D0b80 equ $0b80
D0ba0 equ $0ba0
D0bc0 equ $0bc0
D0be0 equ $0be0
D0bff equ $0bff
D0c00 equ $0c00
D0c01 equ $0c01
D0c02 equ $0c02
D0c03 equ $0c03
D0c04 equ $0c04
D0c05 equ $0c05
D0c06 equ $0c06
D0c0c equ $0c0c
D0d00 equ $0d00
D0d0c equ $0d0c
D0e00 equ $0e00
D0f00 equ $0f00
D1003 equ $1003
D1203 equ $1203
D2003 equ $2003
D4003 equ $4003
; locations in host slot pseudoROM (cn00)
D7b00 equ $7b00 ; host $cn00
D7b04 equ $7b04
D7b0b equ $7b0b
D7b0d equ $7b0d
D7b17 equ $7b17 ; beq instruction loop to wait for diagnostic to load
D7b21 equ $7b21
D7b23 equ $7b23
; locations in host shared pseudoROM (c800-cfff)
D7c00 equ $7c00 ; host $cc00
D7c09 equ $7c09 ; host $cc09
; host side defines
HZ00 equ $00
HZ01 equ $01
HZ3c equ $3c
HZ3e equ $3e
HZ3f equ $3f
HZ40 equ $40
HZ41 equ $41
HZ42 equ $42
HZ43 equ $43
HZ44 equ $44
HZ45 equ $45
HZ46 equ $46
HZ47 equ $47
HZ48 equ $48
HZ49 equ $49
HZ4b equ $4b
HZ4c equ $4c
HZ4d equ $4d
HZ4e equ $4e
HZ4f equ $4f
HZ50 equ $50
HZ51 equ $51
HD0100 equ $0100 ; stack
mon_softev equ $03f2
HD0488 equ $0488 ; somewhere in text page 1
HD048d equ $048d
HD0606 equ $0606
HD07f8 equ $07f8 ; host side screen hole, stores $c0+slot
HD0800 equ $0800
HL0801 equ $0801
HDc000 equ $c000 ; keyboard
HDc010 equ $c010 ; keyboard strobe reset
HDc02f equ $c02f
HDc035 equ $c035
HDc036 equ $c036
HDc068 equ $c068
HDc080 equ $c080
HDc082 equ $c082
HDc100 equ $c100 ; why do we care what's in slot 1 ROM space?
; host side shared ROM space
HDc800 equ $c800
HDc801 equ $c801
HDc802 equ $c802
HDc803 equ $c803
HDc804 equ $c804
HDc807 equ $c807
HDc808 equ $c808
HDc80b equ $c80b
HDc80c equ $c80c
HDc833 equ $c833
HDc83f equ $c83f
HDc845 equ $c845
HDc856 equ $c856
HDca00 equ $ca00
HDca02 equ $ca02
HSca43 equ $ca43
HScabf equ $cabf
HScb8c equ $cb8c
HScbaa equ $cbaa
HScbd9 equ $cbd9
HD_slot_1_rom_copy equ $cbee
HDcbfe equ $cbfe
HDcbff equ $cbff
HDcfff equ $cfff ; turn off shared slot ROM
HLe000 equ $e000 ; ROM BASIC cold start (either Integer or Applesoft)
mon_sloop equ $faba
mon_settxt equ $fb39
mon_main_id equ $fbb3 ; $06 for IIe or later
mon_sub_id equ $fbc0 ; $e0 for enhanced IIe or IIgs
mon_home equ $fc58
mon_cr equ $fc62
mon_prbyte equ $fdda
mon_prhex equ $fde3
mon_cout equ $fded
mon_idroutine equ $fe1f
mon_setkbd equ $fe89
mon_setvid equ $fe93
mon_oldrst equ $ff59 ; sets video and keyboard and enters monitor
reset_vec equ $fffc
org $8000
zp_init_tab:
phase $0000
Z00: fcb $ff
Z01: fcb $ff
Z02: fcb $00
Z03: fcb $ff
Z04: fcb $00
Z05: fcb $ff
Z06: fcb $ff
Z07: fcb $00
Z08: fcb $00
Z09: fcb $00
Z0a: fcb $00
Z0b: fcb $00
Z0c: fcb $00
Z0d: fcb $ff
fcb $ff
Z0f: fcb $80
fcb $80
Z11: fcb $00
fcb $00
Z13: fcb $00
Z14: fcb $ff
Z15: fcb $ff
Z16: fcb $ff
Z17: fcb $ff
Z18: fcb $ff
Z19: fcb $ff
Z1a: fcb $00
Z1b: fcb $ff
Z1c: fcb $ff
fcb $00
Z1e: fcb $ff
Z1f: fcb $00
Z20: fcb $00
Z21: fcb $00
Z22: fcb $00
Z23: fcb $00
Z24: fcb $00
fcb $00
fcb $00
Z27: fcb $00
Z28: fcb $00
Z29: fcb $00
Z2a: fcb $00
Z2b: fcb $00
Z2c: fcb $00
Z2d: fcb $00
Z2e: fcb $00
Z2f: fcb $00
Z30: fcb $00
fcb $00
Z32: fcb $00
Z33: fcb $00
Z34: fcb $00
fcb $00
fcb $00
fcb $00
Z38: fcb $00
Z39: fcb $00
Z3a: fcb $00
fcb $00
fcb $00
fcb $00
fcb $00
Z3f: fcb $00
Z40: fcb $00
fcb $00
Z42: fcb $00
fcb $00
Z44: fcb $00
fcb $00
Z46: fcb $00
fcb $00
Z48: fcb $00
fcb $00
Z4a: fcb $00
fcb $00
Z4c: fcb $00
Z4d: fcb $00
Z4e: fcb $00
Z4f: fcb $00
Z50: fcb $00
Z51: fcb $00
fcb $00
fcb $00
fcb $00
fcb $00
Z56: fcb $00
Z57: fcb $00
Z58: fcb $00
Z59: fcb $00
Z5a: fcb $00
Z5b: fcb $00
Z5c: fcb $00
Z5d: fcb $00
Z5e: fcb $00
Z5f: fcb $00
Z60: fcb $00
Z61: fcb $00
Z62: fcb $04
Z63: fcb $80
Z64: fcb $00
Z65: fcb $05
Z66: fcb $00
Z67: fcb $00
Z68: fcb $00
Z69: fcb $00
Z6a: fcb $00
Z6b: fcb $00
Z6c: fcb $00
Z6d: fcb $00
Z6e: fcb $00
Z6f: fcb $80
Z70: fcb $1b
Z71: fcb $00
; Hooks
; see _Apple IIgs Firmware Reference_,
; Chapter 7: SmartPort Firmware,
; "UniDisk 3.5 internal functions",
; "Hook table" (p. 145)
Z72: jmp Le50a ; RdAddr?
Z75: jmp Le619 ; ReadData?
Z78: jmp Le889 ; WriteData?
Z7b: jmp Ld5db ; Seek?
Z7e: jmp Lefb0 ; Format?
Z81: jmp Lf0fc ; WriteTrk?
Z84: jmp Lf1ea ; Verify?
; zero page jump vectors (not hooks)
Z87: jmp Sd1e7
Z8a: jmp cmd_init
; Mark table
; see _Apple IIgs Firmware Reference_,
; Chapter 7: SmartPort Firmware,
; "SmartPort calls specific to Apple 3.5 disk drive",
; SetMark (control code $07) (pp. 140-141)
; and
; "UniDisk 3.5 internal functions",
; "Mark table" (pp. 144-145)
Z8d: fcb $ff ; sector number
; data mark (reverse order)
Z8e: fcb $ad,$aa,$d5 ; data mark
Z91: fcb $ff
Z92: fcb $fc,$f3,$cf,$3f,$ff ; sync bytes
; bit-slip mark (reverse order)
Z97: fcb $ff,$aa,$de ; bit-slip mark
fcb $ff
fcb $ff,$ff,$ff,$ff ; interheader gap
; address mark (reverse order)
Z9f: fcb $96,$aa,$d5
fcb $ff
; end of Mark table
Za3: fcb $00
Za4: fcb $00
Za5: fcb $00
Za6: fcb $00
fcb $00
fcb $00
fcb $00
fcb $00
Zab: fcb $00
Zac: fcb $00
Zad: fcb $00
Zae: fcb $00
Zaf: fcb $00
Zb0: fcb $00
Zb1: fcb $00
Zb2: fcb $00
fcb $00
Zb4: fcb $00
Zb5: fcb $00
Zb6: fcb $00
fcb $00
fcb $00
Zb9: fcb $00
Zba: fcb $00
Zbb: fcb $00
Zbc: fcb $4a,$cf,$41,$55
fillto $00e0
Ze0: fcb $00
Ze1: fcb $00
Ze2: fcb $00
Ze3: fcb $00
Ze4: fcb $00
fillto $00fc
Zfc: fdb $0000 ; used to accumulate CRC16 of ROM
Zfe: fdb $0000 ; pointer used for ROM checksum and
; CRC16 computation, and ROM copying
dephase
fillto $8100
D8100:
phase $c600
cpu 6502 ; host CPU might be 6502, 65C02, or 65816
; host-side slot ROM
; boot entry point
HLcn00: ldx #$20 ; cn01 must be $20 for block device
ldx #$00 ; cn03 must be $00 for block device
HLcn04: ldy #$03 ; cn05 must be $03 for block device
lda #$00 ; cn07 must be $00 for SmartPort device
sec
adc #$7f
HLcn0b: bvs HLcn0b
; diagnostic entry point at $Cn0d
HLcn0d: php
sei
bit HDcfff
jsr HScf38
HLcn15: plp
tax
HL_diag_load_wait:
beq HL_diag_load_wait ; Wait for host side of diagnostic code
; to be loaded into shared pseudoROM.
; Card diag code two instructions after
jmp HLcc00
; ProDOS entry point
HLcn1c: clc
bcc HLcn20
; Protocol Converter (SmartPort) entry point
; must be at ProDOS entry point + 3
sec
; wait for card firmware to be ready
HLcn20: clv
HLcn21: bvc HLcn21 ; card firmware will change this branch
; target to HLcn23
HLcn23: php ; save carry (ProDOS vs. SmartPort) and
; interrupt enable state
sei ; disable interrupts
lda HDcfff ; turn off other cards' shared ROM
; get $C0 + slot number
jsr HScc08 ; known ret instruction
tsx
lda HD0100,x
sta HD07f8
tay
ldx HD_slotmap,y ; map $C0+slot to slot*10
lda HDc082,x
jsr HScfd9
; save HZ40..HZ51 in pseudoROM HDCa02..HDCa13
ldx #$12
HLcn3e: lda HZ40-1,x ; HZ40..HZ51 copied to HDCa02..HDCa13
sta HDca02-1,x
dex
bne HLcn3e
plp ; restore carry (ProDOS vs. SmartPort) and
; previous interrupt state
ldx HD_slotmap,y ; map $C0+slot to slot*10
lda HDc080,x
bvc HLcn54
jsr HScabf
beq HLcn15
HLcn54: bit HDcc09
bpl HLcn5f
jsr HDca00
ldy HD07f8
HLcn5f: bcc HLcna9 ; if carry clear, go handle ProDOS command
pla ; pop ret address as ptr to SmartPort command
sta HZ40
pla
sta HZ41
ldy #$01 ; first byte is command number
lda (HZ40),y
sta HZ50
iny
lda (HZ40),y ; second and third bytes are param list pointer
sta HZ4c
iny
lda (HZ40),y
sta HZ4d
iny
lda (Z40),y
dey
bit HZ50 ; is it an extended SmartPort command?
bvc HLcn86 ; no
ldy #$05 ; yes, command is longer
bit HDcc09 ; on a IIgs?
bvs HLcn88 ; yes
HLcn86: lda #$00 ; high byte of param list pointer is zero
HLcn88: sta HZ4e ; store high byte of param list pointer
tya ; compute return address
clc
adc HZ40
tax
lda #$00
adc HZ41
pha ; push new return address
txa
pha
jsr HSca43
lda HZ43
and #$bf
cmp #$0c
bcc HLcnb7
HLcna1: lda #$01
bne HLcnbc ; always taken
lda #$11
bne HLcnbc ; always taken
; handle ProDOS command
HLcna9: lda HZ42
cmp #$04
bcs HLcna1
jsr HScefe
lda HZ43
clc
adc #$8c
HLcnb7: jsr HScbd9
lda HZ50
HLcnbc: pha ; push error code
lda HZ4e ; push X and Y result
pha
lda HZ4f
pha
ldy HD07f8
ldx HD_slotmap,y ; map $C0+slot to slot*10
lda HDc082,x
; restore HZ40..HZ51 from pseudoROM HDCa02..HDCa13
ldx #$00
HLcnce: ldy HDca02,x
sty HZ40,x
inx
cpx #$12
bcc HLcnce
lda #$00
sta HDca00
pla ; pop Y, X, and error code
tay
pla
tax
pla
cmp #$01 ; set carry flag if error code non-zero
ora #$00 ; set zero flag appropriately
rts
; copy first 16 bytes of slot 1 ROM into our pseudoROM
HLcne7: ldy #$0f
HLcne9: lda HDc100,y
bit HDcfff
sta HD_slot_1_rom_copy,y
dey
bpl HLcne9
rts
fillto $c6fb
HDcnfb: fcb $c0 ; SmartPort ID type byte
; bit 7=1: supports extended commands (32-bit)
; bit 6=1: supports additional commands
; (see _Apple IIgs Firmware Reference
; 1 MB Apple IIgs Update)
; SetFormatOption ($0a, $4a)
; GetFormatOption ($0b, $4b)
; bit 1=0: not SCSI
; bit 0=0: not RAM card
HDcnfc: fdb $00 ; ProDOS block count
HDcnfe: fcb $bf ; ProDOS block device characteristics
; bit 7=1: removable medium
; bit 6=0: not interruptible
; bits 5..4=11:
; bit 3=1: supports formatting
; bit 2=1: supports write
; bit 1=1: supports read
; bit 0=1: supports status
HDcnff: fcb HLcn1c & $ff ; pointer to ProDOS entry
; end of slot ROM
dephase
D8200:
phase $ca00
HSca00: php
sei
lda HDc068
pha
ldx #$0a
HLca08: eor #$0e
sta HDc068
cmp HDc068
bne HLca31
dex
bne HLca08
pla
sta HDc068
; Determine host type
lda mon_main_id ; IIe or newer?
cmp #$06
bne HLca32 ; no
lda mon_sub_id
cmp #$e0 ; enhanced IIe or IIgs?
bne HLca32 ; no
sec ; IIgs?
jsr mon_idroutine
bcs HLca32 ; no
lda #$7f
bne HLca34
HLca31: pla
HLca32: lda #$7e
HLca34: bit HDc800
bpl HLca34
sta HDc800
HLca3c: bit HDc800
bpl HLca3c
plp
rts
bit HZ50
bvs HLca64
ldy #$08
HLca49: tax
lda (HZ4c),y
dey
bmi HLca5d
cpy #$03
bcc HLca58
sta HZ43,y
bcs HLca49
HLca58: sta HZ41,y
bcc HLca49
HLca5d: iny
sty HZ44
sty HZ4b
beq HLca7a
HLca64: ldy #$0b
HLca66: tax
bit HDcc09
bvs HLca70
lda (HZ4c),y
bvc HLca72
HLca70:
cpu 65816
assume m:1
ldal (HZ4c),y ; NOTE: HZ4c is a 24-bit pointer! IIgs only
cpu 65c02
HLca72: dey
bmi HLca7a
sta HZ41,y
bpl HLca66
HLca7a: ldy HZ50
sta HZ50
lda HZ42
sta HZ40
lda HZ43
sta HZ41
lda HZ44
sta HZ42
stx HZ44
sty HZ43
rts
tablh macro namel,nameh
namel label *
nameh label *+(ARGCOUNT-2)
shift
shift
irp addr,ALLARGS
fcb (addr-1) & $ff
endm
irp addr,ALLARGS
fcb (addr-1) >> 8
endm
endm
tablh HDca8f,HDca9f,HLcc3e,HLcd52,HLcde6,HLcc0a,HLcca1,HLcd34,HLcc0a,HLcc0a,HLcc3e,HLcc92,HLcd0c,HLcc3e,HLcc11,HLcd52,HLcde6,HLcc0a
; required arg length?
HDcaaf: fcb $03,$03,$03,$01,$03,$01,$01,$01
fcb $04,$04,$03,$03,$ff,$ff,$ff,$ff
stx HZ51
jsr HSca00
lda #$00
sta HZ4e
sta HZ4f
ldx #$03
stx HZ3c
ldy mon_main_id
cpy #$06
beq HLcadc
lda HDc000
ora #$80
bmi HLcb02
HLcadc: bit HDc010
bpl HLcb1e
bmi HLcae6
HLcae3: sta HDc010
HLcae6: lda HDc000
bmi HLcb02
cpy #$06
bne HLcaf4
bit HDc010
bpl HLcb1e
HLcaf4: inc HZ4e
bne HLcae6
inc HZ4f
bne HLcae6
dec HZ3c
bne HLcae6
beq HLcb1e
HLcb02: cmp #$84
bne HLcb1e
dex
bne HLcae3
php
sei
pla
tay
pla
sta HZ4e
pla
sta HZ4f
tya
pha
lda HZ4f
pha
lda HZ4e
pha
jmp HScf38
HLcb1e: ldx #$03
HLcb20: lda HDc800
bmi HLcb36
inc HZ4e
bne HLcb20
inc HZ4f
bne HLcb20
dex
bne HLcb20
lda #$30
sta HZ50
bne HLcb87
HLcb36: lda #$ff
sta HDc801
lda #$00
sta HDc803
lda #$81
sta HZ43
lda #$0c
sta HDc800
lda #$08
sta HZ41
lda #$00
sta HZ40
sta HZ42
jsr HScd55
ldx HZ51
cmp #$01
bcs HLcb87
lda #$01
sta HZ42
stx HZ43
lda #$08
sta HZ45
lda #$00
sta HZ44
sta HZ46
sta HZ47
lda HD0800
cmp #$01
bne HLcb87
lda HL0801
beq HLcb87
lda #$00 ; 0 .
bit HDcc09
bvc HLcb84
sta HDc035
HLcb84: jmp HL0801
HLcb87: stx HZ51
jmp HLcf53
Pcb8c: bit HZ43
bpl HLcba9
cmp #$00
beq HLcba9
cmp #$2b
beq HLcba9
cmp #$28
beq HLcba9
cmp #$2f
beq HLcba9
cmp #$11
bne HLcba7
lda #$28
rts
HLcba7: lda #$27
HLcba9: rts
Pcbaa: cpy #$10
beq HLcbb9
lda #$2b
cpy #$14
beq HLcbb6
lda #$2f
HLcbb6: sta HDc856
HLcbb9: rts
fillto $cbd4
HLcbd4: lda #$04
sta HZ50
rts
Pcbd9: ldy HD07f8
ldx HD_slotmap,y ; map $C0+slot to slot*10
stx HZ51
tax
lda HDcaaf,x
bmi HLcbeb
cmp HZ50
bne HLcbd4
HLcbeb: lda HDca9f,x
pha
lda HDca8f,x
pha
lda #$00
sta HZ50
sta HZ4f
sta HZ4e
ldx HZ51
jsr HScfb1
HLcc00: lda HDc080,x
HLcc03: lda HDc800
bpl HLcc03
HScc08: rts
HDcc09: fcb $80
HLcc0a: jsr HSced6
clc
jmp HLceb4
HLcc11: lda #$00
sta HZ46
jsr HSced6
HLcc18: lda HDc801
bmi HLcc18
beq HLcc3b
jsr HScd3b
ldy #$02
lda (HZ4c),y
sta HZ4f
dey
lda (HZ4c),y
sta HZ4e
dey
lda (HZ4c),y
and #$14
tay
ldx HZ51
lda HDc080,x
jsr HScbaa
HLcc3b: jmp HLceb3
HLcc3e: lda HZ46
sta HDc80b
lda HZ47
sta HDc80c
jsr HSced6
HLcc4b: lda HDc801
bmi HLcc4b
beq HLcc6f
ldx HDc80b
stx HZ4e
ldx HDc80c
stx HZ4f
jsr HScd3b
ldx HZ4f
beq HLcc67
sec
jsr HScc72
HLcc67: ldx HZ4e
beq HLcc6f
clc
jsr HScc72
HLcc6f: jmp HLceb3
HScc72: ldy #$00
HLcc74: lda (HZ4c),y
bit HDcc09
bvc HLcc7f
cpu 65816
assume m:1
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
bvs HLcc81
cpu 65c02
HLcc7f: sta (HZ40),y
HLcc81: iny
bcc HLcc8e
bne HLcc74
inc HZ4d
inc HZ41
bne HLcc8e
inc HZ42
HLcc8e: dex
bne HLcc74
rts
HLcc92: lda HZ46
sta HDc80b
pha
lda HZ47
sta HDc80c
pha
jmp HLccc6
HLcca1: ldy #$00
bit HDcc09
HLcca6: bvc HLccac
cpu 65816
assume m:1
ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
bvs HLccae
cpu 65c02
HLccac: lda (HZ40),y
HLccae: sta HDc80b,y
pha
iny
cpy #$01
beq HLcca6
lda HZ40
clc
adc #$02
sta HZ40
bcc HLccc6
inc HZ41
bne HLccc6
inc HZ42
HLccc6: jsr HSced6
HLccc9: lda HDc801
bmi HLccc9
beq HLcce7
jsr HScd3b
pla
tax
beq HLccdb
sec
jsr HSccec
HLccdb: pla
tax
beq HLcce3
clc
jsr HSccec
HLcce3: clc
jmp HLceb4
HLcce7: pla
pla
jmp HLceb3
HSccec: ldy #$00
HLccee: bit HDcc09
bvc HLccf7
cpu 65816
assume m:1
ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
bvs HLccf9
cpu 65c02
HLccf7: lda (HZ40),y
HLccf9: sta (HZ4c),y
iny
bcc HLcd08
bne HLccee
inc HZ4d
inc HZ41
bne HLcd08
inc HZ42
HLcd08: dex
bne HLccee
rts
HLcd0c: lda #$00
ldx HZ46
sta HZ46
sta HZ47
sta HZ48
sta HZ49
beq HLcd34
cpx #$05
bcc HLcd20
ldx #$04
HLcd20: ldy #$00
HLcd22: bit HDcc09
bvc HLcd2b
cpu 65816
assume m:1
ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
bvs HLcd2d
cpu 65c02
HLcd2b: lda (HZ40),y
HLcd2d: sta HZ46,y
iny
dex
bne HLcd22
HLcd34: jsr HSced6
clc
jmp HLceb4
HScd3b: and #$1f
lsr
php
clc
adc HZ51
tax
lda HDc080,x
lda #$00
sta HZ4c
plp
rol
asl
adc #$c8
sta HZ4d
rts
HLcd52: jsr HSced6
HScd55: lda HDc801
bmi HScd55
bne HLcd62
lda HDc856
jmp HLcd7c
HLcd62: jsr HScd3b
ldx #$02
ldy #$00
bit HDcc09
bvs HLcd80
; Apple IIe (65C02) read loop
HLcd6e: lda (HZ4c),y
sta (HZ40),y
iny
bne HLcd6e
inc HZ4d
inc HZ41
dex
bne HLcd6e
HLcd7c: sec
jmp HLcead
; Apple IIgs (65816) read loop
cpu 65816
assume m:1
HLcd80: clc
xce
php
lda HDc036
pha
ora #$80
sta HDc036
lda #$02
bit HZ4d
rep #$20 ; clear 65816 M bit for 16-bit data
assume m:0
bne HLcdb8
HLcd94: lda HDc800,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
lda HDc800,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
bne HLcd94
inc HZ41
HLcda6: lda HDc800+$100,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
lda HDc800+$100,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
bne HLcda6
beq HLcdda
HLcdb8: lda HDc800+$200,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
lda HDc800+$200,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
bne HLcdb8
inc HZ41
HLcdca: lda $c800+$300,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
lda $c800+$300,y
stal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer! IIgs only
iny
iny
bne HLcdca
HLcdda: sep #$30 ; set 65816 M bit for 8-bit data,
assume m:1 ; and X bit for 8-bit indexing
assume x:1
pla
sta HDc036
plp
xce
sec
jmp HLcead
cpu 65c02
HLcde6: jsr HSced6
HLcde9: ldx HDc801
bmi HLcde9
bne HLcdf3
jmp HLceb3
HLcdf3: lda HDc804
php
bpl HLcdff
sei
lda #$c0
sta HDc804
HLcdff: txa
jsr HScd3b
ldy #$00
bit HDcc09 ; bit 6 set for IIgs
bvs HLce1e
; Apple IIe (65C02) write loop
plp
ldx #$02
HLce0d: lda (HZ40),y
sta (HZ4c),y
iny
bne HLce0d
inc HZ41
inc HZ4d
dex
bne HLce0d
jmp HLceac
; Apple IIgs (65816) write loop
cpu 65816
assume m:1
HLce1e: clc
xce
php
lda HDc036
pha
ora #$80
sta HDc036
phx
lda #$02
bit Z4d
rep #$20 ; clear 65816 M bit for 16-bit data
assume m:0
bne HLce67
HLce33: ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer!
sta HDc800,y
iny
iny
ldal (HZ40),y
sta HDc800,y ; NOTE: HZ40 is a 24-bit pointer!
iny
iny
bne HLce33
inc HZ41
sep #$20 ; set 65816 M bit for 8-bit data
assume m:1
ldx HZ51
lda HDc080,x
inc HDc804
plx
lda HDc080,x
rep #$20 ; clear 65816 M bit for 16-bit data
assume m:0
HLce55: ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer!
sta HDc800+$100,y
iny
iny
ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer!
sta HDc800+$100,y
iny
iny
bne HLce55
beq HLce99
HLce67: ldal (HZ40),y
sta HDc800+$200,y
iny
iny
ldal (HZ40),y
sta HDc800+$200,y
iny
iny
bne HLce67
inc HZ41
sep #$20 ; set 65816 M bit for 8-bit data
assume m:1
ldx HZ51
lda HDc080,x
inc HDc804
plx
lda HDc080,x
rep #$20 ; clear 65816 M bit for 16-bit data
assume m:0
HLce89: ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer!
sta HDc800+$300,y
iny
iny
ldal (HZ40),y ; NOTE: HZ40 is a 24-bit pointer!
sta HDc800+$300,y
iny
iny
bne HLce89
HLce99: sep #$30 ; set 65816 M bit for 8-bit data,
assume m:1 ; and X bit for 8-bit indexing
assume x:1
pla
sta HDc036
plp
xce
ldx HZ51
lda HDc080,x
lda #$d0
sta HDc804
plp
cpu 65c02
HLceac: clc
HLcead: lda #$02
sta HZ4f
bne HLceb4
HLceb3: sec
HLceb4: ldx HZ51
lda HDc080,x
lda HDc801
ora #$f0
sta HDc801
bcs HLcec8
HLcec3: lda HDc800
bpl HLcec3
HLcec8: lda HDc856
jsr HScb8c
sta HZ50
ldx #$00
stx HDc856
rts
HSced6: lda HDc800
bpl HSced6
lda #$ff
sta HDc801
txa
pha
ldx #$08
HLcee4: lda HZ43,x
sta HDc802,x
dex
bpl HLcee4
pla
tax
lda HDc802
and #$1f
sta HDc800
rts
; table used to map $C0+slot to slot*10
HD_slotmap equ *-$c1
fcb $10,$20,$30,$40,$50,$60,$70
HScefe: ora #$80
ldx HZ43
sta HZ43
lda HZ44
sta HZ40
lda HZ45
sta HZ41
lda #$00
sta HZ42
sta HZ48
sta HZ49
txa
and #$70
beq HLcf35
lsr
lsr
lsr
lsr
ora #$c0
sta HZ44
lda #$00
cpy HZ44
beq HLcf31
lda #$c0
eor HZ44
cmp #$02
beq HLcf31
lda #$04
HLcf31: cpx #$80
adc #$01
HLcf35: sta HZ44
rts
HScf38: tsx
lda HD0100+2,x
sta HD07f8
tay
ldx HD_slotmap,y ; map $C0+slot to slot*10
lda HDc080,x
HLcf46: bit HDc800
bpl HLcf46
lda #$3d
sta HDc800
lda #$00
rts
HLcf53: bit HDc082
lda HZ00
bne HLcf64
lda HZ01
cmp HD07f8
bne HLcf64
jmp mon_sloop
HLcf64: jsr mon_setvid
jsr mon_setkbd
jsr mon_settxt
jsr mon_home
ldy #$00
lda HZ50
cmp #$30
bne HLcf7a
ldy #HDcf9a-HDcf8b
HLcf7a: ldx #$00
HLcf7c: lda HDcf8b,y
beq HLcf88
sta HD0488,x
iny
inx
bne HLcf7c
HLcf88: jmp HLe000
HDcf8b: fcchz "UNABLE TO BOOT"
HDcf9a: fcchz "CONTROLLER NEVER READY"
HScfb1: lda HZ44
beq HLcfca
cmp #$05
bcs HLcfca
tya
pha
txa
pha
lda HDc082,x
jsr HScfcb
pla
tax
lda HDc080,x
pla
tay
HLcfca: rts
HScfcb: lda #$cb
pha
ldx HZ44
lda HDcfd5-1,x
pha
rts
HDcfd5: fcb $7f,$9f,$bf,$df
HScfd9: bvs HLcfe0
bit HDcc09
bpl HLcfe6
HLcfe0: lda #$00
sta HDca00
rts
HLcfe6: bit HDca00
bmi HLcff1
lda #$80
sta HDca00
rts
HLcff1: pla
pla
lda #$01
plp
sec
rts
fillto $d000
dephase
; 8800-8dff is host diagnostic code, copied into host shared ROM space
; at host ca00-cfff
D8800:
phase $ca00
H2Lca00:
jsr mon_cr
lda #msg_table_heading >> 8
sta HZ3f
lda #msg_table_heading & $ff
jsr H2Scea7
lda HDc833
tax
jsr mon_prhex
jsr mon_cr
txa
bne H2Lca1c
jmp H2Lcac9
H2Lca1c:
lda #$01
pha
H2Lca1f:
pla
pha
tay
jsr mon_prhex
lda HDc833,y
cmp #$01
bne H2Lca34
lda #$a4
jsr H2Scea7
jmp H2Lca52
H2Lca34:
cmp #$03
bne H2Lca40
lda #$b1
jsr H2Scea7
jmp H2Lca52
H2Lca40:
cmp #$80
bne H2Lca52
lda #$97
jsr H2Scea7
jmp H2Lcab9
jsr H2Scafe
jmp H2Lcab9
H2Lca52:
pla
pha
tay
lda HDc83f,y
cmp #$02
bne H2Lca64
lda #msg_400k & $ff
jsr H2Scea7
jmp H2Lca9e
H2Lca64:
cmp #$08
bne H2Lca70
lda #msg_720k & $ff
jsr H2Scea7
jmp H2Lca9e
H2Lca70:
cmp #$04
bne H2Lca7a
jsr H2Scaf8
jmp H2Lca9e
H2Lca7a:
cmp #$06
bne H2Lca84
jsr H2Scaf8
jmp H2Lca9e
H2Lca84:
cmp #$0a
bne H2Lca8e
jsr H2Scaf2
jmp H2Lca9e
H2Lca8e:
cmp #$0c
bne H2Lca98
jsr H2Scaf2
jmp H2Lca9e
H2Lca98:
jsr H2Scafe
jmp H2Lcab9
H2Lca9e:
pla
pha
cmp #$03
bcs H2Lcab9
tay
lda HDc845,y
and #$20
beq H2Lcab4
lda #msg_yes & $ff
jsr H2Scea7
jmp H2Lcab9
H2Lcab4:
lda #msg_no & $ff
jsr H2Scea7
H2Lcab9:
pla
tay
cmp HDc833
beq H2Lcac9
iny
tya
pha
jsr mon_cr
jmp H2Lca1f
H2Lcac9:
jsr mon_cr
jsr mon_cr
jsr H2Scebd
lda #msg_passed_rw_for_unit & $ff
jsr H2Scea7
lda #$01
jsr mon_prhex
jsr mon_cr
jsr H2Scebd
lda #msg_passed_rw_for_unit & $ff
jsr H2Scea7
lda #$02
jsr mon_prhex
jsr mon_cr
jsr H2Scebd
H2Scaf2:
lda #msg_1440k & $ff
jsr H2Scea7
rts
H2Scaf8:
lda #msg_800k & $ff
jsr H2Scea7
rts
H2Scafe:
lda #msg_unknown_size & $ff
jsr H2Scea7
rts
fillto $cb3f
msg_passed_rw_for_unit:
fcchz "Passed R/W for Unit "
; cb54
fcchz "R/W Failure on block $"
; cb6b
fcchz " Err=$"
msg_table_heading:
fcchz "# Unit Volume W/P Drives="
; cb97
fcchz " UniDisk 3.5"
; cba4
fcchz " Apple 3.5 "
; cbb0
fcchz " Apple FDHD "
msg_400k:
fcchz " 400K "
msg_720k:
fcchz " 720K "
msg_800k:
fcchz " 800K "
msg_1440k:
fcchz " 1440K"
msg_unknown_size:
fcchz " ??? "
msg_yes:
fcchz " YES"
msg_no:
fcchz " NO"
fillto $cc00
H2Lcc00:
sei
jsr mon_setvid
jsr mon_setkbd
jsr mon_settxt
jsr mon_home
lda #$ff
sta HZ43
lda #$06
cmp mon_main_id
beq H2Lcc1c
lda #$df
sta HZ43
H2Lcc1c:
lda #msg_banner >> 8
sta HZ3f
lda #msg_banner & $ff
jsr H2Scea7
jsr mon_cr
lda #msg_credit & $ff
jsr H2Scea7
jsr mon_cr
lda #msg_copyright & $ff
jsr H2Scea7
jsr mon_cr
jsr mon_cr
lda #msg_tests & $ff
jsr H2Scea7
jsr mon_cr
lda #msg_slot & $ff
jsr H2Scea7
lda HD07f8
jsr mon_prhex
lda HD07f8
asl
asl
asl
asl
ora #$80
sta HZ40
lda #$c0
sta HZ41
jsr mon_cr
lda #msg_card_pseudorom & $ff
jsr H2Scea7
jsr H2Sce38
lda #msg_card_rom_crc & $ff
jsr H2Scea7
jsr H2Sce38
lda #msg_card_rom_checksum & $ff
jsr H2Scea7
jsr H2Sce38
lda #msg_swim_regs & $ff
jsr H2Scea7
jsr H2Sce38
lda #msg_card_ram & $ff
jsr H2Scea7
jsr H2Sce38
lda #msg_host_card_shared_data & $ff
jsr H2Scea7
lda #$00
tax
ldy #$06
stx HZ3e
H2Lcc94:
stx HZ42
sty HZ44
ldy HZ42
sta (HZ40),y
ldy HZ44
ldx #$c8
stx HZ3f
ldx #$cc
H2Lcca4:
clc
adc (HZ3e),y
iny
bne H2Lcca4
inc HZ3f
cpx HZ3f
bne H2Lcca4
ldx HZ42
cpx #$01
bne H2Lccb7
inx
H2Lccb7:
cpx #$0f
beq H2Lccbf
inx
jmp H2Lcc94
H2Lccbf:
ldx #$cc
stx HZ3f
ldx #$cf
H2Lccc5:
clc
adc (HZ3e),y
iny
bne H2Lccc5
inc HZ3f
cpx HZ3f
bne H2Lccc5
H2Lccd1:
clc
adc (HZ3e),y
iny
cpy #$ff
bne H2Lccd1
ldy #$02
sta (HZ40),y
ldy #$00
ldx #$cb
stx HZ3f
H2Lcce3:
clc
adc (HZ3e),y
iny
bne H2Lcce3
ldx HD07f8
stx HZ3f
H2Lccee:
clc
adc (HZ3e),y
iny
bne H2Lccee
ldx #$c8
stx HZ3f
ldx #$ca
H2Lccfa:
clc
adc (HZ3e),y
iny
bne H2Lccfa
inc HZ3f
cpx HZ3f
bne H2Lccfa
cmp #$ff
beq H2Lcd10
H2Lcd0a:
jsr H2Sce9a
jmp H2Lcda0
H2Lcd10:
jsr H2Sce8d
lda #msg_host_ram & $ff
jsr H2Scea7
ldx #$00
stx HZ3e
inx
H2Lcd1d:
stx HZ42
jsr H2Sce78
ldy HZ42
sta (HZ40),y
ldy #$00
ldx #$c8
stx HZ3f
ldx #$cc
H2Lcd2e:
tya
clc
adc HZ42
adc HZ3f
sta (HZ3e),y
iny
bne H2Lcd2e
inc HZ3f
cpx HZ3f
bne H2Lcd2e
ldx HZ42
cpx #$0f
beq H2Lcd49
inx
jmp H2Lcd1d
H2Lcd49:
ldx #$00
stx HZ3e
inx
H2Lcd4e:
stx HZ42
jsr H2Sce78
ldy HZ42
sta (HZ40),y
ldy #$00
ldx #$c8
stx HZ3f
ldx #$cc
H2Lcd5f:
tya
clc
adc HZ42
adc HZ3f
cmp (HZ3e),y
beq H2Lcd6c
jmp H2Lcd0a
H2Lcd6c:
iny
bne H2Lcd5f
inc HZ3f
cpx HZ3f
bne H2Lcd5f
ldx HZ42
cpx #$0f
beq H2Lcd7f
inx
jmp H2Lcd4e
H2Lcd7f:
jsr H2Sce8d
ldy #$00
sta (HZ40),y
lda #$cd
pha
lda #$93
pha
lda HD07f8
pha
lda #$e6
pha
rts
lda HDc02f
sta HDcbfe
jsr H2Scebd
jmp HDca00
H2Lcda0:
lda #$a6
sta HD048d
ldy #$00
sta (HZ40),y
lda #$4f
sta HDcbff
jsr mon_cr
lda #msg_press_e_to_exit >> 8
sta HZ3f
lda #msg_press_e_to_exit & $ff
jsr H2Scea7
jsr mon_cr
lda HDc010
H2Lcdc0:
ldx #$00
stx HZ3e
H2Lcdc4:
stx HZ42
ldy HZ42
sta (HZ40),y
ldy #$00
ldx #$c8
stx HZ3f
ldx #$cc
H2Lcdd2:
lda (HZ3e),y
iny
bne H2Lcdd2
inc HZ3f
cpx HZ3f
bne H2Lcdd2
ldx HZ42
cpx #$0f
beq H2Lcde7
inx
jmp H2Lcdc4
H2Lcde7:
ldx HD07f8
stx HZ3f
H2Lcdec:
lda (HZ3e),y
iny
bne H2Lcdec
ldx #$cc
stx HZ3f
ldx #$cf
H2Lcdf7:
lda (HZ3e),y
iny
bne H2Lcdf7
inc HZ3f
cpx HZ3f
bne H2Lcdf7
H2Lce02:
lda (HZ3e),y
iny
cpy #$ff
bne H2Lce02
lda HDc000 ; check keyboard
bpl H2Lcdc0 ; no key
sta HDc010 ; reset key
cmp #'E'+$80
beq H2Lce1b
cmp #'e'+$80
beq H2Lce1b
bne H2Lcdc0
; force a host reset
H2Lce1b:
lda mon_softev+1 ; make sure soft reset vector is invalid
sta mon_softev+2
lda reset_vec+1
pha
lda reset_vec
pha
ldy #$00
sta (HZ40),y
lda #$55 ; tell card that we're going to reset
sta HDcbff
H2Lce32: ; wait for card to clear Cbff
lda HDcbff
bne H2Lce32
rts ; return to reset vector (pushed above)
H2Sce38:
jsr H2Sce78
ldy #$02
sta (HZ40),y
ldy #$00
lda HDca00
tax
H2Lce45:
inx
txa
sta HDca00,y
iny
bne H2Lce45 ; immediately following!
H2Lce4d:
inx
txa
cmp HDca00,y
bne H2Lce5a
iny
bne H2Lce4d
jmp H2Lce5f
H2Lce5a:
lda #$c5
sta HD0606
H2Lce5f:
ldy #$00
sta (HZ40),y
lda HDc802
beq H2Sce38
cmp #$a1
beq H2Lce72
jsr H2Sce9a
jmp H2Lcda0
H2Lce72:
sty HDc802
jmp H2Sce8d
H2Sce78:
lda HD048d
ldy #$04
H2Lce7d:
cmp H2Dcffa,y
beq H2Lce86
dey
bne H2Lce7d
iny
H2Lce86:
lda H2Dcffa-1,y
sta HD048d
rts
H2Sce8d:
lda #msg_pass >> 8
sta HZ3f
lda #msg_pass & $ff
jsr H2Scea7
jsr mon_cr
rts
H2Sce9a:
lda #msg_fail >> 8
sta HZ3f
lda #msg_fail & $ff
jsr H2Scea7
jsr mon_cr
rts
H2Scea7:
sta HZ3e
ldy #$00
H2Lceab:
lda (HZ3e),y
bne H2Lceb0
rts
H2Lceb0:
cmp #$c0
bcc H2Lceb6
and HZ43
H2Lceb6:
jsr mon_cout
iny
bne H2Lceab
rts
H2Scebd:
ldy #$00
sta (HZ40),y
lda #$a1
sta HDcbff
H2Lcec6:
jsr H2Sce78
lda HDcbff
cmp #$4f
bne H2Lced3
jmp H2Lcda0
H2Lced3:
cmp #$4e
bne H2Lcef9
lda #$54
jsr H2Scea7
lda HDc808
jsr mon_prbyte
lda HDc807
jsr mon_prbyte
lda #$6b
jsr H2Scea7
lda HDc856
jsr mon_prbyte
jsr mon_cr
jmp H2Lcda0
H2Lcef9:
cmp #$00
bne H2Lcec6
rts
fillto $cf21
msg_banner:
fcchz " 3.5\" Disk Controller Test"
msg_credit:
fcchz " J.Arkley & T.Rudin"
msg_copyright:
fcchz "(C)Apple Computer Inc.,1991"
msg_tests:
fcchz "Tests:"
msg_slot:
fcchz "Slot #"
msg_card_pseudorom:
fcchz "Card pseudoROM"
msg_card_rom_crc:
fcchz "Card ROM CRC"
msg_card_rom_checksum:
fcchz "Card ROM Checksum"
msg_swim_regs:
fcchz "SWIM Regs."
msg_card_ram:
fcchz "Card RAM"
msg_host_card_shared_data:
fcchz "Host/Card shared data"
msg_host_ram:
fcchz "Host RAM"
msg_pass:
fcchz "-PASS"
msg_fail:
fcchz "-FAIL"
msg_press_e_to_exit:
fcchz "Press E to Exit"
H2Dcffa:
fcb $ad,$af,$fc,$dc,$ad,$00
dephase
cpu 65c02 ; done with host code, rest is on-card 65c02
; data copied to zero page - all but first two bytes are zero
D8e00:
fcb $55,$0f
fillto $8f00
L8f00: sei
cld
ldx #$ff
txs
; test first six bytes of zero page with two patterns
ldx #$05
L8f07: lda D990b,x
sta Z00,x
dex
bpl L8f07
ldx #$05
L8f11: lda D990b,x
cmp Z00,x
beq L8f1b
jmp L95cd
L8f1b: dex
bpl L8f11
ldx #$05
L8f20: lda D9911,x
sta Z00,x
dex
bpl L8f20
ldx #$05
L8f2a: lda D9911,x
cmp Z00,x
beq L8f34
jmp L95cd
L8f34: dex
bpl L8f2a
; Test all of zero page, though most of it will just be zeros
jsr copy_D8e00_to_zp
jsr compare_D8e00_to_zp
bcc L8f42
jmp L95cd
L8f42: jsr copy_diag_to_host ; copy some of host diagnostic code to host shared ROM
stz Z02
stz D7b17+1 ; change branch target of HL_diag_load_wait to allow
; host to continue
lda #$fe ; prevent host from proceeding
sta D7b0b+1
sta D7b21+1
jsr verify_slot_pseudorom
bcc L8f5a
jmp L95cd
L8f5a: jsr verify_diag_copied_correctly
bcc L8f62
jmp L95cd
L8f62: jsr S92ac
jsr S93f5
bcc L8f6d
jmp L95cd
L8f6d: jsr S92ac
jsr S93b1
bcc L8f78
jmp L95cd
L8f78: jsr S92ac
jsr S92b5
bcc L8f83
jmp L95cd
L8f83: jsr S92ac
lda #$06
sta Z04
stz Z05
lda #$01
sta Z00
stz Z01
L8f92: lda #$0a
cmp Z05
bne L8f9c
lda #$0b
sta Z05
L8f9c: lda #$7b
cmp Z05
beq L8fc7
lda Z00
sta (Z04)
inc Z04
lda Z01
sta (Z04)
inc Z04
bne L8fb2
inc Z05
L8fb2: clc
rol Z00
rol Z01
bcc L8f92
lda #$0b
eor Z00
sta Z00
lda #$10
eor Z01
sta Z01
bra L8f92
L8fc7: lda #$06
sta Z04
stz Z05
lda #$01
sta Z00
stz Z01
L8fd3: lda #$0a
cmp Z05
bne L8fdd
lda #$0b
sta Z05
L8fdd: lda #$7b
cmp Z05
beq L9012
lda Z00
cmp (Z04)
beq L8fec
jmp L95cd
L8fec: inc Z04
lda Z01
cmp (Z04)
beq L8ff7
jmp L95cd
L8ff7: inc Z04
bne L8ffd
inc Z05
L8ffd: clc
rol Z00
rol Z01
bcc L8fd3
lda #$0b
eor Z00
sta Z00
lda #$10
eor Z01
sta Z01
bra L8fd3
L9012: lda #$06
sta Z04
stz Z05
lda #$01
sta Z00
stz Z01
L901e: lda #$0a
cmp Z05
bne L9028
lda #$0b
sta Z05
L9028: lda #$7b
cmp Z05
beq L9057
lda Z00
eor #$ff
sta (Z04)
inc Z04
lda Z01
eor #$ff
sta (Z04)
inc Z04
bne L9042
inc Z05
L9042: clc
rol Z00
rol Z01
bcc L901e
lda #$0b
eor Z00
sta Z00
lda #$10
eor Z01
sta Z01
bra L901e
L9057: lda #$06
sta Z04
stz Z05
lda #$01
sta Z00
stz Z01
L9063: lda #$0a
cmp Z05
bne L906d
lda #$0b
sta Z05
L906d: lda #$7b
cmp Z05
beq L90a6
lda Z00
eor #$ff
cmp (Z04)
beq L907e
jmp L95cd
L907e: inc Z04
lda Z01
eor #$ff
cmp (Z04)
beq L908b
jmp L95cd
L908b: inc Z04
bne L9091
inc Z05
L9091: clc
rol Z00
rol Z01
bcc L9063
lda #$0b
eor Z00
sta Z00
lda #$10
eor Z01
sta Z01
bra L9063
L90a6: ldy #$00 ; copy first two pages of diagnostic code to host shared ROM
L90a8: lda D8800,y
sta D0200,y
lda D8800+$100,y
sta D0200+$100,y
dey
bne L90a8
lda #$91
pha
lda #$36
pha
pla
pla
stz Z00
stz Z01
lda #$00
ldy #$06
stz D09ff
L90ca: clc
adc (Z00),y
iny
bne L90ca
inc Z01
ldx #$08
cpx Z01
bne L90ca
ldx #$0c
stx Z01
L90dc: clc
adc (Z00),y
iny
bne L90dc
inc Z01
ldx #$40
cpx Z01
bne L90dc
ldx #$7c
stx Z01
L90ee: clc
adc (Z00),y
iny
bne L90ee
inc Z01
ldx #$7f
cpx Z01
bne L90ee
L90fc: clc
adc (Z00),y
iny
cpy #$ff
bne L90fc
iny
ldx #$0b
stx Z01
L9109: clc
adc (Z00),y
iny
bne L9109
ldx #$7b
stx Z01
L9113: clc
adc (Z00),y
iny
bne L9113
ldx #$08
stx Z01
L911d: clc
adc (Z00),y
iny
bne L911d
inc Z01
ldx #$0a
cpx Z01
bne L911d
eor #$ff
sta D09ff
lda #$a1
sta Z02
jsr S929b
jsr Sd2a1
lda #$ff
sta Z00
stz D03ff
jsr S929b
; look for a 16 byte signature from the host slot 1 card
; the slot ROM subroutine at HLcne7 has copied c100..c10f
; to cbee..cbfd, which we see from 03ee..03fd
ldy #$0f
L9146: lda slot_1_rom_copy,y
cmp slot_1_template,y
bne L9154
dey
bpl L9146
jmp L915c
L9154: lda #$4f
sta D03ff
jmp L9269
L915c: lda Z33
bne L9163
jmp L9154
L9163: lda #$01
sta Z03
jsr S917f
lda Z33
cmp #$02
bcc L9177
lda #$02
sta Z03
jsr S917f
L9177: lda #$4f
sta D03ff
jmp L9269
S917f: jsr S9248
jsr S91b4
bcs L91a1
jsr S91fa
bcs L91a1
jsr S9244
jsr S91b4
bcs L91a1
jsr S91fa
stz D03ff
lda iwm_motor_off
jsr S929b
rts
L91a1: lda Z05
sta Z07
lda Z06
sta Z08
lda #$4e
sta D03ff
lda iwm_motor_off
jmp L9269
S91b4: jsr Sd80b
lda #$02
sta Z02
lda D03fe
lsr
lda D03fe
stz Z06
rol
sta Z05
rol Z06
lda #$ff
sta Z01
sta Zb9
lda #$02
sta Z00
jsr Sd1e7
stz Zb9
bcs L91de
lda #$ff
sta Z00
L91de: lda Z56
beq L91e4
sec
rts
L91e4: lda Z2d
jsr Sd9b0
ldy #$00
L91eb: lda (Zab),y
sta D0400,y
lda (Zaf),y
sta D0500,y
iny
bne L91eb
clc
rts
S91fa: jsr Sd80b
lda #$01
sta Z02
lda D03fe
lsr
lda D03fe
stz Z06
rol
sta Z05
rol Z06
lda #$ff
sta Z01
sta Z5f
lda #$01
sta Z00
jsr Sd1e7
lda #$fe
sta Z00
lda Z2d
jsr Sd9b0
lda #$ff
sta Z01
lda Z56
beq L922f
L922d: sec
rts
L922f: ldy #$00
L9231: lda (Zab),y
cmp D0400,y
bne L922d
lda (Zaf),y
cmp D0500,y
bne L922d
iny
bne L9231
clc
rts
S9244: ldy #$c3
bra L924a
S9248: ldy #$a5
L924a: lda #$08
L924c: jsr S9255
inc
cmp #$1c
bcc L924c
rts
S9255: pha
jsr Sd9b0
tya
sec
phy
ldy #$00
L925e: sta (Zab),y
sta (Zaf),y
rol
iny
bne L925e
ply
pla
rts
L9269: ldy #$00
sty Z04
sty Z05
L926f: lda #$0a
cmp Z05
bne L927c
tya
and #$c0
bne L927c
bra L927e
L927c: lda (Z04),y
L927e: iny
bne L926f
inc Z05
bne L926f
lda D03ff
cmp #$55
bne L9269
L928c: lda #$00
sta D03ff
sta D0a80
nop
nop
nop
nop
jmp RESET
S929b: lda D03ff
cmp #$a1
bne L92a3
rts
L92a3: cmp #$4f
bne S929b
pla
pla
jmp L9269
S92ac: lda #$a1
sta Z02
L92b0: lda Z02
bne L92b0
rts
; SWIM chip test
S92b5: bit iwm_q7l ; reset IWM (assumed not to be in ISM mode)
bit iwm_q6l
bit iwm_ph0_off
bit iwm_ph1_off
bit iwm_ph2_off
bit iwm_ph3_off
bit iwm_motor_off
lda iwm_q7l ; Q6L,Q7L - should read all ones
cmp #$ff
beq L92d3 ; yes
sec ; no, failure
rts
L92d3: lda #$1f
bit iwm_q6h
sta iwm_q7h ; Q6H,Q7H - write mode register
eor iwm_q7l ; Q6H,Q7L - read status register (low 5 match mode reg)
and #$1f ; match?
beq L92e4 ; yes
sec ; no, failure
rts
L92e4: lda #$00
sta iwm_q7h ; Q6H,Q7H - write mode register
eor iwm_q7l ; Q6H,Q7L - read status register
and #$1f ; match?
beq L92f2 ; yes
sec ; no, failure
rts
L92f2: lda #$0f
bit iwm_q6h
sta iwm_q7h ; Q6H,Q7H - write mode register
eor iwm_q7l ; Q6H,Q7L - read status register
and #$1f ; match?
beq L9303 ; yes
sec ; no, failure
rts
; set SWIM to ISM mode
L9303: lda #$4f
bit iwm_q6h
sta iwm_q7h ; Q6H,Q7H - write mode register, MZ=1
eor #$40
sta iwm_q7h ; Q6H,Q7H - write mode register, MZ=0
eor #$40
sta iwm_q7h ; Q6H,Q7H - write mode register, MZ=1
sta iwm_q7h ; Q6H,Q7H - write mode register, MZ=1
lda #$05 ; wait to meet IWM-to-ISM timing spec
L931a: dec
bne L931a
lda ism_r_phase ; phase should be all enabled, low
cmp #$f0
bne L935a
lda ism_r_status ; status should be motor on, bit 6=1
and #$c0
cmp #$40
bne L935a
stz ism_w_zeros ; reset param pointer
lda #$01
L9332: sta ism_w_param ; loop writing a single one bit
asl
bcc L9332
lda #$fe
L933a: sta ism_w_param ; loop writing a single zero bit
rol
bcs L933a
stz ism_w_zeros ; reset param pointer
lda #$01
L9345: cmp ism_r_param
bne L935a
asl
bcc L9345
lda #$fe
L934f: cmp ism_r_param
bne L935a
sec
rol
bcs L934f
bra L935c
L935a: sec
rts
L935c: lda #$f8 ; switch SWIM from ISM to IWM mode
sta ism_w_zeros
bit iwm_q7l ; reset IWM (assumed not to be in ISM mode)
bit iwm_q6l
bit iwm_ph0_off
bit iwm_ph1_off
bit iwm_ph2_off
bit iwm_ph3_off
bit iwm_motor_off
lda iwm_q7l ; Q6L,Q7L - should read all ones
cmp #$ff
beq L937f ; yes
sec ; no, failure
rts
; repeat IWM tests
L937f: lda #$1f
bit iwm_q6h
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L9390
sec
rts
L9390: lda #$00
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L939e
sec
rts
L939e: lda #$0f
bit iwm_q6h
sta iwm_q7h
eor iwm_q7l
and #$1f
bne L93af
clc
rts
L93af: sec
rts
; compute ROM checksum
S93b1: stz Zfe
lda #$80
sta Zfe+1
lda #$00
tax
tay
L93bb: clc
adc (Zfe),y
bcc L93c1
inx
L93c1: iny
bne L93bb
inc Zfe+1
tay
lda Zfe+1
inc
beq L93d1
tya
ldy #$00
bra L93bb
L93d1: tya
ldy #$00
L93d4: clc
adc (Zfe),y
bcc L93da
inx
L93da: iny
beq L93e4
cpy #$f9
bne L93d4
iny
bra L93d4
L93e4: tay
beq L93ea
jmp L9888
L93ea: txa
clc
adc Dfffa-1
beq L93f3
sec
rts
L93f3: clc
rts
; compute CRC16 of ROM in 2KB pieces using an unrolled loop
S93f5: stz Zfe
lda #$80
sta Zfe+1
L93fb: stz Zfc
stz Zfc+1
L93ff: clc
rol Zfc
rol Zfc+1
bcs L941a
lda (Zfe)
ror
tay
bcc L9422
L940c: lda #$21
eor Zfc
sta Zfc
lda #$10
eor Zfc+1
sta Zfc+1
bra L9422
L941a: lda (Zfe)
ror
tay
bcs L9422 ; these two instr could be "bcc L940c"
bra L940c
L9422:
rept 7
clc
rol Zfc
rol Zfc+1
bcs L943c
tya
ror
tay
bcc L9443
L942e: lda #$21
eor Zfc
sta Zfc
lda #$10
eor Zfc+1
sta Zfc+1
bra L9443
L943c: tya
ror
tay
bcs L9443
bra L942e
L9443:
endm
inc Zfe
beq L9510
jmp L93ff
L9510: inc Zfe+1
lda Zfe+1
sec
sbc #$80
tax
and #$07
beq L951f
jmp L93ff
L951f: txa
clc
ror
ror
ror
dec
asl
tax
lda Dffda,x
cmp Zfc
beq L9530
L952e: sec
rts
L9530: lda Dffda+1,x
cmp Zfc+1
bne L952e
cpx #$1c
beq L953e
jmp L93fb
L953e: clc
rts
; verify slot pseudoROM (7b00, host cn00) against slot ROM image (8100),
; except that Cn18 is expected to be $00
verify_slot_pseudorom:
ldx #$00
L9542: cpx #$18
bne L954a
lda #$00
bra L954d
L954a: lda D8100,x
L954d: cmp D7b00,x
bne L9557
dex
bne L9542
clc
rts
L9557: sec
rts
; copy some of diagnostic code to host shared ROM
copy_diag_to_host:
ldx #$00
L955b: lda D8800+$0200,x
sta D7c00,x
dex
bne L955b
L9564: lda D8800+$0300,x
sta D7c00+$0100,x
dex
bne L9564
L956d: lda D8800+$0400,x
sta D7c00+$0200,x
dex
bne L956d
L9576: lda D8800+$0500,x
sta D7c00+$0300,x
dex
bne L9576
rts
verify_diag_copied_correctly:
ldx #$00
L9582: lda D8800+$0200,x
cmp D7c00,x
bne L95b0
dex
bne L9582
L958d: lda D8800+$0300,x
cmp D7c00+$0100,x
bne L95b0
dex
bne L958d
L9598: lda D8800+$0400,x
cmp D7c00+$0200,x
bne L95b0
dex
bne L9598
L95a3: lda D8800+$0500,x
cmp D7c00+$0300,x
bne L95b0
dex
bne L95a3
clc
rts
L95b0: sec
rts
copy_D8e00_to_zp:
ldx #$00
L95b4: lda D8e00,x
sta Z00,x
dex
bne L95b4
rts
compare_D8e00_to_zp:
ldx #$00
L95bf: lda D8e00,x
cmp Z00,x
bne L95cb
dex
bne L95bf
clc
rts
L95cb: sec
rts
; test fail
L95cd: lda #$4f
sta Z02
L95d1: sta D0a81
ldx #$00
L95d6: lda #$00
L95d8: dec
bne L95db
L95db: nop
nop
bne L95d8
dex
bne L95d6
sta D0a80
ldx #$00
L95e7: lda #$00
L95e9: dec
rept 6
bne *+2
endm
nop
bne L95e9
dex
bne L95e7
sta D0a81
ldx #$ff
L9601: lda #$cb
L9603: dec
bne L9606
L9606: nop
bne L9603
dex
bne L9601
sta D0a80
ldx #$96
L9611: lda #$cb
L9613: dec
bne L9616
L9616: nop
bne L9613
dex
bne L9611
sta D0a81
ldx #$ff
L9621: lda #$cb
L9623: dec
bne L9626
L9626: nop
bne L9623
dex
bne L9621
sta D0a80
ldx #$96
L9631: lda #$cb
L9633: dec
bne L9636
L9636: nop
bne L9633
dex
bne L9631
sta D0a81
lda D03ff
cmp #$55
bne L95d1
jmp L928c
; copy 35 bytes of slot ROM image into slot pseudoROM
; (minimum required while on-board processor is doing
; self-test and initialization)
; rest copied later
reset2: ldy #(HLcn23-HLcn00)-1
L964b: lda D8100,y
sta D7b00,y
dey
bpl L964b
; compute ROM checksum
stz Zfe
lda #$80
sta Zfe+1
lda #$00
tax
tay
L965e: clc
adc (Zfe),y
bcc L9664
inx
L9664: iny
bne L965e
inc Zfe+1
tay
lda Zfe+1
inc
beq L9674
tya
ldy #$00
bra L965e
L9674: tya
ldy #$00
L9677: clc
adc (Zfe),y
bcc L967d
inx
L967d: iny
beq L9687
cpy #$f9
bne L9677
iny
bra L9677
L9687: tay
beq L968d
jmp L9888
L968d: txa
clc
adc Dfffa-1
beq L9697
jmp L9888
L9697: bit iwm_q7l ; reset IWM (assumed not to be in ISM mode)
bit iwm_q6l
bit iwm_ph0_off
bit iwm_ph1_off
bit iwm_ph2_off
bit iwm_ph3_off
bit iwm_motor_off
lda iwm_q7l ; Q6L,Q7L - should read all ones
cmp #$ff
beq L96b6 ; yes
jmp L9888 ; no, failure
L96b6: lda #$1f
bit iwm_q6h
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L96c8
jmp L9888
L96c8: lda #$00
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L96d7
jmp L9888
L96d7: lda #$0f
bit iwm_q6h
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L96e9
jmp L9888
; set SWIM to ISM mode
L96e9: lda #$4f
bit iwm_q6h
sta iwm_q7h
eor #$40
sta iwm_q7h
eor #$40
sta iwm_q7h
sta iwm_q7h
lda #$05
L9700: dec
bne L9700
lda iwm_q6l
cmp #$f0
bne L9740
lda iwm_q7l
and #$c0
cmp #$40
bne L9740
stz iwm_ph3_off
lda #$01
L9718: sta iwm_ph1_on
asl
bcc L9718
lda #$fe
L9720: sta iwm_ph1_on
rol
bcs L9720
stz iwm_ph3_off
lda #$01
L972b: cmp iwm_sel_drive_2
bne L9740
asl
bcc L972b
lda #$fe
L9735: cmp iwm_sel_drive_2
bne L9740
sec
rol
bcs L9735
bra L9743
L9740: jmp L9888
L9743: lda #$f8 ; switch SWIM from ISM to IWM mode
sta ism_w_zeros
bit iwm_q7l ; reset IWM (assumed not to be in ISM mode)
bit iwm_q6l
bit iwm_ph0_off
bit iwm_ph1_off
bit iwm_ph2_off
bit iwm_ph3_off
bit iwm_motor_off
lda iwm_q7l ; Q6L,Q7L should read all ones
cmp #$ff
beq L9767 ; yes
jmp L9888 ; no, failure
L9767: lda #$1f
bit iwm_q6h
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L9779
jmp L9888
L9779: lda #$00
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L9788
jmp L9888
L9788: lda #$0f
bit iwm_q6h
sta iwm_q7h
eor iwm_q7l
and #$1f
beq L979a
jmp L9888
L979a: lda #$00
tax
L979d: sta D0100,x
inc
inx
bne L979d
lda #$01
sta D0403
asl
sta D0503
asl
sta D0603
asl
sta D0803
asl
sta D1003
asl
sta D1203
asl
sta D2003
asl
sta D4003
lda #$01
cmp D0403
beq L97cf
jmp L9888
L97cf: asl
cmp D0503
beq L97d8
jmp L9888
L97d8: asl
cmp D0603
beq L97e1
jmp L9888
L97e1: asl
cmp D0803
beq L97ea
jmp L9888
L97ea: asl
cmp D1003
beq L97f3
jmp L9888
L97f3: asl
cmp D1203
beq L97fc
jmp L9888
L97fc: asl