From b47910465f708f1cbec2c36698647bbebd3484bf Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Sun, 3 Jun 2012 13:38:03 +0000 Subject: [PATCH] - make ALLOC optional (will be removed in next commit) - implement SPI-CRC (CRC routines not yet reviewed for improvements) --- P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo | Bin 9216 -> 27648 bytes .../P8000_WDC_Emulator/Debug/Makefile | 4 +- .../P8000_WDC_Emulator.cproj | 3 - .../P8000_WDC_Emulator/wdc_drv_mmc.c | 167 ++++++++++-- .../P8000_WDC_Emulator/wdc_drv_mmc.h | 4 +- .../P8000_WDC_Emulator/wdc_if_disk.c | 31 ++- .../P8000_WDC_Emulator/wdc_if_p8000.h | 4 +- .../P8000_WDC_Emulator/wdc_main.c | 241 ++++++++++++------ .../P8000_WDC_Emulator/wdc_main.h | 4 +- 9 files changed, 354 insertions(+), 104 deletions(-) diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo b/P8000_WDC_Emulator/P8000_WDC_Emulator.atsuo index 468a8af5122143215ec070f34391f83b675d066f..53d88090388c1cbfda49a73c0cdd04ff99cfcb3a 100755 GIT binary patch literal 27648 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 delta 707 zcmZ8fL2DCH5Pq|HyWLH?ag&Wr-Kb5{T4QbF#$FXt2wH=5SLmUow6w=kr6OCXUa|*| z3T@`%!IOelNpsgg1w|CmQ%|D*KybZCX`HuBWa+@SGw++3k9o7tKLCGrrwY)Tc@O-k z+wJ0@WXmErYTbDayQ@Z%--ZD!@R6ju_+)AC`e%qS#yUxS#6PNMC=^E=DHqV@1L&(9 zw`G5LjYwgk5~+!zP~K3y*<$Z7M*ad}oN$p)B3vR&5H1rY38JY?{z@;d^n57xNy)e7 zGtg8Y@7f%0;@9bE{IzIEn-6ep+{ERLycno0Yi~dU66$8C`~R##+{JgMjb6f44NAl# z$##%%IPRMj^o)6~L^2o{js_Yri74x(Ts29=V3Z6}&apu^uh- zO#k#K5i1gX$l~ldMZiAb&l^wsSNc(#NCE>mE@A7{lUWX|c9O#{3q^GF(q3jo!f$dB zJ43JVK(?AzP35GNCiFKF{&$8Ct-1y#@m3^P~bZ2WV! z(N{TF$9-N&T%~fcKQe4&XYg4zgRVY_RlVBooR3N2f`YuOW~m}4s(Np!?G<8>TEAC* b3!C2$f6q1QchzeOpi#E*{>DxSS1True 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_ */