mirror of
https://github.com/86Box/86Box.git
synced 2026-02-25 12:55:32 -07:00
Merge branch '86Box:master' into main
This commit is contained in:
26
src/86box.c
26
src/86box.c
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
24
src/include/86box/vid_ps55da2.h
Normal file
24
src/include/86box/vid_ps55da2.h
Normal 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*/
|
||||
@@ -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];
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
16
src/mca.c
16
src/mca.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
//@}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
3257
src/video/vid_ps55da2.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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. */
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user