From 406774a3822b510248572307722e22be777387f5 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Sat, 9 Jun 2012 19:47:31 +0000 Subject: [PATCH] getting closer to a final version --- .../P8000_WDC_Emulator/Makefile | 1 + .../P8000_WDC_Emulator/wdc_config.h | 4 +- .../P8000_WDC_Emulator/wdc_drv_mmc.c | 54 +- .../P8000_WDC_Emulator/wdc_if_disk.c | 11 +- .../P8000_WDC_Emulator/wdc_if_disk_perf.c | 32 +- .../P8000_WDC_Emulator/wdc_if_p8000.c | 30 +- .../P8000_WDC_Emulator/wdc_if_p8000.h | 5 +- .../P8000_WDC_Emulator/wdc_main.c | 507 +++++++++--------- .../P8000_WDC_Emulator/wdc_main.h | 8 +- .../P8000_WDC_Emulator/wdc_par.c | 17 +- .../P8000_WDC_Emulator/wdc_par.h | 17 +- 11 files changed, 374 insertions(+), 312 deletions(-) diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/Makefile b/P8000_WDC_Emulator/P8000_WDC_Emulator/Makefile index ad2799d..0708701 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/Makefile +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/Makefile @@ -14,6 +14,7 @@ RM := rm -rf OBJS += \ main.o \ mmc.o \ +mmc_perf.o \ uart.o \ wdc_if_pio.o \ wdc_if_sdcard.o \ diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h index 8d721e2..9727018 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_config.h @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_config.h,v 1.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 #undef MEASURE_SDCARD_TIME +#define DEBUG 0 + #endif /* CONFIG_H_ */ \ No newline at end of file diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c index 8530b27..040ba23 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_drv_mmc.c @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_drv_mmc.c,v 1.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 @@ -39,8 +39,8 @@ #define send_dummy_byte() SPDR = 0xFF; wait_till_send_done() #define recv_byte() SPDR #define xmit_byte(x) SPDR = x -#define MMC_Disable() PORT_MMC|= (1< 1000 ) { - MMC_Disable(); + mmc_disable(); return ( 1 ); } } @@ -254,7 +254,7 @@ uint8_t mmc_init () while ( mmc_cmd ( cmd ) != 0 ) { send_dummy_byte(); if ( t16++ > 1000 ) { - MMC_Disable(); + mmc_disable(); return ( 2 ); } } @@ -269,7 +269,7 @@ uint8_t mmc_init () mmc_enable_crc ( 1 ); #endif - MMC_Disable(); + mmc_disable(); return ( 0 ); } @@ -310,7 +310,7 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer ) uint8_t crcl, crch; #endif - MMC_Enable(); + mmc_enable(); wait_till_card_ready(); /* convert blocks to bytes */ @@ -327,7 +327,7 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer ) */ tmp = mmc_cmd ( cmd ); if ( tmp != 0 ) { - MMC_Disable(); + mmc_disable(); return ( tmp ); } @@ -363,11 +363,11 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer ) /* check for errors */ send_dummy_byte(); if ( ( recv_byte() & 0x1F ) != 0x05 ) { - MMC_Disable(); + mmc_disable(); return ( 2 ); } - MMC_Disable(); + mmc_disable(); return ( 0 ); } @@ -380,12 +380,12 @@ uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes ) uint16_t crc; #endif - MMC_Enable(); + mmc_enable(); wait_till_card_ready(); /* send command */ if ( mmc_cmd ( cmd ) != 0 ) { - MMC_Disable(); + mmc_disable(); return ( 1 ); } @@ -421,14 +421,14 @@ uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes ) wait_till_send_done(); crc |= recv_byte(); if ( crc != crc16 ( buffer, bytes ) ) { - MMC_Disable(); + mmc_disable(); return ( 3 ); } #else send_dummy_byte(); #endif - MMC_Disable(); + mmc_disable(); return ( 0 ); } @@ -465,7 +465,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks uint16_t crc; #endif - MMC_Enable(); + mmc_enable(); #ifdef MMC_MULTIBLOCK #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 ); if ( resp > 1 ) { - MMC_Disable(); + mmc_disable(); return ( 1 ); } #else @@ -528,7 +528,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks */ resp = mmc_cmd ( cmd ); if ( resp > 1 ) { - MMC_Disable(); + mmc_disable(); return ( 1 ); } 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(); crc |= recv_byte(); if ( crc != crc16 ( buffer, MMC_BLOCKLEN ) ) { - MMC_Disable(); + mmc_disable(); return ( 3 ); } 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 if ( resp > 1 ) { - MMC_Disable(); + mmc_disable(); return ( 2 ); } */ @@ -593,7 +593,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks send_dummy_byte(); #endif - MMC_Disable() + mmc_disable() return ( 0 ); } @@ -610,7 +610,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks uint8_t crcl, crch; #endif - MMC_Enable(); + mmc_enable(); wait_till_card_ready(); #ifdef MMC_MULTIBLOCK #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 ); if ( resp > 1 ) { - MMC_Disable(); + mmc_disable(); return ( 1 ); } #else @@ -668,7 +668,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks */ resp = mmc_cmd ( cmd ); if ( resp != 0 ) { - MMC_Disable(); + mmc_disable(); return ( resp ); } 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(); if ( ( recv_byte() & 0x1F ) != 0x05 ) { - MMC_Disable(); + mmc_disable(); return ( 2 ); } @@ -738,7 +738,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks /* Pad 8 */ send_dummy_byte(); #endif - MMC_Disable(); + mmc_disable(); return ( 0 ); } diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c index 8544f83..1bd9a9e 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk.c @@ -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 @@ -36,14 +36,7 @@ uint8_t wdc_init_sdcard() { - uint8_t errorcode; - - errorcode=mmc_init(); - if ( errorcode ) { - uart_putc_hex ( errorcode ); - uart_putc ( '\n' ); - } - return errorcode; + return mmc_init(); } uint32_t wdc_sector2sdblock ( uint16_t req_cylinder, uint8_t req_head, uint8_t req_sector ) diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c index 4a23144..5950e18 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_disk_perf.c @@ -1,8 +1,32 @@ -/* - * mmc_perf.c +/*- + * Copyright (c) 2012 Oliver Lehmann + * All rights reserved. * - * Created: 07.06.2012 21:42:41 - * Author: olivleh1 + * Redistribution and use in source and binary forms, with or without + * 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 diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.c index 70da99f..9009e33 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.c @@ -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 #include #include "wdc_if_pio.h" +#include "wdc_par.h" +#include "uart.h" #define nop() __asm__ __volatile__ ("nop" ::) @@ -55,11 +57,12 @@ void wdc_wait_for_reset() while ( !isset_info_reset() ) { port_data_set ( DATA_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; @@ -68,7 +71,9 @@ void wdc_read_data_from_p8k ( uint8_t *buffer, uint16_t count, uint8_t wdc_statu configure_port_data_read(); datacnt = 0; port_info_set ( wdc_status ); - while ( !isset_info_te() ); + while ( !isset_info_te() ) + if ( !isset_info_reset() ) + return 0; while ( !isset_info_wdardy() ); do { 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 ); port_info_set ( INFO_CLEAR ); + return 1; } 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() ); port_info_set ( INFO_TR | INFO_ASTB | wdc_status ); nop(); - nop(); port_info_set ( INFO_TR | wdc_status ); configure_port_data_read(); 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 - , count - , INFO_STAT_GCMD - ); + return wdc_read_data_from_p8k ( buffer + , count + , INFO_STAT_GCMD + ); } 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() +{ + wdc_send_errorcode ( 0x01 ); +} + +void wdc_send_errorcode ( uint8_t error ) { uint8_t buffer[1]; - buffer[0] = 0x01; + buffer[0] = error; wdc_write_data_to_p8k ( buffer , 1 diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h index 090f914..2b54aa5 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_if_p8000.h @@ -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_ @@ -69,9 +69,10 @@ extern void wdc_init_ports(); 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_send_data ( uint8_t *buffer, uint16_t count ); extern void wdc_send_error(); +extern void wdc_send_errorcode ( uint8_t error ); #endif /* WDC_IF_PIO_H_ */ \ No newline at end of file diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c index fa0e12e..7a993f3 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.c @@ -29,20 +29,11 @@ /* * 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) - * - 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] + * TODO: - right now, BTT entries are not taken into account */ -#define DEBUG 1 - #include #include @@ -50,6 +41,7 @@ #include #include #include +#include "config.h" #include "main.h" #ifdef DEBUG #include "uart.h" @@ -58,7 +50,7 @@ #include "wdc_par.h" #include "wdc_if_pio.h" #include "wdc_if_sdcard.h" -#include "config.h" + void atmega_setup ( void ); @@ -91,7 +83,7 @@ main ( void ) #endif 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 measure_performance(); @@ -121,278 +113,299 @@ main ( void ) wdc_wait_for_reset(); - wdc_receive_cmd ( cmd_buffer - , cmd_counter - ); + if ( wdc_receive_cmd ( cmd_buffer + , cmd_counter + ) ) { #if DEBUG >= 2 #if DEBUG >= 3 - uart_puts_p ( PSTR ( " CMD:" ) ); + uart_puts_p ( PSTR ( " CMD:" ) ); #endif - uart_putc_hex ( cmd_buffer[0] ); + uart_putc_hex ( cmd_buffer[0] ); #if DEBUG >= 3 - uart_putc_hex ( cmd_buffer[1] ); - uart_putc_hex ( cmd_buffer[2] ); - uart_putc_hex ( cmd_buffer[3] ); - uart_putc_hex ( cmd_buffer[4] ); - uart_putc_hex ( cmd_buffer[5] ); - uart_putc_hex ( cmd_buffer[6] ); - uart_putc_hex ( cmd_buffer[7] ); - uart_putc_hex ( cmd_buffer[8] ); - uart_putc ( '\n' ); + uart_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 #endif - /* if the disk is not valid, only maintenance commands are allowed */ - if ( ! wdc_get_disk_valid() - && cmd_buffer[0] != CMD_RD_WDC_RAM - && cmd_buffer[0] != CMD_FMTRD_TRACK - && cmd_buffer[0] != CMD_WR_WDC_RAM - && cmd_buffer[0] != CMD_FMTBTT_TRACK - && cmd_buffer[0] != CMD_RD_PARTAB - && cmd_buffer[0] != CMD_RD_WDCERR - && cmd_buffer[0] != CMD_VER_TRACK - && cmd_buffer[0] != CMD_DL_BTTAB - && cmd_buffer[0] != CMD_RD_BTTAB - && cmd_buffer[0] != CMD_WR_BTTAB - && cmd_buffer[0] != CMD_WR_PARTAB - && cmd_buffer[0] != CMD_ST_PARBTT - ) { - wdc_send_error(); - } else { + /* no drive attached */ + if ( wdc_get_initialized() && wdc_get_num_of_drvs() == 0 ) { + if ( cmd_buffer[0] == CMD_WR_WDC_RAM + || cmd_buffer[0] == CMD_RD_BLOCK ) { + wdc_send_errorcode ( 0xc1 ); + } else if ( cmd_buffer[0] == CMD_RD_WDC_RAM ) { + wdc_send_errorcode ( ERR_NO_DRIVE_READY ); + wdc_set_initialized ( 0 ); + } + /* WDC freshly initialized after RESET, the disk is not valid */ + } else if ( wdc_get_initialized() + && ! wdc_get_disk_valid() + && ( cmd_buffer[0] == CMD_WR_WDC_RAM || cmd_buffer[0] == CMD_RD_BLOCK ) ) { + wdc_send_errorcode ( ERR_CYL0_NOT_READABLE ); + wdc_set_initialized ( 0 ); + /* if the disk is not valid, only maintenance commands are allowed */ + } 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] ) { - case CMD_WR_BLOCK: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + switch ( cmd_buffer[0] ) { + case CMD_WR_BLOCK: + 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] ); - wdc_receive_data ( data_buffer - , data_counter - ); - errorcode = 1; - if ( data_counter == WDC_BLOCKLEN ) { - errorcode = wdc_write_sector ( blockno, data_buffer ); - } else { - errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); - } + blockno = wdc_p8kblock2sdblock ( ( ( uint32_t ) cmd_buffer[5] << 24 ) | ( ( uint32_t ) cmd_buffer[4] << 16 ) | ( ( uint16_t ) cmd_buffer[3] << 8 ) | cmd_buffer[2] ); + wdc_receive_data ( data_buffer + , data_counter + ); + errorcode = 1; + if ( data_counter == WDC_BLOCKLEN ) { + errorcode = wdc_write_sector ( blockno, data_buffer ); + } else { + errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); + } - if ( errorcode ) - wdc_send_error(); - break; + if ( errorcode ) + wdc_send_error(); + break; - case CMD_RD_BLOCK: - data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + case CMD_RD_BLOCK: + 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; - if ( data_counter == WDC_BLOCKLEN ) { - errorcode = wdc_read_sector ( blockno, data_buffer ); - } else { - errorcode = wdc_read_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); - } + errorcode = 1; + if ( data_counter == WDC_BLOCKLEN ) { + errorcode = wdc_read_sector ( blockno, data_buffer ); + } else { + errorcode = wdc_read_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); + } + + if ( errorcode ) { + wdc_send_error(); + } else { + wdc_send_data ( data_buffer + , data_counter + ); + } + break; + + case CMD_WR_WDC_RAM: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + wdc_receive_data ( data_buffer + , data_counter + ); + + wdc_write_data_to_ram ( data_buffer + , convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] ) + , data_counter + ); + break; + + case CMD_RD_WDC_RAM: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + wdc_read_data_from_ram ( data_buffer + , convert_ram_address ( ( cmd_buffer[2] << 8 ) | cmd_buffer[1] ) + , data_counter + ); - if ( errorcode ) { - wdc_send_error(); - } else { wdc_send_data ( data_buffer , data_counter ); - } - break; - 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 - ); - - 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 ) + wdc_set_initialized ( 0 ); 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 ); - blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) - , cmd_buffer[4] - , cmd_buffer[5] - ); + wdc_read_par_table ( data_buffer + , data_counter ); - errorcode = 1; - for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { - errorcode = wdc_write_sector ( blockno, data_buffer ); - if ( errorcode ) break; - blockno++; - } + wdc_send_data ( data_buffer + , data_counter + ); + break; + case CMD_WR_PARTAB: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; - if ( errorcode ) { - if ( cmd_buffer[0] == CMD_FMTRD_TRACK ) { - wdc_send_error(); - } else { - if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) { + wdc_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; + + 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(); } else { - data_buffer[0] = cmd_buffer[2]; /* Track Low */ - data_buffer[1] = cmd_buffer[3]; /* Track High */ - data_buffer[2] = cmd_buffer[4]; /* Head */ + errorcode = wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ); + if ( errorcode ) { + 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 - , 3 - ); + wdc_send_data ( data_buffer + , 3 + ); + } } } - } - break; + break; - case CMD_ST_PARBTT: - data_counter = WDC_BLOCKLEN; + case CMD_ST_PARBTT: + data_counter = WDC_BLOCKLEN; - blockno = 0; - wdc_set_disk_valid(); - wdc_read_par_table ( data_buffer - , data_counter ); + blockno = 0; + wdc_set_disk_valid(); + wdc_read_par_table ( data_buffer + , 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 ); - } else { - errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); - } + if ( errorcode ) + wdc_send_error(); - if ( errorcode ) - wdc_send_error(); - break; + break; - default: + case CMD_RD_WDCERR: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + memset ( &data_buffer[0], 0x00, data_counter ); + wdc_send_data ( data_buffer + , data_counter + ); + break; + + case CMD_VER_TRACK: + data_counter = WDC_BLOCKLEN; + + blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) + , cmd_buffer[4] + , cmd_buffer[5] + ); + errorcode = 1; + for ( i8 = 0; i8 < wdc_get_hdd_sectors(); i8++ ) { + errorcode = wdc_read_sector ( blockno, data_buffer ); + if ( errorcode ) break; + blockno++; + } + if ( errorcode ) + wdc_send_error(); + break; + + case CMD_RD_SECTOR: + data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6]; + + blockno = wdc_sector2sdblock ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) + , cmd_buffer[4] + , cmd_buffer[5] + ); + errorcode = 1; + + if ( data_counter == WDC_BLOCKLEN ) { + errorcode = wdc_write_sector ( blockno, data_buffer ); + } else { + errorcode = wdc_write_multiblock ( blockno, data_buffer, data_counter / WDC_BLOCKLEN ); + } + + if ( errorcode ) + wdc_send_error(); + break; + + default: #if DEBUG >= 1 - uart_puts_p ( PSTR ( " Unknown command:" ) ); - uart_putc_hex ( cmd_buffer[0] ); - uart_putc_hex ( cmd_buffer[1] ); - uart_putc_hex ( cmd_buffer[2] ); - uart_putc_hex ( cmd_buffer[3] ); - uart_putc_hex ( cmd_buffer[4] ); - uart_putc_hex ( cmd_buffer[5] ); - uart_putc_hex ( cmd_buffer[6] ); - uart_putc_hex ( cmd_buffer[7] ); - uart_putc_hex ( cmd_buffer[8] ); - uart_putc ( '\n' ); + uart_puts_p ( PSTR ( " Unknown command:" ) ); + uart_putc_hex ( cmd_buffer[0] ); + uart_putc_hex ( cmd_buffer[1] ); + uart_putc_hex ( cmd_buffer[2] ); + uart_putc_hex ( cmd_buffer[3] ); + uart_putc_hex ( cmd_buffer[4] ); + uart_putc_hex ( cmd_buffer[5] ); + uart_putc_hex ( cmd_buffer[6] ); + uart_putc_hex ( cmd_buffer[7] ); + uart_putc_hex ( cmd_buffer[8] ); + uart_putc ( '\n' ); #endif - wdc_send_error(); - break; + wdc_send_error(); + break; + } } } } diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h index 5e0b667..867b1a4 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_main.h @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_main.h,v 1.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_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_ */ diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c index 0566751..25389f1 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.c @@ -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 +#include "main.h" #include "wdc_par.h" +#include "uart.h" /* * 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 initialized; 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 ); return ( 0 ); } else { - return ( 1 ); + return ( ERR_BTT_FULL ); } } @@ -251,4 +254,14 @@ uint8_t wdc_get_disk_valid() uint8_t wdc_get_num_of_drvs() { return par_table[49]; +} + +void wdc_set_initialized(uint8_t num) +{ + initialized=num; +} + +uint8_t wdc_get_initialized() +{ + return initialized; } \ No newline at end of file diff --git a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h index cb202f6..5324151 100644 --- a/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h +++ b/P8000_WDC_Emulator/P8000_WDC_Emulator/wdc_par.h @@ -26,7 +26,7 @@ */ /* - * $Id: wdc_par.h,v 1.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_ @@ -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 uint16_t wdc_get_btt_count(); extern uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head ); - extern uint8_t wdc_get_hdd_sectors(); extern uint8_t wdc_get_hdd_heads(); - -void wdc_set_disk_invalid(); -void wdc_set_disk_valid(); -uint8_t wdc_get_disk_valid(); - -void wdc_set_no_disk(); -uint8_t wdc_get_num_of_drvs(); +extern void wdc_set_disk_invalid(); +extern void wdc_set_disk_valid(); +extern uint8_t wdc_get_disk_valid(); +extern void wdc_set_no_disk(); +extern uint8_t wdc_get_num_of_drvs(); +extern void wdc_set_initialized ( uint8_t num ); +extern uint8_t wdc_get_initialized (); #define POS_PAR_VERSION 0 #define POS_PAR_WDC_PAR 8