OpenCores
URL https://opencores.org/ocsvn/rtf65002/rtf65002/trunk

Subversion Repositories rtf65002

[/] [rtf65002/] [trunk/] [software/] [asm/] [SDCard.asm] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 40 robfinch
 
2
; ============================================================================
3
;        __
4
;   \\__/ o\    (C) 2013, 2014  Robert Finch, Stratford
5
;    \  __ /    All rights reserved.
6
;     \/_//     robfinch@opencores.org
7
;       ||
8
;
9
;
10
; This source file is free software: you can redistribute it and/or modify
11
; it under the terms of the GNU Lesser General Public License as published
12
; by the Free Software Foundation, either version 3 of the License, or
13
; (at your option) any later version.
14
;
15
; This source file is distributed in the hope that it will be useful,
16
; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
; GNU General Public License for more details.
19
;
20
; You should have received a copy of the GNU General Public License
21
; along with this program.  If not, see .
22
;
23
; SDCard.asm
24
; ============================================================================
25
;
26
                cpu             RTF65002
27
 
28
                .code
29
 
30
        align   4
31
;------------------------------------------------------------------------------
32
; Static device control block (SDBC) structure
33
;------------------------------------------------------------------------------
34
 
35
public SDCardDCB:
36
        align   4
37
        db      "CARD1       "  ; name
38
        dw      5       ; number of chars in name
39
        dw      16      ; type
40
        dw      1       ; nBPB
41
        dw      0        ; last erc
42
        dw      8388608 ; nBlocks
43
        dw      SDCmdProc
44
        dw      SDInit
45
        dw      SDStat
46
        dw      1       ; reentrancy count (1 to 255 are valid)
47
        dw      0        ; single user
48
        dw      0        ; hJob
49
        dw      0        ; OSD1
50
        dw      0        ; OSD2
51
        dw      0        ; OSD3
52
        dw      0        ; OSD4
53
        dw      0        ; OSD5
54
        dw      0        ; OSD6
55
 
56
SDOpTbl:
57
        dw      SDNop
58
        dw      SDInit
59
        dw      SDMediaCheck
60
        dw      SDBuildBPB
61
        dw      SDNop           ;       GetChar                         ; GetChar()
62
        dw      SDNop           ;       CheckForChar            ; PeekChar()
63
        dw      SDNop           ;       GetCharDirect           ; unbuffered GetChar()
64
        dw      SDNop           ;       CheckForCharDirect      ; unbuffered PeekChar()
65
        dw      SDNop           ;       PutChar                         ; KeybdPutChar
66
        dw      SDNop           ;       SetEcho
67
        dw      SDSetpos                                ; set position
68
        dw      SDReadBlocks                    ; block read
69
        dw      SDWriteBlocks                   ; block write
70
        dw      SDNop
71
        dw      SDNop
72
        dw      SDNop
73
 
74
SDStat:
75
        rts
76
SDBuildBPB:
77
        rts
78
SDSetpos:
79
        rts
80
;
81
;------------------------------------------------------------------------------
82
; SDCmdProc:
83
;       Device command processor.
84
;
85
; Parameters:
86
;       r1 = device #
87
;       r2 = opcode
88
;       r3 = position
89
;       r4 = number of blocks
90
;       r5 = pointer to data area
91
;------------------------------------------------------------------------------
92
 
93
SDCmdProc:
94
        cmp             #16
95
        bne             .0001
96
        phx
97
        phy
98
        push    r4
99
        push    r5
100
        mul             r1,r1,#DCB_SIZE         ; convert device number to DCB pointer
101
        add             #DCBs
102
        ld              r0,DCB_pDevInit,r1      ; check for an initialization routine
103
        beq             .0002                           ; to see if device present
104
        cmp             r2,#MAX_DEV_OP
105
        bhi             .0003
106
        pha                                                     ; save off DCB pointer
107
        jsr             (SDOpTbl>>2,x)
108
        plx
109
        sta             DCB_last_erc,x          ; stuff the error return code in the DCB
110
.ret:
111
        pop             r5
112
        pop             r4
113
        ply
114
        plx
115
        rts
116
.0001:
117
        lda             #E_BadDevNum
118
        rts
119
.0002:
120
        lda             #E_NoDev
121
        bra             .ret
122
.0003:
123
        lda             #E_BadDevOp
124
        bra             .ret
125
 
126
;------------------------------------------------------------------------------
127
; SDNop:
128
; No-operation routine.
129
;------------------------------------------------------------------------------
130
 
131
SDNop:
132
        lda             #E_Ok
133
        rts
134
 
135
;------------------------------------------------------------------------------
136
;------------------------------------------------------------------------------
137
 
138
SDMediaCheck:
139
        lda             #E_Ok
140
        rts
141
 
142
;------------------------------------------------------------------------------
143
; Initialize the SD card
144
; Returns
145
; acc = 0 if successful, 1 otherwise
146
; Z=1 if successful, otherwise Z=0
147
;------------------------------------------------------------------------------
148
;
149
message "SDInit"
150
public SDInit:
151
        lda             #SPI_INIT_SD
152
        sta             SPIMASTER+SPI_TRANS_TYPE_REG
153
        lda             #SPI_TRANS_START
154
        sta             SPIMASTER+SPI_TRANS_CTRL_REG
155
        nop
156
.spi_init1
157
        lda             SPIMASTER+SPI_TRANS_STATUS_REG
158
        nop
159
        nop
160
        cmp             #SPI_TRANS_BUSY
161
        beq             .spi_init1
162
        lda             SPIMASTER+SPI_TRANS_ERROR_REG
163
        and             #3
164
        cmp             #SPI_INIT_NO_ERROR
165
        bne             spi_error
166
;       lda             #spi_init_ok_msg
167
;       jsr             DisplayStringB
168
        lda             #0
169
        rts
170
spi_error
171
        jsr             DisplayByte
172
        lda             #spi_init_error_msg
173
        jsr             DisplayStringB
174
        lda             SPIMASTER+SPI_RESP_BYTE1
175
        jsr             DisplayByte
176
        lda             SPIMASTER+SPI_RESP_BYTE2
177
        jsr             DisplayByte
178
        lda             SPIMASTER+SPI_RESP_BYTE3
179
        jsr             DisplayByte
180
        lda             SPIMASTER+SPI_RESP_BYTE4
181
        jsr             DisplayByte
182
        lda             #1
183
        rts
184
 
185
spi_delay:
186
        nop
187
        nop
188
        rts
189
 
190
 
191
;------------------------------------------------------------------------------
192
; SD read sector
193
;
194
; r1= sector number to read
195
; r2= address to place read data
196
; Returns:
197
; r1 = 0 if successful
198
;------------------------------------------------------------------------------
199
;
200
public SDReadSector:
201
        phx
202
        phy
203
        push    r4
204
 
205
        sta             SPIMASTER+SPI_SD_SECT_7_0_REG
206
        lsr             r1,r1,#8
207
        sta             SPIMASTER+SPI_SD_SECT_15_8_REG
208
        lsr             r1,r1,#8
209
        sta             SPIMASTER+SPI_SD_SECT_23_16_REG
210
        lsr             r1,r1,#8
211
        sta             SPIMASTER+SPI_SD_SECT_31_24_REG
212
 
213
        ld              r4,#20  ; retry count
214
 
215
.spi_read_retry:
216
        ; Force the reciever fifo to be empty, in case a prior error leaves it
217
        ; in an unknown state.
218
        lda             #1
219
        sta             SPIMASTER+SPI_RX_FIFO_CTRL_REG
220
 
221
        lda             #RW_READ_SD_BLOCK
222
        sta             SPIMASTER+SPI_TRANS_TYPE_REG
223
        lda             #SPI_TRANS_START
224
        sta             SPIMASTER+SPI_TRANS_CTRL_REG
225
        nop
226
.spi_read_sect1:
227
        lda             SPIMASTER+SPI_TRANS_STATUS_REG
228
        jsr             spi_delay                       ; just a delay between consecutive status reg reads
229
        cmp             #SPI_TRANS_BUSY
230
        beq             .spi_read_sect1
231
        lda             SPIMASTER+SPI_TRANS_ERROR_REG
232
        lsr
233
        lsr
234
        and             #3
235
        cmp             #SPI_READ_NO_ERROR
236
        bne             .spi_read_error
237
        ldy             #512            ; read 512 bytes from fifo
238
.spi_read_sect2:
239
        lda             SPIMASTER+SPI_RX_FIFO_DATA_REG
240
        sb              r1,0,x
241
        inx
242
        dey
243
        bne             .spi_read_sect2
244
        lda             #0
245
        bra             .spi_read_ret
246
.spi_read_error:
247
        dec             r4
248
        bne             .spi_read_retry
249
        jsr             DisplayByte
250
        lda             #spi_read_error_msg
251
        jsr             DisplayStringB
252
        lda             #1
253
.spi_read_ret:
254
        pop             r4
255
        ply
256
        plx
257
        rts
258
 
259
;------------------------------------------------------------------------------
260
; BlocksToSectors:
261
;       Convert a logical block number (LBA) to a sector number
262
;------------------------------------------------------------------------------
263
 
264
BlocksToSectors:
265
        asl             r1,r1,#1                        ; 1k blocks = 2 sectors
266
        rts
267
 
268
;------------------------------------------------------------------------------
269
; SDReadBlocks:
270
;
271
; Registers Affected: r1-r5
272
; Parameters:
273
;       r1 = pointer to DCB
274
;       r3 = block number
275
;       r4 = number of blocks
276
;       r5 = pointer to data area
277
;------------------------------------------------------------------------------
278
 
279
public SDReadBlocks:
280
        cpy             DCB_nBlocks,r1
281
        bhs             .0002
282
        add             r2,r3,r4
283
        cpx             DCB_nBlocks,r1
284
        bhi             .0003
285
        ld              r2,r5                           ; x = pointer to data buffer
286
        tya
287
        jsr             BlocksToSectors         ; acc = sector number
288
        pha
289
        ld              r1,r4
290
        jsr             BlocksToSectors
291
        tay                                                     ; y = # of blocks to read
292
        pla                                                     ; acc = sector number again
293
        jsr             SDReadMultiple
294
        cmp             #0
295
        bne             .0001
296
        lda             #E_Ok
297
        rts
298
.0001
299
        lda             #E_ReadError
300
        rts
301
.0002
302
        lda             #E_BadBlockNum
303
        rts
304
.0003:
305
        lda             #E_TooManyBlocks
306
        rts
307
 
308
;------------------------------------------------------------------------------
309
; SDWriteBlocks:
310
;
311
; Parameters:
312
;       r1 = pointer to DCB
313
;       r3 = block number
314
;       r4 = number of blocks
315
;       r5 = pointer to data area
316
;------------------------------------------------------------------------------
317
 
318
public SDWriteBlocks:
319
        cpy             DCB_nBlocks,r1
320
        bhs             .0002
321
        add             r2,r3,r4
322
        cpx             DCB_nBlocks,r1
323
        bhi             .0003
324
        ld              r2,r5                           ; x = pointer to data buffer
325
        tya
326
        jsr             BlocksToSectors         ; acc = sector number
327
        pha
328
        ld              r1,r4
329
        jsr             BlocksToSectors
330
        tay                                                     ; y = # of blocks to read
331
        pla                                                     ; acc = sector number again
332
        jsr             SDWriteMultiple
333
        cmp             #0
334
        bne             .0001
335
        lda             #E_Ok
336
        rts
337
.0001
338
        lda             #E_WriteError
339
        rts
340
.0002
341
        lda             #E_BadBlockNum
342
        rts
343
.0003:
344
        lda             #E_TooManyBlocks
345
        rts
346
 
347
;------------------------------------------------------------------------------
348
; SDWriteSector:
349
;
350
; r1= sector number to write
351
; r2= address to get data from
352
; Returns:
353
; r1 = 0 if successful
354
;------------------------------------------------------------------------------
355
;
356
public SDWriteSector:
357
        phx
358
        phy
359
        pha
360
        ; Force the transmitter fifo to be empty, in case a prior error leaves it
361
        ; in an unknown state.
362
        lda             #1
363
        sta             SPIMASTER+SPI_TX_FIFO_CTRL_REG
364
        nop                     ; give I/O time to respond
365
        nop
366
 
367
        ; now fill up the transmitter fifo
368
        ldy             #512
369
.spi_write_sect1:
370
        lb              r1,0,x
371
        sta             SPIMASTER+SPI_TX_FIFO_DATA_REG
372
        nop                     ; give the I/O time to respond
373
        nop
374
        inx
375
        dey
376
        bne             .spi_write_sect1
377
 
378
        ; set the sector number in the spi master address registers
379
        pla
380
        sta             SPIMASTER+SPI_SD_SECT_7_0_REG
381
        lsr             r1,r1,#8
382
        sta             SPIMASTER+SPI_SD_SECT_15_8_REG
383
        lsr             r1,r1,#8
384
        sta             SPIMASTER+SPI_SD_SECT_23_16_REG
385
        lsr             r1,r1,#8
386
        sta             SPIMASTER+SPI_SD_SECT_31_24_REG
387
 
388
        ; issue the write command
389
        lda             #RW_WRITE_SD_BLOCK
390
        sta             SPIMASTER+SPI_TRANS_TYPE_REG
391
        lda             #SPI_TRANS_START
392
        sta             SPIMASTER+SPI_TRANS_CTRL_REG
393
        nop
394
.spi_write_sect2:
395
        lda             SPIMASTER+SPI_TRANS_STATUS_REG
396
        nop                                                     ; just a delay between consecutive status reg reads
397
        nop
398
        cmp             #SPI_TRANS_BUSY
399
        beq             .spi_write_sect2
400
        lda             SPIMASTER+SPI_TRANS_ERROR_REG
401
        lsr             r1,r1,#4
402
        and             #3
403
        cmp             #SPI_WRITE_NO_ERROR
404
        bne             .spi_write_error
405
        lda             #0
406
        bra             .spi_write_ret
407
.spi_write_error:
408
        jsr             DisplayByte
409
        lda             #spi_write_error_msg
410
        jsr             DisplayStringB
411
        lda             #1
412
 
413
.spi_write_ret:
414
        ply
415
        plx
416
        rts
417
 
418
;------------------------------------------------------------------------------
419
; SDReadMultiple: read multiple sectors
420
;
421
; r1= sector number to read
422
; r2= address to write data
423
; r3= number of sectors to read
424
;
425
; Returns:
426
; r1 = 0 if successful
427
;
428
;------------------------------------------------------------------------------
429
 
430
public SDReadMultiple:
431
        push    r4
432
        ld              r4,#0
433
.spi_rm1:
434
        pha
435
        jsr             SDReadSector
436
        add             r4,r4,r1
437
        add             r2,r2,#512
438
        pla
439
        ina
440
        dey
441
        bne             .spi_rm1
442
        ld              r1,r4
443
        pop             r4
444
        rts
445
 
446
;------------------------------------------------------------------------------
447
; SPI write multiple sector
448
;
449
; r1= sector number to write
450
; r2= address to get data from
451
; r3= number of sectors to write
452
;
453
; Returns:
454
; r1 = 0 if successful
455
;------------------------------------------------------------------------------
456
;
457
public SDWriteMultiple:
458
        push    r4
459
        ld              r4,#0
460
.spi_wm1:
461
        pha
462
        jsr             SDWriteSector
463
        add             r4,r4,r1                ; accumulate an error count
464
        add             r2,r2,#512              ; 512 bytes per sector
465
        pla
466
        ina
467
        dey
468
        bne             .spi_wm1
469
        ld              r1,r4
470
        pop             r4
471
        rts
472
 
473
;------------------------------------------------------------------------------
474
; read the partition table to find out where the boot sector is.
475
; Returns
476
; r1 = 0 everything okay, 1=read error
477
; also Z=1=everything okay, Z=0=read error
478
;------------------------------------------------------------------------------
479
 
480
public SDReadPart:
481
        phx
482
        stz             startSector                                             ; default starting sector
483
        lda             #0                                                              ; r1 = sector number (#0)
484
        ldx             #BYTE_SECTOR_BUF                                ; r2 = target address (word to byte address)
485
        jsr             SDReadSector
486
        cmp             #0
487
        bne             .spi_rp1
488
        lb              r1,BYTE_SECTOR_BUF+$1C9
489
        asl             r1,r1,#8
490
        orb             r1,r1,BYTE_SECTOR_BUF+$1C8
491
        asl             r1,r1,#8
492
        orb             r1,r1,BYTE_SECTOR_BUF+$1C7
493
        asl             r1,r1,#8
494
        orb             r1,r1,BYTE_SECTOR_BUF+$1C6
495
        sta             startSector                                             ; r1 = 0, for okay status
496
        lb              r1,BYTE_SECTOR_BUF+$1CD
497
        asl             r1,r1,#8
498
        orb             r1,r1,BYTE_SECTOR_BUF+$1CC
499
        asl             r1,r1,#8
500
        orb             r1,r1,BYTE_SECTOR_BUF+$1CB
501
        asl             r1,r1,#8
502
        orb             r1,r1,BYTE_SECTOR_BUF+$1CA
503
        sta             disk_size                                               ; r1 = 0, for okay status
504
        plx
505
        lda             #0
506
        rts
507
.spi_rp1:
508
        plx
509
        lda             #1
510
        rts
511
 
512
;------------------------------------------------------------------------------
513
; Read the boot sector from the disk.
514
; Make sure it's the boot sector by looking for the signature bytes 'EB' and '55AA'.
515
; Returns:
516
; r1 = 0 means this card is bootable
517
; r1 = 1 means a read error occurred
518
; r1 = 2 means the card is not bootable
519
;------------------------------------------------------------------------------
520
 
521
public SDReadBoot:
522
        phx
523
        phy
524
        push    r5
525
        lda             startSector                                     ; r1 = sector number
526
        ldx             #BYTE_SECTOR_BUF                        ; r2 = target address
527
        jsr             SDReadSector
528
        cmp             #0
529
        bne             spi_read_boot_err
530
        lb              r1,BYTE_SECTOR_BUF
531
        cmp             #$EB
532
        bne             spi_eb_err
533
spi_read_boot2:
534
        lda             #msgFoundEB
535
        jsr             DisplayStringB
536
        lb              r1,BYTE_SECTOR_BUF+$1FE         ; check for 0x55AA signature
537
        cmp             #$55
538
        bne             spi_eb_err
539
        lb              r1,BYTE_SECTOR_BUF+$1FF         ; check for 0x55AA signature
540
        cmp             #$AA
541
        bne             spi_eb_err
542
        pop             r5
543
        ply
544
        plx
545
        lda             #0                                              ; r1 = 0, for okay status
546
        rts
547
spi_read_boot_err:
548
        pop             r5
549
        ply
550
        plx
551
        lda             #1
552
        rts
553
spi_eb_err:
554
        lda             #msgNotFoundEB
555
        jsr             DisplayStringB
556
        pop             r5
557
        ply
558
        plx
559
        lda             #2
560
        rts
561
 
562
msgFoundEB:
563
        db      "Found EB code.",CR,LF,0
564
msgNotFoundEB:
565
        db      "EB/55AA Code missing.",CR,LF,0
566
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.