; Filesystem functions for the Interaction with BIOS and Disks
;
; Copyright (C) 2010 Frank Zoll
+; Copyright (C) 2010,2011,2013 Leo C.
;
; This file is part of avrcpm.
;
.dseg
+fsys_vars:
+
; The following 3 variables are copied from DRAM.
; Don't change order.
biosenddat: .byte 2 ;
ndisks: .byte 1 ;Number of CP/M disks
+ .equ o_ndisks = ndisks-fsys_vars
; The following 5 variables are accessed from 8080/z80 via the
; virtual port interface. Don't change order.
seektrk: .byte 2 ;seek track number
seeksec: .byte 2 ;seek sector number
dmaadr: .byte 2 ;last dma address
-hostpart: .byte 1 ;part of hostbuf to transfer
+ .equ o_bcbadr = bcbadr-fsys_vars
+ .equ o_seekdsk = seekdsk-fsys_vars
+ .equ o_seektrk = seektrk-fsys_vars
+ .equ o_seeksec = seeksec-fsys_vars
+ .equ o_dmaadr = dmaadr-fsys_vars
hdrsize: .byte 1 ;Image header size (offset)
cpmspt: .byte 1 ;CP/M sectors per track
unacnt: .byte 1 ;unalloc rec cnt
unadsk: .byte 1 ;last unalloc disk
unalba: .byte 2 ;last unalloc disk block
-unapart: .byte 1 ;last unalloc disk buffer part
+ .equ o_hdrsize = hdrsize-fsys_vars
+ .equ o_cpmspt = cpmspt-fsys_vars
+ .equ o_secpblk = secpblk-fsys_vars
+ .equ o_unacnt = unacnt-fsys_vars
+ .equ o_unadsk = unadsk-fsys_vars
+ .equ o_unalba = unalba-fsys_vars
erflag: .byte 1 ;error reporting
wrtype: .byte 1 ;write operation type
+ .equ o_erflag = erflag-fsys_vars
+ .equ o_wrtype = wrtype-fsys_vars
hostdsk: .byte 1 ;host disk number
hostlba: .byte 2 ;host sector number (relative to partition start)
+ .equ o_hostdsk = hostdsk-fsys_vars
+ .equ o_hostlba = hostlba-fsys_vars
+
hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
hostparttbltop:
hostbuf: .byte HOSTSIZE ;host buffer (from/to SD-card)
push temp
printnewline
printstring "drvtbl ("
- lds xl,biosdrvtbl
- lds xh,biosdrvtbl+1
+ ldsw x,biosdrvtbl
movw temp,x
lcall printhexw
printstring "): "
pop xl
pop xh
ret
-
+
dbg_print_biosd:
printnewline
lds temp,bcbadr
printstring " "
ret
.endif
-
+
; ====================================================================
; ====================================================================
; Function: Get a Pointer to a Partitiontable entry
; Description:
; ====================================================================
dsk_getpartentry:
-
+
ldi zh,PARTENTRY_SIZE
mul zh,zl
ldiw z,hostparttbl
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
-;
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
-
+
dsk_param_getadr:
ldiw z,biospar_base
add zl,temp3
st z+,temp
dec temp3
brne sbcb_l
-
+
; rcall dbg_print_biosd
rcall dpb_drvtblclear
; rcall dbg_prdrvtbl
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
+; Registers :
+; Variables :
; return 0, if selected disk not exist.
; return !0, if disk exist
; --------------------------------------------------------------------
ldi temp,1
lcall clockput
.endif
- rcall mgr_init_partitions ;disk chanched?
+ rcall mgr_init_partitions ;disk changed?
push temp
.if 0
ldi temp2,0x40
ldi temp,2
lcall clockput
-; sbrs temp,7
+; sbrs temp,7
; rjmp dsk_dchpart0
lcall mgr_prnt_parttbl
dsk_dchpart0:
cbr temp2,0x80
lds temp,seekdsk
-
+
; Check if selected disk # is less then # of disks.
dsk_dchpart1:
printstring ", "
lcall printhexw
pop temp
-.endif
+.endif
ret
dsk_dch_err:
ldi temp,0 ;error return
- ret
-
+ ret
+
; Check RAMDISK
dsk_dchrd:
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
+; Registers :
+; Variables :
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dskErrorRet:
lds temp,erflag
ret
-
+
; ====================================================================
; ====================================================================
- .dseg
-tmpdpb: .byte 16
-
- .cseg
str_CPM_Disk:
.db 10,"<CPM_Disk>",0
dpbdat_avrcpm: ;(dpb243)
.db 0x00,0x1A ;sector offset, low(spt)
- .db 0x00,0x03 ;high (spt), block shift
- .db 0x07,0x00 ;bock mask, extent mask
+ .db 0x00,0x03 ;high (spt), block shift
+ .db 0x07,0x00 ;bock mask, extent mask
.db 0xF2,0x00 ;disk size - 1,
- .db 0x3F,0x00 ;dir max
+ .db 0x3F,0x00 ;dir max
.db 0xC0,0x00 ;alloc0, alloc1
.db 0x10,0x00 ;chk size
.db 0x02,0x00 ;offset
dpbdat_myz80: ;
.db 0x02,0x80 ;sector offset, low(spt)
- .db 0x00,0x05 ;high (spt), block shift
- .db 0x1F,0x01 ;bock mask, extent mask
+ .db 0x00,0x05 ;high (spt), block shift
+ .db 0x1F,0x01 ;bock mask, extent mask
.db 0xFF,0x07 ;disk size - 1,
- .db 0xFF,0x03 ;dir max
+ .db 0xFF,0x03 ;dir max
.db 0xFF,0x00 ;alloc0, alloc1
.db 0x00,0x01 ;chk size
.db 0x00,0x00 ;offset
dpbdat_simhd: ;
.db 0x00,0x20 ;sector offset, low(spt)
- .db 0x00,0x05 ;high (spt), block shift
- .db 0x1F,0x01 ;bock mask, extent mask
+ .db 0x00,0x05 ;high (spt), block shift
+ .db 0x1F,0x01 ;bock mask, extent mask
.db 0xF9,0x07 ;disk size - 1,
- .db 0xFF,0x03 ;dir max
+ .db 0xFF,0x03 ;dir max
.db 0xFF,0x00 ;alloc0, alloc1
.db 0x00,0x01 ;chk size
.db 0x06,0x00 ;offset
#if 0
-;rd1016
+;rd1016
.db 0x20,0x00 ;spt
.db 0x04,0x0F ;block shift, bock mask
- .db 0x00,0xFB ;extent mask, low(disk size -1),
+ .db 0x00,0xFB ;extent mask, low(disk size -1),
.db 0x01,0xBF ;high(disk size -1), low(dir max)
.db 0x00,0xE0 ;high(dir max), alloc0
.db 0x00,0x30 ;alloc1, low(chk size)
;rd9192s
.db 0x20,0x00 ;spt
.db 0x05,0x1F ;block shift, bock mask
- .db 0x01,0xFD ;extent mask, low(disk size -1),
+ .db 0x01,0xFD ;extent mask, low(disk size -1),
.db 0x07,0xFF ;high(disk size -1), low(dir max)
.db 0x01,0xF0 ;high(dir max), alloc0
.db 0x00,0x80 ;alloc1, low(chk size)
#endif
-; Copy the dpb data from flash memory, pointed to by Z, to temp ram.
-
-dpb_copy_p:
- push yh
- push yl
- ldi temp2,16
- ldiw y,tmpdpb
-cpydpb_pl:
- lpm temp,z+
- st y+,temp
- dec temp2
- brne cpydpb_pl
- pop yl
- pop yh
- ret
-
-; Copy the dpb data, pointed to by Z to temp ram.
-
-dpb_copy:
- st y+,temp
- ldi temp2,15
-cpydpb_l:
- ld temp,z+
- st y+,temp
- dec temp2
- brne cpydpb_l
- ret
-
; ====================================================================
; Function: get drive table entry pointer for drive # in temp
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
-;
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
add xl,temp
adc xh,_0
ret
-
+
; ====================================================================
; Function: get drive table entry for drive # in temp
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
-;
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
dpb_drvtbl_entry_get:
rcall dpb_drvtbl_entry_p
- ljmp dram_readw_pp
+ ljmp dram_readw_pp
; ====================================================================
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
-;
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
ldsw x,biosdrvtbl
sbiw x,0
breq dpb_drvi_ex
-
+
dpb_drvi_1:
ldi temp3,8
dpb_drvi_lp:
rcall dram_writew_pp
dec temp3
brne dpb_drvi_lp
-
+
lds temp,biosenddat
lds temp2,biosenddat+1
cp temp,_0
; Parameters
; --------------------------------------------------------------------
; Registers : temp drive #
-;
+;
; --------------------------------------------------------------------
; Description: Not implemented yet.
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Registers : temp drive #
-;
+;
; --------------------------------------------------------------------
; Description: From the YAZE Doc:
;
lpm temp2,z+ ; get length
lcall strncmp_p
brne dsk_tyze_not
-
- ldiw z,hostbuf+32
- ldiw y,tmpdpb
+
+ ldiw z,hostbuf+31
+ clt ;dpb in RAM
ldi temp,1 ;1 sector header size
- rcall dpb_copy
+ st z,temp
ori temp,0xff
ret
dsk_tyze_not:
clr temp ;Not a YAZE disk image.
ret
-
+
; ====================================================================
; Function: Test disk format: MyZ80
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Registers : temp drive #
-;
+;
; --------------------------------------------------------------------
; Description: Test, if first 2 Sectors are filled with 0xE5,
; and Size = 8192KB + 256Bytes.
; ====================================================================
+
dsk_tst_myz80:
mov zl,temp3
ldi temp,high(16385)
cpc temp2,temp
brne dsk_tmyz80_not ;wrong size
-
+
ldiw z,hostbuf
ldi temp2,0
-
+
dsk_tmyz80_loop:
ld temp,z+
cpi temp,0xE5
dec temp2
brne dsk_tmyz80_loop
+ ldiw z,dpbdat_myz80*2
+ set
ori temp,0xff
ret
dsk_tmyz80_not:
clr temp ;Not a MyZ80 hard disk image.
ret
-
+
; ====================================================================
; Function: Test disk format: simhd, simh altair 8800 hard disk format
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Registers : temp drive #
-;
+;
; --------------------------------------------------------------------
-; Description: Test, if Size = 8192 KB and
+; Description: Test, if Size = 8192 KB and
; first 6 tracks are filled with 0xE5.
-; Actually, only the first phys. sector is tested, since
+; Actually, only the first phys. sector is tested, since
; the other 47 sectors are not in memory at this time.
; ====================================================================
+
dsk_tst_simhd:
mov zl,temp3
ldi temp,high(16384)
cpc temp2,temp
brne dsk_tsimhd_not ;wrong size
-
+
ldiw y,hostbuf+128-10
ldiw z,str_CPM_Disk*2
lpm temp2,z+ ; get length
lcall strncmp_p
breq dsk_tsimhd_found
-
+
ldiw z,hostbuf
ldi temp2,high(512)
clr _tmp0 ;low(512)
ld temp,z+
cpi temp,0xE5
brne dsk_tsimhd_not
- dec _tmp0
- brne dsk_tsimhd_loop
- dec temp2
+ add _tmp0,_255
+ adc temp2,_255
brne dsk_tsimhd_loop
dsk_tsimhd_found:
+ ldiw z,dpbdat_simhd*2
+ set
ori temp,0xff
ret
dsk_tsimhd_not:
clr temp ;Not a simhd hard disk image.
ret
-
+
; ====================================================================
-; Function:
+; Function:
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Registers : temp3 drive #
-;
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
; Get first sector (512 byte) of current drive into hostbuf.
- ldi temp,0
+ ldi temp,0
ldi temp2,0 ;
rcall dsk_readhost_lba
-
+
; Test for variable format avrcpmhd.
rcall dsk_tst_avrcpmhd
; Test for simhd format.
rcall dsk_tst_simhd
- ldiw z,dpbdat_simhd*2
- brne dsk_imgt_fixed
+ brne dsk_imgt_done
; Test for MyZ80 format.
rcall dsk_tst_myz80
- ldiw z,dpbdat_myz80*2
- brne dsk_imgt_fixed
-
+ brne dsk_imgt_done
+
; No special image found. Use avrcpm.
ldiw z,dpbdat_avrcpm*2
-
-dsk_imgt_fixed:
- rcall dpb_copy_p
+ set
ori temp,0xff
+
dsk_imgt_done:
- ret
+ ret
; ====================================================================
; Function: Add CP/M image format data to partition table data
; Parameters
; --------------------------------------------------------------------
; Registers : temp3 drive #
-;
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
dpb_imgdata_get:
-; Test for known CP/M formats
+; Test for known CP/M formats
- rcall dsk_format_get
+ rcall dsk_format_get
breq dpb_imgd_err ;no known format detected
-;
+dpb_imgd_0:
+ brtc dpb_imgd_variable
+dpb_imgd_fixed:
+ lpm temp, z+ ;image header
+ lpm yl,z+ ;low(SPT)
+ lpm yh,z+ ;high(SPT)
+ lpm temp2,z+ ;BSH
+ rjmp dpb_imgd_common
+
+dpb_imgd_variable:
+ ld temp, z+ ;image header
+ ld yl,z+ ;low(SPT)
+ ld yh,z+ ;high(SPT)
+ ld temp2,z+ ;BSH
+
+dpb_imgd_common:
mov zl,temp3
rcall dsk_getpartentry ;get partition entry
- ldiw y,tmpdpb
-
-; std y+12,_0 ;Test: set check size to 0
-; std y+13,_0
-
- ldd temp,y+0
- andi temp,~dskType_MASK
- ldd temp2,z+PTAB_TYPE
- andi temp2,dskType_MASK
- or temp,temp2
- std z+PTAB_TYPE,temp
- ldd temp,y+1
- std z+PTAB_SPT,temp
- ldd temp,y+2
- tst temp ;more then 256 sectors per track?
- brne dsk_imgprp_err ;todo: support 16 bit sector numbers
- ldd temp2,y+3
- andi temp2,0x0f
- swap temp2
- std z+PTAB_BSH,temp2
-
- ori temp,255
- ret
+ std z+PTAB_SPT,yl
+ tst yh ;more then 256 sectors per track?
+ breq dpb_imgd_1 ;todo: support 16 bit sector numbers
dsk_imgprp_err:
printnewline
clr temp
ret
+dpb_imgd_1:
+ andi temp2,0x0f
+ swap temp2
+ std z+PTAB_BSH,temp2
+
+ andi temp,~dskType_MASK
+ ldd temp2,z+PTAB_TYPE
+ andi temp2,dskType_MASK
+ or temp,temp2
+ std z+PTAB_TYPE,temp
+
+ ori temp,255
+ ret
+
; ====================================================================
-; Function:
+; Function:
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Registers : temp drive #
-;
+;
; return !0 if ok
; 0 on error
; --------------------------------------------------------------------
-; Description: Init CP/M data structures
+; Description: Init CP/M data structures
;
; -----------------------------------------------------------------
; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
; -------------------------------------------------------------
; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
; -------------------------------------------------------------
-;offset: 0 2 3 4 5 7 9 10 11 13
+;offset: 0 2 3 4 5 7 9 10 11 13
; ====================================================================
dpb_biosdph_get:
mov temp3,temp ;save disk #
- rcall dsk_format_get
+ rcall dsk_format_get
brne dpb_di_0
rjmp dpb_di_err
dpb_di_0:
-; get mem for DPH
+; get mem for DPH
ldi temp, low (16)
ldi temp2,high(16)
lds temp2,biosdirbuf+1
rcall dram_writew_pp ;DIRBUF
-; get mem for DPB
-
+; get mem for DPB
+
ldi temp, low (15)
ldi temp2,high(15)
rcall heap_get
breq dpb_di_err_p1
movw x,temp
-
- ldiw z,tmpdpb+1 ;skip sector offset byte
+
+ adiw z,1 ;skip sector offset byte
+ push temp3
+ ldi temp3,15
dpb_dicpl:
- ld temp,z+
+ brtc PC+2 ;
+ lpm temp,z+
+ brts PC+2 ;
+ ld temp,z+
rcall dram_write_pp
- cpi zl,low(tmpdpb + 16)
+ dec temp3
brne dpb_dicpl
+ pop temp3
sbiw x,15
+ sbiw z,15
movw temp,x
movw x,y
adiw x,10
rcall dram_writew_pp ;DPB
-
+
+ brtc dpb_dicks_variable
+dpb_dicks_fixed:
+ adiw z,5
+ lpm _tmp0,z+ ;dsm
+ lpm _tmp1,z+
+ adiw z,11-5-2
+ lpm temp,z+ ;cks
+ lpm temp2,z+
+ rjmp dpb_dicks_common
+dpb_dicks_variable:
+ ldd _tmp0,z+5 ;dsm
+ ldd _tmp1,z+5+1
+ ldd temp,z+11 ;cks
+ ldd temp2,z+11+1
+
; get mem for dir check vector
- lds temp,tmpdpb+12 ;cks
- lds temp2,tmpdpb+12+1
+dpb_dicks_common:
cp temp,_0
cpc temp2,_0
breq dpb_dicks0
; get mem for alloc vector
- lds temp,tmpdpb+6 ;dsm
- lds temp2,tmpdpb+6+1
+ movw temp,_tmp0
subi temp, low (-8)
sbci temp2,high(-8)
lsr temp2
mov temp,temp3
rcall dpb_drvtbl_entry_p
movw temp,y
- rcall dram_writew_pp
+ rcall dram_writew_pp
ori temp,0xff ;return ok
ret
dpb_di_err:
eor temp,temp ;return 0 (+ Z-flag)
ret
-
+
; ====================================================================
-; Function:
+; Function:
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
+; Registers :
;
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dsk_setdrvparam:
ldd temp2,z+PTAB_TYPE
andi temp2,~dskType_MASK ;Lower nibble is image header size
- sts hdrsize,temp2
+ std y+o_hdrsize,temp2
ldd temp2,z+PTAB_SPT
- sts cpmspt,temp2 ;CP/M sectors per track
+ std y+o_cpmspt,temp2 ;CP/M sectors per track
ldd temp2,z+PTAB_BSH
swap temp2
andi temp2,0x0f
lsl _tmp0
dec temp2
brne dsk_sdrvpl
- sts secpblk,_tmp0 ;Sectors per block
+ std y+o_secpblk,_tmp0 ;Sectors per block
ret
-
+
; ====================================================================
; Function: Does a Disk interaction
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers :
-; Variables :
-;
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
dskDoIt:
+
+ ldiw y,fsys_vars
+ std y+o_erflag,_0
+
.if DISK_DEBUG
push temp
sbrc temp,HOME_FUNC
printnewline
printstring " BOOT: "
dskdbg1:
- lds temp,seekdsk
+ ldd temp,y+o_seekdsk
subi temp,-('A')
- rcall uartputc
+ lcall uartputc
printstring ": trk "
- lds temp2,seektrk+1
- lds temp,seektrk
+ ldd temp2,y+o_seektrk+1
+ ldd temp,y+o_seektrk
lcall printhexw
printstring ", sec "
- lds temp,seeksec
+ ldd temp,y+o_seeksec
lcall printhex
printstring ", dma "
- lds temp2,dmaadr+1
- lds temp,dmaadr
+ ldd temp2,y+o_dmaadr+1
+ ldd temp,y+o_dmaadr
lcall printhexw
dskdbge:
- pop temp
+ pop temp
.endif
- sts erflag,_0
-
;See what has to be done.
sbrc temp,READ_FUNC
rjmp dsk_readwrite
ljmp haltinv
dsk_boot:
- sts ndisks,_0 ;no active partitions
+ std y+o_ndisks,_0 ;no active partitions
dsk_inval_hostbuf:
cbi flags,hostact ;host buffer inactive
- sts unacnt,_0 ;clear unalloc count
+ std y+o_unacnt,_0 ;clear unalloc count
ret
dsk_home:
; RAM disk?
- lds zl,seekdsk
+ ldd zl,y+o_seekdsk
#if RAMDISKCNT
cpi zl,RAMDISKNR
brlt dsk_rw_noramdisk
sbi flags,readop ;Set read operation flag
sbi flags,rsflag ;must read data
- sts unacnt,_0
+ std y+o_unacnt,_0
ldi temp,WRUAL ;write type
- sts wrtype,temp ;treat as unalloc
+ std y+o_wrtype,temp ;treat as unalloc
rjmp dsk_rw
dsk_write:
cbi flags,readop ;Not a read operation
andi temp,WRTMSK
- sts wrtype,temp ;save write type
+ std y+o_wrtype,temp ;save write type
dsk_rw:
rcall dsk_setdrvparam ;todo: do this only if needed (disk change)
; Convert track/sector to an LBA address (in 128byte blocks)
- lds xl,seeksec ;
+ ldd xl,y+o_seeksec ;
ldi xh,0 ;
- ldi temp3,0 ;
- lds temp,hdrsize ;add image header size
+ ldi temp2,0 ;
+ ldd temp,y+o_hdrsize ;add image header size
add xl,temp ;
adc xh,_0 ;
- lds temp2,cpmspt ;
- lds temp,seektrk ;
- mul temp,temp2 ;
+ ldd temp,y+o_cpmspt ;
+ ldd _tmp0,y+o_seektrk ;
+ mul temp,_tmp0 ;
add xl,r0 ;
adc xh,r1 ;
- lds temp,seektrk+1 ;
- mul temp,temp2 ;
- add xh,r0 ;temp3:xh:xl := sec + trk * SectorsPerTrack
- adc temp3,r1 ;
- mov temp,xl
- andi temp,SECMSK ;mask buffer number
- sts hostpart,temp ;save for later
+ ldd _tmp0,y+o_seektrk+1 ;
+ mul temp,_tmp0 ;
+ add xh,r0 ;temp2:xh:xl := sec + trk * SectorsPerTrack
+ adc temp2,r1 ;
+ mov temp3,xl
+ andi temp3,SECMSK ;mask buffer number
; Convert from CP/M LBA blocks to host LBA blocks
ldi temp,SECSHF
dsk_sh1:
- lsr temp3
+ lsr temp2
ror xh
ror xl
dec temp
brne dsk_sh1
- ;todo: temp3 should be 0 here.
+ ;todo: temp2 should be 0 here.
;xh:xl = host block to seek
-;
+;
sbic flags,readop
rjmp dsk_rwoper ;to perform the read
; Write operation
cbi flags,rsflag ;rsflag = 0
- lds temp,wrtype ;
+ ldd temp,y+o_wrtype ;
cpi temp,WRUAL ;write unallocated?
brne dsk_chkuna ;check for unalloc
; write to unallocated, set parameters
- lds temp,secpblk ;next unalloc recs (blocksize/128)
- lds temp2,hostpart ;
- sts unapart,temp2 ;
- cpi temp2,0 ;cpm sector on phys. sector boundary?
+ ldd temp,y+o_secpblk ;next unalloc recs (blocksize/128)
+ cpi temp3,0 ;cpm sector on phys. sector boundary?
breq dsk_una1
sbi flags,rsflag ; no, rsflag = 1
subi temp,HOSTBLK ;don't write
- lds _tmp0,hdrsize ; in next bock
+ ldd _tmp0,y+o_hdrsize ; in next bock
add temp,_tmp0 ; if there is a header
dsk_una1:
- sts unacnt,temp
- lds temp,seekdsk ;disk to seek
- sts unadsk,temp ;unadsk = sekdsk
- sts unalba, xl ;unalba = seeklba (== hostlba)
- sts unalba+1,xh
+ std y+o_unacnt,temp
+ ldd temp,y+o_seekdsk ;disk to seek
+ std y+o_unadsk,temp ;unadsk = sekdsk
+ std y+o_unalba, xl ;unalba = seeklba (== hostlba)
+ std y+o_unalba+1,xh
; check for write to unallocated sector
dsk_chkuna:
- lds temp,unacnt ;any unalloc remain?
+ ldd temp,y+o_unacnt ;any unalloc remain?
tst temp
breq dsk_alloc ;skip if not
; more unallocated records remain
dec temp ;unacnt = unacnt-1
- sts unacnt,temp
- lds temp,seekdsk ;same disk?
- lds temp2,unadsk
+ std y+o_unacnt,temp
+ ldd temp,y+o_seekdsk ;same disk?
+ ldd temp2,y+o_unadsk
cp temp,temp2 ;seekdsk = unadsk?
brne dsk_alloc ;skip if not
; disks are the same
- lds temp,unalba
- lds temp2,unalba+1
- cp temp,xl ;seeklba = unalba?
- cpc temp2,xh
+ ldd _tmp0,y+o_unalba
+ ldd _tmp1,y+o_unalba+1
+ cp _tmp0,xl ;seeklba = unalba?
+ cpc _tmp1,xh
brne dsk_alloc ;skip if not
; block address is the same
+; move to next sector for future ref
- lds _tmp0,hostpart ;same part?
- lds temp3,unapart
- cp _tmp0,temp3 ;seekpart = unapart?
- brne dsk_alloc ;skip if not
-
-; match, move to next sector for future ref
-
- inc temp3 ;next part
- andi temp3,SECMSK
- sts unapart,temp3
+ mov temp,temp3
+ inc temp ;next part
+ andi temp,SECMSK
brne dsk_noovf ;skip if no overflow
; overflow to next block
- subi temp, low(-1) ;unalba = unalba+1
- sbci temp2,high(-1)
- sts unalba,temp
- sts unalba+1,temp2
+ sub _tmp0,_255 ;unalba = unalba+1
+ sbc _tmp1,_255
+ std y+o_unalba, _tmp0
+ std y+o_unalba+1,_tmp1
dsk_noovf:
rjmp dsk_rwoper ;to perform the write
; not an unallocated record, requires pre-read
dsk_alloc:
- sts unacnt,_0 ;unacnt = 0
+ std y+o_unacnt,_0 ;unacnt = 0
sbi flags,rsflag ;rsflag = 1
printstring ", flags|wtyp "
in temp,flags
cbr temp,WRTMSK
- lds _tmp0,wrtype
+ ldd _tmp0,y+o_wrtype
or temp,_tmp0
lcall printhex
printstring ", buf "
- lds temp,hostpart
+ mov temp,temp3
lcall printhex
.endif
+ push temp3
movw temp,x
- lds temp3,seekdsk
+ ldd temp3,y+o_seekdsk
rcall dsk_rw_hostbuf
+ pop temp ;get back buffer number (which part of hostbuf)
+ ldiw y,fsys_vars
; copy data to or from buffer
ldiw z,hostbuf
- lds temp,hostpart ;get buffer number (which part of hostbuf)
- ldi temp2,128
- mul temp,temp2
+ ldi temp3,128
+ mul temp,temp3
add zl,r0 ;offset in hostbuf
adc zh,r1
- lds xl,dmaadr
- lds xh,dmaadr+1
- ldi temp3,128 ;length of move
+ ldd xl,y+o_dmaadr
+ ldd xh,y+o_dmaadr+1
sbic flags,readop ;which way?
rjmp dsk_rmove ;skip if read
dec temp3
brne dsk_wmove
rjmp dsk_rwmfin
-
+
dsk_rmove:
ld temp,z+
mem_write
dsk_rwmfin:
; data has been moved to/from host buffer
- lds temp,wrtype ;write type
+ ldd temp,y+o_wrtype ;write type
cpi temp,WRDIR ;to directory?
breq dsk_wdir
ret ;no further processing
; clear host buffer for directory write
dsk_wdir:
- lds temp,erflag
+ ldd temp,y+o_erflag
tst temp ;errors?
breq dsk_wdir1
ret ;skip if so
ret
; ====================================================================
-; Function:
+; Function:
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Registers : temp2:temp block to read (lba)
; temp3 disk #
-;
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
-;
+
dsk_readhost_lba:
+
.if HOSTRW_DEBUG
printnewline
printstring "Readhost LBA"
; --------------------------------------------------------------------
; Registers : temp2:temp host block to read/write (lba)
; temp3 disk #
-;
+;
; --------------------------------------------------------------------
-; Description:
+; Description:
; ====================================================================
dsk_rw_hostbuf:
+ ldiw y,fsys_vars
;xh:xl = host block to seek
- sts erflag,_0 ;no errors (yet)
+ std y+o_erflag,_0 ;no errors (yet)
; active host sector?
; host buffer active, same as seek buffer?
- lds _tmp0,hostdsk ;same disk?
+ ldd _tmp0,y+o_hostdsk ;same disk?
cp temp3,_tmp0 ;seekdsk = hostdsk?
brne dsk_nomatch
; same disk, same block?
- lds _tmp0,hostlba
- cp temp,_tmp0
- lds _tmp0,hostlba+1
+ ldd _tmp0,y+o_hostlba
+ cp temp, _tmp0
+ ldd _tmp0,y+o_hostlba+1
cpc temp2,_tmp0
breq dsk_match
; may have to fill the host buffer
dsk_filhst:
- sts hostlba,temp
- sts hostlba+1,temp2
- sts hostdsk,temp3
+ ldiw y,fsys_vars
+ std y+o_hostlba,temp
+ std y+o_hostlba+1,temp2
+ std y+o_hostdsk,temp3
sbic flags,rsflag ;need to read?
rcall dsk_readhost ;yes, if 1
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dsk_writehost:
- lds zl,hostdsk
- rcall dsk_getpartentry
- ld temp,z
- andi temp,dskType_MASK
-#if FAT16_SUPPORT
-; Is it a FAT16 Diskimage ?
- cpi temp,dskType_FAT
- brne PC+2
- rjmp fat_writehost
-#endif
+.if HOSTRW_DEBUG
+.if DISK_DEBUG == 0
+ printnewline
+ printstring "Host write: "
+.else
+ printstring ", hst WR "
+.endif
+.endif
-; Is it a CP/M Partition ?
- cpi temp,dskType_CPM
- brne PC+2
- rjmp cpm_writehost
-; Disktype not supported -> Return
+ rcall dsk_hostparam
+ breq dsk_hstwr_err
+
+ ldiw z,hostbuf
+ lcall mmcWriteSect
+ tst temp
+ brne dsk_hstwr_err
+
+dsk_hstwr_ok:
+ sts erflag,_0
+ ret
+
+dsk_hstwr_err:
+ sts erflag,_255
ret
; ====================================================================
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dsk_readhost:
-#if 0
+.if HOSTRW_DEBUG
+.if DISK_DEBUG == 0
printnewline
- printstring "readhost"
- ldiw z,biosdrvtbl
- rcall dbg_hexdump_line
- adiw z,16
- rcall dbg_hexdump_line
-#endif
-
+ printstring "Host read: "
+.else
+ printstring ", hst RD "
+.endif
+.endif
+
+ rcall dsk_hostparam
+ breq dsk_hstrd_err
+
+ ldiw z,hostbuf
+ lcall mmcReadSect
+ tst temp
+ brne dsk_hstrd_err
+
+dsk_hstrd_ok:
+ sts erflag,_0
+ ret
+
+dsk_hstrd_err:
+ sts erflag,_255
+ ret
+
+; ====================================================================
+; Function: Does a Disk write operation
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers : none
+; Variables : [r] seekdsk Number of Disk to Read
+; [r] seeksec Sector to read
+; [r] seektrk Track to read
+; hostdsk = host disk #, (partition #)
+; hostlba = host block #, relative to partition start
+; Read/Write "hostsize" bytes to/from hostbuf
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+
+dsk_hostparam:
+
lds zl,hostdsk
+
+.if HOSTRW_DEBUG
+ mov temp,zl
+ subi temp,-('A')
+ lcall uartputc
+.endif
rcall dsk_getpartentry
- ld temp,z
+ lds xl,hostlba ; get sector to access
+ lds xh,hostlba+1
+
+.if HOSTRW_DEBUG
+ printstring ": lba "
+ push r15
+ push r14
+ clr r14
+ clr r15
+ movw temp,x
+ lcall print_ultoa
+ pop r14
+ pop r15
+.endif
+
+ ldd _tmp0,z+PTAB_SIZE ; get disksize
+ ldd _tmp1,z+PTAB_SIZE+1
+
+ cp xl,_tmp0 ; check given sector against disksize
+ cpc xh,_tmp1
+ brcc dsk_hst_param_err
+
+ ldd temp,z+PTAB_TYPE
andi temp,dskType_MASK
#if FAT16_SUPPORT
; Is it a FAT16 Diskimage ?
cpi temp,dskType_FAT
- brne PC+2
- rjmp fat_readhost
+ brne dsk_hstpar_nofat
+ rcall fat_lba_to_phys
+ rjmp dsk_hstpar_gotit
+dsk_hstpar_nofat:
#endif
-
+#if CPMDSK_SUPPORT
; Is it a CP/M Partition ?
cpi temp,dskType_CPM
- brne PC+2
- rjmp cpm_readhost
-; Disktype not supported -> Return
+ brne dsk_hstpar_nocpm
+ lcall cpm_lba_to_phys
+ rjmp dsk_hstpar_gotit
+dsk_hstpar_nocpm:
+#endif
+; Disktype not supported
+ rjmp dsk_hst_param_err
+
+dsk_hstpar_gotit:
+
+.if HOSTRW_DEBUG
+ printstring ", abs "
+ push r15
+ push r14
+ push temp2
+ push temp
+ movw temp,x
+ movw r14,y
+ lcall print_ultoa
+ pop temp
+ pop temp2
+ pop r14
+ pop r15
+.endif
+
+ ori temp,255
ret
+dsk_hst_param_err:
-; vim:set ts=8 noet nowrap
+.if HOSTRW_DEBUG
+ printstring ", max: "
+ push r15
+ push r14
+ push temp2
+ push temp
+ movw temp,_tmp0
+ clr r14
+ clr r15
+ lcall print_ultoa
+ pop temp
+ pop temp2
+ pop r14
+ pop r15
+ printstring " "
+.endif
+
+ clr temp
+ ret
+; --------------------------------------------------------------------
+; vim:set ts=8 noet nowrap