From 27e65d1fa9f0e7dd811c90b8fcb8158a9514ea50 Mon Sep 17 00:00:00 2001 From: Bill Beech Date: Fri, 15 Jul 2016 13:13:12 -0700 Subject: [PATCH] IMDS-225: Initial check in of new experimental simulator for the Intel MDS-225 IPC --- Intel-Systems/common/ioc-cont.c | 125 ++++++++ Intel-Systems/common/ipc-cont.c | 160 ++++++++++ Intel-Systems/common/ipceprom.c | 187 +++++++++++ Intel-Systems/common/ipcmultibus.c | 258 +++++++++++++++ Intel-Systems/common/ipcram8.c | 164 ++++++++++ Intel-Systems/common/isbc202.c | 130 ++++++++ Intel-Systems/common/zx200a.c | 444 ++++++++++++++++++++++++++ Intel-Systems/imds-225/imds-225_sys.c | 79 +++++ Intel-Systems/imds-225/ipc.c | 143 +++++++++ Intel-Systems/imds-225/system_defs.h | 121 +++++++ 10 files changed, 1811 insertions(+) create mode 100644 Intel-Systems/common/ioc-cont.c create mode 100644 Intel-Systems/common/ipc-cont.c create mode 100644 Intel-Systems/common/ipceprom.c create mode 100644 Intel-Systems/common/ipcmultibus.c create mode 100644 Intel-Systems/common/ipcram8.c create mode 100644 Intel-Systems/common/isbc202.c create mode 100644 Intel-Systems/common/zx200a.c create mode 100644 Intel-Systems/imds-225/imds-225_sys.c create mode 100644 Intel-Systems/imds-225/ipc.c create mode 100644 Intel-Systems/imds-225/system_defs.h diff --git a/Intel-Systems/common/ioc-cont.c b/Intel-Systems/common/ioc-cont.c new file mode 100644 index 00000000..5915d76d --- /dev/null +++ b/Intel-Systems/common/ioc-cont.c @@ -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 */ diff --git a/Intel-Systems/common/ipc-cont.c b/Intel-Systems/common/ipc-cont.c new file mode 100644 index 00000000..0e3391b4 --- /dev/null +++ b/Intel-Systems/common/ipc-cont.c @@ -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 */ diff --git a/Intel-Systems/common/ipceprom.c b/Intel-Systems/common/ipceprom.c new file mode 100644 index 00000000..ef87c08d --- /dev/null +++ b/Intel-Systems/common/ipceprom.c @@ -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 */ diff --git a/Intel-Systems/common/ipcmultibus.c b/Intel-Systems/common/ipcmultibus.c new file mode 100644 index 00000000..5e8a7c8e --- /dev/null +++ b/Intel-Systems/common/ipcmultibus.c @@ -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 */ + diff --git a/Intel-Systems/common/ipcram8.c b/Intel-Systems/common/ipcram8.c new file mode 100644 index 00000000..f0202d37 --- /dev/null +++ b/Intel-Systems/common/ipcram8.c @@ -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 */ diff --git a/Intel-Systems/common/isbc202.c b/Intel-Systems/common/isbc202.c new file mode 100644 index 00000000..aafd9611 --- /dev/null +++ b/Intel-Systems/common/isbc202.c @@ -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 */ diff --git a/Intel-Systems/common/zx200a.c b/Intel-Systems/common/zx200a.c new file mode 100644 index 00000000..ae5994a6 --- /dev/null +++ b/Intel-Systems/common/zx200a.c @@ -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 \"\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 */ diff --git a/Intel-Systems/imds-225/imds-225_sys.c b/Intel-Systems/imds-225/imds-225_sys.c new file mode 100644 index 00000000..dc119096 --- /dev/null +++ b/Intel-Systems/imds-225/imds-225_sys.c @@ -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" +}; + diff --git a/Intel-Systems/imds-225/ipc.c b/Intel-Systems/imds-225/ipc.c new file mode 100644 index 00000000..c3321185 --- /dev/null +++ b/Intel-Systems/imds-225/ipc.c @@ -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 */ diff --git a/Intel-Systems/imds-225/system_defs.h b/Intel-Systems/imds-225/system_defs.h new file mode 100644 index 00000000..15b6d588 --- /dev/null +++ b/Intel-Systems/imds-225/system_defs.h @@ -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 +#include +#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 */ +