Flash and NVR file names are now generated from the model's internal name;

NVR masks are now stored in the model struct;
More AX JEGA work, still not hooked anywhere;
Fixed a stray wsprintf() in win.c to the correct _swprintf() instead;
Loading a configuration file from the menu now causes the status bar to be updated.
This commit is contained in:
OBattler
2017-06-08 00:58:47 +02:00
parent 112ee420a5
commit c1b7fe015d
9 changed files with 416 additions and 299 deletions

View File

@@ -9,7 +9,7 @@
* Emulation of the EGA, Chips & Technologies SuperEGA, and
* AX JEGA graphics cards.
*
* Version: @(#)vid_ega.c 1.0.1 2017/06/01
* Version: @(#)vid_ega.c 1.0.2 2017/06/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -45,15 +45,8 @@ static int old_overscan_color = 0;
int update_overscan = 0;
#define SBCS 0
#define DBCS 1
#define ID_LEN 6
#define NAME_LEN 8
#define SBCS19_LEN 256 * 19
#define DBCS16_LEN 65536 * 32
uint8_t jfont_sbcs_19[SBCS19_LEN];//256 * 19( * 8)
uint8_t jfont_dbcs_16[DBCS16_LEN];//65536 * 16 * 2 (* 8)
uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */
uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */
typedef struct {
char id[ID_LEN];
@@ -68,6 +61,16 @@ typedef struct {
uint16_t end;
} fontxTbl;
static __inline int ega_jega_enabled(ega_t *ega)
{
if (!ega->is_jega)
{
return 0;
}
return !(ega->RMOD1 & 0x40);
}
void ega_jega_write_font(ega_t *ega)
{
unsigned int chr = ega->RDFFB;
@@ -529,7 +532,14 @@ void ega_poll(void *p)
}
else if (!(ega->gdcreg[6] & 1))
{
ega_render_text_standard(ega, drawcursor);
if (ega_jega_enabled(ega))
{
ega_render_text_jega(ega, drawcursor);
}
else
{
ega_render_text_standard(ega, drawcursor);
}
}
else
{

View File

@@ -9,7 +9,7 @@
* Emulation of the EGA, Chips & Technologies SuperEGA, and
* AX JEGA graphics cards.
*
* Version: @(#)vid_ega.h 1.0.0 2017/05/30
* Version: @(#)vid_ega.h 1.0.1 2017/06/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -110,3 +110,13 @@ void ega_init(ega_t *ega);
extern device_t ega_device;
extern device_t cpqega_device;
extern device_t sega_device;
#define SBCS 0
#define DBCS 1
#define ID_LEN 6
#define NAME_LEN 8
#define SBCS19_LEN 256 * 19
#define DBCS16_LEN 65536 * 32
extern uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */
extern uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */

View File

@@ -8,7 +8,7 @@
*
* EGA renderers.
*
* Version: @(#)vid_ega_render.c 1.0.0 2017/05/30
* Version: @(#)vid_ega_render.c 1.0.1 2017/06/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -147,6 +147,237 @@ void ega_render_text_standard(ega_t *ega, int drawcursor)
}
}
static __inline int is_kanji1(uint8_t chr)
{
return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc);
}
static __inline int is_kanji2(uint8_t chr)
{
return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc);
}
void ega_jega_render_blit_text(ega_t *ega, int x, int dl, int start, int width, uint16_t dat, int cw, uint32_t fg, uint32_t bg)
{
int x_add = (enable_overscan) ? 8 : 0;
int xx = 0;
int xxx = 0;
if (ega->seqregs[1] & 8)
{
for (xx = start; xx < (start + width); xx++)
for (xxx = 0; xxx < cw; xxx++)
((uint32_t *)buffer32->line[dl])[(((x * width) + 32 + (xxx << 1) + ((xx << 1) * cw)) & 2047) + x_add] =
((uint32_t *)buffer32->line[dl])[(((x * width) + 33 + (xxx << 1) + ((xx << 1) * cw)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg;
}
else
{
for (xx = start; xx < (start + width); xx++)
((uint32_t *)buffer32->line[dl])[(((x * width) + 32 + xxx + (xx * cw)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg;
}
}
void ega_render_text_jega(ega_t *ega, int drawcursor)
{
int x_add = (enable_overscan) ? 8 : 0;
int dl = ega_display_line(ega);
uint8_t chr, attr;
uint16_t dat, dat2;
uint32_t charaddr;
int x, xx;
uint32_t fg, bg;
/* Temporary for DBCS. */
unsigned int chr_left;
unsigned int bsattr;
int chr_wide = 0;
uint32_t bg_ex = 0;
uint32_t fg_ex = 0;
int blocks = ega->hdisp;
int fline;
unsigned int pad_y, exattr;
if (fullchange)
{
for (x = 0; x < ega->hdisp; x++)
{
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
chr = ega->vram[(ega->ma << 1) & ega->vrammask];
attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask];
if (chr_wide = 0)
{
if (ega->RMOD2 & 0x80)
{
fg_ex = ega->pallook[ega->egapal[attr & 15]];
if (attr & 0x80 && ega->attrregs[0x10] & 8)
{
bg_ex = ega->pallook[ega->egapal[(attr >> 4) & 7]];
}
else
{
bg_ex = ega->pallook[ega->egapal[attr >> 4]];
}
}
else
{
if (attr & 0x40)
{
/* Reversed in JEGA mode */
bg_ex = ega->pallook[ega->egapal[attr & 15]];
fg_ex = ega->pallook[0];
}
else
{
/* Reversed in JEGA mode */
fg_ex = ega->pallook[ega->egapal[attr & 15]];
bg_ex = ega->pallook[0];
}
}
if (drawcursor)
{
bg = fg_ex;
fg = bg_ex;
}
else
{
fg = fg_ex;
bg = bg_ex;
}
if (attr & 0x80 && ega->attrregs[0x10] & 8)
{
if (ega->blink & 16)
fg = bg;
}
/* Stay drawing if the char code is DBCS and not at last column. */
if (is_kanji1(dat) && (blocks > 1))
{
/* Set the present char/attr code to the next loop. */
chr_left = chr;
chr_wide = 1;
}
else
{
/* The char code is ANK (8 dots width). */
dat = jfont_sbcs_19[chr*19+(ega->sc)]; /* w8xh19 font */
ega_jega_render_blit_text(ega, x, dl, 0, 8, dat, 1, fg, bg);
if (bsattr & 0x20)
{
/* Vertical line. */
dat = 0x18;
ega_jega_render_blit_text(ega, x, fline, 0, 8, dat, 1, fg, bg);
}
if (ega->sc == 18 && bsattr & 0x10)
{
/* Underline. */
dat = 0xff;
ega_jega_render_blit_text(ega, x, fline, 0, 8, dat, 1, fg, bg);
}
chr_wide = 0;
blocks--;
}
}
else
{
/* The char code may be in DBCS. */
pad_y = ega->RPSSC;
exattr = 0;
/* Note: The second column should be applied its basic attribute. */
if (ega->RMOD2 & 0x40)
{
/* If JEGA Extended Attribute is enabled. */
exattr = attr;
if ((exattr & 0x30) == 0x30) pad_y = ega->RPSSL; /* Set top padding of lower 2x character. */
else if (exattr & 0x30) pad_y = ega->RPSSU; /* Set top padding of upper 2x character. */
}
if (ega->sc >= pad_y && ega->sc < 16 + pad_y)
{
/* Check the char code is in Wide charset of Shift-JIS. */
if (is_kanji2(chr))
{
fline = ega->sc - pad_y;
chr_left <<= 8;
/* Fix vertical position. */
chr |= chr_left;
/* Horizontal wide font (Extended Attribute). */
if (exattr & 0x20)
{
if (exattr & 0x10) fline = (fline >> 1) + 8;
else fline = fline >> 1;
}
/* Vertical wide font (Extended Attribute). */
if (exattr & 0x40)
{
dat = jfont_dbcs_16[chr * 32 + fline * 2];
if (!(exattr & 0x08))
dat = jfont_dbcs_16[chr * 32 + fline * 2 + 1];
/* Draw 8 dots. */
ega_jega_render_blit_text(ega, x, dl, 0, 8, dat, 2, fg, bg);
}
else
{
/* Get the font pattern. */
dat = jfont_dbcs_16[chr * 32 + fline * 2];
dat <<= 8;
dat |= jfont_dbcs_16[chr * 32 + fline * 2 + 1];
/* Bold (Extended Attribute). */
if (exattr &= 0x80)
{
dat2 = dat;
dat2 >>= 1;
dat |= dat2;
/* Original JEGA colours the last row with the next column's attribute. */
}
/* Draw 16 dots */
ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg);
}
}
else
{
/* Ignore wide char mode, put blank. */
dat = 0;
ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg);
}
}
else if (ega->sc == (17 + pad_y) && (bsattr & 0x10))
{
/* Underline. */
dat = 0xffff;
ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg);
}
else
{
/* Draw blank */
dat = 0;
ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg);
}
if (bsattr & 0x20)
{
/* Vertical line draw at last. */
dat = 0x0180;
ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg);
}
chr_wide = 0;
blocks -= 2; /* Move by 2 columns. */
}
ega->ma += 4;
ega->ma &= ega->vrammask;
}
}
}
void ega_render_2bpp_lowres(ega_t *ega)
{
int x_add = (enable_overscan) ? 8 : 0;

View File

@@ -8,7 +8,7 @@
*
* EGA renderers.
*
* Version: @(#)vid_ega_render.h 1.0.0 2017/05/30
* Version: @(#)vid_ega_render.h 1.0.1 2017/06/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -29,7 +29,7 @@ extern uint8_t edatlookup[4][4];
void ega_render_blank(ega_t *ega);
void ega_render_text_standard(ega_t *ega, int drawcursor);
void ega_render_text_jega(ega_t *ega);
void ega_render_text_jega(ega_t *ega, int drawcursor);
void ega_render_2bpp_lowres(ega_t *ega);
void ega_render_2bpp_highres(ega_t *ega);

View File

@@ -486,7 +486,7 @@ void create_cdrom_submenu(HMENU m, int id)
for (i = 0; i < 26; i++)
{
wsprintf(s, L"Host CD/DVD Drive (%c:)", i + 0x41);
_swprintf(s, L"Host CD/DVD Drive (%c:)", i + 0x41);
if (host_cdrom_drive_available[i])
{
AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i << 3) | id, s);
@@ -2026,6 +2026,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
/* pclog_w(L"NVR path: %s\n", nvr_path); */
mem_resize();
loadbios();
update_status_bar_panes(hwndStatus);
resetpchard();
}
}

View File

@@ -18,8 +18,10 @@
#include <stdlib.h>
#include "ibm.h"
#include "CPU/cpu.h"
#include "device.h"
#include "mem.h"
#include "model.h"
#include "rom.h"
#define FLASH_IS_BXB 2
@@ -171,75 +173,23 @@ void *intel_flash_init(uint8_t type)
FILE *f;
int i;
flash_t *flash;
wchar_t *model_name;
wchar_t *flash_name;
flash = malloc(sizeof(flash_t));
memset(flash, 0, sizeof(flash_t));
switch(romset)
{
case ROM_REVENGE:
wcscpy(flash_path, L"revenge.bin");
break;
#if 0
case ROM_586MC1:
wcscpy(flash_path, L"586mc1.bin");
break;
#endif
case ROM_PLATO:
wcscpy(flash_path, L"plato.bin");
break;
case ROM_ENDEAVOR:
wcscpy(flash_path, L"endeavor.bin");
break;
case ROM_MB500N:
wcscpy(flash_path, L"mb500n.bin");
break;
case ROM_P54TP4XE:
wcscpy(flash_path, L"p54tp4xe.bin");
break;
case ROM_AP53:
wcscpy(flash_path, L"ap53.bin");
break;
case ROM_P55T2S:
wcscpy(flash_path, L"p55t2s.bin");
break;
case ROM_ACERM3A:
wcscpy(flash_path, L"acerm3a.bin");
break;
#if 0
case ROM_ACERV35N:
wcscpy(flash_path, L"acerv35n.bin");
break;
case ROM_430VX:
wcscpy(flash_path, L"430vx.bin");
break;
#endif
case ROM_P55VA:
wcscpy(flash_path, L"p55va.bin");
break;
case ROM_P55T2P4:
wcscpy(flash_path, L"p55t2p4.bin");
break;
case ROM_P55TVP4:
wcscpy(flash_path, L"p55tvp4.bin");
break;
case ROM_440FX:
wcscpy(flash_path, L"440fx.bin");
break;
case ROM_THOR:
wcscpy(flash_path, L"thor.bin");
break;
case ROM_MRTHOR:
wcscpy(flash_path, L"mrthor.bin");
break;
case ROM_ZAPPA:
wcscpy(flash_path, L"zappa.bin");
break;
case ROM_S1668:
wcscpy(flash_path, L"tpatx.bin");
break;
default:
fatal("intel_flash_init on unsupported ROM set %i\n", romset);
}
model_name = (wchar_t *) malloc((strlen(model_get_internal_name_ex(model)) << 1) + 2);
mbstowcs(model_name, model_get_internal_name_ex(model), strlen(model_get_internal_name_ex(model)) + 1);
flash_name = (wchar_t *) malloc((wcslen(model_name) << 1) + 2 + 8);
_swprintf(flash_name, L"%s.bin", model_name);
wcscpy(flash_path, flash_name);
free(flash_name);
free(model_name);
pclog_w(L"Flash path: %s\n", flash_name);
flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94;
flash->invert_high_pin = (type & FLASH_INVERT);

View File

@@ -119,27 +119,17 @@ extern void at_wd76c10_init(void);
extern void at_ali1429_init(void);
extern void at_headland_init(void);
extern void at_opti495_init(void);
extern void at_sis496_init(void);
#if 0
extern void at_i430vx_init(void);
#endif
extern void at_batman_init(void);
extern void at_endeavor_init(void);
extern void at_dtk486_init(void);
extern void at_r418_init(void);
#if 0
extern void at_586mc1_init(void);
#endif
extern void at_plato_init(void);
extern void at_mb500n_init(void);
extern void at_p54tp4xe_init(void);
extern void at_ap53_init(void);
extern void at_p55t2s_init(void);
extern void at_acerm3a_init(void);
#if 0
extern void at_acerv35n_init(void);
#endif
extern void at_p55t2p4_init(void);
extern void at_p55tvp4_init(void);
extern void at_p55va_init(void);
@@ -161,83 +151,73 @@ int romset;
MODEL models[] =
{
{"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, xt_init, NULL},
{"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device},
{"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL},
{"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL},
{"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
{"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device},
{"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device},
{"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL},
{"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL},
{"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL},
{"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL},
{"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL},
{"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL},
{"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL},
{"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL},
{"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, ibm_at_init, NULL},
{"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL},
{"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL},
{"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL},
{"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL},
{"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL},
{"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL},
{"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL},
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL},
{"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps2_m30_286_init, NULL},
{"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL},
{"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL},
{"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL},
{"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL},
{"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL},
{"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL},
{"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL},
{"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL},
{"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_headland_init, NULL},
{"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL},
{"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, 0, xt_init, NULL},
{"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device},
{"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_laserxt_init, NULL},
{"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_laserxt_init, NULL},
{"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL},
{"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device},
{"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device},
{"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL},
{"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL},
{"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL},
{"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, 0, europc_init, NULL},
{"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL},
{"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL},
{"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL},
{"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL},
{"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 63, ibm_at_init, NULL},
{"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL},
{"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL},
{"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_ide_init, NULL},
{"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL},
{"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_scat_init, NULL},
{"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL},
{"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL},
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps1_m2011_init, NULL},
{"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL},
{"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL},
{"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL},
{"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL},
{"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL},
{"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL},
{"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL},
{"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL},
{"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL},
{"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_headland_init, NULL},
{"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL},
/* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */
{"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL},
{"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL},
{"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL},
{"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, ps1_m2133_init, NULL},
{"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL},
{"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL},
{"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_dtk486_init, NULL},
{"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_sis496_init, NULL},
{"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_r418_init, NULL},
{"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_batman_init, NULL},
#if 0
{"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_586mc1_init, NULL},
#endif
{"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_plato_init, NULL},
{"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL},
{"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL},
{"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_mb500n_init, NULL},
{"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL},
{"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL},
{"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p54tp4xe_init, NULL},
{"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_ap53_init, NULL},
{"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2s_init, NULL},
{"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerm3a_init, NULL},
#if 0
{"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerv35n_init, NULL},
#endif
{"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2p4_init, NULL},
#if 0
{"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL},
#endif
{"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL},
{"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55tvp4_init, NULL},
{"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i440fx_init, NULL},
{"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_s1668_init, NULL},
{"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0}
{"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL},
{"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL},
{"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL},
{"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL},
{"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL},
{"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL},
{"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL},
{"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL},
{"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL},
{"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL},
{"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL},
{"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL},
{"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL},
{"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL},
{"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL},
{"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL},
{"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL},
{"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL},
{"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL},
{"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL},
{"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL},
{"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL},
{"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL},
{"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL},
{"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0,0, 0}
};
@@ -286,6 +266,16 @@ char *model_get_internal_name(void)
return models[model].internal_name;
}
char *model_get_internal_name_ex(int m)
{
return models[m].internal_name;
}
int model_get_nvrmask(int m)
{
return models[m].nvrmask;
}
int model_get_model_from_internal_name(char *s)
{
int c = 0;

View File

@@ -44,6 +44,7 @@ typedef struct {
int flags;
int min_ram, max_ram;
int ram_granularity;
int nvrmask;
void (*init)(void);
device_t *device;
} MODEL;
@@ -62,6 +63,7 @@ extern int model_get_model_from_internal_name(char *s);
extern void model_init(void);
extern device_t *model_getdevice(int model);
extern int model_getromset_ex(int m);
extern char *model_get_internal_name_ex(int m);
extern int model_get_nvrmask(int m);
#endif /*EMU_MODEL_H*/

183
src/nvr.c
View File

@@ -18,16 +18,22 @@
* Copyright 2016-2017 Mahod.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "ibm.h"
#include "CPU/cpu.h"
#include "device.h"
#include "io.h"
#include "mem.h"
#include "model.h"
#include "nvr.h"
#include "pic.h"
#include "rom.h"
#include "timer.h"
#include "rtc.h"
int oldromset;
int oldmodel;
int nvrmask=63;
char nvrram[128];
int nvraddr;
@@ -208,71 +214,27 @@ void loadnvr(void)
FILE *f;
int c;
nvrmask=63;
oldromset=romset;
switch (romset)
{
case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"rb"); break;
case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"rb"); break;
case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"rb"); break;
case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"rb"); break;
case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"rb"); break;
case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"rb"); break;
case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"rb"); nvrmask = 127; break;
case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"rb"); nvrmask = 127; break;
case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"rb"); nvrmask = 127; break;
case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"rb"); nvrmask = 127; break;
case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"rb"); break;
case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"rb"); break;
case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"rb"); break;
case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"rb"); nvrmask = 127; break;
case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"rb"); break;
case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"rb"); break;
case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"rb"); nvrmask = 127; break;
case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"rb"); nvrmask = 127; break;
case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"rb"); nvrmask = 127; break;
case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"rb"); nvrmask = 127; break;
case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"rb"); nvrmask = 127; break;
case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"rb"); break;
case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"rb"); break;
case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"rb"); nvrmask = 127; break;
case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"rb"); nvrmask = 127; break;
case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"rb"); nvrmask = 127; break;
case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"rb"); nvrmask = 127; break;
case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"rb"); nvrmask = 127; break;
case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"rb"); nvrmask = 127; break;
#if 0
case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"rb"); nvrmask = 127; break;
#endif
case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"rb"); nvrmask = 127; break;
case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"rb"); nvrmask = 127; break;
case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"rb"); nvrmask = 127; break;
case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"rb"); nvrmask = 127; break;
case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"rb"); nvrmask = 127; break;
case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"rb"); nvrmask = 127; break;
case ROM_R418: f = nvrfopen(L"r418.nvr", L"rb"); nvrmask = 127; break;
#if 0
case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"rb"); nvrmask = 127; break;
#endif
case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"rb"); nvrmask = 127; break;
case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"rb"); nvrmask = 127; break;
case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"rb"); nvrmask = 127; break;
case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"rb"); nvrmask = 127; break;
case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"rb"); nvrmask = 127; break;
case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"rb"); nvrmask = 127; break;
#if 0
case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"rb"); nvrmask = 127; break;
#endif
case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"rb"); nvrmask = 127; break;
case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"rb"); nvrmask = 127; break;
case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"rb"); nvrmask = 127; break;
case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"rb"); nvrmask = 127; break;
case ROM_THOR: f = nvrfopen(L"thor.nvr", L"rb"); nvrmask = 127; break;
case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"rb"); nvrmask = 127; break;
case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"rb"); nvrmask = 127; break;
case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"rb"); nvrmask = 127; break;
case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"rb"); nvrmask = 127; break;
default: return;
}
oldmodel = model;
wchar_t *model_name;
wchar_t *nvr_name;
model_name = (wchar_t *) malloc((strlen(model_get_internal_name_ex(model)) << 1) + 2);
mbstowcs(model_name, model_get_internal_name_ex(model), strlen(model_get_internal_name_ex(model)) + 1);
nvr_name = (wchar_t *) malloc((wcslen(model_name) << 1) + 2 + 8);
_swprintf(nvr_name, L"%s.nvr", model_name);
pclog_w(L"Opening NVR file: %s...\n", nvr_name);
if (model_get_nvrmask(model) != 0)
{
f = nvrfopen(nvr_name, L"rb");
nvrmask = model_get_nvrmask(model);
}
free(nvr_name);
free(model_name);
if (!f)
{
memset(nvrram,0xFF,128);
@@ -297,73 +259,34 @@ void loadnvr(void)
c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1);
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
}
void savenvr(void)
{
FILE *f;
switch (oldromset)
{
case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"wb"); break;
case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"wb"); break;
case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"wb"); break;
case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"wb"); break;
case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"wb"); break;
case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"wb"); break;
case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"wb"); break;
case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"wb"); break;
case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"wb"); break;
case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"wb"); break;
case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"wb"); break;
case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"wb"); break;
case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"wb"); break;
case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"wb"); break;
case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"wb"); break;
case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"wb"); break;
case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"wb"); break;
case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"wb"); break;
case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"wb"); break;
case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"wb"); break;
case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"wb"); break;
case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"wb"); break;
case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"wb"); break;
case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"wb"); break;
case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"wb"); break;
case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"wb"); break;
case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"wb"); break;
case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"wb"); break;
case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"wb"); break;
#if 0
case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"wb"); break;
#endif
case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"wb"); break;
case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"wb"); break;
case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"wb"); break;
case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"wb"); break;
case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"wb"); break;
case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"wb"); break;
case ROM_R418: f = nvrfopen(L"r418.nvr", L"wb"); break;
#if 0
case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"wb"); break;
#endif
case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"wb"); break;
case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"wb"); break;
case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"wb"); break;
case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"wb"); break;
case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"wb"); break;
case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"wb"); break;
#if 0
case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"wb"); break;
#endif
case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"wb"); break;
case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"wb"); break;
case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"wb"); break;
case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"wb"); break;
case ROM_THOR: f = nvrfopen(L"thor.nvr", L"wb"); break;
case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"wb"); break;
case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"wb"); break;
case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"wb"); break;
case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"wb"); break;
default: return;
}
wchar_t *model_name;
wchar_t *nvr_name;
model_name = (wchar_t *) malloc((strlen(model_get_internal_name_ex(oldmodel)) << 1) + 2);
mbstowcs(model_name, model_get_internal_name_ex(oldmodel), strlen(model_get_internal_name_ex(oldmodel)) + 1);
nvr_name = (wchar_t *) malloc((wcslen(model_name) << 1) + 2 + 8);
_swprintf(nvr_name, L"%s.nvr", model_name);
pclog_w(L"Saving NVR file: %s...\n", nvr_name);
if (model_get_nvrmask(oldmodel) != 0)
{
f = nvrfopen(nvr_name, L"wb");
}
free(nvr_name);
free(model_name);
if (!f)
{
return;
}
fwrite(nvrram,128,1,f);
fclose(f);
}