]> cloudbase.mooo.com Git - avrcpm.git/commitdiff
* Initial changes for FAT16 support.
authorFrank Zoll <fzoll@web.de>
Thu, 30 Sep 2010 23:45:42 +0000 (23:45 +0000)
committerFrank Zoll <fzoll@web.de>
Thu, 30 Sep 2010 23:45:42 +0000 (23:45 +0000)
* 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@106 57430480-672e-4586-8877-bcf8adbbf3b7

avrcpm/avr/avrcpm.asm
avrcpm/avr/config.inc
avrcpm/avr/dsk_fat16.asm [new file with mode: 0644]
avrcpm/avr/dsk_fsys.asm [new file with mode: 0644]
avrcpm/avr/dsk_mgr.asm [new file with mode: 0644]
avrcpm/avr/dsk_ram.asm [new file with mode: 0644]
avrcpm/avr/init.asm
avrcpm/avr/macros.inc
avrcpm/avr/mmc.asm
avrcpm/avr/remainders.asm
avrcpm/avr/virt_ports.asm [new file with mode: 0644]

index 10da30261d034eadf7b77d4895cebfa8ec45b89e..4e666c99d76a70e6d892ff4daae843824817aa4a 100644 (file)
        .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"
index e14ef4386af59da2cf2af92e9f554c8c67f89693..d65608780ad73048fed39de1bbc6692bb966bd09 100644 (file)
@@ -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/avrcpm/avr/dsk_fat16.asm b/avrcpm/avr/dsk_fat16.asm
new file mode 100644 (file)
index 0000000..0cc32af
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+;
+;    $Id$
+;\r
+\r
+; ===========================================================================\r
+; Prelimitary !\r
+; °°°°°°°°°°°°°\r
+; Size of a Sector is fixed to 512 Bytes by Base - MMC Driver implementation\r
+; The Functions below therefore assume a fixed Size of 512 Bytes per Sector.\r
+; ===========================================================================\r
+\r
+#ifndef FAT16_SUPPORT\r
+       #define FAT16_SUPPORT 1\r
+       #define FAT16_DEBUG   2\r
+#endif\r
+\r
+#if FAT16_SUPPORT\r
+\r
+\r
+;-------------------------------- Defines for FAT16 Structures
+#define PARTID_FAT16 0x0E\r
+\r
+;#define FAT16_BSO_SECSIZE     0x0b            ; BootSectorOffset to Sectorsize Word\r
+#define FAT16_BSO_CLUSTSZ   0x0d        ; BootSectorOffset to Clustersize Byte\r
+#define FAT16_BSO_RESSECT   0x0e               ; BootSectorOffset to Number of Reserved Sectors\r
+#define FAT16_BSO_VOLPTR    0x1c        ; BootSectorOffset to First VolumeSector\r
+#define FAT16_BSO_SECPERFAT 0x16        ; BootSectorOffset to Number of Sectors per Fat\r
+#define FAT16_BSO_NUMFATCP  0x10               ; BootSectorOffset to Ammount of FAT Copys\r
+#define FAT16_BSO_NUMDIRENT 0x11               ; BootSectorOffset to Max. Root Dir. Entrys\r
+\r
+;-------------------------------- Start of Data Segment
+
+       .dseg\r
+\r
+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\r
+fat_clustersize: .byte   1   ; sectors per cluster\r
+fat_ressectors:  .byte   2   ; number of reserved sectors\r
+fat_secperfat:   .byte   2   ; number of sectors per fat\r
+fat_numfatcp:    .byte   1   ; Number of FAT Copies\r
+fat_numdirentrys:.byte   2   ; Max. ammount of Directory Entrys within Rootdirektory\r
+fat_ptr2fat:     .byte   4   ; pointer to the first fat sector\r
+fat_ptr2dir:     .byte   4   ; pointer to the first root directory sector\r
+fat_ptr2dat:     .byte   4   ; pointer to the first data sector\r
+\r
+; ------------------------------- Start of Code Segment
+       .cseg\r
+\r
+; ====================================================================\r
+; Function: Does a Disk read/write operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+fat_init_partitiontable:\r
+\r
+       sts fat_partfound,_0\r
+\r
+       ldiw    y,fat_parttbl\r
+       st      y+,_0\r
+       st      y+,_0\r
+       st      y+,_0\r
+       st      y+,_0\r
+       st      y+,_0\r
+       st      y+,_0\r
+       st      y+,_0\r
+       st      y+,_0\r
+       ret\r
+\r
+; ====================================================================\r
+; Function: Add's a FAT16 Partition for later Scanning
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : \r
+; Variables  : \r
+; --------------------------------------------------------------------\r
+; Description:\r
+; This funktion sets the internal Variables to set Start and Size\r
+; of a given FAT16 Paritition. This Information will be used for a\r
+; later scanning of the Partition. See Function "fat_scan_partition"\r
+; for more information. \r
+; ====================================================================\r
+fat_add_partition:\r
+       \r
+.if FAT16_DEBUG > 0
+       printstring "fat16 part found",0\r
+       printnewline\r
+.endif\r
+\r
+\r
+;   save variables on stack\r
+       push    yl\r
+       push    yh\r
+\r
+; set fat16 partition found flag\r
+       ldi     yl,1\r
+       sts     fat_partfound,yl\r
+\r
+;   save data from first fat16 partition\r
+       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\r
+\r
+\r
+;   reload variables from stack\r
+       pop             yh\r
+       pop     yl\r
+
+       ret
+\r
+; --------------------------------------------------------------------------- \r
+; Read and Scann a FAT16 Partition for Imagedatefiles 
+; --------------------------------------------------------------------------- \r
+; This Routine reads the Bootblock and scanns it for a Diskimage\r
+; Input Registers  : none\r
+; Output Registers : none\r
+; Changes Variables: none\r
+; --------------------------------------------------------------------------- \r
+\r
+\r
+fat_scan_partition:\r
+\r
+.if FAT16_DEBUG > 0
+       printstring "fat16 scanning",0\r
+       printnewline\r
+.endif\r
+\r
+; Check if a FAT16 Partition was realy found\r
+       lds             yl,fat_partfound\r
+       cpi     yl,1    \r
+       brne    fat_scan_error \r
+\r
+\r
+.if FAT16_DEBUG > 0
+       printstring "free entrys in ptable ?",0\r
+       printnewline\r
+.endif\r
+\r
+; Check for free Entrys in Partition table\r
+       lds             yl,ndisks\r
+       cpi             yl,MAXDISKS\r
+       breq    fat_scan_error\r
+\r
+.if FAT16_DEBUG > 0
+       printstring "read fat bootblock.",0\r
+       printnewline\r
+.endif\r
+\r
+; Scan partition start\r
+       ldiw    z,fat_parttbl   
+       ldd             xl,z+0          
+       ldd             xh,z+1
+       ldd             yl,z+2
+       ldd             yh,z+3\r
+\r
+; Load first sector from Partition
+       rcall   mmcReadSect
+       tst         temp
+       breq    fat_bootblock_check\r
+\r
+; Read error: Block not found\r
+fat_scan_error:\r
+       clr temp\r
+       ret\r
+\r
+fat_bootblock_check:\r
+\r
+.if FAT16_DEBUG > 0
+       printstring "fat16 bootblock check",0\r
+       printnewline\r
+.endif\r
+\r
+; -> Size of Sectors fixed at 512 Bytes\r
+;   Get ammount of Bytes per Sector\r
+;      ldiw    z,hostbuf+FAT16_BSO_SECSIZE\r
+;      ldiw    y,fat_sectorsize\r
+;      ld          temp,z\r
+;      st      y+, temp\r
+;      ldd         temp2,z+1\r
+;      st      y , temp2\r
+;\r
+;.if FAT16_DEBUG > 0\r
+;      printstring "Bytes per Sector ",0\r
+;      rcall printhexw\r
+;      printnewline\r
+;.endif\r
+\r
+;   Anzahl der Sectoren pro Cluster lesen\r
+       ldiw    z,hostbuf+FAT16_BSO_CLUSTSZ\r
+       ld              temp,z\r
+       sts     fat_clustersize,temp\r
+\r
+.if FAT16_DEBUG > 0\r
+       printstring "Sectors per Cluster ",0\r
+       rcall printhex\r
+       printnewline\r
+.endif\r
+\r
+;   Anzahl der reservierten Sectoren\r
+       ldiw    z,hostbuf+FAT16_BSO_RESSECT\r
+       ld              temp,z+\r
+       sts     fat_ressectors,temp                     ; low byte\r
+       ld              temp2,z\r
+       sts             fat_ressectors+1,temp2          ; high byte\r
+\r
+.if FAT16_DEBUG > 0\r
+       printstring "Reserved Sectors__: ",0\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+;   Anzahl der Sectoren pro FAT\r
+       ldiw    z,hostbuf+FAT16_BSO_SECPERFAT\r
+       ld              temp,z+\r
+       sts     fat_secperfat,temp                      ; low byte\r
+       ld              temp2,z\r
+       sts             fat_secperfat+1,temp2           ; high byte\r
+\r
+.if FAT16_DEBUG > 0\r
+       printstring "Sectors per FAT__: ",0\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+;   Anzahl der FAT kopien\r
+       ldiw    z,hostbuf+FAT16_BSO_NUMFATCP\r
+       ld              temp,z\r
+       sts     fat_numfatcp,temp                       ; low byte\r
+\r
+.if FAT16_DEBUG > 0\r
+       printstring "Ammount of FAT copies: ",0\r
+       rcall printhex\r
+       printnewline\r
+.endif\r
+\r
+;   Max. Anzahl der Dir. Enträge im Root Verz.\r
+       ldiw    z,hostbuf+FAT16_BSO_NUMDIRENT\r
+       ld              temp,z+\r
+       sts     fat_numdirentrys,temp                   ; low byte\r
+       ld              temp2,z\r
+       sts             fat_numdirentrys+1,temp2                ; high byte\r
+\r
+.if FAT16_DEBUG > 0\r
+       printstring "Max. entrys in Rootdir.: ",0\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+; Print begin of Volume\r
+.if FAT16_DEBUG > 1\r
+\r
+       ldiw    z,fat_parttbl   
+       ldd             xl,z+0          
+       ldd             xh,z+1
+       ldd             yl,z+2
+       ldd             yh,z+3\r
+\r
+       printstring "Begin of Volume at: ",0\r
+       mov             temp ,yl\r
+       mov             temp2,yh\r
+       rcall printhexw\r
+       mov             temp ,xl\r
+       mov             temp2,xh\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+; Calculate begin of FAT within the Volume\r
+       lds             temp ,fat_ressectors\r
+       lds             temp2,fat_ressectors+1\r
+\r
+       ldiw    z,fat_parttbl   
+       ldd             xl,z+0          
+       ldd             xh,z+1
+       ldd             yl,z+2
+       ldd             yh,z+3\r
+\r
+       add             xl,temp\r
+       adc     xh,temp2\r
+       adc             yl,_0\r
+       adc             yh,_0\r
+\r
+       sts             fat_ptr2fat  ,xl\r
+       sts             fat_ptr2fat+1,xh\r
+       sts             fat_ptr2fat+2,yl\r
+       sts             fat_ptr2fat+3,yh\r
+\r
+.if FAT16_DEBUG > 1\r
+       printstring "Begin of FAT at___: ",0\r
+       mov             temp ,yl\r
+       mov             temp2,yh\r
+       rcall printhexw\r
+       mov             temp ,xl\r
+       mov             temp2,xh\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+; Calculate begin of Root- Directory within the Volume\r
+       ldiw    z,fat_ptr2fat\r
+       ldd             xl,z+0\r
+       ldd             xh,z+1\r
+       ldd             yl,z+2\r
+       ldd             yh,z+3\r
+\r
+       lds             temp ,fat_secperfat\r
+       lds             temp2,fat_secperfat+1\r
+       lds             temp3,fat_numfatcp\r
+\r
+fat_calc_dp_loop:\r
+       cp              temp3,_0\r
+       breq    fat_calc_dp_lend\r
+\r
+       add             xl,temp\r
+       adc             xh,temp2\r
+       adc             yl,_0\r
+       adc             yh,_0\r
+\r
+       dec             temp3\r
+\r
+       jmp             fat_calc_dp_loop\r
+fat_calc_dp_lend:\r
+\r
+       sts             fat_ptr2dir  ,xl\r
+       sts             fat_ptr2dir+1,xh\r
+       sts             fat_ptr2dir+2,yl\r
+       sts             fat_ptr2dir+3,yh\r
+\r
+\r
+.if FAT16_DEBUG > 1\r
+       printstring "Begin of DIR at___: ",0\r
+       mov             temp ,yl\r
+       mov             temp2,yh\r
+       rcall printhexw\r
+       mov             temp ,xl\r
+       mov             temp2,xh\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+; Calculate begin of DATA Clusters within the Volume\r
+; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor\r
+\r
+; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor\r
+\r
+       lds     zl,fat_numdirentrys                     ; low byte\r
+       lds             zh,fat_numdirentrys+1           ; high byte\r
+\r
+;   Num. Direntrys / 16\r
+       lsr             zh\r
+       ror             zl\r
+       lsr             zh\r
+       ror             zl\r
+       lsr             zh\r
+       ror             zl\r
+       lsr             zh\r
+       ror             zl\r
+\r
+       lds             xl,fat_ptr2dir\r
+       lds             xh,fat_ptr2dir+1\r
+       lds             yl,fat_ptr2dir+2\r
+       lds             yh,fat_ptr2dir+3\r
+\r
+       add             xl,zl\r
+       adc             xh,zh\r
+       adc             yl,_0\r
+       adc             yh,_0\r
+\r
+       sts             fat_ptr2dat  ,xl\r
+       sts             fat_ptr2dat+1,xh\r
+       sts             fat_ptr2dat+2,yl\r
+       sts             fat_ptr2dat+3,yh\r
+\r
+.if FAT16_DEBUG > 1\r
+       printstring "Begin of Data at__: ",0\r
+       mov             temp ,yl\r
+       mov             temp2,yh\r
+       rcall printhexw\r
+       mov             temp ,xl\r
+       mov             temp2,xh\r
+       rcall printhexw\r
+       printnewline\r
+.endif\r
+\r
+; Here Starts the Scann of the Directory for valid image Files.\r
+\r
+       lds             xl,fat_ptr2dir\r
+       lds             xh,fat_ptr2dir+1\r
+       lds             yl,fat_ptr2dir+2\r
+       lds             yh,fat_ptr2dir+3\r
+\r
+;  Load first sector from Directory
+       call    mmcReadSect
+       tst         temp
+       breq    fat_look_for_images\r
+\r
+; Read error: Block not found\r
+       clr temp\r
+       ret\r
+\r
+; Looks at a read directory block for image entrys\r
+fat_look_for_images:\r
+       \r
+       ldiw    z,hostbuf\r
+       ldi             temp2,0\r
+\r
+fat_look_for_loop:     \r
+       ldd     temp,z+0\r
+       cpi             temp,'C'\r
+       brne    fat_look_not_ok\r
+       \r
+       ldd             temp,z+1\r
+       cpi             temp,'P'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+2\r
+       cpi             temp,'M'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+3\r
+       cpi             temp,'D'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+4\r
+       cpi             temp,'S'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+5\r
+       cpi             temp,'K'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+6\r
+       cpi             temp,'_'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+8\r
+       cpi             temp,'I'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+9\r
+       cpi             temp,'M'\r
+       brne    fat_look_not_ok\r
+\r
+       ldd             temp,z+10\r
+       cpi             temp,'G'\r
+       brne    fat_look_not_ok\r
+\r
+       jmp             fat_store_new_entry\r
+\r
+fat_look_not_ok:\r
+       \r
+       //ldi           temp,32\r
+       addiw   z,32                    \r
+\r
+       inc             temp2\r
+       cpi             temp2,16                                ; max entrys/sector\r
+       breq    fat_scan_next_sector\r
+       jmp     fat_look_for_loop\r
+\r
+fat_scan_next_sector:\r
+\r
+       ret\r
+\r
+\r
+;      Create new Partition Entry\r
+fat_store_new_entry:\r
+\r
+;   Found a valid image\r
+.if FAT16_DEBUG > 1\r
+       printstring "Found a valid Image ! ",0\r
+       printnewline\r
+.endif\r
+\r
+       ldiw    y,hostparttbl\r
+       lds             temp,ndisks\r
+\r
+fat_look_store_loop:\r
+       cp              temp,_0\r
+       breq    fat_look_store\r
+\r
+       adiw    y,PARTENTRY_SIZE\r
+       dec             temp\r
+       jmp             fat_look_store_loop\r
+\r
+fat_look_store:\r
+;   Set Type of Partition to FAT16- Fileimage\r
+       ldi temp,dskType_FAT\r
+       st      y+,temp\r
+\r
+;   Offset to Startcluster + 2
+       ldd     temp,z+0x1A
+       st      y+,temp
+       ldd     temp,z+0x1B
+       st      y+,temp \r
+       ldi     temp,0\r
+       st      y+,temp
+       st      y+,temp\r
+\r
+;   Filesize in Bytes - 2,4,8,16,32,64,128,256,512 \r
+;      ldd     temp,z+0x1C\r
+;      st      y+,temp
+;      ldd     temp,z+0x1D\r
+;      st      y+,temp
+;      ldd     temp,z+0x1E\r
+;      st      y+,temp
+;      ldd     temp,z+0x1F\r
+;      st      y+,temp\r
+\r
+;   Convert Filesize to ammount of sectors\r
+       ldd     xl,z+0x1D\r
+       ldd     xh,z+0x1E\r
+       ldd     zl,z+0x1F\r
+       mov     zh,_0\r
+\r
+       lsr     zh\r
+       ror zl\r
+       ror xh\r
+       ror xl\r
+\r
+;   store ammount of sectors in partitiontable \r
+       st  y+,xl
+       st  y+,xh
+       st  y+,zl
+       st  y+,zh
+\r
+; Check for another free entry in partition table\r
+       lds     temp,ndisks\r
+       inc     temp\r
+       sts     ndisks,temp\r
+       \r
+\r
+.if FAT16_DEBUG > 1\r
+; Test finding of the first sector\r
+       ldd     xl,z+0x1A\r
+       ldd     xh,z+0x1B\r
+       ldi     zl,0\r
+\r
+       rcall   fat_gethostsec\r
+\r
+       printstring "Begin of Image at: ",0\r
+       mov             temp ,yl\r
+       mov             temp2,yh\r
+       rcall printhexw\r
+       mov             temp ,xl\r
+       mov             temp2,xh\r
+       rcall printhexw\r
+       printnewline\r
+\r
+.endif\r
+       \r
+;      cp              temp,MAXDISKS\r
+;      brne    fat_scan_for_more       \r
+               \r
+       ret\r
+\r
+\r
+; ====================================================================\r
+; Function: Cluster+Offset to HostSector 
+; ====================================================================\r
+; Parameters: [in]     xh,xl                   Cluster Number\r
+;                        [in]  zl                              Offset\r
+;                        [out] yh,yl,xh,xl             Sector Number on Disk\r
+; --------------------------------------------------------------------\r
+; Registers  :         \r
+; Variables  :         [used]  fat_clustersize Ammount of Sectors per Cluster\r
+;                              [changes] temp\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ! Only works with Clustersizes 1,2,4,8,16,32,64,128 !\r
+; ====================================================================\r
+fat_gethostsec:\r
+\r
+;      Get Offset into Data area of Disk\r
+       rcall   fat_clusttosec\r
+\r
+;      add given offset\r
+       add             xl,zl\r
+       adc             xh,_0\r
+       adc             yl,_0\r
+       adc             yh,_0\r
+\r
+;      add begin of data area to offset\r
+       lds             temp,fat_ptr2dat+0\r
+       add             xl,temp\r
+       lds             temp,fat_ptr2dat+1\r
+       adc             xh,temp\r
+       lds             temp,fat_ptr2dat+2\r
+       adc             yl,temp\r
+       lds             temp,fat_ptr2dat+3\r
+       adc             yh,temp\r
+       ret\r
+\r
+; ====================================================================\r
+; Function: Cluster to Sector 
+; ====================================================================\r
+; Parameters: [in]     xl,xh                   Cluster Number\r
+;                        [out] xl,xh,yl,yh             Sector Number\r
+; --------------------------------------------------------------------\r
+; Registers  :         \r
+; Variables  :         [used]  fat_clustersize Ammount of Sectors per Cluster\r
+;                              [changes] temp\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ! Only works with Clustersizes 1,2,4,8,16,32,64,128 !\r
+; ====================================================================\r
+fat_clusttosec:\r
+       clr     yl\r
+       clr             yh\r
+\r
+       ldi             temp,2\r
+       sub             xl,temp         ; Substract the 2 reserved clusters\r
+       sbc             xh,_0\r
+\r
+       lds             temp,fat_clustersize\r
+\r
+fat_c2s_loop:\r
+       lsr             temp\r
+       tst             temp\r
+       breq    fat_c2s_end\r
+\r
+       lsl             xl\r
+       rol             xh\r
+       rol             yl\r
+       rol             yh\r
+       rjmp    fat_c2s_loop\r
+\r
+fat_c2s_end:\r
+       ret\r
+\r
+; ====================================================================\r
+; Function: CP/M Sector to Cluster & Offset 
+; ====================================================================\r
+; Parameters: [in]     xl,xh                   Cluster Number\r
+;                        [out] xl,xh,yl,yh             Sector Number\r
+; --------------------------------------------------------------------\r
+; Registers  :         \r
+; Variables  :         [used]  fat_clustersize Ammount of Sectors per Cluster\r
+;                              [changes] temp\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ! Only works with Clustersizes 1,2,4,8,16,32,64,128 !\r
+; ====================================================================\r
+fat_cpmtoclust:\r
+\r
+       ret\r
+\r
+; ====================================================================\r
+; Function: Does a Disk write operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; hostdsk = host disk #,  (partition #)
+; hostlba = host block #, relative to partition start 
+; Read/Write "hostsize" bytes to/from hostbuf\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================
+
+fat_hostparam:
+       lds             xl,hostdsk
+\r
+.if HOSTRW_DEBUG
+       mov     temp,xl
+       subi    temp,-('A')
+       rcall   uartputc
+       printstring ": "
+.endif
+\r
+       rcall dsk_getpartentry  ; get partition entry
+\r
+fat_hostlend:\r
+       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\r
+
+.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\r
+
+       ori             temp,255
+fat_hpex:
+       ret
+
+; ====================================================================\r
+; Function: Does a Disk write operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================
+
+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
+
+; ====================================================================\r
+; Function: Does a Disk read operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+
+fat_readhost:
+.if HOSTRW_DEBUG
+       printnewline
+       printstring "host read  "
+.endif\r
+
+       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\r
+#endif\r
diff --git a/avrcpm/avr/dsk_fsys.asm b/avrcpm/avr/dsk_fsys.asm
new file mode 100644 (file)
index 0000000..ccf1ae2
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+;
+;    $Id$
+;\r
+\r
+\r
+; ---------------- Defines for the Filesystem Interface -------
+
+\r
+;*****************************************************
+;*        Disk-Manager constants                     *
+;*****************************************************
+       .equ    dskType_None    = 0\r
+       .equ    dskType_CPM             = 1\r
+       .equ    dskType_FAT             = 2\r
+       .equ    dskType_RAM             = 3\r
+
+;*****************************************************
+;*         CP/M to host disk constants               *
+;*****************************************************
+       .equ    MAXDISKS  = 4                   ;Max number of Disks (partitions)\r
+       .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\r
+;----------------------------------------------- Start of Data Segment
+
+       .dseg\r
+\r
+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\r
+
+hostbuf:               .byte   hostsize ;host buffer (from/to SD-card)\r
+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)\r
+hostlba:               .byte   3               ;host sector number (relative to partition start)\r
+\r
+\r
+; ------------------------------- Start of Code Segment
+       .cseg\r
+\r
+; ====================================================================\r
+; Function: Get a Pointer to a Partitiontable entry
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : [w] z                   Pointer to the Partitionentry\r
+;              [r] xl                  Number of Diskentry to Read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+dsk_getpartentry:\r
+       \r
+       ldiw    z,hostparttbl\r
+       mov             temp,xl\r
+\r
+dsk_getpartentryloop:\r
+       cp              temp,_0\r
+       breq    dsk_getpartentryloopend\r
+       adiw    z,PARTENTRY_SIZE\r
+       dec             temp\r
+       jmp             dsk_getpartentryloop\r
+dsk_getpartentryloopend:\r
+       ret
+\r
+; ====================================================================\r
+; Function: 
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seeksec             Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+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\r
+
+; ====================================================================\r
+; Function: Does a Disk interaction
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seeksec             Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================
+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
+\r
+\r
+
+; ====================================================================\r
+; Function: Does a Disk read operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================
+dsk_read:
+       sts             erflag,_0
+       sbi             flags,readop            ; Set read operation flag\r
+       lds     xl,seekdsk
+       rcall   dsk_getpartentry        ; Get Paritiontableentry\r
+       ld      temp,z                          ; Get Partitiontype\r
+\r
+; Isn't it a Disk ?\r
+       cpi             temp,dskType_None\r
+       brne    PC+2\r
+       rjmp    dsk_read_err\r
+; Is it a RamDisk ?
+       cpi             temp,dskType_RAM\r
+       brne    PC+2\r
+       rjmp    rdsk_read\r
+; It must be a FAT16-Imagefile or CP/M Partition.\r
+       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\r
+
+dsk_read_err:\r
+       ret\r
+
+; ====================================================================\r
+; Function: Does a Disk write operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================
+dsk_write:
+       ;write the selected sector
+       sts             erflag,_0
+       cbi             flags,readop            ; not a read operation\r
+       lds     xl,seekdsk
+       rcall   dsk_getpartentry        ; Get Paritiontableentry\r
+       ld      temp,z                          ; Get Partitiontype\r
+\r
+; Isn't it a Disk ?\r
+       cpi             temp,dskType_None\r
+       brne    PC+2\r
+       rjmp    dsk_write_err\r
+\r
+; Is it a RamDisk ?
+       cpi             temp,dskType_RAM\r
+       brne    PC+2\r
+       rjmp    rdsk_write\r
+\r
+; It must be a FAT16-Imagefile or CP/M Partition.\r
+
+       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\r
+\r
+dsk_write_err:\r
+       ret\r
+\r
+; ====================================================================\r
+; Function: Does a Disk read/write operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+dsk_rwoper:\r
+       ;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\r
+
+.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\r
+\r
+; ====================================================================\r
+; Function: Does a Disk write operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+dsk_writehost:\r
+       lds    xl,hostdsk\r
+       rcall  dsk_getpartentry\r
+       ld     temp,z\r
+\r
+; Is it a FAT16 Diskimage ?
+       cpi             temp,dskType_FAT\r
+       brne    PC+2\r
+       rjmp    fat_writehost\r
+\r
+; Is it a CP/M Partition ?
+       cpi             temp,dskType_CPM\r
+       brne    PC+2\r
+       rjmp    cpm_writehost\r
+; Disktype not supported -> Return \r
+       ret\r
+\r
+; ====================================================================\r
+; Function: Does a Disk read operation
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [r] seekdsk             Number of Disk to Read\r
+;                         [r] seeksec          Sector to read\r
+;              [r] seektrk             Track  to read\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+dsk_readhost:\r
+       lds    xl,hostdsk\r
+       rcall  dsk_getpartentry\r
+       ld     temp,z\r
+\r
+; Is it a FAT16 Diskimage ?
+       cpi             temp,dskType_FAT\r
+       brne    PC+2\r
+       rjmp    fat_readhost\r
+\r
+; Is it a CP/M Partition ?
+       cpi             temp,dskType_CPM\r
+       brne    PC+2\r
+       rjmp    cpm_readhost\r
+; Disktype not supported -> Return \r
+       ret\r
+\r
diff --git a/avrcpm/avr/dsk_mgr.asm b/avrcpm/avr/dsk_mgr.asm
new file mode 100644 (file)
index 0000000..ac9b0d4
--- /dev/null
@@ -0,0 +1,317 @@
+;    Various Management functions for the Interaction with the File-\r
+;    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 <http://www.gnu.org/licenses/>.
+;
+;    $Id$
+;\r
+\r
+\r
+; ------------------------- Defines for the disk management Structures
+\r
+;----------------------------------------------- Start of Data Segment
+
+       .dseg\r
+\r
+\r
+\r
+; ------------------------------- Start of Code Segment
+       .cseg\r
+\r
+; ====================================================================\r
+; Function: Scans a Disk for CP/M Partions
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  : none\r
+; Variables  : [w] temp                Status of Operation\r
+;                                                      (0x80 - Operation Failure )\r
+;                                                      (others - Operation Suceded)\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; This Function scans an SD-Cards Boot-Sector for valid Partitions.\r
+; First all original CP/M Partitions will be usesed as Drives for\r
+; the CPM-System. Wenn all CP/M Partitions are found, a second\r
+; scann will be made. In the second Scan, the first FAT16 Partition\r
+; on the Disk will be used for a detailed analyses. If there\r
+; are any Files like "cpm_x.img" are found, these Files will be\r
+; used as Disks by the CP/M- System. ( x must be in the Range A to D )\r
+; ==================================================================== 
+mgr_init_partitions:\r
+\r
+       sts             ndisks,_0               ; Set Number of Disks to 0\r
+\r
+; Initialize temp partition table\r
+       ldiw    y,tmp_tbl
+       ldi             temp2,PARTENTRY_SIZE*MAXDISKS
+mgr_picl:
+       st              y+,_0
+       dec             temp2
+       brne    mgr_picl\r
+\r
+; 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\r
+\r
+mgr_check_bootsektor:\r
+;Pointer to first temp table entry\r
+       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)\r
+       ldi     temp2,dskType_CPM\r
+       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\r
+\r
+; Search for valid Partitions and ImageFiles \r
+mgr_search:\r
+       sbiw    z,63                    ;Now at first byte of partition table
+       ldi             temp4,high(hostbuf+510)
+\r
+mgr_ploop:
+\r
+;      Get Partitiontype\r
+       ldd             temp,z+PART_TYPE
+\r
+;   Test for CP/M Partition\r
+       cpi             temp,PARTID_CPM
+       brne    mgr_nextp
+       
+       rcall    cpm_add_partition
+\r
+       inc             temp3
+       cpi             temp3,MAXDISKS
+       breq    mgr_pend\r
+       rjmp    mgr_nextp\r
+       
+mgr_nextp:
+       adiw    zl,16
+       cpi             zl,low(hostbuf+510)
+       cpc             zh,temp4
+       brlo    mgr_ploop\r
+\r
+; Test for FAT16 Partition\r
+       ldiw    z,hostbuf+510-1-63      ;Point to  first byte of partition table
+       ldi             temp4,high(hostbuf+510)
+\r
+mgr_ploop2:
+\r
+;      Get Partitiontype\r
+       ldd             temp,z+PART_TYPE
+\r
+;   Test for FAT Partition\r
+       cpi             temp,PARTID_FAT16
+       brne    mgr_nextp2
+       
+       rcall    fat_add_partition
+
+       rjmp    mgr_pend\r
+               
+mgr_nextp2:
+       adiw    zl,16
+       cpi             zl,low(hostbuf+510)
+       cpc             zh,temp4
+       brlo    mgr_ploop2\r
+\r
+mgr_pend:\r
+\r
+; Initialize RAM-Disks\r
+       rcall   rdsk_add_partition\r
+\r
+;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\r
+
+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\r
+\r
+       lds             temp,ndisks\r
+       sbr             temp,0x80
+
+mgr_pcpe:\r
+
+       ret\r
+\r
+\r
+; ====================================================================\r
+; Function: Print partition table info
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  :  none\r
+; Variables  :  [r] hostparttbl                Table with Partitioninformations\r
+;               [r] hostparttbltop     Pointer to the Top of the Table\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+
+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
+\r
+; Partitiontype examining\r
+       ldd     xl,z+0\r
+; CP/M ?\r
+       cpi             xl,dskType_CPM\r
+       brne    mgr_prtb_nocpm\r
+       rcall   mgr_prnt_table_cpm
+       rjmp    mgr_prnt_size\r
+\r
+; FAT16 ?\r
+mgr_prtb_nocpm:
+       cpi             xl,dskType_FAT\r
+       brne    mgr_prtb_nofat\r
+       rcall   mgr_prnt_table_fat
+       rjmp    mgr_prnt_size
+; RAMDISK ?\r
+mgr_prtb_nofat:\r
+       cpi             xl,dskType_RAM\r
+       brne    mgr_prnt_err\r
+       rcall   mgr_prnt_table_ram
+       rjmp    mgr_prnt_size\r
+; Entry Error\r
+mgr_prnt_err:  \r
+       rcall   mgr_prnt_table_err
+       rjmp    mgr_prnt_size\r
+\r
+mgr_prnop:
+       rcall   mgr_prnt_image
+\r
+mgr_prnt_size:\r
+       rcall   print_ultoa
+       printstring ", size: "
+\r
+       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."\r
+
+mgr_goto_next_part:    
+       adiw    z,PARTENTRY_SIZE
+       ldi             temp,high(hostparttbltop)
+       cpi             zl,  low (hostparttbltop)
+       cpc             zh,temp
+       brlo    pprl
+\r
+mgr_pppre:
+       ret
+       \r
+\r
+mgr_prnt_fatsize:
+       rcall   print_ultoa
+       printstring ", size: "
+       \r
+       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\r
+
+mgr_prnt_table_cpm:
+       printstring "CP/M partition at: "
+       ret\r
+\r
+mgr_prnt_table_fat:
+       printstring "FAT16 File-Image at: "
+       ret\r
+\r
+mgr_prnt_table_ram:
+       printstring "Ramdisk at: "
+       ret\r
+\r
+mgr_prnt_table_err:
+       printstring "Unknown Entry at: "
+       ret\r
+
+mgr_prnt_image:
+       printstring "Assuming CP/M image at: "
+       ret\r
+
+\r
diff --git a/avrcpm/avr/dsk_ram.asm b/avrcpm/avr/dsk_ram.asm
new file mode 100644 (file)
index 0000000..4216506
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+;
+;    $Id$
+;\r
+\r
+#ifndef RAMDSK_SUPPORT\r
+       #define RAMDSK_SUPPORT 0        \r
+#endif\r
+\r
+#if RAMDSK_SUPPORT\r
+\r
+;-------------------------------------- Defines for RAMDISK Structures
+\r
+;----------------------------------------------- Start of Data Segment
+
+       .dseg\r
+\r
+rdskbuf:       .byte   128                     ; Buffer for RAM-Disk interaktions\r
+\r
+; ---------------------------------------------- Start of Code Segment
+       .cseg\r
+
+; ====================================================================\r
+; Function: Calculate an sets the adress of Sector within the RAMDISK
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  :  none\r
+; Variables  :  [r] seeksec            Sector to read\r
+;               [r] seektrk            Track  to read\r
+;                              [w] temp3               Number of Bytes per Sector (128)                \r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+
+
+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<<ram_ras), ~0,(1<<ram_a8)|(1<<ram_oe)
+       cbi     P_RAS,ram_ras
+
+.if DISK_DEBUG > 1
+       mov     temp,xh
+       rcall   printhex
+       printstring " "
+       mov     temp,xl
+       rcall   printhex
+       printstring " "
+.endif
+       ret
+
+; ====================================================================\r
+; Function: Does a read opperation on a RAMDISK
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  :  none\r
+; Variables  :  [r] seeksec            Sector to read\r
+;               [r] seektrk            Track  to read\r
+;                              [r] flags               RW operation Flags\r
+;                              [w] erflag              Error Status of the operation\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+
+
+rdsk_read:
+\r
+.if DISK_DEBUG > 1
+       printnewline
+       printstring "rd-adr: "
+.endif
+       rcall   rdsk_adr
+\r
+rdsk_rdl:
+       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+       cbi     P_CAS,ram_cas
+       cbi     P_A8,ram_a8
+       inc     xl
+       dram_wait DRAM_WAITSTATES       ;
+       in      temp,P_DQ-2             ; PIN
+       sbi     P_CAS,ram_cas
+
+       cbi     P_CAS,ram_cas
+       andi    temp,0x0f
+       swap    temp
+       dram_wait DRAM_WAITSTATES       ;
+       in      temp2,P_DQ-2            ; PIN
+       andi    temp2,0x0f
+       or      temp,temp2
+
+       sbi     P_OE,ram_oe
+       sbi     P_CAS,ram_cas
+       dec     temp3
+       st      z+,temp
+       brne    rdsk_rdl
+
+       sbi     P_RAS,ram_ras
+       ldiw    z,rdskbuf
+       lds     xl,dmaadr
+       lds     xh,dmaadr+1
+       ldi     temp3,128       
+rdsk_rdstl:
+       ld      temp,z+
+       mem_write
+       adiw    x,1
+       dec     temp3
+       brne    rdsk_rdstl
+       ret
+       
+; ====================================================================\r
+; Function: Does a write opperation on a RAMDISK
+; ====================================================================\r
+; Parameters\r
+; --------------------------------------------------------------------\r
+; Registers  :  none\r
+; Variables  :  [r] seeksec            Sector to read\r
+;               [r] seektrk            Track  to read\r
+;                              [r] flags               RW operation Flags\r
+;                              [w] erflag              Error Status of the operation\r
+; --------------------------------------------------------------------\r
+; Description:\r
+; ====================================================================\r
+
+rdsk_write:
+.if DISK_DEBUG > 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<<ram_w) | (1<<ram_cas)
+       out     DDRC,temp2
+       rcall   rdsk_adr
+rdsk_wrl:
+       ld      temp,z+
+       mov     temp2,temp
+       andi    temp,RAM_DQ_MASK & ~(1<<ram_w)
+       ori     temp,(1<<ram_cas)
+       out     PORTC,temp
+       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+       cbi     PORTC,ram_cas
+       sbi     PORTD,ram_a8
+       sbi     PORTC,ram_cas
+       swap    temp2
+       andi    temp2,RAM_DQ_MASK & ~(1<<ram_w)
+       ori     temp2,(1<<ram_cas)
+       out     PORTC,temp2
+       cbi     PORTC,ram_cas
+       inc     xl
+       sbi     PORTC,ram_cas
+       dec     temp3
+       brne    rdsk_wrl
+
+       sbi     P_RAS,ram_ras
+       ldi     temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
+       out     DDRC,temp
+       out     PORTC,temp
+       ret\r
+\r
+\r
+rdsk_add_partition:\r
+       ret\r
+\r
+
+#else\r
+\r
+rdsk_read:\r
+       ret\r
+rdsk_write:\r
+       ret\r
+rdsk_add_partition:\r
+       ret\r
+\r
+#endif\r
index 7b9d9fb6c71f119e5f624d48f84b347abccb8cb2..50e1fa24e6d5f1c6e3f5099e7abe362b9834718f 100644 (file)
@@ -205,11 +205,13 @@ ramfillw:
 boot_again:
        printnewline
        printstring "Initing mmc...",0
-       rcall   dsk_partinit
+       printnewline
+       call    mgr_init_partitions
 
        cbr     temp,0x80
        brne    boot_ipl2
        printstring "No bootable CP/M disk found! Please change MMC/SD-Card."
+       printnewline
        ldi     temp2,18
 boot_iplwl:
        ldi     temp,255
@@ -220,16 +222,16 @@ boot_iplwl:
        
 
 boot_ipl2:
-       rcall   prnt_parttbl
+       call    mgr_prnt_parttbl
        printnewline
        printstring "Partinit done."
 
 ; Read first sector of first CP/M partition
 
-       lds     xl,hostparttbl
-       lds     xh,hostparttbl+1
-       lds     yl,hostparttbl+2
-       lds     yh,hostparttbl+3
+       lds     xl,hostparttbl+1
+       lds     xh,hostparttbl+2
+       lds     yl,hostparttbl+3
+       lds     yh,hostparttbl+4
        rcall   mmcReadSect
 
        rcall   dsk_cboot               ;init (de)blocking buffer
@@ -247,6 +249,6 @@ iplwriteloop:
        brne iplwriteloop
        cpi zh,high(hostbuf+128)
        brne iplwriteloop
-       rjmp z80_init
+       jmp z80_init
 
 
index e6559c54972a4393fcd19fc3272061d1da83da0b..b1091655455e4eeff4c2a180e462357f5d2ea0ba 100644 (file)
@@ -82,7 +82,7 @@
 ;      printstring "String"
 
 .macro printstring
-  rcall        printstr
+  call printstr
   .if strlen(@0) % 2
     .db @0,0
   .else
index 1a04542157d96c74ab0a6076688fbfc3158d1831..49a1b9cd716a874542bedcf2d0ee2626c892c9cf 100644 (file)
@@ -591,6 +591,81 @@ mmc_rdex:
 .endif
        ret
 
+\r
+;--------------------------------------------------------------
+; Read word \r
+; TODO: Read Word to ZL,ZH at given ZL/ZH Offset\r
+; Need for reading of single FAT16 Entrys without killing the\r
+; Entrys in hostbuffer...\r
+;
+;      in      zh,zl:          Pointer to Word within the Sector to read       
+;   in yh..xl: Start sector number (LBA)
+;      out     xh,xl   : word thats been read\r
+
+mmcReadWord:
+.if MMC_DEBUG > 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)
+\r
+       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\r
 
 ;--------------------------------------------------------------
 ; Write sector 
index 2af753204be706c13aa96ca969c095329156f8bb..a1372a60f567280d09fcc67f7b353e5f911fb462 100644 (file)
@@ -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)
+\r
+       .dseg\r
 
 
        .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<<ram_ras), ~0,(1<<ram_a8)|(1<<ram_oe)
-       cbi     P_RAS,ram_ras
-
-.if DISK_DEBUG > 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<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
-       cbi     P_CAS,ram_cas
-       cbi     P_A8,ram_a8
-       inc     xl
-       dram_wait DRAM_WAITSTATES       ;
-       in      temp,P_DQ-2             ; PIN
-       sbi     P_CAS,ram_cas
-
-       cbi     P_CAS,ram_cas
-       andi    temp,0x0f
-       swap    temp
-       dram_wait DRAM_WAITSTATES       ;
-       in      temp2,P_DQ-2            ; PIN
-       andi    temp2,0x0f
-       or      temp,temp2
-
-       sbi     P_OE,ram_oe
-       sbi     P_CAS,ram_cas
-       dec     temp3
-       st      z+,temp
-       brne    rdsk_rdl
-
-       sbi     P_RAS,ram_ras
-       ldiw    z,rdskbuf
-       lds     xl,dmaadr
-       lds     xh,dmaadr+1
-       ldi     temp3,128       
-rdsk_rdstl:
-       ld      temp,z+
-       mem_write
-       adiw    x,1
-       dec     temp3
-       brne    rdsk_rdstl
-       ret
-       
-
-rdsk_wr:
-.if DISK_DEBUG > 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<<ram_w) | (1<<ram_cas)
-       out     DDRC,temp2
-       rcall   rdsk_adr
-rdsk_wrl:
-       ld      temp,z+
-       mov     temp2,temp
-       andi    temp,RAM_DQ_MASK & ~(1<<ram_w)
-       ori     temp,(1<<ram_cas)
-       out     PORTC,temp
-       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
-       cbi     PORTC,ram_cas
-       sbi     PORTD,ram_a8
-       sbi     PORTC,ram_cas
-       swap    temp2
-       andi    temp2,RAM_DQ_MASK & ~(1<<ram_w)
-       ori     temp2,(1<<ram_cas)
-       out     PORTC,temp2
-       cbi     PORTC,ram_cas
-       inc     xl
-       sbi     PORTC,ram_cas
-       dec     temp3
-       brne    rdsk_wrl
-
-       sbi     P_RAS,ram_ras
-       ldi     temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
-       out     DDRC,temp
-       out     PORTC,temp
-       ret
-
-
-#endif /* RAMDISKCNT */
-
-;---------------------------------------------------------------------
-
-; Partition table offsets:
-#define PART_TYPE   4
-#define PART_START  8
-#define PART_SIZE  12
-
-       .dseg
-tmp_tbl:
-       .byte   8*MAXDISKS
-
-       .cseg
-dsk_partinit:
-       sts     ndisks,_0
-       rcall   mmcInit
-       andi    temp,MMCST_NOINIT & MMCST_NODISK
-       brne    dsk_pierr
-       
-;Load first sector from MMC (boot sector)
-       ldiw    y,0                     ; Sector 0
-       movw    x,y
-       rcall   mmcReadSect
-       tst     temp
-       breq    dsk_pi1
-
-dsk_pierr:
-       clr     temp
-       ret
-
-dsk_pi1:
-       ldiw    y,tmp_tbl
-       ldi     temp2,8*MAXDISKS
-dsk_picl:
-       st      y+,_0
-       dec     temp2
-       brne    dsk_picl
-       sbiw    y,8*MAXDISKS
-
-;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    dsk_part
-
-;No MBR, no partition table ...
-       inc     temp3                   ;pretend we have one.
-       ldi     temp,high((1<<16) * 128/512)
-       std     y+0,_0                  ;start at beginning of card
-       std     y+1,_0
-       std     y+2,_0
-       std     y+3,_0
-       std     y+4,_0                  ;max CP/M 2.2 disk size
-       std     y+5,temp                ;
-       std     y+6,_0
-       std     y+7,_0
-       rjmp    dsk_pend
-               
-;Search Partition Table for CP/M partitions
-dsk_part:
-       sbiw    z,63                    ;Now at first byte of partition table
-       ldi     temp4,high(hostbuf+510)
-dsk_ploop:
-       ldd     temp,z+PART_TYPE
-       cpi     temp,PARTID
-       brne    dsk_nextp
-       
-; Found a CP/M partition
-       
-       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
-
-       inc     temp3
-       cpi     temp3,MAXDISKS
-       breq    dsk_pend        
-dsk_nextp:
-       adiw    zl,16
-       cpi     zl,low(hostbuf+510)
-       cpc     zh,temp4
-       brlo    dsk_ploop
-
-dsk_pend:
-
-;Store new partitions and check if the SD card has been changed.
-
-       ldiw    y,tmp_tbl
-       ldiw    z,hostparttbl
-       ldi     temp4,8*MAXDISKS
-       clt
-dsk_pcpl:
-       ld      temp,y+
-       ld      temp2,z
-       st      z+,temp
-       cpse    temp,temp2
-        set
-       dec     temp4
-       brne    dsk_pcpl
-
-       mov     temp,temp3
-       sts     ndisks,temp
-       brtc    dsk_pcpe
-
-       tst     temp
-       breq    dsk_pcpe
-
-; SD card changed.
-       sbr     temp,0x80
-
-dsk_pcpe:
-       ret
-
-;---------------------------------------------------------------------
-; Print partition table info
-
-prnt_parttbl:
-       ldiw    z,hostparttbl
-pprl:
-       ldd     xl,z+4                  ;Get partition size
-       ldd     xh,z+5
-       ldd     yl,z+6
-       ldd     yh,z+7
-       cp      xl,_0                   ;If zero ...
-       cpc     xh,_0
-       cpc     yl,_0
-       cpc     yh,_0
-       breq    pppre           ;... No more partitions.
-
-       ldd     temp,z+0                ;Get partition start
-       ldd     temp2,z+1
-       ldd     temp3,z+2
-       ldd     temp4,z+3
-       printnewline
-       cp      temp,_0                 ;If zero ...
-       cpc     temp2,_0
-       cpc     temp3,_0
-       cpc     temp4,_0
-       breq    prnop           ;... no partition table at 0
-
-       rcall   prstr_table
-       rjmp    pprsz
-prnop:
-       rcall   prstr_image
-pprsz:
-       rcall   print_ultoa
-       printstring ", size: "
-       movw    temp,x
-       movw    temp3,y
-
-       lsr     temp4
-       ror     temp3
-       ror     temp2
-       ror     temp
-       rcall   print_ultoa
-       printstring "KB."
-       
-       adiw    z,8
-       ldi     temp,high(hostparttbltop)
-       cpi     zl,  low (hostparttbltop)
-       cpc     zh,temp
-       brlo    pprl
-pppre:
-       ret
-       
-prstr_table:
-       printstring "CP/M partition at: "
-       ret
-prstr_image:
-       printstring "Assuming CP/M image at: "
-       ret
        
 ; ****************************************************************************
 
diff --git a/avrcpm/avr/virt_ports.asm b/avrcpm/avr/virt_ports.asm
new file mode 100644 (file)
index 0000000..92c26d1
--- /dev/null
@@ -0,0 +1,162 @@
+;    Virtual Ports for the BIOS Interaction
+;
+;    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 <http://www.gnu.org/licenses/>.
+;
+;    $Id$
+;\r
+\r
+\r
+; ---------------- 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
+\r
+;----------------------------------------------- Start of Data Segment
+
+       .dseg\r
+\r
+\r
+; ---------------------------------------------- Start of Code Segment
+       .cseg\r
+\r
+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\r
+\r
+conStatus:
+       lds     temp,rxcount
+       cpse    temp,_0
+        ldi    temp,0xff
+       ret
+
+conInp:
+       rjmp uartgetc
+
+dbgOut:
+       printnewline
+       printstring "Debug: "
+       rcall printhex
+       ret
+
+conOut:
+       rjmp uartputc\r
+\r
+;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\r
+\r
+
+\r
+
+;---------------------------------------------------------------------