diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c
index 3759653a5..cc1bd52fd 100644
--- a/src/machine/m_amstrad.c
+++ b/src/machine/m_amstrad.c
@@ -6,10 +6,9 @@
*
* This file is part of the 86Box distribution.
*
- * Emulation of the Amstrad series of PC's.
- *
- * The module supports the PC1512, PC1640 and PC200, including
- * their keyboard, mouse and video devices.
+ * Emulation of the Amstrad series of PC's: PC1512, PC1640 and
+ * PC200, including their keyboard, mouse and video devices, as
+ * well as the PC2086 and PC3086 systems.
*
* PC1512: The PC1512 extends CGA with a bit-planar 640x200x16 mode.
* Most CRTC registers are fixed.
@@ -23,9 +22,15 @@
* PC200: CGA with some NMI stuff. But we don't need that as it's only
* used for TV and LCD displays, and we're emulating a CRT.
*
+ * TODO: This module is not complete yet:
+ *
+ * PC1512: The BIOS assumes 512K RAM, because I cannot figure out how to
+ * read the status of the LK4 jumper on the mainboard, which is
+ * somehow linked to the bus gate array on the NDMACS line...
*
- * TODO: EGA mode does not seem to work in the PC1640; it displays some
- * semi-random junk. Video-memory pointer maybe?
+ * PC1612: EGA mode does not seem to work in the PC1640; it works fine
+ * in alpha mode, but in highres ("ECD350") mode, it displays
+ * some semi-random junk. Video-memory pointer maybe?
*
* Version: @(#)m_amstrad.c 1.0.3 2017/11/08
*
@@ -70,9 +75,6 @@
#include "machine.h"
-#define BIOS_1640_PATH L"roms/machines/pc1640/40100"
-
-
#define STAT_PARITY 0x80
#define STAT_RTIMEOUT 0x40
#define STAT_TTIMEOUT 0x20
@@ -121,8 +123,8 @@ typedef struct {
typedef struct {
/* Machine stuff. */
uint8_t dead;
- uint8_t systemstat_1,
- systemstat_2;
+ uint8_t stat1,
+ stat2;
/* Keyboard stuff. */
int8_t wantirq;
@@ -173,11 +175,11 @@ vid_out_1512(uint16_t addr, uint8_t val, void *priv)
uint8_t old;
switch (addr) {
- case 0x3d4:
+ case 0x03d4:
vid->crtcreg = val & 31;
return;
- case 0x3d5:
+ case 0x03d5:
old = vid->crtc[vid->crtcreg];
vid->crtc[vid->crtcreg] = val & crtc_mask[vid->crtcreg];
if (old != val) {
@@ -188,7 +190,7 @@ vid_out_1512(uint16_t addr, uint8_t val, void *priv)
}
return;
- case 0x3d8:
+ case 0x03d8:
if ((val & 0x12) == 0x12 && (vid->cgamode & 0x12) != 0x12) {
vid->plane_write = 0xf;
vid->plane_read = 0;
@@ -196,19 +198,19 @@ vid_out_1512(uint16_t addr, uint8_t val, void *priv)
vid->cgamode = val;
return;
- case 0x3d9:
+ case 0x03d9:
vid->cgacol = val;
return;
- case 0x3dd:
+ case 0x03dd:
vid->plane_write = val;
return;
- case 0x3de:
+ case 0x03de:
vid->plane_read = val & 3;
return;
- case 0x3df:
+ case 0x03df:
vid->border = val;
return;
}
@@ -222,13 +224,13 @@ vid_in_1512(uint16_t addr, void *priv)
uint8_t ret = 0xff;
switch (addr) {
- case 0x3d4:
+ case 0x03d4:
ret = vid->crtcreg;
- case 0x3d5:
+ case 0x03d5:
ret = vid->crtc[vid->crtcreg];
- case 0x3da:
+ case 0x03da:
ret = vid->stat;
}
@@ -465,10 +467,6 @@ vid_poll_1512(void *priv)
x = (vid->crtc[1] << 3) + 16;
else
x = (vid->crtc[1] << 4) + 16;
-#if 0
-//FIXME: this doesnt seem right???? --FvK
- x = 640 + 16;
-#endif
vid->lastline++;
if ((x != xsize) || ((vid->lastline - vid->firstline) != ysize) || video_force_resize_get()) {
@@ -683,7 +681,8 @@ vid_init_1640(amstrad_t *ams)
vid = (amsvid_t *)malloc(sizeof(amsvid_t));
memset(vid, 0x00, sizeof(amsvid_t));
- rom_init(&vid->bios_rom, BIOS_1640_PATH, 0xc0000, 0x8000, 0x7fff, 0, 0);
+ rom_init(&vid->bios_rom, L"roms/machines/pc1640/40100",
+ 0xc0000, 0x8000, 0x7fff, 0, 0);
ega_init(&vid->ega);
vid->cga.vram = vid->ega.vram;
@@ -744,7 +743,7 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv)
uint8_t old;
switch (addr) {
- case 0x3d5:
+ case 0x03d5:
if (!(vid->plane_read & 0x40) && cga->crtcreg <= 11) {
if (vid->plane_read & 0x80)
nmi = 1;
@@ -763,7 +762,7 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv)
}
return;
- case 0x3d8:
+ case 0x03d8:
old = cga->cgamode;
cga->cgamode = val;
if ((cga->cgamode ^ old) & 3)
@@ -773,7 +772,7 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv)
nmi = 1;
return;
- case 0x3de:
+ case 0x03de:
vid->plane_read = val;
vid->plane_write = 0x1f;
if (val & 0x80)
@@ -793,19 +792,19 @@ vid_in_200(uint16_t addr, void *priv)
uint8_t ret;
switch (addr) {
- case 0x3d8:
+ case 0x03d8:
return(cga->cgamode);
- case 0x3dd:
+ case 0x03dd:
ret = vid->plane_write;
vid->plane_write &= 0x1f;
nmi = 0;
return(ret);
- case 0x3de:
+ case 0x03de:
return((vid->plane_read & 0xc7) | 0x10); /*External CGA*/
- case 0x3df:
+ case 0x03df:
return(vid->border);
}
@@ -934,6 +933,9 @@ static void
kbd_write(uint16_t port, uint8_t val, void *priv)
{
amstrad_t *ams = (amstrad_t *)priv;
+#ifdef WALTJE
+ int i = 0;
+#endif
#if ENABLE_KEYBOARD_LOG
pclog("keyboard_amstrad : write %04X %02X %02X\n", port, val, ams->pb);
@@ -941,13 +943,26 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
switch (port) {
case 0x61:
+ /*
+ * PortB - System Control.
+ *
+ * 7 Enable Status-1/Disable Keyboard Code on Port A.
+ * 6 Enable incoming Keyboard Clock.
+ * 5 Prevent external parity errors from causing NMI.
+ * 4 Disable parity checking of on-board system Ram.
+ * 3 Undefined (Not Connected).
+ * 2 Enable Port C LSB / Disable MSB. (See 1.8.3)
+ * 1 Speaker Drive.
+ * 0 8253 GATE 2 (Speaker Modulate).
+ *
+ * This register is controlled by BIOS and/or ROS.
+ */
#if ENABLE_KEYBOARD_LOG
- pclog("keyboard_amstrad : pb write %02X %02X %i %02X %i\n",
- val, ams->pb, !(ams->pb&0x40), ams->pb&0x40, (val&0x40));
+ pclog("AMSkb: write PB %02x (%02x)\n", val, ams->pb);
#endif
if (!(ams->pb & 0x40) && (val & 0x40)) { /*Reset keyboard*/
#if ENABLE_KEYBOARD_LOG
- pclog("keyboard_amstrad : reset keyboard\n");
+ pclog("AMSkb: reset keyboard\n");
#endif
kbd_adddata(0xaa);
}
@@ -958,29 +973,46 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
timer_update_outstanding();
speaker_update();
- speaker_gated = val & 1;
- speaker_enable = val & 2;
+ speaker_gated = val & 0x01;
+ speaker_enable = val & 0x02;
if (speaker_enable)
was_speaker_enable = 1;
- pit_set_gate(&pit, 2, val & 1);
+ pit_set_gate(&pit, 2, val & 0x01);
- if (val & 0x80)
- ams->pa = 0;
+ if (val & 0x80) {
+ /* Keyboard enabled, so enable PA reading. */
+ ams->pa = 0x00;
+ }
break;
case 0x63:
break;
case 0x64:
- ams->systemstat_1 = val;
+#ifdef WALTJE
+ pclog("AMSkb: STAT1 = %02x (%02x)\n", val, ams->stat1);
+#endif
+ ams->stat1 = val;
break;
case 0x65:
- ams->systemstat_2 = val;
+#ifdef WALTJE
+ pclog("AMSkb: STAT2 = %02x (%02x)\n", val, ams->stat2);
+ i = 512 + (((val & 0x1f) - 0x0e) * 32);
+ pclog("AMSkb: %d KB RAM installed.\n", i);
+#endif
+ ams->stat2 = val;
+ break;
+
+ case 0x66:
+#ifdef WALTJE
+ pclog("AMSkb: RESET REQUESTED !\n");
+#endif
+ pc_reset(1);
break;
default:
- pclog("\nBad Amstrad keyboard write %04X %02X\n", port, val);
+ pclog("AMSkb: bad keyboard write %04X %02X\n", port, val);
}
}
@@ -994,7 +1026,29 @@ kbd_read(uint16_t port, void *priv)
switch (port) {
case 0x60:
if (ams->pb & 0x80) {
- ret = (ams->systemstat_1 | 0xd) & 0x7f;
+ /*
+ * PortA - System Status 1
+ *
+ * 7 Always 0 (KBD7)
+ * 6 Second Floppy disk drive installed (KBD6)
+ * 5 DDM1 - Default Display Mode bit 1 (KBD5)
+ * 4 DDM0 - Default Display Mode bit 0 (KBD4)
+ * 3 Always 1 (KBD3)
+ * 2 Always 1 (KBD2)
+ * 1 8087 NDP installed (KBD1)
+ * 0 Always 1 (KBD0)
+ *
+ * DDM00
+ * 00 unknown, external color?
+ * 01 Color,alpha,40x25, bright white on black.
+ * 10 Color,alpha,80x25, bright white on black.
+ * 11 External Monochrome,80x25.
+ *
+ * Following a reset, the hardware selects VDU mode
+ * 2. The ROS then sets the initial VDU state based
+ * on the DDM value.
+ */
+ ret = (0x0d | ams->stat1) & 0x7f;
} else {
ret = ams->pa;
if (key_queue_start == key_queue_end) {
@@ -1010,19 +1064,44 @@ kbd_read(uint16_t port, void *priv)
case 0x61:
ret = ams->pb;
break;
-
+
case 0x62:
+ /*
+ * PortC - System Status 2.
+ *
+ * 7 On-board system RAM parity error.
+ * 6 External parity error (I/OCHCK from expansion bus).
+ * 5 8253 PIT OUT2 output.
+ * 4 Undefined (Not Connected).
+ *-------------------------------------------
+ * LSB MSB (depends on PB2)
+ *-------------------------------------------
+ * 3 RAM3 Undefined
+ * 2 RAM2 Undefined
+ * 1 RAM1 Undefined
+ * 0 RAM0 RAM4
+ *
+ * PC7 is forced to 0 when on-board system RAM parity
+ * checking is disabled by PB4.
+ *
+ * RAM4:0
+ * 01110 512K bytes on-board.
+ * 01111 544K bytes (32K external).
+ * 10000 576K bytes (64K external).
+ * 10001 608K bytes (96K external).
+ * 10010 640K bytes (128K external or fitted on-board).
+ */
if (ams->pb & 0x04)
- ret = ams->systemstat_2 & 0xf;
- else
- ret = ams->systemstat_2 >> 4;
+ ret = ams->stat2 & 0x0f;
+ else
+ ret = ams->stat2 >> 4;
ret |= (ppispeakon ? 0x20 : 0);
if (nmi)
ret |= 0x40;
break;
default:
- pclog("\nBad Amstrad keyboard read %04X\n", port);
+ pclog("AMDkb: bad keyboard read %04X\n", port);
}
return(ret);
@@ -1057,32 +1136,8 @@ kbd_poll(void *priv)
}
-static uint8_t
-amstrad_read(uint16_t port, void *priv)
-{
- amstrad_t *ams = (amstrad_t *)priv;
-
- pclog("amstrad_read: %04X\n", port);
-
- switch (port) {
- case 0x379:
- return(7);
-
- case 0x37a:
- if (romset == ROM_PC1512) return(0x20);
- if (romset == ROM_PC200) return(0x80);
- return(0);
-
- case 0xdead:
- return(ams->dead);
- }
-
- return(0xff);
-}
-
-
static void
-amstrad_write(uint16_t port, uint8_t val, void *priv)
+ams_write(uint16_t port, uint8_t val, void *priv)
{
amstrad_t *ams = (amstrad_t *)priv;
@@ -1094,6 +1149,50 @@ amstrad_write(uint16_t port, uint8_t val, void *priv)
}
+static uint8_t
+ams_read(uint16_t port, void *priv)
+{
+ amstrad_t *ams = (amstrad_t *)priv;
+ uint8_t ret = 0xff;
+
+ switch (port) {
+ case 0x0379: /* printer control, also set LK1-3.
+ * 0 English Language.
+ * 1 German Language.
+ * 2 French Language.
+ * 3 Spanish Language.
+ * 4 Danish Language.
+ * 5 Swedish Language.
+ * 6 Italian Language.
+ * 7 Diagnostic Mode.
+ */
+ ret = 0x02; /* ENGLISH. no Diags mode */
+ break;
+
+ case 0x037a: /* printer status */
+ switch(romset) {
+ case ROM_PC1512:
+ ret = 0x20;
+ break;
+
+ case ROM_PC200:
+ ret = 0x80;
+ break;
+
+ default:
+ ret = 0x00;
+ }
+ break;
+
+ case 0xdead:
+ ret = ams->dead;
+ break;
+ }
+
+ return(ret);
+}
+
+
void
machine_amstrad_init(machine_t *model)
{
@@ -1102,6 +1201,8 @@ machine_amstrad_init(machine_t *model)
ams = (amstrad_t *)malloc(sizeof(amstrad_t));
memset(ams, 0x00, sizeof(amstrad_t));
+ nvr_at_init(1);
+
machine_common_init(model);
nmi_init();
@@ -1109,10 +1210,10 @@ machine_amstrad_init(machine_t *model)
lpt2_remove_ams();
io_sethandler(0x0379, 2,
- amstrad_read, NULL, NULL, NULL, NULL, NULL, ams);
+ ams_read, NULL, NULL, NULL, NULL, NULL, ams);
io_sethandler(0xdead, 1,
- amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, ams);
+ ams_read, NULL, NULL, ams_write, NULL, NULL, ams);
io_sethandler(0x0078, 1,
ms_read, NULL, NULL, ms_write, NULL, NULL, ams);
@@ -1120,8 +1221,9 @@ machine_amstrad_init(machine_t *model)
io_sethandler(0x007a, 1,
ms_read, NULL, NULL, ms_write, NULL, NULL, ams);
- switch(romset) {
+ if (gfxcard == GFX_INTERNAL) switch(romset) {
case ROM_PC1512:
+ loadfont(L"roms/machines/pc1512/40078", 2);
vid_init_1512(ams);
device_add_ex(&vid_1512_device, ams->vid);
break;
@@ -1132,6 +1234,7 @@ machine_amstrad_init(machine_t *model)
break;
case ROM_PC200:
+ loadfont(L"roms/machines/pc200/40109.bin", 1);
vid_init_200(ams);
device_add_ex(&vid_200_device, ams->vid);
break;
@@ -1147,11 +1250,11 @@ machine_amstrad_init(machine_t *model)
case ROM_MEGAPC:
device_add(¶dise_wd90c11_megapc_device);
break;
- }
+ }
/* Initialize the (custom) keyboard/mouse interface. */
ams->wantirq = 0;
- io_sethandler(0x0060, 6,
+ io_sethandler(0x0060, 7,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, ams);
timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, ams);
keyboard_set_table(scancode_xt);
@@ -1164,8 +1267,5 @@ machine_amstrad_init(machine_t *model)
if (joystick_type != 7)
device_add(&gameport_device);
- /* FIXME: make sure this is correct? */
- nvr_at_init(1);
-
fdc_set_dskchg_activelow();
}
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index e4ea8c968..44991314a 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -46,8 +46,8 @@ machine_t machines[] = {
{ "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 1152, 64, 0, machine_xt_laserxt_init, NULL },
{ "[8088] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 1152, 64, 0, machine_xt_laserxt_init, NULL },
- { "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
- { "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
+ { "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", 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", {{"", 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", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
diff --git a/src/mem.c b/src/mem.c
index 653fff268..51f47cf23 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -392,7 +392,6 @@ void addwritelookup(uint32_t virt, uint32_t phys)
cycles -= 9;
}
-#undef printf
uint8_t *getpccache(uint32_t a)
{
uint32_t a2=a;
@@ -428,7 +427,6 @@ uint8_t *getpccache(uint32_t a)
pclog("Bad getpccache %08X\n", a);
return &ff_array[0-(uintptr_t)(a2 & ~0xFFF)];
}
-#define printf pclog
uint32_t mem_logical_addr;
uint8_t readmembl(uint32_t addr)
@@ -447,7 +445,9 @@ uint8_t readmembl(uint32_t addr)
}
addr &= rammask;
- if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+ if (_mem_read_b[addr >> 14]) {
+ return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+ }
return 0xFF;
}
diff --git a/src/rom.c b/src/rom.c
index c185edc10..0e6434e7d 100644
--- a/src/rom.c
+++ b/src/rom.c
@@ -13,7 +13,7 @@
* - c386sx16 BIOS fails checksum
* - the loadfont() calls should be done elsewhere
*
- * Version: @(#)rom.c 1.0.17 2017/11/04
+ * Version: @(#)rom.c 1.0.18 2017/11/08
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -348,10 +348,12 @@ rom_load_bios(int rom_id)
case ROM_PC1512: /* Amstrad PC-1512 */
if (! rom_load_interleaved(
- L"roms/machines/pc1512/40043.v1",
- L"roms/machines/pc1512/40044.v1",
+ L"roms/machines/pc1512/40044",
+ L"roms/machines/pc1512/40043",
0x00c000, 16384, 0, rom)) break;
- loadfont(L"roms/machines/pc1512/40078.ic127", 2);
+ f = rom_fopen(L"roms/machines/pc1512/40078", L"rb");
+ if (f == NULL) break;
+ (void)fclose(f);
return(1);
case ROM_PC1640: /* Amstrad PC-1640 */
@@ -369,7 +371,8 @@ rom_load_bios(int rom_id)
L"roms/machines/pc200/pc20v2.1",
L"roms/machines/pc200/pc20v2.0",
0x00c000, 16384, 0, rom)) break;
- loadfont(L"roms/machines/pc200/40109.bin", 1);
+ f = rom_fopen(L"roms/machines/pc200/40109", L"rb");
+ if (f == NULL) break;
return(1);
case ROM_TANDY:
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index 052b594c4..f1632239c 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -175,6 +175,7 @@ video_reset(int card)
if ((card == GFX_NONE) || \
(card == GFX_INTERNAL) || machines[machine].fixed_gfxcard) return;
+pclog("VIDEO: initializing '%s'\n", video_cards[video_old_to_new(card)].name);
/* Initialize the video card. */
device_add(video_cards[video_old_to_new(card)].device);