IMDS-225: Initial check in of new experimental simulator for the Intel MDS-225 IPC

This commit is contained in:
Bill Beech 2016-07-15 13:13:12 -07:00 committed by Mark Pizzolato
parent cdb94a9d9f
commit 27e65d1fa9
10 changed files with 1811 additions and 0 deletions

View file

@ -0,0 +1,125 @@
/* ioc-cont.c: Intel IPC DBB adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
27 Jun 16 - Original file.
NOTES:
*/
#include "system_defs.h" /* system header in system dir */
/* function prototypes */
uint8 ioc_cont(t_bool io, uint8 data, uint8 devnum); /* ioc_cont*/
t_stat ioc_cont_reset (DEVICE *dptr, uint16 base, uint8 devnum);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16 port, uint8 devnum);
extern uint32 saved_PC; /* program counter */
/* globals */
UNIT ioc_cont_unit[] = {
{ UDATA (0, 0, 0) }, /* ioc_cont*/
};
REG ioc_cont_reg[] = {
{ HRDATA (CONTROL0, ioc_cont_unit[0].u3, 8) }, /* ioc_cont */
{ NULL }
};
DEBTAB ioc_cont_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE ioc_cont_dev = {
"IOC-CONT", //name
ioc_cont_unit, //units
ioc_cont_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &ioc_cont_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
ioc_cont_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* IOC control port functions */
uint8 ioc_cont(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read status port */
sim_printf(" ioc_cont: read data=%02X port=%02X returned 0x00 from PC=%04X\n", data, devnum, saved_PC);
return 0x00;
} else { /* write control port */
sim_printf(" ioc_cont: data=%02X port=%02X\n", data, devnum);
}
}
/* Reset routine */
t_stat ioc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum)
{
reg_dev(ioc_cont, base, devnum);
reg_dev(ioc_cont, base + 1, devnum);
ioc_cont_unit[devnum].u3 = 0x00; /* ipc reset */
sim_printf(" ioc_cont[%d]: Reset\n", devnum);
sim_printf(" ioc_cont[%d]: Registered at %04X\n", devnum, base);
return SCPE_OK;
}
/* end of ioc-cont.c */

View file

@ -0,0 +1,160 @@
/* ipc-cont.c: Intel IPC control port PIO adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
07 Jun 16 - Original file.
NOTES:
*/
#include "system_defs.h" /* system header in system dir */
/* function prototypes */
uint8 ipc_cont(t_bool io, uint8 data, uint8 devnum); /* ipc_cont*/
t_stat ipc_cont_reset (DEVICE *dptr, uint16 base, uint8 devnum);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16 port, uint8 devnum);
/* globals */
UNIT ipc_cont_unit[] = {
{ UDATA (0, 0, 0) }, /* ipc_cont*/
};
REG ipc_cont_reg[] = {
{ HRDATA (CONTROL0, ipc_cont_unit[0].u3, 8) }, /* ipc_cont */
{ NULL }
};
DEBTAB ipc_cont_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE ipc_cont_dev = {
"IPC-CONT", //name
ipc_cont_unit, //units
ipc_cont_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &ipc_cont_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
ipc_cont_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* IPC control port functions */
uint8 ipc_cont(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read status port */
sim_printf(" ipc_cont: read data=%02X port=%02X returned 0xFF\n", ipc_cont_unit[devnum].u3, devnum);
return ipc_cont_unit[devnum].u3;
} else { /* write control port */
//this simulates an 74ls259 register
//d0-d2 address the reg(in reverse order!), d3 is the data to be latched
switch(data & 0x07) {
case 5: //interrupt enable
if(data & 0x08) //bit high
ipc_cont_unit[0].u3 |= 0x10;
else //bit low
ipc_cont_unit[0].u3 &= 0xEF;
break;
case 4: //*selboot
if(data & 0x08) //bit high
ipc_cont_unit[0].u3 |= 0x08;
else //bit low
ipc_cont_unit[0].u3 &= 0xF7;
break;
case 2: //*startup
if(data & 0x08) //bit high
ipc_cont_unit[0].u3 |= 0x04;
else //bit low
ipc_cont_unit[0].u3 &= 0xFB;
break;
case 1: //over ride
if(data & 0x08) //bit high
ipc_cont_unit[0].u3 |= 0x02;
else //bit low
ipc_cont_unit[0].u3 &= 0xFD;
break;
case 0: //aux prom enable
if(data & 0x08) //bit high
ipc_cont_unit[0].u3 |= 0x01;
else //bit low
ipc_cont_unit[0].u3 &= 0xFE;
break;
default:
break;
}
sim_printf(" ipc_cont: data=%02X ipc_cont[%d]=%02X\n", data, devnum, ipc_cont_unit[0].u3);
}
return 0;
}
/* Reset routine */
t_stat ipc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum)
{
reg_dev(ipc_cont, base, devnum);
ipc_cont_unit[devnum].u3 = 0x00; /* ipc reset */
sim_printf(" ipc_cont[%d]: Reset\n", devnum);
sim_printf(" ipc_cont[%d]: Registered at %04X\n", devnum, base);
return SCPE_OK;
}
/* end of ipc-cont.c */

View file

@ -0,0 +1,187 @@
/* iEPROM.c: Intel EPROM simulator for 8-bit SBCs
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated ROM devices on an iSBC-80/XX SBCs.
This allows the attachment of the device to a binary file containing the EPROM
code image. Unit will support a single 2708, 2716, 2732, or 2764 type EPROM.
These functions also support bit 1 of 8255 number 1, port B, to enable/
disable the onboard ROM.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* function prototypes */
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
t_stat EPROM_reset (DEVICE *dptr, uint16 size);
uint8 EPROM_get_mbyte(uint16 addr);
/* external function prototypes */
extern uint8 xack; /* XACK signal */
/* SIMH EPROM Standard I/O Data Structures */
UNIT EPROM_unit = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0), 0
};
DEBTAB EPROM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE EPROM_dev = {
"EPROM", //name
&EPROM_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &EPROM_reset, //reset
NULL, //reset
NULL, //boot
&EPROM_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
EPROM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
/* EPROM functions */
/* EPROM attach */
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr)
{
uint16 j;
int c;
FILE *fp;
t_stat r;
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n");
return r;
}
sim_debug (DEBUG_read, &EPROM_dev, "\tAllocate buffer\n");
if (EPROM_unit.filebuf == NULL) { /* no buffer allocated */
EPROM_unit.filebuf = malloc(EPROM_unit.capac); /* allocate EPROM buffer */
if (EPROM_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Malloc error\n");
return SCPE_MEM;
}
}
sim_debug (DEBUG_read, &EPROM_dev, "\tOpen file %s\n", EPROM_unit.filename);
fp = fopen(EPROM_unit.filename, "rb"); /* open EPROM file */
if (fp == NULL) {
sim_printf("EPROM: Unable to open ROM file %s\n", EPROM_unit.filename);
sim_printf("\tNo ROM image loaded!!!\n");
return SCPE_OK;
}
sim_debug (DEBUG_read, &EPROM_dev, "\tRead file\n");
j = 0; /* load EPROM file */
c = fgetc(fp);
while (c != EOF) {
*((uint8 *)EPROM_unit.filebuf + j++) = c & 0xFF;
c = fgetc(fp);
if (j > EPROM_unit.capac) {
sim_printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
sim_printf("\tImage size=%04X unit_capac=%04X\n", j, EPROM_unit.capac);
sim_debug (DEBUG_read, &EPROM_dev, "\tClose file\n");
fclose(fp);
sim_printf("EPROM: %d bytes of ROM image %s loaded\n", j, EPROM_unit.filename);
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Done\n");
return SCPE_OK;
}
/* EPROM reset */
t_stat EPROM_reset (DEVICE *dptr, uint16 size)
{
// sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=0000 size=%04X\n", size);
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
EPROM_unit.capac = size; /* set EPROM size to 0 */
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
// sim_printf(" EPROM: Available [%04X-%04XH]\n",
// 0, EPROM_unit.capac - 1);
return SCPE_OK;
}
if ((EPROM_unit.flags & UNIT_ATT) == 0) {
sim_printf("EPROM: No file attached\n");
}
sim_debug (DEBUG_flow, &EPROM_dev, "Done2\n");
return SCPE_OK;
}
/* get a byte from memory */
uint8 EPROM_get_mbyte(uint16 addr)
{
uint8 val;
sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%04X\n", addr);
if (addr < EPROM_unit.capac) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &EPROM_dev, "EPROM_get_mbyte: Set XACK for %04X\n", addr);
val = *((uint8 *)EPROM_unit.filebuf + addr);
sim_debug (DEBUG_read, &EPROM_dev, " val=%04X\n", val);
return (val & 0xFF);
}
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
return 0xFF;
}
/* end of iEPROM.c */

View file

@ -0,0 +1,258 @@
/* ipcmultibus.c: Multibus I simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
int32 mbirq = 0; /* set no multibus interrupts */
/* function prototypes */
t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num);
void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 data, uint8 devnum);
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num);
extern UNIT zx200a_unit;
extern t_stat zx200a_reset(DEVICE *dptr, uint16 base, uint8 devnum);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
/* multibus Standard SIMH Device Data Structures */
UNIT multibus_unit = {
UDATA (&multibus_svc, 0, 0), 20
};
REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) }
};
DEBTAB multibus_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE multibus_dev = {
"MBIRQ", //name
&multibus_unit, //units
multibus_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&multibus_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
multibus_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_1:
set_cpuint(INT_R);
#if NIPC
clr_irq(SBC202_INT); /***** bad, bad, bad! */
#endif
// sim_printf("multibus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
break;
default:
// sim_printf("multibus_svc: default mbirq=%04X\n", mbirq);
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
return SCPE_OK;
}
/* Reset routine */
t_stat multibus_reset(DEVICE *dptr)
{
SBC_reset(NULL);
zx200a_reset(NULL, ZX200A_BASE_DD, 0);
zx200a_reset(NULL, ZX200A_BASE_SD, 0);
sim_printf(" Multibus: Reset\n");
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
}
void set_irq(int32 int_num)
{
mbirq |= int_num;
// sim_printf("set_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
void clr_irq(int32 int_num)
{
mbirq &= ~int_num;
// sim_printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
/* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered.
*/
struct idev {
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 devnum;
};
struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
};
uint8 nulldev(t_bool flag, uint8 data, uint8 devnum)
{
SET_XACK(0); /* set no XACK */
if (flag == 0) /* if we got here, no valid I/O device */
return (0xFF);
return 0;
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
// sim_printf("Multibus: I/O Port %02X is already assigned\n", port);
} else {
// sim_printf("Port %02X is assigned\n", port);
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* end of ipcmultibus.c */

View file

@ -0,0 +1,164 @@
/* iRAM8.c: Intel RAM simulator for 8-bit SBCs
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 11 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated RAM devices on an iSBC-80/XX SBCs.
These functions also support bit 2 of 8255 number 1, port B, to enable/
disable the onboard RAM.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* function prototypes */
t_stat RAM_svc (UNIT *uptr);
t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
uint8 RAM_get_mbyte(uint16 addr);
void RAM_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */
extern UNIT i8255_unit[];
extern uint8 xack; /* XACK signal */
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
DEBTAB RAM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE RAM_dev = {
"RAM", //name
&RAM_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &RAM_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
RAM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
/* RAM functions */
/* RAM reset */
t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size)
{
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1);
if (RAM_unit.capac == 0) { /* if undefined */
RAM_unit.capac = size;
RAM_unit.u3 = base;
}
if (RAM_unit.filebuf == NULL) { /* no buffer allocated */
RAM_unit.filebuf = malloc(RAM_unit.capac);
if (RAM_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &RAM_dev, "RAM_set_size: Malloc error\n");
return SCPE_MEM;
}
}
// sim_printf(" RAM: Available [%04X-%04XH]\n",
// RAM_unit.u3,
// RAM_unit.u3 + RAM_unit.capac - 1);
sim_debug (DEBUG_flow, &RAM_dev, "RAM_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
uint8 RAM_get_mbyte(uint16 addr)
{
uint8 val;
if (i8255_unit[0].u5 & 0x02) { /* enable RAM */
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
if ((addr >= RAM_unit.u3) && ((uint32) addr < (RAM_unit.u3 + RAM_unit.capac))) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &RAM_dev, "RAM_get_mbyte: Set XACK for %04X\n", addr);
val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3));
sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val);
return (val & 0xFF);
}
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
return 0xFF;
}
sim_debug (DEBUG_read, &RAM_dev, " RAM disabled\n");
return 0xFF;
}
/* put a byte to memory */
void RAM_put_mbyte(uint16 addr, uint8 val)
{
if (i8255_unit[0].u5 & 0x02) { /* enable RAM */
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if ((addr >= RAM_unit.u3) && ((uint32)addr < RAM_unit.u3 + RAM_unit.capac)) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &RAM_dev, "RAM_put_mbyte: Set XACK for %04X\n", addr);
*((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
sim_debug (DEBUG_write, &RAM_dev, "\n");
return;
}
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
return;
}
sim_debug (DEBUG_write, &RAM_dev, " RAM disabled\n");
}
/* end of iRAM8.c */

View file

@ -0,0 +1,130 @@
/* isbc202.c: Intel double density disk adapter adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
27 Jun 16 - Original file.
NOTES:
*/
#include "system_defs.h" /* system header in system dir */
/* function prototypes */
uint8 isbc202(t_bool io, uint8 data, uint8 devnum); /* isbc202*/
t_stat isbc202_reset(DEVICE *dptr, uint16 base, uint8 devnum);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16 port, uint8 devnum);
/* globals */
UNIT isbc202_unit[] = {
{ UDATA (0, 0, 0) }, /* isbc202*/
};
REG isbc202_reg[] = {
{ HRDATA (CONTROL0, isbc202_unit[0].u3, 8) }, /* isbc202 */
{ NULL }
};
DEBTAB isbc202_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE isbc202_dev = {
"ISBC202", //name
isbc202_unit, //units
isbc202_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &isbc202_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
isbc202_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* ISBC202 control port functions */
uint8 isbc202(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* always return 0 */
sim_printf(" isbc202: read data=%02X port=%02X returned 0\n", data, devnum);
return 0x00;
} else { /* write control port */
sim_printf(" isbc202: data=%02X port=%02X\n", data, devnum);
}
}
/* Reset routine */
t_stat isbc202_reset(DEVICE *dptr, uint16 base, uint8 devnum)
{
reg_dev(isbc202, base, devnum);
reg_dev(isbc202, base + 1, devnum);
reg_dev(isbc202, base + 2, devnum);
reg_dev(isbc202, base + 3, devnum);
reg_dev(isbc202, base + 4, devnum);
reg_dev(isbc202, base + 5, devnum);
reg_dev(isbc202, base + 6, devnum);
reg_dev(isbc202, base + 7, devnum);
isbc202_unit[devnum].u3 = 0x00; /* ipc reset */
sim_printf(" isbc202-%d: Reset\n", devnum);
sim_printf(" isbc202-%d: Registered at %04X\n", devnum, base);
return SCPE_OK;
}
/* end of isbc202.c */

View file

@ -0,0 +1,444 @@
/* zx-200a.c: Intel double density disk adapter adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
28 Jun 16 - Original file.
NOTES:
This controller will mount 4 DD disk images on drives :F0: thru :F3: addressed
at ports 078H to 07FH. It also will mount 2 SD disk images on :F4: and :F5:
addressed at ports 088H to 08FH. These are on physical drives :F0: and :F1:.
Registers:
078H - Read - Subsystem status
bit 0 - ready status of drive 0
bit 1 - ready status of drive 1
bit 2 - state of channel's interrupt FF
bit 3 - controller presence indicator
bit 4 - DD controller presence indicator
bit 5 - ready status of drive 2
bit 6 - ready status of drive 3
bit 7 - zero
079H - Read - Read result type (bits 2-7 are zero)
00 - I/O complete with error
01 - Reserved
10 - Result byte contains diskette ready status
11 - Reserved
079H - Write - IOPB address low byte.
07AH - Write - IOPB address high byte and start operation.
07BH - Read - Read result byte
If result type is 00H
bit 0 - deleted record
bit 1 - CRC error
bit 2 - seek error
bit 3 - address error
bit 4 - data overrun/underrun
bit 5 - write protect
bit 6 - write error
bit 7 - not ready
If result type is 10H
bit 0 - zero
bit 1 - zero
bit 2 - zero
bit 3 - zero
bit 4 - drive 2 ready
bit 5 - drive 3 ready
bit 6 - drive 0 ready
bit 7 - drive 1 ready
07FH - Write - Reset diskette system.
Operations:
Recalibrate -
Seek -
Format Track -
Write Data -
Write Deleted Data -
Read Data -
Verify CRC -
IOPB - I/O Parameter Block
Byte 0 - Channel Word
bit 3 - data word length (=8-bit, 1=16-bit)
bit 4-5 - interrupt control
00 - I/O complete interrupt to be issued
01 - I/O complete interrupts are disabled
10 - illegal code
11 - illegal code
bit 6- randon format sequence
Byte 1 - Diskette Instruction
bit 0-2 - operation code
000 - no operation
001 - seek
010 - format track
011 - recalibrate
100 - read data
101 - verify CRC
110 - write data
111 - write deleted data
bit 3 - data word length ( same as byte-0, bit-3)
bit 4-5 - unit select
00 - drive 0
01 - drive 1
10 - drive 2
11 - drive 3
bit 6-7 - reserved (zero)
Byte 2 - Number of Records
Byte 4 - Track Address
Byte 5 - Sector Address
Byte 6 - Buffer Low Address
Byte 7 - Buffer High Address
u3 -
u4 -
u5 -
u6 - fdd number.
*/
#include "system_defs.h" /* system header in system dir */
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 4
#define WP 0x40 /* Write protect */
#define RDY 0x20 /* Ready */
#define T0 0x10 /* Track 0 */
#define TS 0x08 /* Two sided */
/* internal function prototypes */
t_stat zx200a_svc (UNIT *uptr);
uint8 zx200a0(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a1(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a2(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a3(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a7(t_bool io, uint8 data, uint8 devnum);
t_stat zx200a_attach (UNIT *uptr, CONST char *cptr);
t_stat zx200a_reset(DEVICE *dptr, uint16 base, uint8 devnum);
void zx200a_reset1(void);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16 port, uint8 devnum);
/* globals */
uint16 iopb;
uint8 syssta = 0, rsttyp = 0, rstbyt1 = 0, rstbyt2 = 0, cmd = 0;
uint8 *zx200a_buf[FDD_NUM] = { /* FDD buffer pointers */
NULL,
NULL,
NULL,
NULL
};
int32 fddst[FDD_NUM] = { // fdd status
0, // status of FDD 0
0, // status of FDD 1
0, // status of FDD 2
0 // status of FDD 3
};
int32 maxsec[FDD_NUM] = { // last sector
0, // status of FDD 0
0, // status of FDD 1
0, // status of FDD 2
0 // status of FDD 3
};
int8 maxcyl[FDD_NUM] = {
0, // last cylinder + 1 of FDD 0
0, // last cylinder + 1 of FDD 1
0, // last cylinder + 1 of FDD 2
0 // last cylinder + 1 of FDD 3
};
UNIT zx200a_unit[] = {
{ UDATA (&zx200a_svc, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 },
{ UDATA (&zx200a_svc, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 },
{ UDATA (&zx200a_svc, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 },
{ UDATA (&zx200a_svc, UNIT_ATTABLE+UNIT_DISABLE, 0), 20 }
};
REG zx200a_reg[] = {
{ HRDATA (SUBSYSSTA, zx200a_unit[0].u3, 8) }, /* subsytem status */
{ HRDATA (RSTTYP, zx200a_unit[0].u4, 8) }, /* result type */
{ HRDATA (RSTBYT0, zx200a_unit[0].u5, 8) }, /* result byte 0 RSTTYP = 0*/
{ HRDATA (RSTBYT1, zx200a_unit[0].u6, 8) }, /* result byte 1 RSTTYP = 10*/
{ NULL }
};
DEBTAB zx200a_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE zx200a_dev = {
"ZX200A", //name
zx200a_unit, //units
zx200a_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &zx200a_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
zx200a_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* Service routines to handle simulator functions */
/* service routine - actually does the simulated disk I/O */
t_stat zx200a_svc (UNIT *uptr)
{
sim_activate(&zx200a_unit[uptr->u6], zx200a_unit[uptr->u6].wait);
return SCPE_OK;
}
/* zx200a control port functions */
uint8 zx200a0(t_bool io, uint8 data, uint8 devnum)
{
int val;
if (io == 0) { /* read operation */
val = zx200a_unit[0].u3;
sim_printf(" zx200a0: read data=%02X devnum=%02X val=%02X\n", data, devnum, val);
return val;
} else { /* write control port */
sim_printf(" zx200a0: write data=%02X port=%02X\n", data, devnum);
}
}
uint8 zx200a1(t_bool io, uint8 data, uint8 devnum)
{
int val;
if (io == 0) { /* read operation */
val = zx200a_unit[0].u4;
sim_printf(" zx200a1: read data=%02X devnum=%02X val=%02X\n", data, devnum, val);
return val;
} else { /* write control port */
iopb = data;
sim_printf(" zx200a1: write data=%02X port=%02X iopb=%04X\n", data, devnum, iopb);
}
}
uint8 zx200a2(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read operation */
sim_printf(" zx200a2: read data=%02X devnum=%02X\n", data, devnum);
return 0x00;
} else { /* write control port */
iopb |= (data << 8);
sim_printf(" zx200a2: write data=%02X port=%02X iopb=%04X\n", data, devnum, iopb);
}
}
uint8 zx200a3(t_bool io, uint8 data, uint8 devnum)
{
int val;
if (io == 0) { /* read operation */
if (zx200a_unit[0].u4)
val = zx200a_unit[0].u5;
else
val = zx200a_unit[0].u6;
sim_printf(" zx200a3: read data=%02X devnum=%02X val=%02X\n", data, devnum, val);
return val;
} else { /* write control port */
sim_printf(" zx200a3: write data=%02X port=%02X\n", data, devnum);
}
}
/* reset ZX-200A */
uint8 zx200a7(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read operation */
sim_printf(" zx200a7: read data=%02X devnum=%02X\n", data, devnum);
return 0x00;
} else { /* write control port */
sim_printf(" zx200a7: write data=%02X port=%02X\n", data, devnum);
zx200a_reset(NULL, ZX200A_BASE_DD, 0); //for now
}
}
/* zx200a attach - attach an .IMG file to a FDD */
t_stat zx200a_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
FILE *fp;
int32 i, c = 0;
long flen;
sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_attach: Entered with uptr=%08X cptr=%s\n", uptr, cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" zx200a_attach: Attach error\n");
return r;
}
fp = fopen(uptr->filename, "rb");
if (fp == NULL) {
sim_printf(" Unable to open disk image file %s\n", uptr->filename);
sim_printf(" No disk image loaded!!!\n");
} else {
sim_printf("zx200a: Attach\n");
fseek(fp, 0, SEEK_END); /* size disk image */
flen = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (zx200a_buf[uptr->u6] == NULL) { /* no buffer allocated */
zx200a_buf[uptr->u6] = (uint8 *)malloc(flen);
if (zx200a_buf[uptr->u6] == NULL) {
sim_printf(" zx200a_attach: Malloc error\n");
return SCPE_MEM;
}
}
uptr->capac = flen;
i = 0;
c = fgetc(fp); // copy disk image into buffer
while (c != EOF) {
*(zx200a_buf[uptr->u6] + i++) = c & 0xFF;
c = fgetc(fp);
}
fclose(fp);
switch(uptr->u6){
case 0:
fddst[uptr->u6] |= 0x01; /* set unit ready */
break;
case 1:
fddst[uptr->u6] |= 0x02; /* set unit ready */
break;
case 2:
fddst[uptr->u6] |= 0x20; /* set unit ready */
break;
case 3:
fddst[uptr->u6] |= 0x40; /* set unit ready */
break;
}
if (flen == 256256) { /* 8" 256K SSSD */
maxcyl[uptr->u6] = 77;
maxsec[uptr->u6] = 26;
}
else if (flen == 512512) { /* 8" 512K SSDD */
maxcyl[uptr->u6] = 77;
maxsec[uptr->u6] = 52;
}
sim_printf(" Drive-%d: %d bytes of disk image %s loaded, fddst=%02X\n",
uptr->u6, i, uptr->filename, fddst[uptr->u6]);
}
sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_attach: Done\n");
return SCPE_OK;
}
/* Reset routine */
t_stat zx200a_reset(DEVICE *dptr, uint16 base, uint8 devnum)
{
reg_dev(zx200a0, base, devnum);
reg_dev(zx200a1, base + 1, devnum);
reg_dev(zx200a2, base + 2, devnum);
reg_dev(zx200a3, base + 3, devnum);
reg_dev(zx200a7, base + 7, devnum);
zx200a_unit[devnum].u3 = 0x00; /* ipc reset */
sim_printf(" zx200a-%d: Reset\n", devnum);
sim_printf(" zx200a-%d: Registered at %04X\n", devnum, base);
if ((zx200a_dev.flags & DEV_DIS) == 0)
zx200a_reset1();
return SCPE_OK;
}
void zx200a_reset1(void)
{
int32 i;
UNIT *uptr;
static int flag = 1;
if (flag) sim_printf("ZX-200A: Initializing\n");
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = zx200a_dev.units + i;
if (uptr->capac == 0) { /* if not configured */
// sim_printf(" ZX-200A%d: Not configured\n", i);
// if (flag) {
// sim_printf(" ALL: \"set ZX-200A en\"\n");
// sim_printf(" EPROM: \"att ZX-200A0 <filename>\"\n");
// flag = 0;
// }
uptr->capac = 0; /* initialize unit */
uptr->u3 = 0;
uptr->u4 = 0;
uptr->u5 = 0;
uptr->u6 = i; /* unit number - only set here! */
fddst[i] = WP + T0 + i; /* initial drive status */
uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */
sim_activate (&zx200a_unit[uptr->u6], zx200a_unit[uptr->u6].wait);
} else {
fddst[i] = RDY + WP + T0 + i; /* initial attach drive status */
// sim_printf(" SBC208%d: Configured, Attached to %s\n", i, uptr->filename);
}
}
cmd = 0; /* clear command */
flag = 0;
}
/* end of zx-200a.c */

View file

@ -0,0 +1,79 @@
/* mds225_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
07 Jun 16 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-225";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&ipc_cont_dev,
&multibus_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -0,0 +1,143 @@
/* ipc.c: Intel IPC Processor simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
07 Jun 16 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
t_stat SBC_reset (DEVICE *dptr);
/* external function prototypes */
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
//extern uint8 multibus_get_mbyte(uint16 addr);
//extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT i8255_unit;
extern UNIT EPROM_unit;
extern UNIT RAM_unit;
extern UNIT ipc_cont_unit;
extern UNIT ioc_cont_unit;
extern t_stat i8251_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8253_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8255_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8259_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat EPROM_reset(DEVICE *dptr, uint16 size);
extern t_stat RAM_reset(DEVICE *dptr, uint16 base, uint16 size);
extern t_stat ipc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat ioc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern uint32 saved_PC; /* program counter */
/* CPU reset routine
put here to cause a reset of the entire IPC system */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing MDS-225\n");
i8080_reset(NULL);
i8251_reset(NULL, I8251_BASE_0, 0);
i8251_reset(NULL, I8251_BASE_1, 0);
i8253_reset(NULL, I8253_BASE, 0);
i8255_reset(NULL, I8255_BASE_0, 0);
i8255_reset(NULL, I8255_BASE_1, 1);
i8259_reset(NULL, I8259_BASE_0, 0);
i8259_reset(NULL, I8259_BASE_1, 1);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
ipc_cont_reset(NULL, ICONT_BASE, 0);
ioc_cont_reset(NULL, DBB_BASE, 0);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
if (addr >= 0xF800) { //monitor ROM - always there
// sim_printf("get_mbyte: Monitor ROM ipc_cont=%02X\n", ipc_cont_unit.u3);
return EPROM_get_mbyte(addr - 0xF000);
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x01) == 0)) { //startup
// sim_printf("get_mbyte: Startup ROM ipc_cont=%02X\n", ipc_cont_unit.u3);
return EPROM_get_mbyte(addr);
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //diagnostic ROM
// sim_printf("get_mbyte: Diagnostic ROM ipc_cont=%02X\n", ipc_cont_unit.u3);
return EPROM_get_mbyte(addr - 0xE800);
}
return RAM_get_mbyte(addr);
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
if (addr >= 0xF800) { //monitor ROM - always there
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, saved_PC);
return;
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x01) == 0)) { //startup
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, saved_PC);
return;
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //diagnostic ROM
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, saved_PC);
return;
}
RAM_put_mbyte(addr, val);
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of ipc.c */

View file

@ -0,0 +1,121 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define IPC 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE_DD 0x78
#define ZX200A_BASE_SD 0x88
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8253 */
#define I8253_BASE 0xF0
#define I8253_NUM 1
/* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4
#define I8251_BASE_1 0xF6
#define I8251_NUM 2
/* set the base I/O address for the 8259 */
#define I8259_BASE_0 0xFA
#define I8259_BASE_1 0xFC
#define I8259_NUM 2
/* set the base I/O address for the IPC control port */
#define ICONT_BASE 0xFF
/* set the base and size for the EPROM on the MDS 225 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the MDS 225 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0xF800
/* set INTR for CPU */
#define INTR INT_1
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupts definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */