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