This commit is contained in:
RichardG867
2020-06-26 18:05:57 -03:00
51 changed files with 1867 additions and 299 deletions

269
src/mem/catalyst_flash.c Normal file
View File

@@ -0,0 +1,269 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel 1 Mbit and 2 Mbit, 8-bit and
* 16-bit flash devices.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/machine.h>
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/plat.h>
#define FLAG_WORD 4
#define FLAG_BXB 2
#define FLAG_INV_A16 1
enum
{
BLOCK_MAIN1,
BLOCK_MAIN2,
BLOCK_DATA1,
BLOCK_DATA2,
BLOCK_BOOT,
BLOCKS_NUM
};
enum
{
CMD_SET_READ = 0x00,
CMD_READ_SIGNATURE = 0x90,
CMD_ERASE = 0x20,
CMD_ERASE_CONFIRM = 0x20,
CMD_ERASE_VERIFY = 0xA0,
CMD_PROGRAM = 0x40,
CMD_PROGRAM_VERIFY = 0xC0,
CMD_RESET = 0xFF
};
typedef struct flash_t
{
uint8_t command, pad,
pad0, pad1,
*array;
mem_mapping_t mapping, mapping_h[2];
} flash_t;
static wchar_t flash_path[1024];
static uint8_t
flash_read(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *) p;
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_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;
uint16_t *q;
addr &= biosmask;
q = (uint16_t *)&(dev->array[addr]);
return *q;
}
static uint32_t
flash_readl(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *)p;
uint32_t *q;
addr &= biosmask;
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;
addr &= biosmask;
switch (dev->command) {
case CMD_ERASE:
if (val == CMD_ERASE_CONFIRM)
memset(dev->array, 0xff, biosmask + 1);
break;
case CMD_PROGRAM:
dev->array[addr] = 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_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_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_ROMCS, (void *) dev);
}
static void
catalyst_flash_reset(void *priv)
{
flash_t *dev = (flash_t *) priv;
dev->command = CMD_RESET;
}
static void *
catalyst_flash_init(const device_t *info)
{
FILE *f;
int l;
flash_t *dev;
wchar_t *machine_name, *flash_name;
dev = malloc(sizeof(flash_t));
memset(dev, 0, sizeof(flash_t));
l = strlen(machine_get_internal_name_ex(machine))+1;
machine_name = (wchar_t *) malloc(l * sizeof(wchar_t));
mbstowcs(machine_name, machine_get_internal_name_ex(machine), l);
l = wcslen(machine_name)+5;
flash_name = (wchar_t *)malloc(l*sizeof(wchar_t));
swprintf(flash_name, l, L"%ls.bin", machine_name);
if (wcslen(flash_name) <= 1024)
wcscpy(flash_path, flash_name);
else
wcsncpy(flash_path, flash_name, 1024);
mem_mapping_disable(&bios_mapping);
mem_mapping_disable(&bios_high_mapping);
dev->array = (uint8_t *) malloc(0x20000);
memset(dev->array, 0xff, 0x20000);
catalyst_flash_add_mappings(dev);
dev->command = CMD_RESET;
f = nvr_fopen(flash_path, L"rb");
if (f) {
fread(dev->array, 0x20000, 1, f);
fclose(f);
}
free(flash_name);
free(machine_name);
return dev;
}
static void
catalyst_flash_close(void *p)
{
FILE *f;
flash_t *dev = (flash_t *)p;
f = nvr_fopen(flash_path, L"wb");
fwrite(dev->array, 0x20000, 1, f);
fclose(f);
free(dev->array);
dev->array = NULL;
free(dev);
}
const device_t catalyst_flash_device =
{
"Catalyst 28F010-D Flash BIOS",
DEVICE_PCI,
0,
catalyst_flash_init,
catalyst_flash_close,
catalyst_flash_reset,
NULL, NULL, NULL, NULL
};

View File

@@ -463,6 +463,9 @@ intel_flash_close(void *p)
fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
fclose(f);
free(dev->array);
dev->array = NULL;
free(dev);
}

View File

@@ -81,6 +81,7 @@ page_t *pages, /* RAM page table */
uint32_t pages_sz; /* #pages in table */
uint8_t *ram, *ram2; /* the virtual RAM */
uint8_t page_ff[4096];
uint32_t rammask;
uint8_t *rom; /* the virtual ROM */
@@ -1720,6 +1721,9 @@ page_remove_from_evict_list(page_t *p)
void
mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
{
if ((p != NULL) && (p->mem == page_ff))
return;
#ifdef USE_DYNAREC
if (val != p->mem[addr & 0xfff] || codegen_in_recompile) {
#else
@@ -1743,6 +1747,9 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
void
mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
{
if ((p != NULL) && (p->mem == page_ff))
return;
#ifdef USE_DYNAREC
if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) {
#else
@@ -1776,6 +1783,9 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
void
mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
{
if ((p != NULL) && (p->mem == page_ff))
return;
#ifdef USE_DYNAREC
if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) {
#else
@@ -1805,6 +1815,9 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
void
mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
{
if ((p != NULL) && (p->mem == page_ff))
return;
#ifdef USE_DYNAREC
if ((p == NULL) || (p->mem == NULL) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) {
#else
@@ -1820,6 +1833,9 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
void
mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
{
if ((p != NULL) && (p->mem == page_ff))
return;
#ifdef USE_DYNAREC
if ((p == NULL) || (p->mem == NULL) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
#else
@@ -1837,6 +1853,9 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
void
mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
{
if ((p != NULL) && (p->mem == page_ff))
return;
#ifdef USE_DYNAREC
if ((p == NULL) || (p->mem == NULL) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
#else
@@ -2606,13 +2625,17 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
#endif
for (c = 0; c < pages_sz; c++) {
if (mem_size > 1048576) {
if ((c << 12) < (1 << 30))
if ((c << 12) >= (mem_size << 10))
pages[c].mem = page_ff;
else {
if (mem_size > 1048576) {
if ((c << 12) < (1 << 30))
pages[c].mem = &ram[c << 12];
else
pages[c].mem = &ram2[(c << 12) - (1 << 30)];
} else
pages[c].mem = &ram[c << 12];
else
pages[c].mem = &ram2[(c << 12) - (1 << 30)];
} else
pages[c].mem = &ram[c << 12];
}
if (c < m) {
pages[c].write_b = mem_write_ramb_page;
pages[c].write_w = mem_write_ramw_page;
@@ -2745,6 +2768,7 @@ mem_init(void)
#if FIXME
memset(ff_array, 0xff, sizeof(ff_array));
#endif
memset(page_ff, 0xff, sizeof(page_ff));
/* Reset the memory state. */
mem_reset();

View File

@@ -25,6 +25,7 @@
#include <86box/device.h>
#include <86box/smbus.h>
#include <86box/spd.h>
#include <86box/version.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))