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