]> cloudbase.mooo.com Git - avrcpm.git/blame - avrcpm/avr/dsk_fsys.asm
* Start of dynamic disk size code.
[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;*****************************************************
eb85ce65 38 .equ MAXDISKS = 6 ;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:
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
390#if 0
391;rd1016
392 .db 0x20,0x00 ;spt
393 .db 0x04,0x0F ;block shift, bock mask
394 .db 0x00,0xFB ;extent mask, low(disk size -1),
395 .db 0x01,0xBF ;high(disk size -1), low(dir max)
396 .db 0x00,0xE0 ;high(dir max), alloc0
397 .db 0x00,0x30 ;alloc1, low(chk size)
398 .db 0x00,0x02 ;high(chk size), low(offset)
399 .db 0x00,0x00 ;high(offset), fill
400;rd9192s
401 .db 0x20,0x00 ;spt
402 .db 0x05,0x1F ;block shift, bock mask
403 .db 0x01,0xFD ;extent mask, low(disk size -1),
404 .db 0x07,0xFF ;high(disk size -1), low(dir max)
405 .db 0x01,0xF0 ;high(dir max), alloc0
406 .db 0x00,0x80 ;alloc1, low(chk size)
407 .db 0x00,0x02 ;high(chk size), low(offset)
408 .db 0x00,0x00 ;high(offset), fill
409#endif
410
411; Test
412cpy_dpb:
413 push zh
414 push zl
415 push yh
416 push yl
417 ldiw z,dpblist*2
418 ldi temp2,16
419 mul temp,temp2
420 add zl,_tmp0
421 adc zh,_tmp1
422 ldiw y,tmpdpb
423cpydpb_l:
424 lpm temp,z+
425 st y+,temp
426 cpi yl,low(tmpdpb + 15)
427 brne cpydpb_l
428 pop yl
429 pop yh
430 pop zl
431 pop zh
64219415 432 ret
29ce189c
L
433
434; clear drive table
435; for now, only entries 1 - 3 are cleared.
436
437; ====================================================================
438; Function: Clear drive table
439; ====================================================================
440; Parameters
441; --------------------------------------------------------------------
442; Registers :
443; Variables :
444;
445; --------------------------------------------------------------------
446; Description:
447; ====================================================================
64219415 448
29ce189c
L
449; For now, only entries 1 - 3 are cleared.
450
451dsk_drvtblinit:
452 ldsw x,biosdrvtbl
453 adiw x,2
454 ldi temp3,3
455dsk_drvi_l:
456 ldi temp,0
457 ldi temp2,0
458 rcall dram_writew_pp
459 dec temp3
460 brne dsk_drvi_l
461
462 lds temp,biosenddat
463 lds temp2,biosenddat+1
464 rcall heap_init
465 clr temp
64219415
FZ
466 ret
467
29ce189c
L
468
469; ----------------------------------------------------------------------
470; Init CP/M data structures
471; temp = drive #
472;
473; return !0 if ok
474; 0 on error
475
476
477dsk_diskinit:
478 mov temp3,temp ;save disk #
479
480
481; Test
482 rcall cpy_dpb
483
484
485
486
487; get mem for DPH
488; -----------------------------------------------------------------
489; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
490; -----------------------------------------------------------------
491;(offset) 0 2 4 6 8 10 12 14
492
493 ldi temp, low (16)
494 ldi temp2,high(16)
495 rcall heap_get
496 brne dsk_di_1
497 rjmp dsk_di_err ;
498dsk_di_1:
499 movw x,temp
500 movw y,temp
501 ldi temp,0
502 ldi temp2,0
503 rcall dram_writew_pp ;XLT
504 adiw x,6
505 lds temp,biosdirbuf
506 lds temp2,biosdirbuf+1
507 rcall dram_writew_pp ;DIRBUF
508
509; get mem for DPB
510; -------------------------------------------------------------
511; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
512; -------------------------------------------------------------
513; 0 5 7 11 13
514
515 ldi temp, low (15)
516 ldi temp2,high(15)
517 rcall heap_get
518 breq dsk_di_err_p1
519 movw x,temp
520
521 ldiw z,tmpdpb
522dsk_dicpl:
523 ld temp,z+
524 rcall dram_write_pp
525 cpi zl,low(tmpdpb + 15)
526 brne dsk_dicpl
527 sbiw x,15
528 movw temp,x
529 movw x,y
530 adiw x,10
531 rcall dram_writew_pp ;DPB
532
533; get mem for dir check vector
534
535 lds temp,tmpdpb+11 ;cks
536 lds temp2,tmpdpb+11+1
537 cp temp,_0
538 cpc temp2,_0
539 breq dsk_dicks0
540 rcall heap_get
541 breq dsk_di_err_p1
542dsk_dicks0:
543 rcall dram_writew_pp ;CSV
544
545; get mem for alloc vector
546
547 lds temp,tmpdpb+5 ;dsm
548 lds temp2,tmpdpb+5+1
549 subi temp, low (-8)
550 sbci temp2,high(-8)
551 lsr temp2
552 ror temp
553 lsr temp2
554 ror temp
555 lsr temp2
556 ror temp ;(dsm+1+7)/8
557 rcall heap_get
558 breq dsk_di_err_p1
559 rcall dram_writew_pp ;ALV
560
561; success, insert DPH into drvtbl
562
563 lds xl,biosdrvtbl
564 lds xh,biosdrvtbl+1
565 lsl temp3 ;drive #
566 add xl,temp3
567 adc xh,_0
568 movw temp,y
569 rcall dram_writew_pp
570 ori temp,0xff ;return ok
64219415
FZ
571 ret
572
29ce189c
L
573; error, free mem
574
575dsk_di_err_p1:
576 movw temp,y
577 rcall heap_release
578dsk_di_err:
579 eor temp,temp ;return 0 (+ Z-flag)
b741422e 580 ret
29ce189c 581
64219415 582
b741422e 583; ====================================================================
64219415 584; Function: Does a Disk interaction
b741422e
L
585; ====================================================================
586; Parameters
587; --------------------------------------------------------------------
588; Registers : none
589; Variables : [r] seeksec Sector to read
590; [r] seektrk Track to read
591; --------------------------------------------------------------------
592; Description:
64219415
FZ
593; ====================================================================
594dskDoIt:
595.if DISK_DEBUG
596 push temp
597 sbrc temp,READ_FUNC
598 rjmp dskdbgr
599 sbrc temp,WRITE_FUNC
600 rjmp dskdbgw
601 rjmp dskdbge
602
603dskdbgr:
604 printnewline
605 printstring "Disk read: "
606 rjmp dskdbg1
607dskdbgw:
608 printnewline
609 printstring "Disk write: "
610dskdbg1:
611 lds temp,seekdsk
612 subi temp,-('A')
613 rcall uartputc
614 printstring ": track "
615 lds temp2,seektrk+1
616 lds temp,seektrk
617 rcall printhexw
618 printstring ", sector "
619 lds temp,seeksec
620 rcall printhex
621 printstring ", dma-addr "
622 lds temp2,dmaadr+1
623 lds temp,dmaadr
624 rcall printhexw
625 pop temp
626 push temp
627 sbrs temp,WRITE_FUNC
628 rjmp dskdbge
629 printstring " wrtype "
630 andi temp,3
631 rcall printhex
632dskdbge:
633 pop temp
634.endif
635 ;See what has to be done.
636 sbrc temp,READ_FUNC
637 rjmp dsk_read
638 sbrc temp,WRITE_FUNC
639 rjmp dsk_write
640 sbrc temp,HOME_FUNC
641 rjmp dsk_home
642 sbrc temp,BOOT_FUNC
643 rjmp dsk_boot
644
645 printstring "DISK I/O: Invalid Function code: "
646 rcall printhex
647 rjmp haltinv
648
649dsk_boot:
650 sts ndisks,_0 ;no active partitions
651dsk_cboot:
652 cbi flags,hostact ;host buffer inactive
653 sts unacnt,_0 ;clear unalloc count
654 ret
655
656dsk_home:
657 sbis flags,hostwrt ;check for pending write
658 cbi flags,hostact ;clear host active flag
659 ret
64219415 660
b741422e
L
661
662
663; ====================================================================
64219415 664; Function: Does a Disk read operation
b741422e
L
665; ====================================================================
666; Parameters
667; --------------------------------------------------------------------
eb85ce65 668; Registers : in: temp
b741422e 669; Variables : [r] seekdsk Number of Disk to Read
1eeb9cbe 670; [r] seeksec Sector to read
b741422e
L
671; [r] seektrk Track to read
672; --------------------------------------------------------------------
673; Description:
64219415
FZ
674; ====================================================================
675dsk_read:
676 sts erflag,_0
b741422e 677 sbi flags,readop ; Set read operation flag
29ce189c 678
eb85ce65 679 ;RAM disk?
1eeb9cbe 680 lds xl,seekdsk
eb85ce65
L
681#if RAMDISKCNT
682 cpi xl,RAMDISKNR
683 brlt PC+2
684 rjmp rdsk_read
685#endif
b741422e 686 rcall dsk_getpartentry ; Get Paritiontableentry
1eeb9cbe 687 ld temp,z ; Get Partitiontype
b741422e
L
688
689; Isn't it a Disk ?
1eeb9cbe 690 cpi temp,dskType_None
b741422e
L
691 brne PC+2
692 rjmp dsk_read_err
29ce189c 693
b741422e 694; It must be a FAT16-Imagefile or CP/M Partition.
1eeb9cbe
L
695 sts unacnt,_0
696 sbi flags,rsflag ;must read data
697 ldi temp,WRUAL ;write type
698 sts wrtype,temp ;treat as unalloc
b741422e 699 rjmp dsk_rwoper ;to perform the read
64219415 700
b741422e
L
701dsk_read_err:
702 ret
64219415 703
b741422e 704; ====================================================================
64219415 705; Function: Does a Disk write operation
b741422e
L
706; ====================================================================
707; Parameters
708; --------------------------------------------------------------------
eb85ce65 709; Registers : in: temp Write type
1eeb9cbe
L
710; Variables : [r] seekdsk Number of Disk to Read
711; [r] seeksec Sector to read
712; [r] seektrk Track to read
b741422e
L
713; --------------------------------------------------------------------
714; Description:
64219415
FZ
715; ====================================================================
716dsk_write:
717 ;write the selected sector
1eeb9cbe
L
718 sts erflag,_0
719 cbi flags,readop ; not a read operation
eb85ce65 720 ;RAM disk?
1eeb9cbe 721 lds xl,seekdsk
eb85ce65
L
722#if RAMDISKCNT
723 cpi xl,RAMDISKNR
724 brlt PC+2
725 rjmp rdsk_write
726#endif
b741422e 727 rcall dsk_getpartentry ; Get Paritiontableentry
eb85ce65 728 ld temp2,z ; Get Partitiontype
b741422e
L
729
730; Isn't it a Disk ?
eb85ce65 731 cpi temp2,dskType_None
b741422e
L
732 brne PC+2
733 rjmp dsk_write_err
734
1eeb9cbe 735
b741422e 736; It must be a FAT16-Imagefile or CP/M Partition.
64219415 737
1eeb9cbe 738 cbi flags,readop ;not a read operation
64219415
FZ
739
740 andi temp,WRTMSK
1eeb9cbe 741 sts wrtype,temp ;save write type
64219415 742
1eeb9cbe 743 cpi temp,WRUAL ;write unallocated?
64219415
FZ
744 brne dsk_chkuna ;check for unalloc
745
746; write to unallocated, set parameters
747 ldi temp,blksize/128 ;next unalloc recs
748 sts unacnt,temp
749 lds temp,seekdsk ;disk to seek
750 sts unadsk,temp ;unadsk = sekdsk
751 lds temp,seektrk
752 sts unatrk,temp ;unatrk = sectrk
753 lds temp,seektrk+1
754 sts unatrk+1,temp ;unatrk = sectrk
755 lds temp,seeksec
756 sts unasec,temp ;unasec = seksec
757;
758dsk_chkuna:
759 ;check for write to unallocated sector
760 lds temp,unacnt ;any unalloc remain?
761 tst temp
762 breq dsk_alloc ;skip if not
763
764; more unallocated records remain
765 dec temp ;unacnt = unacnt-1
766 sts unacnt,temp
767 lds temp,seekdsk ;same disk?
768 lds temp2,unadsk
769 cp temp,temp2 ;seekdsk = unadsk?
770 brne dsk_alloc ;skip if not
771
772; disks are the same
773 lds temp,unatrk
774 lds temp2,unatrk+1
775 lds temp3,seektrk
776 lds temp4,seektrk+1
777 cp temp,temp3 ;seektrk = unatrk?
778 cpc temp2,temp4
779 brne dsk_alloc ;skip if not
780
781; tracks are the same
782 lds temp,seeksec ;same sector?
783 lds temp2,unasec
784 cp temp,temp2 ;seeksec = unasec?
785 brne dsk_alloc ;skip if not
786
787; match, move to next sector for future ref
788 inc temp2 ;unasec = unasec+1
789 sts unasec,temp2
790 cpi temp2,CPMSPT ;end of track? (count CP/M sectors)
791 brlo dsk_noovf ;skip if no overflow
792
793; overflow to next track
794 sts unasec,_0 ;unasec = 0
795 lds temp,unatrk
796 lds temp2,unatrk+1
797 subi temp, low(-1) ;unatrk = unatrk+1
798 sbci temp2,high(-1)
799 sts unatrk,temp
800 sts unatrk+1,temp2
801;
802dsk_noovf:
803 cbi flags,rsflag ;rsflag = 0
804 rjmp dsk_rwoper ;to perform the write
805;
806dsk_alloc:
807 ;not an unallocated record, requires pre-read
808 sts unacnt,_0 ;unacnt = 0
809 sbi flags,rsflag ;rsflag = 1
b741422e
L
810 rjmp dsk_rwoper
811
812dsk_write_err:
813 ret
814
815; ====================================================================
64219415 816; Function: Does a Disk read/write operation
b741422e
L
817; ====================================================================
818; Parameters
819; --------------------------------------------------------------------
820; Registers : none
821; Variables : [r] seekdsk Number of Disk to Read
822; [r] seeksec Sector to read
823; [r] seektrk Track to read
824; --------------------------------------------------------------------
825; Description:
826; ====================================================================
827dsk_rwoper:
64219415
FZ
828 ;enter here to perform the read/write
829.if DISK_DEBUG
830 printstring ", flags: "
831 in temp,flags
832 rcall printhex
833.endif
834 sts erflag,_0 ;no errors (yet)
835
836 ;Convert track/sector to an LBA address (in 128byte blocks)
837
838 lds xl,seeksec ;
839 ldi xh,0 ;
840 ldi yl,0 ;
841 lds temp3,seektrk ;
842 lds temp4,seektrk+1 ;
843 ldi temp,CPMSPT ;
844 mul temp3,temp ;
845 add xl,r0 ;
846 adc xh,r1 ;
847 mul temp4,temp ;
848 add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack
849 adc yl,r1 ;
850
851 mov temp,xl
852 andi temp,SECMSK ;mask buffer number
853 push temp ;save for later
854
855 ;Convert from CP/M LBA blocks to host LBA blocks
856 ldi temp,SECSHF
857dsk_sh1:
858 lsr yl
859 ror xh
860 ror xl
861 dec temp
862 brne dsk_sh1
863 ;yl:xh:xl = host block to seek
864; active host sector?
865 in _tmp0,flags ;host active flag
866 sbi flags,hostact ;always becomes 1
867 sbrs _tmp0,hostact ;was it already?
868 rjmp dsk_filhst ;fill host if not
869
870; host buffer active, same as seek buffer?
871 lds temp,seekdsk
872 lds temp2,hostdsk ;same disk?
873 cp temp,temp2 ;seekdsk = hostdsk?
874 brne dsk_nomatch
875
876; same disk, same block?
877 lds temp,hostlba
878 lds temp2,hostlba+1
879 lds temp3,hostlba+2
880 cp xl,temp
881 cpc xh,temp2
882 cpc yl,temp3
883 breq dsk_match
884;
885dsk_nomatch:
886 ;proper disk, but not correct sector
887 sbis flags,hostwrt ;host written?
888 rjmp dsk_filhst
889 push xl
890 push xh
891 push yl
892 rcall dsk_writehost ;clear host buff
893 pop yl
894 pop xh
895 pop xl
896
897dsk_filhst:
898 ;may have to fill the host buffer
899 lds temp,seekdsk
900 sts hostdsk,temp
901 sts hostlba,xl
902 sts hostlba+1,xh
903 sts hostlba+2,yl
904
905 sbic flags,rsflag ;need to read?
906 rcall dsk_readhost ;yes, if 1
907 cbi flags,hostwrt ;no pending write
908
909dsk_match:
910
911 ;copy data to or from buffer
912 ldiw z,hostbuf
913 ldi temp,128
914 pop temp2 ;get buffer number (which part of hostbuf)
915 mul temp2,temp
916 add zl,r0 ;offset in hostbuf
b741422e 917 adc zh,r1
64219415
FZ
918
919.if DISK_DEBUG > 2
920 push r0
921 push r1
922 printstring "; host buf adr: "
923 pop temp2
924 pop temp
925 rcall printhexw
926.endif
927
928 lds xl,dmaadr
929 lds xh,dmaadr+1
930 ldi temp3,128 ;length of move
931 sbic flags,readop ;which way?
932 rjmp dsk_rmove ;skip if read
933
934; mark write operation
935 sbi flags,hostwrt ;hostwrt = 1
936dsk_wmove:
937 mem_read
938 st z+,temp
939 adiw xl,1
940 dec temp3
941 brne dsk_wmove
942 rjmp dsk_rwmfin
943
944dsk_rmove:
945 ld temp,z+
946 mem_write
947 adiw xl,1
948 dec temp3
949 brne dsk_rmove
950dsk_rwmfin:
951; data has been moved to/from host buffer
952 lds temp,wrtype ;write type
953 cpi temp,WRDIR ;to directory?
954 breq dsk_wdir
955 ret ;no further processing
956dsk_wdir:
957; clear host buffer for directory write
958 lds temp,erflag
959 tst temp ;errors?
960 breq dsk_wdir1
961 ret ;skip if so
962dsk_wdir1:
963 rcall dsk_writehost ;clear host buff
964 cbi flags,hostwrt ;buffer written
b741422e
L
965 ret
966
967; ====================================================================
64219415 968; Function: Does a Disk write operation
b741422e
L
969; ====================================================================
970; Parameters
971; --------------------------------------------------------------------
972; Registers : none
973; Variables : [r] seekdsk Number of Disk to Read
974; [r] seeksec Sector to read
975; [r] seektrk Track to read
976; --------------------------------------------------------------------
977; Description:
978; ====================================================================
979dsk_writehost:
980 lds xl,hostdsk
981 rcall dsk_getpartentry
982 ld temp,z
983
984#if FAT16_SUPPORT
64219415 985; Is it a FAT16 Diskimage ?
b741422e
L
986 cpi temp,dskType_FAT
987 brne PC+2
988 rjmp fat_writehost
989#endif
990
64219415 991; Is it a CP/M Partition ?
b741422e
L
992 cpi temp,dskType_CPM
993 brne PC+2
994 rjmp cpm_writehost
995; Disktype not supported -> Return
996 ret
997
998; ====================================================================
64219415 999; Function: Does a Disk read operation
b741422e
L
1000; ====================================================================
1001; Parameters
1002; --------------------------------------------------------------------
1003; Registers : none
1004; Variables : [r] seekdsk Number of Disk to Read
1005; [r] seeksec Sector to read
1006; [r] seektrk Track to read
1007; --------------------------------------------------------------------
1008; Description:
1009; ====================================================================
1010dsk_readhost:
1011 lds xl,hostdsk
1012 rcall dsk_getpartentry
1013 ld temp,z
1014
1015#if FAT16_SUPPORT
64219415 1016; Is it a FAT16 Diskimage ?
b741422e
L
1017 cpi temp,dskType_FAT
1018 brne PC+2
1019 rjmp fat_readhost
1020#endif
1021
64219415 1022; Is it a CP/M Partition ?
b741422e
L
1023 cpi temp,dskType_CPM
1024 brne PC+2
1025 rjmp cpm_readhost
1026; Disktype not supported -> Return
1027 ret
1028