Rewritten 808x CPU emulation core based on reenigne's XTCE, VisiOn, SnatchIt, and 8088 MPH now work correctly;

Fixed PC speaker sound volume in PIT mode 0;
A few CPU emulation clean-ups;
Hard disk controller changing redone in a less messy way;
Re-added the long-missing key send delay handling to the XT keyboard handler;
Fixed a bug that was causing SLiRP not to work when compiled with MingW/GCC 7.3.0-2 or newer;
Some serial mouse and port fixes;
A lot of changes to printer emulation, mostly based on DOSBox-X;
Printer PNG writer now uses statically linked libpng;
Added support for the HxC MFM floppy image format and upped 86F format version to 2.12;
Ported various things from PCem and some from VARCem;
Added the S3 86c801/805 emulation (patch from TheCollector1995);
Fixed and renamed the EGA monitor options;
Better synchronized the 808x to the PIT and the CGA;
Fixed the CGA wait state calculation;
Cleaned up some things in mem.c;
Fixed some things in the floppy emulation to make VisiOn get the correct errors from the copy protection disk;
Fixed several renderer-related bugs, including the SDL2 renderer's failure to take screenshots;
The Jenkins builds are now compiled with MingW/GCC 7.4.0-1 and include all the required DLL's.
This commit is contained in:
OBattler
2019-02-06 03:34:39 +01:00
parent c91b1f2b8e
commit 46d0ed2baa
104 changed files with 7749 additions and 6608 deletions

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Commodore PC3 system.
*
* Version: @(#)m_at_commodore.c 1.0.1 2018/11/06
* Version: @(#)m_at_commodore.c 1.0.2 2018/11/12
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -51,49 +51,54 @@
#include "machine.h"
static void cbm_io_write(uint16_t port, uint8_t val, void *p)
{
serial_t *uart = machine_get_serial(0);
static serial_t *cmd_uart;
lpt1_remove();
lpt2_remove();
switch (val & 3)
{
case 1:
lpt1_init(0x3bc);
break;
case 2:
lpt1_init(0x378);
break;
case 3:
lpt1_init(0x278);
break;
}
switch (val & 0xc)
{
case 0x4:
serial_setup(uart, 0x2f8, 3);
break;
case 0x8:
serial_setup(uart, 0x3f8, 4);
break;
}
static void
cbm_io_write(uint16_t port, uint8_t val, void *p)
{
lpt1_remove();
lpt2_remove();
switch (val & 3) {
case 1:
lpt1_init(0x3bc);
break;
case 2:
lpt1_init(0x378);
break;
case 3:
lpt1_init(0x278);
break;
}
switch (val & 0xc) {
case 0x4:
serial_setup(cmd_uart, 0x2f8, 3);
break;
case 0x8:
serial_setup(cmd_uart, 0x3f8, 4);
break;
}
}
static void cbm_io_init()
static void
cbm_io_init()
{
io_sethandler(0x0230, 0x0001, NULL,NULL,NULL, cbm_io_write,NULL,NULL, NULL);
io_sethandler(0x0230, 0x0001, NULL,NULL,NULL, cbm_io_write,NULL,NULL, NULL);
}
void
machine_at_cmdpc_init(const machine_t *model)
{
machine_at_ide_init(model);
mem_remap_top(384);
device_add(&fdc_at_device);
machine_at_ide_init(model);
cbm_io_init();
mem_remap_top(384);
device_add(&fdc_at_device);
cmd_uart = device_add(&i8250_device);
cbm_io_init();
}

View File

@@ -9,7 +9,7 @@
* SiS sis85c471 Super I/O Chip
* Used by DTK PKM-0038S E-2
*
* Version: @(#)m_at_sis85c471.c 1.0.12 2018/11/09
* Version: @(#)m_at_sis85c471.c 1.0.13 2018/11/12
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -36,6 +36,7 @@
typedef struct {
uint8_t cur_reg,
regs[39];
serial_t *uart[2];
} sis_85c471_t;
@@ -45,7 +46,6 @@ sis_85c471_write(uint16_t port, uint8_t val, void *priv)
sis_85c471_t *dev = (sis_85c471_t *) priv;
uint8_t index = (port & 1) ? 0 : 1;
uint8_t valxor;
serial_t *uart[2];
if (index) {
if ((val >= 0x50) && (val <= 0x76))
@@ -68,13 +68,11 @@ sis_85c471_write(uint16_t port, uint8_t val, void *priv)
ide_pri_enable();
}
if (valxor & 0x20) {
uart[0] = machine_get_serial(0);
uart[1] = machine_get_serial(1);
serial_remove(uart[0]);
serial_remove(uart[1]);
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
if (val & 0x20) {
serial_setup(uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(uart[0], SERIAL2_ADDR, SERIAL2_IRQ);
serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(dev->uart[0], SERIAL2_ADDR, SERIAL2_IRQ);
}
}
if (valxor & 0x10) {
@@ -204,6 +202,9 @@ sis_85c471_init(const device_t *info)
dev->regs[0x23] = 0xF0;
dev->regs[0x26] = 1;
dev->uart[0] = device_add_inst(&i8250_device, 1);
dev->uart[1] = device_add_inst(&i8250_device, 2);
io_sethandler(0x0022, 0x0002,
sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, dev);

View File

@@ -22,6 +22,8 @@ static uint16_t wd76c10_2072;
static uint16_t wd76c10_2872;
static uint16_t wd76c10_5872;
static serial_t *wd76c10_uart[2];
static fdc_t *wd76c10_fdc;
@@ -50,11 +52,6 @@ wd76c10_read(uint16_t port, void *priv)
static void
wd76c10_write(uint16_t port, uint16_t val, void *priv)
{
serial_t *uart[2];
uart[0] = machine_get_serial(0);
uart[1] = machine_get_serial(1);
switch (port)
{
case 0x0092:
@@ -67,27 +64,27 @@ wd76c10_write(uint16_t port, uint16_t val, void *priv)
case 0x2072:
wd76c10_2072 = val;
serial_remove(uart[0]);
serial_remove(wd76c10_uart[0]);
if (!(val & 0x10))
{
switch ((val >> 5) & 7)
{
case 1: serial_setup(uart[0], 0x3f8, 4); break;
case 2: serial_setup(uart[0], 0x2f8, 4); break;
case 3: serial_setup(uart[0], 0x3e8, 4); break;
case 4: serial_setup(uart[0], 0x2e8, 4); break;
case 1: serial_setup(wd76c10_uart[0], 0x3f8, 4); break;
case 2: serial_setup(wd76c10_uart[0], 0x2f8, 4); break;
case 3: serial_setup(wd76c10_uart[0], 0x3e8, 4); break;
case 4: serial_setup(wd76c10_uart[0], 0x2e8, 4); break;
default: break;
}
}
serial_remove(uart[1]);
serial_remove(wd76c10_uart[1]);
if (!(val & 0x01))
{
switch ((val >> 1) & 7)
{
case 1: serial_setup(uart[1], 0x3f8, 3); break;
case 2: serial_setup(uart[1], 0x2f8, 3); break;
case 3: serial_setup(uart[1], 0x3e8, 3); break;
case 4: serial_setup(uart[1], 0x2e8, 3); break;
case 1: serial_setup(wd76c10_uart[1], 0x3f8, 3); break;
case 2: serial_setup(wd76c10_uart[1], 0x2f8, 3); break;
case 3: serial_setup(wd76c10_uart[1], 0x3e8, 3); break;
case 4: serial_setup(wd76c10_uart[1], 0x2e8, 3); break;
default: break;
}
}
@@ -152,6 +149,8 @@ machine_at_wd76c10_init(const machine_t *model)
device_add(&keyboard_ps2_quadtel_device);
wd76c10_fdc = device_add(&fdc_at_device);
wd76c10_uart[0] = device_add_inst(&i8250_device, 1);
wd76c10_uart[1] = device_add_inst(&i8250_device, 2);
wd76c10_init();

View File

@@ -8,7 +8,7 @@
*
* Emulation of the IBM PCjr.
*
* Version: @(#)m_pcjr.c 1.0.11 2018/11/06
* Version: @(#)m_pcjr.c 1.0.12 2018/11/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -756,9 +756,6 @@ machine_pcjr_init(const machine_t *model)
else
setrtcconst(14318184.0);
if (serial_enabled[0])
serial_setup(machine_get_serial(0), 0x2f8, 3);
/* Initialize the video controller. */
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
vid_read, NULL, NULL,

View File

@@ -28,7 +28,7 @@
* boot. Sometimes, they do, and then it shows an "Incorrect
* DOS" error message?? --FvK
*
* Version: @(#)m_ps1.c 1.0.13 2018/11/06
* Version: @(#)m_ps1.c 1.0.14 2018/11/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -98,6 +98,8 @@ typedef struct {
ps1_190;
int ps1_e0_addr;
uint8_t ps1_e0_regs[256];
serial_t *uart;
} ps1_t;
@@ -292,7 +294,6 @@ static void
ps1_write(uint16_t port, uint8_t val, void *priv)
{
ps1_t *ps = (ps1_t *)priv;
serial_t *uart;
switch (port) {
case 0x0092:
@@ -328,11 +329,10 @@ ps1_write(uint16_t port, uint8_t val, void *priv)
case 0x0102:
lpt1_remove();
uart = machine_get_serial(0);
if (val & 0x04)
serial_setup(uart, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(ps->uart, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_remove(uart);
serial_remove(ps->uart);
if (val & 0x10) {
switch ((val >> 5) & 3) {
case 0:
@@ -449,6 +449,8 @@ ps1_setup(int model)
io_sethandler(0x0190, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
ps->uart = device_add_inst(&i8250_device, 1);
lpt1_remove();
lpt1_init(0x3bc);
@@ -459,9 +461,6 @@ ps1_setup(int model)
lpt2_remove();
serial_remove(machine_get_serial(0));
serial_remove(machine_get_serial(1));
/* Enable the PS/1 VGA controller. */
if (model == 2011)
device_add(&ps1vga_device);

View File

@@ -22,6 +22,7 @@
static uint8_t ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190;
static serial_t *ps2_uart;
static struct
@@ -70,8 +71,6 @@ static uint8_t ps2_read(uint16_t port, void *p)
static void ps2_write(uint16_t port, uint8_t val, void *p)
{
serial_t *uart = machine_get_serial(0);
switch (port)
{
case 0x94:
@@ -80,9 +79,9 @@ static void ps2_write(uint16_t port, uint8_t val, void *p)
case 0x102:
lpt1_remove();
if (val & 0x04)
serial_setup(uart, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(ps2_uart, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_remove(uart);
serial_remove(ps2_uart);
if (val & 0x10)
{
switch ((val >> 5) & 3)
@@ -143,6 +142,8 @@ static void ps2board_init(void)
ps2_190 = 0;
ps2_uart = device_add_inst(&i8250_device, 1);
lpt1_init(0x3bc);
memset(&ps2_hd, 0, sizeof(ps2_hd));

View File

@@ -8,7 +8,7 @@
*
* Implementation of MCA-based PS/2 machines.
*
* Version: @(#)m_ps2_mca.c 1.0.4 2018/11/06
* Version: @(#)m_ps2_mca.c 1.0.5 2018/11/12
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -97,6 +97,8 @@ static struct
uint8_t mem_2mb_pos_regs[8];
int pending_cache_miss;
serial_t *uart;
} ps2;
/*The model 70 type 3/4 BIOS performs cache testing. Since 86Box doesn't have any
@@ -372,8 +374,6 @@ static uint8_t model_80_read(uint16_t port)
static void model_50_write(uint16_t port, uint8_t val)
{
serial_t *uart = machine_get_serial(0);
switch (port)
{
case 0x100:
@@ -383,13 +383,13 @@ static void model_50_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial_remove(uart);
serial_remove(ps2.uart);
if (val & 0x04)
{
if (val & 0x08)
serial_setup(uart, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(ps2.uart, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_setup(uart, SERIAL2_ADDR, SERIAL2_IRQ);
serial_setup(ps2.uart, SERIAL2_ADDR, SERIAL2_IRQ);
}
if (val & 0x10)
{
@@ -428,8 +428,6 @@ static void model_50_write(uint16_t port, uint8_t val)
static void model_55sx_write(uint16_t port, uint8_t val)
{
serial_t *uart = machine_get_serial(0);
switch (port)
{
case 0x100:
@@ -439,13 +437,13 @@ static void model_55sx_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial_remove(uart);
serial_remove(ps2.uart);
if (val & 0x04)
{
if (val & 0x08)
serial_setup(uart, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(ps2.uart, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_setup(uart, SERIAL2_ADDR, SERIAL2_IRQ);
serial_setup(ps2.uart, SERIAL2_ADDR, SERIAL2_IRQ);
}
if (val & 0x10)
{
@@ -505,8 +503,6 @@ static void model_55sx_write(uint16_t port, uint8_t val)
static void model_70_type3_write(uint16_t port, uint8_t val)
{
serial_t *uart = machine_get_serial(0);
switch (port)
{
case 0x100:
@@ -515,13 +511,13 @@ static void model_70_type3_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial_remove(uart);
serial_remove(ps2.uart);
if (val & 0x04)
{
if (val & 0x08)
serial_setup(uart, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(ps2.uart, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_setup(uart, SERIAL2_ADDR, SERIAL2_IRQ);
serial_setup(ps2.uart, SERIAL2_ADDR, SERIAL2_IRQ);
}
if (val & 0x10)
{
@@ -555,8 +551,6 @@ static void model_70_type3_write(uint16_t port, uint8_t val)
static void model_80_write(uint16_t port, uint8_t val)
{
serial_t *uart = machine_get_serial(0);
switch (port)
{
case 0x100:
@@ -565,13 +559,13 @@ static void model_80_write(uint16_t port, uint8_t val)
break;
case 0x102:
lpt1_remove();
serial_remove(uart);
serial_remove(ps2.uart);
if (val & 0x04)
{
if (val & 0x08)
serial_setup(uart, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(ps2.uart, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_setup(uart, SERIAL2_ADDR, SERIAL2_IRQ);
serial_setup(ps2.uart, SERIAL2_ADDR, SERIAL2_IRQ);
}
if (val & 0x10)
{
@@ -1246,6 +1240,8 @@ machine_ps2_common_init(const machine_t *model)
pit_ps2_init();
nmi_mask = 0x80;
ps2.uart = device_add_inst(&i8250_device, 1);
}

View File

@@ -115,7 +115,7 @@ static uint8_t mem_read_laserxtems(uint32_t addr, void *priv)
}
static void laserxt_init(is_lxt3)
static void laserxt_init(int is_lxt3)
{
int i;

113
src/machine/m_xt_zenith.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* 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.
*
* Emulation of various Zenith PC compatible machines.
* Currently only the Zenith Data Systems Supersport is emulated.
*
* Version: @(#)m_xt_compaq.c 1.0.0 2019/01/13
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* TheCollector1995, <mariogplayer@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../nmi.h"
#include "../pit.h"
#include "../mem.h"
#include "../rom.h"
#include "../device.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../game/gameport.h"
#include "../keyboard.h"
#include "../lpt.h"
#include "machine.h"
typedef struct {
mem_mapping_t scratchpad_mapping;
uint8_t *scratchpad_ram;
} zenith_t;
static uint8_t zenith_scratchpad_read(uint32_t addr, void *p)
{
zenith_t *dev = (zenith_t *)p;
return dev->scratchpad_ram[addr & 0x3fff];
}
static void zenith_scratchpad_write(uint32_t addr, uint8_t val, void *p)
{
zenith_t *dev = (zenith_t *)p;
dev->scratchpad_ram[addr & 0x3fff] = val;
}
static void *
zenith_scratchpad_init(const device_t *info)
{
zenith_t *dev;
dev = (zenith_t *)malloc(sizeof(zenith_t));
memset(dev, 0x00, sizeof(zenith_t));
dev->scratchpad_ram = malloc(0x4000);
mem_mapping_disable(&bios_mapping[4]);
mem_mapping_disable(&bios_mapping[5]);
mem_mapping_add(&dev->scratchpad_mapping, 0xf0000, 0x4000,
zenith_scratchpad_read, NULL, NULL,
zenith_scratchpad_write, NULL, NULL,
dev->scratchpad_ram, MEM_MAPPING_EXTERNAL, dev);
return dev;
}
static void
zenith_scratchpad_close(void *p)
{
zenith_t *dev = (zenith_t *)p;
free(dev->scratchpad_ram);
free(dev);
}
static const device_t zenith_scratchpad_device = {
"Zenith scratchpad RAM",
0, 0,
zenith_scratchpad_init, zenith_scratchpad_close, NULL,
NULL,
NULL,
NULL
};
void
machine_xt_zenith_init(const machine_t *model)
{
machine_common_init(model);
lpt2_remove(); /* only one parallel port */
device_add(&zenith_scratchpad_device);
pit_set_out_func(&pit, 1, pit_refresh_timer_xt);
device_add(&keyboard_xt_device);
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type != 7)
device_add(&gameport_device);
}

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine.c 1.0.36 2018/11/05
* Version: @(#)machine.c 1.0.37 2018/11/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -42,8 +42,6 @@ int machine;
int AT, PCI;
int romset;
static serial_t *uart[2];
#ifdef ENABLE_MACHINE_LOG
int machine_do_log = ENABLE_MACHINE_LOG;
@@ -92,12 +90,6 @@ machine_init(void)
/* All good, boot the machine! */
machines[machine].init(&machines[machine]);
/* For non-PCI machines, add two regular 8250 UART's. */
if (!PCI) {
uart[0] = device_add_inst(&i8250_device, 1);
uart[1] = device_add_inst(&i8250_device, 2);
}
/* If it's a PCI or MCA machine, reset the video card
after initializing the machine, so the slots work correctly. */
if (PCI || MCA)
@@ -105,13 +97,6 @@ machine_init(void)
}
serial_t *
machine_get_serial(int port)
{
return uart[port];
}
void
machine_common_init(const machine_t *model)
{

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine.h 1.0.30 2018/09/15
* Version: @(#)machine.h 1.0.32 2019/01/13
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -82,9 +82,6 @@ extern int machine_getmachine(int romset);
extern char *machine_getname(void);
extern char *machine_get_internal_name(void);
extern int machine_get_machine_from_internal_name(char *s);
#ifdef EMU_SERIAL_H
extern serial_t *machine_get_serial(int port);
#endif
extern void machine_init(void);
#ifdef EMU_DEVICE_H
extern const device_t *machine_getdevice(int machine);
@@ -199,6 +196,7 @@ extern void machine_xt_t1000_init(const machine_t *);
extern void machine_xt_t1200_init(const machine_t *);
extern void machine_xt_xi8088_init(const machine_t *);
extern void machine_xt_zenith_init(const machine_t *);
#ifdef EMU_DEVICE_H
extern const device_t *xi8088_get_device(void);

View File

@@ -11,7 +11,7 @@
* NOTES: OpenAT wip for 286-class machine with open BIOS.
* PS2_M80-486 wip, pending receipt of TRM's for machine.
*
* Version: @(#)machine_table.c 1.0.44 2018/11/03
* Version: @(#)machine_table.c 1.0.45 2019/01/13
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -51,7 +51,8 @@ const machine_t machines[] = {
{ "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL },
#endif
{ "[8088] Xi8088", ROM_XI8088, "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL },
{ "[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL },
{ "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },