1; 2; Ullrich von Bassewitz, 2002-11-17, 2009-02-22 3; 4; Handle disk command channels 5; 6 7 .export isdisk 8 .export opencmdchannel 9 .export closecmdchannel 10 .export readdiskerror 11 .export writediskcmd 12 .export writefndiskcmd 13 14 .import fncmd, fnlen, fnunit 15 .importzp tmp1, ptr1 16 17 .include "cbm.inc" 18 .include "filedes.inc" 19 20;-------------------------------------------------------------------------- 21; isdisk: Return carry clear if the unit number in X is a disk, return 22; carry set if not. 23 24.proc isdisk 25 26 cpx #FIRST_DRIVE ; Disk unit? 27 bcc @L1 ; Branch if no disk 28 cpx #FIRST_DRIVE+MAX_DRIVES 29 rts 30 31@L1: sec 32 rts 33 34.endproc 35 36;-------------------------------------------------------------------------- 37; Open the command channel for the disk unit in X. The function returns an 38; error code in A and sets the flags according to the contents of A. 39 40opencmdchannel: 41 42 jsr isdisk ; Disk unit? 43 bcs success 44 45; Is this channel already open? 46 47 ldy opentab-FIRST_DRIVE,x 48 bne isopen 49 50; Open the command channel, Carry is still clear 51 52 stx tmp1 ; Save the unit number 53 txa ; Get unit number 54 adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE) 55 ldy #15 ; Secondary address for cmd channel 56 jsr SETLFS 57 58 lda #0 59 jsr SETNAM ; No name supplied to OPEN 60 61 jsr OPEN 62 bcs done ; Error, code is in A 63 64; Command channel is open now. Increment the count 65 66 ldx tmp1 ; Unit number 67 ldy opentab-FIRST_DRIVE,x 68isopen: iny 69 tya 70 sta opentab-FIRST_DRIVE,x 71 72; Done, return success 73 74success:lda #$00 75done: cmp #$00 ; Set flags for return code 76 rts 77 78 79;-------------------------------------------------------------------------- 80; closecmdchannel: Decrement the counter for the disk command channel and 81; close the channel if the counter drops to zero. The function expects the 82; drive number in X and returns an error code in A. The flags for the return 83; code are set when the function returns. 84 85closecmdchannel: 86 87 jsr isdisk ; Disk unit? 88 bcs success 89 90; Is this channel really open? 91 92 ldy opentab-FIRST_DRIVE,x 93 beq success ; OOPS! Channel is not open 94 95; Decrement the count and stor it back 96 97 dey 98 tya 99 sta opentab-FIRST_DRIVE,x 100 101; If the counter is now zero, close the channel. We still have carry clear 102; when we come here. 103 104 bne success 105 txa ; Make LFN from drive number 106 adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE) 107 jsr CLOSE 108 bcs done 109 bcc success 110 111;-------------------------------------------------------------------------- 112; readdiskerror: Read a disk error from an already open command channel. 113; Returns an error code in A, which may either be the code read from the 114; command channel, or another error when accessing the command channel failed. 115 116readdiskerror: 117 118 jsr isdisk 119 bcs success 120 121; Read the command channel. We won't check the status after the channel is 122; open, because this seems to be unnecessary in most cases. 123 124 txa 125 clc ; Make LFN from drive number 126 adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE) 127 tax 128 jsr CHKIN ; Make the command channel input 129 bcs done ; Bail out with error code in A 130 131 jsr BASIN 132 and #$0F ; Make digit value from PETSCII 133 sta tmp1 134 asl a ; * 2 135 asl a ; * 4, carry clear 136 adc tmp1 ; * 5 137 asl a ; * 10 138 sta tmp1 139 140 jsr BASIN 141 and #$0F ; Make digit value from PETSCII 142 clc 143 adc tmp1 144 145; Errors below 20 are not real errors. Fix that 146 147 cmp #20+1 148 bcs @L1 149 lda #$00 150@L1: pha 151 152; Read the remainder of the message and throw it away 153 154@L2: jsr BASIN 155 cmp #$0D 156 bne @L2 157 158; Close the input channel 159 160 jsr CLRCH 161 162; Restore the error code (will also set the flags) and return 163 164 pla 165 rts 166 167;-------------------------------------------------------------------------- 168; writefndiskcmd: Write the contents of fncmd to the command channel of the 169; drive in fnunit. Returns an error code in A, flags are set according to 170; the contents of A. 171 172writefndiskcmd: 173 lda #<fncmd 174 sta ptr1 175 lda #>fncmd 176 sta ptr1+1 177 178 ldx fnlen 179 inx ; Account for command char in fncmd 180 txa ; Length of name into A 181 ldx fnunit ; Unit 182 183; Run directly into writediskcmd 184 185; jmp writediskcmd 186 187;-------------------------------------------------------------------------- 188; writediskcmd: Gets pointer to data in ptr1, length in A. Writes all data 189; to the command channel of the drive in X. Returns an error code in A, 190; flags are set according to the contents of A. 191 192writediskcmd: 193 194 jsr isdisk 195 bcs success ; No disk - already done 196 197; Remember the length 198 199 sta tmp1 200 201; Write to the command channel. 202 203 txa 204 clc ; Make LFN from drive number 205 adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE) 206 tax 207 jsr CKOUT ; Make the command channel output 208 bcs done ; Bail out with error code in A 209 210 ldy #$00 211@L1: cpy tmp1 212 bcs @L3 213 lda (ptr1),y 214 iny 215 jsr BSOUT 216 bcc @L1 217 218@L2: pha 219 jsr CLRCH 220 pla 221 rts 222 223@L3: jsr CLRCH 224 lda #$00 225 rts 226 227 228;-------------------------------------------------------------------------- 229; Data 230 231.bss 232 233opentab: .res MAX_DRIVES, 0 234