X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/64ce65a196afbeec09018a6ad90d223f990d8050..e8384f88b1a073f47591b9ca13b73da12a7c59a8:/avr/dsk_fsys.asm diff --git a/avr/dsk_fsys.asm b/avr/dsk_fsys.asm index 228438f..4f9b226 100644 --- a/avr/dsk_fsys.asm +++ b/avr/dsk_fsys.asm @@ -1,6 +1,7 @@ ; 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. ; @@ -20,7 +21,6 @@ ; $Id$ ; -.equ DSKSEL_DEBUG = 0 ; ---------------- Defines for the Filesystem Interface ------- @@ -64,15 +64,12 @@ .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. @@ -81,6 +78,7 @@ biosdirbuf: .byte 2 ; 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. @@ -91,20 +89,35 @@ seekdsk: .byte 1 ;seek disk number 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) @@ -125,15 +138,14 @@ dbg_prdrvtbl: 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 @@ -148,19 +160,19 @@ dbg_print_biosd: 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 @@ -255,7 +267,7 @@ dskDiskCheck: .if DSKSEL_DEBUG printnewline printstring "DiskCheck: " - rcall printhexw + lcall printhexw .endif cpi temp,RAMDISKNR brsh dsk_dchrd ;maybe ramdisk @@ -299,7 +311,7 @@ dsk_dchpart1: .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 @@ -315,7 +327,7 @@ dsk_dchend: rcall dpb_drvtbl_entry_get printstring ", " - rcall printhexw + lcall printhexw pop temp .endif @@ -350,6 +362,7 @@ dsk_dchrd_err: ; -------------------------------------------------------------------- ; Description: ; ==================================================================== + dskErrorRet: lds temp,erflag ret @@ -359,10 +372,6 @@ dskErrorRet: ; ==================================================================== - .dseg -tmpdpb: .byte 16 - - .cseg str_CPM_Disk: .db 10,"",0 @@ -422,34 +431,6 @@ dpbdat_simhd: ; #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 @@ -586,10 +567,10 @@ dsk_tst_yaze: 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 @@ -609,6 +590,7 @@ dsk_tyze_not: ; Description: Test, if first 2 Sectors are filled with 0xE5, ; and Size = 8192KB + 256Bytes. ; ==================================================================== + dsk_tst_myz80: mov zl,temp3 @@ -630,6 +612,8 @@ dsk_tmyz80_loop: dec temp2 brne dsk_tmyz80_loop + ldiw z,dpbdat_myz80*2 + set ori temp,0xff ret @@ -650,6 +634,7 @@ dsk_tmyz80_not: ; 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 @@ -674,12 +659,13 @@ dsk_tsimhd_loop: 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 @@ -719,22 +705,19 @@ dsk_format_get: ; 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 @@ -756,32 +739,27 @@ dpb_imgdata_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 @@ -795,6 +773,20 @@ dpb_imgd_err: 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: ; ==================================================================== @@ -853,22 +845,43 @@ dpb_di_1: 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 @@ -879,8 +892,7 @@ 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 @@ -922,12 +934,13 @@ dpb_di_err: ; -------------------------------------------------------------------- ; 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 @@ -937,7 +950,7 @@ dsk_sdrvpl: lsl _tmp0 dec temp2 brne dsk_sdrvpl - sts secpblk,_tmp0 + std y+o_secpblk,_tmp0 ;Sectors per block ret @@ -946,58 +959,71 @@ dsk_sdrvpl: ; ==================================================================== ; 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 "Disk read: " + printstring "dsk RD: " rjmp dskdbg1 -dskdbgw: +dskdbgwrite: printnewline - printstring "Disk write: " + printstring "dsk WR: " + rjmp dskdbg1 +dskdbghome: + printnewline + printstring " HOME: " + rjmp dskdbg1 +dskdbgboot: + printnewline + 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 + printstring ": trk " + ldd temp2,y+o_seektrk+1 + ldd temp,y+o_seektrk lcall printhexw - printstring ", sector " - lds temp,seeksec + printstring ", sec " + ldd temp,y+o_seeksec lcall printhex - printstring ", dma-addr " - lds temp2,dmaadr+1 - lds temp,dmaadr + printstring ", dma " + ldd temp2,y+o_dmaadr+1 + ldd temp,y+o_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 + ;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 @@ -1008,10 +1034,10 @@ dskdbge: 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: @@ -1021,239 +1047,190 @@ 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 - -dsk_read_err: - ret + std y+o_wrtype,temp ;treat as unalloc + rjmp dsk_rw -; ==================================================================== -; 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) + + 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 - 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_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 + 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 -; 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 + 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 + ldiw z,hostbuf - 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 -.if DISK_DEBUG > 2 - movw temp,r0 - printstring "; host buf adr: " - lcall 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 @@ -1276,14 +1253,14 @@ dsk_rmove: 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 @@ -1304,11 +1281,13 @@ dsk_wdir1: ; -------------------------------------------------------------------- ; 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 @@ -1327,8 +1306,9 @@ dsk_readhost_lba: ; 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? @@ -1339,15 +1319,15 @@ dsk_rw_hostbuf: ; 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 @@ -1365,9 +1345,10 @@ dsk_nomatch: ; 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 @@ -1388,24 +1369,32 @@ dsk_match: ; -------------------------------------------------------------------- ; 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 ; ==================================================================== @@ -1420,36 +1409,146 @@ dsk_writehost: ; -------------------------------------------------------------------- ; 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