; 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.
;
; $Id$
;
-.equ DSKSEL_DEBUG = 0
; ---------------- Defines for the Filesystem Interface -------
; Fields in the parttabl
- .equ MAXDISKS = 8 ;Max number of Disks (partitions)
+ .equ MAXDISKS = 8 ;Max number of Disks (partitions)
.equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry
.equ PTAB_TYPE = 0
.equ WRUAL = 2 ;write to unallocated
.equ WRTMSK= 3 ;write type mask
- .equ READ_FUNC = 7
- .equ WRITE_FUNC = 6
- .equ BOOT_FUNC = 5
- .equ HOME_FUNC = 4
-
;----------------------------------------------- Start of Data Segment
.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
+ .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
secpblk: .byte 1 ;sectors per block (alloc size)
unacnt: .byte 1 ;unalloc rec cnt
unadsk: .byte 1 ;last unalloc disk
-unatrk: .byte 2 ;last unalloc track
-unasec: .byte 2 ;last unalloc sector
+unalba: .byte 2 ;last unalloc disk block
+ .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
- rcall printhexw
+ lcall printhexw
printstring "): "
ldi temp3,16
dbg_pcpel:
- rcall dram_readw_pp
- rcall printhexw
+ lcall dram_readw_pp
+ lcall printhexw
printstring " "
dec temp3
brne dbg_pcpel
printnewline
lds temp,bcbadr
lds temp2,bcbadr+1
- rcall printhexw
+ lcall printhexw
printstring " "
lds temp,biosdrvtbl
lds temp2,biosdrvtbl+1
- rcall printhexw
+ lcall printhexw
printstring " "
lds temp,biosdirbuf
lds temp2,biosdirbuf+1
- rcall printhexw
+ lcall printhexw
printstring " "
lds temp,biosenddat
lds temp2,biosenddat+1
- rcall printhexw
+ lcall printhexw
printstring " "
ret
.endif
.if DSKSEL_DEBUG
printnewline
printstring "DiskCheck: "
- rcall printhexw
+ lcall printhexw
.endif
cpi temp,RAMDISKNR
brsh dsk_dchrd ;maybe ramdisk
.if DSKSEL_DEBUG
printnewline
printstring "Select: "
- rcall printhex
+ lcall printhex
.endif
rcall dpb_drvtbl_entry_get
or temp,temp2 ;if !0, drive is allready initialized
rcall dpb_drvtbl_entry_get
printstring ", "
- rcall printhexw
+ lcall printhexw
pop temp
.endif
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dskErrorRet:
lds temp,erflag
ret
; ====================================================================
- .dseg
-tmpdpb: .byte 16
-
- .cseg
str_CPM_Disk:
.db 10,"<CPM_Disk>",0
#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
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
; Description: Test, if first 2 Sectors are filled with 0xE5,
; and Size = 8192KB + 256Bytes.
; ====================================================================
+
dsk_tst_myz80:
mov zl,temp3
dec temp2
brne dsk_tmyz80_loop
+ ldiw z,dpbdat_myz80*2
+ set
ori temp,0xff
ret
; 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
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
; Get first sector (512 byte) of current drive into hostbuf.
- push temp3
ldi temp,0
ldi temp2,0 ;
rcall dsk_readhost_lba
; 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:
- pop temp3
ret
; ====================================================================
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:
; ====================================================================
; --------------------------------------------------------------------
; Description: Init CP/M data structures
;
-; -----------------------------------------------------------------
-; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
-; -----------------------------------------------------------------
-;offset: 0 2 4 6 8 10 12 14
+; -----------------------------------------------------------------
+; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
+; -----------------------------------------------------------------
+;offset: 0 2 4 6 8 10 12 14
;
-; -------------------------------------------------------------
-; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
-; -------------------------------------------------------------
-;offset: 0 5 7 11 13
+; -------------------------------------------------------------
+; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
+; -------------------------------------------------------------
+;offset: 0 2 3 4 5 7 9 10 11 13
; ====================================================================
dpb_biosdph_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
; --------------------------------------------------------------------
; 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
+ 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
+ std y+o_secpblk,_tmp0 ;Sectors per block
ret
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seeksec Sector to read
-; [r] seektrk Track to read
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dskDoIt:
+
+ ldiw y,fsys_vars
+ std y+o_erflag,_0
+
.if DISK_DEBUG
push temp
+ sbrc temp,HOME_FUNC
+ rjmp dskdbghome
+ sbrc temp,BOOT_FUNC
+ rjmp dskdbgboot
+.if DISK_DEBUG > 1
sbrc temp,READ_FUNC
- rjmp dskdbgr
+ rjmp dskdbgread
sbrc temp,WRITE_FUNC
- rjmp dskdbgw
+ rjmp dskdbgwrite
+.endif
rjmp dskdbge
-dskdbgr:
+dskdbgread:
+ printnewline
+ printstring "dsk RD: "
+ rjmp dskdbg1
+dskdbgwrite:
+ printnewline
+ printstring "dsk WR: "
+ rjmp dskdbg1
+dskdbghome:
printnewline
- printstring "Disk read: "
+ printstring " HOME: "
rjmp dskdbg1
-dskdbgw:
+dskdbgboot:
printnewline
- printstring "Disk write: "
+ printstring " BOOT: "
dskdbg1:
- lds temp,seekdsk
+ ldd temp,y+o_seekdsk
subi temp,-('A')
rcall uartputc
- printstring ": track "
- lds temp2,seektrk+1
- lds temp,seektrk
- rcall printhexw
- printstring ", sector "
- lds temp,seeksec
- rcall printhex
- printstring ", dma-addr "
- lds temp2,dmaadr+1
- lds temp,dmaadr
- rcall printhexw
- pop temp
- push temp
- sbrs temp,WRITE_FUNC
- rjmp dskdbge
- printstring " wrtype "
- andi temp,3
- rcall printhex
+ printstring ": trk "
+ ldd temp2,y+o_seektrk+1
+ ldd temp,y+o_seektrk
+ lcall printhexw
+ printstring ", sec "
+ ldd temp,y+o_seeksec
+ lcall printhex
+ printstring ", dma "
+ ldd temp2,y+o_dmaadr+1
+ ldd temp,y+o_dmaadr
+ lcall printhexw
dskdbge:
- pop temp
+ pop temp
.endif
+
;See what has to be done.
sbrc temp,READ_FUNC
- rjmp dsk_read
+ rjmp dsk_readwrite
sbrc temp,WRITE_FUNC
- rjmp dsk_write
+ rjmp dsk_readwrite
sbrc temp,HOME_FUNC
rjmp dsk_home
sbrc temp,BOOT_FUNC
printstring "DISK I/O: Invalid Function code: "
lcall printhex
- rjmp haltinv
+ 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:
-; ====================================================================
-; Function: Does a Disk read operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : in: temp
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; --------------------------------------------------------------------
-; Description:
-; ====================================================================
-dsk_read:
- sts erflag,_0
- sbi flags,readop ; Set read operation flag
- ;RAM disk?
- lds zl,seekdsk
+dsk_readwrite:
+
+; RAM disk?
+
+ ldd zl,y+o_seekdsk
#if RAMDISKCNT
cpi zl,RAMDISKNR
- brlt PC+2
- rjmp rdsk_read
+ brlt dsk_rw_noramdisk
+ sbrc temp,WRITE_FUNC
+ rjmp rdsk_write
+ rjmp rdsk_read
+dsk_rw_noramdisk:
#endif
- rcall dsk_getpartentry ; Get Paritiontableentry
- ld temp,z ; Get Partitiontype
- andi temp,dskType_MASK
+ rcall dsk_getpartentry ;Get Paritiontableentry
+ ld temp2,z ;Get Partitiontype
+ andi temp2,dskType_MASK
; Isn't it a Disk ?
- cpi temp,dskType_None
+
+ cpi temp2,dskType_None
brne PC+2
- rjmp dsk_read_err
+ ret ;return error
; It must be a FAT16-Imagefile or CP/M Partition.
- rcall dsk_setdrvparam ;todo: do this only if needed (disk change)
+ sbrc temp,WRITE_FUNC
+ rjmp dsk_write
- sts unacnt,_0
+ sbi flags,readop ;Set read operation flag
sbi flags,rsflag ;must read data
+ std y+o_unacnt,_0
ldi temp,WRUAL ;write type
- sts wrtype,temp ;treat as unalloc
-
- rjmp dsk_rwoper ;to perform the read
+ std y+o_wrtype,temp ;treat as unalloc
+ rjmp dsk_rw
-dsk_read_err:
- ret
-
-; ====================================================================
-; Function: Does a Disk write operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : in: temp Write type
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; --------------------------------------------------------------------
-; Description:
-; ====================================================================
dsk_write:
- ;write the selected sector
- sts erflag,_0
- cbi flags,readop ; not a read operation
- ;RAM disk?
- lds zl,seekdsk
-#if RAMDISKCNT
- cpi zl,RAMDISKNR
- brlt PC+2
- rjmp rdsk_write
-#endif
- rcall dsk_getpartentry ; Get Paritiontableentry
- ld temp2,z ; Get Partitiontype
- andi temp2,dskType_MASK
+ cbi flags,readop ;Not a read operation
+ andi temp,WRTMSK
+ std y+o_wrtype,temp ;save write type
+dsk_rw:
+ rcall dsk_setdrvparam ;todo: do this only if needed (disk change)
-; Isn't it a Disk ?
- cpi temp2,dskType_None
- brne PC+2
- rjmp dsk_write_err
+; Convert track/sector to an LBA address (in 128byte blocks)
+ ldd xl,y+o_seeksec ;
+ ldi xh,0 ;
+ ldi temp2,0 ;
+ ldd temp,y+o_hdrsize ;add image header size
+ add xl,temp ;
+ adc xh,_0 ;
+ ldd temp,y+o_cpmspt ;
+ ldd _tmp0,y+o_seektrk ;
+ mul temp,_tmp0 ;
+ add xl,r0 ;
+ adc xh,r1 ;
+ 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
-; It must be a FAT16-Imagefile or CP/M Partition.
+; Convert from CP/M LBA blocks to host LBA blocks
- rcall dsk_setdrvparam ;TODO: do this only if needed (disk change)
+ ldi temp,SECSHF
+dsk_sh1:
+ lsr temp2
+ ror xh
+ ror xl
+ dec temp
+ brne dsk_sh1
+ ;todo: temp2 should be 0 here.
+ ;xh:xl = host block to seek
+;
+ sbic flags,readop
+ rjmp dsk_rwoper ;to perform the read
- andi temp,WRTMSK
- sts wrtype,temp ;save write type
+; Write operation
+ cbi flags,rsflag ;rsflag = 0
+ 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)
- sts unacnt,temp
- lds temp,seekdsk ;disk to seek
- sts unadsk,temp ;unadsk = sekdsk
- lds temp,seektrk
- sts unatrk,temp ;unatrk = sectrk
- lds temp,seektrk+1
- sts unatrk+1,temp ;unatrk = sectrk
- lds temp,seeksec
- sts unasec,temp ;unasec = seksec
-;
+; write to unallocated, set parameters
+
+ 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
+ ldd _tmp0,y+o_hdrsize ; in next bock
+ add temp,_tmp0 ; if there is a header
+dsk_una1:
+ 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:
- ;check for write to unallocated sector
- 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
+; 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,unatrk
- lds temp2,unatrk+1
- lds _tmp0,seektrk
- lds _tmp1,seektrk+1
- cp temp,_tmp0 ;seektrk = unatrk?
- cpc temp2,_tmp1
- brne dsk_alloc ;skip if not
+; disks are the same
-; tracks are the same
- lds temp,seeksec ;same sector?
- lds temp2,unasec
- cp temp,temp2 ;seeksec = unasec?
+ 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
-; match, move to next sector for future ref
- inc temp2 ;unasec = unasec+1
- sts unasec,temp2
- lds _tmp0,cpmspt
- cp temp2,_tmp0 ;end of track? (count CP/M sectors)
- brlo dsk_noovf ;skip if no overflow
-
-; overflow to next track
- sts unasec,_0 ;unasec = 0
- lds temp,unatrk
- lds temp2,unatrk+1
- subi temp, low(-1) ;unatrk = unatrk+1
- sbci temp2,high(-1)
- sts unatrk,temp
- sts unatrk+1,temp2
-;
+; block address is the same
+; move to next sector for future ref
+
+ mov temp,temp3
+ inc temp ;next part
+ andi temp,SECMSK
+ brne dsk_noovf ;skip if no overflow
+
+; overflow to next block
+
+ sub _tmp0,_255 ;unalba = unalba+1
+ sbc _tmp1,_255
+ std y+o_unalba, _tmp0
+ std y+o_unalba+1,_tmp1
+
dsk_noovf:
- cbi flags,rsflag ;rsflag = 0
rjmp dsk_rwoper ;to perform the write
-;
+
+; not an unallocated record, requires pre-read
+
dsk_alloc:
- ;not an unallocated record, requires pre-read
- sts unacnt,_0 ;unacnt = 0
+ std y+o_unacnt,_0 ;unacnt = 0
sbi flags,rsflag ;rsflag = 1
- rjmp dsk_rwoper
-dsk_write_err:
- ret
-; ====================================================================
-; Function: Does a Disk read/write operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; --------------------------------------------------------------------
-; Description:
-; ====================================================================
+; Enter here to perform the read/write
+
dsk_rwoper:
- ;enter here to perform the read/write
-.if DISK_DEBUG
- printstring ", flags: "
+
+.if DISK_DEBUG > 1
+ printstring ", flags|wtyp "
in temp,flags
- rcall printhex
+ cbr temp,WRTMSK
+ ldd _tmp0,y+o_wrtype
+ or temp,_tmp0
+ lcall printhex
+ printstring ", buf "
+ mov temp,temp3
+ lcall printhex
.endif
- ;Convert track/sector to an LBA address (in 128byte blocks)
- lds xl,seeksec ;
- ldi xh,0 ;
- ldi yl,0 ;
- lds temp,hdrsize ;add image header size
- add xl,temp ;
- adc xh,_0 ;
- lds temp,seektrk ;
- lds temp2,seektrk+1 ;
- lds temp3,cpmspt ;
- mul temp,temp3 ;
- add xl,r0 ;
- adc xh,r1 ;
- mul temp2,temp3 ;
- add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack
- adc yl,r1 ;
- mov temp,xl
- andi temp,SECMSK ;mask buffer number
- push temp ;save for later
-
- ;Convert from CP/M LBA blocks to host LBA blocks
- ldi temp,SECSHF
-dsk_sh1:
- lsr yl
- ror xh
- ror xl
- dec temp
- brne dsk_sh1
- ;todo: yl should be 0 here.
- ;xh:xl = host block to seek
+ 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
- ;copy data to or from buffer
ldiw z,hostbuf
-#if 1
- pop temp2 ;get buffer number (which part of hostbuf)
- clr temp
- lsr temp2 ;temp2:temp = temp2 * 128
- ror temp
- add zl,temp ;offset in hostbuf
- adc zh,temp2
-#else
- ldi temp,128
- pop temp2 ;get buffer number (which part of hostbuf)
- mul temp2,temp
+ ldi temp3,128
+ mul temp,temp3
add zl,r0 ;offset in hostbuf
adc zh,r1
-#endif
-.if DISK_DEBUG > 2
- movw temp,r0
- printstring "; host buf adr: "
- rcall printhexw
-.endif
- 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
-; mark write operation
+; mark write operation
sbi flags,hostwrt ;hostwrt = 1
dsk_wmove:
mem_read
adiw xl,1
dec temp3
brne dsk_rmove
+
dsk_rwmfin:
-; data has been moved to/from host buffer
- lds temp,wrtype ;write type
+; data has been moved to/from host buffer
+ 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:
-; clear host buffer for directory write
- lds temp,erflag
+ ldd temp,y+o_erflag
tst temp ;errors?
breq dsk_wdir1
ret ;skip if so
+
dsk_wdir1:
rcall dsk_writehost ;clear host buff
cbi flags,hostwrt ;buffer written
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dsk_readhost_lba:
-#if 0
+
+.if HOSTRW_DEBUG
printnewline
- printstring "readhst lba"
-#endif
+ printstring "Readhost LBA"
+.endif
sbi flags,rsflag ;must read data
rcall dsk_rw_hostbuf
lds temp,erflag ;returns 0, if ok
; 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?
-; active host sector?
in _tmp0,flags ;host active flag
sbi flags,hostact ;always becomes 1
sbrs _tmp0,hostact ;was it already?
rjmp dsk_filhst ;fill host if not
-; host buffer active, same as seek buffer?
- lds _tmp0,hostdsk ;same disk?
+; host buffer active, same as seek buffer?
+
+ 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
+; same disk, same block?
+
+ ldd _tmp0,y+o_hostlba
+ cp temp, _tmp0
+ ldd _tmp0,y+o_hostlba+1
cpc temp2,_tmp0
breq dsk_match
pop temp2
pop temp3
+; may have to fill the host buffer
dsk_filhst:
- ;may have to fill the host buffer
- 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
+ rcall 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:
+
+.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