clang-format in src/mem/
This commit is contained in:
@@ -30,14 +30,11 @@
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/plat.h>
|
||||
|
||||
#define FLAG_WORD 4
|
||||
#define FLAG_BXB 2
|
||||
#define FLAG_INV_A16 1
|
||||
|
||||
#define FLAG_WORD 4
|
||||
#define FLAG_BXB 2
|
||||
#define FLAG_INV_A16 1
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
BLOCK_MAIN1,
|
||||
BLOCK_MAIN2,
|
||||
BLOCK_DATA1,
|
||||
@@ -46,88 +43,80 @@ enum
|
||||
BLOCKS_NUM
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CMD_SET_READ = 0x00,
|
||||
enum {
|
||||
CMD_SET_READ = 0x00,
|
||||
CMD_READ_SIGNATURE = 0x90,
|
||||
CMD_ERASE = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0x20,
|
||||
CMD_ERASE_VERIFY = 0xA0,
|
||||
CMD_PROGRAM = 0x40,
|
||||
CMD_ERASE = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0x20,
|
||||
CMD_ERASE_VERIFY = 0xA0,
|
||||
CMD_PROGRAM = 0x40,
|
||||
CMD_PROGRAM_VERIFY = 0xC0,
|
||||
CMD_RESET = 0xFF
|
||||
CMD_RESET = 0xFF
|
||||
};
|
||||
|
||||
typedef struct flash_t {
|
||||
uint8_t command, pad,
|
||||
pad0, pad1,
|
||||
*array;
|
||||
|
||||
typedef struct flash_t
|
||||
{
|
||||
uint8_t command, pad,
|
||||
pad0, pad1,
|
||||
*array;
|
||||
|
||||
mem_mapping_t mapping, mapping_h[2];
|
||||
mem_mapping_t mapping, mapping_h[2];
|
||||
} flash_t;
|
||||
|
||||
|
||||
static char flash_path[1024];
|
||||
|
||||
static char flash_path[1024];
|
||||
|
||||
static uint8_t
|
||||
flash_read(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *) p;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= biosmask;
|
||||
|
||||
switch (dev->command) {
|
||||
case CMD_ERASE_VERIFY:
|
||||
case CMD_PROGRAM_VERIFY:
|
||||
case CMD_RESET:
|
||||
case CMD_SET_READ:
|
||||
ret = dev->array[addr];
|
||||
break;
|
||||
case CMD_ERASE_VERIFY:
|
||||
case CMD_PROGRAM_VERIFY:
|
||||
case CMD_RESET:
|
||||
case CMD_SET_READ:
|
||||
ret = dev->array[addr];
|
||||
break;
|
||||
|
||||
case CMD_READ_SIGNATURE:
|
||||
if (addr == 0x00000)
|
||||
ret = 0x31; /* CATALYST */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xB4; /* 28F010 */
|
||||
break;
|
||||
case CMD_READ_SIGNATURE:
|
||||
if (addr == 0x00000)
|
||||
ret = 0x31; /* CATALYST */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xB4; /* 28F010 */
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
flash_readw(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *)p;
|
||||
flash_t *dev = (flash_t *) p;
|
||||
uint16_t *q;
|
||||
|
||||
addr &= biosmask;
|
||||
|
||||
q = (uint16_t *)&(dev->array[addr]);
|
||||
q = (uint16_t *) &(dev->array[addr]);
|
||||
|
||||
return *q;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
flash_readl(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *)p;
|
||||
flash_t *dev = (flash_t *) p;
|
||||
uint32_t *q;
|
||||
|
||||
addr &= biosmask;
|
||||
|
||||
q = (uint32_t *)&(dev->array[addr]);
|
||||
q = (uint32_t *) &(dev->array[addr]);
|
||||
|
||||
return *q;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flash_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
@@ -136,55 +125,51 @@ flash_write(uint32_t addr, uint8_t val, void *p)
|
||||
addr &= biosmask;
|
||||
|
||||
switch (dev->command) {
|
||||
case CMD_ERASE:
|
||||
if (val == CMD_ERASE_CONFIRM)
|
||||
memset(dev->array, 0xff, biosmask + 1);
|
||||
break;
|
||||
case CMD_ERASE:
|
||||
if (val == CMD_ERASE_CONFIRM)
|
||||
memset(dev->array, 0xff, biosmask + 1);
|
||||
break;
|
||||
|
||||
case CMD_PROGRAM:
|
||||
dev->array[addr] = val;
|
||||
break;
|
||||
case CMD_PROGRAM:
|
||||
dev->array[addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->command = val;
|
||||
break;
|
||||
default:
|
||||
dev->command = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flash_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flash_writel(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
catalyst_flash_add_mappings(flash_t *dev)
|
||||
{
|
||||
memcpy(dev->array, rom, biosmask + 1);
|
||||
|
||||
mem_mapping_add(&dev->mapping, 0xe0000, 0x20000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
|
||||
mem_mapping_add(&(dev->mapping_h[0]), 0xfffc0000, 0x20000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
mem_mapping_add(&(dev->mapping_h[1]), 0xfffe0000, 0x20000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
catalyst_flash_reset(void *priv)
|
||||
{
|
||||
@@ -193,11 +178,10 @@ catalyst_flash_reset(void *priv)
|
||||
dev->command = CMD_RESET;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
catalyst_flash_init(const device_t *info)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
flash_t *dev;
|
||||
|
||||
dev = malloc(sizeof(flash_t));
|
||||
@@ -217,19 +201,18 @@ catalyst_flash_init(const device_t *info)
|
||||
|
||||
f = nvr_fopen(flash_path, "rb");
|
||||
if (f) {
|
||||
(void) !fread(dev->array, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
(void) !fread(dev->array, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
catalyst_flash_close(void *p)
|
||||
{
|
||||
FILE *f;
|
||||
flash_t *dev = (flash_t *)p;
|
||||
FILE *f;
|
||||
flash_t *dev = (flash_t *) p;
|
||||
|
||||
f = nvr_fopen(flash_path, "wb");
|
||||
fwrite(dev->array, 0x20000, 1, f);
|
||||
@@ -241,17 +224,16 @@ catalyst_flash_close(void *p)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t catalyst_flash_device = {
|
||||
.name = "Catalyst 28F010-D Flash BIOS",
|
||||
.name = "Catalyst 28F010-D Flash BIOS",
|
||||
.internal_name = "catalyst_flash",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = catalyst_flash_init,
|
||||
.close = catalyst_flash_close,
|
||||
.reset = catalyst_flash_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = catalyst_flash_init,
|
||||
.close = catalyst_flash_close,
|
||||
.reset = catalyst_flash_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
@@ -24,36 +24,32 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/i2c.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
void *i2c;
|
||||
uint8_t addr, *data, writable;
|
||||
void *i2c;
|
||||
uint8_t addr, *data, writable;
|
||||
|
||||
uint32_t addr_mask, addr_register;
|
||||
uint8_t addr_len, addr_pos;
|
||||
uint32_t addr_mask, addr_register;
|
||||
uint8_t addr_len, addr_pos;
|
||||
} i2c_eeprom_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_I2C_EEPROM_LOG
|
||||
int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG;
|
||||
|
||||
|
||||
static void
|
||||
i2c_eeprom_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (i2c_eeprom_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define i2c_eeprom_log(fmt, ...)
|
||||
# define i2c_eeprom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t
|
||||
i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
{
|
||||
@@ -62,19 +58,18 @@ i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr);
|
||||
|
||||
if (!read) {
|
||||
dev->addr_pos = 0;
|
||||
dev->addr_register = (addr << dev->addr_len) & dev->addr_mask;
|
||||
dev->addr_pos = 0;
|
||||
dev->addr_register = (addr << dev->addr_len) & dev->addr_mask;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
|
||||
uint8_t ret = dev->data[dev->addr_register];
|
||||
uint8_t ret = dev->data[dev->addr_register];
|
||||
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret);
|
||||
dev->addr_register++;
|
||||
@@ -83,33 +78,31 @@ i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
{
|
||||
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
|
||||
|
||||
if (dev->addr_pos < dev->addr_len) {
|
||||
dev->addr_register <<= 8;
|
||||
dev->addr_register |= data;
|
||||
dev->addr_register &= (1 << dev->addr_len) - 1;
|
||||
dev->addr_register |= addr << dev->addr_len;
|
||||
dev->addr_register &= dev->addr_mask;
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: write(address, %06X)\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register);
|
||||
dev->addr_pos += 8;
|
||||
dev->addr_register <<= 8;
|
||||
dev->addr_register |= data;
|
||||
dev->addr_register &= (1 << dev->addr_len) - 1;
|
||||
dev->addr_register |= addr << dev->addr_len;
|
||||
dev->addr_register &= dev->addr_mask;
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: write(address, %06X)\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register);
|
||||
dev->addr_pos += 8;
|
||||
} else {
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable);
|
||||
if (dev->writable)
|
||||
dev->data[dev->addr_register] = data;
|
||||
dev->addr_register++;
|
||||
dev->addr_register &= dev->addr_mask; /* roll-over */
|
||||
return dev->writable;
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable);
|
||||
if (dev->writable)
|
||||
dev->data[dev->addr_register] = data;
|
||||
dev->addr_register++;
|
||||
dev->addr_register &= dev->addr_mask; /* roll-over */
|
||||
return dev->writable;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i2c_eeprom_stop(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
@@ -120,17 +113,15 @@ i2c_eeprom_stop(void *bus, uint8_t addr, void *priv)
|
||||
dev->addr_pos = 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
log2i(uint32_t i)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
while ((i >>= 1))
|
||||
ret++;
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t writable)
|
||||
{
|
||||
@@ -140,17 +131,17 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w
|
||||
/* Round size up to the next power of 2. */
|
||||
uint32_t pow_size = 1 << log2i(size);
|
||||
if (pow_size < size)
|
||||
size = pow_size << 1;
|
||||
size = pow_size << 1;
|
||||
size &= 0x7fffff; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits */
|
||||
|
||||
i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable);
|
||||
|
||||
dev->i2c = i2c;
|
||||
dev->addr = addr;
|
||||
dev->data = data;
|
||||
dev->i2c = i2c;
|
||||
dev->addr = addr;
|
||||
dev->data = data;
|
||||
dev->writable = writable;
|
||||
|
||||
dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */
|
||||
dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */
|
||||
dev->addr_mask = size - 1;
|
||||
|
||||
i2c_sethandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev);
|
||||
@@ -158,7 +149,6 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
i2c_eeprom_close(void *dev_handle)
|
||||
{
|
||||
|
@@ -30,14 +30,11 @@
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/plat.h>
|
||||
|
||||
#define FLAG_WORD 4
|
||||
#define FLAG_BXB 2
|
||||
#define FLAG_INV_A16 1
|
||||
|
||||
#define FLAG_WORD 4
|
||||
#define FLAG_BXB 2
|
||||
#define FLAG_INV_A16 1
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
BLOCK_MAIN1,
|
||||
BLOCK_MAIN2,
|
||||
BLOCK_MAIN3,
|
||||
@@ -48,239 +45,231 @@ enum
|
||||
BLOCKS_NUM
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CMD_READ_ARRAY = 0xff,
|
||||
CMD_IID = 0x90,
|
||||
CMD_READ_STATUS = 0x70,
|
||||
CMD_CLEAR_STATUS = 0x50,
|
||||
CMD_ERASE_SETUP = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0xd0,
|
||||
CMD_ERASE_SUSPEND = 0xb0,
|
||||
CMD_PROGRAM_SETUP = 0x40,
|
||||
enum {
|
||||
CMD_READ_ARRAY = 0xff,
|
||||
CMD_IID = 0x90,
|
||||
CMD_READ_STATUS = 0x70,
|
||||
CMD_CLEAR_STATUS = 0x50,
|
||||
CMD_ERASE_SETUP = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0xd0,
|
||||
CMD_ERASE_SUSPEND = 0xb0,
|
||||
CMD_PROGRAM_SETUP = 0x40,
|
||||
CMD_PROGRAM_SETUP_ALT = 0x10
|
||||
};
|
||||
|
||||
typedef struct flash_t {
|
||||
uint8_t command, status,
|
||||
pad, flags,
|
||||
*array;
|
||||
|
||||
typedef struct flash_t
|
||||
{
|
||||
uint8_t command, status,
|
||||
pad, flags,
|
||||
*array;
|
||||
uint16_t flash_id, pad16;
|
||||
|
||||
uint16_t flash_id, pad16;
|
||||
uint32_t program_addr,
|
||||
block_start[BLOCKS_NUM], block_end[BLOCKS_NUM],
|
||||
block_len[BLOCKS_NUM];
|
||||
|
||||
uint32_t program_addr,
|
||||
block_start[BLOCKS_NUM], block_end[BLOCKS_NUM],
|
||||
block_len[BLOCKS_NUM];
|
||||
|
||||
mem_mapping_t mapping[4], mapping_h[16];
|
||||
mem_mapping_t mapping[4], mapping_h[16];
|
||||
} flash_t;
|
||||
|
||||
|
||||
static char flash_path[1024];
|
||||
|
||||
static char flash_path[1024];
|
||||
|
||||
static uint8_t
|
||||
flash_read(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *) p;
|
||||
uint8_t ret = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
addr ^= 0x10000;
|
||||
addr ^= 0x10000;
|
||||
addr &= biosmask;
|
||||
|
||||
switch (dev->command) {
|
||||
case CMD_READ_ARRAY:
|
||||
default:
|
||||
ret = dev->array[addr];
|
||||
break;
|
||||
case CMD_READ_ARRAY:
|
||||
default:
|
||||
ret = dev->array[addr];
|
||||
break;
|
||||
|
||||
case CMD_IID:
|
||||
if (addr & 1)
|
||||
ret = dev->flash_id & 0xff;
|
||||
else
|
||||
ret = 0x89;
|
||||
break;
|
||||
case CMD_IID:
|
||||
if (addr & 1)
|
||||
ret = dev->flash_id & 0xff;
|
||||
else
|
||||
ret = 0x89;
|
||||
break;
|
||||
|
||||
case CMD_READ_STATUS:
|
||||
ret = dev->status;
|
||||
break;
|
||||
case CMD_READ_STATUS:
|
||||
ret = dev->status;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
flash_readw(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *) p;
|
||||
flash_t *dev = (flash_t *) p;
|
||||
uint16_t *q;
|
||||
uint16_t ret = 0xffff;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
addr ^= 0x10000;
|
||||
addr ^= 0x10000;
|
||||
addr &= biosmask;
|
||||
|
||||
if (dev->flags & FLAG_WORD)
|
||||
addr &= 0xfffffffe;
|
||||
addr &= 0xfffffffe;
|
||||
|
||||
q = (uint16_t *)&(dev->array[addr]);
|
||||
q = (uint16_t *) &(dev->array[addr]);
|
||||
ret = *q;
|
||||
|
||||
if (dev->flags & FLAG_WORD) switch (dev->command) {
|
||||
case CMD_READ_ARRAY:
|
||||
default:
|
||||
break;
|
||||
if (dev->flags & FLAG_WORD)
|
||||
switch (dev->command) {
|
||||
case CMD_READ_ARRAY:
|
||||
default:
|
||||
break;
|
||||
|
||||
case CMD_IID:
|
||||
if (addr & 2)
|
||||
ret = dev->flash_id;
|
||||
else
|
||||
ret = 0x0089;
|
||||
break;
|
||||
case CMD_IID:
|
||||
if (addr & 2)
|
||||
ret = dev->flash_id;
|
||||
else
|
||||
ret = 0x0089;
|
||||
break;
|
||||
|
||||
case CMD_READ_STATUS:
|
||||
ret = dev->status;
|
||||
break;
|
||||
}
|
||||
case CMD_READ_STATUS:
|
||||
ret = dev->status;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
flash_readl(uint32_t addr, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *)p;
|
||||
flash_t *dev = (flash_t *) p;
|
||||
uint32_t *q;
|
||||
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
addr ^= 0x10000;
|
||||
addr ^= 0x10000;
|
||||
addr &= biosmask;
|
||||
|
||||
q = (uint32_t *)&(dev->array[addr]);
|
||||
q = (uint32_t *) &(dev->array[addr]);
|
||||
|
||||
return *q;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flash_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *) p;
|
||||
int i;
|
||||
int i;
|
||||
uint32_t bb_mask = biosmask & 0xffffe000;
|
||||
if (biosmask == 0x7ffff)
|
||||
bb_mask &= 0xffff8000;
|
||||
bb_mask &= 0xffff8000;
|
||||
else if (biosmask == 0x3ffff)
|
||||
bb_mask &= 0xffffc000;
|
||||
bb_mask &= 0xffffc000;
|
||||
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
addr ^= 0x10000;
|
||||
addr ^= 0x10000;
|
||||
addr &= biosmask;
|
||||
|
||||
switch (dev->command) {
|
||||
case CMD_ERASE_SETUP:
|
||||
if (val == CMD_ERASE_CONFIRM) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
|
||||
}
|
||||
case CMD_ERASE_SETUP:
|
||||
if (val == CMD_ERASE_CONFIRM) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
|
||||
}
|
||||
|
||||
dev->status = 0x80;
|
||||
}
|
||||
dev->command = CMD_READ_STATUS;
|
||||
break;
|
||||
dev->status = 0x80;
|
||||
}
|
||||
dev->command = CMD_READ_STATUS;
|
||||
break;
|
||||
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
|
||||
dev->array[addr] = val;
|
||||
dev->command = CMD_READ_STATUS;
|
||||
dev->status = 0x80;
|
||||
break;
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
|
||||
dev->array[addr] = val;
|
||||
dev->command = CMD_READ_STATUS;
|
||||
dev->status = 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->command = val;
|
||||
switch (val) {
|
||||
case CMD_CLEAR_STATUS:
|
||||
dev->status = 0;
|
||||
break;
|
||||
case CMD_ERASE_SETUP:
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
dev->program_addr = i;
|
||||
}
|
||||
break;
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
dev->program_addr = addr;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dev->command = val;
|
||||
switch (val) {
|
||||
case CMD_CLEAR_STATUS:
|
||||
dev->status = 0;
|
||||
break;
|
||||
case CMD_ERASE_SETUP:
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
dev->program_addr = i;
|
||||
}
|
||||
break;
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
dev->program_addr = addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flash_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
flash_t *dev = (flash_t *) p;
|
||||
int i;
|
||||
int i;
|
||||
uint32_t bb_mask = biosmask & 0xffffe000;
|
||||
if (biosmask == 0x7ffff)
|
||||
bb_mask &= 0xffff8000;
|
||||
bb_mask &= 0xffff8000;
|
||||
else if (biosmask == 0x3ffff)
|
||||
bb_mask &= 0xffffc000;
|
||||
bb_mask &= 0xffffc000;
|
||||
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
addr ^= 0x10000;
|
||||
addr ^= 0x10000;
|
||||
addr &= biosmask;
|
||||
|
||||
if (dev->flags & FLAG_WORD) switch (dev->command) {
|
||||
case CMD_ERASE_SETUP:
|
||||
if (val == CMD_ERASE_CONFIRM) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
|
||||
}
|
||||
if (dev->flags & FLAG_WORD)
|
||||
switch (dev->command) {
|
||||
case CMD_ERASE_SETUP:
|
||||
if (val == CMD_ERASE_CONFIRM) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
|
||||
}
|
||||
|
||||
dev->status = 0x80;
|
||||
}
|
||||
dev->command = CMD_READ_STATUS;
|
||||
break;
|
||||
dev->status = 0x80;
|
||||
}
|
||||
dev->command = CMD_READ_STATUS;
|
||||
break;
|
||||
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
|
||||
*(uint16_t *) (&dev->array[addr]) = val;
|
||||
dev->command = CMD_READ_STATUS;
|
||||
dev->status = 0x80;
|
||||
break;
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
|
||||
*(uint16_t *) (&dev->array[addr]) = val;
|
||||
dev->command = CMD_READ_STATUS;
|
||||
dev->status = 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->command = val & 0xff;
|
||||
switch (val) {
|
||||
case CMD_CLEAR_STATUS:
|
||||
dev->status = 0;
|
||||
break;
|
||||
case CMD_ERASE_SETUP:
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
dev->program_addr = i;
|
||||
}
|
||||
break;
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
dev->program_addr = addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
dev->command = val & 0xff;
|
||||
switch (val) {
|
||||
case CMD_CLEAR_STATUS:
|
||||
dev->status = 0;
|
||||
break;
|
||||
case CMD_ERASE_SETUP:
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
|
||||
dev->program_addr = i;
|
||||
}
|
||||
break;
|
||||
case CMD_PROGRAM_SETUP:
|
||||
case CMD_PROGRAM_SETUP_ALT:
|
||||
dev->program_addr = addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flash_writel(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
@@ -290,70 +279,67 @@ flash_writel(uint32_t addr, uint32_t val, void *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
intel_flash_add_mappings(flash_t *dev)
|
||||
{
|
||||
int max = 2, i = 0;
|
||||
int max = 2, i = 0;
|
||||
uint32_t base, fbase;
|
||||
uint32_t sub = 0x20000;
|
||||
|
||||
if (biosmask == 0x7ffff) {
|
||||
sub = 0x80000;
|
||||
max = 8;
|
||||
sub = 0x80000;
|
||||
max = 8;
|
||||
} else if (biosmask == 0x3ffff) {
|
||||
sub = 0x40000;
|
||||
max = 4;
|
||||
sub = 0x40000;
|
||||
max = 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
if (biosmask == 0x7ffff)
|
||||
base = 0x80000 + (i << 16);
|
||||
else if (biosmask == 0x3ffff)
|
||||
base = 0xc0000 + (i << 16);
|
||||
else
|
||||
base = 0xe0000 + (i << 16);
|
||||
if (biosmask == 0x7ffff)
|
||||
base = 0x80000 + (i << 16);
|
||||
else if (biosmask == 0x3ffff)
|
||||
base = 0xc0000 + (i << 16);
|
||||
else
|
||||
base = 0xe0000 + (i << 16);
|
||||
|
||||
fbase = base & biosmask;
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
fbase ^= 0x10000;
|
||||
fbase = base & biosmask;
|
||||
if (dev->flags & FLAG_INV_A16)
|
||||
fbase ^= 0x10000;
|
||||
|
||||
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
|
||||
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
|
||||
|
||||
if ((max == 2) || (i >= 2)) {
|
||||
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
mem_mapping_add(&(dev->mapping_h[i + max]), (base | 0xfff00000), 0x10000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
if ((max == 2) || (i >= 2)) {
|
||||
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
mem_mapping_add(&(dev->mapping_h[i + max]), (base | 0xfff00000), 0x10000,
|
||||
flash_read, flash_readw, flash_readl,
|
||||
flash_write, flash_writew, flash_writel,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
intel_flash_reset(void *priv)
|
||||
{
|
||||
flash_t *dev = (flash_t *) priv;
|
||||
|
||||
dev->command = CMD_READ_ARRAY;
|
||||
dev->status = 0;
|
||||
dev->status = 0;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
intel_flash_init(const device_t *info)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
flash_t *dev;
|
||||
uint8_t type = info->local & 0xff;
|
||||
uint8_t type = info->local & 0xff;
|
||||
|
||||
dev = malloc(sizeof(flash_t));
|
||||
memset(dev, 0, sizeof(flash_t));
|
||||
@@ -369,186 +355,185 @@ intel_flash_init(const device_t *info)
|
||||
memset(dev->array, 0xff, biosmask + 1);
|
||||
|
||||
switch (biosmask) {
|
||||
case 0x7ffff:
|
||||
if (dev->flags & FLAG_WORD)
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470;
|
||||
else
|
||||
dev->flash_id =(dev->flags & FLAG_BXB) ? 0x8A : 0x89;
|
||||
case 0x7ffff:
|
||||
if (dev->flags & FLAG_WORD)
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470;
|
||||
else
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x8A : 0x89;
|
||||
|
||||
/* The block lengths are the same both flash types. */
|
||||
dev->block_len[BLOCK_MAIN1] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN2] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN3] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN4] = 0x18000;
|
||||
dev->block_len[BLOCK_DATA1] = 0x02000;
|
||||
dev->block_len[BLOCK_DATA2] = 0x02000;
|
||||
dev->block_len[BLOCK_BOOT] = 0x04000;
|
||||
/* The block lengths are the same both flash types. */
|
||||
dev->block_len[BLOCK_MAIN1] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN2] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN3] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN4] = 0x18000;
|
||||
dev->block_len[BLOCK_DATA1] = 0x02000;
|
||||
dev->block_len[BLOCK_DATA2] = 0x02000;
|
||||
dev->block_len[BLOCK_BOOT] = 0x04000;
|
||||
|
||||
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
|
||||
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_BOOT] = 0x1ffff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_DATA2] = 0x3ffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_DATA1] = 0x5ffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0x77fff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_MAIN3] = 0x79fff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x7bfff;
|
||||
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x7ffff;
|
||||
} else {
|
||||
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x3ffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0x5ffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0x77fff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x79fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x7bfff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x7ffff;
|
||||
}
|
||||
break;
|
||||
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
|
||||
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_BOOT] = 0x1ffff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_DATA2] = 0x3ffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_DATA1] = 0x5ffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0x77fff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_MAIN3] = 0x79fff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x7bfff;
|
||||
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x7ffff;
|
||||
} else {
|
||||
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x3ffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0x5ffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0x77fff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x79fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x7bfff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x7ffff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3ffff:
|
||||
if (dev->flags & FLAG_WORD)
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274;
|
||||
else
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C;
|
||||
case 0x3ffff:
|
||||
if (dev->flags & FLAG_WORD)
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274;
|
||||
else
|
||||
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C;
|
||||
|
||||
/* The block lengths are the same both flash types. */
|
||||
dev->block_len[BLOCK_MAIN1] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN2] = 0x18000;
|
||||
dev->block_len[BLOCK_MAIN3] = 0x00000;
|
||||
dev->block_len[BLOCK_MAIN4] = 0x00000;
|
||||
dev->block_len[BLOCK_DATA1] = 0x02000;
|
||||
dev->block_len[BLOCK_DATA2] = 0x02000;
|
||||
dev->block_len[BLOCK_BOOT] = 0x04000;
|
||||
/* The block lengths are the same both flash types. */
|
||||
dev->block_len[BLOCK_MAIN1] = 0x20000;
|
||||
dev->block_len[BLOCK_MAIN2] = 0x18000;
|
||||
dev->block_len[BLOCK_MAIN3] = 0x00000;
|
||||
dev->block_len[BLOCK_MAIN4] = 0x00000;
|
||||
dev->block_len[BLOCK_DATA1] = 0x02000;
|
||||
dev->block_len[BLOCK_DATA2] = 0x02000;
|
||||
dev->block_len[BLOCK_BOOT] = 0x04000;
|
||||
|
||||
if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x3ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x07fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x05fff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x03fff;
|
||||
} else { /* 28F002BX-T/28F200BX-T */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x37fff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x39fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x3bfff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x3ffff;
|
||||
}
|
||||
break;
|
||||
if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x3ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x07fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x05fff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x03fff;
|
||||
} else { /* 28F002BX-T/28F200BX-T */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0x37fff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x39fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x3bfff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x3ffff;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94;
|
||||
default:
|
||||
dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94;
|
||||
|
||||
/* The block lengths are the same both flash types. */
|
||||
dev->block_len[BLOCK_MAIN1] = 0x1c000;
|
||||
dev->block_len[BLOCK_MAIN2] = 0x00000;
|
||||
dev->block_len[BLOCK_MAIN3] = 0x00000;
|
||||
dev->block_len[BLOCK_MAIN4] = 0x00000;
|
||||
dev->block_len[BLOCK_DATA1] = 0x01000;
|
||||
dev->block_len[BLOCK_DATA2] = 0x01000;
|
||||
dev->block_len[BLOCK_BOOT] = 0x02000;
|
||||
/* The block lengths are the same both flash types. */
|
||||
dev->block_len[BLOCK_MAIN1] = 0x1c000;
|
||||
dev->block_len[BLOCK_MAIN2] = 0x00000;
|
||||
dev->block_len[BLOCK_MAIN3] = 0x00000;
|
||||
dev->block_len[BLOCK_MAIN4] = 0x00000;
|
||||
dev->block_len[BLOCK_DATA1] = 0x01000;
|
||||
dev->block_len[BLOCK_DATA2] = 0x01000;
|
||||
dev->block_len[BLOCK_BOOT] = 0x02000;
|
||||
|
||||
if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x02fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x03fff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x01fff;
|
||||
} else { /* 28F001BX-T/28F100BX-T */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1bfff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x1cfff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x1dfff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x1ffff;
|
||||
}
|
||||
break;
|
||||
if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x02fff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x03fff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x01fff;
|
||||
} else { /* 28F001BX-T/28F100BX-T */
|
||||
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
|
||||
dev->block_end[BLOCK_MAIN1] = 0x1bfff;
|
||||
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
|
||||
dev->block_end[BLOCK_MAIN2] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
|
||||
dev->block_end[BLOCK_MAIN3] = 0xfffff;
|
||||
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
|
||||
dev->block_end[BLOCK_MAIN4] = 0xfffff;
|
||||
dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */
|
||||
dev->block_end[BLOCK_DATA1] = 0x1cfff;
|
||||
dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */
|
||||
dev->block_end[BLOCK_DATA2] = 0x1dfff;
|
||||
dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */
|
||||
dev->block_end[BLOCK_BOOT] = 0x1ffff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
intel_flash_add_mappings(dev);
|
||||
|
||||
dev->command = CMD_READ_ARRAY;
|
||||
dev->status = 0;
|
||||
dev->status = 0;
|
||||
|
||||
f = nvr_fopen(flash_path, "rb");
|
||||
if (f) {
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN2])
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN3])
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN4])
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN2])
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN3])
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN4])
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
|
||||
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
|
||||
fclose(f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
intel_flash_close(void *p)
|
||||
{
|
||||
FILE *f;
|
||||
flash_t *dev = (flash_t *)p;
|
||||
FILE *f;
|
||||
flash_t *dev = (flash_t *) p;
|
||||
|
||||
f = nvr_fopen(flash_path, "wb");
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN2])
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN3])
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN4])
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
|
||||
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
|
||||
fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
|
||||
@@ -562,43 +547,43 @@ intel_flash_close(void *p)
|
||||
|
||||
/* For AMI BIOS'es - Intel 28F001BXT with A16 pin inverted. */
|
||||
const device_t intel_flash_bxt_ami_device = {
|
||||
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
|
||||
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
|
||||
.internal_name = "intel_flash_bxt_ami",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = FLAG_INV_A16,
|
||||
.init = intel_flash_init,
|
||||
.close = intel_flash_close,
|
||||
.reset = intel_flash_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = FLAG_INV_A16,
|
||||
.init = intel_flash_init,
|
||||
.close = intel_flash_close,
|
||||
.reset = intel_flash_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t intel_flash_bxt_device = {
|
||||
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
|
||||
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
|
||||
.internal_name = "intel_flash_bxt",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = intel_flash_init,
|
||||
.close = intel_flash_close,
|
||||
.reset = intel_flash_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = intel_flash_init,
|
||||
.close = intel_flash_close,
|
||||
.reset = intel_flash_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t intel_flash_bxb_device = {
|
||||
.name = "Intel 28F001BXB/28F002BXB/28F004BXB Flash BIOS",
|
||||
.name = "Intel 28F001BXB/28F002BXB/28F004BXB Flash BIOS",
|
||||
.internal_name = "intel_flash_bxb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = FLAG_BXB,
|
||||
.init = intel_flash_init,
|
||||
.close = intel_flash_close,
|
||||
.reset = intel_flash_reset,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = FLAG_BXB,
|
||||
.init = intel_flash_init,
|
||||
.close = intel_flash_close,
|
||||
.reset = intel_flash_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
2566
src/mem/mem.c
2566
src/mem/mem.c
File diff suppressed because it is too large
Load Diff
415
src/mem/rom.c
415
src/mem/rom.c
@@ -38,35 +38,32 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/m_xt_xi8088.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_ROM_LOG
|
||||
int rom_do_log = ENABLE_ROM_LOG;
|
||||
|
||||
|
||||
static void
|
||||
rom_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (rom_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define rom_log(fmt, ...)
|
||||
# define rom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
void
|
||||
rom_add_path(const char* path)
|
||||
rom_add_path(const char *path)
|
||||
{
|
||||
char cwd[1024] = { 0 };
|
||||
|
||||
rom_path_t* rom_path = &rom_paths;
|
||||
rom_path_t *rom_path = &rom_paths;
|
||||
|
||||
if (rom_paths.path[0] != '\0')
|
||||
{
|
||||
if (rom_paths.path[0] != '\0') {
|
||||
// Iterate to the end of the list.
|
||||
while (rom_path->next != NULL) {
|
||||
rom_path = rom_path->next;
|
||||
@@ -77,7 +74,7 @@ rom_add_path(const char* path)
|
||||
}
|
||||
|
||||
// Save the path, turning it into absolute if needed.
|
||||
if (!path_abs((char*) path)) {
|
||||
if (!path_abs((char *) path)) {
|
||||
plat_getcwd(cwd, sizeof(cwd));
|
||||
path_slash(cwd);
|
||||
snprintf(rom_path->path, sizeof(rom_path->path), "%s%s", cwd, path);
|
||||
@@ -89,13 +86,12 @@ rom_add_path(const char* path)
|
||||
path_slash(rom_path->path);
|
||||
}
|
||||
|
||||
|
||||
FILE *
|
||||
rom_fopen(char *fn, char *mode)
|
||||
{
|
||||
char temp[1024];
|
||||
char temp[1024];
|
||||
rom_path_t *rom_path;
|
||||
FILE *fp = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
if (strstr(fn, "roms/") == fn) {
|
||||
/* Relative path */
|
||||
@@ -114,11 +110,10 @@ rom_fopen(char *fn, char *mode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rom_getfile(char *fn, char *s, int size)
|
||||
{
|
||||
char temp[1024];
|
||||
char temp[1024];
|
||||
rom_path_t *rom_path;
|
||||
|
||||
if (strstr(fn, "roms/") == fn) {
|
||||
@@ -144,7 +139,6 @@ rom_getfile(char *fn, char *s, int size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rom_present(char *fn)
|
||||
{
|
||||
@@ -152,104 +146,99 @@ rom_present(char *fn)
|
||||
|
||||
f = rom_fopen(fn, "rb");
|
||||
if (f != NULL) {
|
||||
(void)fclose(f);
|
||||
return(1);
|
||||
(void) fclose(f);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
rom_read(uint32_t addr, void *priv)
|
||||
{
|
||||
rom_t *rom = (rom_t *)priv;
|
||||
rom_t *rom = (rom_t *) priv;
|
||||
|
||||
#ifdef ROM_TRACE
|
||||
if (rom->mapping.base==ROM_TRACE)
|
||||
rom_log("ROM: read byte from BIOS at %06lX\n", addr);
|
||||
if (rom->mapping.base == ROM_TRACE)
|
||||
rom_log("ROM: read byte from BIOS at %06lX\n", addr);
|
||||
#endif
|
||||
|
||||
if (addr < rom->mapping.base)
|
||||
return 0xff;
|
||||
return 0xff;
|
||||
if (addr >= (rom->mapping.base + rom->sz))
|
||||
return 0xff;
|
||||
return(rom->rom[(addr - rom->mapping.base) & rom->mask]);
|
||||
return 0xff;
|
||||
return (rom->rom[(addr - rom->mapping.base) & rom->mask]);
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
rom_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
rom_t *rom = (rom_t *)priv;
|
||||
rom_t *rom = (rom_t *) priv;
|
||||
|
||||
#ifdef ROM_TRACE
|
||||
if (rom->mapping.base==ROM_TRACE)
|
||||
rom_log("ROM: read word from BIOS at %06lX\n", addr);
|
||||
if (rom->mapping.base == ROM_TRACE)
|
||||
rom_log("ROM: read word from BIOS at %06lX\n", addr);
|
||||
#endif
|
||||
|
||||
if (addr < (rom->mapping.base - 1))
|
||||
return 0xffff;
|
||||
return 0xffff;
|
||||
if (addr >= (rom->mapping.base + rom->sz))
|
||||
return 0xffff;
|
||||
return(*(uint16_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]);
|
||||
return 0xffff;
|
||||
return (*(uint16_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask]);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
rom_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
rom_t *rom = (rom_t *)priv;
|
||||
rom_t *rom = (rom_t *) priv;
|
||||
|
||||
#ifdef ROM_TRACE
|
||||
if (rom->mapping.base==ROM_TRACE)
|
||||
rom_log("ROM: read long from BIOS at %06lX\n", addr);
|
||||
if (rom->mapping.base == ROM_TRACE)
|
||||
rom_log("ROM: read long from BIOS at %06lX\n", addr);
|
||||
#endif
|
||||
|
||||
if (addr < (rom->mapping.base - 3))
|
||||
return 0xffffffff;
|
||||
return 0xffffffff;
|
||||
if (addr >= (rom->mapping.base + rom->sz))
|
||||
return 0xffffffff;
|
||||
return(*(uint32_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]);
|
||||
return 0xffffffff;
|
||||
return (*(uint32_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask]);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
|
||||
{
|
||||
FILE *f = rom_fopen(fn, "rb");
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (f == NULL) {
|
||||
rom_log("ROM: image '%s' not found\n", fn);
|
||||
return(0);
|
||||
rom_log("ROM: image '%s' not found\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Make sure we only look at the base-256K offset. */
|
||||
if (addr >= 0x40000)
|
||||
addr = 0;
|
||||
addr = 0;
|
||||
else
|
||||
addr &= 0x03ffff;
|
||||
addr &= 0x03ffff;
|
||||
|
||||
if (ptr != NULL) {
|
||||
if (fseek(f, off, SEEK_SET) == -1)
|
||||
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
|
||||
for (i = 0; i < (sz >> 1); i++) {
|
||||
if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1)
|
||||
fatal("rom_load_linear(): Error reading even data\n");
|
||||
}
|
||||
for (i = 0; i < (sz >> 1); i++) {
|
||||
if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1)
|
||||
fatal("rom_load_linear(): Error reading od data\n");
|
||||
}
|
||||
if (fseek(f, off, SEEK_SET) == -1)
|
||||
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
|
||||
for (i = 0; i < (sz >> 1); i++) {
|
||||
if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1)
|
||||
fatal("rom_load_linear(): Error reading even data\n");
|
||||
}
|
||||
for (i = 0; i < (sz >> 1); i++) {
|
||||
if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1)
|
||||
fatal("rom_load_linear(): Error reading od data\n");
|
||||
}
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
(void) fclose(f);
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/* Load a ROM BIOS from its chips, interleaved mode. */
|
||||
int
|
||||
rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
|
||||
@@ -257,29 +246,28 @@ rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
|
||||
FILE *f = rom_fopen(fn, "rb");
|
||||
|
||||
if (f == NULL) {
|
||||
rom_log("ROM: image '%s' not found\n", fn);
|
||||
return(0);
|
||||
rom_log("ROM: image '%s' not found\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Make sure we only look at the base-256K offset. */
|
||||
if (addr >= 0x40000)
|
||||
addr = 0;
|
||||
addr = 0;
|
||||
else
|
||||
addr &= 0x03ffff;
|
||||
addr &= 0x03ffff;
|
||||
|
||||
if (ptr != NULL) {
|
||||
if (fseek(f, off, SEEK_SET) == -1)
|
||||
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
|
||||
if (fread(ptr+addr, 1, sz, f) > sz)
|
||||
fatal("rom_load_linear(): Error reading data\n");
|
||||
if (fseek(f, off, SEEK_SET) == -1)
|
||||
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
|
||||
if (fread(ptr + addr, 1, sz, f) > sz)
|
||||
fatal("rom_load_linear(): Error reading data\n");
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
(void) fclose(f);
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/* Load a ROM BIOS from its chips, linear mode with high bit flipped. */
|
||||
int
|
||||
rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
|
||||
@@ -287,84 +275,80 @@ rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
|
||||
FILE *f = rom_fopen(fn, "rb");
|
||||
|
||||
if (f == NULL) {
|
||||
rom_log("ROM: image '%s' not found\n", fn);
|
||||
return(0);
|
||||
rom_log("ROM: image '%s' not found\n", fn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Make sure we only look at the base-256K offset. */
|
||||
if (addr >= 0x40000)
|
||||
{
|
||||
addr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr &= 0x03ffff;
|
||||
if (addr >= 0x40000) {
|
||||
addr = 0;
|
||||
} else {
|
||||
addr &= 0x03ffff;
|
||||
}
|
||||
|
||||
(void)fseek(f, 0, SEEK_END);
|
||||
(void) fseek(f, 0, SEEK_END);
|
||||
if (ftell(f) < sz) {
|
||||
(void)fclose(f);
|
||||
return(0);
|
||||
(void) fclose(f);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (ptr != NULL) {
|
||||
if (fseek(f, off, SEEK_SET) == -1)
|
||||
fatal("rom_load_linear_inverted(): Error seeking to the beginning of the file\n");
|
||||
if (fread(ptr+addr+0x10000, 1, sz >> 1, f) > (sz >> 1))
|
||||
fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
|
||||
if (fread(ptr+addr, sz >> 1, 1, f) > (sz >> 1))
|
||||
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n");
|
||||
if (fseek(f, off, SEEK_SET) == -1)
|
||||
fatal("rom_load_linear_inverted(): Error seeking to the beginning of the file\n");
|
||||
if (fread(ptr + addr + 0x10000, 1, sz >> 1, f) > (sz >> 1))
|
||||
fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
|
||||
if (fread(ptr + addr, sz >> 1, 1, f) > (sz >> 1))
|
||||
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n");
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
(void) fclose(f);
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/* Load a ROM BIOS from its chips, interleaved mode. */
|
||||
int
|
||||
rom_load_interleaved(char *fnl, char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr)
|
||||
{
|
||||
FILE *fl = rom_fopen(fnl, "rb");
|
||||
FILE *fh = rom_fopen(fnh, "rb");
|
||||
int c;
|
||||
int c;
|
||||
|
||||
if (fl == NULL || fh == NULL) {
|
||||
if (fl == NULL) rom_log("ROM: image '%s' not found\n", fnl);
|
||||
else (void)fclose(fl);
|
||||
if (fh == NULL) rom_log("ROM: image '%s' not found\n", fnh);
|
||||
else (void)fclose(fh);
|
||||
if (fl == NULL)
|
||||
rom_log("ROM: image '%s' not found\n", fnl);
|
||||
else
|
||||
(void) fclose(fl);
|
||||
if (fh == NULL)
|
||||
rom_log("ROM: image '%s' not found\n", fnh);
|
||||
else
|
||||
(void) fclose(fh);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Make sure we only look at the base-256K offset. */
|
||||
if (addr >= 0x40000)
|
||||
{
|
||||
addr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr &= 0x03ffff;
|
||||
if (addr >= 0x40000) {
|
||||
addr = 0;
|
||||
} else {
|
||||
addr &= 0x03ffff;
|
||||
}
|
||||
|
||||
if (ptr != NULL) {
|
||||
(void)fseek(fl, off, SEEK_SET);
|
||||
(void)fseek(fh, off, SEEK_SET);
|
||||
for (c=0; c<sz; c+=2) {
|
||||
ptr[addr+c] = fgetc(fl) & 0xff;
|
||||
ptr[addr+c+1] = fgetc(fh) & 0xff;
|
||||
}
|
||||
(void) fseek(fl, off, SEEK_SET);
|
||||
(void) fseek(fh, off, SEEK_SET);
|
||||
for (c = 0; c < sz; c += 2) {
|
||||
ptr[addr + c] = fgetc(fl) & 0xff;
|
||||
ptr[addr + c + 1] = fgetc(fh) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
(void)fclose(fh);
|
||||
(void)fclose(fl);
|
||||
(void) fclose(fh);
|
||||
(void) fclose(fl);
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bios_normalize(int n, int up)
|
||||
{
|
||||
@@ -373,38 +357,35 @@ bios_normalize(int n, int up)
|
||||
|
||||
/* 0x2000 -> 0x4000; 0x4000 -> 0x4000; 0x6000 -> 0x8000 */
|
||||
if (up && (n % MEM_GRANULARITY_SIZE))
|
||||
temp_n += MEM_GRANULARITY_SIZE;
|
||||
temp_n += MEM_GRANULARITY_SIZE;
|
||||
|
||||
return temp_n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t *
|
||||
rom_reset(uint32_t addr, int sz)
|
||||
{
|
||||
biosaddr = bios_normalize(addr, 0);
|
||||
biosmask = bios_normalize(sz, 1) - 1;
|
||||
if ((biosaddr + biosmask) > 0x000fffff)
|
||||
biosaddr = 0x000fffff - biosmask;
|
||||
biosaddr = 0x000fffff - biosmask;
|
||||
|
||||
rom_log("Load BIOS: %i bytes at %08X-%08X\n", biosmask + 1, biosaddr, biosaddr + biosmask);
|
||||
|
||||
/* If not done yet, allocate a 128KB buffer for the BIOS ROM. */
|
||||
if (rom != NULL) {
|
||||
rom_log("ROM allocated, freeing...\n");
|
||||
free(rom);
|
||||
rom = NULL;
|
||||
rom_log("ROM allocated, freeing...\n");
|
||||
free(rom);
|
||||
rom = NULL;
|
||||
}
|
||||
rom_log("Allocating ROM...\n");
|
||||
rom = (uint8_t *)malloc(biosmask + 1);
|
||||
rom = (uint8_t *) malloc(biosmask + 1);
|
||||
rom_log("Filling ROM with FF's...\n");
|
||||
memset(rom, 0xff, biosmask + 1);
|
||||
|
||||
return rom;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
bios_read(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -413,12 +394,11 @@ bios_read(uint32_t addr, void *priv)
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = rom[addr - biosaddr];
|
||||
ret = rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
bios_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -427,12 +407,11 @@ bios_readw(uint32_t addr, void *priv)
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint16_t *)&rom[addr - biosaddr];
|
||||
ret = *(uint16_t *) &rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
bios_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -441,113 +420,110 @@ bios_readl(uint32_t addr, void *priv)
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint32_t *)&rom[addr - biosaddr];
|
||||
ret = *(uint32_t *) &rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bios_add(void)
|
||||
{
|
||||
int temp_cpu_type, temp_cpu_16bitbus = 1;
|
||||
int temp_is286 = 0, temp_is6117 = 0;
|
||||
|
||||
if (/*AT && */cpu_s) {
|
||||
temp_cpu_type = cpu_s->cpu_type;
|
||||
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC );
|
||||
temp_is286 = (temp_cpu_type >= CPU_286);
|
||||
temp_is6117 = !strcmp(cpu_f->manufacturer, "ALi");
|
||||
if (/*AT && */ cpu_s) {
|
||||
temp_cpu_type = cpu_s->cpu_type;
|
||||
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC);
|
||||
temp_is286 = (temp_cpu_type >= CPU_286);
|
||||
temp_is6117 = !strcmp(cpu_f->manufacturer, "ALi");
|
||||
}
|
||||
|
||||
if (biosmask > 0x1ffff) {
|
||||
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
|
||||
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
NULL,NULL,NULL,
|
||||
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
|
||||
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
|
||||
bios_read, bios_readw, bios_readl,
|
||||
NULL, NULL, NULL,
|
||||
&rom[0x20000], MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(0x0e0000, 0x20000,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
mem_set_mem_state_both(0x0e0000, 0x20000,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
} else {
|
||||
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
NULL,NULL,NULL,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
|
||||
bios_read, bios_readw, bios_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr, biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
mem_set_mem_state_both(biosaddr, biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
}
|
||||
|
||||
if (temp_is6117) {
|
||||
mem_mapping_add(&bios_high_mapping, biosaddr | 0x03f00000, biosmask + 1,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
NULL,NULL,NULL,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
mem_mapping_add(&bios_high_mapping, biosaddr | 0x03f00000, biosmask + 1,
|
||||
bios_read, bios_readw, bios_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr | 0x03f00000, biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
mem_set_mem_state_both(biosaddr | 0x03f00000, biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
} else if (temp_is286) {
|
||||
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
NULL,NULL,NULL,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
bios_read, bios_readw, bios_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* These four are for loading the BIOS. */
|
||||
int
|
||||
bios_load(char *fn1, char *fn2, uint32_t addr, int sz, int off, int flags)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint8_t ret = 0;
|
||||
uint8_t *ptr = NULL;
|
||||
int i, old_sz = sz;
|
||||
int i, old_sz = sz;
|
||||
|
||||
/*
|
||||
f0000, 65536 = prepare 64k rom starting at f0000, load 64k bios at 0000
|
||||
fe000, 65536 = prepare 64k rom starting at f0000, load 8k bios at e000
|
||||
fe000, 49152 = prepare 48k rom starting at f4000, load 8k bios at a000
|
||||
fe000, 8192 = prepare 16k rom starting at fc000, load 8k bios at 2000
|
||||
f0000, 65536 = prepare 64k rom starting at f0000, load 64k bios at 0000
|
||||
fe000, 65536 = prepare 64k rom starting at f0000, load 8k bios at e000
|
||||
fe000, 49152 = prepare 48k rom starting at f4000, load 8k bios at a000
|
||||
fe000, 8192 = prepare 16k rom starting at fc000, load 8k bios at 2000
|
||||
*/
|
||||
if (!bios_only)
|
||||
ptr = (flags & FLAG_AUX) ? rom : rom_reset(addr, sz);
|
||||
ptr = (flags & FLAG_AUX) ? rom : rom_reset(addr, sz);
|
||||
|
||||
if (!(flags & FLAG_AUX) && ((addr + sz) > 0x00100000))
|
||||
sz = 0x00100000 - addr;
|
||||
sz = 0x00100000 - addr;
|
||||
|
||||
#ifdef ENABLE_ROM_LOG
|
||||
if (!bios_only)
|
||||
rom_log("%sing %i bytes of %sBIOS starting with ptr[%08X] (ptr = %08X)\n", (bios_only) ? "Check" : "Load", sz, (flags & FLAG_AUX) ? "auxiliary " : "", addr - biosaddr, ptr);
|
||||
rom_log("%sing %i bytes of %sBIOS starting with ptr[%08X] (ptr = %08X)\n", (bios_only) ? "Check" : "Load", sz, (flags & FLAG_AUX) ? "auxiliary " : "", addr - biosaddr, ptr);
|
||||
#endif
|
||||
|
||||
if (flags & FLAG_INT)
|
||||
ret = rom_load_interleaved(fn1, fn2, addr - biosaddr, sz, off, ptr);
|
||||
ret = rom_load_interleaved(fn1, fn2, addr - biosaddr, sz, off, ptr);
|
||||
else {
|
||||
if (flags & FLAG_INV)
|
||||
ret = rom_load_linear_inverted(fn1, addr - biosaddr, sz, off, ptr);
|
||||
else
|
||||
ret = rom_load_linear(fn1, addr - biosaddr, sz, off, ptr);
|
||||
if (flags & FLAG_INV)
|
||||
ret = rom_load_linear_inverted(fn1, addr - biosaddr, sz, off, ptr);
|
||||
else
|
||||
ret = rom_load_linear(fn1, addr - biosaddr, sz, off, ptr);
|
||||
}
|
||||
|
||||
if (!bios_only && (flags & FLAG_REP) && (old_sz >= 65536) && (sz < old_sz)) {
|
||||
old_sz /= sz;
|
||||
for (i = 0; i < (old_sz - 1); i++) {
|
||||
rom_log("Copying ptr[%08X] to ptr[%08X]\n", addr - biosaddr, i * sz);
|
||||
memcpy(&(ptr[i * sz]), &(ptr[addr - biosaddr]), sz);
|
||||
}
|
||||
old_sz /= sz;
|
||||
for (i = 0; i < (old_sz - 1); i++) {
|
||||
rom_log("Copying ptr[%08X] to ptr[%08X]\n", addr - biosaddr, i * sz);
|
||||
memcpy(&(ptr[i * sz]), &(ptr[addr - biosaddr]), sz);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bios_only && ret && !(flags & FLAG_AUX))
|
||||
bios_add();
|
||||
bios_add();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bios_load_linear_combined(char *fn1, char *fn2, int sz, int off)
|
||||
{
|
||||
@@ -559,7 +535,6 @@ bios_load_linear_combined(char *fn1, char *fn2, int sz, int off)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off)
|
||||
{
|
||||
@@ -570,12 +545,11 @@ bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5
|
||||
ret &= bios_load_aux_linear(fn2, 0x000c0000, 65536, off);
|
||||
ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off);
|
||||
if (fn5 != NULL)
|
||||
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0);
|
||||
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off)
|
||||
{
|
||||
@@ -586,12 +560,11 @@ bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *
|
||||
ret &= bios_load_aux_linear(fn2, 0x000d0000, 65536, off);
|
||||
ret &= bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off);
|
||||
if (fn5 != NULL)
|
||||
ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0);
|
||||
ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags)
|
||||
{
|
||||
@@ -602,26 +575,25 @@ rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_
|
||||
memset(rom->rom, 0xff, sz);
|
||||
|
||||
/* Load the image file into the buffer. */
|
||||
if (! rom_load_linear(fn, addr, sz, off, rom->rom)) {
|
||||
/* Nope.. clean up. */
|
||||
free(rom->rom);
|
||||
rom->rom = NULL;
|
||||
return(-1);
|
||||
if (!rom_load_linear(fn, addr, sz, off, rom->rom)) {
|
||||
/* Nope.. clean up. */
|
||||
free(rom->rom);
|
||||
rom->rom = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
rom->sz = sz;
|
||||
rom->sz = sz;
|
||||
rom->mask = mask;
|
||||
|
||||
mem_mapping_add(&rom->mapping,
|
||||
addr, sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
|
||||
addr, sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags)
|
||||
{
|
||||
@@ -632,26 +604,25 @@ rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off,
|
||||
memset(rom->rom, 0xff, sz);
|
||||
|
||||
/* Load the image file into the buffer. */
|
||||
if (! rom_load_linear_oddeven(fn, addr, sz, off, rom->rom)) {
|
||||
/* Nope.. clean up. */
|
||||
free(rom->rom);
|
||||
rom->rom = NULL;
|
||||
return(-1);
|
||||
if (!rom_load_linear_oddeven(fn, addr, sz, off, rom->rom)) {
|
||||
/* Nope.. clean up. */
|
||||
free(rom->rom);
|
||||
rom->rom = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
rom->sz = sz;
|
||||
rom->sz = sz;
|
||||
rom->mask = mask;
|
||||
|
||||
mem_mapping_add(&rom->mapping,
|
||||
addr, sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
|
||||
addr, sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, int mask, int off, uint32_t flags)
|
||||
{
|
||||
@@ -660,21 +631,21 @@ rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, in
|
||||
memset(rom->rom, 0xff, sz);
|
||||
|
||||
/* Load the image file into the buffer. */
|
||||
if (! rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) {
|
||||
/* Nope.. clean up. */
|
||||
free(rom->rom);
|
||||
rom->rom = NULL;
|
||||
return(-1);
|
||||
if (!rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) {
|
||||
/* Nope.. clean up. */
|
||||
free(rom->rom);
|
||||
rom->rom = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
rom->sz = sz;
|
||||
rom->sz = sz;
|
||||
rom->mask = mask;
|
||||
|
||||
mem_mapping_add(&rom->mapping,
|
||||
addr, sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
|
||||
addr, sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
260
src/mem/smram.c
260
src/mem/smram.c
@@ -29,117 +29,107 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
|
||||
static smram_t *base_smram, *last_smram;
|
||||
|
||||
static smram_t *base_smram, *last_smram;
|
||||
|
||||
static uint8_t use_separate_smram = 0;
|
||||
static uint8_t smram[0x40000];
|
||||
|
||||
static uint8_t use_separate_smram = 0;
|
||||
static uint8_t smram[0x40000];
|
||||
|
||||
#ifdef ENABLE_SMRAM_LOG
|
||||
int smram_do_log = ENABLE_SMRAM_LOG;
|
||||
|
||||
|
||||
static void
|
||||
smram_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (smram_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define smram_log(fmt, ...)
|
||||
# define smram_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t
|
||||
smram_read(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gb(new_addr, priv);
|
||||
return mem_read_ram_2gb(new_addr, priv);
|
||||
else if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
return mem_read_ram(new_addr, priv);
|
||||
return mem_read_ram(new_addr, priv);
|
||||
else
|
||||
return dev->mapping.exec[addr - dev->host_base];
|
||||
return dev->mapping.exec[addr - dev->host_base];
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
smram_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbw(new_addr, priv);
|
||||
return mem_read_ram_2gbw(new_addr, priv);
|
||||
else if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
return mem_read_ramw(new_addr, priv);
|
||||
return mem_read_ramw(new_addr, priv);
|
||||
else
|
||||
return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]);
|
||||
return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
smram_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbl(new_addr, priv);
|
||||
return mem_read_ram_2gbl(new_addr, priv);
|
||||
else if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
return mem_read_raml(new_addr, priv);
|
||||
return mem_read_raml(new_addr, priv);
|
||||
else
|
||||
return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]);
|
||||
return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smram_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
mem_write_ram(new_addr, val, priv);
|
||||
mem_write_ram(new_addr, val, priv);
|
||||
else
|
||||
dev->mapping.exec[addr - dev->host_base] = val;
|
||||
dev->mapping.exec[addr - dev->host_base] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smram_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
mem_write_ramw(new_addr, val, priv);
|
||||
mem_write_ramw(new_addr, val, priv);
|
||||
else
|
||||
*(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
|
||||
*(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smram_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
mem_write_raml(new_addr, val, priv);
|
||||
mem_write_raml(new_addr, val, priv);
|
||||
else
|
||||
*(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
|
||||
*(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
|
||||
}
|
||||
|
||||
|
||||
/* Make a backup copy of host_base and size of all the SMRAM structs, needed so that if
|
||||
the SMRAM mappings change while in SMM, they will be recalculated on return. */
|
||||
void
|
||||
@@ -148,15 +138,14 @@ smram_backup_all(void)
|
||||
smram_t *temp_smram = base_smram, *next;
|
||||
|
||||
while (temp_smram != NULL) {
|
||||
temp_smram->old_host_base = temp_smram->host_base;
|
||||
temp_smram->old_size = temp_smram->size;
|
||||
temp_smram->old_host_base = temp_smram->host_base;
|
||||
temp_smram->old_size = temp_smram->size;
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Recalculate any mappings, including the backup if returning from SMM. */
|
||||
void
|
||||
smram_recalc_all(int ret)
|
||||
@@ -164,55 +153,54 @@ smram_recalc_all(int ret)
|
||||
smram_t *temp_smram = base_smram, *next;
|
||||
|
||||
if (base_smram == NULL)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ret) {
|
||||
while (temp_smram != NULL) {
|
||||
if (temp_smram->old_size != 0x00000000)
|
||||
mem_mapping_recalc(temp_smram->old_host_base, temp_smram->old_size);
|
||||
temp_smram->old_host_base = temp_smram->old_size = 0x00000000;
|
||||
while (temp_smram != NULL) {
|
||||
if (temp_smram->old_size != 0x00000000)
|
||||
mem_mapping_recalc(temp_smram->old_host_base, temp_smram->old_size);
|
||||
temp_smram->old_host_base = temp_smram->old_size = 0x00000000;
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
}
|
||||
|
||||
temp_smram = base_smram;
|
||||
|
||||
while (temp_smram != NULL) {
|
||||
if (temp_smram->size != 0x00000000)
|
||||
mem_mapping_recalc(temp_smram->host_base, temp_smram->size);
|
||||
if (temp_smram->size != 0x00000000)
|
||||
mem_mapping_recalc(temp_smram->host_base, temp_smram->size);
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
/* Delete a SMRAM mapping. */
|
||||
void
|
||||
smram_del(smram_t *smr)
|
||||
{
|
||||
/* Do a sanity check */
|
||||
if ((base_smram == NULL) && (last_smram != NULL)) {
|
||||
fatal("smram_del(): NULL base SMRAM with non-NULL last SMRAM\n");
|
||||
return;
|
||||
fatal("smram_del(): NULL base SMRAM with non-NULL last SMRAM\n");
|
||||
return;
|
||||
} else if ((base_smram != NULL) && (last_smram == NULL)) {
|
||||
fatal("smram_del(): Non-NULL base SMRAM with NULL last SMRAM\n");
|
||||
return;
|
||||
fatal("smram_del(): Non-NULL base SMRAM with NULL last SMRAM\n");
|
||||
return;
|
||||
} else if ((base_smram != NULL) && (base_smram->prev != NULL)) {
|
||||
fatal("smram_del(): Base SMRAM with a preceding SMRAM\n");
|
||||
return;
|
||||
fatal("smram_del(): Base SMRAM with a preceding SMRAM\n");
|
||||
return;
|
||||
} else if ((last_smram != NULL) && (last_smram->next != NULL)) {
|
||||
fatal("smram_del(): Last SMRAM with a following SMRAM\n");
|
||||
return;
|
||||
fatal("smram_del(): Last SMRAM with a following SMRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (smr == NULL) {
|
||||
fatal("smram_del(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
fatal("smram_del(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable the entry. */
|
||||
@@ -220,20 +208,19 @@ smram_del(smram_t *smr)
|
||||
|
||||
/* Zap it from the list. */
|
||||
if (smr->prev != NULL)
|
||||
smr->prev->next = smr->next;
|
||||
smr->prev->next = smr->next;
|
||||
if (smr->next != NULL)
|
||||
smr->next->prev = smr->prev;
|
||||
smr->next->prev = smr->prev;
|
||||
|
||||
/* Check if it's the first or the last mapping. */
|
||||
if (base_smram == smr)
|
||||
base_smram = smr->next;
|
||||
base_smram = smr->next;
|
||||
if (last_smram == smr)
|
||||
last_smram = smr->prev;
|
||||
last_smram = smr->prev;
|
||||
|
||||
free(smr);
|
||||
}
|
||||
|
||||
|
||||
/* Add a SMRAM mapping. */
|
||||
smram_t *
|
||||
smram_add(void)
|
||||
@@ -242,63 +229,61 @@ smram_add(void)
|
||||
|
||||
/* Do a sanity check */
|
||||
if ((base_smram == NULL) && (last_smram != NULL)) {
|
||||
fatal("smram_add(): NULL base SMRAM with non-NULL last SMRAM\n");
|
||||
return NULL;
|
||||
fatal("smram_add(): NULL base SMRAM with non-NULL last SMRAM\n");
|
||||
return NULL;
|
||||
} else if ((base_smram != NULL) && (last_smram == NULL)) {
|
||||
fatal("smram_add(): Non-NULL base SMRAM with NULL last SMRAM\n");
|
||||
return NULL;
|
||||
fatal("smram_add(): Non-NULL base SMRAM with NULL last SMRAM\n");
|
||||
return NULL;
|
||||
} else if ((base_smram != NULL) && (base_smram->prev != NULL)) {
|
||||
fatal("smram_add(): Base SMRAM with a preceding SMRAM\n");
|
||||
return NULL;
|
||||
fatal("smram_add(): Base SMRAM with a preceding SMRAM\n");
|
||||
return NULL;
|
||||
} else if ((last_smram != NULL) && (last_smram->next != NULL)) {
|
||||
fatal("smram_add(): Last SMRAM with a following SMRAM\n");
|
||||
return NULL;
|
||||
fatal("smram_add(): Last SMRAM with a following SMRAM\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
temp_smram = (smram_t *) malloc(sizeof(smram_t));
|
||||
if (temp_smram == NULL) {
|
||||
fatal("smram_add(): temp_smram malloc failed\n");
|
||||
return NULL;
|
||||
fatal("smram_add(): temp_smram malloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(temp_smram, 0x00, sizeof(smram_t));
|
||||
memset(&(temp_smram->mapping), 0x00, sizeof(mem_mapping_t));
|
||||
|
||||
/* Add struct to the beginning of the list if necessary.*/
|
||||
if (base_smram == NULL)
|
||||
base_smram = temp_smram;
|
||||
base_smram = temp_smram;
|
||||
|
||||
/* Add struct to the end of the list.*/
|
||||
if (last_smram == NULL)
|
||||
temp_smram->prev = NULL;
|
||||
else {
|
||||
temp_smram->prev = last_smram;
|
||||
last_smram->next = temp_smram;
|
||||
temp_smram->prev = NULL;
|
||||
else {
|
||||
temp_smram->prev = last_smram;
|
||||
last_smram->next = temp_smram;
|
||||
}
|
||||
last_smram = temp_smram;
|
||||
|
||||
mem_mapping_add(&(temp_smram->mapping), 0x00000000, 0x00000000,
|
||||
smram_read,smram_readw,smram_readl,
|
||||
smram_write,smram_writew,smram_writel,
|
||||
ram, MEM_MAPPING_SMRAM, temp_smram);
|
||||
smram_read, smram_readw, smram_readl,
|
||||
smram_write, smram_writew, smram_writel,
|
||||
ram, MEM_MAPPING_SMRAM, temp_smram);
|
||||
|
||||
smram_set_separate_smram(0);
|
||||
|
||||
return temp_smram;
|
||||
}
|
||||
|
||||
|
||||
/* Set memory state in the specified model (normal or SMM) according to the specified flags,
|
||||
separately for bus and CPU. */
|
||||
void
|
||||
smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram)
|
||||
{
|
||||
if (bus)
|
||||
mem_set_access_smram_bus(smm, addr, size, is_smram);
|
||||
mem_set_access_smram_bus(smm, addr, size, is_smram);
|
||||
else
|
||||
mem_set_access_smram_cpu(smm, addr, size, is_smram);
|
||||
mem_set_access_smram_cpu(smm, addr, size, is_smram);
|
||||
}
|
||||
|
||||
|
||||
/* Set memory state in the specified model (normal or SMM) according to the specified flags. */
|
||||
void
|
||||
smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
|
||||
@@ -307,28 +292,26 @@ smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
|
||||
smram_map_ex(1, smm, addr, size, is_smram);
|
||||
}
|
||||
|
||||
|
||||
/* Disable a specific SMRAM mapping. */
|
||||
void
|
||||
smram_disable(smram_t *smr)
|
||||
{
|
||||
if (smr == NULL) {
|
||||
fatal("smram_disable(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
fatal("smram_disable(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (smr->size != 0x00000000) {
|
||||
smram_map(0, smr->host_base, smr->size, 0);
|
||||
smram_map(1, smr->host_base, smr->size, 0);
|
||||
smram_map(0, smr->host_base, smr->size, 0);
|
||||
smram_map(1, smr->host_base, smr->size, 0);
|
||||
|
||||
smr->host_base = smr->ram_base = 0x00000000;
|
||||
smr->size = 0x00000000;
|
||||
smr->host_base = smr->ram_base = 0x00000000;
|
||||
smr->size = 0x00000000;
|
||||
|
||||
mem_mapping_disable(&(smr->mapping));
|
||||
mem_mapping_disable(&(smr->mapping));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Disable all SMRAM mappings. */
|
||||
void
|
||||
smram_disable_all(void)
|
||||
@@ -336,56 +319,54 @@ smram_disable_all(void)
|
||||
smram_t *temp_smram = base_smram, *next;
|
||||
|
||||
while (temp_smram != NULL) {
|
||||
smram_disable(temp_smram);
|
||||
smram_disable(temp_smram);
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus
|
||||
and CPU. */
|
||||
void
|
||||
smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
|
||||
int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus)
|
||||
int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus)
|
||||
{
|
||||
if (smr == NULL) {
|
||||
fatal("smram_add(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
fatal("smram_add(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size != 0x00000000) && (flags_normal || flags_smm)) {
|
||||
smr->host_base = host_base;
|
||||
smr->ram_base = ram_base,
|
||||
smr->size = size;
|
||||
smr->host_base = host_base;
|
||||
smr->ram_base = ram_base,
|
||||
smr->size = size;
|
||||
|
||||
mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size);
|
||||
if (!use_separate_smram || (smr->ram_base >= 0x000a0000)) {
|
||||
if (smr->ram_base < (1 << 30))
|
||||
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
|
||||
else
|
||||
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
|
||||
} else {
|
||||
if (smr->ram_base == 0x00030000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram);
|
||||
else if (smr->ram_base == 0x00040000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram + 0x10000);
|
||||
else if (smr->ram_base == 0x00060000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram + 0x20000);
|
||||
else if (smr->ram_base == 0x00070000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram + 0x30000);
|
||||
}
|
||||
mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size);
|
||||
if (!use_separate_smram || (smr->ram_base >= 0x000a0000)) {
|
||||
if (smr->ram_base < (1 << 30))
|
||||
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
|
||||
else
|
||||
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
|
||||
} else {
|
||||
if (smr->ram_base == 0x00030000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram);
|
||||
else if (smr->ram_base == 0x00040000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram + 0x10000);
|
||||
else if (smr->ram_base == 0x00060000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram + 0x20000);
|
||||
else if (smr->ram_base == 0x00070000)
|
||||
mem_mapping_set_exec(&(smr->mapping), smram + 0x30000);
|
||||
}
|
||||
|
||||
smram_map_ex(0, 0, host_base, size, flags_normal);
|
||||
smram_map_ex(1, 0, host_base, size, flags_normal_bus);
|
||||
smram_map_ex(0, 1, host_base, size, flags_smm);
|
||||
smram_map_ex(1, 1, host_base, size, flags_smm_bus);
|
||||
smram_map_ex(0, 0, host_base, size, flags_normal);
|
||||
smram_map_ex(1, 0, host_base, size, flags_normal_bus);
|
||||
smram_map_ex(0, 1, host_base, size, flags_smm);
|
||||
smram_map_ex(1, 1, host_base, size, flags_smm_bus);
|
||||
} else
|
||||
smram_disable(smr);
|
||||
smram_disable(smr);
|
||||
}
|
||||
|
||||
|
||||
/* Enable SMRAM mappings according to flags for both normal and SMM modes. */
|
||||
void
|
||||
smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm)
|
||||
@@ -393,7 +374,6 @@ smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
|
||||
smram_enable_ex(smr, host_base, ram_base, size, flags_normal, flags_normal, flags_smm, flags_smm);
|
||||
}
|
||||
|
||||
|
||||
/* Checks if a SMRAM mapping is enabled or not. */
|
||||
int
|
||||
smram_enabled(smram_t *smr)
|
||||
@@ -401,27 +381,25 @@ smram_enabled(smram_t *smr)
|
||||
int ret = 0;
|
||||
|
||||
if (smr == NULL)
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
else
|
||||
ret = (smr->size != 0x00000000);
|
||||
ret = (smr->size != 0x00000000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Changes the SMRAM state. */
|
||||
void
|
||||
smram_state_change(smram_t *smr, int smm, int flags)
|
||||
{
|
||||
if (smr == NULL) {
|
||||
fatal("smram_tate_change(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
fatal("smram_tate_change(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
smram_map(smm, smr->host_base, smr->size, flags);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
smram_set_separate_smram(uint8_t set)
|
||||
{
|
||||
|
669
src/mem/spd.c
669
src/mem/spd.c
@@ -28,58 +28,52 @@
|
||||
#include <86box/version.h>
|
||||
#include <86box/machine.h>
|
||||
|
||||
#define SPD_ROLLUP(x) ((x) >= 16 ? ((x) -15) : (x))
|
||||
|
||||
#define SPD_ROLLUP(x) ((x) >= 16 ? ((x) - 15) : (x))
|
||||
|
||||
|
||||
int spd_present = 0;
|
||||
spd_t *spd_modules[SPD_MAX_SLOTS];
|
||||
int spd_present = 0;
|
||||
spd_t *spd_modules[SPD_MAX_SLOTS];
|
||||
|
||||
static const device_t spd_device;
|
||||
|
||||
|
||||
#ifdef ENABLE_SPD_LOG
|
||||
int spd_do_log = ENABLE_SPD_LOG;
|
||||
|
||||
|
||||
static void
|
||||
spd_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (spd_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define spd_log(fmt, ...)
|
||||
# define spd_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
spd_close(void *priv)
|
||||
{
|
||||
spd_log("SPD: close()\n");
|
||||
|
||||
for (uint8_t i = 0; i < SPD_MAX_SLOTS; i++) {
|
||||
if (spd_modules[i])
|
||||
i2c_eeprom_close(spd_modules[i]->eeprom);
|
||||
if (spd_modules[i])
|
||||
i2c_eeprom_close(spd_modules[i]->eeprom);
|
||||
}
|
||||
|
||||
spd_present = 0;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
spd_init(const device_t *info)
|
||||
{
|
||||
spd_log("SPD: init()\n");
|
||||
|
||||
for (uint8_t i = 0; i < SPD_MAX_SLOTS; i++) {
|
||||
if (spd_modules[i])
|
||||
spd_modules[i]->eeprom = i2c_eeprom_init(i2c_smbus, SPD_BASE_ADDR + i, spd_modules[i]->data, sizeof(spd_modules[i]->data), 0);
|
||||
if (spd_modules[i])
|
||||
spd_modules[i]->eeprom = i2c_eeprom_init(i2c_smbus, SPD_BASE_ADDR + i, spd_modules[i]->data, sizeof(spd_modules[i]->data), 0);
|
||||
}
|
||||
|
||||
spd_present = 1;
|
||||
@@ -87,7 +81,6 @@ spd_init(const device_t *info)
|
||||
return &spd_modules;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
comp_ui16_rev(const void *elem1, const void *elem2)
|
||||
{
|
||||
@@ -96,123 +89,120 @@ comp_ui16_rev(const void *elem1, const void *elem2)
|
||||
return ((a > b) ? -1 : ((a < b) ? 1 : 0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym)
|
||||
{
|
||||
uint8_t row, next_empty_row, split, i;
|
||||
uint8_t row, next_empty_row, split, i;
|
||||
uint16_t asym;
|
||||
|
||||
/* Populate rows with modules in power-of-2 capacities. */
|
||||
memset(rows, 0, SPD_MAX_SLOTS << 1);
|
||||
for (row = 0; row < slot_count && total_size; row++) {
|
||||
/* populate slot */
|
||||
rows[row] = 1 << log2i(MIN(total_size, max_module_size));
|
||||
if (total_size >= rows[row]) {
|
||||
spd_log("SPD: Initial row %d = %d MB\n", row, rows[row]);
|
||||
total_size -= rows[row];
|
||||
} else {
|
||||
rows[row] = 0;
|
||||
break;
|
||||
}
|
||||
/* populate slot */
|
||||
rows[row] = 1 << log2i(MIN(total_size, max_module_size));
|
||||
if (total_size >= rows[row]) {
|
||||
spd_log("SPD: Initial row %d = %d MB\n", row, rows[row]);
|
||||
total_size -= rows[row];
|
||||
} else {
|
||||
rows[row] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we populate all the RAM? */
|
||||
if (total_size) {
|
||||
/* Work backwards to add the missing RAM as asymmetric modules if possible. */
|
||||
if (enable_asym) {
|
||||
row = slot_count - 1;
|
||||
do {
|
||||
asym = (1 << log2i(MIN(total_size, rows[row])));
|
||||
if (rows[row] + asym <= max_module_size) {
|
||||
rows[row] += asym;
|
||||
total_size -= asym;
|
||||
}
|
||||
} while ((row-- > 0) && total_size);
|
||||
}
|
||||
/* Work backwards to add the missing RAM as asymmetric modules if possible. */
|
||||
if (enable_asym) {
|
||||
row = slot_count - 1;
|
||||
do {
|
||||
asym = (1 << log2i(MIN(total_size, rows[row])));
|
||||
if (rows[row] + asym <= max_module_size) {
|
||||
rows[row] += asym;
|
||||
total_size -= asym;
|
||||
}
|
||||
} while ((row-- > 0) && total_size);
|
||||
}
|
||||
|
||||
if (total_size) /* still not enough */
|
||||
spd_log("SPD: Not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size);
|
||||
if (total_size) /* still not enough */
|
||||
spd_log("SPD: Not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size);
|
||||
}
|
||||
|
||||
/* Populate empty rows by splitting modules... */
|
||||
split = (total_size == 0); /* ...if possible. */
|
||||
while (split) {
|
||||
/* Look for a module to split. */
|
||||
split = 0;
|
||||
for (row = 0; row < slot_count; row++) {
|
||||
if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row]))))
|
||||
continue; /* no module here, module is too small to be split, or asymmetric module */
|
||||
/* Look for a module to split. */
|
||||
split = 0;
|
||||
for (row = 0; row < slot_count; row++) {
|
||||
if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row]))))
|
||||
continue; /* no module here, module is too small to be split, or asymmetric module */
|
||||
|
||||
/* Find next empty row. */
|
||||
next_empty_row = 0;
|
||||
for (i = row + 1; i < slot_count && !next_empty_row; i++) {
|
||||
if (!rows[i])
|
||||
next_empty_row = i;
|
||||
}
|
||||
if (!next_empty_row)
|
||||
break; /* no empty rows left */
|
||||
/* Find next empty row. */
|
||||
next_empty_row = 0;
|
||||
for (i = row + 1; i < slot_count && !next_empty_row; i++) {
|
||||
if (!rows[i])
|
||||
next_empty_row = i;
|
||||
}
|
||||
if (!next_empty_row)
|
||||
break; /* no empty rows left */
|
||||
|
||||
/* Split the module into its own row and the next empty row. */
|
||||
spd_log("SPD: splitting row %d (%d MB) into %d and %d (%d MB each)\n", row, rows[row], row, next_empty_row, rows[row] >> 1);
|
||||
rows[row] = rows[next_empty_row] = rows[row] >> 1;
|
||||
split = 1;
|
||||
break;
|
||||
}
|
||||
/* Split the module into its own row and the next empty row. */
|
||||
spd_log("SPD: splitting row %d (%d MB) into %d and %d (%d MB each)\n", row, rows[row], row, next_empty_row, rows[row] >> 1);
|
||||
rows[row] = rows[next_empty_row] = rows[row] >> 1;
|
||||
split = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sort rows by descending capacity if any were split. */
|
||||
if (split)
|
||||
qsort(rows, slot_count, sizeof(uint16_t), comp_ui16_rev);
|
||||
/* Sort rows by descending capacity if any were split. */
|
||||
if (split)
|
||||
qsort(rows, slot_count, sizeof(uint16_t), comp_ui16_rev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
spd_write_part_no(char *part_no, char *type, uint16_t size)
|
||||
{
|
||||
char size_unit;
|
||||
|
||||
if (size >= 1024) {
|
||||
size_unit = 'G';
|
||||
size >>= 10;
|
||||
size_unit = 'G';
|
||||
size >>= 10;
|
||||
} else {
|
||||
size_unit = 'M';
|
||||
size_unit = 'M';
|
||||
}
|
||||
|
||||
return sprintf(part_no, EMU_NAME "-%s-%03d%c", type, size, size_unit);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
|
||||
{
|
||||
uint8_t slot, slot_count, row, i;
|
||||
uint16_t min_module_size, rows[SPD_MAX_SLOTS], asym;
|
||||
spd_edo_t *edo_data;
|
||||
uint8_t slot, slot_count, row, i;
|
||||
uint16_t min_module_size, rows[SPD_MAX_SLOTS], asym;
|
||||
spd_edo_t *edo_data;
|
||||
spd_sdram_t *sdram_data;
|
||||
|
||||
/* Determine the minimum module size for this RAM type. */
|
||||
switch (ram_type) {
|
||||
case SPD_TYPE_FPM:
|
||||
case SPD_TYPE_EDO:
|
||||
min_module_size = SPD_MIN_SIZE_EDO;
|
||||
break;
|
||||
case SPD_TYPE_FPM:
|
||||
case SPD_TYPE_EDO:
|
||||
min_module_size = SPD_MIN_SIZE_EDO;
|
||||
break;
|
||||
|
||||
case SPD_TYPE_SDRAM:
|
||||
min_module_size = SPD_MIN_SIZE_SDRAM;
|
||||
break;
|
||||
case SPD_TYPE_SDRAM:
|
||||
min_module_size = SPD_MIN_SIZE_SDRAM;
|
||||
break;
|
||||
|
||||
default:
|
||||
spd_log("SPD: unknown RAM type %02X\n", ram_type);
|
||||
return;
|
||||
default:
|
||||
spd_log("SPD: unknown RAM type %02X\n", ram_type);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Count how many slots are enabled. */
|
||||
slot_count = 0;
|
||||
for (slot = 0; slot < SPD_MAX_SLOTS; slot++) {
|
||||
rows[slot] = 0;
|
||||
if (slot_mask & (1 << slot))
|
||||
slot_count++;
|
||||
rows[slot] = 0;
|
||||
if (slot_mask & (1 << slot))
|
||||
slot_count++;
|
||||
}
|
||||
|
||||
/* Populate rows. */
|
||||
@@ -221,372 +211,367 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
|
||||
/* Register SPD devices and populate their data according to the rows. */
|
||||
row = 0;
|
||||
for (slot = 0; (slot < SPD_MAX_SLOTS) && rows[row]; slot++) {
|
||||
if (!(slot_mask & (1 << slot)))
|
||||
continue; /* slot disabled */
|
||||
if (!(slot_mask & (1 << slot)))
|
||||
continue; /* slot disabled */
|
||||
|
||||
spd_modules[slot] = (spd_t *) malloc(sizeof(spd_t));
|
||||
memset(spd_modules[slot], 0, sizeof(spd_t));
|
||||
spd_modules[slot]->slot = slot;
|
||||
spd_modules[slot]->size = rows[row];
|
||||
spd_modules[slot] = (spd_t *) malloc(sizeof(spd_t));
|
||||
memset(spd_modules[slot], 0, sizeof(spd_t));
|
||||
spd_modules[slot]->slot = slot;
|
||||
spd_modules[slot]->size = rows[row];
|
||||
|
||||
/* Determine the second row size, from which the first row size can be obtained. */
|
||||
asym = rows[row] - (1 << log2i(rows[row])); /* separate the powers of 2 */
|
||||
if (!asym) /* is the module asymmetric? */
|
||||
asym = rows[row] >> 1; /* symmetric, therefore divide by 2 */
|
||||
/* Determine the second row size, from which the first row size can be obtained. */
|
||||
asym = rows[row] - (1 << log2i(rows[row])); /* separate the powers of 2 */
|
||||
if (!asym) /* is the module asymmetric? */
|
||||
asym = rows[row] >> 1; /* symmetric, therefore divide by 2 */
|
||||
|
||||
spd_modules[slot]->row1 = rows[row] - asym;
|
||||
spd_modules[slot]->row2 = asym;
|
||||
spd_modules[slot]->row1 = rows[row] - asym;
|
||||
spd_modules[slot]->row2 = asym;
|
||||
|
||||
spd_log("SPD: Registering slot %d = row %d = %d MB (%d/%d)\n", slot, row, rows[row], spd_modules[slot]->row1, spd_modules[slot]->row2);
|
||||
spd_log("SPD: Registering slot %d = row %d = %d MB (%d/%d)\n", slot, row, rows[row], spd_modules[slot]->row1, spd_modules[slot]->row2);
|
||||
|
||||
switch (ram_type) {
|
||||
case SPD_TYPE_FPM:
|
||||
case SPD_TYPE_EDO:
|
||||
edo_data = &spd_modules[slot]->edo_data;
|
||||
switch (ram_type) {
|
||||
case SPD_TYPE_FPM:
|
||||
case SPD_TYPE_EDO:
|
||||
edo_data = &spd_modules[slot]->edo_data;
|
||||
|
||||
/* EDO SPD is specified by JEDEC and present in some modules, but
|
||||
most utilities cannot interpret it correctly. SIV32 at least gets
|
||||
the module capacities right, so it was used as a reference here. */
|
||||
edo_data->bytes_used = 0x80;
|
||||
edo_data->spd_size = 0x08;
|
||||
edo_data->mem_type = ram_type;
|
||||
edo_data->row_bits = SPD_ROLLUP(7 + log2i(spd_modules[slot]->row1)); /* first row */
|
||||
edo_data->col_bits = 9;
|
||||
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
|
||||
edo_data->row_bits |= SPD_ROLLUP(7 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
|
||||
edo_data->col_bits |= 9 << 4; /* same as first row, but just in case */
|
||||
}
|
||||
edo_data->banks = 2;
|
||||
edo_data->data_width_lsb = 64;
|
||||
edo_data->signal_level = SPD_SIGNAL_LVTTL;
|
||||
edo_data->trac = 50;
|
||||
edo_data->tcac = 13;
|
||||
edo_data->refresh_rate = SPD_REFRESH_NORMAL;
|
||||
edo_data->dram_width = 8;
|
||||
/* EDO SPD is specified by JEDEC and present in some modules, but
|
||||
most utilities cannot interpret it correctly. SIV32 at least gets
|
||||
the module capacities right, so it was used as a reference here. */
|
||||
edo_data->bytes_used = 0x80;
|
||||
edo_data->spd_size = 0x08;
|
||||
edo_data->mem_type = ram_type;
|
||||
edo_data->row_bits = SPD_ROLLUP(7 + log2i(spd_modules[slot]->row1)); /* first row */
|
||||
edo_data->col_bits = 9;
|
||||
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
|
||||
edo_data->row_bits |= SPD_ROLLUP(7 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
|
||||
edo_data->col_bits |= 9 << 4; /* same as first row, but just in case */
|
||||
}
|
||||
edo_data->banks = 2;
|
||||
edo_data->data_width_lsb = 64;
|
||||
edo_data->signal_level = SPD_SIGNAL_LVTTL;
|
||||
edo_data->trac = 50;
|
||||
edo_data->tcac = 13;
|
||||
edo_data->refresh_rate = SPD_REFRESH_NORMAL;
|
||||
edo_data->dram_width = 8;
|
||||
|
||||
edo_data->spd_rev = 0x12;
|
||||
for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]);
|
||||
i < sizeof(edo_data->part_no); i++)
|
||||
edo_data->part_no[i] = ' '; /* part number should be space-padded */
|
||||
edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
|
||||
edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
|
||||
edo_data->mfg_year = 20;
|
||||
edo_data->mfg_week = 17;
|
||||
edo_data->spd_rev = 0x12;
|
||||
for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]);
|
||||
i < sizeof(edo_data->part_no); i++)
|
||||
edo_data->part_no[i] = ' '; /* part number should be space-padded */
|
||||
edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
|
||||
edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
|
||||
edo_data->mfg_year = 20;
|
||||
edo_data->mfg_week = 17;
|
||||
|
||||
for (i = 0; i < 63; i++)
|
||||
edo_data->checksum += spd_modules[slot]->data[i];
|
||||
for (i = 0; i < 129; i++)
|
||||
edo_data->checksum2 += spd_modules[slot]->data[i];
|
||||
break;
|
||||
for (i = 0; i < 63; i++)
|
||||
edo_data->checksum += spd_modules[slot]->data[i];
|
||||
for (i = 0; i < 129; i++)
|
||||
edo_data->checksum2 += spd_modules[slot]->data[i];
|
||||
break;
|
||||
|
||||
case SPD_TYPE_SDRAM:
|
||||
sdram_data = &spd_modules[slot]->sdram_data;
|
||||
case SPD_TYPE_SDRAM:
|
||||
sdram_data = &spd_modules[slot]->sdram_data;
|
||||
|
||||
sdram_data->bytes_used = 0x80;
|
||||
sdram_data->spd_size = 0x08;
|
||||
sdram_data->mem_type = ram_type;
|
||||
sdram_data->row_bits = SPD_ROLLUP(6 + log2i(spd_modules[slot]->row1)); /* first row */
|
||||
sdram_data->col_bits = 9;
|
||||
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
|
||||
sdram_data->row_bits |= SPD_ROLLUP(6 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
|
||||
sdram_data->col_bits |= 9 << 4; /* same as first row, but just in case */
|
||||
}
|
||||
sdram_data->rows = 2;
|
||||
sdram_data->data_width_lsb = 64;
|
||||
sdram_data->signal_level = SPD_SIGNAL_LVTTL;
|
||||
sdram_data->tclk = 0x75; /* 7.5 ns = 133.3 MHz */
|
||||
sdram_data->tac = 0x10;
|
||||
sdram_data->refresh_rate = SPD_SDR_REFRESH_SELF | SPD_REFRESH_NORMAL;
|
||||
sdram_data->sdram_width = 8;
|
||||
sdram_data->tccd = 1;
|
||||
sdram_data->burst = SPD_SDR_BURST_PAGE | 1 | 2 | 4 | 8;
|
||||
sdram_data->banks = 4;
|
||||
sdram_data->cas = 0x1c; /* CAS 5/4/3 supported */
|
||||
sdram_data->cslat = sdram_data->we = 0x7f;
|
||||
sdram_data->dev_attr = SPD_SDR_ATTR_EARLY_RAS | SPD_SDR_ATTR_AUTO_PC | SPD_SDR_ATTR_PC_ALL | SPD_SDR_ATTR_W1R_BURST;
|
||||
sdram_data->tclk2 = 0xA0; /* 10 ns = 100 MHz */
|
||||
sdram_data->tclk3 = 0xF0; /* 15 ns = 66.7 MHz */
|
||||
sdram_data->tac2 = sdram_data->tac3 = 0x10;
|
||||
sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1;
|
||||
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) {
|
||||
/* Utilities interpret bank_density a bit differently on asymmetric modules. */
|
||||
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 2); /* first row */
|
||||
sdram_data->bank_density |= 1 << (log2i(spd_modules[slot]->row2 >> 1) - 2); /* second row */
|
||||
} else {
|
||||
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */
|
||||
}
|
||||
sdram_data->ca_setup = sdram_data->data_setup = 0x15;
|
||||
sdram_data->ca_hold = sdram_data->data_hold = 0x08;
|
||||
sdram_data->bytes_used = 0x80;
|
||||
sdram_data->spd_size = 0x08;
|
||||
sdram_data->mem_type = ram_type;
|
||||
sdram_data->row_bits = SPD_ROLLUP(6 + log2i(spd_modules[slot]->row1)); /* first row */
|
||||
sdram_data->col_bits = 9;
|
||||
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
|
||||
sdram_data->row_bits |= SPD_ROLLUP(6 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
|
||||
sdram_data->col_bits |= 9 << 4; /* same as first row, but just in case */
|
||||
}
|
||||
sdram_data->rows = 2;
|
||||
sdram_data->data_width_lsb = 64;
|
||||
sdram_data->signal_level = SPD_SIGNAL_LVTTL;
|
||||
sdram_data->tclk = 0x75; /* 7.5 ns = 133.3 MHz */
|
||||
sdram_data->tac = 0x10;
|
||||
sdram_data->refresh_rate = SPD_SDR_REFRESH_SELF | SPD_REFRESH_NORMAL;
|
||||
sdram_data->sdram_width = 8;
|
||||
sdram_data->tccd = 1;
|
||||
sdram_data->burst = SPD_SDR_BURST_PAGE | 1 | 2 | 4 | 8;
|
||||
sdram_data->banks = 4;
|
||||
sdram_data->cas = 0x1c; /* CAS 5/4/3 supported */
|
||||
sdram_data->cslat = sdram_data->we = 0x7f;
|
||||
sdram_data->dev_attr = SPD_SDR_ATTR_EARLY_RAS | SPD_SDR_ATTR_AUTO_PC | SPD_SDR_ATTR_PC_ALL | SPD_SDR_ATTR_W1R_BURST;
|
||||
sdram_data->tclk2 = 0xA0; /* 10 ns = 100 MHz */
|
||||
sdram_data->tclk3 = 0xF0; /* 15 ns = 66.7 MHz */
|
||||
sdram_data->tac2 = sdram_data->tac3 = 0x10;
|
||||
sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1;
|
||||
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) {
|
||||
/* Utilities interpret bank_density a bit differently on asymmetric modules. */
|
||||
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 2); /* first row */
|
||||
sdram_data->bank_density |= 1 << (log2i(spd_modules[slot]->row2 >> 1) - 2); /* second row */
|
||||
} else {
|
||||
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */
|
||||
}
|
||||
sdram_data->ca_setup = sdram_data->data_setup = 0x15;
|
||||
sdram_data->ca_hold = sdram_data->data_hold = 0x08;
|
||||
|
||||
sdram_data->spd_rev = 0x12;
|
||||
for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]);
|
||||
i < sizeof(sdram_data->part_no); i++)
|
||||
sdram_data->part_no[i] = ' '; /* part number should be space-padded */
|
||||
sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
|
||||
sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
|
||||
sdram_data->mfg_year = 20;
|
||||
sdram_data->mfg_week = 13;
|
||||
sdram_data->spd_rev = 0x12;
|
||||
for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]);
|
||||
i < sizeof(sdram_data->part_no); i++)
|
||||
sdram_data->part_no[i] = ' '; /* part number should be space-padded */
|
||||
sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
|
||||
sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
|
||||
sdram_data->mfg_year = 20;
|
||||
sdram_data->mfg_week = 13;
|
||||
|
||||
sdram_data->freq = 100;
|
||||
sdram_data->features = 0xFF;
|
||||
sdram_data->freq = 100;
|
||||
sdram_data->features = 0xFF;
|
||||
|
||||
for (i = 0; i < 63; i++)
|
||||
sdram_data->checksum += spd_modules[slot]->data[i];
|
||||
for (i = 0; i < 129; i++)
|
||||
sdram_data->checksum2 += spd_modules[slot]->data[i];
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 63; i++)
|
||||
sdram_data->checksum += spd_modules[slot]->data[i];
|
||||
for (i = 0; i < 129; i++)
|
||||
sdram_data->checksum2 += spd_modules[slot]->data[i];
|
||||
break;
|
||||
}
|
||||
|
||||
row++;
|
||||
row++;
|
||||
}
|
||||
|
||||
device_add(&spd_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
|
||||
{
|
||||
uint8_t row, dimm, drb, apollo = 0;
|
||||
uint8_t row, dimm, drb, apollo = 0;
|
||||
uint16_t size, rows[SPD_MAX_SLOTS];
|
||||
|
||||
/* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */
|
||||
if (reg_max < reg_min) {
|
||||
apollo = reg_max;
|
||||
reg_max = reg_min + 7;
|
||||
apollo = reg_max;
|
||||
reg_max = reg_min + 7;
|
||||
}
|
||||
|
||||
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
|
||||
if (!spd_present) {
|
||||
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
}
|
||||
|
||||
/* Write DRBs for each row. */
|
||||
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
|
||||
for (row = 0; row <= (reg_max - reg_min); row++) {
|
||||
dimm = (row >> 1);
|
||||
size = 0;
|
||||
dimm = (row >> 1);
|
||||
size = 0;
|
||||
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
if (spd_modules[dimm]) {
|
||||
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
|
||||
size = (row & 1) ? 0 : drb_unit;
|
||||
else
|
||||
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
|
||||
}
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
if (spd_modules[dimm]) {
|
||||
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
|
||||
size = (row & 1) ? 0 : drb_unit;
|
||||
else
|
||||
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
|
||||
}
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
if (apollo && ((drb & 0xf) < 0xa))
|
||||
drb = apollo + (drb & 0xf);
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
if (apollo && ((drb & 0xf) < 0xa))
|
||||
drb = apollo + (drb & 0xf);
|
||||
|
||||
/* Write DRB register, adding the previous DRB's value. */
|
||||
if (row == 0)
|
||||
regs[drb] = 0;
|
||||
else if ((apollo) && (drb == apollo))
|
||||
regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */
|
||||
else
|
||||
regs[drb] = regs[drb - 1];
|
||||
if (size)
|
||||
regs[drb] += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
|
||||
/* Write DRB register, adding the previous DRB's value. */
|
||||
if (row == 0)
|
||||
regs[drb] = 0;
|
||||
else if ((apollo) && (drb == apollo))
|
||||
regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */
|
||||
else
|
||||
regs[drb] = regs[drb - 1];
|
||||
if (size)
|
||||
regs[drb] += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Needed for 430LX. */
|
||||
void
|
||||
spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
|
||||
{
|
||||
uint8_t row, dimm, drb;
|
||||
uint8_t row, dimm, drb;
|
||||
uint16_t size, row_val = 0, rows[SPD_MAX_SLOTS];
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
|
||||
if (!spd_present) {
|
||||
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
}
|
||||
|
||||
/* Write DRBs for each row. */
|
||||
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
|
||||
for (row = 0; row <= (reg_max - reg_min); row++) {
|
||||
dimm = (row >> 1);
|
||||
size = 0;
|
||||
dimm = (row >> 1);
|
||||
size = 0;
|
||||
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
if (spd_modules[dimm]) {
|
||||
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
|
||||
size = (row & 1) ? 0 : drb_unit;
|
||||
else
|
||||
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
|
||||
}
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
if (spd_modules[dimm]) {
|
||||
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
|
||||
size = (row & 1) ? 0 : drb_unit;
|
||||
else
|
||||
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
|
||||
}
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
|
||||
/* Write DRB register, adding the previous DRB's value. */
|
||||
if (row == 0)
|
||||
row_val = 0;
|
||||
if (size)
|
||||
row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
|
||||
regs[drb] = row_val & 0xff;
|
||||
drb = reg_min + 8 + (row >> 1);
|
||||
shift = (row & 0x01) << 3;
|
||||
regs[drb] = (((row_val & 0xfff) >> 8) << shift);
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
|
||||
/* Write DRB register, adding the previous DRB's value. */
|
||||
if (row == 0)
|
||||
row_val = 0;
|
||||
if (size)
|
||||
row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
|
||||
regs[drb] = row_val & 0xff;
|
||||
drb = reg_min + 8 + (row >> 1);
|
||||
shift = (row & 0x01) << 3;
|
||||
regs[drb] = (((row_val & 0xfff) >> 8) << shift);
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Used by ALi M1531 and M1541/2. */
|
||||
void
|
||||
spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
|
||||
{
|
||||
uint8_t row, dimm;
|
||||
uint8_t drb;
|
||||
uint8_t row, dimm;
|
||||
uint8_t drb;
|
||||
uint16_t size, size_acc = 0;
|
||||
uint16_t rows[SPD_MAX_SLOTS];
|
||||
|
||||
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
|
||||
if (!spd_present) {
|
||||
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
}
|
||||
|
||||
/* Write DRBs for each row. */
|
||||
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
|
||||
for (row = 0; row <= (reg_max - reg_min); row += 2) {
|
||||
dimm = (row >> 2);
|
||||
size = 0;
|
||||
dimm = (row >> 2);
|
||||
size = 0;
|
||||
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
if (spd_modules[dimm]) {
|
||||
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
|
||||
size = ((row >> 1) & 1) ? 0 : drb_unit;
|
||||
else
|
||||
size = ((row >> 1) & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
|
||||
}
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
if (spd_modules[dimm]) {
|
||||
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
|
||||
size = ((row >> 1) & 1) ? 0 : drb_unit;
|
||||
else
|
||||
size = ((row >> 1) & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
|
||||
}
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
/* Determine the DRB register to write. */
|
||||
drb = reg_min + row;
|
||||
|
||||
/* Calculate previous and new size. */
|
||||
if (row == 0)
|
||||
size_acc = 0;
|
||||
else
|
||||
size_acc += (size / drb_unit);
|
||||
/* Calculate previous and new size. */
|
||||
if (row == 0)
|
||||
size_acc = 0;
|
||||
else
|
||||
size_acc += (size / drb_unit);
|
||||
|
||||
/* Write DRB register, adding the previous DRB's value. */
|
||||
regs[drb] = size_acc & 0xff;
|
||||
regs[drb + 1] = (regs[drb + 1] & 0xf0) | ((size_acc >> 8) & 0x0f);
|
||||
/* Write DRB register, adding the previous DRB's value. */
|
||||
regs[drb] = size_acc & 0xff;
|
||||
regs[drb + 1] = (regs[drb + 1] & 0xf0) | ((size_acc >> 8) & 0x0f);
|
||||
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row >> 1, size, regs[drb]);
|
||||
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row >> 1, size, regs[drb]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is needed because the ALi M1621 does this stuff completely differently,
|
||||
as it has DRAM bank registers instead of DRAM row boundary registers. */
|
||||
void
|
||||
spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max)
|
||||
{
|
||||
uint8_t dimm, drb;
|
||||
uint8_t dimm, drb;
|
||||
uint16_t size;
|
||||
uint16_t rows[SPD_MAX_SLOTS];
|
||||
|
||||
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
|
||||
if (!spd_present) {
|
||||
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, 4, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
|
||||
spd_populate(rows, dimm, mem_size >> 10, 4, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
|
||||
}
|
||||
|
||||
/* Write DRBs for each row. */
|
||||
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
|
||||
for (dimm = 0; dimm <= ((reg_max - reg_min) >> 2); dimm++) {
|
||||
size = 0;
|
||||
drb = reg_min + (dimm << 2);
|
||||
size = 0;
|
||||
drb = reg_min + (dimm << 2);
|
||||
|
||||
regs[drb] = 0xff;
|
||||
regs[drb + 1] = 0xff;
|
||||
regs[drb + 2] = 0x00;
|
||||
regs[drb + 3] = 0xf0;
|
||||
regs[drb] = 0xff;
|
||||
regs[drb + 1] = 0xff;
|
||||
regs[drb + 2] = 0x00;
|
||||
regs[drb + 3] = 0xf0;
|
||||
|
||||
if (spd_modules[dimm] == NULL)
|
||||
continue;
|
||||
if (spd_modules[dimm] == NULL)
|
||||
continue;
|
||||
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
size = (spd_modules[dimm]->row1 + spd_modules[dimm]->row2) >> 1;
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
if (spd_present) {
|
||||
/* SPD enabled: use SPD info for this slot, if present. */
|
||||
size = (spd_modules[dimm]->row1 + spd_modules[dimm]->row2) >> 1;
|
||||
} else {
|
||||
/* No SPD: use the values calculated above. */
|
||||
size = (rows[dimm] >> 1);
|
||||
}
|
||||
|
||||
if (spd_modules[dimm]->row1)
|
||||
regs[drb + 3] |= 0x06;
|
||||
if (spd_modules[dimm]->row1)
|
||||
regs[drb + 3] |= 0x06;
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
default:
|
||||
regs[drb + 2] = 0x00;
|
||||
break;
|
||||
case 8:
|
||||
regs[drb + 2] = 0x10;
|
||||
break;
|
||||
case 16:
|
||||
regs[drb + 2] = 0x20;
|
||||
break;
|
||||
case 32:
|
||||
regs[drb + 2] = 0x30;
|
||||
break;
|
||||
case 64:
|
||||
regs[drb + 2] = 0x40;
|
||||
break;
|
||||
case 128:
|
||||
regs[drb + 2] = 0x50;
|
||||
break;
|
||||
case 256:
|
||||
regs[drb + 2] = 0x60;
|
||||
break;
|
||||
}
|
||||
switch (size) {
|
||||
case 4:
|
||||
default:
|
||||
regs[drb + 2] = 0x00;
|
||||
break;
|
||||
case 8:
|
||||
regs[drb + 2] = 0x10;
|
||||
break;
|
||||
case 16:
|
||||
regs[drb + 2] = 0x20;
|
||||
break;
|
||||
case 32:
|
||||
regs[drb + 2] = 0x30;
|
||||
break;
|
||||
case 64:
|
||||
regs[drb + 2] = 0x40;
|
||||
break;
|
||||
case 128:
|
||||
regs[drb + 2] = 0x50;
|
||||
break;
|
||||
case 256:
|
||||
regs[drb + 2] = 0x60;
|
||||
break;
|
||||
}
|
||||
|
||||
if (spd_modules[dimm]->row2) {
|
||||
regs[drb + 3] |= 0x01;
|
||||
regs[drb + 2] |= 0x80;
|
||||
}
|
||||
if (spd_modules[dimm]->row2) {
|
||||
regs[drb + 3] |= 0x01;
|
||||
regs[drb + 2] |= 0x80;
|
||||
}
|
||||
|
||||
spd_log("SPD: DIMM %i: %02X %02X %02X %02X\n", regs[drb], regs[drb + 1], regs[drb + 2], regs[drb + 3]);
|
||||
spd_log("SPD: DIMM %i: %02X %02X %02X %02X\n", regs[drb], regs[drb + 1], regs[drb + 2], regs[drb + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const device_t spd_device = {
|
||||
.name = "Serial Presence Detect ROMs",
|
||||
.name = "Serial Presence Detect ROMs",
|
||||
.internal_name = "spd",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = spd_init,
|
||||
.close = spd_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = spd_init,
|
||||
.close = spd_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
@@ -32,62 +32,57 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/m_xt_xi8088.h>
|
||||
|
||||
typedef struct sst_t {
|
||||
uint8_t manufacturer, id, has_bbp, is_39,
|
||||
page_bytes, sdp, bbp_first_8k, bbp_last_8k;
|
||||
|
||||
typedef struct sst_t
|
||||
{
|
||||
uint8_t manufacturer, id, has_bbp, is_39,
|
||||
page_bytes, sdp, bbp_first_8k, bbp_last_8k;
|
||||
int command_state, id_mode,
|
||||
dirty;
|
||||
|
||||
int command_state, id_mode,
|
||||
dirty;
|
||||
uint32_t size, mask,
|
||||
page_mask, page_base,
|
||||
last_addr;
|
||||
|
||||
uint32_t size, mask,
|
||||
page_mask, page_base,
|
||||
last_addr;
|
||||
uint8_t page_buffer[128],
|
||||
page_dirty[128];
|
||||
uint8_t *array;
|
||||
|
||||
uint8_t page_buffer[128],
|
||||
page_dirty[128];
|
||||
uint8_t *array;
|
||||
mem_mapping_t mapping[8], mapping_h[8];
|
||||
|
||||
mem_mapping_t mapping[8], mapping_h[8];
|
||||
|
||||
pc_timer_t page_write_timer;
|
||||
pc_timer_t page_write_timer;
|
||||
} sst_t;
|
||||
|
||||
static char flash_path[1024];
|
||||
|
||||
static char flash_path[1024];
|
||||
#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */
|
||||
#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */
|
||||
#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */
|
||||
#define W_BOOT_BLOCK_PROT 0x40 /* Only W29C020 */
|
||||
#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */
|
||||
#define SST_ERASE 0x80 /* Both 29 and 39 */
|
||||
/* With data 60h on 6th cycle, it's alt. ID */
|
||||
#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */
|
||||
#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */
|
||||
#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */
|
||||
/* 1st cycle variant only on 39 */
|
||||
|
||||
#define SST 0xbf /* SST Manufacturer's ID */
|
||||
#define SST29EE010 0x0700
|
||||
#define SST29LE_VE010 0x0800
|
||||
#define SST29EE020 0x1000
|
||||
#define SST29LE_VE020 0x1200
|
||||
#define SST39SF512 0xb400
|
||||
#define SST39SF010 0xb500
|
||||
#define SST39SF020 0xb600
|
||||
#define SST39SF040 0xb700
|
||||
|
||||
#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */
|
||||
#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */
|
||||
#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */
|
||||
#define W_BOOT_BLOCK_PROT 0x40 /* Only W29C020 */
|
||||
#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */
|
||||
#define SST_ERASE 0x80 /* Both 29 and 39 */
|
||||
/* With data 60h on 6th cycle, it's alt. ID */
|
||||
#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */
|
||||
#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */
|
||||
#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */
|
||||
/* 1st cycle variant only on 39 */
|
||||
|
||||
#define SST 0xbf /* SST Manufacturer's ID */
|
||||
#define SST29EE010 0x0700
|
||||
#define SST29LE_VE010 0x0800
|
||||
#define SST29EE020 0x1000
|
||||
#define SST29LE_VE020 0x1200
|
||||
#define SST39SF512 0xb400
|
||||
#define SST39SF010 0xb500
|
||||
#define SST39SF020 0xb600
|
||||
#define SST39SF040 0xb700
|
||||
|
||||
#define WINBOND 0xda /* Winbond Manufacturer's ID */
|
||||
#define W29C020 0x4500
|
||||
|
||||
#define SIZE_512K 0x010000
|
||||
#define SIZE_1M 0x020000
|
||||
#define SIZE_2M 0x040000
|
||||
#define SIZE_4M 0x080000
|
||||
#define WINBOND 0xda /* Winbond Manufacturer's ID */
|
||||
#define W29C020 0x4500
|
||||
|
||||
#define SIZE_512K 0x010000
|
||||
#define SIZE_1M 0x020000
|
||||
#define SIZE_2M 0x040000
|
||||
#define SIZE_4M 0x080000
|
||||
|
||||
static void
|
||||
sst_sector_erase(sst_t *dev, uint32_t addr)
|
||||
@@ -95,330 +90,323 @@ sst_sector_erase(sst_t *dev, uint32_t addr)
|
||||
uint32_t base = addr & (dev->mask & ~0xfff);
|
||||
|
||||
if ((base < 0x2000) && (dev->bbp_first_8k & 0x01))
|
||||
return;
|
||||
return;
|
||||
else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01))
|
||||
return;
|
||||
return;
|
||||
|
||||
memset(&dev->array[base], 0xff, 4096);
|
||||
dev->dirty = 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sst_new_command(sst_t *dev, uint32_t addr, uint8_t val)
|
||||
{
|
||||
uint32_t base = 0x00000, size = dev->size;
|
||||
|
||||
if (dev->command_state == 5) switch (val) {
|
||||
case SST_CHIP_ERASE:
|
||||
if (dev->bbp_first_8k & 0x01) {
|
||||
base += 0x2000;
|
||||
size -= 0x2000;
|
||||
}
|
||||
if (dev->command_state == 5)
|
||||
switch (val) {
|
||||
case SST_CHIP_ERASE:
|
||||
if (dev->bbp_first_8k & 0x01) {
|
||||
base += 0x2000;
|
||||
size -= 0x2000;
|
||||
}
|
||||
|
||||
if (dev->bbp_last_8k & 0x01)
|
||||
size -= 0x2000;
|
||||
if (dev->bbp_last_8k & 0x01)
|
||||
size -= 0x2000;
|
||||
|
||||
memset(&(dev->array[base]), 0xff, size);
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
memset(&(dev->array[base]), 0xff, size);
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
|
||||
case SST_SDP_DISABLE:
|
||||
if (!dev->is_39)
|
||||
dev->sdp = 0;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case SST_SDP_DISABLE:
|
||||
if (!dev->is_39)
|
||||
dev->sdp = 0;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
|
||||
case SST_SECTOR_ERASE:
|
||||
if (dev->is_39)
|
||||
sst_sector_erase(dev, addr);
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case SST_SECTOR_ERASE:
|
||||
if (dev->is_39)
|
||||
sst_sector_erase(dev, addr);
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
|
||||
case SST_SET_ID_MODE_ALT:
|
||||
dev->id_mode = 1;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case SST_SET_ID_MODE_ALT:
|
||||
dev->id_mode = 1;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
} else switch (val) {
|
||||
case SST_ERASE:
|
||||
dev->command_state = 3;
|
||||
break;
|
||||
default:
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (val) {
|
||||
case SST_ERASE:
|
||||
dev->command_state = 3;
|
||||
break;
|
||||
|
||||
case SST_SET_ID_MODE:
|
||||
dev->id_mode = 1;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case SST_SET_ID_MODE:
|
||||
dev->id_mode = 1;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
|
||||
case SST_BYTE_PROGRAM:
|
||||
if (!dev->is_39) {
|
||||
dev->sdp = 1;
|
||||
memset(dev->page_buffer, 0xff, 128);
|
||||
memset(dev->page_dirty, 0x00, 128);
|
||||
dev->page_bytes = 0;
|
||||
dev->last_addr = 0xffffffff;
|
||||
timer_on_auto(&dev->page_write_timer, 210.0);
|
||||
}
|
||||
dev->command_state = 6;
|
||||
break;
|
||||
case SST_BYTE_PROGRAM:
|
||||
if (!dev->is_39) {
|
||||
dev->sdp = 1;
|
||||
memset(dev->page_buffer, 0xff, 128);
|
||||
memset(dev->page_dirty, 0x00, 128);
|
||||
dev->page_bytes = 0;
|
||||
dev->last_addr = 0xffffffff;
|
||||
timer_on_auto(&dev->page_write_timer, 210.0);
|
||||
}
|
||||
dev->command_state = 6;
|
||||
break;
|
||||
|
||||
case W_BOOT_BLOCK_PROT:
|
||||
dev->command_state = dev->has_bbp ? 8 : 0;
|
||||
break;
|
||||
case W_BOOT_BLOCK_PROT:
|
||||
dev->command_state = dev->has_bbp ? 8 : 0;
|
||||
break;
|
||||
|
||||
case SST_CLEAR_ID_MODE:
|
||||
dev->id_mode = 0;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case SST_CLEAR_ID_MODE:
|
||||
dev->id_mode = 0;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sst_page_write(void *priv)
|
||||
{
|
||||
sst_t *dev = (sst_t *) priv;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (dev->last_addr != 0xffffffff) {
|
||||
dev->page_base = dev->last_addr & dev->page_mask;
|
||||
for (i = 0; i < 128; i++) {
|
||||
if (dev->page_dirty[i]) {
|
||||
if (((dev->page_base + i) < 0x2000) && (dev->bbp_first_8k & 0x01))
|
||||
continue;
|
||||
else if (((dev->page_base + i) >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01))
|
||||
continue;
|
||||
dev->page_base = dev->last_addr & dev->page_mask;
|
||||
for (i = 0; i < 128; i++) {
|
||||
if (dev->page_dirty[i]) {
|
||||
if (((dev->page_base + i) < 0x2000) && (dev->bbp_first_8k & 0x01))
|
||||
continue;
|
||||
else if (((dev->page_base + i) >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01))
|
||||
continue;
|
||||
|
||||
dev->array[dev->page_base + i] = dev->page_buffer[i];
|
||||
dev->dirty |= 1;
|
||||
}
|
||||
}
|
||||
dev->array[dev->page_base + i] = dev->page_buffer[i];
|
||||
dev->dirty |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev->page_bytes = 0;
|
||||
dev->page_bytes = 0;
|
||||
dev->command_state = 0;
|
||||
timer_disable(&dev->page_write_timer);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sst_read_id(uint32_t addr, void *p)
|
||||
{
|
||||
sst_t *dev = (sst_t *) p;
|
||||
sst_t *dev = (sst_t *) p;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
if ((addr & 0xffff) == 0)
|
||||
ret = dev->manufacturer;
|
||||
ret = dev->manufacturer;
|
||||
else if ((addr & 0xffff) == 1)
|
||||
ret = dev->id;
|
||||
ret = dev->id;
|
||||
#ifdef UNKNOWN_FLASH
|
||||
else if ((addr & 0xffff) == 0x100)
|
||||
ret = 0x1c;
|
||||
ret = 0x1c;
|
||||
else if ((addr & 0xffff) == 0x101)
|
||||
ret = 0x92;
|
||||
ret = 0x92;
|
||||
#endif
|
||||
else if (dev->has_bbp) {
|
||||
if (addr == 0x00002)
|
||||
ret = dev->bbp_first_8k;
|
||||
else if (addr == 0x3fff2)
|
||||
ret = dev->bbp_last_8k;
|
||||
if (addr == 0x00002)
|
||||
ret = dev->bbp_first_8k;
|
||||
else if (addr == 0x3fff2)
|
||||
ret = dev->bbp_last_8k;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sst_buf_write(sst_t *dev, uint32_t addr, uint8_t val)
|
||||
{
|
||||
dev->page_buffer[addr & 0x0000007f] = val;
|
||||
dev->page_dirty[addr & 0x0000007f] = 1;
|
||||
dev->page_dirty[addr & 0x0000007f] = 1;
|
||||
dev->page_bytes++;
|
||||
dev->last_addr = addr;
|
||||
if (dev->page_bytes >= 128) {
|
||||
sst_page_write(dev);
|
||||
sst_page_write(dev);
|
||||
} else
|
||||
timer_on_auto(&dev->page_write_timer, 210.0);
|
||||
timer_on_auto(&dev->page_write_timer, 210.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sst_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
sst_t *dev = (sst_t *) p;
|
||||
|
||||
switch (dev->command_state) {
|
||||
case 0:
|
||||
case 3:
|
||||
/* 1st and 4th Bus Write Cycle */
|
||||
if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) {
|
||||
if (dev->id_mode)
|
||||
dev->id_mode = 0;
|
||||
dev->command_state = 0;
|
||||
} else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa))
|
||||
dev->command_state++;
|
||||
else {
|
||||
if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) {
|
||||
/* 29 series, software data protection off, start loading the page. */
|
||||
memset(dev->page_buffer, 0xff, 128);
|
||||
memset(dev->page_dirty, 0x00, 128);
|
||||
dev->page_bytes = 0;
|
||||
dev->command_state = 7;
|
||||
sst_buf_write(dev, addr, val);
|
||||
} else
|
||||
dev->command_state = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
/* 2nd and 5th Bus Write Cycle */
|
||||
if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55))
|
||||
dev->command_state++;
|
||||
else
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
/* 3rd and 6th Bus Write Cycle */
|
||||
if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) {
|
||||
/* Sector erase - can be on any address. */
|
||||
sst_new_command(dev, addr, val);
|
||||
} else if ((addr & 0x7fff) == 0x5555)
|
||||
sst_new_command(dev, addr, val);
|
||||
else
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case 6:
|
||||
/* Page Load Cycle (29) / Data Write Cycle (39SF) */
|
||||
if (dev->is_39) {
|
||||
dev->command_state = 0;
|
||||
case 0:
|
||||
case 3:
|
||||
/* 1st and 4th Bus Write Cycle */
|
||||
if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) {
|
||||
if (dev->id_mode)
|
||||
dev->id_mode = 0;
|
||||
dev->command_state = 0;
|
||||
} else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa))
|
||||
dev->command_state++;
|
||||
else {
|
||||
if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) {
|
||||
/* 29 series, software data protection off, start loading the page. */
|
||||
memset(dev->page_buffer, 0xff, 128);
|
||||
memset(dev->page_dirty, 0x00, 128);
|
||||
dev->page_bytes = 0;
|
||||
dev->command_state = 7;
|
||||
sst_buf_write(dev, addr, val);
|
||||
} else
|
||||
dev->command_state = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
/* 2nd and 5th Bus Write Cycle */
|
||||
if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55))
|
||||
dev->command_state++;
|
||||
else
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
/* 3rd and 6th Bus Write Cycle */
|
||||
if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) {
|
||||
/* Sector erase - can be on any address. */
|
||||
sst_new_command(dev, addr, val);
|
||||
} else if ((addr & 0x7fff) == 0x5555)
|
||||
sst_new_command(dev, addr, val);
|
||||
else
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
case 6:
|
||||
/* Page Load Cycle (29) / Data Write Cycle (39SF) */
|
||||
if (dev->is_39) {
|
||||
dev->command_state = 0;
|
||||
|
||||
dev->array[addr & dev->mask] = val;
|
||||
dev->dirty = 1;
|
||||
} else {
|
||||
dev->command_state++;
|
||||
sst_buf_write(dev, addr, val);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (!dev->is_39)
|
||||
sst_buf_write(dev, addr, val);
|
||||
break;
|
||||
case 8:
|
||||
if ((addr == 0x00000) && (val == 0x00))
|
||||
dev->bbp_first_8k = 0xff;
|
||||
else if ((addr == 0x3ffff) && (val == 0xff))
|
||||
dev->bbp_last_8k = 0xff;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
dev->array[addr & dev->mask] = val;
|
||||
dev->dirty = 1;
|
||||
} else {
|
||||
dev->command_state++;
|
||||
sst_buf_write(dev, addr, val);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (!dev->is_39)
|
||||
sst_buf_write(dev, addr, val);
|
||||
break;
|
||||
case 8:
|
||||
if ((addr == 0x00000) && (val == 0x00))
|
||||
dev->bbp_first_8k = 0xff;
|
||||
else if ((addr == 0x3ffff) && (val == 0xff))
|
||||
dev->bbp_last_8k = 0xff;
|
||||
dev->command_state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sst_read(uint32_t addr, void *p)
|
||||
{
|
||||
sst_t *dev = (sst_t *) p;
|
||||
sst_t *dev = (sst_t *) p;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if (dev->id_mode)
|
||||
ret = sst_read_id(addr, p);
|
||||
ret = sst_read_id(addr, p);
|
||||
else {
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = dev->array[addr - biosaddr];
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = dev->array[addr - biosaddr];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
sst_readw(uint32_t addr, void *p)
|
||||
{
|
||||
sst_t *dev = (sst_t *) p;
|
||||
sst_t *dev = (sst_t *) p;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if (dev->id_mode)
|
||||
ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8);
|
||||
ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8);
|
||||
else {
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint16_t *)&dev->array[addr - biosaddr];
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint16_t *) &dev->array[addr - biosaddr];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
sst_readl(uint32_t addr, void *p)
|
||||
{
|
||||
sst_t *dev = (sst_t *) p;
|
||||
sst_t *dev = (sst_t *) p;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if (dev->id_mode)
|
||||
ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16);
|
||||
ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16);
|
||||
else {
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint32_t *)&dev->array[addr - biosaddr];
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint32_t *) &dev->array[addr - biosaddr];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sst_add_mappings(sst_t *dev)
|
||||
{
|
||||
int i = 0, count;
|
||||
int i = 0, count;
|
||||
uint32_t base, fbase;
|
||||
uint32_t root_base;
|
||||
|
||||
count = dev->size >> 16;
|
||||
count = dev->size >> 16;
|
||||
root_base = 0x100000 - dev->size;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
base = root_base + (i << 16);
|
||||
fbase = base & biosmask;
|
||||
base = root_base + (i << 16);
|
||||
fbase = base & biosmask;
|
||||
|
||||
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
|
||||
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
if (is6117) {
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | 0x3f00000), 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
} else {
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | (cpu_16bitbus ? 0xf00000 : 0xfff00000)), 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
if (base >= 0xe0000) {
|
||||
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
if (is6117) {
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | 0x3f00000), 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
} else {
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | (cpu_16bitbus ? 0xf00000 : 0xfff00000)), 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sst_init(const device_t *info)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
sst_t *dev = malloc(sizeof(sst_t));
|
||||
memset(dev, 0, sizeof(sst_t));
|
||||
|
||||
@@ -431,48 +419,47 @@ sst_init(const device_t *info)
|
||||
memset(dev->array, 0xff, biosmask + 1);
|
||||
|
||||
dev->manufacturer = info->local & 0xff;
|
||||
dev->id = (info->local >> 8) & 0xff;
|
||||
dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020);
|
||||
dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512);
|
||||
dev->id = (info->local >> 8) & 0xff;
|
||||
dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020);
|
||||
dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512);
|
||||
|
||||
dev->size = info->local & 0xffff0000;
|
||||
if ((dev->size == 0x20000) && (strstr(machine_get_internal_name_ex(machine), "xi8088")) && !xi8088_bios_128kb())
|
||||
dev->size = 0x10000;
|
||||
dev->size = 0x10000;
|
||||
|
||||
dev->mask = dev->size - 1;
|
||||
dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */
|
||||
dev->sdp = 1;
|
||||
dev->mask = dev->size - 1;
|
||||
dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */
|
||||
dev->sdp = 1;
|
||||
dev->bbp_first_8k = dev->bbp_last_8k = 0xfe;
|
||||
|
||||
sst_add_mappings(dev);
|
||||
|
||||
f = nvr_fopen(flash_path, "rb");
|
||||
if (f) {
|
||||
if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size)
|
||||
pclog("Less than %i bytes read from the SST Flash ROM file\n", dev->size);
|
||||
fclose(f);
|
||||
if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size)
|
||||
pclog("Less than %i bytes read from the SST Flash ROM file\n", dev->size);
|
||||
fclose(f);
|
||||
} else
|
||||
dev->dirty = 1; /* It is by definition dirty on creation. */
|
||||
dev->dirty = 1; /* It is by definition dirty on creation. */
|
||||
|
||||
if (!dev->is_39)
|
||||
timer_add(&dev->page_write_timer, sst_page_write, dev, 0);
|
||||
timer_add(&dev->page_write_timer, sst_page_write, dev, 0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sst_close(void *p)
|
||||
{
|
||||
FILE *f;
|
||||
sst_t *dev = (sst_t *)p;
|
||||
FILE *f;
|
||||
sst_t *dev = (sst_t *) p;
|
||||
|
||||
if (dev->dirty) {
|
||||
f = nvr_fopen(flash_path, "wb");
|
||||
if (f != NULL) {
|
||||
fwrite(&(dev->array[0x00000]), dev->size, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
f = nvr_fopen(flash_path, "wb");
|
||||
if (f != NULL) {
|
||||
fwrite(&(dev->array[0x00000]), dev->size, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
free(dev->array);
|
||||
@@ -482,85 +469,85 @@ sst_close(void *p)
|
||||
}
|
||||
|
||||
const device_t sst_flash_29ee010_device = {
|
||||
.name = "SST 29EE010 Flash BIOS",
|
||||
.name = "SST 29EE010 Flash BIOS",
|
||||
.internal_name = "sst_flash_29ee010",
|
||||
.flags = 0,
|
||||
.local = SST | SST29EE010 | SIZE_1M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = SST | SST29EE010 | SIZE_1M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sst_flash_29ee020_device = {
|
||||
.name = "SST 29EE020 Flash BIOS",
|
||||
.name = "SST 29EE020 Flash BIOS",
|
||||
.internal_name = "sst_flash_29ee020",
|
||||
.flags = 0,
|
||||
.local = SST | SST29EE020 | SIZE_2M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = SST | SST29EE020 | SIZE_2M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t winbond_flash_w29c020_device = {
|
||||
.name = "Winbond W29C020 Flash BIOS",
|
||||
.name = "Winbond W29C020 Flash BIOS",
|
||||
.internal_name = "winbond_flash_w29c020",
|
||||
.flags = 0,
|
||||
.local = WINBOND | W29C020 | SIZE_2M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = WINBOND | W29C020 | SIZE_2M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sst_flash_39sf010_device = {
|
||||
.name = "SST 39SF010 Flash BIOS",
|
||||
.name = "SST 39SF010 Flash BIOS",
|
||||
.internal_name = "sst_flash_39sf010",
|
||||
.flags = 0,
|
||||
.local = SST | SST39SF010 | SIZE_1M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = SST | SST39SF010 | SIZE_1M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sst_flash_39sf020_device = {
|
||||
.name = "SST 39SF020 Flash BIOS",
|
||||
.name = "SST 39SF020 Flash BIOS",
|
||||
.internal_name = "sst_flash_39sf020",
|
||||
.flags = 0,
|
||||
.local = SST | SST39SF020 | SIZE_2M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = SST | SST39SF020 | SIZE_2M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sst_flash_39sf040_device = {
|
||||
.name = "SST 39SF040 Flash BIOS",
|
||||
.name = "SST 39SF040 Flash BIOS",
|
||||
.internal_name = "sst_flash_39sf040",
|
||||
.flags = 0,
|
||||
.local = SST | SST39SF040 | SIZE_4M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = SST | SST39SF040 | SIZE_4M,
|
||||
.init = sst_init,
|
||||
.close = sst_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
Reference in New Issue
Block a user