Fixes for the (S)VGA common DAC and some card-specific DAT's (ATi 68860, BT48x family, and the Cirrus Logic DAC), fixes Star Control II among other things.
This commit is contained in:
1306
src/machine/m_amstrad - Cópia.c
Normal file
1306
src/machine/m_amstrad - Cópia.c
Normal file
File diff suppressed because it is too large
Load Diff
111
src/machine/m_at.c$
Normal file
111
src/machine/m_at.c$
Normal file
@@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../pic.h"
|
||||
#include "../pit.h"
|
||||
#include "../dma.h"
|
||||
#include "../mem.h"
|
||||
#include "../device.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../nvr.h"
|
||||
#include "../game/gameport.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../lpt.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
void
|
||||
machine_at_common_init(const machine_t *model)
|
||||
{
|
||||
machine_common_init(model);
|
||||
|
||||
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
|
||||
pic2_init();
|
||||
dma16_init();
|
||||
|
||||
if (lpt_enabled)
|
||||
lpt2_remove();
|
||||
|
||||
device_add(&at_nvr_device);
|
||||
|
||||
if (joystick_type != 7)
|
||||
device_add(&gameport_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_ps2_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&keyboard_ps2_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_common_ide_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&ide_isa_2ch_opt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_ide_init(const machine_t *model)
|
||||
{
|
||||
machine_at_init(model);
|
||||
|
||||
device_add(&ide_isa_2ch_opt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_ps2_ide_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(model);
|
||||
|
||||
device_add(&ide_isa_2ch_opt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_top_remap_init(const machine_t *model)
|
||||
{
|
||||
machine_at_init(model);
|
||||
|
||||
if (mem_size >= 1024)
|
||||
mem_remap_top_384k();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_ide_top_remap_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ide_init(model);
|
||||
|
||||
if (mem_size >= 1024)
|
||||
mem_remap_top_384k();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_ibm_init(const machine_t *model)
|
||||
{
|
||||
machine_at_top_remap_init(model);
|
||||
|
||||
device_add(&fdc_at_device);
|
||||
}
|
||||
578
src/machine/m_at_headland - Cópia.c
Normal file
578
src/machine/m_at_headland - Cópia.c
Normal file
@@ -0,0 +1,578 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../cpu/x86.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "machine.h"
|
||||
#include "../video/video.h"
|
||||
#include "../video/vid_et4000.h"
|
||||
#include "../video/vid_oak_oti.h"
|
||||
|
||||
|
||||
static int headland_index;
|
||||
static uint8_t headland_regs[256];
|
||||
static uint8_t headland_port_92 = 0xFC, headland_ems_mar = 0, headland_cri = 0;
|
||||
static uint8_t headland_regs_cr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static uint16_t headland_ems_mr[64];
|
||||
|
||||
static mem_mapping_t headland_low_mapping;
|
||||
static mem_mapping_t headland_ems_mapping[64];
|
||||
static mem_mapping_t headland_mid_mapping;
|
||||
static mem_mapping_t headland_high_mapping;
|
||||
static mem_mapping_t headland_4000_9FFF_mapping[24];
|
||||
|
||||
/* TODO - Headland chipset's memory address mapping emulation isn't fully implemented yet,
|
||||
so memory configuration is hardcoded now. */
|
||||
static int headland_mem_conf_cr0[41] = { 0x00, 0x00, 0x20, 0x40, 0x60, 0xA0, 0x40, 0xE0,
|
||||
0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, 0xE0, 0xE0,
|
||||
0xE0, 0x20, 0x40, 0x40, 0xA0, 0xC0, 0xE0, 0xE0,
|
||||
0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
|
||||
0x20, 0x40, 0x60, 0x60, 0xC0, 0xE0, 0xE0, 0xE0,
|
||||
0xE0 };
|
||||
static int headland_mem_conf_cr1[41] = { 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
|
||||
0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40 };
|
||||
|
||||
|
||||
static uint32_t
|
||||
get_headland_addr(uint32_t addr, uint16_t *mr)
|
||||
{
|
||||
if (mr && (headland_regs_cr[0] & 2) && (*mr & 0x200)) {
|
||||
addr = (addr & 0x3fff) | ((*mr & 0x1F) << 14);
|
||||
|
||||
if (headland_regs_cr[1] & 0x40) {
|
||||
if ((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) {
|
||||
if (headland_regs_cr[0] & 0x80) {
|
||||
addr |= (*mr & 0x60) << 14;
|
||||
if (*mr & 0x100)
|
||||
addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x80) << 15);
|
||||
else
|
||||
addr += (*mr & 0x80) << 14;
|
||||
} else if (*mr & 0x100)
|
||||
addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x20) << 15);
|
||||
else
|
||||
addr += (*mr & 0x80) << 12;
|
||||
} else if (headland_regs_cr[0] & 0x80)
|
||||
addr |= (*mr & 0x100) ? ((*mr & 0x80) + 0x400) << 12 : (*mr & 0xE0) << 14;
|
||||
else
|
||||
addr |= (*mr & 0x100) ? ((*mr & 0xE0) + 0x40) << 14 : (*mr & 0x80) << 12;
|
||||
} else {
|
||||
if ((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) {
|
||||
if (headland_regs_cr[0] & 0x80) {
|
||||
addr |= ((*mr & 0x60) << 14);
|
||||
if (*mr & 0x180)
|
||||
addr += ((*mr & 0xC00) << 13) + (((*mr & 0x180) - 0x60) << 16);
|
||||
} else
|
||||
addr |= ((*mr & 0x60) << 14) | ((*mr & 0x180) << 16) | ((*mr & 0xC00) << 13);
|
||||
} else if (headland_regs_cr[0] & 0x80)
|
||||
addr |= (*mr & 0x1E0) << 14;
|
||||
else
|
||||
addr |= (*mr & 0x180) << 12;
|
||||
}
|
||||
} else if (mr == NULL && (headland_regs_cr[0] & 4) == 0 && mem_size >= 1024 && addr >= 0x100000)
|
||||
addr -= 0x60000;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
headland_set_global_EMS_state(int state)
|
||||
{
|
||||
int i;
|
||||
uint32_t base_addr, virt_addr;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
base_addr = (i + 16) << 14;
|
||||
if (i >= 24)
|
||||
base_addr += 0x20000;
|
||||
if ((state & 2) && (headland_ems_mr[((state & 1) << 5) | i] & 0x200)) {
|
||||
virt_addr = get_headland_addr(base_addr, &headland_ems_mr[((state & 1) << 5) | i]);
|
||||
if (i < 24)
|
||||
mem_mapping_disable(&headland_4000_9FFF_mapping[i]);
|
||||
mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]);
|
||||
mem_mapping_enable(&headland_ems_mapping[((state & 1) << 5) | i]);
|
||||
if (virt_addr < (mem_size << 10))
|
||||
mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], NULL);
|
||||
} else {
|
||||
mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + base_addr);
|
||||
mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]);
|
||||
mem_mapping_disable(&headland_ems_mapping[((state & 1) << 5) | i]);
|
||||
|
||||
if (i < 24)
|
||||
mem_mapping_enable(&headland_4000_9FFF_mapping[i]);
|
||||
}
|
||||
}
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
headland_memmap_state_update(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t addr;
|
||||
|
||||
for (i=0; i<24; i++) {
|
||||
addr = get_headland_addr(0x40000 + (i << 14), NULL);
|
||||
mem_mapping_set_exec(&headland_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL);
|
||||
}
|
||||
|
||||
mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
|
||||
if (mem_size > 640) {
|
||||
if ((headland_regs_cr[0] & 4) == 0) {
|
||||
mem_mapping_set_addr(&headland_mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000);
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_set_addr(&headland_high_mapping, 0x160000, (mem_size - 1024) << 10);
|
||||
mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000);
|
||||
}
|
||||
} else {
|
||||
mem_mapping_set_addr(&headland_mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000);
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_set_addr(&headland_high_mapping, 0x100000, (mem_size - 1024) << 10);
|
||||
mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
headland_set_global_EMS_state(headland_regs_cr[0] & 3);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
headland_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t old_val, index;
|
||||
uint32_t base_addr, virt_addr;
|
||||
|
||||
switch(addr) {
|
||||
case 0x22:
|
||||
headland_index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
old_val = headland_regs[headland_index];
|
||||
if ((headland_index == 0xc1) && !is486)
|
||||
val = 0;
|
||||
headland_regs[headland_index] = val;
|
||||
if (headland_index == 0x82) {
|
||||
shadowbios = val & 0x10;
|
||||
shadowbios_write = !(val & 0x10);
|
||||
if (shadowbios)
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (headland_index == 0x87) {
|
||||
if ((val & 1) && !(old_val & 1))
|
||||
softresetx86();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
if ((mem_a20_alt ^ val) & 2) {
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
if ((~headland_port_92 & val) & 1) {
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
headland_port_92 = val | 0xFC;
|
||||
break;
|
||||
|
||||
case 0x1EC:
|
||||
headland_ems_mr[headland_ems_mar & 0x3F] = val | 0xFF00;
|
||||
index = headland_ems_mar & 0x1F;
|
||||
base_addr = (index + 16) << 14;
|
||||
if (index >= 24)
|
||||
base_addr += 0x20000;
|
||||
if ((headland_regs_cr[0] & 2) && ((headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5))) {
|
||||
virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]);
|
||||
if (index < 24)
|
||||
mem_mapping_disable(&headland_4000_9FFF_mapping[index]);
|
||||
if (virt_addr < (mem_size << 10))
|
||||
mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL);
|
||||
mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]);
|
||||
flushmmucache();
|
||||
}
|
||||
if (headland_ems_mar & 0x80)
|
||||
headland_ems_mar++;
|
||||
break;
|
||||
|
||||
case 0x1ED:
|
||||
headland_cri = val;
|
||||
break;
|
||||
|
||||
case 0x1EE:
|
||||
headland_ems_mar = val;
|
||||
break;
|
||||
|
||||
case 0x1EF:
|
||||
old_val = headland_regs_cr[headland_cri];
|
||||
switch(headland_cri) {
|
||||
case 0:
|
||||
headland_regs_cr[0] = (val & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
mem_set_mem_state(0xE0000, 0x10000, (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state(0xF0000, 0x10000, (val & 0x10 ? MEM_READ_INTERNAL: MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED);
|
||||
headland_memmap_state_update();
|
||||
break;
|
||||
case 1:
|
||||
headland_regs_cr[1] = (val & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
headland_memmap_state_update();
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
headland_regs_cr[headland_cri] = val;
|
||||
headland_memmap_state_update();
|
||||
break;
|
||||
case 4:
|
||||
headland_regs_cr[4] = (headland_regs_cr[4] & 0xF0) | (val & 0x0F);
|
||||
if (val & 1) {
|
||||
mem_mapping_disable(&bios_mapping[0]);
|
||||
mem_mapping_disable(&bios_mapping[1]);
|
||||
mem_mapping_disable(&bios_mapping[2]);
|
||||
mem_mapping_disable(&bios_mapping[3]);
|
||||
} else {
|
||||
mem_mapping_enable(&bios_mapping[0]);
|
||||
mem_mapping_enable(&bios_mapping[1]);
|
||||
mem_mapping_enable(&bios_mapping[2]);
|
||||
mem_mapping_enable(&bios_mapping[3]);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (headland_regs_cr[4] & 0x80) {
|
||||
headland_regs_cr[headland_cri] = (val & 0xFE) | (mem_size > 8192 ? 1 : 0);
|
||||
headland_memmap_state_update();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
headland_writew(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
uint8_t index;
|
||||
uint32_t base_addr, virt_addr;
|
||||
|
||||
switch(addr) {
|
||||
case 0x1EC:
|
||||
headland_ems_mr[headland_ems_mar & 0x3F] = val;
|
||||
index = headland_ems_mar & 0x1F;
|
||||
base_addr = (index + 16) << 14;
|
||||
if (index >= 24)
|
||||
base_addr += 0x20000;
|
||||
if ((headland_regs_cr[0] & 2) && (headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5)) {
|
||||
if(val & 0x200) {
|
||||
virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]);
|
||||
if (index < 24)
|
||||
mem_mapping_disable(&headland_4000_9FFF_mapping[index]);
|
||||
if (virt_addr < (mem_size << 10))
|
||||
mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL);
|
||||
mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]);
|
||||
} else {
|
||||
mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + base_addr);
|
||||
mem_mapping_disable(&headland_ems_mapping[headland_ems_mar & 0x3F]);
|
||||
if (index < 24)
|
||||
mem_mapping_enable(&headland_4000_9FFF_mapping[index]);
|
||||
}
|
||||
flushmmucache();
|
||||
}
|
||||
if (headland_ems_mar & 0x80)
|
||||
headland_ems_mar++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
headland_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
switch(addr) {
|
||||
case 0x22:
|
||||
val = headland_index;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix)
|
||||
val = 0xff; /*Don't conflict with Cyrix config registers*/
|
||||
else
|
||||
val = headland_regs[headland_index];
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
val = headland_port_92 | 0xFC;
|
||||
break;
|
||||
|
||||
case 0x1EC:
|
||||
val = headland_ems_mr[headland_ems_mar & 0x3F];
|
||||
if (headland_ems_mar & 0x80)
|
||||
headland_ems_mar++;
|
||||
break;
|
||||
|
||||
case 0x1ED:
|
||||
val = headland_cri;
|
||||
break;
|
||||
|
||||
case 0x1EE:
|
||||
val = headland_ems_mar;
|
||||
break;
|
||||
|
||||
case 0x1EF:
|
||||
switch(headland_cri) {
|
||||
case 0:
|
||||
val = (headland_regs_cr[0] & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
break;
|
||||
case 1:
|
||||
val = (headland_regs_cr[1] & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
break;
|
||||
case 6:
|
||||
if (headland_regs_cr[4] & 0x80)
|
||||
val = (headland_regs_cr[6] & 0xFE) | (mem_size > 8192 ? 1 : 0);
|
||||
else
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
val = headland_regs_cr[headland_cri];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
val = 0xFF;
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
headland_readw(uint16_t addr, void *priv)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
switch(addr) {
|
||||
case 0x1EC:
|
||||
val = headland_ems_mr[headland_ems_mar & 0x3F] | ((headland_regs_cr[4] & 0x80) ? 0xF000 : 0xFC00);
|
||||
if (headland_ems_mar & 0x80)
|
||||
headland_ems_mar++;
|
||||
break;
|
||||
|
||||
default:
|
||||
val = 0xFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
mem_read_headlandb(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t val = 0xff;
|
||||
|
||||
addr = get_headland_addr(addr, priv);
|
||||
if (addr < (mem_size << 10))
|
||||
val = ram[addr];
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
mem_read_headlandw(uint32_t addr, void *priv)
|
||||
{
|
||||
uint16_t val = 0xffff;
|
||||
|
||||
addr = get_headland_addr(addr, priv);
|
||||
if (addr < (mem_size << 10))
|
||||
val = *(uint16_t *)&ram[addr];
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
mem_read_headlandl(uint32_t addr, void *priv)
|
||||
{
|
||||
uint32_t val = 0xffffffff;
|
||||
|
||||
addr = get_headland_addr(addr, priv);
|
||||
if (addr < (mem_size << 10))
|
||||
val = *(uint32_t *)&ram[addr];
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_headlandb(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
addr = get_headland_addr(addr, priv);
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_headlandw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
addr = get_headland_addr(addr, priv);
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_headlandl(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
addr = get_headland_addr(addr, priv);
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint32_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
headland_init(int ht386)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<8; i++)
|
||||
headland_regs_cr[i] = 0;
|
||||
headland_regs_cr[0] = 4;
|
||||
|
||||
if (ht386) {
|
||||
headland_regs_cr[4] = 0x20;
|
||||
io_sethandler(0x0092, 0x0001, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL);
|
||||
} else
|
||||
headland_regs_cr[4] = 0;
|
||||
|
||||
io_sethandler(0x01EC, 0x0001, headland_read, headland_readw, NULL, headland_write, headland_writew, NULL, NULL);
|
||||
io_sethandler(0x01ED, 0x0003, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL);
|
||||
|
||||
for(i=0; i<64; i++)
|
||||
headland_ems_mr[i] = 0;
|
||||
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
|
||||
mem_mapping_add(&headland_low_mapping, 0, 0x40000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram, MEM_MAPPING_INTERNAL, NULL);
|
||||
|
||||
if(mem_size > 640) {
|
||||
mem_mapping_add(&headland_mid_mapping, 0xA0000, 0x60000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_enable(&headland_mid_mapping);
|
||||
}
|
||||
|
||||
if(mem_size > 1024) {
|
||||
mem_mapping_add(&headland_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_enable(&headland_high_mapping);
|
||||
}
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
mem_mapping_add(&headland_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_enable(&headland_4000_9FFF_mapping[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
headland_ems_mr[i] = 0;
|
||||
mem_mapping_add(&headland_ems_mapping[i], ((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14), 0, &headland_ems_mr[i]);
|
||||
mem_mapping_disable(&headland_ems_mapping[i]);
|
||||
}
|
||||
|
||||
headland_memmap_state_update();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
machine_at_headland_common_init(int ht386)
|
||||
{
|
||||
device_add(&keyboard_at_ami_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
headland_init(ht386);
|
||||
}
|
||||
|
||||
void
|
||||
machine_at_headland_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
machine_at_headland_common_init(1);
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_tg286m_get_device(void)
|
||||
{
|
||||
return &et4000k_tg286_isa_device;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_tg286m_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
machine_at_headland_common_init(0);
|
||||
|
||||
if (gfxcard == GFX_INTERNAL)
|
||||
device_add(&et4000k_tg286_isa_device);
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_ama932j_get_device(void)
|
||||
{
|
||||
return &oti067_ama932j_device;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_ama932j_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
machine_at_headland_common_init(1);
|
||||
|
||||
if (gfxcard == GFX_INTERNAL)
|
||||
device_add(&oti067_ama932j_device);
|
||||
}
|
||||
767
src/machine/m_europc - Cópia.c
Normal file
767
src/machine/m_europc - Cópia.c
Normal file
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
* VARCem Virtual ARchaeological Computer EMulator.
|
||||
* An emulator of (mostly) x86-based PC systems and devices,
|
||||
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
|
||||
* spanning the era between 1981 and 1995.
|
||||
*
|
||||
* This file is part of the VARCem Project.
|
||||
*
|
||||
* Implementation of the Schneider EuroPC system.
|
||||
*
|
||||
* NOTES: BIOS info (taken from MAME, thanks guys!!)
|
||||
*
|
||||
* f000:e107 bios checksum test
|
||||
* memory test
|
||||
* f000:e145 irq vector init
|
||||
* f000:e156
|
||||
* f000:e169-d774 test of special registers 254/354
|
||||
* f000:e16c-e817
|
||||
* f000:e16f
|
||||
* f000:ec08 test of special registers 800a rtc time
|
||||
* or date error, rtc corrected
|
||||
* f000:ef66 0xf
|
||||
* f000:db3e 0x8..0xc
|
||||
* f000:d7f8
|
||||
* f000:db5f
|
||||
* f000:e172
|
||||
* f000:ecc5 801a video setup error
|
||||
* f000:d6c9 copyright output
|
||||
* f000:e1b7
|
||||
* f000:e1be DI bits set mean output text!!! (801a)
|
||||
* f000: 0x8000 output
|
||||
* 1 rtc error
|
||||
* 2 rtc time or date error
|
||||
* 4 checksum error in setup
|
||||
* 8 rtc status corrected
|
||||
* 10 video setup error
|
||||
* 20 video ram bad
|
||||
* 40 monitor type not recogniced
|
||||
* 80 mouse port enabled
|
||||
* 100 joystick port enabled
|
||||
* f000:e1e2-dc0c CPU speed is 4.77 mhz
|
||||
* f000:e1e5-f9c0 keyboard processor error
|
||||
* f000:e1eb-c617 external lpt1 at 0x3bc
|
||||
* f000:e1ee-e8ee external coms at
|
||||
*
|
||||
* Routines:
|
||||
* f000:c92d output text at bp
|
||||
* f000:db3e RTC read reg cl
|
||||
* f000:e8ee piep
|
||||
* f000:e95e RTC write reg cl
|
||||
* polls until JIM 0xa is zero,
|
||||
* output cl at jim 0xa
|
||||
* write ah hinibble as lownibble into jim 0xa
|
||||
* write ah lownibble into jim 0xa
|
||||
* f000:ef66 RTC read reg cl
|
||||
* polls until jim 0xa is zero,
|
||||
* output cl at jim 0xa
|
||||
* read low 4 nibble at jim 0xa
|
||||
* read low 4 nibble at jim 0xa
|
||||
* return first nibble<<4|second nibble in ah
|
||||
* f000:f046 seldom compares ret
|
||||
* f000:fe87 0 -> ds
|
||||
*
|
||||
* Memory:
|
||||
* 0000:0469 bit 0: b0000 memory available
|
||||
* bit 1: b8000 memory available
|
||||
* 0000:046a: 00 jim 250 01 jim 350
|
||||
*
|
||||
* WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK.
|
||||
*
|
||||
* Version: @(#)europc.c 1.0.7 2018/08/04
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Inspired by the "jim.c" file originally present, but a
|
||||
* fully re-written module, based on the information from
|
||||
* Schneider's schematics and technical manuals, and the
|
||||
* input from people with real EuroPC hardware.
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with
|
||||
* or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the entire
|
||||
* above notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names
|
||||
* of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <time.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../io.h"
|
||||
#include "../nmi.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../mouse.h"
|
||||
#include "../game/gameport.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../video/video.h"
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
#define EUROPC_DEBUG 0 /* current debugging level */
|
||||
|
||||
|
||||
/* M3002 RTC chip registers. */
|
||||
#define MRTC_SECONDS 0x00 /* BCD, 00-59 */
|
||||
#define MRTC_MINUTES 0x01 /* BCD, 00-59 */
|
||||
#define MRTC_HOURS 0x02 /* BCD, 00-23 */
|
||||
#define MRTC_DAYS 0x03 /* BCD, 01-31 */
|
||||
#define MRTC_MONTHS 0x04 /* BCD, 01-12 */
|
||||
#define MRTC_YEARS 0x05 /* BCD, 00-99 (year only) */
|
||||
#define MRTC_WEEKDAY 0x06 /* BCD, 01-07 */
|
||||
#define MRTC_WEEKNO 0x07 /* BCD, 01-52 */
|
||||
#define MRTC_CONF_A 0x08 /* EuroPC config, binary */
|
||||
#define MRTC_CONF_B 0x09 /* EuroPC config, binary */
|
||||
#define MRTC_CONF_C 0x0a /* EuroPC config, binary */
|
||||
#define MRTC_CONF_D 0x0b /* EuroPC config, binary */
|
||||
#define MRTC_CONF_E 0x0c /* EuroPC config, binary */
|
||||
#define MRTC_CHECK_LO 0x0d /* Checksum, low byte */
|
||||
#define MRTC_CHECK_HI 0x0e /* Checksum, high byte */
|
||||
#define MRTC_CTRLSTAT 0x0f /* RTC control/status, binary */
|
||||
|
||||
typedef struct {
|
||||
uint16_t jim; /* JIM base address */
|
||||
|
||||
uint8_t regs[16]; /* JIM internal regs (8) */
|
||||
|
||||
nvr_t nvr; /* NVR */
|
||||
uint8_t nvr_stat;
|
||||
uint8_t nvr_addr;
|
||||
} europc_t;
|
||||
|
||||
|
||||
static europc_t europc;
|
||||
|
||||
|
||||
#ifdef ENABLE_EUROPC_LOG
|
||||
int europc_do_log = ENABLE_EUROPC_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
europc_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_EUROPC_LOG
|
||||
va_list ap;
|
||||
|
||||
if (europc_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called every second through the NVR/RTC hook.
|
||||
*
|
||||
* We fake a 'running' RTC by updating its registers on
|
||||
* each passing second. Not exactly accurate, but good
|
||||
* enough.
|
||||
*
|
||||
* Note that this code looks nasty because of all the
|
||||
* BCD to decimal vv going on.
|
||||
*
|
||||
* FIXME: should we mark NVR as dirty?
|
||||
*/
|
||||
static void
|
||||
europc_rtc_tick(nvr_t *nvr)
|
||||
{
|
||||
uint8_t *regs;
|
||||
int mon, yr;
|
||||
|
||||
/* Only if RTC is running.. */
|
||||
regs = nvr->regs;
|
||||
if (! (regs[MRTC_CTRLSTAT] & 0x01)) return;
|
||||
|
||||
regs[MRTC_SECONDS] = RTC_BCDINC(nvr->regs[MRTC_SECONDS], 1);
|
||||
if (regs[MRTC_SECONDS] >= RTC_BCD(60)) {
|
||||
regs[MRTC_SECONDS] = RTC_BCD(0);
|
||||
regs[MRTC_MINUTES] = RTC_BCDINC(regs[MRTC_MINUTES], 1);
|
||||
if (regs[MRTC_MINUTES] >= RTC_BCD(60)) {
|
||||
regs[MRTC_MINUTES] = RTC_BCD(0);
|
||||
regs[MRTC_HOURS] = RTC_BCDINC(regs[MRTC_HOURS], 1);
|
||||
if (regs[MRTC_HOURS] >= RTC_BCD(24)) {
|
||||
regs[MRTC_HOURS] = RTC_BCD(0);
|
||||
regs[MRTC_DAYS] = RTC_BCDINC(regs[MRTC_DAYS], 1);
|
||||
mon = RTC_DCB(regs[MRTC_MONTHS]);
|
||||
yr = RTC_DCB(regs[MRTC_YEARS]) + 1900;
|
||||
if (RTC_DCB(regs[MRTC_DAYS]) > nvr_get_days(mon, yr)) {
|
||||
regs[MRTC_DAYS] = RTC_BCD(1);
|
||||
regs[MRTC_MONTHS] = RTC_BCDINC(regs[MRTC_MONTHS], 1);
|
||||
if (regs[MRTC_MONTHS] > RTC_BCD(12)) {
|
||||
regs[MRTC_MONTHS] = RTC_BCD(1);
|
||||
regs[MRTC_YEARS] = RTC_BCDINC(regs[MRTC_YEARS], 1) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get the current NVR time. */
|
||||
static void
|
||||
rtc_time_get(uint8_t *regs, struct tm *tm)
|
||||
{
|
||||
/* NVR is in BCD data mode. */
|
||||
tm->tm_sec = RTC_DCB(regs[MRTC_SECONDS]);
|
||||
tm->tm_min = RTC_DCB(regs[MRTC_MINUTES]);
|
||||
tm->tm_hour = RTC_DCB(regs[MRTC_HOURS]);
|
||||
tm->tm_wday = (RTC_DCB(regs[MRTC_WEEKDAY]) - 1);
|
||||
tm->tm_mday = RTC_DCB(regs[MRTC_DAYS]);
|
||||
tm->tm_mon = (RTC_DCB(regs[MRTC_MONTHS]) - 1);
|
||||
tm->tm_year = RTC_DCB(regs[MRTC_YEARS]);
|
||||
#if USE_Y2K
|
||||
tm->tm_year += (RTC_DCB(regs[MRTC_CENTURY]) * 100) - 1900;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Set the current NVR time. */
|
||||
static void
|
||||
rtc_time_set(uint8_t *regs, struct tm *tm)
|
||||
{
|
||||
/* NVR is in BCD data mode. */
|
||||
regs[MRTC_SECONDS] = RTC_BCD(tm->tm_sec);
|
||||
regs[MRTC_MINUTES] = RTC_BCD(tm->tm_min);
|
||||
regs[MRTC_HOURS] = RTC_BCD(tm->tm_hour);
|
||||
regs[MRTC_WEEKDAY] = RTC_BCD(tm->tm_wday + 1);
|
||||
regs[MRTC_DAYS] = RTC_BCD(tm->tm_mday);
|
||||
regs[MRTC_MONTHS] = RTC_BCD(tm->tm_mon + 1);
|
||||
regs[MRTC_YEARS] = RTC_BCD(tm->tm_year % 100);
|
||||
#if USE_Y2K
|
||||
regs[MRTC_CENTURY] = RTC_BCD((tm->tm_year+1900) / 100);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rtc_start(nvr_t *nvr)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
/* Initialize the internal and chip times. */
|
||||
if (time_sync & TIME_SYNC_ENABLED) {
|
||||
/* Use the internal clock's time. */
|
||||
nvr_time_get(&tm);
|
||||
rtc_time_set(nvr->regs, &tm);
|
||||
} else {
|
||||
/* Set the internal clock from the chip time. */
|
||||
rtc_time_get(nvr->regs, &tm);
|
||||
nvr_time_set(&tm);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Start the RTC - BIOS will do this. */
|
||||
nvr->regs[MRTC_CTRLSTAT] = 0x01;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Create a valid checksum for the current NVR data. */
|
||||
static uint8_t
|
||||
rtc_checksum(uint8_t *ptr)
|
||||
{
|
||||
uint8_t sum;
|
||||
int i;
|
||||
|
||||
/* Calculate all bytes with XOR. */
|
||||
sum = 0x00;
|
||||
for (i=MRTC_CONF_A; i<=MRTC_CONF_E; i++)
|
||||
sum += ptr[i];
|
||||
|
||||
return(sum);
|
||||
}
|
||||
|
||||
|
||||
/* Reset the machine's NVR to a sane state. */
|
||||
static void
|
||||
rtc_reset(nvr_t *nvr)
|
||||
{
|
||||
/* Initialize the RTC to a known state. */
|
||||
nvr->regs[MRTC_SECONDS] = RTC_BCD(0); /* seconds */
|
||||
nvr->regs[MRTC_MINUTES] = RTC_BCD(0); /* minutes */
|
||||
nvr->regs[MRTC_HOURS] = RTC_BCD(0); /* hours */
|
||||
nvr->regs[MRTC_DAYS] = RTC_BCD(1); /* days */
|
||||
nvr->regs[MRTC_MONTHS] = RTC_BCD(1); /* months */
|
||||
nvr->regs[MRTC_YEARS] = RTC_BCD(80); /* years */
|
||||
nvr->regs[MRTC_WEEKDAY] = RTC_BCD(1); /* weekday */
|
||||
nvr->regs[MRTC_WEEKNO] = RTC_BCD(1); /* weekno */
|
||||
|
||||
/*
|
||||
* EuroPC System Configuration:
|
||||
*
|
||||
* [A] unknown
|
||||
*
|
||||
* [B] 7 1 bootdrive extern
|
||||
* 0 bootdribe intern
|
||||
* 6:5 11 invalid hard disk type
|
||||
* 10 hard disk installed, type 2
|
||||
* 01 hard disk installed, type 1
|
||||
* 00 hard disk not installed
|
||||
* 4:3 11 invalid external drive type
|
||||
* 10 external drive 720K
|
||||
* 01 external drive 360K
|
||||
* 00 external drive disabled
|
||||
* 2 unknown
|
||||
* 1:0 11 invalid internal drive type
|
||||
* 10 internal drive 360K
|
||||
* 01 internal drive 720K
|
||||
* 00 internal drive disabled
|
||||
*
|
||||
* [C] 7:6 unknown
|
||||
* 5 monitor detection OFF
|
||||
* 4 unknown
|
||||
* 3:2 11 illegal memory size
|
||||
* 10 512K
|
||||
* 01 256K
|
||||
* 00 640K
|
||||
* 1:0 11 illegal game port
|
||||
* 10 gameport as mouse port
|
||||
* 01 gameport as joysticks
|
||||
* 00 gameport disabled
|
||||
*
|
||||
* [D] 7:6 10 9MHz CPU speed
|
||||
* 01 7MHz CPU speed
|
||||
* 00 4.77 MHz CPU
|
||||
* 5 unknown
|
||||
* 4 external: color, internal: mono
|
||||
* 3 unknown
|
||||
* 2 internal video ON
|
||||
* 1:0 11 mono
|
||||
* 10 color80
|
||||
* 01 color40
|
||||
* 00 special (EGA,VGA etc)
|
||||
*
|
||||
* [E] 7:4 unknown
|
||||
* 3:0 country (00=Deutschland, 0A=ASCII)
|
||||
*/
|
||||
nvr->regs[MRTC_CONF_A] = 0x00; /* CONFIG A */
|
||||
nvr->regs[MRTC_CONF_B] = 0x0A; /* CONFIG B */
|
||||
nvr->regs[MRTC_CONF_C] = 0x28; /* CONFIG C */
|
||||
nvr->regs[MRTC_CONF_D] = 0x12; /* CONFIG D */
|
||||
nvr->regs[MRTC_CONF_E] = 0x0A; /* CONFIG E */
|
||||
|
||||
nvr->regs[MRTC_CHECK_LO] = 0x00; /* checksum (LO) */
|
||||
nvr->regs[MRTC_CHECK_HI] = 0x00; /* checksum (HI) */
|
||||
|
||||
nvr->regs[MRTC_CTRLSTAT] = 0x01; /* status/control */
|
||||
|
||||
/* Generate a valid checksum. */
|
||||
nvr->regs[MRTC_CHECK_LO] = rtc_checksum(nvr->regs);
|
||||
}
|
||||
|
||||
|
||||
/* Execute a JIM control command. */
|
||||
static void
|
||||
jim_set(europc_t *sys, uint8_t reg, uint8_t val)
|
||||
{
|
||||
switch(reg) {
|
||||
case 0: /* MISC control (WO) */
|
||||
// bit0: enable MOUSE
|
||||
// bit1: enable joystick
|
||||
break;
|
||||
|
||||
case 2: /* AGA control */
|
||||
if (! (val & 0x80)) {
|
||||
/* Reset AGA. */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case 0x1f: /* 0001 1111 */
|
||||
case 0x0b: /* 0000 1011 */
|
||||
//europc_jim.mode=AGA_MONO;
|
||||
europc_log("EuroPC: AGA Monochrome mode!\n");
|
||||
break;
|
||||
|
||||
case 0x18: /* 0001 1000 */
|
||||
case 0x1a: /* 0001 1010 */
|
||||
//europc_jim.mode=AGA_COLOR;
|
||||
break;
|
||||
|
||||
case 0x0e: /* 0000 1100 */
|
||||
/*80 columns? */
|
||||
europc_log("EuroPC: AGA 80-column mode!\n");
|
||||
break;
|
||||
|
||||
case 0x0d: /* 0000 1011 */
|
||||
/*40 columns? */
|
||||
europc_log("EuroPC: AGA 40-column mode!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
//europc_jim.mode=AGA_OFF;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* CPU Speed control */
|
||||
switch(val & 0xc0) {
|
||||
case 0x00: /* 4.77 MHz */
|
||||
// cpu_set_clockscale(0, 1.0/2);
|
||||
break;
|
||||
|
||||
case 0x40: /* 7.16 MHz */
|
||||
// cpu_set_clockscale(0, 3.0/4);
|
||||
break;
|
||||
|
||||
default: /* 9.54 MHz */
|
||||
// cpu_set_clockscale(0, 1);break;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sys->regs[reg] = val;
|
||||
}
|
||||
|
||||
|
||||
/* Write to one of the JIM registers. */
|
||||
static void
|
||||
jim_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
europc_t *sys = (europc_t *)priv;
|
||||
uint8_t b;
|
||||
|
||||
#if EUROPC_DEBUG > 1
|
||||
europc_log("EuroPC: jim_wr(%04x, %02x)\n", addr, val);
|
||||
#endif
|
||||
|
||||
switch (addr & 0x000f) {
|
||||
case 0x00: /* JIM internal registers (WRONLY) */
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04: /* JIM internal registers (R/W) */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
jim_set(sys, (addr & 0x07), val);
|
||||
break;
|
||||
|
||||
case 0x0a: /* M3002 RTC INDEX/DATA register */
|
||||
switch(sys->nvr_stat) {
|
||||
case 0: /* save index */
|
||||
sys->nvr_addr = val & 0x0f;
|
||||
sys->nvr_stat++;
|
||||
break;
|
||||
|
||||
case 1: /* save data HI nibble */
|
||||
b = sys->nvr.regs[sys->nvr_addr] & 0x0f;
|
||||
b |= (val << 4);
|
||||
sys->nvr.regs[sys->nvr_addr] = b;
|
||||
sys->nvr_stat++;
|
||||
nvr_dosave++;
|
||||
break;
|
||||
|
||||
case 2: /* save data LO nibble */
|
||||
b = sys->nvr.regs[sys->nvr_addr] & 0xf0;
|
||||
b |= (val & 0x0f);
|
||||
sys->nvr.regs[sys->nvr_addr] = b;
|
||||
sys->nvr_stat = 0;
|
||||
nvr_dosave++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
europc_log("EuroPC: invalid JIM write %02x, val %02x\n", addr, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read from one of the JIM registers. */
|
||||
static uint8_t
|
||||
jim_read(uint16_t addr, void *priv)
|
||||
{
|
||||
europc_t *sys = (europc_t *)priv;
|
||||
uint8_t r = 0xff;
|
||||
|
||||
switch (addr & 0x000f) {
|
||||
case 0x00: /* JIM internal registers (WRONLY) */
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
r = 0x00;
|
||||
break;
|
||||
|
||||
case 0x04: /* JIM internal registers (R/W) */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
r = sys->regs[addr & 0x07];
|
||||
break;
|
||||
|
||||
case 0x0a: /* M3002 RTC INDEX/DATA register */
|
||||
switch(sys->nvr_stat) {
|
||||
case 0:
|
||||
r = 0x00;
|
||||
break;
|
||||
|
||||
case 1: /* read data HI nibble */
|
||||
r = (sys->nvr.regs[sys->nvr_addr] >> 4);
|
||||
sys->nvr_stat++;
|
||||
break;
|
||||
|
||||
case 2: /* read data LO nibble */
|
||||
r = (sys->nvr.regs[sys->nvr_addr] & 0x0f);
|
||||
sys->nvr_stat = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
europc_log("EuroPC: invalid JIM read %02x\n", addr);
|
||||
break;
|
||||
}
|
||||
|
||||
#if EUROPC_DEBUG > 1
|
||||
europc_log("EuroPC: jim_rd(%04x): %02x\n", addr, r);
|
||||
#endif
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the mainboard 'device' of the machine. */
|
||||
static void *
|
||||
europc_boot(const device_t *info)
|
||||
{
|
||||
europc_t *sys = &europc;
|
||||
uint8_t b;
|
||||
|
||||
#if EUROPC_DEBUG
|
||||
europc_log("EuroPC: booting mainboard..\n");
|
||||
#endif
|
||||
|
||||
europc_log("EuroPC: NVR=[ %02x %02x %02x %02x %02x ] %sVALID\n",
|
||||
sys->nvr.regs[MRTC_CONF_A], sys->nvr.regs[MRTC_CONF_B],
|
||||
sys->nvr.regs[MRTC_CONF_C], sys->nvr.regs[MRTC_CONF_D],
|
||||
sys->nvr.regs[MRTC_CONF_E],
|
||||
(sys->nvr.regs[MRTC_CHECK_LO]!=rtc_checksum(sys->nvr.regs))?"IN":"");
|
||||
|
||||
/*
|
||||
* Now that we have initialized the NVR (either from file,
|
||||
* or by setting it to defaults) we can start overriding it
|
||||
* with values set by the user.
|
||||
*/
|
||||
b = (sys->nvr.regs[MRTC_CONF_D] & ~0x17);
|
||||
switch(gfxcard) {
|
||||
case GFX_CGA: /* Color, CGA */
|
||||
case GFX_COLORPLUS: /* Color, Hercules ColorPlus */
|
||||
b |= 0x12; /* external video, CGA80 */
|
||||
break;
|
||||
|
||||
case GFX_MDA: /* Monochrome, MDA */
|
||||
case GFX_HERCULES: /* Monochrome, Hercules */
|
||||
case GFX_INCOLOR: /* Color, ? */
|
||||
b |= 0x03; /* external video, mono */
|
||||
break;
|
||||
|
||||
default: /* EGA, VGA etc */
|
||||
b |= 0x10; /* external video, special */
|
||||
|
||||
}
|
||||
sys->nvr.regs[MRTC_CONF_D] = b;
|
||||
|
||||
/* Update the memory size. */
|
||||
b = (sys->nvr.regs[MRTC_CONF_C] & 0xf3);
|
||||
switch(mem_size) {
|
||||
case 256:
|
||||
b |= 0x04;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
b |= 0x08;
|
||||
break;
|
||||
|
||||
case 640:
|
||||
b |= 0x00;
|
||||
break;
|
||||
}
|
||||
sys->nvr.regs[MRTC_CONF_C] = b;
|
||||
|
||||
/* Update CPU speed. */
|
||||
b = (sys->nvr.regs[MRTC_CONF_D] & 0x3f);
|
||||
switch(cpu) {
|
||||
case 0: /* 8088, 4.77 MHz */
|
||||
b |= 0x00;
|
||||
break;
|
||||
|
||||
case 1: /* 8088, 7.15 MHz */
|
||||
b |= 0x40;
|
||||
break;
|
||||
|
||||
case 2: /* 8088, 9.56 MHz */
|
||||
b |= 0x80;
|
||||
break;
|
||||
}
|
||||
sys->nvr.regs[MRTC_CONF_D] = b;
|
||||
|
||||
/* Set up game port. */
|
||||
b = (sys->nvr.regs[MRTC_CONF_C] & 0xfc);
|
||||
if (mouse_type == MOUSE_TYPE_LOGIBUS) {
|
||||
b |= 0x01; /* enable port as MOUSE */
|
||||
} else if (joystick_type != 7) {
|
||||
b |= 0x02; /* enable port as joysticks */
|
||||
device_add(&gameport_device);
|
||||
}
|
||||
sys->nvr.regs[MRTC_CONF_C] = b;
|
||||
|
||||
#if 0
|
||||
/* Set up floppy types. */
|
||||
sys->nvr.regs[MRTC_CONF_B] = 0x2a;
|
||||
#endif
|
||||
|
||||
/* Validate the NVR checksum and save. */
|
||||
sys->nvr.regs[MRTC_CHECK_LO] = rtc_checksum(sys->nvr.regs);
|
||||
nvr_dosave++;
|
||||
|
||||
/*
|
||||
* Allocate the system's I/O handlers.
|
||||
*
|
||||
* The first one is for the JIM. Note that although JIM usually
|
||||
* resides at 0x0250, a special solder jumper on the mainboard
|
||||
* (JS9) can be used to "move" it to 0x0350, to get it out of
|
||||
* the way of other cards that need this range.
|
||||
*/
|
||||
io_sethandler(sys->jim, 16,
|
||||
jim_read,NULL,NULL, jim_write,NULL,NULL, sys);
|
||||
|
||||
/* Only after JIM has been initialized. */
|
||||
(void)device_add(&keyboard_xt_device);
|
||||
|
||||
/* Enable and set up the FDC. */
|
||||
(void)device_add(&fdc_xt_device);
|
||||
|
||||
/*
|
||||
* Set up and enable the HD20 disk controller.
|
||||
*
|
||||
* We only do this if we have not configured another one.
|
||||
*/
|
||||
if (hdc_current == 1)
|
||||
(void)device_add(&xta_hd20_device);
|
||||
|
||||
return(sys);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
europc_close(void *priv)
|
||||
{
|
||||
nvr_t *nvr = &europc.nvr;
|
||||
|
||||
if (nvr->fn != NULL)
|
||||
free(nvr->fn);
|
||||
}
|
||||
|
||||
|
||||
static const device_config_t europc_config[] = {
|
||||
{
|
||||
"js9", "JS9 Jumper (JIM)", CONFIG_INT, "", 0,
|
||||
{
|
||||
{
|
||||
"Disabled (250h)", 0
|
||||
},
|
||||
{
|
||||
"Enabled (350h)", 1
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const device_t europc_device = {
|
||||
"EuroPC System Board",
|
||||
0, 0,
|
||||
europc_boot, europc_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
europc_config
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This function sets up the Scheider EuroPC machine.
|
||||
*
|
||||
* Its task is to allocate a clean machine data block,
|
||||
* and then simply enable the mainboard "device" which
|
||||
* allows it to reset (dev init) and configured by the
|
||||
* user.
|
||||
*/
|
||||
void
|
||||
machine_europc_init(const machine_t *model)
|
||||
{
|
||||
machine_common_init(model);
|
||||
nmi_init();
|
||||
|
||||
/* Clear the machine state. */
|
||||
memset(&europc, 0x00, sizeof(europc_t));
|
||||
europc.jim = 0x0250;
|
||||
|
||||
mem_add_bios();
|
||||
|
||||
/* This is machine specific. */
|
||||
europc.nvr.size = model->nvrmask + 1;
|
||||
europc.nvr.irq = -1;
|
||||
|
||||
/* Set up any local handlers here. */
|
||||
europc.nvr.reset = rtc_reset;
|
||||
europc.nvr.start = rtc_start;
|
||||
europc.nvr.tick = europc_rtc_tick;
|
||||
|
||||
/* Initialize the actual NVR. */
|
||||
nvr_init(&europc.nvr);
|
||||
|
||||
/* Enable and set up the mainboard device. */
|
||||
device_add(&europc_device);
|
||||
}
|
||||
572
src/machine/m_ps1 - Cópia.c
Normal file
572
src/machine/m_ps1 - Cópia.c
Normal file
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the IBM PS/1 models 2011, 2121 and 2133.
|
||||
*
|
||||
* Model 2011: The initial model, using a 10MHz 80286.
|
||||
*
|
||||
* Model 2121: This is similar to model 2011 but some of the functionality
|
||||
* has moved to a chip at ports 0xe0 (index)/0xe1 (data). The
|
||||
* only functions I have identified are enables for the first
|
||||
* 512K and next 128K of RAM, in bits 0 of registers 0 and 1
|
||||
* respectively.
|
||||
*
|
||||
* Port 0x105 has bit 7 forced high. Without this 128K of
|
||||
* memory will be missed by the BIOS on cold boots.
|
||||
*
|
||||
* The reserved 384K is remapped to the top of extended memory.
|
||||
* If this is not done then you get an error on startup.
|
||||
*
|
||||
* NOTES: Floppy does not seem to work. --FvK
|
||||
* The "ROM DOS" shell does not seem to work. We do have the
|
||||
* correct BIOS images now, and they do load, but they do not
|
||||
* boot. Sometimes, they do, and then it shows an "Incorrect
|
||||
* DOS" error message?? --FvK
|
||||
*
|
||||
* Version: @(#)m_ps1.c 1.0.11 2018/09/15
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../io.h"
|
||||
#include "../dma.h"
|
||||
#include "../pic.h"
|
||||
#include "../pit.h"
|
||||
#include "../mem.h"
|
||||
#include "../nmi.h"
|
||||
#include "../rom.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../game/gameport.h"
|
||||
#include "../lpt.h"
|
||||
#include "../serial.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/hdc_ide.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../sound/sound.h"
|
||||
#include "../sound/snd_sn76489.h"
|
||||
#include "../video/video.h"
|
||||
#include "../video/vid_vga.h"
|
||||
#include "../video/vid_ti_cf62011.h"
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
sn76489_t sn76489;
|
||||
uint8_t status, ctrl;
|
||||
int64_t timer_latch, timer_count, timer_enable;
|
||||
uint8_t fifo[2048];
|
||||
int fifo_read_idx, fifo_write_idx;
|
||||
int fifo_threshold;
|
||||
uint8_t dac_val;
|
||||
int16_t buffer[SOUNDBUFLEN];
|
||||
int pos;
|
||||
} ps1snd_t;
|
||||
|
||||
typedef struct {
|
||||
int model;
|
||||
|
||||
rom_t high_rom;
|
||||
|
||||
uint8_t ps1_91,
|
||||
ps1_92,
|
||||
ps1_94,
|
||||
ps1_102,
|
||||
ps1_103,
|
||||
ps1_104,
|
||||
ps1_105,
|
||||
ps1_190;
|
||||
int ps1_e0_addr;
|
||||
uint8_t ps1_e0_regs[256];
|
||||
} ps1_t;
|
||||
|
||||
|
||||
static void
|
||||
update_irq_status(ps1snd_t *snd)
|
||||
{
|
||||
if (((snd->status & snd->ctrl) & 0x12) && (snd->ctrl & 0x01))
|
||||
picint(1 << 7);
|
||||
else
|
||||
picintc(1 << 7);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
snd_read(uint16_t port, void *priv)
|
||||
{
|
||||
ps1snd_t *snd = (ps1snd_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port & 7) {
|
||||
case 0: /* ADC data */
|
||||
snd->status &= ~0x10;
|
||||
update_irq_status(snd);
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 2: /* status */
|
||||
ret = snd->status;
|
||||
ret |= (snd->ctrl & 0x01);
|
||||
if ((snd->fifo_write_idx - snd->fifo_read_idx) >= 2048)
|
||||
ret |= 0x08; /* FIFO full */
|
||||
if (snd->fifo_read_idx == snd->fifo_write_idx)
|
||||
ret |= 0x04; /* FIFO empty */
|
||||
break;
|
||||
|
||||
case 3: /* FIFO timer */
|
||||
/*
|
||||
* The PS/1 Technical Reference says this should return
|
||||
* thecurrent value, but the PS/1 BIOS and Stunt Island
|
||||
* expect it not to change.
|
||||
*/
|
||||
ret = snd->timer_latch;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
snd_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
ps1snd_t *snd = (ps1snd_t *)priv;
|
||||
|
||||
switch (port & 7) {
|
||||
case 0: /* DAC output */
|
||||
if ((snd->fifo_write_idx - snd->fifo_read_idx) < 2048) {
|
||||
snd->fifo[snd->fifo_write_idx & 2047] = val;
|
||||
snd->fifo_write_idx++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* control */
|
||||
snd->ctrl = val;
|
||||
if (! (val & 0x02))
|
||||
snd->status &= ~0x02;
|
||||
update_irq_status(snd);
|
||||
break;
|
||||
|
||||
case 3: /* timer reload value */
|
||||
snd->timer_latch = val;
|
||||
snd->timer_count = (int64_t) ((0xff-val) * TIMER_USEC);
|
||||
snd->timer_enable = (val != 0);
|
||||
break;
|
||||
|
||||
case 4: /* almost empty */
|
||||
snd->fifo_threshold = val * 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
snd_update(ps1snd_t *snd)
|
||||
{
|
||||
for (; snd->pos < sound_pos_global; snd->pos++)
|
||||
snd->buffer[snd->pos] = (int8_t)(snd->dac_val ^ 0x80) * 0x20;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
snd_callback(void *priv)
|
||||
{
|
||||
ps1snd_t *snd = (ps1snd_t *)priv;
|
||||
|
||||
snd_update(snd);
|
||||
|
||||
if (snd->fifo_read_idx != snd->fifo_write_idx) {
|
||||
snd->dac_val = snd->fifo[snd->fifo_read_idx & 2047];
|
||||
snd->fifo_read_idx++;
|
||||
}
|
||||
|
||||
if ((snd->fifo_write_idx - snd->fifo_read_idx) == snd->fifo_threshold)
|
||||
snd->status |= 0x02; /*FIFO almost empty*/
|
||||
|
||||
snd->status |= 0x10; /*ADC data ready*/
|
||||
update_irq_status(snd);
|
||||
|
||||
snd->timer_count += snd->timer_latch * TIMER_USEC;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
snd_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
ps1snd_t *snd = (ps1snd_t *)priv;
|
||||
int c;
|
||||
|
||||
snd_update(snd);
|
||||
|
||||
for (c = 0; c < len * 2; c++)
|
||||
buffer[c] += snd->buffer[c >> 1];
|
||||
|
||||
snd->pos = 0;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
snd_init(const device_t *info)
|
||||
{
|
||||
ps1snd_t *snd;
|
||||
|
||||
snd = malloc(sizeof(ps1snd_t));
|
||||
memset(snd, 0x00, sizeof(ps1snd_t));
|
||||
|
||||
sn76489_init(&snd->sn76489, 0x0205, 0x0001, SN76496, 4000000);
|
||||
|
||||
io_sethandler(0x0200, 1, snd_read,NULL,NULL, snd_write,NULL,NULL, snd);
|
||||
io_sethandler(0x0202, 6, snd_read,NULL,NULL, snd_write,NULL,NULL, snd);
|
||||
|
||||
timer_add(snd_callback, &snd->timer_count, &snd->timer_enable, snd);
|
||||
|
||||
sound_add_handler(snd_get_buffer, snd);
|
||||
|
||||
return(snd);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
snd_close(void *priv)
|
||||
{
|
||||
ps1snd_t *snd = (ps1snd_t *)priv;
|
||||
|
||||
free(snd);
|
||||
}
|
||||
|
||||
|
||||
static const device_t snd_device = {
|
||||
"PS/1 Audio Card",
|
||||
0, 0,
|
||||
snd_init, snd_close, NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
recalc_memory(ps1_t *ps)
|
||||
{
|
||||
/* Enable first 512K */
|
||||
mem_set_mem_state(0x00000, 0x80000,
|
||||
(ps->ps1_e0_regs[0] & 0x01) ?
|
||||
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
|
||||
(MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
|
||||
|
||||
/* Enable 512-640K */
|
||||
mem_set_mem_state(0x80000, 0x20000,
|
||||
(ps->ps1_e0_regs[1] & 0x01) ?
|
||||
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
|
||||
(MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ps1_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
ps1_t *ps = (ps1_t *)priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x0092:
|
||||
if (ps->model != 2011) {
|
||||
if (val & 1) {
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
ps->ps1_92 = val & ~1;
|
||||
} else {
|
||||
ps->ps1_92 = val;
|
||||
}
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
|
||||
case 0x0094:
|
||||
ps->ps1_94 = val;
|
||||
break;
|
||||
|
||||
case 0x00e0:
|
||||
if (ps->model != 2011) {
|
||||
ps->ps1_e0_addr = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x00e1:
|
||||
if (ps->model != 2011) {
|
||||
ps->ps1_e0_regs[ps->ps1_e0_addr] = val;
|
||||
recalc_memory(ps);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0102:
|
||||
lpt1_remove();
|
||||
if (val & 0x04)
|
||||
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
|
||||
else
|
||||
serial_remove(1);
|
||||
if (val & 0x10) {
|
||||
switch ((val >> 5) & 3) {
|
||||
case 0:
|
||||
lpt1_init(0x03bc);
|
||||
break;
|
||||
case 1:
|
||||
lpt1_init(0x0378);
|
||||
break;
|
||||
case 2:
|
||||
lpt1_init(0x0278);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ps->ps1_102 = val;
|
||||
break;
|
||||
|
||||
case 0x0103:
|
||||
ps->ps1_103 = val;
|
||||
break;
|
||||
|
||||
case 0x0104:
|
||||
ps->ps1_104 = val;
|
||||
break;
|
||||
|
||||
case 0x0105:
|
||||
ps->ps1_105 = val;
|
||||
break;
|
||||
|
||||
case 0x0190:
|
||||
ps->ps1_190 = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ps1_read(uint16_t port, void *priv)
|
||||
{
|
||||
ps1_t *ps = (ps1_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x0091:
|
||||
ret = ps->ps1_91;
|
||||
ps->ps1_91 = 0;
|
||||
break;
|
||||
|
||||
case 0x0092:
|
||||
ret = ps->ps1_92;
|
||||
break;
|
||||
|
||||
case 0x0094:
|
||||
ret = ps->ps1_94;
|
||||
break;
|
||||
|
||||
case 0x00e1:
|
||||
if (ps->model != 2011) {
|
||||
ret = ps->ps1_e0_regs[ps->ps1_e0_addr];
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0102:
|
||||
if (ps->model == 2011)
|
||||
ret = ps->ps1_102 | 0x08;
|
||||
else
|
||||
ret = ps->ps1_102;
|
||||
break;
|
||||
|
||||
case 0x0103:
|
||||
ret = ps->ps1_103;
|
||||
break;
|
||||
|
||||
case 0x0104:
|
||||
ret = ps->ps1_104;
|
||||
break;
|
||||
|
||||
case 0x0105:
|
||||
if (ps->model == 2011)
|
||||
ret = ps->ps1_105;
|
||||
else
|
||||
ret = ps->ps1_105 | 0x80;
|
||||
break;
|
||||
|
||||
case 0x0190:
|
||||
ret = ps->ps1_190;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ps1_setup(int model)
|
||||
{
|
||||
ps1_t *ps;
|
||||
void *priv;
|
||||
|
||||
ps = (ps1_t *)malloc(sizeof(ps1_t));
|
||||
memset(ps, 0x00, sizeof(ps1_t));
|
||||
ps->model = model;
|
||||
|
||||
io_sethandler(0x0091, 1,
|
||||
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
|
||||
io_sethandler(0x0092, 1,
|
||||
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
|
||||
io_sethandler(0x0094, 1,
|
||||
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
|
||||
io_sethandler(0x0102, 4,
|
||||
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
|
||||
io_sethandler(0x0190, 1,
|
||||
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
|
||||
|
||||
lpt1_remove();
|
||||
lpt1_init(0x3bc);
|
||||
|
||||
if (model == 2011) {
|
||||
rom_init(&ps->high_rom,
|
||||
L"roms/machines/ibmps1es/f80000.bin",
|
||||
0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
lpt2_remove();
|
||||
|
||||
serial_remove(1);
|
||||
serial_remove(2);
|
||||
|
||||
/* Enable the PS/1 VGA controller. */
|
||||
if (model == 2011)
|
||||
device_add(&ps1vga_device);
|
||||
else
|
||||
device_add(&ibm_ps1_2121_device);
|
||||
|
||||
device_add(&snd_device);
|
||||
|
||||
device_add(&fdc_at_actlow_device);
|
||||
|
||||
/* Enable the builtin HDC. */
|
||||
if (hdc_current == 1) {
|
||||
priv = device_add(&ps1_hdc_device);
|
||||
|
||||
ps1_hdc_inform(priv, ps);
|
||||
}
|
||||
|
||||
mem_mapping_add(&romext_mapping, 0xc8000, 0x08000,
|
||||
mem_read_romext,mem_read_romextw,mem_read_romextl,
|
||||
NULL,NULL, NULL, romext, 0, NULL);
|
||||
}
|
||||
|
||||
if (model == 2121) {
|
||||
io_sethandler(0x00e0, 2,
|
||||
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
|
||||
|
||||
#if 0
|
||||
rom_init(&ps->high_rom,
|
||||
L"roms/machines/ibmps1_2121/fc0000.bin",
|
||||
0xfc0000, 0x20000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
#endif
|
||||
|
||||
/* Initialize the video controller. */
|
||||
if (gfxcard == GFX_INTERNAL)
|
||||
device_add(&ibm_ps1_2121_device);
|
||||
|
||||
device_add(&fdc_at_ps1_device);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
device_add(&snd_device);
|
||||
}
|
||||
|
||||
if (model == 2133) {
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ps1_common_init(const machine_t *model)
|
||||
{
|
||||
machine_common_init(model);
|
||||
|
||||
mem_remap_top(384);
|
||||
|
||||
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
|
||||
|
||||
dma16_init();
|
||||
pic2_init();
|
||||
|
||||
device_add(&ps_nvr_device);
|
||||
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
/* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */
|
||||
if (joystick_type != 7)
|
||||
device_add(&gameport_201_device);
|
||||
}
|
||||
|
||||
|
||||
/* Set the Card Selected Flag */
|
||||
void
|
||||
ps1_set_feedback(void *priv)
|
||||
{
|
||||
ps1_t *ps = (ps1_t *)priv;
|
||||
|
||||
ps->ps1_91 |= 0x01;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_ps1_m2011_init(const machine_t *model)
|
||||
{
|
||||
ps1_common_init(model);
|
||||
|
||||
ps1_setup(2011);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_ps1_m2121_init(const machine_t *model)
|
||||
{
|
||||
ps1_common_init(model);
|
||||
|
||||
ps1_setup(2121);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_ps1_m2133_init(const machine_t *model)
|
||||
{
|
||||
ps1_common_init(model);
|
||||
|
||||
ps1_setup(2133);
|
||||
|
||||
nmi_mask = 0x80;
|
||||
}
|
||||
1107
src/machine/m_xt_t1000 - Cópia.c
Normal file
1107
src/machine/m_xt_t1000 - Cópia.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user