Intel-Systems: Cleanup and reorganized multibus code

This commit is contained in:
Bill Beech 2020-02-04 16:24:05 -07:00
parent f01e8900ed
commit a2998ebaf2
28 changed files with 142 additions and 1339 deletions

View file

@ -475,14 +475,11 @@ int32 sim_instr(void)
IR = OP = fetch_byte(0); /* instruction fetch */
/*
if (GET_XACK(1) == 0) { // no XACK for instruction fetch
reason = STOP_XACK;
// if (uptr->flags & UNIT_XACK)
sim_printf("Failed XACK for Instruction Fetch from %04X\n", PCX);
continue;
// reason = STOP_XACK;
// sim_printf("Failed XACK for Instruction Fetch from %04X\n", PCX);
// continue;
}
*/
// first instruction decode
if (OP == 0x76) { /* HLT Instruction*/
@ -906,20 +903,16 @@ int32 sim_instr(void)
}
loop_end:
/*
if (GET_XACK(1) == 0) { // no XACK for operand fetch
reason = STOP_XACK;
if (OP == 0xD3 || OP == 0xDB) {
// if (uptr->flags & UNIT_XACK)
sim_printf("Failed XACK for Port %02X Fetch from %04X\n", port, PCX);
} else {
// if (uptr->flags & UNIT_XACK)
sim_printf("Failed XACK for Operand %04X Fetch from %04X\n", addr, PCX);
continue;
// reason = STOP_XACK;
// if (OP == 0xD3 || OP == 0xDB) {
// sim_printf("Failed XACK for Port %02X Fetch from %04X\n", port, PCX);
// } else {
// sim_printf("Failed XACK for Operand %04X Fetch from %04X\n", addr, PCX);
// continue;
// }
}
}
*/;
}
/* Simulation halted */

View file

@ -49,9 +49,6 @@ uint8 EPROM_get_mbyte(uint16 addr);
/* external globals */
extern uint8 xack; /* XACK signal */
extern uint8 i8255_C[4]; //port C byte I/O
/* globals */
/* SIMH EPROM Standard I/O Data Structures */
@ -135,17 +132,9 @@ uint8 EPROM_get_mbyte(uint16 addr)
{
uint8 val;
if ((addr >= EPROM_unit.u3) && ((uint16) addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
SET_XACK(1); /* good memory address */
val = *((uint8 *)EPROM_unit.filebuf + (addr - EPROM_unit.u3));
val &= 0xFF;
return val;
} else {
SET_XACK(0); /* bad memory address */
sim_printf("EPROM: Out of range\n");
}
SET_XACK(0); /* bad memory address */
return 0;
}
/* end of iEPROM.c */

View file

@ -136,15 +136,9 @@ uint8 EPROM1_get_mbyte(uint16 addr)
{
uint8 val;
if ((addr >= EPROM1_unit->u3) && ((uint16) addr <= (EPROM1_unit->u3 + EPROM1_unit->capac))) {
SET_XACK(1); /* good memory address */
val = *((uint8 *)EPROM1_unit->filebuf + (addr - EPROM1_unit->u3));
val &= 0xFF;
return val;
} else {
sim_printf("EPROM1: Out of range\n");
}
return 0;
}
/* end of iEPROM1.c */

View file

@ -30,11 +30,12 @@
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
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 */
@ -70,6 +71,7 @@ int onetime = 0;
/* extern globals */
extern uint16 PCX; /* program counter */
extern uint8 xack; /* XACK signal */
extern UNIT i8255_unit;
extern UNIT EPROM_unit;
extern UNIT RAM_unit;
@ -124,6 +126,7 @@ t_stat SBC_reset (DEVICE *dptr)
uint8 get_mbyte(uint16 addr)
{
SET_XACK(1); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return EPROM_get_mbyte(addr - 0xF000); //top half of EPROM
}
@ -133,9 +136,10 @@ uint8 get_mbyte(uint16 addr)
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return EPROM_get_mbyte(addr - 0xE800); //bottom half of EPROM
}
if (addr < 0x8000) //IPB RAM
if (addr < 0x8000) { //IPB RAM
return RAM_get_mbyte(addr);
else
}
SET_XACK(0); /* set no XACK */
return multibus_get_mbyte(addr); //check multibus cards
}
@ -154,6 +158,7 @@ uint16 get_mword(uint16 addr)
void put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return;
}

View file

@ -1,373 +0,0 @@
/* 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:
01 Mar 18 - Original file.
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
*/
#include "system_defs.h"
int32 mbirq = 0; /* set no multibus interrupts */
/* function prototypes */
t_stat multibus_cfg(void);
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);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
uint16 multibus_get_mword(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
void multibus_put_mword(uint16 addr, uint16 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num);
extern t_stat zx200a_reset(DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr);
extern t_stat isbc206_reset (DEVICE *dptr);
extern t_stat isbc464_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern DEVICE isbc464_dev;
extern DEVICE isbc064_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE zx200a_dev;
/* 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) },
{ NULL }
};
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 */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
return SCPE_OK;
}
/* 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)
{
if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n");
if (SBC064_NUM) { //device installed
isbc064_reset(&isbc064_dev);
sim_printf(" Multibus: SBC064 reset\n");
}
if (SBC464_NUM) { //unit enabled
isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
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 port;
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 */
return 0; //should be 0xff, but ISIS won't boot if not 0!
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine) { /* different device? */
sim_printf(" Multibus: I/O Port %04X is already assigned to different device\n", port);
return 1;
} else
return 0;
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
uint8 val = 0;
SET_XACK(0); /* set no XACK */
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= SBC464_BASE && addr <= (SBC464_BASE + SBC464_SIZE - 1))
return(isbc464_get_mbyte(addr));
}
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= SBC064_BASE && addr <= (SBC064_BASE + SBC064_SIZE - 1))
val = isbc064_get_mbyte(addr);
}
if (xack == 0)
val = RAM_get_mbyte(addr);
return val;
}
/* get a word from memory */
uint16 multibus_get_mword(uint16 addr)
{
uint16 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= SBC064_BASE && addr <= (SBC064_BASE + SBC064_SIZE - 1))
isbc064_put_mbyte(addr, val);
}
RAM_put_mbyte(addr, val);
}
/* put a word to memory */
void multibus_put_mword(uint16 addr, uint16 val)
{
multibus_put_mbyte(addr, val & 0xff);
multibus_put_mbyte(addr+1, val >> 8);
}
/* end of ipbmultibus.c */

View file

@ -34,15 +34,17 @@
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
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);
@ -67,6 +69,7 @@ extern t_stat multibus_cfg();
/* external globals */
extern uint8 xack;
extern uint32 PCX; /* program counter */
extern UNIT i8255_unit;
extern UNIT EPROM_unit;
@ -126,17 +129,22 @@ t_stat SBC_reset (DEVICE *dptr)
uint8 get_mbyte(uint16 addr)
{
SET_XACK(1); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return EPROM_get_mbyte(addr - 0xF000); //top half of EPROM
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return EPROM_get_mbyte(addr);
return EPROM_get_mbyte(addr); //top half of EPROM for boot
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return EPROM_get_mbyte(addr - 0xE800);
return EPROM_get_mbyte(addr - 0xE800); //bottom half of EPROM
}
if (addr < 0x8000) { //IPC RAM
return RAM_get_mbyte(addr);
}
SET_XACK(0); /* set no XACK */
return multibus_get_mbyte(addr); //check multibus cards
}
/* get a word from memory */
@ -153,6 +161,7 @@ uint16 get_mword(uint16 addr)
void put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return;
}
@ -162,7 +171,11 @@ void put_mbyte(uint16 addr, uint8 val)
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return;
}
RAM_put_mbyte(addr, val);
if (addr < 0x8000) {
RAM_put_mbyte(addr, val); //IPB RAM
return;
}
multibus_put_mbyte(addr, val); //check multibus cards
}
/* put a word to memory */

View file

@ -1,375 +0,0 @@
/* 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.
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 */
int32 flag = 0;
/* function prototypes */
t_stat multibus_cfg(void);
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 flag, uint8 data, uint8 devnum);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
uint16 multibus_get_mword(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
void multibus_put_mword(uint16 addr, uint16 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num);
extern t_stat isbc064_reset (DEVICE *dptr);
extern t_stat isbc464_reset (DEVICE *dptr);
extern t_stat zx200a_reset(DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr);
extern t_stat isbc206_reset (DEVICE *dptr);
extern t_stat isbc208_reset (DEVICE *dptr);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat isbc208_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev;
/* 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) },
{ NULL }
};
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 */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
if (SBC208_NUM) isbc208_cfg(SBC208_BASE);
if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
return SCPE_OK;
}
/* 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)
{
if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n");
if (SBC064_NUM) { //device installed
isbc064_reset(&isbc064_dev);
sim_printf(" Multibus: SBC064 reset\n");
}
if (SBC464_NUM) { //unit enabled
isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (SBC208_NUM) { //unit enabled
isbc208_reset(&isbc208_dev);
sim_printf(" Multibus: SBC208 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
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;
}
/* 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 port;
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 */
return 0; //should be 0xff, but ISIS won't boot if not 0!
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine) { /* different device? */
sim_printf(" Multibus: I/O Port %02X is already assigned to different device\n", port);
return 1;
} else
return 0;
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
uint8 val = 0;
SET_XACK(0); /* set no XACK */
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= SBC464_BASE && addr <= (SBC464_BASE + SBC464_SIZE))
return(isbc464_get_mbyte(addr));
}
if (xack == 0)
val = RAM_get_mbyte(addr);
return val;
}
/* get a word from memory */
uint16 multibus_get_mword(uint16 addr)
{
uint16 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
RAM_put_mbyte(addr, val);
}
/* put a word to memory */
void multibus_put_mword(uint16 addr, uint16 val)
{
multibus_put_mbyte(addr, val & 0xff);
multibus_put_mbyte(addr+1, val >> 8);
}
/* end of ipcmultibus.c */

View file

@ -45,8 +45,6 @@ void RAM_put_mbyte(uint16 addr, uint8 val);
/* external globals */
extern uint8 xack; /* XACK signal */
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
@ -93,15 +91,15 @@ DEVICE RAM_dev = {
t_stat RAM_cfg(uint16 base, uint16 size)
{
RAM_unit.capac = size & 0xFFFF; /* set RAM size */
RAM_unit.u3 = base & 0xFFFF; /* set RAM base */
RAM_unit.filebuf = (uint8 *)calloc(size, size * sizeof(uint8));
RAM_unit.capac = size; /* set RAM size */
RAM_unit.u3 = base; /* set RAM base */
RAM_unit.filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (RAM_unit.filebuf == NULL) {
sim_printf (" RAM: Malloc error\n");
sim_printf (" RAM: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" RAM: 0%04XH bytes at base 0%04XH\n",
size, base & 0xFFFF);
size, base);
return SCPE_OK;
}
@ -118,29 +116,16 @@ uint8 RAM_get_mbyte(uint16 addr)
{
uint8 val;
if ((addr >= RAM_unit.u3) && ((uint32) addr <= (RAM_unit.u3 + RAM_unit.capac))) {
SET_XACK(1); /* good memory address */
val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3));
return (val & 0xFF);
} else {
SET_XACK(0); /* bad memory address */
return 0xFF;
}
}
/* put a byte into memory */
void RAM_put_mbyte(uint16 addr, uint8 val)
{
if ((addr >= RAM_unit.u3) && ((uint32)addr <= RAM_unit.u3 + RAM_unit.capac)) {
SET_XACK(1); /* good memory address */
*((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
return;
} else {
SET_XACK(0); /* bad memory address */
return;
}
}
/* end of iRAM8.c */

View file

@ -40,8 +40,6 @@
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define SET_XACK(VAL) (xack = VAL)
/* prototypes */
t_stat isbc064_cfg(uint16 base, uint16 size);
@ -56,7 +54,6 @@ void isbc064_put_mbyte(uint16 addr, uint8 val);
/* external globals */
extern uint16 PCX; /* program counter */
extern uint8 xack;
/* isbc064 Standard SIMH Device Data Structures */
@ -121,7 +118,7 @@ t_stat isbc064_cfg(uint16 base, uint16 size)
isbc064_unit.u3 = base; //and base
isbc064_unit.filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (isbc064_unit.filebuf == NULL) {
sim_printf (" sbc064: Malloc error\n");
sim_printf (" sbc064: Calloc error\n");
return SCPE_MEM;
}
return SCPE_OK;
@ -150,41 +147,18 @@ t_stat isbc064_reset (DEVICE *dptr)
uint8 isbc064_get_mbyte(uint16 addr)
{
uint32 val;
uint8 val;
if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if ((addr >= isbc064_unit.u3) && (addr <= (isbc064_unit.u3 + isbc064_unit.capac))) {
SET_XACK(1); /* good memory address */
val = *((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.u3));
return (val & 0xFF);
} else {
sim_printf("isbc064_get_mbyte: Read-Enabled Out of range addr=%04X PC=%04X\n", addr, PCX);
SET_XACK(0); /* bad memory address */
return 0xff; /* multibus has active high pullups and inversion */
}
} //device is disabled/not installed
sim_printf ("isbc064_get_mbyte: Read-Disabled addr=%04X PC=%04X\n", addr, PCX);
SET_XACK(0); /* bad memory address */
return 0xff; /* multibus has active high pullups and inversion */
}
/* put a byte into memory */
void isbc064_put_mbyte(uint16 addr, uint8 val)
{
if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if ((addr >= isbc064_unit.u3) && (addr <= (isbc064_unit.u3 + isbc064_unit.capac))) {
SET_XACK(1); /* good memory address */
*((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.u3)) = val & 0xFF;
return;
} else {
sim_printf("isbc064_put_mbyte: Write Out of range addr=%04X PC=%04X\n", addr, PCX);
SET_XACK(0); /* bad memory address */
return;
}
} //device is disabled/not installed
sim_printf ("isbc064_put_mbyte: Write-Disabled addr=%04X PC=%04X\n", addr, PCX);
SET_XACK(0); /* bad memory address */
}
/* end of isbc064.c */

View file

@ -189,8 +189,8 @@ extern uint16 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
/* function prototypes */
@ -483,13 +483,13 @@ void isbc202_diskio(void)
uint8 *fbuf;
//parse the IOPB
cw = multibus_get_mbyte(fdc202.iopb);
di = multibus_get_mbyte(fdc202.iopb + 1);
nr = multibus_get_mbyte(fdc202.iopb + 2);
ta = multibus_get_mbyte(fdc202.iopb + 3);
sa = multibus_get_mbyte(fdc202.iopb + 4);
ba = multibus_get_mbyte(fdc202.iopb + 5);
ba |= (multibus_get_mbyte(fdc202.iopb + 6) << 8);
cw = get_mbyte(fdc202.iopb);
di = get_mbyte(fdc202.iopb + 1);
nr = get_mbyte(fdc202.iopb + 2);
ta = get_mbyte(fdc202.iopb + 3);
sa = get_mbyte(fdc202.iopb + 4);
ba = get_mbyte(fdc202.iopb + 5);
ba |= (get_mbyte(fdc202.iopb + 6) << 8);
fddnum = (di & 0x30) >> 4;
uptr = isbc202_dev.units + fddnum;
fbuf = (uint8 *) uptr->filebuf;
@ -581,7 +581,7 @@ void isbc202_diskio(void)
sim_printf("\n SBC202: FDD %d - Write protect error DFMT", fddnum);
return;
}
fmtb = multibus_get_mbyte(ba); //get the format byte
fmtb = get_mbyte(ba); //get the format byte
//calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * SECSIZ;
for(i=0; i<=((uint32)(MAXSECDD) * SECSIZ); i++) {
@ -599,7 +599,7 @@ void isbc202_diskio(void)
//copy sector from disk image to RAM
for (i=0; i<SECSIZ; i++) {
data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data);
put_mbyte(ba + i, data);
}
sa++;
ba+=0x80;
@ -624,7 +624,7 @@ void isbc202_diskio(void)
dskoff = ((ta * MAXSECDD) + (sa - 1)) * SECSIZ;
//copy sector from RAM to disk image
for (i=0; i<SECSIZ; i++) {
data = multibus_get_mbyte(ba + i);
data = get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data;
}
sa++;

View file

@ -39,7 +39,6 @@ t_stat isbc064_cfg(uint16 base, uint16 size);
t_stat isbc464_reset (DEVICE *dptr);
t_stat isbc464_attach (UNIT *uptr, CONST char *cptr);
uint8 isbc464_get_mbyte(uint16 addr);
void isbc464_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */
@ -132,46 +131,11 @@ uint8 isbc464_get_mbyte(uint16 addr)
uint32 val, org, len;
uint8 *fbuf;
if ((isbc464_dev.flags & DEV_DIS) == 0) {
org = isbc464_unit.u3;
len = isbc464_unit.capac;
fbuf = (uint8 *) isbc464_unit.filebuf;
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
val = *(fbuf + (addr - org));
return (val & 0xFF);
} else {
sim_printf("isbc464_get_mbyte: Out of range\n");
SET_XACK(0); /* bad memory address */
return 0; /* multibus has active high pullups and inversion */
}
}
sim_printf ("isbc464_put_mbyte: Write-Disabled addr=%04X\n", addr);
SET_XACK(0); /* bad memory address */
return 0; /* multibus has active high pullups and inversion */
}
/* put a byte into memory */
void isbc464_put_mbyte(uint16 addr, uint8 val)
{
uint32 org, len;
if ((isbc464_dev.flags & DEV_DIS) == 0) {
org = isbc464_unit.u3;
len = isbc464_unit.capac;
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(0); /* bad memory address */
sim_printf ("isbc464_put_mbyte: Read-only Memory\n");
return;
} else {
sim_printf ("isbc464_put_mbyte: Out of range\n");
SET_XACK(0); /* bad memory address */
return;
}
}
sim_printf ("isbc464_put_mbyte: Disabled\n");
SET_XACK(0); /* bad memory address */
}
/* end of isbc464.c */

View file

@ -1,373 +0,0 @@
/* m800multibus.c: Multibus I simulator for M800/810
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_cfg(void);
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), uint8 port, uint8 devnum);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
uint16 multibus_get_mword(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
void multibus_put_mword(uint16 addr, uint16 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num);
extern t_stat zx200a_reset(DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr);
extern t_stat isbc206_reset (DEVICE *dptr);
extern t_stat isbc208_reset (DEVICE *dptr);
extern t_stat isbc464_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr);
extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat isbc208_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev;
/* 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) },
{ NULL }
};
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 */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
if (SBC208_NUM) isbc208_cfg(SBC208_BASE);
if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
return SCPE_OK;
}
/* 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)
{
if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n");
if (SBC064_NUM) { //device installed
isbc064_reset(&isbc064_dev);
sim_printf(" Multibus: SBC064 reset\n");
}
if (SBC464_NUM) { //unit enabled
isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (SBC208_NUM) { //unit enabled
isbc208_reset(&isbc208_dev);
sim_printf(" Multibus: SBC208 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
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 port;
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 */
return 0; //should be 0xff, but ISIS won't boot if not 0!
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
sim_printf(" Multibus: I/O Port %04X is already assigned\n", port);
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
uint8 val = 0;
SET_XACK(0); /* set no XACK */
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr);
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= SBC464_BASE && addr <= (SBC464_BASE + SBC464_SIZE))
return(isbc464_get_mbyte(addr));
}
if (xack == 0)
val = isbc064_get_mbyte(addr);
return val;
}
/* get a word from memory */
uint16 multibus_get_mword(uint16 addr)
{
uint16 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
// sim_printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr);
isbc064_put_mbyte(addr, val);
// sim_printf("multibus_put_mbyte: Done XACK=%dX\n", XACK);
}
/* put a word to memory */
void multibus_put_mword(uint16 addr, uint16 val)
{
multibus_put_mbyte(addr, val & 0xff);
multibus_put_mbyte(addr+1, val >> 8);
}
/* end of m800multibus.c */

View file

@ -77,7 +77,7 @@
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
#define SBC202_NUM 0
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
@ -96,13 +96,13 @@
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_SIZE 0x47FF
#define SBC464_NUM 1
/* set the base and size for the iSBC 064 RAM */
#define SBC064_BASE 0x8000
#define SBC064_SIZE 0x7FFF
#define SBC064_NUM 1
#define SBC064_NUM 0
/* set INTR for CPU */
#define INTR INT_1

View file

@ -30,7 +30,6 @@
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define IPC 0
#define SET_XACK(VAL) (xack = VAL)
/* set the base for the DBB ports */
@ -72,12 +71,12 @@
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_2
#define SBC201_NUM 1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_2
#define SBC202_NUM 1
#define SBC202_NUM 0
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
@ -97,7 +96,7 @@
/* set the base and size for the iSBC 064 RAM*/
#define SBC064_BASE 0x8000
#define SBC064_SIZE 0x7FFF
#define SBC064_NUM 1
#define SBC064_NUM 0
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800

View file

@ -33,12 +33,12 @@
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
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_config(void);
// globals

View file

@ -110,7 +110,7 @@
/* Memory */
#define MAXMEMSIZE 0x0FFFF /* 8080 max memory size */
#define MAXMEMSIZE 0xFFFF /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint16) (x)) <= MEMSIZE)

View file

@ -55,12 +55,12 @@
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_3
#define SBC201_NUM 1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_3
#define SBC202_NUM 1
#define SBC202_NUM 0
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
@ -80,12 +80,12 @@
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0xFFFF
#define SBC064_NUM 1
#define SBC064_NUM 0
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x47FF
#define SBC464_NUM 0
#define SBC464_NUM 1
/* set INTR for CPU */
#define INTR INT_3
@ -110,7 +110,7 @@
/* Memory */
#define MAXMEMSIZE 0x0FFFF /* 8080 max memory size */
#define MAXMEMSIZE 0xFFFF /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint16) (x)) <= MEMSIZE)

View file

@ -48,6 +48,7 @@ void put_mword(uint16 addr, uint16 val);
/* external globals */
extern uint8 i8255_C[4]; //port C byte I/O
extern uint16 PCX; /* External view of PC */
extern DEVICE i8080_dev;
extern DEVICE i8251_dev;
extern DEVICE i8255_dev;
@ -111,12 +112,12 @@ uint8 get_mbyte(uint16 addr)
{
/* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr);
}
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
@ -140,13 +141,13 @@ void put_mbyte(uint16 addr, uint8 val)
{
/* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr);
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val);
return;
}

View file

@ -31,20 +31,19 @@
#include "system_defs.h"
int flag = 1;
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
extern uint16 PCX; /* External view of PC */
/* external function prototypes */
@ -130,11 +129,11 @@ uint8 get_mbyte(uint16 addr)
{
/* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac)))
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac)))
return EPROM_get_mbyte(addr);
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac)))
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac)))
return RAM_get_mbyte(addr);
} /* otherwise, try the multibus */
return multibus_get_mbyte(addr);
@ -158,7 +157,7 @@ void put_mbyte(uint16 addr, uint8 val)
/* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr);
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
} /* if local RAM handle it */

View file

@ -38,11 +38,11 @@
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
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 globals */
@ -131,12 +131,12 @@ uint8 get_mbyte(uint16 addr)
{
/* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr);
}
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x10)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */

View file

@ -117,12 +117,12 @@ uint8 get_mbyte(uint16 addr)
{
/* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr);
}
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */

View file

@ -224,10 +224,6 @@
RelativePath="..\Intel-Systems\common\ipb.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipbmultibus.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipc-cont.c"
>
@ -252,10 +248,18 @@
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc208.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\multibus.c"
>
</File>
<File
RelativePath="..\scp.c"
>

View file

@ -225,7 +225,7 @@
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipbmultibus.c"
RelativePath="..\Intel-Systems\common\multibus.c"
>
</File>
<File

View file

@ -232,7 +232,7 @@
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipcmultibus.c"
RelativePath="..\Intel-Systems\common\multibus.c"
>
</File>
<File

View file

@ -225,7 +225,7 @@
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipbmultibus.c"
RelativePath="..\Intel-Systems\common\multibus.c"
>
</File>
<File

View file

@ -245,7 +245,7 @@
>
</File>
<File
RelativePath="..\Intel-Systems\common\m800multibus.c"
RelativePath="..\Intel-Systems\common\multibus.c"
>
</File>
<File

View file

@ -245,7 +245,7 @@
>
</File>
<File
RelativePath="..\Intel-Systems\common\m800multibus.c"
RelativePath="..\Intel-Systems\common\multibus.c"
>
</File>
<File

View file

@ -1763,11 +1763,12 @@ IMDS210 = ${IMDS210C}/i8080.c ${IMDS210D}/imds-210_sys.c \
${IMDS210C}/i8251.c ${IMDS210C}/i8255.c \
${IMDS210C}/i8259.c ${IMDS210C}/i8253.c \
${IMDS210C}/ieprom.c ${IMDS210C}/iram8.c \
${IMDS210C}/ipbmultibus.c ${IMDS210C}/ipb.c \
${IMDS210C}/multibus.c ${IMDS210C}/ipb.c \
${IMDS210C}/ipc-cont.c ${IMDS210C}/ioc-cont.c \
${IMDS210C}/isbc202.c ${IMDS210C}/isbc201.c \
${IMDS210C}/isbc206.c ${IMDS210C}/isbc464.c \
${IMDS210C}/zx200a.c ${IMDS210C}/isbc064.c
${IMDS210C}/isbc206.c ${IMDS210C}/isbc208.c \
${IMDS210C}/isbc464.c ${IMDS210C}/zx200a.c \
${IMDS210C}/isbc064.c
IMDS210_OPT = -I ${IMDS210D}
@ -1777,11 +1778,12 @@ IMDS220 = ${IMDS220C}/i8080.c ${IMDS220D}/imds-220_sys.c \
${IMDS220C}/i8251.c ${IMDS220C}/i8255.c \
${IMDS220C}/i8259.c ${IMDS220C}/i8253.c \
${IMDS220C}/ieprom.c ${IMDS220C}/iram8.c \
${IMDS220C}/ipbmultibus.c ${IMDS220C}/ipb.c \
${IMDS220C}/multibus.c ${IMDS220C}/ipb.c \
${IMDS220C}/ipc-cont.c ${IMDS220C}/ioc-cont.c \
${IMDS220C}/isbc202.c ${IMDS220C}/isbc201.c \
${IMDS220C}/isbc206.c ${IMDS220C}/isbc464.c \
${IMDS220C}/zx200a.c ${IMDS220C}/isbc064.c
${IMDS220C}/isbc206.c ${IMDS210C}/isbc208.c \
${IMDS220C}/isbc464.c ${IMDS220C}/zx200a.c \
${IMDS220C}/isbc064.c
IMDS220_OPT = -I ${IMDS220D}
@ -1791,11 +1793,12 @@ IMDS225 = ${IMDS225C}/i8080.c ${IMDS225D}/imds-225_sys.c \
${IMDS225C}/i8251.c ${IMDS225C}/i8255.c \
${IMDS225C}/i8259.c ${IMDS225C}/i8253.c \
${IMDS225C}/ieprom.c ${IMDS225C}/iram8.c \
${IMDS225C}/ipcmultibus.c ${IMDS225C}/ipc.c \
${IMDS225C}/multibus.c ${IMDS225C}/ipc.c \
${IMDS225C}/ipc-cont.c ${IMDS225C}/ioc-cont.c \
${IMDS225C}/isbc202.c ${IMDS225C}/isbc201.c \
${IMDS225C}/zx200a.c ${IMDS225C}/isbc464.c \
${IMDS225C}/isbc206.c
${IMDS225C}/isbc206.c ${IMDS225C}/isbc208.c \
${IMDS220C}/isbc064.c
IMDS225_OPT = -I ${IMDS225D}
@ -1805,11 +1808,12 @@ IMDS230 = ${IMDS230C}/i8080.c ${IMDS230D}/imds-230_sys.c \
${IMDS230C}/i8251.c ${IMDS230C}/i8255.c \
${IMDS230C}/i8259.c ${IMDS230C}/i8253.c \
${IMDS230C}/ieprom.c ${IMDS230C}/iram8.c \
${IMDS230C}/ipbmultibus.c ${IMDS230C}/ipb.c \
${IMDS230C}/multibus.c ${IMDS230C}/ipb.c \
${IMDS230C}/ipc-cont.c ${IMDS230C}/ioc-cont.c \
${IMDS230C}/isbc202.c ${IMDS230C}/isbc201.c \
${IMDS230C}/isbc206.c ${IMDS230C}/isbc464.c \
${IMDS230C}/zx200a.c ${IMDS230C}/isbc064.c
${IMDS230C}/isbc206.c ${IMDS230C}/isbc208.c \
${IMDS230C}/isbc464.c ${IMDS230C}/zx200a.c \
${IMDS230C}/isbc064.c
IMDS230_OPT = -I ${IMDS230D}
@ -1819,7 +1823,7 @@ IMDS800 = ${IMDS800C}/i8080.c ${IMDS800D}/imds-800_sys.c \
${IMDS800D}/cpu.c ${IMDS800D}/front_panel.c \
${IMDS800D}/monitor.c ${IMDS800C}/ieprom1.c \
${IMDS800C}/i8251.c ${IMDS800C}/ieprom.c \
${IMDS800C}/m800multibus.c ${IMDS800C}/isbc064.c \
${IMDS800C}/multibus.c ${IMDS800C}/isbc064.c \
${IMDS800C}/isbc202.c ${IMDS800C}/isbc201.c \
${IMDS800C}/zx200a.c ${IMDS800C}/isbc464.c \
${IMDS800C}/isbc206.c ${IMDS800C}/i3214.c
@ -1832,7 +1836,7 @@ IMDS810 = ${IMDS800C}/i8080.c ${IMDS810D}/imds-810_sys.c \
${IMDS810D}/cpu.c ${IMDS810D}/front_panel.c \
${IMDS810D}/monitor.c ${IMDS810C}/ieprom1.c \
${IMDS810C}/i8251.c ${IMDS810C}/ieprom.c \
${IMDS810C}/m800multibus.c ${IMDS810C}/isbc064.c \
${IMDS810C}/multibus.c ${IMDS810C}/isbc064.c \
${IMDS810C}/isbc202.c ${IMDS810C}/isbc201.c \
${IMDS810C}/zx200a.c ${IMDS810C}/isbc464.c \
${IMDS810C}/isbc206.c ${IMDS800C}/i3214.c