Added the Western Digital WDXT-150 XTA disk controller.
Updated SettingsUI to have a <configure> for disk controllers. Moved machine config code to machine/machine_table.c. Fixed more constness stuff in device.c and machine_table.c Fixed an issue in win_devconf.c (buffers too small.) Misc changes and fixes.
This commit is contained in:
@@ -1596,7 +1596,7 @@ config_read(const wchar_t *fn)
|
||||
if (buff[c] == L'[') { /*Section*/
|
||||
c++;
|
||||
d = 0;
|
||||
while (buff[c] != L']' && buff[c])
|
||||
while (buff[c] && (buff[c] != L']'))
|
||||
wctomb(&(sname[d++]), buff[c++]);
|
||||
sname[d] = L'\0';
|
||||
|
||||
|
||||
88
src/device.c
88
src/device.c
@@ -9,7 +9,7 @@
|
||||
* Implementation of the generic device interface to handle
|
||||
* all devices attached to the emulator.
|
||||
*
|
||||
* Version: @(#)device.c 1.0.6 2018/04/09
|
||||
* Version: @(#)device.c 1.0.7 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -247,14 +247,14 @@ device_add_status_info(char *s, int max_len)
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
device_get_config_string(char *s)
|
||||
const char *
|
||||
device_get_config_string(const 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));
|
||||
return(config_get_string(device_current->name, s, c->default_string));
|
||||
|
||||
c++;
|
||||
}
|
||||
@@ -264,13 +264,13 @@ device_get_config_string(char *s)
|
||||
|
||||
|
||||
int
|
||||
device_get_config_int(char *s)
|
||||
device_get_config_int(const 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));
|
||||
return(config_get_int(device_current->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
@@ -280,29 +280,29 @@ device_get_config_int(char *s)
|
||||
|
||||
|
||||
int
|
||||
device_get_config_int_ex(char *s, int default_int)
|
||||
device_get_config_int_ex(const char *s, int def)
|
||||
{
|
||||
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));
|
||||
return(config_get_int(device_current->name, s, def));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(default_int);
|
||||
return(def);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_get_config_hex16(char *s)
|
||||
device_get_config_hex16(const 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));
|
||||
return(config_get_hex16(device_current->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
@@ -312,13 +312,13 @@ device_get_config_hex16(char *s)
|
||||
|
||||
|
||||
int
|
||||
device_get_config_hex20(char *s)
|
||||
device_get_config_hex20(const 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));
|
||||
return(config_get_hex20(device_current->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
@@ -328,29 +328,29 @@ device_get_config_hex20(char *s)
|
||||
|
||||
|
||||
int
|
||||
device_get_config_mac(char *s, int default_int)
|
||||
device_get_config_mac(const char *s, int def)
|
||||
{
|
||||
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));
|
||||
return(config_get_mac(device_current->name, s, def));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(default_int);
|
||||
return(def);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_set_config_int(char *s, int val)
|
||||
device_set_config_int(const 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);
|
||||
config_set_int(device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -360,13 +360,13 @@ device_set_config_int(char *s, int val)
|
||||
|
||||
|
||||
void
|
||||
device_set_config_hex16(char *s, int val)
|
||||
device_set_config_hex16(const 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);
|
||||
config_set_hex16(device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -376,13 +376,13 @@ device_set_config_hex16(char *s, int val)
|
||||
|
||||
|
||||
void
|
||||
device_set_config_hex20(char *s, int val)
|
||||
device_set_config_hex20(const 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);
|
||||
config_set_hex20(device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -392,13 +392,13 @@ device_set_config_hex20(char *s, int val)
|
||||
|
||||
|
||||
void
|
||||
device_set_config_mac(char *s, int val)
|
||||
device_set_config_mac(const 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);
|
||||
config_set_mac(device_current->name, s, val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -431,43 +431,3 @@ device_is_valid(const device_t *device, int mflags)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
42
src/device.h
42
src/device.h
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the device handler.
|
||||
*
|
||||
* Version: @(#)device.h 1.0.4 2018/04/09
|
||||
* Version: @(#)device.h 1.0.5 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -99,12 +99,12 @@ typedef struct _device_ {
|
||||
uint32_t local; /* flags local to device */
|
||||
|
||||
void *(*init)(const struct _device_ *);
|
||||
void (*close)(void *p);
|
||||
void (*reset)(void *p);
|
||||
void (*close)(void *priv);
|
||||
void (*reset)(void *priv);
|
||||
int (*available)(/*void*/);
|
||||
void (*speed_changed)(void *p);
|
||||
void (*force_redraw)(void *p);
|
||||
void (*add_status_info)(char *s, int max_len, void *p);
|
||||
void (*speed_changed)(void *priv);
|
||||
void (*force_redraw)(void *priv);
|
||||
void (*add_status_info)(char *s, int max_len, void *priv);
|
||||
|
||||
const device_config_t *config;
|
||||
} device_t;
|
||||
@@ -115,30 +115,28 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern void device_init(void);
|
||||
extern void *device_add(const device_t *d);
|
||||
extern void *device_add(const device_t *);
|
||||
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_get_priv(const device_t *d);
|
||||
extern int device_available(const device_t *d);
|
||||
extern void *device_get_priv(const device_t *);
|
||||
extern int device_available(const device_t *);
|
||||
extern void device_speed_changed(void);
|
||||
extern void device_force_redraw(void);
|
||||
extern void device_add_status_info(char *s, int max_len);
|
||||
|
||||
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 device_is_valid(const device_t *, int machine_flags);
|
||||
|
||||
extern int machine_get_config_int(char *s);
|
||||
extern char *machine_get_config_string(char *s);
|
||||
extern int device_get_config_int(const char *name);
|
||||
extern int device_get_config_int_ex(const char *s, int default_int);
|
||||
extern int device_get_config_hex16(const char *name);
|
||||
extern int device_get_config_hex20(const char *name);
|
||||
extern int device_get_config_mac(const char *name, int default_int);
|
||||
extern void device_set_config_int(const char *s, int val);
|
||||
extern void device_set_config_hex16(const char *s, int val);
|
||||
extern void device_set_config_hex20(const char *s, int val);
|
||||
extern void device_set_config_mac(const char *s, int val);
|
||||
extern const char *device_get_config_string(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Common code to handle all sorts of disk controllers.
|
||||
*
|
||||
* Version: @(#)hdc.c 1.0.10 2018/04/23
|
||||
* Version: @(#)hdc.c 1.0.12 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -112,10 +112,8 @@ static const struct {
|
||||
{ "[ISA] [ST506] DTC-5150X Fixed Disk Adapter", "st506_dtc5150x",
|
||||
&st506_xt_dtc5150x_device, 1 },
|
||||
|
||||
#ifdef USE_XTA
|
||||
{ "[ISA] [IDE] PC/XT IDE (XTA) Adapter", "xta_isa",
|
||||
&xta_isa_device, 0, },
|
||||
#endif
|
||||
{ "[ISA] [IDE] WDXT-150 IDE (XTA) Adapter", "xta_wdxt150",
|
||||
&xta_wdxt150_device, 0, },
|
||||
|
||||
{ "[ISA] [IDE] PC/XT XTIDE (ATA)", "xtide",
|
||||
&xtide_device, 0 },
|
||||
@@ -213,6 +211,7 @@ hdc_get_internal_name(int hdc)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const device_t *
|
||||
hdc_get_device(int hdc)
|
||||
{
|
||||
@@ -220,6 +219,19 @@ hdc_get_device(int hdc)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hdc_has_config(int hdc)
|
||||
{
|
||||
const device_t *dev = hdc_get_device(hdc);
|
||||
|
||||
if (dev == NULL) return(0);
|
||||
|
||||
if (dev->config == NULL) return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hdc_get_flags(int hdc)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the common disk controller handler.
|
||||
*
|
||||
* Version: @(#)hdc.h 1.0.10 2018/04/23
|
||||
* Version: @(#)hdc.h 1.0.13 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -62,8 +62,8 @@ extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */
|
||||
extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */
|
||||
extern const device_t esdi_ps2_device; /* esdi_mca */
|
||||
|
||||
extern const device_t xta_isa_device; /* xta_isa */
|
||||
extern const device_t xta_ps1_device; /* xta_ps1 */
|
||||
extern const device_t xta_wdxt150_device; /* xta_wdxt150 */
|
||||
extern const device_t xta_hd20_device; /* EuroPC internal */
|
||||
|
||||
extern const device_t xtide_device; /* xtide_xt */
|
||||
extern const device_t xtide_acculogic_device; /* xtide_ps2 */
|
||||
@@ -87,6 +87,7 @@ extern void hdc_reset(void);
|
||||
|
||||
extern const char *hdc_get_name(int hdc);
|
||||
extern const char *hdc_get_internal_name(int hdc);
|
||||
extern int hdc_has_config(int hdc);
|
||||
extern const device_t *hdc_get_device(int hdc);
|
||||
extern int hdc_get_flags(int hdc);
|
||||
extern int hdc_available(int hdc);
|
||||
|
||||
1201
src/disk/hdc_ide_xta.c
Normal file
1201
src/disk/hdc_ide_xta.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -163,6 +163,7 @@ dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dma_m |= (1 << (val & 3));
|
||||
else
|
||||
dma_m &= ~(1 << (val & 3));
|
||||
//pclog("DMA: %s mask for channel %d\n", (val&4)?"set":"clear", val&3);
|
||||
return;
|
||||
|
||||
case 0xb: /*Mode*/
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Intel 430FX PCISet chip.
|
||||
*
|
||||
* Version: @(#)m_at_430fx.c 1.0.9 2018/04/15
|
||||
* Version: @(#)m_at_430fx.c 1.0.10 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -54,10 +54,6 @@
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
/* Defined in the Video module. */
|
||||
extern const device_t s3_phoenix_trio64_onboard_pci_device;
|
||||
|
||||
|
||||
static uint8_t card_i430fx[256];
|
||||
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
* bit 1: b8000 memory available
|
||||
* 0000:046a: 00 jim 250 01 jim 350
|
||||
*
|
||||
* Version: @(#)m_europc.c 1.0.7 2018/04/14
|
||||
* Version: @(#)m_europc.c 1.0.8 2018/04/24
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -651,13 +651,16 @@ europc_boot(const device_t *info)
|
||||
/* 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_type == 1)
|
||||
(void)device_add(&europc_hdc_device);
|
||||
(void)device_add(&xta_hd20_device);
|
||||
|
||||
return(sys);
|
||||
}
|
||||
@@ -714,14 +717,13 @@ const device_t europc_device = {
|
||||
void
|
||||
machine_europc_init(const machine_t *model, void *arg)
|
||||
{
|
||||
machine_common_init(model, arg);
|
||||
nmi_init();
|
||||
|
||||
/* Clear the machine state. */
|
||||
memset(&europc, 0x00, sizeof(europc_t));
|
||||
europc.jim = 0x0250;
|
||||
|
||||
machine_common_init(model, arg);
|
||||
nmi_init();
|
||||
mem_add_bios();
|
||||
|
||||
/* This is machine specific. */
|
||||
europc.nvr.size = model->nvrsz;
|
||||
europc.nvr.irq = -1;
|
||||
@@ -734,9 +736,6 @@ machine_europc_init(const machine_t *model, void *arg)
|
||||
/* Initialize the actual NVR. */
|
||||
nvr_init(&europc.nvr);
|
||||
|
||||
/* Enable and set up the FDC. */
|
||||
(void)device_add(&fdc_xt_device);
|
||||
|
||||
/* Enable and set up the mainboard device. */
|
||||
device_add(&europc_device);
|
||||
}
|
||||
|
||||
@@ -1,987 +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 EuroPC HD20 internal controller.
|
||||
*
|
||||
* The HD20 was an externally-connected drive, very often a
|
||||
* 8425XT (20MB, 615/4/17) from Miniscribe. These drives used
|
||||
* an 8-bit version of IDE called X-IDE, also known as XTA.
|
||||
* Some older units had a 8225XT drive (20MB, 771/2/17.)
|
||||
*
|
||||
* To access the HD disk formatter, enter the "debug" program
|
||||
* in DOS, and type "g=f000:a000" to start that utility, which
|
||||
* is hidden in the PC's ROM BIOS.
|
||||
*
|
||||
* This driver is based on the information found in the IBM-PC
|
||||
* Technical Reference manual, pp 187 and on.
|
||||
*
|
||||
* Based on the original "xebec.c" from Sarah Walker.
|
||||
*
|
||||
* Version: @(#)m_europc_hdc.c 1.0.5 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#define __USE_LARGEFILE64
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include "../emu.h"
|
||||
#include "../io.h"
|
||||
#include "../dma.h"
|
||||
#include "../pic.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "../plat.h"
|
||||
#include "../ui.h"
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
#define HDC_DEBUG 0
|
||||
#define HDC_NEWPARAMS 1 /* use NEW parameter block */
|
||||
|
||||
#define HDD_IOADDR 0x0320
|
||||
#define HDD_IRQCHAN 5
|
||||
#define HDD_DMACHAN 3
|
||||
|
||||
|
||||
#define HDC_TIME (200*TIMER_USEC)
|
||||
|
||||
|
||||
enum {
|
||||
STATE_IDLE,
|
||||
STATE_CMD,
|
||||
STATE_RUN,
|
||||
STATE_RXDTA,
|
||||
STATE_RDATA,
|
||||
STATE_TXDTA,
|
||||
STATE_TDATA,
|
||||
STATE_COMPL
|
||||
};
|
||||
|
||||
|
||||
/* Command values. */
|
||||
#define CMD_TEST_DRV_RDY 0x00
|
||||
#define CMD_RECALIBRATE 0x01
|
||||
/* unused 0x02 */
|
||||
#define CMD_READ_SENSE 0x03
|
||||
#define CMD_FORMAT_DRIVE 0x04
|
||||
#define CMD_READY_VERIFY 0x05
|
||||
#define CMD_FORMAT_TRACK 0x06
|
||||
#define CMD_FORMAT_BAD_TRACK 0x07
|
||||
#define CMD_READ_SECTORS 0x08
|
||||
/* unused 0x09 */
|
||||
#define CMD_WRITE_SECTORS 0x0a
|
||||
#define CMD_SEEK 0x0b
|
||||
#define CMD_SET_DRIVE_PARAMS 0x0c
|
||||
#define CMD_READ_ECC_BURST 0x0d
|
||||
#define CMD_READ_SECTOR_BUFFER 0x0e
|
||||
#define CMD_WRITE_SECTOR_BUFFER 0x0f
|
||||
#define CMD_RAM_DIAGS 0xe0
|
||||
/* unused 0xe1 */
|
||||
/* unused 0xe2 */
|
||||
#define CMD_DRIVE_DIAGS 0xe3
|
||||
#define CMD_CTRL_DIAGS 0xe4
|
||||
#define CMD_READ_LONG 0xe5
|
||||
#define CMD_WRITE_LONG 0xe6
|
||||
|
||||
/* STATUS register values. */
|
||||
#define STAT_REQ 0x01
|
||||
#define STAT_IO 0x02
|
||||
#define STAT_CD 0x04
|
||||
#define STAT_BSY 0x08
|
||||
#define STAT_DRQ 0x10
|
||||
#define STAT_IRQ 0x20
|
||||
|
||||
/* Sense Error codes. */
|
||||
#define ERR_NOERROR 0x00 /* no error detected */
|
||||
#define ERR_NOINDEX 0x01 /* drive did not detect IDX pulse */
|
||||
#define ERR_NOSEEK 0x02 /* drive did not complete SEEK */
|
||||
#define ERR_WRFAULT 0x03 /* write fault during last cmd */
|
||||
#define ERR_NOTRDY 0x04 /* drive did not go READY after cmd */
|
||||
#define ERR_NOTRK000 0x06 /* drive did not see TRK0 signal */
|
||||
#define ERR_LONGSEEK 0x08 /* long seek in progress */
|
||||
#define ERR_IDREAD 0x10 /* ECC error during ID field */
|
||||
#define ERR_DATA 0x11 /* uncorrectable ECC err in data */
|
||||
#define ERR_NOMARK 0x12 /* no address mark detected */
|
||||
#define ERR_NOSECT 0x14 /* sector not found */
|
||||
#define ERR_SEEK 0x15 /* seek error */
|
||||
#define ERR_ECCDATA 0x18 /* ECC corrected data */
|
||||
#define ERR_BADTRK 0x19 /* bad track detected */
|
||||
#define ERR_ILLCMD 0x20 /* invalid command received */
|
||||
#define ERR_ILLADDR 0x21 /* invalid disk address received */
|
||||
#define ERR_BADRAM 0x30 /* bad RAM in sector data buffer */
|
||||
#define ERR_BADROM 0x31 /* bad checksum in ROM test */
|
||||
#define ERR_BADECC 0x32 /* ECC polynomial generator bad */
|
||||
|
||||
/* Completion Byte fields. */
|
||||
#define COMP_DRIVE 0x20
|
||||
#define COMP_ERR 0x02
|
||||
|
||||
#define IRQ_ENA 0x02
|
||||
#define DMA_ENA 0x01
|
||||
|
||||
|
||||
/* The device control block (6 bytes) */
|
||||
#pragma pack(push,1)
|
||||
struct dcb {
|
||||
uint8_t cmd; /* [7:5] class, [4:0] opcode */
|
||||
uint8_t head:5, /* [4:0] head number */
|
||||
drvsel:1, /* [5] drive select */
|
||||
unused:2; /* [7:6] unused MBZ */
|
||||
uint8_t sector:6, /* [5:0] sector number 0-63 */
|
||||
cylh:2; /* [7:6] cylinder [9:8] bits */
|
||||
uint8_t cyl; /* [7:0] cylinder [7:0] bits */
|
||||
uint8_t count; /* [7:0] blk count / interleave */
|
||||
uint8_t ctrl; /* [7:0] control field */
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* The (configured) Drive Parameters.
|
||||
*
|
||||
* Although the IBM specification calls for a total of 8 bytes
|
||||
* in the Paramater Block, the EuroPC uses a 16-byte block. It
|
||||
* looks like it has extended (translated?) information there,
|
||||
* as well as the actual data we need.
|
||||
*
|
||||
* [ 03 ac 04 01 f4 02 67 0b 11 04 67 02 00 00 01 00]
|
||||
*
|
||||
* is what was sent for a standard 615/4/17 disk with rdwrcyl
|
||||
* set to 500, and precomp to 615.
|
||||
*
|
||||
* For now, we will just look at the rest of the data.
|
||||
*/
|
||||
#pragma pack(push,1)
|
||||
struct dprm {
|
||||
#if HDC_NEWPARAMS
|
||||
uint16_t tracks; /* total number of sectors on drive */
|
||||
uint8_t heads; /* number of heads per cylinder */
|
||||
uint16_t rwcurrent; /* (MSB) reduced write current cylinder */
|
||||
uint16_t wprecomp; /* (MSB) write precompensation cylinder */
|
||||
uint8_t maxecc; /* max ECC data burst length */
|
||||
#else
|
||||
uint16_t tracks; /* (MSB) max number of cylinders */
|
||||
uint8_t heads; /* number of heads per cylinder */
|
||||
uint16_t rwcurrent; /* (MSB) reduced write current cylinder */
|
||||
uint16_t wprecomp; /* (MSB) write precompensation cylinder */
|
||||
uint8_t maxecc; /* max ECC data burst length */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t spt,
|
||||
hpc;
|
||||
uint16_t tracks;
|
||||
|
||||
struct dprm params;
|
||||
uint8_t cfg_spt,
|
||||
cfg_hpc;
|
||||
uint16_t cfg_tracks;
|
||||
|
||||
uint16_t cur_cyl;
|
||||
|
||||
int8_t present,
|
||||
hdd_num;
|
||||
} drive_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t base;
|
||||
int8_t irq;
|
||||
int8_t dma;
|
||||
uint8_t mask;
|
||||
|
||||
int8_t state;
|
||||
int64_t callback;
|
||||
|
||||
uint8_t sense; /* current SENSE ERROR value */
|
||||
uint8_t status; /* current operational status */
|
||||
|
||||
/* Current operation parameters. */
|
||||
int16_t buf_idx, /* command buffer index and pointer */
|
||||
buf_len;
|
||||
uint8_t *buf_ptr;
|
||||
uint16_t track; /* requested track# */
|
||||
uint8_t head, /* requested head# */
|
||||
sector, /* requested sector# */
|
||||
comp; /* operation completion byte */
|
||||
int count; /* requested sector count */
|
||||
|
||||
struct dcb dcb; /* device control block */
|
||||
|
||||
drive_t drives[ST506_NUM];
|
||||
|
||||
uint8_t data[512]; /* data buffer */
|
||||
uint8_t sector_buf[512];
|
||||
} hd20_t;
|
||||
|
||||
|
||||
static void
|
||||
hd20_intr(hd20_t *dev)
|
||||
{
|
||||
dev->status = STAT_REQ|STAT_CD|STAT_IO|STAT_BSY;
|
||||
dev->state = STATE_COMPL;
|
||||
if (dev->mask & IRQ_ENA) {
|
||||
dev->status |= STAT_IRQ;
|
||||
picint(1<<dev->irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_sector(hd20_t *dev, drive_t *drive, off64_t *addr)
|
||||
{
|
||||
int heads = drive->cfg_hpc;
|
||||
|
||||
if (drive->cur_cyl != dev->track) {
|
||||
pclog("HD20: get_sector: wrong cylinder %d/%d\n",
|
||||
drive->cur_cyl, dev->track);
|
||||
dev->sense = ERR_ILLADDR;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (dev->head > heads) {
|
||||
pclog("HD20: get_sector: past end of configured heads\n");
|
||||
dev->sense = ERR_ILLADDR;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (dev->head > drive->hpc) {
|
||||
pclog("HD20: get_sector: past end of heads\n");
|
||||
dev->sense = ERR_ILLADDR;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (dev->sector >= 17) {
|
||||
pclog("HD20: get_sector: past end of sectors\n");
|
||||
dev->sense = ERR_ILLADDR;
|
||||
return(1);
|
||||
}
|
||||
|
||||
*addr = ((((off64_t) dev->track*heads) + dev->head)*17) + dev->sector;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
next_sector(hd20_t *dev, drive_t *drive)
|
||||
{
|
||||
if (++dev->sector >= 17) {
|
||||
dev->sector = 0;
|
||||
if (++dev->head >= drive->cfg_hpc) {
|
||||
dev->head = 0;
|
||||
dev->track++;
|
||||
drive->cur_cyl++;
|
||||
if (drive->cur_cyl >= drive->cfg_tracks)
|
||||
drive->cur_cyl = drive->cfg_tracks-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Execute the DCB we just received. */
|
||||
static void
|
||||
hd20_callback(void *priv)
|
||||
{
|
||||
hd20_t *dev = (hd20_t *)priv;
|
||||
struct dcb *dcb = &dev->dcb;
|
||||
drive_t *drive;
|
||||
off64_t addr;
|
||||
int val;
|
||||
|
||||
dev->callback = 0;
|
||||
|
||||
drive = &dev->drives[dcb->drvsel];
|
||||
dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00;
|
||||
|
||||
switch (dcb->cmd) {
|
||||
case CMD_TEST_DRV_RDY:
|
||||
#if HDC_DEBUG
|
||||
if (dcb->drvsel == 0)
|
||||
pclog("HD20: test_rdy(%d) ready=%d\n",
|
||||
dcb->drvsel, drive->present);
|
||||
#endif
|
||||
if (! drive->present) {
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_NOTRDY;
|
||||
}
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_RECALIBRATE:
|
||||
#if HDC_DEBUG
|
||||
if (dcb->drvsel == 0)
|
||||
pclog("HD20: recalibrate(%d) ready=%d\n",
|
||||
dcb->drvsel, drive->present);
|
||||
#endif
|
||||
if (! drive->present) {
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_NOTRDY;
|
||||
} else {
|
||||
dev->track = drive->cur_cyl = 0;
|
||||
}
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ_SENSE:
|
||||
if (dev->state == STATE_RUN) {
|
||||
#if HDC_DEBUG
|
||||
if (dcb->drvsel == 0)
|
||||
pclog("HD20: sense(%d)\n", dcb->drvsel);
|
||||
#endif
|
||||
dev->buf_idx = 0;
|
||||
dev->buf_len = 4;
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->data[0] = dev->sense;
|
||||
dev->data[1] = dcb->drvsel ? 0x20 : 0x00;
|
||||
dev->data[2] = dev->data[3] = 0x00;
|
||||
dev->sense = ERR_NOERROR;
|
||||
dev->status = STAT_BSY|STAT_IO|STAT_REQ;
|
||||
dev->state = STATE_TXDTA;
|
||||
} else if (dev->state == STATE_TDATA) {
|
||||
hd20_intr(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_READY_VERIFY:
|
||||
if (dev->state == STATE_RUN) {
|
||||
/* Seek to cylinder. */
|
||||
dev->track = dcb->cyl | (dcb->cylh<<2);
|
||||
if (dev->track >= drive->cfg_tracks)
|
||||
drive->cur_cyl = drive->cfg_tracks-1;
|
||||
else
|
||||
drive->cur_cyl = dev->track;
|
||||
dev->head = dcb->head;
|
||||
dev->sector = dcb->sector;
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: verify_sector(%d) %d,%d,%d\n",
|
||||
dcb->drvsel, dev->track, dev->head,dev->sector);
|
||||
#endif
|
||||
|
||||
/* Get sector count; count=0 means 256. */
|
||||
dev->count = (int)dcb->count;
|
||||
if (dev->count == 0) dev->count = 256;
|
||||
while (dev->count-- > 0) {
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
pclog("HD20: get_sector failed\n");
|
||||
dev->comp |= COMP_ERR;
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
next_sector(dev, drive);
|
||||
}
|
||||
|
||||
hd20_intr(dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FORMAT_DRIVE:
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: format_drive(%d)\n", dcb->drvsel);
|
||||
#endif
|
||||
for (dev->track=0; dev->track<drive->tracks; dev->track++) {
|
||||
drive->cur_cyl = dev->track;
|
||||
for (dev->head=0; dev->head<drive->hpc; dev->head++) {
|
||||
dev->sector = 0;
|
||||
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
pclog("HD20: get_sector failed\n");
|
||||
dev->comp |= COMP_ERR;
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num,addr,drive->spt);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
}
|
||||
}
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_FORMAT_TRACK:
|
||||
/* Seek to cylinder. */
|
||||
dev->track = dcb->cyl | (dcb->cylh<<2);
|
||||
if (dev->track >= drive->cfg_tracks)
|
||||
drive->cur_cyl = drive->cfg_tracks-1;
|
||||
else
|
||||
drive->cur_cyl = dev->track;
|
||||
dev->head = dcb->head;
|
||||
dev->sector = 0;
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: format_track(%d) %d,%d\n",
|
||||
dcb->drvsel, dev->track, dev->head);
|
||||
#endif
|
||||
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
pclog("HD20: get_sector failed\n");
|
||||
dev->comp |= COMP_ERR;
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, drive->spt);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ_SECTORS:
|
||||
switch (dev->state) {
|
||||
case STATE_RUN:
|
||||
/* Seek to cylinder. */
|
||||
dev->track = dcb->cyl | (dcb->cylh<<2);
|
||||
if (dev->track >= drive->cfg_tracks)
|
||||
drive->cur_cyl = drive->cfg_tracks-1;
|
||||
else
|
||||
drive->cur_cyl = dev->track;
|
||||
dev->head = dcb->head;
|
||||
dev->sector = dcb->sector;
|
||||
|
||||
/* Get sector count; count=0 means 256. */
|
||||
dev->count = (int)dcb->count;
|
||||
if (dev->count == 0) dev->count = 256;
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: read_sector(%d) %d,%d,%d cnt=%d\n",
|
||||
dcb->drvsel, dev->track, dev->head,
|
||||
dev->sector, dev->count);
|
||||
#endif
|
||||
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
dev->comp |= COMP_ERR;
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
/* Ready to transfer the data out. */
|
||||
dev->buf_idx = 0;
|
||||
dev->buf_len = 512;
|
||||
dev->state = STATE_TXDTA;
|
||||
|
||||
if (! (dev->mask & DMA_ENA)) {
|
||||
memcpy(dev->data, dev->sector_buf, 512);
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->status = STAT_BSY|STAT_IO|STAT_REQ;
|
||||
} else {
|
||||
dev->callback = HDC_TIME;
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_TXDTA:
|
||||
dev->status = STAT_BSY;
|
||||
while (dev->buf_idx < dev->buf_len) {
|
||||
val = dma_channel_write(dev->dma,
|
||||
*dev->buf_ptr++);
|
||||
if (val == DMA_NODATA) {
|
||||
pclog("CMD_READ_SECTORS out of data!\n");
|
||||
dev->status = STAT_BSY|STAT_CD|STAT_IO|STAT_REQ;
|
||||
dev->callback = HDC_TIME;
|
||||
return;
|
||||
}
|
||||
dev->buf_idx++;
|
||||
}
|
||||
dev->state = STATE_TDATA;
|
||||
dev->callback = HDC_TIME;
|
||||
break;
|
||||
|
||||
case STATE_TDATA:
|
||||
next_sector(dev, drive);
|
||||
|
||||
dev->buf_idx = 0;
|
||||
if (--dev->count == 0) {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
dev->comp |= COMP_ERR;
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
dev->state = STATE_TXDTA;
|
||||
|
||||
if (! (dev->mask & DMA_ENA)) {
|
||||
memcpy(dev->data, dev->sector_buf, 512);
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->status = STAT_BSY|STAT_IO|STAT_REQ;
|
||||
} else {
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
dev->callback = HDC_TIME;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_WRITE_SECTORS:
|
||||
switch (dev->state) {
|
||||
case STATE_RUN:
|
||||
/* Seek to cylinder. */
|
||||
dev->track = dcb->cyl | (dcb->cylh<<2);
|
||||
if (dev->track >= drive->cfg_tracks)
|
||||
drive->cur_cyl = drive->cfg_tracks-1;
|
||||
else
|
||||
drive->cur_cyl = dev->track;
|
||||
dev->head = dcb->head;
|
||||
dev->sector = dcb->sector;
|
||||
|
||||
/* Get sector count; count=0 means 256. */
|
||||
dev->count = (int)dev->dcb.count;
|
||||
if (dev->count == 0) dev->count = 256;
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: write_sector(%d) %d,%d,%d cnt=%d\n",
|
||||
dcb->drvsel, dev->track, dev->head,
|
||||
dev->sector, dev->count);
|
||||
#endif
|
||||
dev->buf_idx = 0;
|
||||
dev->buf_len = 512;
|
||||
dev->state = STATE_RXDTA;
|
||||
if (! (dev->mask & DMA_ENA)) {
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->status = STAT_BSY|STAT_REQ;
|
||||
} else {
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
dev->callback = HDC_TIME;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_RXDTA:
|
||||
dev->status = STAT_BSY;
|
||||
while (dev->buf_idx < dev->buf_len) {
|
||||
val = dma_channel_read(dev->dma);
|
||||
if (val == DMA_NODATA) {
|
||||
pclog("CMD_WRITE_SECTORS out of data!\n");
|
||||
dev->status = STAT_BSY|STAT_CD|STAT_IO|STAT_REQ;
|
||||
dev->callback = HDC_TIME;
|
||||
return;
|
||||
}
|
||||
|
||||
*dev->buf_ptr++ = (val & 0xff);
|
||||
dev->buf_idx++;
|
||||
}
|
||||
dev->state = STATE_RDATA;
|
||||
dev->callback = HDC_TIME;
|
||||
break;
|
||||
|
||||
case STATE_RDATA:
|
||||
#if 0
|
||||
/* If I enable this, we get data corruption.. ??? -FvK */
|
||||
if (! (dev->mask & DMA_ENA))
|
||||
memcpy(dev->sector_buf, dev->data, 512);
|
||||
#endif
|
||||
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
dev->comp |= COMP_ERR;
|
||||
hd20_intr(dev);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
next_sector(dev, drive);
|
||||
|
||||
dev->buf_idx = 0;
|
||||
if (--dev->count == 0) {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->state = STATE_RXDTA;
|
||||
if (! (dev->mask & DMA_ENA)) {
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->status = STAT_BSY|STAT_REQ;
|
||||
} else {
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
dev->callback = HDC_TIME;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SEEK:
|
||||
if (! drive->present) {
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_NOTRDY;
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Seek to cylinder. */
|
||||
val = dcb->cyl | (dcb->cylh<<2);
|
||||
if (val >= drive->cfg_tracks)
|
||||
drive->cur_cyl = drive->cfg_tracks-1;
|
||||
else
|
||||
drive->cur_cyl = val;
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: seek(%d) %d/%d\n",
|
||||
dcb->drvsel, val, drive->cur_cyl);
|
||||
#endif
|
||||
|
||||
if (val != drive->cur_cyl) {
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_SEEK;
|
||||
}
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_SET_DRIVE_PARAMS:
|
||||
if (dev->state == STATE_RUN) {
|
||||
dev->state = STATE_RXDTA;
|
||||
dev->buf_idx = 0;
|
||||
dev->buf_len = sizeof(struct dprm);
|
||||
dev->buf_ptr = (uint8_t *)&drive->params;
|
||||
dev->status = STAT_BSY|STAT_REQ;
|
||||
} else {
|
||||
dev->buf_ptr=(uint8_t *)&drive->params;
|
||||
pclog("HD20: PARAMS=[");
|
||||
for(val=0;val<8;val++)pclog(" %02x",*dev->buf_ptr++);
|
||||
pclog(" ]\n");
|
||||
#if 0
|
||||
drive->cfg_tracks = drive->params.tracks;
|
||||
drive->cfg_hpc = drive->params.heads;
|
||||
drive->cfg_spt = drive->spt;
|
||||
#endif
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: set_params(%d) cyl=%d,hd=%d,spt=%d\n",
|
||||
dcb->drvsel, drive->cfg_tracks,
|
||||
drive->cfg_hpc, drive->cfg_spt);
|
||||
#endif
|
||||
hd20_intr(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_WRITE_SECTOR_BUFFER:
|
||||
switch (dev->state) {
|
||||
case STATE_RUN:
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: write_sector_buffer(%d)\n",
|
||||
dcb->drvsel);
|
||||
#endif
|
||||
dev->buf_idx = 0;
|
||||
dev->buf_len = 512;
|
||||
dev->state = STATE_RXDTA;
|
||||
if (! (dev->mask & DMA_ENA)) {
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->status = STAT_BSY|STAT_REQ;
|
||||
} else {
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
dev->callback = HDC_TIME;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_RXDTA:
|
||||
dev->status = STAT_BSY;
|
||||
if (! (dev->mask & DMA_ENA)) break;
|
||||
|
||||
while (dev->buf_idx++ < dev->buf_len) {
|
||||
val = dma_channel_read(dev->dma);
|
||||
if (val == DMA_NODATA) {
|
||||
pclog("CMD_WRITE_SECTORS out of data!\n");
|
||||
dev->status = STAT_BSY|STAT_CD|STAT_IO|STAT_REQ;
|
||||
dev->callback = HDC_TIME;
|
||||
return;
|
||||
}
|
||||
|
||||
*dev->buf_ptr++ = (val & 0xff);
|
||||
}
|
||||
dev->state = STATE_RDATA;
|
||||
dev->callback = HDC_TIME;
|
||||
break;
|
||||
|
||||
case STATE_RDATA:
|
||||
if (! (dev->mask & DMA_ENA))
|
||||
memcpy(dev->sector_buf, dev->data, 512);
|
||||
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_RAM_DIAGS:
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: ram_diags\n");
|
||||
#endif
|
||||
dev->callback = 5*HDC_TIME;
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_DRIVE_DIAGS:
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: drive_diags(%d)\n", dcb->drvsel);
|
||||
#endif
|
||||
dev->callback = 5*HDC_TIME;
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
case CMD_CTRL_DIAGS:
|
||||
#if HDC_DEBUG
|
||||
pclog("HD20: ctrl_diags\n");
|
||||
#endif
|
||||
dev->callback = 5*HDC_TIME;
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("HD20: unknown command - %02x\n", dcb->cmd);
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_ILLCMD;
|
||||
hd20_intr(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read one of the HD controller registers. */
|
||||
static uint8_t
|
||||
hd20_read(uint16_t port, void *priv)
|
||||
{
|
||||
hd20_t *dev = (hd20_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port-dev->base) {
|
||||
case 0: /* read data */
|
||||
dev->status &= ~STAT_IRQ;
|
||||
|
||||
if (dev->state == STATE_TXDTA) {
|
||||
if ((dev->status & 0x0f) !=
|
||||
(STAT_IO|STAT_REQ|STAT_BSY))
|
||||
fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", dev->status);
|
||||
if (dev->buf_idx > dev->buf_len) {
|
||||
pclog("HD20: read with empty buffer!\n");
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_ILLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = dev->data[dev->buf_idx++];
|
||||
if (dev->buf_idx == dev->buf_len) {
|
||||
dev->status = STAT_BSY;
|
||||
dev->state = STATE_TDATA;
|
||||
dev->callback = HDC_TIME;
|
||||
}
|
||||
} else if (dev->state == STATE_COMPL) {
|
||||
if ((dev->status & 0x0f) !=
|
||||
(STAT_CD|STAT_IO|STAT_REQ|STAT_BSY))
|
||||
fatal("Read data STATE_COMPL, status=%02x\n", dev->status);
|
||||
ret = dev->comp;
|
||||
dev->status = 0x00;
|
||||
dev->state = STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* read status */
|
||||
ret = dev->status;
|
||||
break;
|
||||
|
||||
case 2: /* read option jumpers */
|
||||
ret = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
#if HDC_DEBUG > 1
|
||||
pclog("HD20: read(%04x) = %02x\n", port, ret);
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hd20_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
hd20_t *dev = (hd20_t *)priv;
|
||||
|
||||
#if HDC_DEBUG > 1
|
||||
pclog("HD20: write(%04x,%02x)\n", port, val);
|
||||
#endif
|
||||
switch (port-dev->base) {
|
||||
case 0: /* write command/data */
|
||||
if (! (dev->status & STAT_REQ)) {
|
||||
pclog("HD20: not ready for command/data!\n");
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_ILLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->buf_idx >= dev->buf_len) {
|
||||
pclog("HD20: write with full buffer!\n");
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_ILLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Store the data into the buffer. */
|
||||
*dev->buf_ptr++ = val;
|
||||
if (++dev->buf_idx == dev->buf_len) {
|
||||
/* We got all the data we need. */
|
||||
dev->status &= ~STAT_REQ;
|
||||
dev->state = (dev->state==STATE_CMD) ? STATE_RUN : STATE_RDATA;
|
||||
dev->callback = HDC_TIME;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* controller reset */
|
||||
dev->sense = 0x00;
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
case 2: /* generate controller-select-pulse */
|
||||
dev->status = STAT_BSY|STAT_CD|STAT_REQ;
|
||||
dev->buf_idx = 0;
|
||||
dev->buf_len = sizeof(struct dcb);
|
||||
dev->buf_ptr = (uint8_t *)&dev->dcb;
|
||||
dev->state = STATE_CMD;
|
||||
break;
|
||||
|
||||
case 3: /* DMA/IRQ mask register */
|
||||
dev->mask = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
hd20_init(const device_t *info)
|
||||
{
|
||||
drive_t *drive;
|
||||
hd20_t *dev;
|
||||
int c, i;
|
||||
|
||||
pclog("EuroPC: initializing HD20 controller.\n");
|
||||
|
||||
dev = malloc(sizeof(hd20_t));
|
||||
memset(dev, 0x00, sizeof(hd20_t));
|
||||
dev->base = HDD_IOADDR;
|
||||
dev->irq = HDD_IRQCHAN;
|
||||
dev->dma = HDD_DMACHAN;
|
||||
|
||||
for (c=0,i=0; i<HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_ST506) && (hdd[i].id.st506_channel < ST506_NUM)) {
|
||||
drive = &dev->drives[hdd[i].id.st506_channel];
|
||||
|
||||
if (! hdd_image_load(i)) {
|
||||
drive->present = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* These are the "hardware" parameters (from the image.) */
|
||||
drive->spt = (uint8_t)(hdd[i].spt & 0xff);
|
||||
drive->hpc = (uint8_t)(hdd[i].hpc & 0xff);
|
||||
drive->tracks = (uint16_t)hdd[i].tracks;
|
||||
|
||||
/* Use them as "configured" parameters until overwritten. */
|
||||
drive->cfg_spt = drive->spt;
|
||||
drive->cfg_hpc = drive->hpc;
|
||||
drive->cfg_tracks = drive->tracks;
|
||||
|
||||
drive->hdd_num = i;
|
||||
drive->present = 1;
|
||||
|
||||
pclog("HD20: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n",
|
||||
hdd[i].id.st506_channel,drive->tracks,drive->hpc,drive->spt,i);
|
||||
|
||||
if (++c > ST506_NUM) break;
|
||||
}
|
||||
}
|
||||
|
||||
io_sethandler(dev->base, 4,
|
||||
hd20_read, NULL, NULL, hd20_write, NULL, NULL, dev);
|
||||
|
||||
timer_add(hd20_callback, &dev->callback, &dev->callback, dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hd20_close(void *priv)
|
||||
{
|
||||
hd20_t *dev = (hd20_t *)priv;
|
||||
drive_t *drive;
|
||||
int d;
|
||||
|
||||
for (d=0; d<2; d++) {
|
||||
drive = &dev->drives[d];
|
||||
|
||||
hdd_image_close(drive->hdd_num);
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hd20_available(void)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
const device_t europc_hdc_device = {
|
||||
"EuroPC HD20",
|
||||
0, 0,
|
||||
hd20_init, hd20_close, NULL,
|
||||
hd20_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the emulated machines.
|
||||
*
|
||||
* Version: @(#)machine.h 1.0.19 2018/04/20
|
||||
* Version: @(#)machine.h 1.0.20 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -234,147 +234,147 @@ extern int romspresent[ROM_MAX];
|
||||
|
||||
|
||||
/* Core functions. */
|
||||
extern int machine_count(void);
|
||||
extern int machine_getromset(void);
|
||||
extern int machine_getmachine(int romset);
|
||||
extern int machine_count(void);
|
||||
extern int machine_getromset(void);
|
||||
extern int machine_getmachine(int romset);
|
||||
extern const char *machine_getname(void);
|
||||
extern const char *machine_get_internal_name(void);
|
||||
extern int machine_get_machine_from_internal_name(const char *s);
|
||||
extern int machine_available(int id);
|
||||
extern int machine_detect(void);
|
||||
extern void machine_init(void);
|
||||
extern void machine_close(void);
|
||||
extern int machine_get_machine_from_internal_name(const char *s);
|
||||
extern int machine_available(int id);
|
||||
extern int machine_detect(void);
|
||||
extern void machine_init(void);
|
||||
extern void machine_close(void);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *machine_getdevice(int machine);
|
||||
#endif
|
||||
extern int machine_getromset_ex(int m);
|
||||
extern int machine_getromset_ex(int m);
|
||||
extern const char *machine_get_internal_name_ex(int m);
|
||||
extern void machine_close(void);
|
||||
extern int machine_get_config_int(const char *s);
|
||||
extern const char *machine_get_config_string(const char *s);
|
||||
|
||||
|
||||
/* Initialization functions for boards and systems. */
|
||||
extern void machine_common_init(const machine_t *, void *);
|
||||
extern void machine_common_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_common_init(const machine_t *, void *);
|
||||
extern void machine_at_init(const machine_t *, void *);
|
||||
extern void machine_at_ps2_init(const machine_t *, void *);
|
||||
extern void machine_at_common_ide_init(const machine_t *, void *);
|
||||
extern void machine_at_ide_init(const machine_t *, void *);
|
||||
extern void machine_at_ps2_ide_init(const machine_t *, void *);
|
||||
extern void machine_at_top_remap_init(const machine_t *, void *);
|
||||
extern void machine_at_ide_top_remap_init(const machine_t *, void *);
|
||||
extern void machine_at_common_init(const machine_t *, void *);
|
||||
extern void machine_at_init(const machine_t *, void *);
|
||||
extern void machine_at_ps2_init(const machine_t *, void *);
|
||||
extern void machine_at_common_ide_init(const machine_t *, void *);
|
||||
extern void machine_at_ide_init(const machine_t *, void *);
|
||||
extern void machine_at_ps2_ide_init(const machine_t *, void *);
|
||||
extern void machine_at_top_remap_init(const machine_t *, void *);
|
||||
extern void machine_at_ide_top_remap_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_ibm_init(const machine_t *, void *);
|
||||
extern void machine_at_ibm_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_t3100e_init(const machine_t *, void *);
|
||||
extern void machine_at_t3100e_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_p54tp4xe_init(const machine_t *, void *);
|
||||
extern void machine_at_endeavor_init(const machine_t *, void *);
|
||||
extern void machine_at_p54tp4xe_init(const machine_t *, void *);
|
||||
extern void machine_at_endeavor_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t s3_phoenix_trio64_onboard_pci_device;
|
||||
#define m_at_endeavor_device s3_phoenix_trio64_onboard_pci_device
|
||||
extern const device_t s3_phoenix_trio64_onboard_pci_device;
|
||||
#endif
|
||||
extern void machine_at_zappa_init(const machine_t *, void *);
|
||||
extern void machine_at_mb500n_init(const machine_t *, void *);
|
||||
extern void machine_at_president_init(const machine_t *, void *);
|
||||
extern void machine_at_thor_init(const machine_t *, void *);
|
||||
extern void machine_at_zappa_init(const machine_t *, void *);
|
||||
extern void machine_at_mb500n_init(const machine_t *, void *);
|
||||
extern void machine_at_president_init(const machine_t *, void *);
|
||||
extern void machine_at_thor_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_acerm3a_init(const machine_t *, void *);
|
||||
extern void machine_at_acerv35n_init(const machine_t *, void *);
|
||||
extern void machine_at_ap53_init(const machine_t *, void *);
|
||||
extern void machine_at_p55t2p4_init(const machine_t *, void *);
|
||||
extern void machine_at_p55t2s_init(const machine_t *, void *);
|
||||
extern void machine_at_acerm3a_init(const machine_t *, void *);
|
||||
extern void machine_at_acerv35n_init(const machine_t *, void *);
|
||||
extern void machine_at_ap53_init(const machine_t *, void *);
|
||||
extern void machine_at_p55t2p4_init(const machine_t *, void *);
|
||||
extern void machine_at_p55t2s_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_batman_init(const machine_t *, void *);
|
||||
extern void machine_at_plato_init(const machine_t *, void *);
|
||||
extern void machine_at_batman_init(const machine_t *, void *);
|
||||
extern void machine_at_plato_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_p55tvp4_init(const machine_t *, void *);
|
||||
extern void machine_at_i430vx_init(const machine_t *, void *);
|
||||
extern void machine_at_p55va_init(const machine_t *, void *);
|
||||
extern void machine_at_p55tvp4_init(const machine_t *, void *);
|
||||
extern void machine_at_i430vx_init(const machine_t *, void *);
|
||||
extern void machine_at_p55va_init(const machine_t *, void *);
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
extern void machine_at_i440fx_init(const machine_t *, void *);
|
||||
extern void machine_at_s1668_init(const machine_t *, void *);
|
||||
extern void machine_at_i440fx_init(const machine_t *, void *);
|
||||
extern void machine_at_s1668_init(const machine_t *, void *);
|
||||
#endif
|
||||
extern void machine_at_ali1429_init(const machine_t *, void *);
|
||||
extern void machine_at_cmdpc_init(const machine_t *, void *);
|
||||
extern void machine_at_ali1429_init(const machine_t *, void *);
|
||||
extern void machine_at_cmdpc_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_headland_init(const machine_t *, void *);
|
||||
extern void machine_at_neat_init(const machine_t *, void *);
|
||||
extern void machine_at_neat_ami_init(const machine_t *, void *);
|
||||
extern void machine_at_opti495_init(const machine_t *, void *);
|
||||
extern void machine_at_opti495_ami_init(const machine_t *, void *);
|
||||
extern void machine_at_scat_init(const machine_t *, void *);
|
||||
extern void machine_at_scatsx_init(const machine_t *, void *);
|
||||
extern void machine_at_compaq_init(const machine_t *, void *);
|
||||
extern void machine_at_headland_init(const machine_t *, void *);
|
||||
extern void machine_at_neat_init(const machine_t *, void *);
|
||||
extern void machine_at_neat_ami_init(const machine_t *, void *);
|
||||
extern void machine_at_opti495_init(const machine_t *, void *);
|
||||
extern void machine_at_opti495_ami_init(const machine_t *, void *);
|
||||
extern void machine_at_scat_init(const machine_t *, void *);
|
||||
extern void machine_at_scatsx_init(const machine_t *, void *);
|
||||
extern void machine_at_compaq_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_dtk486_init(const machine_t *, void *);
|
||||
extern void machine_at_r418_init(const machine_t *, void *);
|
||||
extern void machine_at_dtk486_init(const machine_t *, void *);
|
||||
extern void machine_at_r418_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_at_wd76c10_init(const machine_t *, void *);
|
||||
extern void machine_at_wd76c10_init(const machine_t *, void *);
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_GREENB)
|
||||
extern void machine_at_4gpv31_init(const machine_t *, void *);
|
||||
extern void machine_at_4gpv31_init(const machine_t *, void *);
|
||||
#endif
|
||||
|
||||
extern void machine_pcjr_init(const machine_t *, void *);
|
||||
extern void machine_pcjr_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t m_pcjr_device;
|
||||
#endif
|
||||
|
||||
extern void machine_ps1_m2011_init(const machine_t *, void *);
|
||||
extern void machine_ps1_m2121_init(const machine_t *, void *);
|
||||
extern void machine_ps1_m2133_init(const machine_t *, void *);
|
||||
extern void machine_ps1_m2011_init(const machine_t *, void *);
|
||||
extern void machine_ps1_m2121_init(const machine_t *, void *);
|
||||
extern void machine_ps1_m2133_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern void ps1_hdc_inform(void *, void *);
|
||||
extern void ps1_set_feedback(void *);
|
||||
extern void ps1_hdc_inform(void *, void *);
|
||||
extern void ps1_set_feedback(void *);
|
||||
extern const device_t m_ps1_device;
|
||||
extern const device_t ps1_hdc_device;
|
||||
#endif
|
||||
|
||||
extern void machine_ps2_m30_286_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_50_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_55sx_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_70_type3_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_70_type4_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_80_init(const machine_t *, void *);
|
||||
extern void machine_ps2_m30_286_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_50_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_55sx_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_70_type3_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_70_type4_init(const machine_t *, void *);
|
||||
extern void machine_ps2_model_80_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_amstrad_init(const machine_t *, void *);
|
||||
extern void machine_amstrad_init(const machine_t *, void *);
|
||||
|
||||
extern void machine_europc_init(const machine_t *, void *);
|
||||
extern void machine_europc_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t europc_device, europc_hdc_device;
|
||||
extern const device_t m_europc_device;
|
||||
#endif
|
||||
|
||||
extern void machine_olim24_init(const machine_t *, void *);
|
||||
extern void machine_olim24_video_init(void);
|
||||
extern void machine_olim24_init(const machine_t *, void *);
|
||||
extern void machine_olim24_video_init(void);
|
||||
|
||||
extern void machine_tandy1k_init(const machine_t *, void *);
|
||||
extern void machine_tandy1k_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t m_tandy1k_device;
|
||||
extern const device_t m_tandy1k_hx_device;
|
||||
extern const device_t m_tandy1k_sl2_device;
|
||||
#endif
|
||||
extern int tandy1k_eeprom_read(void);
|
||||
extern int tandy1k_eeprom_read(void);
|
||||
|
||||
extern void machine_xt_init(const machine_t *, void *);
|
||||
extern void machine_xt_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t m_xt_device;
|
||||
#endif
|
||||
|
||||
extern void machine_xt_compaq_init(const machine_t *, void *);
|
||||
extern void machine_xt_compaq_init(const machine_t *, void *);
|
||||
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
|
||||
extern void machine_xt_laserxt_init(const machine_t *, void *);
|
||||
extern void machine_xt_laserxt_init(const machine_t *, void *);
|
||||
#endif
|
||||
|
||||
extern void machine_xt_t1000_init(const machine_t *, void *);
|
||||
extern void machine_xt_t1000_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t m_xt_t1000_device;
|
||||
#endif
|
||||
extern void machine_xt_t1200_init(const machine_t *, void *);
|
||||
extern void machine_xt_t1x00_close(void);
|
||||
extern void machine_xt_t1200_init(const machine_t *, void *);
|
||||
extern void machine_xt_t1x00_close(void);
|
||||
|
||||
extern void machine_xt_xi8088_init(const machine_t *, void *);
|
||||
extern void machine_xt_xi8088_init(const machine_t *, void *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t m_xi8088_device;
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* NOTES: OpenAT wip for 286-class machine with open BIOS.
|
||||
* PS2_M80-486 wip, pending receipt of TRM's for machine.
|
||||
*
|
||||
* Version: @(#)machine_table.c 1.0.19 2018/04/20
|
||||
* Version: @(#)machine_table.c 1.0.20 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../emu.h"
|
||||
#include "../config.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../mem.h"
|
||||
#include "../nvr.h"
|
||||
@@ -142,7 +143,7 @@ const machine_t machines[] = {
|
||||
{ "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "intel_plato", L"intel/plato", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 128, machine_at_plato_init, NULL, NULL },
|
||||
|
||||
{ "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "asus_p54tp4xe", L"asus/p54tp4xe", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_p54tp4xe_init, NULL, NULL },
|
||||
{ "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "intel_endeavor", L"intel/endeavor", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 128, machine_at_endeavor_init, &m_at_endeavor_device, NULL },
|
||||
{ "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "intel_endeavor", L"intel/endeavor", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 128, machine_at_endeavor_init, &s3_phoenix_trio64_onboard_pci_device, NULL },
|
||||
{ "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "intel_zappa", L"intel/zappa", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 128, machine_at_zappa_init, NULL, NULL },
|
||||
{ "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "pcpartner_mb500n", L"pcpartner/mb500n", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_mb500n_init, NULL, NULL },
|
||||
{ "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", L"president/president", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_president_init, NULL, NULL },
|
||||
@@ -269,3 +270,43 @@ machine_get_machine_from_internal_name(const char *s)
|
||||
/* Not found. */
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_get_config_int(const 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(d->name, s, c->default_int));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
machine_get_config_string(const 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(d->name, s, c->default_string));
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* or to use a generic handler, and then pass it a pointer
|
||||
* to a command table. For now, we don't.
|
||||
*
|
||||
* Version: @(#)rom_load.c 1.0.7 2018/04/01
|
||||
* Version: @(#)rom_load.c 1.0.8 2018/04/25
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -60,6 +60,7 @@
|
||||
#include <wchar.h>
|
||||
#include <ctype.h>
|
||||
#include "emu.h"
|
||||
#include "machine/machine.h"
|
||||
#include "mem.h"
|
||||
#include "rom.h"
|
||||
#include "device.h"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* website (for 32bit and 64bit Windows) are working, and
|
||||
* need no additional support files other than sound fonts.
|
||||
*
|
||||
* Version: @(#)midi_fluidsynth.c 1.0.6 2018/03/31
|
||||
* Version: @(#)midi_fluidsynth.c 1.0.7 2018/04/25
|
||||
*
|
||||
* Code borrowed from scummvm.
|
||||
*
|
||||
@@ -293,7 +293,7 @@ fluidsynth_init(const device_t *info)
|
||||
|
||||
data->synth = f_new_fluid_synth(data->settings);
|
||||
|
||||
char* sound_font = device_get_config_string("sound_font");
|
||||
const char *sound_font = device_get_config_string("sound_font");
|
||||
data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1);
|
||||
|
||||
if (device_get_config_int("chorus")) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Application resource script for Windows.
|
||||
*
|
||||
* Version: @(#)VARCem.rc 1.0.20 2018/04/23
|
||||
* Version: @(#)VARCem.rc 1.0.21 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -542,8 +542,9 @@ BEGIN
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12
|
||||
|
||||
LTEXT "HD Controller:",IDT_1717,7,26,61,10
|
||||
COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST |
|
||||
COMBOBOX IDC_COMBO_HDC,71,25,140,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_HDC,214,25,46,12
|
||||
|
||||
LTEXT "Tertiary IDE:",IDT_1718,7,44,61,10
|
||||
COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST |
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Windows systems using the MinGW32 environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.28 2018/04/23
|
||||
# Version: @(#)Makefile.mingw 1.0.30 2018/04/24
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -119,9 +119,6 @@ endif
|
||||
ifndef I686
|
||||
I686 := n
|
||||
endif
|
||||
ifndef XTA
|
||||
XTA := n
|
||||
endif
|
||||
ifndef OPENAL
|
||||
OPENAL := y
|
||||
endif
|
||||
@@ -447,10 +444,6 @@ ifeq ($(DEV_BRANCH), y)
|
||||
DEVBROBJ += m_at_440fx.o
|
||||
endif
|
||||
|
||||
ifeq ($(XTA), y)
|
||||
OPTS += -DUSE_XTA
|
||||
endif
|
||||
|
||||
ifeq ($(STEALTH32), y)
|
||||
OPTS += -DUSE_STEALTH32
|
||||
DEVBROBJ += vid_icd2061.o
|
||||
@@ -510,8 +503,7 @@ MCHOBJ := machine.o machine_table.o \
|
||||
m_xt_t1000.o m_xt_t1000_vid.o \
|
||||
m_xt_xi8088.o \
|
||||
m_pcjr.o \
|
||||
m_amstrad.o \
|
||||
m_europc.o m_europc_hdc.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 \
|
||||
@@ -547,10 +539,7 @@ HDDOBJ := hdd.o \
|
||||
hdc.o \
|
||||
hdc_st506_xt.o hdc_st506_at.o \
|
||||
hdc_esdi_at.o hdc_esdi_mca.o \
|
||||
hdc_ide.o hdc_xtide.o
|
||||
ifeq ($(XTA), y)
|
||||
HDDOBJ += hdc_ide_xta.o
|
||||
endif
|
||||
hdc_ide.o hdc_xtide.o hdc_ide_xta.o
|
||||
|
||||
CDROMOBJ := cdrom.o \
|
||||
cdrom_dosbox.o cdrom_image.o cdrom_null.o
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Windows using Visual Studio 2015.
|
||||
#
|
||||
# Version: @(#)Makefile.VC 1.0.14 2018/04/23
|
||||
# Version: @(#)Makefile.VC 1.0.16 2018/04/24
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -119,9 +119,6 @@ endif
|
||||
ifndef I686
|
||||
I686 := n
|
||||
endif
|
||||
ifndef XTA
|
||||
XTA := n
|
||||
endif
|
||||
ifndef OPENAL
|
||||
OPENAL := y
|
||||
endif
|
||||
@@ -415,10 +412,6 @@ ifeq ($(DEV_BRANCH), y)
|
||||
DEVBROBJ += m_at_440fx.obj
|
||||
endif
|
||||
|
||||
ifeq ($(XTA), y)
|
||||
OPTS += -DUSE_XTA
|
||||
endif
|
||||
|
||||
ifeq ($(STEALTH32), y)
|
||||
OPTS += -DUSE_STEALTH32
|
||||
DEVBROBJ += vid_icd2061.obj
|
||||
@@ -475,8 +468,7 @@ MCHOBJ := machine.obj machine_table.obj \
|
||||
m_xt_t1000.obj m_xt_t1000_vid.obj \
|
||||
m_xt_xi8088.obj \
|
||||
m_pcjr.obj \
|
||||
m_amstrad.obj \
|
||||
m_europc.obj m_europc_hdc.obj \
|
||||
m_amstrad.obj m_europc.obj \
|
||||
m_olivetti_m24.obj m_tandy.obj \
|
||||
m_at.obj \
|
||||
m_at_ali1429.obj m_at_commodore.obj \
|
||||
@@ -512,10 +504,7 @@ HDDOBJ := hdd.obj \
|
||||
hdc.obj \
|
||||
hdc_st506_xt.obj hdc_st506_at.obj \
|
||||
hdc_esdi_at.obj hdc_esdi_mca.obj \
|
||||
hdc_ide.obj hdc_xtide.obj
|
||||
ifeq ($(XTA), y)
|
||||
HDDOBJ += hdc_ide_xta.o
|
||||
#endif
|
||||
hdc_ide.obj hdc_xtide.obj hdc_ide_xta.o
|
||||
|
||||
CDROMOBJ := cdrom.obj \
|
||||
cdrom_dosbox.obj cdrom_image.obj cdrom_null.obj
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Windows resource defines.
|
||||
*
|
||||
* Version: @(#)resource.h 1.0.10 2018/04/08
|
||||
* Version: @(#)resource.h 1.0.11 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -178,9 +178,10 @@
|
||||
#define IDC_COMBO_SCSI 1121
|
||||
#define IDC_CONFIGURE_SCSI 1122
|
||||
#define IDC_COMBO_HDC 1123
|
||||
#define IDC_COMBO_IDE_TER 1124
|
||||
#define IDC_COMBO_IDE_QUA 1125
|
||||
#define IDC_CHECK_BUGGER 1126
|
||||
#define IDC_CONFIGURE_HDC 1124
|
||||
#define IDC_COMBO_IDE_TER 1125
|
||||
#define IDC_COMBO_IDE_QUA 1126
|
||||
#define IDC_CHECK_BUGGER 1127
|
||||
|
||||
#define IDC_HARD_DISKS 1130 /* hard disk config */
|
||||
#define IDC_LIST_HARD_DISKS 1131
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* and builds a complete Win32 DIALOG resource block in a
|
||||
* buffer in memory, and then passes that to the API handler.
|
||||
*
|
||||
* Version: @(#)win_devconf.c 1.0.10 2018/04/14
|
||||
* Version: @(#)win_devconf.c 1.0.11 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -476,11 +476,11 @@ deviceconfig_open(HWND hwnd, device_t *device)
|
||||
*data++ = 0; /* no menu bar */
|
||||
*data++ = 0; /* predefined dialog box class */
|
||||
sprintf(temp, "%s Configuration", device->name);
|
||||
data += MultiByteToWideChar(CP_ACP, 0, temp, -1, data, 50);
|
||||
data += MultiByteToWideChar(CP_ACP, 0, temp, -1, data, 120);
|
||||
|
||||
/* Font style and size to use. */
|
||||
*data++ = 9; /* point size */
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50);
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 120);
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Settings dialog.
|
||||
*
|
||||
* Version: @(#)win_settings_periph.h 1.0.3 2018/04/10
|
||||
* Version: @(#)win_settings_periph.h 1.0.4 2018/04/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -171,6 +171,12 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC);
|
||||
if (hdc_has_config(temp_hdc_type))
|
||||
EnableWindow(h, TRUE);
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
recalc_hdc_list(hdlg, temp_machine, 0);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER);
|
||||
@@ -209,6 +215,13 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card));
|
||||
break;
|
||||
|
||||
case IDC_CONFIGURE_HDC:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HDC);
|
||||
temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]);
|
||||
|
||||
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)hdc_get_device(temp_hdc_type));
|
||||
break;
|
||||
|
||||
case IDC_COMBO_SCSI:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_SCSI);
|
||||
temp_scsi_card = list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)];
|
||||
@@ -219,6 +232,17 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
break;
|
||||
|
||||
case IDC_COMBO_HDC:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HDC);
|
||||
temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC);
|
||||
if (hdc_has_config(temp_hdc_type))
|
||||
EnableWindow(h, TRUE);
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Status Bar module.
|
||||
*
|
||||
* Version: @(#)win_stbar.c 1.0.10 2018/04/23
|
||||
* Version: @(#)win_stbar.c 1.0.11 2018/04/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -667,7 +667,7 @@ ui_sb_update_panes(void)
|
||||
/* Could be Internal or External IDE.. */
|
||||
if (((cdrom_drives[i].bus_type==CDROM_BUS_ATAPI_PIO_ONLY) &&
|
||||
(cdrom_drives[i].bus_type==CDROM_BUS_ATAPI_PIO_AND_DMA)) &&
|
||||
!(hdint || !strncmp(hdc, "ide", 3))) {
|
||||
!(hdint || !strncmp(hdc, "ide", 3) || !strncmp(hdc, "xta", 3))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ ui_sb_update_panes(void)
|
||||
/* Could be Internal or External IDE.. */
|
||||
if (((zip_drives[i].bus_type==ZIP_BUS_ATAPI_PIO_ONLY) &&
|
||||
(zip_drives[i].bus_type==ZIP_BUS_ATAPI_PIO_AND_DMA)) &&
|
||||
!(hdint || !strncmp(hdc, "ide", 3))) {
|
||||
!(hdint || !strncmp(hdc, "ide", 3) || !strncmp(hdc, "xta", 3))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ ui_sb_update_panes(void)
|
||||
/* ESDI drives, and ESDI or Internal controller. */
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_ide_pio && (hdint || !strncmp(hdc, "ide", 3))) {
|
||||
if (c_ide_pio && (hdint || !strncmp(hdc, "ide", 3) || !strncmp(hdc, "xta", 3))) {
|
||||
/* IDE_PIO drives, and IDE or Internal controller. */
|
||||
sb_parts++;
|
||||
}
|
||||
@@ -813,7 +813,7 @@ ui_sb_update_panes(void)
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ESDI;
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_ide_pio && (hdint || !strncmp(hdc, "ide", 3))) {
|
||||
if (c_ide_pio && (hdint || !strncmp(hdc, "ide", 3) || !strncmp(hdc, "xta", 3))) {
|
||||
edge += SB_ICON_WIDTH;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE_PIO_ONLY;
|
||||
|
||||
Reference in New Issue
Block a user