PAGE SBTTL "--- DISK ACCESS CODE: CBM PLUS/4 ---" ; -------------- ; OPEN DRIVE [A] ; -------------- ; ENTRY: DISK ID (8 OR 9 BINARY) IN [A] I0: DB "I0" I0L EQU $-I0 DOPEN: STA DRIVE ; SAVE DRIVE ID HERE JSR DCLOSE ; CLOSE COMMAND & DATA CHANNELS LDA #15 ; LOGICAL FILE # TAY ; SECONDARY ADDRESS LDX DRIVE ; DEVICE # (8 OR 9) JSR SETLFS ; SET UP LOGICAL FILE LDX #LOW I0 ; POINT TO FILENAME LDY #HIGH I0 ; "I0:" LDA #I0L ; LENGTH OF FILENAME JSR SETNAM JMP OPEN ; OPEN THE DISK (CARRY CLEAR IF OK) ; -------------------------- ; OPEN DIRECT ACCESS CHANNEL ; -------------------------- POUND: DB "#" POUNDL EQU $-POUND AOPEN: JSR ACLOSE LDA #2 ; D/A CHANNEL ID TAY ; SECONDARY ID LDX DRIVE JSR SETLFS LDX #LOW POUND ; POINT TO FILENAME LDY #HIGH POUND ; "#" LDA #POUNDL JSR SETNAM JMP OPEN ; OPEN CHANNEL (CARRY CLEAR IF OK) ; ------------------- ; CLOSE CURRENT DRIVE ; ------------------- DCLOSE: LDA #15 ; CLOSE COMMAND CHANNEL JSR CLOSE ; FALL THROUGH ... ; --------------------- ; CLOSE THE D/A CHANNEL ; --------------------- ACLOSE: LDA #2 ; AND THE JMP CLOSE ; DATA CHANNEL ; ---------------- ; DIVIDE [A] BY 10 ; ---------------- ; EXIT: QUOTIENT IN [X], REMAINDER IN [A] DIV10: LDX #0 ; START WITH ZERO QUOTIENT D10L: CMP #10 ; IF DIVISOR < 10, BCC D10EX ; WE'RE DONE SBC #10 ; ELSE SUBTRACT ANOTHER 10 INX ; UPDATE QUOTIENT BNE D10L ; BRANCH ALWAYS D10EX: RTS ; --------------- ; SEND Ux COMMAND ; --------------- ; ENTRY: ASCII "1" OR "2" IN [A] COMLIN: DB "U" DCOMM: DB "*" DB ":2,0," DTRAK: DB "***," DSECT: DB "***" DB EOL CMLL EQU $-COMLIN SENDU: STA DCOMM ; INSERT COMMAND ("1" OR "2") IN STRING ; CONVERT [TRACK] AND [SECTOR] TO ASCII IN [COMLIN] LDA TRACK LDY #2 TCON: JSR DIV10 ; DIVIDE BY 10 ORA #'0' ; CONVERT TO ASCII STA DTRAK,Y ; STORE INTO STRING TXA ; GET QUOTIENT INTO [A] DEY ; ZERO-FILL USUSED BYTES BPL TCON LDA SECTOR ; SAME FOR SECTOR ID LDY #2 SCON: JSR DIV10 ORA #'0' STA DSECT,Y TXA DEY BPL SCON ; SEND COMMAND JSR CLRCHN LDX #15 ; OUTPUT TO THE JSR CHKOUT ; COMMAND CHANNEL BCS UEX ; EXIT W/CARRY SET IF ERROR LDY #0 SCM0: LDA COMLIN,Y ; SEND THE COMMAND LINE JSR CHROUT ; TO THE DRIVE CHANNEL BCS UEX INY ; A BYTE AT A TIME CPY #CMLL BCC SCM0 CLC ; NO ERRORS! UEX: RTS ; ---------------------- ; SET THE BUFFER POINTER ; ---------------------- BPLINE: DB "B-P:2,0" DB EOL BPLL EQU $-BPLINE SETBP: JSR CLRCHN LDX #15 ; OUTPUT TO JSR CHKOUT ; COMMAND CHANNEL BCS BEX LDY #0 SBPL: LDA BPLINE,Y JSR CHROUT BCS BEX INY CPY #BPLL BCC SBPL CLC ; NO ERRORS! BEX: RTS ; ------------------------------ ; READ/WRITE A BLOCK TO [IOBUFF] ; ------------------------------ ; ENTRY: [TRACK] = TRACK # (1-35) ; [SECTOR] = SECTOR # (0-15) ; [DRIVE] = DRIVE ID (8 OR 9) ; CARRY CLEAR TO READ, CARRY SET TO WRITE DISK: BCS DWRITE ; WRITE IF CARRY SET ; READ A DISK BLOCK ; LDA FASTEN ; FAST-READ AVAILABLE? ; BEQ SLOW ; USE SLOW CODE IF NOT ; LDA FAST ; FAST-READ ENGAGED? ; BEQ SLOW ; NO, USE SLOW ; JMP DOFAST ; ELSE USE FAST-READ ROUTINES SLOW: JSR AOPEN ; OPEN THE ACCESS CHANNEL BCS BADISK ; CARRY SET IF ERROR LDA #'1' ; SEND A "U1" COMMAND JSR SENDU BCS BADISK JSR SETBP ; SET THE BUFFER POINTER BCS BADISK JSR CLRCHN LDX #2 ; INPUT FROM JSR CHKIN ; DATA CHANNEL BCS BADISK LDY #0 READ1: JSR CHRIN ; GET A BYTE BCS BADISK STA IOBUFF,Y ; MOVE TO I/O BUFFER INY BNE READ1 ; DO 256 BYTES BEQ SHUTD ; THEN EXIT ; WRITE A BLOCK DWRITE: JSR AOPEN ; OPEN THE ACCESS CHANNEL BCS BADISK ; CARRY SET IF ERROR JSR SETBP ; SET THE BUFFER POINTER BCS BADISK JSR CLRCHN LDX #2 ; OUTPUT TO JSR CHKOUT ; DATA CHANNEL BCS BADISK LDY #0 WRITE1: LDA IOBUFF,Y ; SEND CONTENTS OF [IOBUFF] JSR CHROUT ; TO THE DRIVE BCS BADISK INY BNE WRITE1 ; WRITE 256 BYTES LDA #'2' ; ISSUE A "U2" COMMAND JSR SENDU BCS BADISK ; EXIT W/CARRY SET IF ERROR SHUTD: JSR READST ; READ STATUS BYTE AND #%10000011 ; MASK UNINTERESTING BITS BNE BADISK ; ERROR IF ANY BIT SET JSR CLRCHN ; RESET CHANNELS CLC ; CLEAR CARRY FOR SUCCESS RTS BADISK: JSR CLRCHN SEC ; SET CARRY FOR FAILURE RTS END