1511
|
1 ********************************************************************
|
|
2 * MMCDRV Color Computer MultiMedia Card Driver
|
|
3 * Version 2.0.1
|
|
4 * Copyright (C) 2003 Jim Hathaway III KG4KNB@hat3.net
|
|
5 ********************************************************************
|
|
6
|
|
7 ************************************************************************
|
|
8 * Updates:
|
|
9 * 06/16/03 - Copied code from version 321 driver and changed for asm
|
|
10 * Did this to see if there is some other issue with ASM
|
|
11 * cross assembly of this module. Still having problems when
|
|
12 * trying to write any file to a MMC formatted with the
|
|
13 * newer driver driver. This driver seems to work with ASM
|
|
14 * there must be a bug with the other modified version
|
|
15 * 06/17/03 - Moved from 001b version to 100 after testing showed no
|
|
16 * issues.
|
|
17 * Worked on making code similar to other code. Need to test
|
|
18 * this code as is to see if it will still work.
|
|
19 * Made EXTREME changes to the code. Will need mucho debugo
|
|
20 * 06/18/03 - More time working through.
|
|
21 * 06/19/03 - Fixed a bug in the read code that did not set PD.BUF correctly
|
|
22 * Y was being loaded with V.PORT before PD.BUF,y was calculated
|
|
23 * Write sector routine was missing Y=V.Port setup as well as
|
|
24 * MDN,u setup before calling GREAD.
|
|
25 * LSN0PROC - missing RTS, also moved clearing of the LSN0 flag
|
|
26 * to the LSN0PROC subroutine and removed it from the READ
|
|
27 * subroutine. Found and fixed several bugs today. Including
|
|
28 * the problem last night with an iniz causing the driver to
|
|
29 * loop and access the card.
|
|
30 * 06/24/03 - Found a bug in the error return routines, comb should have
|
|
31 * been done BEFORE the error number is loaded. Was causing
|
|
32 * a read error 244 to be returned as error 011
|
|
33 * 06/29/03 - Found final bug causing problems in nlevel2. IF an error
|
|
34 * was returned from the chkrs routine the delay was not called
|
|
35 * before exit, then the calling routine went back and sent the
|
|
36 * command again and stepped on the spi transfer. After all
|
|
37 * bytes are written or read at slow speed the delay routine
|
|
38 * MUST be called!
|
|
39 *************************************************************************
|
|
40
|
|
41 NUMDRIVE equ 2 Max. # of device descriptors for this driver
|
|
42 CMDREAD equ $51 Command to read a single block
|
|
43 CMDWRITE equ $58 Command to write a sector
|
|
44 MMCCSB equ $80 MMC control register slow clock bit
|
|
45 MMCCRO equ 1 MMC control register offset from data port
|
|
46 DLYAMT equ $28 Standard delay amount used in DLYSTART
|
|
47 CRDPULS equ $A Number of times to loop for card init
|
|
48
|
|
49 nam MMCDRV
|
|
50 ttl MMC device driver for CoCo
|
|
51
|
|
52 ifp1
|
|
53 use defsfile
|
|
54 endc
|
|
55
|
|
56 tylg set Drivr+Objct
|
|
57 atrv set ReEnt+rev
|
|
58 rev set $02
|
|
59 edition equ 2
|
|
60
|
|
61 mod eom,name,tylg,atrv,start,size
|
|
62
|
|
63 org 0
|
|
64 rmb DRVBEG+(DRVMEM*NUMDRIVE)
|
|
65
|
|
66 * Start of driver-specific statics
|
|
67 LSN0 rmb 1 Byte flag to indicate LSN0
|
|
68 MDN rmb 1 MMC Drive Number
|
|
69 SECT2WR rmb 1 Determines the sector to write
|
|
70 OS9SECT rmb 2 Temp storage for OS9 sector address
|
|
71 SECTPNT rmb 2 Temp storage for Sector Buffer pointer
|
|
72 BUFFER1 rmb 256 Sector buffer location for write cmds
|
|
73 RCMDBLK rmb 6
|
|
74 WCMDBLK rmb 6
|
|
75
|
|
76 size equ .
|
|
77
|
|
78 fcb $FF mode byte
|
|
79
|
|
80 name fcs /MMCDRV/ module name
|
|
81 fcb edition module edition
|
|
82
|
|
83
|
|
84 * Start point
|
|
85 start lbra INIT
|
|
86 lbra READ
|
|
87 lbra WRITE
|
|
88 lbra GETSTA
|
|
89 lbra SETSTA
|
|
90 lbra TERM
|
|
91 * End start
|
|
92
|
|
93 ********************************
|
|
94 * Command bytes storage area
|
|
95 ********************************
|
|
96 CMD0 fcb $40,0,0,0,0,$95
|
|
97 CMD1 fcb $41,0,0,0,0,$95
|
|
98 CMD13 fcb $4D,0,0,0,0,$95
|
|
99 CMD171 fcb $50,0,0,1,0,$95
|
|
100 CMD172 fcb $50,0,0,2,0,$95
|
|
101
|
|
102 ***************************************************************
|
|
103 * LSN0PROC - Process drive table when LSN0 is loaded.
|
|
104 * Called from READ
|
|
105 * Added pshs, puls y to preserve y holding the address of the
|
|
106 * MMC 6/19/03 JMH
|
|
107 ***************************************************************
|
|
108 LSN0PROC pshs y Save y for return
|
|
109 ldb MDN,u Get drive number
|
|
110 decb Make drive 1 = 0, drive 2 = 1
|
|
111 lda #DRVMEM # bytes to copy from LSN0 to drive table
|
|
112 mul Compute drive table location
|
|
113 leay DRVBEG,u Point to start of drive tables
|
|
114 leay d,y
|
|
115 ldx SECTPNT,u We need to get the sector buffer to use
|
|
116 lda #DD.SIZ Get drive table size
|
|
117 RDCL1 ldb ,x+ From copy
|
|
118 stb ,y+ To Copy
|
|
119 deca Loop for entire path descriptor
|
|
120 bne RDCL1 Loop till done
|
|
121 clr LSN0,u Set LSN0 false 0=f 1=t
|
|
122 puls y,pc Restore/return
|
|
123
|
|
124 * End LSN0PROC
|
|
125
|
|
126 ***************************************************************
|
|
127 * Send a command string to the MMC (6 bytes) with delay
|
|
128 * Can be called as SNDCS for sending command and checking status
|
|
129 * or just chkrs can be called to see if the card returns the
|
|
130 * correct response
|
|
131 * Entry: X=Pointer to command string to send
|
|
132 * Y=MMC Command data port
|
|
133 * A=Used for loop and not preserved
|
|
134 *
|
|
135 ***************************************************************
|
|
136 SNDCS pshs d,x Save regs
|
|
137 ldb #6 Number of command bytes
|
|
138 SNDCLS lda ,x+ Get command byte
|
|
139 sta ,y Send command byte
|
|
140 lbsr DLYSTRT Call our delay routine
|
|
141 decb Are we done?
|
|
142 bne SNDCLS Keep looping until complete
|
|
143 puls d,x Restore regs
|
|
144
|
|
145 CHKRS pshs d
|
|
146 clrb
|
|
147 CHKRSL1 lbsr DLYSTRT Call our delay routine
|
|
148 cmpa ,y Check for response
|
|
149 beq CHKRSG Response is good, exit without error
|
|
150 decb Keep looping?
|
|
151 bne CHKRSL1 Done yet?
|
|
152
|
|
153 CHKRSB lbsr DLYSTRT Call our delay routine
|
|
154 comb Set error state
|
|
155 puls d,pc Cleanup/Return
|
|
156 CHKRSG lbsr DLYSTRT Call our delay routine
|
|
157 clrb Set no error
|
|
158 puls d,pc Restore / Return
|
|
159
|
|
160 *********************************************************************
|
|
161 * Delay Routine - For use during initialization to slow down the
|
|
162 * read and write commands to the MMC because we must use a speed of
|
|
163 * less than 400k for the clock until CMD1 is issued (per MMC specs.)
|
|
164 *********************************************************************
|
|
165 DLYSTRT pshs b Save b register for return
|
|
166 ldb #DLYAMT Standard delay amount
|
|
167 DLYLP1 decb Start of delay loop
|
|
168 bne DLYLP1 End of delay loop
|
|
169 puls b,pc Get value of b register back
|
|
170 * End delay routine
|
|
171
|
|
172 *******************************************************************
|
|
173 * INIT - Standard OS9 init function. Enable all MMCs if present and
|
|
174 * request sector buffer block. Also set drive tables values.
|
|
175 ********************************************************************
|
|
176 INIT ldy V.PORT,u Get MMC base port address
|
|
177 lda #NUMDRIVE Number of cards to init
|
|
178
|
|
179 INITL1 sta MDN,u Get card number
|
|
180 lbsr INITCRD Try and init card
|
|
181 deca
|
|
182 bne INITL1 Keep looping
|
|
183
|
|
184 lda #CMDREAD Setup bytes for each command area
|
|
185 sta RCMDBLK,u Save them to each area
|
|
186 lda #CMDWRITE
|
|
187 sta WCMDBLK,u
|
|
188 ldd #$0095 Final two cmd bytes
|
|
189 std RCMDBLK+4,u Save last two cmd bytes for read
|
|
190 std WCMDBLK+4,u Save last two cmd bytes for write
|
|
191
|
|
192 clr LSN0,u Set LSN0 false 0=f 1=t
|
|
193
|
|
194 leax DRVBEG,u Point to start of drive tables
|
|
195 ldb #NUMDRIVE Number of drives supported
|
|
196 stb V.NDRV,u Store the number of drives
|
|
197 lda #$ff
|
|
198 INITL2 sta DD.TOT,x DD.TOT MSB to bogus value
|
|
199 sta V.TRAK,x Init current track # to bogus value
|
|
200 leax DRVMEM,x Get next drive table location
|
|
201 decb Loop counter
|
|
202 bne INITL2 Keep looping?
|
|
203
|
|
204 clr MMCCRO,y Deselect any cards in use
|
|
205
|
|
206 GETSTA
|
|
207 SETSTA
|
|
208 TERM
|
|
209 clrb
|
|
210 rts
|
|
211
|
|
212 ********************************************************************
|
|
213 * WRITE SECTOR
|
|
214 * Must read in correct sector then write out
|
|
215 * a 512 byte sector. MMCs only support 512 byte sectors
|
|
216 * for write.
|
|
217 ********************************************************************
|
|
218 WRITE stb RCMDBLK+1,u Save LSN for read command
|
|
219 stx RCMDBLK+2,u Save LSN for read command
|
|
220
|
|
221 stb WCMDBLK+1,u Save LSN for write command
|
|
222 stx WCMDBLK+2,u Save LSN for write command
|
|
223
|
|
224 ldx PD.BUF,y Get real sector address for later
|
|
225 stx OS9SECT,u Save os9 sector address for later
|
|
226
|
|
227 lda WCMDBLK+3,u Adjust WLSN
|
|
228 anda #$FE Mask bit 0
|
|
229 sta WCMDBLK+3,u Adjust WLSN
|
|
230
|
|
231 lda RCMDBLK+3,u Get lowest LSN byte
|
|
232 anda #1 Mask bits 7-1
|
|
233 sta SECT2WR,u Save it for later
|
|
234 beq WRROWE Go RO WE 1=(RE,WO) 0=(RO,WE)
|
|
235
|
|
236 WRREWO ldd RCMDBLK+2,u Get upper LSN
|
|
237 subd #1
|
|
238 std RCMDBLK+2,u
|
|
239 ldb RCMDBLK+1,u
|
|
240 sbcb #0
|
|
241 stb RCMDBLK+1,u
|
|
242
|
|
243 bra WRGO
|
|
244
|
|
245 WRROWE ldd RCMDBLK+2,u Get upper LSN
|
|
246 addd #1
|
|
247 std RCMDBLK+2,u
|
|
248 ldb RCMDBLK+1,u
|
|
249 adcb #0
|
|
250 stb RCMDBLK+1,u
|
|
251
|
|
252 WRGO leax BUFFER1,u
|
|
253 stx SECTPNT,u Save sector buffer for read
|
|
254
|
|
255 lda PD.DRV,y Get drive # requested
|
|
256 inca
|
|
257 sta MDN,u Save requested drive number
|
|
258
|
|
259 ldy V.PORT,u Get MMC base port address
|
|
260
|
|
261 lbsr GREAD Go get buffered sector
|
|
262 lbcs EWRITE Write error
|
|
263
|
|
264 WRGO1 leax CMD172,pcr Get command to change sector to 512 bytes
|
|
265 lda #$00 Expected response
|
|
266 lbsr SNDCF Go send the command (cmd17-2)
|
|
267 lbcs ENOTRDY Not ready
|
|
268
|
|
269 leax WCMDBLK,u Get address of write command block
|
|
270 lda #$00 Expected response
|
|
271 lbsr SNDCF Send this command without delay
|
|
272 lbcs ENOTRDY Not ready
|
|
273
|
|
274 lda #254 Start of data sector byte
|
|
275 sta ,y Save start of sector byte
|
|
276
|
|
277 WRGO2 tst SECT2WR,u 1=(RE,WO) 0=(RO,WE)
|
|
278 bne WRREWO1
|
|
279
|
|
280 WRROWE1 ldx OS9SECT,u Get real sector buffer
|
|
281 bsr WRSEC Go write 256 bytes
|
|
282 leax BUFFER1,u Get buffered sector
|
|
283 bra WRDC1 Data send complete
|
|
284
|
|
285 WRREWO1 leax BUFFER1,u Get buffered sector buffer
|
|
286 bsr WRSEC Go write 256 bytes
|
|
287 ldx OS9SECT,u Get real sector buffer
|
|
288 WRDC1 bsr WRSEC Go write 256 bytes
|
|
289
|
|
290 * dropped the code to send two crc bytes - the routine
|
|
291 * that reads the card to see if the $E5 response is given
|
|
292 * also sends data, so no separate crc code is needed
|
|
293
|
|
294 lda #$E5 Response - Data accepted tolken
|
|
295 lbsr CHKRF Check for correct response
|
|
296 lbcs EWRITE Write error
|
|
297
|
|
298 lda #$FF Response - Card complete with write
|
|
299 lbsr CHKRF Check for correct response
|
|
300 lbcs EWRITE Write error
|
|
301
|
|
302 leax CMD13,pcr Get check status command
|
|
303 lda #$00 Expected response
|
|
304 lbsr SNDCF Go send the command (cmd13)
|
|
305 lbcs EWRITE Write error
|
|
306 lbsr CHKRF Check for correct response
|
|
307 lbcs EWRITE Write error
|
|
308
|
|
309 leax CMD171,pcr Get command to change sector to 256
|
|
310 lda #$00 Expected response
|
|
311 lbsr SNDCF Go send the command (cmd17-1)
|
|
312 lbcs ENOTRDY Not ready
|
|
313
|
|
314 lbsr WREXIT Clean exit
|
|
315
|
|
316 * End of write sector routine
|
|
317
|
|
318 ********************************************************
|
|
319 * WRSEC - Write a single 256 byte sector to the MMC
|
|
320 * Entry: Y=MMC data port address
|
|
321 * X=Sector location to copy from
|
|
322 ********************************************************
|
|
323 IFNE SMALLC
|
|
324 WRSEC clrb Loop counter
|
|
325 WRLP1 lda ,x+ Get data byte
|
|
326 sta ,y Store data byte
|
|
327 decb
|
|
328 bne WRLP1 Keep looping?
|
|
329 rts Return
|
|
330
|
|
331 ELSE
|
|
332
|
|
333 WRSEC leax 15,x
|
|
334 lda #8 Number of loops to run
|
|
335 pshs a Used for loop counter
|
|
336 WRBLK1 ldd -15,x Get 2 bytes
|
|
337 sta ,y Save byte 1
|
|
338 nop Delay to complete SPI transfer
|
|
339 stb ,y Save byte 2
|
|
340 ldd -13,x Get 2 more bytes
|
|
341 sta ,y Save byte 3
|
|
342 nop Delay to complete SPI transfer
|
|
343 stb ,y Save byte 4
|
|
344 ldd -11,x Get 2 more bytes
|
|
345 sta ,y Save byte 5
|
|
346 nop Delay to complete SPI transfer
|
|
347 stb ,y Save byte 6
|
|
348 ldd -9,x Get 2 more bytes
|
|
349 sta ,y Save byte 7
|
|
350 nop Delay to complete SPI transfer
|
|
351 stb ,y Save byte 8
|
|
352 ldd -7,x Get 2 more bytes
|
|
353 sta ,y Save byte 9
|
|
354 nop Delay to complete SPI transfer
|
|
355 stb ,y Save byte 10
|
|
356 ldd -5,x Get 2 more bytes
|
|
357 sta ,y Save byte 11
|
|
358 nop Delay to complete SPI transfer
|
|
359 stb ,y Save byte 12
|
|
360 ldd -3,x Get 2 more bytes
|
|
361 sta ,y Save byte 13
|
|
362 nop Delay to complete SPI transfer
|
|
363 stb ,y Save byte 14
|
|
364 ldd -1,x Get 2 more bytes
|
|
365 sta ,y Save byte 15
|
|
366 nop Delay to complete SPI transfer
|
|
367 stb ,y Save byte 16
|
|
368 ldd 1,x Get 2 more bytes
|
|
369 sta ,y Save byte 17
|
|
370 nop Delay to complete SPI transfer
|
|
371 stb ,y Save byte 18
|
|
372 ldd 3,x Get 2 more bytes
|
|
373 sta ,y Save byte 19
|
|
374 nop Delay to complete SPI transfer
|
|
375 stb ,y Save byte 20
|
|
376 ldd 5,x Get 2 more bytes
|
|
377 sta ,y Save byte 21
|
|
378 nop Delay to complete SPI transfer
|
|
379 stb ,y Save byte 22
|
|
380 ldd 7,x Get 2 more bytes
|
|
381 sta ,y Save byte 23
|
|
382 nop Delay to complete SPI transfer
|
|
383 stb ,y Save byte 24
|
|
384 ldd 9,x Get 2 more bytes
|
|
385 sta ,y Save byte 25
|
|
386 nop Delay to complete SPI transfer
|
|
387 stb ,y Save byte 26
|
|
388 ldd 11,x Get 2 more bytes
|
|
389 sta ,y Save byte 27
|
|
390 nop Delay to complete SPI transfer
|
|
391 stb ,y Save byte 28
|
|
392 ldd 13,x Get 2 more bytes
|
|
393 sta ,y Save byte 29
|
|
394 nop Delay to complete SPI transfer
|
|
395 stb ,y Save byte 30
|
|
396 ldd 15,x Get 2 more bytes
|
|
397 sta ,y Save byte 31
|
|
398 nop Delay to complete SPI transfer
|
|
399 stb ,y Save byte 32
|
|
400 leax 32,x Add 32 bytes
|
|
401 dec ,s Loop counter
|
|
402 bne WRBLK1 Loop back and do it again
|
|
403 puls a,pc Clean stack, return
|
|
404
|
|
405 ENDC
|
|
406
|
|
407 * End of WRSEC subroutine
|
|
408
|
|
409 *************************************************
|
|
410 * INITCRD : Init a single card
|
|
411 * Entry: Y=MMC data port address
|
|
412 * MDN,u = card number (1..X)
|
|
413 * Registers preserved
|
|
414 *************************************************
|
|
415 INITCRD pshs d,x
|
|
416
|
|
417 lda #MMCCSB Change MMC clock to slow speed
|
|
418 sta MMCCRO,y Write slow speed bit
|
|
419 lda #CRDPULS Clock pulses needed to init cards
|
|
420
|
|
421 * Per MMC spec - before any commands are sent to the card 80 clock
|
|
422 * pulses must be sent at a speed of less than 400k. After init
|
|
423 * is complete we will use the full speed of 3.56 Mhz. This is the
|
|
424 * clock speed of the serial shift. 8 cycles at 3.56 Mhz are required
|
|
425 * to complete the SPI transfer.
|
|
426
|
|
427 ICLKPL1 tst ,y Send 8 clock pulses to card
|
|
428 lbsr DLYSTRT Call our delay routine
|
|
429 deca Loop counter
|
|
430 bne ICLKPL1 Loop until all clocks done
|
|
431
|
|
432 lda MDN,u Get card number
|
|
433 ora #MMCCSB Select slow clock bit
|
|
434 sta MMCCRO,y Write to MMC control register slow speed
|
|
435
|
|
436 leax CMD0,pcr x = cmd0 address
|
|
437 lda #$01 Response
|
|
438 lbsr SNDCS Go send the command w/ delay
|
|
439 lbcs INITCE1 This card is not ready exit
|
|
440
|
|
441 ldb #20 Number of times to send CMD1 before error
|
|
442 INCMD1L leax CMD1,pcr Load address into x for cmd1
|
|
443 lda #$00 Expected response
|
|
444 lbsr SNDCS Go send the command (cmd1)
|
|
445 bcc INC1C We got our response, continue
|
|
446 decb Loop counter
|
|
447 bne INCMD1L Keep trying to get a response of 0
|
|
448 lbcs INITCE1 This card is not ready exit
|
|
449
|
|
450 INC1C lda MDN,u Get card number
|
|
451 sta MMCCRO,y Write to MMC control register full speed
|
|
452
|
|
453 leax CMD171,pcr Get command to change sector to 256 bytes
|
|
454 lda #$00 Expected response
|
|
455 lbsr SNDCF Go send the command (cmd17-1) w/o delay
|
|
456 bcs INITCE1 Error changing to 256 byte sector
|
|
457
|
|
458 clrb No error
|
|
459 puls d,x,pc Clean exit
|
|
460
|
|
461 INITCE1 comb Error, we could not init card
|
|
462 puls d,x,pc
|
|
463
|
|
464 * End of INITCRD
|
|
465
|
|
466
|
|
467 *****************************************************************
|
|
468 * READ - Read a single 256 byte sector. Uses GREAD to get the
|
|
469 * sector into memory
|
|
470 *****************************************************************
|
|
471 READ stb RCMDBLK+1,u Save LSN
|
|
472 stx RCMDBLK+2,u Save LSN
|
|
473
|
|
474 leax 0,x Check for LSN0
|
|
475 bne RDS1
|
|
476 tstb Check for LSN0
|
|
477 bne RDS1
|
|
478 inc LSN0,u Set LSN0 Flag
|
|
479
|
|
480 RDS1 lda PD.DRV,y Get drive # requested
|
|
481 inca Set drive number correctly
|
|
482 sta MDN,u Save drive number
|
|
483
|
|
484 ldx PD.BUF,y Get physical sector buffer pointer
|
|
485 stx SECTPNT,u Store the sector buffer location
|
|
486
|
|
487 ldy V.PORT,u Get MMC base port address
|
|
488
|
|
489 bsr GREAD Get our sector
|
|
490 lbcs EREAD Exit with read error
|
|
491
|
|
492 tst LSN0,u Is this LSN0?
|
|
493 beq RDEX1 Complete - return
|
|
494
|
|
495 lbsr LSN0PROC Process LSN0 information
|
|
496
|
|
497 WREXIT
|
|
498 RDEX1 clrb Set no errors
|
|
499 clr MMCCRO,y Deselect any cards in use
|
|
500 rts Read complete with no errors
|
|
501
|
|
502 * End of READ
|
|
503
|
|
504 ***************************************************************
|
|
505 * Send a command string to the MMC (6 bytes) w/o delay
|
|
506 * Can be called as SNDCF for sending command and checking status
|
|
507 * or just CHKRF can be called to see if the card returns the
|
|
508 * correct response
|
|
509 * Entry: X = Pointer to command string to send
|
|
510 * Y = MMC Command data port
|
|
511 * A = Used for loop and not preserved
|
|
512 ***************************************************************
|
|
513 SNDCF
|
|
514 IFNE SMALLC
|
|
515
|
|
516 pshs d,x Save regs
|
|
517 ldb #$06 Loop amount
|
|
518 SNDCFL1 lda ,x+ Get command byte
|
|
519 sta ,y Save byte to card
|
|
520 decb Loop counter
|
|
521 bne SNDCFL1 Keep looping?
|
|
522 puls d,x Restore regs
|
|
523
|
|
524 ELSE
|
|
525
|
|
526 pshs d Save regs
|
|
527 ldd ,x Get command bytes
|
|
528 sta ,y Save byte 1
|
|
529 nop Delay to complete SPI transfer
|
|
530 stb ,y Save byte 2
|
|
531 ldd 2,x Get command bytes
|
|
532 sta ,y Save byte 3
|
|
533 nop Delay to complete SPI transfer
|
|
534 stb ,y Save byte 4
|
|
535 ldd 4,x Get command bytes
|
|
536 sta ,y Save byte 5
|
|
537 nop Delay to complete SPI transfer
|
|
538 stb ,y Save byte 6
|
|
539 puls d Restore regs
|
|
540
|
|
541 ENDC
|
|
542
|
|
543 * Try to quickly get a response from the MMC. 128 loops
|
|
544 * is only a guess as to how long an average command response
|
|
545 * might be. After the 128 loops it is obvious that the card
|
|
546 * may need more time to process the command (such as a write)
|
|
547 * command. At that point we sleep for 1 tick to give the
|
|
548 * card time to complete the request. Then try another 255 times
|
|
549 * to get the response before we return an error.
|
|
550 * 6-24-03 JMH - Found something interesting in NLevel2 V030102
|
|
551 * testing last night. The MMC would not initialize aparently
|
|
552 * based on the LED pattern being displayed. Level2 OS9 is able
|
|
553 * to use this driver without problems. As I think about it more
|
|
554 * it might be the fact that in 6309 mode the CPU is able to
|
|
555 * execute instructions faster and so it is stepping on the
|
|
556 * spi shift.
|
|
557 * 6-24-03 JMH - Moved pshs x lower into subroutine to save
|
|
558 * some time if a sleep is not needed then there is no reason
|
|
559 * to pshs x and puls x.
|
|
560
|
|
561 CHKRF pshs d Save regs
|
|
562 clrb Number of loops
|
|
563
|
|
564 CHKRFL1 cmpa ,y
|
|
565 beq CHKRFG Got our response
|
|
566 cmpa ,y
|
|
567 beq CHKRFG Got our response
|
|
568 decb Loop counter
|
|
569 bne CHKRFL1 Keep looping?
|
|
570
|
|
571 * This sleep should only occur when writing to the card
|
|
572 pshs x Save x for later
|
|
573 ldx #1 Sleep for remainder of this tick
|
|
574 os9 F$Sleep Wait for card
|
|
575 puls x Restore
|
|
576
|
|
577 clrb Number of loops = 256
|
|
578 CHKRFL2 cmpa ,y
|
|
579 beq CHKRFG Got our response
|
|
580 decb Loop counter
|
|
581 bne CHKRFL2 Keep looping?
|
|
582
|
|
583 CHKRFB comb Set error state
|
|
584 puls d,pc Cleanup/Return
|
|
585 CHKRFG clrb Set no error
|
|
586 puls d,pc Cleanup/Return
|
|
587
|
|
588 ***************************************************************
|
|
589 * GREAD - New generic read subroutine. Requires:
|
|
590 * MDN,u = drive number
|
|
591 * RCMDBLK,u LSN (RCMDBLK+1,RCMDBLK+2,RCMDBLK+3)
|
|
592 * SECTPNT,u = location to copy sector to
|
|
593 * Y = V.port,u (MMC base port address)
|
|
594 ***************************************************************
|
|
595 GREAD
|
|
596 lda MDN,u
|
|
597 sta MMCCRO,y Select MMC
|
|
598
|
|
599 lda ,y Burn a byte - bug fix
|
|
600
|
|
601 lda #$FF Expected card response
|
|
602 bsr CHKRF Go check for response byte
|
|
603 bcc RDN1 Is card ready? If yes continue
|
|
604
|
|
605 lbsr INITCRD Try and initialize the card requested
|
|
606 lbcs ENOTRDY Not ready - no card found in slot
|
|
607
|
|
608 lda MDN,u Get drive number
|
|
609 sta MMCCRO,y Write to MMC control register
|
|
610
|
|
611 RDN1 leax RCMDBLK,u Read command block
|
|
612 lda #$00 Expected response
|
|
613 bsr SNDCF Send this command without delay
|
|
614 bcc RDN2 If command did not generate err continue
|
|
615
|
|
616 lbsr INITCRD Try and initialize the card requested
|
|
617 lbcs ENOTRDY Not ready
|
|
618
|
|
619 lda MDN,u Get drive number again
|
|
620 sta MMCCRO,y Set card selected at full speed
|
|
621
|
|
622 leax RCMDBLK,u Read command block
|
|
623 lda #$00 Expected response - cmd accepted
|
|
624 bsr SNDCF Send this command without delay
|
|
625 lbcs ENOTRDY Not ready
|
|
626
|
|
627 RDN2 lda #$FE Expected response start of sector
|
|
628 bsr CHKRF Check for response
|
|
629 lbcs EREAD Read Error
|
|
630
|
|
631 ldx SECTPNT,u We need to get the sector buffer to use
|
|
632 bsr RDSEC Go read the sector
|
|
633
|
|
634 clrb Set no errors
|
|
635 rts
|
|
636
|
|
637 ***************************************************************
|
|
638 * RDSEC - Read a single 256 byte sector from the MMC + 2 CRC bytes
|
|
639 * Entry: Y=MMC data port address
|
|
640 * X=Sector location to copy to
|
|
641 ***************************************************************
|
|
642 IFNE SMALLC
|
|
643 RDSEC pshs x Save x
|
|
644 clrb Loop counter
|
|
645 RDLP1 lda ,y Get data byte
|
|
646 sta ,x+ Store data byte
|
|
647 decb
|
|
648 bne RDLP1 Keep looping?
|
|
649 * ldd ,y Get CRC bytes
|
|
650 * lda ,y Get CRC bytes
|
|
651 puls x,pc Restore/return
|
|
652
|
|
653 ELSE
|
|
654
|
|
655 * Using a 5 bit offset only adds 1 cycle to each of the STD instructs.
|
|
656 * incrementing the X index register each time by ++ adds 3 instructions
|
|
657 * so this saves 2 cycles for every 2 bytes transfered. 2 cycles * 16
|
|
658 * STD instructions = 32 saved cycles per loop or 256 cycles per sector
|
|
659 * read. This loop uses about 1900 cycles to complete. A simple lda
|
|
660 * sta single byte move loop takes about 3900 cycles to complete. This
|
|
661 * is a more than 50% increase in speed for this loop (this is where
|
|
662 * the driver uses the most CPU time). 6309 users note! a TFM will not
|
|
663 * work because you need AT LEAST 4 coco (regardless of the CoCo's actual
|
|
664 * speed) cycles between data port access for the SPI cycle to complete.
|
|
665 * If a write or read occurs during the four cycles
|
|
666 * after a byte is read/wrote to the SPI data port then the data
|
|
667 * transfer will be corrupted.
|
|
668
|
|
669 RDSEC leax 15,x Move to the middle of the 32 byte block
|
|
670 lda #8 Number of loops to run
|
|
671 pshs a Used for loop
|
|
672 RDLP1 ldd ,y Load byte 1
|
|
673 ldb ,y Load byte 2
|
|
674 std -15,x Store two bytes
|
|
675 ldd ,y Load byte 3
|
|
676 ldb ,y Load byte 4
|
|
677 std -13,x Store two bytes
|
|
678 ldd ,y Load byte 5
|
|
679 ldb ,y Load byte 6
|
|
680 std -11,x Store two bytes
|
|
681 ldd ,y Load byte 7
|
|
682 ldb ,y Load byte 8
|
|
683 std -9,x Store two bytes
|
|
684 ldd ,y Load byte 9
|
|
685 ldb ,y Load byte 10
|
|
686 std -7,x Store two bytes
|
|
687 ldd ,y Load byte 11
|
|
688 ldb ,y Load byte 12
|
|
689 std -5,x Store two bytes
|
|
690 ldd ,y Load byte 13
|
|
691 ldb ,y Load byte 14
|
|
692 std -3,x Store two bytes
|
|
693 ldd ,y Load byte 15
|
|
694 ldb ,y Load byte 16
|
|
695 std -1,x Store two bytes
|
|
696 ldd ,y Load byte 17
|
|
697 ldb ,y Load byte 18
|
|
698 std 1,x Store two bytes
|
|
699 ldd ,y Load byte 19
|
|
700 ldb ,y Load byte 20
|
|
701 std 3,x Store two bytes
|
|
702 ldd ,y Load byte 21
|
|
703 ldb ,y Load byte 22
|
|
704 std 5,x Store two bytes
|
|
705 ldd ,y Load byte 23
|
|
706 ldb ,y Load byte 24
|
|
707 std 7,x Store two bytes
|
|
708 ldd ,y Load byte 25
|
|
709 ldb ,y Load byte 26
|
|
710 std 9,x Store two bytes
|
|
711 ldd ,y Load byte 27
|
|
712 ldb ,y Load byte 28
|
|
713 std 11,x Store two bytes
|
|
714 ldd ,y Load byte 29
|
|
715 ldb ,y Load byte 30
|
|
716 std 13,x Store two bytes
|
|
717 ldd ,y Load byte 31
|
|
718 ldb ,y Load byte 32
|
|
719 std 15,x Store two bytes
|
|
720 leax 32,x Add 32 bytes
|
|
721 dec ,s Loop counter
|
|
722 bne RDLP1 Loop back and do it again
|
|
723
|
|
724 * Eliminated the code to pull two CRC bytes from the card.
|
|
725 * The routine that checks for the correct response will
|
|
726 * extract these two bytes from the MMC
|
|
727
|
|
728 * ldd ,y Get 1 byte of CRC data from card
|
|
729 * ldb ,y Get 1 byte of CRC data from card
|
|
730
|
|
731 puls a,pc
|
|
732
|
|
733 ENDC
|
|
734
|
|
735 * End of RDSEC subroutine
|
|
736
|
|
737 ENOTRDY bsr ERREXIT
|
|
738 comb
|
|
739 ldb #E$NotRdy Not ready
|
|
740 rts
|
|
741
|
|
742 EWRITE bsr ERREXIT
|
|
743 comb
|
|
744 ldb #E$Write Write error
|
|
745 rts
|
|
746
|
|
747 EREAD bsr ERREXIT
|
|
748 comb
|
|
749 ldb #E$Read Read error
|
|
750 rts
|
|
751
|
|
752 * Added to handle things that need to occur if an error occurs
|
|
753 * 1. Select the card (may already be selected)
|
|
754 * 2. Send command to change sector size back to 256 bytes
|
|
755 * 3. Clear the LSN0 flag (may already be cleared)
|
|
756 * 4. Deselect all cards.
|
|
757
|
|
758 ERREXIT lda MDN,u Get drive number
|
|
759 sta MMCCRO,y Select card (in case not selected)
|
|
760 leax CMD171,pcr Get command to change sector to 256 bytes
|
|
761 lda #$00 Expected response
|
|
762 lbsr SNDCF Go send the command (cmd17-1) w/o delay
|
|
763
|
|
764 clr lsn0,u Clear LSN0 flag if set
|
|
765 clr MMCCRO,y Deselect any cards
|
|
766 rts
|
|
767
|
|
768 emod
|
|
769 eom equ *
|
|
770 end
|