micro-sci-a2-controller/firmware/util.s
2023-07-29 06:08:13 +09:00

189 lines
7.1 KiB
ArmAsm

; Micro-SCI / Franklin "Technician Mode" firmware
;
; Thanks to S.Elliott@AppleFritter for comments/analysis
.setcpu "6502"
.org $c600
A2L := $3e
SLOTx16 := $fd
; motherboard IO ports
KBD := $C000
KBDSTRB := $C010
; DEVSEL ports, accessed via SLOTx16 in X reg
STEPOFF := $C080
STEPON := $C081
MOTOROFF := $C088
MOTORON := $C089
Q6OFF := $C08C
Q6ON := $C08D
Q7OFF := $C08E
Q7ON := $C08F
MON_WAIT := $FCA8
GETLNZ := $FD67
BELL := $FF3A
IORTS := $FF58
GETNUM := $FFA7
KEY_POUND := $A3
KEY_S := $EC
KEY_W := $F0
KEY_Z := $F3
KEY_M := $06
KEY_R := $EB
KEY_X := $F1
KEY_Q := $EA
lda #KEY_POUND
sta $33 ; set input-prompt character to '#'
LC604: jsr BELL
LC607: jsr GETLNZ ; start new line and take input
lda #$00
sta $F2
PARSER: sta KBDSTRB ; clear keyboard strobe
sta $F3
ldy $F2
jsr GETNUM ; parse hex into A2, A has last char xor $b0
; plus $89
sty $F2
cmp #$C6 ; $C6 from $8D (return)
beq LC607 ; no more input, go prompt for new input
cmp #KEY_S ; 'S'
beq CMD_S
cmp #KEY_W ; 'W'
beq CMD_W
cmp #KEY_Z ; 'Z'
beq CMD_Z
ldy #$7F
cmp #KEY_M ; 'M'
beq CMD_MX
cmp #KEY_R ; 'R'
beq CMD_R
ldx #$06
stx $F3
cmp #KEY_X ; 'X'
beq CMD_MX
cmp #KEY_Q ; 'Q'
bne LC604 ; BEEP and prompt for new input
brk ; 'Q' exits out
; 'R': recalibrate by seeking track 0 from track 80
CMD_R: lda #80 ; set starting track
sta $FC ; store accumulator as 'current' track at $FC
txa ; set accumulator to 0
adc #$00 ; inc A (carry still set from CMP #$EB)
sta $F3 ; set ($F3)=01
lda #$00 ; pass target track 0 through accumulator
beq LC651 ; branch to end of 'S' command to finish
; 'S': seek logical-track index in A2L ('22S' seeks logical track $22)
CMD_S: lda A2L ; load logical track-index from A2L
asl a ; convert to physical track-index
LC651: sta $F0 ; store accumulator as target track at $F0
ldy #$FF ; value to be stored at $09 = #$FF
bne CMD_MX ; branch to 'M' command for next step
; 'Z': seek logical-track index in A2L (eg: "22Z" seeks logical track $22)
CMD_Z: lda A2L ; load logical track-index from A2L
asl a ; convert to physical track-index
sta $F1 ; store as target track in $F1
ldy #$00 ; value to stored at $09 = #$00
beq CMD_MX ; branch to 'M' command for next step
; temporarily stop motor, then branch to turn it on again
STOP_MOTOR: lda #$50
jsr MON_WAIT
sta MOTOROFF,x
ldy A2L
LC66A: jsr MON_WAIT
dey
bpl LC66A
bmi LC68E
; EXIT THRU GIFT SHOP, current command finished, go back to parser
DONE: lda #$00
beq PARSER
; 'W' command, write nibble-pattern in A2L (eg: "96W" writes 96 96 96...)
CMD_W: lda A2L ; pattern to write
sta $FF
ldy #$0F
; 'M' command while Y=#7F and X=#00
; 'X' command while Y=#7F and X=#06 and ($f3)=#06
CMD_MX: sty $09 ; preserve actual command
jsr IORTS ; put our address on stack
tsx
lda $0100,x ; derive our DEVSEL index
asl a
asl a
asl a
asl a
sta SLOTx16 ; save DEVSEL index for future IO
adc $F3
tax
LC68E: sta MOTORON,x
lda $09
beq LC6BA ; Y=00, branch for 'Z'
bmi LC6BA ; Y=FF, branch for 'S'
asl a
bmi LC6AC
sta Q7ON,x ; start writing/erasing
LC69D: lda $09 ; [3 cycles] reload saved Y byte
asl a ; [2] shift-left to test second bit
bmi STOP_MOTOR ; [2] branch to stop motor for M/X/S commands
nop
nop
lda $FF ; byte value to be written
sta Q6ON,x ; store into data register
; (wrong timing for Disk II, it would probably
; write $DD instead)
cmp Q6OFF,x ; [4] shift data-out
LC6AC: lda KBD ; get keypress
eor #$9B ; ESC?
bne LC69D ; if not, continue loop
ldx SLOTx16
sta Q7OFF,x
LC6B8: beq DONE ; all done, branch to branch-to-parser
LC6BA: ldx SLOTx16
sta MOTORON,x
LC6BF: ldy $FC
LC6C1: cpy $F0 ; compare track index in Y to target track (result in carry flag)
bne LC6E3 ; track doesn't match, go to stepper routine
lda $F0 ; load current track into A (why not tya?)
sta $FC ; store current track
lda $09
bne DONE ; Y=00, branch for 'Z'
lda $F0 ; exchange target track indexes in $F0 vs $F1
ldy $F1
sta $F1
sty $F0
lda KBD ; read current key value
eor #$9B ; $9B = <esc>
beq LC6B8 ; if current key is <esc> then branch
lda #$73
jsr MON_WAIT ; delay for mechanical seek time
bcs LC6BF
LC6E3: bcs LC6E7 ; track numbers increasing or decreasing?
iny ; increment track number in Y reg
iny ; decrement track number in Y reg
LC6E7: dey
tya
and #$03 ; mask track to just 4 low bits, numbers 00-01-02-03
asl a ; shift left, convert to stepper-motor phases 02-04-06-08
ora SLOTx16 ; bitwise-OR for DEVSEL-relative IO address
tax ; move it into X for IO
lsr a ; shift right to make track number again
lsr a ; shift low-bit into carry flag (odd vs even)
sta STEPON,x ; turn on stepper motor phase indicated in X
nop ; dead code
nop
lda #$56
jsr MON_WAIT ; wait stepper delay (returns A=00, carry set)
sta STEPOFF,x ; turn off stepper motor phase indicated in X
bcs LC6C1 ; branch always