X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/b741422ef658ff493a77618efc302ee1cad07ab3..50302378a423ed3275f0b6a5cfd11486635c1ca2:/avrcpm/avr/dsk_fsys.asm diff --git a/avrcpm/avr/dsk_fsys.asm b/avrcpm/avr/dsk_fsys.asm index 018aeba..1f3a195 100644 --- a/avrcpm/avr/dsk_fsys.asm +++ b/avrcpm/avr/dsk_fsys.asm @@ -20,31 +20,31 @@ ; $Id$ ; +.equ DSKSEL_DEBUG = 0 ; ---------------- Defines for the Filesystem Interface ------- - ;***************************************************** ;* Disk-Manager constants * ;***************************************************** - .equ dskType_None = 0 + .equ dskType_None = 0 .equ dskType_CPM = 1 .equ dskType_FAT = 2 - .equ dskType_RAM = 3 +; .equ dskType_RAM = 3 ;***************************************************** ;* CP/M to host disk constants * ;***************************************************** - .equ MAXDISKS = 4 ;Max number of Disks (partitions) + .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 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 SECSHF = log2(hostblk) ;sector shift ;***************************************************** ;* BDOS constants on entry to write * @@ -53,36 +53,106 @@ .equ WRDIR = 1 ;write to directory .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 -ndisks: .byte 1 ;Number of CP/M disks +; The following 3 variables are copied from DRAM. +; Don't change order. + +biosdrvtbl: .byte 2 ; +biosdirbuf: .byte 2 ; +biosenddat: .byte 2 ; -seekdsk: .byte 1 ;seek disk number -seektrk: .byte 2 ;seek track number -seeksec: .byte 1 ;seek sector number +ndisks: .byte 1 ;Number of CP/M disks -unacnt: .byte 1 ;unalloc rec cnt -unadsk: .byte 1 ;last unalloc disk -unatrk: .byte 2 ;last unalloc track -unasec: .byte 1 ;last unalloc sector +; The following 5 variables are accessed from 8080/z80 via the +; virtual port interface. Don't change order. -erflag: .byte 1 ;error reporting -wrtype: .byte 1 ;write operation type -dmaadr: .byte 2 ;last dma address +biospar_base: +bcbadr: .byte 2 ;adr of BiosControlBlock +seekdsk: .byte 1 ;seek disk number +seektrk: .byte 2 ;seek track number +seeksec: .byte 2 ;seek sector number +dmaadr: .byte 2 ;last dma address -hostbuf: .byte hostsize ;host buffer (from/to SD-card) +unacnt: .byte 1 ;unalloc rec cnt +unadsk: .byte 1 ;last unalloc disk +unatrk: .byte 2 ;last unalloc track +unasec: .byte 1 ;last unalloc sector + +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) +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) ; ------------------------------- Start of Code Segment .cseg +;--------------------------------------------------------------------- + +.if DSKSEL_DEBUG + +dbg_prdrvtbl: + push xh + push xl + push temp3 + push temp2 + push temp + printnewline + printstring "drvtbl (" + lds xl,biosdrvtbl + lds xh,biosdrvtbl+1 + movw temp,x + rcall printhexw + printstring "): " + ldi temp3,16 +dbg_pcpel: + rcall dram_readw_pp + rcall printhexw + printstring " " + dec temp3 + brne dbg_pcpel + pop temp + pop temp2 + pop temp3 + pop xl + pop xh + ret + +dbg_print_biosd: + printnewline + lds temp,bcbadr + lds temp2,bcbadr+1 + rcall printhexw + printstring " " + lds temp,biosdrvtbl + lds temp2,biosdrvtbl+1 + rcall printhexw + printstring " " + lds temp,biosdirbuf + lds temp2,biosdirbuf+1 + rcall printhexw + printstring " " + lds temp,biosenddat + lds temp2,biosenddat+1 + rcall printhexw + printstring " " + ret +.endif + ; ==================================================================== ; Function: Get a Pointer to a Partitiontable entry ; ==================================================================== @@ -90,96 +160,458 @@ hostlba: .byte 3 ;host sector number (relative to partition start) ; -------------------------------------------------------------------- ; Registers : [w] z Pointer to the Partitionentry ; [r] xl Number of Diskentry to Read +; [w] _tmp0 scratch +; [w] _tmp1 " ; -------------------------------------------------------------------- ; Description: ; ==================================================================== dsk_getpartentry: + ldi zl,PARTENTRY_SIZE + mul xl,zl ldiw z,hostparttbl - mov temp,xl + add zl,_tmp0 + add zh,_tmp1 + ret + +; ==================================================================== +; Function: Virtual Port Interface +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; +; -------------------------------------------------------------------- +; Description: +; ==================================================================== + +dsk_param_getadr: + ldiw z,biospar_base + add zl,temp3 + adc zh,_0 + ret + +dsk_param_wr: + rcall dsk_param_getadr + st z,temp + cpi temp3,bcbadr+1-seektrk + brne dsk_param_wr1 + std z+1,_0 +dsk_param_wr1: + cpi temp3,bcbadr+1-biospar_base + breq SetBCB + ret + +dsk_param_rd: + cpi temp3,seekdsk-biospar_base + breq dskDiskCheck + rcall dsk_param_getadr + ld temp,z + ret + +SetBCB: + lds xl,bcbadr + mov xh,temp + ldiw z,biosdrvtbl + ldi temp3,6 +sbcb_l: + rcall dram_read_pp + st z+,temp + dec temp3 + brne sbcb_l + +; rcall dbg_print_biosd + rcall dsk_drvtblinit +; rcall dbg_prdrvtbl -dsk_getpartentryloop: - cp temp,_0 - breq dsk_getpartentryloopend - adiw z,PARTENTRY_SIZE - dec temp - rjmp dsk_getpartentryloop -dsk_getpartentryloopend: ret ; ==================================================================== -; Function: +; Function: Check if disk exists ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : none -; Variables : [r] seeksec Sector to read -; [r] seektrk Track to read +; Registers : +; Variables : +; return 0, if selected disk not exist. +; return !0, if disk exist ; -------------------------------------------------------------------- ; Description: ; ==================================================================== dskDiskCheck: - lds temp2,seekdsk - cpi temp2,RAMDISKNR + lds temp,ndisks + lds temp2,seekdsk +.if DSKSEL_DEBUG + printnewline + printstring "DiskCheck: " + rcall printhexw +.endif + cpi temp2,RAMDISKNR brsh dsk_dchrd ;maybe ramdisk ; Check if selected disk # is less then # of disks. - lds temp,ndisks - tst temp + lds temp,ndisks + tst temp ;0 disks? brne dsk_dchpart1 -; Need to init +; No disks yet, need to init - rcall mgr_init_partitions - cbr temp,0x80 - lds temp2,seekdsk + rcall mgr_init_partitions ;disk chanched? +; sbrs temp,7 +; rjmp dsk_dchpart0 + push temp + rcall dsk_drvtblinit +; rcall dbg_prdrvtbl + pop temp +dsk_dchpart0: + cbr temp,0x80 + lds temp2,seekdsk dsk_dchpart1: - cp temp2,temp - brsh dsk_dcher + cp temp2,temp + brsh dsk_dch_err + +.if DSKSEL_DEBUG + printnewline + printstring "Select: " + mov temp,temp2 + rcall printhex +.endif + ldsw x,biosdrvtbl + lsl temp2 ;drive # + add xl,temp2 + adc xh,_0 + rcall dram_readw_pp ;get drive table entry + + or temp,temp2 ;if !0, drive is allready initialized + brne dsk_dchend + lds temp,seekdsk + rcall dsk_diskinit dsk_dchend: - ldi temp,0 +.if DSKSEL_DEBUG + push temp + ldsw x,biosdrvtbl + lds temp,seekdsk + lsl temp ;drive # + add xl,temp + adc xh,_0 + rcall dram_readw_pp + printstring ", " + rcall printhexw + pop temp +.endif + ret +dsk_dch_err: + ldi temp,0 ;error return + ret + +; Check RAMDISK + dsk_dchrd: #if RAMDISKCNT - cpi temp,RAMDISKNR+RAMDISKCNT - brlo dsk_dchend + cpi temp,RAMDISKNR+RAMDISKCNT + brsh dsk_dchrd_err + + ldi temp,0xff ;return ok + ret #endif -dsk_dcher: - ldi temp,0xff ;error return +dsk_dchrd_err: + ldi temp,0 ;error return ret - + + +; ==================================================================== +; Function: Return status of last disk i/o function +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; -------------------------------------------------------------------- +; Description: +; ==================================================================== dskErrorRet: - lds temp,erflag + lds temp,erflag ret -dskDiskSel: - sts seekdsk,temp - ret + +; ------------------------------------------------------------------- -dskTrackSel_l: - sts seektrk,temp - sts seektrk+1,_0 - ret -dskTrackSel_h: - sts seektrk+1,temp + .dseg +tmpdpb: .byte 15 + + .cseg + +; Test DPBs (avrcpm format) + +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 0x04,0x0F ;block shift, bock mask + .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) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +;rd9192s + .db 0x20,0x00 ;spt + .db 0x05,0x1F ;block shift, bock mask + .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) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +#endif + +; Test +cpy_dpb: + push zh + push zl + 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: + lpm temp,z+ + st y+,temp + cpi yl,low(tmpdpb + 15) + brne cpydpb_l + pop yl + pop yh + pop zl + pop zh ret + +; ==================================================================== +; Function: Clear drive table +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; +; -------------------------------------------------------------------- +; Description: +; ==================================================================== -dskSecSel: - sts seeksec,temp +; For now, only entries 1 - 7 are cleared. + +dsk_drvtblinit: + ldsw x,biosdrvtbl + adiw x,2 + ldi temp3,7 +dsk_drvi_l: + ldi temp,0 + ldi temp2,0 + rcall dram_writew_pp + dec temp3 + brne dsk_drvi_l + + lds temp,biosenddat + lds temp2,biosenddat+1 + rcall heap_init + clr temp ret -dskDmal: - sts dmaadr,temp + +; ---------------------------------------------------------------------- +; Init CP/M data structures +; temp = drive # +; +; return !0 if ok +; 0 on error + + +dsk_diskinit: + mov temp3,temp ;save disk # + + +; Test + rcall cpy_dpb + + + + +; get mem for DPH +; ----------------------------------------------------------------- +; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV | +; ----------------------------------------------------------------- +;(offset) 0 2 4 6 8 10 12 14 + + ldi temp, low (16) + ldi temp2,high(16) + rcall heap_get + brne dsk_di_1 + rjmp dsk_di_err ; +dsk_di_1: + movw x,temp + movw y,temp + ldi temp,0 + ldi temp2,0 + rcall dram_writew_pp ;XLT + adiw x,6 + lds temp,biosdirbuf + lds temp2,biosdirbuf+1 + rcall dram_writew_pp ;DIRBUF + +; get mem for DPB +; ------------------------------------------------------------- +; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF | +; ------------------------------------------------------------- +; 0 5 7 11 13 + + ldi temp, low (15) + ldi temp2,high(15) + rcall heap_get + breq dsk_di_err_p1 + movw x,temp + + ldiw z,tmpdpb +dsk_dicpl: + ld temp,z+ + rcall dram_write_pp + cpi zl,low(tmpdpb + 15) + brne dsk_dicpl + sbiw x,15 + movw temp,x + movw x,y + adiw x,10 + rcall dram_writew_pp ;DPB + +; get mem for dir check vector + + lds temp,tmpdpb+11 ;cks + lds temp2,tmpdpb+11+1 + cp temp,_0 + cpc temp2,_0 + breq dsk_dicks0 + rcall heap_get + breq dsk_di_err_p1 +dsk_dicks0: + rcall dram_writew_pp ;CSV + +; get mem for alloc vector + + lds temp,tmpdpb+5 ;dsm + lds temp2,tmpdpb+5+1 + subi temp, low (-8) + sbci temp2,high(-8) + lsr temp2 + ror temp + lsr temp2 + ror temp + lsr temp2 + ror temp ;(dsm+1+7)/8 + rcall heap_get + breq dsk_di_err_p1 + rcall dram_writew_pp ;ALV + +; success, insert DPH into drvtbl + + lds xl,biosdrvtbl + lds xh,biosdrvtbl+1 + lsl temp3 ;drive # + add xl,temp3 + adc xh,_0 + movw temp,y + rcall dram_writew_pp + ori temp,0xff ;return ok ret -dskDmah: - sts dmaadr+1,temp +; error, free mem + +dsk_di_err_p1: + movw temp,y + rcall heap_release +dsk_di_err: + eor temp,temp ;return 0 (+ Z-flag) ret + ; ==================================================================== ; Function: Does a Disk interaction @@ -266,7 +698,7 @@ dsk_home: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : none +; Registers : in: temp ; Variables : [r] seekdsk Number of Disk to Read ; [r] seeksec Sector to read ; [r] seektrk Track to read @@ -276,7 +708,14 @@ dsk_home: dsk_read: sts erflag,_0 sbi flags,readop ; Set read operation flag + + ;RAM disk? lds xl,seekdsk +#if RAMDISKCNT + cpi xl,RAMDISKNR + brlt PC+2 + rjmp rdsk_read +#endif rcall dsk_getpartentry ; Get Paritiontableentry ld temp,z ; Get Partitiontype @@ -284,10 +723,6 @@ dsk_read: cpi temp,dskType_None brne PC+2 rjmp dsk_read_err -; Is it a RamDisk ? - cpi temp,dskType_RAM - brne PC+2 - rjmp rdsk_read ; It must be a FAT16-Imagefile or CP/M Partition. sts unacnt,_0 sbi flags,rsflag ;must read data @@ -303,7 +738,7 @@ dsk_read_err: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : none +; Registers : in: temp Write type ; Variables : [r] seekdsk Number of Disk to Read ; [r] seeksec Sector to read ; [r] seektrk Track to read @@ -314,19 +749,21 @@ dsk_write: ;write the selected sector sts erflag,_0 cbi flags,readop ; not a read operation + ;RAM disk? lds xl,seekdsk +#if RAMDISKCNT + cpi xl,RAMDISKNR + brlt PC+2 + rjmp rdsk_write +#endif rcall dsk_getpartentry ; Get Paritiontableentry - ld temp,z ; Get Partitiontype + ld temp2,z ; Get Partitiontype ; Isn't it a Disk ? - cpi temp,dskType_None + cpi temp2,dskType_None brne PC+2 rjmp dsk_write_err -; Is it a RamDisk ? - cpi temp,dskType_RAM - brne PC+2 - rjmp rdsk_write ; It must be a FAT16-Imagefile or CP/M Partition.