diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo b/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo
index 468a8af..53d8809 100755
Binary files a/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo and b/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo differ
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile b/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile
index fb2a763..75fadc2 100755
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/Debug/Makefile
@@ -110,7 +110,7 @@ OUTPUT_FILE_DEP:= ./makedep.mk
./%.o: .././%.c
@echo Building file: $<
@echo Invoking: AVR/GNU C Compiler : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2
- $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fpack-struct -fshort-enums -Wall -Wundef -Werror -pedantic -pedantic-errors -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -mmcu=atmega1284p -o"$@" "$<"
+ $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -funsigned-char -funsigned-bitfields -O1 -fpack-struct -fshort-enums -Wall -Wundef -Werror -pedantic -pedantic-errors -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -mmcu=atmega1284p -o"$@" "$<"
@echo Finished building: $<
@@ -138,7 +138,7 @@ all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)
$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP)
@echo Building target: $@
@echo Invoking: AVR/GNU Linker : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2
- $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="P8000_WDC_Emulator.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -mrelax -mmcu=atmega1284p
+ $(QUOTE)C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="P8000_WDC_Emulator.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -mmcu=atmega1284p
@echo Finished building target: $@
"C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "P8000_WDC_Emulator.elf" "P8000_WDC_Emulator.hex"
"C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "P8000_WDC_Emulator.elf" "P8000_WDC_Emulator.eep" || exit 0
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj b/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj
index 3c4dd7d..9c8ae6d 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/P8000_WDC_Emulator.cproj
@@ -51,7 +51,6 @@
True
True
Optimize (-O1)
- True
True
True
True
@@ -64,8 +63,6 @@
m
- True
- True
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c
index c7ed158..0875458 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c
@@ -27,6 +27,105 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "mmc.h"
+#ifdef SPI_CRC
+const uint16_t crc_itu_t_table[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+#define CRC7_POLY 0x09
+unsigned char CRC_7Bit ( unsigned char *pData, unsigned int uiLen )
+{
+
+ unsigned int i, c, bit;
+ unsigned int crc = 0;
+
+ while ( uiLen-- ) {
+
+ c = ( unsigned long ) * pData++;
+
+ for ( i = 0x80; i; i >>= 1 ) {
+
+ bit = crc & 0x40;
+ crc <<= 1;
+ if ( c & i ) crc |= 1;
+ if ( bit ) crc ^= CRC7_POLY;
+ }
+ }
+
+ for ( i = 0; i < 7; i++ ) {
+
+ if ( crc & 0x40 ) {
+ crc = ( crc << 1 ) ^ CRC7_POLY;
+ } else
+ crc <<= 1;
+ }
+
+ return ( crc & 0x7F );
+}
+
+
+unsigned short CRC_16Bit ( unsigned char *pData, unsigned int uiLen )
+{
+ unsigned short usCRC;
+
+ //Init CRC register to zero (Required by SD card)
+ usCRC = 0x0000;
+
+ while ( uiLen-- ) {
+ //Do table lookup and xor result
+ //see "Painless guide to CRC error detection algorithms" section 10
+ usCRC = ( usCRC << 8 ) ^ crc_itu_t_table[ ( usCRC >> 8 ) ^ *pData++];
+ }
+
+ return usCRC;
+}
+#endif
+
+unsigned int SDSetCRC ( unsigned int uiCRC )
+{
+ unsigned char ucSDSetCRC[] = {0x3B, 0x00, 0x00, 0x00, 0x00, 0xFF};
+
+ ucSDSetCRC[0] = 0x3B;
+ //tail bit of uiCRC sets or clears CRC mode
+ ucSDSetCRC[4] = uiCRC & 0x01;
+
+ if ( mmc_write_command ( ucSDSetCRC ) != 0 ) {
+ return 1;
+ }
+ return 0;
+}
+
//############################################################################
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
uint8_t mmc_init ()
@@ -81,6 +180,12 @@ uint8_t mmc_init ()
SPSR = SPSR | ( 1 << SPI2X );
#endif
+#ifdef SPI_CRC
+ SDSetCRC ( 1 );
+#else
+ SDSetCRC ( 0 );
+#endif
+
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return ( 0 );
@@ -93,7 +198,14 @@ uint8_t mmc_write_command ( uint8_t *cmd )
{
uint8_t tmp = 0xff;
uint8_t Timeout = 0;
+#ifdef SPI_CRC
+ unsigned char ucCRC;
+ //Calculate CRC and framing bits
+ cmd [0] = ( cmd[0] | ( 1 << 6 ) ) & 0x7F;
+ ucCRC = CRC_7Bit ( cmd, 5 ) << 1;
+ cmd[5] = ucCRC;
+#endif
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
@@ -180,7 +292,9 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *Buffer )
uint8_t tmp;
//Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte
uint8_t cmd[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
-
+#ifdef SPI_CRC
+ unsigned int uiCheckSum;
+#endif
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingefügt*/
@@ -198,6 +312,10 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *Buffer )
SPDR = 0xFE; //Sendet Startbyte
+#ifdef SPI_CRC
+ uiCheckSum = CRC_16Bit ( Buffer, 512 );
+#endif
+
//Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
for ( uint16_t a = 0; a < 512; a++ ) {
uint8_t data = *Buffer;
@@ -208,15 +326,21 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *Buffer )
while ( ! ( SPSR & ( 1 << SPIF ) ) );
//CRC-Byte schreiben
+#ifdef SPI_CRC
+ SPDR = uiCheckSum >> 8;
+ while ( ! ( SPSR & ( 1 << SPIF ) ) );
+ SPDR = uiCheckSum & 0xFF;
+#else
SPDR = 0xFF;
while ( ! ( SPSR & ( 1 << SPIF ) ) );
SPDR = 0xFF;
+#endif
while ( ! ( SPSR & ( 1 << SPIF ) ) );
//Fehler beim schreiben? (Data Response XXX00101 = OK)
SPDR = 0xff;
while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
- if ( ( SPDR & 0x1F ) != 0x05 ) return ( 1 );
+ if ( ( SPDR & 0x1F ) != 0x05 ) return ( 0x02 );
//Wartet auf MMC/SD-Karte Bussy
while ( 1 ) {
@@ -234,16 +358,18 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *Buffer )
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
-void mmc_read_block ( uint8_t *cmd, uint8_t *Buffer, uint16_t Bytes )
+uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *Buffer, uint16_t Bytes )
//############################################################################
{
+#ifdef SPI_CRC
+ uint16_t crc;
+#endif
//Sendet Commando cmd an MMC/SD-Karte
if ( mmc_write_command ( cmd ) != 0 ) {
- return;
+ return ( 1 );
}
//Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
- // while ( mmc_read_byte() != 0xfe ) {};
while ( 1 ) {
SPDR = 0xff;
while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
@@ -251,7 +377,6 @@ void mmc_read_block ( uint8_t *cmd, uint8_t *Buffer, uint16_t Bytes )
break;
}
-
SPDR = 0xff;
while ( ! ( SPSR & ( 1 << SPIF ) ) );
*Buffer = SPDR;
@@ -264,18 +389,35 @@ void mmc_read_block ( uint8_t *cmd, uint8_t *Buffer, uint16_t Bytes )
*Buffer = SPDR;
}
+ Buffer = Buffer - ( Bytes - 1 );
+
//CRC-Byte auslesen
+#ifdef SPI_CRC
+ SPDR = 0xff;
+ while ( ! ( SPSR & ( 1 << SPIF ) ) );
+ crc = SPDR << 8;
+ SPDR = 0xff;
+ while ( ! ( SPSR & ( 1 << SPIF ) ) );
+ crc |= SPDR;
+
+ if ( crc != CRC_16Bit ( Buffer, Bytes ) ) {
+ MMC_Disable();
+ return ( 1 );
+ }
+#else
SPDR = 0xff;
while ( ! ( SPSR & ( 1 << SPIF ) ) );
SPDR;
SPDR = 0xff;
while ( ! ( SPSR & ( 1 << SPIF ) ) );
SPDR;
+#endif
+
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
- return;
+ return ( 0 );
}
//############################################################################
@@ -296,9 +438,8 @@ uint8_t mmc_read_sector ( uint32_t addr, uint8_t *Buffer )
cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
- mmc_read_block ( cmd, Buffer, 512 );
+ return mmc_read_block ( cmd, Buffer, 512 );
- return ( 0 );
}
//############################################################################
@@ -309,9 +450,7 @@ uint8_t mmc_read_cid ( uint8_t *Buffer )
//Commando zum lesen des CID Registers
uint8_t cmd[] = {0x4A, 0x00, 0x00, 0x00, 0x00, 0xFF};
- mmc_read_block ( cmd, Buffer, 16 );
-
- return ( 0 );
+ return mmc_read_block ( cmd, Buffer, 16 );
}
//############################################################################
@@ -322,7 +461,5 @@ uint8_t mmc_read_csd ( uint8_t *Buffer )
//Commando zum lesen des CSD Registers
uint8_t cmd[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};
- mmc_read_block ( cmd, Buffer, 16 );
-
- return ( 0 );
+ return mmc_read_block ( cmd, Buffer, 16 );
}
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h
index 0bff449..6236d42 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.h
@@ -12,6 +12,8 @@ Copyright (C) 2004 Ulrich Radig
#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI
//#define SPI_Mode 0
+#define SPI_CRC 1
+
#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
#define MMC_Read PINB
#define MMC_Direction_REG DDRB
@@ -25,7 +27,7 @@ Copyright (C) 2004 Ulrich Radig
extern uint8_t mmc_read_byte ( void );
extern void mmc_write_byte ( uint8_t );
-extern void mmc_read_block ( uint8_t *, uint8_t *, uint16_t );
+extern uint8_t mmc_read_block ( uint8_t *, uint8_t *, uint16_t );
extern uint8_t mmc_init ( void );
extern uint8_t mmc_read_sector ( uint32_t, uint8_t * );
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c
index d2a8438..bd8a5b2 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c
@@ -1,11 +1,12 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_if_disk.c,v 1.3 2012/06/02 23:04:30 olivleh1 Exp $
+ * $Id: wdc_if_disk.c,v 1.4 2012/06/03 13:38:03 olivleh1 Exp $
*
*/
#include "mmc.h"
+#include "uart.h"
extern uint8_t par_table[200];
uint8_t wdc_init_sdcard()
@@ -32,15 +33,37 @@ uint32_t wdc_p8kblock2sdblock ( uint32_t blockno )
/* +----------------------------------------------- configured heads form the harddisk
* | +------------------------------- configured sectors for the harddisk
* | |*/
- return ( blockno + ( par_table[25] * par_table[26] ) );
+ return ( blockno + ( par_table[25] * par_table[26] ) );
}
uint8_t wdc_write_sector ( uint16_t addr, uint8_t *sector )
{
- return mmc_write_sector ( addr, sector );
+ uint8_t errorcode;
+
+ errorcode = mmc_write_sector ( addr, sector );
+ if ( errorcode ) {
+ uart_puts_p ( PSTR ( " write error at address: " ) );
+ uart_putw_dec ( addr );
+ uart_puts_p ( PSTR ( " / errorcode is: " ) );
+ uart_putc_hex ( errorcode );
+ uart_putc ( '\n' );
+ return errorcode;
+ } else
+ return 0;
}
uint8_t wdc_read_sector ( uint16_t addr, uint8_t *sector )
{
- return mmc_read_sector ( addr, sector );
+ uint8_t errorcode;
+
+ errorcode = mmc_read_sector ( addr, sector );
+ if ( errorcode ) {
+ uart_puts_p ( PSTR ( " read error at address: " ) );
+ uart_putw_dec ( addr );
+ uart_puts_p ( PSTR ( " / errorcode is: " ) );
+ uart_putc_hex ( errorcode );
+ uart_putc ( '\n' );
+ return errorcode;
+ } else
+ return 0;
}
\ No newline at end of file
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h
index 1f88d05..9777ece 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h
@@ -1,14 +1,14 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_if_p8000.h,v 1.3 2012/06/02 23:04:30 olivleh1 Exp $
+ * $Id: wdc_if_p8000.h,v 1.4 2012/06/03 13:38:03 olivleh1 Exp $
*
*/
#ifndef WDC_IF_PIO_H_
#define WDC_IF_PIO_H_
-#define DELAY_PIO_US 400
+#define DELAY_PIO_US 500
#define configure_port_data_read() DDR_DATA = 0x00 /* programs the DATA-Port as Input-only for reading from the P8000*/
#define configure_port_data_write() DDR_DATA = 0xff /* programs the DATA-Port as Out-only for writing to the P8000*/
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c
index e46d037..48bde57 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c
@@ -1,9 +1,11 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_main.c,v 1.7 2012/06/02 23:04:30 olivleh1 Exp $
+ * $Id: wdc_main.c,v 1.8 2012/06/03 13:38:03 olivleh1 Exp $
*
- * TODO: - Prio 1: more commandcodes
+ * TODO: - Different Errorcodes in the MMC layer (use defines)
+ * - errorchecking in several places
+ * - Prio 1: more commandcodes
* - Prio 2: check if BTT is really cleaned when sa.format gets called all the time with a real drive
* ----------> no the old BTT from the previous formatting is shown
* ----------> check if after formatting, no BTT is written to the disk, the old BTT is still there
@@ -27,6 +29,7 @@
#define DEBUG 1
#undef MEASURE_SDCARD_TIME
+#undef USE_ALLOC
void atmega_setup ( void );
@@ -38,14 +41,20 @@ ISR ( TIMER0_OVF_vect )
}
#endif
-int main ( void )
+int __attribute__ ( ( OS_main ) )
+main ( void )
{
uint16_t cmd_counter = 9;
uint16_t data_counter;
uint32_t blockno;
uint8_t errorcode;
+#ifdef USE_ALLOC
uint8_t *data_buffer = NULL;
uint8_t *cmd_buffer = NULL;
+#else
+ uint8_t data_buffer[4096];
+ uint8_t cmd_buffer[9];
+#endif
uint8_t i8;
uint16_t i16;
@@ -91,7 +100,9 @@ int main ( void )
/* load Parameter Table into RAM if valid */
blockno = 0;
data_counter = 512;
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
+#endif
while ( wdc_read_sector ( blockno, data_buffer ) ) {
#if DEBUG >= 1
uart_puts_p ( PSTR ( "Block 0 of SD-Card not readable" ) );
@@ -104,12 +115,17 @@ int main ( void )
wdc_write_par_table ( data_buffer, data_counter );
};
+#ifdef USE_ALLOC
+ free ( data_buffer );
+#endif
+
while ( 1 ) {
wdc_wait_for_reset();
+#ifdef USE_ALLOC
cmd_buffer = malloc ( cmd_counter * sizeof ( *cmd_buffer ) );
-
+#endif
wdc_receive_cmd ( cmd_buffer
, cmd_counter
);
@@ -129,11 +145,94 @@ int main ( void )
#endif
switch ( cmd_buffer[0] ) {
+ case CMD_WR_BLOCK:
+ data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
+ if ( data_counter % 512 > 0 )
+ data_buffer = malloc ( ( data_counter + 512 - ( data_counter % 512 ) ) * sizeof ( *data_buffer ) );
+ else
+ data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
+#endif
+ blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] );
+
+ wdc_receive_data ( data_buffer
+ , data_counter
+ );
+#ifdef USE_ALLOC
+ i8 = 0;
+#endif
+ errorcode = 1;
+ for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
+#ifdef USE_ALLOC
+ errorcode = wdc_write_sector ( blockno, data_buffer );
+#else
+ errorcode = wdc_write_sector ( blockno, &data_buffer[i16] );
+#endif
+ if ( errorcode ) break;
+#ifdef USE_ALLOC
+ i8++;
+ data_buffer += 512;
+#endif
+ blockno++;
+ }
+#ifdef USE_ALLOC
+ data_buffer -= ( 512 * i8 );
+#endif
+ if ( errorcode )
+ wdc_send_error();
+#ifdef USE_ALLOC
+ free ( data_buffer );
+#endif
+ break;
+
+ case CMD_RD_BLOCK:
+ data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
+ if ( data_counter % 512 > 0 )
+ data_buffer = malloc ( ( data_counter + 512 - ( data_counter % 512 ) ) * sizeof ( *data_buffer ) );
+ else
+ data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
+#endif
+ blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] );
+
+#ifdef USE_ALLOC
+ i8 = 0;
+#endif
+ errorcode = 1;
+ for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
+#ifdef USE_ALLOC
+ errorcode = wdc_read_sector ( blockno, data_buffer );
+#else
+ errorcode = wdc_read_sector ( blockno, &data_buffer[i16] );
+#endif
+ if ( errorcode ) break;
+#ifdef USE_ALLOC
+ i8++;
+ data_buffer += 512;
+#endif
+ blockno++;
+ }
+#ifdef USE_ALLOC
+ data_buffer -= ( 512 * i8 );
+#endif
+ if ( errorcode )
+ wdc_send_error();
+
+ wdc_send_data ( data_buffer
+ , data_counter
+ );
+
+#ifdef USE_ALLOC
+ free ( data_buffer );
+#endif
+ break;
+
case CMD_WR_WDC_RAM:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
wdc_receive_data ( data_buffer
, data_counter
);
@@ -143,14 +242,17 @@ int main ( void )
, data_counter
);
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_RD_WDC_RAM:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
wdc_read_data_from_ram ( data_buffer
, convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] )
, data_counter
@@ -160,14 +262,17 @@ int main ( void )
, data_counter
);
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_RD_PARTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
wdc_read_par_table ( data_buffer
, data_counter );
@@ -175,14 +280,17 @@ int main ( void )
, data_counter
);
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_WR_PARTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
wdc_receive_data ( data_buffer
, data_counter
);
@@ -190,7 +298,9 @@ int main ( void )
wdc_write_wdc_par ( data_buffer
, data_counter );
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_DL_BTTAB:
@@ -201,23 +311,26 @@ int main ( void )
case CMD_RD_BTTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
wdc_read_wdc_btt ( data_buffer
, data_counter );
wdc_send_data ( data_buffer
, data_counter
);
-
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_WR_BTTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
wdc_receive_data ( data_buffer
, data_counter
);
@@ -225,13 +338,19 @@ int main ( void )
wdc_write_wdc_btt ( data_buffer
, data_counter );
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_FMTBTT_TRACK:
data_counter = 512;
+#ifdef USE_ALLOC
data_buffer = calloc ( data_counter, sizeof ( *data_buffer ) );
+#else
+ memset ( &data_buffer[0], 0x00, 512 );
+#endif
blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 )
, cmd_buffer[4]
@@ -249,8 +368,10 @@ int main ( void )
if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) {
wdc_send_error();
} else {
+#ifdef USE_ALLOC
free ( data_buffer );
data_buffer = malloc ( 3 * sizeof ( *data_buffer ) );
+#endif
data_buffer[0] = cmd_buffer[2]; // Track Low
data_buffer[1] = cmd_buffer[3]; // Track High
data_buffer[2] = cmd_buffer[4]; // Head
@@ -261,7 +382,9 @@ int main ( void )
}
}
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_ST_PARBTT:
@@ -269,7 +392,9 @@ int main ( void )
blockno = 0;
data_counter = 512;
+#ifdef USE_ALLOC
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
+#endif
wdc_read_par_table ( data_buffer
, data_counter );
@@ -277,25 +402,34 @@ int main ( void )
if ( errorcode )
wdc_send_error();
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_RD_WDCERR:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
data_buffer = calloc ( data_counter, sizeof ( *data_buffer ) );
+#else
+ memset ( &data_buffer[0], 0x00, 512 );
+#endif
wdc_send_data ( data_buffer
, data_counter
);
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_VER_TRACK:
data_counter = 512;
- data_buffer = calloc ( data_counter, sizeof ( *data_buffer ) );
-
+#ifdef USE_ALLOC
+ data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
+#endif
blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 )
, cmd_buffer[4]
, cmd_buffer[5]
@@ -310,97 +444,52 @@ int main ( void )
if ( errorcode )
wdc_send_error();
-
+#ifdef USE_ALLOC
free ( data_buffer );
+#endif
break;
case CMD_RD_SECTOR:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
+#ifdef USE_ALLOC
if ( data_counter % 512 > 0 )
data_buffer = malloc ( ( data_counter + 512 - ( data_counter % 512 ) ) * sizeof ( *data_buffer ) );
else
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
+#endif
blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 )
, cmd_buffer[4]
, cmd_buffer[5]
);
+#ifdef USE_ALLOC
i8 = 0;
+#endif
errorcode = 1;
for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
+#ifdef USE_ALLOC
errorcode = wdc_read_sector ( blockno, data_buffer );
+#else
+ errorcode = wdc_read_sector ( blockno, &data_buffer[i16] );
+#endif
if ( errorcode ) break;
+#ifdef USE_ALLOC
i8++;
- blockno++;
data_buffer += 512;
+#endif
+ blockno++;
}
+#ifdef USE_ALLOC
data_buffer -= ( 512 * i8 );
+#endif
if ( errorcode )
wdc_send_error();
+#ifdef USE_ALLOC
free ( data_buffer );
- break;
-
- case CMD_WR_BLOCK:
- data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
- if ( data_counter % 512 > 0 )
- data_buffer = malloc ( ( data_counter + 512 - ( data_counter % 512 ) ) * sizeof ( *data_buffer ) );
- else
- data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
- blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] );
-
- wdc_receive_data ( data_buffer
- , data_counter
- );
- i8 = 0;
- errorcode = 1;
- for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
- errorcode = wdc_write_sector ( blockno, data_buffer );
- if ( errorcode ) break;
- i8++;
- blockno++;
- data_buffer += 512;
- }
- data_buffer -= ( 512 * i8 );
-
- if ( errorcode )
- wdc_send_error();
-
- free ( data_buffer );
- break;
-
- case CMD_RD_BLOCK:
- data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
- if ( data_counter % 512 > 0 )
- data_buffer = malloc ( ( data_counter + 512 - ( data_counter % 512 ) ) * sizeof ( *data_buffer ) );
- else
- data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
-
- blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] );
-
- i8 = 0;
- errorcode = 1;
- for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
- errorcode = wdc_read_sector ( blockno, data_buffer );
- if ( errorcode ) break;
- i8++;
- blockno++;
- data_buffer += 512;
- }
- data_buffer -= ( 512 * i8 );
-
- if ( errorcode )
- wdc_send_error();
-
- wdc_send_data ( data_buffer
- , data_counter
- );
-
- free ( data_buffer );
+#endif
break;
default:
@@ -421,7 +510,9 @@ int main ( void )
break;
}
+#ifdef USE_ALLOC
free ( cmd_buffer );
+#endif
}
return 0;
diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h
index 2b24ae0..f262620 100644
--- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h
+++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h
@@ -1,7 +1,7 @@
/*
* P8000 WDC Emulator
*
- * $Id: wdc_main.h,v 1.7 2012/06/02 23:04:30 olivleh1 Exp $
+ * $Id: wdc_main.h,v 1.8 2012/06/03 13:38:03 olivleh1 Exp $
*
*/
@@ -32,7 +32,7 @@
#define NO_CMD_DL_TRACK 0x84 /* delete a track */
#define NO_CMD_WRRDBTT_SECTOR 0x92 /* write and reread sector taking BTT into account */
#define NO_CMD_CP_BLOCK 0xa1 /* copy block from drive 1 to drive 0 */
-#define NO_CMD_WRRD_BLOCK 0xa2 /* wrid and reread block */
+#define NO_CMD_WRRD_BLOCK 0xa2 /* write and reread block */
#define CMD_ST_PARBTT 0xc2 /* store PAR and BTT on harddisk */
#endif /* MAIN_H_ */