X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/64ce65a196afbeec09018a6ad90d223f990d8050..12a27f27734b18ba4dea8d411095cf53c3870ef2:/avr/dsk_fsys.asm diff --git a/avr/dsk_fsys.asm b/avr/dsk_fsys.asm index 228438f..0081468 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 @@ -143,28 +155,28 @@ dbg_pcpel: pop xl pop xh ret - + 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 - + ; ==================================================================== ; ==================================================================== ; Function: Get a Pointer to a Partitiontable entry @@ -179,7 +191,7 @@ dbg_print_biosd: ; Description: ; ==================================================================== dsk_getpartentry: - + ldi zh,PARTENTRY_SIZE mul zh,zl ldiw z,hostparttbl @@ -193,13 +205,13 @@ dsk_getpartentry: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : -; Variables : -; +; Registers : +; Variables : +; ; -------------------------------------------------------------------- ; Description: ; ==================================================================== - + dsk_param_getadr: ldiw z,biospar_base add zl,temp3 @@ -230,7 +242,7 @@ sbcb_l: st z+,temp dec temp3 brne sbcb_l - + ; rcall dbg_print_biosd rcall dpb_drvtblclear ; rcall dbg_prdrvtbl @@ -242,8 +254,8 @@ sbcb_l: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : -; Variables : +; Registers : +; Variables : ; return 0, if selected disk not exist. ; return !0, if disk exist ; -------------------------------------------------------------------- @@ -255,7 +267,7 @@ dskDiskCheck: .if DSKSEL_DEBUG printnewline printstring "DiskCheck: " - rcall printhexw + lcall printhexw .endif cpi temp,RAMDISKNR brsh dsk_dchrd ;maybe ramdisk @@ -271,13 +283,13 @@ dskDiskCheck: ldi temp,1 lcall clockput .endif - rcall mgr_init_partitions ;disk chanched? + rcall mgr_init_partitions ;disk changed? push temp .if 0 ldi temp2,0x40 ldi temp,2 lcall clockput -; sbrs temp,7 +; sbrs temp,7 ; rjmp dsk_dchpart0 lcall mgr_prnt_parttbl @@ -289,7 +301,7 @@ dskDiskCheck: dsk_dchpart0: cbr temp2,0x80 lds temp,seekdsk - + ; Check if selected disk # is less then # of disks. dsk_dchpart1: @@ -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,16 +327,16 @@ dsk_dchend: rcall dpb_drvtbl_entry_get printstring ", " - rcall printhexw + lcall printhexw pop temp -.endif +.endif ret dsk_dch_err: ldi temp,0 ;error return - ret - + ret + ; Check RAMDISK dsk_dchrd: @@ -345,24 +357,21 @@ dsk_dchrd_err: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : -; Variables : +; Registers : +; Variables : ; -------------------------------------------------------------------- ; Description: ; ==================================================================== + dskErrorRet: lds temp,erflag ret - + ; ==================================================================== ; ==================================================================== - .dseg -tmpdpb: .byte 16 - - .cseg str_CPM_Disk: .db 10,"",0 @@ -372,39 +381,39 @@ str_CPM_Disk: 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 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 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 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,0x03 ;dir max .db 0xFF,0x00 ;alloc0, alloc1 .db 0x00,0x01 ;chk size .db 0x00,0x00 ;offset dpbdat_simhd: ; .db 0x00,0x20 ;sector offset, low(spt) - .db 0x00,0x05 ;high (spt), block shift - .db 0x1F,0x01 ;bock mask, extent mask + .db 0x00,0x05 ;high (spt), block shift + .db 0x1F,0x01 ;bock mask, extent mask .db 0xF9,0x07 ;disk size - 1, - .db 0xFF,0x03 ;dir max + .db 0xFF,0x03 ;dir max .db 0xFF,0x00 ;alloc0, alloc1 .db 0x00,0x01 ;chk size .db 0x06,0x00 ;offset #if 0 -;rd1016 +;rd1016 .db 0x20,0x00 ;spt .db 0x04,0x0F ;block shift, bock mask - .db 0x00,0xFB ;extent mask, low(disk size -1), + .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) @@ -413,7 +422,7 @@ dpbdat_simhd: ; ;rd9192s .db 0x20,0x00 ;spt .db 0x05,0x1F ;block shift, bock mask - .db 0x01,0xFD ;extent mask, low(disk size -1), + .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) @@ -422,43 +431,15 @@ 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 ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : -; Variables : -; +; Registers : +; Variables : +; ; -------------------------------------------------------------------- ; Description: ; ==================================================================== @@ -470,16 +451,16 @@ dpb_drvtbl_entry_p: add xl,temp adc xh,_0 ret - + ; ==================================================================== ; Function: get drive table entry for drive # in temp ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : -; Variables : -; +; Registers : +; Variables : +; ; -------------------------------------------------------------------- ; Description: ; ==================================================================== @@ -487,7 +468,7 @@ dpb_drvtbl_entry_p: dpb_drvtbl_entry_get: rcall dpb_drvtbl_entry_p - ljmp dram_readw_pp + ljmp dram_readw_pp ; ==================================================================== @@ -495,9 +476,9 @@ dpb_drvtbl_entry_get: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : -; Variables : -; +; Registers : +; Variables : +; ; -------------------------------------------------------------------- ; Description: ; ==================================================================== @@ -508,7 +489,7 @@ dpb_drvtblclear: ldsw x,biosdrvtbl sbiw x,0 breq dpb_drvi_ex - + dpb_drvi_1: ldi temp3,8 dpb_drvi_lp: @@ -517,7 +498,7 @@ dpb_drvi_lp: rcall dram_writew_pp dec temp3 brne dpb_drvi_lp - + lds temp,biosenddat lds temp2,biosenddat+1 cp temp,_0 @@ -535,7 +516,7 @@ dpb_drvi_ex: ; Parameters ; -------------------------------------------------------------------- ; Registers : temp drive # -; +; ; -------------------------------------------------------------------- ; Description: Not implemented yet. ; ==================================================================== @@ -551,7 +532,7 @@ dsk_tst_avrcpmhd: ; Parameters ; -------------------------------------------------------------------- ; Registers : temp drive # -; +; ; -------------------------------------------------------------------- ; Description: From the YAZE Doc: ; @@ -585,11 +566,11 @@ dsk_tst_yaze: lpm temp2,z+ ; get length 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 @@ -597,18 +578,19 @@ dsk_tst_yaze: dsk_tyze_not: clr temp ;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 = 8192KB + 256Bytes. ; ==================================================================== + dsk_tst_myz80: mov zl,temp3 @@ -619,10 +601,10 @@ dsk_tst_myz80: ldi temp,high(16385) cpc temp2,temp brne dsk_tmyz80_not ;wrong size - + ldiw z,hostbuf ldi temp2,0 - + dsk_tmyz80_loop: ld temp,z+ cpi temp,0xE5 @@ -630,26 +612,29 @@ dsk_tmyz80_loop: dec temp2 brne dsk_tmyz80_loop + ldiw z,dpbdat_myz80*2 + set ori temp,0xff ret dsk_tmyz80_not: clr temp ;Not a MyZ80 hard disk image. ret - + ; ==================================================================== ; Function: Test disk format: simhd, simh altair 8800 hard disk format ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- ; Registers : temp drive # -; +; ; -------------------------------------------------------------------- -; Description: Test, if Size = 8192 KB and +; Description: Test, if Size = 8192 KB and ; first 6 tracks are filled with 0xE5. -; Actually, only the first phys. sector is tested, since +; 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 @@ -660,13 +645,13 @@ dsk_tst_simhd: ldi temp,high(16384) cpc temp2,temp brne dsk_tsimhd_not ;wrong size - + ldiw y,hostbuf+128-10 ldiw z,str_CPM_Disk*2 lpm temp2,z+ ; get length lcall strncmp_p breq dsk_tsimhd_found - + ldiw z,hostbuf ldi temp2,high(512) clr _tmp0 ;low(512) @@ -674,26 +659,27 @@ 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 dsk_tsimhd_not: clr temp ;Not a simhd hard disk image. ret - + ; ==================================================================== -; Function: +; Function: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- ; Registers : temp3 drive # -; +; ; -------------------------------------------------------------------- ; Description: ; ==================================================================== @@ -702,10 +688,10 @@ dsk_format_get: ; Get first sector (512 byte) of current drive into hostbuf. - ldi temp,0 + ldi temp,0 ldi temp2,0 ; rcall dsk_readhost_lba - + ; Test for variable format avrcpmhd. rcall dsk_tst_avrcpmhd @@ -719,24 +705,21 @@ 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 + ret ; ==================================================================== ; Function: Add CP/M image format data to partition table data @@ -744,44 +727,39 @@ dsk_imgt_done: ; Parameters ; -------------------------------------------------------------------- ; Registers : temp3 drive # -; +; ; -------------------------------------------------------------------- ; Description: ; ==================================================================== dpb_imgdata_get: -; Test for known CP/M formats +; Test for known CP/M formats - rcall dsk_format_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,17 +773,31 @@ 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: +; Function: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- ; Registers : temp drive # -; +; ; return !0 if ok ; 0 on error ; -------------------------------------------------------------------- -; Description: Init CP/M data structures +; Description: Init CP/M data structures ; ; ----------------------------------------------------------------- ; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV | @@ -815,19 +807,19 @@ dpb_imgd_err: ; ------------------------------------------------------------- ; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF | ; ------------------------------------------------------------- -;offset: 0 2 3 4 5 7 9 10 11 13 +;offset: 0 2 3 4 5 7 9 10 11 13 ; ==================================================================== dpb_biosdph_get: mov temp3,temp ;save disk # - rcall dsk_format_get + rcall dsk_format_get brne dpb_di_0 rjmp dpb_di_err dpb_di_0: -; get mem for DPH +; get mem for DPH ldi temp, low (16) ldi temp2,high(16) @@ -845,30 +837,51 @@ dpb_di_1: lds temp2,biosdirbuf+1 rcall dram_writew_pp ;DIRBUF -; get mem for DPB - +; get mem for DPB + ldi temp, low (15) ldi temp2,high(15) rcall heap_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 @@ -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 @@ -898,7 +910,7 @@ dpb_dicks0: mov temp,temp3 rcall dpb_drvtbl_entry_p movw temp,y - rcall dram_writew_pp + rcall dram_writew_pp ori temp,0xff ;return ok ret @@ -911,23 +923,24 @@ dpb_di_err_p1: dpb_di_err: eor temp,temp ;return 0 (+ Z-flag) ret - + ; ==================================================================== -; Function: +; Function: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : +; Registers : ; ; -------------------------------------------------------------------- ; 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,67 +950,80 @@ dsk_sdrvpl: lsl _tmp0 dec temp2 brne dsk_sdrvpl - sts secpblk,_tmp0 + std y+o_secpblk,_tmp0 ;Sectors per block ret - + ; ==================================================================== ; Function: Does a Disk interaction ; ==================================================================== ; 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 + lcall uartputc + 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 + 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) + + 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 @@ -1266,7 +1243,7 @@ dsk_wmove: dec temp3 brne dsk_wmove rjmp dsk_rwmfin - + dsk_rmove: ld temp,z+ mem_write @@ -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 @@ -1294,21 +1271,23 @@ dsk_wdir1: ret ; ==================================================================== -; Function: +; Function: ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- ; Registers : temp2:temp block to read (lba) ; temp3 disk # -; +; ; -------------------------------------------------------------------- ; 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 @@ -1322,13 +1301,14 @@ dsk_readhost_lba: ; -------------------------------------------------------------------- ; Registers : temp2:temp host block to read/write (lba) ; temp3 disk # -; +; ; -------------------------------------------------------------------- -; Description: +; 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 + lcall mmcWriteSect + tst temp + brne dsk_hstwr_err + +dsk_hstwr_ok: + sts erflag,_0 + ret + +dsk_hstwr_err: + sts erflag,_255 ret ; ==================================================================== @@ -1420,36 +1409,145 @@ 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: -; vim:set ts=8 noet nowrap +.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