diff --git a/firmware/Makefile b/firmware/Makefile index 0f072b2..57b8790 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,18 +1,18 @@ -all: util.bin 16.bin 13.bin legend-franklin.bin legend-usci.bin - cat util.bin 16.bin 13.bin legend-franklin.bin > firmware-franklin.bin - cat util.bin 16.bin 13.bin legend-usci.bin > firmware-usci.bin +all: technician.bin 16.bin 13.bin splash-franklin.bin splash-usci.bin + cat technician.bin 16.bin 13.bin splash-franklin.bin > firmware-franklin.bin + cat technician.bin 16.bin 13.bin splash-usci.bin > firmware-usci.bin -legend-franklin.bin: - ca65 --target apple2 -o legend-franklin.o legend.s - ld65 --config apple2-asm.cfg -o legend-franklin.bin legend-franklin.o +splash-franklin.bin: + ca65 --target apple2 -o splash-franklin.o splash.s + ld65 --config apple2-asm.cfg -o splash-franklin.bin splash-franklin.o -legend-usci.bin: - ca65 --target apple2 -DMICROSCI -o legend-usci.o legend.s - ld65 --config apple2-asm.cfg -o legend-usci.bin legend-usci.o +splash-usci.bin: + ca65 --target apple2 -DMICROSCI -o splash-usci.o splash.s + ld65 --config apple2-asm.cfg -o splash-usci.bin splash-usci.o -util.bin: - ca65 --target apple2 -o util.o util.s - ld65 --config apple2-asm.cfg -o util.bin util.o +technician.bin: + ca65 --target apple2 -o technician.o technician.s + ld65 --config apple2-asm.cfg -o technician.bin technician.o 13.bin: ca65 --target apple2 -DSECSIZE_13 -o 13.o firmware.s diff --git a/firmware/splash.s b/firmware/splash.s new file mode 100644 index 0000000..b3d017b --- /dev/null +++ b/firmware/splash.s @@ -0,0 +1,70 @@ +; Micro-SCI Floppy Drive Controller info disassembly + +PRINTVEC := $08 +PRBL2 := $F94A +HOME := $FC58 +COUT := $FDED + +.include "screencode.h" +.org $c600 + + ldx #$20 ; controller signature + ldy #$00 + ldx #$03 + stx $3C + + jsr HOME ; clear display, home cursor + tsx + lda $0100,x ; current address (#$c6 for slot 6) + sta PRINTVEC+1 + lda #0 + sta PRINTVEC + ldy # +; +; ---------JUMPER-------- +; ! ! ! +; V V V +; +; ### ! ! ! ### ! ! ! ### +; ### ! ! ! ### ! ! ! ### +; ### ! ! ! ### ! ! ! ### +; ### ! ! ! ### ! ! ! ### +; XXXXXXX XXXXXXX XXXXXXX +; 3.2 INFO 3.3&PASCAL +; +; Franklin differs on the first three lines: +; <--KEYBOARD ACE 1000 REAR--> +; +; ------JUMPER------ + +info: screencode $0d, "<--KEYBOARD" +.ifdef MICROSCI + screencode $08, "U-SCI", $08, "REAR-->", $0d, $0d + screencode $08, "---------JUMPER--------", $0d +.else + + screencode $06, "ACE 1000", $06, "REAR-->", $0d, $0d + screencode $07, " ", $02, "------JUMPER------", $0d +.endif + screencode $07, "!", $0b, "!", $0b, "!", $0d + screencode $07, "V", $0b, "V", $0b, "V", $0d, $0d + screencode $06, "### ! !", $03, "! ### !", $03, "! ! ###", $0d + screencode $06, "### ! !", $03, "! ### !", $03, "! ! ###", $0d + screencode $06, "### ! !", $03, "! ### !", $03, "! ! ###", $0d + screencode $06, "### ! !", $03, "! ### !", $03, "! ! ###", $0d + + screencode $06, "XXXXXXX", $03, "XXXXXXX", $03, "XXXXXXX", $0d + screencode $08, "3.2", $06, "INFO", $04, "3.3&PASCAL", $0d, $0d diff --git a/firmware/sums b/firmware/sums index ad7f683..2cf8fc6 100644 --- a/firmware/sums +++ b/firmware/sums @@ -4,6 +4,6 @@ 2020aa1413ff77fe29353f3ee72dc295 16.bin eb8628274eb1a3601723023d3ffe7ef3 firmware-franklin.bin 94fe3d85c9232b53f28a1c6a2a9c9764 firmware-usci.bin -b2e7d74cdf9b43ee8ae3036b1f21cbd5 legend-franklin.bin -105927e7c409116974a45e366beab55b legend-usci.bin -6681f504c6cc3b6887fef51726c96ca1 util.bin +b2e7d74cdf9b43ee8ae3036b1f21cbd5 splash-franklin.bin +105927e7c409116974a45e366beab55b splash-usci.bin +6681f504c6cc3b6887fef51726c96ca1 technician.bin diff --git a/firmware/technician.s b/firmware/technician.s new file mode 100644 index 0000000..8020ec3 --- /dev/null +++ b/firmware/technician.s @@ -0,0 +1,188 @@ +; 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 = + beq LC6B8 ; if current key is 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