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

Subversion Repositories ffr16

[/] [ffr16/] [branches/] [APERT/] [sources/] [fpu/] [050803KN/] [compile/] [FAT16RD.PSM] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 armando
; FAT16 READER V.050303 - Armando Astarloa - 16 BIT VER.
2 5 armando
; APERT - UPV/EHU 2003 - DISTRIBUTED UNDER GPL LICENSE
3 2 armando
;
4
; s0 -> TMP0 s1 -> TMP1 s2 -> TMP2 s3 -> TMP3 s4 -> TMP4 / SECTORS_PER_CLUSTER_READED s5 -> TMP5/SECTOR_WORDS_READED (256 TO 0)
5
; s6 -> TMP s7 -> SECTORS_PER_CLUSTER s8 -> CLUSTER_BEGIN_LBA0 (FAT) s9 -> CLUSTER_BEGIN_LBA1 sA -> CLUSTER_BEGIN_LBA2
6
; sB -> CLUSTER_BEGIN_LBA3 sC -> ROOT_DIRECTORY_FIRST_CLUSTER0 (SUPPOSED LESS THAN 256 - USUALLY 2)
7
; sD -> data[7:0] WB MASTER sE -> data[15:8] WB MASTER sF -> acummulator
8
                CONSTANT DATA_WB_OUT_7_0_MASTER,00
9
                CONSTANT DATA_WB_OUT_15_8_MASTER,01
10
                CONSTANT CONTROL_WB_OUT_MASTER,02
11
                                                        ; D7 = D6 = D5 = D4 = D3 = D2 = A0_MASTER D1 = W_WE_MASTER D0 = STB_O_MASTER
12
                                                        ; STROBE_O_MASTER = 1 & W_WE=0 & WB_A0 = 0
13
                                                        CONSTANT READ_SLAVE,01
14
                                                        ; STROBE_O_MASTER = 1 & W_WE=1 & WB_A0 = 0
15
                                                        CONSTANT WRITE_LBA_15_0,03
16
                                                        ; STROBE_CF_READER = 1 & W_WE=1 & WB_A0 = 1
17
                                                        CONSTANT WRITE_LBA_27_16,07
18
 
19
                ;--
20
                ;-- SLAVE INTERFACE
21
                ;--
22
                CONSTANT DATA_WB_OUT_7_0_SLAVE,03
23
                CONSTANT DATA_WB_OUT_15_8_SLAVE,04
24
                CONSTANT CONTROL_WB_OUT_SLAVE,05
25
                                                        ; D7 =  D6 =  D5  D4 =  D3 =
26
                                                        ; D2 = TAG1_ERROR
27
                                                        ; D1 = TAG0_WORD_AVAILABLE
28
                                                        ; D0 = ACK_O_SLAVE
29
                                                        CONSTANT ACK_O_SLAVE,01
30
                                                        CONSTANT TAG0_WORD_AVAILABLE,02
31
                                                        CONSTANT ERROR,04
32
 
33
                ;--
34
                ;-- BUS CONTROL SIGNALS
35
                ;--
36
                CONSTANT CONTROL_OUT_MASTER,06
37
                                                        ; D7 =  D6 = D5 = D4 = D3 = D2 = D1 =
38
                                                        ; D0 = WB_BUS_MASTER_WRITE_ENABLE
39
                                                        CONSTANT WB_BUS_MASTER_WRITE_ENABLE,01
40
                CONSTANT CONTROL_OUT_SLAVE,07
41
                                                        ; D7 =  D6 = D5 = D4 = D3 = D2 = D1 =
42
                                                        ; D0 = WB_BUS_SLAVE_WRITE_ENABLE
43
                                                        CONSTANT WB_BUS_SLAVE_WRITE_ENABLE,01
44
                ;--
45
                ;-- EXTERNAL REGISTERS FOR MORE DATA ALLOCATION (OTHER OPTION IS THE USE OF
46
                ;-- ANOTHER BLOCK RAM IF IT IS AVALIABLE
47
                ;--
48
                CONSTANT TMP_OUT_0,08
49
                CONSTANT TMP_OUT_1,09
50
                CONSTANT TMP_OUT_2,0A
51
                CONSTANT TMP_OUT_3,0B
52
                CONSTANT TMP_OUT_4,0C
53
                CONSTANT TMP_OUT_5,0D
54
                CONSTANT TMP_OUT_6,0E
55
                CONSTANT TMP_OUT_7,0F
56
;--
57
;-- INPUT PORTS
58
;--
59
                ;--
60
                ;-- WISHBONE INTERFACE PORTS - INPUTS
61
                ;--
62
                CONSTANT CONTROL_WB_IN_MASTER,00
63
                                                        ; D7 = D6 = D5 = D4 = D3 = D2 =
64
                                                        ; D1 = ERROR_INPUT
65
                                                        ; D0 = ACK_I_MASTER
66
                                                        ;
67
                                                        CONSTANT ACK_I_MASTER,01
68
                                                        CONSTANT ERROR_INPUT,02
69
                CONSTANT CONTROL_WB_IN_SLAVE,01
70
                                                        ; D7 = D6 = D5 = D4 = D3 = D2 =
71
                                                        ; D1 = -
72
                                                        ; D0 = STB_I_SLAVE
73
                                                        ;
74
                                                        CONSTANT STB_I_SLAVE,01
75
                                                        ;CONSTANT TAG0_FORCE_RESET,02
76
                ;--
77
                ;-- WISHBONE INTERFACE PORTS - INPUTS
78
                ;--
79
                CONSTANT DATA_WB_IN_7_0_MASTER,02
80
                CONSTANT DATA_WB_IN_15_8_MASTER,03
81
                ;--
82
                ;-- EXTERNAL REGISTERS FOR MORE DATA ALLOCATION (OTHER OPTION IS THE USE OF
83
                ;-- ANOTHER BLOCK RAM IF IT IS AVALIABLE
84
                ;--
85
                CONSTANT TMP_IN_0,04
86
                CONSTANT TMP_IN_1,05
87
                CONSTANT TMP_IN_2,06
88
                CONSTANT TMP_IN_3,07
89
                CONSTANT TMP_IN_4,08
90
                CONSTANT TMP_IN_5,09
91
                CONSTANT TMP_IN_6,0A
92
                CONSTANT TMP_IN_7,0B
93
;--
94
;-- REGISTERS INITIALIZATION
95
;--
96 5 armando
initialization:
97 2 armando
                ;
98 5 armando
                ; WISHBONE INTERFACES INITIALIZATION
99 2 armando
                ;
100
                LOAD sF,00
101
                OUTPUT sF,DATA_WB_OUT_7_0_MASTER
102
                OUTPUT sF,DATA_WB_OUT_15_8_MASTER
103
                OUTPUT sF,DATA_WB_OUT_7_0_SLAVE
104
                OUTPUT sF,DATA_WB_OUT_15_8_SLAVE
105
                OUTPUT sF,CONTROL_WB_OUT_MASTER
106
                OUTPUT sF,CONTROL_WB_OUT_SLAVE
107
                ;
108
                ; WAIT FOR 410NS*3 (RESET DELAY)
109
 
110
main:
111
 
112
                ; PROCESS MASTER BOOT RECORD
113
                CALL process_master_boot_record
114
                ; PROCESS ROOT DIRECTORY
115
                CALL process_root_directory
116
 
117
start:
118
                CALL cluster_2_lba
119
                ;CALL write_lba_to_slave
120
                ; sector_per_cluster -> sector_per_cluster_readed
121
                LOAD s4,s7
122
                ; 256 -> (s6) SECTOR_WORDS_READED
123
                CALL read_sector
124
idle:
125
                INPUT s6,CONTROL_WB_IN_SLAVE
126
                ; CHECK STB INPUT
127
                ; CONTROL_WB_IN_SLAVE-> TMP (s6)
128
                ; IF STB=1 GO TO THE NEXT STATE
129
                ; IF STB=0 GO TO THE IDLE STATE
130
                AND s6,STB_I_SLAVE
131
                JUMP Z,idle
132
transfer_word_to_master:
133
                CALL read_word_from_slave
134
                CALL write_a_word_to_master
135
                ; (SECTOR WORDS READED)-1
136
                SUB s5,01
137
check_sectors_words_readed:
138
                ; IF sector_words_readed = 0 THEN READ_NEW_SECTOR
139
                ; IF sector_words_readed > 0 THEN TRANSFER_WORD_TO_MASTER
140
                AND s5,s5
141
                CALL Z,check_sector_per_cluster_readed
142
                JUMP idle
143
track_new_cluster:
144
                ; save the number of dummy reads that must be done when the fat sector will be readed
145
                ; an are stored into s5 register
146
                ; in s0 bits 6-0 of the cluster number (offset in the sector -> 256 words-fat16 entries)
147
                ; as is each read operation a word is readed no multiplication is needed
148
                ; RESTORE CLUSTER NUMBER
149
                INPUT s0,TMP_IN_4
150
                INPUT s1,TMP_IN_5
151
                INPUT s2,TMP_IN_6
152
                INPUT s3,TMP_IN_7
153
                ;
154
                ; compose LBA address of the sector of the fat that must be readed
155
                ;
156
                ; SHIFT RIGHT 15-8 TO 7-0
157
                ;
158
                LOAD sF,07
159
        do_shift:
160
                SR0 s3
161
                ; uses the carry for the MSB and stores LSB into the carry
162
                SRA s2
163
                SRA s1
164
                SRA s0
165
                SUB sF,01
166
                JUMP NZ,do_shift
167
                CALL add_load_fat_begin_lba
168
                ; adds fat_begin_lba to the sector relative to the fat obteined from the cluster
169
                ; now there is the lba of the FAT sector that must be readed in s0,s1,s2,s3
170
                CALL write_lba_to_slave
171
                ; -- DUMMY READ OF THE WORDS OF THE SECTOR TILL THE ONE OF THE CLUSTER INTEGER
172
                INPUT sF,TMP_IN_4
173
                AND sF,7F
174
                CALL do_dummy_reads_from_slave
175
                ;
176
                ;  (sD) data[7:0] WB MASTER -> (s0) TEMPORAL REGISTER
177
                ;  (sE) data[7:0] WB MASTER -> (s1) TEMPORAL REGISTER
178
                ; READ 2 BYTES
179
                CALL read_word_from_slave
180
                LOAD s0,sD
181
                LOAD s1,sE
182
                ;  (sD) data[7:0] WB MASTER -> (s2) TEMPORAL REGISTER
183
                ;  (sE) data[7:0] WB MASTER -> (s3) TEMPORAL REGISTER
184
                ; READ 2 BYTES
185
                ;
186
                ; CHECK IF ITS THE LAST ONE
187
                ; CB3-CL2-CB1-CB0 IN FAT LITTLE ENDIAN ORDER CB0-CB1 CB2-CB3
188
                LOAD sF,sE
189
                SUB sF,FF
190
                JUMP NZ,continue_file_processing
191
                LOAD sF,sD
192
                SUB sF,FF
193
                JUMP NZ,continue_file_processing
194
        file_end:
195
                ; infinite loop (file readed and tranferred)
196
                JUMP file_end
197
        continue_file_processing:
198
                ; in s0,s1 is the cluster name
199
                ; --
200
                ; (SECTOR WORDS READED)= 256
201
                ; sector_per_cluster -> sector_per_cluster_readed
202
                LOAD s2,00
203
                LOAD s3,00
204
                LOAD s4,s7
205
                CALL cluster_2_lba
206
                CALL read_sector
207
                RETURN
208
 
209
        add_load_fat_begin_lba:
210
                INPUT sF,TMP_IN_0
211
                ADD s0,sF
212
                INPUT sF,TMP_IN_1
213
                ADDCY s1,sF
214
                INPUT sF,TMP_IN_2
215
                ADDCY s2,sF
216
                INPUT sF,TMP_IN_3
217
                ADDCY s3,sF
218
                RETURN
219
 
220
check_sector_per_cluster_readed:
221
                ; IF sector_per_cluster_readed = 0 THEN TRACK_NEW_CLUSTER
222
                ; IF sector_per_cluster_readed > 0 THEN CHECK SECTOR WORDS READED
223
                ; (sector_per_cluster_readed)-1
224
                ; (SECTOR WORDS READED)= 256
225
                SUB s4,01
226
                AND s4,s4
227
                JUMP Z,track_new_cluster
228
read_new_sector:
229
                ; (SECTOR WORDS READED)= 256
230
                ; increment LBA
231
                ; sector_per_cluster -> sector_per_cluster_readed-1
232
                ADD s0,01
233
                ADDCY s1,00
234
                ADDCY s2,00
235
                ADDCY s3,00
236
read_sector:
237
                LOAD s5,00
238
                CALL write_lba_to_slave
239
                RETURN
240
;
241
; --
242
; -- PROCESS MASTER BOOT RECORD (READ LBA BEGIN OF THE FIRST PARTITION)
243
; --
244
process_master_boot_record:
245
                ;
246
                ; LOAD LBA FOR MBR READ
247
                ;
248
                LOAD s0,00
249
                LOAD s1,00
250
                LOAD s2,00
251
                LOAD s3,00
252
                CALL write_lba_to_slave
253
                ; information of the lba begin for the first partition
254
                ; has an offset of 454 bytes -> 227(0xE3) words
255
                LOAD sF,E3
256
                CALL do_dummy_reads_from_slave
257
                ;
258
                ; --
259
                ; -- MBR READ - Partition_LBA_Begin EXTRACTION
260
                ; --
261
                ;
262
                ;  (sD) data[7:0] WB MASTER -> (s0) lba
263
                ;  (sE) data[15:8] WB MASTER -> (s1) lba
264
                ;  (sD) data[7:0] WB MASTER -> (s2) lba
265
                ;  (sE) data[15:8] WB MASTER -> (s3) lba
266
                call store_all_temporal_registers
267
                LOAD s8,s0
268
                LOAD s9,s1
269
                LOAD sA,s2
270
                LOAD sB,s3
271
                ;
272
                ; NOW IS THE LBA_BEGIN ON THE TMP REGISTERS
273
                ; --------------------
274
                ; READ FIRST SECTOR (FAT32 VOLUMEN ID) OF THE PARTITION
275
                ; ---------------------
276
                CALL write_lba_to_slave
277
                ;
278
                ; READ -> SECTORS_PER_CLUSTER (OFFSET 0x0D)
279
                ;
280
                ; offset 0x0D (13) => READ 13 bytes -> 6(0x06) words and drop LSB in the next
281
                LOAD sF,06
282
                CALL do_dummy_reads_from_slave
283
                ;
284
                ;  (sE) data[7:0] WB MASTER -> (s7) SECTORS PER CLUSTER
285
                CALL read_word_from_slave
286
                LOAD s7,sE
287
                ;
288
                ; READ -> Number_of_Reserved_Sectors (2 bytes) (OFFSET 0x0E)
289
                ;
290
                ; offset 0x0E (14) => READ 2 bytes -> 1(0x01) words
291
                ;  (sD) data[15:8] WB MASTER -> (s6) TEMPORAL REGISTER
292
                CALL read_word_from_slave
293
                LOAD s6,sD
294
                ;  (sE) data[7:0] WB MASTER -> (s4) TEMPORAL REGISTER
295
                ;
296
                LOAD s4,sE
297
                ;
298
                ;fat_begin_lba = Partition_LBA_Begin + Number_of_Reserved_Sectors
299
                ;
300
                ADD s8,s6
301
                ADDCY s9,s4
302
                ADDCY sA,00
303
                ADDCY sB,00
304
                ; store fat_begin_lba in external registers
305
                OUTPUT s8,TMP_OUT_0
306
                OUTPUT s9,TMP_OUT_1
307
                OUTPUT sA,TMP_OUT_2
308
                OUTPUT sB,TMP_OUT_3
309
                ;
310
                ;cluster_begin_lba = Partition_LBA_Begin + Number_of_Reserved_Sectors +
311
                ;                               (Number_of_FATs * Sectors_Per_FAT)+ RootDirSectors;
312
                ;cluster_begin_lba = fat_begin_lba + (Number_of_FATs * Sectors_Per_FAT)+ RootDirSectors;
313
                ; READ -> Number_of_Fats (OFFSET 0x10) (always 2)
314
                ;
315
                ; offset 0x10 (16) => READ 2 bytes -> 1(0x01) words
316
                ;
317
                ;  (sD) data[7:0] WB MASTER -> (s6) TEMPORAL REGISTER
318
                CALL read_word_from_slave
319
                LOAD s6,sD
320
                ;
321
                ; FOR FAT16 => NUMBER OF SECTORS OCCUPIED BY THE ROOT DIRECTORY (BYTES_PER_SEC=512)
322
                ;
323
                ; READ -> RootEntCnt (OFFSET 0x11) (FAT16 PROCESSING)
324
                ; RootDirSectors=((BPB_RootEntCnt*32)+(BPB_BytesPerSec-1))/BPB_BytesPerSec
325
                ; offset 0x11 (17) => READ 1 bytes
326
                ;
327
                ;  (sE) data[7:0] WB MASTER -> (s0) TEMPORAL REGISTER
328
                LOAD s0,sE
329
                ;  (sD) data[15:0] WB MASTER -> (sD) TEMPORAL REGISTER - offset 0x12 (18) => READ 1 bytes
330
                CALL read_word_from_slave
331
                LOAD s1,sD
332
                ; MULTIPLY BY 32 (100000) 5 SHIFTS TO THE LEFT
333
                LOAD sF,05
334
                ; LSB '0'
335
        mult_32:
336
                SL0 s0
337
                ; CARRY -> LSB , MSB -> CARRY
338
                SLA s1
339
                SUB sF,01
340
                JUMP NZ,mult_32
341
                ;BPB_RootEntCnt*32+(BPB_BytesPerSec-1) 511 (0x1FF)
342
                ;ADD s0,FF (if rounds up => not necessary??)
343
                ;ADDCY s1,01
344
                ;/BPB_BytesPerSec (512) (1000000000)9 SHIFTS TO THE RIGHT
345
                LOAD sF,09
346
        div_512:
347
                ; uses the carry for the MSB and stores LSB into the carry
348
                SR0 s1
349
                SRA s0
350
                SUB sF,01
351
                JUMP NZ,div_512
352
                ; ROUNDs UP
353
                ;ADD s0,01
354
                ;ADDCY s1,00
355
                ;fat_begin_lba + RootDirSectors
356
                ADD s8,s0
357
                ADDCY s9,s1
358
                ADDCY sA,s2
359
                ADDCY sB,s3
360
                ; READ -> Sectors_per_fat (OFFSET 0x24)
361
                ;
362
                ; offset 0x16 (22) => READ 2 bytes -> 01(0x01) words
363
                ;
364
                LOAD sF,01
365
                CALL do_dummy_reads_from_slave
366
                CALL store_all_temporal_registers
367
                ;  (Number_of_FATs * Sectors_Per_FAT)
368
                ; Number_of_FATs = 2 (10) . Do a shift to the left of the Sectors_Per_Fat
369
                ; ***   FAT16 = Sectors_per_fat(BPB_FATSz16)
370
                ; LSB '0'
371
                SL0 s0
372
                ; CARRY -> LSB , MSB -> CARRY
373
                SLA s1
374
                ;SLA s2 for fat16 only 2 bytes
375
                ;SLA s3
376
                ; fat_begin_lba + RootDirSectors + (Number_of_FATs * Sectors_Per_FAT)
377
                ADD s8,s0
378
                ADDCY s9,s1
379
                ADDCY sA,00
380
                ADDCY sB,00
381
                ; cluster_begin_lba is stored in s8, s9, sA, SB
382
                ;
383
                ; FOR FAT16 ROOT DIRECTORY POSITION IS FIXED
384
                ; root_first_lba =  fat_begin_lba(in external regs) + (Number_of_FATs * Sectors_Per_FAT) (s0,s1,s2,s3)
385
                ;
386
                LOAD s2,00
387
                LOAD s3,00
388
                CALL add_load_fat_begin_lba
389
                ; s0,s1,s2,s3 have Root directory begin lba
390
                RETURN
391
 
392
store_all_temporal_registers:
393
                ; READ 2 BYTES
394
                CALL read_word_from_slave
395
                ;  (sD) data[7:0] WB MASTER -> (s0) TEMPORAL REGISTER
396
                ;  (sE) data[7:0] WB MASTER -> (s1) TEMPORAL REGISTER
397
                LOAD s0,sD
398
                LOAD s1,sE
399
                ;  (sD) data[7:0] WB MASTER -> (s2) TEMPORAL REGISTER
400
                ;  (sE) data[7:0] WB MASTER -> (s3) TEMPORAL REGISTER
401
                ; READ 2 BYTES
402
                CALL read_word_from_slave
403
                LOAD s2,sD
404
                LOAD s3,sE
405
                RETURN
406
process_root_directory:
407
                ; INPUT :
408
                ; s0,s1,s2,s3 root directory lba (FAT16- FIXED)
409
                ; CALL cluster_2_lba
410
                ; now s0,s1,s2,s3 contains the lba for the root directory
411
                ; the first 32 byte record on the sector must be the root directory information
412
                ; check if EOF (first byte of the 32 bytes is 0)
413
                CALL write_lba_to_slave
414
        check_for_a_file:
415
                CALL read_word_from_slave
416
                ;  (sD) data[7:0] WB MASTER -> (s6) TEMPORAL REGISTER
417
                LOAD s6,sD
418
                LOAD sF,s6
419
                AND sF,sF
420
                ; if sF=0 the is not directory => error
421
                JUMP Z,put_error_code
422
                ;
423
                ; check that is not a deleted entry
424
                ;
425
                ;  (sD) data[7:0] WB MASTER -> (s6) TEMPORAL REGISTER
426
                LOAD sF,E5
427
                AND sF,s6
428
                ; if s6=E5 is a deteled entry => check for new one (offset => sF)
429
                JUMP Z,check_next_directory_entry
430
        check_attribute:
431
                ; ATTRIBUTE -> OFFSET Bh
432
                ; check that is not a directory or LONG NAME
433
                ; 00arshdv - DV for long name - D for directory
434
                ;  (sD) data[7:0] WB MASTER -> (s6) TEMPORAL REGISTER
435
                LOAD sF,04
436
                CALL do_dummy_reads_from_slave
437
                CALL read_word_from_slave
438
                LOAD s6,sE
439
                LOAD sF,03
440
                AND sF,s6
441
                JUMP NZ,check_next_directory_entry_attribute
442
                ; if s6=0 that is not a file => error
443
                ;JUMP Z,check_next_directory_entry
444
                ; check that is not a directory
445
                ; check that is a file (short filename entry)
446
                ; in other case error
447
                ;
448
                ;
449
                ; READ CLUSTER INFORMATION FOR THE FILE
450
                ;
451
                CALL read_dir_cluster_hi_cluster_low
452
                RETURN
453
        check_next_directory_entry:
454
                ; go fwd 11 words
455
                LOAD sF,05
456
                CALL do_dummy_reads_from_slave
457
        check_next_directory_entry_attribute:
458
                ; go fwd 5 words
459
                LOAD sF,0A
460
                CALL do_dummy_reads_from_slave
461
                JUMP check_for_a_file
462
read_dir_cluster_hi_cluster_low:
463
                ; INPUT :
464
                ;          before arrive here first two bytes of the directory
465
                ;          structure must be readed
466
                ; OUTPUT :
467
                ; s0,s1 : CLUS_LOW
468
                ; s2,s3 : CLUS_HI
469
                ;
470
                ; READ -> cluster_HI (OFFSET 0x14)
471
                ;
472
                ; offset 0x14 (20) => READ 18 bytes -> 9(0x09) words
473
                ;
474
                LOAD sF,04
475
                CALL do_dummy_reads_from_slave
476
                ;  (sD) data[7:0] WB MASTER -> s2
477
                ;  (sE) data[7:0] WB MASTER -> s3
478
                ; READ 2 BYTES
479
                CALL read_word_from_slave
480
                LOAD s2,sD
481
                LOAD s3,sE
482
                OUTPUT sE,TMP_OUT_7
483
                ;
484
                ; READ -> cluster_low(OFFSET 0x1A)
485
                ;
486
                ; offset 0x1A (26) => READ 4 bytes -> 2(0x02) words
487
                ;
488
                LOAD sF,02
489
                CALL do_dummy_reads_from_slave
490
                ;  (sD) data[7:0] WB MASTER ->  s0
491
                ;  (sE) data[7:0] WB MASTER ->  s1
492
                ; READ 2 BYTES
493
                CALL read_word_from_slave
494
                LOAD s0,sD
495
                LOAD s1,sE
496
                ; s0,s1 clus_low s3,s4 - clus_high
497
                RETURN
498
 
499
; -- MBR READ OPERATION - LBA BEGIN DETERMINATION
500
; '00' -> LBA_7_0,LBA_15_8,LBA_23_16,LD_LBA_27_24
501
 
502
cluster_2_lba:
503
        ; --
504
        ; -- LBA ADDRESS DETERMINATION
505
        ; --
506
        ; lba_addr = cluster_begin_lba + (cluster_number - 2) * sectors_per_cluster;
507
        ;
508
        ; INPUT :
509
        ; s0 : CLUSTER_NUMBER0, s1 : CLUSTER_NUMBER1, s2: CLUSTER_NUMBER2, s3 : CLUSTER_NUMBER3
510
        ; OUTPUT :
511
        ; s0 : LBA_ADDR_7_0 TMP1, s1 : LBA_ADDR_15_8, s2 : LBA_ADDR_24_16, s3 : LBA_ADDR_27_24
512
        ;
513
        ; cluster_number - 2
514
        ;
515
        OUTPUT s0,TMP_OUT_4
516
        OUTPUT s1,TMP_OUT_5
517
        OUTPUT s2,TMP_OUT_6
518
        OUTPUT s3,TMP_OUT_7
519
        SUB s0,02
520
        SUBCY s1,00
521
        SUBCY s2,00
522
        SUBCY s3,00
523
        ;
524
        ; (cluster_number - 2) * sectors_per_cluster(s7);
525
        ;
526
        ; to perform the multiplication as sector_per_cluster is 2 multiple must be known
527
        ; who many times must be shifted
528
        ; (use sD as temporal register)
529
        LOAD sF,08
530
        LOAD sD,s7
531
 
532
multiply:
533
        SR0 sD
534
        ; loop until detection of the 1 (2 multiple) - Add timeout!!!
535
        JUMP C,add_cluster_begin_lba
536
        ; LSB '0'
537
        SL0 s0
538
        ; CARRY -> LSB , MSB -> CARRY
539
        SLA s1
540
        SLA s2
541
        SLA s3
542
        JUMP multiply
543
 
544
add_cluster_begin_lba:
545
        ; lba_addr (TMP0,TMP1,TMP2,TMP3)= cluster_begin_lba + (cluster_number - 2) * sectors_per_cluster;
546
        ADD s0,s8
547
        ADDCY s1,s9
548
        ADDCY s2,sA
549
        ADDCY s3,sB
550
        RETURN
551
 
552
; --
553
; -- WRITE A WORD INTO THE WB SLAVE INTERFACE (TO THE MASTER)
554
; --
555
; INPUTS :
556
; TMP0 : LSB TO DATA_WB_OUT_7_0_SLAVE
557
; TMP1 : MSB TO DATA_WB_OUT_15_8_SLAVE
558
;
559
write_a_word_to_master:
560
        ; TMP0 => DATA_WB_OUT_7_0_SLAVE
561
        OUTPUT sD,DATA_WB_OUT_7_0_SLAVE
562
        ; 00 => DATA_WB_OUT_15_8_SLAVE
563
        ;LOAD sF,00 -- 8 BIT VERSION
564
        ;OUTPUT sF,DATA_WB_OUT_15_8_SLAVE -- 8 BIT VERSION
565
        OUTPUT sE,DATA_WB_OUT_15_8_SLAVE
566
        CALL write_a_byte_to_master
567
                ;
568
                ; CHECK STB INPUT | CONTROL_WB_IN_SLAVE-> TMP (s6)
569
                ;
570
        wait_strobe:
571
                INPUT s6,CONTROL_WB_IN_SLAVE
572
                ;
573
                ;
574
                AND s6,STB_I_SLAVE
575
                JUMP Z,wait_strobe
576
        ; TMP1 => DATA_WB_OUT_7_0_SLAVE
577
        ; OUTPUT sE,DATA_WB_OUT_7_0_SLAVE
578
        ; 00 =>DATA_WB_OUT_15_8_SLAVE
579
        ;LOAD sF,00 -- 8 BIT VERSION
580
        ;OUTPUT sF,DATA_WB_OUT_15_8_SLAVE -- 8 BIT VERSION
581
        ;CALL write_a_byte_to_master -- 8 BIT VERSION
582
        RETURN
583
 
584
write_a_byte_to_master:
585
        ;
586
        ; WB SLAVE WRITE ENABLE ACTIVE
587
        ;
588
        LOAD sF,WB_BUS_SLAVE_WRITE_ENABLE
589
        OUTPUT sF,CONTROL_OUT_SLAVE
590
        ;
591
        ; ACK TO THE MASTER UNTIL STB FINISH
592
        ;
593
ack_to_the_master:
594
        LOAD sF,ACK_O_SLAVE
595
        OUTPUT sF,CONTROL_WB_OUT_SLAVE
596
        ;
597
        ;
598
        LOAD sF,00
599
        OUTPUT sF,CONTROL_OUT_SLAVE
600
        OUTPUT sF,CONTROL_WB_OUT_SLAVE
601
        RETURN
602
; --
603
; -- WRITE A LBA INTO THE WB MASTER INTERFACE (TO THE SLAVE)
604
; --
605
; INPUTS :
606
; TMP0 : LBA_ADDR_7_0, TMP1 : LBA_ADDR_15_8, TMP2 : LBA_ADDR_24_16, TMP3 : LBA_ADDR_27_24
607
;
608
;
609
write_lba_to_slave:
610
        ;
611
        ; WB MASTER WRITE ENABLE ACTIVE
612
        ;
613
        LOAD sF,WB_BUS_MASTER_WRITE_ENABLE
614
        OUTPUT sF,CONTROL_OUT_MASTER
615
 
616
        ;write_lba_15_0_to_slave:
617
        ;
618
        ; TMP0 : LBA_ADDR_7_0 (s0)      => DATA_WB_OUT_7_0_MASTER
619
        ; TMP1 : LBA_ADDR_15_8 (s1)     => DATA_WB_OUT_15_8_MASTER
620
        ;
621
        OUTPUT s0,DATA_WB_OUT_7_0_MASTER
622
        OUTPUT s1,DATA_WB_OUT_15_8_MASTER
623
        ;
624
        ; --
625
        ; -- WRITE LBA 15-0 TO THE SLAVE
626
        ; --
627
        ;
628
        ; WB_CONTROL_OUT_MASTER
629
        ; W_WE_MASTER = 1
630
        ; STB_O_MASTER = 1
631
        ; A0 = 0
632
        ;
633
        LOAD sF,WRITE_LBA_15_0
634
        OUTPUT sF,CONTROL_WB_OUT_MASTER
635
        ;
636
        ; WAIT FOR THE ACK
637
        ;
638
        CALL wait_for_the_ack
639
 
640
        ;write_lba_27_16_to_slave:
641
        ;
642
        ; TMP2 : LBA_ADDR_23_16 (s2)    => DATA_WB_OUT_7_0_MASTER
643
        ; TMP3 : LBA_ADDR_27_24 (s3)    => DATA_WB_OUT_15_8_MASTER
644
        ;
645
        OUTPUT s2,DATA_WB_OUT_7_0_MASTER
646
        OUTPUT s3,DATA_WB_OUT_15_8_MASTER
647
 
648
        ; --
649
        ; -- WRITE LBA 27-16 TO THE SLAVE
650
        ; --
651
        ; WB_CONTROL_OUT_MASTER
652
        ; W_WE_MASTER = 1
653
        ; STB_O_MASTER = 1
654
        ; A0 = 0
655
        ;
656
        LOAD sF,WRITE_LBA_27_16
657
        OUTPUT sF,CONTROL_WB_OUT_MASTER
658
        ;
659
        ; WAIT FOR THE ACK
660
        ;
661
        CALL wait_for_the_ack
662
        ; --
663
        ; -- FINISH WRITE OPERATION ON THE MASTER WB INTERFACE
664
        ; --
665
        ;
666
        ; WB_CONTROL_OUT_MASTER
667
        ; W_WE_MASTER = 0
668
        ; STB_O_MASTER = 0
669
        ; A0 = 0
670
        ;
671
        LOAD sF,00
672
        OUTPUT sF,CONTROL_WB_OUT_MASTER
673
        OUTPUT sF,CONTROL_OUT_MASTER
674
        RETURN
675
 
676
; --
677
; -- PERFORM DUMMY READS FROM THE WB SLAVE
678
; --
679
; -- IN sF ARE THE NUMBER OF WORDS THAT MUST BE READED
680
; --
681
do_dummy_reads_from_slave:
682
      LOAD s6,sF
683
dummy_reads_from_slave:
684
        CALL read_word_from_slave
685
      SUB s6,01
686
      JUMP NZ,dummy_reads_from_slave
687
        RETURN
688
 
689
; --
690
; -- PERFORM A WORD READING FROM THE WB SLAVE
691
; --
692
read_word_from_slave:
693
        ; WB_CONTROL_OUT_MASTER
694
        ; W_WE_MASTER = 0
695
        ; STB_O_MASTER = 1
696
        ; A0 = 0
697
        ; wait state
698
        LOAD sF,READ_SLAVE
699
        OUTPUT sF,CONTROL_WB_OUT_MASTER
700
        ;
701
        ; WAIT FOR THE ACK
702
        ;
703
        ; CALL wait_for_the_ack
704
        ;JUMP Z,data_available_on_wb_master
705
 
706
wait_for_the_ack:
707
        ;
708
        ; CONTROL_WB_IN_MASTER -> TMP (s6)
709
        ;
710
        INPUT sF,CONTROL_WB_IN_MASTER
711
        ;
712
        AND sF,ACK_I_MASTER
713
        JUMP Z,wait_for_the_ack
714
 
715
data_available_on_wb_master:
716
        ; This part is not necessary in write operations
717
        ; DATA_WB_IN_7_0_MASTER -> (sD) data[7:0] WB MASTER
718
        ; DATA_WB_IN_15_8_MASTER -> (sE) data[15:8] WB MASTER
719
        INPUT sD,DATA_WB_IN_7_0_MASTER
720
        INPUT sE,DATA_WB_IN_15_8_MASTER
721
        ; DISABLE RD/WR OPERATION REQUEST
722
        LOAD sF,00
723
        OUTPUT sF,CONTROL_WB_OUT_MASTER
724
        RETURN
725
 
726
put_error_code:
727
        LOAD sF,ERROR
728
        OUTPUT sF,CONTROL_WB_OUT_SLAVE
729
        JUMP put_error_code
730
 
731
interrupt:
732
                RETURNI ENABLE
733
 
734
 

powered by: WebSVN 2.1.0

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