From 29ce189c438e15067a26aebcb12227a9c172a384 Mon Sep 17 00:00:00 2001 From: Leo Date: Fri, 8 Oct 2010 00:29:36 +0000 Subject: [PATCH] * Start of dynamic disk size code. git-svn-id: svn://cu.loc/avr-cpm/trunk@137 57430480-672e-4586-8877-bcf8adbbf3b7 --- avrcpm/avr/avrcpm.asm | 2 +- avrcpm/avr/dsk_cpm.asm | 178 ++++++-------- avrcpm/avr/dsk_fsys.asm | 506 ++++++++++++++++++++++++++++++++++---- avrcpm/avr/dsk_mgr.asm | 239 +++++++----------- avrcpm/avr/virt_ports.asm | 271 ++++++++++++-------- 5 files changed, 794 insertions(+), 402 deletions(-) diff --git a/avrcpm/avr/avrcpm.asm b/avrcpm/avr/avrcpm.asm index 4665c7c..2517d3c 100644 --- a/avrcpm/avr/avrcpm.asm +++ b/avrcpm/avr/avrcpm.asm @@ -59,7 +59,7 @@ .include "dram-refresh.asm" .include "timer.asm" .include "utils.asm" -; .include "heap.asm" + .include "heap.asm" .include "mmc.asm" ; .include "mmc-old.asm" diff --git a/avrcpm/avr/dsk_cpm.asm b/avrcpm/avr/dsk_cpm.asm index 6835c93..69d02e3 100644 --- a/avrcpm/avr/dsk_cpm.asm +++ b/avrcpm/avr/dsk_cpm.asm @@ -18,56 +18,56 @@ ; along with avrcpm. If not, see . ; ; $Id$ -; - -#ifndef CPMDSK_SUPPORT - #define CPMDSK_SUPPORT 1 -#endif - -#if CPMDSK_SUPPORT - +; + +#ifndef CPMDSK_SUPPORT + #define CPMDSK_SUPPORT 1 +#endif + +#if CPMDSK_SUPPORT + ;------------------------------------------ Defines for CPM Structures #define PART_TYPE 4 #define PART_START 8 -#define PART_SIZE 12 - +#define PART_SIZE 12 + #define PARTID_CPM 0x52 /* Partition table id */ - /* http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */ + /* http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */ ;----------------------------------------------- Start of Data Segment - .dseg - + .dseg + ;----------------------------------------------- Start of Code Segment - .cseg + .cseg -; ==================================================================== +; ==================================================================== ; 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 +; ==================================================================== +; 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: +; Read/Write "hostsize" bytes to/from hostbuf +; -------------------------------------------------------------------- +; Description: ; ==================================================================== cpm_hostparam: lds xl,hostdsk - + .if HOSTRW_DEBUG mov temp,xl subi temp,-('A') rcall uartputc printstring ": " .endif - + rcall dsk_getpartentry ; get partition entry - + lds temp,hostlba ; get sector to access lds temp2,hostlba+1 lds temp3,hostlba+2 @@ -116,7 +116,7 @@ cpm_hp1: add xl,temp ; add offset to startsector adc xh,temp2 adc yl,temp3 - adc yh,_0 + adc yh,_0 .if HOSTRW_DEBUG printstring ", abs:" @@ -132,23 +132,23 @@ cpm_hp1: pop temp3 pop temp4 printstring " " -.endif +.endif ori temp,255 cpm_hpex: 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 -; -------------------------------------------------------------------- -; Description: +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seekdsk Number of Disk to Read +; [r] seeksec Sector to read +; [r] seektrk Track to read +; -------------------------------------------------------------------- +; Description: ; ==================================================================== cpm_writehost: @@ -160,88 +160,62 @@ cpm_writehost: breq cpm_rdwr_err rcall mmcWriteSect - tst temp - breq cpm_rdwr_ok - - rjmp cpm_rdwr_err ; skip disk change detection code - -; After a second thought, the following code doesn't make sense, because -; disk change (change of one or more disk images) can not reliably detected. -; At least with the existing code. - - rcall mgr_init_partitions ;reinit card - cbr temp,0x80 ;this should have been a test of bit 7. - breq cpm_rdwr_err - - rcall cpm_hostparam ;if same card, try again. - breq cpm_rdwr_err - rcall mmcWriteSect - tst temp + tst temp brne cpm_rdwr_err + rjmp cpm_rdwr_ok + -; ==================================================================== +; ==================================================================== ; Function: Does a Disk read operation -; ==================================================================== -; Parameters -; -------------------------------------------------------------------- -; Registers : none -; Variables : [r] seekdsk Number of Disk to Read -; [r] seeksec Sector to read -; [r] seektrk Track to read -; -------------------------------------------------------------------- -; Description: +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seekdsk Number of Disk to Read +; [r] seeksec Sector to read +; [r] seektrk Track to read +; -------------------------------------------------------------------- +; Description: ; ==================================================================== cpm_readhost: .if HOSTRW_DEBUG printnewline printstring "host read " -.endif +.endif rcall cpm_hostparam breq cpm_rdwr_err rcall mmcReadSect - tst temp - breq cpm_rdwr_ok - - rjmp cpm_rdwr_err ; skip disk change detection code - - rcall mgr_init_partitions ;reinit card - cbr temp,0x80 - breq cpm_rdwr_err - - rcall cpm_hostparam ;if same card, try again. - breq cpm_rdwr_err - rcall mmcReadSect - tst temp + tst temp brne cpm_rdwr_err cpm_rdwr_ok: - sts erflag,_0 + sts erflag,_0 ret cpm_rdwr_err: - sts erflag,_255 - ret - - -; ==================================================================== + sts erflag,_255 + ret + + +; ==================================================================== ; Function: Add's a CP/M Partition to the Partition table -; ==================================================================== -; Parameters -; -------------------------------------------------------------------- -; Registers : none -; Variables : [r] seekdsk Number of Disk to Read -; [r] seeksec Sector to read -; [r] seektrk Track to read -; -------------------------------------------------------------------- -; Description: +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seekdsk Number of Disk to Read +; [r] seeksec Sector to read +; [r] seektrk Track to read +; -------------------------------------------------------------------- +; Description: ; ==================================================================== cpm_add_partition: - - ldi temp,dskType_CPM - st y+,temp + + ldi temp,dskType_CPM + st y+,temp ldd temp,z+PART_START st y+,temp @@ -260,6 +234,6 @@ cpm_add_partition: st y+,temp ldd temp,z+PART_SIZE+3 st y+,temp - ret - -#endif + ret + +#endif diff --git a/avrcpm/avr/dsk_fsys.asm b/avrcpm/avr/dsk_fsys.asm index 6645bf9..8565620 100644 --- a/avrcpm/avr/dsk_fsys.asm +++ b/avrcpm/avr/dsk_fsys.asm @@ -20,17 +20,17 @@ ; $Id$ ; +.equ DSKSEL_DEBUG = 0 ; ---------------- Defines for the Filesystem Interface ------- - ;***************************************************** ;* Disk-Manager constants * ;***************************************************** .equ dskType_None = 0 .equ dskType_CPM = 1 .equ dskType_FAT = 2 - .equ dskType_RAM = 3 +; .equ dskType_RAM = 3 ;***************************************************** ;* CP/M to host disk constants * @@ -63,32 +63,96 @@ .dseg -ndisks: .byte 1 ;Number of CP/M disks +; The following 3 variables are copied from DRAM. +; Don't change order. + +biosdrvtbl: .byte 2 ; +biosdirbuf: .byte 2 ; +biosenddat: .byte 2 ; + +ndisks: .byte 1 ;Number of CP/M disks + +; The following 5 variables are accessed from 8080/z80 via the +; virtual port interface. Don't change order. -seekdsk: .byte 1 ;seek disk number -seektrk: .byte 2 ;seek track number -seeksec: .byte 1 ;seek sector number +biospar_base: +bcbadr: .byte 2 ;adr of BiosControlBlock +seekdsk: .byte 1 ;seek disk number +seektrk: .byte 2 ;seek track number +seeksec: .byte 2 ;seek sector number +dmaadr: .byte 2 ;last dma address -unacnt: .byte 1 ;unalloc rec cnt -unadsk: .byte 1 ;last unalloc disk -unatrk: .byte 2 ;last unalloc track -unasec: .byte 1 ;last unalloc sector +unacnt: .byte 1 ;unalloc rec cnt +unadsk: .byte 1 ;last unalloc disk +unatrk: .byte 2 ;last unalloc track +unasec: .byte 1 ;last unalloc sector -erflag: .byte 1 ;error reporting -wrtype: .byte 1 ;write operation type -dmaadr: .byte 2 ;last dma address +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) +hostbuf: .byte hostsize ;host buffer (from/to SD-card) +hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count) hostparttbltop: -hostdsk: .byte 1 ;host disk number -hosttype: .byte 1 ;host disk type (same entry as 1 parition entry) -hostlba: .byte 3 ;host sector number (relative to partition start) +hostdsk: .byte 1 ;host disk number +hosttype: .byte 1 ;host disk type (same entry as 1 parition entry) +hostlba: .byte 3 ;host sector number (relative to partition start) ; ------------------------------- Start of Code Segment .cseg +;--------------------------------------------------------------------- + +.if DSKSEL_DEBUG + +dbg_prdrvtbl: + push xh + push xl + push temp3 + push temp2 + push temp + printnewline + printstring "drvtbl (" + lds xl,biosdrvtbl + lds xh,biosdrvtbl+1 + movw temp,x + rcall printhexw + printstring "): " + ldi temp3,16 +dbg_pcpel: + rcall dram_readw_pp + rcall printhexw + printstring " " + dec temp3 + brne dbg_pcpel + pop temp + pop temp2 + pop temp3 + pop xl + pop xh + ret + +dbg_print_biosd: + printnewline + lds temp,bcbadr + lds temp2,bcbadr+1 + rcall printhexw + printstring " " + lds temp,biosdrvtbl + lds temp2,biosdrvtbl+1 + rcall printhexw + printstring " " + lds temp,biosdirbuf + lds temp2,biosdirbuf+1 + rcall printhexw + printstring " " + lds temp,biosenddat + lds temp2,biosenddat+1 + rcall printhexw + printstring " " + ret +.endif + ; ==================================================================== ; Function: Get a Pointer to a Partitiontable entry ; ==================================================================== @@ -96,6 +160,8 @@ hostlba: .byte 3 ;host sector number (relative to partition start) ; -------------------------------------------------------------------- ; Registers : [w] z Pointer to the Partitionentry ; [r] xl Number of Diskentry to Read +; [w] _tmp0 scratch +; [w] _tmp1 " ; -------------------------------------------------------------------- ; Description: ; ==================================================================== @@ -109,78 +175,410 @@ dsk_getpartentry: ret ; ==================================================================== -; Function: +; Function: Virtual Port Interface ; ==================================================================== ; Parameters ; -------------------------------------------------------------------- -; Registers : none -; Variables : [r] seeksec Sector to read -; [r] seektrk Track to read +; Registers : +; Variables : +; +; -------------------------------------------------------------------- +; Description: +; ==================================================================== + +dsk_param_getadr: + ldiw z,biospar_base + add zl,temp3 + adc zh,_0 + ret + +dsk_param_wr: + rcall dsk_param_getadr + st z,temp + cpi temp3,bcbadr+1-seektrk + brne dsk_param_wr1 + std z+1,_0 +dsk_param_wr1: + cpi temp3,bcbadr+1-biospar_base + breq SetBCB + ret + +dsk_param_rd: + cpi temp3,seekdsk-biospar_base + breq dskDiskCheck + rcall dsk_param_getadr + ld temp,z + ret + +SetBCB: + lds xl,bcbadr + mov xh,temp + ldiw z,biosdrvtbl + ldi temp3,6 +sbcb_l: + rcall dram_read_pp + st z+,temp + dec temp3 + brne sbcb_l + +; rcall dbg_print_biosd + rcall dsk_drvtblinit +; rcall dbg_prdrvtbl + + ret + +; ==================================================================== +; Function: Check if disk exists +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; return 0, if selected disk not exist. +; return !0, if disk exist ; -------------------------------------------------------------------- ; Description: ; ==================================================================== dskDiskCheck: - lds temp2,seekdsk - cpi temp2,RAMDISKNR + lds temp,ndisks + lds temp2,seekdsk +.if DSKSEL_DEBUG + printnewline + printstring "DiskCheck: " + rcall printhexw +.endif + cpi temp2,RAMDISKNR brsh dsk_dchrd ;maybe ramdisk ; Check if selected disk # is less then # of disks. - lds temp,ndisks - tst temp + lds temp,ndisks + tst temp ;0 disks? brne dsk_dchpart1 ; No disks yet, need to init - rcall mgr_init_partitions - cbr temp,0x80 - lds temp2,seekdsk + rcall mgr_init_partitions ;disk chanched? +; sbrs temp,7 +; rjmp dsk_dchpart0 + push temp + rcall dsk_drvtblinit +; rcall dbg_prdrvtbl + pop temp +dsk_dchpart0: + cbr temp,0x80 + lds temp2,seekdsk dsk_dchpart1: - cp temp2,temp - brsh dsk_dcher + cp temp2,temp + brsh dsk_dch_err + +.if DSKSEL_DEBUG + printnewline + printstring "Select: " + mov temp,temp2 + rcall printhex +.endif + ldsw x,biosdrvtbl + lsl temp2 ;drive # + add xl,temp2 + adc xh,_0 + rcall dram_readw_pp ;get drive table entry + + or temp,temp2 ;if !0, drive is allready initialized + brne dsk_dchend + lds temp,seekdsk + rcall dsk_diskinit dsk_dchend: - ldi temp,0 +.if DSKSEL_DEBUG + push temp + ldsw x,biosdrvtbl + lds temp,seekdsk + lsl temp ;drive # + add xl,temp + adc xh,_0 + rcall dram_readw_pp + printstring ", " + rcall printhexw + pop temp +.endif + ret +dsk_dch_err: + ldi temp,0 ;error return + ret + +; Check RAMDISK + dsk_dchrd: #if RAMDISKCNT - cpi temp,RAMDISKNR+RAMDISKCNT - brlo dsk_dchend + cpi temp,RAMDISKNR+RAMDISKCNT + brsh dsk_dchrd_err + + ldi temp,0xff ;return ok + ret #endif -dsk_dcher: - ldi temp,0xff ;error return +dsk_dchrd_err: + ldi temp,0 ;error return ret - + + +; ==================================================================== +; Function: Return status of last disk i/o function +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; -------------------------------------------------------------------- +; Description: +; ==================================================================== dskErrorRet: - lds temp,erflag + lds temp,erflag ret -dskDiskSel: - sts seekdsk,temp - ret + +; ------------------------------------------------------------------- -dskTrackSel_l: - sts seektrk,temp - sts seektrk+1,_0 - ret -dskTrackSel_h: - sts seektrk+1,temp + .dseg +tmpdpb: .byte 15 + + .cseg + +; Test DPBs (avrcpm format) + +dpblist: +;dpb243 + .db 0x1A,0x00 ;spt + .db 0x03,0x07 ;block shift, bock mask + .db 0x00,0xF2 ;extent mask, low(disk size -1), + .db 0x00,0x3F ;high(disk size -1), low(dir max) + .db 0x00,0xC0 ;high(dir max), alloc0 + .db 0x00,0x10 ;alloc1, low(chk size) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +;dpb243 + .db 0x1A,0x00 ;spt + .db 0x03,0x07 ;block shift, bock mask + .db 0x00,0xF2 ;extent mask, low(disk size -1), + .db 0x00,0x3F ;high(disk size -1), low(dir max) + .db 0x00,0xC0 ;high(dir max), alloc0 + .db 0x00,0x10 ;alloc1, low(chk size) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +;dpb243 + .db 0x1A,0x00 ;spt + .db 0x03,0x07 ;block shift, bock mask + .db 0x00,0xF2 ;extent mask, low(disk size -1), + .db 0x00,0x3F ;high(disk size -1), low(dir max) + .db 0x00,0xC0 ;high(dir max), alloc0 + .db 0x00,0x10 ;alloc1, low(chk size) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +;dpb243 + .db 0x1A,0x00 ;spt + .db 0x03,0x07 ;block shift, bock mask + .db 0x00,0xF2 ;extent mask, low(disk size -1), + .db 0x00,0x3F ;high(disk size -1), low(dir max) + .db 0x00,0xC0 ;high(dir max), alloc0 + .db 0x00,0x10 ;alloc1, low(chk size) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +#if 0 +;rd1016 + .db 0x20,0x00 ;spt + .db 0x04,0x0F ;block shift, bock mask + .db 0x00,0xFB ;extent mask, low(disk size -1), + .db 0x01,0xBF ;high(disk size -1), low(dir max) + .db 0x00,0xE0 ;high(dir max), alloc0 + .db 0x00,0x30 ;alloc1, low(chk size) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +;rd9192s + .db 0x20,0x00 ;spt + .db 0x05,0x1F ;block shift, bock mask + .db 0x01,0xFD ;extent mask, low(disk size -1), + .db 0x07,0xFF ;high(disk size -1), low(dir max) + .db 0x01,0xF0 ;high(dir max), alloc0 + .db 0x00,0x80 ;alloc1, low(chk size) + .db 0x00,0x02 ;high(chk size), low(offset) + .db 0x00,0x00 ;high(offset), fill +#endif + +; Test +cpy_dpb: + push zh + push zl + push yh + push yl + ldiw z,dpblist*2 + ldi temp2,16 + mul temp,temp2 + add zl,_tmp0 + adc zh,_tmp1 + ldiw y,tmpdpb +cpydpb_l: + lpm temp,z+ + st y+,temp + cpi yl,low(tmpdpb + 15) + brne cpydpb_l + pop yl + pop yh + pop zl + pop zh ret + +; clear drive table +; for now, only entries 1 - 3 are cleared. -dskSecSel: - sts seeksec,temp +; ==================================================================== +; Function: Clear drive table +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; +; -------------------------------------------------------------------- +; Description: +; ==================================================================== + +; For now, only entries 1 - 3 are cleared. + +dsk_drvtblinit: + ldsw x,biosdrvtbl + adiw x,2 + ldi temp3,3 +dsk_drvi_l: + ldi temp,0 + ldi temp2,0 + rcall dram_writew_pp + dec temp3 + brne dsk_drvi_l + + lds temp,biosenddat + lds temp2,biosenddat+1 + rcall heap_init + clr temp ret -dskDmal: - sts dmaadr,temp + +; ---------------------------------------------------------------------- +; Init CP/M data structures +; temp = drive # +; +; return !0 if ok +; 0 on error + + +dsk_diskinit: + mov temp3,temp ;save disk # + + +; Test + rcall cpy_dpb + + + + +; get mem for DPH +; ----------------------------------------------------------------- +; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV | +; ----------------------------------------------------------------- +;(offset) 0 2 4 6 8 10 12 14 + + ldi temp, low (16) + ldi temp2,high(16) + rcall heap_get + brne dsk_di_1 + rjmp dsk_di_err ; +dsk_di_1: + movw x,temp + movw y,temp + ldi temp,0 + ldi temp2,0 + rcall dram_writew_pp ;XLT + adiw x,6 + lds temp,biosdirbuf + lds temp2,biosdirbuf+1 + rcall dram_writew_pp ;DIRBUF + +; get mem for DPB +; ------------------------------------------------------------- +; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF | +; ------------------------------------------------------------- +; 0 5 7 11 13 + + ldi temp, low (15) + ldi temp2,high(15) + rcall heap_get + breq dsk_di_err_p1 + movw x,temp + + ldiw z,tmpdpb +dsk_dicpl: + ld temp,z+ + rcall dram_write_pp + cpi zl,low(tmpdpb + 15) + brne dsk_dicpl + sbiw x,15 + movw temp,x + movw x,y + adiw x,10 + rcall dram_writew_pp ;DPB + +; get mem for dir check vector + + lds temp,tmpdpb+11 ;cks + lds temp2,tmpdpb+11+1 + cp temp,_0 + cpc temp2,_0 + breq dsk_dicks0 + rcall heap_get + breq dsk_di_err_p1 +dsk_dicks0: + rcall dram_writew_pp ;CSV + +; get mem for alloc vector + + lds temp,tmpdpb+5 ;dsm + lds temp2,tmpdpb+5+1 + subi temp, low (-8) + sbci temp2,high(-8) + lsr temp2 + ror temp + lsr temp2 + ror temp + lsr temp2 + ror temp ;(dsm+1+7)/8 + rcall heap_get + breq dsk_di_err_p1 + rcall dram_writew_pp ;ALV + +; success, insert DPH into drvtbl + + lds xl,biosdrvtbl + lds xh,biosdrvtbl+1 + lsl temp3 ;drive # + add xl,temp3 + adc xh,_0 + movw temp,y + rcall dram_writew_pp + ori temp,0xff ;return ok ret -dskDmah: - sts dmaadr+1,temp +; error, free mem + +dsk_di_err_p1: + movw temp,y + rcall heap_release +dsk_di_err: + eor temp,temp ;return 0 (+ Z-flag) ret + ; ==================================================================== ; Function: Does a Disk interaction @@ -277,6 +675,7 @@ dsk_home: dsk_read: sts erflag,_0 sbi flags,readop ; Set read operation flag + ;RAM disk? lds xl,seekdsk #if RAMDISKCNT @@ -291,6 +690,7 @@ dsk_read: cpi temp,dskType_None brne PC+2 rjmp dsk_read_err + ; It must be a FAT16-Imagefile or CP/M Partition. sts unacnt,_0 sbi flags,rsflag ;must read data diff --git a/avrcpm/avr/dsk_mgr.asm b/avrcpm/avr/dsk_mgr.asm index 4b108a3..eae22a6 100644 --- a/avrcpm/avr/dsk_mgr.asm +++ b/avrcpm/avr/dsk_mgr.asm @@ -28,11 +28,6 @@ .dseg - -; Partition table offsets: -tmp_tbl: - .byte PARTENTRY_SIZE*MAXDISKS - ; ------------------------------- Start of Code Segment .cseg @@ -57,14 +52,14 @@ tmp_tbl: ; ==================================================================== mgr_init_partitions: - sts ndisks,_0 ; Set Number of Disks to 0 + sts ndisks,_0 ; Set Number of Disks to 0 -; Initialize temp partition table - ldiw y,tmp_tbl - ldi temp2,PARTENTRY_SIZE*MAXDISKS +; Initialize partition table + ldiw y,hostparttbl + ldi temp2,PARTENTRY_SIZE*MAXDISKS mgr_picl: - st y+,_0 - dec temp2 + st y+,_0 + dec temp2 brne mgr_picl ; Start mmc Card interaction @@ -76,7 +71,7 @@ mgr_picl: ldiw y,0 ; Sector 0 movw x,y lcall mmcReadSect - tst temp + tst temp breq mgr_check_bootsektor mgr_pierr: @@ -84,138 +79,91 @@ mgr_pierr: ret mgr_check_bootsektor: -;Pointer to first temp table entry - ldiw y,tmp_tbl -;Test, if it has a valid MBR +;Pointer to first table entry + ldiw y,hostparttbl + ldi temp3,0 ;temp3 holds number of found disks (paritions) - ldiw z,hostbuf+510-1 ;Point to last byte of partition table +;Test, if it has a valid MBR - ldi temp3,0 ;temp3 holds number of found disks (paritions) - ldd temp,z+1 ;MBR signature (0xAA55) at and of sector? - ldd temp2,z+2 - ldi temp4,0xAA - cpi temp,0x55 - cpc temp2,temp4 + lds temp,hostbuf+510 ;MBR signature (0xAA55) at and of sector? + lds temp2,hostbuf+510+1 + ldi temp4,0xAA + cpi temp,0x55 + cpc temp2,temp4 breq mgr_search ;No MBR, no partition table ... - inc temp3 ;pretend we have one. - ldi temp,high((1<<16) * 128/512) + + inc temp3 ;pretend we have one. + sts ndisks,temp3 + ldi temp,high((1<<16) * 128/512) ldi temp2,dskType_CPM - std y+0,temp2 - std y+1,_0 ;start at beginning of card - std y+2,_0 - std y+3,_0 - std y+4,_0 - std y+5,_0 ;max CP/M 2.2 disk size - std y+6,temp ; - std y+7,_0 - std y+8,_0 + std y+0,temp2 + std y+1,_0 ;start at beginning of card + std y+2,_0 + std y+3,_0 + std y+4,_0 + std y+5,_0 ;max CP/M 2.2 disk size + std y+6,temp ; + std y+7,_0 + std y+8,_0 rjmp mgr_pend ; Search for valid Partitions and ImageFiles mgr_search: - sbiw z,63 ;Now at first byte of partition table - ldi temp4,high(hostbuf+510) + ldiw z,hostbuf+510-64 ;Point to first byte of partition table + ldi temp4,4 ;Partition table has 4 entries. mgr_ploop: ; Get Partitiontype - ldd temp,z+PART_TYPE + ldd temp,z+PART_TYPE ; Test for CP/M Partition - cpi temp,PARTID_CPM + cpi temp,PARTID_CPM brne mgr_nextp rcall cpm_add_partition - inc temp3 - cpi temp3,MAXDISKS + inc temp3 + sts ndisks,temp3 + cpi temp3,MAXDISKS breq mgr_pend mgr_nextp: adiw zl,16 - cpi zl,low(hostbuf+510) - cpc zh,temp4 - brlo mgr_ploop + dec temp4 + brne mgr_ploop #if FAT16_SUPPORT ; Test for FAT16 Partition - ldiw z,hostbuf+510-1-63 ;Point to first byte of partition table - ldi temp4,high(hostbuf+510) + ldiw z,hostbuf+510-64 ;Point to first byte of partition table + ldi temp4,4 mgr_ploop2: - ; Get Partitiontype - ldd temp,z+PART_TYPE + ldd temp,z+PART_TYPE ; Test for FAT Partition - cpi temp,PARTID_FAT16 + cpi temp,PARTID_FAT16 brne mgr_nextp2 - rcall fat_add_partition + rcall fat_add_partition - rjmp mgr_pend + rcall fat_scan_partition + rcall fat_reset_cache + + rjmp mgr_pend ;Stop after first FAT16 parrtition found. mgr_nextp2: adiw zl,16 - cpi zl,low(hostbuf+510) - cpc zh,temp4 - brlo mgr_ploop2 + dec temp4 + brne mgr_ploop2 #endif mgr_pend: - -#if 0 /* ToDo: ramdisks are not in sd-card partitions */ -; Initialize RAM-Disks - rcall rdsk_add_partition -#endif - -/* - Don't use change info. It doesn't word reliably with partitions, - and it doesn't work at all with fat images: -*/ -#define CHANGEINFO 0 - -;Store new partitions and check if the SD card has been changed. - - ldiw y,tmp_tbl - ldiw z,hostparttbl - ldi temp4,PARTENTRY_SIZE*MAXDISKS - clt - -mgr_pcpl: - ld temp,y+ - ld temp2,z - st z+,temp - cpse temp,temp2 - set - dec temp4 - brne mgr_pcpl - - mov temp,temp3 - sts ndisks,temp -#if CHANGEINFO - brtc mgr_pcpe - -; SD card changed. -#endif - tst temp - breq mgr_pcpe - - -#if FAT16_SUPPORT - rcall fat_scan_partition - rcall fat_reset_cache -#endif - lds temp,ndisks -#if CHANGEINFO - sbr temp,0x80 -#endif - -mgr_pcpe: - + lds temp,ndisks ;return # of "disks" tst temp ret @@ -234,48 +182,52 @@ mgr_pcpe: mgr_prnt_parttbl: ldiw z,hostparttbl - lds yl,ndisks - ldi xh,'A' + lds yl,ndisks + ldi xh,'A' -pprl: - ldd temp ,z+1 ;Get partition start - ldd temp2,z+2 - ldd temp3,z+3 - ldd temp4,z+4 +pprl: + ldd temp ,z+1 ;Get partition start + ldd temp2,z+2 + ldd temp3,z+3 + ldd temp4,z+4 printnewline - cp temp,_0 ;If zero ... - cpc temp2,_0 - cpc temp3,_0 - cpc temp4,_0 - breq mgr_prnop ;... no partition table at 0 + cp temp,_0 ;If zero ... + cpc temp2,_0 + cpc temp3,_0 + cpc temp4,_0 + breq mgr_prnop ;... no partition table at 0 ; Partitiontype examining ldd xl,z+0 ; CP/M ? - cpi xl,dskType_CPM + cpi xl,dskType_CPM brne mgr_prtb_nocpm rcall mgr_prnt_diskname rcall mgr_prnt_table_cpm rjmp mgr_prnt_size -; FAT16 ? mgr_prtb_nocpm: - cpi xl,dskType_FAT +#if FAT16_SUPPORT +; FAT16 ? + cpi xl,dskType_FAT brne mgr_prtb_nofat rcall mgr_prnt_diskname rcall mgr_prnt_table_fat rjmp mgr_prnt_size -; RAMDISK ? mgr_prtb_nofat: - cpi xl,dskType_RAM +#endif +#if 0 /* RAMDISK is not on SD card */ +; RAMDISK ? + cpi xl,dskType_RAM brne mgr_prnt_err rcall mgr_prnt_diskname rcall mgr_prnt_table_ram rjmp mgr_prnt_size -; Entry Error +#endif mgr_prnt_err: +; Entry Error rcall mgr_prnt_table_err rjmp mgr_prnt_size @@ -284,27 +236,26 @@ mgr_prnop: rcall mgr_prnt_image mgr_prnt_size: - call print_ultoa + lcall print_ultoa printstring ", size: " - ldd temp ,z+5 ;Get partition size - ldd temp2,z+6 ;Get partition size - ldd temp3,z+7 ;Get partition size - ldd temp4,z+8 ;Get partition size + ldd temp ,z+5 ;Get partition size + ldd temp2,z+6 + ldd temp3,z+7 + ldd temp4,z+8 - lsr temp4 - ror temp3 - ror temp2 - ror temp - call print_ultoa + lsr temp4 + ror temp3 + ror temp2 + ror temp + lcall print_ultoa printstring "KB." mgr_goto_next_part: adiw z,PARTENTRY_SIZE - inc xh - dec yl - tst yl - brne pprl + inc xh + dec yl + brne pprl mgr_pppre: ret @@ -314,23 +265,23 @@ mgr_prnt_fatsize: lcall print_ultoa printstring ", size: " - ldd temp ,z+5 ;Get partition size - ldd temp2,z+6 ;Get partition size - ldd temp3,z+7 ;Get partition size - ldd temp4,z+8 ;Get partition size + ldd temp ,z+5 ;Get partition size + ldd temp2,z+6 + ldd temp3,z+7 + ldd temp4,z+8 lcall print_ultoa printstring "BYTE." - rjmp mgr_goto_next_part + rjmp mgr_goto_next_part mgr_prnt_diskname: push temp - mov temp,xh - call uartputc - ldi temp,':' - call uartputc - pop temp + mov temp,xh + lcall uartputc + ldi temp,':' + lcall uartputc + pop temp ret mgr_prnt_table_cpm: diff --git a/avrcpm/avr/virt_ports.asm b/avrcpm/avr/virt_ports.asm index 7861165..bffb78f 100644 --- a/avrcpm/avr/virt_ports.asm +++ b/avrcpm/avr/virt_ports.asm @@ -1,6 +1,6 @@ ; Virtual Ports for the BIOS Interaction ; -; Copyright (C) 2010 Frank Zoll +; Copyright (C) 2010 Leo C. ; ; This file is part of avrcpm. ; @@ -18,34 +18,165 @@ ; along with avrcpm. If not, see . ; ; $Id$ -; - - -; ---------------- Defines for the Virtual peripherial interface ------- - -;The hw is modelled to make writing a CPM BIOS easier. -;Ports: -;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise. -;1 - Console input, aka UDR. -;2 - Console output -;3 - "UART" status: bit 0=rx, bit 1 = tx -;4 - "UART" data register, no wait -;15 - Disk select -;16,17 - Track select -;18 - Sector select -;20 - Write addr l -;21 - Write addr h -;22 - Trigger - write to read, to write a sector using the above info; -; , write to allocated/dirctory/unallocated - -;----------------------------------------------- Start of Data Segment - - .dseg - - +; + + +; +; Port Direction Function +;hex dez +;------------------------------------------------------------------------- +;00 0 in - Con status. +; Returns 0xFF if the UART has a byte, 0 otherwise. +;01 1 in/out - Console input, aka UDR. / Console Output +;02 2 out - Console Output (deprecated) +;03 3 in - "UART" status: bit 0 = rx, bit 1 = tx +;04 4 in - "UART" data register, no wait +; +;0D,0E 13,14 in/out - Set address of Bios Controll Block +;0F 15 in/out - Disk select +;10,11 16,17 in/out - Track select +;12,13 18,19 in/out - Sector select +;14,15 20,21 in/out - Write addr +; +;16 22 out - Trigger disk i/o operations +; Bit 7 = 1: Read sector +; Bit 6 = 1: Write sector +; Bit 5 = 1: BIOS WBOOT +; Bit 4 = 1: BIOS Home +; Only one of bits 4..7 may be set. +; If Write function (bit 6=1): +; Bits 0..2: 0 - write to allocated +; 1 - write to directory +; 2 - write unallocated +; 3 - write to directory +; +;16 22 in - Result of last read/write operation. +; 0x00 = ok, 0xff = error (--> Bad Sector) +; +;40 64-71 in/out - Timer/Clock controll. +;46 + + ; ---------------------------------------------- Start of Code Segment - .cseg - + .cseg +vport_tbl: + .db 00,1 ;Port 0, length 1 + .dw conStatus ; in + .dw dbgOut ; out + .db 01,1 + .dw uartgetc + .dw uartputc + .db 02,1 ;Port 2 (old console output) + .dw uartgetc ; filler + .dw uartputc ; deprecated + .db 03,1 + .dw uartstat + .dw vport_out_dummy + .db 04,1 + .dw uartin + .dw uartout + + .db 13,9 ; Port 13-21, (lenth 9) + .dw dsk_param_rd + .dw dsk_param_wr + .db 22,1 + .dw dskErrorRet + .dw dskDoIt + + .db TIMERPORT,7 + .dw clockget + .dw clockput + .db 0,0 ; Stop mark + +;--------------------------------------------------------------------- + +;Called with port in temp2 and value in temp. +portWrite: + set + rjmp vprw_start + +;Called with port in temp2. Should return value in temp. +portRead: + clt + +vprw_start: +.if PORT_DEBUG > 1 + tst temp2 + brne dvp_1 ;don't debug console status + brts dvp_1 + rjmp conStatus +dvp_1: + printnewline + brts dvp_11 + printstring "Port In: " + rjmp dvp_12 +dvp_11: + printstring "Port Out: " +dvp_12: + push temp + mov temp,temp2 + rcall printhex + pop temp +.endif + ldiw z,vport_tbl*2 + +vprw_loop: + lpm _tmp0,z+ + lpm temp4,z+ ;length + cpi temp4,0 + breq vprw_exit ;no more ports + + mov temp3,temp2 + sub temp3,_tmp0 ;base port + brcs vprw_next ;port # too high + cp temp3,temp4 ;may be in range + brcs vprw_found ; +vprw_next: ;port # not in range, test next block. + adiw z,4 + rjmp vprw_loop +vprw_found: + brtc PC+2 + adiw z,2 + lpm _tmp0,z+ + lpm _tmp1,z+ + movw z,_tmp0 + +.if PORT_DEBUG > 1 + push temp2 + push temp + printstring ", exec: " + movw temp,z + rcall printhexw + printstring ", rel port: " + mov temp,temp3 + rcall printhex + pop temp + pop temp2 + printstring ", val: " + brts dvp_2 + icall + rcall printhex + printstring " " + ret +dvp_2: + rcall printhex + printstring " " + ijmp ; relative port # in temp3 +.else + ijmp +.endif + +vprw_exit: + ; trap for nonexistent port? +.if PORT_DEBUG > 1 + printstring ", not found!" +.endif +vport_in_dummy: + ldi temp,0xff +vport_out_dummy: + ret + + uartstat: clr temp lds temp2,rxcount @@ -58,6 +189,13 @@ uartstat: uartst_1: ret +uartin: + clr temp + lds temp2,rxcount + cpse temp2,_0 + rjmp uartgetc + ret + uartout: lds temp2,txcount cpi temp2,TXBUFSIZE @@ -66,21 +204,13 @@ uartout: uartout_1: ret -uartin: - clr temp - lds temp2,rxcount - cpse temp2,_0 - rjmp uartgetc - ret - + conStatus: lds temp,rxcount cpse temp,_0 ldi temp,0xff ret -conInp: - rjmp uartgetc dbgOut: printnewline @@ -88,70 +218,7 @@ dbgOut: rcall printhex ret -conOut: - rjmp uartputc - -;Called with port in temp2. Should return value in temp. -portRead: - cpi temp2,0 - breq conStatus - cpi temp2,1 - breq conInp - cpi temp2,3 - breq uartstat - cpi temp2,4 - breq uartin - - cpi temp2,15 - breq dskDiskCheck - cpi temp2,22 - breq dskErrorRet - - cpi temp2,TIMER_MSECS - brlo pr_noclock - cpi temp2,TIMER_MSECS+6 - brsh pr_noclock - rjmp clockget - -pr_noclock: - ldi temp,0xFF - ret - -;Called with port in temp2 and value in temp. -portWrite: - cpi temp2,0 - breq dbgOut - cpi temp2,2 - breq conOut - cpi temp2,4 - breq uartout - - cpi temp2,15 - breq dskDiskSel - cpi temp2,16 - breq dskTrackSel_l - cpi temp2,17 - breq dskTrackSel_h - cpi temp2,18 - breq dskSecSel - cpi temp2,20 - breq dskDmaL - cpi temp2,21 - breq dskDmaH - - cpi temp2,22 - breq dskDoIt - - cpi temp2,TIMERPORT - brlo pw_noclock - cpi temp2,TIMER_MSECS+6 - brsh pw_noclock - rjmp clockput - -pw_noclock: - ret - - - ;--------------------------------------------------------------------- +; vim:set ts=8 noet nowrap + -- 2.39.2