Removed hopefully all the remaining excess files.
This commit is contained in:
2263
src/config - Cópia.c
2263
src/config - Cópia.c
File diff suppressed because it is too large
Load Diff
2225
src/config.c$
2225
src/config.c$
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3324
src/cpu/808x.c%
3324
src/cpu/808x.c%
File diff suppressed because it is too large
Load Diff
@@ -1,543 +0,0 @@
|
||||
/*
|
||||
* 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 generic device interface to handle
|
||||
* all devices attached to the emulator.
|
||||
*
|
||||
* Version: @(#)device.c 1.0.10 2018/09/04
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
*
|
||||
* Free Software Foundation, Inc.
|
||||
* 59 Temple Place - Suite 330
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "86box.h"
|
||||
#include "cpu/cpu.h"
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "machine/machine.h"
|
||||
#include "sound/sound.h"
|
||||
|
||||
|
||||
#define DEVICE_MAX 256 /* max # of devices */
|
||||
|
||||
|
||||
typedef struct clonedev {
|
||||
const device_t *master;
|
||||
int count;
|
||||
struct clonedev *next;
|
||||
} clonedev_t;
|
||||
|
||||
|
||||
static device_t *devices[DEVICE_MAX];
|
||||
static void *device_priv[DEVICE_MAX];
|
||||
static device_t *device_current;
|
||||
static clonedev_t *clones = NULL;
|
||||
|
||||
|
||||
#ifdef ENABLE_DEVICE_LOG
|
||||
int device_do_log = ENABLE_DEVICE_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
device_log(const char *format, ...)
|
||||
{
|
||||
#ifdef ENABLE_DEVICE_LOG
|
||||
va_list ap;
|
||||
|
||||
if (device_do_log) {
|
||||
va_start(ap, format);
|
||||
pclog_ex(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the module for use. */
|
||||
void
|
||||
device_init(void)
|
||||
{
|
||||
clonedev_t *ptr;
|
||||
|
||||
memset(devices, 0x00, sizeof(devices));
|
||||
|
||||
ptr = NULL;
|
||||
while (clones != NULL)
|
||||
{
|
||||
ptr = clones->next;
|
||||
free(clones);
|
||||
clones = ptr;
|
||||
}
|
||||
|
||||
clones = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Clone a master device for multi-instance devices. */
|
||||
const device_t *
|
||||
device_clone(const device_t *master)
|
||||
{
|
||||
char temp[1024], *sp;
|
||||
clonedev_t *cl, *ptr;
|
||||
device_t *dev;
|
||||
|
||||
/* Look up the master. */
|
||||
for (ptr = clones; ptr != NULL; ptr = ptr->next)
|
||||
if (ptr->master == master) break;
|
||||
|
||||
/* If not found, add this master to the list. */
|
||||
if (ptr == NULL) {
|
||||
ptr = (clonedev_t *)malloc(sizeof(clonedev_t));
|
||||
memset(ptr, 0x00, sizeof(clonedev_t));
|
||||
if (clones != NULL) {
|
||||
for (cl = clones; cl->next != NULL; cl = cl->next)
|
||||
;
|
||||
cl->next = ptr;
|
||||
} else
|
||||
clones = ptr;
|
||||
ptr->master = master;
|
||||
}
|
||||
|
||||
/* Create a new device. */
|
||||
dev = (device_t *)malloc(sizeof(device_t));
|
||||
|
||||
/* Copy the master info. */
|
||||
memcpy(dev, ptr->master, sizeof(device_t));
|
||||
|
||||
/* Set up a clone. */
|
||||
if (++ptr->count > 1)
|
||||
sprintf(temp, "%s #%i", ptr->master->name, ptr->count);
|
||||
else
|
||||
strcpy(temp, ptr->master->name);
|
||||
sp = (char *)malloc(strlen(temp) + 1);
|
||||
strcpy(sp, temp);
|
||||
dev->name = (const char *)sp;
|
||||
|
||||
return((const device_t *)dev);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
device_add(const device_t *d)
|
||||
{
|
||||
void *priv = NULL;
|
||||
int c;
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
if (devices[c] == (device_t *)d) {
|
||||
device_log("DEVICE: device already exists!\n");
|
||||
return(NULL);
|
||||
}
|
||||
if (devices[c] == NULL) break;
|
||||
}
|
||||
if (c >= DEVICE_MAX)
|
||||
fatal("DEVICE: too many devices\n");
|
||||
|
||||
device_current = (device_t *)d;
|
||||
|
||||
devices[c] = (device_t *)d;
|
||||
|
||||
if (d->init != NULL) {
|
||||
priv = d->init(d);
|
||||
if (priv == NULL) {
|
||||
if (d->name)
|
||||
device_log("DEVICE: device '%s' init failed\n", d->name);
|
||||
else
|
||||
device_log("DEVICE: device init failed\n");
|
||||
|
||||
device_priv[c] = NULL;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
device_priv[c] = priv;
|
||||
|
||||
return(priv);
|
||||
}
|
||||
|
||||
|
||||
/* For devices that do not have an init function (internal video etc.) */
|
||||
void
|
||||
device_add_ex(const device_t *d, void *priv)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
if (devices[c] == (device_t *)d) {
|
||||
fatal("device_add: device already exists!\n");
|
||||
break;
|
||||
}
|
||||
if (devices[c] == NULL) break;
|
||||
}
|
||||
if (c >= DEVICE_MAX)
|
||||
fatal("device_add: too many devices\n");
|
||||
|
||||
device_current = (device_t *)d;
|
||||
|
||||
devices[c] = (device_t *)d;
|
||||
device_priv[c] = priv;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_close_all(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<DEVICE_MAX; c++) {
|
||||
if (devices[c] != NULL) {
|
||||
if (devices[c]->close != NULL)
|
||||
devices[c]->close(device_priv[c]);
|
||||
devices[c] = device_priv[c] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_reset_all(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<DEVICE_MAX; c++) {
|
||||
if (devices[c] != NULL) {
|
||||
if (devices[c]->reset != NULL)
|
||||
devices[c]->reset(device_priv[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Reset all attached PCI devices - needed for PCI turbo reset control. */
|
||||
void
|
||||
device_reset_all_pci(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<DEVICE_MAX; c++) {
|
||||
if (devices[c] != NULL) {
|
||||
if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI))
|
||||
devices[c]->reset(device_priv[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
device_get_priv(const device_t *d)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<DEVICE_MAX; c++) {
|
||||
if (devices[c] != NULL) {
|
||||
if (devices[c] == d)
|
||||
return(device_priv[c]);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_available(const device_t *d)
|
||||
{
|
||||
#ifdef RELEASE_BUILD
|
||||
if (d->flags & DEVICE_NOT_WORKING) return(0);
|
||||
#endif
|
||||
if (d->available != NULL)
|
||||
return(d->available());
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_speed_changed(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<DEVICE_MAX; c++) {
|
||||
if (devices[c] != NULL) {
|
||||
if (devices[c]->speed_changed != NULL)
|
||||
devices[c]->speed_changed(device_priv[c]);
|
||||
}
|
||||
}
|
||||
|
||||
sound_speed_changed();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_force_redraw(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c=0; c<DEVICE_MAX; c++) {
|
||||
if (devices[c] != NULL) {
|
||||
if (devices[c]->force_redraw != NULL)
|
||||
devices[c]->force_redraw(device_priv[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
device_get_config_string(char *s)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_string((char *)device_current->name, s, (char *)c->default_string));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_get_config_int(char *s)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_int((char *)device_current->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_get_config_int_ex(char *s, int default_int)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_int((char *)device_current->name, s, default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(default_int);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_get_config_hex16(char *s)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_hex16((char *)device_current->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_get_config_hex20(char *s)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_hex20((char *)device_current->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_get_config_mac(char *s, int default_int)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_mac((char *)device_current->name, s, default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(default_int);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_set_config_int(char *s, int val)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name)) {
|
||||
config_set_int((char *)device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_set_config_hex16(char *s, int val)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name)) {
|
||||
config_set_hex16((char *)device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_set_config_hex20(char *s, int val)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name)) {
|
||||
config_set_hex20((char *)device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_set_config_mac(char *s, int val)
|
||||
{
|
||||
const device_config_t *c = device_current->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name)) {
|
||||
config_set_mac((char *)device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_is_valid(const device_t *device, int mflags)
|
||||
{
|
||||
if (device == NULL) return(1);
|
||||
|
||||
if ((device->flags & DEVICE_AT) && !(mflags & MACHINE_AT)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_CBUS) && !(mflags & MACHINE_CBUS)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_ISA) && !(mflags & MACHINE_ISA)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_MCA) && !(mflags & MACHINE_MCA)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_EISA) && !(mflags & MACHINE_EISA)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_VLB) && !(mflags & MACHINE_VLB)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_PCI) && !(mflags & MACHINE_PCI)) return(0);
|
||||
|
||||
if ((device->flags & DEVICE_PS2) && !(mflags & MACHINE_HDC_PS2)) return(0);
|
||||
if ((device->flags & DEVICE_AGP) && !(mflags & MACHINE_AGP)) return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_get_config_int(char *s)
|
||||
{
|
||||
const device_t *d = machine_getdevice(machine);
|
||||
const device_config_t *c;
|
||||
|
||||
if (d == NULL) return(0);
|
||||
|
||||
c = d->config;
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_int((char *)d->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
machine_get_config_string(char *s)
|
||||
{
|
||||
const device_t *d = machine_getdevice(machine);
|
||||
const device_config_t *c;
|
||||
|
||||
if (d == NULL) return(0);
|
||||
|
||||
c = d->config;
|
||||
while (c && c->type != -1) {
|
||||
if (! strcmp(s, c->name))
|
||||
return(config_get_string((char *)d->name, s, (char *)c->default_string));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the device handler.
|
||||
*
|
||||
* Version: @(#)device.h 1.0.6 2018/09/02
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
*
|
||||
* Free Software Foundation, Inc.
|
||||
* 59 Temple Place - Suite 330
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
#ifndef EMU_DEVICE_H
|
||||
# define EMU_DEVICE_H
|
||||
|
||||
|
||||
#define CONFIG_STRING 0
|
||||
#define CONFIG_INT 1
|
||||
#define CONFIG_BINARY 2
|
||||
#define CONFIG_SELECTION 3
|
||||
#define CONFIG_MIDI 4
|
||||
#define CONFIG_FNAME 5
|
||||
#define CONFIG_SPINNER 6
|
||||
#define CONFIG_HEX16 7
|
||||
#define CONFIG_HEX20 8
|
||||
#define CONFIG_MAC 9
|
||||
|
||||
|
||||
enum {
|
||||
DEVICE_NOT_WORKING = 1, /* does not currently work correctly and will be disabled in a release build*/
|
||||
DEVICE_AT = 2, /* requires an AT-compatible system */
|
||||
DEVICE_PS2 = 4, /* requires a PS/1 or PS/2 system */
|
||||
DEVICE_ISA = 8, /* requires the ISA bus */
|
||||
DEVICE_CBUS = 0x10, /* requires the C-BUS bus */
|
||||
DEVICE_MCA = 0x20, /* requires the MCA bus */
|
||||
DEVICE_EISA = 0x40, /* requires the EISA bus */
|
||||
DEVICE_VLB = 0x80, /* requires the PCI bus */
|
||||
DEVICE_PCI = 0x100, /* requires the VLB bus */
|
||||
DEVICE_AGP = 0x200 /* requires the AGP bus */
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *description;
|
||||
int value;
|
||||
} device_config_selection_t;
|
||||
|
||||
typedef struct {
|
||||
const char *description;
|
||||
const char *extensions[5];
|
||||
} device_config_file_filter_t;
|
||||
|
||||
typedef struct {
|
||||
int min;
|
||||
int max;
|
||||
int step;
|
||||
} device_config_spinner_t;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *description;
|
||||
int type;
|
||||
const char *default_string;
|
||||
int default_int;
|
||||
device_config_selection_t selection[16];
|
||||
device_config_file_filter_t file_filter[16];
|
||||
device_config_spinner_t spinner;
|
||||
} device_config_t;
|
||||
|
||||
typedef struct _device_ {
|
||||
const char *name;
|
||||
uint32_t flags; /* system flags */
|
||||
uint32_t local; /* flags local to device */
|
||||
|
||||
void *(*init)(const struct _device_ *);
|
||||
void (*close)(void *p);
|
||||
void (*reset)(void *p);
|
||||
int (*available)(/*void*/);
|
||||
void (*speed_changed)(void *p);
|
||||
void (*force_redraw)(void *p);
|
||||
|
||||
const device_config_t *config;
|
||||
} device_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void device_init(void);
|
||||
extern const device_t * device_clone(const device_t *master);
|
||||
extern void *device_add(const device_t *d);
|
||||
extern void device_add_ex(const device_t *d, void *priv);
|
||||
extern void device_close_all(void);
|
||||
extern void device_reset_all(void);
|
||||
extern void device_reset_all_pci(void);
|
||||
extern void *device_get_priv(const device_t *d);
|
||||
extern int device_available(const device_t *d);
|
||||
extern void device_speed_changed(void);
|
||||
extern void device_force_redraw(void);
|
||||
|
||||
extern int device_get_config_int(char *name);
|
||||
extern int device_get_config_int_ex(char *s, int default_int);
|
||||
extern int device_get_config_hex16(char *name);
|
||||
extern int device_get_config_hex20(char *name);
|
||||
extern int device_get_config_mac(char *name, int default_int);
|
||||
extern void device_set_config_int(char *s, int val);
|
||||
extern void device_set_config_hex16(char *s, int val);
|
||||
extern void device_set_config_hex20(char *s, int val);
|
||||
extern void device_set_config_mac(char *s, int val);
|
||||
extern char *device_get_config_string(char *name);
|
||||
extern int device_is_valid(const device_t *device, int machine_flags);
|
||||
|
||||
extern int machine_get_config_int(char *s);
|
||||
extern char *machine_get_config_string(char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*EMU_DEVICE_H*/
|
||||
1058
src/isamem - Cópia.c
1058
src/isamem - Cópia.c
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the ISAMEM cards.
|
||||
*
|
||||
* Version: @(#)isamem.h 1.0.1 2018/08/18
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 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.
|
||||
*/
|
||||
#ifndef ISAMEM_H
|
||||
# define ISAMEM_H
|
||||
|
||||
|
||||
#define ISAMEM_MAX 4 /* max #cards in system */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Global variables. */
|
||||
extern const device_t isamem_device;
|
||||
extern const device_t isamem_brat80_device;
|
||||
extern const device_t isamem_ev159_device;
|
||||
|
||||
|
||||
/* Functions. */
|
||||
extern void isamem_reset(void);
|
||||
|
||||
extern char *isamem_get_name(int t);
|
||||
extern char *isamem_get_internal_name(int t);
|
||||
extern int isamem_get_from_internal_name(char *s);
|
||||
extern const device_t *isamem_get_device(int t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*ISAMEM_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,111 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,578 +0,0 @@
|
||||
/* 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);
|
||||
}
|
||||
@@ -1,767 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -1,572 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
1156
src/pc - Cópia.c
1156
src/pc - Cópia.c
File diff suppressed because it is too large
Load Diff
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Handling of the SCSI controllers.
|
||||
*
|
||||
* Version: @(#)scsi.c 1.0.20 2018/06/02
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi_disk.h"
|
||||
#include "scsi_device.h"
|
||||
#include "scsi_aha154x.h"
|
||||
#include "scsi_buslogic.h"
|
||||
#include "scsi_ncr5380.h"
|
||||
#include "scsi_ncr53c810.h"
|
||||
#ifdef WALTJE
|
||||
# include "scsi_wd33c93.h"
|
||||
#endif
|
||||
#include "scsi_x54x.h"
|
||||
|
||||
|
||||
scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
char scsi_fn[SCSI_NUM][512];
|
||||
uint16_t scsi_disk_location[SCSI_NUM];
|
||||
|
||||
int scsi_card_current = 0;
|
||||
int scsi_card_last = 0;
|
||||
|
||||
uint32_t SCSI_BufferLength;
|
||||
static volatile
|
||||
mutex_t *scsiMutex;
|
||||
|
||||
|
||||
typedef const struct {
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
const device_t *device;
|
||||
} SCSI_CARD;
|
||||
|
||||
|
||||
static SCSI_CARD scsi_cards[] = {
|
||||
{ "None", "none", NULL, },
|
||||
{ "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, },
|
||||
{ "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, },
|
||||
{ "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, },
|
||||
{ "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, },
|
||||
{ "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,},
|
||||
{ "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,},
|
||||
{ "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, },
|
||||
{ "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, },
|
||||
{ "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, },
|
||||
#ifdef WALTJE
|
||||
{ "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, },
|
||||
#endif
|
||||
{ "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, },
|
||||
{ "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,},
|
||||
{ "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, },
|
||||
{ "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,},
|
||||
{ "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,},
|
||||
{ "", "", NULL, },
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_SCSI_LOG
|
||||
int scsi_do_log = ENABLE_SCSI_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
scsi_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_SCSI_LOG
|
||||
va_list ap;
|
||||
|
||||
if (scsi_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int scsi_card_available(int card)
|
||||
{
|
||||
if (scsi_cards[card].device)
|
||||
return(device_available(scsi_cards[card].device));
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
char *scsi_card_getname(int card)
|
||||
{
|
||||
return((char *) scsi_cards[card].name);
|
||||
}
|
||||
|
||||
|
||||
const device_t *scsi_card_getdevice(int card)
|
||||
{
|
||||
return(scsi_cards[card].device);
|
||||
}
|
||||
|
||||
|
||||
int scsi_card_has_config(int card)
|
||||
{
|
||||
if (! scsi_cards[card].device) return(0);
|
||||
|
||||
return(scsi_cards[card].device->config ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
char *scsi_card_get_internal_name(int card)
|
||||
{
|
||||
return((char *) scsi_cards[card].internal_name);
|
||||
}
|
||||
|
||||
|
||||
int scsi_card_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (strlen((char *) scsi_cards[c].internal_name)) {
|
||||
if (!strcmp((char *) scsi_cards[c].internal_name, s))
|
||||
return(c);
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void scsi_mutex(uint8_t start)
|
||||
{
|
||||
if (start)
|
||||
scsiMutex = thread_create_mutex(L"86Box.SCSIMutex");
|
||||
else
|
||||
thread_close_mutex((mutex_t *) scsiMutex);
|
||||
}
|
||||
|
||||
|
||||
void scsi_card_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!scsi_cards[scsi_card_current].device)
|
||||
return;
|
||||
|
||||
scsi_log("Building SCSI hard disk map...\n");
|
||||
build_scsi_disk_map();
|
||||
scsi_log("Building SCSI CD-ROM map...\n");
|
||||
build_scsi_cdrom_map();
|
||||
scsi_log("Building SCSI ZIP map...\n");
|
||||
build_scsi_zip_map();
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
if (scsi_disks[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_DISK;
|
||||
else if (scsi_cdrom_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_CDROM;
|
||||
else if (scsi_zip_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[i].LunType = SCSI_NONE;
|
||||
if (SCSIDevices[i].CmdBuffer)
|
||||
free(SCSIDevices[i].CmdBuffer);
|
||||
SCSIDevices[i].CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
|
||||
scsi_card_last = scsi_card_current;
|
||||
}
|
||||
|
||||
|
||||
/* Initialization function for the SCSI layer */
|
||||
void SCSIReset(uint8_t id)
|
||||
{
|
||||
uint8_t cdrom_id = scsi_cdrom_drives[id];
|
||||
uint8_t zip_id = scsi_zip_drives[id];
|
||||
uint8_t hdc_id = scsi_disks[id];
|
||||
|
||||
if (hdc_id != 0xff)
|
||||
SCSIDevices[id].LunType = SCSI_DISK;
|
||||
else if (cdrom_id != 0xff)
|
||||
SCSIDevices[id].LunType = SCSI_CDROM;
|
||||
else if (zip_id != 0xff)
|
||||
SCSIDevices[id].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[id].LunType = SCSI_NONE;
|
||||
|
||||
scsi_device_reset(id);
|
||||
|
||||
if (SCSIDevices[id].CmdBuffer)
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_mutex_wait(uint8_t wait)
|
||||
{
|
||||
if (wait)
|
||||
thread_wait_mutex((mutex_t *) scsiMutex);
|
||||
else
|
||||
thread_release_mutex((mutex_t *) scsiMutex);
|
||||
}
|
||||
@@ -1,374 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* SCSI controller handler header.
|
||||
*
|
||||
* Version: @(#)scsi_h 1.0.18 2018/09/12
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2016-2018 TheCollector1995.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef EMU_SCSI_H
|
||||
#define EMU_SCSI_H
|
||||
|
||||
|
||||
#ifdef WALTJE
|
||||
#define SCSI_TIME (50 * (1 << TIMER_SHIFT))
|
||||
#else
|
||||
#define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT))
|
||||
#endif
|
||||
|
||||
|
||||
/* Configuration. */
|
||||
#define SCSI_ID_MAX 16 /* 16 on wide buses */
|
||||
#define SCSI_LUN_MAX 8 /* always 8 */
|
||||
|
||||
|
||||
/* SCSI commands. */
|
||||
#define GPCMD_TEST_UNIT_READY 0x00
|
||||
#define GPCMD_REZERO_UNIT 0x01
|
||||
#define GPCMD_REQUEST_SENSE 0x03
|
||||
#define GPCMD_FORMAT_UNIT 0x04
|
||||
#define GPCMD_IOMEGA_SENSE 0x06
|
||||
#define GPCMD_READ_6 0x08
|
||||
#define GPCMD_WRITE_6 0x0a
|
||||
#define GPCMD_SEEK_6 0x0b
|
||||
#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c
|
||||
#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */
|
||||
#define GPCMD_INQUIRY 0x12
|
||||
#define GPCMD_VERIFY_6 0x13
|
||||
#define GPCMD_MODE_SELECT_6 0x15
|
||||
#define GPCMD_SCSI_RESERVE 0x16
|
||||
#define GPCMD_SCSI_RELEASE 0x17
|
||||
#define GPCMD_MODE_SENSE_6 0x1a
|
||||
#define GPCMD_START_STOP_UNIT 0x1b
|
||||
#define GPCMD_SEND_DIAGNOSTIC 0x1d
|
||||
#define GPCMD_PREVENT_REMOVAL 0x1e
|
||||
#define GPCMD_READ_FORMAT_CAPACITIES 0x23
|
||||
#define GPCMD_READ_CDROM_CAPACITY 0x25
|
||||
#define GPCMD_READ_10 0x28
|
||||
#define GPCMD_WRITE_10 0x2a
|
||||
#define GPCMD_SEEK_10 0x2b
|
||||
#define GPCMD_WRITE_AND_VERIFY_10 0x2e
|
||||
#define GPCMD_VERIFY_10 0x2f
|
||||
#define GPCMD_READ_BUFFER 0x3c
|
||||
#define GPCMD_WRITE_SAME_10 0x41
|
||||
#define GPCMD_READ_SUBCHANNEL 0x42
|
||||
#define GPCMD_READ_TOC_PMA_ATIP 0x43
|
||||
#define GPCMD_READ_HEADER 0x44
|
||||
#define GPCMD_PLAY_AUDIO_10 0x45
|
||||
#define GPCMD_GET_CONFIGURATION 0x46
|
||||
#define GPCMD_PLAY_AUDIO_MSF 0x47
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48
|
||||
#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
|
||||
#define GPCMD_PAUSE_RESUME 0x4b
|
||||
#define GPCMD_STOP_PLAY_SCAN 0x4e
|
||||
#define GPCMD_READ_DISC_INFORMATION 0x51
|
||||
#define GPCMD_READ_TRACK_INFORMATION 0x52
|
||||
#define GPCMD_MODE_SELECT_10 0x55
|
||||
#define GPCMD_MODE_SENSE_10 0x5a
|
||||
#define GPCMD_PLAY_AUDIO_12 0xa5
|
||||
#define GPCMD_READ_12 0xa8
|
||||
#define GPCMD_WRITE_12 0xaa
|
||||
#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */
|
||||
#define GPCMD_WRITE_AND_VERIFY_12 0xae
|
||||
#define GPCMD_VERIFY_12 0xaf
|
||||
#define GPCMD_PLAY_CD_OLD 0xb4
|
||||
#define GPCMD_READ_CD_OLD 0xb8
|
||||
#define GPCMD_READ_CD_MSF 0xb9
|
||||
#define GPCMD_SCAN 0xba
|
||||
#define GPCMD_SET_SPEED 0xbb
|
||||
#define GPCMD_PLAY_CD 0xbc
|
||||
#define GPCMD_MECHANISM_STATUS 0xbd
|
||||
#define GPCMD_READ_CD 0xbe
|
||||
#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */
|
||||
#define GPCMD_PAUSE_RESUME_ALT 0xc2
|
||||
#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */
|
||||
#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */
|
||||
|
||||
/* Mode page codes for mode sense/set */
|
||||
#define GPMODE_R_W_ERROR_PAGE 0x01
|
||||
#define GPMODE_CDROM_PAGE 0x0d
|
||||
#define GPMODE_CDROM_AUDIO_PAGE 0x0e
|
||||
#define GPMODE_CAPABILITIES_PAGE 0x2a
|
||||
#define GPMODE_ALL_PAGES 0x3f
|
||||
|
||||
/* Mode page codes for presence */
|
||||
#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL
|
||||
#define GPMODEP_UNK_PAGE_02 0x0000000000000004LL
|
||||
#define GPMODEP_UNK_PAGE_03 0x0000000000000008LL
|
||||
#define GPMODEP_UNK_PAGE_04 0x0000000000000010LL
|
||||
#define GPMODEP_UNK_PAGE_05 0x0000000000000020LL
|
||||
#define GPMODEP_UNK_PAGE_08 0x0000000000000100LL
|
||||
#define GPMODEP_CDROM_PAGE 0x0000000000002000LL
|
||||
#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL
|
||||
#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL
|
||||
#define GPMODEP_UNK_PAGE_2F 0x0000800000000000LL
|
||||
#define GPMODEP_UNK_PAGE_30 0x0001000000000000LL
|
||||
#define GPMODEP_ALL_PAGES 0x8000000000000000LL
|
||||
|
||||
/* SCSI Status Codes */
|
||||
#define SCSI_STATUS_OK 0
|
||||
#define SCSI_STATUS_CHECK_CONDITION 2
|
||||
|
||||
/* SCSI Sense Keys */
|
||||
#define SENSE_NONE 0
|
||||
#define SENSE_NOT_READY 2
|
||||
#define SENSE_ILLEGAL_REQUEST 5
|
||||
#define SENSE_UNIT_ATTENTION 6
|
||||
|
||||
/* SCSI Additional Sense Codes */
|
||||
#define ASC_AUDIO_PLAY_OPERATION 0x00
|
||||
#define ASC_NOT_READY 0x04
|
||||
#define ASC_ILLEGAL_OPCODE 0x20
|
||||
#define ASC_LBA_OUT_OF_RANGE 0x21
|
||||
#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
|
||||
#define ASC_INV_LUN 0x25
|
||||
#define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26
|
||||
#define ASC_WRITE_PROTECTED 0x27
|
||||
#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
|
||||
#define ASC_CAPACITY_DATA_CHANGED 0x2A
|
||||
#define ASC_INCOMPATIBLE_FORMAT 0x30
|
||||
#define ASC_MEDIUM_NOT_PRESENT 0x3a
|
||||
#define ASC_DATA_PHASE_ERROR 0x4b
|
||||
#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64
|
||||
|
||||
#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01
|
||||
#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define ASCQ_CAPACITY_DATA_CHANGED 0x09
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13
|
||||
|
||||
/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw).
|
||||
Not that it means anything */
|
||||
#define CDROM_SPEED 706 /* 0x2C2 */
|
||||
|
||||
#define BUFFER_SIZE (256*1024)
|
||||
|
||||
#define RW_DELAY (TIMER_USEC * 500)
|
||||
|
||||
/* Some generally useful CD-ROM information */
|
||||
#define CD_MINS 75 /* max. minutes per CD */
|
||||
#define CD_SECS 60 /* seconds per minute */
|
||||
#define CD_FRAMES 75 /* frames per second */
|
||||
#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
|
||||
#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE)
|
||||
#define CD_MAX_SECTORS (CD_MAX_BYTES / 512)
|
||||
|
||||
/* Event notification classes for GET EVENT STATUS NOTIFICATION */
|
||||
#define GESN_NO_EVENTS 0
|
||||
#define GESN_OPERATIONAL_CHANGE 1
|
||||
#define GESN_POWER_MANAGEMENT 2
|
||||
#define GESN_EXTERNAL_REQUEST 3
|
||||
#define GESN_MEDIA 4
|
||||
#define GESN_MULTIPLE_HOSTS 5
|
||||
#define GESN_DEVICE_BUSY 6
|
||||
|
||||
/* Event codes for MEDIA event status notification */
|
||||
#define MEC_NO_CHANGE 0
|
||||
#define MEC_EJECT_REQUESTED 1
|
||||
#define MEC_NEW_MEDIA 2
|
||||
#define MEC_MEDIA_REMOVAL 3 /* only for media changers */
|
||||
#define MEC_MEDIA_CHANGED 4 /* only for media changers */
|
||||
#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */
|
||||
#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */
|
||||
#define MS_TRAY_OPEN 1
|
||||
#define MS_MEDIA_PRESENT 2
|
||||
|
||||
/*
|
||||
* The MMC values are not IDE specific and might need to be moved
|
||||
* to a common header if they are also needed for the SCSI emulation
|
||||
*/
|
||||
|
||||
/* Profile list from MMC-6 revision 1 table 91 */
|
||||
#define MMC_PROFILE_NONE 0x0000
|
||||
#define MMC_PROFILE_CD_ROM 0x0008
|
||||
#define MMC_PROFILE_CD_R 0x0009
|
||||
#define MMC_PROFILE_CD_RW 0x000A
|
||||
#define MMC_PROFILE_DVD_ROM 0x0010
|
||||
#define MMC_PROFILE_DVD_R_SR 0x0011
|
||||
#define MMC_PROFILE_DVD_RAM 0x0012
|
||||
#define MMC_PROFILE_DVD_RW_RO 0x0013
|
||||
#define MMC_PROFILE_DVD_RW_SR 0x0014
|
||||
#define MMC_PROFILE_DVD_R_DL_SR 0x0015
|
||||
#define MMC_PROFILE_DVD_R_DL_JR 0x0016
|
||||
#define MMC_PROFILE_DVD_RW_DL 0x0017
|
||||
#define MMC_PROFILE_DVD_DDR 0x0018
|
||||
#define MMC_PROFILE_DVD_PLUS_RW 0x001A
|
||||
#define MMC_PROFILE_DVD_PLUS_R 0x001B
|
||||
#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A
|
||||
#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B
|
||||
#define MMC_PROFILE_BD_ROM 0x0040
|
||||
#define MMC_PROFILE_BD_R_SRM 0x0041
|
||||
#define MMC_PROFILE_BD_R_RRM 0x0042
|
||||
#define MMC_PROFILE_BD_RE 0x0043
|
||||
#define MMC_PROFILE_HDDVD_ROM 0x0050
|
||||
#define MMC_PROFILE_HDDVD_R 0x0051
|
||||
#define MMC_PROFILE_HDDVD_RAM 0x0052
|
||||
#define MMC_PROFILE_HDDVD_RW 0x0053
|
||||
#define MMC_PROFILE_HDDVD_R_DL 0x0058
|
||||
#define MMC_PROFILE_HDDVD_RW_DL 0x005A
|
||||
#define MMC_PROFILE_INVALID 0xFFFF
|
||||
|
||||
#define SCSI_ONLY 32
|
||||
#define ATAPI_ONLY 16
|
||||
#define IMPLEMENTED 8
|
||||
#define NONDATA 4
|
||||
#define CHECK_READY 2
|
||||
#define ALLOW_UA 1
|
||||
|
||||
|
||||
extern uint8_t SCSICommandTable[0x100];
|
||||
extern uint8_t mode_sense_pages[0x40];
|
||||
extern int readcdmode;
|
||||
|
||||
/* Mode sense/select stuff. */
|
||||
extern uint8_t mode_pages_in[256][256];
|
||||
extern uint8_t page_flags[256];
|
||||
extern uint8_t prefix_len;
|
||||
extern uint8_t page_current;
|
||||
#define PAGE_CHANGEABLE 1
|
||||
#define PAGE_CHANGED 2
|
||||
|
||||
struct _scsisense_ {
|
||||
uint8_t SenseBuffer[18];
|
||||
uint8_t SenseLength;
|
||||
uint8_t UnitAttention;
|
||||
uint8_t SenseKey;
|
||||
uint8_t Asc;
|
||||
uint8_t Ascq;
|
||||
} SCSISense;
|
||||
|
||||
extern int cd_status;
|
||||
extern int prev_status;
|
||||
|
||||
enum {
|
||||
SCSI_NONE = 0,
|
||||
SCSI_DISK,
|
||||
SCSI_CDROM,
|
||||
SCSI_ZIP
|
||||
};
|
||||
|
||||
#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f)
|
||||
|
||||
#define MSG_COMMAND_COMPLETE 0x00
|
||||
|
||||
#define BUS_DBP 0x01
|
||||
#define BUS_SEL 0x02
|
||||
#define BUS_IO 0x04
|
||||
#define BUS_CD 0x08
|
||||
#define BUS_MSG 0x10
|
||||
#define BUS_REQ 0x20
|
||||
#define BUS_BSY 0x40
|
||||
#define BUS_RST 0x80
|
||||
#define BUS_ACK 0x200
|
||||
#define BUS_ATN 0x200
|
||||
#define BUS_ARB 0x8000
|
||||
#define BUS_SETDATA(val) ((uint32_t)val << 16)
|
||||
#define BUS_GETDATA(val) ((val >> 16) & 0xff)
|
||||
#define BUS_DATAMASK 0xff0000
|
||||
|
||||
#define BUS_IDLE (1 << 31)
|
||||
|
||||
#define SCSI_PHASE_DATA_OUT 0
|
||||
#define SCSI_PHASE_DATA_IN BUS_IO
|
||||
#define SCSI_PHASE_COMMAND BUS_CD
|
||||
#define SCSI_PHASE_STATUS (BUS_CD | BUS_IO)
|
||||
#define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD)
|
||||
#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO)
|
||||
|
||||
typedef struct {
|
||||
uint8_t *CmdBuffer;
|
||||
int LunType;
|
||||
int32_t BufferLength;
|
||||
uint8_t Status;
|
||||
uint8_t Phase;
|
||||
} scsi_device_t;
|
||||
|
||||
|
||||
extern scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
|
||||
extern void SCSIReset(uint8_t id);
|
||||
|
||||
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
|
||||
extern int cdrom_LBAtoMSF_accurate(void);
|
||||
|
||||
extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save);
|
||||
extern int mode_select_terminate(int force);
|
||||
extern int mode_select_write(uint8_t val);
|
||||
|
||||
extern int scsi_card_current;
|
||||
|
||||
extern int scsi_card_available(int card);
|
||||
extern char *scsi_card_getname(int card);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *scsi_card_getdevice(int card);
|
||||
#endif
|
||||
extern int scsi_card_has_config(int card);
|
||||
extern char *scsi_card_get_internal_name(int card);
|
||||
extern int scsi_card_get_from_internal_name(char *s);
|
||||
extern void scsi_mutex(uint8_t start);
|
||||
extern void scsi_card_init(void);
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t hi;
|
||||
uint8_t mid;
|
||||
uint8_t lo;
|
||||
} addr24;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF))
|
||||
#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Scatter/Gather Segment List Definitions
|
||||
*
|
||||
* Adapter limits
|
||||
*/
|
||||
#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint32_t Segment;
|
||||
uint32_t SegmentPointer;
|
||||
} SGE32;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
addr24 Segment;
|
||||
addr24 SegmentPointer;
|
||||
} SGE;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t pages[0x40][0x40];
|
||||
} mode_sense_pages_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#define MODE_SELECT_PHASE_IDLE 0
|
||||
#define MODE_SELECT_PHASE_HEADER 1
|
||||
#define MODE_SELECT_PHASE_BLOCK_DESC 2
|
||||
#define MODE_SELECT_PHASE_PAGE_HEADER 3
|
||||
#define MODE_SELECT_PHASE_PAGE 4
|
||||
|
||||
#endif /*EMU_SCSI_H*/
|
||||
|
||||
extern void scsi_mutex_wait(uint8_t wait);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +0,0 @@
|
||||
#ifndef SCSI_AHA154X_H
|
||||
# define SCSI_AHA154X_H
|
||||
|
||||
|
||||
extern const device_t aha1540b_device;
|
||||
extern const device_t aha1542c_device;
|
||||
extern const device_t aha1542cf_device;
|
||||
extern const device_t aha1640_device;
|
||||
|
||||
extern void aha_device_reset(void *p);
|
||||
|
||||
|
||||
#endif /*SCSI_AHA154X_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI
|
||||
* controllers.
|
||||
*
|
||||
* Version: @(#)scsi_buslogic.h 1.0.3 2018/03/18
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
|
||||
#ifndef SCSI_BUSLOGIC_H
|
||||
# define SCSI_BUSLOGIC_H
|
||||
|
||||
|
||||
extern const device_t buslogic_device;
|
||||
extern const device_t buslogic_545s_device;
|
||||
extern const device_t buslogic_640a_device;
|
||||
extern const device_t buslogic_445s_device;
|
||||
extern const device_t buslogic_pci_device;
|
||||
|
||||
extern void BuslogicDeviceReset(void *p);
|
||||
|
||||
|
||||
#endif /*SCSI_BUSLOGIC_H*/
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.c 1.0.17 2018/06/02
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
uint8_t scsi_null_device_sense[18] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0,0,0,0,0 };
|
||||
|
||||
|
||||
static uint8_t
|
||||
scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_command(scsi_disk[id], cdb);
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
cdrom_command(cdrom[id], cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
case SCSI_ZIP:
|
||||
zip_command(zip[id], cdb);
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_callback(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
cdrom_phase_callback(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
zip_phase_callback(zip[id]);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
case SCSI_ZIP:
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int64_t scsi_device_get_callback(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->callback;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->callback;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->callback;
|
||||
break;
|
||||
default:
|
||||
return -1LL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t *scsi_device_sense(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->sense;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->sense;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->sense;
|
||||
break;
|
||||
default:
|
||||
return scsi_null_device_sense;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_request_sense_for_scsi(zip[id], buffer, alloc_length);
|
||||
break;
|
||||
default:
|
||||
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_reset(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_reset(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_reset(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_reset(zip[id]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t *type, uint8_t *rmb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
*type = *rmb = 0x00;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
*type = 0x05;
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
*type = 0x00;
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
default:
|
||||
*type = *rmb = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len);
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom_read_capacity(cdrom[id], cdb, buffer, len);
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip_read_capacity(zip[id], cdb, buffer, len);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_present(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_NONE:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_valid(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return (id == 0xFF) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_cdb_length(uint8_t scsi_id)
|
||||
{
|
||||
/* Right now, it's 12 for all devices. */
|
||||
return 12;
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb)
|
||||
{
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_STATUS;
|
||||
SCSIDevices[scsi_id].Status = SCSI_STATUS_CHECK_CONDITION;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_COMMAND;
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_command(lun_type, id, cdb);
|
||||
|
||||
if (SCSIDevices[scsi_id].Phase == SCSI_PHASE_STATUS) {
|
||||
/* Command completed (either OK or error) - call the phase callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
}
|
||||
/* If the phase is DATA IN or DATA OUT, finish this here. */
|
||||
}
|
||||
|
||||
void scsi_device_command_phase1(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call the second phase. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||
/* Command second phase complete - call the callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
}
|
||||
|
||||
int32_t *scsi_device_get_buf_len(uint8_t scsi_id)
|
||||
{
|
||||
return &SCSIDevices[scsi_id].BufferLength;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.h 1.0.8 2018/06/12
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
#ifndef SCSI_DEVICE_H
|
||||
# define SCSI_DEVICE_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int state;
|
||||
int new_state;
|
||||
int clear_req;
|
||||
uint32_t bus_in, bus_out;
|
||||
int dev_id;
|
||||
|
||||
int command_pos;
|
||||
uint8_t command[20];
|
||||
int data_pos;
|
||||
|
||||
int change_state_delay;
|
||||
int new_req_delay;
|
||||
} scsi_bus_t;
|
||||
|
||||
extern uint8_t *scsi_device_sense(uint8_t id);
|
||||
extern void scsi_device_type_data(uint8_t id, uint8_t *type, uint8_t *rmb);
|
||||
extern int64_t scsi_device_get_callback(uint8_t scsi_id);
|
||||
extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer,
|
||||
uint8_t alloc_length);
|
||||
extern void scsi_device_reset(uint8_t scsi_id);
|
||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t *cdb,
|
||||
uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_device_present(uint8_t id);
|
||||
extern int scsi_device_valid(uint8_t id);
|
||||
extern int scsi_device_cdb_length(uint8_t id);
|
||||
extern void scsi_device_command(uint8_t id, int cdb_len, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(uint8_t scsi_id);
|
||||
extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id);
|
||||
|
||||
extern int scsi_bus_update(scsi_bus_t *bus, int bus_assert);
|
||||
extern int scsi_bus_read(scsi_bus_t *bus);
|
||||
extern int scsi_bus_match(scsi_bus_t *bus, int bus_assert);
|
||||
|
||||
#endif /*SCSI_DEVICE_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.h 1.0.5 2018/06/02
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
hard_disk_t *drv;
|
||||
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint16_t request_length;
|
||||
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
|
||||
uint64_t current_page_code;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
} scsi_disk_t;
|
||||
|
||||
|
||||
extern scsi_disk_t *scsi_disk[HDD_NUM];
|
||||
extern uint8_t scsi_disks[16];
|
||||
|
||||
|
||||
extern void scsi_loadhd(int scsi_id, int id);
|
||||
extern void scsi_disk_global_init(void);
|
||||
extern void scsi_disk_hard_reset(void);
|
||||
extern void scsi_disk_close(void);
|
||||
|
||||
extern int scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_disk_err_stat_to_scsi(scsi_disk_t *dev);
|
||||
extern int scsi_disk_phase_to_scsi(scsi_disk_t *dev);
|
||||
extern int find_hdd_for_scsi_id(uint8_t scsi_id);
|
||||
extern void build_scsi_disk_map(void);
|
||||
extern void scsi_disk_reset(scsi_disk_t *dev);
|
||||
extern void scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb);
|
||||
extern void scsi_disk_callback(scsi_disk_t *dev);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the NCR 5380 series of SCSI Host Adapters
|
||||
* made by NCR. These controllers were designed for
|
||||
* the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.2 2018/03/18
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2017-2018 Sarah Walker.
|
||||
* Copyright 2017-2018 TheCollector1995.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef SCSI_NCR5380_H
|
||||
# define SCSI_NCR5380_H
|
||||
|
||||
|
||||
extern const device_t scsi_lcs6821n_device;
|
||||
extern const device_t scsi_rt1000b_device;
|
||||
extern const device_t scsi_t130b_device;
|
||||
extern const device_t scsi_scsiat_device;
|
||||
|
||||
|
||||
#endif /*SCSI_NCR5380_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the NCR 53C810 SCSI Host Adapter made by
|
||||
* NCR and later Symbios and LSI. This controller was designed
|
||||
* for the PCI bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.1 2018/03/18
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Paul Brook (QEMU),
|
||||
* Artyom Tarasenko (QEMU),
|
||||
*
|
||||
* Copyright 2006-2018 Paul Brook.
|
||||
* Copyright 2009-2018 Artyom Tarasenko.
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
*/
|
||||
#ifndef SCSI_NCR5C3810_H
|
||||
# define SCSI_NCR53C810_H
|
||||
|
||||
|
||||
extern const device_t ncr53c810_pci_device;
|
||||
|
||||
|
||||
#endif /*SCSI_NCR53C810_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,510 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header of the code common to the AHA-154x series of SCSI
|
||||
* Host Adapters made by Adaptec, Inc. and the BusLogic series
|
||||
* of SCSI Host Adapters made by Mylex.
|
||||
* These controllers were designed for various buses.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.h 1.0.7 2018/04/06
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef SCSI_X54X_H
|
||||
|
||||
#define SCSI_X54X_H
|
||||
|
||||
#define SCSI_DELAY_TM 1 /* was 50 */
|
||||
|
||||
|
||||
#define ROM_SIZE 16384 /* one ROM is 16K */
|
||||
#define NVR_SIZE 256 /* size of NVR */
|
||||
|
||||
|
||||
/* EEPROM map and bit definitions. */
|
||||
#define EE0_HOSTID 0x07 /* EE(0) [2:0] */
|
||||
#define EE0_ALTFLOP 0x80 /* EE(0) [7] FDC at 370h */
|
||||
#define EE1_IRQCH 0x07 /* EE(1) [3:0] */
|
||||
#define EE1_DMACH 0x70 /* EE(1) [7:4] */
|
||||
#define EE2_RMVOK 0x01 /* EE(2) [0] Support removable disks */
|
||||
#define EE2_HABIOS 0x02 /* EE(2) [1] HA Bios Space Reserved */
|
||||
#define EE2_INT19 0x04 /* EE(2) [2] HA Bios Controls INT19 */
|
||||
#define EE2_DYNSCAN 0x08 /* EE(2) [3] Dynamically scan bus */
|
||||
#define EE2_TWODRV 0x10 /* EE(2) [4] Allow more than 2 drives */
|
||||
#define EE2_SEEKRET 0x20 /* EE(2) [5] Immediate return on seek */
|
||||
#define EE2_EXT1G 0x80 /* EE(2) [7] Extended Translation >1GB */
|
||||
#define EE3_SPEED 0x00 /* EE(3) [7:0] DMA Speed */
|
||||
#define SPEED_33 0xFF
|
||||
#define SPEED_50 0x00
|
||||
#define SPEED_56 0x04
|
||||
#define SPEED_67 0x01
|
||||
#define SPEED_80 0x02
|
||||
#define SPEED_10 0x03
|
||||
#define EE4_FLOPTOK 0x80 /* EE(4) [7] Support Flopticals */
|
||||
#define EE6_PARITY 0x01 /* EE(6) [0] parity check enable */
|
||||
#define EE6_TERM 0x02 /* EE(6) [1] host term enable */
|
||||
#define EE6_RSTBUS 0x04 /* EE(6) [2] reset SCSI bus on boot */
|
||||
#define EEE_SYNC 0x01 /* EE(E) [0] Enable Sync Negotiation */
|
||||
#define EEE_DISCON 0x02 /* EE(E) [1] Enable Disconnection */
|
||||
#define EEE_FAST 0x04 /* EE(E) [2] Enable FAST SCSI */
|
||||
#define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */
|
||||
|
||||
|
||||
/*
|
||||
* Host Adapter I/O ports.
|
||||
*
|
||||
* READ Port x+0: STATUS
|
||||
* WRITE Port x+0: CONTROL
|
||||
*
|
||||
* READ Port x+1: DATA
|
||||
* WRITE Port x+1: COMMAND
|
||||
*
|
||||
* READ Port x+2: INTERRUPT STATUS
|
||||
* WRITE Port x+2: (undefined?)
|
||||
*
|
||||
* R/W Port x+3: (undefined)
|
||||
*/
|
||||
|
||||
/* WRITE CONTROL commands. */
|
||||
#define CTRL_HRST 0x80 /* Hard reset */
|
||||
#define CTRL_SRST 0x40 /* Soft reset */
|
||||
#define CTRL_IRST 0x20 /* interrupt reset */
|
||||
#define CTRL_SCRST 0x10 /* SCSI bus reset */
|
||||
|
||||
/* READ STATUS. */
|
||||
#define STAT_STST 0x80 /* self-test in progress */
|
||||
#define STAT_DFAIL 0x40 /* internal diagnostic failure */
|
||||
#define STAT_INIT 0x20 /* mailbox initialization required */
|
||||
#define STAT_IDLE 0x10 /* HBA is idle */
|
||||
#define STAT_CDFULL 0x08 /* Command/Data output port is full */
|
||||
#define STAT_DFULL 0x04 /* Data input port is full */
|
||||
#define STAT_INVCMD 0x01 /* Invalid command */
|
||||
|
||||
/* READ/WRITE DATA. */
|
||||
#define CMD_NOP 0x00 /* No operation */
|
||||
#define CMD_MBINIT 0x01 /* mailbox initialization */
|
||||
#define CMD_START_SCSI 0x02 /* Start SCSI command */
|
||||
#define CMD_BIOSCMD 0x03 /* Execute ROM BIOS command */
|
||||
#define CMD_INQUIRY 0x04 /* Adapter inquiry */
|
||||
#define CMD_EMBOI 0x05 /* enable Mailbox Out Interrupt */
|
||||
#define CMD_SELTIMEOUT 0x06 /* Set SEL timeout */
|
||||
#define CMD_BUSON_TIME 0x07 /* set bus-On time */
|
||||
#define CMD_BUSOFF_TIME 0x08 /* set bus-off time */
|
||||
#define CMD_DMASPEED 0x09 /* set ISA DMA speed */
|
||||
#define CMD_RETDEVS 0x0A /* return installed devices */
|
||||
#define CMD_RETCONF 0x0B /* return configuration data */
|
||||
#define CMD_TARGET 0x0C /* set HBA to target mode */
|
||||
#define CMD_RETSETUP 0x0D /* return setup data */
|
||||
#define CMD_WRITE_CH2 0x1A /* write channel 2 buffer */
|
||||
#define CMD_READ_CH2 0x1B /* read channel 2 buffer */
|
||||
#define CMD_ECHO 0x1F /* ECHO command data */
|
||||
#define CMD_OPTIONS 0x21 /* set adapter options */
|
||||
|
||||
/* READ INTERRUPT STATUS. */
|
||||
#define INTR_ANY 0x80 /* any interrupt */
|
||||
#define INTR_SRCD 0x08 /* SCSI reset detected */
|
||||
#define INTR_HACC 0x04 /* HA command complete */
|
||||
#define INTR_MBOA 0x02 /* MBO empty */
|
||||
#define INTR_MBIF 0x01 /* MBI full */
|
||||
|
||||
|
||||
/* Structure for the INQUIRE_SETUP_INFORMATION reply. */
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t uOffset :4,
|
||||
uTransferPeriod :3,
|
||||
fSynchronous :1;
|
||||
} ReplyInquireSetupInformationSynchronousValue;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t fSynchronousInitiationEnabled :1,
|
||||
fParityCheckingEnabled :1,
|
||||
uReserved1 :6;
|
||||
uint8_t uBusTransferRate;
|
||||
uint8_t uPreemptTimeOnBus;
|
||||
uint8_t uTimeOffBus;
|
||||
uint8_t cMailbox;
|
||||
addr24 MailboxAddress;
|
||||
ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8];
|
||||
uint8_t uDisconnectPermittedId0To7;
|
||||
uint8_t VendorSpecificData[28];
|
||||
} ReplyInquireSetupInformation;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Count;
|
||||
addr24 Address;
|
||||
} MailboxInit_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* Mailbox Definitions.
|
||||
*
|
||||
* Mailbox Out (MBO) command values.
|
||||
*/
|
||||
#define MBO_FREE 0x00
|
||||
#define MBO_START 0x01
|
||||
#define MBO_ABORT 0x02
|
||||
|
||||
/* Mailbox In (MBI) status values. */
|
||||
#define MBI_FREE 0x00
|
||||
#define MBI_SUCCESS 0x01
|
||||
#define MBI_ABORT 0x02
|
||||
#define MBI_NOT_FOUND 0x03
|
||||
#define MBI_ERROR 0x04
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t CmdStatus;
|
||||
addr24 CCBPointer;
|
||||
} Mailbox_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint32_t CCBPointer;
|
||||
union {
|
||||
struct {
|
||||
uint8_t Reserved[3];
|
||||
uint8_t ActionCode;
|
||||
} out;
|
||||
struct {
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t Reserved;
|
||||
uint8_t CompletionCode;
|
||||
} in;
|
||||
} u;
|
||||
} Mailbox32_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
*
|
||||
* CCB - SCSI Command Control Block
|
||||
*
|
||||
* The CCB is a superset of the CDB (Command Descriptor Block)
|
||||
* and specifies detailed information about a SCSI command.
|
||||
*
|
||||
*/
|
||||
/* Byte 0 Command Control Block Operation Code */
|
||||
#define SCSI_INITIATOR_COMMAND 0x00
|
||||
#define TARGET_MODE_COMMAND 0x01
|
||||
#define SCATTER_GATHER_COMMAND 0x02
|
||||
#define SCSI_INITIATOR_COMMAND_RES 0x03
|
||||
#define SCATTER_GATHER_COMMAND_RES 0x04
|
||||
#define BUS_RESET 0x81
|
||||
|
||||
/* Byte 1 Address and Direction Control */
|
||||
#define CCB_TARGET_ID_SHIFT 0x06 /* CCB Op Code = 00, 02 */
|
||||
#define CCB_INITIATOR_ID_SHIFT 0x06 /* CCB Op Code = 01 */
|
||||
#define CCB_DATA_XFER_IN 0x01
|
||||
#define CCB_DATA_XFER_OUT 0x02
|
||||
#define CCB_LUN_MASK 0x07 /* Logical Unit Number */
|
||||
|
||||
/* Byte 2 SCSI_Command_Length - Length of SCSI CDB
|
||||
Byte 3 Request Sense Allocation Length */
|
||||
#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */
|
||||
#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
|
||||
|
||||
/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */
|
||||
/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */
|
||||
/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */
|
||||
/* Byte 13 Command Link ID - TBD (I don't know yet) */
|
||||
/* Byte 14 Host Status - Host Adapter status */
|
||||
#define CCB_COMPLETE 0x00 /* CCB completed without error */
|
||||
#define CCB_LINKED_COMPLETE 0x0A /* Linked command completed */
|
||||
#define CCB_LINKED_COMPLETE_INT 0x0B /* Linked complete with intr */
|
||||
#define CCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
|
||||
#define CCB_DATA_OVER_UNDER_RUN 0x12
|
||||
#define CCB_UNEXPECTED_BUS_FREE 0x13 /* Trg dropped SCSI BSY */
|
||||
#define CCB_PHASE_SEQUENCE_FAIL 0x14 /* Trg bus phase sequence fail */
|
||||
#define CCB_BAD_MBO_COMMAND 0x15 /* MBO command not 0, 1 or 2 */
|
||||
#define CCB_INVALID_OP_CODE 0x16 /* CCB invalid operation code */
|
||||
#define CCB_BAD_LINKED_LUN 0x17 /* Linked CCB LUN diff from 1st */
|
||||
#define CCB_INVALID_DIRECTION 0x18 /* Invalid target direction */
|
||||
#define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */
|
||||
#define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */
|
||||
|
||||
/* Byte 15 Target Status
|
||||
|
||||
See scsi.h files for these statuses.
|
||||
Bytes 16 and 17 Reserved (must be 0)
|
||||
Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Opcode;
|
||||
uint8_t Reserved1 :3,
|
||||
ControlByte :2,
|
||||
TagQueued :1,
|
||||
QueueTag :2;
|
||||
uint8_t CdbLength;
|
||||
uint8_t RequestSenseLength;
|
||||
uint32_t DataLength;
|
||||
uint32_t DataPointer;
|
||||
uint8_t Reserved2[2];
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t Id;
|
||||
uint8_t Lun :5,
|
||||
LegacyTagEnable :1,
|
||||
LegacyQueueTag :2;
|
||||
uint8_t Cdb[12];
|
||||
uint8_t Reserved3[6];
|
||||
uint32_t SensePointer;
|
||||
} CCB32;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Opcode;
|
||||
uint8_t Lun :3,
|
||||
ControlByte :2,
|
||||
Id :3;
|
||||
uint8_t CdbLength;
|
||||
uint8_t RequestSenseLength;
|
||||
addr24 DataLength;
|
||||
addr24 DataPointer;
|
||||
addr24 LinkPointer;
|
||||
uint8_t LinkId;
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t Reserved[2];
|
||||
uint8_t Cdb[12];
|
||||
} CCB;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Opcode;
|
||||
uint8_t Pad1 :3,
|
||||
ControlByte :2,
|
||||
Pad2 :3;
|
||||
uint8_t CdbLength;
|
||||
uint8_t RequestSenseLength;
|
||||
uint8_t Pad3[9];
|
||||
uint8_t CompletionCode; /* Only used by the 1542C/CF(/CP?) BIOS mailboxes */
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t Pad4[2];
|
||||
uint8_t Cdb[12];
|
||||
} CCBC;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef union {
|
||||
CCB32 new;
|
||||
CCB old;
|
||||
CCBC common;
|
||||
} CCBU;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
CCBU CmdBlock;
|
||||
uint8_t *RequestSenseBuffer;
|
||||
uint32_t CCBPointer;
|
||||
int Is24bit;
|
||||
uint8_t TargetID,
|
||||
LUN,
|
||||
HostStatus,
|
||||
TargetStatus,
|
||||
MailboxCompletionCode;
|
||||
} Req_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct {
|
||||
int8_t type; /* type of device */
|
||||
|
||||
char vendor[16]; /* name of device vendor */
|
||||
char name[16]; /* name of device */
|
||||
|
||||
int64_t timer_period, temp_period;
|
||||
uint8_t callback_phase;
|
||||
int64_t media_period;
|
||||
double ha_bps; /* bytes per second */
|
||||
|
||||
int8_t Irq;
|
||||
uint8_t IrqEnabled;
|
||||
|
||||
int8_t DmaChannel;
|
||||
int8_t HostID;
|
||||
uint32_t Base;
|
||||
uint8_t pos_regs[8]; /* MCA */
|
||||
|
||||
wchar_t *bios_path; /* path to BIOS image file */
|
||||
uint32_t rom_addr; /* address of BIOS ROM */
|
||||
uint16_t rom_ioaddr; /* offset in BIOS of I/O addr */
|
||||
uint16_t rom_shram; /* index to shared RAM */
|
||||
uint16_t rom_shramsz; /* size of shared RAM */
|
||||
uint16_t rom_fwhigh; /* offset in BIOS of ver ID */
|
||||
rom_t bios; /* BIOS memory descriptor */
|
||||
rom_t uppersck; /* BIOS memory descriptor */
|
||||
uint8_t *rom1; /* main BIOS image */
|
||||
uint8_t *rom2; /* SCSI-Select image */
|
||||
|
||||
wchar_t *nvr_path; /* path to NVR image file */
|
||||
uint8_t *nvr; /* EEPROM buffer */
|
||||
|
||||
int64_t ResetCB;
|
||||
|
||||
volatile uint8_t /* for multi-threading, keep */
|
||||
Status, /* these volatile */
|
||||
Interrupt;
|
||||
|
||||
Req_t Req;
|
||||
uint8_t Geometry;
|
||||
uint8_t Control;
|
||||
uint8_t Command;
|
||||
uint8_t CmdBuf[128];
|
||||
uint8_t CmdParam;
|
||||
uint32_t CmdParamLeft;
|
||||
uint8_t DataBuf[65536];
|
||||
uint16_t DataReply;
|
||||
uint16_t DataReplyLeft;
|
||||
|
||||
volatile uint32_t
|
||||
MailboxInit,
|
||||
MailboxCount,
|
||||
MailboxOutAddr,
|
||||
MailboxOutPosCur,
|
||||
MailboxInAddr,
|
||||
MailboxInPosCur,
|
||||
MailboxReq;
|
||||
|
||||
volatile int
|
||||
Mbx24bit,
|
||||
MailboxOutInterrupts;
|
||||
|
||||
volatile int
|
||||
PendingInterrupt,
|
||||
Lock;
|
||||
|
||||
uint8_t shadow_ram[128];
|
||||
|
||||
volatile uint8_t
|
||||
MailboxIsBIOS,
|
||||
ToRaise;
|
||||
|
||||
uint8_t shram_mode;
|
||||
|
||||
uint8_t sync;
|
||||
uint8_t parity;
|
||||
|
||||
uint8_t dma_buffer[128];
|
||||
|
||||
volatile
|
||||
uint32_t BIOSMailboxInit,
|
||||
BIOSMailboxCount,
|
||||
BIOSMailboxOutAddr,
|
||||
BIOSMailboxOutPosCur,
|
||||
BIOSMailboxReq,
|
||||
Residue;
|
||||
|
||||
uint8_t BusOnTime,
|
||||
BusOffTime,
|
||||
ATBusSpeed;
|
||||
|
||||
char *fw_rev; /* The 4 bytes of the revision command information + 2 extra bytes for BusLogic */
|
||||
uint16_t bus; /* Basically a copy of device flags */
|
||||
uint8_t setup_info_len;
|
||||
uint8_t max_id;
|
||||
uint8_t pci_slot;
|
||||
uint8_t bit32;
|
||||
uint8_t lba_bios;
|
||||
|
||||
mem_mapping_t mmio_mapping;
|
||||
|
||||
uint8_t int_geom_writable;
|
||||
uint8_t cdrom_boot;
|
||||
|
||||
/* Pointer to a structure of vendor-specific data that only the vendor-specific code can understand */
|
||||
void *ven_data;
|
||||
|
||||
/* Pointer to a function that performs vendor-specific operation during the timer callback */
|
||||
void (*ven_callback)(void *p);
|
||||
/* Pointer to a function that executes the second parameter phase of the vendor-specific command */
|
||||
void (*ven_cmd_phase1)(void *p);
|
||||
/* Pointer to a function that gets the host adapter ID in case it has to be read from a non-standard location */
|
||||
uint8_t (*ven_get_host_id)(void *p);
|
||||
/* Pointer to a function that updates the IRQ in the vendor-specific space */
|
||||
uint8_t (*ven_get_irq)(void *p);
|
||||
/* Pointer to a function that updates the DMA channel in the vendor-specific space */
|
||||
uint8_t (*ven_get_dma)(void *p);
|
||||
/* Pointer to a function that returns whether command is fast */
|
||||
uint8_t (*ven_cmd_is_fast)(void *p);
|
||||
/* Pointer to a function that executes vendor-specific fast path commands */
|
||||
uint8_t (*ven_fast_cmds)(void *p, uint8_t cmd);
|
||||
/* Pointer to a function that gets the parameter length for vendor-specific commands */
|
||||
uint8_t (*get_ven_param_len)(void *p);
|
||||
/* Pointer to a function that executes vendor-specific commands and returns whether or not to suppress the IRQ */
|
||||
uint8_t (*ven_cmds)(void *p);
|
||||
/* Pointer to a function that fills in the vendor-specific setup data */
|
||||
void (*get_ven_data)(void *p);
|
||||
/* Pointer to a function that determines if the mode is aggressive */
|
||||
uint8_t (*is_aggressive_mode)(void *p);
|
||||
/* Pointer to a function that returns interrupt type (0 = edge, 1 = level) */
|
||||
uint8_t (*interrupt_type)(void *p);
|
||||
/* Pointer to a function that resets vendor-specific data */
|
||||
void (*ven_reset)(void *p);
|
||||
} x54x_t;
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t command;
|
||||
uint8_t lun:3,
|
||||
reserved:2,
|
||||
id:3;
|
||||
union {
|
||||
struct {
|
||||
uint16_t cyl;
|
||||
uint8_t head;
|
||||
uint8_t sec;
|
||||
} chs;
|
||||
struct {
|
||||
uint8_t lba0; /* MSB */
|
||||
uint8_t lba1;
|
||||
uint8_t lba2;
|
||||
uint8_t lba3; /* LSB */
|
||||
} lba;
|
||||
} u;
|
||||
uint8_t secount;
|
||||
addr24 dma_address;
|
||||
} BIOSCMD;
|
||||
#pragma pack(pop)
|
||||
#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \
|
||||
(p->u.lba.lba2<<8) | p->u.lba.lba3)
|
||||
|
||||
|
||||
extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset);
|
||||
extern void x54x_buf_alloc(uint8_t id, int length);
|
||||
extern void x54x_buf_free(uint8_t id);
|
||||
extern uint8_t x54x_mbo_process(x54x_t *dev);
|
||||
extern void x54x_wait_for_poll(void);
|
||||
extern void x54x_io_set(x54x_t *dev, uint32_t base, uint8_t len);
|
||||
extern void x54x_io_remove(x54x_t *dev, uint32_t base, uint8_t len);
|
||||
extern void x54x_mem_init(x54x_t *dev, uint32_t addr);
|
||||
extern void x54x_mem_enable(x54x_t *dev);
|
||||
extern void x54x_mem_set_addr(x54x_t *dev, uint32_t base);
|
||||
extern void x54x_mem_disable(x54x_t *dev);
|
||||
extern void *x54x_init(const device_t *info);
|
||||
extern void x54x_close(void *priv);
|
||||
extern void x54x_device_reset(void *priv);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,176 +0,0 @@
|
||||
|
||||
---------- STARTBLIT.FND
|
||||
|
||||
---------- VIDEO.C
|
||||
|
||||
---------- VIDEO.H
|
||||
|
||||
---------- VID_ATI18800.C
|
||||
|
||||
---------- VID_ATI18800.H
|
||||
|
||||
---------- VID_ATI28800.C
|
||||
|
||||
---------- VID_ATI28800.H
|
||||
|
||||
---------- VID_ATI68860_RAMDAC.C
|
||||
|
||||
---------- VID_ATI68860_RAMDAC.H
|
||||
|
||||
---------- VID_ATI_EEPROM.C
|
||||
|
||||
---------- VID_ATI_EEPROM.H
|
||||
|
||||
---------- VID_ATI_MACH64.C
|
||||
|
||||
---------- VID_ATI_MACH64.H
|
||||
|
||||
---------- VID_BT485_RAMDAC.C
|
||||
|
||||
---------- VID_BT485_RAMDAC.H
|
||||
|
||||
---------- VID_CGA.C
|
||||
|
||||
---------- VID_CGA.H
|
||||
|
||||
---------- VID_CGA_COMP.C
|
||||
|
||||
---------- VID_CGA_COMP.H
|
||||
|
||||
---------- VID_CL54XX.C
|
||||
|
||||
---------- VID_CL54XX.H
|
||||
|
||||
---------- VID_COLORPLUS.C
|
||||
|
||||
---------- VID_COLORPLUS.H
|
||||
|
||||
---------- VID_COMPAQ_CGA.C
|
||||
|
||||
---------- VID_COMPAQ_CGA.H
|
||||
|
||||
---------- VID_EGA.C
|
||||
|
||||
---------- VID_EGA.H
|
||||
|
||||
---------- VID_EGA_RENDER.C
|
||||
|
||||
---------- VID_EGA_RENDER.H
|
||||
|
||||
---------- VID_ET4000.C
|
||||
|
||||
---------- VID_ET4000.H
|
||||
|
||||
---------- VID_ET4000W32.C
|
||||
|
||||
---------- VID_ET4000W32.H
|
||||
|
||||
---------- VID_ET4000W32I.C
|
||||
|
||||
---------- VID_GENIUS.C
|
||||
|
||||
---------- VID_GENIUS.H
|
||||
|
||||
---------- VID_HERCULES.C
|
||||
|
||||
---------- VID_HERCULES.H
|
||||
|
||||
---------- VID_HERCULESPLUS.C
|
||||
|
||||
---------- VID_HERCULESPLUS.H
|
||||
|
||||
---------- VID_ICD2061.C
|
||||
|
||||
---------- VID_ICD2061.H
|
||||
|
||||
---------- VID_ICS2595.C
|
||||
|
||||
---------- VID_ICS2595.H
|
||||
|
||||
---------- VID_INCOLOR.C
|
||||
|
||||
---------- VID_INCOLOR.H
|
||||
|
||||
---------- VID_MDA.C
|
||||
|
||||
---------- VID_MDA.H
|
||||
|
||||
---------- VID_NVIDIA.C
|
||||
|
||||
---------- VID_NVIDIA.H
|
||||
|
||||
---------- VID_NV_RIVA128.C
|
||||
|
||||
---------- VID_NV_RIVA128.H
|
||||
|
||||
---------- VID_OAK_OTI.C
|
||||
|
||||
---------- VID_OAK_OTI.H
|
||||
|
||||
---------- VID_PARADISE.C
|
||||
|
||||
---------- VID_PARADISE.H
|
||||
|
||||
---------- VID_S3.C
|
||||
|
||||
---------- VID_S3.H
|
||||
|
||||
---------- VID_S3_VIRGE.C
|
||||
|
||||
---------- VID_S3_VIRGE.H
|
||||
|
||||
---------- VID_SC1502X_RAMDAC.C
|
||||
|
||||
---------- VID_SC1502X_RAMDAC.H
|
||||
|
||||
---------- VID_SDAC_RAMDAC.C
|
||||
|
||||
---------- VID_SDAC_RAMDAC.H
|
||||
|
||||
---------- VID_STG_RAMDAC.C
|
||||
|
||||
---------- VID_STG_RAMDAC.H
|
||||
|
||||
---------- VID_SVGA.C
|
||||
|
||||
---------- VID_SVGA.H
|
||||
|
||||
---------- VID_SVGA_RENDER.C
|
||||
|
||||
---------- VID_SVGA_RENDER.H
|
||||
|
||||
---------- VID_TABLE.C
|
||||
|
||||
---------- VID_TGUI9440.C
|
||||
|
||||
---------- VID_TGUI9440.H
|
||||
|
||||
---------- VID_TI_CF62011.C
|
||||
|
||||
---------- VID_TI_CF62011.H
|
||||
|
||||
---------- VID_TKD8001_RAMDAC.C
|
||||
|
||||
---------- VID_TKD8001_RAMDAC.H
|
||||
|
||||
---------- VID_TVGA.C
|
||||
|
||||
---------- VID_TVGA.H
|
||||
|
||||
---------- VID_VGA.C
|
||||
|
||||
---------- VID_VGA.H
|
||||
|
||||
---------- VID_VOODOO.C
|
||||
|
||||
---------- VID_VOODOO.H
|
||||
|
||||
---------- VID_VOODOO_CODEGEN_X86-64.H
|
||||
|
||||
---------- VID_VOODOO_CODEGEN_X86.H
|
||||
|
||||
---------- VID_VOODOO_DITHER.H
|
||||
|
||||
---------- VID_WY700.C
|
||||
|
||||
---------- VID_WY700.H
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* ATI 68860 RAMDAC emulation (for Mach64)
|
||||
*
|
||||
* ATI 68860/68880 Truecolor DACs:
|
||||
* REG08 (R/W):
|
||||
* bit 0-? Always 2 ??
|
||||
*
|
||||
* REG0A (R/W):
|
||||
* bit 0-? Always 1Dh ??
|
||||
*
|
||||
* REG0B (R/W): (GMR ?)
|
||||
* bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp,
|
||||
* A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
|
||||
* E3h: 32bpp (80h for VGA modes ?)
|
||||
*
|
||||
* REG0C (R/W): Device Setup Register A
|
||||
* bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
|
||||
* 2-3 Depends on Video memory (= VRAM width ?) .
|
||||
* 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb
|
||||
* 5-6 Always set ?
|
||||
* 7 If set can remove "snow" in some cases
|
||||
* (A860_Delay_L ?) ??
|
||||
*
|
||||
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_ati68860_ramdac.h"
|
||||
#include "vid_svga_render.h"
|
||||
|
||||
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0x4:
|
||||
ramdac->dac_write = val;
|
||||
ramdac->dac_pos = 0;
|
||||
break;
|
||||
case 0x5:
|
||||
switch (ramdac->dac_pos)
|
||||
{
|
||||
case 0:
|
||||
ramdac->dac_r = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
ramdac->dac_g = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
if (ramdac->dac_write > 1)
|
||||
break;
|
||||
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
|
||||
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
|
||||
ramdac->pal[ramdac->dac_write].b = val;
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
|
||||
else
|
||||
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
|
||||
ramdac->dac_pos = 0;
|
||||
ramdac->dac_write = (ramdac->dac_write + 1) & 255;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
switch (val)
|
||||
{
|
||||
case 0x82:
|
||||
ramdac->render = svga_render_4bpp_highres;
|
||||
break;
|
||||
case 0x83:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 0xa0: case 0xb0:
|
||||
ramdac->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 0xa1: case 0xb1:
|
||||
ramdac->render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 0xc0: case 0xd0:
|
||||
ramdac->render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 0xe2: case 0xf7:
|
||||
ramdac->render = svga_render_32bpp_highres;
|
||||
break;
|
||||
case 0xe3:
|
||||
ramdac->render = svga_render_ABGR8888_highres;
|
||||
break;
|
||||
case 0xf2:
|
||||
ramdac->render = svga_render_RGBA8888_highres;
|
||||
break;
|
||||
default:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xc:
|
||||
svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
ret = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
ret = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
ret = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
ret = svga_in(0x3c7, svga);
|
||||
break;
|
||||
case 4: case 8:
|
||||
ret = 2;
|
||||
break;
|
||||
case 6: case 0xa:
|
||||
ret = 0x1d;
|
||||
break;
|
||||
case 0xf:
|
||||
ret = 0xd0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = ramdac->regs[addr & 0xf];
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
|
||||
{
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
}
|
||||
|
||||
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (ramdac->ramdac_type != type)
|
||||
{
|
||||
ramdac->ramdac_type = type;
|
||||
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b);
|
||||
else
|
||||
ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* ATI 68860 RAMDAC emulation (for Mach64)
|
||||
*
|
||||
* ATI 68860/68880 Truecolor DACs:
|
||||
* REG08 (R/W):
|
||||
* bit 0-? Always 2 ??
|
||||
*
|
||||
* REG0A (R/W):
|
||||
* bit 0-? Always 1Dh ??
|
||||
*
|
||||
* REG0B (R/W): (GMR ?)
|
||||
* bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp,
|
||||
* A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
|
||||
* E3h: 32bpp (80h for VGA modes ?)
|
||||
*
|
||||
* REG0C (R/W): Device Setup Register A
|
||||
* bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
|
||||
* 2-3 Depends on Video memory (= VRAM width ?) .
|
||||
* 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb
|
||||
* 5-6 Always set ?
|
||||
* 7 If set can remove "snow" in some cases
|
||||
* (A860_Delay_L ?) ??
|
||||
*
|
||||
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_ati68860_ramdac.h"
|
||||
#include "vid_svga_render.h"
|
||||
|
||||
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0x4:
|
||||
ramdac->dac_write = val;
|
||||
ramdac->dac_pos = 0;
|
||||
break;
|
||||
case 0x5:
|
||||
switch (ramdac->dac_pos)
|
||||
{
|
||||
case 0:
|
||||
ramdac->dac_r = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
ramdac->dac_g = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
if (ramdac->dac_write > 1)
|
||||
break;
|
||||
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
|
||||
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
|
||||
ramdac->pal[ramdac->dac_write].b = val;
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
|
||||
else
|
||||
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
|
||||
ramdac->dac_pos = 0;
|
||||
ramdac->dac_write = (ramdac->dac_write + 1) & 255;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
switch (val)
|
||||
{
|
||||
case 0x82:
|
||||
ramdac->render = svga_render_4bpp_highres;
|
||||
break;
|
||||
case 0x83:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 0xa0: case 0xb0:
|
||||
ramdac->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 0xa1: case 0xb1:
|
||||
ramdac->render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 0xc0: case 0xd0:
|
||||
ramdac->render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 0xe2: case 0xf7:
|
||||
ramdac->render = svga_render_32bpp_highres;
|
||||
break;
|
||||
case 0xe3:
|
||||
ramdac->render = svga_render_ABGR8888_highres;
|
||||
break;
|
||||
case 0xf2:
|
||||
ramdac->render = svga_render_RGBA8888_highres;
|
||||
break;
|
||||
default:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xc:
|
||||
svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
ret = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
ret = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
ret = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
ret = svga_in(0x3c7, svga);
|
||||
break;
|
||||
case 4: case 8:
|
||||
ret = 2;
|
||||
break;
|
||||
case 6: case 0xa:
|
||||
ret = 0x1d;
|
||||
break;
|
||||
case 0xf:
|
||||
ret = 0xd0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = ramdac->regs[addr & 0xf];
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
|
||||
{
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
}
|
||||
|
||||
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (ramdac->ramdac_type != type)
|
||||
{
|
||||
ramdac->ramdac_type = type;
|
||||
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b);
|
||||
else
|
||||
ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* ATI 68860 RAMDAC emulation (for Mach64)
|
||||
*
|
||||
* ATI 68860/68880 Truecolor DACs:
|
||||
* REG08 (R/W):
|
||||
* bit 0-? Always 2 ??
|
||||
*
|
||||
* REG0A (R/W):
|
||||
* bit 0-? Always 1Dh ??
|
||||
*
|
||||
* REG0B (R/W): (GMR ?)
|
||||
* bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp,
|
||||
* A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
|
||||
* E3h: 32bpp (80h for VGA modes ?)
|
||||
*
|
||||
* REG0C (R/W): Device Setup Register A
|
||||
* bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
|
||||
* 2-3 Depends on Video memory (= VRAM width ?) .
|
||||
* 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb
|
||||
* 5-6 Always set ?
|
||||
* 7 If set can remove "snow" in some cases
|
||||
* (A860_Delay_L ?) ??
|
||||
*
|
||||
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_ati68860_ramdac.h"
|
||||
#include "vid_svga_render.h"
|
||||
|
||||
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0x4:
|
||||
ramdac->dac_write = val;
|
||||
ramdac->dac_pos = 0;
|
||||
break;
|
||||
case 0x5:
|
||||
switch (ramdac->dac_pos)
|
||||
{
|
||||
case 0:
|
||||
ramdac->dac_r = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
ramdac->dac_g = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
if (ramdac->dac_write > 1)
|
||||
break;
|
||||
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
|
||||
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
|
||||
ramdac->pal[ramdac->dac_write].b = val;
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
|
||||
else
|
||||
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
|
||||
ramdac->dac_pos = 0;
|
||||
ramdac->dac_write = (ramdac->dac_write + 1) & 255;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
switch (val)
|
||||
{
|
||||
case 0x82:
|
||||
ramdac->render = svga_render_4bpp_highres;
|
||||
break;
|
||||
case 0x83:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 0xa0: case 0xb0:
|
||||
ramdac->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 0xa1: case 0xb1:
|
||||
ramdac->render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 0xc0: case 0xd0:
|
||||
ramdac->render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 0xe2: case 0xf7:
|
||||
ramdac->render = svga_render_32bpp_highres;
|
||||
break;
|
||||
case 0xe3:
|
||||
ramdac->render = svga_render_ABGR8888_highres;
|
||||
break;
|
||||
case 0xf2:
|
||||
ramdac->render = svga_render_RGBA8888_highres;
|
||||
break;
|
||||
default:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xc:
|
||||
svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
ret = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
ret = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
ret = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
ret = svga_in(0x3c7, svga);
|
||||
break;
|
||||
case 4: case 8:
|
||||
ret = 2;
|
||||
break;
|
||||
case 6: case 0xa:
|
||||
ret = 0x1d;
|
||||
break;
|
||||
case 0xf:
|
||||
ret = 0xd0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = ramdac->regs[addr & 0xf];
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
|
||||
{
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
}
|
||||
|
||||
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (ramdac->ramdac_type != type)
|
||||
{
|
||||
ramdac->ramdac_type = type;
|
||||
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b);
|
||||
else
|
||||
ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
typedef struct ati68860_ramdac_t
|
||||
{
|
||||
uint8_t regs[16];
|
||||
void (*render)(struct svga_t *svga);
|
||||
|
||||
int dac_write, dac_pos;
|
||||
int dac_r, dac_g;
|
||||
PALETTE pal;
|
||||
uint32_t pallook[2];
|
||||
|
||||
int ramdac_type;
|
||||
} ati68860_ramdac_t;
|
||||
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga);
|
||||
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac);
|
||||
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type);
|
||||
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* 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 Brooktree BT485 and BT485A true colour
|
||||
* RAM DAC's.
|
||||
*
|
||||
* Version: @(#)vid_bt485_ramdac.c 1.0.11 2018/10/03
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* TheCollector1995,
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2018 TheCollector1995.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_bt485_ramdac.h"
|
||||
|
||||
|
||||
static void
|
||||
bt485_set_bpp(bt485_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
if (!(ramdac->cr2 & 0x20))
|
||||
svga->bpp = 8;
|
||||
else switch ((ramdac->cr1 >> 5) & 0x03) {
|
||||
case 0:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 1:
|
||||
if (ramdac->cr1 & 0x08)
|
||||
svga->bpp = 16;
|
||||
else
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 2:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 3:
|
||||
svga->bpp = 4;
|
||||
break;
|
||||
}
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint32_t o32;
|
||||
uint8_t *cd;
|
||||
uint8_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= (!!rs2 << 2);
|
||||
rs |= (!!rs3 << 3);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x03: /* Palette Read Index Register (RS value = 0011) */
|
||||
svga_out(addr, val, svga);
|
||||
if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64)) {
|
||||
svga->dac_read |= ((int) (ramdac->cr3 & 0x03) << 8);
|
||||
svga->dac_write |= ((int) (ramdac->cr3 & 0x03) << 8);
|
||||
}
|
||||
break;
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
ramdac->ext_write = val;
|
||||
svga->dac_pos = 0;
|
||||
svga->dac_status = 0;
|
||||
ramdac->ext_read = (val - 1) & 0xff;
|
||||
break;
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
ramdac->ext_read = val;
|
||||
svga->dac_pos = 0;
|
||||
svga->dac_status = 3;
|
||||
ramdac->ext_write = (val + 1) & 0xff;
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
svga->dac_status = 0;
|
||||
svga->fullchange = changeframecount;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_r = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_g = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
index = ramdac->ext_write & 3;
|
||||
ramdac->extpal[index].r = svga->dac_r;
|
||||
ramdac->extpal[index].g = svga->dac_g;
|
||||
ramdac->extpal[index].b = val;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b);
|
||||
else
|
||||
ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]);
|
||||
|
||||
if ((svga->crtc[0x33] & 0x40) && !index) {
|
||||
o32 = svga->overscan_color;
|
||||
svga->overscan_color = ramdac->extpallook[0];
|
||||
if (o32 != svga->overscan_color)
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
ramdac->ext_write = (ramdac->ext_write + 1);
|
||||
svga->dac_pos = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Command Register 0 (RS value = 0110) */
|
||||
ramdac->cr0 = val;
|
||||
svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT;
|
||||
break;
|
||||
case 0x08: /* Command Register 1 (RS value = 1000) */
|
||||
ramdac->cr1 = val;
|
||||
bt485_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x09: /* Command Register 2 (RS value = 1001) */
|
||||
ramdac->cr2 = val;
|
||||
svga->hwcursor.ena = !!(val & 0x03);
|
||||
pclog("Hardware cursor is now %s\n", svga->hwcursor.ena ? "ON" : "OFF");
|
||||
bt485_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x0a:
|
||||
if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) {
|
||||
switch ((svga->dac_write & 0xff)) {
|
||||
case 0x01:
|
||||
/* Command Register 3 (RS value = 1010) */
|
||||
ramdac->cr3 = val;
|
||||
svga->hwcursor.xsize = svga->hwcursor.ysize = (val & 4) ? 64 : 32;
|
||||
svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0;
|
||||
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
|
||||
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
|
||||
if (svga->hwcursor.xsize == 64)
|
||||
svga->dac_write = (svga->dac_write & 0x00ff) | ((val & 0x03) << 8);
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
if (ramdac->type != BT485A)
|
||||
break;
|
||||
else if (svga->dac_write == 2) {
|
||||
ramdac->cr4 = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
if (svga->hwcursor.xsize == 64)
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
|
||||
cd[svga->dac_write] = val;
|
||||
|
||||
svga->dac_write++;
|
||||
svga->dac_write &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff);
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val;
|
||||
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val;
|
||||
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t *cd;
|
||||
uint8_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= (!!rs2 << 2);
|
||||
rs |= (!!rs3 << 3);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
case 0x03: /* Palette Read Index Register (RS value = 0011) */
|
||||
temp = svga->dac_read & 0xff;
|
||||
break;
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
temp = ramdac->ext_write;
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
index = ramdac->ext_read & 3;
|
||||
svga->dac_status = 3;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].r;
|
||||
else
|
||||
temp = ramdac->extpal[index].r & 0x3f;
|
||||
case 1:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].g;
|
||||
else
|
||||
temp = ramdac->extpal[index].g & 0x3f;
|
||||
case 2:
|
||||
svga->dac_pos=0;
|
||||
ramdac->ext_read = ramdac->ext_read + 1;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].b;
|
||||
else
|
||||
temp = ramdac->extpal[index].b & 0x3f;
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Command Register 0 (RS value = 0110) */
|
||||
temp = ramdac->cr0;
|
||||
break;
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
temp = ramdac->ext_read;
|
||||
break;
|
||||
case 0x08: /* Command Register 1 (RS value = 1000) */
|
||||
temp = ramdac->cr1;
|
||||
break;
|
||||
case 0x09: /* Command Register 2 (RS value = 1001) */
|
||||
temp = ramdac->cr2;
|
||||
break;
|
||||
case 0x0a:
|
||||
if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) {
|
||||
switch ((svga->dac_write & 0xff)) {
|
||||
case 0x00:
|
||||
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
|
||||
break;
|
||||
case 0x01:
|
||||
temp = ramdac->cr3;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
if (ramdac->type != BT485A)
|
||||
break;
|
||||
else if (svga->dac_write == 2) {
|
||||
temp = ramdac->cr4;
|
||||
break;
|
||||
} else {
|
||||
/* TODO: Red, Green, and Blue Signature Analysis Registers */
|
||||
temp = 0xff;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
if (svga->hwcursor.xsize == 64)
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
|
||||
temp = cd[svga->dac_read];
|
||||
|
||||
svga->dac_read++;
|
||||
svga->dac_read &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff);
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
temp = ramdac->hwc_x & 0xff;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
temp = (ramdac->hwc_x >> 8) & 0xff;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
temp = ramdac->hwc_y & 0xff;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
temp = (ramdac->hwc_y >> 8) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void bt485_init(bt485_ramdac_t *ramdac, svga_t *svga, uint8_t type)
|
||||
{
|
||||
memset(ramdac, 0, sizeof(bt485_ramdac_t));
|
||||
ramdac->type = type;
|
||||
|
||||
if (ramdac->type < BT485) {
|
||||
/* The BT484 and AT&T 20C504 only have a 32x32 cursor. */
|
||||
svga->hwcursor.xsize = svga->hwcursor.ysize = 32;
|
||||
svga->hwcursor.yoff = 32;
|
||||
}
|
||||
|
||||
/* Set the RAM DAC status byte to the correct ID bits.
|
||||
|
||||
Both the BT484 and BT485 datasheets say this:
|
||||
SR7-SR6: These bits are identification values. SR7=0 and SR6=1.
|
||||
But all other sources seem to assume SR7=1 and SR6=0. */
|
||||
switch (ramdac->type) {
|
||||
case BT484:
|
||||
ramdac->status = 0x40;
|
||||
break;
|
||||
case ATT20C504:
|
||||
ramdac->status = 0x40;
|
||||
break;
|
||||
case BT485:
|
||||
ramdac->status = 0x60;
|
||||
break;
|
||||
case ATT20C505:
|
||||
ramdac->status = 0xd0;
|
||||
break;
|
||||
case BT485A:
|
||||
ramdac->status = 0x20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header of the emulation of the Brooktree BT485 and BT485A
|
||||
* true colour RAM DAC's.
|
||||
*
|
||||
* Version: @(#)vid_bt485_ramdac.h 1.0.3 2018/10/03
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* TheCollector1995,
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2018 TheCollector1995.
|
||||
*/
|
||||
typedef struct bt485_ramdac_t
|
||||
{
|
||||
PALETTE extpal;
|
||||
uint32_t extpallook[256];
|
||||
uint8_t cursor32_data[256];
|
||||
uint8_t cursor64_data[1024];
|
||||
int hwc_y, hwc_x;
|
||||
uint8_t cr0;
|
||||
uint8_t cr1;
|
||||
uint8_t cr2;
|
||||
uint8_t cr3;
|
||||
uint8_t cr4;
|
||||
uint8_t status;
|
||||
uint8_t type;
|
||||
uint8_t ext_read, ext_write;
|
||||
} bt485_ramdac_t;
|
||||
|
||||
enum {
|
||||
BT484 = 0,
|
||||
ATT20C504,
|
||||
BT485,
|
||||
ATT20C505,
|
||||
BT485A
|
||||
};
|
||||
|
||||
extern void bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga);
|
||||
extern uint8_t bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga);
|
||||
extern void bt485_init(bt485_ramdac_t *ramdac, svga_t *svga, uint8_t type);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,818 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Main video-rendering module.
|
||||
*
|
||||
* Video timing settings -
|
||||
*
|
||||
* 8-bit - 1mb/sec
|
||||
* B = 8 ISA clocks
|
||||
* W = 16 ISA clocks
|
||||
* L = 32 ISA clocks
|
||||
*
|
||||
* Slow 16-bit - 2mb/sec
|
||||
* B = 6 ISA clocks
|
||||
* W = 8 ISA clocks
|
||||
* L = 16 ISA clocks
|
||||
*
|
||||
* Fast 16-bit - 4mb/sec
|
||||
* B = 3 ISA clocks
|
||||
* W = 3 ISA clocks
|
||||
* L = 6 ISA clocks
|
||||
*
|
||||
* Slow VLB/PCI - 8mb/sec (ish)
|
||||
* B = 4 bus clocks
|
||||
* W = 8 bus clocks
|
||||
* L = 16 bus clocks
|
||||
*
|
||||
* Mid VLB/PCI -
|
||||
* B = 4 bus clocks
|
||||
* W = 5 bus clocks
|
||||
* L = 10 bus clocks
|
||||
*
|
||||
* Fast VLB/PCI -
|
||||
* B = 3 bus clocks
|
||||
* W = 3 bus clocks
|
||||
* L = 4 bus clocks
|
||||
*
|
||||
* Version: @(#)video.c 1.0.26 2018/09/19
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../config.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
|
||||
|
||||
bitmap_t *screen = NULL,
|
||||
*buffer = NULL,
|
||||
*buffer32 = NULL;
|
||||
uint8_t fontdat[2048][8]; /* IBM CGA font */
|
||||
uint8_t fontdatm[2048][16]; /* IBM MDA font */
|
||||
uint8_t fontdatw[512][32]; /* Wyse700 font */
|
||||
uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
|
||||
dbcs_font_t *fontdatksc5601 = NULL; /* Korean KSC-5601 font */
|
||||
dbcs_font_t *fontdatksc5601_user = NULL; /* Korean KSC-5601 user defined font */
|
||||
uint32_t pal_lookup[256];
|
||||
int xsize = 1,
|
||||
ysize = 1;
|
||||
int cga_palette = 0;
|
||||
uint32_t *video_6to8 = NULL,
|
||||
*video_15to32 = NULL,
|
||||
*video_16to32 = NULL;
|
||||
int egareads = 0,
|
||||
egawrites = 0,
|
||||
changeframecount = 2;
|
||||
uint8_t rotatevga[8][256];
|
||||
int frames = 0;
|
||||
int fullchange = 0;
|
||||
uint8_t edatlookup[4][4];
|
||||
int overscan_x = 0,
|
||||
overscan_y = 0;
|
||||
int video_timing_read_b = 0,
|
||||
video_timing_read_w = 0,
|
||||
video_timing_read_l = 0;
|
||||
int video_timing_write_b = 0,
|
||||
video_timing_write_w = 0,
|
||||
video_timing_write_l = 0;
|
||||
int video_res_x = 0,
|
||||
video_res_y = 0,
|
||||
video_bpp = 0;
|
||||
static int video_force_resize;
|
||||
int invert_display = 0;
|
||||
int video_grayscale = 0;
|
||||
int video_graytype = 0;
|
||||
static int vid_type;
|
||||
static const video_timings_t *vid_timings;
|
||||
|
||||
|
||||
PALETTE cgapal = {
|
||||
{0,0,0}, {0,42,0}, {42,0,0}, {42,21,0},
|
||||
{0,0,0}, {0,42,42}, {42,0,42}, {42,42,42},
|
||||
{0,0,0}, {21,63,21}, {63,21,21}, {63,63,21},
|
||||
{0,0,0}, {21,63,63}, {63,21,63}, {63,63,63},
|
||||
|
||||
{0,0,0}, {0,0,42}, {0,42,0}, {0,42,42},
|
||||
{42,0,0}, {42,0,42}, {42,21,00}, {42,42,42},
|
||||
{21,21,21}, {21,21,63}, {21,63,21}, {21,63,63},
|
||||
{63,21,21}, {63,21,63}, {63,63,21}, {63,63,63},
|
||||
|
||||
{0,0,0}, {0,21,0}, {0,0,42}, {0,42,42},
|
||||
{42,0,21}, {21,10,21}, {42,0,42}, {42,0,63},
|
||||
{21,21,21}, {21,63,21}, {42,21,42}, {21,63,63},
|
||||
{63,0,0}, {42,42,0}, {63,21,42}, {41,41,41},
|
||||
|
||||
{0,0,0}, {0,42,42}, {42,0,0}, {42,42,42},
|
||||
{0,0,0}, {0,42,42}, {42,0,0}, {42,42,42},
|
||||
{0,0,0}, {0,63,63}, {63,0,0}, {63,63,63},
|
||||
{0,0,0}, {0,63,63}, {63,0,0}, {63,63,63},
|
||||
};
|
||||
PALETTE cgapal_mono[6] = {
|
||||
{ /* 0 - green, 4-color-optimized contrast. */
|
||||
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},
|
||||
{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},
|
||||
{0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01},
|
||||
{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},
|
||||
{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17},
|
||||
},
|
||||
{ /* 1 - green, 16-color-optimized contrast. */
|
||||
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},
|
||||
{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},
|
||||
{0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08},
|
||||
{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},
|
||||
{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17},
|
||||
},
|
||||
{ /* 2 - amber, 4-color-optimized contrast. */
|
||||
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},
|
||||
{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},
|
||||
{0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00},
|
||||
{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},
|
||||
{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d},
|
||||
},
|
||||
{ /* 3 - amber, 16-color-optimized contrast. */
|
||||
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},
|
||||
{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},
|
||||
{0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00},
|
||||
{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},
|
||||
{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d},
|
||||
},
|
||||
{ /* 4 - grey, 4-color-optimized contrast. */
|
||||
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},
|
||||
{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},
|
||||
{0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b},
|
||||
{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},
|
||||
{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b},
|
||||
},
|
||||
{ /* 5 - grey, 16-color-optimized contrast. */
|
||||
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},
|
||||
{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},
|
||||
{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21},
|
||||
{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},
|
||||
{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b},
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const uint32_t shade[5][256] =
|
||||
{
|
||||
{0}, // RGB Color (unused)
|
||||
{0}, // RGB Grayscale (unused)
|
||||
{ // Amber monitor
|
||||
0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300,
|
||||
0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00,
|
||||
0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200,
|
||||
0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00,
|
||||
0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800,
|
||||
0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400,
|
||||
0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200,
|
||||
0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100,
|
||||
0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101,
|
||||
0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201,
|
||||
0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303,
|
||||
0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606,
|
||||
0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b,
|
||||
0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14,
|
||||
0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122,
|
||||
0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739
|
||||
},
|
||||
{ // Green monitor
|
||||
0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00,
|
||||
0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401,
|
||||
0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803,
|
||||
0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906,
|
||||
0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09,
|
||||
0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d,
|
||||
0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912,
|
||||
0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718,
|
||||
0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e,
|
||||
0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325,
|
||||
0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d,
|
||||
0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36,
|
||||
0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f,
|
||||
0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749,
|
||||
0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354,
|
||||
0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60
|
||||
},
|
||||
{ // White monitor
|
||||
0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12,
|
||||
0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23,
|
||||
0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33,
|
||||
0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43,
|
||||
0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52,
|
||||
0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61,
|
||||
0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70,
|
||||
0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e,
|
||||
0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c,
|
||||
0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a,
|
||||
0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8,
|
||||
0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6,
|
||||
0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3,
|
||||
0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1,
|
||||
0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf,
|
||||
0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static struct {
|
||||
int x, y, y1, y2, w, h;
|
||||
int busy;
|
||||
int buffer_in_use;
|
||||
|
||||
thread_t *blit_thread;
|
||||
event_t *wake_blit_thread;
|
||||
event_t *blit_complete;
|
||||
event_t *buffer_not_in_use;
|
||||
} blit_data;
|
||||
|
||||
|
||||
static void (*blit_func)(int x, int y, int y1, int y2, int w, int h);
|
||||
|
||||
|
||||
static
|
||||
void blit_thread(void *param)
|
||||
{
|
||||
while (1) {
|
||||
thread_wait_event(blit_data.wake_blit_thread, -1);
|
||||
thread_reset_event(blit_data.wake_blit_thread);
|
||||
|
||||
if (blit_func)
|
||||
blit_func(blit_data.x, blit_data.y,
|
||||
blit_data.y1, blit_data.y2,
|
||||
blit_data.w, blit_data.h);
|
||||
|
||||
blit_data.busy = 0;
|
||||
thread_set_event(blit_data.blit_complete);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_setblit(void(*blit)(int,int,int,int,int,int))
|
||||
{
|
||||
blit_func = blit;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_blit_complete(void)
|
||||
{
|
||||
blit_data.buffer_in_use = 0;
|
||||
|
||||
thread_set_event(blit_data.buffer_not_in_use);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_wait_for_blit(void)
|
||||
{
|
||||
while (blit_data.busy)
|
||||
thread_wait_event(blit_data.blit_complete, -1);
|
||||
thread_reset_event(blit_data.blit_complete);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_wait_for_buffer(void)
|
||||
{
|
||||
while (blit_data.buffer_in_use)
|
||||
thread_wait_event(blit_data.buffer_not_in_use, -1);
|
||||
thread_reset_event(blit_data.buffer_not_in_use);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
if (h <= 0) return;
|
||||
|
||||
video_wait_for_blit();
|
||||
|
||||
blit_data.busy = 1;
|
||||
blit_data.buffer_in_use = 1;
|
||||
blit_data.x = x;
|
||||
blit_data.y = y;
|
||||
blit_data.y1 = y1;
|
||||
blit_data.y2 = y2;
|
||||
blit_data.w = w;
|
||||
blit_data.h = h;
|
||||
|
||||
thread_set_event(blit_data.wake_blit_thread);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_blit_memtoscreen_8(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
int yy, xx;
|
||||
|
||||
if (h <= 0) return;
|
||||
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer->h)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
*(uint32_t *) &(buffer32->line[y + yy][(x + xx) << 2]) = pal_lookup[buffer->line[y + yy][x + xx]];
|
||||
}
|
||||
}
|
||||
|
||||
video_blit_memtoscreen(x, y, y1, y2, w, h);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cgapal_rebuild(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
/* We cannot do this (yet) if we have not been enabled yet. */
|
||||
if (video_6to8 == NULL) return;
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
pal_lookup[c] = makecol(video_6to8[cgapal[c].r],
|
||||
video_6to8[cgapal[c].g],
|
||||
video_6to8[cgapal[c].b]);
|
||||
}
|
||||
|
||||
if ((cga_palette > 1) && (cga_palette < 8)) {
|
||||
if (vid_cga_contrast != 0) {
|
||||
for (c=0; c<16; c++) {
|
||||
pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
}
|
||||
} else {
|
||||
for (c=0; c<16; c++) {
|
||||
pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].g],
|
||||
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cga_palette == 8)
|
||||
pal_lookup[0x16] = makecol(video_6to8[42],video_6to8[42],video_6to8[0]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_inform(int type, const video_timings_t *ptr)
|
||||
{
|
||||
vid_type = type;
|
||||
vid_timings = ptr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_get_type(void)
|
||||
{
|
||||
return vid_type;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_update_timing(void)
|
||||
{
|
||||
if (!vid_timings)
|
||||
pclog("WARNING: vid_timings is NULL\n");
|
||||
|
||||
if (vid_timings->type == VIDEO_ISA) {
|
||||
video_timing_read_b = ISA_CYCLES(vid_timings->read_b);
|
||||
video_timing_read_w = ISA_CYCLES(vid_timings->read_w);
|
||||
video_timing_read_l = ISA_CYCLES(vid_timings->read_l);
|
||||
video_timing_write_b = ISA_CYCLES(vid_timings->write_b);
|
||||
video_timing_write_w = ISA_CYCLES(vid_timings->write_w);
|
||||
video_timing_write_l = ISA_CYCLES(vid_timings->write_l);
|
||||
} else {
|
||||
video_timing_read_b = (int)(bus_timing * vid_timings->read_b);
|
||||
video_timing_read_w = (int)(bus_timing * vid_timings->read_w);
|
||||
video_timing_read_l = (int)(bus_timing * vid_timings->read_l);
|
||||
video_timing_write_b = (int)(bus_timing * vid_timings->write_b);
|
||||
video_timing_write_w = (int)(bus_timing * vid_timings->write_w);
|
||||
video_timing_write_l = (int)(bus_timing * vid_timings->write_l);
|
||||
}
|
||||
|
||||
if (cpu_16bitbus) {
|
||||
video_timing_read_l = video_timing_read_w * 2;
|
||||
video_timing_write_l = video_timing_write_w * 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
calc_6to8(int c)
|
||||
{
|
||||
int ic, i8;
|
||||
double d8;
|
||||
|
||||
ic = c;
|
||||
if (ic == 64)
|
||||
ic = 63;
|
||||
else
|
||||
ic &= 0x3f;
|
||||
d8 = (ic / 63.0) * 255.0;
|
||||
i8 = (int) d8;
|
||||
|
||||
return(i8 & 0xff);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
calc_15to32(int c)
|
||||
{
|
||||
int b, g, r;
|
||||
double db, dg, dr;
|
||||
|
||||
b = (c & 31);
|
||||
g = ((c >> 5) & 31);
|
||||
r = ((c >> 10) & 31);
|
||||
db = (((double) b) / 31.0) * 255.0;
|
||||
dg = (((double) g) / 31.0) * 255.0;
|
||||
dr = (((double) r) / 31.0) * 255.0;
|
||||
b = (int) db;
|
||||
g = ((int) dg) << 8;
|
||||
r = ((int) dr) << 16;
|
||||
|
||||
return(b | g | r);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
calc_16to32(int c)
|
||||
{
|
||||
int b, g, r;
|
||||
double db, dg, dr;
|
||||
|
||||
b = (c & 31);
|
||||
g = ((c >> 5) & 63);
|
||||
r = ((c >> 11) & 31);
|
||||
db = (((double) b) / 31.0) * 255.0;
|
||||
dg = (((double) g) / 63.0) * 255.0;
|
||||
dr = (((double) r) / 31.0) * 255.0;
|
||||
b = (int) db;
|
||||
g = ((int) dg) << 8;
|
||||
r = ((int) dr) << 16;
|
||||
|
||||
return(b | g | r);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hline(bitmap_t *b, int x1, int y, int x2, uint32_t col)
|
||||
{
|
||||
if (y < 0 || y >= buffer->h)
|
||||
return;
|
||||
|
||||
if (b == buffer)
|
||||
memset(&b->line[y][x1], col, x2 - x1);
|
||||
else
|
||||
memset(&((uint32_t *)b->line[y])[x1], col, (x2 - x1) * 4);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_palette(PALETTE p)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
destroy_bitmap(bitmap_t *b)
|
||||
{
|
||||
if (b->dat != NULL)
|
||||
free(b->dat);
|
||||
free(b);
|
||||
}
|
||||
|
||||
|
||||
bitmap_t *
|
||||
create_bitmap(int x, int y)
|
||||
{
|
||||
bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint8_t *)));
|
||||
int c;
|
||||
|
||||
b->dat = malloc(x * y * 4);
|
||||
for (c = 0; c < y; c++)
|
||||
b->line[c] = b->dat + (c * x * 4);
|
||||
b->w = x;
|
||||
b->h = y;
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_init(void)
|
||||
{
|
||||
int c, d, e;
|
||||
|
||||
/* Account for overscan. */
|
||||
buffer32 = create_bitmap(2048, 2048);
|
||||
|
||||
buffer = create_bitmap(2048, 2048);
|
||||
for (c = 0; c < 64; c++) {
|
||||
cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
if ((c & 0x17) == 6)
|
||||
cgapal[c + 64].g >>= 1;
|
||||
}
|
||||
for (c = 0; c < 64; c++) {
|
||||
cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21;
|
||||
cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21;
|
||||
}
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
e = c;
|
||||
for (d = 0; d < 8; d++) {
|
||||
rotatevga[d][c] = e;
|
||||
e = (e >> 1) | ((e & 1) ? 0x80 : 0);
|
||||
}
|
||||
}
|
||||
for (c = 0; c < 4; c++) {
|
||||
for (d = 0; d < 4; d++) {
|
||||
edatlookup[c][d] = 0;
|
||||
if (c & 1) edatlookup[c][d] |= 1;
|
||||
if (d & 1) edatlookup[c][d] |= 2;
|
||||
if (c & 2) edatlookup[c][d] |= 0x10;
|
||||
if (d & 2) edatlookup[c][d] |= 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
video_6to8 = malloc(4 * 256);
|
||||
for (c = 0; c < 256; c++)
|
||||
video_6to8[c] = calc_6to8(c);
|
||||
video_15to32 = malloc(4 * 65536);
|
||||
#if 0
|
||||
for (c = 0; c < 65536; c++)
|
||||
video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19);
|
||||
#endif
|
||||
for (c = 0; c < 65536; c++)
|
||||
video_15to32[c] = calc_15to32(c);
|
||||
|
||||
video_16to32 = malloc(4 * 65536);
|
||||
#if 0
|
||||
for (c = 0; c < 65536; c++)
|
||||
video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19);
|
||||
#endif
|
||||
for (c = 0; c < 65536; c++)
|
||||
video_16to32[c] = calc_16to32(c);
|
||||
|
||||
blit_data.wake_blit_thread = thread_create_event();
|
||||
blit_data.blit_complete = thread_create_event();
|
||||
blit_data.buffer_not_in_use = thread_create_event();
|
||||
blit_data.blit_thread = thread_create(blit_thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_close(void)
|
||||
{
|
||||
thread_kill(blit_data.blit_thread);
|
||||
thread_destroy_event(blit_data.buffer_not_in_use);
|
||||
thread_destroy_event(blit_data.blit_complete);
|
||||
thread_destroy_event(blit_data.wake_blit_thread);
|
||||
|
||||
free(video_6to8);
|
||||
free(video_15to32);
|
||||
free(video_16to32);
|
||||
|
||||
destroy_bitmap(buffer);
|
||||
destroy_bitmap(buffer32);
|
||||
|
||||
if (fontdatksc5601) {
|
||||
free(fontdatksc5601);
|
||||
fontdatksc5601 = NULL;
|
||||
}
|
||||
|
||||
if (fontdatksc5601_user) {
|
||||
free(fontdatksc5601_user);
|
||||
fontdatksc5601_user = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
video_force_resize_get(void)
|
||||
{
|
||||
return video_force_resize;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_force_resize_set(uint8_t res)
|
||||
{
|
||||
video_force_resize = res;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
loadfont(wchar_t *s, int format)
|
||||
{
|
||||
FILE *f;
|
||||
int c,d;
|
||||
|
||||
f = rom_fopen(s, L"rb");
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
switch (format) {
|
||||
case 0: /* MDA */
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<8; d++)
|
||||
fontdatm[c][d] = fgetc(f);
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<8; d++)
|
||||
fontdatm[c][d+8] = fgetc(f);
|
||||
(void)fseek(f, 4096+2048, SEEK_SET);
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<8; d++)
|
||||
fontdat[c][d] = fgetc(f);
|
||||
break;
|
||||
|
||||
case 1: /* PC200 */
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<8; d++)
|
||||
fontdatm[c][d] = fgetc(f);
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<8; d++)
|
||||
fontdatm[c][d+8] = fgetc(f);
|
||||
(void)fseek(f, 4096, SEEK_SET);
|
||||
for (c=0; c<256; c++) {
|
||||
for (d=0; d<8; d++)
|
||||
fontdat[c][d] = fgetc(f);
|
||||
for (d=0; d<8; d++) (void)fgetc(f);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case 2: /* CGA */
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<8; d++)
|
||||
fontdat[c][d] = fgetc(f);
|
||||
break;
|
||||
|
||||
case 3: /* Wyse 700 */
|
||||
for (c=0; c<512; c++)
|
||||
for (d=0; d<32; d++)
|
||||
fontdatw[c][d] = fgetc(f);
|
||||
break;
|
||||
|
||||
case 4: /* MDSI Genius */
|
||||
for (c=0; c<256; c++)
|
||||
for (d=0; d<16; d++)
|
||||
fontdat8x12[c][d] = fgetc(f);
|
||||
break;
|
||||
|
||||
case 5: /* Toshiba 3100e */
|
||||
for (d = 0; d < 2048; d += 512) /* Four languages... */
|
||||
{
|
||||
for (c = d; c < d+256; c++)
|
||||
{
|
||||
fread(&fontdatm[c][8], 1, 8, f);
|
||||
}
|
||||
for (c = d+256; c < d+512; c++)
|
||||
{
|
||||
fread(&fontdatm[c][8], 1, 8, f);
|
||||
}
|
||||
for (c = d; c < d+256; c++)
|
||||
{
|
||||
fread(&fontdatm[c][0], 1, 8, f);
|
||||
}
|
||||
for (c = d+256; c < d+512; c++)
|
||||
{
|
||||
fread(&fontdatm[c][0], 1, 8, f);
|
||||
}
|
||||
fseek(f, 4096, SEEK_CUR); /* Skip blank section */
|
||||
for (c = d; c < d+256; c++)
|
||||
{
|
||||
fread(&fontdat[c][0], 1, 8, f);
|
||||
}
|
||||
for (c = d+256; c < d+512; c++)
|
||||
{
|
||||
fread(&fontdat[c][0], 1, 8, f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: /* Korean KSC-5601 */
|
||||
if (!fontdatksc5601)
|
||||
fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t));
|
||||
|
||||
if (!fontdatksc5601_user)
|
||||
fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t));
|
||||
|
||||
for (c = 0; c < 16384; c++)
|
||||
{
|
||||
for (d = 0; d < 32; d++)
|
||||
fontdatksc5601[c].chr[d]=getc(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
video_color_transform(uint32_t color)
|
||||
{
|
||||
uint8_t *clr8 = (uint8_t *) &color;
|
||||
/* if (!video_grayscale && !invert_display)
|
||||
return color; */
|
||||
if (video_grayscale) {
|
||||
if (video_graytype) {
|
||||
if (video_graytype == 1)
|
||||
color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255;
|
||||
else
|
||||
color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3;
|
||||
} else
|
||||
color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255;
|
||||
switch (video_grayscale) {
|
||||
case 2: case 3: case 4:
|
||||
color = (uint32_t) shade[video_grayscale][color];
|
||||
break;
|
||||
default:
|
||||
clr8[3] = 0;
|
||||
clr8[0] = color;
|
||||
clr8[1] = clr8[2] = clr8[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (invert_display)
|
||||
color ^= 0x00ffffff;
|
||||
return color;
|
||||
}
|
||||
|
||||
void
|
||||
video_transform_copy(uint32_t *dst, uint32_t *src, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
*dst = video_color_transform(*src);
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the video controller module.
|
||||
*
|
||||
* Version: @(#)video.h 1.0.35 2018/09/19
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef EMU_VIDEO_H
|
||||
# define EMU_VIDEO_H
|
||||
|
||||
|
||||
#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
|
||||
#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
|
||||
|
||||
|
||||
enum {
|
||||
GFX_NONE = 0,
|
||||
GFX_INTERNAL,
|
||||
GFX_CGA,
|
||||
GFX_COMPAQ_CGA, /* Compaq CGA */
|
||||
GFX_COMPAQ_CGA_2, /* Compaq CGA 2 */
|
||||
GFX_COLORPLUS, /* Plantronics ColorPlus */
|
||||
GFX_WY700, /* Wyse 700 */
|
||||
GFX_MDA,
|
||||
GFX_GENIUS, /* MDSI Genius */
|
||||
GFX_HERCULES,
|
||||
GFX_HERCULESPLUS,
|
||||
GFX_INCOLOR, /* Hercules InColor */
|
||||
GFX_EGA, /* Using IBM EGA BIOS */
|
||||
GFX_COMPAQ_EGA, /* Compaq EGA */
|
||||
GFX_SUPER_EGA, /* Using Chips & Technologies SuperEGA BIOS */
|
||||
GFX_VGA, /* IBM VGA */
|
||||
GFX_TVGA, /* Using Trident TVGA8900D BIOS */
|
||||
GFX_ET4000_ISA, /* Tseng ET4000 */
|
||||
GFX_ET4000_MCA, /* Tseng ET4000 */
|
||||
GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/
|
||||
GFX_ET4000W32_CARDEX_VLB, /* Tseng ET4000/W32p (Cardex) VLB */
|
||||
GFX_ET4000W32_CARDEX_PCI, /* Tseng ET4000/W32p (Cardex) PCI */
|
||||
#if defined(DEV_BRANCH) && defined(USE_STEALTH32)
|
||||
GFX_ET4000W32_VLB, /* Tseng ET4000/W32p (Diamond Stealth 32) VLB */
|
||||
GFX_ET4000W32_PCI, /* Tseng ET4000/W32p (Diamond Stealth 32) PCI */
|
||||
#endif
|
||||
GFX_BAHAMAS64_VLB, /* S3 Vision864 (Paradise Bahamas 64) VLB */
|
||||
GFX_BAHAMAS64_PCI, /* S3 Vision864 (Paradise Bahamas 64) PCI */
|
||||
GFX_N9_9FX_VLB, /* S3 764/Trio64 (Number Nine 9FX) VLB */
|
||||
GFX_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */
|
||||
GFX_TGUI9400CXI, /* Trident TGUI9400CXi VLB */
|
||||
GFX_TGUI9440_VLB, /* Trident TGUI9440AGi VLB */
|
||||
GFX_TGUI9440_PCI, /* Trident TGUI9440AGi PCI */
|
||||
GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/
|
||||
GFX_VGA88, /* ATI VGA-88 (18800-1) */
|
||||
GFX_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */
|
||||
GFX_VGACHARGER, /* ATI VGA Charger (28800-5) */
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
GFX_VGAWONDER, /* Compaq ATI VGA Wonder (18800) */
|
||||
#endif
|
||||
GFX_VGAWONDERXL, /* Compaq ATI VGA Wonder XL (28800-5) */
|
||||
#if defined(DEV_BRANCH) && defined(USE_XL24)
|
||||
GFX_VGAWONDERXL24, /* Compaq ATI VGA Wonder XL24 (28800-6) */
|
||||
#endif
|
||||
GFX_MACH64GX_ISA, /* ATI Graphics Pro Turbo (Mach64) ISA */
|
||||
GFX_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */
|
||||
GFX_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */
|
||||
GFX_MACH64VT2, /* ATI Mach64 VT2 */
|
||||
GFX_CL_GD5424_ISA, /* Cirrus Logic CL-GD 5424 ISA */
|
||||
GFX_CL_GD5424_VLB, /* Cirrus Logic CL-GD 5424 VLB */
|
||||
GFX_CL_GD5426_VLB, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD 5426) VLB */
|
||||
GFX_CL_GD5428_ISA, /* Cirrus Logic CL-GD 5428 ISA */
|
||||
GFX_CL_GD5428_VLB, /* Cirrus Logic CL-GD 5428 VLB */
|
||||
GFX_CL_GD5429_ISA, /* Cirrus Logic CL-GD 5429 ISA */
|
||||
GFX_CL_GD5429_VLB, /* Cirrus Logic CL-GD 5429 VLB */
|
||||
GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) VLB */
|
||||
GFX_CL_GD5430_PCI, /* Cirrus Logic CL-GD 5430 PCI */
|
||||
GFX_CL_GD5434_ISA, /* Cirrus Logic CL-GD 5434 ISA */
|
||||
GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */
|
||||
GFX_CL_GD5434_PCI, /* Cirrus Logic CL-GD 5434 PCI */
|
||||
GFX_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */
|
||||
GFX_CL_GD5440_PCI, /* Cirrus Logic CL-GD 5440 PCI */
|
||||
GFX_CL_GD5446_PCI, /* Cirrus Logic CL-GD 5446 PCI */
|
||||
GFX_CL_GD5446_STB_PCI, /* STB Nitro 64V (Cirrus Logic CL-GD 5446) PCI */
|
||||
GFX_CL_GD5480_PCI, /* Cirrus Logic CL-GD 5480 PCI */
|
||||
GFX_EXPERTCOLOR_VLB, /* S3 Vision868 (ExpertColor DSV3868P CF55) VLB */
|
||||
GFX_EXPERTCOLOR_PCI, /* S3 Vision868 (ExpertColor DSV3868P CF55) PCI */
|
||||
GFX_OTI037C, /* Oak OTI-037C */
|
||||
GFX_OTI067, /* Oak OTI-067 */
|
||||
GFX_OTI077, /* Oak OTI-077 */
|
||||
GFX_PVGA1A, /* Paradise PVGA1A Standalone */
|
||||
GFX_WD90C11, /* Paradise WD90C11-LR Standalone */
|
||||
GFX_WD90C30, /* Paradise WD90C30-LR Standalone */
|
||||
GFX_PHOENIX_VISION864_VLB, /* S3 Vision864 (Phoenix) VLB */
|
||||
GFX_PHOENIX_VISION864_PCI, /* S3 Vision864 (Phoenix) PCI */
|
||||
GFX_PHOENIX_TRIO32_VLB, /* S3 732/Trio32 (Phoenix) VLB */
|
||||
GFX_PHOENIX_TRIO32_PCI, /* S3 732/Trio32 (Phoenix) PCI */
|
||||
GFX_PHOENIX_TRIO64_VLB, /* S3 764/Trio64 (Phoenix) VLB */
|
||||
GFX_PHOENIX_TRIO64_PCI, /* S3 764/Trio64 (Phoenix) PCI */
|
||||
GFX_STEALTH64_VLB, /* S3 Trio64 (Diamond Stealth 64) VLB */
|
||||
GFX_STEALTH64_PCI, /* S3 Trio64 (Diamond Stealth 64) PCI */
|
||||
#if defined(DEV_BRANCH) && defined(USE_TI)
|
||||
GFX_TICF62011, /* TI CF62011 */
|
||||
#endif
|
||||
GFX_VIRGE_VLB, /* S3 Virge VLB */
|
||||
GFX_VIRGE_PCI, /* S3 Virge PCI */
|
||||
GFX_VIRGEDX_VLB, /* S3 Virge/DX VLB */
|
||||
GFX_VIRGEDX_PCI, /* S3 Virge/DX PCI */
|
||||
GFX_VIRGEDX4_VLB, /* S3 Virge/DX (VBE 2.0) VLB */
|
||||
GFX_VIRGEDX4_PCI, /* S3 Virge/DX (VBE 2.0) PCI */
|
||||
GFX_VIRGEVX_VLB, /* S3 Virge/VX VLB */
|
||||
GFX_VIRGEVX_PCI, /* S3 Virge/VX PCI */
|
||||
|
||||
GFX_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
FULLSCR_SCALE_FULL = 0,
|
||||
FULLSCR_SCALE_43,
|
||||
FULLSCR_SCALE_SQ,
|
||||
FULLSCR_SCALE_INT,
|
||||
FULLSCR_SCALE_KEEPRATIO
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
VIDEO_ISA = 0,
|
||||
VIDEO_MCA,
|
||||
VIDEO_BUS
|
||||
};
|
||||
|
||||
#define VIDEO_FLAG_TYPE_CGA 0
|
||||
#define VIDEO_FLAG_TYPE_MDA 1
|
||||
#define VIDEO_FLAG_TYPE_SPECIAL 2
|
||||
#define VIDEO_FLAG_TYPE_MASK 3
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
int write_b, write_w, write_l;
|
||||
int read_b, read_w, read_l;
|
||||
} video_timings_t;
|
||||
|
||||
typedef struct {
|
||||
int w, h;
|
||||
uint8_t *dat;
|
||||
uint8_t *line[2048];
|
||||
} bitmap_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t r, g, b;
|
||||
} rgb_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t chr[32];
|
||||
} dbcs_font_t;
|
||||
|
||||
typedef rgb_t PALETTE[256];
|
||||
|
||||
|
||||
extern int gfx_present[GFX_MAX];
|
||||
extern int egareads,
|
||||
egawrites;
|
||||
extern int changeframecount;
|
||||
|
||||
extern bitmap_t *screen,
|
||||
*buffer,
|
||||
*buffer32;
|
||||
extern PALETTE cgapal,
|
||||
cgapal_mono[6];
|
||||
extern uint32_t pal_lookup[256];
|
||||
extern int video_fullscreen,
|
||||
video_fullscreen_scale,
|
||||
video_fullscreen_first;
|
||||
extern int fullchange;
|
||||
extern uint8_t fontdat[2048][8];
|
||||
extern uint8_t fontdatm[2048][16];
|
||||
extern dbcs_font_t *fontdatksc5601;
|
||||
extern dbcs_font_t *fontdatksc5601_user;
|
||||
extern uint32_t *video_6to8,
|
||||
*video_15to32,
|
||||
*video_16to32;
|
||||
extern int xsize,ysize;
|
||||
extern int enable_overscan;
|
||||
extern int overscan_x,
|
||||
overscan_y;
|
||||
extern int force_43;
|
||||
extern int video_timing_read_b,
|
||||
video_timing_read_w,
|
||||
video_timing_read_l;
|
||||
extern int video_timing_write_b,
|
||||
video_timing_write_w,
|
||||
video_timing_write_l;
|
||||
extern int video_res_x,
|
||||
video_res_y,
|
||||
video_bpp;
|
||||
extern int vid_resize;
|
||||
extern int cga_palette;
|
||||
extern int vid_cga_contrast;
|
||||
extern int video_grayscale;
|
||||
extern int video_graytype;
|
||||
|
||||
extern float cpuclock;
|
||||
extern int emu_fps,
|
||||
frames;
|
||||
extern int readflash;
|
||||
|
||||
|
||||
/* Function handler pointers. */
|
||||
extern void (*video_recalctimings)(void);
|
||||
|
||||
|
||||
/* Table functions. */
|
||||
extern int video_card_available(int card);
|
||||
extern char *video_card_getname(int card);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *video_card_getdevice(int card);
|
||||
#endif
|
||||
extern int video_card_has_config(int card);
|
||||
extern int video_card_getid(char *s);
|
||||
extern int video_old_to_new(int card);
|
||||
extern int video_new_to_old(int card);
|
||||
extern char *video_get_internal_name(int card);
|
||||
extern int video_get_video_from_internal_name(char *s);
|
||||
extern int video_is_mda(void);
|
||||
extern int video_is_cga(void);
|
||||
extern int video_is_ega_vga(void);
|
||||
extern void video_inform(int type, const video_timings_t *ptr);
|
||||
extern int video_get_type(void);
|
||||
|
||||
|
||||
extern void video_setblit(void(*blit)(int,int,int,int,int,int));
|
||||
extern void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
|
||||
extern void video_blit_memtoscreen_8(int x, int y, int y1, int y2, int w, int h);
|
||||
extern void video_blit_complete(void);
|
||||
extern void video_wait_for_blit(void);
|
||||
extern void video_wait_for_buffer(void);
|
||||
|
||||
extern bitmap_t *create_bitmap(int w, int h);
|
||||
extern void destroy_bitmap(bitmap_t *b);
|
||||
extern void cgapal_rebuild(void);
|
||||
extern void hline(bitmap_t *b, int x1, int y, int x2, uint32_t col);
|
||||
extern void updatewindowsize(int x, int y);
|
||||
|
||||
extern void video_init(void);
|
||||
extern void video_close(void);
|
||||
extern void video_font_reset(void);
|
||||
extern void video_reset(int card);
|
||||
extern uint8_t video_force_resize_get(void);
|
||||
extern void video_force_resize_set(uint8_t res);
|
||||
extern void video_update_timing(void);
|
||||
|
||||
extern void loadfont(wchar_t *s, int format);
|
||||
|
||||
extern int get_actual_size_x(void);
|
||||
extern int get_actual_size_y(void);
|
||||
|
||||
#ifdef ENABLE_VRAM_DUMP
|
||||
extern void svga_dump_vram(void);
|
||||
#endif
|
||||
|
||||
extern uint32_t video_color_transform(uint32_t color);
|
||||
extern void video_transform_copy(uint32_t *dst, uint32_t *src, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*EMU_VIDEO_H*/
|
||||
@@ -1,644 +0,0 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Makefile for Win32 (MinGW32) environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.123 2018/08/02
|
||||
#
|
||||
# Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
# Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
|
||||
# Various compile-time options.
|
||||
ifndef STUFF
|
||||
STUFF :=
|
||||
endif
|
||||
|
||||
# Add feature selections here.
|
||||
ifndef EXTRAS
|
||||
EXTRAS :=
|
||||
endif
|
||||
|
||||
ifndef DEV_BUILD
|
||||
DEV_BUILD := n
|
||||
endif
|
||||
|
||||
ifeq ($(DEV_BUILD), y)
|
||||
ifndef DEBUG
|
||||
DEBUG := y
|
||||
endif
|
||||
ifndef DEV_BRANCH
|
||||
DEV_BRANCH := y
|
||||
endif
|
||||
ifndef AMD_K
|
||||
AMD_K := y
|
||||
endif
|
||||
ifndef CRASHDUMP
|
||||
CRASHDUMP := y
|
||||
endif
|
||||
ifndef D2D
|
||||
D2D := y
|
||||
endif
|
||||
ifndef I686
|
||||
I686 := y
|
||||
endif
|
||||
ifndef LASERXT
|
||||
LASERXT := y
|
||||
endif
|
||||
ifndef MRTHOR
|
||||
MRTHOR := y
|
||||
endif
|
||||
ifndef PAS16
|
||||
PAS16 := y
|
||||
endif
|
||||
ifndef PORTABLE3
|
||||
PORTABLE3 := y
|
||||
endif
|
||||
ifndef STEALTH32
|
||||
STEALTH32 := y
|
||||
endif
|
||||
ifndef VNC
|
||||
VNC := y
|
||||
endif
|
||||
ifndef XL24
|
||||
XL24 := y
|
||||
endif
|
||||
else
|
||||
ifndef DEBUG
|
||||
DEBUG := n
|
||||
endif
|
||||
ifndef DEV_BRANCH
|
||||
DEV_BRANCH := n
|
||||
endif
|
||||
ifndef AMD_K
|
||||
AMD_K := n
|
||||
endif
|
||||
ifndef CRASHDUMP
|
||||
CRASHDUMP := n
|
||||
endif
|
||||
ifndef D2D
|
||||
D2D := n
|
||||
endif
|
||||
ifndef I686
|
||||
I686 := n
|
||||
endif
|
||||
ifndef LASERXT
|
||||
LASERXT := n
|
||||
endif
|
||||
ifndef MRTHOR
|
||||
MRTHOR := n
|
||||
endif
|
||||
ifndef PAS16
|
||||
PAS16 := n
|
||||
endif
|
||||
ifndef PORTABLE3
|
||||
PORTABLE3 := n
|
||||
endif
|
||||
ifndef STEALTH32
|
||||
STEALTH32 := n
|
||||
endif
|
||||
ifndef VGAWONDER
|
||||
VGAWONDER := n
|
||||
endif
|
||||
ifndef VNC
|
||||
VNC := n
|
||||
endif
|
||||
ifndef XL24
|
||||
XL24 := n
|
||||
endif
|
||||
endif
|
||||
|
||||
# Defaults for several build options (possibly defined in a chained file.)
|
||||
ifndef AUTODEP
|
||||
AUTODEP := n
|
||||
endif
|
||||
ifndef OPTIM
|
||||
OPTIM := n
|
||||
endif
|
||||
ifndef RELEASE
|
||||
RELEASE := n
|
||||
endif
|
||||
ifndef X64
|
||||
X64 := n
|
||||
endif
|
||||
ifndef USB
|
||||
USB := n
|
||||
endif
|
||||
ifndef RDP
|
||||
RDP := n
|
||||
endif
|
||||
ifndef OPENAL
|
||||
OPENAL := y
|
||||
endif
|
||||
ifndef FLUIDSYNTH
|
||||
FLUIDSYNTH := y
|
||||
endif
|
||||
ifndef MUNT
|
||||
MUNT := y
|
||||
endif
|
||||
ifndef DYNAREC
|
||||
DYNAREC := y
|
||||
endif
|
||||
|
||||
|
||||
# Name of the executable.
|
||||
ifndef PROG
|
||||
PROG := 86Box
|
||||
endif
|
||||
|
||||
|
||||
#########################################################################
|
||||
# Nothing should need changing from here on.. #
|
||||
#########################################################################
|
||||
VPATH := $(EXPATH) . cpu \
|
||||
cdrom disk floppy game machine \
|
||||
sound \
|
||||
sound/munt sound/munt/c_interface sound/munt/sha1 \
|
||||
sound/munt/srchelper \
|
||||
sound/resid-fp \
|
||||
scsi video network network/slirp win
|
||||
ifeq ($(X64), y)
|
||||
CPP := g++ -m64
|
||||
CC := gcc -m64
|
||||
else
|
||||
CPP := g++ -m32
|
||||
CC := gcc -m32
|
||||
endif
|
||||
WINDRES := windres
|
||||
DEPS = -MMD -MF $*.d -c $<
|
||||
DEPFILE := win/.depends
|
||||
|
||||
# Set up the correct toolchain flags.
|
||||
OPTS := $(EXTRAS) $(STUFF)
|
||||
ifdef EXFLAGS
|
||||
OPTS += $(EXFLAGS)
|
||||
endif
|
||||
ifdef EXINC
|
||||
OPTS += -I$(EXINC)
|
||||
endif
|
||||
ifeq ($(X64), y)
|
||||
ifeq ($(OPTIM), y)
|
||||
DFLAGS := -march=corei7
|
||||
else
|
||||
DFLAGS :=
|
||||
endif
|
||||
else
|
||||
ifeq ($(OPTIM), y)
|
||||
DFLAGS := -march=corei7
|
||||
else
|
||||
DFLAGS := -march=i686
|
||||
endif
|
||||
endif
|
||||
ifeq ($(DEBUG), y)
|
||||
DFLAGS += -ggdb -DDEBUG
|
||||
AOPTIM :=
|
||||
ifndef COPTIM
|
||||
COPTIM := -Og
|
||||
endif
|
||||
else
|
||||
DFLAGS += -g0
|
||||
ifeq ($(OPTIM), y)
|
||||
AOPTIM := -mtune=corei7
|
||||
ifndef COPTIM
|
||||
# COPTIM := -O3 -flto
|
||||
COPTIM := -O3
|
||||
endif
|
||||
else
|
||||
ifndef COPTIM
|
||||
COPTIM := -O3
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
AFLAGS := -msse2 -mfpmath=sse
|
||||
RFLAGS := --input-format=rc -O coff
|
||||
ifeq ($(RELEASE), y)
|
||||
OPTS += -DRELEASE_BUILD
|
||||
RFLAGS += -DRELEASE_BUILD
|
||||
endif
|
||||
ifeq ($(VRAMDUMP), y)
|
||||
OPTS += -DENABLE_VRAM_DUMP
|
||||
RFLAGS += -DENABLE_VRAM_DUMP
|
||||
endif
|
||||
ifeq ($(X64), y)
|
||||
PLATCG := codegen_x86-64.o
|
||||
CGOPS := codegen_ops_x86-64.h
|
||||
VCG := vid_voodoo_codegen_x86-64.h
|
||||
else
|
||||
PLATCG := codegen_x86.o
|
||||
CGOPS := codegen_ops_x86.h
|
||||
VCG := vid_voodoo_codegen_x86.h
|
||||
endif
|
||||
|
||||
|
||||
# Optional modules.
|
||||
ifeq ($(DYNAREC), y)
|
||||
OPTS += -DUSE_DYNAREC
|
||||
RFLAGS += -DUSE_DYNAREC
|
||||
DYNARECOBJ := 386_dynarec_ops.o \
|
||||
codegen.o \
|
||||
codegen_ops.o \
|
||||
codegen_timing_common.o codegen_timing_486.o \
|
||||
codegen_timing_686.o codegen_timing_pentium.o \
|
||||
codegen_timing_winchip.o $(PLATCG)
|
||||
endif
|
||||
|
||||
UIOBJ := win_ui.o win_stbar.o \
|
||||
win_ddraw.o win_d2d.o win_d3d.o win_sdl.o \
|
||||
win_dialog.o win_about.o \
|
||||
win_settings.o win_devconf.o win_snd_gain.o \
|
||||
win_new_floppy.o win_jsconf.o
|
||||
|
||||
ifeq ($(OPENAL), y)
|
||||
OPTS += -DUSE_OPENAL
|
||||
endif
|
||||
ifeq ($(FLUIDSYNTH), y)
|
||||
OPTS += -DUSE_FLUIDSYNTH
|
||||
FSYNTHOBJ := midi_fluidsynth.o
|
||||
endif
|
||||
|
||||
ifeq ($(MUNT), y)
|
||||
OPTS += -DUSE_MUNT
|
||||
MUNTOBJ := midi_mt32.o \
|
||||
Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \
|
||||
LA32FloatWaveGenerator.o LA32WaveGenerator.o \
|
||||
MidiStreamParser.o Part.o Partial.o PartialManager.o \
|
||||
Poly.o ROMInfo.o SampleRateConverter_dummy.o Synth.o \
|
||||
Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o
|
||||
endif
|
||||
|
||||
ifeq ($(D2D), y)
|
||||
OPTS += -DUSE_D2D
|
||||
RFLAGS += -DUSE_D2D
|
||||
D2DLIB := -ld2d1
|
||||
endif
|
||||
|
||||
ifeq ($(VNC), y)
|
||||
OPTS += -DUSE_VNC
|
||||
RFLAGS += -DUSE_VNC
|
||||
ifneq ($(VNC_PATH), )
|
||||
OPTS += -I$(VNC_PATH)\INCLUDE
|
||||
VNCLIB := -L$(VNC_PATH)\LIB
|
||||
endif
|
||||
VNCLIB += -lvncserver
|
||||
VNCOBJ := vnc.o vnc_keymap.o
|
||||
endif
|
||||
|
||||
ifeq ($(RDP), y)
|
||||
OPTS += -DUSE_RDP
|
||||
RFLAGS += -DUSE_RDP
|
||||
ifneq ($(RDP_PATH), )
|
||||
OPTS += -I$(RDP_PATH)\INCLUDE
|
||||
RDPLIB := -L$(RDP_PATH)\LIB
|
||||
endif
|
||||
RDPLIB += -lrdp
|
||||
RDPOBJ := rdp.o
|
||||
endif
|
||||
|
||||
# Options for the DEV branch.
|
||||
ifeq ($(DEV_BRANCH), y)
|
||||
OPTS += -DDEV_BRANCH
|
||||
DEVBROBJ :=
|
||||
|
||||
ifeq ($(AMD_K), y)
|
||||
OPTS += -DUSE_AMD_K
|
||||
endif
|
||||
|
||||
ifeq ($(CRASHDUMPOBJ), y)
|
||||
OPTS += -DUSE_CRASHDUMP
|
||||
DEVBROBJ += win_crashdump.o
|
||||
endif
|
||||
|
||||
ifeq ($(I686), y)
|
||||
OPTS += -DUSE_I686
|
||||
endif
|
||||
|
||||
ifeq ($(LASERXT), y)
|
||||
OPTS += -DUSE_LASERXT
|
||||
DEVBROBJ += m_xt_laserxt.o
|
||||
endif
|
||||
|
||||
ifeq ($(MRTHOR), y)
|
||||
OPTS += -DUSE_MRTHOR
|
||||
endif
|
||||
|
||||
ifeq ($(PAS16), y)
|
||||
OPTS += -DUSE_PAS16
|
||||
DEVBROBJ += snd_pas16.o
|
||||
endif
|
||||
|
||||
ifeq ($(PORTABLE3), y)
|
||||
OPTS += -DUSE_PORTABLE3
|
||||
endif
|
||||
|
||||
ifeq ($(STEALTH32), y)
|
||||
OPTS += -DUSE_STEALTH32
|
||||
DEVBROBJ += vid_icd2061.o
|
||||
endif
|
||||
|
||||
ifeq ($(VGAWONDER), y)
|
||||
OPTS += -DUSE_VGAWONDER
|
||||
endif
|
||||
|
||||
ifeq ($(XL24), y)
|
||||
OPTS += -DUSE_XL24
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
# Options for works-in-progress.
|
||||
ifndef SERIAL
|
||||
SERIAL := serial.o
|
||||
endif
|
||||
|
||||
|
||||
# Final versions of the toolchain flags.
|
||||
CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \
|
||||
$(AFLAGS) -m32 -fomit-frame-pointer -mstackrealign -Wall \
|
||||
-fno-strict-aliasing
|
||||
|
||||
|
||||
#########################################################################
|
||||
# Create the (final) list of objects to build. #
|
||||
#########################################################################
|
||||
MAINOBJ := pc.o config.o random.o timer.o io.o dma.o nmi.o pic.o \
|
||||
pit.o ppi.o pci.o mca.o mcr.o mem.o memregs.o rom.o \
|
||||
device.o nvr.o nvr_at.o nvr_ps2.o $(VNCOBJ) $(RDPOBJ)
|
||||
|
||||
INTELOBJ := intel.o \
|
||||
intel_flash.o \
|
||||
intel_sio.o intel_piix.o
|
||||
|
||||
CPUOBJ := cpu.o cpu_table.o \
|
||||
808x.o 386.o 386_dynarec.o \
|
||||
x86seg.o x87.o \
|
||||
$(DYNARECOBJ)
|
||||
|
||||
MCHOBJ := machine.o machine_table.o \
|
||||
m_xt.o m_xt_compaq.o \
|
||||
m_xt_t1000.o m_xt_t1000_vid.o \
|
||||
m_xt_xi8088.o \
|
||||
m_pcjr.o \
|
||||
m_amstrad.o \
|
||||
m_europc.o \
|
||||
m_olivetti_m24.o m_tandy.o \
|
||||
m_at.o \
|
||||
m_at_ali1429.o m_at_commodore.o \
|
||||
m_at_neat.o m_at_headland.o \
|
||||
m_at_t3100e.o m_at_t3100e_vid.o \
|
||||
m_ps1.o m_ps1_hdc.o \
|
||||
m_ps2_isa.o m_ps2_mca.o \
|
||||
m_at_opti495.o m_at_scat.o \
|
||||
m_at_compaq.o m_at_wd76c10.o \
|
||||
m_at_sis_85c471.o m_at_sis_85c496.o \
|
||||
m_at_4x0.o
|
||||
|
||||
DEVOBJ := bugger.o lpt.o $(SERIAL) \
|
||||
sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \
|
||||
sio_pc87306.o sio_w83877f.o sio_um8669f.o \
|
||||
keyboard.o \
|
||||
keyboard_xt.o keyboard_at.o \
|
||||
gameport.o \
|
||||
joystick_standard.o joystick_ch_flightstick_pro.o \
|
||||
joystick_sw_pad.o joystick_tm_fcs.o \
|
||||
mouse.o \
|
||||
mouse_bus.o \
|
||||
mouse_serial.o mouse_ps2.o
|
||||
|
||||
FDDOBJ := fdd.o fdc.o fdi2raw.o \
|
||||
fdd_common.o fdd_86f.o \
|
||||
fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \
|
||||
fdd_td0.o
|
||||
|
||||
HDDOBJ := hdd.o \
|
||||
hdd_image.o hdd_table.o \
|
||||
hdc.o \
|
||||
hdc_mfm_xt.o hdc_mfm_at.o \
|
||||
hdc_xta.o \
|
||||
hdc_esdi_at.o hdc_esdi_mca.o \
|
||||
hdc_xtide.o hdc_ide.o
|
||||
|
||||
CDROMOBJ := cdrom.o \
|
||||
cdrom_dosbox.o cdrom_image.o cdrom_null.o
|
||||
|
||||
ZIPOBJ := zip.o
|
||||
|
||||
ifeq ($(USB), y)
|
||||
USBOBJ := usb.o
|
||||
endif
|
||||
|
||||
SCSIOBJ := scsi.o \
|
||||
scsi_bus.o scsi_device.o \
|
||||
scsi_disk.o \
|
||||
scsi_x54x.o \
|
||||
scsi_aha154x.o scsi_buslogic.o \
|
||||
scsi_ncr5380.o scsi_ncr53c810.o
|
||||
|
||||
NETOBJ := network.o \
|
||||
net_pcap.o \
|
||||
net_slirp.o \
|
||||
bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \
|
||||
ip_input.o queue.o tcp_input.o debug.o ip_output.o \
|
||||
sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \
|
||||
net_dp8390.o \
|
||||
net_3c503.o net_ne2000.o \
|
||||
net_wd8003.o
|
||||
|
||||
SNDOBJ := sound.o \
|
||||
openal.o \
|
||||
snd_opl.o snd_dbopl.o \
|
||||
dbopl.o nukedopl.o \
|
||||
snd_resid.o \
|
||||
convolve.o convolve-sse.o envelope.o extfilt.o \
|
||||
filter.o pot.o sid.o voice.o wave6581__ST.o \
|
||||
wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \
|
||||
wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \
|
||||
wave8580_PST.o wave.o \
|
||||
midi.o midi_system.o \
|
||||
snd_speaker.o \
|
||||
snd_pssj.o \
|
||||
snd_lpt_dac.o snd_lpt_dss.o \
|
||||
snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \
|
||||
snd_cms.o \
|
||||
snd_gus.o \
|
||||
snd_sb.o snd_sb_dsp.o \
|
||||
snd_emu8k.o snd_mpu401.o \
|
||||
snd_sn76489.o snd_ssi2001.o \
|
||||
snd_wss.o \
|
||||
snd_ym7128.o
|
||||
|
||||
VIDOBJ := video.o \
|
||||
vid_table.o \
|
||||
vid_cga.o vid_cga_comp.o \
|
||||
vid_compaq_cga.o \
|
||||
vid_mda.o \
|
||||
vid_hercules.o vid_herculesplus.o vid_incolor.o \
|
||||
vid_colorplus.o \
|
||||
vid_genius.o \
|
||||
vid_wy700.o \
|
||||
vid_ega.o vid_ega_render.o \
|
||||
vid_svga.o vid_svga_render.o \
|
||||
vid_vga.o \
|
||||
vid_ati_eeprom.o \
|
||||
vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati_mach64.o vid_ati68860_ramdac.o \
|
||||
vid_ics2595.o \
|
||||
vid_cl54xx.o \
|
||||
vid_et4000.o vid_sc1502x_ramdac.o \
|
||||
vid_et4000w32.o vid_stg_ramdac.o \
|
||||
vid_oak_oti.o \
|
||||
vid_paradise.o \
|
||||
vid_ti_cf62011.o \
|
||||
vid_tvga.o \
|
||||
vid_tgui9440.o vid_tkd8001_ramdac.o \
|
||||
vid_s3.o vid_s3_virge.o \
|
||||
vid_sdac_ramdac.o \
|
||||
vid_voodoo.o
|
||||
|
||||
PLATOBJ := win.o \
|
||||
win_dynld.o win_thread.o \
|
||||
win_cdrom.o win_keyboard.o \
|
||||
win_mouse.o win_joystick.o win_midi.o
|
||||
|
||||
OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \
|
||||
$(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \
|
||||
$(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \
|
||||
$(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) \
|
||||
$(DEVBROBJ)
|
||||
ifdef EXOBJ
|
||||
OBJ += $(EXOBJ)
|
||||
endif
|
||||
|
||||
LIBS := -mwindows \
|
||||
-lopenal.dll \
|
||||
-lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \
|
||||
-lcomctl32 -lwinmm
|
||||
ifeq ($(D2D), y)
|
||||
LIBS += $(D2DLIB)
|
||||
endif
|
||||
ifeq ($(VNC), y)
|
||||
LIBS += $(VNCLIB) -lws2_32
|
||||
endif
|
||||
ifeq ($(RDP), y)
|
||||
LIBS += $(RDPLIB)
|
||||
endif
|
||||
LIBS += -lpng -lz -lwsock32 -liphlpapi
|
||||
LIBS += -static -lstdc++ -lgcc
|
||||
ifneq ($(X64), y)
|
||||
LIBS += -Wl,--large-address-aware
|
||||
endif
|
||||
|
||||
|
||||
# Build module rules.
|
||||
ifeq ($(AUTODEP), y)
|
||||
%.o: %.c
|
||||
@echo $<
|
||||
@$(CC) $(CFLAGS) $(DEPS) -c $<
|
||||
|
||||
%.o: %.cc
|
||||
@echo $<
|
||||
@$(CPP) $(CFLAGS) $(DEPS) -c $<
|
||||
|
||||
%.o: %.cpp
|
||||
@echo $<
|
||||
@$(CPP) $(CFLAGS) $(DEPS) -c $<
|
||||
else
|
||||
%.o: %.c
|
||||
@echo $<
|
||||
@$(CC) $(CFLAGS) -c $<
|
||||
|
||||
%.o: %.cc
|
||||
@echo $<
|
||||
@$(CPP) $(CFLAGS) -c $<
|
||||
|
||||
%.o: %.cpp
|
||||
@echo $<
|
||||
@$(CPP) $(CFLAGS) -c $<
|
||||
|
||||
%.d: %.c $(wildcard $*.d)
|
||||
@echo $<
|
||||
@$(CC) $(CFLAGS) $(DEPS) -E $< >NUL
|
||||
|
||||
%.d: %.cc $(wildcard $*.d)
|
||||
@echo $<
|
||||
@$(CPP) $(CFLAGS) $(DEPS) -E $< >NUL
|
||||
|
||||
%.d: %.cpp $(wildcard $*.d)
|
||||
@echo $<
|
||||
@$(CPP) $(CFLAGS) $(DEPS) -E $< >NUL
|
||||
endif
|
||||
|
||||
|
||||
all: $(PROG).exe pcap_if.exe
|
||||
|
||||
|
||||
86Box.res: 86Box.rc
|
||||
@echo Processing $<
|
||||
@$(WINDRES) $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res
|
||||
|
||||
$(PROG).exe: $(OBJ) 86Box.res
|
||||
@echo Linking $(PROG).exe ..
|
||||
@$(CC) -m32 -o $(PROG).exe $(OBJ) 86Box.res $(LIBS)
|
||||
ifneq ($(DEBUG), y)
|
||||
@strip $(PROG).exe
|
||||
endif
|
||||
|
||||
pcap_if.res: pcap_if.rc
|
||||
@echo Processing $<
|
||||
@$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res
|
||||
|
||||
pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res
|
||||
@echo Linking pcap_if.exe ..
|
||||
@$(CC) -m32 -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res
|
||||
ifneq ($(DEBUG), y)
|
||||
@strip pcap_if.exe
|
||||
endif
|
||||
|
||||
hello.exe: hello.o
|
||||
$(CXX) $(LDFLAGS) -o hello.exe hello.o $(LIBS)
|
||||
ifneq ($(DEBUG), y)
|
||||
@strip hello.exe
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
@echo Cleaning objects..
|
||||
@-rm -f *.o 2>NUL
|
||||
@-rm -f *.res 2>NUL
|
||||
|
||||
clobber: clean
|
||||
@echo Cleaning executables..
|
||||
@-rm -f *.d 2>NUL
|
||||
@-rm -f *.exe 2>NUL
|
||||
# @-rm -f $(DEPFILE) 2>NUL
|
||||
|
||||
ifneq ($(AUTODEP), y)
|
||||
depclean:
|
||||
@-rm -f $(DEPFILE) 2>NUL
|
||||
@echo Creating dependencies..
|
||||
@echo # Run "make depends" to re-create this file. >$(DEPFILE)
|
||||
|
||||
depends: DEPOBJ=$(OBJ:%.o=%.d)
|
||||
depends: depclean $(OBJ:%.o=%.d)
|
||||
@-cat $(DEPOBJ) >>$(DEPFILE)
|
||||
@-rm -f $(DEPOBJ)
|
||||
|
||||
$(DEPFILE):
|
||||
endif
|
||||
|
||||
|
||||
# Module dependencies.
|
||||
ifeq ($(AUTODEP), y)
|
||||
#-include $(OBJ:%.o=%.d) (better, but sloooowwwww)
|
||||
-include *.d
|
||||
else
|
||||
include $(wildcard $(DEPFILE))
|
||||
endif
|
||||
|
||||
|
||||
# End of Makefile.mingw.
|
||||
Reference in New Issue
Block a user