From 8b13b36c6542ac4fac3a69ae45f7e296f7754bdb Mon Sep 17 00:00:00 2001 From: Frank Zoll Date: Thu, 30 Sep 2010 23:45:42 +0000 Subject: [PATCH] * Initial changes for FAT16 support. * The following files are splitt from 'avr/avrcpm.asm': - avr/dsk_mgr.asm - avr/dsk_fsys.asm - avr/dsk_cpm.asm - avr/dsk_ram.asm - avr/virt_ports.asm * New file: - avr/dsk_fat16.asm git-svn-id: svn://cu.loc/avr-cpm/trunk/avrcpm/avr@106 57430480-672e-4586-8877-bcf8adbbf3b7 --- avrcpm.asm | 12 + config.inc | 2 - dsk_fat16.asm | 867 ++++++++++++++++++++++++++++++++++++++++ dsk_fsys.asm | 619 +++++++++++++++++++++++++++++ dsk_mgr.asm | 317 +++++++++++++++ dsk_ram.asm | 214 ++++++++++ init.asm | 16 +- macros.inc | 2 +- mmc.asm | 75 ++++ remainders.asm | 1028 +----------------------------------------------- virt_ports.asm | 162 ++++++++ 11 files changed, 2278 insertions(+), 1036 deletions(-) create mode 100644 dsk_fat16.asm create mode 100644 dsk_fsys.asm create mode 100644 dsk_mgr.asm create mode 100644 dsk_ram.asm create mode 100644 virt_ports.asm diff --git a/avrcpm.asm b/avrcpm.asm index 10da302..4e666c9 100644 --- a/avrcpm.asm +++ b/avrcpm.asm @@ -58,6 +58,18 @@ .include "dram-4bit.asm" #endif .include "remainders.asm" + +; >>>-------------------------------------- Virtual Devices + .include "virt_ports.asm" ; Virtual Ports for BIOS +; <<<-------------------------------------- Virtual Devices + +; >>>-------------------------------------- File System Management + .include "dsk_fsys.asm" ; Basic Filesystem definitions + .include "dsk_cpm.asm" ; CPM- Disk Interaktion + .include "dsk_ram.asm" ; RAM- Disk Interaktion + .include "dsk_fat16.asm" ; FAT16-DISK Interaktion + .include "dsk_mgr.asm" ; Disk- Manager +; <<<-------------------------------------- File System Management ; .include "z80int.asm" ;Old 8080 interpreter. ; .include "8080int.asm" ;New 8080 interpreter. ; .include "8080int-t3.asm" diff --git a/config.inc b/config.inc index e14ef43..d656087 100644 --- a/config.inc +++ b/config.inc @@ -35,8 +35,6 @@ #define BAUD 38400 /* console baud rate */ #endif -#define PARTID 0x52 /* Partition table id */ - /* http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */ #define K 1024 #define M 1204*K diff --git a/dsk_fat16.asm b/dsk_fat16.asm new file mode 100644 index 0000000..0cc32af --- /dev/null +++ b/dsk_fat16.asm @@ -0,0 +1,867 @@ +; Various functions for the Interaction with the FAT16 Filesystem +; +; Copyright (C) 2010 Frank Zoll +; +; This file is part of avrcpm. +; +; avrcpm is free software: you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; avrcpm is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with avrcpm. If not, see . +; +; $Id$ +; + +; =========================================================================== +; Prelimitary ! +; °°°°°°°°°°°°° +; Size of a Sector is fixed to 512 Bytes by Base - MMC Driver implementation +; The Functions below therefore assume a fixed Size of 512 Bytes per Sector. +; =========================================================================== + +#ifndef FAT16_SUPPORT + #define FAT16_SUPPORT 1 + #define FAT16_DEBUG 2 +#endif + +#if FAT16_SUPPORT + + +;-------------------------------- Defines for FAT16 Structures +#define PARTID_FAT16 0x0E + +;#define FAT16_BSO_SECSIZE 0x0b ; BootSectorOffset to Sectorsize Word +#define FAT16_BSO_CLUSTSZ 0x0d ; BootSectorOffset to Clustersize Byte +#define FAT16_BSO_RESSECT 0x0e ; BootSectorOffset to Number of Reserved Sectors +#define FAT16_BSO_VOLPTR 0x1c ; BootSectorOffset to First VolumeSector +#define FAT16_BSO_SECPERFAT 0x16 ; BootSectorOffset to Number of Sectors per Fat +#define FAT16_BSO_NUMFATCP 0x10 ; BootSectorOffset to Ammount of FAT Copys +#define FAT16_BSO_NUMDIRENT 0x11 ; BootSectorOffset to Max. Root Dir. Entrys + +;-------------------------------- Start of Data Segment + + .dseg + +fat_partfound: .byte 1 ; (0= no fat partition found 1=found partition) +fat_parttbl: .byte 8 ; first fat16 partition entry (start sector, sector count) +;fat_sectorsize: .byte 2 ; size of sector in bytes +fat_clustersize: .byte 1 ; sectors per cluster +fat_ressectors: .byte 2 ; number of reserved sectors +fat_secperfat: .byte 2 ; number of sectors per fat +fat_numfatcp: .byte 1 ; Number of FAT Copies +fat_numdirentrys:.byte 2 ; Max. ammount of Directory Entrys within Rootdirektory +fat_ptr2fat: .byte 4 ; pointer to the first fat sector +fat_ptr2dir: .byte 4 ; pointer to the first root directory sector +fat_ptr2dat: .byte 4 ; pointer to the first data sector + +; ------------------------------- Start of Code Segment + .cseg + +; ==================================================================== +; 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: +; ==================================================================== +fat_init_partitiontable: + + sts fat_partfound,_0 + + ldiw y,fat_parttbl + st y+,_0 + st y+,_0 + st y+,_0 + st y+,_0 + st y+,_0 + st y+,_0 + st y+,_0 + st y+,_0 + ret + +; ==================================================================== +; Function: Add's a FAT16 Partition for later Scanning +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : +; Variables : +; -------------------------------------------------------------------- +; Description: +; This funktion sets the internal Variables to set Start and Size +; of a given FAT16 Paritition. This Information will be used for a +; later scanning of the Partition. See Function "fat_scan_partition" +; for more information. +; ==================================================================== +fat_add_partition: + +.if FAT16_DEBUG > 0 + printstring "fat16 part found",0 + printnewline +.endif + + +; save variables on stack + push yl + push yh + +; set fat16 partition found flag + ldi yl,1 + sts fat_partfound,yl + +; save data from first fat16 partition + ldiw y,fat_parttbl + + ldd temp,z+PART_START + st y+,temp + ldd temp,z+PART_START+1 + st y+,temp + ldd temp,z+PART_START+2 + st y+,temp + ldd temp,z+PART_START+3 + st y+,temp + + ldd temp,z+PART_SIZE + st y+,temp + ldd temp,z+PART_SIZE+1 + st y+,temp + ldd temp,z+PART_SIZE+2 + st y+,temp + ldd temp,z+PART_SIZE+3 + st y+,temp + + +; reload variables from stack + pop yh + pop yl + + ret + +; --------------------------------------------------------------------------- +; Read and Scann a FAT16 Partition for Imagedatefiles +; --------------------------------------------------------------------------- +; This Routine reads the Bootblock and scanns it for a Diskimage +; Input Registers : none +; Output Registers : none +; Changes Variables: none +; --------------------------------------------------------------------------- + + +fat_scan_partition: + +.if FAT16_DEBUG > 0 + printstring "fat16 scanning",0 + printnewline +.endif + +; Check if a FAT16 Partition was realy found + lds yl,fat_partfound + cpi yl,1 + brne fat_scan_error + + +.if FAT16_DEBUG > 0 + printstring "free entrys in ptable ?",0 + printnewline +.endif + +; Check for free Entrys in Partition table + lds yl,ndisks + cpi yl,MAXDISKS + breq fat_scan_error + +.if FAT16_DEBUG > 0 + printstring "read fat bootblock.",0 + printnewline +.endif + +; Scan partition start + ldiw z,fat_parttbl + ldd xl,z+0 + ldd xh,z+1 + ldd yl,z+2 + ldd yh,z+3 + +; Load first sector from Partition + rcall mmcReadSect + tst temp + breq fat_bootblock_check + +; Read error: Block not found +fat_scan_error: + clr temp + ret + +fat_bootblock_check: + +.if FAT16_DEBUG > 0 + printstring "fat16 bootblock check",0 + printnewline +.endif + +; -> Size of Sectors fixed at 512 Bytes +; Get ammount of Bytes per Sector +; ldiw z,hostbuf+FAT16_BSO_SECSIZE +; ldiw y,fat_sectorsize +; ld temp,z +; st y+, temp +; ldd temp2,z+1 +; st y , temp2 +; +;.if FAT16_DEBUG > 0 +; printstring "Bytes per Sector ",0 +; rcall printhexw +; printnewline +;.endif + +; Anzahl der Sectoren pro Cluster lesen + ldiw z,hostbuf+FAT16_BSO_CLUSTSZ + ld temp,z + sts fat_clustersize,temp + +.if FAT16_DEBUG > 0 + printstring "Sectors per Cluster ",0 + rcall printhex + printnewline +.endif + +; Anzahl der reservierten Sectoren + ldiw z,hostbuf+FAT16_BSO_RESSECT + ld temp,z+ + sts fat_ressectors,temp ; low byte + ld temp2,z + sts fat_ressectors+1,temp2 ; high byte + +.if FAT16_DEBUG > 0 + printstring "Reserved Sectors__: ",0 + rcall printhexw + printnewline +.endif + +; Anzahl der Sectoren pro FAT + ldiw z,hostbuf+FAT16_BSO_SECPERFAT + ld temp,z+ + sts fat_secperfat,temp ; low byte + ld temp2,z + sts fat_secperfat+1,temp2 ; high byte + +.if FAT16_DEBUG > 0 + printstring "Sectors per FAT__: ",0 + rcall printhexw + printnewline +.endif + +; Anzahl der FAT kopien + ldiw z,hostbuf+FAT16_BSO_NUMFATCP + ld temp,z + sts fat_numfatcp,temp ; low byte + +.if FAT16_DEBUG > 0 + printstring "Ammount of FAT copies: ",0 + rcall printhex + printnewline +.endif + +; Max. Anzahl der Dir. Enträge im Root Verz. + ldiw z,hostbuf+FAT16_BSO_NUMDIRENT + ld temp,z+ + sts fat_numdirentrys,temp ; low byte + ld temp2,z + sts fat_numdirentrys+1,temp2 ; high byte + +.if FAT16_DEBUG > 0 + printstring "Max. entrys in Rootdir.: ",0 + rcall printhexw + printnewline +.endif + +; Print begin of Volume +.if FAT16_DEBUG > 1 + + ldiw z,fat_parttbl + ldd xl,z+0 + ldd xh,z+1 + ldd yl,z+2 + ldd yh,z+3 + + printstring "Begin of Volume at: ",0 + mov temp ,yl + mov temp2,yh + rcall printhexw + mov temp ,xl + mov temp2,xh + rcall printhexw + printnewline +.endif + +; Calculate begin of FAT within the Volume + lds temp ,fat_ressectors + lds temp2,fat_ressectors+1 + + ldiw z,fat_parttbl + ldd xl,z+0 + ldd xh,z+1 + ldd yl,z+2 + ldd yh,z+3 + + add xl,temp + adc xh,temp2 + adc yl,_0 + adc yh,_0 + + sts fat_ptr2fat ,xl + sts fat_ptr2fat+1,xh + sts fat_ptr2fat+2,yl + sts fat_ptr2fat+3,yh + +.if FAT16_DEBUG > 1 + printstring "Begin of FAT at___: ",0 + mov temp ,yl + mov temp2,yh + rcall printhexw + mov temp ,xl + mov temp2,xh + rcall printhexw + printnewline +.endif + +; Calculate begin of Root- Directory within the Volume + ldiw z,fat_ptr2fat + ldd xl,z+0 + ldd xh,z+1 + ldd yl,z+2 + ldd yh,z+3 + + lds temp ,fat_secperfat + lds temp2,fat_secperfat+1 + lds temp3,fat_numfatcp + +fat_calc_dp_loop: + cp temp3,_0 + breq fat_calc_dp_lend + + add xl,temp + adc xh,temp2 + adc yl,_0 + adc yh,_0 + + dec temp3 + + jmp fat_calc_dp_loop +fat_calc_dp_lend: + + sts fat_ptr2dir ,xl + sts fat_ptr2dir+1,xh + sts fat_ptr2dir+2,yl + sts fat_ptr2dir+3,yh + + +.if FAT16_DEBUG > 1 + printstring "Begin of DIR at___: ",0 + mov temp ,yl + mov temp2,yh + rcall printhexw + mov temp ,xl + mov temp2,xh + rcall printhexw + printnewline +.endif + +; Calculate begin of DATA Clusters within the Volume +; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor + +; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor + + lds zl,fat_numdirentrys ; low byte + lds zh,fat_numdirentrys+1 ; high byte + +; Num. Direntrys / 16 + lsr zh + ror zl + lsr zh + ror zl + lsr zh + ror zl + lsr zh + ror zl + + lds xl,fat_ptr2dir + lds xh,fat_ptr2dir+1 + lds yl,fat_ptr2dir+2 + lds yh,fat_ptr2dir+3 + + add xl,zl + adc xh,zh + adc yl,_0 + adc yh,_0 + + sts fat_ptr2dat ,xl + sts fat_ptr2dat+1,xh + sts fat_ptr2dat+2,yl + sts fat_ptr2dat+3,yh + +.if FAT16_DEBUG > 1 + printstring "Begin of Data at__: ",0 + mov temp ,yl + mov temp2,yh + rcall printhexw + mov temp ,xl + mov temp2,xh + rcall printhexw + printnewline +.endif + +; Here Starts the Scann of the Directory for valid image Files. + + lds xl,fat_ptr2dir + lds xh,fat_ptr2dir+1 + lds yl,fat_ptr2dir+2 + lds yh,fat_ptr2dir+3 + +; Load first sector from Directory + call mmcReadSect + tst temp + breq fat_look_for_images + +; Read error: Block not found + clr temp + ret + +; Looks at a read directory block for image entrys +fat_look_for_images: + + ldiw z,hostbuf + ldi temp2,0 + +fat_look_for_loop: + ldd temp,z+0 + cpi temp,'C' + brne fat_look_not_ok + + ldd temp,z+1 + cpi temp,'P' + brne fat_look_not_ok + + ldd temp,z+2 + cpi temp,'M' + brne fat_look_not_ok + + ldd temp,z+3 + cpi temp,'D' + brne fat_look_not_ok + + ldd temp,z+4 + cpi temp,'S' + brne fat_look_not_ok + + ldd temp,z+5 + cpi temp,'K' + brne fat_look_not_ok + + ldd temp,z+6 + cpi temp,'_' + brne fat_look_not_ok + + ldd temp,z+8 + cpi temp,'I' + brne fat_look_not_ok + + ldd temp,z+9 + cpi temp,'M' + brne fat_look_not_ok + + ldd temp,z+10 + cpi temp,'G' + brne fat_look_not_ok + + jmp fat_store_new_entry + +fat_look_not_ok: + + //ldi temp,32 + addiw z,32 + + inc temp2 + cpi temp2,16 ; max entrys/sector + breq fat_scan_next_sector + jmp fat_look_for_loop + +fat_scan_next_sector: + + ret + + +; Create new Partition Entry +fat_store_new_entry: + +; Found a valid image +.if FAT16_DEBUG > 1 + printstring "Found a valid Image ! ",0 + printnewline +.endif + + ldiw y,hostparttbl + lds temp,ndisks + +fat_look_store_loop: + cp temp,_0 + breq fat_look_store + + adiw y,PARTENTRY_SIZE + dec temp + jmp fat_look_store_loop + +fat_look_store: +; Set Type of Partition to FAT16- Fileimage + ldi temp,dskType_FAT + st y+,temp + +; Offset to Startcluster + 2 + ldd temp,z+0x1A + st y+,temp + ldd temp,z+0x1B + st y+,temp + ldi temp,0 + st y+,temp + st y+,temp + +; Filesize in Bytes - 2,4,8,16,32,64,128,256,512 +; ldd temp,z+0x1C +; st y+,temp +; ldd temp,z+0x1D +; st y+,temp +; ldd temp,z+0x1E +; st y+,temp +; ldd temp,z+0x1F +; st y+,temp + +; Convert Filesize to ammount of sectors + ldd xl,z+0x1D + ldd xh,z+0x1E + ldd zl,z+0x1F + mov zh,_0 + + lsr zh + ror zl + ror xh + ror xl + +; store ammount of sectors in partitiontable + st y+,xl + st y+,xh + st y+,zl + st y+,zh + +; Check for another free entry in partition table + lds temp,ndisks + inc temp + sts ndisks,temp + + +.if FAT16_DEBUG > 1 +; Test finding of the first sector + ldd xl,z+0x1A + ldd xh,z+0x1B + ldi zl,0 + + rcall fat_gethostsec + + printstring "Begin of Image at: ",0 + mov temp ,yl + mov temp2,yh + rcall printhexw + mov temp ,xl + mov temp2,xh + rcall printhexw + printnewline + +.endif + +; cp temp,MAXDISKS +; brne fat_scan_for_more + + ret + + +; ==================================================================== +; Function: Cluster+Offset to HostSector +; ==================================================================== +; Parameters: [in] xh,xl Cluster Number +; [in] zl Offset +; [out] yh,yl,xh,xl Sector Number on Disk +; -------------------------------------------------------------------- +; Registers : +; Variables : [used] fat_clustersize Ammount of Sectors per Cluster +; [changes] temp +; -------------------------------------------------------------------- +; Description: +; ! Only works with Clustersizes 1,2,4,8,16,32,64,128 ! +; ==================================================================== +fat_gethostsec: + +; Get Offset into Data area of Disk + rcall fat_clusttosec + +; add given offset + add xl,zl + adc xh,_0 + adc yl,_0 + adc yh,_0 + +; add begin of data area to offset + lds temp,fat_ptr2dat+0 + add xl,temp + lds temp,fat_ptr2dat+1 + adc xh,temp + lds temp,fat_ptr2dat+2 + adc yl,temp + lds temp,fat_ptr2dat+3 + adc yh,temp + ret + +; ==================================================================== +; Function: Cluster to Sector +; ==================================================================== +; Parameters: [in] xl,xh Cluster Number +; [out] xl,xh,yl,yh Sector Number +; -------------------------------------------------------------------- +; Registers : +; Variables : [used] fat_clustersize Ammount of Sectors per Cluster +; [changes] temp +; -------------------------------------------------------------------- +; Description: +; ! Only works with Clustersizes 1,2,4,8,16,32,64,128 ! +; ==================================================================== +fat_clusttosec: + clr yl + clr yh + + ldi temp,2 + sub xl,temp ; Substract the 2 reserved clusters + sbc xh,_0 + + lds temp,fat_clustersize + +fat_c2s_loop: + lsr temp + tst temp + breq fat_c2s_end + + lsl xl + rol xh + rol yl + rol yh + rjmp fat_c2s_loop + +fat_c2s_end: + ret + +; ==================================================================== +; Function: CP/M Sector to Cluster & Offset +; ==================================================================== +; Parameters: [in] xl,xh Cluster Number +; [out] xl,xh,yl,yh Sector Number +; -------------------------------------------------------------------- +; Registers : +; Variables : [used] fat_clustersize Ammount of Sectors per Cluster +; [changes] temp +; -------------------------------------------------------------------- +; Description: +; ! Only works with Clustersizes 1,2,4,8,16,32,64,128 ! +; ==================================================================== +fat_cpmtoclust: + + 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: +; ==================================================================== + +fat_hostparam: + lds xl,hostdsk + +.if HOSTRW_DEBUG + mov temp,xl + subi temp,-('A') + rcall uartputc + printstring ": " +.endif + + rcall dsk_getpartentry ; get partition entry + +fat_hostlend: + lds temp ,hostlba + lds temp2,hostlba+1 + lds temp3,hostlba+2 + +.if HOSTRW_DEBUG + printstring "lba: " + clr temp4 + rcall print_ultoa +.endif + + ldd xl,z+5 ; get size of disk in sectors + ldd xh,z+6 + ldd yl,z+7 + + cp temp,xl ; check given sector against disksize + cpc temp2,xh + cpc temp3,yl + brcs fat_hp1 + +.if HOSTRW_DEBUG + printstring ", max: " + push temp4 + push temp3 + push temp2 + push temp + movw temp,x + mov temp3,yl + clr temp4 + rcall print_ultoa + pop temp + pop temp2 + pop temp3 + pop temp4 + printstring " " +.endif + + clr temp + ret + +fat_hp1: + ldd xl,z+1 ; startsector + ldd xh,z+2 + ldd yl,z+3 + ldd yh,z+4 + + add xl,temp ; startsector + offset + adc xh,temp2 + adc yl,temp3 + adc yh,_0 + +.if HOSTRW_DEBUG + printstring ", abs:" + push temp4 + push temp3 + push temp2 + push temp + movw temp,x + movw temp3,y + rcall print_ultoa + pop temp + pop temp2 + pop temp3 + pop temp4 + printstring " " +.endif + + ori temp,255 +fat_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: +; ==================================================================== + +fat_writehost: +.if HOSTRW_DEBUG + printnewline + printstring "host write " +.endif + rcall fat_hostparam + breq fat_rdwr_err + + ;call mmcWriteSect ; disabled till read is functioning + tst temp + breq fat_rdwr_ok + + rcall mgr_init_partitions + cbr temp,0x80 + breq fat_rdwr_err + + rcall fat_hostparam + breq fat_rdwr_err + ;call mmcWriteSect ; disabled till read is functioning + tst temp + brne fat_rdwr_err + rjmp fat_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: +; ==================================================================== + +fat_readhost: +.if HOSTRW_DEBUG + printnewline + printstring "host read " +.endif + + rcall fat_hostparam + breq fat_rdwr_err + + call mmcReadSect + tst temp + breq fat_rdwr_ok + + rcall mgr_init_partitions + cbr temp,0x80 + breq fat_rdwr_err + + rcall fat_hostparam + breq fat_rdwr_err + call mmcReadSect + tst temp + brne fat_rdwr_err + +fat_rdwr_ok: + sts erflag,_0 + ret + +fat_rdwr_err: + sts erflag,_255 + ret +#endif diff --git a/dsk_fsys.asm b/dsk_fsys.asm new file mode 100644 index 0000000..ccf1ae2 --- /dev/null +++ b/dsk_fsys.asm @@ -0,0 +1,619 @@ +; Filesystem functions for the Interaction with BIOS and Disks +; +; Copyright (C) 2010 Frank Zoll +; +; This file is part of avrcpm. +; +; avrcpm is free software: you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; avrcpm is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with avrcpm. If not, see . +; +; $Id$ +; + + +; ---------------- Defines for the Filesystem Interface ------- + + +;***************************************************** +;* Disk-Manager constants * +;***************************************************** + .equ dskType_None = 0 + .equ dskType_CPM = 1 + .equ dskType_FAT = 2 + .equ dskType_RAM = 3 + +;***************************************************** +;* CP/M to host disk constants * +;***************************************************** + .equ MAXDISKS = 4 ;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 + +;***************************************************** +;* BDOS constants on entry to write * +;***************************************************** + .equ WRALL = 0 ;write to allocated + .equ WRDIR = 1 ;write to directory + .equ WRUAL = 2 ;write to unallocated + .equ WRTMSK= 3 ;write type mask +;----------------------------------------------- Start of Data Segment + + .dseg + +ndisks: .byte 1 ;Number of CP/M disks + +seekdsk: .byte 1 ;seek disk number +seektrk: .byte 2 ;seek track number +seeksec: .byte 1 ;seek sector number + +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 + +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) + + +; ------------------------------- Start of Code Segment + .cseg + +; ==================================================================== +; Function: Get a Pointer to a Partitiontable entry +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : [w] z Pointer to the Partitionentry +; [r] xl Number of Diskentry to Read +; -------------------------------------------------------------------- +; Description: +; ==================================================================== +dsk_getpartentry: + + ldiw z,hostparttbl + mov temp,xl + +dsk_getpartentryloop: + cp temp,_0 + breq dsk_getpartentryloopend + adiw z,PARTENTRY_SIZE + dec temp + jmp dsk_getpartentryloop +dsk_getpartentryloopend: + ret + +; ==================================================================== +; Function: +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seeksec Sector to read +; [r] seektrk Track to read +; -------------------------------------------------------------------- +; Description: +; ==================================================================== +dskDiskCheck: + lds temp2,seekdsk + cpi temp2,RAMDISKNR + brsh dsk_dchrd ;maybe ramdisk + +; Check if selected disk # is less then # of disks. + + lds temp,ndisks + tst temp + brne dsk_dchpart1 + +; Need to init + + rcall mgr_init_partitions + cbr temp,0x80 + lds temp2,seekdsk + +dsk_dchpart1: + cp temp2,temp + brsh dsk_dcher + +dsk_dchend: + ldi temp,0 + ret + +dsk_dchrd: +#if RAMDISKCNT + cpi temp,RAMDISKNR+RAMDISKCNT + brlo dsk_dchend +#endif +dsk_dcher: + ldi temp,0xff ;error return + ret + +dskErrorRet: + 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 + ret + +dskSecSel: + sts seeksec,temp + ret + +dskDmal: + sts dmaadr,temp + ret + +dskDmah: + sts dmaadr+1,temp + ret + +; ==================================================================== +; Function: Does a Disk interaction +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seeksec Sector to read +; [r] seektrk Track to read +; -------------------------------------------------------------------- +; Description: +; ==================================================================== +dskDoIt: +.if DISK_DEBUG + push temp + sbrc temp,READ_FUNC + rjmp dskdbgr + sbrc temp,WRITE_FUNC + rjmp dskdbgw + rjmp dskdbge + +dskdbgr: + printnewline + printstring "Disk read: " + rjmp dskdbg1 +dskdbgw: + printnewline + printstring "Disk write: " +dskdbg1: + lds temp,seekdsk + subi temp,-('A') + rcall uartputc + printstring ": track " + lds temp2,seektrk+1 + lds temp,seektrk + rcall printhexw + printstring ", sector " + lds temp,seeksec + rcall printhex + printstring ", dma-addr " + lds temp2,dmaadr+1 + lds temp,dmaadr + rcall printhexw + pop temp + push temp + sbrs temp,WRITE_FUNC + rjmp dskdbge + printstring " wrtype " + andi temp,3 + rcall printhex +dskdbge: + pop temp +.endif + ;See what has to be done. + sbrc temp,READ_FUNC + rjmp dsk_read + sbrc temp,WRITE_FUNC + rjmp dsk_write + sbrc temp,HOME_FUNC + rjmp dsk_home + sbrc temp,BOOT_FUNC + rjmp dsk_boot + + printstring "DISK I/O: Invalid Function code: " + rcall printhex + rjmp haltinv + +dsk_boot: + sts ndisks,_0 ;no active partitions +dsk_cboot: + 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 + ret + + + +; ==================================================================== +; 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: +; ==================================================================== +dsk_read: + sts erflag,_0 + sbi flags,readop ; Set read operation flag + lds xl,seekdsk + rcall dsk_getpartentry ; Get Paritiontableentry + ld temp,z ; Get Partitiontype + +; Isn't it a Disk ? + cpi temp,dskType_None + brne PC+2 + rjmp dsk_read_err +; Is it a RamDisk ? + cpi temp,dskType_RAM + brne PC+2 + rjmp rdsk_read +; It must be a FAT16-Imagefile or CP/M Partition. + sts unacnt,_0 + sbi flags,rsflag ;must read data + ldi temp,WRUAL ;write type + sts wrtype,temp ;treat as unalloc + rjmp dsk_rwoper ;to perform the read + +dsk_read_err: + 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: +; ==================================================================== +dsk_write: + ;write the selected sector + sts erflag,_0 + cbi flags,readop ; not a read operation + lds xl,seekdsk + rcall dsk_getpartentry ; Get Paritiontableentry + ld temp,z ; Get Partitiontype + +; Isn't it a Disk ? + cpi temp,dskType_None + brne PC+2 + rjmp dsk_write_err + +; Is it a RamDisk ? + cpi temp,dskType_RAM + brne PC+2 + rjmp rdsk_write + +; It must be a FAT16-Imagefile or CP/M Partition. + + cbi flags,readop ;not a read operation + + andi temp,WRTMSK + sts wrtype,temp ;save write type + + 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 +; +dsk_chkuna: + ;check for write to unallocated sector + 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 + +; 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 + +; tracks are the same + 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 + +; 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 +; +dsk_noovf: + 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 + 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: +; ==================================================================== +dsk_rwoper: + ;enter here to perform the read/write +.if DISK_DEBUG + printstring ", flags: " + in temp,flags + rcall printhex +.endif + 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 + + ;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 + ;yl:xh:xl = host block to seek +; active host sector? + 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 + +; host buffer active, same as seek buffer? + 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 + breq dsk_match +; +dsk_nomatch: + ;proper disk, but not correct sector + sbis flags,hostwrt ;host written? + rjmp dsk_filhst + push xl + push xh + push yl + rcall dsk_writehost ;clear host buff + 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 + + sbic flags,rsflag ;need to read? + rcall dsk_readhost ;yes, if 1 + 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 + +.if DISK_DEBUG > 2 + push r0 + push r1 + printstring "; host buf adr: " + pop temp2 + pop temp + rcall printhexw +.endif + + lds xl,dmaadr + lds xh,dmaadr+1 + ldi temp3,128 ;length of move + sbic flags,readop ;which way? + rjmp dsk_rmove ;skip if read + +; mark write operation + sbi flags,hostwrt ;hostwrt = 1 +dsk_wmove: + mem_read + st z+,temp + adiw xl,1 + dec temp3 + brne dsk_wmove + rjmp dsk_rwmfin + +dsk_rmove: + ld temp,z+ + mem_write + adiw xl,1 + 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? + breq dsk_wdir + ret ;no further processing +dsk_wdir: +; clear host buffer for directory write + lds temp,erflag + tst temp ;errors? + breq dsk_wdir1 + ret ;skip if so +dsk_wdir1: + rcall dsk_writehost ;clear host buff + cbi flags,hostwrt ;buffer written + 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: +; ==================================================================== +dsk_writehost: + lds xl,hostdsk + rcall dsk_getpartentry + ld temp,z + +; Is it a FAT16 Diskimage ? + cpi temp,dskType_FAT + brne PC+2 + rjmp fat_writehost + +; Is it a CP/M Partition ? + cpi temp,dskType_CPM + brne PC+2 + rjmp cpm_writehost +; Disktype not supported -> Return + ret + +; ==================================================================== +; 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: +; ==================================================================== +dsk_readhost: + lds xl,hostdsk + rcall dsk_getpartentry + ld temp,z + +; Is it a FAT16 Diskimage ? + cpi temp,dskType_FAT + brne PC+2 + rjmp fat_readhost + +; Is it a CP/M Partition ? + cpi temp,dskType_CPM + brne PC+2 + rjmp cpm_readhost +; Disktype not supported -> Return + ret + diff --git a/dsk_mgr.asm b/dsk_mgr.asm new file mode 100644 index 0000000..ac9b0d4 --- /dev/null +++ b/dsk_mgr.asm @@ -0,0 +1,317 @@ +; Various Management functions for the Interaction with the File- +; systems +; +; Copyright (C) 2010 Frank Zoll +; +; This file is part of avrcpm. +; +; avrcpm is free software: you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; avrcpm is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with avrcpm. If not, see . +; +; $Id$ +; + + +; ------------------------- Defines for the disk management Structures + +;----------------------------------------------- Start of Data Segment + + .dseg + + + +; ------------------------------- Start of Code Segment + .cseg + +; ==================================================================== +; Function: Scans a Disk for CP/M Partions +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [w] temp Status of Operation +; (0x80 - Operation Failure ) +; (others - Operation Suceded) +; -------------------------------------------------------------------- +; Description: +; This Function scans an SD-Cards Boot-Sector for valid Partitions. +; First all original CP/M Partitions will be usesed as Drives for +; the CPM-System. Wenn all CP/M Partitions are found, a second +; scann will be made. In the second Scan, the first FAT16 Partition +; on the Disk will be used for a detailed analyses. If there +; are any Files like "cpm_x.img" are found, these Files will be +; used as Disks by the CP/M- System. ( x must be in the Range A to D ) +; ==================================================================== +mgr_init_partitions: + + sts ndisks,_0 ; Set Number of Disks to 0 + +; Initialize temp partition table + ldiw y,tmp_tbl + ldi temp2,PARTENTRY_SIZE*MAXDISKS +mgr_picl: + st y+,_0 + dec temp2 + brne mgr_picl + +; Start mmc Card interaction + call mmcInit + andi temp,MMCST_NOINIT & MMCST_NODISK + brne mgr_pierr + +;Load first sector from MMC (boot sector) + ldiw y,0 ; Sector 0 + movw x,y + call mmcReadSect + tst temp + breq mgr_check_bootsektor + +mgr_pierr: + clr temp + ret + +mgr_check_bootsektor: +;Pointer to first temp table entry + ldiw y,tmp_tbl +;Test, if it has a valid MBR + + ldiw z,hostbuf+510-1 ;Point to last byte of partition table + + 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 + breq mgr_search + +;No MBR, no partition table ... + inc temp3 ;pretend we have one. + 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 + 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) + +mgr_ploop: + +; Get Partitiontype + ldd temp,z+PART_TYPE + +; Test for CP/M Partition + cpi temp,PARTID_CPM + brne mgr_nextp + + rcall cpm_add_partition + + inc temp3 + cpi temp3,MAXDISKS + breq mgr_pend + rjmp mgr_nextp + +mgr_nextp: + adiw zl,16 + cpi zl,low(hostbuf+510) + cpc zh,temp4 + brlo mgr_ploop + +; Test for FAT16 Partition + ldiw z,hostbuf+510-1-63 ;Point to first byte of partition table + ldi temp4,high(hostbuf+510) + +mgr_ploop2: + +; Get Partitiontype + ldd temp,z+PART_TYPE + +; Test for FAT Partition + cpi temp,PARTID_FAT16 + brne mgr_nextp2 + + rcall fat_add_partition + + rjmp mgr_pend + +mgr_nextp2: + adiw zl,16 + cpi zl,low(hostbuf+510) + cpc zh,temp4 + brlo mgr_ploop2 + +mgr_pend: + +; Initialize RAM-Disks + rcall rdsk_add_partition + +;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 + brtc mgr_pcpe + + tst temp + breq mgr_pcpe + +; SD card not changed. + rcall fat_scan_partition + + lds temp,ndisks + sbr temp,0x80 + +mgr_pcpe: + + ret + + +; ==================================================================== +; Function: Print partition table info +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] hostparttbl Table with Partitioninformations +; [r] hostparttbltop Pointer to the Top of the Table +; -------------------------------------------------------------------- +; Description: +; ==================================================================== + +mgr_prnt_parttbl: + ldiw z,hostparttbl +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 + +; Partitiontype examining + ldd xl,z+0 +; CP/M ? + cpi xl,dskType_CPM + brne mgr_prtb_nocpm + rcall mgr_prnt_table_cpm + rjmp mgr_prnt_size + +; FAT16 ? +mgr_prtb_nocpm: + cpi xl,dskType_FAT + brne mgr_prtb_nofat + rcall mgr_prnt_table_fat + rjmp mgr_prnt_size +; RAMDISK ? +mgr_prtb_nofat: + cpi xl,dskType_RAM + brne mgr_prnt_err + rcall mgr_prnt_table_ram + rjmp mgr_prnt_size +; Entry Error +mgr_prnt_err: + rcall mgr_prnt_table_err + rjmp mgr_prnt_size + +mgr_prnop: + rcall mgr_prnt_image + +mgr_prnt_size: + rcall 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 + + lsr temp4 + ror temp3 + ror temp2 + ror temp + rcall print_ultoa + printstring "KB." + +mgr_goto_next_part: + adiw z,PARTENTRY_SIZE + ldi temp,high(hostparttbltop) + cpi zl, low (hostparttbltop) + cpc zh,temp + brlo pprl + +mgr_pppre: + ret + + +mgr_prnt_fatsize: + rcall 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 + + rcall print_ultoa + printstring "BYTE." + + jmp mgr_goto_next_part + +mgr_prnt_table_cpm: + printstring "CP/M partition at: " + ret + +mgr_prnt_table_fat: + printstring "FAT16 File-Image at: " + ret + +mgr_prnt_table_ram: + printstring "Ramdisk at: " + ret + +mgr_prnt_table_err: + printstring "Unknown Entry at: " + ret + +mgr_prnt_image: + printstring "Assuming CP/M image at: " + ret + + diff --git a/dsk_ram.asm b/dsk_ram.asm new file mode 100644 index 0000000..4216506 --- /dev/null +++ b/dsk_ram.asm @@ -0,0 +1,214 @@ +; Various functions for the Interaction with the CPM Filesystem +; +; Copyright (C) 2010 Frank Zoll +; +; This file is part of avrcpm. +; +; avrcpm is free software: you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; avrcpm is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with avrcpm. If not, see . +; +; $Id$ +; + +#ifndef RAMDSK_SUPPORT + #define RAMDSK_SUPPORT 0 +#endif + +#if RAMDSK_SUPPORT + +;-------------------------------------- Defines for RAMDISK Structures + +;----------------------------------------------- Start of Data Segment + + .dseg + +rdskbuf: .byte 128 ; Buffer for RAM-Disk interaktions + +; ---------------------------------------------- Start of Code Segment + .cseg + +; ==================================================================== +; Function: Calculate an sets the adress of Sector within the RAMDISK +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seeksec Sector to read +; [r] seektrk Track to read +; [w] temp3 Number of Bytes per Sector (128) +; -------------------------------------------------------------------- +; Description: +; ==================================================================== + + +rdsk_adr: + ldi xl,0 + lds xh,seeksec + lds temp2,seektrk + + lsr xh + ror xl ;Col 0..7 + + mov temp,temp2 + andi temp,0x0f + swap temp + or xh,temp ;Row 0..7 + + ldiw z,rdskbuf + ldi temp3,128 + DRAM_SETADDR xh, ~0,(1< 1 + mov temp,xh + rcall printhex + printstring " " + mov temp,xl + rcall printhex + printstring " " +.endif + ret + +; ==================================================================== +; Function: Does a read opperation on a RAMDISK +; ==================================================================== +; Parameters +; -------------------------------------------------------------------- +; Registers : none +; Variables : [r] seeksec Sector to read +; [r] seektrk Track to read +; [r] flags RW operation Flags +; [w] erflag Error Status of the operation +; -------------------------------------------------------------------- +; Description: +; ==================================================================== + + +rdsk_read: + +.if DISK_DEBUG > 1 + printnewline + printstring "rd-adr: " +.endif + rcall rdsk_adr + +rdsk_rdl: + DRAM_SETADDR xl, ~(1< 1 + printnewline + printstring "wr-adr: " +.endif + lds xl,dmaadr + lds xh,dmaadr+1 + ldiw z,rdskbuf + ldi temp3,128 +rdsk_wrldl: + mem_read + st z+,temp + adiw x,1 + dec temp3 + brne rdsk_wrldl + + ldi temp2,RAM_DQ_MASK | (1< 1 + printnewline + printstring "mmcRdWord " +.endif + lds _tmp0,mmcStat + ldi temp,RES_NOTRDY + sbrc _tmp0,MMCST_NOINIT + ret + + spi_clkfast + lds temp,mmcCardType + sbrs temp,log2(CT_BLOCK) + rcall mul_yx_512 ;Convert to byte address (*512) + + ldi temp2,CMD17 + rcall mmcCmd + ldi temp2,RES_ERROR + brne mmc_rdexw + +; Receive a data packet from MMC + + ldiw y,512 ;Number of bytes to tranfer + ldi temp,200 ;Wait for data packet in timeout of 200ms. + sts delay_timer1,temp +mmc_rcvw_wl: + rcall spi_rcvr + cp temp,_255 + brne mmc_rcvw_start + lds temp2,delay_timer1 + cpi temp2,0 + brne mmc_rcvw_wl +mmc_rcvw_start: + cpi temp,0xFE ;If not valid data token, + ldi temp2,RES_ERROR + brne mmc_rdexw + + rcall spi_rcvr ;Shift in first byte. + out SPDR,_255 ;Start shift in next byte. +mmc_rcvw_rl: + sbiw yl,1 + breq mmc_rcvw_rle + //st z+,temp + spi_waitm + in temp,SPDR + out SPDR,_255 + rjmp mmc_rcvw_rl + +mmc_rcvw_rle: + //st z+,temp ;Store last byte in buffer + rcall spi_wait ; while SPI module shifts in crc part1. + rcall spi_rcvr ;Read second crc. + + ldi temp2,RES_OK ;Return success +mmc_rdexw: + rcall mmcDeselect + spi_disable + mov temp,temp2 +.if MMC_DEBUG > 1 + printstring "RdWordRes: " + rcall printhex + printstring " " +.endif + ret ;-------------------------------------------------------------- ; Write sector diff --git a/remainders.asm b/remainders.asm index 2af7532..a1372a6 100644 --- a/remainders.asm +++ b/remainders.asm @@ -182,1040 +182,16 @@ printstr_end: pop zl pop zh ret - -; ---------------- 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 - - .equ READ_FUNC = 7 - .equ WRITE_FUNC = 6 - .equ BOOT_FUNC = 5 - .equ HOME_FUNC = 4 - - - -;***************************************************** -;* CP/M to host disk constants * -;***************************************************** - .equ MAXDISKS = 4 ;Max number of Disks (partitions) - .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 - -;***************************************************** -;* BDOS constants on entry to write * -;***************************************************** - .equ WRALL = 0 ;write to allocated - .equ WRDIR = 1 ;write to directory - .equ WRUAL = 2 ;write to unallocated - .equ WRTMSK= 3 ;write type mask - - - .dseg -ndisks: .byte 1 ;Number of CP/M disks - -seekdsk: .byte 1 ;seek disk number -seektrk: .byte 2 ;seek track number -seeksec: .byte 1 ;seek sector number - -hostparttbl: .byte 8*MAXDISKS ;host partition table (start sector, sector count) -hostparttbltop: -hostdsk: .byte 1 ;host disk number -hostlba: .byte 3 ;host sector number (relative to partition start) - -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 -hostbuf: .byte hostsize ;host buffer (from/to SD-card) + + .dseg .cseg -conStatus: - lds temp,rxcount - cpse temp,_0 - ldi temp,0xff - ret - -conInp: - rjmp uartgetc - -dbgOut: - printnewline - printstring "Debug: " - rcall printhex - ret - -conOut: - rjmp uartputc - -uartstat: - clr temp - lds temp2,rxcount - cpse temp2,_0 - sbr temp,0x01 - lds temp2,txcount - cpi temp2,TXBUFSIZE - breq uartst_1 - sbr temp,0x02 -uartst_1: - ret - -uartout: - lds temp2,txcount - cpi temp2,TXBUFSIZE - breq uartout_1 - rjmp uartputc -uartout_1: - ret - -uartin: - clr temp - lds temp2,rxcount - cpse temp2,_0 - rjmp uartgetc - ret - -;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 - - -dskDiskCheck: - lds temp2,seekdsk - cpi temp2,RAMDISKNR - brsh dsk_dchrd ;maybe ramdisk - -; Check if selected disk # is less then # of disks. - - lds temp,ndisks - tst temp - brne dsk_dchpart1 - -; Need to init - - rcall dsk_partinit - cbr temp,0x80 - lds temp2,seekdsk - -dsk_dchpart1: - cp temp2,temp - brsh dsk_dcher - -dsk_dchend: - ldi temp,0 - ret - -dsk_dchrd: -#if RAMDISKCNT - cpi temp,RAMDISKNR+RAMDISKCNT - brlo dsk_dchend -#endif -dsk_dcher: - ldi temp,0xff ;error return - ret - - - - -dskErrorRet: - 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 - ret - -dskSecSel: - sts seeksec,temp - ret - -dskDmal: - sts dmaadr,temp - ret - -dskDmah: - sts dmaadr+1,temp - ret - -dskDoIt: -.if DISK_DEBUG - push temp - sbrc temp,READ_FUNC - rjmp dskdbgr - sbrc temp,WRITE_FUNC - rjmp dskdbgw - rjmp dskdbge - -dskdbgr: - printnewline - printstring "Disk read: " - rjmp dskdbg1 -dskdbgw: - printnewline - printstring "Disk write: " -dskdbg1: - lds temp,seekdsk - subi temp,-('A') - rcall uartputc - printstring ": track " - lds temp2,seektrk+1 - lds temp,seektrk - rcall printhexw - printstring ", sector " - lds temp,seeksec - rcall printhex - printstring ", dma-addr " - lds temp2,dmaadr+1 - lds temp,dmaadr - rcall printhexw - pop temp - push temp - sbrs temp,WRITE_FUNC - rjmp dskdbge - printstring " wrtype " - andi temp,3 - rcall printhex -dskdbge: - pop temp -.endif - ;See what has to be done. - sbrc temp,READ_FUNC - rjmp dsk_read - sbrc temp,WRITE_FUNC - rjmp dsk_write - sbrc temp,HOME_FUNC - rjmp dsk_home - sbrc temp,BOOT_FUNC - rjmp dsk_boot - - printstring "DISK I/O: Invalid Function code: " - rcall printhex - rjmp haltinv - -dsk_boot: - sts ndisks,_0 ;no active partitions -dsk_cboot: - 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 - ret - - -dsk_read: - - sbi flags,readop ;read operation - ;RAM disk? - lds temp2,seekdsk -#if RAMDISKCNT - cpi temp2,RAMDISKNR - brlt PC+2 - rjmp rdskDoIt -#endif - 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_write: - ;write the selected CP/M sector - - cbi flags,readop ;not a read operation - - ;RAM disk? - lds temp2,seekdsk -#if RAMDISKCNT - cpi temp2,RAMDISKNR - brlt PC+2 - rjmp rdskDoIt -#endif - andi temp,WRTMSK - sts wrtype,temp ;save write type - - 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 -; -dsk_chkuna: - ;check for write to unallocated sector - 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 - -; 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 - -; tracks are the same - 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 - -; 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 -; -dsk_noovf: - 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 - -;***************************************************** -;* Common code for READ and WRITE follows * -;***************************************************** - -dsk_rwoper: - ;enter here to perform the read/write -.if DISK_DEBUG - printstring ", flags: " - in temp,flags - rcall printhex -.endif - 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 - - ;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 - ;yl:xh:xl = host block to seek -; active host sector? - 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 - -; host buffer active, same as seek buffer? - 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 - breq dsk_match -; -dsk_nomatch: - ;proper disk, but not correct sector - sbis flags,hostwrt ;host written? - rjmp dsk_filhst - push xl - push xh - push yl - rcall dsk_writehost ;clear host buff - 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 - - sbic flags,rsflag ;need to read? - rcall dsk_readhost ;yes, if 1 - 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 -.if DISK_DEBUG > 2 - push r0 - push r1 - printstring "; host buf adr: " - pop temp2 - pop temp - rcall printhexw -.endif - - lds xl,dmaadr - lds xh,dmaadr+1 - ldi temp3,128 ;length of move - sbic flags,readop ;which way? - rjmp dsk_rmove ;skip if read - -; mark write operation - sbi flags,hostwrt ;hostwrt = 1 -dsk_wmove: - mem_read - st z+,temp - adiw xl,1 - dec temp3 - brne dsk_wmove - rjmp dsk_rwmfin - -dsk_rmove: - ld temp,z+ - mem_write - adiw xl,1 - 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? - breq dsk_wdir - ret ;no further processing -dsk_wdir: -; clear host buffer for directory write - lds temp,erflag - tst temp ;errors? - breq dsk_wdir1 - ret ;skip if so -dsk_wdir1: - rcall dsk_writehost ;clear host buff - cbi flags,hostwrt ;buffer written - ret -;***************************************************** - -; hostdsk = host disk #, (partition #) -; hostlba = host block #, relative to partition start -; Read/Write "hostsize" bytes to/from hostbuf -dsk_hostparam: - ldiw z,hostparttbl - lds temp,hostdsk -.if HOSTRW_DEBUG - push temp - subi temp,-('A') - rcall uartputc - printstring ": " - pop temp -.endif - - lsl temp - lsl temp - lsl temp - add zl,temp - adc zh,_0 - - lds temp,hostlba - lds temp2,hostlba+1 - lds temp3,hostlba+2 - -.if HOSTRW_DEBUG - printstring "lba: " - clr temp4 - rcall print_ultoa -.endif - ldd xl,z+4 - ldd xh,z+5 - ldd yl,z+6 - - cp temp,xl - cpc temp2,xh - cpc temp3,yl - brcs dsk_hp1 - -.if HOSTRW_DEBUG - printstring ", max: " - push temp4 - push temp3 - push temp2 - push temp - movw temp,x - mov temp3,yl - clr temp4 - rcall print_ultoa - pop temp - pop temp2 - pop temp3 - pop temp4 - printstring " " -.endif - - clr temp - ret - -dsk_hp1: - ldd xl,z+0 - ldd xh,z+1 - ldd yl,z+2 - ldd yh,z+3 - - add xl,temp - adc xh,temp2 - adc yl,temp3 - adc yh,_0 -.if HOSTRW_DEBUG - printstring ", abs:" - push temp4 - push temp3 - push temp2 - push temp - movw temp,x - movw temp3,y - rcall print_ultoa - pop temp - pop temp2 - pop temp3 - pop temp4 - printstring " " -.endif - ori temp,255 -dsk_hpex: - ret - -;***************************************************** -;* WRITEhost performs the physical write to * -;* the host disk, READhost reads the physical * -;* disk. * -;***************************************************** - -dsk_writehost: -.if HOSTRW_DEBUG - printnewline - printstring "host write " -.endif - rcall dsk_hostparam - breq dsk_rdwr_err - - rcall mmcWriteSect - tst temp - breq dsk_rdwr_ok - - rcall dsk_partinit - cbr temp,0x80 - breq dsk_rdwr_err - - rcall dsk_hostparam - breq dsk_rdwr_err - rcall mmcWriteSect - tst temp - brne dsk_rdwr_err - rjmp dsk_rdwr_ok - - -dsk_readhost: -.if HOSTRW_DEBUG - printnewline - printstring "host read " -.endif - rcall dsk_hostparam - breq dsk_rdwr_err - - rcall mmcReadSect - tst temp - breq dsk_rdwr_ok - - rcall dsk_partinit - cbr temp,0x80 - breq dsk_rdwr_err - - rcall dsk_hostparam - breq dsk_rdwr_err - rcall mmcReadSect - tst temp - brne dsk_rdwr_err - -dsk_rdwr_ok: - sts erflag,_0 - ret - -dsk_rdwr_err: - sts erflag,_255 - ret - -;*************************************************************************** - -#if RAMDISKCNT - -; ----------------- RAM disk ----------------- - - .dseg -rdskbuf: - .byte 128 - - .cseg -;---------------------------------------------- - -rdsk_adr: - ldi xl,0 - lds xh,seeksec - lds temp2,seektrk - - lsr xh - ror xl ;Col 0..7 - - mov temp,temp2 - andi temp,0x0f - swap temp - or xh,temp ;Row 0..7 - - ldiw z,rdskbuf - ldi temp3,128 - DRAM_SETADDR xh, ~0,(1< 1 - mov temp,xh - rcall printhex - printstring " " - mov temp,xl - rcall printhex - printstring " " -.endif - ret - -;---------------------------------------------- - -rdskDoIt: - sts erflag,_0 - sbis flags,readop - rjmp rdsk_wr - -.if DISK_DEBUG > 1 - printnewline - printstring "rd-adr: " -.endif - rcall rdsk_adr -rdsk_rdl: - DRAM_SETADDR xl, ~(1< 1 - printnewline - printstring "wr-adr: " -.endif - lds xl,dmaadr - lds xh,dmaadr+1 - ldiw z,rdskbuf - ldi temp3,128 -rdsk_wrldl: - mem_read - st z+,temp - adiw x,1 - dec temp3 - brne rdsk_wrldl - - ldi temp2,RAM_DQ_MASK | (1<. +; +; $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 + + .equ READ_FUNC = 7 + .equ WRITE_FUNC = 6 + .equ BOOT_FUNC = 5 + .equ HOME_FUNC = 4 + +;----------------------------------------------- Start of Data Segment + + .dseg + + +; ---------------------------------------------- Start of Code Segment + .cseg + +uartstat: + clr temp + lds temp2,rxcount + cpse temp2,_0 + sbr temp,0x01 + lds temp2,txcount + cpi temp2,TXBUFSIZE + breq uartst_1 + sbr temp,0x02 +uartst_1: + ret + +uartout: + lds temp2,txcount + cpi temp2,TXBUFSIZE + breq uartout_1 + rjmp uartputc +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 + printstring "Debug: " + 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 + + + + +;--------------------------------------------------------------------- -- 2.39.2