]> cloudbase.mooo.com Git - avrcpm.git/blame - avr/dsk_fsys.asm
* FAT buffer on ATmega328
[avrcpm.git] / 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
23
64219415
FZ
24; ---------------- Defines for the Filesystem Interface -------
25
64219415
FZ
26;*****************************************************
27;* Disk-Manager constants *
28;*****************************************************
dd7aea8c
L
29
30; Fields in the parttabl
31
96a054ef 32 .equ MAXDISKS = 8 ;Max number of Disks (partitions)
dd7aea8c
L
33 .equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry
34
35 .equ PTAB_TYPE = 0
36 .equ PTAB_START = 1
37 .equ PTAB_SIZE = 5
38 .equ PTAB_SPT = 7
39 .equ PTAB_BSH = 8
40
41 .equ dskType_None = 0 << 4
42 .equ dskType_CPM = 1 << 4
43 .equ dskType_FAT = 2 << 4
44; .equ dskType_RAM = 3 << 4
45 .equ dskType_MASK = 0xf << 4
64219415
FZ
46
47;*****************************************************
48;* CP/M to host disk constants *
49;*****************************************************
dd7aea8c
L
50; .equ blksize = 1024 ;CP/M allocation size
51; .equ CPMSPT = 26 ;
52
53 .equ HOSTSIZE = 512 ;host disk sector size
54 .equ HOSTBLK = HOSTSIZE/128 ;CP/M sects/host buff
55 .equ SECMSK = HOSTBLK-1 ;sector mask
56 .equ SECSHF = log2(HOSTBLK) ;sector shift
64219415
FZ
57
58;*****************************************************
59;* BDOS constants on entry to write *
60;*****************************************************
61 .equ WRALL = 0 ;write to allocated
62 .equ WRDIR = 1 ;write to directory
63 .equ WRUAL = 2 ;write to unallocated
b741422e 64 .equ WRTMSK= 3 ;write type mask
eb85ce65 65
64219415
FZ
66;----------------------------------------------- Start of Data Segment
67
b741422e
L
68 .dseg
69
6cb1222d
L
70fsys_vars:
71
29ce189c
L
72; The following 3 variables are copied from DRAM.
73; Don't change order.
74
75biosdrvtbl: .byte 2 ;
76biosdirbuf: .byte 2 ;
77biosenddat: .byte 2 ;
78
79ndisks: .byte 1 ;Number of CP/M disks
6cb1222d 80 .equ o_ndisks = ndisks-fsys_vars
64219415 81
29ce189c
L
82; The following 5 variables are accessed from 8080/z80 via the
83; virtual port interface. Don't change order.
64219415 84
29ce189c
L
85biospar_base:
86bcbadr: .byte 2 ;adr of BiosControlBlock
87seekdsk: .byte 1 ;seek disk number
88seektrk: .byte 2 ;seek track number
89seeksec: .byte 2 ;seek sector number
90dmaadr: .byte 2 ;last dma address
6cb1222d
L
91 .equ o_bcbadr = bcbadr-fsys_vars
92 .equ o_seekdsk = seekdsk-fsys_vars
93 .equ o_seektrk = seektrk-fsys_vars
94 .equ o_seeksec = seeksec-fsys_vars
95 .equ o_dmaadr = dmaadr-fsys_vars
64219415 96
dd7aea8c
L
97hdrsize: .byte 1 ;Image header size (offset)
98cpmspt: .byte 1 ;CP/M sectors per track
99secpblk: .byte 1 ;sectors per block (alloc size)
29ce189c
L
100unacnt: .byte 1 ;unalloc rec cnt
101unadsk: .byte 1 ;last unalloc disk
2ccaac16 102unalba: .byte 2 ;last unalloc disk block
6cb1222d
L
103 .equ o_hdrsize = hdrsize-fsys_vars
104 .equ o_cpmspt = cpmspt-fsys_vars
105 .equ o_secpblk = secpblk-fsys_vars
106 .equ o_unacnt = unacnt-fsys_vars
107 .equ o_unadsk = unadsk-fsys_vars
108 .equ o_unalba = unalba-fsys_vars
64219415 109
29ce189c
L
110erflag: .byte 1 ;error reporting
111wrtype: .byte 1 ;write operation type
6cb1222d
L
112 .equ o_erflag = erflag-fsys_vars
113 .equ o_wrtype = wrtype-fsys_vars
29ce189c 114
29ce189c 115hostdsk: .byte 1 ;host disk number
5482d75f 116hostlba: .byte 2 ;host sector number (relative to partition start)
6cb1222d
L
117 .equ o_hostdsk = hostdsk-fsys_vars
118 .equ o_hostlba = hostlba-fsys_vars
119
dd7aea8c
L
120hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
121hostparttbltop:
122hostbuf: .byte HOSTSIZE ;host buffer (from/to SD-card)
b741422e
L
123
124
64219415 125; ------------------------------- Start of Code Segment
b741422e
L
126 .cseg
127
29ce189c
L
128;---------------------------------------------------------------------
129
130.if DSKSEL_DEBUG
131
132dbg_prdrvtbl:
133 push xh
134 push xl
135 push temp3
136 push temp2
137 push temp
138 printnewline
139 printstring "drvtbl ("
6cb1222d 140 ldsw x,biosdrvtbl
29ce189c 141 movw temp,x
2ccaac16 142 lcall printhexw
29ce189c
L
143 printstring "): "
144 ldi temp3,16
145dbg_pcpel:
2ccaac16
L
146 lcall dram_readw_pp
147 lcall printhexw
29ce189c
L
148 printstring " "
149 dec temp3
150 brne dbg_pcpel
151 pop temp
152 pop temp2
153 pop temp3
154 pop xl
155 pop xh
156 ret
157
158dbg_print_biosd:
159 printnewline
160 lds temp,bcbadr
161 lds temp2,bcbadr+1
2ccaac16 162 lcall printhexw
29ce189c
L
163 printstring " "
164 lds temp,biosdrvtbl
165 lds temp2,biosdrvtbl+1
2ccaac16 166 lcall printhexw
29ce189c
L
167 printstring " "
168 lds temp,biosdirbuf
169 lds temp2,biosdirbuf+1
2ccaac16 170 lcall printhexw
29ce189c
L
171 printstring " "
172 lds temp,biosenddat
173 lds temp2,biosenddat+1
2ccaac16 174 lcall printhexw
29ce189c
L
175 printstring " "
176 ret
177.endif
178
5482d75f 179; ====================================================================
b741422e 180; ====================================================================
1eeb9cbe 181; Function: Get a Pointer to a Partitiontable entry
b741422e
L
182; ====================================================================
183; Parameters
184; --------------------------------------------------------------------
825ecc9d
L
185; Registers : [w] z Pointer to the Partitionentry
186; [r] zl Number of Diskentry to Read
187; [w] r0 scratch
188; [w] r1 "
b741422e
L
189; --------------------------------------------------------------------
190; Description:
191; ====================================================================
1eeb9cbe
L
192dsk_getpartentry:
193
dd7aea8c
L
194 ldi zh,PARTENTRY_SIZE
195 mul zh,zl
1eeb9cbe 196 ldiw z,hostparttbl
825ecc9d
L
197 add zl,r0
198 adc zh,r1
64219415 199 ret
b741422e 200
5482d75f 201; ====================================================================
1eeb9cbe 202; ====================================================================
29ce189c 203; Function: Virtual Port Interface
1eeb9cbe
L
204; ====================================================================
205; Parameters
206; --------------------------------------------------------------------
29ce189c
L
207; Registers :
208; Variables :
209;
210; --------------------------------------------------------------------
211; Description:
212; ====================================================================
213
214dsk_param_getadr:
215 ldiw z,biospar_base
216 add zl,temp3
217 adc zh,_0
218 ret
219
5482d75f 220dsk_param_set:
29ce189c
L
221 rcall dsk_param_getadr
222 st z,temp
29ce189c
L
223 cpi temp3,bcbadr+1-biospar_base
224 breq SetBCB
225 ret
226
5482d75f 227dsk_param_get:
29ce189c
L
228 cpi temp3,seekdsk-biospar_base
229 breq dskDiskCheck
230 rcall dsk_param_getadr
231 ld temp,z
232 ret
233
234SetBCB:
235 lds xl,bcbadr
236 mov xh,temp
237 ldiw z,biosdrvtbl
238 ldi temp3,6
239sbcb_l:
240 rcall dram_read_pp
241 st z+,temp
242 dec temp3
243 brne sbcb_l
244
245; rcall dbg_print_biosd
5482d75f 246 rcall dpb_drvtblclear
29ce189c
L
247; rcall dbg_prdrvtbl
248
249 ret
250
251; ====================================================================
252; Function: Check if disk exists
253; ====================================================================
254; Parameters
255; --------------------------------------------------------------------
256; Registers :
257; Variables :
258; return 0, if selected disk not exist.
259; return !0, if disk exist
1eeb9cbe
L
260; --------------------------------------------------------------------
261; Description:
262; ====================================================================
64219415 263dskDiskCheck:
637689de
L
264 lds temp2,ndisks
265 lds temp,seekdsk
29ce189c
L
266.if DSKSEL_DEBUG
267 printnewline
268 printstring "DiskCheck: "
2ccaac16 269 lcall printhexw
29ce189c 270.endif
637689de 271 cpi temp,RAMDISKNR
64219415
FZ
272 brsh dsk_dchrd ;maybe ramdisk
273
637689de 274 tst temp2 ;0 disks?
64219415
FZ
275 brne dsk_dchpart1
276
eb85ce65 277; No disks yet, need to init
64219415 278
5482d75f
L
279 rcall dpb_drvtblclear
280.if 0
281 ldi temp2,0x40
282 ldi temp,1
283 lcall clockput
284.endif
29ce189c 285 rcall mgr_init_partitions ;disk chanched?
5482d75f
L
286 push temp
287.if 0
288 ldi temp2,0x40
289 ldi temp,2
290 lcall clockput
29ce189c
L
291; sbrs temp,7
292; rjmp dsk_dchpart0
5482d75f
L
293
294 lcall mgr_prnt_parttbl
295 printnewline
296.endif
297
29ce189c 298; rcall dbg_prdrvtbl
637689de 299 pop temp2
29ce189c 300dsk_dchpart0:
637689de
L
301 cbr temp2,0x80
302 lds temp,seekdsk
64219415 303
5482d75f
L
304; Check if selected disk # is less then # of disks.
305
64219415 306dsk_dchpart1:
637689de 307 cp temp,temp2
29ce189c
L
308 brsh dsk_dch_err
309
310.if DSKSEL_DEBUG
311 printnewline
312 printstring "Select: "
2ccaac16 313 lcall printhex
29ce189c 314.endif
637689de 315 rcall dpb_drvtbl_entry_get
29ce189c
L
316 or temp,temp2 ;if !0, drive is allready initialized
317 brne dsk_dchend
5482d75f
L
318 lds temp3,seekdsk
319 mov temp,temp3
320 rcall dpb_biosdph_get
64219415 321dsk_dchend:
5482d75f 322
29ce189c
L
323.if DSKSEL_DEBUG
324 push temp
29ce189c 325 lds temp,seekdsk
637689de
L
326 rcall dpb_drvtbl_entry_get
327
29ce189c 328 printstring ", "
2ccaac16 329 lcall printhexw
29ce189c
L
330 pop temp
331.endif
332
64219415
FZ
333 ret
334
29ce189c
L
335dsk_dch_err:
336 ldi temp,0 ;error return
337 ret
338
339; Check RAMDISK
340
64219415
FZ
341dsk_dchrd:
342#if RAMDISKCNT
29ce189c
L
343 cpi temp,RAMDISKNR+RAMDISKCNT
344 brsh dsk_dchrd_err
345
346 ldi temp,0xff ;return ok
347 ret
64219415 348#endif
29ce189c
L
349dsk_dchrd_err:
350 ldi temp,0 ;error return
64219415 351 ret
29ce189c
L
352
353
354; ====================================================================
355; Function: Return status of last disk i/o function
356; ====================================================================
357; Parameters
358; --------------------------------------------------------------------
359; Registers :
360; Variables :
361; --------------------------------------------------------------------
362; Description:
363; ====================================================================
6cb1222d 364
64219415 365dskErrorRet:
29ce189c 366 lds temp,erflag
64219415
FZ
367 ret
368
29ce189c 369
5482d75f
L
370; ====================================================================
371; ====================================================================
64219415 372
64219415 373
29ce189c 374
dcd7e502
L
375str_CPM_Disk:
376 .db 10,"<CPM_Disk>",0
377
dd7aea8c
L
378; DPBs for varios fixed formats
379; dpb data starts at 2. byte
380
381dpbdat_avrcpm: ;(dpb243)
382 .db 0x00,0x1A ;sector offset, low(spt)
383 .db 0x00,0x03 ;high (spt), block shift
384 .db 0x07,0x00 ;bock mask, extent mask
385 .db 0xF2,0x00 ;disk size - 1,
386 .db 0x3F,0x00 ;dir max
387 .db 0xC0,0x00 ;alloc0, alloc1
388 .db 0x10,0x00 ;chk size
389 .db 0x02,0x00 ;offset
390
dd7aea8c
L
391dpbdat_myz80: ;
392 .db 0x02,0x80 ;sector offset, low(spt)
393 .db 0x00,0x05 ;high (spt), block shift
394 .db 0x1F,0x01 ;bock mask, extent mask
395 .db 0xFF,0x07 ;disk size - 1,
396 .db 0xFF,0x03 ;dir max
397 .db 0xFF,0x00 ;alloc0, alloc1
398 .db 0x00,0x01 ;chk size
399 .db 0x00,0x00 ;offset
29ce189c 400
b165699b
L
401dpbdat_simhd: ;
402 .db 0x00,0x20 ;sector offset, low(spt)
403 .db 0x00,0x05 ;high (spt), block shift
404 .db 0x1F,0x01 ;bock mask, extent mask
405 .db 0xF9,0x07 ;disk size - 1,
406 .db 0xFF,0x03 ;dir max
407 .db 0xFF,0x00 ;alloc0, alloc1
408 .db 0x00,0x01 ;chk size
409 .db 0x06,0x00 ;offset
410
29ce189c
L
411#if 0
412;rd1016
413 .db 0x20,0x00 ;spt
414 .db 0x04,0x0F ;block shift, bock mask
415 .db 0x00,0xFB ;extent mask, low(disk size -1),
416 .db 0x01,0xBF ;high(disk size -1), low(dir max)
417 .db 0x00,0xE0 ;high(dir max), alloc0
418 .db 0x00,0x30 ;alloc1, low(chk size)
419 .db 0x00,0x02 ;high(chk size), low(offset)
420 .db 0x00,0x00 ;high(offset), fill
421;rd9192s
422 .db 0x20,0x00 ;spt
423 .db 0x05,0x1F ;block shift, bock mask
424 .db 0x01,0xFD ;extent mask, low(disk size -1),
425 .db 0x07,0xFF ;high(disk size -1), low(dir max)
426 .db 0x01,0xF0 ;high(dir max), alloc0
427 .db 0x00,0x80 ;alloc1, low(chk size)
428 .db 0x00,0x02 ;high(chk size), low(offset)
429 .db 0x00,0x00 ;high(offset), fill
430#endif
431
dd7aea8c 432
dd7aea8c 433
637689de
L
434; ====================================================================
435; Function: get drive table entry pointer for drive # in temp
436; ====================================================================
437; Parameters
438; --------------------------------------------------------------------
439; Registers :
440; Variables :
441;
442; --------------------------------------------------------------------
443; Description:
444; ====================================================================
445
446dpb_drvtbl_entry_p:
447
448 ldsw x,biosdrvtbl
449 lsl temp ;drive #
450 add xl,temp
451 adc xh,_0
452 ret
453
454
455; ====================================================================
456; Function: get drive table entry for drive # in temp
457; ====================================================================
458; Parameters
459; --------------------------------------------------------------------
460; Registers :
461; Variables :
462;
463; --------------------------------------------------------------------
464; Description:
465; ====================================================================
466
467dpb_drvtbl_entry_get:
468
469 rcall dpb_drvtbl_entry_p
470 ljmp dram_readw_pp
471
472
29ce189c 473; ====================================================================
dd7aea8c 474; Function: Clear drive table (entries 0 to 7)
29ce189c
L
475; ====================================================================
476; Parameters
477; --------------------------------------------------------------------
478; Registers :
479; Variables :
480;
481; --------------------------------------------------------------------
482; Description:
483; ====================================================================
64219415 484
dd7aea8c 485;
29ce189c 486
5482d75f 487dpb_drvtblclear:
29ce189c 488 ldsw x,biosdrvtbl
5482d75f
L
489 sbiw x,0
490 breq dpb_drvi_ex
491
492dpb_drvi_1:
dd7aea8c 493 ldi temp3,8
5482d75f 494dpb_drvi_lp:
29ce189c
L
495 ldi temp,0
496 ldi temp2,0
497 rcall dram_writew_pp
498 dec temp3
5482d75f 499 brne dpb_drvi_lp
29ce189c
L
500
501 lds temp,biosenddat
502 lds temp2,biosenddat+1
5482d75f
L
503 cp temp,_0
504 cpc temp2,_0
505 breq dpb_drvi_ex
506
29ce189c 507 rcall heap_init
5482d75f 508dpb_drvi_ex:
29ce189c 509 clr temp
64219415
FZ
510 ret
511
dd7aea8c 512; ====================================================================
5482d75f 513; Function: Test disk format: avrcpmhd
dd7aea8c
L
514; ====================================================================
515; Parameters
516; --------------------------------------------------------------------
517; Registers : temp drive #
518;
519; --------------------------------------------------------------------
5482d75f 520; Description: Not implemented yet.
dd7aea8c
L
521; ====================================================================
522
523dsk_tst_avrcpmhd:
5482d75f 524 clr temp ; Test, return 'not found' for now.
dd7aea8c
L
525 ret
526
527
528; ====================================================================
529; Function: Test disk format: YAZE
530; ====================================================================
531; Parameters
532; --------------------------------------------------------------------
533; Registers : temp drive #
534;
535; --------------------------------------------------------------------
536; Description: From the YAZE Doc:
537;
538; The new disk header occupies the first 128 BYTES of the file and has the
539; new format:
540;
541; 0 - 9 <CPM_Disk>
542; 10 - 15 a null-terminated ascii comment (may be empty)
543; new 16 version (0 = yaze-1.06/1.10, 1 = yaze-ag-2.xx)
544; 17 - 31 a null-terminated ascii comment (may be empty)
545; 32 - 33 sectors per track
546; 34 block shift factor
547; 35 block mask
548; 36 extent mask
549; 37 - 38 disk size max
550; 39 - 40 directory max
551; 41 al0
552; 42 al1
553; 43 - 44 check size (always zero)
554; 45 - 46 track offset
555; new 47 psh (used if version=1 and CP/M 3.1 is running)
556; new 48 phm ( " " " " " " " " " )
557; 49 - 127 unused (zeros)
558; ====================================================================
559
560
dd7aea8c
L
561dsk_tst_yaze:
562
563 ldiw y,hostbuf
dcd7e502 564 ldiw z,str_CPM_Disk*2
dd7aea8c 565 lpm temp2,z+ ; get length
623dd899 566 lcall strncmp_p
dd7aea8c
L
567 brne dsk_tyze_not
568
02d57479
L
569 ldiw z,hostbuf+31
570 clt ;dpb in RAM
dd7aea8c 571 ldi temp,1 ;1 sector header size
02d57479 572 st z,temp
dd7aea8c 573
5482d75f 574 ori temp,0xff
dd7aea8c
L
575 ret
576
577dsk_tyze_not:
5482d75f 578 clr temp ;Not a YAZE disk image.
dd7aea8c 579 ret
29ce189c 580
dd7aea8c
L
581; ====================================================================
582; Function: Test disk format: MyZ80
583; ====================================================================
584; Parameters
585; --------------------------------------------------------------------
586; Registers : temp drive #
587;
588; --------------------------------------------------------------------
589; Description: Test, if first 2 Sectors are filled with 0xE5,
b165699b 590; and Size = 8192KB + 256Bytes.
dd7aea8c 591; ====================================================================
6cb1222d 592
dd7aea8c
L
593dsk_tst_myz80:
594
595 mov zl,temp3
596 rcall dsk_getpartentry ;get partition entry
597 ldd temp,z+PTAB_SIZE
b165699b
L
598 ldd temp2,z+PTAB_SIZE+1 ;check, if size is 16385 phys. sectors
599 cpi temp,low(16385)
600 ldi temp,high(16385)
dd7aea8c
L
601 cpc temp2,temp
602 brne dsk_tmyz80_not ;wrong size
603
604 ldiw z,hostbuf
605 ldi temp2,0
606
607dsk_tmyz80_loop:
608 ld temp,z+
609 cpi temp,0xE5
610 brne dsk_tmyz80_not
611 dec temp2
612 brne dsk_tmyz80_loop
613
02d57479
L
614 ldiw z,dpbdat_myz80*2
615 set
5482d75f 616 ori temp,0xff
dd7aea8c
L
617 ret
618
619dsk_tmyz80_not:
5482d75f 620 clr temp ;Not a MyZ80 hard disk image.
dd7aea8c
L
621 ret
622
b165699b
L
623; ====================================================================
624; Function: Test disk format: simhd, simh altair 8800 hard disk format
625; ====================================================================
626; Parameters
627; --------------------------------------------------------------------
628; Registers : temp drive #
629;
630; --------------------------------------------------------------------
dcd7e502
L
631; Description: Test, if Size = 8192 KB and
632; first 6 tracks are filled with 0xE5.
b165699b
L
633; Actually, only the first phys. sector is tested, since
634; the other 47 sectors are not in memory at this time.
635; ====================================================================
6cb1222d 636
b165699b
L
637dsk_tst_simhd:
638
639 mov zl,temp3
640 rcall dsk_getpartentry ;get partition entry
641 ldd temp,z+PTAB_SIZE
642 ldd temp2,z+PTAB_SIZE+1 ;check, if size is 16384 phys. sectors
643 cpi temp,low(16384)
644 ldi temp,high(16384)
645 cpc temp2,temp
646 brne dsk_tsimhd_not ;wrong size
647
dcd7e502
L
648 ldiw y,hostbuf+128-10
649 ldiw z,str_CPM_Disk*2
650 lpm temp2,z+ ; get length
623dd899 651 lcall strncmp_p
dcd7e502
L
652 breq dsk_tsimhd_found
653
b165699b
L
654 ldiw z,hostbuf
655 ldi temp2,high(512)
656 clr _tmp0 ;low(512)
b165699b
L
657dsk_tsimhd_loop:
658 ld temp,z+
659 cpi temp,0xE5
660 brne dsk_tsimhd_not
6cb1222d
L
661 add _tmp0,_255
662 adc temp2,_255
b165699b
L
663 brne dsk_tsimhd_loop
664
dcd7e502 665dsk_tsimhd_found:
02d57479
L
666 ldiw z,dpbdat_simhd*2
667 set
5482d75f 668 ori temp,0xff
b165699b
L
669 ret
670
671dsk_tsimhd_not:
5482d75f 672 clr temp ;Not a simhd hard disk image.
b165699b
L
673 ret
674
dd7aea8c
L
675; ====================================================================
676; Function:
677; ====================================================================
678; Parameters
679; --------------------------------------------------------------------
5482d75f 680; Registers : temp3 drive #
dd7aea8c
L
681;
682; --------------------------------------------------------------------
683; Description:
684; ====================================================================
685
5482d75f 686dsk_format_get:
dd7aea8c
L
687
688; Get first sector (512 byte) of current drive into hostbuf.
689
dd7aea8c
L
690 ldi temp,0
691 ldi temp2,0 ;
692 rcall dsk_readhost_lba
693
dd7aea8c
L
694; Test for variable format avrcpmhd.
695
696 rcall dsk_tst_avrcpmhd
5482d75f 697 brne dsk_imgt_done
dd7aea8c
L
698
699; Test for YAZE formats.
700
701 rcall dsk_tst_yaze
5482d75f 702 brne dsk_imgt_done
dd7aea8c 703
b165699b
L
704; Test for simhd format.
705
706 rcall dsk_tst_simhd
02d57479 707 brne dsk_imgt_done
b165699b 708
dd7aea8c
L
709; Test for MyZ80 format.
710
711 rcall dsk_tst_myz80
02d57479 712 brne dsk_imgt_done
dd7aea8c
L
713
714; No special image found. Use avrcpm.
715
716 ldiw z,dpbdat_avrcpm*2
02d57479 717 set
5482d75f 718 ori temp,0xff
02d57479 719
5482d75f 720dsk_imgt_done:
5482d75f 721 ret
dd7aea8c 722
5482d75f
L
723; ====================================================================
724; Function: Add CP/M image format data to partition table data
725; ====================================================================
726; Parameters
727; --------------------------------------------------------------------
728; Registers : temp3 drive #
729;
730; --------------------------------------------------------------------
731; Description:
732; ====================================================================
733
734dpb_imgdata_get:
735
736; Test for known CP/M formats
737
738 rcall dsk_format_get
739 breq dpb_imgd_err ;no known format detected
740
02d57479
L
741dpb_imgd_0:
742 brtc dpb_imgd_variable
743dpb_imgd_fixed:
744 lpm temp, z+ ;image header
745 lpm yl,z+ ;low(SPT)
746 lpm yh,z+ ;high(SPT)
747 lpm temp2,z+ ;BSH
748 rjmp dpb_imgd_common
749
750dpb_imgd_variable:
751 ld temp, z+ ;image header
752 ld yl,z+ ;low(SPT)
753 ld yh,z+ ;high(SPT)
754 ld temp2,z+ ;BSH
755
756dpb_imgd_common:
dd7aea8c
L
757 mov zl,temp3
758 rcall dsk_getpartentry ;get partition entry
02d57479
L
759 std z+PTAB_SPT,yl
760 tst yh ;more then 256 sectors per track?
761 brne dsk_imgprp_err ;todo: support 16 bit sector numbers
762
763 andi temp2,0x0f
764 swap temp2
765 std z+PTAB_BSH,temp2
dd7aea8c 766
dd7aea8c
L
767 andi temp,~dskType_MASK
768 ldd temp2,z+PTAB_TYPE
769 andi temp2,dskType_MASK
770 or temp,temp2
771 std z+PTAB_TYPE,temp
02d57479 772
dd7aea8c
L
773 ori temp,255
774 ret
775
776dsk_imgprp_err:
777 printnewline
778 ldi temp,'A'
779 add temp,temp3
08716d4f 780 lcall uartputc
dd7aea8c
L
781 printstring ": Format not supported: Too much sectors per track! "
782 printnewline
783
5482d75f 784dpb_imgd_err:
dd7aea8c
L
785 clr temp
786 ret
787
5482d75f
L
788; ====================================================================
789; Function:
790; ====================================================================
791; Parameters
792; --------------------------------------------------------------------
793; Registers : temp drive #
794;
795; return !0 if ok
796; 0 on error
797; --------------------------------------------------------------------
798; Description: Init CP/M data structures
29ce189c 799;
34527fc2
L
800; -----------------------------------------------------------------
801; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
802; -----------------------------------------------------------------
803;offset: 0 2 4 6 8 10 12 14
5482d75f 804;
34527fc2
L
805; -------------------------------------------------------------
806; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
807; -------------------------------------------------------------
808;offset: 0 2 3 4 5 7 9 10 11 13
5482d75f 809; ====================================================================
29ce189c 810
5482d75f 811dpb_biosdph_get:
29ce189c
L
812 mov temp3,temp ;save disk #
813
5482d75f 814 rcall dsk_format_get
dd7aea8c
L
815 brne dpb_di_0
816 rjmp dpb_di_err
29ce189c 817
dd7aea8c 818dpb_di_0:
29ce189c
L
819
820; get mem for DPH
29ce189c
L
821
822 ldi temp, low (16)
823 ldi temp2,high(16)
5482d75f 824 rcall heap_get ;returns ptr to dph mem
637689de
L
825 brne dpb_di_1
826 rjmp dpb_di_err ;
827dpb_di_1:
29ce189c 828 movw x,temp
637689de 829 movw y,temp ;save dph pointer
29ce189c
L
830 ldi temp,0
831 ldi temp2,0
832 rcall dram_writew_pp ;XLT
833 adiw x,6
834 lds temp,biosdirbuf
835 lds temp2,biosdirbuf+1
836 rcall dram_writew_pp ;DIRBUF
837
838; get mem for DPB
29ce189c
L
839
840 ldi temp, low (15)
841 ldi temp2,high(15)
842 rcall heap_get
637689de 843 breq dpb_di_err_p1
29ce189c
L
844 movw x,temp
845
02d57479
L
846 adiw z,1 ;skip sector offset byte
847 push temp3
848 ldi temp3,15
637689de 849dpb_dicpl:
02d57479
L
850 brtc PC+2 ;
851 lpm temp,z+
852 brts PC+2 ;
853 ld temp,z+
29ce189c 854 rcall dram_write_pp
02d57479 855 dec temp3
637689de 856 brne dpb_dicpl
02d57479 857 pop temp3
29ce189c 858 sbiw x,15
02d57479 859 sbiw z,15
29ce189c
L
860 movw temp,x
861 movw x,y
862 adiw x,10
863 rcall dram_writew_pp ;DPB
02d57479
L
864
865 brtc dpb_dicks_variable
866dpb_dicks_fixed:
867 adiw z,5
868 lpm _tmp0,z+ ;dsm
869 lpm _tmp1,z+
870 adiw z,11-5-2
871 lpm temp,z+ ;cks
872 lpm temp2,z+
873 rjmp dpb_dicks_common
874dpb_dicks_variable:
875 ldd _tmp0,z+5 ;dsm
876 ldd _tmp1,z+5+1
877 ldd temp,z+11 ;cks
878 ldd temp2,z+11+1
879
29ce189c
L
880; get mem for dir check vector
881
02d57479 882dpb_dicks_common:
29ce189c
L
883 cp temp,_0
884 cpc temp2,_0
637689de 885 breq dpb_dicks0
29ce189c 886 rcall heap_get
637689de
L
887 breq dpb_di_err_p1
888dpb_dicks0:
29ce189c
L
889 rcall dram_writew_pp ;CSV
890
891; get mem for alloc vector
892
02d57479 893 movw temp,_tmp0
29ce189c
L
894 subi temp, low (-8)
895 sbci temp2,high(-8)
896 lsr temp2
897 ror temp
898 lsr temp2
899 ror temp
900 lsr temp2
901 ror temp ;(dsm+1+7)/8
902 rcall heap_get
637689de 903 breq dpb_di_err_p1
29ce189c
L
904 rcall dram_writew_pp ;ALV
905
906; success, insert DPH into drvtbl
907
637689de
L
908 mov temp,temp3
909 rcall dpb_drvtbl_entry_p
29ce189c
L
910 movw temp,y
911 rcall dram_writew_pp
dd7aea8c 912
29ce189c 913 ori temp,0xff ;return ok
64219415
FZ
914 ret
915
29ce189c
L
916; error, free mem
917
637689de 918dpb_di_err_p1:
29ce189c
L
919 movw temp,y
920 rcall heap_release
637689de 921dpb_di_err:
29ce189c 922 eor temp,temp ;return 0 (+ Z-flag)
b741422e 923 ret
29ce189c 924
dd7aea8c
L
925; ====================================================================
926; Function:
927; ====================================================================
928; Parameters
929; --------------------------------------------------------------------
930; Registers :
931;
932; --------------------------------------------------------------------
933; Description:
934; ====================================================================
6cb1222d 935
dd7aea8c
L
936dsk_setdrvparam:
937 ldd temp2,z+PTAB_TYPE
938 andi temp2,~dskType_MASK ;Lower nibble is image header size
6cb1222d 939 std y+o_hdrsize,temp2
dd7aea8c 940 ldd temp2,z+PTAB_SPT
6cb1222d 941 std y+o_cpmspt,temp2 ;CP/M sectors per track
dd7aea8c
L
942 ldd temp2,z+PTAB_BSH
943 swap temp2
944 andi temp2,0x0f
945 clr _tmp0
946 inc _tmp0
947dsk_sdrvpl:
948 lsl _tmp0
949 dec temp2
950 brne dsk_sdrvpl
6cb1222d 951 std y+o_secpblk,_tmp0 ;Sectors per block
dd7aea8c
L
952 ret
953
64219415 954
b741422e 955; ====================================================================
64219415 956; Function: Does a Disk interaction
b741422e
L
957; ====================================================================
958; Parameters
959; --------------------------------------------------------------------
2ccaac16
L
960; Registers :
961; Variables :
962;
b741422e
L
963; --------------------------------------------------------------------
964; Description:
64219415 965; ====================================================================
2ccaac16 966
64219415 967dskDoIt:
6cb1222d
L
968
969 ldiw y,fsys_vars
970 std y+o_erflag,_0
971
64219415
FZ
972.if DISK_DEBUG
973 push temp
2ccaac16
L
974 sbrc temp,HOME_FUNC
975 rjmp dskdbghome
976 sbrc temp,BOOT_FUNC
977 rjmp dskdbgboot
978.if DISK_DEBUG > 1
64219415 979 sbrc temp,READ_FUNC
2ccaac16 980 rjmp dskdbgread
64219415 981 sbrc temp,WRITE_FUNC
2ccaac16
L
982 rjmp dskdbgwrite
983.endif
64219415
FZ
984 rjmp dskdbge
985
2ccaac16
L
986dskdbgread:
987 printnewline
988 printstring "dsk RD: "
989 rjmp dskdbg1
990dskdbgwrite:
64219415 991 printnewline
2ccaac16 992 printstring "dsk WR: "
64219415 993 rjmp dskdbg1
2ccaac16 994dskdbghome:
64219415 995 printnewline
2ccaac16
L
996 printstring " HOME: "
997 rjmp dskdbg1
998dskdbgboot:
999 printnewline
1000 printstring " BOOT: "
64219415 1001dskdbg1:
6cb1222d 1002 ldd temp,y+o_seekdsk
64219415
FZ
1003 subi temp,-('A')
1004 rcall uartputc
2ccaac16 1005 printstring ": trk "
6cb1222d
L
1006 ldd temp2,y+o_seektrk+1
1007 ldd temp,y+o_seektrk
dc705dc0 1008 lcall printhexw
2ccaac16 1009 printstring ", sec "
6cb1222d 1010 ldd temp,y+o_seeksec
dc705dc0 1011 lcall printhex
2ccaac16 1012 printstring ", dma "
6cb1222d
L
1013 ldd temp2,y+o_dmaadr+1
1014 ldd temp,y+o_dmaadr
dc705dc0 1015 lcall printhexw
64219415 1016dskdbge:
6cb1222d 1017 pop temp
64219415 1018.endif
2ccaac16 1019
64219415
FZ
1020 ;See what has to be done.
1021 sbrc temp,READ_FUNC
2ccaac16 1022 rjmp dsk_readwrite
64219415 1023 sbrc temp,WRITE_FUNC
2ccaac16 1024 rjmp dsk_readwrite
64219415
FZ
1025 sbrc temp,HOME_FUNC
1026 rjmp dsk_home
1027 sbrc temp,BOOT_FUNC
1028 rjmp dsk_boot
1029
1030 printstring "DISK I/O: Invalid Function code: "
08716d4f 1031 lcall printhex
dc705dc0 1032 ljmp haltinv
64219415
FZ
1033
1034dsk_boot:
6cb1222d 1035 std y+o_ndisks,_0 ;no active partitions
dd7aea8c
L
1036dsk_inval_hostbuf:
1037 cbi flags,hostact ;host buffer inactive
6cb1222d 1038 std y+o_unacnt,_0 ;clear unalloc count
64219415
FZ
1039 ret
1040
1041dsk_home:
dd7aea8c
L
1042 sbis flags,hostwrt ;check for pending write
1043 cbi flags,hostact ;clear host active flag
64219415 1044 ret
64219415 1045
b741422e
L
1046
1047
29ce189c 1048
2ccaac16
L
1049dsk_readwrite:
1050
1051; RAM disk?
1052
6cb1222d 1053 ldd zl,y+o_seekdsk
eb85ce65 1054#if RAMDISKCNT
dd7aea8c 1055 cpi zl,RAMDISKNR
2ccaac16
L
1056 brlt dsk_rw_noramdisk
1057 sbrc temp,WRITE_FUNC
1058 rjmp rdsk_write
1059 rjmp rdsk_read
1060dsk_rw_noramdisk:
eb85ce65 1061#endif
2ccaac16
L
1062 rcall dsk_getpartentry ;Get Paritiontableentry
1063 ld temp2,z ;Get Partitiontype
1064 andi temp2,dskType_MASK
b741422e
L
1065
1066; Isn't it a Disk ?
2ccaac16
L
1067
1068 cpi temp2,dskType_None
b741422e 1069 brne PC+2
2ccaac16 1070 ret ;return error
dd7aea8c 1071
b741422e 1072; It must be a FAT16-Imagefile or CP/M Partition.
dd7aea8c 1073
2ccaac16
L
1074 sbrc temp,WRITE_FUNC
1075 rjmp dsk_write
dd7aea8c 1076
2ccaac16 1077 sbi flags,readop ;Set read operation flag
637689de 1078 sbi flags,rsflag ;must read data
6cb1222d 1079 std y+o_unacnt,_0
637689de 1080 ldi temp,WRUAL ;write type
6cb1222d 1081 std y+o_wrtype,temp ;treat as unalloc
2ccaac16 1082 rjmp dsk_rw
dd7aea8c 1083
64219415 1084dsk_write:
2ccaac16
L
1085 cbi flags,readop ;Not a read operation
1086 andi temp,WRTMSK
6cb1222d 1087 std y+o_wrtype,temp ;save write type
2ccaac16
L
1088dsk_rw:
1089 rcall dsk_setdrvparam ;todo: do this only if needed (disk change)
b741422e 1090
2ccaac16 1091; Convert track/sector to an LBA address (in 128byte blocks)
b741422e 1092
6cb1222d 1093 ldd xl,y+o_seeksec ;
2ccaac16 1094 ldi xh,0 ;
6cb1222d
L
1095 ldi temp2,0 ;
1096 ldd temp,y+o_hdrsize ;add image header size
2ccaac16
L
1097 add xl,temp ;
1098 adc xh,_0 ;
6cb1222d
L
1099 ldd temp,y+o_cpmspt ;
1100 ldd _tmp0,y+o_seektrk ;
1101 mul temp,_tmp0 ;
2ccaac16
L
1102 add xl,r0 ;
1103 adc xh,r1 ;
6cb1222d
L
1104 ldd _tmp0,y+o_seektrk+1 ;
1105 mul temp,_tmp0 ;
1106 add xh,r0 ;temp2:xh:xl := sec + trk * SectorsPerTrack
1107 adc temp2,r1 ;
1108 mov temp3,xl
1109 andi temp3,SECMSK ;mask buffer number
1eeb9cbe 1110
2ccaac16 1111; Convert from CP/M LBA blocks to host LBA blocks
64219415 1112
2ccaac16
L
1113 ldi temp,SECSHF
1114dsk_sh1:
6cb1222d 1115 lsr temp2
2ccaac16
L
1116 ror xh
1117 ror xl
1118 dec temp
1119 brne dsk_sh1
6cb1222d 1120 ;todo: temp2 should be 0 here.
2ccaac16
L
1121 ;xh:xl = host block to seek
1122;
1123 sbic flags,readop
1124 rjmp dsk_rwoper ;to perform the read
dd7aea8c 1125
2ccaac16 1126; Write operation
64219415 1127
2ccaac16 1128 cbi flags,rsflag ;rsflag = 0
6cb1222d 1129 ldd temp,y+o_wrtype ;
dd7aea8c
L
1130 cpi temp,WRUAL ;write unallocated?
1131 brne dsk_chkuna ;check for unalloc
64219415 1132
64ce65a1 1133; write to unallocated, set parameters
2ccaac16 1134
6cb1222d
L
1135 ldd temp,y+o_secpblk ;next unalloc recs (blocksize/128)
1136 cpi temp3,0 ;cpm sector on phys. sector boundary?
2ccaac16
L
1137 breq dsk_una1
1138 sbi flags,rsflag ; no, rsflag = 1
64ce65a1 1139 subi temp,HOSTBLK ;don't write
6cb1222d 1140 ldd _tmp0,y+o_hdrsize ; in next bock
64ce65a1 1141 add temp,_tmp0 ; if there is a header
2ccaac16 1142dsk_una1:
6cb1222d
L
1143 std y+o_unacnt,temp
1144 ldd temp,y+o_seekdsk ;disk to seek
1145 std y+o_unadsk,temp ;unadsk = sekdsk
1146 std y+o_unalba, xl ;unalba = seeklba (== hostlba)
1147 std y+o_unalba+1,xh
2ccaac16
L
1148
1149; check for write to unallocated sector
64ce65a1 1150
64219415 1151dsk_chkuna:
2ccaac16 1152
6cb1222d 1153 ldd temp,y+o_unacnt ;any unalloc remain?
dd7aea8c
L
1154 tst temp
1155 breq dsk_alloc ;skip if not
64219415 1156
64ce65a1 1157; more unallocated records remain
2ccaac16 1158
dd7aea8c 1159 dec temp ;unacnt = unacnt-1
6cb1222d
L
1160 std y+o_unacnt,temp
1161 ldd temp,y+o_seekdsk ;same disk?
1162 ldd temp2,y+o_unadsk
dd7aea8c
L
1163 cp temp,temp2 ;seekdsk = unadsk?
1164 brne dsk_alloc ;skip if not
64219415 1165
64ce65a1 1166; disks are the same
2ccaac16 1167
6cb1222d
L
1168 ldd _tmp0,y+o_unalba
1169 ldd _tmp1,y+o_unalba+1
1170 cp _tmp0,xl ;seeklba = unalba?
1171 cpc _tmp1,xh
dd7aea8c 1172 brne dsk_alloc ;skip if not
64219415 1173
2ccaac16 1174; block address is the same
6cb1222d 1175; move to next sector for future ref
2ccaac16 1176
6cb1222d
L
1177 mov temp,temp3
1178 inc temp ;next part
1179 andi temp,SECMSK
2ccaac16
L
1180 brne dsk_noovf ;skip if no overflow
1181
1182; overflow to next block
1183
6cb1222d
L
1184 sub _tmp0,_255 ;unalba = unalba+1
1185 sbc _tmp1,_255
1186 std y+o_unalba, _tmp0
1187 std y+o_unalba+1,_tmp1
64ce65a1 1188
64219415 1189dsk_noovf:
dd7aea8c 1190 rjmp dsk_rwoper ;to perform the write
64ce65a1 1191
2ccaac16
L
1192; not an unallocated record, requires pre-read
1193
64219415 1194dsk_alloc:
6cb1222d 1195 std y+o_unacnt,_0 ;unacnt = 0
dd7aea8c 1196 sbi flags,rsflag ;rsflag = 1
b741422e 1197
b741422e 1198
2ccaac16
L
1199; Enter here to perform the read/write
1200
b741422e 1201dsk_rwoper:
2ccaac16
L
1202
1203.if DISK_DEBUG > 1
1204 printstring ", flags|wtyp "
dd7aea8c 1205 in temp,flags
2ccaac16 1206 cbr temp,WRTMSK
6cb1222d 1207 ldd _tmp0,y+o_wrtype
2ccaac16
L
1208 or temp,_tmp0
1209 lcall printhex
1210 printstring ", buf "
6cb1222d 1211 mov temp,temp3
dc705dc0 1212 lcall printhex
64219415 1213.endif
64ce65a1 1214
6cb1222d 1215 push temp3
5482d75f 1216 movw temp,x
6cb1222d 1217 ldd temp3,y+o_seekdsk
5482d75f 1218 rcall dsk_rw_hostbuf
6cb1222d
L
1219 pop temp ;get back buffer number (which part of hostbuf)
1220 ldiw y,fsys_vars
64219415 1221
64ce65a1 1222; copy data to or from buffer
2ccaac16 1223
64219415 1224 ldiw z,hostbuf
6cb1222d
L
1225 ldi temp3,128
1226 mul temp,temp3
dd7aea8c
L
1227 add zl,r0 ;offset in hostbuf
1228 adc zh,r1
64219415 1229
6cb1222d
L
1230 ldd xl,y+o_dmaadr
1231 ldd xh,y+o_dmaadr+1
64219415 1232 sbic flags,readop ;which way?
dd7aea8c 1233 rjmp dsk_rmove ;skip if read
64219415 1234
64ce65a1 1235; mark write operation
dd7aea8c 1236 sbi flags,hostwrt ;hostwrt = 1
64219415
FZ
1237dsk_wmove:
1238 mem_read
dd7aea8c 1239 st z+,temp
64219415 1240 adiw xl,1
dd7aea8c 1241 dec temp3
64219415
FZ
1242 brne dsk_wmove
1243 rjmp dsk_rwmfin
1244
1245dsk_rmove:
dd7aea8c 1246 ld temp,z+
64219415
FZ
1247 mem_write
1248 adiw xl,1
dd7aea8c 1249 dec temp3
64219415 1250 brne dsk_rmove
64ce65a1 1251
64219415 1252dsk_rwmfin:
64ce65a1 1253; data has been moved to/from host buffer
6cb1222d 1254 ldd temp,y+o_wrtype ;write type
dd7aea8c 1255 cpi temp,WRDIR ;to directory?
64219415 1256 breq dsk_wdir
dd7aea8c 1257 ret ;no further processing
64ce65a1
L
1258
1259; clear host buffer for directory write
64219415 1260dsk_wdir:
6cb1222d 1261 ldd temp,y+o_erflag
dd7aea8c 1262 tst temp ;errors?
64219415 1263 breq dsk_wdir1
dd7aea8c 1264 ret ;skip if so
64ce65a1 1265
64219415
FZ
1266dsk_wdir1:
1267 rcall dsk_writehost ;clear host buff
dd7aea8c 1268 cbi flags,hostwrt ;buffer written
b741422e
L
1269 ret
1270
dd7aea8c
L
1271; ====================================================================
1272; Function:
1273; ====================================================================
1274; Parameters
1275; --------------------------------------------------------------------
1276; Registers : temp2:temp block to read (lba)
1277; temp3 disk #
1278;
1279; --------------------------------------------------------------------
1280; Description:
1281; ====================================================================
6cb1222d 1282
dd7aea8c 1283dsk_readhost_lba:
6cb1222d 1284
2ccaac16 1285.if HOSTRW_DEBUG
dd7aea8c 1286 printnewline
2ccaac16
L
1287 printstring "Readhost LBA"
1288.endif
5482d75f
L
1289 sbi flags,rsflag ;must read data
1290 rcall dsk_rw_hostbuf
1291 lds temp,erflag ;returns 0, if ok
1292 tst temp
1293 ret
dd7aea8c 1294
5482d75f
L
1295; ====================================================================
1296; Function: Get physical disk sector in hostbuf.
1297; ====================================================================
1298; Parameters
1299; --------------------------------------------------------------------
1300; Registers : temp2:temp host block to read/write (lba)
1301; temp3 disk #
1302;
1303; --------------------------------------------------------------------
1304; Description:
1305; ====================================================================
1306dsk_rw_hostbuf:
6cb1222d 1307 ldiw y,fsys_vars
5482d75f 1308 ;xh:xl = host block to seek
6cb1222d 1309 std y+o_erflag,_0 ;no errors (yet)
5482d75f 1310
64ce65a1
L
1311; active host sector?
1312
5482d75f
L
1313 in _tmp0,flags ;host active flag
1314 sbi flags,hostact ;always becomes 1
1315 sbrs _tmp0,hostact ;was it already?
1316 rjmp dsk_filhst ;fill host if not
1317
64ce65a1
L
1318; host buffer active, same as seek buffer?
1319
6cb1222d 1320 ldd _tmp0,y+o_hostdsk ;same disk?
5482d75f
L
1321 cp temp3,_tmp0 ;seekdsk = hostdsk?
1322 brne dsk_nomatch
1323
64ce65a1
L
1324; same disk, same block?
1325
6cb1222d
L
1326 ldd _tmp0,y+o_hostlba
1327 cp temp, _tmp0
1328 ldd _tmp0,y+o_hostlba+1
825ecc9d 1329 cpc temp2,_tmp0
5482d75f
L
1330 breq dsk_match
1331
1332dsk_nomatch:
1333 ;proper disk, but not correct sector
1334 sbis flags,hostwrt ;host written?
1335 rjmp dsk_filhst
1336 push temp3
1337 push temp2
1338 push temp
1339 rcall dsk_writehost ;clear host buff
1340 pop temp
1341 pop temp2
1342 pop temp3
1343
64ce65a1 1344; may have to fill the host buffer
5482d75f 1345dsk_filhst:
6cb1222d
L
1346 ldiw y,fsys_vars
1347 std y+o_hostlba,temp
1348 std y+o_hostlba+1,temp2
1349 std y+o_hostdsk,temp3
5482d75f
L
1350
1351 sbic flags,rsflag ;need to read?
1352 rcall dsk_readhost ;yes, if 1
1353 cbi flags,hostwrt ;no pending write
1354
1355dsk_match:
1356 ret
dd7aea8c 1357
b741422e 1358; ====================================================================
64219415 1359; Function: Does a Disk write operation
b741422e
L
1360; ====================================================================
1361; Parameters
1362; --------------------------------------------------------------------
1363; Registers : none
1364; Variables : [r] seekdsk Number of Disk to Read
1365; [r] seeksec Sector to read
1366; [r] seektrk Track to read
1367; --------------------------------------------------------------------
1368; Description:
1369; ====================================================================
ce520bff 1370
b741422e 1371dsk_writehost:
b741422e 1372
ce520bff 1373.if HOSTRW_DEBUG
02d57479
L
1374.if DISK_DEBUG == 0
1375 printnewline
1376 printstring "Host write: "
1377.else
ce520bff 1378 printstring ", hst WR "
02d57479 1379.endif
ce520bff 1380.endif
b741422e 1381
ce520bff
L
1382 rcall dsk_hostparam
1383 breq dsk_hstwr_err
1384
02d57479 1385 ldiw z,hostbuf
ce520bff
L
1386 rcall mmcWriteSect
1387 tst temp
1388 brne dsk_hstwr_err
1389
1390dsk_hstwr_ok:
1391 sts erflag,_0
1392 ret
1393
1394dsk_hstwr_err:
1395 sts erflag,_255
b741422e
L
1396 ret
1397
1398; ====================================================================
64219415 1399; Function: Does a Disk read operation
b741422e
L
1400; ====================================================================
1401; Parameters
1402; --------------------------------------------------------------------
1403; Registers : none
1404; Variables : [r] seekdsk Number of Disk to Read
1405; [r] seeksec Sector to read
1406; [r] seektrk Track to read
1407; --------------------------------------------------------------------
1408; Description:
1409; ====================================================================
ce520bff 1410
b741422e 1411dsk_readhost:
dd7aea8c 1412
ce520bff 1413.if HOSTRW_DEBUG
02d57479
L
1414.if DISK_DEBUG == 0
1415 printnewline
1416 printstring "Host read: "
1417.else
ce520bff 1418 printstring ", hst RD "
02d57479 1419.endif
ce520bff
L
1420.endif
1421
1422 rcall dsk_hostparam
1423 breq dsk_hstrd_err
1424
02d57479 1425 ldiw z,hostbuf
ce520bff
L
1426 rcall mmcReadSect
1427 tst temp
1428 brne dsk_hstrd_err
1429
1430dsk_hstrd_ok:
1431 sts erflag,_0
1432 ret
1433
1434dsk_hstrd_err:
1435 sts erflag,_255
1436 ret
1437
1438; ====================================================================
1439; Function: Does a Disk write operation
1440; ====================================================================
1441; Parameters
1442; --------------------------------------------------------------------
1443; Registers : none
1444; Variables : [r] seekdsk Number of Disk to Read
1445; [r] seeksec Sector to read
1446; [r] seektrk Track to read
1447; hostdsk = host disk #, (partition #)
1448; hostlba = host block #, relative to partition start
1449; Read/Write "hostsize" bytes to/from hostbuf
1450; --------------------------------------------------------------------
1451; Description:
1452; ====================================================================
1453
1454dsk_hostparam:
1455
dd7aea8c 1456 lds zl,hostdsk
ce520bff
L
1457
1458.if HOSTRW_DEBUG
1459 mov temp,zl
1460 subi temp,-('A')
1461 lcall uartputc
1462.endif
b741422e 1463 rcall dsk_getpartentry
ce520bff
L
1464 lds xl,hostlba ; get sector to access
1465 lds xh,hostlba+1
1466
1467.if HOSTRW_DEBUG
1468 printstring ": lba "
1469 push r15
1470 push r14
1471 clr r14
1472 clr r15
1473 movw temp,x
1474 lcall print_ultoa
1475 pop r14
1476 pop r15
1477.endif
1478
1479 ldd _tmp0,z+PTAB_SIZE ; get disksize
1480 ldd _tmp1,z+PTAB_SIZE+1
1481
1482 cp xl,_tmp0 ; check given sector against disksize
1483 cpc xh,_tmp1
1484 brcc dsk_hst_param_err
1485
1486 ldd temp,z+PTAB_TYPE
637689de 1487 andi temp,dskType_MASK
b741422e
L
1488
1489#if FAT16_SUPPORT
64219415 1490; Is it a FAT16 Diskimage ?
637689de 1491 cpi temp,dskType_FAT
ce520bff
L
1492 brne dsk_hstpar_nofat
1493 rcall fat_lba_to_phys
1494 rjmp dsk_hstpar_gotit
1495dsk_hstpar_nofat:
b741422e 1496#endif
ce520bff 1497#if CPMDSK_SUPPORT
64219415 1498; Is it a CP/M Partition ?
637689de 1499 cpi temp,dskType_CPM
ce520bff
L
1500 brne dsk_hstpar_nocpm
1501 rcall cpm_lba_to_phys
1502 rjmp dsk_hstpar_gotit
1503dsk_hstpar_nocpm:
1504#endif
1505; Disktype not supported
1506 rjmp dsk_hst_param_err
1507
1508dsk_hstpar_gotit:
1509
1510.if HOSTRW_DEBUG
1511 printstring ", abs "
1512 push r15
1513 push r14
1514 push temp2
1515 push temp
1516 movw temp,x
1517 movw r14,y
1518 lcall print_ultoa
1519 pop temp
1520 pop temp2
1521 pop r14
1522 pop r15
1523.endif
1524
1525 ori temp,255
b741422e
L
1526 ret
1527
ce520bff 1528dsk_hst_param_err:
5482d75f 1529
ce520bff
L
1530.if HOSTRW_DEBUG
1531 printstring ", max: "
1532 push r15
1533 push r14
1534 push temp2
1535 push temp
1536 movw temp,_tmp0
1537 clr r14
1538 clr r15
1539 lcall print_ultoa
1540 pop temp
1541 pop temp2
1542 pop r14
1543 pop r15
1544 printstring " "
1545.endif
1546
1547 clr temp
1548 ret
1549
1550; --------------------------------------------------------------------
5482d75f
L
1551; vim:set ts=8 noet nowrap
1552