; $Id$
;
-.equ DSKSEL_DEBUG = 0
; ---------------- Defines for the Filesystem Interface -------
.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
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
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
+unapart: .byte 1 ;last unalloc disk buffer part
erflag: .byte 1 ;error reporting
wrtype: .byte 1 ;write operation type
lds xl,biosdrvtbl
lds xh,biosdrvtbl+1
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
andi temp2,~dskType_MASK ;Lower nibble is image header size
sts hdrsize,temp2
ldd temp2,z+PTAB_SPT
- sts cpmspt,temp2
+ sts 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
+ sts secpblk,_tmp0 ;Sectors per block
ret
; ====================================================================
; Parameters
; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seeksec Sector to read
-; [r] seektrk Track to read
+; Registers :
+; Variables :
+;
; --------------------------------------------------------------------
; Description:
; ====================================================================
+
dskDoIt:
.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
subi temp,-('A')
rcall uartputc
- printstring ": track "
+ printstring ": trk "
lds temp2,seektrk+1
lds temp,seektrk
lcall printhexw
- printstring ", sector "
+ printstring ", sec "
lds temp,seeksec
lcall printhex
- printstring ", dma-addr "
+ printstring ", dma "
lds temp2,dmaadr+1
lds temp,dmaadr
lcall printhexw
- pop temp
- push temp
- sbrs temp,WRITE_FUNC
- rjmp dskdbge
- printstring " wrtype "
- andi temp,3
- lcall printhex
dskdbge:
- pop temp
+ pop temp
.endif
+
+ sts erflag,_0
+
;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
-; ====================================================================
-; 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?
+dsk_readwrite:
+
+; RAM disk?
+
lds zl,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
+ sts unacnt,_0
ldi temp,WRUAL ;write type
sts wrtype,temp ;treat as unalloc
+ rjmp dsk_rw
- rjmp dsk_rwoper ;to perform the read
-
-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
+ sts 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)
+ lds xl,seeksec ;
+ ldi xh,0 ;
+ ldi temp3,0 ;
+ lds temp,hdrsize ;add image header size
+ add xl,temp ;
+ adc xh,_0 ;
+ lds temp2,cpmspt ;
+ lds temp,seektrk ;
+ mul temp,temp2 ;
+ 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
-; 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 temp3
+ ror xh
+ ror xl
+ dec temp
+ brne dsk_sh1
+ ;todo: temp3 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
+ lds temp,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?
+ breq dsk_una1
+ sbi flags,rsflag ; no, rsflag = 1
subi temp,HOSTBLK ;don't write
lds _tmp0,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
- 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
+ sts unalba, xl ;unalba = seeklba (== hostlba)
+ sts unalba+1,xh
+
+; check for write to unallocated sector
dsk_chkuna:
- ;check for write to unallocated sector
+
lds temp,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?
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
+
+ lds temp,unalba
+ lds temp2,unalba+1
+ cp temp,xl ;seeklba = unalba?
+ cpc temp2,xh
brne dsk_alloc ;skip if not
-; tracks are the same
- lds temp,seeksec ;same sector?
- lds temp2,unasec
- cp temp,temp2 ;seeksec = unasec?
+; block address is the same
+
+ 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 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
+
+ inc temp3 ;next part
+ andi temp3,SECMSK
+ sts unapart,temp3
+ brne dsk_noovf ;skip if no overflow
+
+; overflow to next block
+
+ subi temp, low(-1) ;unalba = unalba+1
sbci temp2,high(-1)
- sts unatrk,temp
- sts unatrk+1,temp2
+ sts unalba,temp
+ sts unalba+1,temp2
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
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
+ cbr temp,WRTMSK
+ lds _tmp0,wrtype
+ or temp,_tmp0
+ lcall printhex
+ printstring ", buf "
+ lds temp,hostpart
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
movw temp,x
lds temp3,seekdsk
rcall dsk_rw_hostbuf
; copy data to or from buffer
+
ldiw z,hostbuf
- ldi temp,128
- pop temp2 ;get buffer number (which part of hostbuf)
- mul temp2,temp
+ lds temp,hostpart ;get buffer number (which part of hostbuf)
+ ldi temp2,128
+ mul temp,temp2
add zl,r0 ;offset in hostbuf
adc zh,r1
-.if DISK_DEBUG > 2
- movw temp,r0
- printstring "; host buf adr: "
- lcall printhexw
-.endif
lds xl,dmaadr
lds xh,dmaadr+1
; --------------------------------------------------------------------
; 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