]> git.sur5r.net Git - cc65/blob - libsrc/cbm/diskcmd.s
Fixed bugs; and, improved the efficiency of some pce library functions.
[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         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
40 opencmdchannel:
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
68 isopen: iny
69         tya
70         sta     opentab-FIRST_DRIVE,x
71
72 ; Done, return success
73
74 success:lda     #$00
75 done:   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
85 closecmdchannel:
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
116 readdiskerror:
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
172 writefndiskcmd:
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
192 writediskcmd:
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
233 opentab:        .res    MAX_DRIVES, 0