;*****************************************************
;* Disk-Manager constants *
;*****************************************************
- .equ dskType_None = 0*16
- .equ dskType_CPM = 1*16
- .equ dskType_FAT = 2*16
-; .equ dskType_RAM = 3*16
- .equ dskType_MASK = 0xf*16
+
+; Fields in the parttabl
+
+ .equ MAXDISKS = 8 ;Max number of Disks (partitions)
+ .equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry
+
+ .equ PTAB_TYPE = 0
+ .equ PTAB_START = 1
+ .equ PTAB_SIZE = 5
+ .equ PTAB_SPT = 7
+ .equ PTAB_BSH = 8
+
+ .equ dskType_None = 0 << 4
+ .equ dskType_CPM = 1 << 4
+ .equ dskType_FAT = 2 << 4
+; .equ dskType_RAM = 3 << 4
+ .equ dskType_MASK = 0xf << 4
;*****************************************************
;* CP/M to host disk constants *
;*****************************************************
- .equ MAXDISKS = 8 ;Max number of Disks (partitions)
- .equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry
- .equ blksize = 1024 ;CP/M allocation size
- .equ hostsize = 512 ;host disk sector size
-; .equ hostspt = 20 ;host disk sectors/trk
- .equ hostblk = hostsize/128 ;CP/M sects/host buff
-; .equ CPMSPT = hostblk*hostspt ;CP/M sectors/track
- .equ CPMSPT = 26 ;
- .equ SECMSK = hostblk-1 ;sector mask
- .equ SECSHF = log2(hostblk) ;sector shift
+; .equ blksize = 1024 ;CP/M allocation size
+; .equ CPMSPT = 26 ;
+
+ .equ HOSTSIZE = 512 ;host disk sector size
+ .equ HOSTBLK = HOSTSIZE/128 ;CP/M sects/host buff
+ .equ SECMSK = HOSTBLK-1 ;sector mask
+ .equ SECSHF = log2(HOSTBLK) ;sector shift
;*****************************************************
;* BDOS constants on entry to write *
seeksec: .byte 2 ;seek sector number
dmaadr: .byte 2 ;last dma address
+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
erflag: .byte 1 ;error reporting
wrtype: .byte 1 ;write operation type
-hostbuf: .byte hostsize ;host buffer (from/to SD-card)
-hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
-hostparttbltop:
hostdsk: .byte 1 ;host disk number
-hosttype: .byte 1 ;host disk type (same entry as 1 parition entry)
hostlba: .byte 3 ;host sector number (relative to partition start)
+hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
+hostparttbltop:
+hostbuf: .byte HOSTSIZE ;host buffer (from/to SD-card)
; ------------------------------- Start of Code Segment
; Parameters
; --------------------------------------------------------------------
; Registers : [w] z Pointer to the Partitionentry
-; [r] xl Number of Diskentry to Read
+; [r] zl Number of Diskentry to Read
; [w] _tmp0 scratch
; [w] _tmp1 "
; --------------------------------------------------------------------
; ====================================================================
dsk_getpartentry:
- ldi zl,PARTENTRY_SIZE
- mul xl,zl
+ ldi zh,PARTENTRY_SIZE
+ mul zh,zl
ldiw z,hostparttbl
add zl,_tmp0
add zh,_tmp1
.dseg
-tmpdpb: .byte 15
+tmpdpb: .byte 16
.cseg
-; Test DPBs (avrcpm format)
+; DPBs for varios fixed formats
+; dpb data starts at 2. byte
+
+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 0xF2,0x00 ;disk size - 1,
+ .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 0xFF,0x07 ;disk size - 1,
+ .db 0xFF,0x03 ;dir max
+ .db 0xFF,0x00 ;alloc0, alloc1
+ .db 0x00,0x01 ;chk size
+ .db 0x00,0x00 ;offset
-dpblist:
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
-;dpb243
- .db 0x1A,0x00 ;spt
- .db 0x03,0x07 ;block shift, bock mask
- .db 0x00,0xF2 ;extent mask, low(disk size -1),
- .db 0x00,0x3F ;high(disk size -1), low(dir max)
- .db 0x00,0xC0 ;high(dir max), alloc0
- .db 0x00,0x10 ;alloc1, low(chk size)
- .db 0x00,0x02 ;high(chk size), low(offset)
- .db 0x00,0x00 ;high(offset), fill
#if 0
;rd1016
.db 0x20,0x00 ;spt
.db 0x00,0x00 ;high(offset), fill
#endif
-; Test
-dpb_copy:
- push zh
- push zl
+
+; Copy the dpb data in flash memory, pointed to by Z to temp ram.
+
+dpb_copy_p:
push yh
push yl
- ldiw z,dpblist*2
ldi temp2,16
- mul temp,temp2
- add zl,_tmp0
- adc zh,_tmp1
ldiw y,tmpdpb
-cpydpb_l:
+cpydpb_pl:
lpm temp,z+
st y+,temp
- cpi yl,low(tmpdpb + 15)
- brne cpydpb_l
+ dec temp2
+ brne cpydpb_pl
pop yl
pop yh
- pop zl
- pop zh
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
+
+
+; String compare (z, y), one z-string in flash.
+
+strcmp_p:
+ lpm _tmp0,z+
+ tst _tmp0
+ breq strcmp_pex
+
+ ld temp, y+
+ lpm _tmp0, z+
+ sub temp,_tmp0
+ brne strcmp_pex
+ tst _tmp0
+ brne strcmp_p
+strcmp_pex:
+ ret
+
+; String compare (x, y, temp2). Max temp2 bytes are compared.
+
+strncmp_p:
+ subi temp2,1
+ brcs strncmp_peq
+ ld temp,y+
+ lpm _tmp0, z+
+ sub temp,_tmp0
+ brne strncmp_pex
+ tst _tmp0
+ brne strncmp_p
+strncmp_peq:
+ sub temp,temp
+strncmp_pex:
+ ret
+
; ====================================================================
; Function: get drive table entry pointer for drive # in temp
; ====================================================================
; ====================================================================
-; Function: Clear drive table
+; Function: Clear drive table (entries 0 to 7)
; ====================================================================
; Parameters
; --------------------------------------------------------------------
; Description:
; ====================================================================
-; For now, only entries 1 - 7 are cleared.
+;
dpb_drvtblinit:
ldsw x,biosdrvtbl
- adiw x,2
- ldi temp3,7
+; adiw x,2
+ ldi temp3,8
dpb_drvi_l:
ldi temp,0
ldi temp2,0
clr temp
ret
+; ====================================================================
+; Function:
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers : temp drive #
+;
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+
+dsk_tst_avrcpmhd:
+ ori temp,0xff ; Test, return 'not found' for now.
+ ret
+
+
+; ====================================================================
+; Function: Test disk format: YAZE
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers : temp drive #
+;
+; --------------------------------------------------------------------
+; Description: From the YAZE Doc:
+;
+; The new disk header occupies the first 128 BYTES of the file and has the
+; new format:
+;
+; 0 - 9 <CPM_Disk>
+; 10 - 15 a null-terminated ascii comment (may be empty)
+; new 16 version (0 = yaze-1.06/1.10, 1 = yaze-ag-2.xx)
+; 17 - 31 a null-terminated ascii comment (may be empty)
+; 32 - 33 sectors per track
+; 34 block shift factor
+; 35 block mask
+; 36 extent mask
+; 37 - 38 disk size max
+; 39 - 40 directory max
+; 41 al0
+; 42 al1
+; 43 - 44 check size (always zero)
+; 45 - 46 track offset
+; new 47 psh (used if version=1 and CP/M 3.1 is running)
+; new 48 phm ( " " " " " " " " " )
+; 49 - 127 unused (zeros)
+; ====================================================================
+
+
+pstrn_YAZE:
+ .db 10,"<CPM_Disk>",0
+
+
+dsk_tst_yaze:
+
+ ldiw y,hostbuf
+ ldiw z,pstrn_YAZE*2
+ lpm temp2,z+ ; get length
+ rcall strncmp_p
+ brne dsk_tyze_not
+
+ ldiw z,hostbuf+32
+ ldiw y,tmpdpb
+ ldi temp,1 ;1 sector header size
+ rcall dpb_copy
+
+ clr temp
+ ret
+
+dsk_tyze_not:
+ ori temp,0xff ;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 = 8192 KB.
+; ====================================================================
+dsk_tst_myz80:
+
+ mov zl,temp3
+ rcall dsk_getpartentry ;get partition entry
+ ldd temp,z+PTAB_SIZE
+ ldd temp2,z+PTAB_SIZE+1 ;check, if (rounded) size is 8192KB
+ lsr temp2
+ ror temp
+ cpi temp,low(8192)
+ ldi temp,high(8192)
+ cpc temp2,temp
+ brne dsk_tmyz80_not ;wrong size
+
+ ldiw z,hostbuf
+ ldi temp2,0
+
+dsk_tmyz80_loop:
+ ld temp,z+
+ cpi temp,0xE5
+ brne dsk_tmyz80_not
+ dec temp2
+ brne dsk_tmyz80_loop
+
+ clr temp
+ ret
+
+dsk_tmyz80_not:
+ ori temp,0xff ;Not a MyZ80 hard disk image.
+ ret
+
+; ====================================================================
+; Function:
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers : temp drive #
+;
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+
+dsk_img_type:
+
+; todo: flush hostbuf!
+; todo: flush hostbuf!
+
+; Get first sector (512 byte) of current drive into hostbuf.
+
+ push temp3
+ mov temp3,temp
+ ldi temp,0
+ ldi temp2,0 ;
+ rcall dsk_readhost_lba
+
+ pop temp3
+ push temp3
+
+; Test for variable format avrcpmhd.
+
+ rcall dsk_tst_avrcpmhd
+ breq dsk_img_prep
+
+; Test for YAZE formats.
+
+ rcall dsk_tst_yaze
+ breq dsk_img_prep
+
+; Test for MyZ80 format.
+
+ rcall dsk_tst_myz80
+ ldiw z,dpbdat_myz80*2
+ breq dsk_img_fix
+
+; No special image found. Use avrcpm.
+
+ ldiw z,dpbdat_avrcpm*2
+
+dsk_img_fix:
+ rcall dpb_copy_p
+
+dsk_img_prep:
+
+ pop temp3
+ 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
+
+dsk_imgprp_err:
+ printnewline
+ ldi temp,'A'
+ add temp,temp3
+ call uartputc
+ printstring ": Format not supported: Too much sectors per track! "
+ printnewline
+
+ clr temp
+ ret
+
; ----------------------------------------------------------------------
; Init CP/M data structures
; temp = drive #
dpb_diskinit:
mov temp3,temp ;save disk #
+ rcall dsk_img_type
+ brne dpb_di_0
+ rjmp dpb_di_err
-; Test
- rcall dpb_copy
-
-
-
+dpb_di_0:
; get mem for DPH
; -----------------------------------------------------------------
breq dpb_di_err_p1
movw x,temp
- ldiw z,tmpdpb
+ ldiw z,tmpdpb+1 ;skip sector offset byte
dpb_dicpl:
ld temp,z+
rcall dram_write_pp
- cpi zl,low(tmpdpb + 15)
+ cpi zl,low(tmpdpb + 16)
brne dpb_dicpl
sbiw x,15
movw temp,x
; get mem for dir check vector
- lds temp,tmpdpb+11 ;cks
- lds temp2,tmpdpb+11+1
+ lds temp,tmpdpb+12 ;cks
+ lds temp2,tmpdpb+12+1
cp temp,_0
cpc temp2,_0
breq dpb_dicks0
; get mem for alloc vector
- lds temp,tmpdpb+5 ;dsm
- lds temp2,tmpdpb+5+1
+ lds temp,tmpdpb+6 ;dsm
+ lds temp2,tmpdpb+6+1
subi temp, low (-8)
sbci temp2,high(-8)
lsr temp2
rcall dpb_drvtbl_entry_p
movw temp,y
rcall dram_writew_pp
+
ori temp,0xff ;return ok
ret
eor temp,temp ;return 0 (+ Z-flag)
ret
+; ====================================================================
+; Function:
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers :
+;
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+dsk_setdrvparam:
+ ldd temp2,z+PTAB_TYPE
+ andi temp2,~dskType_MASK ;Lower nibble is image header size
+ sts hdrsize,temp2
+ ldd temp2,z+PTAB_SPT
+ sts cpmspt,temp2
+ ldd temp2,z+PTAB_BSH
+ swap temp2
+ andi temp2,0x0f
+ clr _tmp0
+ inc _tmp0
+dsk_sdrvpl:
+ lsl _tmp0
+ dec temp2
+ brne dsk_sdrvpl
+ sts secpblk,_tmp0
+ ret
+
; ====================================================================
; Function: Does a Disk interaction
rjmp haltinv
dsk_boot:
- sts ndisks,_0 ;no active partitions
-dsk_cboot:
- cbi flags,hostact ;host buffer inactive
- sts unacnt,_0 ;clear unalloc count
+ sts ndisks,_0 ;no active partitions
+dsk_inval_hostbuf:
+ cbi flags,hostact ;host buffer inactive
+ sts unacnt,_0 ;clear unalloc count
ret
dsk_home:
- sbis flags,hostwrt ;check for pending write
- cbi flags,hostact ;clear host active flag
+ sbis flags,hostwrt ;check for pending write
+ cbi flags,hostact ;clear host active flag
ret
sbi flags,readop ; Set read operation flag
;RAM disk?
- lds xl,seekdsk
+ lds zl,seekdsk
#if RAMDISKCNT
- cpi xl,RAMDISKNR
+ cpi zl,RAMDISKNR
brlt PC+2
rjmp rdsk_read
#endif
cpi temp,dskType_None
brne PC+2
rjmp dsk_read_err
+
; It must be a FAT16-Imagefile or CP/M Partition.
+
+ rcall dsk_setdrvparam ;todo: do this only if needed (disk change)
+
sts unacnt,_0
sbi flags,rsflag ;must read data
ldi temp,WRUAL ;write type
sts wrtype,temp ;treat as unalloc
+
rjmp dsk_rwoper ;to perform the read
dsk_read_err:
sts erflag,_0
cbi flags,readop ; not a read operation
;RAM disk?
- lds xl,seekdsk
+ lds zl,seekdsk
#if RAMDISKCNT
- cpi xl,RAMDISKNR
+ cpi zl,RAMDISKNR
brlt PC+2
rjmp rdsk_write
#endif
rcall dsk_getpartentry ; Get Paritiontableentry
- ld temp2,z ; Get Partitiontype
+ ld temp2,z ; Get Partitiontype
andi temp,dskType_MASK
; Isn't it a Disk ?
; It must be a FAT16-Imagefile or CP/M Partition.
+ rcall dsk_setdrvparam ;todo: do this only if needed (disk change)
+
cbi flags,readop ;not a read operation
andi temp,WRTMSK
- sts wrtype,temp ;save write type
+ sts wrtype,temp ;save write type
- cpi temp,WRUAL ;write unallocated?
- brne dsk_chkuna ;check for unalloc
+ cpi temp,WRUAL ;write unallocated?
+ brne dsk_chkuna ;check for unalloc
; write to unallocated, set parameters
- ldi temp,blksize/128 ;next unalloc recs
- 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
+ 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
;
dsk_chkuna:
;check for write to unallocated sector
- lds temp,unacnt ;any unalloc remain?
- tst temp
- breq dsk_alloc ;skip if not
+ 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?
- lds temp2,unadsk
- cp temp,temp2 ;seekdsk = unadsk?
- brne dsk_alloc ;skip if not
+ dec temp ;unacnt = unacnt-1
+ sts unacnt,temp
+ lds temp,seekdsk ;same disk?
+ lds temp2,unadsk
+ cp temp,temp2 ;seekdsk = unadsk?
+ brne dsk_alloc ;skip if not
; disks are the same
- lds temp,unatrk
- lds temp2,unatrk+1
- lds temp3,seektrk
- lds temp4,seektrk+1
- cp temp,temp3 ;seektrk = unatrk?
- cpc temp2,temp4
- brne dsk_alloc ;skip if not
+ lds temp,unatrk
+ lds temp2,unatrk+1
+ lds temp3,seektrk
+ lds temp4,seektrk+1
+ cp temp,temp3 ;seektrk = unatrk?
+ cpc temp2,temp4
+ brne dsk_alloc ;skip if not
; tracks are the same
- lds temp,seeksec ;same sector?
- lds temp2,unasec
- cp temp,temp2 ;seeksec = unasec?
- brne dsk_alloc ;skip if not
+ lds temp,seeksec ;same sector?
+ lds temp2,unasec
+ cp temp,temp2 ;seeksec = unasec?
+ brne dsk_alloc ;skip if not
; match, move to next sector for future ref
- inc temp2 ;unasec = unasec+1
- sts unasec,temp2
- cpi temp2,CPMSPT ;end of track? (count CP/M sectors)
- brlo dsk_noovf ;skip if no overflow
+ 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
+ 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
+ sts unatrk,temp
+ sts unatrk+1,temp2
;
dsk_noovf:
- cbi flags,rsflag ;rsflag = 0
- rjmp dsk_rwoper ;to perform the write
+ cbi flags,rsflag ;rsflag = 0
+ rjmp dsk_rwoper ;to perform the write
;
dsk_alloc:
;not an unallocated record, requires pre-read
- sts unacnt,_0 ;unacnt = 0
- sbi flags,rsflag ;rsflag = 1
+ sts unacnt,_0 ;unacnt = 0
+ sbi flags,rsflag ;rsflag = 1
rjmp dsk_rwoper
dsk_write_err:
;enter here to perform the read/write
.if DISK_DEBUG
printstring ", flags: "
- in temp,flags
+ in temp,flags
rcall printhex
.endif
- sts erflag,_0 ;no errors (yet)
+ sts erflag,_0 ;no errors (yet)
;Convert track/sector to an LBA address (in 128byte blocks)
- lds xl,seeksec ;
- ldi xh,0 ;
- ldi yl,0 ;
- lds temp3,seektrk ;
- lds temp4,seektrk+1 ;
- ldi temp,CPMSPT ;
- mul temp3,temp ;
- add xl,r0 ;
- adc xh,r1 ;
- mul temp4,temp ;
- 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
+ lds xl,seeksec ;
+ ldi xh,0 ;
+ ldi yl,0 ;
+ lds temp,hdrsize ;add image header size
+ add xl,temp ;
+ adc xh,_0 ;
+ lds temp3,seektrk ;
+ lds temp4,seektrk+1 ;
+ lds temp,cpmspt ;
+ mul temp3,temp ;
+ add xl,r0 ;
+ adc xh,r1 ;
+ mul temp4,temp ;
+ 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
+ ldi temp,SECSHF
dsk_sh1:
- lsr yl
- ror xh
- ror xl
- dec temp
+ lsr yl
+ ror xh
+ ror xl
+ dec temp
brne dsk_sh1
;yl:xh:xl = host block to seek
; active host sector?
- in _tmp0,flags ;host active flag
- sbi flags,hostact ;always becomes 1
+ 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
+ rjmp dsk_filhst ;fill host if not
; host buffer active, same as seek buffer?
- lds temp,seekdsk
- lds temp2,hostdsk ;same disk?
- cp temp,temp2 ;seekdsk = hostdsk?
+ lds temp,seekdsk
+ lds temp2,hostdsk ;same disk?
+ cp temp,temp2 ;seekdsk = hostdsk?
brne dsk_nomatch
; same disk, same block?
- lds temp,hostlba
- lds temp2,hostlba+1
- lds temp3,hostlba+2
- cp xl,temp
- cpc xh,temp2
- cpc yl,temp3
+ lds temp,hostlba
+ lds temp2,hostlba+1
+ lds temp3,hostlba+2
+ cp xl,temp
+ cpc xh,temp2
+ cpc yl,temp3
breq dsk_match
;
dsk_nomatch:
push xh
push yl
rcall dsk_writehost ;clear host buff
- pop yl
- pop xh
- pop xl
+ pop yl
+ pop xh
+ pop xl
dsk_filhst:
;may have to fill the host buffer
- lds temp,seekdsk
- sts hostdsk,temp
- sts hostlba,xl
- sts hostlba+1,xh
- sts hostlba+2,yl
+ lds temp,seekdsk
+ sts hostdsk,temp
+ sts hostlba,xl
+ sts hostlba+1,xh
+ sts hostlba+2,yl
sbic flags,rsflag ;need to read?
rcall dsk_readhost ;yes, if 1
- cbi flags,hostwrt ;no pending write
+ cbi flags,hostwrt ;no pending write
dsk_match:
;copy data to or from buffer
ldiw z,hostbuf
- ldi temp,128
- pop temp2 ;get buffer number (which part of hostbuf)
- mul temp2,temp
- add zl,r0 ;offset in hostbuf
- adc zh,r1
+ ldi temp,128
+ pop temp2 ;get buffer number (which part of hostbuf)
+ mul temp2,temp
+ add zl,r0 ;offset in hostbuf
+ adc zh,r1
.if DISK_DEBUG > 2
push r0
push r1
printstring "; host buf adr: "
- pop temp2
- pop temp
+ pop temp2
+ pop temp
rcall printhexw
.endif
- lds xl,dmaadr
- lds xh,dmaadr+1
- ldi temp3,128 ;length of move
+ lds xl,dmaadr
+ lds xh,dmaadr+1
+ ldi temp3,128 ;length of move
sbic flags,readop ;which way?
- rjmp dsk_rmove ;skip if read
+ rjmp dsk_rmove ;skip if read
; mark write operation
- sbi flags,hostwrt ;hostwrt = 1
+ sbi flags,hostwrt ;hostwrt = 1
dsk_wmove:
mem_read
- st z+,temp
+ st z+,temp
adiw xl,1
- dec temp3
+ dec temp3
brne dsk_wmove
rjmp dsk_rwmfin
dsk_rmove:
- ld temp,z+
+ ld temp,z+
mem_write
adiw xl,1
- dec temp3
+ dec temp3
brne dsk_rmove
dsk_rwmfin:
; data has been moved to/from host buffer
- lds temp,wrtype ;write type
- cpi temp,WRDIR ;to directory?
+ lds temp,wrtype ;write type
+ cpi temp,WRDIR ;to directory?
breq dsk_wdir
- ret ;no further processing
+ ret ;no further processing
dsk_wdir:
; clear host buffer for directory write
- lds temp,erflag
- tst temp ;errors?
+ lds temp,erflag
+ tst temp ;errors?
breq dsk_wdir1
- ret ;skip if so
+ ret ;skip if so
dsk_wdir1:
rcall dsk_writehost ;clear host buff
- cbi flags,hostwrt ;buffer written
+ cbi flags,hostwrt ;buffer written
ret
+; ====================================================================
+; Function:
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers : temp2:temp block to read (lba)
+; temp3 disk #
+;
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+dsk_readhost_lba:
+ sts hostlba+0,temp
+ sts hostlba+1,temp2
+ sts hostlba+2,_0
+ sts hostdsk,temp3
+#if 0
+ printnewline
+ printstring "readhst lba"
+#endif
+ rjmp dsk_readhost ;returns 0, if ok
+
+
; ====================================================================
; Function: Does a Disk write operation
; ====================================================================
; Description:
; ====================================================================
dsk_writehost:
- lds xl,hostdsk
+ lds zl,hostdsk
rcall dsk_getpartentry
ld temp,z
andi temp,dskType_MASK
; Description:
; ====================================================================
dsk_readhost:
- lds xl,hostdsk
+
+#if 0
+ printnewline
+ printstring "readhost"
+ ldiw z,biosdrvtbl
+ rcall dbg_hexdump_line
+ adiw z,16
+ rcall dbg_hexdump_line
+#endif
+
+ lds zl,hostdsk
rcall dsk_getpartentry
ld temp,z
andi temp,dskType_MASK