getting closer to a final version

This commit is contained in:
Oliver Lehmann 2012-06-09 19:47:31 +00:00
parent 33783a4bb2
commit 406774a382
11 changed files with 374 additions and 312 deletions

View File

@ -14,6 +14,7 @@ RM := rm -rf
OBJS += \ OBJS += \
main.o \ main.o \
mmc.o \ mmc.o \
mmc_perf.o \
uart.o \ uart.o \
wdc_if_pio.o \ wdc_if_pio.o \
wdc_if_sdcard.o \ wdc_if_sdcard.o \

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_config.h,v 1.11 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_config.h,v 1.12 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
@ -81,4 +81,6 @@
#define MEASURE_SDCARD_TIME 1 #define MEASURE_SDCARD_TIME 1
#undef MEASURE_SDCARD_TIME #undef MEASURE_SDCARD_TIME
#define DEBUG 0
#endif /* CONFIG_H_ */ #endif /* CONFIG_H_ */

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_drv_mmc.c,v 1.15 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_drv_mmc.c,v 1.16 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#include <avr/io.h> #include <avr/io.h>
@ -39,8 +39,8 @@
#define send_dummy_byte() SPDR = 0xFF; wait_till_send_done() #define send_dummy_byte() SPDR = 0xFF; wait_till_send_done()
#define recv_byte() SPDR #define recv_byte() SPDR
#define xmit_byte(x) SPDR = x #define xmit_byte(x) SPDR = x
#define MMC_Disable() PORT_MMC|= (1<<PIN_MMC_CS); #define mmc_disable() PORT_MMC|= (1<<PIN_MMC_CS);
#define MMC_Enable() PORT_MMC=~(1<<PIN_MMC_CS); #define mmc_enable() PORT_MMC=~(1<<PIN_MMC_CS);
#define nop() __asm__ __volatile__ ("nop" ::) #define nop() __asm__ __volatile__ ("nop" ::)
#define CMD0 (0x40 + 0) #define CMD0 (0x40 + 0)
@ -195,13 +195,13 @@ uint8_t mmc_init ()
SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 ) | ( 1 << SPR1 ); /* Enable SPI, SPI in Master Mode */ SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 ) | ( 1 << SPR1 ); /* Enable SPI, SPI in Master Mode */
SPSR = ( 0 << SPI2X ); SPSR = ( 0 << SPI2X );
MMC_Disable(); mmc_disable();
for ( a = 0; a < 0x0f; a++ ) { for ( a = 0; a < 0x0f; a++ ) {
send_dummy_byte(); send_dummy_byte();
} }
MMC_Enable(); mmc_enable();
/* /*
* send CMD0 * send CMD0
@ -209,7 +209,7 @@ uint8_t mmc_init ()
uint8_t cmd[] = {CMD0, 0x00, 0x00, 0x00, 0x00, 0x95}; uint8_t cmd[] = {CMD0, 0x00, 0x00, 0x00, 0x00, 0x95};
while ( mmc_cmd ( cmd ) != 1 ) { while ( mmc_cmd ( cmd ) != 1 ) {
if ( t16++ > 1000 ) { if ( t16++ > 1000 ) {
MMC_Disable(); mmc_disable();
return ( 1 ); return ( 1 );
} }
} }
@ -254,7 +254,7 @@ uint8_t mmc_init ()
while ( mmc_cmd ( cmd ) != 0 ) { while ( mmc_cmd ( cmd ) != 0 ) {
send_dummy_byte(); send_dummy_byte();
if ( t16++ > 1000 ) { if ( t16++ > 1000 ) {
MMC_Disable(); mmc_disable();
return ( 2 ); return ( 2 );
} }
} }
@ -269,7 +269,7 @@ uint8_t mmc_init ()
mmc_enable_crc ( 1 ); mmc_enable_crc ( 1 );
#endif #endif
MMC_Disable(); mmc_disable();
return ( 0 ); return ( 0 );
} }
@ -310,7 +310,7 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer )
uint8_t crcl, crch; uint8_t crcl, crch;
#endif #endif
MMC_Enable(); mmc_enable();
wait_till_card_ready(); wait_till_card_ready();
/* convert blocks to bytes */ /* convert blocks to bytes */
@ -327,7 +327,7 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer )
*/ */
tmp = mmc_cmd ( cmd ); tmp = mmc_cmd ( cmd );
if ( tmp != 0 ) { if ( tmp != 0 ) {
MMC_Disable(); mmc_disable();
return ( tmp ); return ( tmp );
} }
@ -363,11 +363,11 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer )
/* check for errors */ /* check for errors */
send_dummy_byte(); send_dummy_byte();
if ( ( recv_byte() & 0x1F ) != 0x05 ) { if ( ( recv_byte() & 0x1F ) != 0x05 ) {
MMC_Disable(); mmc_disable();
return ( 2 ); return ( 2 );
} }
MMC_Disable(); mmc_disable();
return ( 0 ); return ( 0 );
} }
@ -380,12 +380,12 @@ uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes )
uint16_t crc; uint16_t crc;
#endif #endif
MMC_Enable(); mmc_enable();
wait_till_card_ready(); wait_till_card_ready();
/* send command */ /* send command */
if ( mmc_cmd ( cmd ) != 0 ) { if ( mmc_cmd ( cmd ) != 0 ) {
MMC_Disable(); mmc_disable();
return ( 1 ); return ( 1 );
} }
@ -421,14 +421,14 @@ uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes )
wait_till_send_done(); wait_till_send_done();
crc |= recv_byte(); crc |= recv_byte();
if ( crc != crc16 ( buffer, bytes ) ) { if ( crc != crc16 ( buffer, bytes ) ) {
MMC_Disable(); mmc_disable();
return ( 3 ); return ( 3 );
} }
#else #else
send_dummy_byte(); send_dummy_byte();
#endif #endif
MMC_Disable(); mmc_disable();
return ( 0 ); return ( 0 );
} }
@ -465,7 +465,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
uint16_t crc; uint16_t crc;
#endif #endif
MMC_Enable(); mmc_enable();
#ifdef MMC_MULTIBLOCK #ifdef MMC_MULTIBLOCK
#ifdef MMC_PRESET_MULTIBLOCKCOUNT #ifdef MMC_PRESET_MULTIBLOCKCOUNT
@ -507,7 +507,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
*/ */
resp = mmc_cmd ( cmd ); resp = mmc_cmd ( cmd );
if ( resp > 1 ) { if ( resp > 1 ) {
MMC_Disable(); mmc_disable();
return ( 1 ); return ( 1 );
} }
#else #else
@ -528,7 +528,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
*/ */
resp = mmc_cmd ( cmd ); resp = mmc_cmd ( cmd );
if ( resp > 1 ) { if ( resp > 1 ) {
MMC_Disable(); mmc_disable();
return ( 1 ); return ( 1 );
} }
x.value32 += MMC_BLOCKLEN; x.value32 += MMC_BLOCKLEN;
@ -561,7 +561,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
send_dummy_byte(); send_dummy_byte();
crc |= recv_byte(); crc |= recv_byte();
if ( crc != crc16 ( buffer, MMC_BLOCKLEN ) ) { if ( crc != crc16 ( buffer, MMC_BLOCKLEN ) ) {
MMC_Disable(); mmc_disable();
return ( 3 ); return ( 3 );
} }
buffer = buffer + MMC_BLOCKLEN; buffer = buffer + MMC_BLOCKLEN;
@ -585,7 +585,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
/* TODO: Apacer Card I have sends 0x7f after some reads - No idea why - CRC was correct /* TODO: Apacer Card I have sends 0x7f after some reads - No idea why - CRC was correct
if ( resp > 1 ) { if ( resp > 1 ) {
MMC_Disable(); mmc_disable();
return ( 2 ); return ( 2 );
} }
*/ */
@ -593,7 +593,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
send_dummy_byte(); send_dummy_byte();
#endif #endif
MMC_Disable() mmc_disable()
return ( 0 ); return ( 0 );
} }
@ -610,7 +610,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
uint8_t crcl, crch; uint8_t crcl, crch;
#endif #endif
MMC_Enable(); mmc_enable();
wait_till_card_ready(); wait_till_card_ready();
#ifdef MMC_MULTIBLOCK #ifdef MMC_MULTIBLOCK
#ifdef MMC_PRESET_MULTIBLOCKCOUNT #ifdef MMC_PRESET_MULTIBLOCKCOUNT
@ -648,7 +648,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
*/ */
resp = mmc_cmd ( cmd ); resp = mmc_cmd ( cmd );
if ( resp > 1 ) { if ( resp > 1 ) {
MMC_Disable(); mmc_disable();
return ( 1 ); return ( 1 );
} }
#else #else
@ -668,7 +668,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
*/ */
resp = mmc_cmd ( cmd ); resp = mmc_cmd ( cmd );
if ( resp != 0 ) { if ( resp != 0 ) {
MMC_Disable(); mmc_disable();
return ( resp ); return ( resp );
} }
x.value32 += MMC_BLOCKLEN; x.value32 += MMC_BLOCKLEN;
@ -718,7 +718,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
send_dummy_byte(); send_dummy_byte();
if ( ( recv_byte() & 0x1F ) != 0x05 ) { if ( ( recv_byte() & 0x1F ) != 0x05 ) {
MMC_Disable(); mmc_disable();
return ( 2 ); return ( 2 );
} }
@ -738,7 +738,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
/* Pad 8 */ /* Pad 8 */
send_dummy_byte(); send_dummy_byte();
#endif #endif
MMC_Disable(); mmc_disable();
return ( 0 ); return ( 0 );
} }

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_if_disk.c,v 1.10 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_if_disk.c,v 1.11 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#include <stdint.h> #include <stdint.h>
@ -36,14 +36,7 @@
uint8_t wdc_init_sdcard() uint8_t wdc_init_sdcard()
{ {
uint8_t errorcode; return mmc_init();
errorcode=mmc_init();
if ( errorcode ) {
uart_putc_hex ( errorcode );
uart_putc ( '\n' );
}
return errorcode;
} }
uint32_t wdc_sector2sdblock ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector ) uint32_t wdc_sector2sdblock ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector )

View File

@ -1,8 +1,32 @@
/* /*-
* mmc_perf.c * Copyright (c) 2012 Oliver Lehmann
* All rights reserved.
* *
* Created: 07.06.2012 21:42:41 * Redistribution and use in source and binary forms, with or without
* Author: olivleh1 * modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* $Id: wdc_if_disk_perf.c,v 1.4 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#include <avr/io.h> #include <avr/io.h>

View File

@ -26,13 +26,15 @@
*/ */
/* /*
* $Id: wdc_if_p8000.c,v 1.5 2012/06/07 18:01:02 olivleh1 Exp $ * $Id: wdc_if_p8000.c,v 1.6 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#include "config.h" #include "config.h"
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <util/delay.h> #include <util/delay.h>
#include "wdc_if_pio.h" #include "wdc_if_pio.h"
#include "wdc_par.h"
#include "uart.h"
#define nop() __asm__ __volatile__ ("nop" ::) #define nop() __asm__ __volatile__ ("nop" ::)
@ -55,11 +57,12 @@ void wdc_wait_for_reset()
while ( !isset_info_reset() ) { while ( !isset_info_reset() ) {
port_data_set ( DATA_CLEAR ); port_data_set ( DATA_CLEAR );
port_info_set ( INFO_CLEAR ); port_info_set ( INFO_CLEAR );
wdc_set_initialized ( 1 );
} }
} }
void wdc_read_data_from_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_status ) uint8_t wdc_read_data_from_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_status )
{ {
uint16_t datacnt; uint16_t datacnt;
@ -68,7 +71,9 @@ void wdc_read_data_from_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_statu
configure_port_data_read(); configure_port_data_read();
datacnt = 0; datacnt = 0;
port_info_set ( wdc_status ); port_info_set ( wdc_status );
while ( !isset_info_te() ); while ( !isset_info_te() )
if ( !isset_info_reset() )
return 0;
while ( !isset_info_wdardy() ); while ( !isset_info_wdardy() );
do { do {
while ( isset_info_wdardy() ); while ( isset_info_wdardy() );
@ -80,6 +85,7 @@ void wdc_read_data_from_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_statu
} while ( datacnt < count ); } while ( datacnt < count );
port_info_set ( INFO_CLEAR ); port_info_set ( INFO_CLEAR );
return 1;
} }
void wdc_write_data_to_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_status ) void wdc_write_data_to_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_status )
@ -104,7 +110,6 @@ void wdc_write_data_to_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_status
while ( isset_info_wdardy() ); while ( isset_info_wdardy() );
port_info_set ( INFO_TR | INFO_ASTB | wdc_status ); port_info_set ( INFO_TR | INFO_ASTB | wdc_status );
nop(); nop();
nop();
port_info_set ( INFO_TR | wdc_status ); port_info_set ( INFO_TR | wdc_status );
configure_port_data_read(); configure_port_data_read();
while ( !isset_info_wdardy() ); while ( !isset_info_wdardy() );
@ -112,12 +117,12 @@ void wdc_write_data_to_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_status
} }
void wdc_receive_cmd ( uint8_t *buffer, uint16_t count ) uint8_t wdc_receive_cmd ( uint8_t *buffer, uint16_t count )
{ {
wdc_read_data_from_p8k ( buffer return wdc_read_data_from_p8k ( buffer
, count , count
, INFO_STAT_GCMD , INFO_STAT_GCMD
); );
} }
void wdc_receive_data ( uint8_t *buffer, uint16_t count ) void wdc_receive_data ( uint8_t *buffer, uint16_t count )
@ -137,10 +142,15 @@ void wdc_send_data ( uint8_t *buffer, uint16_t count )
} }
void wdc_send_error() void wdc_send_error()
{
wdc_send_errorcode ( 0x01 );
}
void wdc_send_errorcode ( uint8_t error )
{ {
uint8_t buffer[1]; uint8_t buffer[1];
buffer[0] = 0x01; buffer[0] = error;
wdc_write_data_to_p8k ( buffer wdc_write_data_to_p8k ( buffer
, 1 , 1

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_if_p8000.h,v 1.7 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_if_p8000.h,v 1.8 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#ifndef WDC_IF_PIO_H_ #ifndef WDC_IF_PIO_H_
@ -69,9 +69,10 @@
extern void wdc_init_ports(); extern void wdc_init_ports();
extern void wdc_wait_for_reset(); extern void wdc_wait_for_reset();
extern void wdc_receive_cmd ( uint8_t *buffer, uint16_t count ); extern uint8_t wdc_receive_cmd ( uint8_t *buffer, uint16_t count );
extern void wdc_receive_data ( uint8_t *buffer, uint16_t count ); extern void wdc_receive_data ( uint8_t *buffer, uint16_t count );
extern void wdc_send_data ( uint8_t *buffer, uint16_t count ); extern void wdc_send_data ( uint8_t *buffer, uint16_t count );
extern void wdc_send_error(); extern void wdc_send_error();
extern void wdc_send_errorcode ( uint8_t error );
#endif /* WDC_IF_PIO_H_ */ #endif /* WDC_IF_PIO_H_ */

View File

@ -29,20 +29,11 @@
/* /*
* P8000 WDC Emulator * P8000 WDC Emulator
* *
* $Id: wdc_main.c,v 1.23 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_main.c,v 1.24 2012/06/09 19:47:31 olivleh1 Exp $
* *
* TODO: - Different Errorcodes in the MMC layer (use defines) * TODO: - right now, BTT entries are not taken into account
* - errorchecking in several places
* - 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
* - 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]
*/ */
#define DEBUG 1
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
@ -50,6 +41,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/sleep.h> #include <avr/sleep.h>
#include "config.h"
#include "main.h" #include "main.h"
#ifdef DEBUG #ifdef DEBUG
#include "uart.h" #include "uart.h"
@ -58,7 +50,7 @@
#include "wdc_par.h" #include "wdc_par.h"
#include "wdc_if_pio.h" #include "wdc_if_pio.h"
#include "wdc_if_sdcard.h" #include "wdc_if_sdcard.h"
#include "config.h"
void atmega_setup ( void ); void atmega_setup ( void );
@ -91,7 +83,7 @@ main ( void )
#endif #endif
atmega_setup(); atmega_setup();
uart_puts_p ( PSTR ( "P8000 WDC Emulator 0.01\n" ) ); uart_puts_p ( PSTR ( "P8000 WDC Emulator 0.90\n" ) );
#ifdef MEASURE_SDCARD_TIME #ifdef MEASURE_SDCARD_TIME
measure_performance(); measure_performance();
@ -121,278 +113,299 @@ main ( void )
wdc_wait_for_reset(); wdc_wait_for_reset();
wdc_receive_cmd ( cmd_buffer if ( wdc_receive_cmd ( cmd_buffer
, cmd_counter , cmd_counter
); ) ) {
#if DEBUG >= 2 #if DEBUG >= 2
#if DEBUG >= 3 #if DEBUG >= 3
uart_puts_p ( PSTR ( " CMD:" ) ); uart_puts_p ( PSTR ( " CMD:" ) );
#endif #endif
uart_putc_hex ( cmd_buffer[0] ); uart_putc_hex ( cmd_buffer[0] );
#if DEBUG >= 3 #if DEBUG >= 3
uart_putc_hex ( cmd_buffer[1] ); uart_putc_hex ( cmd_buffer[1] );
uart_putc_hex ( cmd_buffer[2] ); uart_putc_hex ( cmd_buffer[2] );
uart_putc_hex ( cmd_buffer[3] ); uart_putc_hex ( cmd_buffer[3] );
uart_putc_hex ( cmd_buffer[4] ); uart_putc_hex ( cmd_buffer[4] );
uart_putc_hex ( cmd_buffer[5] ); uart_putc_hex ( cmd_buffer[5] );
uart_putc_hex ( cmd_buffer[6] ); uart_putc_hex ( cmd_buffer[6] );
uart_putc_hex ( cmd_buffer[7] ); uart_putc_hex ( cmd_buffer[7] );
uart_putc_hex ( cmd_buffer[8] ); uart_putc_hex ( cmd_buffer[8] );
uart_putc ( '\n' ); uart_putc ( '\n' );
#endif #endif
#endif #endif
/* if the disk is not valid, only maintenance commands are allowed */ /* no drive attached */
if ( ! wdc_get_disk_valid() if ( wdc_get_initialized() && wdc_get_num_of_drvs() == 0 ) {
&& cmd_buffer[0] != CMD_RD_WDC_RAM if ( cmd_buffer[0] == CMD_WR_WDC_RAM
&& cmd_buffer[0] != CMD_FMTRD_TRACK || cmd_buffer[0] == CMD_RD_BLOCK ) {
&& cmd_buffer[0] != CMD_WR_WDC_RAM wdc_send_errorcode ( 0xc1 );
&& cmd_buffer[0] != CMD_FMTBTT_TRACK } else if ( cmd_buffer[0] == CMD_RD_WDC_RAM ) {
&& cmd_buffer[0] != CMD_RD_PARTAB wdc_send_errorcode ( ERR_NO_DRIVE_READY );
&& cmd_buffer[0] != CMD_RD_WDCERR wdc_set_initialized ( 0 );
&& cmd_buffer[0] != CMD_VER_TRACK }
&& cmd_buffer[0] != CMD_DL_BTTAB /* WDC freshly initialized after RESET, the disk is not valid */
&& cmd_buffer[0] != CMD_RD_BTTAB } else if ( wdc_get_initialized()
&& cmd_buffer[0] != CMD_WR_BTTAB && ! wdc_get_disk_valid()
&& cmd_buffer[0] != CMD_WR_PARTAB && ( cmd_buffer[0] == CMD_WR_WDC_RAM || cmd_buffer[0] == CMD_RD_BLOCK ) ) {
&& cmd_buffer[0] != CMD_ST_PARBTT wdc_send_errorcode ( ERR_CYL0_NOT_READABLE );
) { wdc_set_initialized ( 0 );
wdc_send_error(); /* if the disk is not valid, only maintenance commands are allowed */
} else { } else 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
) {
if ( cmd_buffer[0] == CMD_RD_BLOCK )
wdc_send_errorcode ( ERR_SECT_N_ON_SURFACE );
else
wdc_send_error();
} else {
switch ( cmd_buffer[0] ) { switch ( cmd_buffer[0] ) {
case CMD_WR_BLOCK: case CMD_WR_BLOCK:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] ); 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 wdc_receive_data ( data_buffer
, data_counter , data_counter
); );
errorcode = 1; errorcode = 1;
if ( data_counter == WDC_BLOCKLEN ) { if ( data_counter == WDC_BLOCKLEN ) {
errorcode = wdc_write_sector ( blockno, data_buffer ); errorcode = wdc_write_sector ( blockno, data_buffer );
} else { } else {
errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN );
} }
if ( errorcode ) if ( errorcode )
wdc_send_error(); wdc_send_error();
break; break;
case CMD_RD_BLOCK: case CMD_RD_BLOCK:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] ); 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; errorcode = 1;
if ( data_counter == WDC_BLOCKLEN ) { if ( data_counter == WDC_BLOCKLEN ) {
errorcode = wdc_read_sector ( blockno, data_buffer ); errorcode = wdc_read_sector ( blockno, data_buffer );
} else { } else {
errorcode = wdc_read_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); 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 wdc_send_data ( data_buffer
, data_counter , data_counter
); );
}
break;
case CMD_WR_WDC_RAM: wdc_set_initialized ( 0 );
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
);
wdc_send_data ( data_buffer
, data_counter
);
break;
case CMD_RD_PARTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
wdc_read_par_table ( data_buffer
, data_counter );
wdc_send_data ( data_buffer
, data_counter
);
break;
case CMD_WR_PARTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
wdc_receive_data ( data_buffer
, data_counter
);
wdc_write_wdc_par ( data_buffer
, data_counter );
break;
case CMD_DL_BTTAB:
wdc_del_wdc_btt();
break;
case CMD_RD_BTTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
wdc_read_wdc_btt ( data_buffer
, data_counter );
wdc_send_data ( data_buffer
, data_counter
);
break;
case CMD_WR_BTTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
wdc_receive_data ( data_buffer
, data_counter
);
wdc_write_wdc_btt ( data_buffer
, data_counter );
break;
case CMD_FMTRD_TRACK:
case CMD_FMTBTT_TRACK:
/* 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; break;
data_counter = WDC_BLOCKLEN; case CMD_RD_PARTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
memset ( &data_buffer[0], 0x00, data_counter ); wdc_read_par_table ( data_buffer
blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) , data_counter );
, cmd_buffer[4]
, cmd_buffer[5]
);
errorcode = 1; wdc_send_data ( data_buffer
for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { , data_counter
errorcode = wdc_write_sector ( blockno, data_buffer ); );
if ( errorcode ) break; break;
blockno++;
}
case CMD_WR_PARTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
if ( errorcode ) { wdc_receive_data ( data_buffer
if ( cmd_buffer[0] == CMD_FMTRD_TRACK ) { , data_counter
wdc_send_error(); );
} else {
if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) { wdc_write_wdc_par ( data_buffer
, data_counter );
break;
case CMD_DL_BTTAB:
wdc_del_wdc_btt();
break;
case CMD_RD_BTTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
wdc_read_wdc_btt ( data_buffer
, data_counter );
wdc_send_data ( data_buffer
, data_counter
);
break;
case CMD_WR_BTTAB:
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
wdc_receive_data ( data_buffer
, data_counter
);
wdc_write_wdc_btt ( data_buffer
, data_counter );
break;
case CMD_FMTRD_TRACK:
case CMD_FMTBTT_TRACK:
/* 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;
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 ( cmd_buffer[0] == CMD_FMTRD_TRACK ) {
wdc_send_error(); wdc_send_error();
} else { } else {
data_buffer[0] = cmd_buffer[2]; /* Track Low */ errorcode = wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] );
data_buffer[1] = cmd_buffer[3]; /* Track High */ if ( errorcode ) {
data_buffer[2] = cmd_buffer[4]; /* Head */ wdc_send_errorcode ( errorcode );
} 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 wdc_send_data ( data_buffer
, 3 , 3
); );
}
} }
} }
} break;
break;
case CMD_ST_PARBTT: case CMD_ST_PARBTT:
data_counter = WDC_BLOCKLEN; data_counter = WDC_BLOCKLEN;
blockno = 0; blockno = 0;
wdc_set_disk_valid(); wdc_set_disk_valid();
wdc_read_par_table ( data_buffer wdc_read_par_table ( data_buffer
, data_counter ); , data_counter );
errorcode = wdc_write_sector ( blockno, data_buffer );
if ( errorcode )
wdc_send_error();
break;
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 ); errorcode = wdc_write_sector ( blockno, data_buffer );
} else { if ( errorcode )
errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); wdc_send_error();
}
if ( errorcode ) break;
wdc_send_error();
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 #if DEBUG >= 1
uart_puts_p ( PSTR ( " Unknown command:" ) ); uart_puts_p ( PSTR ( " Unknown command:" ) );
uart_putc_hex ( cmd_buffer[0] ); uart_putc_hex ( cmd_buffer[0] );
uart_putc_hex ( cmd_buffer[1] ); uart_putc_hex ( cmd_buffer[1] );
uart_putc_hex ( cmd_buffer[2] ); uart_putc_hex ( cmd_buffer[2] );
uart_putc_hex ( cmd_buffer[3] ); uart_putc_hex ( cmd_buffer[3] );
uart_putc_hex ( cmd_buffer[4] ); uart_putc_hex ( cmd_buffer[4] );
uart_putc_hex ( cmd_buffer[5] ); uart_putc_hex ( cmd_buffer[5] );
uart_putc_hex ( cmd_buffer[6] ); uart_putc_hex ( cmd_buffer[6] );
uart_putc_hex ( cmd_buffer[7] ); uart_putc_hex ( cmd_buffer[7] );
uart_putc_hex ( cmd_buffer[8] ); uart_putc_hex ( cmd_buffer[8] );
uart_putc ( '\n' ); uart_putc ( '\n' );
#endif #endif
wdc_send_error(); wdc_send_error();
break; break;
}
} }
} }
} }

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_main.h,v 1.11 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_main.h,v 1.12 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
@ -59,4 +59,10 @@
#define ___CMD_WRRD_BLOCK 0xa2 /* write and reread block */ #define ___CMD_WRRD_BLOCK 0xa2 /* write and reread block */
#define CMD_ST_PARBTT 0xc2 /* store PAR and BTT on hard disk */ #define CMD_ST_PARBTT 0xc2 /* store PAR and BTT on hard disk */
#define ERR_STANDARD 0x01
#define ERR_SECT_N_ON_SURFACE 0x0A
#define ERR_BTT_FULL 0x16
#define ERR_NO_DRIVE_READY 0x27
#define ERR_CYL0_NOT_READABLE 0x31
#endif /* MAIN_H_ */ #endif /* MAIN_H_ */

View File

@ -26,11 +26,13 @@
*/ */
/* /*
* $Id: wdc_par.c,v 1.3 2012/06/09 00:22:28 olivleh1 Exp $ * $Id: wdc_par.c,v 1.4 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "main.h"
#include "wdc_par.h" #include "wdc_par.h"
#include "uart.h"
/* /*
* unformatted ST138 * unformatted ST138
@ -97,6 +99,7 @@ par_tab_no_dsk[128] = {'W', 'D', 'C', '_', '4', '.', '2', 0x81, 0x81, 0x
}; };
uint8_t valid_disk = 1; uint8_t valid_disk = 1;
uint8_t initialized;
void wdc_read_par_table ( uint8_t *buffer, uint16_t count ) void wdc_read_par_table ( uint8_t *buffer, uint16_t count )
{ {
@ -182,7 +185,7 @@ uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head )
wdc_set_btt_count ( btt_count ); wdc_set_btt_count ( btt_count );
return ( 0 ); return ( 0 );
} else { } else {
return ( 1 ); return ( ERR_BTT_FULL );
} }
} }
@ -252,3 +255,13 @@ uint8_t wdc_get_num_of_drvs()
{ {
return par_table[49]; return par_table[49];
} }
void wdc_set_initialized(uint8_t num)
{
initialized=num;
}
uint8_t wdc_get_initialized()
{
return initialized;
}

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_par.h,v 1.3 2012/06/09 00:22:29 olivleh1 Exp $ * $Id: wdc_par.h,v 1.4 2012/06/09 19:47:31 olivleh1 Exp $
*/ */
#ifndef WDC_PAR_H_ #ifndef WDC_PAR_H_
@ -43,16 +43,15 @@ extern void wdc_read_wdc_btt ( uint8_t *buffer, uint16_t count );
extern void wdc_write_wdc_btt ( uint8_t *buffer, uint16_t count ); extern void wdc_write_wdc_btt ( uint8_t *buffer, uint16_t count );
extern uint16_t wdc_get_btt_count(); extern uint16_t wdc_get_btt_count();
extern uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head ); 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_sectors();
extern uint8_t wdc_get_hdd_heads(); extern uint8_t wdc_get_hdd_heads();
extern void wdc_set_disk_invalid();
void wdc_set_disk_invalid(); extern void wdc_set_disk_valid();
void wdc_set_disk_valid(); extern uint8_t wdc_get_disk_valid();
uint8_t wdc_get_disk_valid(); extern void wdc_set_no_disk();
extern uint8_t wdc_get_num_of_drvs();
void wdc_set_no_disk(); extern void wdc_set_initialized ( uint8_t num );
uint8_t wdc_get_num_of_drvs(); extern uint8_t wdc_get_initialized ();
#define POS_PAR_VERSION 0 #define POS_PAR_VERSION 0
#define POS_PAR_WDC_PAR 8 #define POS_PAR_WDC_PAR 8