; da65 V2.11.0 - (C) Copyright 2000-2005, Ullrich von Bassewitz ; Created: 2022-01-26 21:00:18 ; Input file: xaa ; Page: 1 .setcpu "6502" ; monitor routine addresses MON_WAIT = $FCA8 GETLNZ = SLOTx1667 BELL = $FF3A IORTS = $FF58 GETNUM = $FFA7 ; monitor-defined ZP locations A2L equ 3E ; motherboard IO ports KBD equ $C000 KBDSTRB equ $C010 ; DEVSEL ports, accessed via SLOTx16 in X reg STEPOFF equ $C080 STEPON equ $C081 MOTOROFF equ $C088 MOTORON equ $C089 Q6OFF equ $C08C Q6ON equ $C08D Q7OFF equ $C08E Q7ON equ $C08F ; SLOTx16 equ $FD * = $c600 lda #$A3 ;* $A3 = '#' sta $33 ;* set input-prompt character to '#' LC604: jsr BELL LC607: jsr GETLNZ ;* start new line with prompt character and take input lda #$00 sta $F2 ;* parse-index starts at #00 LC60E: sta KBDSTRB ;* clear keyboard strobe (to allow multiple commands) sta $F3 ;* initially set ($F3)=#00 ldy $F2 ;* get parse-index in Y reg jsr GETNUM ;* parse hexadecimal input into pointer A2, accumulator contains last char EOR'd with $B0 plus $89 (X=00 on return) sty $F2 ;* save parse-index from Y reg cmp #$C6 ;* $C6 from $8D (return key) beq LC607 ;* no more input, go prompt for new input cmp #$EC ;* $EC from $D3 = 'S' beq LC64E cmp #$F0 ;* $F0 from $D7 = 'W' beq LC676 cmp #$F3 ;* $F3 from $DA = 'Z' beq LC657 ldy #$7F cmp #$06 ;* $06 from $CD = 'M' beq LC67C cmp #$EB ;* $EB from $D2 = 'R' beq LC641 ldx #$06 stx $F3 ;* set ($F3)=#06 cmp #$F1 ;* $F1 from $D8 = 'X' beq LC67C cmp #$EA ;* $EA from $D1 = 'Q' bne LC604 ;* if not 'Q' then branch to BEEP and prompt for new input brk ;* ---BREAK--- ;;;;;; 'R' command, recalibrate by seeking track $00 from track $50 LC641: lda #$50 ;* set starting track to #$50 sta $FC ;* store accumulator as 'current' track at $FC txa ;* set accumulator to 0 adc #$00 ;* increment accumulator (carry is still set from CMP #$EB instruction) sta $F3 ;* set ($F3)=01 lda #$00 ;* pass target track #$00 through accumulator beq LC651 ;* branch to latter part of 'S' command for next step ;;;;;; 'S' command, seek logical-track index in A2L (eg: "22S" seeks logical track $22) LC64E: 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 LC67C ;* branch to 'M' command for next step ;;;;;; 'Z' command, seek logical-track index in A2L (eg: "22Z" seeks logical track $22) LC657: 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 LC67C ;* branch to 'M' command for next step ;;;;;; temporarily stop motor, then branch to turn it on again LC660: 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 LC672: lda #$00 beq LC60E ;* branch back to command parser ;;;;;; 'W' command, write nibble-pattern in A2L (eg: "96W" writes 96 96 96...) LC676: lda A2L sta $FF ldy #$0F ;;;;;; 'M' command while Y=#7F and X=#00 ;;;;;; 'X' command while Y=#7F and X=#06 and ($f3)=#06 LC67C: sty $09 ;* store Y (7F for 'M' and 'X', 00 for 'Z', FF for 'S') jsr IORTS ;* call a return instruction to put our return address onto stack tsx lda $0100,x ;* retrieve the high-byte of our own return address into accumulator asl a ;* shift accumulator left until it contains our slot number times 16 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 LC660 ;* [2] branch to stop motor for 'M' and 'X' and 'S' commands nop ;* [2] nop ;* [2] lda $FF ;* [3] load accumulator with byte value to be written sta Q6ON,x ;* [5] store accumulator into data register (wrong timing for Disk II, it would probably write $DD instead) cmp Q6OFF,x ;* [4] shift data-out LC6AC: lda KBD ;* [4] load key eor #$9B ;* [2] test if user presseed ESC key ($9B = ) bne LC69D ;* [3] if not, loop back and write another byte ldx SLOTx16 sta Q7OFF,x ;* stop writing LC6B8: beq LC672 ;* all done, branch to branch-to-parser LC6BA: ldx SLOTx16 sta MOTORON,x LC6BF: ldy $FC LC6C1: cpy $F0 ;* compare track index in Y against target track (result in carry flag) bne LC6E3 ;* track doesn't match, go to stepper routine lda $F0 ;* load current track into accumulator (redundant, same value is already in Y reg) sta $FC ;* store current track lda $09 bne LC672 ;* 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 to allow mechanism to move before next step bcs LC6BF LC6E3: bcs LC6E7 ;* track numbers increasing or decreasing? iny ;* increment track number in Y reg iny ;* increment again to compensate for decrement in next instruction LC6E7: dey ;* decrement track number in Y reg 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 to make it into a DEVSEL-relative IO address tax ;* move it into X reg for IO lsr a ;* shift right to make track number again lsr a ;* now shift low-bit into carry flag (odd vs even) sta STEPON,x ;* turn on stepper motor phase indicated in X reg nop ;* probably deleted code nop ;* (NOPs serve no purpose here) lda #$56 jsr MON_WAIT ;* wait stepper delay (returns with A=00, carry set) sta STEPOFF,x ;* turn off stepper motor phase indicated in X reg bcs LC6C1 ;* branch always