The PCjr now correctly supports 64 kB of RAM, also other fixes and added support to PCjr ports 11h and 12h to the POST card (it now supports up to 4 different ports in the range).

This commit is contained in:
OBattler
2023-08-09 06:26:59 +02:00
parent b28d82a38e
commit fdac446d25
4 changed files with 109 additions and 32 deletions

View File

@@ -29,10 +29,14 @@
#include <86box/postcard.h>
#include "cpu.h"
#define POSTCARDS_NUM 4
#define POSTCARD_MASK (POSTCARDS_NUM - 1)
static uint16_t postcard_port;
static uint8_t postcard_written;
static uint8_t postcard_code;
static uint8_t postcard_prev_code;
static uint8_t postcard_written[POSTCARDS_NUM];
static uint8_t postcard_ports_num = 1;
static uint8_t postcard_codes[POSTCARDS_NUM];
static uint8_t postcard_prev_codes[POSTCARDS_NUM];
#define UISTR_LEN 13
static char postcard_str[UISTR_LEN]; /* UI output string */
@@ -61,12 +65,46 @@ int postcard_do_log = 0;
static void
postcard_setui(void)
{
if (!postcard_written)
sprintf(postcard_str, "POST: -- --");
else if (postcard_written == 1)
sprintf(postcard_str, "POST: %02X --", postcard_code);
else
sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code);
if (postcard_ports_num > 1) {
char ps[2][POSTCARDS_NUM][64] = { { 0 },
{ 0 } };
for (uint8_t i = 0; i < POSTCARDS_NUM; i++) {
if (!postcard_written[i]) {
sprintf(ps[0][i], "--");
sprintf(ps[1][i], "--");
} else if (postcard_written[i] == 1) {
sprintf(ps[0][i], "%02X", postcard_codes[i]);
sprintf(ps[1][i], "--");
} else {
sprintf(ps[0][i], "%02X", postcard_codes[i]);
sprintf(ps[1][i], "%02X", postcard_prev_codes[i]);
}
}
switch (postcard_ports_num) {
default:
case 2:
sprintf(postcard_str, "POST: %s%s %s%s",
ps[0][0], ps[0][1], ps[1][0], ps[1][1]);
break;
case 3:
sprintf(postcard_str, "POST: %s/%s%s %s/%s%s",
ps[0][0], ps[0][1], ps[0][2], ps[1][0], ps[1][1], ps[1][2]);
break;
case 4:
sprintf(postcard_str, "POST: %s%s/%s%s %s%s/%s%s",
ps[0][0], ps[0][1], ps[0][2], ps[0][3],
ps[1][0], ps[1][1], ps[1][2], ps[1][3]);
break;
}
} else {
if (!postcard_written[0])
sprintf(postcard_str, "POST: -- --");
else if (postcard_written[0] == 1)
sprintf(postcard_str, "POST: %02X --", postcard_codes[0]);
else
sprintf(postcard_str, "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]);
}
ui_sb_bugui(postcard_str);
@@ -79,22 +117,27 @@ postcard_setui(void)
static void
postcard_reset(void)
{
postcard_written = 0;
postcard_code = postcard_prev_code = 0x00;
memset(postcard_written, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
memset(postcard_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
memset(postcard_prev_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
postcard_setui();
}
static void
postcard_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
postcard_write(uint16_t port, uint8_t val, UNUSED(void *priv))
{
if (postcard_written && (val == postcard_code))
uint8_t matches = 0;
if (postcard_written[port & POSTCARD_MASK] &&
(val == postcard_codes[port & POSTCARD_MASK]))
return;
postcard_prev_code = postcard_code;
postcard_code = val;
if (postcard_written < 2)
postcard_written++;
postcard_prev_codes[port & POSTCARD_MASK] = postcard_codes[port & POSTCARD_MASK];
postcard_codes[port & POSTCARD_MASK] = val;
if (postcard_written[port & POSTCARD_MASK] < 2)
postcard_written[port & POSTCARD_MASK]++;
postcard_setui();
}
@@ -102,7 +145,7 @@ postcard_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
static void *
postcard_init(UNUSED(const device_t *info))
{
postcard_reset();
postcard_ports_num = 1;
if (machine_has_bus(machine, MACHINE_BUS_MCA))
postcard_port = 0x680; /* MCA machines */
@@ -110,16 +153,21 @@ postcard_init(UNUSED(const device_t *info))
postcard_port = 0x190; /* ISA PS/2 machines */
else if (strstr(machines[machine].name, " IBM XT "))
postcard_port = 0x60; /* IBM XT */
else if (strstr(machines[machine].name, " IBM PCjr"))
else if (strstr(machines[machine].name, " IBM PCjr")) {
postcard_port = 0x10; /* IBM PCjr */
else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI))
postcard_ports_num = 3; /* IBM PCjr error ports 11h and 12h */
} else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI))
postcard_port = 0x84; /* ISA Compaq machines */
else if (strstr(machines[machine].name, "Olivetti"))
postcard_port = 0x378; /* Olivetti machines */
else
postcard_port = 0x80; /* AT and clone machines */
postcard_log("POST card initializing on port %04Xh\n", postcard_port);
postcard_reset();
if (postcard_port)
io_sethandler(postcard_port, 1,
io_sethandler(postcard_port, postcard_ports_num,
NULL, NULL, NULL, postcard_write, NULL, NULL, NULL);
return postcard_write;
@@ -129,7 +177,7 @@ static void
postcard_close(UNUSED(void *priv))
{
if (postcard_port)
io_removehandler(postcard_port, 1,
io_removehandler(postcard_port, postcard_ports_num,
NULL, NULL, NULL, postcard_write, NULL, NULL, NULL);
}

View File

@@ -122,12 +122,20 @@ static int key_queue_end = 0;
static void
recalc_address(pcjr_t *pcjr)
{
uint8_t masked_memctrl = pcjr->memctrl;
/* According to the Technical Reference, bits 2 and 5 are
ignored if there is only 64k of RAM and there are only
4 pages. */
if (mem_size < 128)
masked_memctrl &= ~0x24;
if ((pcjr->memctrl & 0xc0) == 0xc0) {
pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14];
pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11];
pcjr->vram = &ram[(masked_memctrl & 0x06) << 14];
pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11];
} else {
pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14];
pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11];
pcjr->vram = &ram[(masked_memctrl & 0x07) << 14];
pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11];
}
}
@@ -160,11 +168,17 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
uint8_t old;
switch (addr) {
case 0x3d0:
case 0x3d2:
case 0x3d4:
case 0x3d6:
pcjr->crtcreg = val & 0x1f;
return;
case 0x3d1:
case 0x3d3:
case 0x3d5:
case 0x3d7:
old = pcjr->crtc[pcjr->crtcreg];
pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg];
if (old != val) {
@@ -190,6 +204,10 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
case 0x3df:
pcjr->memctrl = val;
pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to
then be readable from port 60, others it errors out
with only 64k RAM set (but somehow, still works with
128k or more RAM). */
pcjr->addr_mode = val >> 6;
recalc_address(pcjr);
break;
@@ -206,11 +224,17 @@ vid_in(uint16_t addr, void *priv)
uint8_t ret = 0xff;
switch (addr) {
case 0x3d0:
case 0x3d2:
case 0x3d4:
case 0x3d6:
ret = pcjr->crtcreg;
break;
case 0x3d1:
case 0x3d3:
case 0x3d5:
case 0x3d7:
ret = pcjr->crtc[pcjr->crtcreg];
break;
@@ -591,8 +615,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0x61:
pcjr->pb = val;
timer_process();
if (cassette != NULL)
pc_cas_set_motor(cassette, (pcjr->pb & 0x08) == 0);
@@ -647,7 +669,9 @@ kbd_read(uint16_t port, void *priv)
case 0x62:
ret = (pcjr->latched ? 1 : 0);
ret |= 0x02; /*Modem card not installed*/
ret |= 0x02; /* Modem card not installed */
if (mem_size < 128)
ret |= 0x08; /* 64k expansion card not installed */
if ((pcjr->pb & 0x08) || (cassette == NULL))
ret |= (ppispeakon ? 0x10 : 0);
else
@@ -810,6 +834,8 @@ machine_pcjr_init(UNUSED(const machine_t *model))
pcjr = malloc(sizeof(pcjr_t));
memset(pcjr, 0x00, sizeof(pcjr_t));
pcjr->memctrl = -1;
if (mem_size < 128)
pcjr->memctrl &= ~0x24;
display_type = machine_get_config_int("display_type");
pcjr->composite = (display_type != PCJR_RGB);
@@ -853,7 +879,10 @@ machine_pcjr_init(UNUSED(const machine_t *model))
device_add(&ns8250_pcjr_device);
serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */
/* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119 */
/* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119
Note by Miran Grca: Meanwhile, the same Technical Reference clearly says that
the gameport is on ports 201-207. */
standalone_gameport_type = &gameport_201_device;
return ret;

View File

@@ -302,7 +302,7 @@ const machine_t machines[] = {
.bus_flags = MACHINE_PCJR,
.flags = MACHINE_VIDEO_FIXED,
.ram = {
.min = 128,
.min = 64,
.max = 640,
.step = 64
},

View File

@@ -492,7 +492,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
if (is286)
update_pending();
else
timer_on_auto(&pic_timer, .0 * ((10000000.0 * (double) xt_cpu_multi) / (double) cpu_s->rspeed));
timer_on_auto(&pic_timer, 1.0 * ((10000000.0 * (double) xt_cpu_multi) / (double) cpu_s->rspeed));
break;
default: