File: diskcmd.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (233 lines) | stat: -rw-r--r-- 6,235 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
;
; Ullrich von Bassewitz, 2002-11-17, 2009-02-22
;
; Handle disk command channels
;

        .export         isdisk
        .export         opencmdchannel
        .export         closecmdchannel
        .export         readdiskerror
        .export         writediskcmd
        .export         writefndiskcmd

        .import         fncmd, fnlen, fnunit
        .importzp       tmp1, ptr1

        .include        "cbm.inc"
        .include        "filedes.inc"

;--------------------------------------------------------------------------
; isdisk: Return carry clear if the unit number in X is a disk, return
; carry set if not.

.proc   isdisk

        cpx     #FIRST_DRIVE    ; Disk unit?
        bcc     @L1             ; Branch if no disk
        cpx     #FIRST_DRIVE+MAX_DRIVES
        rts

@L1:    sec
        rts

.endproc

;--------------------------------------------------------------------------
; Open the command channel for the disk unit in X. The function returns an
; error code in A and sets the flags according to the contents of A.

opencmdchannel:

        jsr     isdisk          ; Disk unit?
        bcs     success

; Is this channel already open?

        ldy     opentab-FIRST_DRIVE,x
        bne     isopen

; Open the command channel, Carry is still clear

        stx     tmp1            ; Save the unit number
        txa                     ; Get unit number
        adc     #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
        ldy     #15             ; Secondary address for cmd channel
        jsr     SETLFS

        lda     #0
        jsr     SETNAM          ; No name supplied to OPEN

        jsr     OPEN
        bcs     done            ; Error, code is in A

; Command channel is open now. Increment the count

        ldx     tmp1            ; Unit number
        ldy     opentab-FIRST_DRIVE,x
isopen: iny
        tya
        sta     opentab-FIRST_DRIVE,x

; Done, return success

success:lda     #$00
done:   cmp     #$00            ; Set flags for return code
        rts


;--------------------------------------------------------------------------
; closecmdchannel: Decrement the counter for the disk command channel and
; close the channel if the counter drops to zero. The function expects the
; drive number in X and returns an error code in A. The flags for the return
; code are set when the function returns.

closecmdchannel:

        jsr     isdisk          ; Disk unit?
        bcs     success

; Is this channel really open?

        ldy     opentab-FIRST_DRIVE,x
        beq     success         ; OOPS! Channel is not open

; Decrement the count and stor it back

        dey
        tya
        sta     opentab-FIRST_DRIVE,x

; If the counter is now zero, close the channel. We still have carry clear
; when we come here.

        bne     success
        txa                     ; Make LFN from drive number
        adc     #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
        jsr     CLOSE
        bcs     done
        bcc     success

;--------------------------------------------------------------------------
; readdiskerror: Read a disk error from an already open command channel.
; Returns an error code in A, which may either be the code read from the
; command channel, or another error when accessing the command channel failed.

readdiskerror:

        jsr     isdisk
        bcs     success

; Read the command channel. We won't check the status after the channel is
; open, because this seems to be unnecessary in most cases.

        txa
        clc                     ; Make LFN from drive number
        adc     #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
        tax
        jsr     CHKIN           ; Make the command channel input
        bcs     done            ; Bail out with error code in A

        jsr     BASIN
        and     #$0F            ; Make digit value from PETSCII
        sta     tmp1
        asl     a               ; * 2
        asl     a               ; * 4, carry clear
        adc     tmp1            ; * 5
        asl     a               ; * 10
        sta     tmp1

        jsr     BASIN
        and     #$0F            ; Make digit value from PETSCII
        clc
        adc     tmp1

; Errors below 20 are not real errors. Fix that

        cmp     #20+1
        bcs     @L1
        lda     #$00
@L1:    pha

; Read the remainder of the message and throw it away

@L2:    jsr     BASIN
        cmp     #$0D
        bne     @L2

; Close the input channel

        jsr     CLRCH

; Restore the error code (will also set the flags) and return

        pla
        rts

;--------------------------------------------------------------------------
; writefndiskcmd: Write the contents of fncmd to the command channel of the
; drive in fnunit. Returns an error code in A, flags are set according to
; the contents of A.

writefndiskcmd:
        lda     #<fncmd
        sta     ptr1
        lda     #>fncmd
        sta     ptr1+1

        ldx     fnlen
        inx                     ; Account for command char in fncmd
        txa                     ; Length of name into A
        ldx     fnunit          ; Unit

; Run directly into writediskcmd

;       jmp     writediskcmd

;--------------------------------------------------------------------------
; writediskcmd: Gets pointer to data in ptr1, length in A. Writes all data
; to the command channel of the drive in X. Returns an error code in A,
; flags are set according to the contents of A.

writediskcmd:

        jsr     isdisk
        bcs     success         ; No disk - already done

; Remember the length

        sta     tmp1

; Write to the command channel.

        txa
        clc                     ; Make LFN from drive number
        adc     #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
        tax
        jsr     CKOUT           ; Make the command channel output
        bcs     done            ; Bail out with error code in A

        ldy     #$00
@L1:    cpy     tmp1
        bcs     @L3
        lda     (ptr1),y
        iny
        jsr     BSOUT
        bcc     @L1

@L2:    pha
        jsr     CLRCH
        pla
        rts

@L3:    jsr     CLRCH
        lda     #$00
        rts


;--------------------------------------------------------------------------
; Data

.bss

opentab:        .res    MAX_DRIVES, 0