diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h index e2f0cff..8d721e2 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_config.h,v 1.10 2012/06/08 10:40:39 olivleh1 Exp $ + * $Id: wdc_config.h,v 1.11 2012/06/09 00:22:28 olivleh1 Exp $ */ @@ -78,6 +78,7 @@ #define MMC_MULTIBLOCK 1 +#define MEASURE_SDCARD_TIME 1 #undef MEASURE_SDCARD_TIME #endif /* CONFIG_H_ */ \ No newline at end of file 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 6c5a59a..8530b27 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_drv_mmc.c,v 1.14 2012/06/08 11:11:26 olivleh1 Exp $ + * $Id: wdc_drv_mmc.c,v 1.15 2012/06/09 00:22:28 olivleh1 Exp $ */ #include @@ -45,6 +45,7 @@ #define CMD0 (0x40 + 0) #define CMD1 (0x40 + 1) +#define CMD8 (0x40 + 8) #define CMD12 (0x40 + 12) #define CMD17 (0x40 + 17) #define CMD18 (0x40 + 18) @@ -61,6 +62,8 @@ uint8_t mmc_read_block ( uint8_t *, uint8_t *, uint16_t ); uint8_t mmc_cmd ( uint8_t * ); +uint8_t is_sdhc = 0; + typedef union { uint32_t value32; struct { @@ -177,6 +180,7 @@ uint8_t mmc_enable_crc ( uint8_t on_off ) uint8_t mmc_init () { uint16_t t16 = 0; + uint8_t a; DDR_MMC &= ~ ( 1 << PIN_MMC_MISO ); @@ -184,7 +188,7 @@ uint8_t mmc_init () DDR_MMC |= ( 1 << PIN_MMC_MOSI ); DDR_MMC |= ( 1 << PIN_MMC_CS ); - for ( uint8_t a = 0; a < 200; a++ ) { + for ( a = 0; a < 200; a++ ) { nop(); }; @@ -193,7 +197,7 @@ uint8_t mmc_init () MMC_Disable(); - for ( uint8_t b = 0; b < 0x0f; b++ ) { + for ( a = 0; a < 0x0f; a++ ) { send_dummy_byte(); } @@ -212,12 +216,41 @@ uint8_t mmc_init () send_dummy_byte(); + cmd[0] = CMD8; + cmd[1] = 0x00; + cmd[2] = 0x00; + cmd[3] = 0x01; + cmd[4] = 0xaa; + cmd[5] = 0x86; + a = mmc_cmd ( cmd ); + /* if SDHC Card */ + if ( a <= 1 ) { + /* skip 6 bytes */ + for ( a = 0; a < 6; a++ ) + send_dummy_byte(); + + is_sdhc = 1; + + /* prepare next cmd */ + cmd[0] = CMD1; + cmd[1] = 0x40; + cmd[2] = cmd[3] = cmd[4] = 0x00; + cmd[5] = 0xFF; + } else { + + send_dummy_byte(); + is_sdhc = 0; + + /* prepare next cmd */ + cmd[0] = CMD1; + cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0x00; + cmd[5] = 0xFF; + } + /* * send CMD1 */ t16 = 0; - cmd[0] = CMD1; - cmd[5] = 0xFF; while ( mmc_cmd ( cmd ) != 0 ) { send_dummy_byte(); if ( t16++ > 1000 ) { @@ -281,11 +314,13 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer ) wait_till_card_ready(); /* convert blocks to bytes */ - addr = addr * MMC_BLOCKLEN; + if ( !is_sdhc ) + addr = addr * MMC_BLOCKLEN; x.value32 = addr; cmd[1] = x.value8.hh; cmd[2] = x.value8.hl; cmd[3] = x.value8.lh; + cmd[4] = x.value8.ll; /* * send CMD24 @@ -340,7 +375,7 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer ) uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes ) { uint16_t i = 1; -uint8_t by; + uint8_t by; #ifdef SPI_CRC uint16_t crc; #endif @@ -373,7 +408,7 @@ uint8_t by; wait_till_send_done(); by = recv_byte(); xmit_byte ( 0xff ); - } while ( i @@ -34,8 +34,6 @@ #include "uart.h" #include "wdc_par.h" -extern uint8_t par_table[]; - uint8_t wdc_init_sdcard() { uint8_t errorcode; diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c index f8fd026..4a23144 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c @@ -18,7 +18,7 @@ #include "uart.h" #ifdef MEASURE_SDCARD_TIME -#define BLOCKNO 150000 +#define BLOCKNO 300000 extern uint32_t overflow; @@ -108,13 +108,13 @@ void test_read512(uint8_t numblocks, uint8_t nr_of_tests) uint32_t blockno = 0; uint8_t i8, errorcode; - uart_puts_p ( PSTR ( "Test Read 5000 512B-Blocks with Multiblock-Read (4KB Blocksize):" ) ); + uart_puts_p ( PSTR ( "Test Read 5000 512B-Blocks with Singleblock-Read (512B Blocksize):" ) ); uart_putc ( '\n' ); for ( i8 = 0; i8 < nr_of_tests; i8++ ) { blockno = BLOCKNO; - for ( starttime = overflow; blockno < ( BLOCKNO + 5000 ); blockno += numblocks ) { - errorcode = wdc_read_multiblock ( blockno, data_buffer, numblocks ); + for ( starttime = overflow; blockno < ( BLOCKNO + 5000 ); blockno++ ) { + errorcode = wdc_read_sector ( blockno, data_buffer ); if ( errorcode ) { break; } 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 4625b09..090f914 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h @@ -26,13 +26,13 @@ */ /* - * $Id: wdc_if_p8000.h,v 1.6 2012/06/07 18:01:02 olivleh1 Exp $ + * $Id: wdc_if_p8000.h,v 1.7 2012/06/09 00:22:28 olivleh1 Exp $ */ #ifndef WDC_IF_PIO_H_ #define WDC_IF_PIO_H_ -#define DELAY_PIO_US 500 +#define DELAY_PIO_US 450 #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 d233e75..fa0e12e 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c @@ -29,7 +29,7 @@ /* * P8000 WDC Emulator * - * $Id: wdc_main.c,v 1.22 2012/06/08 11:11:26 olivleh1 Exp $ + * $Id: wdc_main.c,v 1.23 2012/06/09 00:22:28 olivleh1 Exp $ * * TODO: - Different Errorcodes in the MMC layer (use defines) * - errorchecking in several places @@ -41,6 +41,8 @@ * - Prio 3: put the whole par_table handling from wdc_ram.[ch] into wdc_par.[ch] */ +#define DEBUG 1 + #include #include @@ -49,15 +51,15 @@ #include #include #include "main.h" +#ifdef DEBUG #include "uart.h" +#endif #include "wdc_ram.h" #include "wdc_par.h" #include "wdc_if_pio.h" #include "wdc_if_sdcard.h" #include "config.h" -#define DEBUG 1 - void atmega_setup ( void ); #ifdef MEASURE_SDCARD_TIME @@ -68,9 +70,13 @@ ISR ( TIMER0_OVF_vect ) overflow ++; } #else + /* switched from local to global for keeping an eye on memory usage */ uint8_t data_buffer[4096]; uint8_t cmd_buffer[9]; + +extern uint8_t valid_disk; + #endif int __attribute__ ( ( OS_main ) ) @@ -92,19 +98,24 @@ main ( void ) #else /* load Parameter Table into RAM if valid */ - blockno = 0; - data_counter = WDC_BLOCKLEN; - while ( wdc_read_sector ( blockno, data_buffer ) ) { -#if DEBUG >= 1 - uart_puts_p ( PSTR ( "Block 0 of SD-Card not readable" ) ); -#endif - } + if ( wdc_get_disk_valid() ) { + blockno = 0; + data_counter = WDC_BLOCKLEN; + wdc_read_sector ( blockno, data_buffer ); - if ( data_buffer[0] == 'W' && - data_buffer[1] == 'D' && - data_buffer[2] == 'C' ) { - wdc_write_par_table ( data_buffer, data_counter ); - }; + if ( data_buffer[0] == 'W' && + data_buffer[1] == 'D' && + data_buffer[2] == 'C' && + data_buffer[3] == '_' && + data_buffer[4] == '4' && + data_buffer[5] == '.' && + data_buffer[6] == '2' ) { + wdc_write_par_table ( data_buffer, data_counter ); + wdc_set_disk_valid(); + } else { + wdc_set_disk_invalid(); + }; + } while ( 1 ) { @@ -132,224 +143,257 @@ main ( void ) #endif #endif - switch ( cmd_buffer[0] ) { - case CMD_WR_BLOCK: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + /* if the disk is not valid, only maintenance commands are allowed */ + if ( ! wdc_get_disk_valid() + && cmd_buffer[0] != CMD_RD_WDC_RAM + && cmd_buffer[0] != CMD_FMTRD_TRACK + && cmd_buffer[0] != CMD_WR_WDC_RAM + && cmd_buffer[0] != CMD_FMTBTT_TRACK + && cmd_buffer[0] != CMD_RD_PARTAB + && cmd_buffer[0] != CMD_RD_WDCERR + && cmd_buffer[0] != CMD_VER_TRACK + && cmd_buffer[0] != CMD_DL_BTTAB + && cmd_buffer[0] != CMD_RD_BTTAB + && cmd_buffer[0] != CMD_WR_BTTAB + && cmd_buffer[0] != CMD_WR_PARTAB + && cmd_buffer[0] != CMD_ST_PARBTT + ) { + wdc_send_error(); + } else { - 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 - ); - errorcode = 1; - if ( data_counter == WDC_BLOCKLEN ) { - errorcode = wdc_write_sector ( blockno, data_buffer ); - } else { - errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); - } + switch ( cmd_buffer[0] ) { + case CMD_WR_BLOCK: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - if ( errorcode ) - wdc_send_error(); - break; + 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 + ); + errorcode = 1; + if ( data_counter == WDC_BLOCKLEN ) { + errorcode = wdc_write_sector ( blockno, data_buffer ); + } else { + errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); + } - case CMD_RD_BLOCK: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + if ( errorcode ) + wdc_send_error(); + break; - blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] ); + case CMD_RD_BLOCK: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - errorcode = 1; - if ( data_counter == WDC_BLOCKLEN ) { - errorcode = wdc_read_sector ( blockno, data_buffer ); - } else { - errorcode = wdc_read_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); - } + blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] ); + + errorcode = 1; + if ( data_counter == WDC_BLOCKLEN ) { + errorcode = wdc_read_sector ( blockno, data_buffer ); + } else { + errorcode = wdc_read_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); + } + + if ( errorcode ) { + wdc_send_error(); + } else { + wdc_send_data ( data_buffer + , data_counter + ); + } + break; + + case CMD_WR_WDC_RAM: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + wdc_receive_data ( data_buffer + , data_counter + ); + + wdc_write_data_to_ram ( data_buffer + , convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] ) + , data_counter + ); + break; + + case CMD_RD_WDC_RAM: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + wdc_read_data_from_ram ( data_buffer + , convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] ) + , data_counter + ); - if ( errorcode ) { - wdc_send_error(); - } else { wdc_send_data ( data_buffer , data_counter ); - } - break; + break; - case CMD_WR_WDC_RAM: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + case CMD_RD_PARTAB: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - wdc_receive_data ( data_buffer - , data_counter - ); + wdc_read_par_table ( data_buffer + , data_counter ); - wdc_write_data_to_ram ( data_buffer - , convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] ) - , data_counter - ); - break; + wdc_send_data ( data_buffer + , data_counter + ); + break; - case CMD_RD_WDC_RAM: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + case CMD_WR_PARTAB: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - wdc_read_data_from_ram ( data_buffer - , convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] ) - , data_counter - ); + wdc_receive_data ( data_buffer + , data_counter + ); - wdc_send_data ( data_buffer - , data_counter - ); - break; + wdc_write_wdc_par ( data_buffer + , data_counter ); - case CMD_RD_PARTAB: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + break; - wdc_read_par_table ( data_buffer - , data_counter ); + case CMD_DL_BTTAB: + wdc_del_wdc_btt(); + break; - wdc_send_data ( data_buffer - , data_counter - ); - break; + case CMD_RD_BTTAB: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - case CMD_WR_PARTAB: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + wdc_read_wdc_btt ( data_buffer + , data_counter ); - wdc_receive_data ( data_buffer - , data_counter - ); + wdc_send_data ( data_buffer + , data_counter + ); + break; - wdc_write_wdc_par ( data_buffer - , data_counter ); - break; + case CMD_WR_BTTAB: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - case CMD_DL_BTTAB: - wdc_del_wdc_btt(); - break; + wdc_receive_data ( data_buffer + , data_counter + ); - case CMD_RD_BTTAB: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + wdc_write_wdc_btt ( data_buffer + , data_counter ); + break; - wdc_read_wdc_btt ( data_buffer - , data_counter ); + case CMD_FMTRD_TRACK: + case CMD_FMTBTT_TRACK: - wdc_send_data ( data_buffer - , data_counter - ); - break; + /* no cylinder 0 formatting if command is CMD_FMTBTT_TRACK */ + if ( cmd_buffer[0] == CMD_FMTBTT_TRACK && ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) ) == 0 ) + break; - case CMD_WR_BTTAB: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + data_counter = WDC_BLOCKLEN; - wdc_receive_data ( data_buffer - , data_counter - ); + memset ( &data_buffer[0], 0x00, data_counter ); + blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) + , cmd_buffer[4] + , cmd_buffer[5] + ); - wdc_write_wdc_btt ( data_buffer - , data_counter ); - break; - - case CMD_FMTBTT_TRACK: - data_counter = WDC_BLOCKLEN; - - memset ( &data_buffer[0], 0x00, data_counter ); - blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) - , cmd_buffer[4] - , cmd_buffer[5] - ); - - errorcode = 1; - for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { - errorcode = wdc_write_sector ( blockno, data_buffer ); - if ( errorcode ) break; - blockno++; - } - - if ( errorcode ) { - if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) { - wdc_send_error(); - } else { - data_buffer[0] = cmd_buffer[2]; /* Track Low */ - data_buffer[1] = cmd_buffer[3]; /* Track High */ - data_buffer[2] = cmd_buffer[4]; /* Head */ - - wdc_send_data ( data_buffer - , 3 - ); + errorcode = 1; + for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { + errorcode = wdc_write_sector ( blockno, data_buffer ); + if ( errorcode ) break; + blockno++; } - } - break; - case CMD_ST_PARBTT: - data_counter = WDC_BLOCKLEN; - blockno = 0; - wdc_read_par_table ( data_buffer - , data_counter ); + if ( errorcode ) { + if ( cmd_buffer[0] == CMD_FMTRD_TRACK ) { + wdc_send_error(); + } else { + if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) { + wdc_send_error(); + } else { + data_buffer[0] = cmd_buffer[2]; /* Track Low */ + data_buffer[1] = cmd_buffer[3]; /* Track High */ + data_buffer[2] = cmd_buffer[4]; /* Head */ - errorcode = wdc_write_sector ( blockno, data_buffer ); - if ( errorcode ) - wdc_send_error(); - break; + wdc_send_data ( data_buffer + , 3 + ); + } + } + } + break; - case CMD_RD_WDCERR: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + case CMD_ST_PARBTT: + data_counter = WDC_BLOCKLEN; - memset ( &data_buffer[0], 0x00, data_counter ); - wdc_send_data ( data_buffer - , data_counter - ); - break; + blockno = 0; + wdc_set_disk_valid(); + wdc_read_par_table ( data_buffer + , data_counter ); - case CMD_VER_TRACK: - data_counter = WDC_BLOCKLEN; - - blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) - , cmd_buffer[4] - , cmd_buffer[5] - ); - errorcode = 1; - for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { - errorcode = wdc_read_sector ( blockno, data_buffer ); - if ( errorcode ) break; - blockno++; - } - if ( errorcode ) - wdc_send_error(); - break; - - case CMD_RD_SECTOR: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - - blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) - , cmd_buffer[4] - , cmd_buffer[5] - ); - errorcode = 1; - - if ( data_counter == WDC_BLOCKLEN ) { errorcode = wdc_write_sector ( blockno, data_buffer ); - } else { - errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); - } + if ( errorcode ) + wdc_send_error(); - if ( errorcode ) - wdc_send_error(); - break; + break; - default: + case CMD_RD_WDCERR: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + memset ( &data_buffer[0], 0x00, data_counter ); + wdc_send_data ( data_buffer + , data_counter + ); + break; + + case CMD_VER_TRACK: + data_counter = WDC_BLOCKLEN; + + blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) + , cmd_buffer[4] + , cmd_buffer[5] + ); + errorcode = 1; + for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { + errorcode = wdc_read_sector ( blockno, data_buffer ); + if ( errorcode ) break; + blockno++; + } + if ( errorcode ) + wdc_send_error(); + break; + + case CMD_RD_SECTOR: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) + , cmd_buffer[4] + , cmd_buffer[5] + ); + errorcode = 1; + + if ( data_counter == WDC_BLOCKLEN ) { + errorcode = wdc_write_sector ( blockno, data_buffer ); + } else { + errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); + } + + if ( errorcode ) + wdc_send_error(); + break; + + default: #if DEBUG >= 1 - uart_puts_p ( PSTR ( " Unknown command:" ) ); - uart_putc_hex ( cmd_buffer[0] ); - uart_putc_hex ( cmd_buffer[1] ); - uart_putc_hex ( cmd_buffer[2] ); - uart_putc_hex ( cmd_buffer[3] ); - uart_putc_hex ( cmd_buffer[4] ); - uart_putc_hex ( cmd_buffer[5] ); - uart_putc_hex ( cmd_buffer[6] ); - uart_putc_hex ( cmd_buffer[7] ); - uart_putc_hex ( cmd_buffer[8] ); - uart_putc ( '\n' ); + uart_puts_p ( PSTR ( " Unknown command:" ) ); + uart_putc_hex ( cmd_buffer[0] ); + uart_putc_hex ( cmd_buffer[1] ); + uart_putc_hex ( cmd_buffer[2] ); + uart_putc_hex ( cmd_buffer[3] ); + uart_putc_hex ( cmd_buffer[4] ); + uart_putc_hex ( cmd_buffer[5] ); + uart_putc_hex ( cmd_buffer[6] ); + uart_putc_hex ( cmd_buffer[7] ); + uart_putc_hex ( cmd_buffer[8] ); + uart_putc ( '\n' ); #endif - wdc_send_error(); - break; + wdc_send_error(); + break; + } } } #endif @@ -361,10 +405,8 @@ void atmega_setup ( void ) set_sleep_mode ( SLEEP_MODE_IDLE ); uart_init(); wdc_init_ports(); - while ( wdc_init_sdcard() ) { -#if DEBUG >= 1 - uart_puts_p ( PSTR ( "SDCard initialisation failed!" ) ); -#endif + if ( wdc_init_sdcard() ) { + wdc_set_no_disk(); } } \ No newline at end of file diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h index 8b06a9e..5e0b667 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_main.h,v 1.10 2012/06/07 18:01:02 olivleh1 Exp $ + * $Id: wdc_main.h,v 1.11 2012/06/09 00:22:28 olivleh1 Exp $ */ @@ -39,7 +39,7 @@ #define CMD_RD_WDC_RAM 0x08 /* read data from WDC RAM */ #define ___CMD_RDBTT_SECTOR 0x11 /* read sector taking BTT into account */ #define ___CMD_WRBTT_SECTOR 0x12 /* write sector taking BTT into account */ -#define ___CMD_FMTRD_TRACK 0x14 /* format and reread a track */ +#define CMD_FMTRD_TRACK 0x14 /* format and reread a track */ #define CMD_WR_WDC_RAM 0x18 /* write data to WDC RAM */ #define CMD_RD_BLOCK 0x21 /* read data beginning at given block */ #define CMD_WR_BLOCK 0x22 /* write data beginning at given block */ diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c index 1cf8046..0566751 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c @@ -26,19 +26,78 @@ */ /* - * $Id: wdc_par.c,v 1.2 2012/06/07 18:01:02 olivleh1 Exp $ + * $Id: wdc_par.c,v 1.3 2012/06/09 00:22:28 olivleh1 Exp $ */ #include #include "wdc_par.h" -uint8_t par_table[512] = {'W', 'D', 'C', '_', '4', '.', '2', 0x00, 'R', 'O', 'B', ' ', 'K', '5', '5', '0', - '4', '.', '5', '0', 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x12, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x67, 0x01, 0x00, 0x01, 0x01, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +/* + * unformatted ST138 + * + * 57 44 43 5F 34 2E 32 81 81 81 81 81 81 81 81 81 + * 81 81 81 81 81 81 81 64 00 02 12 64 00 01 81 81 + * 81 81 81 81 81 81 81 81 81 81 EB 0D 00 00 41 00 + * 01 01 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * 81 81 81 81 81 EB 0D 00 00 24 00 00 81 81 81 81 + * 00 81 00 80 FE 00 00 00 01 81 81 73 00 12 81 01 + * 00 02 00 00 81 81 81 00 41 D7 28 81 81 81 81 81 + * 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * + * + * fresh formatted ST138 + * + * 57 44 43 5F 34 2E 32 81 53 54 32 35 31 2D 31 20 + * 20 20 20 20 81 00 00 34 03 06 12 34 03 01 00 00 + * 00 00 00 00 CB D1 FB FD F1 F3 83 59 01 00 01 09 + * 00 01 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * 81 81 81 81 81 83 59 01 00 6C 00 00 81 81 81 E5 + * 00 81 00 80 FE 00 00 00 01 81 81 33 00 12 81 00 + * 00 00 00 00 81 81 81 09 01 D7 28 81 81 81 81 81 + * 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * + * + * no harddrive attached: + * + * 57 44 43 5F 34 2E 32 81 81 81 81 81 81 81 81 81 + * 81 81 81 81 81 81 81 64 00 02 12 64 00 01 81 81 + * 81 81 81 81 81 81 81 81 81 81 81 81 81 81 40 00 + * 00 00 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * 00 81 00 80 81 81 81 81 81 81 81 33 00 12 81 00 + * 81 81 81 81 81 81 81 00 40 D7 81 81 81 81 81 81 + * 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 + * + */ +uint8_t par_table[512]; +const uint8_t +par_tab_new_dsk[128] = {'W', 'D', 'C', '_', '4', '.', '2', 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x64, 0x00, 0x02, 0x12, 0x64, 0x00, 0x01, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, /* init with sa.format ends here */ + /* to be initiated by controller starts here */ 0xEB, 0x0D, 0x00, 0x00, 0x41, 0x00, + 0x01, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0xEB, 0x0D, 0x00, 0x00, 0x24, 0x00, 0x00, 0x81, 0x81, 0x81, 0x81, + 0x00, 0x81, 0x00, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x81, 0x81, 0x73, 0x00, 0x12, 0x81, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x81, 0x81, 0x81, 0x00, 0x41, 0xd7, 0x28, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + }; + +const uint8_t +par_tab_no_dsk[128] = {'W', 'D', 'C', '_', '4', '.', '2', 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x64, 0x00, 0x02, 0x12, 0x64, 0x00, 0x01, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, /* init with sa.format ends here */ + /* to be initiated by controller starts here */ 0x81, 0x81, 0x81, 0x81, 0x40, 0x00, + 0x00, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x00, 0x81, 0x00, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x33, 0x00, 0x12, 0x81, 0x00, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x40, 0xd7, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + }; + +uint8_t valid_disk = 1; + void wdc_read_par_table ( uint8_t *buffer, uint16_t count ) { do { @@ -136,3 +195,60 @@ uint8_t wdc_get_hdd_heads() { return ( par_table[17 + POS_PAR_WDC_PAR] ); } +uint16_t wdc_get_hdd_cylinder() +{ + return ( ( par_table[16 + POS_PAR_WDC_PAR] << 8 ) | par_table[15 + POS_PAR_WDC_PAR] ); +} + +void wdc_set_disk_invalid() +{ + valid_disk = 0; + uint8_t i; + for ( i = 0; i < 128; i++ ) + par_table[i] = par_tab_new_dsk[i]; +} + +void wdc_set_disk_valid() +{ + uint32_t blocks; + uint16_t zw0, zw1; + + blocks = (uint32_t)wdc_get_hdd_sectors() * (uint32_t)wdc_get_hdd_heads() * (uint32_t) wdc_get_hdd_cylinder() + - (uint32_t)wdc_get_hdd_sectors() * (uint32_t)wdc_get_hdd_heads(); + + zw0 = blocks / 65536; + zw1 = ( blocks % 65536 ) - 1; + + valid_disk = 1; + par_table[42] = zw1; + par_table[43] = zw1 >> 8; + par_table[44] = zw0; + par_table[45] = zw0 >> 8; + par_table[46] = 0x01; + par_table[47] = 0x09; + par_table[48] = 0x00; + par_table[69] = 0x83; + par_table[70] = 0x59; + par_table[71] = 0x01; + par_table[73] = 0x6c; + par_table[91] = 0x33; + par_table[95] = 0x00; +} + +void wdc_set_no_disk() +{ + uint8_t i; + valid_disk = 0; + for ( i = 0; i < 128; i++ ) + par_table[i] = par_tab_no_dsk[i]; +} + +uint8_t wdc_get_disk_valid() +{ + return valid_disk; +} + +uint8_t wdc_get_num_of_drvs() +{ + return par_table[49]; +} \ No newline at end of file diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h index 7c9955c..cb202f6 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_par.h,v 1.2 2012/06/07 18:01:02 olivleh1 Exp $ + * $Id: wdc_par.h,v 1.3 2012/06/09 00:22:29 olivleh1 Exp $ */ #ifndef WDC_PAR_H_ @@ -47,12 +47,19 @@ extern uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head ); extern uint8_t wdc_get_hdd_sectors(); extern uint8_t wdc_get_hdd_heads(); +void wdc_set_disk_invalid(); +void wdc_set_disk_valid(); +uint8_t wdc_get_disk_valid(); + +void wdc_set_no_disk(); +uint8_t wdc_get_num_of_drvs(); + #define POS_PAR_VERSION 0 #define POS_PAR_WDC_PAR 8 -#define POS_PAR_WDC_BTT 88 +#define POS_PAR_WDC_BTT 0x88 #define SIZE_PAR_VERSION 8 -#define SIZE_PAR_WDC_PAR 80 +#define SIZE_PAR_WDC_PAR 0x80 #define SIZE_PAR_WDC_BTT 125 #endif /* WDC_PAR_H_ */ \ No newline at end of file