Merge branch '86Box:master' into main

This commit is contained in:
MaxwellS04
2025-02-27 05:52:10 +07:00
committed by GitHub
53 changed files with 6195 additions and 170 deletions

View File

@@ -189,6 +189,7 @@ int voodoo_enabled = 0; /* (C) video o
int lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */
int ibm8514_standalone_enabled = 0; /* (C) video option */
int xga_standalone_enabled = 0; /* (C) video option */
int da2_standalone_enabled = 0; /* (C) video option */
uint32_t mem_size = 0; /* (C) memory size (Installed on
system board)*/
uint32_t isa_mem_size = 0; /* (C) memory size (ISA Memory Cards) */
@@ -1093,13 +1094,24 @@ pc_init_modules(void)
void
pc_send_ca(uint16_t sc)
{
keyboard_input(1, 0x1D); /* Ctrl key pressed */
keyboard_input(1, 0x38); /* Alt key pressed */
keyboard_input(1, sc);
usleep(50000);
keyboard_input(0, sc);
keyboard_input(0, 0x38); /* Alt key released */
keyboard_input(0, 0x1D); /* Ctrl key released */
if (keyboard_mode >= 0x81) {
/* Use R-Alt because PS/55 DOS and OS/2 assign L-Alt Kanji */
keyboard_input(1, 0x1D); /* Ctrl key pressed */
keyboard_input(1, 0x138); /* R-Alt key pressed */
keyboard_input(1, sc);
usleep(50000);
keyboard_input(0, sc);
keyboard_input(0, 0x138); /* R-Alt key released */
keyboard_input(0, 0x1D); /* Ctrl key released */
} else {
keyboard_input(1, 0x1D); /* Ctrl key pressed */
keyboard_input(1, 0x38); /* Alt key pressed */
keyboard_input(1, sc);
usleep(50000);
keyboard_input(0, sc);
keyboard_input(0, 0x38); /* Alt key released */
keyboard_input(0, 0x1D); /* Ctrl key released */
}
}
/* Send the machine a Control-Alt-DEL sequence. */

View File

@@ -454,6 +454,7 @@ load_video(void)
ibm8514_active = ibm8514_standalone_enabled;
xga_standalone_enabled = !!ini_section_get_int(cat, "xga", 0);
xga_active = xga_standalone_enabled;
da2_standalone_enabled = !!ini_section_get_int(cat, "da2", 0);
show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1);
video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0);
@@ -2139,6 +2140,11 @@ save_video(void)
else
ini_section_set_int(cat, "xga", xga_standalone_enabled);
if (da2_standalone_enabled == 0)
ini_section_delete_var(cat, "da2");
else
ini_section_set_int(cat, "da2", da2_standalone_enabled);
// TODO
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
if (gfxcard[i] == 0)

View File

@@ -113,12 +113,33 @@ typedef union {
static __inline void
x87_push(double i)
{
#ifdef X87_INLINE_ASM
unsigned char buffer[10];
#else
x87_conv_t test;
#endif
#ifdef USE_NEW_DYNAREC
cpu_state.TOP--;
#else
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
#endif
cpu_state.ST[cpu_state.TOP & 7] = i;
#ifdef X87_INLINE_ASM
__asm volatile(""
:
:
: "memory");
__asm volatile("fldl %1\n"
"fstpt %0\n" : "=m"(buffer) : "m"(i));
cpu_state.MM[cpu_state.TOP & 7].q = (*(uint64_t*)buffer);
#else
x87_to80(i, &test);
cpu_state.MM[cpu_state.TOP & 7].q = test.eind.ll;
#endif
#ifdef USE_NEW_DYNAREC
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
#else
@@ -129,6 +150,11 @@ x87_push(double i)
static __inline void
x87_push_u64(uint64_t i)
{
#ifdef X87_INLINE_ASM
unsigned char buffer[10];
#else
x87_conv_t test;
#endif
union {
double d;
uint64_t ll;
@@ -142,6 +168,21 @@ x87_push_u64(uint64_t i)
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
#endif
cpu_state.ST[cpu_state.TOP & 7] = td.d;
#ifdef X87_INLINE_ASM
__asm volatile(""
:
:
: "memory");
__asm volatile("fldl %1\n"
"fstpt %0\n" : "=m"(buffer) : "m"(td.d));
cpu_state.MM[cpu_state.TOP & 7].q = (*(uint64_t*)buffer);
#else
x87_to80(td.d, &test);
cpu_state.MM[cpu_state.TOP & 7].q = test.eind.ll;
#endif
#ifdef USE_NEW_DYNAREC
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
#else

View File

@@ -490,7 +490,7 @@ device_get_name(const device_t *dev, int bus, char *name)
const char *sbus = NULL;
const char *fbus;
char *tname;
char pbus[12] = { 0 };
char pbus[16] = { 0 };
if (dev == NULL)
return;

View File

@@ -715,7 +715,7 @@ cassette_init(UNUSED(const device_t *info))
const device_t cassette_device = {
.name = "IBM PC/PCjr Cassette Device",
.internal_name = "cassette",
.flags = 0,
.flags = DEVICE_CASETTE,
.local = 0,
.init = cassette_init,
.close = cassette_close,

View File

@@ -862,7 +862,7 @@ static const device_config_t mm58167_config[] = {
static const device_t mm58167_device = {
.name = "Generic MM58167 RTC",
.internal_name = "rtc_mm58167",
.flags = DEVICE_ISA,
.flags = DEVICE_ISA | DEVICE_SIDECAR,
.local = ISARTC_MM58167,
.init = isartc_init,
.close = isartc_close,

View File

@@ -18,10 +18,13 @@
* Copyright 2015-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van Kempen.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/machine.h>
#include <86box/keyboard.h>
@@ -41,6 +44,24 @@ uint16_t key_prefix_2_2 = 0x000; /* Invalid */
uint16_t key_uncapture_1 = 0x058; /* F12 */
uint16_t key_uncapture_2 = 0x000; /* Invalid */
#ifdef ENABLE_KBC_AT_LOG
int kbc_at_do_log = ENABLE_KBC_AT_LOG;
static void
kbc_at_log(const char* fmt, ...)
{
va_list ap;
if (kbc_at_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define kbc_at_log(fmt, ...)
#endif
void (*keyboard_send)(uint16_t val);
static int recv_key[512] = { 0 }; /* keyboard input buffer */
@@ -56,6 +77,39 @@ static uint8_t num_lock = 0;
static uint8_t scroll_lock = 0;
static uint8_t shift = 0;
static int key5576mode = 0;
typedef struct {
const uint16_t sc;
const uint8_t mk[4];
const uint8_t brk[4];
} scconvtbl;
static scconvtbl scconv55_8a[18 + 1] =
{
// clang-format off
{.sc = 0x02 , .mk = { 0x48 }, .brk = { 0 } }, /* '1' -> 'Clear/ /SysRq' */
{.sc = 0x03 , .mk = { 0x49 }, .brk = { 0 } }, /* '2' -> '終了 (Exit)' */
{.sc = 0x04 , .mk = { 0x46 }, .brk = { 0 } }, /* '3' -> 'メッセージ (Message)/ /応答 (Respond)' */
{.sc = 0x05 , .mk = { 0x44 }, .brk = { 0 } }, /* '4' -> 'サイズ変換 (Change Size)/ /横倍角 (2x Width)' */
{.sc = 0x06 , .mk = { 0x42 }, .brk = { 0 } }, /* '5' -> '単語登録 (Register Word)/ /再交換 (Re-change)' */
{.sc = 0x07 , .mk = { 0x43 }, .brk = { 0 } }, /* '6' -> '漢字 (Kanji)/ /番号 (Number)' */
{.sc = 0x08 , .mk = { 0x40 }, .brk = { 0 } }, /* '7' -> '取消 (Cancel)' */
{.sc = 0x09 , .mk = { 0x51 }, .brk = { 0 } }, /* '8' -> 'コピー (Copy)/ /移動 (Move)' */
{.sc = 0x3d , .mk = { 0x76 }, .brk = { 0 } }, /* 'F3' -> 'Cr Bnk/領域呼出 (Call Range)/All Cr/登録 (Register)' */
{.sc = 0x3e , .mk = { 0x77 }, .brk = { 0 } }, /* 'F4' -> '割込み (Interrupt)' */
{.sc = 0x3f , .mk = { 0x78 }, .brk = { 0 } }, /* 'F5' -> 'UF1' */
{.sc = 0x40 , .mk = { 0x79 }, .brk = { 0 } }, /* 'F6' -> 'UF2' */
{.sc = 0x41 , .mk = { 0x7a }, .brk = { 0 } }, /* 'F7' -> 'UF3' */
{.sc = 0x42 , .mk = { 0x7b }, .brk = { 0 } }, /* 'F8' -> 'UF4' */
{.sc = 0x43 , .mk = { 0x7c }, .brk = { 0 } }, /* 'F9' -> 'EOF/Erase/ErInp' */
{.sc = 0x44 , .mk = { 0x7d }, .brk = { 0 } }, /* 'F10' -> 'Attn/ /CrSel' */
{.sc = 0x57 , .mk = { 0x7e }, .brk = { 0 } }, /* 'F11' -> 'PA1/ /DvCncl' */
{.sc = 0x58 , .mk = { 0x7f }, .brk = { 0 } }, /* 'F12' -> 'PA2/ /PA3' */
{.sc = 0 , .mk = { 0 }, .brk = { 0 } } /* end */
// clang-format on
};
void
keyboard_init(void)
{
@@ -111,6 +165,36 @@ key_process(uint16_t scan, int down)
oldkey[scan] = down;
kbc_at_log("Key %04X,%d in process\n", scan, down);
c = 0;
/* According to Japanese DOS K3.3 manual (N:SC18-2194-1),
IBM 5576-002, -003 keyboards have the one-time key conversion mode
that emulates 18 out of 131 keys on IBM 5576-001 keyboard.
It is triggered by pressing L-Shift (⇧) + L-Ctrl + R-Alt (前面キー)
when the scancode set is 82h or 8ah.
*/
if (key5576mode) {
int i = 0;
if (!down) {
/* Do and exit the 5576-001 emulation when a key is pressed other than trigger keys. */
if (scan != 0x1d && scan != 0x2a && scan != 0x138)
{
key5576mode = 0;
kbc_at_log("5576-001 key emulation disabled.\n");
}
}
while (scconv55_8a[i].sc != 0)
{
if (scconv55_8a[i].sc == scan) {
while (scconv55_8a[i].mk[c] != 0)
keyboard_send(scconv55_8a[i].mk[c++]);
return;
}
i++;
}
}
if (down && (codes[scan].mk[0] == 0))
return;
@@ -137,6 +221,13 @@ key_process(uint16_t scan, int down)
if (fake_shift_needed(scan))
keyboard_send(0x101);
}
/* Enter the 5576-001 emulation mode. */
if (keyboard_mode == 0x8a && down && ((keyboard_get_shift() & 0x43) == 0x43))
{
key5576mode = 1;
kbc_at_log("5576-001 key emulation enabled.\n");
}
}
/* Handle a keystroke event from the UI layer. */
@@ -232,7 +323,7 @@ keyboard_input(int down, uint16_t scan)
}
}
/* pclog("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */
/* kbc_at_log("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */
recv_key_ui[scan & 0x1ff] = down;
if (mouse_capture || !kbd_req_capture || video_fullscreen) {
@@ -241,6 +332,20 @@ keyboard_input(int down, uint16_t scan)
}
}
void
keyboard_all_up(void)
{
for (unsigned short i = 0; i < 0x200; i++) {
if (recv_key_ui[i]) {
recv_key_ui[i] = 0;
}
if (recv_key[i]) {
recv_key[i] = 0;
key_process(i, 0);
}
}
}
static uint8_t
keyboard_do_break(uint16_t scan)
{

File diff suppressed because it is too large Load Diff

View File

@@ -815,7 +815,7 @@ static const device_config_t ms_config[] = {
const device_t mouse_logibus_device = {
.name = "Logitech/Microsoft Bus Mouse",
.internal_name = "logibus",
.flags = DEVICE_ISA,
.flags = DEVICE_ISA | DEVICE_SIDECAR,
.local = MOUSE_TYPE_LOGIBUS,
.init = bm_init,
.close = bm_close,
@@ -843,7 +843,7 @@ const device_t mouse_logibus_onboard_device = {
const device_t mouse_msinport_device = {
.name = "Microsoft Bus Mouse (InPort)",
.internal_name = "msbus",
.flags = DEVICE_ISA,
.flags = DEVICE_ISA | DEVICE_SIDECAR,
.local = MOUSE_TYPE_INPORT,
.init = bm_init,
.close = bm_close,

View File

@@ -77,6 +77,7 @@ static const struct {
{ &xtide_acculogic_device },
{ &xtide_device },
{ &esdi_ps2_device },
{ &esdi_integrated_device },
{ &ide_pci_device },
{ &ide_pci_2ch_device },
{ &ide_vlb_device },

View File

@@ -150,6 +150,11 @@ typedef struct esdi_t {
uint8_t pos_regs[8];
} esdi_t;
enum {
ESDI_IS_ADAPTER,
ESDI_IS_INTEGRATED
};
#define STATUS_DMA_ENA (1 << 7)
#define STATUS_IRQ_PENDING (1 << 6)
#define STATUS_CMD_IN_PROGRESS (1 << 5)
@@ -694,32 +699,48 @@ esdi_callback(void *priv)
break;
case CMD_GET_DEV_CONFIG:
ESDI_DRIVE_ONLY();
if (!drive->present) {
device_not_present(dev);
return;
if (dev->cmd_dev == ATTN_HOST_ADAPTER)
{
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
/* INT 13, AX=1C0B - ESDI FIXED DISK - GET ADAPTER CONFIGURATION */
/* The PS/55 will test sector buffer after this request is done. */
dev->status_len = 6;
dev->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER;
dev->status_data[1] = 0;
dev->status_data[2] = 0;
/* bit 15-12: chip revision = 0011b, bit 11-8: sector buffer size = n * 256 bytes (n must be < 6) */
dev->status_data[3] = 0x3200;
dev->status_data[4] = 0;
dev->status_data[5] = 0;
}
else
{
ESDI_DRIVE_ONLY();
if (!drive->present) {
device_not_present(dev);
return;
}
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
dev->status_len = 6;
dev->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER;
dev->status_data[1] = 0x10; /*Zero defect*/
dev->status_data[2] = drive->sectors & 0xffff;
dev->status_data[3] = drive->sectors >> 16;
dev->status_data[4] = drive->tracks;
dev->status_data[5] = drive->hpc | (drive->spt << 16);
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
dev->status_len = 6;
dev->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER;
dev->status_data[1] = 0x10; /*Zero defect*/
dev->status_data[2] = drive->sectors & 0xffff;
dev->status_data[3] = drive->sectors >> 16;
dev->status_data[4] = drive->tracks;
dev->status_data[5] = drive->hpc | (drive->spt << 16);
}
esdi_mca_log("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n",
drive->sectors,
dev->status_data[0], dev->status_data[1],
dev->status_data[2], dev->status_data[3],
dev->status_data[4], dev->status_data[5]);
drive->sectors,
dev->status_data[0], dev->status_data[1],
dev->status_data[2], dev->status_data[3],
dev->status_data[4], dev->status_data[5]);
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
@@ -733,7 +754,7 @@ esdi_callback(void *priv)
dev->status_len = 5;
dev->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER;
dev->status_data[1] = 0xffdd; /*MCA ID*/
dev->status_data[1] = dev->pos_regs[1] | (dev->pos_regs[0] << 8); /*MCA ID*/
dev->status_data[2] = dev->pos_regs[3] | (dev->pos_regs[2] << 8);
dev->status_data[3] = 0xff;
dev->status_data[4] = 0xff;
@@ -1233,6 +1254,62 @@ esdi_mca_write(int port, uint8_t val, void *priv)
}
}
static void
esdi_integrated_mca_write(int port, uint8_t val, void* priv)
{
esdi_t* dev = (esdi_t*)priv;
esdi_mca_log("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n",
port, val, dev->pos_regs[2], dev->pos_regs[3]);
if (port < 0x102)
return;
/* Save the new value. */
dev->pos_regs[port & 7] = val;
io_removehandler(ESDI_IOADDR_PRI, 8,
esdi_read, esdi_readw, NULL,
esdi_write, esdi_writew, NULL, dev);
switch (dev->pos_regs[2] & 0x3c) {
case 0x14:
dev->dma = 5;
break;
case 0x18:
dev->dma = 6;
break;
case 0x1c:
dev->dma = 7;
break;
case 0x00:
dev->dma = 0;
break;
case 0x04:
dev->dma = 1;
break;
case 0x0c:
dev->dma = 3;
break;
case 0x10:
dev->dma = 4;
break;
default:
break;
}
if (dev->pos_regs[2] & 1) {
io_sethandler(ESDI_IOADDR_PRI, 8,
esdi_read, esdi_readw, NULL,
esdi_write, esdi_writew, NULL, dev);
/* Say hello. */
esdi_mca_log("ESDI: I/O=3510, IRQ=14, DMA=%d\n",
dev->dma);
}
}
static uint8_t
esdi_mca_feedb(void *priv)
{
@@ -1241,6 +1318,16 @@ esdi_mca_feedb(void *priv)
return (dev->pos_regs[2] & 1);
}
static void esdi_reset(void* priv)
{
esdi_t* dev = (esdi_t*)priv;
if (!dev->in_reset) {
dev->in_reset = 1;
esdi_mca_set_callback(dev, ESDI_TIME * 50);
dev->status = STATUS_BUSY;
}
}
static void *
esdi_init(UNUSED(const device_t *info))
{
@@ -1256,10 +1343,12 @@ esdi_init(UNUSED(const device_t *info))
/* Mark as unconfigured. */
dev->irq_status = 0xff;
rom_init_interleaved(&dev->bios_rom,
BIOS_FILE_H, BIOS_FILE_L,
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
mem_mapping_disable(&dev->bios_rom.mapping);
if (info->local == ESDI_IS_ADAPTER) {
rom_init_interleaved(&dev->bios_rom,
BIOS_FILE_H, BIOS_FILE_L,
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
mem_mapping_disable(&dev->bios_rom.mapping);
}
dev->drives[0].present = dev->drives[1].present = 0;
@@ -1292,12 +1381,25 @@ esdi_init(UNUSED(const device_t *info))
break;
}
/* Set the MCA ID for this controller, 0xFFDD. */
dev->pos_regs[0] = 0xff;
dev->pos_regs[1] = 0xdd;
/* Set the MCA ID for this controller. */
if (info->local == ESDI_IS_ADAPTER) {
dev->pos_regs[0] = 0xff;
dev->pos_regs[1] = 0xdd;
} else if (info->local == ESDI_IS_INTEGRATED) {
dev->pos_regs[0] = 0x9f;
dev->pos_regs[1] = 0xdf;
}
/* Enable the device. */
mca_add(esdi_mca_read, esdi_mca_write, esdi_mca_feedb, NULL, dev);
if (info->local == ESDI_IS_INTEGRATED) {
/* The slot number of this controller is fixed by the planar. IBM PS/55 5551-T assigns it #5. */
int slotno = device_get_config_int("in_esdi_slot");
if (slotno)
mca_add_to_slot(esdi_mca_read, esdi_integrated_mca_write, esdi_mca_feedb, esdi_reset, dev, slotno - 1);
else
mca_add(esdi_mca_read, esdi_integrated_mca_write, esdi_mca_feedb, esdi_reset, dev);
} else
mca_add(esdi_mca_read, esdi_mca_write, esdi_mca_feedb, NULL, dev);
/* Mark for a reset. */
dev->in_reset = 1;
@@ -1337,7 +1439,7 @@ const device_t esdi_ps2_device = {
.name = "IBM PS/2 ESDI Fixed Disk Adapter (MCA)",
.internal_name = "esdi_mca",
.flags = DEVICE_MCA,
.local = 0,
.local = ESDI_IS_ADAPTER,
.init = esdi_init,
.close = esdi_close,
.reset = NULL,
@@ -1346,3 +1448,52 @@ const device_t esdi_ps2_device = {
.force_redraw = NULL,
.config = NULL
};
static device_config_t
esdi_integrated_config[] = {
{
.name = "in_esdi_slot",
.description = "Slot #",
.type = CONFIG_SELECTION,
.selection = {
{ .description = "Auto", .value = 0 },
{ .description = "1", .value = 1 },
{ .description = "2", .value = 2 },
{ .description = "3", .value = 3 },
{ .description = "4", .value = 4 },
{ .description = "5", .value = 5 },
{ .description = "6", .value = 6 },
{ .description = "7", .value = 7 },
{ .description = "8", .value = 8 }
},
.default_int = 0
},
{ .type = -1 }
};
/*
Device for an IBM DBA (Direct Bus Attachment) hard disk.
The Disk BIOS is included in the System ROM.
Some models have an exclusive channel slot for the DBA hard disk.
Following IBM machines are supported:
* PS/2 model 55SX
* PS/2 model 65SX
* PS/2 model 70 type 3 (Slot #4)
* PS/2 model 70 type 4 (Slot #4)
* PS/55 model 5550-T (Slot #5)
* PS/55 model 5550-V (Slot #5)
*/
const device_t
esdi_integrated_device = {
.name = "IBM Integrated Fixed Disk and Controller (MCA)",
.internal_name = "esdi_integrated_mca",
.flags = DEVICE_MCA,
.local = ESDI_IS_INTEGRATED,
.init = esdi_init,
.close = esdi_close,
.reset = esdi_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = esdi_integrated_config
};

View File

@@ -3324,7 +3324,7 @@ const device_t ide_isa_2ch_device = {
const device_t ide_vlb_device = {
.name = "VLB IDE Controller",
.internal_name = "ide_vlb",
.flags = DEVICE_VLB | DEVICE_ISA16,
.flags = DEVICE_VLB,
.local = 2,
.init = ide_init,
.close = ide_close,
@@ -3338,7 +3338,7 @@ const device_t ide_vlb_device = {
const device_t ide_vlb_sec_device = {
.name = "VLB IDE Controller (Secondary)",
.internal_name = "ide_vlb_sec",
.flags = DEVICE_VLB | DEVICE_ISA16,
.flags = DEVICE_VLB,
.local = 2,
.init = ide_sec_init,
.close = ide_sec_close,
@@ -3352,7 +3352,7 @@ const device_t ide_vlb_sec_device = {
const device_t ide_vlb_2ch_device = {
.name = "VLB IDE Controller (Dual-Channel)",
.internal_name = "ide_vlb_2ch",
.flags = DEVICE_VLB | DEVICE_ISA16,
.flags = DEVICE_VLB,
.local = 3,
.init = ide_init,
.close = ide_close,
@@ -3366,7 +3366,7 @@ const device_t ide_vlb_2ch_device = {
const device_t ide_pci_device = {
.name = "PCI IDE Controller",
.internal_name = "ide_pci",
.flags = DEVICE_PCI | DEVICE_ISA16,
.flags = DEVICE_PCI,
.local = 4,
.init = ide_init,
.close = ide_close,
@@ -3380,7 +3380,7 @@ const device_t ide_pci_device = {
const device_t ide_pci_sec_device = {
.name = "PCI IDE Controller (Secondary)",
.internal_name = "ide_pci_sec",
.flags = DEVICE_PCI | DEVICE_ISA16,
.flags = DEVICE_PCI,
.local = 4,
.init = ide_sec_init,
.close = ide_sec_close,
@@ -3394,7 +3394,7 @@ const device_t ide_pci_sec_device = {
const device_t ide_pci_2ch_device = {
.name = "PCI IDE Controller (Dual-Channel)",
.internal_name = "ide_pci_2ch",
.flags = DEVICE_PCI | DEVICE_ISA16,
.flags = DEVICE_PCI,
.local = 5,
.init = ide_init,
.close = ide_close,

View File

@@ -1461,6 +1461,7 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
break;
case GPCMD_WRITE_SAME_10:
mo_set_phase(dev, SCSI_PHASE_DATA_OUT);
alloc_length = 512;
if ((cdb[1] & 6) == 6)

View File

@@ -1506,6 +1506,7 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb)
break;
case GPCMD_WRITE_SAME_10:
zip_set_phase(dev, SCSI_PHASE_DATA_OUT);
alloc_length = 512;
if ((cdb[1] & 6) == 6)

View File

@@ -740,6 +740,18 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
drive = real_drive(fdc, fdc->dor & 3);
fdc_update_rwc(fdc, drive, (val & 0x30) >> 4);
}
/* Bit 2: FIFO test mode (PS/55 5550-S,T only. Undocumented)
The Power-on Self Test of PS/55 writes and verifies 8 bytes of FIFO buffer through I/O 3F5h.
If it fails, then floppy drives will be treated as DD drives. */
if (fdc->flags & FDC_FLAG_PS2_MCA) {
if (val & 0x04) {
fdc->tfifo = 8;
fdc->fifointest = 1;
} else {
fdc->tfifo = 1;
fdc->fifointest = 0;
}
}
return;
case 4: /* DSR */
if (!(fdc->flags & FDC_FLAG_NO_DSR_RESET)) {
@@ -753,6 +765,14 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc->dsr = val;
return;
case 5: /*Command register*/
if (fdc->fifointest) {
/* Write FIFO buffer in the test mode (PS/55) */
fdc_log("FIFO buffer position = %X\n", ((fifo_t *) fdc->fifo_p)->end);
fifo_write(val, fdc->fifo_p);
if (fifo_get_full(fdc->fifo_p))
fdc->stat &= ~0x80;
break;
}
if ((fdc->stat & 0xf0) == 0xb0) {
if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo) {
fdc->dat = val;
@@ -1335,6 +1355,7 @@ fdc_read(uint16_t addr, void *priv)
ret = 0x10;
else
ret = 0x00;
/* PS/55 POST throws an error and halt if ret = 1 or 2, somehow. */
} else if (!fdc->enh_mode)
ret = 0x20;
else
@@ -1344,6 +1365,11 @@ fdc_read(uint16_t addr, void *priv)
ret = fdc->stat;
break;
case 5: /*Data*/
if (fdc->fifointest) {
/* Read FIFO buffer in the test mode (PS/55) */
ret = fifo_read(fdc->fifo_p);
break;
}
if ((fdc->stat & 0xf0) == 0xf0) {
fdc->stat &= ~0x80;
if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo) {
@@ -2249,6 +2275,7 @@ fdc_reset(void *priv)
fdc->fifo = 0;
fdc->tfifo = 1;
fdc->fifointest = 0;
if (fdc->flags & FDC_FLAG_PCJR) {
fdc->dma = 0;

View File

@@ -294,7 +294,7 @@ fdd_type_invert_densel(int type)
int ret;
if (drive_types[type].flags & FLAG_PS2)
ret = (!!strstr(machine_getname(), "PS/1")) || (!!strstr(machine_getname(), "PS/2"));
ret = (!!strstr(machine_getname(), "PS/1")) || (!!strstr(machine_getname(), "PS/2")) || (!!strstr(machine_getname(), "PS/55"));
else
ret = drive_types[type].flags & FLAG_INVERT_DENSEL;

View File

@@ -138,6 +138,7 @@ extern int sound_is_float; /* (C) sound uses FP values */
extern int voodoo_enabled; /* (C) video option */
extern int ibm8514_standalone_enabled; /* (C) video option */
extern int xga_standalone_enabled; /* (C) video option */
extern int da2_standalone_enabled; /* (C) video option */
extern uint32_t mem_size; /* (C) memory size (Installed on system board) */
extern uint32_t isa_mem_size; /* (C) memory size (ISA Memory Cards) */
extern int cpu; /* (C) cpu type */

View File

@@ -79,6 +79,7 @@
// #define CONFIG_STANDALONE 257 /* not available on the on-board variant */
enum {
DEVICE_CASETTE = 1, /* requires a Casette Port */
DEVICE_SIDECAR = 2, /* requires an IBM PCjr */
DEVICE_ISA = 4, /* requires the ISA bus */
DEVICE_XT_KBC = 8, /* requires an XT-compatible keyboard controller */

View File

@@ -103,7 +103,6 @@ typedef struct fdc_t {
uint8_t densel_force;
uint8_t fifo;
uint8_t tfifo;
uint8_t fifobufpos;
uint8_t drv2en;
uint8_t gap;
@@ -148,6 +147,7 @@ typedef struct fdc_t {
int drvrate[4];
void *fifo_p;
int fifointest;
sector_id_t read_track_sector;
sector_id_t format_sector_id;

View File

@@ -48,6 +48,7 @@ extern const device_t st506_xt_toshiba_t1200_device; /* st506_xt_toshiba_t1
extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */
extern const device_t esdi_ps2_device; /* esdi_mca */
extern const device_t esdi_integrated_device; /* esdi_mca */
extern const device_t ide_isa_device; /* isa_ide */
extern const device_t ide_isa_sec_device; /* isa_ide sec*/

View File

@@ -269,6 +269,7 @@ extern void keyboard_poll_host(void);
extern void keyboard_process(void);
extern uint16_t keyboard_convert(int ch);
extern void keyboard_input(int down, uint16_t scan);
extern void keyboard_all_up(void);
extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl);
extern uint8_t keyboard_get_shift(void);
extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl);

View File

@@ -48,7 +48,7 @@
#define MACHINE_BUS_AGP 0x00080000 /* sys has AGP bus */
#define MACHINE_BUS_AC97 0x00100000 /* sys has AC97 bus (ACR/AMR/CNR slot) */
/* Aliases. */
#define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */
#define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */
/* Combined flags. */
#define MACHINE_PC (MACHINE_BUS_ISA) /* sys is PC/XT-compatible (ISA) */
#define MACHINE_AT (MACHINE_BUS_ISA | MACHINE_BUS_ISA16) /* sys is AT-compatible (ISA + ISA16) */
@@ -67,18 +67,19 @@
#define MACHINE_AGP (MACHINE_BUS_AGP | MACHINE_PCI) /* sys is AT-compatible with AGP */
#define MACHINE_AGP98 (MACHINE_BUS_AGP | MACHINE_PCI98) /* sys is NEC PC-98x1 series with AGP (did that even exist?) */
#define MACHINE_PC5150 (MACHINE_PC | MACHINE_CASSETTE) /* sys is IBM PC 5150 */
#define MACHINE_PCJR (MACHINE_PC | MACHINE_CASSETTE | MACHINE_BUS_SIDECAR) /* sys is PCjr */
#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */
#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */
#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */
#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */
#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */
#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */
#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */
#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */
#define MACHINE_PS2_PCIONLY (MACHINE_PS2_NOISA & ~MACHINE_BUS_AGP) /* sys is PCI PS/2 without ISA */
#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */
#define MACHINE_PC5150 (MACHINE_CASSETTE | MACHINE_PC) /* sys is IBM PC 5150 */
#define MACHINE_PCJR (MACHINE_CASSETTE | MACHINE_BUS_SIDECAR) /* sys is PCjr */
#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */
#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */
#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */
#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */
#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */
#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */
#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */
#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */
#define MACHINE_PS2_PCIONLY (MACHINE_PS2_NOISA & ~MACHINE_BUS_AGP) /* sys is PCI PS/2 without ISA */
#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */
/* Feature flags for miscellaneous internal devices. */
#define MACHINE_FLAGS_NONE 0x00000000 /* sys has no int devices */
#define MACHINE_SOFTFLOAT_ONLY 0x00000001 /* sys requires SoftFloat FPU */
@@ -903,6 +904,8 @@ extern int machine_ps2_model_70_type3_init(const machine_t *);
extern int machine_ps2_model_80_init(const machine_t *);
extern int machine_ps2_model_80_axx_init(const machine_t *);
extern int machine_ps2_model_70_type4_init(const machine_t *);
extern int machine_ps55_model_50t_init(const machine_t*);
extern int machine_ps55_model_50v_init(const machine_t*);
/* m_tandy.c */
extern int tandy1k_eeprom_read(void);

View File

@@ -3,6 +3,7 @@
extern void mca_init(int nr_cards);
extern void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), uint8_t (*feedb)(void *priv), void (*reset)(void *priv), void *priv);
extern void mca_add_to_slot(uint8_t(*read)(int addr, void* priv), void (*write)(int addr, uint8_t val, void* priv), uint8_t(*feedb)(void* priv), void (*reset)(void* priv), void* priv, int c);
extern void mca_set_index(int index);
extern uint8_t mca_read(uint16_t port);
extern uint8_t mca_read_index(uint16_t port, int index);

View File

@@ -57,7 +57,7 @@
/* Queue size must be a power of 2 */
#define NET_QUEUE_LEN 16
#define NET_QUEUE_LEN_MASK (NET_QUEUE_LEN - 1)
#define NET_QUEUE_COUNT 3
#define NET_QUEUE_COUNT 4
#define NET_CARD_MAX 4
#define NET_HOST_INTF_MAX 64
@@ -84,9 +84,10 @@ enum {
};
enum {
NET_QUEUE_RX = 0,
NET_QUEUE_TX_VM = 1,
NET_QUEUE_TX_HOST = 2
NET_QUEUE_RX = 0,
NET_QUEUE_TX_VM = 1,
NET_QUEUE_TX_HOST = 2,
NET_QUEUE_RX_ON_TX = 3
};
typedef struct netcard_conf_t {
@@ -199,7 +200,10 @@ extern const device_t *network_card_getdevice(int);
extern int network_tx_pop(netcard_t *card, netpkt_t *out_pkt);
extern int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size);
extern int network_rx_put(netcard_t *card, uint8_t *bufp, int len);
extern int network_rx_on_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size);
extern int network_rx_on_tx_put(netcard_t *card, uint8_t *bufp, int len);
extern int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt);
extern int network_rx_on_tx_put_pkt(netcard_t *card, netpkt_t *pkt);
#ifdef EMU_DEVICE_H
/* 3Com Etherlink */

View File

@@ -0,0 +1,24 @@
/*
* 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.
*
* IBM PS/55 Display Adapter II emulation.
*
*
*
* Authors: Akamaki.
*
* Copyright 2024 Akamaki.
*/
#ifndef VIDEO_DA2_DEVICE_H
#define VIDEO_DA2_DEVICE_H
#ifdef EMU_DEVICE_H
extern const device_t ps55da2_device;
#endif
#endif /*VIDEO_DA2_DEVICE_H*/

View File

@@ -229,6 +229,11 @@ typedef struct svga_t {
int override;
void *priv;
int vga_enabled;
/* The PS/55 POST BIOS has a special monitor detection for its internal VGA
when the monitor is connected to the Display Adapter. */
int cable_connected;
uint8_t crtc[256];
uint8_t gdcreg[256];
uint8_t attrregs[32];

View File

@@ -31,4 +31,8 @@ typedef struct vga_t {
extern void vga_out(uint16_t addr, uint8_t val, void *priv);
extern uint8_t vga_in(uint16_t addr, void *priv);
void vga_disable(void* p);
void vga_enable(void* p);
int vga_isenabled(void* p);
#endif /*VIDEO_VGA_H*/

View File

@@ -18,6 +18,7 @@
#ifndef VIDEO_VOODOO_BANSHEE_H
#define VIDEO_VOODOO_BANSHEE_H
void banshee_cmd_write(void *priv, uint32_t addr, uint32_t val);
void banshee_set_overlay_addr(void *priv, uint32_t addr);
#endif /*VIDEO_VOODOO_BANSHEE_H*/

View File

@@ -420,6 +420,7 @@ typedef struct voodoo_t {
int cmdfifo_rp;
int cmdfifo_ret_addr;
int cmdfifo_in_sub;
int cmdfifo_in_agp;
atomic_int cmdfifo_depth_rd;
atomic_int cmdfifo_depth_wr;
atomic_int cmdfifo_enabled;
@@ -433,6 +434,7 @@ typedef struct voodoo_t {
int cmdfifo_rp_2;
int cmdfifo_ret_addr_2;
int cmdfifo_in_sub_2;
int cmdfifo_in_agp_2;
atomic_int cmdfifo_depth_rd_2;
atomic_int cmdfifo_depth_wr_2;
atomic_int cmdfifo_enabled_2;

View File

@@ -313,6 +313,9 @@ extern const device_t mach32_mca_device;
extern const device_t mach32_pci_device;
extern const device_t mach32_onboard_pci_device;
/* IBM Display Adapter (PS/55) */
extern void da2_device_add(void);
/* ATi Mach64 */
extern const device_t mach64gx_isa_device;
extern const device_t mach64gx_vlb_device;

View File

@@ -320,30 +320,28 @@ ps1_setup(int model)
mem_remap_top(384);
device_add(&ps_nvr_device);
device_add(&fdc_ps2_device);
if (model == 2011) {
if (!strcmp("english_us", device_get_config_bios("bios_language"))) {
/* US English */
rom_init(&ps->high_rom,
device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0),
0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL);
const device_t *d = device_context_get_device();
const char * bios = device_get_config_bios("bios_language");
const char * first = device_get_bios_file(d, bios, 0);
const char * second = device_get_bios_file(d, bios, 1);
} else if ((device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 1)) == NULL) {
if (!strcmp(bios, "english_us")) {
/* US English */
rom_init(&ps->high_rom, first,
0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL);
} else if (second == NULL) {
/* Combined ROM. */
rom_init(&ps->high_rom,
device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0),
rom_init(&ps->high_rom, first,
0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL);
} else {
/* Split ROM. */
rom_init(&ps->mid_rom,
device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0),
rom_init(&ps->mid_rom, first,
0xf80000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&ps->high_rom,
device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 1),
rom_init(&ps->high_rom, second,
0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL);
}
@@ -381,6 +379,8 @@ ps1_setup(int model)
device_add(&ps1snd_device);
}
device_add(&ps_nvr_device);
}
static void

View File

@@ -67,6 +67,8 @@
#include <86box/port_92.h>
#include <86box/serial.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_vga.h>
#include <86box/machine.h>
#include <86box/plat_unused.h>
@@ -103,6 +105,9 @@ static struct ps2_t {
int pending_cache_miss;
serial_t *uart;
vga_t* mb_vga;
int has_e0000_hole;
} ps2;
/*The model 70 type 3/4 BIOS performs cache testing. Since 86Box doesn't have any
@@ -140,7 +145,8 @@ static struct ps2_t {
static uint8_t ps2_cache[65536];
static int ps2_cache_valid[65536 / 8];
static void mem_encoding_update(void);
// #define ENABLE_PS2_MCA_LOG 1
#ifdef ENABLE_PS2_MCA_LOG
int ps2_mca_do_log = ENABLE_PS2_MCA_LOG;
@@ -358,6 +364,114 @@ model_80_read(uint16_t port)
return 0xff;
}
static uint8_t
ps55_model_50t_read(uint16_t port)
{
ps2_mca_log(" Read SysBrd %04X xx %04X:%04X\n", port, cs >> 4, cpu_state.pc);
switch (port) {
case 0x100:
return ps2.planar_id & 0xff;
case 0x101:
return ps2.planar_id >> 8;
case 0x102:
return ps2.option[0];
case 0x103: {
uint8_t val = 0xff;
/*
I/O 103h - Bit 7-4: Memory Card ID (Connector 1 or 3)
Bit 3-0: Memory Card ID (Connector 2)
Memory Card ID: 7h = 2 MB Memory Card 2 or 3 Installed
5h = 4 MB Memory Card 2 Installed
*/
switch (mem_size / 1024) {
case 2:
if (ps2.option[1] & 0x04)
val = 0xff;
else
val = 0x7f;
break;
case 4:
if (ps2.option[1] & 0x04)
val = 0xff;
else
val = 0x77;
break;
case 6:
if (ps2.option[1] & 0x04)
val = 0x7f;
else
val = 0x77;
break;
case 8:
default:
if (ps2.option[1] & 0x04)
val = 0x5f;
else
val = 0x77;
break;
}
ps2_mca_log(" Read MCA %04X %02X %04X:%04X mem_size = %d, ps2option1 = %2X\n", port, val, cs >> 4, cpu_state.pc, mem_size, ps2.option[1]);
return val;
} case 0x104:
return ps2.option[2];
case 0x105:
return ps2.option[3];
case 0x106:
return ps2.subaddr_lo;
case 0x107:
return ps2.subaddr_hi;
}
return 0xff;
}
static uint8_t
ps55_model_50v_read(uint16_t port)
{
switch (port) {
case 0x100:
return ps2.planar_id & 0xff;
case 0x101:
return ps2.planar_id >> 8;
case 0x102:
return ps2.option[0];
case 0x103: {
uint8_t val = 0xff;
/*
I/O 103h - Bit 7-4: Reserved
Bit 3-0: Memory Card ID (Connector 3 or 1)
Memory Card ID: 8h = 4 MB Memory Card IV Installed
Fh = No Card Installed
*/
switch (mem_size / 1024) {
case 4:
if (ps2.option[1] & 0x04)
val = 0xff;
else
val = 0xf8;
break;
case 8:
default:
if (ps2.option[1] & 0x04)
val = 0xf8;
else
val = 0xf8;
break;
}
return val;
} case 0x104:
/* Reading cache ID (bit 3-2) always returns zero */
return ps2.option[2] & 0xf3;
case 0x105:
return ps2.option[3];
case 0x106:
return ps2.subaddr_lo;
case 0x107:
return ps2.subaddr_hi;
}
return 0xff;
}
static void
model_50_write(uint16_t port, uint8_t val)
{
@@ -655,6 +769,62 @@ model_80_write(uint16_t port, uint8_t val)
}
}
static void
ps55_model_50tv_write(uint16_t port, uint8_t val)
{
ps2_mca_log(" Write SysBrd %04X %02X %04X:%04X\n", port, val, cs >> 4, cpu_state.pc);
switch (port) {
case 0x102:
lpt1_remove();
serial_remove(ps2.uart);
if (val & 0x04) {
if (val & 0x08)
serial_setup(ps2.uart, COM1_ADDR, COM1_IRQ);
else
serial_setup(ps2.uart, COM2_ADDR, COM2_IRQ);
}
if (val & 0x10) {
switch ((val >> 5) & 3) {
case 0:
lpt1_setup(LPT_MDA_ADDR);
break;
case 1:
lpt1_setup(LPT1_ADDR);
break;
case 2:
lpt1_setup(LPT2_ADDR);
break;
default:
break;
}
}
ps2.option[0] = val;
break;
case 0x103:
ps2.option[1] = val;
break;
case 0x104:
if ((ps2.option[2] ^ val) & 1) {
/* Disable/Enable E0000 - E0FFF (Make 2 KB hole for Display Adapter) */
ps2.option[2] = val;
mem_encoding_update();
}
ps2.option[2] = val;
break;
case 0x105:
ps2.option[3] = val;
break;
case 0x106:
ps2.subaddr_lo = val;
break;
case 0x107:
ps2.subaddr_hi = val;
break;
default:
break;
}
}
uint8_t
ps2_mca_read(uint16_t port, UNUSED(void *priv))
{
@@ -772,8 +942,15 @@ ps2_mca_write(uint16_t port, uint8_t val, UNUSED(void *priv))
ps2.setup = val;
break;
case 0x96:
if ((val & 0x80) && !(ps2.adapter_setup & 0x80))
if ((val & 0x80) && !(ps2.adapter_setup & 0x80)) {
mca_reset();
if (ps2.has_e0000_hole) {
/* Reset memstate for E0000 - E0FFFh hole (for PS/55 5550-V)
5550-T does this in POST, but 5550-V doesn't. */
ps2.option[2] &= 0xFE;
mem_encoding_update();
}
}
ps2.adapter_setup = val;
mca_set_index(val & 7);
break;
@@ -793,7 +970,16 @@ ps2_mca_write(uint16_t port, uint8_t val, UNUSED(void *priv))
if (!(ps2.setup & PS2_SETUP_IO))
ps2.planar_write(port, val);
else if (!(ps2.setup & PS2_SETUP_VGA))
{
if (ps2.mb_vga)
{
if (vga_isenabled(ps2.mb_vga))
vga_disable(ps2.mb_vga);
if (val & 1)
vga_enable(ps2.mb_vga);
}
ps2.pos_vga = val;
}
else if (ps2.adapter_setup & PS2_ADAPTER_SETUP)
mca_write(port, val);
break;
@@ -1117,6 +1303,11 @@ mem_encoding_update(void)
ps2_mca_log("PS/2 Model 80-111: Split memory block disabled\n");
}
if (ps2.has_e0000_hole && (ps2.option[2] & 1)) {
/* Set memstate for E0000 - E0FFFh hole (PS/55 only) */
mem_set_mem_state(0xe0000, 0x1000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
flushmmucache_nopc();
}
@@ -1311,7 +1502,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots)
}
if (gfxcard[0] == VID_INTERNAL)
device_add(&ps1vga_mca_device);
ps2.mb_vga = device_add(&ps1vga_mca_device);
}
static void
@@ -1385,7 +1576,7 @@ ps2_mca_board_model_80_type2_init(void)
}
if (gfxcard[0] == VID_INTERNAL)
device_add(&ps1vga_mca_device);
ps2.mb_vga = device_add(&ps1vga_mca_device);
ps2.split_size = 0;
}
@@ -1409,6 +1600,8 @@ machine_ps2_common_init(const machine_t *model)
nmi_mask = 0x80;
ps2.uart = device_add_inst(&ns16550_device, 1);
ps2.has_e0000_hole = 0;
}
int
@@ -1576,3 +1769,160 @@ machine_ps2_model_70_type4_init(const machine_t *model)
return ret;
}
static void
ps55_mca_board_model_50t_init(void)
{
ps2_mca_board_common_init();
ps2.split_addr = mem_size * 1024;
/* The slot 5 is reserved for the Integrated Fixed Disk II (an internal ESDI hard drive). */
mca_init(5);
device_add(&keyboard_ps2_mca_1_device);
ps2.planar_read = ps55_model_50t_read;
ps2.planar_write = ps55_model_50tv_write;
device_add(&ps2_nvr_device);
io_sethandler(0x00e0, 0x0002, mem_encoding_read, NULL, NULL, mem_encoding_write, NULL, NULL, NULL);
ps2.mem_regs[1] = 2;
ps2.option[2] &= 0xfe; /* Bit 0: Disable E0000-E0FFFh (4 KB) */
ps2.has_e0000_hole = 1;
mem_mapping_add(&ps2.split_mapping,
(mem_size + 256) * 1024,
256 * 1024,
ps2_read_split_ram,
ps2_read_split_ramw,
ps2_read_split_raml,
ps2_write_split_ram,
ps2_write_split_ramw,
ps2_write_split_raml,
&ram[0xa0000],
MEM_MAPPING_INTERNAL,
NULL);
mem_mapping_disable(&ps2.split_mapping);
if (mem_size > 8192) {
/* Only 8 MB supported on planar, create a memory expansion card for the rest */
ps2_mca_mem_fffc_init(8);
}
if (gfxcard[0] == VID_INTERNAL)
ps2.mb_vga = (vga_t *)device_add(&ps1vga_mca_device);
}
static void
ps55_mca_board_model_50v_init(void)
{
ps2_mca_board_common_init();
ps2.split_addr = mem_size * 1024;
/* The slot 5 is reserved for the Integrated Fixed Disk II (an internal ESDI hard drive). */
mca_init(5);
device_add(&keyboard_ps2_mca_1_device);
ps2.planar_read = ps55_model_50v_read;
ps2.planar_write = ps55_model_50tv_write;
device_add(&ps2_nvr_device);
io_sethandler(0x00e0, 0x0003, mem_encoding_read_cached, NULL, NULL, mem_encoding_write_cached, NULL, NULL, NULL);
ps2.mem_regs[1] = 2;
ps2.option[2] &= 0xf2; /* Bit 3-2: -Cache IDs, Bit 1: Reserved
Bit 0: Disable E0000-E0FFFh (4 KB) */
ps2.has_e0000_hole = 1;
mem_mapping_add(&ps2.split_mapping,
(mem_size + 256) * 1024,
256 * 1024,
ps2_read_split_ram,
ps2_read_split_ramw,
ps2_read_split_raml,
ps2_write_split_ram,
ps2_write_split_ramw,
ps2_write_split_raml,
&ram[0xa0000],
MEM_MAPPING_INTERNAL,
NULL);
mem_mapping_disable(&ps2.split_mapping);
mem_mapping_add(&ps2.cache_mapping,
0,
64 * 1024,
ps2_read_cache_ram,
ps2_read_cache_ramw,
ps2_read_cache_raml,
ps2_write_cache_ram,
NULL,
NULL,
ps2_cache,
MEM_MAPPING_INTERNAL,
NULL);
mem_mapping_disable(&ps2.cache_mapping);
if (mem_size > 8192) {
/* Only 8 MB supported on planar, create a memory expansion card for the rest */
ps2_mca_mem_fffc_init(8);
}
if (gfxcard[0] == VID_INTERNAL)
ps2.mb_vga = (vga_t *)device_add(&ps1vga_mca_device);
}
int
machine_ps55_model_50t_init(const machine_t* model)
{
int ret;
ret = bios_load_linear("roms/machines/ibmps55_m50t/38F6933.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_ps2_common_init(model);
/*
* Planar ID
* FFFAh - PS/55 model 5551-S0x, T0x (stage 1?)
* FFEEh - PS/55 model 5551-S1x, T1x (stage 2?)
* Verification in BIOS P/N 38F6933: FBxx -> 4 slots (error), xxEE -> 5 slots (ok), others -> 8 (error)
*
* The only difference between S and T models is the CPU speed (16 MHz vs 20 MHz).
* The POST measures the speed, and sets a flag in the BIOS Data Area to indicate the sub model.
* The VM in 86Box runs faster than the real, so the POST always determines it as the T model.
*/
ps2.planar_id = 0xffee;
ps55_mca_board_model_50t_init();
return ret;
}
int
machine_ps55_model_50v_init(const machine_t* model)
{
int ret;
ret = bios_load_interleaved("roms/machines/ibmps55_m50v/56F7416.BIN",
"roms/machines/ibmps55_m50v/56F7417.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_ps2_common_init(model);
/*
* Planar ID
* F1FFh - PS/55 model 5551-V0x, V1x
* Verification in BIOS P/N 56F7416,56F7417: FBxx -> 5 slots (ok), F1xx -> 5 slots (ok), others -> 8 (error)
*/
ps2.planar_id = 0xf1ff;
ps55_mca_board_model_50v_init();
return ret;
}

View File

@@ -324,7 +324,7 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_PCJR,
.flags = MACHINE_VIDEO_FIXED,
.flags = MACHINE_VIDEO_FIXED | MACHINE_CARTRIDGE,
.ram = {
.min = 64,
.max = 640,
@@ -5638,6 +5638,86 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/55 5551-Sxx, Txx stage 2 firmware. */
{
.name = "[MCA] IBM PS/55 model 5550-T",
.internal_name = "ibmps55_m50t",
.type = MACHINE_TYPE_386DX,
.chipset = MACHINE_CHIPSET_PROPRIETARY,
.init = machine_ps55_model_50t_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_386DX | CPU_PKG_486BL,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PS2_MCA,
.flags = MACHINE_VIDEO | MACHINE_APM,
.ram = {
.min = 2048,
.max = 16384,
.step = 2048
},
.nvrmask = 63,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/55 5551-V0x, V1x firmware. */
{
.name = "[MCA] IBM PS/55 model 5550-V",
.internal_name = "ibmps55_m50v",
.type = MACHINE_TYPE_386DX,
.chipset = MACHINE_CHIPSET_PROPRIETARY,
.init = machine_ps55_model_50v_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_386DX | CPU_PKG_486BL,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PS2_MCA,
.flags = MACHINE_VIDEO | MACHINE_APM,
.ram = {
.min = 4096,
.max = 16384,
.step = 4096
},
.nvrmask = 63,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* 386DX/486 machines */
/* Has AMIKey F KBC firmware. */

View File

@@ -101,3 +101,19 @@ mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t v
}
}
}
void
mca_add_to_slot(uint8_t (*read)(int addr, void* priv), void (*write)(int addr, uint8_t val, void* priv), uint8_t(*feedb)(void* priv), void (*reset)(void* priv), void* priv, int c)
{
if (mca_card_read[c] || mca_card_write[c])
{
//pclog("cannot add the device to slot %d\n", num);
return;
}
mca_card_read[c] = read;
mca_card_write[c] = write;
mca_card_feedb[c] = feedb;
mca_card_reset[c] = reset;
mca_priv[c] = priv;
return;
}

View File

@@ -60,16 +60,19 @@ enum {
};
typedef struct net_slirp_t {
Slirp *slirp;
uint8_t mac_addr[6];
netcard_t *card; /* netcard attached to us */
thread_t *poll_tid;
net_evt_t tx_event;
net_evt_t stop_event;
netpkt_t pkt;
netpkt_t pkt_tx_v[SLIRP_PKT_BATCH];
Slirp * slirp;
uint8_t mac_addr[6];
netcard_t * card; /* netcard attached to us */
thread_t * poll_tid;
net_evt_t rx_event;
net_evt_t tx_event;
net_evt_t stop_event;
netpkt_t pkt;
netpkt_t pkt_tx_v[SLIRP_PKT_BATCH];
int during_tx;
int recv_on_tx;
#ifdef _WIN32
HANDLE sock_event;
HANDLE sock_event;
#else
uint32_t pfd_len;
uint32_t pfd_size;
@@ -184,7 +187,11 @@ net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque)
memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len);
slirp->pkt.len = pkt_len;
network_rx_put_pkt(slirp->card, &slirp->pkt);
if (slirp->during_tx) {
network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt);
slirp->recv_on_tx = 1;
} else
network_rx_put_pkt(slirp->card, &slirp->pkt);
return pkt_len;
}
@@ -324,6 +331,21 @@ net_slirp_in_available(void *priv)
net_event_set(&slirp->tx_event);
}
static void
net_slirp_rx_deferred_packets(net_slirp_t *slirp)
{
int packets = 0;
if (slirp->recv_on_tx) {
do {
packets = network_rx_on_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
for (int i = 0; i < packets; i++)
network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i]));
} while (packets > 0);
slirp->recv_on_tx = 0;
}
}
#ifdef _WIN32
static void
net_slirp_thread(void *priv)
@@ -352,10 +374,13 @@ net_slirp_thread(void *priv)
case NET_EVENT_TX:
{
slirp->during_tx = 1;
int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
for (int i = 0; i < packets; i++) {
for (int i = 0; i < packets; i++)
net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len);
}
slirp->during_tx = 0;
net_slirp_rx_deferred_packets(slirp);
}
break;
@@ -398,10 +423,13 @@ net_slirp_thread(void *priv)
if (slirp->pfd[NET_EVENT_TX].revents & POLLIN) {
net_event_clear(&slirp->tx_event);
slirp->during_tx = 1;
int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
for (int i = 0; i < packets; i++) {
for (int i = 0; i < packets; i++)
net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len);
}
slirp->during_tx = 0;
net_slirp_rx_deferred_packets(slirp);
}
}
@@ -477,6 +505,7 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv
slirp->pkt_tx_v[i].data = calloc(1, NET_MAX_FRAME);
}
slirp->pkt.data = calloc(1, NET_MAX_FRAME);
net_event_init(&slirp->rx_event);
net_event_init(&slirp->tx_event);
net_event_init(&slirp->stop_event);
#ifdef _WIN32
@@ -531,8 +560,9 @@ net_slirp_close(void *priv)
slirp_log("SLiRP: waiting for thread to end...\n");
thread_wait(slirp->poll_tid);
net_event_close(&slirp->tx_event);
net_event_close(&slirp->stop_event);
net_event_close(&slirp->tx_event);
net_event_close(&slirp->rx_event);
slirp_cleanup(slirp->slirp);
for (int i = 0; i < SLIRP_PKT_BATCH; i++) {
free(slirp->pkt_tx_v[i].data);

View File

@@ -643,6 +643,43 @@ network_rx_put(netcard_t *card, uint8_t *bufp, int len)
return ret;
}
int
network_rx_on_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size)
{
int pkt_count = 0;
netqueue_t *queue = &card->queues[NET_QUEUE_RX_ON_TX];
for (int i = 0; i < vec_size; i++) {
if (!network_queue_get_swap(queue, pkt_vec))
break;
network_dump_packet(pkt_vec);
pkt_count++;
pkt_vec++;
}
return pkt_count;
}
int
network_rx_on_tx_put(netcard_t *card, uint8_t *bufp, int len)
{
int ret = 0;
ret = network_queue_put(&card->queues[NET_QUEUE_RX_ON_TX], bufp, len);
return ret;
}
int
network_rx_on_tx_put_pkt(netcard_t *card, netpkt_t *pkt)
{
int ret = 0;
ret = network_queue_put_swap(&card->queues[NET_QUEUE_RX_ON_TX], pkt);
return ret;
}
int
network_rx_put_pkt(netcard_t *card, netpkt_t *pkt)
{

View File

@@ -277,6 +277,8 @@ MainWindow::MainWindow(QWidget *parent)
if (mouse_capture)
emit setMouseCapture(false);
keyboard_all_up();
if (do_auto_pause && !dopause) {
auto_paused = 1;
plat_pause(1);

View File

@@ -26,6 +26,7 @@ extern "C" {
#include <86box/video.h>
#include <86box/vid_8514a_device.h>
#include <86box/vid_xga_device.h>
#include <86box/vid_ps55da2.h>
}
#include "qt_deviceconfig.hpp"
@@ -58,6 +59,7 @@ SettingsDisplay::save()
voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0;
ibm8514_standalone_enabled = ui->checkBox8514->isChecked() ? 1 : 0;
xga_standalone_enabled = ui->checkBoxXga->isChecked() ? 1 : 0;
da2_standalone_enabled = ui->checkBoxDa2->isChecked() ? 1 : 0;
}
void
@@ -149,6 +151,12 @@ SettingsDisplay::on_pushButtonConfigureXga_clicked()
}
}
void
SettingsDisplay::on_pushButtonConfigureDa2_clicked()
{
DeviceConfig::ConfigureDevice(&ps55da2_device, 0, qobject_cast<Settings *>(Settings::settings));
}
void
SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
{
@@ -174,6 +182,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514);
bool machineSupportsXga = (((machineHasIsa16 && device_available(&xga_isa_device)) || (machineHasMca && device_available(&xga_device))) && !videoCardHasXga);
bool machineSupportsDa2 = machineHasMca && device_available(&ps55da2_device);
ui->checkBox8514->setEnabled(machineSupports8514);
ui->checkBox8514->setChecked(ibm8514_standalone_enabled && machineSupports8514);
@@ -183,7 +192,11 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
ui->checkBoxXga->setEnabled(machineSupportsXga);
ui->checkBoxXga->setChecked(xga_standalone_enabled && machineSupportsXga);
ui->checkBoxDa2->setEnabled(machineSupportsDa2);
ui->checkBoxDa2->setChecked(da2_standalone_enabled && machineSupportsDa2);
ui->pushButtonConfigureXga->setEnabled(ui->checkBoxXga->isEnabled() && ui->checkBoxXga->isChecked());
ui->pushButtonConfigureDa2->setEnabled(ui->checkBoxDa2->isEnabled() && ui->checkBoxDa2->isChecked());
int c = 2;
@@ -264,6 +277,12 @@ SettingsDisplay::on_checkBoxXga_stateChanged(int state)
ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked);
}
void
SettingsDisplay::on_checkBoxDa2_stateChanged(int state)
{
ui->pushButtonConfigureDa2->setEnabled(state == Qt::Checked);
}
void
SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index)
{

View File

@@ -31,10 +31,12 @@ private slots:
void on_checkBoxVoodoo_stateChanged(int state);
void on_checkBox8514_stateChanged(int state);
void on_checkBoxXga_stateChanged(int state);
void on_checkBoxDa2_stateChanged(int state);
void on_comboBoxVideo_currentIndexChanged(int index);
void on_pushButtonConfigureVoodoo_clicked();
void on_pushButtonConfigure8514_clicked();
void on_pushButtonConfigureXga_clicked();
void on_pushButtonConfigureDa2_clicked();
void on_pushButtonConfigure_clicked();
private:

View File

@@ -120,6 +120,20 @@
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="checkBoxDa2">
<property name="text">
<string>IBM PS/55 Display Adapter Graphics</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QPushButton" name="pushButtonConfigureDa2">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="pushButtonConfigureSecondary">
<property name="text">
@@ -140,7 +154,7 @@
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<item row="8" column="0" colspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>

View File

@@ -1024,7 +1024,7 @@ const device_t scsi_t130b_device = {
const device_t scsi_ls2000_device = {
.name = "Corel LS2000",
.internal_name = "ls2000",
.flags = DEVICE_ISA,
.flags = DEVICE_ISA | DEVICE_SIDECAR,
.local = ROM_LS2000,
.init = ncr53c400_init,
.close = ncr53c400_close,

View File

@@ -196,6 +196,7 @@ typedef struct {
#define CMD_UNKNOWN_1C11 0x1c11
#define CMD_WRITE_DATA 0x1c02
#define CMD_VERIFY 0x1c03
#define CMD_WRITE_VERIFY 0x1c04
#define IRQ_TYPE_NONE 0x0
#define IRQ_TYPE_SCB_COMPLETE 0x1
@@ -291,7 +292,7 @@ spock_write(uint16_t port, uint8_t val, void *priv)
{
spock_t *scsi = (spock_t *) priv;
spock_log("spock_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc);
spock_log("spock_writeb: port=%04x, val=%02x, %04x:%04x.\n", port & 7, val, CS, cpu_state.pc);
switch (port & 7) {
case 0:
@@ -332,6 +333,8 @@ spock_writew(uint16_t port, uint16_t val, void *priv)
{
spock_t *scsi = (spock_t *) priv;
spock_log("spock_writew: port=%04x, val=%04x, %04x:%04x.\n", port & 7, val, CS, cpu_state.pc);
switch (port & 7) {
case 0: /*Command Interface Register*/
scsi->cir_pending[0] = val & 0xff;
@@ -347,8 +350,6 @@ spock_writew(uint16_t port, uint16_t val, void *priv)
default:
break;
}
spock_log("spock_writew: port=%04x val=%04x\n", port, val);
}
static uint8_t
@@ -390,7 +391,7 @@ spock_read(uint16_t port, void *priv)
break;
}
spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x.\n", port, temp, CS, cs, cpu_state.pc);
spock_log("spock_readb: port=%04x, val=%02x, %04x:%04x.\n", port & 7, temp, CS, cpu_state.pc);
return temp;
}
@@ -412,7 +413,7 @@ spock_readw(uint16_t port, void *priv)
break;
}
spock_log("spock_readw: port=%04x val=%04x\n", port, temp);
spock_log("spock_readw: port=%04x, val=%04x, %04x:%04x.\n", port & 7, temp, CS, cpu_state.pc);
return temp;
}
@@ -534,7 +535,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
int old_scb_state;
if (scsi->in_reset) {
spock_log("Reset type = %d\n", scsi->in_reset);
spock_log("Reset type=%d\n", scsi->in_reset);
scsi->status &= ~STATUS_BUSY;
scsi->irq_status = 0;
@@ -542,9 +543,8 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
for (c = 0; c < SCSI_ID_MAX; c++)
spock_clear_irq(scsi, c);
if (scsi->in_reset == 1) {
if (scsi->in_reset == 1)
scsi->basic_ctrl |= CTRL_IRQ_ENA;
}
spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
@@ -585,6 +585,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
switch (scsi->scb_state) {
case 0: /* Idle */
spock_log("Start Idle.\n");
break;
case 1: /* Select */
@@ -820,6 +821,28 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->scb_state = 2;
return;
case CMD_WRITE_VERIFY:
if (scsi->present[scsi->scb_id] != 0xff)
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Write with Verify\n");
scsi->cdb[0] = GPCMD_WRITE_AND_VERIFY_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/
scsi->cdb[3] = (scb->lba_addr >> 16) & 0xff;
scsi->cdb[4] = (scb->lba_addr >> 8) & 0xff;
scsi->cdb[5] = scb->lba_addr & 0xff;
scsi->cdb[6] = 0; /*Reserved*/
scsi->cdb[7] = (scb->block_count >> 8) & 0xff;
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_REQUEST_SENSE:
if (scsi->present[scsi->scb_id] != 0xff)
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
@@ -943,7 +966,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
sd->buffer_length = spock_get_len(scsi, scb);
scsi_device_command_phase0(sd, scsi->temp_cdb);
spock_log("SCSI ID %i: Current CDB[0] = %02x, LUN = %i, data len = %i, max len = %i, phase val = %02x\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1] >> 5, sd->buffer_length, spock_get_len(scsi, scb), sd->phase);
spock_log("SCSI ID %i: Current CDB[0]=%02x, LUN=%i, buffer len=%i, max len=%i, phase val=%02x, data len=%d, enable bit 10=%03x\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1] >> 5, sd->buffer_length, spock_get_len(scsi, scb), sd->phase, scsi->data_len, scb->enable & 0x400);
if ((sd->phase != SCSI_PHASE_STATUS) && (sd->buffer_length > 0)) {
p = scsi_device_get_callback(sd);
@@ -1018,12 +1041,11 @@ spock_callback(void *priv)
if (scsi->cmd_timer) {
scsi->cmd_timer--;
if (!scsi->cmd_timer) {
if (!scsi->cmd_timer)
spock_execute_cmd(scsi, scb);
}
}
if (scsi->attention_wait && (scsi->scb_state == 0 || (scsi->attention_pending & 0xf0) == 0xe0)) {
if (scsi->attention_wait && ((scsi->scb_state == 0) || (scsi->attention_pending & 0xf0) == 0xe0)) {
scsi->attention_wait--;
if (!scsi->attention_wait) {
scsi->attention = scsi->attention_pending;

View File

@@ -107,8 +107,10 @@ constexpr unsigned int OSC_DAC_BITS = 12;
* On my 6581R4AR has 0x3A as the only value giving the same output level as 1.prg
*/
//@{
#ifdef USE_RESID_UNUSED
constexpr unsigned int OFFSET_6581 = 0x380;
constexpr unsigned int OFFSET_8580 = 0x9c0;
#endif
//@}
/**

View File

@@ -43,7 +43,9 @@ namespace reSIDfp
constexpr unsigned int FLOATING_OUTPUT_TTL_6581R3 = 54000;
constexpr unsigned int FLOATING_OUTPUT_FADE_6581R3 = 1400;
// ~1s
#ifdef USE_RESID_UNUSED
constexpr unsigned int FLOATING_OUTPUT_TTL_6581R4 = 1000000;
#endif
// ~1s
constexpr unsigned int FLOATING_OUTPUT_TTL_8580R5 = 800000;
constexpr unsigned int FLOATING_OUTPUT_FADE_8580R5 = 50000;
@@ -61,7 +63,9 @@ constexpr unsigned int FLOATING_OUTPUT_FADE_8580R5 = 50000;
constexpr unsigned int SHIFT_REGISTER_RESET_6581R3 = 50000;
constexpr unsigned int SHIFT_REGISTER_FADE_6581R3 = 15000;
// ~2.15s
#ifdef USE_RESID_UNUSED
constexpr unsigned int SHIFT_REGISTER_RESET_6581R4 = 2150000;
#endif
// ~2.8s
constexpr unsigned int SHIFT_REGISTER_RESET_8580R5 = 986000;
constexpr unsigned int SHIFT_REGISTER_FADE_8580R5 = 314300;

View File

@@ -145,7 +145,7 @@ adlib_close(void *priv)
const device_t adlib_device = {
.name = "AdLib",
.internal_name = "adlib",
.flags = DEVICE_ISA,
.flags = DEVICE_ISA | DEVICE_SIDECAR,
.local = 0,
.init = adlib_init,
.close = adlib_close,

View File

@@ -77,6 +77,7 @@ add_library(vid OBJECT
vid_att2xc498_ramdac.c
vid_xga.c
vid_bochs_vbe.c
vid_ps55da2.c
nv/nv_rivatimer.c
)

View File

@@ -336,7 +336,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
}
if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24))
mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n",
mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monopattern = %x.\n",
dev->accel.rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y,
mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable);
@@ -1039,7 +1039,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
}
break;
case 2:
if (mach->accel.dp_config & 0x1000) {
if ((mach->accel.dp_config & 0x1000) || (mach->accel.dp_config & 0x04)) {
mix = mix_dat >> 0x1f;
mix_dat <<= 1;
} else {
@@ -2185,7 +2185,7 @@ mach_accel_out_pixtrans(svga_t *svga, mach_t *mach, ibm8514_t *dev, uint16_t val
case 0x200: /*16-bit size*/
if (mono_src == 2) {
if ((frgd_sel != 2) && (bkgd_sel != 2)) {
if ((mach->accel.dp_config & 0x1000) && !swap) {
if (((mach->accel.dp_config & 0x1000) && !swap) || swap) {
mach_log("16-bit bus size swap.\n");
val = (val >> 8) | (val << 8);
}
@@ -5184,11 +5184,11 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv)
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = (addr - mach->linear_base) & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100) {
(((addr - mach->linear_base) >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if ((addr - mach->linear_base) & 0x100) {
mach_log("Port WORDB Write=%04x.\n", 0x02ee + (port_dword << 8));
mach_accel_outb(0x02ee + (addr & 1) + (port_dword << 8), val, mach);
} else {
@@ -5199,9 +5199,9 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv)
mach_log("Linear WORDB Write=%08x, val=%02x, ON=%x, dpconfig=%04x, apsize=%08x.\n",
addr & dev->vram_mask, val, dev->on, mach->accel.dp_config, mach->ap_size << 20);
if (dev->on)
mach32_write_common(addr, val, 1, mach, svga);
mach32_write_common(addr - mach->linear_base, val, 1, mach, svga);
else
svga_write_linear(addr, val, svga);
svga_write_linear(addr - mach->linear_base, val, svga);
}
}
@@ -5211,11 +5211,11 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv)
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = (addr - mach->linear_base) & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100) {
(((addr - mach->linear_base) >= ((mach->ap_size << 20) - 0x200)) && ((addr - mach->linear_base) < (mach->ap_size << 20)))) {
if ((addr - mach->linear_base) & 0x100) {
mach_log("Port WORDW Write=%04x.\n", 0x02ee + (port_dword << 8));
mach_accel_outw(0x02ee + (port_dword << 8), val, mach);
} else {
@@ -5224,11 +5224,11 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv)
}
} else {
mach_log("Linear WORDW Write=%08x, val=%04x, ON=%x, dpconfig=%04x, apsize=%08x.\n",
addr & dev->vram_mask, val, dev->on, mach->accel.dp_config, mach->ap_size << 20);
addr - mach->linear_base, val, dev->on, mach->accel.dp_config, mach->ap_size << 20);
if (dev->on)
mach32_writew_linear(addr, val, mach);
mach32_writew_linear(addr - mach->linear_base, val, mach);
else
svga_writew_linear(addr, val, svga);
svga_writew_linear(addr - mach->linear_base, val, svga);
}
}
@@ -5238,11 +5238,11 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv)
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = (addr - mach->linear_base) & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100) {
(((addr - mach->linear_base) >= ((mach->ap_size << 20) - 0x200)) && ((addr - mach->linear_base) < (mach->ap_size << 20)))) {
if ((addr - mach->linear_base) & 0x100) {
mach_log("Port WORDL Write=%04x.\n", 0x02ee + (port_dword << 8));
mach_accel_outw(0x02ee + (port_dword << 8), val & 0xffff, mach);
mach_accel_outw(0x02ee + (port_dword << 8) + 4, val >> 16, mach);
@@ -5253,11 +5253,11 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv)
}
} else {
mach_log("Linear WORDL Write=%08x, val=%08x, ON=%x, dpconfig=%04x, apsize=%08x.\n",
addr & dev->vram_mask, val, dev->on, mach->accel.dp_config, mach->ap_size << 20);
addr - mach->linear_base, val, dev->on, mach->accel.dp_config, mach->ap_size << 20);
if (dev->on)
mach32_writel_linear(addr, val, mach);
mach32_writel_linear(addr - mach->linear_base, val, mach);
else
svga_writel_linear(addr, val, svga);
svga_writel_linear(addr - mach->linear_base, val, svga);
}
}
@@ -5268,19 +5268,19 @@ mach32_ap_readb(uint32_t addr, void *priv)
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t temp;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = (addr - mach->linear_base) & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100)
(((addr - mach->linear_base) >= ((mach->ap_size << 20) - 0x200)) && ((addr - mach->linear_base) < (mach->ap_size << 20)))) {
if ((addr - mach->linear_base) & 0x100)
temp = mach_accel_inb(0x02ee + (addr & 1) + (port_dword << 8), mach);
else
temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach);
} else {
if (dev->on)
temp = mach32_read_common(addr, 1, mach, svga);
temp = mach32_read_common(addr - mach->linear_base, 1, mach, svga);
else
temp = svga_read_linear(addr, svga);
temp = svga_read_linear(addr - mach->linear_base, svga);
mach_log("Linear WORDB Read=%08x, ret=%02x, fast=%d.\n", addr, temp, svga->fast);
}
@@ -5295,19 +5295,19 @@ mach32_ap_readw(uint32_t addr, void *priv)
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint16_t temp;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = (addr - mach->linear_base) & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100)
(((addr - mach->linear_base) >= ((mach->ap_size << 20) - 0x200)) && ((addr - mach->linear_base) < (mach->ap_size << 20)))) {
if ((addr - mach->linear_base) & 0x100)
temp = mach_accel_inw(0x02ee + (port_dword << 8), mach);
else
temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach);
} else {
if (dev->on)
temp = mach32_readw_linear(addr, mach);
temp = mach32_readw_linear(addr - mach->linear_base, mach);
else
temp = svga_readw_linear(addr, svga);
temp = svga_readw_linear(addr - mach->linear_base, svga);
mach_log("Linear WORDW Read=%08x, ret=%04x.\n", addr, temp);
}
@@ -5322,11 +5322,11 @@ mach32_ap_readl(uint32_t addr, void *priv)
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint32_t temp;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = (addr - mach->linear_base) & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100) {
(((addr - mach->linear_base) >= ((mach->ap_size << 20) - 0x200)) && ((addr - mach->linear_base) < (mach->ap_size << 20)))) {
if ((addr - mach->linear_base) & 0x100) {
temp = mach_accel_inw(0x02ee + (port_dword << 8), mach);
temp |= (mach_accel_inw(0x02ee + (port_dword << 8) + 4, mach) << 8);
} else {
@@ -5335,9 +5335,9 @@ mach32_ap_readl(uint32_t addr, void *priv)
}
} else {
if (dev->on)
temp = mach32_readl_linear(addr, mach);
temp = mach32_readl_linear(addr - mach->linear_base, mach);
else
temp = svga_readl_linear(addr, svga);
temp = svga_readl_linear(addr - mach->linear_base, svga);
mach_log("Linear WORDL Read=%08x, ret=%08x, ON%d.\n", addr, temp, dev->on);
}

3257
src/video/vid_ps55da2.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -502,10 +502,25 @@ svga_in(uint16_t addr, void *priv)
ret = svga->attrregs[svga->attraddr];
break;
case 0x3c2:
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e)
ret = 0;
else
ret = 0x10;
if (svga->cable_connected) {
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e)
ret = 0;
else
ret = 0x10;
/* Monitor is not connected to the planar VGA if the PS/55 Display Adapter is installed. */
} else {
/*
The IBM PS/55 Display Adapter has own Monitor Type Detection bit in the different I/O port (I/O 3E0h, 3E1h).
When the monitor cable is connected to the Display Adapter, the port 3C2h returns the value as 'no cable connection'.
The POST of PS/55 has an extra code. If the monitor is not detected on the planar VGA,
it reads the POS data in NVRAM set by the reference diskette, and writes the BIOS Data Area (Mem 487h, 489h).
MONCHK.EXE in the reference diskette uses both I/O ports to determine the monitor type, updates the NVRAM and BDA.
*/
if (svga->vgapal[0].r >= 10 || svga->vgapal[0].g >= 10 || svga->vgapal[0].b >= 10)
ret = 0;
else
ret = 0x10;
}
break;
case 0x3c3:
ret = 0x01;
@@ -1526,6 +1541,8 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 32;
svga->translate_address = NULL;
svga->cable_connected = 1;
svga->ksc5601_english_font_type = 0;
/* TODO: Move DEVICE_MCA to 16-bit once the device flags have been appropriately corrected. */

View File

@@ -369,6 +369,8 @@ video_post_reset(void)
if (xga_standalone_enabled)
xga_device_add();
if (da2_standalone_enabled)
da2_device_add();
/* Reset the graphics card (or do nothing if it was already done
by the machine's init function). */
video_reset(gfxcard[0]);

View File

@@ -104,6 +104,37 @@ vga_in(uint16_t addr, void *priv)
return temp;
}
void vga_disable(void* p)
{
vga_t* vga = (vga_t*)p;
svga_t* svga = &vga->svga;
io_removehandler(0x03a0, 0x0040, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
mem_mapping_disable(&svga->mapping);
svga->vga_enabled = 0;
}
void vga_enable(void* p)
{
vga_t* vga = (vga_t*)p;
svga_t* svga = &vga->svga;
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
if (!(svga->miscout & 1))
io_sethandler(0x03a0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
mem_mapping_enable(&svga->mapping);
svga->vga_enabled = 1;
}
int vga_isenabled(void* p)
{
vga_t* vga = (vga_t*)p;
svga_t* svga = &vga->svga;
return svga->vga_enabled;
}
static void *
vga_init(const device_t *info)
{
@@ -150,6 +181,7 @@ ps1vga_init(const device_t *info)
vga->svga.bpp = 8;
vga->svga.miscout = 1;
vga->svga.vga_enabled = 1;
return vga;
}

View File

@@ -30,6 +30,7 @@
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/dma.h>
#include <86box/pci.h>
#include <86box/rom.h>
#include <86box/timer.h>
@@ -43,9 +44,11 @@
#include <86box/vid_svga_render.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_display.h>
#include <86box/vid_voodoo_fb.h>
#include <86box/vid_voodoo_fifo.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
#include <86box/vid_voodoo_texture.h>
#define ROM_BANSHEE "roms/video/voodoo/Pci_sg.rom"
#define ROM_CREATIVE_BANSHEE "roms/video/voodoo/BlasterPCI.rom"
@@ -220,6 +223,7 @@ enum {
Agp_agpHostAddressHigh = 0x08,
Agp_agpGraphicsAddress = 0x0C,
Agp_agpGraphicsStride = 0x10,
Agp_agpMoveCMD = 0x14,
};
#define VGAINIT0_RAMDAC_8BIT (1 << 2)
@@ -1365,6 +1369,10 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr)
case cmdBaseSize0:
ret = voodoo->cmdfifo_size;
if (voodoo->cmdfifo_enabled)
ret |= 0x100;
if (voodoo->cmdfifo_in_agp)
ret |= 0x200;
break;
case cmdBaseAddr1:
@@ -1394,6 +1402,10 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr)
case cmdBaseSize1:
ret = voodoo->cmdfifo_size_2;
if (voodoo->cmdfifo_enabled_2)
ret |= 0x100;
if (voodoo->cmdfifo_in_agp_2)
ret |= 0x200;
break;
case 0x108:
@@ -1613,10 +1625,11 @@ banshee_reg_writew(uint32_t addr, uint16_t val, void *priv)
}
}
static void
banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
void
banshee_cmd_write(void *priv, uint32_t addr, uint32_t val)
{
voodoo_t *voodoo = banshee->voodoo;
banshee_t *banshee = (banshee_t *) priv;
voodoo_t *voodoo = banshee->voodoo;
#if 0
banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val);
#endif
@@ -1641,6 +1654,62 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
banshee->agpReqSize = val;
break;
case Agp_agpMoveCMD: {
uint32_t src_addr = banshee->agpHostAddressLow;
uint32_t src_width = banshee->agpHostAddressHigh & 0x3fff;
uint32_t src_stride = (banshee->agpHostAddressHigh >> 14) & 0x3fff;
uint32_t src_end = src_addr + (banshee->agpReqSize & 0xfffff); /* don't know whether or not stride is accounted for! */
uint32_t dest_addr = banshee->agpGraphicsAddress & 0x3ffffff;
uint32_t dest_stride = banshee->agpGraphicsStride & 0x7fff;
#if 0
banshee_log("AGP: %d bytes W%d from %08x S%d to %d:%08x S%d\n", src_end - src_addr, src_width, src_addr, src_stride, (val >> 3) & 3, dest_addr, dest_stride);
#endif
switch ((val >> 3) & 3) {
case 0: /*Linear framebuffer (Banshee)*/
case 1: /*Planar YUV*/
if (voodoo->texture_present[0][(dest_addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) {
#if 0
banshee_log("texture_present at %08x %i\n", dest_addr, (dest_addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
#endif
flush_texture_cache(voodoo, dest_addr & voodoo->texture_mask, 0);
}
if (voodoo->texture_present[1][(dest_addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) {
#if 0
banshee_log("texture_present at %08x %i\n", dest_addr, (dest_addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
#endif
flush_texture_cache(voodoo, dest_addr & voodoo->texture_mask, 1);
}
while ((src_addr < src_end) && (dest_addr <= voodoo->fb_mask)) {
dma_bm_read(src_addr, &voodoo->fb_mem[dest_addr], MIN(src_width, voodoo->fb_mask - dest_addr), 4);
src_addr += src_stride;
dest_addr += dest_stride;
}
break;
case 2: /*Framebuffer*/
src_width &= ~3;
while (src_addr < src_end) {
for (uint32_t i = 0; i < src_width; i += 4)
voodoo_fb_writel(dest_addr + i, mem_readl_phys(src_addr + i), voodoo);
src_addr += src_stride;
dest_addr += dest_stride;
}
break;
case 3: /*Texture*/
src_width &= ~3;
while (src_addr < src_end) {
for (uint32_t i = 0; i < src_width; i += 4)
voodoo_tex_writel(dest_addr + i, mem_readl_phys(src_addr + i), voodoo);
src_addr += src_stride;
dest_addr += dest_stride;
}
break;
default:
break;
}
break;
}
case cmdBaseAddr0:
voodoo->cmdfifo_base = (val & 0xfff) << 12;
voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12);
@@ -1655,6 +1724,7 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
voodoo->cmdfifo_enabled = val & 0x100;
if (!voodoo->cmdfifo_enabled)
voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/
voodoo->cmdfifo_in_agp = val & 0x200;
#if 0
banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
#endif
@@ -1694,6 +1764,7 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
voodoo->cmdfifo_enabled_2 = val & 0x100;
if (!voodoo->cmdfifo_enabled_2)
voodoo->cmdfifo_in_sub_2 = 0; /*Not sure exactly when this should be reset*/
voodoo->cmdfifo_in_agp_2 = val & 0x200;
#if 0
banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
#endif

View File

@@ -35,6 +35,7 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_banshee.h>
#include <86box/vid_voodoo_banshee_blitter.h>
#include <86box/vid_voodoo_fb.h>
#include <86box/vid_voodoo_fifo.h>
@@ -166,7 +167,10 @@ cmdfifo_get(voodoo_t *voodoo)
}
}
val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask];
if (voodoo->cmdfifo_in_agp)
val = mem_readl_phys(voodoo->cmdfifo_rp);
else
val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask];
if (!voodoo->cmdfifo_in_sub)
voodoo->cmdfifo_depth_rd++;
@@ -200,7 +204,10 @@ cmdfifo_get_2(voodoo_t *voodoo)
}
}
val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp_2 & voodoo->fb_mask];
if (voodoo->cmdfifo_in_agp_2)
val = mem_readl_phys(voodoo->cmdfifo_rp_2);
else
val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp_2 & voodoo->fb_mask];
if (!voodoo->cmdfifo_in_sub_2)
voodoo->cmdfifo_depth_rd_2++;
@@ -362,9 +369,21 @@ voodoo_fifo_thread(void *param)
break;
case 3: /*JMP local frame buffer*/
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
voodoo->cmdfifo_in_agp = 0;
#if 0
voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
voodoo_fifo_log("JMP LFB to %08x %04x\n", voodoo->cmdfifo_rp, header);
#endif
break;
case 4: /*JMP AGP*/
if (UNLIKELY(voodoo->type < VOODOO_BANSHEE))
fatal("CMDFIFO0: Not Banshee %08x\n", header);
voodoo->cmdfifo_rp = ((header >> 4) & 0x1fffffc) | (cmdfifo_get(voodoo) << 25);
voodoo->cmdfifo_in_agp = 1;
#if 0
voodoo_fifo_log("JMP AGP to %08x %04x\n", voodoo->cmdfifo_rp, header);
#endif
break;
@@ -573,6 +592,23 @@ voodoo_fifo_thread(void *param)
}
break;
case 6:
if (UNLIKELY(voodoo->type < VOODOO_BANSHEE)) {
fatal("CMDFIFO6: Not Banshee %08x %08x\n", header, voodoo->cmdfifo_rp);
} else {
uint32_t val = cmdfifo_get(voodoo);
banshee_cmd_write(voodoo->priv, 0x00, val >> 5); /* agpReqSize */
banshee_cmd_write(voodoo->priv, 0x04, cmdfifo_get(voodoo)); /* agpHostAddressLow */
banshee_cmd_write(voodoo->priv, 0x08, cmdfifo_get(voodoo)); /* agpHostAddressHigh */
banshee_cmd_write(voodoo->priv, 0x0c, cmdfifo_get(voodoo)); /* agpGraphicsAddress */
banshee_cmd_write(voodoo->priv, 0x10, cmdfifo_get(voodoo)); /* agpGraphicsStride */
banshee_cmd_write(voodoo->priv, 0x14, (val & 0x18) | 0x00); /* agpMoveCMD - start transfer */
#if 0
voodoo_fifo_log("CMDFIFO6 addr=%08x num=%i\n", addr, banshee->agpReqSize);
#endif
}
break;
default:
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
}
@@ -624,9 +660,21 @@ voodoo_fifo_thread(void *param)
break;
case 3: /*JMP local frame buffer*/
voodoo->cmdfifo_rp_2 = (header >> 4) & 0xfffffc;
voodoo->cmdfifo_rp_2 = (header >> 4) & 0xfffffc;
voodoo->cmdfifo_in_agp_2 = 0;
#if 0
voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
voodoo_fifo_log("JMP LFB to %08x %04x\n", voodoo->cmdfifo_rp_2, header);
#endif
break;
case 4: /*JMP AGP*/
if (UNLIKELY(voodoo->type < VOODOO_BANSHEE))
fatal("CMDFIFO0: Not Banshee %08x\n", header);
voodoo->cmdfifo_rp_2 = ((header >> 4) & 0x1fffffc) | (cmdfifo_get_2(voodoo) << 25);
voodoo->cmdfifo_in_agp_2 = 1;
#if 0
voodoo_fifo_log("JMP AGP to %08x %04x\n", voodoo->cmdfifo_rp_2, header);
#endif
break;
@@ -835,6 +883,23 @@ voodoo_fifo_thread(void *param)
}
break;
case 6:
if (UNLIKELY(voodoo->type < VOODOO_BANSHEE)) {
fatal("CMDFIFO6: Not Banshee %08x %08x\n", header, voodoo->cmdfifo_rp);
} else {
uint32_t val = cmdfifo_get_2(voodoo);
banshee_cmd_write(voodoo->priv, 0x00, val >> 5); /* agpReqSize */
banshee_cmd_write(voodoo->priv, 0x04, cmdfifo_get_2(voodoo)); /* agpHostAddressLow */
banshee_cmd_write(voodoo->priv, 0x08, cmdfifo_get_2(voodoo)); /* agpHostAddressHigh */
banshee_cmd_write(voodoo->priv, 0x0c, cmdfifo_get_2(voodoo)); /* agpGraphicsAddress */
banshee_cmd_write(voodoo->priv, 0x10, cmdfifo_get_2(voodoo)); /* agpGraphicsStride */
banshee_cmd_write(voodoo->priv, 0x14, (val & 0x18) | 0x20); /* agpMoveCMD - start transfer */
#if 0
voodoo_fifo_log("CMDFIFO6 addr=%08x num=%i\n", addr, banshee->agpReqSize);
#endif
}
break;
default:
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
}