From: Leo Date: Sun, 10 Oct 2010 11:48:43 +0000 (+0000) Subject: * This code is experimental and may destroy data on disk images! X-Git-Tag: 2.2^2~14 X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/commitdiff_plain/dd7aea8cf3e0f67cce1a9a2999404bfb5d05ffc5?hp=a17b9bbb1d4482a476629d3efdd20dc3ab01bc77 * This code is experimental and may destroy data on disk images! * At present, the following image formats are recognized: - MyZ80 - YAZE (ydsk) - avrcpm (of course) git-svn-id: svn://cu.loc/avr-cpm/trunk@143 57430480-672e-4586-8877-bcf8adbbf3b7 --- diff --git a/avrcpm/avr/config.inc b/avrcpm/avr/config.inc index ebff192..d947e79 100644 --- a/avrcpm/avr/config.inc +++ b/avrcpm/avr/config.inc @@ -61,21 +61,20 @@ #define EM_Z80 0 /* we don't have any z80 instructions yet */ -.equ BOOT_DEBUG = 0 +.equ BOOTWAIT = 1 +.equ MEMTEST = 1 +.equ MEMFILL = 1 .equ MMC_DEBUG = 0 /* Increase for more debugging */ .equ FAT16_DEBUG = 0 .equ FAT16_RWDEBUG = 0 .equ FAT16_DBG_FAT = 0 -.equ INS_DEBUG = 0 -.equ MEMTEST = 1 -.equ BOOTWAIT = 1 -.equ PORT_DEBUG = 0 .equ DISK_DEBUG = 0 /* Increase for more debugging */ .equ HOSTRW_DEBUG = 0 -.equ MEMFILL = 1 +.equ HEAP_DEBUG = 0 +.equ PORT_DEBUG = 0 +.equ INS_DEBUG = 0 .equ STACK_DBG = 0 .equ PRINT_PC = 0 -.equ HEAP_DEBUG = 0 #define MMC_SPI2X 1 /* 0 = SPI CLK/4, 1 = SPI CLK/2 */ diff --git a/avrcpm/avr/dsk_cpm.asm b/avrcpm/avr/dsk_cpm.asm index 599373a..e154e4b 100644 --- a/avrcpm/avr/dsk_cpm.asm +++ b/avrcpm/avr/dsk_cpm.asm @@ -47,12 +47,12 @@ ; ==================================================================== cpm_hostparam: - lds xl,hostdsk + lds zl,hostdsk .if HOSTRW_DEBUG - mov temp,xl + mov temp,zl subi temp,-('A') - rcall uartputc + lcall uartputc printstring ": " .endif @@ -65,7 +65,7 @@ cpm_hostparam: .if HOSTRW_DEBUG printstring "lba: " clr temp4 - rcall print_ultoa + lcall print_ultoa .endif ldd xl,z+5 ; get disksize diff --git a/avrcpm/avr/dsk_fat16.asm b/avrcpm/avr/dsk_fat16.asm index 3b527ad..d8b74a2 100644 --- a/avrcpm/avr/dsk_fat16.asm +++ b/avrcpm/avr/dsk_fat16.asm @@ -751,11 +751,8 @@ fat_c2s_end: ; Description: ; ==================================================================== fat_find_phsy_clust: - mov temp2,xl - lds xl,hostdsk - + lds zl,hostdsk rcall dsk_getpartentry ; get partition entry - mov xl,temp2 ; Get First FAT- Cluster Number of Diskimage @@ -869,9 +866,7 @@ fat_found_phsy_clust: ; ============================================================================ fat_hostparam: - lds xl,hostdsk - - + lds zl,hostdsk rcall dsk_getpartentry ; get partition entry fat_hostlend: diff --git a/avrcpm/avr/dsk_fsys.asm b/avrcpm/avr/dsk_fsys.asm index 4e472a8..484a0e2 100644 --- a/avrcpm/avr/dsk_fsys.asm +++ b/avrcpm/avr/dsk_fsys.asm @@ -27,25 +27,34 @@ ;***************************************************** ;* 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 * @@ -83,6 +92,9 @@ seektrk: .byte 2 ;seek track number 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 @@ -91,12 +103,11 @@ 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) +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 @@ -160,7 +171,7 @@ dbg_print_biosd: ; 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 " ; -------------------------------------------------------------------- @@ -168,8 +179,8 @@ dbg_print_biosd: ; ==================================================================== 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 @@ -336,85 +347,35 @@ dskErrorRet: .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 @@ -436,29 +397,68 @@ dpblist: .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 ; ==================================================================== @@ -499,7 +499,7 @@ dpb_drvtbl_entry_get: ; ==================================================================== -; Function: Clear drive table +; Function: Clear drive table (entries 0 to 7) ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- @@ -510,12 +510,12 @@ dpb_drvtbl_entry_get: ; 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 @@ -529,7 +529,210 @@ dpb_drvi_l: 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 +; 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,"",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 # @@ -541,12 +744,11 @@ dpb_drvi_l: 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 ; ----------------------------------------------------------------- @@ -582,11 +784,11 @@ dpb_di_1: 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 @@ -596,8 +798,8 @@ dpb_dicpl: ; 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 @@ -608,8 +810,8 @@ 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 @@ -628,6 +830,7 @@ dpb_dicks0: rcall dpb_drvtbl_entry_p movw temp,y rcall dram_writew_pp + ori temp,0xff ;return ok ret @@ -640,6 +843,34 @@ dpb_di_err: 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 @@ -708,15 +939,15 @@ dskdbge: 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 @@ -738,9 +969,9 @@ dsk_read: 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 @@ -752,11 +983,16 @@ dsk_read: 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: @@ -779,14 +1015,14 @@ dsk_write: 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 ? @@ -797,78 +1033,81 @@ dsk_write: ; 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: @@ -890,58 +1129,61 @@ dsk_rwoper: ;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: @@ -952,80 +1194,103 @@ 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 ; ==================================================================== @@ -1039,7 +1304,7 @@ dsk_wdir1: ; Description: ; ==================================================================== dsk_writehost: - lds xl,hostdsk + lds zl,hostdsk rcall dsk_getpartentry ld temp,z andi temp,dskType_MASK @@ -1071,7 +1336,17 @@ dsk_writehost: ; 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 diff --git a/avrcpm/avr/init.asm b/avrcpm/avr/init.asm index 4ffff96..a1b80ac 100644 --- a/avrcpm/avr/init.asm +++ b/avrcpm/avr/init.asm @@ -201,7 +201,7 @@ ramfillw: boot_again: printnewline - printstring "Initing mmc...",0 + printstring "Initing mmc..." printnewline lcall mgr_init_partitions @@ -222,17 +222,14 @@ boot_ipl2: lcall mgr_prnt_parttbl printnewline printstring "Partinit done." + + ldi temp,0 + rcall dsk_img_type ;parameter for boot disk image. - rcall dsk_cboot ;init (de)blocking buffer + lcall dsk_inval_hostbuf ;init (de)blocking buffer ; Read first sector of first CP/M partition (ipl) -; lds xl,hostparttbl+1 -; lds xh,hostparttbl+2 -; lds yl,hostparttbl+3 -; lds yh,hostparttbl+4 -; rcall mmcReadSect - ; Disk 0 sts seekdsk,_0 ; Track 0 @@ -241,22 +238,13 @@ boot_ipl2: ; Sector 0 sts seeksec,_0 - rcall dsk_read - -; rcall dsk_cboot ;init (de)blocking buffer - -;First sector of disk or first CP/M partition is in hostbuf. +; Destination + ldiw x,IPLADDR + stsw dmaadr,x + + lcall dsk_read -;Save to Z80 RAM (only 128 bytes because that's retro) - ldiw z,hostbuf - ldiw x,IPLADDR -iplwriteloop: - ld temp,z+ - rcall dram_write_pp - cpi zl,low(hostbuf+128) - brne iplwriteloop - cpi zh,high(hostbuf+128) - brne iplwriteloop +; lift off ljmp z80_init diff --git a/avrcpm/avr/utils.asm b/avrcpm/avr/utils.asm index 5a6efef..4d8122a 100644 --- a/avrcpm/avr/utils.asm +++ b/avrcpm/avr/utils.asm @@ -111,6 +111,57 @@ printhexn_isno: pop temp ret + +; Prints a single space + +dbg_printspace: + ldi temp,' ' + rjmp uartputc + +; Prints 16 bytes pointed to by Z in hex. + +dbg_hexdump_line: ;Address in z + push temp2 + push temp + printnewline + movw temp,z ;Print address + rcall printhexw + ldi temp2,16 ;16 byte per line + rcall dbg_printspace +dbg_hdl1: + cpi temp2,8 + brne PC+2 + rcall dbg_printspace + + rcall dbg_printspace + ld temp,z+ + rcall printhex + dec temp2 + brne dbg_hdl1 + sbiw z,16 + + rcall dbg_printspace + rcall dbg_printspace + ldi temp2,16 +dbg_hdl2: + ld temp,z+ + cpi temp,' ' + brlo dbg_hdpd + cpi temp,0x7F + brlo dbg_hdp +dbg_hdpd: + ldi temp,'.' +dbg_hdp: + rcall uartputc + dec temp2 + brne dbg_hdl2 + sbiw z,16 + rcall dbg_printspace + pop temp + pop temp2 + ret + + ;Prints the zero-terminated string following the call statement. printstr: