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