3021
|
1 ********************************************************************
|
|
2 * sdrive - Assign disk image to SDC slot
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * Edt/Rev YYYY/MM/DD Modified by
|
|
7 * Comment
|
|
8 * ------------------------------------------------------------------
|
|
9 * 1 2014/11/30 tim lindner
|
|
10 * Started writing code.
|
|
11
|
|
12 nam sdrive
|
|
13 ttl Assign disk image to SDC slot
|
|
14
|
|
15 ifp1
|
|
16 use defsfile
|
|
17 endc
|
|
18
|
|
19 * Here are some tweakable options
|
|
20 DOHELP set 1 1 = include help info
|
|
21 STACKSZ set 32 estimated stack size in bytes
|
|
22 PARMSZ set 256 estimated parameter size in bytes
|
|
23
|
|
24 * Module header definitions
|
|
25 tylg set Prgrm+Objct
|
|
26 atrv set ReEnt+rev
|
|
27 rev set $00
|
|
28 edition set 1
|
|
29
|
|
30 *********************************************************************
|
|
31 *** Hardware Addressing
|
|
32 *********************************************************************
|
|
33 CTRLATCH equ $FF40 ; controller latch (write)
|
|
34 CMDREG equ $FF48 ; command register (write)
|
|
35 STATREG equ $FF48 ; status register (read)
|
|
36 PREG1 equ $FF49 ; param register 1
|
|
37 PREG2 equ $FF4A ; param register 2
|
|
38 PREG3 equ $FF4B ; param register 3
|
|
39 DATREGA equ PREG2 ; first data register
|
|
40 DATREGB equ PREG3 ; second data register
|
|
41 *********************************************************************
|
|
42 *** STATUS BIT MASKS
|
|
43 *********************************************************************
|
|
44 BUSY equ %00000001
|
|
45 READY equ %00000010
|
|
46 FAILED equ %10000000
|
|
47
|
|
48 mod eom,name,tylg,atrv,start,size
|
|
49
|
|
50 org 0
|
|
51 slot rmb 1
|
|
52
|
|
53 cleartop equ . everything up to here gets cleared at start
|
|
54 * Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do
|
|
55 rmb STACKSZ+PARMSZ
|
|
56 size equ .
|
|
57
|
|
58 * The utility name and edition goes here
|
|
59 name fcs /sdrive/
|
|
60 fcb edition
|
|
61 * Place constant strings here
|
|
62 timeout fcc /Timeout./
|
|
63 fcb C$LF
|
|
64 fcb C$CR
|
|
65 timeoutL equ *-timout
|
|
66
|
|
67 targetInUse fcc /Target in use./
|
|
68 fcb C$LF
|
|
69 fcb C$CR
|
|
70 targetInUseL equ *-targetInUse
|
|
71
|
|
72 dirNotFound fcc /Directory not found./
|
|
73 fcb C$LF
|
|
74 fcb C$CR
|
|
75 dirNotFoundL equ *-dirNotFound
|
|
76
|
|
77 pathNameInvalid fcc /Pathname is invalid./
|
|
78 fcb C$LF
|
|
79 fcb C$CR
|
|
80 pathNameInvalidL equ *-pathNameInvalid
|
|
81
|
|
82 miscHardware fcc /Miscellaneous hardware error./
|
|
83 fcb C$LF
|
|
84 fcb C$CR
|
|
85 miscHardwareL equ *-miscHardware
|
|
86
|
|
87 unknown fcc /Unknown error./
|
|
88 fcb C$LF
|
|
89 fcb C$CR
|
|
90 unknownL equ *-unknown
|
|
91
|
|
92 targetNotFound fcc /Target not found./
|
|
93 fcb C$LF
|
|
94 fcb C$CR
|
|
95 targetNotFoundL equ *-targetNotFound
|
|
96
|
|
97 IFNE DOHELP
|
|
98 HlpMsg fcb C$LF
|
|
99 fcc /Use: sdrive <slot> <image name>/
|
|
100 fcb C$LF
|
|
101 fcb C$CR
|
|
102 fcc / <slot> is a number, either 0 or 1./
|
|
103 fcb C$LF
|
|
104 fcb C$CR
|
|
105 fcc / <image name> is valid path and image name./
|
|
106 fcb C$LF
|
|
107 fcb C$CR
|
|
108 fcc / <image name> can be blank to eject an image./
|
|
109 fcb C$LF
|
|
110 fcb C$CR
|
|
111 HlpMsgL equ *-HlpMsg
|
|
112 ENDC
|
|
113 *
|
|
114 * Here's how registers are set when this process is forked:
|
|
115 *
|
|
116 * +-----------------+ <-- Y (highest address)
|
|
117 * ! Parameter !
|
|
118 * ! Area !
|
|
119 * +-----------------+ <-- X, SP
|
|
120 * ! Data Area !
|
|
121 * +-----------------+
|
|
122 * ! Direct Page !
|
|
123 * +-----------------+ <-- U, DP (lowest address)
|
|
124 *
|
|
125 * D = parameter area size
|
|
126 * PC = module entry point abs. address
|
|
127 * CC = F=0, I=0, others undefined
|
|
128
|
|
129 * The start of the program is here.
|
|
130 * main program
|
|
131 start
|
|
132 cmpd #1
|
|
133 lbeq ShowHelp
|
|
134 subb #1
|
|
135 sbca #0
|
|
136 clr d,x put null at end of parameter area (not CR)
|
|
137 leas -3,s make some more room in parameter area
|
|
138 lbsr SkipSpcs
|
|
139 clr slot,u
|
|
140 lda ,x+
|
|
141 cmpa #'0
|
|
142 beq slot0
|
|
143 cmpa #'1
|
|
144 beq slot1
|
|
145 lbra ShowHelp
|
|
146 slot1 inc slot,u
|
|
147 slot0
|
|
148 lbsr SkipSpcs skip forward to parameter
|
|
149 leax -2,x back off two bytes
|
|
150 * Add M: to start of parameter
|
|
151 ldd #"M:
|
|
152 std ,x
|
|
153 * setup SDC for command mode
|
|
154 orcc #IntMasks mask interrupts
|
|
155 lbsr CmdSetup
|
|
156 bcc sendCommand
|
|
157 andcc #^IntMasks unmask interrupts
|
|
158 ldb #$f6 Not ready error code
|
|
159 lbra Exit
|
|
160 sendCommand
|
|
161 ldb #$e0
|
|
162 orb slot,u
|
|
163 stb CMDREG send to SDC command register
|
|
164 exg a,a wait
|
|
165 lbsr txData transmit buffer to SDC
|
|
166 lda #$0
|
|
167 sta CTRLATCH
|
|
168 andcc #^IntMasks unmask interrupts
|
|
169 bcc ExitOK
|
|
170 tstb
|
|
171 beq timeOutError
|
|
172 bitb #$20
|
|
173 bne targetInUseError
|
|
174 bitb #$10
|
|
175 bne targetNotFoundError
|
|
176 bitb #$08
|
|
177 bne miscHardwareError
|
|
178 bitb #$04
|
|
179 bne pathNameInvalidError
|
|
180 bra unknownError
|
|
181 targetInUseError
|
|
182 ldy #targetInUseL
|
|
183 leax targetInUse,pc
|
|
184 bra wrtErr
|
|
185 targetNotFoundError
|
|
186 ldy #targetNotFoundL
|
|
187 leax targetNotFound,pc
|
|
188 bra wrtErr
|
|
189 miscHardwareError
|
|
190 ldy #miscHardwareL
|
|
191 leax miscHardware,pc
|
|
192 bra wrtErr
|
|
193 pathNameInvalidError
|
|
194 ldy #pathNameInvalidL
|
|
195 leax pathNameInvalid,pc
|
|
196 bra wrtErr
|
|
197 unknownError
|
|
198 ldy #unknownL
|
|
199 leax unknown,pc
|
|
200 bra wrtErr
|
|
201 timeOutError
|
|
202 ldy #timeoutL
|
|
203 leax timeout,pc
|
|
204 wrtErr lda #$2
|
|
205 os9 I$Write
|
|
206
|
|
207 ExitOK clrb
|
|
208 Exit
|
|
209 os9 F$Exit
|
|
210
|
|
211 ShowHelp equ *
|
|
212 IFNE DOHELP
|
|
213 leax >HlpMsg,pcr point to help message
|
|
214 ldy #HlpMsgL get length
|
|
215 lda #$02 std error
|
|
216 os9 I$Write write it
|
|
217 ENDC
|
|
218 bra ExitOk
|
|
219
|
|
220 * Stolen from BASIC09
|
|
221 * Convert # in D to ASCII version (decimal)
|
|
222 L09BA pshs y,x,d Preserve End of data mem ptr,?,Data mem size
|
|
223 pshs d Preserve data mem size again
|
|
224 leay <L09ED,pc Point to decimal table (for integers)
|
|
225 L09C1 ldx #$2F00
|
|
226 L09C4 puls d Get data mem size
|
|
227 L09C6 leax >$0100,x Bump X up to $3000
|
|
228 subd ,y Subtract value from table
|
|
229 bhs L09C6 No underflow, keep subtracting current power of 10
|
|
230 addd ,y++ Restore to before underflow state
|
|
231 pshs d Preserve remainder of this power
|
|
232 ldd ,y Get next lower power of 10
|
|
233 tfr x,d Promptly overwrite it with X (doesn't chg flags)
|
|
234 beq L09E6 If finished table, skip ahead
|
|
235 cmpd #$3000 Just went through once?
|
|
236 beq L09C1 Yes, reset X & do again
|
|
237 * lbsr L1373 Go save A @ [<u0082]
|
|
238 ldb 11,u Write A to output buffer
|
|
239 sta b,u
|
|
240 incb
|
|
241 stb 11,u
|
|
242 ldx #$2F01 Reset X differently
|
|
243 bra L09C4 Go do again
|
|
244
|
|
245 L09E6
|
|
246 * lbsr L1373 Go save A @ [<u0082]
|
|
247 ldb 11,u Write A to output buffer
|
|
248 sta b,u
|
|
249 incb
|
|
250 stb 11,u
|
|
251 leas 2,s Eat stack
|
|
252 puls pc,y,x,d Restore regs & return
|
|
253
|
|
254 * Table of decimal values
|
|
255 L09ED fdb $2710 10000
|
|
256 fdb $03E8 1000
|
|
257 fdb $0064 100
|
|
258 fdb $000A 10
|
|
259 fdb $0001 1
|
|
260 fdb $0000 0
|
|
261
|
|
262 *********************************************************************
|
|
263 * Setup Controller for Command Mode
|
|
264 *********************************************************************
|
|
265 * EXIT:
|
|
266 * Carry cleared on success, set on timeout
|
|
267 * All other registers preserved
|
|
268 *
|
|
269 CmdSetup pshs x,a ; preserve registers
|
|
270 lda #$43 ; put controller into..
|
|
271 sta CTRLATCH ; Command Mode
|
|
272 ldx #0 ; long timeout counter = 65536
|
|
273 busyLp lda STATREG ; read status
|
|
274 lsra ; move BUSY bit to Carry
|
|
275 bcc setupExit ; branch if not busy
|
|
276 leax -1,x ; decrement timeout counter
|
|
277 bne busyLp ; loop if not timeout
|
|
278 lda #0 ; clear A without clearing Carry
|
|
279 sta CTRLATCH ; put controller back in emulation
|
|
280 setupExit puls a,x,pc ; restore registers and return
|
|
281
|
|
282 *********************************************************************
|
|
283 * Send 256 bytes of Command Data to SDC Controller
|
|
284 *********************************************************************
|
|
285 * ENTRY:
|
|
286 * X = Data Address
|
|
287 *
|
|
288 * EXIT:
|
|
289 * B = Status
|
|
290 * Carry set on failure or timeout
|
|
291 * All other registers preserved
|
|
292 *
|
|
293 txData pshs u,y,x ; preserve registers
|
|
294 ldy #DATREGA ; point Y at the data registers
|
|
295 * Poll for Controller Ready or Failed.
|
|
296 comb ; set carry in anticipation of failure
|
|
297 ldx #0 ; max timeout counter = 65536
|
|
298 txPoll ldb -2,y ; read status register
|
|
299 bmi txExit ; branch if FAILED bit is set
|
|
300 bitb #READY ; test the READY bit
|
|
301 bne txRdy ; branch if ready
|
|
302 leax -1,x ; decrement timeout counter
|
|
303 beq txExit ; exit if timeout
|
|
304 bra txPoll ; poll again
|
|
305 * Controller Ready. Send the Data.
|
|
306 txRdy ldx ,s ; re-load data address into X
|
|
307 ldb #128 ; 128 words to send (256 bytes)
|
|
308 txWord ldu ,x++ ; get data word from source
|
|
309 stu ,y ; send to controller
|
|
310 decb ; decrement word loop counter
|
|
311 bne txWord ; loop until done
|
|
312 * Done sending data, wait for result
|
|
313 ldx #0 ; wait for result
|
|
314 comb ; assume error
|
|
315 txWait ldb -2,y ; load status
|
|
316 bmi txExit ; branch if failed
|
|
317 lsrb ; clear carry if not busy
|
|
318 bcc txExit ; test ready bit
|
|
319 leax -1,x ; decrememnt timeout counter
|
|
320 bne txWait ; loop back until timeout
|
|
321 txExit puls x,y,u,pc ; restore registers and return
|
|
322
|
|
323 *********************************************************************
|
|
324 * Retrieve 256 bytes of Response Data from SDC Controller
|
|
325 *********************************************************************
|
|
326 * ENTRY:
|
|
327 * X = Data Storage Address
|
|
328 *
|
|
329 * EXIT:
|
|
330 * B = Status
|
|
331 * Carry set on failure or timeout
|
|
332 * All other registers preserved
|
|
333 *
|
|
334 rxData pshs u,y,x ; preserve registers
|
|
335 ldy #DATREGA ; point Y at the data registers
|
|
336 * Poll for Controller Ready or Failed.
|
|
337 comb ; set carry in anticipation of failure
|
|
338 ldx #0 ; max timeout counter = 65536
|
|
339 rxPoll ldb -2,y ; read status register
|
|
340 bmi rxExit ; branch if FAILED bit is set
|
|
341 bitb #READY ; test the READY bit
|
|
342 bne rxRdy ; branch if ready
|
|
343 leax -1,x ; decrement timeout counter
|
|
344 beq rxExit ; exit if timeout
|
|
345 bra rxPoll ; poll again
|
|
346 * Controller Ready. Grab the Data.
|
|
347 rxRdy ldx ,s ; re-load data address into X
|
|
348 ldb #128 ; 128 words to read (256 bytes)
|
|
349 rxWord ldu ,y ; read data word from controller
|
|
350 stu ,x++ ; put into storage
|
|
351 decb ; decrement word loop counter
|
|
352 bne rxWord ; loop until done
|
|
353 clrb ; success! clear the carry flag
|
|
354 rxExit puls x,y,u,pc ; restore registers and return
|
|
355
|
|
356 *********************************************************************
|
|
357 * This routine skip over spaces and commas
|
|
358 *********************************************************************
|
|
359 * Entry:
|
|
360 * X = ptr to data to parse
|
|
361 * Exit:
|
|
362 * X = ptr to first non-whitespace char
|
|
363 * A = non-whitespace char
|
|
364 SkipSpcs lda ,x+
|
|
365 cmpa #C$SPAC
|
|
366 beq SkipSpcs
|
|
367 leax -1,x
|
|
368 rts
|
|
369
|
|
370 emod
|
|
371 eom equ *
|
|
372 end
|