- make ALLOC optional (will be removed in next commit)

- implement SPI-CRC (CRC routines not yet reviewed for improvements)
This commit is contained in:
Oliver Lehmann 2012-06-03 13:38:03 +00:00
parent 5fa55e3943
commit b47910465f
9 changed files with 354 additions and 104 deletions

View File

@ -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

View File

@ -51,7 +51,6 @@
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</avrgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
@ -64,8 +63,6 @@
<Value>m</Value>
</ListValues>
</avrgcc.linker.libraries.Libraries>
<avrgcc.linker.optimization.GarbageCollectUnusedSections>True</avrgcc.linker.optimization.GarbageCollectUnusedSections>
<avrgcc.linker.optimization.RelaxBranches>True</avrgcc.linker.optimization.RelaxBranches>
</AvrGcc>
</ToolchainSettings>
</PropertyGroup>

View File

@ -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 );
}

View File

@ -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 * );

View File

@ -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;
}

View File

@ -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*/

View File

@ -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;

View File

@ -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_ */