much more support now
This commit is contained in:
parent
9c672773b2
commit
a25e66b4ff
|
|
@ -36,6 +36,7 @@ SUBDIRS :=
|
|||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../main.c \
|
||||
../mmc.c \
|
||||
../uart.c \
|
||||
../wdc_if_pio.c \
|
||||
../wdc_if_sdcard.c \
|
||||
|
|
@ -50,6 +51,7 @@ ASM_SRCS +=
|
|||
|
||||
OBJS += \
|
||||
main.o \
|
||||
mmc.o \
|
||||
uart.o \
|
||||
wdc_if_pio.o \
|
||||
wdc_if_sdcard.o \
|
||||
|
|
@ -58,6 +60,7 @@ wdc_ram.o
|
|||
|
||||
OBJS_AS_ARGS += \
|
||||
main.o \
|
||||
mmc.o \
|
||||
uart.o \
|
||||
wdc_if_pio.o \
|
||||
wdc_if_sdcard.o \
|
||||
|
|
@ -66,6 +69,7 @@ wdc_ram.o
|
|||
|
||||
C_DEPS += \
|
||||
main.d \
|
||||
mmc.d \
|
||||
uart.d \
|
||||
wdc_if_pio.d \
|
||||
wdc_if_sdcard.d \
|
||||
|
|
@ -74,6 +78,7 @@ wdc_ram.d
|
|||
|
||||
C_DEPS_AS_ARGS += \
|
||||
main.d \
|
||||
mmc.d \
|
||||
uart.d \
|
||||
wdc_if_pio.d \
|
||||
wdc_if_sdcard.d \
|
||||
|
|
@ -100,10 +105,12 @@ 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 -fpack-struct -fshort-enums -g2 -Wall -Wundef -Werror -pedantic -pedantic-errors -c -std=gnu99 -save-temps -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 -g2 -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: $<
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
main.c
|
||||
|
||||
mmc.c
|
||||
|
||||
uart.c
|
||||
|
||||
wdc_if_pio.c
|
||||
|
|
|
|||
|
|
@ -45,28 +45,27 @@
|
|||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGcc>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<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.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.compiler.warnings.Undefined>True</avrgcc.compiler.warnings.Undefined>
|
||||
<avrgcc.compiler.warnings.WarningsAsErrors>True</avrgcc.compiler.warnings.WarningsAsErrors>
|
||||
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
|
||||
<avrgcc.compiler.warnings.PedanticWarningsAsErrors>True</avrgcc.compiler.warnings.PedanticWarningsAsErrors>
|
||||
<avrgcc.compiler.miscellaneous.DoNotDeleteTemporaryFiles>True</avrgcc.compiler.miscellaneous.DoNotDeleteTemporaryFiles>
|
||||
<avrgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>m</Value>
|
||||
</ListValues>
|
||||
</avrgcc.linker.libraries.Libraries>
|
||||
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
|
||||
</AvrGcc>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<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.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.compiler.warnings.Undefined>True</avrgcc.compiler.warnings.Undefined>
|
||||
<avrgcc.compiler.warnings.WarningsAsErrors>True</avrgcc.compiler.warnings.WarningsAsErrors>
|
||||
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
|
||||
<avrgcc.compiler.warnings.PedanticWarningsAsErrors>True</avrgcc.compiler.warnings.PedanticWarningsAsErrors>
|
||||
<avrgcc.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>m</Value>
|
||||
</ListValues>
|
||||
</avrgcc.linker.libraries.Libraries>
|
||||
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
|
||||
</AvrGcc>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -79,6 +78,12 @@
|
|||
<Compile Include="main.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="mmc.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="mmc.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="uart.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
/*#######################################################################################
|
||||
Connect AVR to MMC/SD
|
||||
|
||||
Copyright (C) 2004 Ulrich Radig
|
||||
|
||||
Bei Fragen und Verbesserungen wendet euch per EMail an
|
||||
|
||||
mail@ulrichradig.de
|
||||
|
||||
oder im Forum meiner Web Page : www.ulrichradig.de
|
||||
|
||||
Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
|
||||
GNU General Public License, wie von der Free Software Foundation veröffentlicht,
|
||||
weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
|
||||
(nach Ihrer Option) jeder späteren Version.
|
||||
|
||||
Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
|
||||
daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
|
||||
sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
|
||||
FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
|
||||
|
||||
Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
|
||||
Programm erhalten haben.
|
||||
Falls nicht, schreiben Sie an die Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
#######################################################################################*/
|
||||
|
||||
#include "mmc.h"
|
||||
|
||||
//############################################################################
|
||||
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
|
||||
uint8_t mmc_init ()
|
||||
//############################################################################
|
||||
{
|
||||
uint8_t Timeout = 0;
|
||||
|
||||
//Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde
|
||||
MMC_Direction_REG &= ~ ( 1 << SPI_DI ); //Setzen von Pin MMC_DI auf Input
|
||||
MMC_Direction_REG |= ( 1 << SPI_Clock ); //Setzen von Pin MMC_Clock auf Output
|
||||
MMC_Direction_REG |= ( 1 << SPI_DO ); //Setzen von Pin MMC_DO auf Output
|
||||
MMC_Direction_REG |= ( 1 << MMC_Chip_Select ); //Setzen von Pin MMC_Chip_Select auf Output
|
||||
MMC_Write |= ( 1 << MMC_Chip_Select ); //Setzt den Pin MMC_Chip_Select auf High Pegel
|
||||
|
||||
for ( uint8_t a = 0; a < 200; a++ ) {
|
||||
nop();
|
||||
}; //Wartet eine kurze Zeit
|
||||
|
||||
#if SPI_Mode
|
||||
//Aktiviren des SPI - Bus, Clock = Idel LOW
|
||||
//SPI Clock teilen durch 128
|
||||
SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 ) | ( 1 << SPR1 ); //Enable SPI, SPI in Master Mode
|
||||
SPSR = ( 0 << SPI2X );
|
||||
#endif
|
||||
|
||||
//Initialisiere MMC/SD-Karte in den SPI-Mode
|
||||
for ( uint8_t b = 0; b < 0x0f; b++ ) { //Sendet min 74+ Clocks an die MMC/SD-Karte
|
||||
mmc_write_byte ( 0xff );
|
||||
}
|
||||
|
||||
//Sendet Commando CMD0 an MMC/SD-Karte
|
||||
uint8_t CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
|
||||
while ( mmc_write_command ( CMD ) != 1 ) {
|
||||
if ( Timeout++ > 200 ) {
|
||||
MMC_Disable();
|
||||
return ( 1 ); //Abbruch bei Commando1 (Return Code1)
|
||||
}
|
||||
}
|
||||
//Sendet Commando CMD1 an MMC/SD-Karte
|
||||
Timeout = 0;
|
||||
CMD[0] = 0x41;//Commando 1
|
||||
CMD[5] = 0xFF;
|
||||
while ( mmc_write_command ( CMD ) != 0 ) {
|
||||
if ( Timeout++ > 400 ) {
|
||||
MMC_Disable();
|
||||
return ( 2 ); //Abbruch bei Commando2 (Return Code2)
|
||||
}
|
||||
}
|
||||
#if SPI_Mode
|
||||
//SPI Bus auf max Geschwindigkeit
|
||||
SPCR &= ~ ( ( 1 << SPR0 ) | ( 1 << SPR1 ) );
|
||||
SPSR = SPSR | ( 1 << SPI2X );
|
||||
#endif
|
||||
|
||||
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
|
||||
MMC_Disable();
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//Sendet ein Commando an die MMC/SD-Karte
|
||||
uint8_t mmc_write_command ( uint8_t *cmd )
|
||||
//############################################################################
|
||||
{
|
||||
uint8_t tmp = 0xff;
|
||||
uint8_t Timeout = 0;
|
||||
|
||||
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
|
||||
MMC_Disable();
|
||||
|
||||
//sendet 8 Clock Impulse
|
||||
mmc_write_byte ( 0xFF );
|
||||
|
||||
//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
|
||||
MMC_Enable();
|
||||
|
||||
//sendet 6 Byte Commando
|
||||
for ( uint8_t a = 0; a < 0x06; a++ ) { //sendet 6 Byte Commando zur MMC/SD-Karte
|
||||
mmc_write_byte ( *cmd++ );
|
||||
}
|
||||
|
||||
//Wartet auf ein gültige Antwort von der MMC/SD-Karte
|
||||
while ( tmp == 0xff ) {
|
||||
tmp = mmc_read_byte();
|
||||
if ( Timeout++ > 500 ) {
|
||||
break; //Abbruch da die MMC/SD-Karte nicht Antwortet
|
||||
}
|
||||
}
|
||||
return ( tmp );
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//Routine zum Empfangen eines Bytes von der MMC-Karte
|
||||
uint8_t mmc_read_byte ( void )
|
||||
//############################################################################
|
||||
{
|
||||
uint8_t Byte = 0;
|
||||
#if SPI_Mode //Routine für Hardware SPI
|
||||
SPDR = 0xff;
|
||||
while ( ! ( SPSR & ( 1 << SPIF ) ) ) {};
|
||||
Byte = SPDR;
|
||||
|
||||
#else //Routine für Software SPI
|
||||
for ( uint8_t a = 8; a > 0; a-- ) { //das Byte wird Bitweise nacheinander Empangen MSB First
|
||||
MMC_Write &= ~ ( 1 << SPI_Clock ); //erzeugt ein Clock Impuls (Low)
|
||||
|
||||
if ( bit_is_set ( MMC_Read, SPI_DI ) > 0 ) { //Lesen des Pegels von MMC_DI
|
||||
Byte |= ( 1 << ( a - 1 ) );
|
||||
} else {
|
||||
Byte &= ~ ( 1 << ( a - 1 ) );
|
||||
}
|
||||
MMC_Write |= ( 1 << SPI_Clock ); //setzt Clock Impuls wieder auf (High)
|
||||
}
|
||||
#endif
|
||||
return ( Byte );
|
||||
}
|
||||
|
||||
|
||||
//############################################################################
|
||||
//Routine zum Senden eines Bytes zur MMC-Karte
|
||||
void mmc_write_byte ( uint8_t Byte )
|
||||
//############################################################################
|
||||
{
|
||||
#if SPI_Mode //Routine für Hardware SPI
|
||||
|
||||
SPDR = Byte; //Sendet ein Byte
|
||||
|
||||
while ( ! ( SPSR & ( 1 << SPIF ) ) ) { //Wartet bis Byte gesendet wurde
|
||||
}
|
||||
|
||||
#else //Routine für Software SPI
|
||||
for ( uint8_t a = 8; a > 0; a-- ) { //das Byte wird Bitweise nacheinander Gesendet MSB First
|
||||
if ( bit_is_set ( Byte, ( a - 1 ) ) > 0 ) { //Ist Bit a in Byte gesetzt
|
||||
MMC_Write |= ( 1 << SPI_DO ); //Set Output High
|
||||
} else {
|
||||
MMC_Write &= ~ ( 1 << SPI_DO ); //Set Output Low
|
||||
}
|
||||
MMC_Write &= ~ ( 1 << SPI_Clock ); //erzeugt ein Clock Impuls (LOW)
|
||||
|
||||
MMC_Write |= ( 1 << SPI_Clock ); //setzt Clock Impuls wieder auf (High)
|
||||
}
|
||||
MMC_Write |= ( 1 << SPI_DO ); //setzt Output wieder auf High
|
||||
#endif
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
|
||||
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};
|
||||
|
||||
/*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*/
|
||||
addr = addr << 9; //addr = addr * 512
|
||||
|
||||
cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
|
||||
cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
|
||||
cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
|
||||
|
||||
//Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
|
||||
tmp = mmc_write_command ( cmd );
|
||||
if ( tmp != 0 ) {
|
||||
return ( tmp );
|
||||
}
|
||||
|
||||
//Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte
|
||||
for ( uint16_t a = 0; a < 100; a++ ) {
|
||||
mmc_read_byte();
|
||||
}
|
||||
|
||||
//Sendet Start Byte an MMC/SD-Karte
|
||||
mmc_write_byte ( 0xFE );
|
||||
|
||||
//Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
|
||||
for ( uint16_t a = 0; a < 512; a++ ) {
|
||||
mmc_write_byte ( *Buffer++ );
|
||||
}
|
||||
|
||||
//CRC-Byte schreiben
|
||||
mmc_write_byte ( 0xFF ); //Schreibt Dummy CRC
|
||||
mmc_write_byte ( 0xFF ); //CRC Code wird nicht benutzt
|
||||
|
||||
//Fehler beim schreiben? (Data Response XXX00101 = OK)
|
||||
if ( ( mmc_read_byte() & 0x1F ) != 0x05 ) return ( 1 );
|
||||
|
||||
//Wartet auf MMC/SD-Karte Bussy
|
||||
while ( mmc_read_byte() != 0xff ) {};
|
||||
|
||||
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
|
||||
MMC_Disable();
|
||||
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//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 )
|
||||
//############################################################################
|
||||
{
|
||||
//Sendet Commando cmd an MMC/SD-Karte
|
||||
if ( mmc_write_command ( cmd ) != 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
|
||||
while ( mmc_read_byte() != 0xfe ) {};
|
||||
|
||||
//Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte
|
||||
for ( uint16_t a = 0; a < Bytes; a++ ) {
|
||||
*Buffer++ = mmc_read_byte();
|
||||
}
|
||||
//CRC-Byte auslesen
|
||||
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
|
||||
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
|
||||
|
||||
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
|
||||
MMC_Disable();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
|
||||
uint8_t mmc_read_sector ( uint32_t addr, uint8_t *Buffer )
|
||||
//############################################################################
|
||||
{
|
||||
//Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
|
||||
uint8_t cmd[] = {0x51, 0x00, 0x00, 0x00, 0x00, 0xFF};
|
||||
|
||||
/*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*/
|
||||
|
||||
addr = addr << 9; //addr = addr * 512
|
||||
|
||||
cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
|
||||
cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
|
||||
cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
|
||||
|
||||
mmc_read_block ( cmd, Buffer, 512 );
|
||||
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
|
||||
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 );
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes)
|
||||
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 );
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*#######################################################################################
|
||||
Connect ARM to MMC/SD
|
||||
|
||||
Copyright (C) 2004 Ulrich Radig
|
||||
#######################################################################################*/
|
||||
|
||||
#ifndef _MMC_H_
|
||||
#define _MMC_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI
|
||||
//#define SPI_Mode 0
|
||||
|
||||
#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
|
||||
|
||||
#define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
|
||||
#define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
|
||||
#define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
|
||||
#define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
|
||||
|
||||
//Prototypes
|
||||
|
||||
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_init ( void );
|
||||
extern uint8_t mmc_read_sector ( uint32_t, uint8_t * );
|
||||
extern uint8_t mmc_write_sector ( uint32_t, uint8_t * );
|
||||
|
||||
extern uint8_t mmc_write_command ( uint8_t * );
|
||||
extern uint8_t mmc_read_csd ( uint8_t * );
|
||||
extern uint8_t mmc_read_cid ( uint8_t * );
|
||||
|
||||
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
|
||||
#define MMC_Disable() MMC_Write|= (1<<MMC_Chip_Select);
|
||||
|
||||
//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
|
||||
#define MMC_Enable() MMC_Write&=~(1<<MMC_Chip_Select);
|
||||
|
||||
#define nop() __asm__ __volatile__ ("nop" ::)
|
||||
|
||||
#endif //_MMC_H_
|
||||
|
||||
|
||||
|
|
@ -1,11 +1,37 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_if_disk.c,v 1.1 2012/05/31 20:21:51 olivleh1 Exp $
|
||||
* $Id: wdc_if_disk.c,v 1.2 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
void wdc_init_sdcard()
|
||||
#include "mmc.h"
|
||||
extern uint8_t par_table[200];
|
||||
|
||||
uint8_t wdc_init_sdcard()
|
||||
{
|
||||
asm("nop");
|
||||
return mmc_init();
|
||||
}
|
||||
|
||||
uint32_t wdc_get_blockno ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector )
|
||||
{
|
||||
/* TODO: no direct access of par_table - use getter functions instead - but only after speed is sufficient */
|
||||
/* +-------------------------------------------------------------- requested cylinder from P8000
|
||||
* | +----------------------------------------------- configured heads form the harddisk
|
||||
* | | +------------------------------- configured sectors for the harddisk
|
||||
* | | | +-------------- requested head from P8000
|
||||
* | | | | +-- configured sectors for the harddisk
|
||||
* | | | | | +---- requested sector from P8000 - 1 as we start counting with 0
|
||||
* | | | | | | */
|
||||
return ( ( req_cylinder * par_table[25] * par_table[26] ) + ( req_head * par_table[26] ) + ( req_sector - 1 ) );
|
||||
}
|
||||
|
||||
uint8_t wdc_write_sector ( uint16_t addr, uint8_t *sector )
|
||||
{
|
||||
return mmc_write_sector ( addr, sector );
|
||||
}
|
||||
|
||||
uint8_t wdc_read_sector ( uint16_t addr, uint8_t *sector )
|
||||
{
|
||||
return mmc_read_sector ( addr, sector );
|
||||
}
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_if_disk.h,v 1.1 2012/05/31 20:21:51 olivleh1 Exp $
|
||||
* $Id: wdc_if_disk.h,v 1.2 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WDC_IF_SDCARD_H_
|
||||
#define WDC_IF_SDCARD_H_
|
||||
|
||||
void wdc_init_sdcard();
|
||||
uint8_t wdc_init_sdcard();
|
||||
uint32_t wdc_get_blockno ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector );
|
||||
uint8_t wdc_write_sector ( uint16_t addr, uint8_t *sector );
|
||||
uint8_t wdc_read_sector ( uint16_t addr, uint8_t *sector );
|
||||
|
||||
#endif /* WDC_IF_SDCARD_H_ */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_if_p8000.h,v 1.1 2012/05/31 20:21:51 olivleh1 Exp $
|
||||
* $Id: wdc_if_p8000.h,v 1.2 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -45,9 +45,9 @@
|
|||
|
||||
void wdc_init_ports();
|
||||
void wdc_wait_for_reset();
|
||||
void wdc_receive_cmd(uint8_t *buffer, uint16_t count);
|
||||
void wdc_receive_data(uint8_t *buffer, uint16_t count);
|
||||
void wdc_send_data(uint8_t *buffer, uint16_t count);
|
||||
void wdc_receive_cmd ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_receive_data ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_send_data ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_send_error();
|
||||
|
||||
#endif /* WDC_IF_PIO_H_ */
|
||||
|
|
@ -1,8 +1,13 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_main.c,v 1.5 2012/05/31 20:21:51 olivleh1 Exp $
|
||||
* $Id: wdc_main.c,v 1.6 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
* TODO: - Prio 1: more commandcodes
|
||||
* - Prio 2: check if BTT is really cleaned when sa.format gets called all the time with a real drive
|
||||
* - Prio 2: respect BTT entries when calculating the block number to use.
|
||||
* - Prio 3: work out how PAR+BTT where originally stored on the harddisks and store them the same way
|
||||
* - Prio 3: put the whole par_table handling from wdc_ram.[ch] into wdc_par.[ch]
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
|
@ -15,7 +20,6 @@
|
|||
#include "wdc_if_pio.h"
|
||||
#include "wdc_if_sdcard.h"
|
||||
|
||||
|
||||
#define DEBUG 1
|
||||
void atmega_setup ( void );
|
||||
|
||||
|
|
@ -23,13 +27,33 @@ int main ( void )
|
|||
{
|
||||
uint16_t cmd_counter = 9;
|
||||
uint16_t data_counter;
|
||||
uint32_t blockno;
|
||||
uint8_t errorcode;
|
||||
uint8_t *data_buffer = NULL;
|
||||
uint8_t *cmd_buffer = NULL;
|
||||
uint8_t i8;
|
||||
uint16_t i16;
|
||||
|
||||
atmega_setup();
|
||||
|
||||
uart_puts_p ( PSTR ( "P8000 WDC Emulator 0.01\n" ) );
|
||||
|
||||
/* load Parameter Table into RAM if valid */
|
||||
blockno = 0;
|
||||
data_counter = 512;
|
||||
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
|
||||
while ( wdc_read_sector ( blockno, data_buffer ) ) {
|
||||
#if DEBUG >= 1
|
||||
uart_puts_p ( PSTR ( "Block 0 of SD-Card not readable" ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( data_buffer[0] == 'W' &&
|
||||
data_buffer[1] == 'D' &&
|
||||
data_buffer[2] == 'C' ) {
|
||||
wdc_write_par_table ( data_buffer, data_counter );
|
||||
};
|
||||
|
||||
while ( 1 ) {
|
||||
|
||||
wdc_wait_for_reset();
|
||||
|
|
@ -40,9 +64,8 @@ int main ( void )
|
|||
, cmd_counter
|
||||
);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
uart_puts_p ( PSTR ( " CMD Buffer:" ) );
|
||||
#if DEBUG == 2
|
||||
uart_puts_p ( PSTR ( " CMD:" ) );
|
||||
uart_putc_hex ( cmd_buffer[0] );
|
||||
uart_putc_hex ( cmd_buffer[1] );
|
||||
uart_putc_hex ( cmd_buffer[2] );
|
||||
|
|
@ -95,8 +118,8 @@ int main ( void )
|
|||
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
|
||||
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
|
||||
|
||||
wdc_read_partab ( data_buffer
|
||||
, data_counter );
|
||||
wdc_read_par_table ( data_buffer
|
||||
, data_counter );
|
||||
|
||||
wdc_send_data ( data_buffer
|
||||
, data_counter
|
||||
|
|
@ -114,15 +137,15 @@ int main ( void )
|
|||
, data_counter
|
||||
);
|
||||
|
||||
wdc_write_partab ( data_buffer
|
||||
, data_counter );
|
||||
wdc_write_wdc_par ( data_buffer
|
||||
, data_counter );
|
||||
|
||||
free ( data_buffer );
|
||||
break;
|
||||
|
||||
case CMD_DL_BTTAB:
|
||||
|
||||
wdc_del_bttab();
|
||||
wdc_del_wdc_btt();
|
||||
break;
|
||||
|
||||
case CMD_RD_BTTAB:
|
||||
|
|
@ -130,8 +153,8 @@ int main ( void )
|
|||
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
|
||||
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
|
||||
|
||||
wdc_read_bttab ( data_buffer
|
||||
, data_counter );
|
||||
wdc_read_wdc_btt ( data_buffer
|
||||
, data_counter );
|
||||
|
||||
wdc_send_data ( data_buffer
|
||||
, data_counter
|
||||
|
|
@ -149,18 +172,140 @@ int main ( void )
|
|||
, data_counter
|
||||
);
|
||||
|
||||
wdc_write_bttab ( data_buffer
|
||||
, data_counter );
|
||||
wdc_write_wdc_btt ( data_buffer
|
||||
, data_counter );
|
||||
|
||||
free ( data_buffer );
|
||||
break;
|
||||
default:
|
||||
case CMD_FMT_BTT:
|
||||
|
||||
data_counter = 512;
|
||||
data_buffer = calloc ( data_counter, sizeof ( *data_buffer ) );
|
||||
|
||||
blockno = wdc_get_blockno ( 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 {
|
||||
free ( data_buffer );
|
||||
data_buffer = malloc ( 3 * sizeof ( *data_buffer ) );
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
free ( data_buffer );
|
||||
break;
|
||||
|
||||
case CMD_ST_PARBTT:
|
||||
|
||||
blockno = 0;
|
||||
|
||||
data_counter = 512;
|
||||
data_buffer = malloc ( data_counter * sizeof ( *data_buffer ) );
|
||||
wdc_read_par_table ( data_buffer
|
||||
, data_counter );
|
||||
|
||||
errorcode = wdc_write_sector ( blockno, data_buffer );
|
||||
if ( errorcode )
|
||||
wdc_send_error();
|
||||
|
||||
free ( data_buffer );
|
||||
break;
|
||||
|
||||
case CMD_RD_WDCERR:
|
||||
|
||||
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
|
||||
data_buffer = calloc ( data_counter, sizeof ( *data_buffer ) );
|
||||
wdc_send_data ( data_buffer
|
||||
, data_counter
|
||||
);
|
||||
|
||||
free ( data_buffer );
|
||||
break;
|
||||
|
||||
case CMD_VER_TRACK:
|
||||
|
||||
data_counter = 512;
|
||||
data_buffer = calloc ( data_counter, sizeof ( *data_buffer ) );
|
||||
|
||||
blockno = wdc_get_blockno ( 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();
|
||||
|
||||
free ( data_buffer );
|
||||
break;
|
||||
|
||||
case CMD_RD_SECTOR:
|
||||
|
||||
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_get_blockno ( cmd_buffer[2] | ( cmd_buffer[3] << 8 )
|
||||
, cmd_buffer[4]
|
||||
, cmd_buffer[5]
|
||||
);
|
||||
|
||||
errorcode = 1;
|
||||
for ( i16 = 0; i16 < data_counter; i16 += 512 ) {
|
||||
errorcode = wdc_read_sector ( blockno, data_buffer );
|
||||
if ( errorcode ) break;
|
||||
}
|
||||
|
||||
if ( errorcode )
|
||||
wdc_send_error();
|
||||
|
||||
free ( data_buffer );
|
||||
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' );
|
||||
#endif
|
||||
wdc_send_error();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
free ( cmd_buffer );
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -169,7 +314,12 @@ int main ( void )
|
|||
void atmega_setup ( void )
|
||||
{
|
||||
set_sleep_mode ( SLEEP_MODE_IDLE );
|
||||
wdc_init_ports();
|
||||
wdc_init_sdcard();
|
||||
uart_init();
|
||||
wdc_init_ports();
|
||||
while ( wdc_init_sdcard() ) {
|
||||
#if DEBUG >= 1
|
||||
uart_puts_p ( PSTR ( "SDCard initialisation failed!" ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_main.h,v 1.5 2012/05/31 20:21:51 olivleh1 Exp $
|
||||
* $Id: wdc_main.h,v 1.6 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -9,12 +9,17 @@
|
|||
#ifndef MAIN_H_
|
||||
#define MAIN_H_
|
||||
|
||||
#define CMD_WR_WDC_RAM 0x18 /* P8000 Command: write data to WDC RAM */
|
||||
#define CMD_RD_WDC_RAM 0x08 /* P8000 Command: read data from WDC RAM */
|
||||
#define CMD_RD_PARTAB 0x28 /* P8000 Command: read Parameter block from WDC RAM */
|
||||
#define CMD_WR_PARTAB 0x78 /* P8000 Command: write Parameter block to WDC RAM */
|
||||
#define CMD_DL_BTTAB 0x48 /* P8000 Command: delete Bad Track Table from WDC RAM */
|
||||
#define CMD_RD_BTTAB 0x58 /* P8000 Command: read Bad Track Table from WDC RAM */
|
||||
#define CMD_WR_BTTAB 0x68 /* P8000 Command: write Bad Track Table to WDC RAM */
|
||||
#define CMD_WR_WDC_RAM 0x18 /* write data to WDC RAM */
|
||||
#define CMD_RD_WDC_RAM 0x08 /* read data from WDC RAM */
|
||||
#define CMD_RD_PARTAB 0x28 /* read Parameter block from WDC RAM */
|
||||
#define CMD_WR_PARTAB 0x78 /* write Parameter block to WDC RAM */
|
||||
#define CMD_DL_BTTAB 0x48 /* delete Bad Track Table from WDC RAM */
|
||||
#define CMD_RD_BTTAB 0x58 /* read Bad Track Table from WDC RAM */
|
||||
#define CMD_WR_BTTAB 0x68 /* write Bad Track Table to WDC RAM */
|
||||
#define CMD_FMT_BTT 0x24 /* format a track and provide BTT info */
|
||||
#define CMD_ST_PARBTT 0xC2 /* store PAR and BTT on harddisk */
|
||||
#define CMD_RD_WDCERR 0x38 /* read error statistics */
|
||||
#define CMD_VER_TRACK 0x44 /* verify track */
|
||||
#define CMD_RD_SECTOR 0x01 /* read data beginning at given sector */
|
||||
|
||||
#endif /* MAIN_H_ */
|
||||
|
|
|
|||
|
|
@ -1,20 +1,19 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_ram.c,v 1.2 2012/05/31 20:34:11 olivleh1 Exp $
|
||||
* $Id: wdc_ram.c,v 1.3 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "wdc_ram.h"
|
||||
|
||||
uint8_t par_table[200] = { '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, 0x00, 0x68, 0x01, 0x00, 0x01, 0x01,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
uint8_t bt_table[125];
|
||||
uint8_t wdc_ram[2048];
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
void wdc_write_data_to_ram ( uint8_t *buffer, uint16_t address, uint16_t count )
|
||||
{
|
||||
|
|
@ -32,7 +31,8 @@ void wdc_read_data_from_ram ( uint8_t *buffer, uint16_t address, uint16_t count
|
|||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
void wdc_read_partab ( uint8_t *buffer, uint16_t count )
|
||||
|
||||
void wdc_read_par_table ( uint8_t *buffer, uint16_t count )
|
||||
{
|
||||
do {
|
||||
count--;
|
||||
|
|
@ -40,33 +40,87 @@ void wdc_read_partab ( uint8_t *buffer, uint16_t count )
|
|||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
void wdc_write_partab ( uint8_t *buffer, uint16_t count )
|
||||
void wdc_write_par_table ( uint8_t *buffer, uint16_t count )
|
||||
{
|
||||
do {
|
||||
count--;
|
||||
par_table[count + 8] = buffer[count];
|
||||
par_table[count] = buffer[count];
|
||||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
void wdc_del_bttab()
|
||||
|
||||
void wdc_read_wdc_par ( uint8_t *buffer, uint16_t count )
|
||||
{
|
||||
do {
|
||||
count--;
|
||||
buffer[count] = par_table[count + POS_PAR_WDC_PAR];
|
||||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
void wdc_write_wdc_par ( uint8_t *buffer, uint16_t count )
|
||||
{
|
||||
do {
|
||||
count--;
|
||||
par_table[count + POS_PAR_WDC_PAR] = buffer[count];
|
||||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
void wdc_del_wdc_btt()
|
||||
{
|
||||
uint8_t i;
|
||||
for ( i = 0; i < 125; i++ )
|
||||
bt_table[i] = 0x00;
|
||||
par_table[i + POS_PAR_WDC_BTT] = 0x00;
|
||||
par_table[122 + POS_PAR_WDC_BTT] = 0xff;
|
||||
}
|
||||
|
||||
void wdc_read_bttab ( uint8_t *buffer, uint16_t count )
|
||||
void wdc_read_wdc_btt ( uint8_t *buffer, uint16_t count )
|
||||
{
|
||||
do {
|
||||
count--;
|
||||
buffer[count] = bt_table[count];
|
||||
buffer[count] = par_table[count + POS_PAR_WDC_BTT];
|
||||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
void wdc_write_bttab ( uint8_t *buffer, uint16_t count )
|
||||
void wdc_write_wdc_btt ( uint8_t *buffer, uint16_t count )
|
||||
{
|
||||
do {
|
||||
count--;
|
||||
bt_table[count] = buffer[count];
|
||||
par_table[count + POS_PAR_WDC_BTT] = buffer[count];
|
||||
} while ( count > 0 );
|
||||
}
|
||||
|
||||
uint16_t wdc_get_btt_count()
|
||||
{
|
||||
return ( ( par_table[0 + POS_PAR_WDC_BTT] | ( par_table[1 + POS_PAR_WDC_BTT] << 8 ) ) );
|
||||
}
|
||||
|
||||
void wdc_set_btt_count ( uint16_t btt_count )
|
||||
{
|
||||
par_table[0 + POS_PAR_WDC_BTT] = ( uint8_t ) btt_count;
|
||||
par_table[1 + POS_PAR_WDC_BTT] = ( btt_count >> 8 );
|
||||
}
|
||||
|
||||
uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head )
|
||||
{
|
||||
uint16_t btt_count = wdc_get_btt_count();
|
||||
|
||||
if ( btt_count < 120 ) {
|
||||
/* +2 because btt_count is just the amount of bytes for the BTT - but in front of it, there are two bytes */
|
||||
/* storing the amount of bytes for the BTT */
|
||||
par_table[btt_count + 2 + POS_PAR_WDC_BTT] = ( cylinder >> 8 );
|
||||
btt_count++;
|
||||
par_table[btt_count + 2 + POS_PAR_WDC_BTT] = ( uint8_t ) cylinder;
|
||||
btt_count++;
|
||||
par_table[btt_count + 2 + POS_PAR_WDC_BTT] = ( uint8_t ) head;
|
||||
btt_count++;
|
||||
wdc_set_btt_count ( btt_count );
|
||||
return ( 0 );
|
||||
} else {
|
||||
return ( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t wdc_get_hdd_sectors()
|
||||
{
|
||||
return ( par_table[18 + POS_PAR_WDC_PAR] );
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* P8000 WDC Emulator
|
||||
*
|
||||
* $Id: wdc_ram.h,v 1.1 2012/05/31 20:21:51 olivleh1 Exp $
|
||||
* $Id: wdc_ram.h,v 1.2 2012/06/02 00:51:55 olivleh1 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -11,13 +11,28 @@
|
|||
void wdc_write_data_to_ram ( uint8_t *buffer, uint16_t address, uint16_t count );
|
||||
void wdc_read_data_from_ram ( uint8_t *buffer, uint16_t address, uint16_t count );
|
||||
|
||||
void wdc_read_partab ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_write_partab ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_read_par_table ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_write_par_table ( uint8_t *buffer, uint16_t count );
|
||||
|
||||
void wdc_del_bttab();
|
||||
void wdc_read_bttab ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_write_bttab ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_read_wdc_par ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_write_wdc_par ( uint8_t *buffer, uint16_t count );
|
||||
|
||||
void wdc_del_wdc_btt();
|
||||
void wdc_read_wdc_btt ( uint8_t *buffer, uint16_t count );
|
||||
void wdc_write_wdc_btt ( uint8_t *buffer, uint16_t count );
|
||||
uint16_t wdc_get_btt_count();
|
||||
uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head );
|
||||
|
||||
uint8_t wdc_get_hdd_sectors();
|
||||
|
||||
#define convert_ram_address(x) ((x) - 0x2000) /* The S-RAM of the original WDC hardware starts at 0x2000. We use an array as RAM here and no direct RAM access */
|
||||
|
||||
#define POS_PAR_VERSION 0
|
||||
#define POS_PAR_WDC_PAR 8
|
||||
#define POS_PAR_WDC_BTT 88
|
||||
|
||||
#define SIZE_PAR_VERSION 8
|
||||
#define SIZE_PAR_WDC_PAR 80
|
||||
#define SIZE_PAR_WDC_BTT 125
|
||||
|
||||
#endif /* WDC_RAM_H_ */
|
||||
Loading…
Reference in New Issue