]> cloudbase.mooo.com Git - avrcpm.git/blame - avrcpm/avr/dsk_fsys.asm
* ipl.mac added
[avrcpm.git] / avrcpm / avr / dsk_fsys.asm
CommitLineData
64219415
FZ
1; Filesystem functions for the Interaction with BIOS and Disks
2;
3; Copyright (C) 2010 Frank Zoll
4;
5; This file is part of avrcpm.
6;
7; avrcpm is free software: you can redistribute it and/or modify it
8; under the terms of the GNU General Public License as published by
9; the Free Software Foundation, either version 3 of the License, or
10; (at your option) any later version.
11;
12; avrcpm is distributed in the hope that it will be useful,
13; but WITHOUT ANY WARRANTY; without even the implied warranty of
14; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15; GNU General Public License for more details.
16;
17; You should have received a copy of the GNU General Public License
18; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
19;
20; $Id$
b741422e
L
21;
22
29ce189c 23.equ DSKSEL_DEBUG = 0
b741422e 24
64219415
FZ
25; ---------------- Defines for the Filesystem Interface -------
26
64219415
FZ
27;*****************************************************
28;* Disk-Manager constants *
29;*****************************************************
2bfd98e4 30 .equ dskType_None = 0
b741422e
L
31 .equ dskType_CPM = 1
32 .equ dskType_FAT = 2
29ce189c 33; .equ dskType_RAM = 3
64219415
FZ
34
35;*****************************************************
36;* CP/M to host disk constants *
37;*****************************************************
92202636 38 .equ MAXDISKS = 8 ;Max number of Disks (partitions)
64219415
FZ
39 .equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry
40 .equ blksize = 1024 ;CP/M allocation size
41 .equ hostsize = 512 ;host disk sector size
42; .equ hostspt = 20 ;host disk sectors/trk
2bfd98e4
FZ
43 .equ hostblk = hostsize/128 ;CP/M sects/host buff
44; .equ CPMSPT = hostblk*hostspt ;CP/M sectors/track
45 .equ CPMSPT = 26 ;
64219415 46 .equ SECMSK = hostblk-1 ;sector mask
2bfd98e4 47 .equ SECSHF = log2(hostblk) ;sector shift
64219415
FZ
48
49;*****************************************************
50;* BDOS constants on entry to write *
51;*****************************************************
52 .equ WRALL = 0 ;write to allocated
53 .equ WRDIR = 1 ;write to directory
54 .equ WRUAL = 2 ;write to unallocated
b741422e 55 .equ WRTMSK= 3 ;write type mask
eb85ce65
L
56
57 .equ READ_FUNC = 7
58 .equ WRITE_FUNC = 6
59 .equ BOOT_FUNC = 5
60 .equ HOME_FUNC = 4
61
64219415
FZ
62;----------------------------------------------- Start of Data Segment
63
b741422e
L
64 .dseg
65
29ce189c
L
66; The following 3 variables are copied from DRAM.
67; Don't change order.
68
69biosdrvtbl: .byte 2 ;
70biosdirbuf: .byte 2 ;
71biosenddat: .byte 2 ;
72
73ndisks: .byte 1 ;Number of CP/M disks
64219415 74
29ce189c
L
75; The following 5 variables are accessed from 8080/z80 via the
76; virtual port interface. Don't change order.
64219415 77
29ce189c
L
78biospar_base:
79bcbadr: .byte 2 ;adr of BiosControlBlock
80seekdsk: .byte 1 ;seek disk number
81seektrk: .byte 2 ;seek track number
82seeksec: .byte 2 ;seek sector number
83dmaadr: .byte 2 ;last dma address
64219415 84
29ce189c
L
85unacnt: .byte 1 ;unalloc rec cnt
86unadsk: .byte 1 ;last unalloc disk
87unatrk: .byte 2 ;last unalloc track
88unasec: .byte 1 ;last unalloc sector
64219415 89
29ce189c
L
90erflag: .byte 1 ;error reporting
91wrtype: .byte 1 ;write operation type
92
93hostbuf: .byte hostsize ;host buffer (from/to SD-card)
94hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
64219415 95hostparttbltop:
29ce189c
L
96hostdsk: .byte 1 ;host disk number
97hosttype: .byte 1 ;host disk type (same entry as 1 parition entry)
98hostlba: .byte 3 ;host sector number (relative to partition start)
b741422e
L
99
100
64219415 101; ------------------------------- Start of Code Segment
b741422e
L
102 .cseg
103
29ce189c
L
104;---------------------------------------------------------------------
105
106.if DSKSEL_DEBUG
107
108dbg_prdrvtbl:
109 push xh
110 push xl
111 push temp3
112 push temp2
113 push temp
114 printnewline
115 printstring "drvtbl ("
116 lds xl,biosdrvtbl
117 lds xh,biosdrvtbl+1
118 movw temp,x
119 rcall printhexw
120 printstring "): "
121 ldi temp3,16
122dbg_pcpel:
123 rcall dram_readw_pp
124 rcall printhexw
125 printstring " "
126 dec temp3
127 brne dbg_pcpel
128 pop temp
129 pop temp2
130 pop temp3
131 pop xl
132 pop xh
133 ret
134
135dbg_print_biosd:
136 printnewline
137 lds temp,bcbadr
138 lds temp2,bcbadr+1
139 rcall printhexw
140 printstring " "
141 lds temp,biosdrvtbl
142 lds temp2,biosdrvtbl+1
143 rcall printhexw
144 printstring " "
145 lds temp,biosdirbuf
146 lds temp2,biosdirbuf+1
147 rcall printhexw
148 printstring " "
149 lds temp,biosenddat
150 lds temp2,biosenddat+1
151 rcall printhexw
152 printstring " "
153 ret
154.endif
155
b741422e 156; ====================================================================
1eeb9cbe 157; Function: Get a Pointer to a Partitiontable entry
b741422e
L
158; ====================================================================
159; Parameters
160; --------------------------------------------------------------------
1eeb9cbe
L
161; Registers : [w] z Pointer to the Partitionentry
162; [r] xl Number of Diskentry to Read
29ce189c
L
163; [w] _tmp0 scratch
164; [w] _tmp1 "
b741422e
L
165; --------------------------------------------------------------------
166; Description:
167; ====================================================================
1eeb9cbe
L
168dsk_getpartentry:
169
eb85ce65
L
170 ldi zl,PARTENTRY_SIZE
171 mul xl,zl
1eeb9cbe 172 ldiw z,hostparttbl
eb85ce65
L
173 add zl,_tmp0
174 add zh,_tmp1
64219415 175 ret
b741422e 176
1eeb9cbe 177; ====================================================================
29ce189c 178; Function: Virtual Port Interface
1eeb9cbe
L
179; ====================================================================
180; Parameters
181; --------------------------------------------------------------------
29ce189c
L
182; Registers :
183; Variables :
184;
185; --------------------------------------------------------------------
186; Description:
187; ====================================================================
188
189dsk_param_getadr:
190 ldiw z,biospar_base
191 add zl,temp3
192 adc zh,_0
193 ret
194
195dsk_param_wr:
196 rcall dsk_param_getadr
197 st z,temp
198 cpi temp3,bcbadr+1-seektrk
199 brne dsk_param_wr1
200 std z+1,_0
201dsk_param_wr1:
202 cpi temp3,bcbadr+1-biospar_base
203 breq SetBCB
204 ret
205
206dsk_param_rd:
207 cpi temp3,seekdsk-biospar_base
208 breq dskDiskCheck
209 rcall dsk_param_getadr
210 ld temp,z
211 ret
212
213SetBCB:
214 lds xl,bcbadr
215 mov xh,temp
216 ldiw z,biosdrvtbl
217 ldi temp3,6
218sbcb_l:
219 rcall dram_read_pp
220 st z+,temp
221 dec temp3
222 brne sbcb_l
223
224; rcall dbg_print_biosd
225 rcall dsk_drvtblinit
226; rcall dbg_prdrvtbl
227
228 ret
229
230; ====================================================================
231; Function: Check if disk exists
232; ====================================================================
233; Parameters
234; --------------------------------------------------------------------
235; Registers :
236; Variables :
237; return 0, if selected disk not exist.
238; return !0, if disk exist
1eeb9cbe
L
239; --------------------------------------------------------------------
240; Description:
241; ====================================================================
64219415 242dskDiskCheck:
29ce189c
L
243 lds temp,ndisks
244 lds temp2,seekdsk
245.if DSKSEL_DEBUG
246 printnewline
247 printstring "DiskCheck: "
248 rcall printhexw
249.endif
250 cpi temp2,RAMDISKNR
64219415
FZ
251 brsh dsk_dchrd ;maybe ramdisk
252
253; Check if selected disk # is less then # of disks.
254
29ce189c
L
255 lds temp,ndisks
256 tst temp ;0 disks?
64219415
FZ
257 brne dsk_dchpart1
258
eb85ce65 259; No disks yet, need to init
64219415 260
29ce189c
L
261 rcall mgr_init_partitions ;disk chanched?
262; sbrs temp,7
263; rjmp dsk_dchpart0
264 push temp
265 rcall dsk_drvtblinit
266; rcall dbg_prdrvtbl
267 pop temp
268dsk_dchpart0:
269 cbr temp,0x80
270 lds temp2,seekdsk
64219415
FZ
271
272dsk_dchpart1:
29ce189c
L
273 cp temp2,temp
274 brsh dsk_dch_err
275
276.if DSKSEL_DEBUG
277 printnewline
278 printstring "Select: "
279 mov temp,temp2
280 rcall printhex
281.endif
282 ldsw x,biosdrvtbl
283 lsl temp2 ;drive #
284 add xl,temp2
285 adc xh,_0
286 rcall dram_readw_pp ;get drive table entry
287
288 or temp,temp2 ;if !0, drive is allready initialized
289 brne dsk_dchend
290 lds temp,seekdsk
291 rcall dsk_diskinit
64219415
FZ
292
293dsk_dchend:
29ce189c
L
294.if DSKSEL_DEBUG
295 push temp
296 ldsw x,biosdrvtbl
297 lds temp,seekdsk
298 lsl temp ;drive #
299 add xl,temp
300 adc xh,_0
301 rcall dram_readw_pp
302 printstring ", "
303 rcall printhexw
304 pop temp
305.endif
306
64219415
FZ
307 ret
308
29ce189c
L
309dsk_dch_err:
310 ldi temp,0 ;error return
311 ret
312
313; Check RAMDISK
314
64219415
FZ
315dsk_dchrd:
316#if RAMDISKCNT
29ce189c
L
317 cpi temp,RAMDISKNR+RAMDISKCNT
318 brsh dsk_dchrd_err
319
320 ldi temp,0xff ;return ok
321 ret
64219415 322#endif
29ce189c
L
323dsk_dchrd_err:
324 ldi temp,0 ;error return
64219415 325 ret
29ce189c
L
326
327
328; ====================================================================
329; Function: Return status of last disk i/o function
330; ====================================================================
331; Parameters
332; --------------------------------------------------------------------
333; Registers :
334; Variables :
335; --------------------------------------------------------------------
336; Description:
337; ====================================================================
64219415 338dskErrorRet:
29ce189c 339 lds temp,erflag
64219415
FZ
340 ret
341
29ce189c
L
342
343; -------------------------------------------------------------------
64219415 344
64219415 345
29ce189c
L
346 .dseg
347tmpdpb: .byte 15
348
349 .cseg
350
351; Test DPBs (avrcpm format)
352
353dpblist:
92202636
L
354;dpb243
355 .db 0x1A,0x00 ;spt
356 .db 0x03,0x07 ;block shift, bock mask
357 .db 0x00,0xF2 ;extent mask, low(disk size -1),
358 .db 0x00,0x3F ;high(disk size -1), low(dir max)
359 .db 0x00,0xC0 ;high(dir max), alloc0
360 .db 0x00,0x10 ;alloc1, low(chk size)
361 .db 0x00,0x02 ;high(chk size), low(offset)
362 .db 0x00,0x00 ;high(offset), fill
363;dpb243
364 .db 0x1A,0x00 ;spt
365 .db 0x03,0x07 ;block shift, bock mask
366 .db 0x00,0xF2 ;extent mask, low(disk size -1),
367 .db 0x00,0x3F ;high(disk size -1), low(dir max)
368 .db 0x00,0xC0 ;high(dir max), alloc0
369 .db 0x00,0x10 ;alloc1, low(chk size)
370 .db 0x00,0x02 ;high(chk size), low(offset)
371 .db 0x00,0x00 ;high(offset), fill
372;dpb243
373 .db 0x1A,0x00 ;spt
374 .db 0x03,0x07 ;block shift, bock mask
375 .db 0x00,0xF2 ;extent mask, low(disk size -1),
376 .db 0x00,0x3F ;high(disk size -1), low(dir max)
377 .db 0x00,0xC0 ;high(dir max), alloc0
378 .db 0x00,0x10 ;alloc1, low(chk size)
379 .db 0x00,0x02 ;high(chk size), low(offset)
380 .db 0x00,0x00 ;high(offset), fill
381;dpb243
382 .db 0x1A,0x00 ;spt
383 .db 0x03,0x07 ;block shift, bock mask
384 .db 0x00,0xF2 ;extent mask, low(disk size -1),
385 .db 0x00,0x3F ;high(disk size -1), low(dir max)
386 .db 0x00,0xC0 ;high(dir max), alloc0
387 .db 0x00,0x10 ;alloc1, low(chk size)
388 .db 0x00,0x02 ;high(chk size), low(offset)
389 .db 0x00,0x00 ;high(offset), fill
29ce189c
L
390;dpb243
391 .db 0x1A,0x00 ;spt
392 .db 0x03,0x07 ;block shift, bock mask
393 .db 0x00,0xF2 ;extent mask, low(disk size -1),
394 .db 0x00,0x3F ;high(disk size -1), low(dir max)
395 .db 0x00,0xC0 ;high(dir max), alloc0
396 .db 0x00,0x10 ;alloc1, low(chk size)
397 .db 0x00,0x02 ;high(chk size), low(offset)
398 .db 0x00,0x00 ;high(offset), fill
399;dpb243
400 .db 0x1A,0x00 ;spt
401 .db 0x03,0x07 ;block shift, bock mask
402 .db 0x00,0xF2 ;extent mask, low(disk size -1),
403 .db 0x00,0x3F ;high(disk size -1), low(dir max)
404 .db 0x00,0xC0 ;high(dir max), alloc0
405 .db 0x00,0x10 ;alloc1, low(chk size)
406 .db 0x00,0x02 ;high(chk size), low(offset)
407 .db 0x00,0x00 ;high(offset), fill
408;dpb243
409 .db 0x1A,0x00 ;spt
410 .db 0x03,0x07 ;block shift, bock mask
411 .db 0x00,0xF2 ;extent mask, low(disk size -1),
412 .db 0x00,0x3F ;high(disk size -1), low(dir max)
413 .db 0x00,0xC0 ;high(dir max), alloc0
414 .db 0x00,0x10 ;alloc1, low(chk size)
415 .db 0x00,0x02 ;high(chk size), low(offset)
416 .db 0x00,0x00 ;high(offset), fill
417;dpb243
418 .db 0x1A,0x00 ;spt
419 .db 0x03,0x07 ;block shift, bock mask
420 .db 0x00,0xF2 ;extent mask, low(disk size -1),
421 .db 0x00,0x3F ;high(disk size -1), low(dir max)
422 .db 0x00,0xC0 ;high(dir max), alloc0
423 .db 0x00,0x10 ;alloc1, low(chk size)
424 .db 0x00,0x02 ;high(chk size), low(offset)
425 .db 0x00,0x00 ;high(offset), fill
426#if 0
427;rd1016
428 .db 0x20,0x00 ;spt
429 .db 0x04,0x0F ;block shift, bock mask
430 .db 0x00,0xFB ;extent mask, low(disk size -1),
431 .db 0x01,0xBF ;high(disk size -1), low(dir max)
432 .db 0x00,0xE0 ;high(dir max), alloc0
433 .db 0x00,0x30 ;alloc1, low(chk size)
434 .db 0x00,0x02 ;high(chk size), low(offset)
435 .db 0x00,0x00 ;high(offset), fill
436;rd9192s
437 .db 0x20,0x00 ;spt
438 .db 0x05,0x1F ;block shift, bock mask
439 .db 0x01,0xFD ;extent mask, low(disk size -1),
440 .db 0x07,0xFF ;high(disk size -1), low(dir max)
441 .db 0x01,0xF0 ;high(dir max), alloc0
442 .db 0x00,0x80 ;alloc1, low(chk size)
443 .db 0x00,0x02 ;high(chk size), low(offset)
444 .db 0x00,0x00 ;high(offset), fill
445#endif
446
447; Test
448cpy_dpb:
449 push zh
450 push zl
451 push yh
452 push yl
453 ldiw z,dpblist*2
454 ldi temp2,16
455 mul temp,temp2
456 add zl,_tmp0
457 adc zh,_tmp1
458 ldiw y,tmpdpb
459cpydpb_l:
460 lpm temp,z+
461 st y+,temp
462 cpi yl,low(tmpdpb + 15)
463 brne cpydpb_l
464 pop yl
465 pop yh
466 pop zl
467 pop zh
64219415 468 ret
29ce189c 469
29ce189c
L
470; ====================================================================
471; Function: Clear drive table
472; ====================================================================
473; Parameters
474; --------------------------------------------------------------------
475; Registers :
476; Variables :
477;
478; --------------------------------------------------------------------
479; Description:
480; ====================================================================
64219415 481
92202636 482; For now, only entries 1 - 7 are cleared.
29ce189c
L
483
484dsk_drvtblinit:
485 ldsw x,biosdrvtbl
486 adiw x,2
92202636 487 ldi temp3,7
29ce189c
L
488dsk_drvi_l:
489 ldi temp,0
490 ldi temp2,0
491 rcall dram_writew_pp
492 dec temp3
493 brne dsk_drvi_l
494
495 lds temp,biosenddat
496 lds temp2,biosenddat+1
497 rcall heap_init
498 clr temp
64219415
FZ
499 ret
500
29ce189c
L
501
502; ----------------------------------------------------------------------
503; Init CP/M data structures
504; temp = drive #
505;
506; return !0 if ok
507; 0 on error
508
509
510dsk_diskinit:
511 mov temp3,temp ;save disk #
512
513
514; Test
515 rcall cpy_dpb
516
517
518
519
520; get mem for DPH
521; -----------------------------------------------------------------
522; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
523; -----------------------------------------------------------------
524;(offset) 0 2 4 6 8 10 12 14
525
526 ldi temp, low (16)
527 ldi temp2,high(16)
528 rcall heap_get
529 brne dsk_di_1
530 rjmp dsk_di_err ;
531dsk_di_1:
532 movw x,temp
533 movw y,temp
534 ldi temp,0
535 ldi temp2,0
536 rcall dram_writew_pp ;XLT
537 adiw x,6
538 lds temp,biosdirbuf
539 lds temp2,biosdirbuf+1
540 rcall dram_writew_pp ;DIRBUF
541
542; get mem for DPB
543; -------------------------------------------------------------
544; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
545; -------------------------------------------------------------
546; 0 5 7 11 13
547
548 ldi temp, low (15)
549 ldi temp2,high(15)
550 rcall heap_get
551 breq dsk_di_err_p1
552 movw x,temp
553
554 ldiw z,tmpdpb
555dsk_dicpl:
556 ld temp,z+
557 rcall dram_write_pp
558 cpi zl,low(tmpdpb + 15)
559 brne dsk_dicpl
560 sbiw x,15
561 movw temp,x
562 movw x,y
563 adiw x,10
564 rcall dram_writew_pp ;DPB
565
566; get mem for dir check vector
567
568 lds temp,tmpdpb+11 ;cks
569 lds temp2,tmpdpb+11+1
570 cp temp,_0
571 cpc temp2,_0
572 breq dsk_dicks0
573 rcall heap_get
574 breq dsk_di_err_p1
575dsk_dicks0:
576 rcall dram_writew_pp ;CSV
577
578; get mem for alloc vector
579
580 lds temp,tmpdpb+5 ;dsm
581 lds temp2,tmpdpb+5+1
582 subi temp, low (-8)
583 sbci temp2,high(-8)
584 lsr temp2
585 ror temp
586 lsr temp2
587 ror temp
588 lsr temp2
589 ror temp ;(dsm+1+7)/8
590 rcall heap_get
591 breq dsk_di_err_p1
592 rcall dram_writew_pp ;ALV
593
594; success, insert DPH into drvtbl
595
596 lds xl,biosdrvtbl
597 lds xh,biosdrvtbl+1
598 lsl temp3 ;drive #
599 add xl,temp3
600 adc xh,_0
601 movw temp,y
602 rcall dram_writew_pp
603 ori temp,0xff ;return ok
64219415
FZ
604 ret
605
29ce189c
L
606; error, free mem
607
608dsk_di_err_p1:
609 movw temp,y
610 rcall heap_release
611dsk_di_err:
612 eor temp,temp ;return 0 (+ Z-flag)
b741422e 613 ret
29ce189c 614
64219415 615
b741422e 616; ====================================================================
64219415 617; Function: Does a Disk interaction
b741422e
L
618; ====================================================================
619; Parameters
620; --------------------------------------------------------------------
621; Registers : none
622; Variables : [r] seeksec Sector to read
623; [r] seektrk Track to read
624; --------------------------------------------------------------------
625; Description:
64219415
FZ
626; ====================================================================
627dskDoIt:
628.if DISK_DEBUG
629 push temp
630 sbrc temp,READ_FUNC
631 rjmp dskdbgr
632 sbrc temp,WRITE_FUNC
633 rjmp dskdbgw
634 rjmp dskdbge
635
636dskdbgr:
637 printnewline
638 printstring "Disk read: "
639 rjmp dskdbg1
640dskdbgw:
641 printnewline
642 printstring "Disk write: "
643dskdbg1:
644 lds temp,seekdsk
645 subi temp,-('A')
646 rcall uartputc
647 printstring ": track "
648 lds temp2,seektrk+1
649 lds temp,seektrk
650 rcall printhexw
651 printstring ", sector "
652 lds temp,seeksec
653 rcall printhex
654 printstring ", dma-addr "
655 lds temp2,dmaadr+1
656 lds temp,dmaadr
657 rcall printhexw
658 pop temp
659 push temp
660 sbrs temp,WRITE_FUNC
661 rjmp dskdbge
662 printstring " wrtype "
663 andi temp,3
664 rcall printhex
665dskdbge:
666 pop temp
667.endif
668 ;See what has to be done.
669 sbrc temp,READ_FUNC
670 rjmp dsk_read
671 sbrc temp,WRITE_FUNC
672 rjmp dsk_write
673 sbrc temp,HOME_FUNC
674 rjmp dsk_home
675 sbrc temp,BOOT_FUNC
676 rjmp dsk_boot
677
678 printstring "DISK I/O: Invalid Function code: "
679 rcall printhex
680 rjmp haltinv
681
682dsk_boot:
683 sts ndisks,_0 ;no active partitions
684dsk_cboot:
685 cbi flags,hostact ;host buffer inactive
686 sts unacnt,_0 ;clear unalloc count
687 ret
688
689dsk_home:
690 sbis flags,hostwrt ;check for pending write
691 cbi flags,hostact ;clear host active flag
692 ret
64219415 693
b741422e
L
694
695
696; ====================================================================
64219415 697; Function: Does a Disk read operation
b741422e
L
698; ====================================================================
699; Parameters
700; --------------------------------------------------------------------
eb85ce65 701; Registers : in: temp
b741422e 702; Variables : [r] seekdsk Number of Disk to Read
1eeb9cbe 703; [r] seeksec Sector to read
b741422e
L
704; [r] seektrk Track to read
705; --------------------------------------------------------------------
706; Description:
64219415
FZ
707; ====================================================================
708dsk_read:
709 sts erflag,_0
b741422e 710 sbi flags,readop ; Set read operation flag
29ce189c 711
eb85ce65 712 ;RAM disk?
1eeb9cbe 713 lds xl,seekdsk
eb85ce65
L
714#if RAMDISKCNT
715 cpi xl,RAMDISKNR
716 brlt PC+2
717 rjmp rdsk_read
718#endif
b741422e 719 rcall dsk_getpartentry ; Get Paritiontableentry
1eeb9cbe 720 ld temp,z ; Get Partitiontype
b741422e
L
721
722; Isn't it a Disk ?
1eeb9cbe 723 cpi temp,dskType_None
b741422e
L
724 brne PC+2
725 rjmp dsk_read_err
b741422e 726; It must be a FAT16-Imagefile or CP/M Partition.
1eeb9cbe
L
727 sts unacnt,_0
728 sbi flags,rsflag ;must read data
729 ldi temp,WRUAL ;write type
730 sts wrtype,temp ;treat as unalloc
b741422e 731 rjmp dsk_rwoper ;to perform the read
64219415 732
b741422e
L
733dsk_read_err:
734 ret
64219415 735
b741422e 736; ====================================================================
64219415 737; Function: Does a Disk write operation
b741422e
L
738; ====================================================================
739; Parameters
740; --------------------------------------------------------------------
eb85ce65 741; Registers : in: temp Write type
1eeb9cbe
L
742; Variables : [r] seekdsk Number of Disk to Read
743; [r] seeksec Sector to read
744; [r] seektrk Track to read
b741422e
L
745; --------------------------------------------------------------------
746; Description:
64219415
FZ
747; ====================================================================
748dsk_write:
749 ;write the selected sector
1eeb9cbe
L
750 sts erflag,_0
751 cbi flags,readop ; not a read operation
eb85ce65 752 ;RAM disk?
1eeb9cbe 753 lds xl,seekdsk
eb85ce65
L
754#if RAMDISKCNT
755 cpi xl,RAMDISKNR
756 brlt PC+2
757 rjmp rdsk_write
758#endif
b741422e 759 rcall dsk_getpartentry ; Get Paritiontableentry
eb85ce65 760 ld temp2,z ; Get Partitiontype
b741422e
L
761
762; Isn't it a Disk ?
eb85ce65 763 cpi temp2,dskType_None
b741422e
L
764 brne PC+2
765 rjmp dsk_write_err
766
1eeb9cbe 767
b741422e 768; It must be a FAT16-Imagefile or CP/M Partition.
64219415 769
1eeb9cbe 770 cbi flags,readop ;not a read operation
64219415
FZ
771
772 andi temp,WRTMSK
1eeb9cbe 773 sts wrtype,temp ;save write type
64219415 774
1eeb9cbe 775 cpi temp,WRUAL ;write unallocated?
64219415
FZ
776 brne dsk_chkuna ;check for unalloc
777
778; write to unallocated, set parameters
779 ldi temp,blksize/128 ;next unalloc recs
780 sts unacnt,temp
781 lds temp,seekdsk ;disk to seek
782 sts unadsk,temp ;unadsk = sekdsk
783 lds temp,seektrk
784 sts unatrk,temp ;unatrk = sectrk
785 lds temp,seektrk+1
786 sts unatrk+1,temp ;unatrk = sectrk
787 lds temp,seeksec
788 sts unasec,temp ;unasec = seksec
789;
790dsk_chkuna:
791 ;check for write to unallocated sector
792 lds temp,unacnt ;any unalloc remain?
793 tst temp
794 breq dsk_alloc ;skip if not
795
796; more unallocated records remain
797 dec temp ;unacnt = unacnt-1
798 sts unacnt,temp
799 lds temp,seekdsk ;same disk?
800 lds temp2,unadsk
801 cp temp,temp2 ;seekdsk = unadsk?
802 brne dsk_alloc ;skip if not
803
804; disks are the same
805 lds temp,unatrk
806 lds temp2,unatrk+1
807 lds temp3,seektrk
808 lds temp4,seektrk+1
809 cp temp,temp3 ;seektrk = unatrk?
810 cpc temp2,temp4
811 brne dsk_alloc ;skip if not
812
813; tracks are the same
814 lds temp,seeksec ;same sector?
815 lds temp2,unasec
816 cp temp,temp2 ;seeksec = unasec?
817 brne dsk_alloc ;skip if not
818
819; match, move to next sector for future ref
820 inc temp2 ;unasec = unasec+1
821 sts unasec,temp2
822 cpi temp2,CPMSPT ;end of track? (count CP/M sectors)
823 brlo dsk_noovf ;skip if no overflow
824
825; overflow to next track
826 sts unasec,_0 ;unasec = 0
827 lds temp,unatrk
828 lds temp2,unatrk+1
829 subi temp, low(-1) ;unatrk = unatrk+1
830 sbci temp2,high(-1)
831 sts unatrk,temp
832 sts unatrk+1,temp2
833;
834dsk_noovf:
835 cbi flags,rsflag ;rsflag = 0
836 rjmp dsk_rwoper ;to perform the write
837;
838dsk_alloc:
839 ;not an unallocated record, requires pre-read
840 sts unacnt,_0 ;unacnt = 0
841 sbi flags,rsflag ;rsflag = 1
b741422e
L
842 rjmp dsk_rwoper
843
844dsk_write_err:
845 ret
846
847; ====================================================================
64219415 848; Function: Does a Disk read/write operation
b741422e
L
849; ====================================================================
850; Parameters
851; --------------------------------------------------------------------
852; Registers : none
853; Variables : [r] seekdsk Number of Disk to Read
854; [r] seeksec Sector to read
855; [r] seektrk Track to read
856; --------------------------------------------------------------------
857; Description:
858; ====================================================================
859dsk_rwoper:
64219415
FZ
860 ;enter here to perform the read/write
861.if DISK_DEBUG
862 printstring ", flags: "
863 in temp,flags
864 rcall printhex
865.endif
866 sts erflag,_0 ;no errors (yet)
867
868 ;Convert track/sector to an LBA address (in 128byte blocks)
869
870 lds xl,seeksec ;
871 ldi xh,0 ;
872 ldi yl,0 ;
873 lds temp3,seektrk ;
874 lds temp4,seektrk+1 ;
875 ldi temp,CPMSPT ;
876 mul temp3,temp ;
877 add xl,r0 ;
878 adc xh,r1 ;
879 mul temp4,temp ;
880 add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack
881 adc yl,r1 ;
882
883 mov temp,xl
884 andi temp,SECMSK ;mask buffer number
885 push temp ;save for later
886
887 ;Convert from CP/M LBA blocks to host LBA blocks
888 ldi temp,SECSHF
889dsk_sh1:
890 lsr yl
891 ror xh
892 ror xl
893 dec temp
894 brne dsk_sh1
895 ;yl:xh:xl = host block to seek
896; active host sector?
897 in _tmp0,flags ;host active flag
898 sbi flags,hostact ;always becomes 1
899 sbrs _tmp0,hostact ;was it already?
900 rjmp dsk_filhst ;fill host if not
901
902; host buffer active, same as seek buffer?
903 lds temp,seekdsk
904 lds temp2,hostdsk ;same disk?
905 cp temp,temp2 ;seekdsk = hostdsk?
906 brne dsk_nomatch
907
908; same disk, same block?
909 lds temp,hostlba
910 lds temp2,hostlba+1
911 lds temp3,hostlba+2
912 cp xl,temp
913 cpc xh,temp2
914 cpc yl,temp3
915 breq dsk_match
916;
917dsk_nomatch:
918 ;proper disk, but not correct sector
919 sbis flags,hostwrt ;host written?
920 rjmp dsk_filhst
921 push xl
922 push xh
923 push yl
924 rcall dsk_writehost ;clear host buff
925 pop yl
926 pop xh
927 pop xl
928
929dsk_filhst:
930 ;may have to fill the host buffer
931 lds temp,seekdsk
932 sts hostdsk,temp
933 sts hostlba,xl
934 sts hostlba+1,xh
935 sts hostlba+2,yl
936
937 sbic flags,rsflag ;need to read?
938 rcall dsk_readhost ;yes, if 1
939 cbi flags,hostwrt ;no pending write
940
941dsk_match:
942
943 ;copy data to or from buffer
944 ldiw z,hostbuf
945 ldi temp,128
946 pop temp2 ;get buffer number (which part of hostbuf)
947 mul temp2,temp
948 add zl,r0 ;offset in hostbuf
b741422e 949 adc zh,r1
64219415
FZ
950
951.if DISK_DEBUG > 2
952 push r0
953 push r1
954 printstring "; host buf adr: "
955 pop temp2
956 pop temp
957 rcall printhexw
958.endif
959
960 lds xl,dmaadr
961 lds xh,dmaadr+1
962 ldi temp3,128 ;length of move
963 sbic flags,readop ;which way?
964 rjmp dsk_rmove ;skip if read
965
966; mark write operation
967 sbi flags,hostwrt ;hostwrt = 1
968dsk_wmove:
969 mem_read
970 st z+,temp
971 adiw xl,1
972 dec temp3
973 brne dsk_wmove
974 rjmp dsk_rwmfin
975
976dsk_rmove:
977 ld temp,z+
978 mem_write
979 adiw xl,1
980 dec temp3
981 brne dsk_rmove
982dsk_rwmfin:
983; data has been moved to/from host buffer
984 lds temp,wrtype ;write type
985 cpi temp,WRDIR ;to directory?
986 breq dsk_wdir
987 ret ;no further processing
988dsk_wdir:
989; clear host buffer for directory write
990 lds temp,erflag
991 tst temp ;errors?
992 breq dsk_wdir1
993 ret ;skip if so
994dsk_wdir1:
995 rcall dsk_writehost ;clear host buff
996 cbi flags,hostwrt ;buffer written
b741422e
L
997 ret
998
999; ====================================================================
64219415 1000; Function: Does a Disk write operation
b741422e
L
1001; ====================================================================
1002; Parameters
1003; --------------------------------------------------------------------
1004; Registers : none
1005; Variables : [r] seekdsk Number of Disk to Read
1006; [r] seeksec Sector to read
1007; [r] seektrk Track to read
1008; --------------------------------------------------------------------
1009; Description:
1010; ====================================================================
1011dsk_writehost:
1012 lds xl,hostdsk
1013 rcall dsk_getpartentry
1014 ld temp,z
1015
1016#if FAT16_SUPPORT
64219415 1017; Is it a FAT16 Diskimage ?
b741422e
L
1018 cpi temp,dskType_FAT
1019 brne PC+2
1020 rjmp fat_writehost
1021#endif
1022
64219415 1023; Is it a CP/M Partition ?
b741422e
L
1024 cpi temp,dskType_CPM
1025 brne PC+2
1026 rjmp cpm_writehost
1027; Disktype not supported -> Return
1028 ret
1029
1030; ====================================================================
64219415 1031; Function: Does a Disk read operation
b741422e
L
1032; ====================================================================
1033; Parameters
1034; --------------------------------------------------------------------
1035; Registers : none
1036; Variables : [r] seekdsk Number of Disk to Read
1037; [r] seeksec Sector to read
1038; [r] seektrk Track to read
1039; --------------------------------------------------------------------
1040; Description:
1041; ====================================================================
1042dsk_readhost:
1043 lds xl,hostdsk
1044 rcall dsk_getpartentry
1045 ld temp,z
1046
1047#if FAT16_SUPPORT
64219415 1048; Is it a FAT16 Diskimage ?
b741422e
L
1049 cpi temp,dskType_FAT
1050 brne PC+2
1051 rjmp fat_readhost
1052#endif
1053
64219415 1054; Is it a CP/M Partition ?
b741422e
L
1055 cpi temp,dskType_CPM
1056 brne PC+2
1057 rjmp cpm_readhost
1058; Disktype not supported -> Return
1059 ret
1060