Implemented some missing functions
This commit is contained in:
parent
725f2c7129
commit
9d4654aca9
4 changed files with 923 additions and 171 deletions
799
src/flashrom.cpp
799
src/flashrom.cpp
|
@ -8,38 +8,288 @@
|
|||
* (c) 2014 Toni Wilen
|
||||
*/
|
||||
|
||||
#include "sysconfig.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "options.h"
|
||||
#include "zfile.h"
|
||||
#include "flashrom.h"
|
||||
#include "memory.h"
|
||||
#include "newcpu.h"
|
||||
#include "gui.h"
|
||||
#include "uae.h"
|
||||
|
||||
#define FLASH_LOG 0
|
||||
#define EEPROM_LOG 0
|
||||
|
||||
/* MICROWIRE EEPROM */
|
||||
|
||||
struct eeprom93xx_eeprom_t {
|
||||
uint8_t tick;
|
||||
uint8_t address;
|
||||
uint8_t command;
|
||||
uint8_t writeable;
|
||||
|
||||
uint8_t eecs;
|
||||
uint8_t eesk;
|
||||
uint8_t eedo;
|
||||
|
||||
uint8_t addrbits;
|
||||
uint16_t size;
|
||||
uint16_t data;
|
||||
uint16_t contents[256];
|
||||
|
||||
uae_u8 *memory;
|
||||
struct zfile *zf;
|
||||
};
|
||||
|
||||
static const char *opstring[] = { "extended", "write", "read", "erase" };
|
||||
|
||||
void eeprom93xx_write(void *eepromp, int eecs, int eesk, int eedi)
|
||||
{
|
||||
eeprom93xx_eeprom_t *eeprom = (eeprom93xx_eeprom_t*)eepromp;
|
||||
uint8_t tick = eeprom->tick;
|
||||
uint8_t eedo = eeprom->eedo;
|
||||
uint16_t address = eeprom->address;
|
||||
uint8_t command = eeprom->command;
|
||||
|
||||
#if EEPROM_LOG
|
||||
write_log("CS=%u SK=%u DI=%u DO=%u, tick = %u\n", eecs, eesk, eedi, eedo, tick);
|
||||
#endif
|
||||
|
||||
if (!eeprom->eecs && eecs) {
|
||||
/* Start chip select cycle. */
|
||||
#if EEPROM_LOG
|
||||
write_log("Cycle start, waiting for 1st start bit (0)\n");
|
||||
#endif
|
||||
tick = 0;
|
||||
command = 0x0;
|
||||
address = 0x0;
|
||||
}
|
||||
else if (eeprom->eecs && !eecs) {
|
||||
/* End chip select cycle. This triggers write / erase. */
|
||||
if (eeprom->writeable) {
|
||||
uint8_t subcommand = address >> (eeprom->addrbits - 2);
|
||||
if (command == 0 && subcommand == 2) {
|
||||
/* Erase all. */
|
||||
for (address = 0; address < eeprom->size; address++) {
|
||||
eeprom->contents[address] = 0xffff;
|
||||
}
|
||||
}
|
||||
else if (command == 3) {
|
||||
/* Erase word. */
|
||||
eeprom->contents[address] = 0xffff;
|
||||
}
|
||||
else if (tick >= 2 + 2 + eeprom->addrbits + 16) {
|
||||
if (command == 1) {
|
||||
/* Write word. */
|
||||
eeprom->contents[address] &= eeprom->data;
|
||||
}
|
||||
else if (command == 0 && subcommand == 1) {
|
||||
/* Write all. */
|
||||
for (address = 0; address < eeprom->size; address++) {
|
||||
eeprom->contents[address] &= eeprom->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Output DO is tristate, read results in 1. */
|
||||
eedo = 1;
|
||||
}
|
||||
else if (eecs && !eeprom->eesk && eesk) {
|
||||
/* Raising edge of clock shifts data in. */
|
||||
if (tick == 0) {
|
||||
/* Wait for 1st start bit. */
|
||||
if (eedi == 0) {
|
||||
#if EEPROM_LOG
|
||||
write_log("Got correct 1st start bit, waiting for 2nd start bit (1)\n");
|
||||
#endif
|
||||
tick++;
|
||||
}
|
||||
else {
|
||||
#if EEPROM_LOG
|
||||
write_log("wrong 1st start bit (is 1, should be 0)\n");
|
||||
#endif
|
||||
tick = 2;
|
||||
//~ assert(!"wrong start bit");
|
||||
}
|
||||
}
|
||||
else if (tick == 1) {
|
||||
/* Wait for 2nd start bit. */
|
||||
if (eedi != 0) {
|
||||
#if EEPROM_LOG
|
||||
write_log("Got correct 2nd start bit, getting command + address\n");
|
||||
#endif
|
||||
tick++;
|
||||
}
|
||||
else {
|
||||
#if EEPROM_LOG
|
||||
|
||||
write_log("1st start bit is longer than needed\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (tick < 2 + 2) {
|
||||
/* Got 2 start bits, transfer 2 opcode bits. */
|
||||
tick++;
|
||||
command <<= 1;
|
||||
if (eedi) {
|
||||
command += 1;
|
||||
}
|
||||
}
|
||||
else if (tick < 2 + 2 + eeprom->addrbits) {
|
||||
/* Got 2 start bits and 2 opcode bits, transfer all address bits. */
|
||||
tick++;
|
||||
address = ((address << 1) | eedi);
|
||||
if (tick == 2 + 2 + eeprom->addrbits) {
|
||||
#if EEPROM_LOG
|
||||
write_log("%s command, address = 0x%02x (value 0x%04x)\n", opstring[command], address, eeprom->contents[address]);
|
||||
#endif
|
||||
if (command == 2) {
|
||||
eedo = 0;
|
||||
}
|
||||
address = address % eeprom->size;
|
||||
if (command == 0) {
|
||||
/* Command code in upper 2 bits of address. */
|
||||
switch (address >> (eeprom->addrbits - 2)) {
|
||||
case 0:
|
||||
#if EEPROM_LOG
|
||||
write_log("write disable command\n");
|
||||
#endif
|
||||
eeprom->writeable = 0;
|
||||
break;
|
||||
case 1:
|
||||
#if EEPROM_LOG
|
||||
write_log("write all command\n");
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
#if EEPROM_LOG
|
||||
write_log("erase all command\n");
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
#if EEPROM_LOG
|
||||
write_log("write enable command\n");
|
||||
#endif
|
||||
eeprom->writeable = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Read, write or erase word. */
|
||||
eeprom->data = eeprom->contents[address];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tick < 2 + 2 + eeprom->addrbits + 16) {
|
||||
/* Transfer 16 data bits. */
|
||||
tick++;
|
||||
if (command == 2) {
|
||||
/* Read word. */
|
||||
eedo = ((eeprom->data & 0x8000) != 0);
|
||||
}
|
||||
eeprom->data <<= 1;
|
||||
eeprom->data += eedi;
|
||||
}
|
||||
else {
|
||||
#if EEPROM_LOG
|
||||
write_log("additional unneeded tick, not processed\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* Save status of EEPROM. */
|
||||
eeprom->tick = tick;
|
||||
eeprom->eecs = eecs;
|
||||
eeprom->eesk = eesk;
|
||||
eeprom->eedo = eedo;
|
||||
eeprom->address = address;
|
||||
eeprom->command = command;
|
||||
}
|
||||
|
||||
uae_u16 eeprom93xx_read(void *eepromp)
|
||||
{
|
||||
eeprom93xx_eeprom_t *eeprom = (eeprom93xx_eeprom_t*)eepromp;
|
||||
/* Return status of pin DO (0 or 1). */
|
||||
#if EEPROM_LOG
|
||||
write_log("CS=%u DO=%u\n", eeprom->eecs, eeprom->eedo);
|
||||
#endif
|
||||
return eeprom->eedo;
|
||||
}
|
||||
|
||||
uae_u8 eeprom93xx_read_byte(void *eepromp, int offset)
|
||||
{
|
||||
eeprom93xx_eeprom_t *eeprom = (eeprom93xx_eeprom_t*)eepromp;
|
||||
if (offset & 1)
|
||||
return eeprom->contents[offset / 2];
|
||||
else
|
||||
return eeprom->contents[offset / 2] >> 8;
|
||||
}
|
||||
|
||||
void *eeprom93xx_new(const uae_u8 *memory, int nwords, struct zfile *zf)
|
||||
{
|
||||
/* Add a new EEPROM (with 16, 64 or 256 words). */
|
||||
eeprom93xx_eeprom_t *eeprom;
|
||||
uint8_t addrbits;
|
||||
|
||||
switch (nwords) {
|
||||
case 16:
|
||||
case 64:
|
||||
addrbits = 6;
|
||||
break;
|
||||
case 128:
|
||||
case 256:
|
||||
addrbits = 8;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eeprom = (eeprom93xx_eeprom_t *)xcalloc(eeprom93xx_eeprom_t, 1);
|
||||
eeprom->size = nwords;
|
||||
eeprom->addrbits = addrbits;
|
||||
for (int i = 0; i < nwords; i++) {
|
||||
eeprom->contents[i] = (memory[i * 2 + 0] << 8) | memory[i * 2 + 1];
|
||||
}
|
||||
/* Output DO is tristate, read results in 1. */
|
||||
eeprom->eedo = 1;
|
||||
// write_log("eeprom = 0x%p, nwords = %u\n", eeprom, nwords);
|
||||
return eeprom;
|
||||
}
|
||||
|
||||
void eeprom93xx_free(void *eepromp)
|
||||
{
|
||||
eeprom93xx_eeprom_t *eeprom = (eeprom93xx_eeprom_t*)eepromp;
|
||||
|
||||
/* Destroy EEPROM. */
|
||||
// write_log("eeprom = 0x%p\n", eeprom);
|
||||
xfree(eeprom);
|
||||
}
|
||||
|
||||
/* I2C EEPROM */
|
||||
|
||||
#define NVRAM_PAGE_SIZE 16
|
||||
|
||||
typedef enum bitbang_i2c_state {
|
||||
STOPPED = 0,
|
||||
SENDING_BIT7,
|
||||
SENDING_BIT6,
|
||||
SENDING_BIT5,
|
||||
SENDING_BIT4,
|
||||
SENDING_BIT3,
|
||||
SENDING_BIT2,
|
||||
SENDING_BIT1,
|
||||
SENDING_BIT0,
|
||||
WAITING_FOR_ACK,
|
||||
RECEIVING_BIT7,
|
||||
RECEIVING_BIT6,
|
||||
RECEIVING_BIT5,
|
||||
RECEIVING_BIT4,
|
||||
RECEIVING_BIT3,
|
||||
RECEIVING_BIT2,
|
||||
RECEIVING_BIT1,
|
||||
RECEIVING_BIT0,
|
||||
SENDING_ACK,
|
||||
SENT_NACK
|
||||
STOPPED = 0,
|
||||
SENDING_BIT7,
|
||||
SENDING_BIT6,
|
||||
SENDING_BIT5,
|
||||
SENDING_BIT4,
|
||||
SENDING_BIT3,
|
||||
SENDING_BIT2,
|
||||
SENDING_BIT1,
|
||||
SENDING_BIT0,
|
||||
WAITING_FOR_ACK,
|
||||
RECEIVING_BIT7,
|
||||
RECEIVING_BIT6,
|
||||
RECEIVING_BIT5,
|
||||
RECEIVING_BIT4,
|
||||
RECEIVING_BIT3,
|
||||
RECEIVING_BIT2,
|
||||
RECEIVING_BIT1,
|
||||
RECEIVING_BIT0,
|
||||
SENDING_ACK,
|
||||
SENT_NACK
|
||||
} bitbang_i2c_state;
|
||||
|
||||
typedef enum eeprom_state {
|
||||
|
@ -49,12 +299,12 @@ typedef enum eeprom_state {
|
|||
} eeprom_state;
|
||||
|
||||
struct bitbang_i2c_interface {
|
||||
bitbang_i2c_state state;
|
||||
int last_data;
|
||||
int last_clock;
|
||||
int device_out;
|
||||
uint8_t buffer;
|
||||
int current_addr;
|
||||
bitbang_i2c_state state;
|
||||
int last_data;
|
||||
int last_clock;
|
||||
int device_out;
|
||||
uint8_t buffer;
|
||||
int current_addr;
|
||||
uae_u8 device_address, device_address_mask;
|
||||
|
||||
eeprom_state estate;
|
||||
|
@ -82,8 +332,8 @@ static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c)
|
|||
if (i2c->write_offset >= 0)
|
||||
nvram_write(i2c, i2c->write_offset, 16);
|
||||
i2c->write_offset = -1;
|
||||
i2c->current_addr = -1;
|
||||
i2c->state = STOPPED;
|
||||
i2c->current_addr = -1;
|
||||
i2c->state = STOPPED;
|
||||
i2c->estate = I2C_DEVICEADDR;
|
||||
}
|
||||
|
||||
|
@ -97,116 +347,131 @@ static int bitbang_i2c_ret(bitbang_i2c_interface *i2c, int level)
|
|||
/* Leave device data pin unodified. */
|
||||
static int bitbang_i2c_nop(bitbang_i2c_interface *i2c)
|
||||
{
|
||||
return bitbang_i2c_ret(i2c, i2c->device_out);
|
||||
return bitbang_i2c_ret(i2c, i2c->device_out);
|
||||
}
|
||||
|
||||
/* Returns data line level. */
|
||||
int eeprom_i2c_set(void *fdv, int line, int level)
|
||||
{
|
||||
struct bitbang_i2c_interface *i2c = (bitbang_i2c_interface*)fdv;
|
||||
int data;
|
||||
int data;
|
||||
|
||||
if (line == BITBANG_I2C_SDA) {
|
||||
if (line == BITBANG_I2C_SDA) {
|
||||
if (level < 0)
|
||||
level = i2c->last_data;
|
||||
if (level == i2c->last_data) {
|
||||
return bitbang_i2c_nop(i2c);
|
||||
}
|
||||
i2c->last_data = level;
|
||||
if (i2c->last_clock == 0) {
|
||||
return bitbang_i2c_nop(i2c);
|
||||
}
|
||||
if (level == 0) {
|
||||
if (level == i2c->last_data) {
|
||||
return bitbang_i2c_nop(i2c);
|
||||
}
|
||||
i2c->last_data = level;
|
||||
if (i2c->last_clock == 0) {
|
||||
return bitbang_i2c_nop(i2c);
|
||||
}
|
||||
if (level == 0) {
|
||||
#if EEPROM_LOG
|
||||
write_log(_T("I2C START\n"));
|
||||
#endif
|
||||
/* START condition. */
|
||||
i2c->state = SENDING_BIT7;
|
||||
i2c->current_addr = -1;
|
||||
i2c->state = SENDING_BIT7;
|
||||
i2c->current_addr = -1;
|
||||
} else {
|
||||
/* STOP condition. */
|
||||
bitbang_i2c_enter_stop(i2c);
|
||||
}
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
} else {
|
||||
/* STOP condition. */
|
||||
bitbang_i2c_enter_stop(i2c);
|
||||
}
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
} else {
|
||||
if (level < 0)
|
||||
level = i2c->last_clock;
|
||||
}
|
||||
|
||||
data = i2c->last_data;
|
||||
if (i2c->last_clock == level) {
|
||||
return bitbang_i2c_nop(i2c);
|
||||
}
|
||||
i2c->last_clock = level;
|
||||
if (level == 0) {
|
||||
/* State is set/read at the start of the clock pulse.
|
||||
release the data line at the end. */
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
}
|
||||
switch (i2c->state) {
|
||||
data = i2c->last_data;
|
||||
if (i2c->last_clock == level) {
|
||||
return bitbang_i2c_nop(i2c);
|
||||
}
|
||||
i2c->last_clock = level;
|
||||
if (level == 0) {
|
||||
/* State is set/read at the start of the clock pulse.
|
||||
release the data line at the end. */
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
}
|
||||
switch (i2c->state) {
|
||||
case STOPPED:
|
||||
case SENT_NACK:
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
|
||||
// Writing to EEPROM
|
||||
case SENDING_BIT7:
|
||||
case SENDING_BIT6:
|
||||
case SENDING_BIT5:
|
||||
case SENDING_BIT4:
|
||||
case SENDING_BIT3:
|
||||
case SENDING_BIT2:
|
||||
case SENDING_BIT1:
|
||||
case SENDING_BIT0:
|
||||
i2c->buffer = (i2c->buffer << 1) | data;
|
||||
/* will end up in WAITING_FOR_ACK */
|
||||
i2c->state = (bitbang_i2c_state)((int)i2c->state + 1);
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
// Writing to EEPROM
|
||||
case SENDING_BIT7:
|
||||
case SENDING_BIT6:
|
||||
case SENDING_BIT5:
|
||||
case SENDING_BIT4:
|
||||
case SENDING_BIT3:
|
||||
case SENDING_BIT2:
|
||||
case SENDING_BIT1:
|
||||
case SENDING_BIT0:
|
||||
i2c->buffer = (i2c->buffer << 1) | data;
|
||||
/* will end up in WAITING_FOR_ACK */
|
||||
i2c->state = (bitbang_i2c_state)((int)i2c->state + 1);
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
|
||||
case WAITING_FOR_ACK:
|
||||
if (i2c->estate == I2C_DEVICEADDR) {
|
||||
i2c->current_addr = i2c->buffer;
|
||||
if ((i2c->current_addr & i2c->device_address_mask) != i2c->device_address) {
|
||||
write_log (_T("I2C WARNING: device address != %02x\n"), i2c->device_address);
|
||||
i2c->state = STOPPED;
|
||||
return bitbang_i2c_ret(i2c, 0);
|
||||
}
|
||||
if (i2c->current_addr & 1) {
|
||||
i2c->estate = I2C_DATA;
|
||||
} else {
|
||||
i2c->estate = I2C_WORDADDR;
|
||||
i2c->eeprom_addr = ((i2c->buffer >> 1) & i2c->addressbitmask) << 8;
|
||||
}
|
||||
} else if (i2c->estate == I2C_WORDADDR) {
|
||||
i2c->estate = I2C_DATA;
|
||||
i2c->eeprom_addr &= i2c->addressbitmask << 8;
|
||||
i2c->eeprom_addr |= i2c->buffer;
|
||||
} else if (!(i2c->current_addr & 1)) {
|
||||
if (i2c->write_offset < 0)
|
||||
i2c->write_offset = i2c->eeprom_addr;
|
||||
if (i2c->write_func) {
|
||||
i2c->write_func(i2c->eeprom_addr, i2c->buffer);
|
||||
} else {
|
||||
i2c->memory[i2c->eeprom_addr] = i2c->buffer;
|
||||
i2c->eeprom_addr = (i2c->eeprom_addr & ~(NVRAM_PAGE_SIZE - 1)) | (i2c->eeprom_addr + 1) & (NVRAM_PAGE_SIZE - 1);
|
||||
gui_flicker_led (LED_MD, 0, 2);
|
||||
}
|
||||
}
|
||||
if (i2c->current_addr & 1) {
|
||||
i2c->state = RECEIVING_BIT7;
|
||||
} else {
|
||||
i2c->state = SENDING_BIT7;
|
||||
}
|
||||
return bitbang_i2c_ret(i2c, 0);
|
||||
if (i2c->estate == I2C_DEVICEADDR) {
|
||||
i2c->current_addr = i2c->buffer;
|
||||
#if EEPROM_LOG
|
||||
write_log(_T("I2C device address 0x%02x\n"), i2c->current_addr);
|
||||
#endif
|
||||
if ((i2c->current_addr & i2c->device_address_mask) != i2c->device_address) {
|
||||
write_log (_T("I2C WARNING: device address != %02x\n"), i2c->device_address);
|
||||
i2c->state = STOPPED;
|
||||
return bitbang_i2c_ret(i2c, 0);
|
||||
}
|
||||
if (i2c->current_addr & 1) {
|
||||
i2c->estate = I2C_DATA;
|
||||
} else {
|
||||
i2c->estate = I2C_WORDADDR;
|
||||
i2c->eeprom_addr = ((i2c->buffer >> 1) & i2c->addressbitmask) << 8;
|
||||
}
|
||||
} else if (i2c->estate == I2C_WORDADDR) {
|
||||
i2c->estate = I2C_DATA;
|
||||
i2c->eeprom_addr &= i2c->addressbitmask << 8;
|
||||
i2c->eeprom_addr |= i2c->buffer;
|
||||
#if EEPROM_LOG
|
||||
write_log(_T("I2C device address 0x%02x (Address %04x)\n"), i2c->buffer, i2c->eeprom_addr);
|
||||
#endif
|
||||
} else if (!(i2c->current_addr & 1)) {
|
||||
#if EEPROM_LOG
|
||||
write_log(_T("I2C sent %04x 0x%02x\n"), i2c->eeprom_addr, i2c->buffer);
|
||||
#endif
|
||||
if (i2c->write_offset < 0)
|
||||
i2c->write_offset = i2c->eeprom_addr;
|
||||
if (i2c->write_func) {
|
||||
i2c->write_func(i2c->eeprom_addr, i2c->buffer);
|
||||
} else {
|
||||
i2c->memory[i2c->eeprom_addr] = i2c->buffer;
|
||||
i2c->eeprom_addr = (i2c->eeprom_addr & ~(NVRAM_PAGE_SIZE - 1)) | (i2c->eeprom_addr + 1) & (NVRAM_PAGE_SIZE - 1);
|
||||
gui_flicker_led(LED_MD, 0, 2);
|
||||
}
|
||||
}
|
||||
if (i2c->current_addr & 1) {
|
||||
i2c->state = RECEIVING_BIT7;
|
||||
} else {
|
||||
i2c->state = SENDING_BIT7;
|
||||
}
|
||||
return bitbang_i2c_ret(i2c, 0);
|
||||
|
||||
// Reading from EEPROM
|
||||
// Reading from EEPROM
|
||||
case RECEIVING_BIT7:
|
||||
if (i2c->read_func) {
|
||||
i2c->buffer = i2c->read_func(i2c->eeprom_addr);
|
||||
} else {
|
||||
i2c->buffer = i2c->memory[i2c->eeprom_addr];
|
||||
}
|
||||
//i2c->buffer = i2c_recv(i2c->bus);
|
||||
i2c->eeprom_addr++;
|
||||
i2c->eeprom_addr &= i2c->size - 1;
|
||||
gui_flicker_led (LED_MD, 0, 1);
|
||||
/* Fall through... */
|
||||
if (i2c->read_func) {
|
||||
i2c->buffer = i2c->read_func(i2c->eeprom_addr);
|
||||
} else {
|
||||
i2c->buffer = i2c->memory[i2c->eeprom_addr];
|
||||
}
|
||||
//i2c->buffer = i2c_recv(i2c->bus);
|
||||
#if EEPROM_LOG
|
||||
write_log(_T("I2C RX byte %04X 0x%02x\n"), i2c->eeprom_addr, i2c->buffer);
|
||||
#endif
|
||||
i2c->eeprom_addr++;
|
||||
i2c->eeprom_addr &= i2c->size - 1;
|
||||
gui_flicker_led (LED_MD, 0, 1);
|
||||
/* Fall through... */
|
||||
case RECEIVING_BIT6:
|
||||
case RECEIVING_BIT5:
|
||||
case RECEIVING_BIT4:
|
||||
|
@ -214,23 +479,34 @@ int eeprom_i2c_set(void *fdv, int line, int level)
|
|||
case RECEIVING_BIT2:
|
||||
case RECEIVING_BIT1:
|
||||
case RECEIVING_BIT0:
|
||||
data = i2c->buffer >> 7;
|
||||
/* will end up in SENDING_ACK */
|
||||
i2c->state = (bitbang_i2c_state)((int)i2c->state + 1);
|
||||
i2c->buffer <<= 1;
|
||||
return bitbang_i2c_ret(i2c, data);
|
||||
data = i2c->buffer >> 7;
|
||||
/* will end up in SENDING_ACK */
|
||||
i2c->state = (bitbang_i2c_state)((int)i2c->state + 1);
|
||||
i2c->buffer <<= 1;
|
||||
return bitbang_i2c_ret(i2c, data);
|
||||
|
||||
case SENDING_ACK:
|
||||
i2c->state = RECEIVING_BIT7;
|
||||
if (data != 0) {
|
||||
i2c->state = SENT_NACK;
|
||||
//i2c_nack(i2c->bus);
|
||||
}
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
}
|
||||
target_startup_msg(_T("Internal error"), _T("eeprom_i2c_set: Unhandled case."));
|
||||
uae_restart(1, NULL);
|
||||
return 0;
|
||||
i2c->state = RECEIVING_BIT7;
|
||||
if (data != 0) {
|
||||
#if EEPROM_LOG > 1
|
||||
write_log(_T("I2C NACKED\n"));
|
||||
#endif
|
||||
i2c->state = SENT_NACK;
|
||||
//i2c_nack(i2c->bus);
|
||||
} else {
|
||||
;
|
||||
#if EEPROM_LOG > 1
|
||||
write_log(_T("I2C ACKED\n"));
|
||||
#endif
|
||||
}
|
||||
return bitbang_i2c_ret(i2c, 1);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
int i2c_set(void *i2c, int line, int level)
|
||||
{
|
||||
return eeprom_i2c_set(i2c, line, level);
|
||||
}
|
||||
|
||||
void eeprom_reset(void *fdv)
|
||||
|
@ -248,9 +524,9 @@ void eeprom_reset(void *fdv)
|
|||
|
||||
void *eeprom_new(uae_u8 *memory, int size, struct zfile *zf)
|
||||
{
|
||||
bitbang_i2c_interface *s;
|
||||
bitbang_i2c_interface *s;
|
||||
|
||||
s = xcalloc(bitbang_i2c_interface, 1);
|
||||
s = xcalloc(bitbang_i2c_interface, 1);
|
||||
|
||||
eeprom_reset(s);
|
||||
|
||||
|
@ -261,7 +537,27 @@ void *eeprom_new(uae_u8 *memory, int size, struct zfile *zf)
|
|||
s->device_address = 0xa0;
|
||||
s->device_address_mask = 0xf0;
|
||||
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *i2c_new(uae_u8 device_address, int size, uae_u8 (*read_func)(uae_u8 addr), void (*write_func)(uae_u8 addr, uae_u8 v))
|
||||
{
|
||||
bitbang_i2c_interface *s;
|
||||
|
||||
s = xcalloc(bitbang_i2c_interface, 1);
|
||||
|
||||
eeprom_reset(s);
|
||||
|
||||
s->memory = NULL;
|
||||
s->size = size;
|
||||
s->zf = NULL;
|
||||
s->addressbitmask = 0;
|
||||
s->device_address = 0xa2;
|
||||
s->device_address_mask = 0xff;
|
||||
|
||||
s->read_func = read_func;
|
||||
s->write_func = write_func;
|
||||
return s;
|
||||
}
|
||||
|
||||
void eeprom_free(void *fdv)
|
||||
|
@ -269,3 +565,236 @@ void eeprom_free(void *fdv)
|
|||
struct bitbang_i2c_interface *i2c = (bitbang_i2c_interface*)fdv;
|
||||
xfree(i2c);
|
||||
}
|
||||
|
||||
void i2c_free(void *fdv)
|
||||
{
|
||||
eeprom_free(fdv);
|
||||
}
|
||||
|
||||
void i2c_reset(void *fdv)
|
||||
{
|
||||
struct bitbang_i2c_interface *i2c = (bitbang_i2c_interface*)fdv;
|
||||
eeprom_reset(i2c);
|
||||
}
|
||||
|
||||
/* FLASH */
|
||||
|
||||
struct flashrom_data
|
||||
{
|
||||
uae_u8 *rom;
|
||||
int flashsize;
|
||||
int allocsize;
|
||||
int mask;
|
||||
int state;
|
||||
int modified;
|
||||
int sectorsize;
|
||||
uae_u8 devicecode, mfgcode;
|
||||
int flags;
|
||||
struct zfile *zf;
|
||||
};
|
||||
|
||||
void *flash_new(uae_u8 *rom, int flashsize, int allocsize, uae_u8 mfgcode, uae_u8 devcode, struct zfile *zf, int flags)
|
||||
{
|
||||
struct flashrom_data *fd = xcalloc(struct flashrom_data, 1);
|
||||
fd->flashsize = flashsize;
|
||||
fd->allocsize = allocsize;
|
||||
fd->mask = fd->flashsize - 1;
|
||||
fd->zf = zf;
|
||||
fd->rom = rom;
|
||||
fd->flags = flags;
|
||||
fd->devicecode = devcode;
|
||||
fd->mfgcode = mfgcode;
|
||||
fd->sectorsize = devcode == 0x20 ? 16384 : 65536;
|
||||
return fd;
|
||||
}
|
||||
|
||||
void flash_free(void *fdv)
|
||||
{
|
||||
struct flashrom_data *fd = (struct flashrom_data*)fdv;
|
||||
if (!fd)
|
||||
return;
|
||||
if (fd->zf && fd->modified) {
|
||||
zfile_fseek(fd->zf, 0, SEEK_SET);
|
||||
if (fd->flags & FLASHROM_EVERY_OTHER_BYTE) {
|
||||
zfile_fseek(fd->zf, (fd->flags & FLASHROM_EVERY_OTHER_BYTE_ODD) ? 1 : 0, SEEK_SET);
|
||||
for (int i = 0; i < fd->allocsize; i++) {
|
||||
zfile_fwrite(&fd->rom[i * 2], 1, 1, fd->zf);
|
||||
zfile_fseek(fd->zf, 1, SEEK_CUR);
|
||||
}
|
||||
} else {
|
||||
zfile_fwrite(fd->rom, fd->allocsize, 1, fd->zf);
|
||||
}
|
||||
}
|
||||
xfree(fdv);
|
||||
}
|
||||
|
||||
int flash_size(void *fdv)
|
||||
{
|
||||
struct flashrom_data *fd = (struct flashrom_data*)fdv;
|
||||
if (!fd)
|
||||
return 0;
|
||||
return fd->flashsize;
|
||||
}
|
||||
|
||||
bool flash_active(void *fdv, uaecptr addr)
|
||||
{
|
||||
struct flashrom_data *fd = (struct flashrom_data*)fdv;
|
||||
if (!fd)
|
||||
return false;
|
||||
return fd->state != 0;
|
||||
}
|
||||
|
||||
bool flash_write(void *fdv, uaecptr addr, uae_u8 v)
|
||||
{
|
||||
struct flashrom_data *fd = (struct flashrom_data*)fdv;
|
||||
int oldstate;
|
||||
uae_u32 addr2;
|
||||
int other_byte_mult = 1;
|
||||
|
||||
if (!fd)
|
||||
return false;
|
||||
|
||||
if (fd->flags & FLASHROM_EVERY_OTHER_BYTE) {
|
||||
addr >>= 1;
|
||||
other_byte_mult = 2;
|
||||
}
|
||||
|
||||
oldstate = fd->state;
|
||||
|
||||
#if FLASH_LOG > 1
|
||||
write_log(_T("flash write %08x %02x (%d) PC=%08x\n"), addr, v, fd->state, m68k_getpc());
|
||||
#endif
|
||||
|
||||
addr &= fd->mask;
|
||||
addr2 = addr & 0xffff;
|
||||
|
||||
if (fd->state >= 7 && fd->state < 7 + 64) {
|
||||
if (!(fd->flags & FLASHROM_PARALLEL_EEPROM)) {
|
||||
fd->state = 100;
|
||||
} else {
|
||||
fd->state++;
|
||||
if (fd->state >= 7 + 64)
|
||||
fd->state = 100;
|
||||
}
|
||||
if (addr >= fd->allocsize)
|
||||
return false;
|
||||
if (fd->rom[addr * other_byte_mult] != v)
|
||||
fd->modified = 1;
|
||||
fd->rom[addr * other_byte_mult] = v;
|
||||
gui_flicker_led (LED_MD, 0, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (v == 0xf0) {
|
||||
fd->state = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// unlock
|
||||
if (addr2 == 0x5555 && fd->state <= 2 && v == 0xaa)
|
||||
fd->state = 1;
|
||||
if (addr2 == 0x2aaa && fd->state == 1 && v == 0x55)
|
||||
fd->state = 2;
|
||||
|
||||
// autoselect
|
||||
if (addr2 == 0x5555 && fd->state == 2 && v == 0x90)
|
||||
fd->state = 3;
|
||||
|
||||
// program
|
||||
if (addr2 == 0x5555 && fd->state == 2 && v == 0xa0)
|
||||
fd->state = 7;
|
||||
|
||||
// chip/sector erase
|
||||
if (addr2 == 0x5555 && fd->state == 2 && v == 0x80)
|
||||
fd->state = 4;
|
||||
if (addr2 == 0x5555 && fd->state == 4 && v == 0xaa)
|
||||
fd->state = 5;
|
||||
if (addr2 == 0x2aaa && fd->state == 5 && v == 0x55)
|
||||
fd->state = 6;
|
||||
if (addr2 == 0x5555 && fd->state == 6 && v == 0x10) {
|
||||
for (int i = 0; i < fd->allocsize; i++) {
|
||||
fd->rom[i * other_byte_mult] = 0xff;
|
||||
}
|
||||
fd->state = 200;
|
||||
fd->modified = 1;
|
||||
#if FLASH_LOG
|
||||
write_log(_T("flash chip erased\n"), addr);
|
||||
#endif
|
||||
gui_flicker_led (LED_MD, 0, 2);
|
||||
return true;
|
||||
} else if (fd->state == 6 && v == 0x30) {
|
||||
int saddr = addr & ~(fd->sectorsize - 1);
|
||||
if (saddr < fd->allocsize) {
|
||||
for (int i = 0; i < fd->sectorsize; i++) {
|
||||
fd->rom[(saddr + i) * other_byte_mult] = 0xff;
|
||||
}
|
||||
}
|
||||
fd->state = 200;
|
||||
fd->modified = 1;
|
||||
#if FLASH_LOG
|
||||
write_log(_T("flash sector %d erased (%08x)\n"), saddr / fd->sectorsize, addr);
|
||||
#endif
|
||||
gui_flicker_led (LED_MD, 0, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fd->state == oldstate)
|
||||
fd->state = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uae_u32 flash_read(void *fdv, uaecptr addr)
|
||||
{
|
||||
struct flashrom_data *fd = (struct flashrom_data*)fdv;
|
||||
uae_u8 v = 0xff;
|
||||
int other_byte_mult = 1;
|
||||
#if FLASH_LOG > 1
|
||||
uaecptr oaddr = addr;
|
||||
#endif
|
||||
|
||||
if (!fd)
|
||||
return 0;
|
||||
|
||||
if (fd->flags & FLASHROM_EVERY_OTHER_BYTE) {
|
||||
addr >>= 1;
|
||||
other_byte_mult = 2;
|
||||
}
|
||||
|
||||
addr &= fd->mask;
|
||||
if (fd->state == 3) {
|
||||
uae_u8 a = addr & 0xff;
|
||||
if (a == 0)
|
||||
v = fd->mfgcode;
|
||||
if (a == 1)
|
||||
v = fd->devicecode;
|
||||
if (a == 2)
|
||||
v = 0x00;
|
||||
gui_flicker_led (LED_MD, 0, 1);
|
||||
} else if (fd->state >= 200) {
|
||||
v = 0;
|
||||
if (fd->state & 1)
|
||||
v ^= 0x40;
|
||||
fd->state++;
|
||||
if (fd->state >= 210)
|
||||
fd->state = 0;
|
||||
v |= 0x08;
|
||||
} else if (fd->state > 7) {
|
||||
v = (fd->rom[addr * other_byte_mult] & 0x80) ^ 0x80;
|
||||
if (fd->state & 1)
|
||||
v ^= 0x40;
|
||||
fd->state++;
|
||||
if (fd->state >= 110)
|
||||
fd->state = 0;
|
||||
} else {
|
||||
fd->state = 0;
|
||||
if (addr >= fd->allocsize)
|
||||
v = 0xff;
|
||||
else
|
||||
v = fd->rom[addr * other_byte_mult];
|
||||
}
|
||||
#if FLASH_LOG > 1
|
||||
write_log(_T("flash read %08x = %02X (%d) PC=%08x\n"), oaddr, v, fd->state, m68k_getpc());
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
195
src/gayle.cpp
195
src/gayle.cpp
|
@ -23,6 +23,8 @@
|
|||
#include "savestate.h"
|
||||
#include "uae.h"
|
||||
#include "threaddep/thread.h"
|
||||
#include "blkdev.h"
|
||||
#include "scsi.h"
|
||||
#include "ide.h"
|
||||
#include "autoconf.h"
|
||||
#include "rommgr.h"
|
||||
|
@ -147,12 +149,20 @@ static int pcmcia_readonly;
|
|||
static int pcmcia_type;
|
||||
static uae_u8 pcmcia_configuration[20];
|
||||
static int pcmcia_configured;
|
||||
static int pcmcia_delayed_insert, pcmcia_delayed_insert_count;
|
||||
static int external_card_int;
|
||||
|
||||
static int gayle_id_cnt;
|
||||
static uae_u8 gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg;
|
||||
static int ide_splitter;
|
||||
|
||||
static struct ide_thread_state gayle_its;
|
||||
static struct ide_thread_state gayle_its, pcmcia_its;
|
||||
|
||||
static bool ne2000_pcmcia_irq;
|
||||
|
||||
static int dataflyer_state;
|
||||
static int dataflyer_disable_irq;
|
||||
static uae_u8 dataflyer_byte;
|
||||
|
||||
static void gayle_reset(int hardreset);
|
||||
static void gayle_map_pcmcia(void);
|
||||
|
@ -179,6 +189,10 @@ static uae_u8 checkgayleideirq (void)
|
|||
int i;
|
||||
bool irq = false;
|
||||
|
||||
if (dataflyer_disable_irq) {
|
||||
gayle_irq &= ~GAYLE_IRQ_IDE;
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (idedrive[i]) {
|
||||
if (!(idedrive[i]->regs.ide_devcon & 2) && (idedrive[i]->irq || (idedrive[i + 2] && idedrive[i + 2]->irq)))
|
||||
|
@ -193,6 +207,11 @@ static uae_u8 checkgayleideirq (void)
|
|||
return irq ? GAYLE_IRQ_IDE : 0;
|
||||
}
|
||||
|
||||
bool isideint(void)
|
||||
{
|
||||
return checkgayleideirq() != 0;
|
||||
}
|
||||
|
||||
static void rethink_gayle (void)
|
||||
{
|
||||
int lev2 = 0;
|
||||
|
@ -480,11 +499,113 @@ addrbank gayle_bank = {
|
|||
ABFLAG_IO, S_READ, S_WRITE
|
||||
};
|
||||
|
||||
void gayle_dataflyer_enable(bool enable)
|
||||
{
|
||||
if (!enable) {
|
||||
dataflyer_state = 0;
|
||||
dataflyer_disable_irq = 0;
|
||||
return;
|
||||
}
|
||||
dataflyer_state = 1;
|
||||
}
|
||||
|
||||
static bool isdataflyerscsiplus(uaecptr addr, uae_u32 *v, int size)
|
||||
{
|
||||
if (!dataflyer_state)
|
||||
return false;
|
||||
uaecptr addrmask = addr & 0xffff;
|
||||
if (addrmask >= GAYLE_IRQ_4000 && addrmask <= GAYLE_IRQ_4000 + 1 && currprefs.cs_ide == IDE_A4000)
|
||||
return false;
|
||||
uaecptr addrbase = (addr & ~0xff) & ~0x1020;
|
||||
int reg = ((addr & 0xffff) & ~0x2020) >> 2;
|
||||
if (reg >= IDE_SECONDARY) {
|
||||
reg &= ~IDE_SECONDARY;
|
||||
if (reg >= 6) // normal IDE registers
|
||||
return false;
|
||||
if (size < 0) {
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // 53C80 fake dma port
|
||||
soft_scsi_put(addrbase | 8, 1, *v);
|
||||
break;
|
||||
case 3:
|
||||
dataflyer_byte = *v;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // 53C80 fake dma port
|
||||
*v = soft_scsi_get(addrbase | 8, 1);
|
||||
break;
|
||||
case 3:
|
||||
*v = 0;
|
||||
if (ide_irq_check(idedrive[0], false))
|
||||
*v = dataflyer_byte;
|
||||
break;
|
||||
case 4: // select SCSI
|
||||
dataflyer_disable_irq = 1;
|
||||
dataflyer_state |= 2;
|
||||
break;
|
||||
case 5: // select IDE
|
||||
dataflyer_disable_irq = 1;
|
||||
dataflyer_state &= ~2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (size < 0)
|
||||
write_log(_T("SECONDARY BASE PUT(%d) %08x %08x PC=%08x\n"), -size, addr, *v, M68K_GETPC);
|
||||
else
|
||||
write_log(_T("SECONDARY BASE GET(%d) %08x PC=%08x\n"), size, addr, M68K_GETPC);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
if (!(dataflyer_state & 2))
|
||||
return false;
|
||||
if (size < 0)
|
||||
soft_scsi_put(addrbase | reg, -size, *v);
|
||||
else
|
||||
*v = soft_scsi_get(addrbase | reg, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
//static bool isa4000t (uaecptr *paddr)
|
||||
//{
|
||||
// if (!is_a4000t_scsi())
|
||||
// return false;
|
||||
// uaecptr addr = *paddr;
|
||||
// if ((addr & 0xffff) >= (GAYLE_BASE_4000 & 0xffff))
|
||||
// return false;
|
||||
// addr &= 0xff;
|
||||
// *paddr = addr;
|
||||
// return true;
|
||||
//}
|
||||
|
||||
static uae_u32 REGPARAM2 gayle_lget (uaecptr addr)
|
||||
{
|
||||
struct ide_hdf *ide = NULL;
|
||||
int ide_reg;
|
||||
uae_u32 v;
|
||||
#ifdef NCR
|
||||
if (is_a4000t_scsi() && (addr & 0xffff) == 0x3000)
|
||||
return 0xffffffff; // NCR DIP BANK
|
||||
if (isdataflyerscsiplus(addr, &v, 4)) {
|
||||
return v;
|
||||
}
|
||||
if (isa4000t (&addr)) {
|
||||
if (addr >= NCR_ALT_OFFSET) {
|
||||
addr &= NCR_MASK;
|
||||
v = (ncr710_io_bget_a4000t(addr + 3) << 0) | (ncr710_io_bget_a4000t(addr + 2) << 8) |
|
||||
(ncr710_io_bget_a4000t(addr + 1) << 16) | (ncr710_io_bget_a4000t(addr + 0) << 24);
|
||||
} else if (addr >= NCR_OFFSET) {
|
||||
addr &= NCR_MASK;
|
||||
v = (ncr710_io_bget_a4000t(addr + 3) << 0) | (ncr710_io_bget_a4000t(addr + 2) << 8) |
|
||||
(ncr710_io_bget_a4000t(addr + 1) << 16) | (ncr710_io_bget_a4000t(addr + 0) << 24);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
ide_reg = get_gayle_ide_reg (addr, &ide);
|
||||
if (ide_reg == IDE_DATA) {
|
||||
v = ide_get_data (ide) << 16;
|
||||
|
@ -500,6 +621,20 @@ static uae_u32 REGPARAM2 gayle_wget (uaecptr addr)
|
|||
struct ide_hdf *ide = NULL;
|
||||
int ide_reg;
|
||||
uae_u32 v;
|
||||
#ifdef NCR
|
||||
if (is_a4000t_scsi() && (addr & (0xffff - 1)) == 0x3000)
|
||||
return 0xffff; // NCR DIP BANK
|
||||
if (isdataflyerscsiplus(addr, &v, 2)) {
|
||||
return v;
|
||||
}
|
||||
if (isa4000t(&addr)) {
|
||||
if (addr >= NCR_OFFSET) {
|
||||
addr &= NCR_MASK;
|
||||
v = (ncr710_io_bget_a4000t(addr) << 8) | ncr710_io_bget_a4000t(addr + 1);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
ide_reg = get_gayle_ide_reg (addr, &ide);
|
||||
if (ide_reg == IDE_DATA) {
|
||||
v = ide_get_data (ide);
|
||||
|
@ -512,6 +647,20 @@ static uae_u32 REGPARAM2 gayle_wget (uaecptr addr)
|
|||
static uae_u32 REGPARAM2 gayle_bget (uaecptr addr)
|
||||
{
|
||||
uae_u32 v;
|
||||
#ifdef NCR
|
||||
if (is_a4000t_scsi() && (addr & (0xffff - 3)) == 0x3000)
|
||||
return 0xff; // NCR DIP BANK
|
||||
if (isdataflyerscsiplus(addr, &v, 1)) {
|
||||
return v;
|
||||
}
|
||||
if (isa4000t(&addr)) {
|
||||
if (addr >= NCR_OFFSET) {
|
||||
addr &= NCR_MASK;
|
||||
return ncr710_io_bget_a4000t(addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
v = gayle_read (addr);
|
||||
return v;
|
||||
}
|
||||
|
@ -520,6 +669,25 @@ static void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value)
|
|||
{
|
||||
struct ide_hdf *ide = NULL;
|
||||
int ide_reg;
|
||||
if (isdataflyerscsiplus(addr, &value, -4)) {
|
||||
return;
|
||||
}
|
||||
//if (isa4000t(&addr)) {
|
||||
// if (addr >= NCR_ALT_OFFSET) {
|
||||
// addr &= NCR_MASK;
|
||||
// ncr710_io_bput_a4000t(addr + 3, value >> 0);
|
||||
// ncr710_io_bput_a4000t(addr + 2, value >> 8);
|
||||
// ncr710_io_bput_a4000t(addr + 1, value >> 16);
|
||||
// ncr710_io_bput_a4000t(addr + 0, value >> 24);
|
||||
// } else if (addr >= NCR_OFFSET) {
|
||||
// addr &= NCR_MASK;
|
||||
// ncr710_io_bput_a4000t(addr + 3, value >> 0);
|
||||
// ncr710_io_bput_a4000t(addr + 2, value >> 8);
|
||||
// ncr710_io_bput_a4000t(addr + 1, value >> 16);
|
||||
// ncr710_io_bput_a4000t(addr + 0, value >> 24);
|
||||
// }
|
||||
// return;
|
||||
//}
|
||||
ide_reg = get_gayle_ide_reg (addr, &ide);
|
||||
if (ide_reg == IDE_DATA) {
|
||||
ide_put_data (ide, value >> 16);
|
||||
|
@ -533,6 +701,19 @@ static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value)
|
|||
{
|
||||
struct ide_hdf *ide = NULL;
|
||||
int ide_reg;
|
||||
#ifdef NCR
|
||||
if (isdataflyerscsiplus(addr, &value, -2)) {
|
||||
return;
|
||||
}
|
||||
if (isa4000t(&addr)) {
|
||||
if (addr >= NCR_OFFSET) {
|
||||
addr &= NCR_MASK;
|
||||
ncr710_io_bput_a4000t(addr, value >> 8);
|
||||
ncr710_io_bput_a4000t(addr + 1, value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ide_reg = get_gayle_ide_reg (addr, &ide);
|
||||
if (ide_reg == IDE_DATA) {
|
||||
ide_put_data (ide, value);
|
||||
|
@ -544,6 +725,18 @@ static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value)
|
|||
|
||||
static void REGPARAM2 gayle_bput (uaecptr addr, uae_u32 value)
|
||||
{
|
||||
#ifdef NCR
|
||||
if (isdataflyerscsiplus(addr, &value, -1)) {
|
||||
return;
|
||||
}
|
||||
if (isa4000t(&addr)) {
|
||||
if (addr >= NCR_OFFSET) {
|
||||
addr &= NCR_MASK;
|
||||
ncr710_io_bput_a4000t(addr, value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
gayle_write (addr, value);
|
||||
}
|
||||
|
||||
|
|
30
src/ide.cpp
30
src/ide.cpp
|
@ -252,6 +252,36 @@ static bool ide_interrupt_do (struct ide_hdf *ide)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ide_drq_check(struct ide_hdf* idep)
|
||||
{
|
||||
for (int i = 0; idep && i < 2; i++) {
|
||||
struct ide_hdf* ide = i == 0 ? idep : idep->pair;
|
||||
if (ide) {
|
||||
if (ide->regs.ide_status & IDE_STATUS_DRQ)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ide_irq_check(struct ide_hdf* idep, bool edge_triggered)
|
||||
{
|
||||
for (int i = 0; idep && i < 2; i++) {
|
||||
struct ide_hdf* ide = i == 0 ? idep : idep->pair;
|
||||
if (ide->irq) {
|
||||
if (edge_triggered) {
|
||||
if (ide->irq_new) {
|
||||
ide->irq_new = false;
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ide_interrupt_hsync(struct ide_hdf *idep)
|
||||
{
|
||||
bool irq = false;
|
||||
|
|
70
src/scsi.cpp
70
src/scsi.cpp
|
@ -562,23 +562,23 @@ struct scsi_data *scsi_alloc_cd(int id, int unitnum, bool atapi, int uae_unitnum
|
|||
return sd;
|
||||
}
|
||||
|
||||
struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool readonly, int uae_unitnum)
|
||||
{
|
||||
struct scsi_data_tape *tape;
|
||||
tape = tape_alloc (id, tape_directory, readonly);
|
||||
if (!tape)
|
||||
return NULL;
|
||||
struct scsi_data *sd = xcalloc (struct scsi_data, 1);
|
||||
sd->id = id;
|
||||
sd->nativescsiunit = -1;
|
||||
sd->cd_emu_unit = -1;
|
||||
sd->blocksize = tape->blocksize;
|
||||
sd->tape = tape;
|
||||
sd->device_type = UAEDEV_TAPE;
|
||||
sd->uae_unitnum = uae_unitnum;
|
||||
allocscsibuf(sd);
|
||||
return sd;
|
||||
}
|
||||
//struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool readonly, int uae_unitnum)
|
||||
//{
|
||||
// struct scsi_data_tape *tape;
|
||||
// tape = tape_alloc (id, tape_directory, readonly);
|
||||
// if (!tape)
|
||||
// return NULL;
|
||||
// struct scsi_data *sd = xcalloc (struct scsi_data, 1);
|
||||
// sd->id = id;
|
||||
// sd->nativescsiunit = -1;
|
||||
// sd->cd_emu_unit = -1;
|
||||
// sd->blocksize = tape->blocksize;
|
||||
// sd->tape = tape;
|
||||
// sd->device_type = UAEDEV_TAPE;
|
||||
// sd->uae_unitnum = uae_unitnum;
|
||||
// allocscsibuf(sd);
|
||||
// return sd;
|
||||
//}
|
||||
|
||||
struct scsi_data *scsi_alloc_native(int id, int nativeunit)
|
||||
{
|
||||
|
@ -708,8 +708,8 @@ int add_scsi_device(struct scsi_data **sd, int ch, struct uaedev_config_info *ci
|
|||
{
|
||||
if (ci->type == UAEDEV_CD)
|
||||
return add_scsi_cd(sd, ch, ci->device_emu_unit);
|
||||
else if (ci->type == UAEDEV_TAPE)
|
||||
return add_scsi_tape(sd, ch, ci->rootdir, ci->readonly);
|
||||
//else if (ci->type == UAEDEV_TAPE)
|
||||
// return add_scsi_tape(sd, ch, ci->rootdir, ci->readonly);
|
||||
else if (ci->type == UAEDEV_HDF)
|
||||
return add_scsi_hd(sd, ch, NULL, ci);
|
||||
return 0;
|
||||
|
@ -1415,23 +1415,23 @@ uae_u8 apollo_scsi_bget(uaecptr addr, uae_u32 config)
|
|||
return v;
|
||||
}
|
||||
|
||||
void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
|
||||
//void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
|
||||
|
||||
void apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
|
||||
{
|
||||
if (ch < 0) {
|
||||
generic_soft_scsi_add(-1, ci, rc, NONCR_APOLLO, -1, -1, ROMTYPE_APOLLO);
|
||||
// make sure IDE side is also initialized
|
||||
struct uaedev_config_info ci2 = { 0 };
|
||||
apollo_add_ide_unit(-1, &ci2, rc);
|
||||
} else {
|
||||
if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST) {
|
||||
apollo_add_ide_unit(ch, ci, rc);
|
||||
} else {
|
||||
generic_soft_scsi_add(ch, ci, rc, NONCR_APOLLO, -1, -1, ROMTYPE_APOLLO);
|
||||
}
|
||||
}
|
||||
}
|
||||
//void apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
|
||||
//{
|
||||
// if (ch < 0) {
|
||||
// generic_soft_scsi_add(-1, ci, rc, NONCR_APOLLO, -1, -1, ROMTYPE_APOLLO);
|
||||
// // make sure IDE side is also initialized
|
||||
// struct uaedev_config_info ci2 = { 0 };
|
||||
// apollo_add_ide_unit(-1, &ci2, rc);
|
||||
// } else {
|
||||
// if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST) {
|
||||
// apollo_add_ide_unit(ch, ci, rc);
|
||||
// } else {
|
||||
// generic_soft_scsi_add(ch, ci, rc, NONCR_APOLLO, -1, -1, ROMTYPE_APOLLO);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg);
|
||||
void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue