Intel-Systems, IBMPC: Standardize to CRLF line endings and spaces for tabs

This commit is contained in:
Bill Beech 2017-03-13 19:42:55 -07:00 committed by Mark Pizzolato
parent 18efafe927
commit a221ac4055
40 changed files with 13418 additions and 13418 deletions

View file

@ -1,97 +1,97 @@
/* ibmpcxt_sys.c: IBM 5160 simulator
Copyright (c) 2016, 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.
11 Jul 16 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8088_dev;
extern REG i8088_reg[];
extern DEVICE i8237_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE xtbus_dev;
/* bit patterns to manipulate 8-bit ports */
#define i82XX_bit_0 0x01 //bit 0 of a port
#define i82XX_bit_1 0x02 //bit 1 of a port
#define i82XX_bit_2 0x04 //bit 2 of a port
#define i82XX_bit_3 0x08 //bit 3 of a port
#define i82XX_bit_4 0x10 //bit 4 of a port
#define i82XX_bit_5 0x20 //bit 5 of a port
#define i82XX_bit_6 0x40 //bit 6 of a port
#define i82XX_bit_7 0x80 //bit 7 of a port
#define i82XX_nbit_0 ~i8255_bit_0 //bit 0 of a port
#define i82XX_nbit_1 ~i8255_bit_1 //bit 1 of a port
#define i82XX_nbit_2 ~i8255_bit_3 //bit 2 of a port
#define i82XX_nbit_3 ~i8255_bit_3 //bit 3 of a port
#define i82XX_nbit_4 ~i8255_bit_4 //bit 4 of a port
#define i82XX_nbit_5 ~i8255_bit_5 //bit 5 of a port
#define i82XX_nbit_6 ~i8255_bit_6 //bit 6 of a port
#define i82XX_nbit_7 ~i8255_bit_7 //bit 7 of a port
/* 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[] = "IBM PC";
REG *sim_PC = &i8088_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8088_dev,
&EPROM_dev,
&RAM_dev,
&i8237_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&xtbus_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* ibmpcxt_sys.c: IBM 5160 simulator
Copyright (c) 2016, 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.
11 Jul 16 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8088_dev;
extern REG i8088_reg[];
extern DEVICE i8237_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE xtbus_dev;
/* bit patterns to manipulate 8-bit ports */
#define i82XX_bit_0 0x01 //bit 0 of a port
#define i82XX_bit_1 0x02 //bit 1 of a port
#define i82XX_bit_2 0x04 //bit 2 of a port
#define i82XX_bit_3 0x08 //bit 3 of a port
#define i82XX_bit_4 0x10 //bit 4 of a port
#define i82XX_bit_5 0x20 //bit 5 of a port
#define i82XX_bit_6 0x40 //bit 6 of a port
#define i82XX_bit_7 0x80 //bit 7 of a port
#define i82XX_nbit_0 ~i8255_bit_0 //bit 0 of a port
#define i82XX_nbit_1 ~i8255_bit_1 //bit 1 of a port
#define i82XX_nbit_2 ~i8255_bit_3 //bit 2 of a port
#define i82XX_nbit_3 ~i8255_bit_3 //bit 3 of a port
#define i82XX_nbit_4 ~i8255_bit_4 //bit 4 of a port
#define i82XX_nbit_5 ~i8255_bit_5 //bit 5 of a port
#define i82XX_nbit_6 ~i8255_bit_6 //bit 6 of a port
#define i82XX_nbit_7 ~i8255_bit_7 //bit 7 of a port
/* 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[] = "IBM PC";
REG *sim_PC = &i8088_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8088_dev,
&EPROM_dev,
&RAM_dev,
&i8237_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&xtbus_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,312 +1,312 @@
/* i8251.c: Intel i8251 UART 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:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8251 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8251 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read from the data port gets the typed character, a write
to the data port writes the character to the device.
*/
#include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8251_devnum = 0; //actual number of 8251 instances + 1
uint16 i8251_port[4]; //baseport port registered to each instance
/* function prototypes */
t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, uint16 baseport);
uint8 i8251_get_dn(void);
uint8 i8251s(t_bool io, uint8 data);
uint8 i8251d(t_bool io, uint8 data);
void i8251_reset1(uint8 devnum);
/* i8251 Standard I/O Data Structures */
/* up to 1 i8251 devices */
UNIT i8251_unit = {
UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT
};
REG i8251_reg[] = {
{ HRDATA (DATA, i8251_unit.buf, 8) },
{ HRDATA (STAT, i8251_unit.u3, 8) },
{ HRDATA (MODE, i8251_unit.u4, 8) },
{ HRDATA (CMD, i8251_unit.u5, 8) },
{ NULL }
};
DEBTAB i8251_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8251_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8251_dev = {
"I8251", //name
&i8251_unit, //units
i8251_reg, //registers
i8251_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8251_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8251_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8251_svc - actually gets char & places in buffer */
t_stat i8251_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8251_unit, i8251_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8251_unit.buf = temp & 0xFF; /* Save char */
i8251_unit.u3 |= RXR; /* Set status */
/* Do any special character handling here */
i8251_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8251_reset (DEVICE *dptr, uint16 baseport)
{
if (i8251_devnum >= I8251_NUM) {
sim_printf("i8251_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8251-%d: Hardware Reset\n", i8251_devnum);
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, baseport);
i8251_port[i8251_devnum] = baseport;
reg_dev(i8251d, baseport, i8251_devnum);
reg_dev(i8251s, baseport + 1, i8251_devnum);
i8251_reset1(i8251_devnum);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
i8251_devnum++;
return SCPE_OK;
}
void i8251_reset1(uint8 devnum)
{
i8251_unit.u3 = TXR + TXE; /* status */
i8251_unit.u4 = 0; /* mode instruction */
i8251_unit.u5 = 0; /* command instruction */
i8251_unit.u6 = 0;
i8251_unit.buf = 0;
i8251_unit.pos = 0;
sim_printf(" 8251-%d: Software Reset\n", devnum);
}
uint8 i8251_get_dn(void)
{
int i;
for (i=0; i<I8251_NUM; i++)
if (port >= i8251_port[i] && port <= i8251_port[i] + 1)
return i;
sim_printf("i8251_get_dn: port %04X not in 8251 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
uint8 i8251s(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
// sim_printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */
return i8251_unit.u3;
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
if (DEBUG)
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8251_reset1(devnum);
} else { /* set mode */
i8251_unit.u4 = data;
if (DEBUG)
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */
}
}
}
return 0;
}
uint8 i8251d(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
}
return 0;
}
/* end of i8251.c */
/* i8251.c: Intel i8251 UART 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:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8251 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8251 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read from the data port gets the typed character, a write
to the data port writes the character to the device.
*/
#include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8251_devnum = 0; //actual number of 8251 instances + 1
uint16 i8251_port[4]; //baseport port registered to each instance
/* function prototypes */
t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, uint16 baseport);
uint8 i8251_get_dn(void);
uint8 i8251s(t_bool io, uint8 data);
uint8 i8251d(t_bool io, uint8 data);
void i8251_reset1(uint8 devnum);
/* i8251 Standard I/O Data Structures */
/* up to 1 i8251 devices */
UNIT i8251_unit = {
UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT
};
REG i8251_reg[] = {
{ HRDATA (DATA, i8251_unit.buf, 8) },
{ HRDATA (STAT, i8251_unit.u3, 8) },
{ HRDATA (MODE, i8251_unit.u4, 8) },
{ HRDATA (CMD, i8251_unit.u5, 8) },
{ NULL }
};
DEBTAB i8251_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8251_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8251_dev = {
"I8251", //name
&i8251_unit, //units
i8251_reg, //registers
i8251_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8251_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8251_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8251_svc - actually gets char & places in buffer */
t_stat i8251_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8251_unit, i8251_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8251_unit.buf = temp & 0xFF; /* Save char */
i8251_unit.u3 |= RXR; /* Set status */
/* Do any special character handling here */
i8251_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8251_reset (DEVICE *dptr, uint16 baseport)
{
if (i8251_devnum >= I8251_NUM) {
sim_printf("i8251_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8251-%d: Hardware Reset\n", i8251_devnum);
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, baseport);
i8251_port[i8251_devnum] = baseport;
reg_dev(i8251d, baseport, i8251_devnum);
reg_dev(i8251s, baseport + 1, i8251_devnum);
i8251_reset1(i8251_devnum);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
i8251_devnum++;
return SCPE_OK;
}
void i8251_reset1(uint8 devnum)
{
i8251_unit.u3 = TXR + TXE; /* status */
i8251_unit.u4 = 0; /* mode instruction */
i8251_unit.u5 = 0; /* command instruction */
i8251_unit.u6 = 0;
i8251_unit.buf = 0;
i8251_unit.pos = 0;
sim_printf(" 8251-%d: Software Reset\n", devnum);
}
uint8 i8251_get_dn(void)
{
int i;
for (i=0; i<I8251_NUM; i++)
if (port >= i8251_port[i] && port <= i8251_port[i] + 1)
return i;
sim_printf("i8251_get_dn: port %04X not in 8251 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
uint8 i8251s(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
// sim_printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */
return i8251_unit.u3;
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
if (DEBUG)
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8251_reset1(devnum);
} else { /* set mode */
i8251_unit.u4 = data;
if (DEBUG)
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */
}
}
}
return 0;
}
uint8 i8251d(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
}
return 0;
}
/* end of i8251.c */

View file

@ -1,248 +1,248 @@
/* i8253.c: Intel i8253 PIT 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:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
*/
#include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8253_devnum = 0; //actual number of 8253 instances + 1
uint16 i8253_port[4]; //baseport port registered to each instance
/* function prototypes */
t_stat i8253_svc (UNIT *uptr);
t_stat i8253_reset (DEVICE *dptr, uint16 baseport);
uint8 i8253_get_dn(void);
uint8 i8253t0(t_bool io, uint8 data);
uint8 i8253t1(t_bool io, uint8 data);
uint8 i8253t2(t_bool io, uint8 data);
uint8 i8253c(t_bool io, uint8 data);
/* i8253 Standard I/O Data Structures */
/* up to 4 i8253 devices */
UNIT i8253_unit[] = {
{ UDATA (&i8253_svc, 0, 0), 20 },
{ UDATA (&i8253_svc, 0, 0), 20 },
{ UDATA (&i8253_svc, 0, 0), 20 },
{ UDATA (&i8253_svc, 0, 0), 20 }
};
REG i8253_reg[] = {
{ HRDATA (T0, i8253_unit[0].u3, 8) },
{ HRDATA (T1, i8253_unit[0].u4, 8) },
{ HRDATA (T2, i8253_unit[0].u5, 8) },
{ HRDATA (CMD, i8253_unit[0].u6, 8) },
{ HRDATA (T0, i8253_unit[1].u3, 8) },
{ HRDATA (T1, i8253_unit[1].u4, 8) },
{ HRDATA (T2, i8253_unit[1].u5, 8) },
{ HRDATA (CMD, i8253_unit[1].u6, 8) },
{ NULL }
};
DEBTAB i8253_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8253_mod[] = {
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8253_dev = {
"I8251", //name
i8253_unit, //units
i8253_reg, //registers
i8253_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8253_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8253_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8253_svc - actually gets char & places in buffer */
t_stat i8253_svc (UNIT *uptr)
{
sim_activate (&i8253_unit[0], i8253_unit[0].wait); /* continue poll */
return SCPE_OK;
}
/* Reset routine */
t_stat i8253_reset (DEVICE *dptr, uint16 baseport)
{
if (i8253_devnum > I8253_NUM) {
sim_printf("i8253_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8253-%d: Reset\n", i8253_devnum);
sim_printf(" 8253-%d: Registered at %04X\n", i8253_devnum, baseport);
i8253_port[i8253_devnum] = baseport;
reg_dev(i8253t0, baseport, i8253_devnum);
reg_dev(i8253t1, baseport + 1, i8253_devnum);
reg_dev(i8253t2, baseport + 2, i8253_devnum);
reg_dev(i8253c, baseport + 3, i8253_devnum);
i8253_unit[i8253_devnum].u3 = 0; /* status */
i8253_unit[i8253_devnum].u4 = 0; /* mode instruction */
i8253_unit[i8253_devnum].u5 = 0; /* command instruction */
i8253_unit[i8253_devnum].u6 = 0;
// sim_activate (&i8253_unit[i8253_devnum], i8253_unit[i8253_devnum].wait); /* activate unit */
i8253_devnum++;
return SCPE_OK;
}
uint8 i8253_get_dn(void)
{
int i;
for (i=0; i<I8253_NUM; i++)
if (port >= i8253_port[i] && port <= i8253_port[i] + 3)
return i;
sim_printf("i8253_get_dn: port %04X not in 8253 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
uint8 i8253t0(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return i8253_unit[devnum].u3;
} else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 0=%02X\n", devnum, data);
i8253_unit[devnum].u3 = data;
//sim_activate_after (&i8253_unit[devnum], );
return 0;
}
}
return 0;
}
//read routine:
//sim_activate_time(&i8253_unit[devnum])/sim_inst_per_second()
uint8 i8253t1(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return i8253_unit[devnum].u4;
} else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 1=%02X\n", devnum, data);
i8253_unit[devnum].u4 = data;
return 0;
}
}
return 0;
}
uint8 i8253t2(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return i8253_unit[devnum].u5;
} else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 2=%02X\n", devnum, data);
i8253_unit[devnum].u5 = data;
return 0;
}
}
return 0;
}
uint8 i8253c(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return i8253_unit[devnum].u6;
} else { /* write data port */
i8253_unit[devnum].u6 = data;
if (DEBUG)
sim_printf(" 8253-%d: Mode Instruction=%02X\n", devnum, data);
return 0;
}
}
return 0;
}
/* end of i8253.c */
/* i8253.c: Intel i8253 PIT 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:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
*/
#include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8253_devnum = 0; //actual number of 8253 instances + 1
uint16 i8253_port[4]; //baseport port registered to each instance
/* function prototypes */
t_stat i8253_svc (UNIT *uptr);
t_stat i8253_reset (DEVICE *dptr, uint16 baseport);
uint8 i8253_get_dn(void);
uint8 i8253t0(t_bool io, uint8 data);
uint8 i8253t1(t_bool io, uint8 data);
uint8 i8253t2(t_bool io, uint8 data);
uint8 i8253c(t_bool io, uint8 data);
/* i8253 Standard I/O Data Structures */
/* up to 4 i8253 devices */
UNIT i8253_unit[] = {
{ UDATA (&i8253_svc, 0, 0), 20 },
{ UDATA (&i8253_svc, 0, 0), 20 },
{ UDATA (&i8253_svc, 0, 0), 20 },
{ UDATA (&i8253_svc, 0, 0), 20 }
};
REG i8253_reg[] = {
{ HRDATA (T0, i8253_unit[0].u3, 8) },
{ HRDATA (T1, i8253_unit[0].u4, 8) },
{ HRDATA (T2, i8253_unit[0].u5, 8) },
{ HRDATA (CMD, i8253_unit[0].u6, 8) },
{ HRDATA (T0, i8253_unit[1].u3, 8) },
{ HRDATA (T1, i8253_unit[1].u4, 8) },
{ HRDATA (T2, i8253_unit[1].u5, 8) },
{ HRDATA (CMD, i8253_unit[1].u6, 8) },
{ NULL }
};
DEBTAB i8253_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8253_mod[] = {
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8253_dev = {
"I8251", //name
i8253_unit, //units
i8253_reg, //registers
i8253_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8253_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8253_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8253_svc - actually gets char & places in buffer */
t_stat i8253_svc (UNIT *uptr)
{
sim_activate (&i8253_unit[0], i8253_unit[0].wait); /* continue poll */
return SCPE_OK;
}
/* Reset routine */
t_stat i8253_reset (DEVICE *dptr, uint16 baseport)
{
if (i8253_devnum > I8253_NUM) {
sim_printf("i8253_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8253-%d: Reset\n", i8253_devnum);
sim_printf(" 8253-%d: Registered at %04X\n", i8253_devnum, baseport);
i8253_port[i8253_devnum] = baseport;
reg_dev(i8253t0, baseport, i8253_devnum);
reg_dev(i8253t1, baseport + 1, i8253_devnum);
reg_dev(i8253t2, baseport + 2, i8253_devnum);
reg_dev(i8253c, baseport + 3, i8253_devnum);
i8253_unit[i8253_devnum].u3 = 0; /* status */
i8253_unit[i8253_devnum].u4 = 0; /* mode instruction */
i8253_unit[i8253_devnum].u5 = 0; /* command instruction */
i8253_unit[i8253_devnum].u6 = 0;
// sim_activate (&i8253_unit[i8253_devnum], i8253_unit[i8253_devnum].wait); /* activate unit */
i8253_devnum++;
return SCPE_OK;
}
uint8 i8253_get_dn(void)
{
int i;
for (i=0; i<I8253_NUM; i++)
if (port >= i8253_port[i] && port <= i8253_port[i] + 3)
return i;
sim_printf("i8253_get_dn: port %04X not in 8253 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
uint8 i8253t0(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return i8253_unit[devnum].u3;
} else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 0=%02X\n", devnum, data);
i8253_unit[devnum].u3 = data;
//sim_activate_after (&i8253_unit[devnum], );
return 0;
}
}
return 0;
}
//read routine:
//sim_activate_time(&i8253_unit[devnum])/sim_inst_per_second()
uint8 i8253t1(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return i8253_unit[devnum].u4;
} else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 1=%02X\n", devnum, data);
i8253_unit[devnum].u4 = data;
return 0;
}
}
return 0;
}
uint8 i8253t2(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return i8253_unit[devnum].u5;
} else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 2=%02X\n", devnum, data);
i8253_unit[devnum].u5 = data;
return 0;
}
}
return 0;
}
uint8 i8253c(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return i8253_unit[devnum].u6;
} else { /* write data port */
i8253_unit[devnum].u6 = data;
if (DEBUG)
sim_printf(" 8253-%d: Mode Instruction=%02X\n", devnum, data);
return 0;
}
}
return 0;
}
/* end of i8253.c */

View file

@ -1,295 +1,295 @@
/* i8255.c: Intel i8255 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:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (i8255s)
and three data ports (i8255a, i8255b, and i8255c).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
This program simulates up to 4 i8255 devices. It handles 2 i8255
devices on the iSBC 80/10 SBC. Other devices could be on other
multibus boards in the simulated system.
*/
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* function prototypes */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport);
uint8 i8255_get_dn(void);
uint8 i8255a(t_bool io, uint8 data);
uint8 i8255b(t_bool io, uint8 data);
uint8 i8255c(t_bool io, uint8 data);
uint8 i8255s(t_bool io, uint8 data);
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8255_devnum = 0; //actual number of 8255 instances + 1
uint16 i8255_port[4]; //baseport port registered to each instance
/* these bytes represent the input and output to/from a port instance */
uint8 i8255_A[4]; //port A byte I/O
uint8 i8255_B[4]; //port B byte I/O
uint8 i8255_C[4]; //port C byte I/O
/* i8255 Standard I/O Data Structures */
/* up to 4 i8255 devices */
UNIT i8255_unit[] = {
{ UDATA (0, 0, 0) }, /* i8255 0 */
{ UDATA (0, 0, 0) }, /* i8255 1 */
{ UDATA (0, 0, 0) }, /* i8255 2 */
{ UDATA (0, 0, 0) } /* i8255 3 */
};
REG i8255_reg[] = {
{ HRDATA (CS0, i8255_unit[0].u3, 8) }, /* i8255 0 */
{ HRDATA (A0, i8255_A[0], 8) },
{ HRDATA (B0, i8255_B[0], 8) },
{ HRDATA (C0, i8255_C[0], 8) },
{ HRDATA (CS1, i8255_unit[1].u3, 8) }, /* i8255 1 */
{ HRDATA (A1, i8255_A[1], 8) },
{ HRDATA (B1, i8255_B[1], 8) },
{ HRDATA (C1, i8255_C[1], 8) },
{ HRDATA (CS2, i8255_unit[2].u3, 8) }, /* i8255 2 */
{ HRDATA (A2, i8255_A[2], 8) },
{ HRDATA (B2, i8255_B[2], 8) },
{ HRDATA (C2, i8255_C[2], 8) },
{ HRDATA (CS3, i8255_unit[3].u3, 8) }, /* i8255 3 */
{ HRDATA (A3, i8255_A[3], 8) },
{ HRDATA (B3, i8255_B[3], 8) },
{ HRDATA (C3, i8255_C[3], 8) },
{ NULL }
};
DEBTAB i8255_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8255_dev = {
"I8255", //name
i8255_unit, //units
i8255_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// i8255_reset2(), //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8255_debug, //debflags
NULL, //msize
NULL //lname
};
/* Reset routine */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport)
{
if (i8255_devnum > I8255_NUM) {
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8255-%d: Reset\n", i8255_devnum);
sim_printf(" 8255-%d: Registered at %04X\n", i8255_devnum, baseport);
i8255_port[i8255_devnum] = baseport;
reg_dev(i8255a, baseport, i8255_devnum);
reg_dev(i8255b, baseport + 1, i8255_devnum);
reg_dev(i8255c, baseport + 2, i8255_devnum);
reg_dev(i8255s, baseport + 3, i8255_devnum);
i8255_unit[i8255_devnum].u3 = 0x9B; /* control */
i8255_A[i8255_devnum] = 0xFF; /* Port A */
i8255_B[i8255_devnum] = 0xFF; /* Port B */
i8255_C[i8255_devnum] = 0xFF; /* Port C */
i8255_devnum++;
return SCPE_OK;
}
uint8 i8255_get_dn(void)
{
int i;
for (i=0; i<I8255_NUM; i++)
if (port >=i8255_port[i] && port <= i8255_port[i] + 3)
return i;
sim_printf("i8255_get_dn: port %04X not in 8255 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* i8255 functions */
uint8 i8255s(t_bool io, uint8 data)
{
uint8 bit;
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return 0xFF; //undefined
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[devnum].u3 = data;
if (DEBUG)
sim_printf(" 8255-%d: Mode Instruction=%02X\n", devnum, data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_C[devnum] |= (0x01 << bit);
} else { /* reset bit */
i8255_C[devnum] &= ~(0x01 << bit);
}
}
}
}
return 0;
}
uint8 i8255a(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
//return (i8255_unit[devnum].u4);
return (i8255_A[devnum]);
} else { /* write data port */
i8255_A[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
}
}
return 0;
}
uint8 i8255b(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return (i8255_B[devnum]);
} else { /* write data port */
i8255_B[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
}
}
return 0;
}
uint8 i8255c(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return (i8255_C[devnum]);
} else { /* write data port */
i8255_C[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
}
}
return 0;
}
/* end of i8255.c */
/* i8255.c: Intel i8255 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:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (i8255s)
and three data ports (i8255a, i8255b, and i8255c).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
This program simulates up to 4 i8255 devices. It handles 2 i8255
devices on the iSBC 80/10 SBC. Other devices could be on other
multibus boards in the simulated system.
*/
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* function prototypes */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport);
uint8 i8255_get_dn(void);
uint8 i8255a(t_bool io, uint8 data);
uint8 i8255b(t_bool io, uint8 data);
uint8 i8255c(t_bool io, uint8 data);
uint8 i8255s(t_bool io, uint8 data);
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8255_devnum = 0; //actual number of 8255 instances + 1
uint16 i8255_port[4]; //baseport port registered to each instance
/* these bytes represent the input and output to/from a port instance */
uint8 i8255_A[4]; //port A byte I/O
uint8 i8255_B[4]; //port B byte I/O
uint8 i8255_C[4]; //port C byte I/O
/* i8255 Standard I/O Data Structures */
/* up to 4 i8255 devices */
UNIT i8255_unit[] = {
{ UDATA (0, 0, 0) }, /* i8255 0 */
{ UDATA (0, 0, 0) }, /* i8255 1 */
{ UDATA (0, 0, 0) }, /* i8255 2 */
{ UDATA (0, 0, 0) } /* i8255 3 */
};
REG i8255_reg[] = {
{ HRDATA (CS0, i8255_unit[0].u3, 8) }, /* i8255 0 */
{ HRDATA (A0, i8255_A[0], 8) },
{ HRDATA (B0, i8255_B[0], 8) },
{ HRDATA (C0, i8255_C[0], 8) },
{ HRDATA (CS1, i8255_unit[1].u3, 8) }, /* i8255 1 */
{ HRDATA (A1, i8255_A[1], 8) },
{ HRDATA (B1, i8255_B[1], 8) },
{ HRDATA (C1, i8255_C[1], 8) },
{ HRDATA (CS2, i8255_unit[2].u3, 8) }, /* i8255 2 */
{ HRDATA (A2, i8255_A[2], 8) },
{ HRDATA (B2, i8255_B[2], 8) },
{ HRDATA (C2, i8255_C[2], 8) },
{ HRDATA (CS3, i8255_unit[3].u3, 8) }, /* i8255 3 */
{ HRDATA (A3, i8255_A[3], 8) },
{ HRDATA (B3, i8255_B[3], 8) },
{ HRDATA (C3, i8255_C[3], 8) },
{ NULL }
};
DEBTAB i8255_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8255_dev = {
"I8255", //name
i8255_unit, //units
i8255_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// i8255_reset2(), //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8255_debug, //debflags
NULL, //msize
NULL //lname
};
/* Reset routine */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport)
{
if (i8255_devnum > I8255_NUM) {
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8255-%d: Reset\n", i8255_devnum);
sim_printf(" 8255-%d: Registered at %04X\n", i8255_devnum, baseport);
i8255_port[i8255_devnum] = baseport;
reg_dev(i8255a, baseport, i8255_devnum);
reg_dev(i8255b, baseport + 1, i8255_devnum);
reg_dev(i8255c, baseport + 2, i8255_devnum);
reg_dev(i8255s, baseport + 3, i8255_devnum);
i8255_unit[i8255_devnum].u3 = 0x9B; /* control */
i8255_A[i8255_devnum] = 0xFF; /* Port A */
i8255_B[i8255_devnum] = 0xFF; /* Port B */
i8255_C[i8255_devnum] = 0xFF; /* Port C */
i8255_devnum++;
return SCPE_OK;
}
uint8 i8255_get_dn(void)
{
int i;
for (i=0; i<I8255_NUM; i++)
if (port >=i8255_port[i] && port <= i8255_port[i] + 3)
return i;
sim_printf("i8255_get_dn: port %04X not in 8255 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* i8255 functions */
uint8 i8255s(t_bool io, uint8 data)
{
uint8 bit;
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return 0xFF; //undefined
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[devnum].u3 = data;
if (DEBUG)
sim_printf(" 8255-%d: Mode Instruction=%02X\n", devnum, data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_C[devnum] |= (0x01 << bit);
} else { /* reset bit */
i8255_C[devnum] &= ~(0x01 << bit);
}
}
}
}
return 0;
}
uint8 i8255a(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
//return (i8255_unit[devnum].u4);
return (i8255_A[devnum]);
} else { /* write data port */
i8255_A[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
}
}
return 0;
}
uint8 i8255b(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return (i8255_B[devnum]);
} else { /* write data port */
i8255_B[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
}
}
return 0;
}
uint8 i8255c(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return (i8255_C[devnum]);
} else { /* write data port */
i8255_C[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
}
}
return 0;
}
/* end of i8255.c */

View file

@ -1,268 +1,268 @@
/* i8259.c: Intel i8259 PIC 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.
NOTES:
This software was written by Bill Beech, 24 Jan 13, to allow emulation of
more complex Multibus Computer Systems.
This program simulates up to 2 i8259 devices. It handles 1 i8259
device on the iSBC 80/20 and iSBC 80/30 SBCs. Other devices could be on
other multibus boards in the simulated system.
*/
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* function prototypes */
uint8 i8259a(t_bool io, uint8 data);
uint8 i8259b(t_bool io, uint8 data);
void i8259_dump(uint8 devnum);
t_stat i8259_reset (DEVICE *dptr, uint16 baseport);
uint8 i8259_get_dn(void);
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8259_devnum = 0; //actual number of 8259 instances + 1
uint16 i8259_port[4]; //baseport port registered to each instance
uint8 i8259_base[I8259_NUM];
uint8 i8259_icw1[I8259_NUM];
uint8 i8259_icw2[I8259_NUM];
uint8 i8259_icw3[I8259_NUM];
uint8 i8259_icw4[I8259_NUM];
uint8 i8259_ocw1[I8259_NUM];
uint8 i8259_ocw2[I8259_NUM];
uint8 i8259_ocw3[I8259_NUM];
uint8 icw_num0 = 1, icw_num1 = 1;
/* i8259 Standard I/O Data Structures */
/* up to 2 i8259 devices */
UNIT i8259_unit[] = {
{ UDATA (0, 0, 0) }, /* i8259 0 */
{ UDATA (0, 0, 0) }, /* i8259 1 */
{ UDATA (0, 0, 0) }, /* i8259 2 */
{ UDATA (0, 0, 0) } /* i8259 3 */
};
REG i8259_reg[] = {
{ HRDATA (IRR0, i8259_unit[0].u3, 8) }, /* i8259 0 */
{ HRDATA (ISR0, i8259_unit[0].u4, 8) },
{ HRDATA (IMR0, i8259_unit[0].u5, 8) },
{ HRDATA (IRR1, i8259_unit[1].u3, 8) }, /* i8259 1 */
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
{ HRDATA (IRR1, i8259_unit[2].u3, 8) }, /* i8259 2 */
{ HRDATA (ISR1, i8259_unit[2].u4, 8) },
{ HRDATA (IMR1, i8259_unit[2].u5, 8) },
{ HRDATA (IRR1, i8259_unit[3].u3, 8) }, /* i8259 3 */
{ HRDATA (ISR1, i8259_unit[3].u4, 8) },
{ HRDATA (IMR1, i8259_unit[3].u5, 8) },
{ NULL }
};
DEBTAB i8259_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 i8259_dev = {
"I8259", //name
i8259_unit, //units
i8259_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8259_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8259_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* Reset routine */
t_stat i8259_reset (DEVICE *dptr, uint16 baseport)
{
if (i8259_devnum >= I8259_NUM) {
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8259-%d: Reset\n", i8259_devnum);
sim_printf(" 8259-%d: Registered at %04X\n", i8259_devnum, baseport);
i8259_port[i8259_devnum] = baseport;
reg_dev(i8259a, baseport, i8259_devnum);
reg_dev(i8259b, baseport + 1, i8259_devnum);
i8259_unit[i8259_devnum].u3 = 0x00; /* IRR */
i8259_unit[i8259_devnum].u4 = 0x00; /* ISR */
i8259_unit[i8259_devnum].u5 = 0x00; /* IMR */
i8259_devnum++;
return SCPE_OK;
}
uint8 i8259_get_dn(void)
{
int i;
for (i=0; i<I8259_NUM; i++)
if (port >= i8259_port[i] && port <= i8259_port[i] + 1)
return i;
sim_printf("i8259_get_dn: port %04X not in 8259 device table\n", port);
return 0xFF;
}
/* i8259 functions */
uint8 i8259a(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8259_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[devnum].u3); /* IRR */
if ((i8259_ocw3[devnum] & 0x03) == 0x03)
return (i8259_unit[devnum].u4); /* ISR */
} else { /* write data port */
if (data & 0x10) {
icw_num0 = 1;
}
if (icw_num0 == 1) {
i8259_icw1[devnum] = data; /* ICW1 */
i8259_unit[devnum].u5 = 0x00; /* clear IMR */
i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
} else {
switch (data & 0x18) {
case 0: /* OCW2 */
i8259_ocw2[devnum] = data;
break;
case 8: /* OCW3 */
i8259_ocw3[devnum] = data;
break;
default:
sim_printf("8259a-%d: OCW Error %02X\n", devnum, data);
break;
}
}
if (DEBUG)
sim_printf(" 8259-%d: A data = %02X\n", devnum, data);
icw_num0++; /* step ICW number */
}
// i8259_dump(devnum);
}
return 0;
}
uint8 i8259b(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8259_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[devnum].u3); /* IRR */
if ((i8259_ocw3[devnum] & 0x03) == 0x03)
return (i8259_unit[devnum].u4); /* ISR */
} else { /* write data port */
if (data & 0x10) {
icw_num1 = 1;
}
if (icw_num1 == 1) {
i8259_icw1[devnum] = data; /* ICW1 */
i8259_unit[devnum].u5 = 0x00; /* clear IMR */
i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
} else {
switch (data & 0x18) {
case 0: /* OCW2 */
i8259_ocw2[devnum] = data;
break;
case 8: /* OCW3 */
i8259_ocw3[devnum] = data;
break;
default:
sim_printf("8259b-%d: OCW Error %02X\n", devnum, data);
break;
}
}
if (DEBUG)
sim_printf(" 8259-%d: B data = %02X\n", devnum, data);
icw_num1++; /* step ICW number */
}
// i8259_dump(devnum);
}
return 0;
}
void i8259_dump(uint8 devnum)
{
sim_printf("Device %d", devnum);
sim_printf(" IRR=%02X", i8259_unit[devnum].u3);
sim_printf(" ISR=%02X", i8259_unit[devnum].u4);
sim_printf(" IMR=%02X", i8259_unit[devnum].u5);
sim_printf(" ICW1=%02X", i8259_icw1[devnum]);
sim_printf(" ICW2=%02X", i8259_icw2[devnum]);
sim_printf(" ICW3=%02X", i8259_icw3[devnum]);
sim_printf(" ICW4=%02X", i8259_icw4[devnum]);
sim_printf(" OCW1=%02X", i8259_ocw1[devnum]);
sim_printf(" OCW2=%02X", i8259_ocw2[devnum]);
sim_printf(" OCW3=%02X\n", i8259_ocw3[devnum]);
}
/* end of i8259.c */
/* i8259.c: Intel i8259 PIC 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.
NOTES:
This software was written by Bill Beech, 24 Jan 13, to allow emulation of
more complex Multibus Computer Systems.
This program simulates up to 2 i8259 devices. It handles 1 i8259
device on the iSBC 80/20 and iSBC 80/30 SBCs. Other devices could be on
other multibus boards in the simulated system.
*/
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* function prototypes */
uint8 i8259a(t_bool io, uint8 data);
uint8 i8259b(t_bool io, uint8 data);
void i8259_dump(uint8 devnum);
t_stat i8259_reset (DEVICE *dptr, uint16 baseport);
uint8 i8259_get_dn(void);
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8259_devnum = 0; //actual number of 8259 instances + 1
uint16 i8259_port[4]; //baseport port registered to each instance
uint8 i8259_base[I8259_NUM];
uint8 i8259_icw1[I8259_NUM];
uint8 i8259_icw2[I8259_NUM];
uint8 i8259_icw3[I8259_NUM];
uint8 i8259_icw4[I8259_NUM];
uint8 i8259_ocw1[I8259_NUM];
uint8 i8259_ocw2[I8259_NUM];
uint8 i8259_ocw3[I8259_NUM];
uint8 icw_num0 = 1, icw_num1 = 1;
/* i8259 Standard I/O Data Structures */
/* up to 2 i8259 devices */
UNIT i8259_unit[] = {
{ UDATA (0, 0, 0) }, /* i8259 0 */
{ UDATA (0, 0, 0) }, /* i8259 1 */
{ UDATA (0, 0, 0) }, /* i8259 2 */
{ UDATA (0, 0, 0) } /* i8259 3 */
};
REG i8259_reg[] = {
{ HRDATA (IRR0, i8259_unit[0].u3, 8) }, /* i8259 0 */
{ HRDATA (ISR0, i8259_unit[0].u4, 8) },
{ HRDATA (IMR0, i8259_unit[0].u5, 8) },
{ HRDATA (IRR1, i8259_unit[1].u3, 8) }, /* i8259 1 */
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
{ HRDATA (IRR1, i8259_unit[2].u3, 8) }, /* i8259 2 */
{ HRDATA (ISR1, i8259_unit[2].u4, 8) },
{ HRDATA (IMR1, i8259_unit[2].u5, 8) },
{ HRDATA (IRR1, i8259_unit[3].u3, 8) }, /* i8259 3 */
{ HRDATA (ISR1, i8259_unit[3].u4, 8) },
{ HRDATA (IMR1, i8259_unit[3].u5, 8) },
{ NULL }
};
DEBTAB i8259_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 i8259_dev = {
"I8259", //name
i8259_unit, //units
i8259_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8259_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8259_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* Reset routine */
t_stat i8259_reset (DEVICE *dptr, uint16 baseport)
{
if (i8259_devnum >= I8259_NUM) {
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8259-%d: Reset\n", i8259_devnum);
sim_printf(" 8259-%d: Registered at %04X\n", i8259_devnum, baseport);
i8259_port[i8259_devnum] = baseport;
reg_dev(i8259a, baseport, i8259_devnum);
reg_dev(i8259b, baseport + 1, i8259_devnum);
i8259_unit[i8259_devnum].u3 = 0x00; /* IRR */
i8259_unit[i8259_devnum].u4 = 0x00; /* ISR */
i8259_unit[i8259_devnum].u5 = 0x00; /* IMR */
i8259_devnum++;
return SCPE_OK;
}
uint8 i8259_get_dn(void)
{
int i;
for (i=0; i<I8259_NUM; i++)
if (port >= i8259_port[i] && port <= i8259_port[i] + 1)
return i;
sim_printf("i8259_get_dn: port %04X not in 8259 device table\n", port);
return 0xFF;
}
/* i8259 functions */
uint8 i8259a(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8259_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[devnum].u3); /* IRR */
if ((i8259_ocw3[devnum] & 0x03) == 0x03)
return (i8259_unit[devnum].u4); /* ISR */
} else { /* write data port */
if (data & 0x10) {
icw_num0 = 1;
}
if (icw_num0 == 1) {
i8259_icw1[devnum] = data; /* ICW1 */
i8259_unit[devnum].u5 = 0x00; /* clear IMR */
i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
} else {
switch (data & 0x18) {
case 0: /* OCW2 */
i8259_ocw2[devnum] = data;
break;
case 8: /* OCW3 */
i8259_ocw3[devnum] = data;
break;
default:
sim_printf("8259a-%d: OCW Error %02X\n", devnum, data);
break;
}
}
if (DEBUG)
sim_printf(" 8259-%d: A data = %02X\n", devnum, data);
icw_num0++; /* step ICW number */
}
// i8259_dump(devnum);
}
return 0;
}
uint8 i8259b(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8259_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[devnum].u3); /* IRR */
if ((i8259_ocw3[devnum] & 0x03) == 0x03)
return (i8259_unit[devnum].u4); /* ISR */
} else { /* write data port */
if (data & 0x10) {
icw_num1 = 1;
}
if (icw_num1 == 1) {
i8259_icw1[devnum] = data; /* ICW1 */
i8259_unit[devnum].u5 = 0x00; /* clear IMR */
i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
} else {
switch (data & 0x18) {
case 0: /* OCW2 */
i8259_ocw2[devnum] = data;
break;
case 8: /* OCW3 */
i8259_ocw3[devnum] = data;
break;
default:
sim_printf("8259b-%d: OCW Error %02X\n", devnum, data);
break;
}
}
if (DEBUG)
sim_printf(" 8259-%d: B data = %02X\n", devnum, data);
icw_num1++; /* step ICW number */
}
// i8259_dump(devnum);
}
return 0;
}
void i8259_dump(uint8 devnum)
{
sim_printf("Device %d", devnum);
sim_printf(" IRR=%02X", i8259_unit[devnum].u3);
sim_printf(" ISR=%02X", i8259_unit[devnum].u4);
sim_printf(" IMR=%02X", i8259_unit[devnum].u5);
sim_printf(" ICW1=%02X", i8259_icw1[devnum]);
sim_printf(" ICW2=%02X", i8259_icw2[devnum]);
sim_printf(" ICW3=%02X", i8259_icw3[devnum]);
sim_printf(" ICW4=%02X", i8259_icw4[devnum]);
sim_printf(" OCW1=%02X", i8259_ocw1[devnum]);
sim_printf(" OCW2=%02X", i8259_ocw2[devnum]);
sim_printf(" OCW3=%02X\n", i8259_ocw3[devnum]);
}
/* end of i8259.c */

View file

@ -1,228 +1,228 @@
/* i8272.c: Intel 8272 FDC 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:
?? ??? 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:
u6 - unit number/device number
*/
#include "system_defs.h"
/* external globals */
extern uint16 port;
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
/* function prototypes */
t_stat i8272_svc (UNIT *uptr);
t_stat i8272_reset (DEVICE *dptr, uint16 base);
void i8272_reset1(uint8 devnum);
uint8 i8272_get_dn(void);
uint8 i8251s(t_bool io, uint8 data);
uint8 i8251d(t_bool io, uint8 data);
/* globals */
int32 i8272_devnum = 0; //initially, no 8272 instances
uint16 i8272_port[4]; //base port assigned to each 8272 instance
/* i8272 Standard I/O Data Structures */
/* up to 4 i8282 devices */
UNIT i8272_unit[4] = {
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT }
};
REG i8272_reg[4] = {
{ HRDATA (DATA, i8272_unit[0].buf, 8) },
{ HRDATA (STAT, i8272_unit[0].u3, 8) },
{ HRDATA (MODE, i8272_unit[0].u4, 8) },
{ HRDATA (CMD, i8272_unit[0].u5, 8) }
};
DEBTAB i8272_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8272_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8272_dev = {
"I8272", //name
i8272_unit, //units
i8272_reg, //registers
i8272_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8272_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8272_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8272_svc - actually does FDD read and write */
t_stat i8272_svc(UNIT *uptr)
{
int32 temp;
sim_activate(&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait); /* continue poll */
if (uptr->u6 >= i8272_devnum) return SCPE_OK;
if ((temp = sim_poll_kbd()) < SCPE_KFLAG)
return temp; /* no char or error? */
//sim_printf("i8272_svc: received character temp=%04X devnum=%d\n", temp, uptr->u6);
i8272_unit[uptr->u6].buf = temp & 0xFF; /* Save char */
i8272_unit[uptr->u6].u3 |= RXR; /* Set status */
return SCPE_OK;
}
/* Reset routine */
t_stat i8272_reset(DEVICE *dptr, uint16 base)
{
if (i8272_devnum >= i8272_NUM) {
sim_printf("8251_reset: too many devices!\n");
return 0;
}
i8272_reset1(i8272_devnum);
sim_printf(" 8251-%d: Registered at %03X\n", i8272_devnum, base);
i8272_port[i8272_devnum] = reg_dev(i8251d, base);
reg_dev(i8251s, base + 1);
i8272_unit[i8272_devnum].u6 = i8272_devnum;
sim_activate(&i8272_unit[i8272_devnum], i8272_unit[i8272_devnum].wait); /* activate unit */
i8272_devnum++;
return SCPE_OK;
}
void i8272_reset1(uint8 devnum)
{
i8272_unit[devnum].u3 = TXR + TXE; /* status */
i8272_unit[devnum].u4 = 0; /* mode instruction */
i8272_unit[devnum].u5 = 0; /* command instruction */
i8272_unit[devnum].buf = 0;
i8272_unit[devnum].pos = 0;
sim_printf(" 8251-%d: Reset\n", devnum);
}
uint8 i8272_get_dn(void)
{
int i;
for (i=0; i<i8272_NUM; i++)
if (port >=i8272_port[i] && port <= i8272_port[i] + 1)
return i;
sim_printf("i8272_get_dn: port %03X not in 8251 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
uint8 i8251s(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8272_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return i8272_unit[devnum].u3;
} else { /* write status port */
if (i8272_unit[devnum].u6) { /* if mode, set cmd */
i8272_unit[devnum].u5 = data;
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8272_reset1(devnum);
} else { /* set mode */
i8272_unit[devnum].u4 = data;
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8272_unit[devnum].u6 = 1; /* set cmd received */
}
}
}
return 0;
}
uint8 i8251d(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8272_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
i8272_unit[devnum].u3 &= ~RXR;
return (i8272_unit[devnum].buf);
} else { /* write data port */
sim_putchar(data);
}
}
return 0;
}
/* end of i8272.c */
/* i8272.c: Intel 8272 FDC 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:
?? ??? 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:
u6 - unit number/device number
*/
#include "system_defs.h"
/* external globals */
extern uint16 port;
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
/* function prototypes */
t_stat i8272_svc (UNIT *uptr);
t_stat i8272_reset (DEVICE *dptr, uint16 base);
void i8272_reset1(uint8 devnum);
uint8 i8272_get_dn(void);
uint8 i8251s(t_bool io, uint8 data);
uint8 i8251d(t_bool io, uint8 data);
/* globals */
int32 i8272_devnum = 0; //initially, no 8272 instances
uint16 i8272_port[4]; //base port assigned to each 8272 instance
/* i8272 Standard I/O Data Structures */
/* up to 4 i8282 devices */
UNIT i8272_unit[4] = {
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT }
};
REG i8272_reg[4] = {
{ HRDATA (DATA, i8272_unit[0].buf, 8) },
{ HRDATA (STAT, i8272_unit[0].u3, 8) },
{ HRDATA (MODE, i8272_unit[0].u4, 8) },
{ HRDATA (CMD, i8272_unit[0].u5, 8) }
};
DEBTAB i8272_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8272_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8272_dev = {
"I8272", //name
i8272_unit, //units
i8272_reg, //registers
i8272_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8272_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8272_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8272_svc - actually does FDD read and write */
t_stat i8272_svc(UNIT *uptr)
{
int32 temp;
sim_activate(&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait); /* continue poll */
if (uptr->u6 >= i8272_devnum) return SCPE_OK;
if ((temp = sim_poll_kbd()) < SCPE_KFLAG)
return temp; /* no char or error? */
//sim_printf("i8272_svc: received character temp=%04X devnum=%d\n", temp, uptr->u6);
i8272_unit[uptr->u6].buf = temp & 0xFF; /* Save char */
i8272_unit[uptr->u6].u3 |= RXR; /* Set status */
return SCPE_OK;
}
/* Reset routine */
t_stat i8272_reset(DEVICE *dptr, uint16 base)
{
if (i8272_devnum >= i8272_NUM) {
sim_printf("8251_reset: too many devices!\n");
return 0;
}
i8272_reset1(i8272_devnum);
sim_printf(" 8251-%d: Registered at %03X\n", i8272_devnum, base);
i8272_port[i8272_devnum] = reg_dev(i8251d, base);
reg_dev(i8251s, base + 1);
i8272_unit[i8272_devnum].u6 = i8272_devnum;
sim_activate(&i8272_unit[i8272_devnum], i8272_unit[i8272_devnum].wait); /* activate unit */
i8272_devnum++;
return SCPE_OK;
}
void i8272_reset1(uint8 devnum)
{
i8272_unit[devnum].u3 = TXR + TXE; /* status */
i8272_unit[devnum].u4 = 0; /* mode instruction */
i8272_unit[devnum].u5 = 0; /* command instruction */
i8272_unit[devnum].buf = 0;
i8272_unit[devnum].pos = 0;
sim_printf(" 8251-%d: Reset\n", devnum);
}
uint8 i8272_get_dn(void)
{
int i;
for (i=0; i<i8272_NUM; i++)
if (port >=i8272_port[i] && port <= i8272_port[i] + 1)
return i;
sim_printf("i8272_get_dn: port %03X not in 8251 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
uint8 i8251s(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8272_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return i8272_unit[devnum].u3;
} else { /* write status port */
if (i8272_unit[devnum].u6) { /* if mode, set cmd */
i8272_unit[devnum].u5 = data;
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8272_reset1(devnum);
} else { /* set mode */
i8272_unit[devnum].u4 = data;
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8272_unit[devnum].u6 = 1; /* set cmd received */
}
}
}
return 0;
}
uint8 i8251d(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8272_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
i8272_unit[devnum].u3 &= ~RXR;
return (i8272_unit[devnum].buf);
} else { /* write data port */
sim_putchar(data);
}
}
return 0;
}
/* end of i8272.c */

View file

@ -1,252 +1,252 @@
/* i8273.c: Intel i8273 UART adapter
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.
These functions support a simulated i8273 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8273 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
uint8
wr0 = 0, /* command register */
wr1 = 0, /* enable register */
wr2 = 0, /* CH A mode register */
/* CH B interrups vector */
wr3 = 0, /* configuration register 1 */
wr4 = 0, /* configuration register 2 */
wr5 = 0, /* configuration register 3 */
wr6 = 0, /* sync low byte */
wr7 = 0, /* sync high byte */
rr0 = 0, /* status register */
rr1 = 0, /* error register */
rr2 = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8273_reset (DEVICE *dptr);
/* i8273 Standard I/O Data Structures */
UNIT i8273_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8273_reg[] = {
{ HRDATA (WR0, wr0, 8) },
{ HRDATA (WR1, wr1, 8) },
{ HRDATA (WR2, wr2, 8) },
{ HRDATA (WR3, wr3, 8) },
{ HRDATA (WR4, wr4, 8) },
{ HRDATA (WR5, wr5, 8) },
{ HRDATA (WR6, wr6, 8) },
{ HRDATA (WR7, wr7, 8) },
{ HRDATA (RR0, rr0, 8) },
{ HRDATA (RR0, rr1, 8) },
{ HRDATA (RR0, rr2, 8) },
{ NULL }
};
MTAB i8273_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8273_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8273_dev = {
"I8273", //name
&i8273_unit, //units
i8273_reg, //registers
i8273_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8273_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8273_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* Reset routine */
t_stat i8273_reset (DEVICE *dptr)
{
wr0 = 0; /* command register */
wr1 = 0; /* enable register */
wr2 = 0; /* CH A mode register */
/* CH B interrups vector */
wr3 = 0; /* configuration register 1 */
wr4 = 0; /* configuration register 2 */
wr5 = 0; /* configuration register 3 */
wr6 = 0; /* sync low byte */
wr7 = 0; /* sync high byte */
rr0 = 0; /* status register */
rr1 = 0; /* error register */
rr2 = 0; /* read interrupt vector */
sim_printf(" 8273 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
*/
int32 i8273s(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8273_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
i8273_unit.u3 = 0x05; /* status */
i8273_unit.u4 = 0; /* mode instruction */
i8273_unit.u5 = 0; /* command instruction */
i8273_unit.u6 = 0;
i8273_unit.buf = 0;
i8273_unit.pos = 0;
sim_printf("8273 Reset\n");
} else if (i8273_unit.u6) {
i8273_unit.u5 = data;
sim_printf("8273 Command Instruction=%02X\n", data);
} else {
i8273_unit.u4 = data;
sim_printf("8273 Mode Instruction=%02X\n", data);
i8273_unit.u6++;
}
return (0);
}
}
int32 i8273d(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8273_unit.u3 &= 0xFD;
return (i8273_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* i8273.c: Intel i8273 UART adapter
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.
These functions support a simulated i8273 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8273 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
uint8
wr0 = 0, /* command register */
wr1 = 0, /* enable register */
wr2 = 0, /* CH A mode register */
/* CH B interrups vector */
wr3 = 0, /* configuration register 1 */
wr4 = 0, /* configuration register 2 */
wr5 = 0, /* configuration register 3 */
wr6 = 0, /* sync low byte */
wr7 = 0, /* sync high byte */
rr0 = 0, /* status register */
rr1 = 0, /* error register */
rr2 = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8273_reset (DEVICE *dptr);
/* i8273 Standard I/O Data Structures */
UNIT i8273_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8273_reg[] = {
{ HRDATA (WR0, wr0, 8) },
{ HRDATA (WR1, wr1, 8) },
{ HRDATA (WR2, wr2, 8) },
{ HRDATA (WR3, wr3, 8) },
{ HRDATA (WR4, wr4, 8) },
{ HRDATA (WR5, wr5, 8) },
{ HRDATA (WR6, wr6, 8) },
{ HRDATA (WR7, wr7, 8) },
{ HRDATA (RR0, rr0, 8) },
{ HRDATA (RR0, rr1, 8) },
{ HRDATA (RR0, rr2, 8) },
{ NULL }
};
MTAB i8273_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8273_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8273_dev = {
"I8273", //name
&i8273_unit, //units
i8273_reg, //registers
i8273_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8273_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8273_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* Reset routine */
t_stat i8273_reset (DEVICE *dptr)
{
wr0 = 0; /* command register */
wr1 = 0; /* enable register */
wr2 = 0; /* CH A mode register */
/* CH B interrups vector */
wr3 = 0; /* configuration register 1 */
wr4 = 0; /* configuration register 2 */
wr5 = 0; /* configuration register 3 */
wr6 = 0; /* sync low byte */
wr7 = 0; /* sync high byte */
rr0 = 0; /* status register */
rr1 = 0; /* error register */
rr2 = 0; /* read interrupt vector */
sim_printf(" 8273 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
*/
int32 i8273s(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8273_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
i8273_unit.u3 = 0x05; /* status */
i8273_unit.u4 = 0; /* mode instruction */
i8273_unit.u5 = 0; /* command instruction */
i8273_unit.u6 = 0;
i8273_unit.buf = 0;
i8273_unit.pos = 0;
sim_printf("8273 Reset\n");
} else if (i8273_unit.u6) {
i8273_unit.u5 = data;
sim_printf("8273 Command Instruction=%02X\n", data);
} else {
i8273_unit.u4 = data;
sim_printf("8273 Mode Instruction=%02X\n", data);
i8273_unit.u6++;
}
return (0);
}
}
int32 i8273d(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8273_unit.u3 &= 0xFD;
return (i8273_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}

View file

@ -1,351 +1,351 @@
/* i8274.c: Intel i8274 MPSC adapter
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.
These functions support a simulated i8274 interface device on an iSBC.
The device had two physical I/O ports which could be connected
to any serial I/O device that would connect to an RS232 interface.
All I/O is via programmed I/O. The i8274 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and two address lines. The data port is at the
lower address and the status/command port is at the higher address for each
channel.
Minimum simulation is provided for this device. Channel A is used as a
console port for the iSBC-88/45
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
/* register definitions */
/* channel A */
uint8 wr0a = 0, /* command register */
wr1a = 0, /* enable register */
wr2a = 0, /* mode register */
wr3a = 0, /* configuration register 1 */
wr4a = 0, /* configuration register 2 */
wr5a = 0, /* configuration register 3 */
wr6a = 0, /* sync low byte */
wr7a = 0, /* sync high byte */
rr0a = 0, /* status register */
rr1a = 0, /* error register */
rr2a = 0; /* read interrupt vector */
/* channel B */
uint8 wr0b = 0, /* command register */
wr1b = 0, /* enable register */
wr2b = 0, /* CH B interrups vector */
wr3b = 0, /* configuration register 1 */
wr4b = 0, /* configuration register 2 */
wr5b = 0, /* configuration register 3 */
wr6b = 0, /* sync low byte */
wr7b = 0, /* sync high byte */
rr0b = 0, /* status register */
rr1b = 0, /* error register */
rr2b = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8274_svc (UNIT *uptr);
t_stat i8274_reset (DEVICE *dptr);
int32 i8274As(int32 io, int32 data);
int32 i8274Ad(int32 io, int32 data);
int32 i8274Bs(int32 io, int32 data);
int32 i8274Bd(int32 io, int32 data);
/* i8274 Standard I/O Data Structures */
UNIT i8274_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8274_reg[] = {
{ HRDATA (WR0A, wr0a, 8) },
{ HRDATA (WR1A, wr1a, 8) },
{ HRDATA (WR2A, wr2a, 8) },
{ HRDATA (WR3A, wr3a, 8) },
{ HRDATA (WR4A, wr4a, 8) },
{ HRDATA (WR5A, wr5a, 8) },
{ HRDATA (WR6A, wr6a, 8) },
{ HRDATA (WR7A, wr7a, 8) },
{ HRDATA (RR0A, rr0a, 8) },
{ HRDATA (RR0A, rr1a, 8) },
{ HRDATA (RR0A, rr2a, 8) },
{ HRDATA (WR0B, wr0b, 8) },
{ HRDATA (WR1B, wr1b, 8) },
{ HRDATA (WR2B, wr2b, 8) },
{ HRDATA (WR3B, wr3b, 8) },
{ HRDATA (WR4B, wr4b, 8) },
{ HRDATA (WR5B, wr5b, 8) },
{ HRDATA (WR6B, wr6b, 8) },
{ HRDATA (WR7B, wr7b, 8) },
{ HRDATA (RR0B, rr0b, 8) },
{ HRDATA (RR0B, rr1b, 8) },
{ HRDATA (RR0B, rr2b, 8) },
{ NULL }
};
MTAB i8274_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8274_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8274_dev = {
"I8274", //name
&i8274_unit, //units
i8274_reg, //registers
i8274_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8274_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8274_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* service routine - actually gets char & places in buffer in CH A*/
t_stat i8274_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8274_unit, i8274_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8274_unit.buf = temp & 0xFF; /* Save char */
rr0a |= 0x01; /* Set rx char ready */
/* Do any special character handling here */
i8274_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8274_reset (DEVICE *dptr)
{
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = wr6a = wr7a = rr0a = rr1a = rr2a = 0;
wr0b = wr1b = wr2b = wr3b = wr4b = wr5b = wr6b = wr7b = rr0b = rr1b = rr2b = 0;
sim_printf(" 8274 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
The 8274 contains 2 separate channels, A and B.
*/
/* channel A command/status */
int32 i8274As(int32 io, int32 data)
{
if (io == 0) { /* read status port */
switch(wr0a & 0x7) {
case 0: /* rr0a */
return rr0a;
case 1: /* rr1a */
return rr1a;
case 2: /* rr1a */
return rr2a;
}
return 0; /* bad register select */
} else { /* write status port */
switch(wr0a & 0x7) {
case 0: /* wr0a */
wr0a = data;
if ((wr0a & 0x38) == 0x18) { /* channel reset */
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = 0;
wr6a = wr7a = rr0a = rr1a = rr2a = 0;
sim_printf("8274 Channel A reset\n");
}
break;
case 1: /* wr1a */
wr1a = data;
break;
case 2: /* wr2a */
wr2a = data;
break;
case 3: /* wr3a */
wr3a = data;
break;
case 4: /* wr4a */
wr4a = data;
break;
case 5: /* wr5a */
wr5a = data;
break;
case 6: /* wr6a */
wr6a = data;
break;
case 7: /* wr7a */
wr7a = data;
break;
}
sim_printf("8274 Command WR%dA=%02X\n", wr0a & 0x7, data);
return 0;
}
}
/* channel A data */
int32 i8274Ad(int32 io, int32 data)
{
if (io == 0) { /* read data port */
rr0a &= 0xFE;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* channel B command/status */
int32 i8274Bs(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8274_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
sim_printf("8274 Reset\n");
} else if (i8274_unit.u6) {
i8274_unit.u5 = data;
sim_printf("8274 Command Instruction=%02X\n", data);
} else {
i8274_unit.u4 = data;
sim_printf("8274 Mode Instruction=%02X\n", data);
i8274_unit.u6++;
}
return (0);
}
}
/* channel B data */
int32 i8274Bd(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8274_unit.u3 &= 0xFD;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* i8274.c: Intel i8274 MPSC adapter
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.
These functions support a simulated i8274 interface device on an iSBC.
The device had two physical I/O ports which could be connected
to any serial I/O device that would connect to an RS232 interface.
All I/O is via programmed I/O. The i8274 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and two address lines. The data port is at the
lower address and the status/command port is at the higher address for each
channel.
Minimum simulation is provided for this device. Channel A is used as a
console port for the iSBC-88/45
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
/* register definitions */
/* channel A */
uint8 wr0a = 0, /* command register */
wr1a = 0, /* enable register */
wr2a = 0, /* mode register */
wr3a = 0, /* configuration register 1 */
wr4a = 0, /* configuration register 2 */
wr5a = 0, /* configuration register 3 */
wr6a = 0, /* sync low byte */
wr7a = 0, /* sync high byte */
rr0a = 0, /* status register */
rr1a = 0, /* error register */
rr2a = 0; /* read interrupt vector */
/* channel B */
uint8 wr0b = 0, /* command register */
wr1b = 0, /* enable register */
wr2b = 0, /* CH B interrups vector */
wr3b = 0, /* configuration register 1 */
wr4b = 0, /* configuration register 2 */
wr5b = 0, /* configuration register 3 */
wr6b = 0, /* sync low byte */
wr7b = 0, /* sync high byte */
rr0b = 0, /* status register */
rr1b = 0, /* error register */
rr2b = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8274_svc (UNIT *uptr);
t_stat i8274_reset (DEVICE *dptr);
int32 i8274As(int32 io, int32 data);
int32 i8274Ad(int32 io, int32 data);
int32 i8274Bs(int32 io, int32 data);
int32 i8274Bd(int32 io, int32 data);
/* i8274 Standard I/O Data Structures */
UNIT i8274_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8274_reg[] = {
{ HRDATA (WR0A, wr0a, 8) },
{ HRDATA (WR1A, wr1a, 8) },
{ HRDATA (WR2A, wr2a, 8) },
{ HRDATA (WR3A, wr3a, 8) },
{ HRDATA (WR4A, wr4a, 8) },
{ HRDATA (WR5A, wr5a, 8) },
{ HRDATA (WR6A, wr6a, 8) },
{ HRDATA (WR7A, wr7a, 8) },
{ HRDATA (RR0A, rr0a, 8) },
{ HRDATA (RR0A, rr1a, 8) },
{ HRDATA (RR0A, rr2a, 8) },
{ HRDATA (WR0B, wr0b, 8) },
{ HRDATA (WR1B, wr1b, 8) },
{ HRDATA (WR2B, wr2b, 8) },
{ HRDATA (WR3B, wr3b, 8) },
{ HRDATA (WR4B, wr4b, 8) },
{ HRDATA (WR5B, wr5b, 8) },
{ HRDATA (WR6B, wr6b, 8) },
{ HRDATA (WR7B, wr7b, 8) },
{ HRDATA (RR0B, rr0b, 8) },
{ HRDATA (RR0B, rr1b, 8) },
{ HRDATA (RR0B, rr2b, 8) },
{ NULL }
};
MTAB i8274_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8274_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8274_dev = {
"I8274", //name
&i8274_unit, //units
i8274_reg, //registers
i8274_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8274_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8274_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* service routine - actually gets char & places in buffer in CH A*/
t_stat i8274_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8274_unit, i8274_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8274_unit.buf = temp & 0xFF; /* Save char */
rr0a |= 0x01; /* Set rx char ready */
/* Do any special character handling here */
i8274_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8274_reset (DEVICE *dptr)
{
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = wr6a = wr7a = rr0a = rr1a = rr2a = 0;
wr0b = wr1b = wr2b = wr3b = wr4b = wr5b = wr6b = wr7b = rr0b = rr1b = rr2b = 0;
sim_printf(" 8274 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
The 8274 contains 2 separate channels, A and B.
*/
/* channel A command/status */
int32 i8274As(int32 io, int32 data)
{
if (io == 0) { /* read status port */
switch(wr0a & 0x7) {
case 0: /* rr0a */
return rr0a;
case 1: /* rr1a */
return rr1a;
case 2: /* rr1a */
return rr2a;
}
return 0; /* bad register select */
} else { /* write status port */
switch(wr0a & 0x7) {
case 0: /* wr0a */
wr0a = data;
if ((wr0a & 0x38) == 0x18) { /* channel reset */
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = 0;
wr6a = wr7a = rr0a = rr1a = rr2a = 0;
sim_printf("8274 Channel A reset\n");
}
break;
case 1: /* wr1a */
wr1a = data;
break;
case 2: /* wr2a */
wr2a = data;
break;
case 3: /* wr3a */
wr3a = data;
break;
case 4: /* wr4a */
wr4a = data;
break;
case 5: /* wr5a */
wr5a = data;
break;
case 6: /* wr6a */
wr6a = data;
break;
case 7: /* wr7a */
wr7a = data;
break;
}
sim_printf("8274 Command WR%dA=%02X\n", wr0a & 0x7, data);
return 0;
}
}
/* channel A data */
int32 i8274Ad(int32 io, int32 data)
{
if (io == 0) { /* read data port */
rr0a &= 0xFE;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* channel B command/status */
int32 i8274Bs(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8274_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
sim_printf("8274 Reset\n");
} else if (i8274_unit.u6) {
i8274_unit.u5 = data;
sim_printf("8274 Command Instruction=%02X\n", data);
} else {
i8274_unit.u4 = data;
sim_printf("8274 Mode Instruction=%02X\n", data);
i8274_unit.u6++;
}
return (0);
}
}
/* channel B data */
int32 i8274Bd(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8274_unit.u3 &= 0xFD;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* end of i8274.c */

View file

@ -1,186 +1,186 @@
/* 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"
/* 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 i8255_C[4]; //port c byte I/O
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
DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
// 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_debug (DEBUG_read, &EPROM_dev, "\tClose file\n");
fclose(fp);
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, 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_printf(" EPROM: Configured, Not attached\n");
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
} else {
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, EPROM_unit.filename);
}
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);
} else {
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
return 0;
}
}
/* end of iEPROM.c */
/* 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"
/* 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 i8255_C[4]; //port c byte I/O
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
DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
// 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_debug (DEBUG_read, &EPROM_dev, "\tClose file\n");
fclose(fp);
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, 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_printf(" EPROM: Configured, Not attached\n");
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
} else {
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, EPROM_unit.filename);
}
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);
} else {
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
return 0;
}
}
/* end of iEPROM.c */

View file

@ -1,486 +1,486 @@
/* iJEDEC.c: Intel JEDEC Universal Site simulator for 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.
These functions support a simulated i2732 JEDEC device on an iSBC. This
allows the attachment of the device to a binary file containing the JEDEC
code.
Unit will support 8, 16 and 32 KB EPROMs as well as 8 and 16 KB static
RAMs in the JEDEC sockets. Units must be configured for 8KB for 8KB
SRAM and 32KB for 32KB SRAM. If configured for 16KB, SRAM cannot be
configured. Size is set by configuring the top JEDEC site for an EPROM.
Size and spacing for the other JEDEC units is derived from the top JEDEC
site configuration. Changing the top JEDEC site will clear the
configuration of all other JEDEC sites. The JEDEC driver can be set for
either 8- or 16bit data access.
The top JEDEC site can only be configured to contain an EPROM.
It contains the reset address for the 8088, 8086, 80188, 80186,
and 80286.
For illustration 8-bit mode - 4 Sites - configured for 8KB chips
+--------+ 0xFFFFF
| |
| jedec3 | Only ROM
| |
+--------+ 0xFE000
+--------+ 0xFDFFF
| |
| jedec2 | RAM/ROM
| |
+--------+ 0xFC000
+--------+ 0xFBFFF
| |
| jedec1 | RAM/ROM
| |
+--------+ 0xFA000
+--------+ 0xF9FFF
| |
| jedec0 | RAM/ROM
| |
+--------+ 0xF8000
For illustration 16-bit mode - 4 Sites - configured for 8KB chips
Odd data byte Even data byte
High data byte Low data byte
+--------+ 0xFFFFF +--------+ 0xFFFFE
| | | |
| jedec3 | Only ROM | jedec2 | Only ROM
| | | |
+--------+ 0xFC001 +--------+ 0xFC000
+--------+ 0xFBFFF +--------+ 0xFBFFE
| | | |
| jedec3 | RAM/ROM | jedec2 | RAM/ROM
| | | |
+--------+ 0xF8001 +--------+ 0xF8000
uptr->filename - ROM image file attached to unit
uptr->capac - unit capacity in bytes
uptr->u3 - unit base address
uptr->u4 - unit device type {none|8krom|16krom|32krom|8kram|32kram}
uptr->u5 - unit flags - ROM or RAM, 8 or 16BIT (top unit only)
uptr->u6 - unit number
*/
#include <stdio.h>
#include "multibus_defs.h"
#define JEDEC_NUM 4
#define UNIT_V_DMODE (UNIT_V_UF) /* data bus mode */
#define UNIT_DMODE (1 << UNIT_V_DMODE)
#define UNIT_V_MSIZE (UNIT_V_UF+1) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_NONE 0 /* No device */
#define UNIT_8KROM 1 /* 8KB ROM */
#define UNIT_16KROM 2 /* 16KB ROM */
#define UNIT_32KROM 3 /* 32KB ROM */
#define UNIT_8KRAM 4 /* 8KB RAM */
#define UNIT_32KRAM 5 /* 32KB RAM */
#define RAM 0x00000001
#define D16BIT 0x00000002
/* function prototypes */
t_stat JEDEC_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat JEDEC_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat JEDEC_attach (UNIT *uptr, char *cptr);
t_stat JEDEC_reset (DEVICE *dptr);
int32 JEDEC_get_mbyte(int32 addr);
void JEDEC_put_mbyte(int32 addr, int32 val);
/* SIMH JEDEC Standard I/O Data Structures */
UNIT JEDEC_unit[] = {
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 }
};
MTAB JEDEC_mod[] = {
{ UNIT_DMODE, 0, "8-Bit", "8B", &JEDEC_set_mode },
{ UNIT_DMODE, UNIT_DMODE, "16-Bit", "16B", &JEDEC_set_mode },
{ UNIT_MSIZE, UNIT_NONE, "Not configured", "NONE", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_8KROM, "8KB ROM", "8KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_16KROM, "16KB ROM", "16KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_32KROM, "32KB ROM", "32KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_8KRAM, "8KB RAM", "8KRAM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_32KRAM, "32KB RAM", "32KRAM", &JEDEC_set_size },
{ 0 }
};
DEBTAB JEDEC_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE JEDEC_dev = {
"JEDEC", //name
JEDEC_unit, //units
NULL, //registers
JEDEC_mod, //modifiers
JEDEC_NUM, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&JEDEC_reset, //reset
NULL, //boot
&JEDEC_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
JEDEC_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
uint8 *JEDEC_buf[JEDEC_NUM] = { /* JEDEC buffer pointers */
NULL,
NULL,
NULL,
NULL
};
/* JEDEC functions */
/* JEDEC attach - force JEDEC reset at completion */
t_stat JEDEC_attach (UNIT *uptr, char *cptr)
{
t_stat r;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_attach: Error\n");
return r;
}
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_attach: Done\n");
return (JEDEC_reset (NULL));
}
/* JEDEC set mode = 8- or 16-bit data bus */
t_stat JEDEC_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
{
UNIT *uptr1;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_set_mode: Entered with val=%08XH, unit=%d\n", val, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds this configuration */
if (val) { /* 16-bit mode */
uptr1->u5 |= D16BIT;
} else { /* 8-bit mode */
uptr1->u5 &= ~D16BIT;
}
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("JEDEC%d->u5=%08XH\n", JEDEC_NUM - 1, uptr1->u5);
sim_printf("\tJEDEC_set_mode: Done\n");
}
/* JEDEC set type = none, 8krom, 16krom, 32krom, 8kram or 32kram */
t_stat JEDEC_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
uint32 i, basadr;
UNIT *uptr1;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_set_size: Entered with val=%d, unit=%d\n", val, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds u5 configuration */
uptr->u4 = val;
switch(val) {
case UNIT_NONE:
uptr->capac = 0;
uptr->u5 &= ~RAM; /* ROM */
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = 0; /* base address */
sim_printf("JEDEC site size set to 8KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
}
break;
case UNIT_8KROM:
uptr->capac = 0x2000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
sim_printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
sim_printf("JEDEC site size set to 8KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_16KROM:
uptr->capac = 0x4000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
sim_printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
sim_printf("JEDEC site size set to 16KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_32KROM:
uptr->capac = 0x8000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
sim_printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
sim_printf("JEDEC site size set to 32KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_8KRAM:
uptr->capac = 0x2000;
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
sim_printf("JEDEC%d cannot be SRAM\n", uptr->u6);
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
} else {
uptr->u5 |= RAM; /* RAM */
}
}
break;
case UNIT_32KRAM:
uptr->capac = 0x8000;
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
sim_printf("JEDEC%d cannot be SRAM\n", uptr->u6);
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
} else {
uptr->u5 |= RAM; /* RAM */
}
}
break;
default:
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_set_size: Error\n");
return SCPE_ARG;
}
if (JEDEC_buf[uptr->u6]) { /* any change requires a new buffer */
free (JEDEC_buf[uptr->u6]);
JEDEC_buf[uptr->u6] = NULL;
}
if (JEDEC_dev.dctrl & DEBUG_flow) {
sim_printf("\tJEDEC%d->capac=%04XH\n", uptr->u6, uptr->capac);
sim_printf("\tJEDEC%d->u3[Base addr]=%06XH\n", uptr->u6, uptr->u3);
sim_printf("\tJEDEC%d->u4[val]=%06XH\n", uptr->u6, uptr->u4);
sim_printf("\tJEDEC%d->u5[Flags]=%06XH\n", uptr->u6, uptr->u5);
sim_printf("\tJEDEC%d->u6[unit #]=%06XH\n", uptr->u6, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds u5 configuration */
sim_printf("\tJEDEC%d->u5[Flags]=%06XH\n", JEDEC_NUM - 1, uptr1->u5);
sim_printf("\tJEDEC_set_size: Done\n");
}
return SCPE_OK;
}
/* JEDEC reset */
t_stat JEDEC_reset (DEVICE *dptr)
{
int32 i, j, c;
FILE *fp;
t_stat r;
UNIT *uptr;
static int flag = 1;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_reset: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* handle all umits */
uptr = JEDEC_dev.units + i;
if (uptr->capac == 0) { /* if not configured */
sim_printf(" JEDEC%d: Not configured\n", i);
if (flag) {
sim_printf(" ALL: \"set JEDEC3 None | 8krom | 16krom | 32krom | 8kram | 32kram\"\n");
sim_printf(" EPROM: \"att JEDEC3 <filename>\"\n");
flag = 0;
}
uptr->capac = 0;
/* assume 8KB in base address calculation */
uptr->u3 = 0xF8000 + (0x2000 * i); /* base address */
uptr->u4 = 0; /* None */
uptr->u5 = 0; /* RO */
uptr->u6 = i; /* unit number - only set here! */
}
if (uptr->capac) { /* if configured */
sim_printf(" JEDEC%d: Initializing %2XKB %s [%04X-%04XH]\n",
i,
uptr->capac / 0x400,
uptr->u5 ? "Ram" : "Rom",
uptr->u3,
uptr->u3 + uptr->capac - 1);
if (JEDEC_buf[uptr->u6] == NULL) {/* no buffer allocated */
JEDEC_buf[uptr->u6] = malloc(uptr->capac);
if (JEDEC_buf[uptr->u6] == NULL) {
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_reset: Malloc error\n");
return SCPE_MEM;
}
}
if ((uptr->u5 & 0x0001) == 0) { /* ROM - load file */
fp = fopen(uptr->filename, "rb");
if (fp == NULL) {
sim_printf("\tUnable to open ROM file %s\n", uptr->filename);
sim_printf("\tNo ROM image loaded!!!\n");
} else {
j = 0;
c = fgetc(fp);
while (c != EOF) {
*(JEDEC_buf[uptr->u6] + j++) = c & 0xFF;
c = fgetc(fp);
if (j >= JEDEC_unit[uptr->u6].capac) {
sim_printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
fclose(fp);
sim_printf("\t%d bytes of ROM image %s loaded\n", j, uptr->filename);
}
}
}
}
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
JEDEC memory read or write is issued.
Need to fix for hi/low memory operations
*/
/* get a byte from memory */
int32 JEDEC_get_mbyte(int32 addr)
{
int32 i, val, org, len;
UNIT *uptr;
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC_get_mbyte: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* test all umits for address */
uptr = JEDEC_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr <= org + len)) {
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC%d Addr=%06XH Org=%06XH Len=%06XH\n", i, addr, org, len);
val = *(JEDEC_buf[uptr->u6] + (addr - org));
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC_get_mbyte: Exit with [%0XH]\n", val & 0xFF);
return (val & 0xFF);
}
}
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC_get_mbyte: Exit - Out of range\n", addr);
return 0xFF;
}
/* put a byte into memory */
void JEDEC_put_mbyte(int32 addr, int32 val)
{
int32 i, org, len, type;
UNIT *uptr;
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC_put_mbyte: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* test all umits for address */
uptr = JEDEC_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr < org + len)) {
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC%d Org=%06XH Len=%06XH\n", i, org, len);
if (uptr->u5 & RAM) { /* can't write to ROM */
*(JEDEC_buf[uptr->u6] + (addr - org)) = val & 0xFF;
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC_put_mbyte: Exit with [%06XH]=%02XH\n", addr, val);
} else
sim_printf("\tJEDEC_put_mbyte: Write to ROM ignored\n");
}
}
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC_put_mbyte: Exit - Out of range\n");
}
/* end of iJEDEC.c */
/* iJEDEC.c: Intel JEDEC Universal Site simulator for 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.
These functions support a simulated i2732 JEDEC device on an iSBC. This
allows the attachment of the device to a binary file containing the JEDEC
code.
Unit will support 8, 16 and 32 KB EPROMs as well as 8 and 16 KB static
RAMs in the JEDEC sockets. Units must be configured for 8KB for 8KB
SRAM and 32KB for 32KB SRAM. If configured for 16KB, SRAM cannot be
configured. Size is set by configuring the top JEDEC site for an EPROM.
Size and spacing for the other JEDEC units is derived from the top JEDEC
site configuration. Changing the top JEDEC site will clear the
configuration of all other JEDEC sites. The JEDEC driver can be set for
either 8- or 16bit data access.
The top JEDEC site can only be configured to contain an EPROM.
It contains the reset address for the 8088, 8086, 80188, 80186,
and 80286.
For illustration 8-bit mode - 4 Sites - configured for 8KB chips
+--------+ 0xFFFFF
| |
| jedec3 | Only ROM
| |
+--------+ 0xFE000
+--------+ 0xFDFFF
| |
| jedec2 | RAM/ROM
| |
+--------+ 0xFC000
+--------+ 0xFBFFF
| |
| jedec1 | RAM/ROM
| |
+--------+ 0xFA000
+--------+ 0xF9FFF
| |
| jedec0 | RAM/ROM
| |
+--------+ 0xF8000
For illustration 16-bit mode - 4 Sites - configured for 8KB chips
Odd data byte Even data byte
High data byte Low data byte
+--------+ 0xFFFFF +--------+ 0xFFFFE
| | | |
| jedec3 | Only ROM | jedec2 | Only ROM
| | | |
+--------+ 0xFC001 +--------+ 0xFC000
+--------+ 0xFBFFF +--------+ 0xFBFFE
| | | |
| jedec3 | RAM/ROM | jedec2 | RAM/ROM
| | | |
+--------+ 0xF8001 +--------+ 0xF8000
uptr->filename - ROM image file attached to unit
uptr->capac - unit capacity in bytes
uptr->u3 - unit base address
uptr->u4 - unit device type {none|8krom|16krom|32krom|8kram|32kram}
uptr->u5 - unit flags - ROM or RAM, 8 or 16BIT (top unit only)
uptr->u6 - unit number
*/
#include <stdio.h>
#include "multibus_defs.h"
#define JEDEC_NUM 4
#define UNIT_V_DMODE (UNIT_V_UF) /* data bus mode */
#define UNIT_DMODE (1 << UNIT_V_DMODE)
#define UNIT_V_MSIZE (UNIT_V_UF+1) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_NONE 0 /* No device */
#define UNIT_8KROM 1 /* 8KB ROM */
#define UNIT_16KROM 2 /* 16KB ROM */
#define UNIT_32KROM 3 /* 32KB ROM */
#define UNIT_8KRAM 4 /* 8KB RAM */
#define UNIT_32KRAM 5 /* 32KB RAM */
#define RAM 0x00000001
#define D16BIT 0x00000002
/* function prototypes */
t_stat JEDEC_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat JEDEC_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat JEDEC_attach (UNIT *uptr, char *cptr);
t_stat JEDEC_reset (DEVICE *dptr);
int32 JEDEC_get_mbyte(int32 addr);
void JEDEC_put_mbyte(int32 addr, int32 val);
/* SIMH JEDEC Standard I/O Data Structures */
UNIT JEDEC_unit[] = {
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 }
};
MTAB JEDEC_mod[] = {
{ UNIT_DMODE, 0, "8-Bit", "8B", &JEDEC_set_mode },
{ UNIT_DMODE, UNIT_DMODE, "16-Bit", "16B", &JEDEC_set_mode },
{ UNIT_MSIZE, UNIT_NONE, "Not configured", "NONE", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_8KROM, "8KB ROM", "8KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_16KROM, "16KB ROM", "16KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_32KROM, "32KB ROM", "32KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_8KRAM, "8KB RAM", "8KRAM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_32KRAM, "32KB RAM", "32KRAM", &JEDEC_set_size },
{ 0 }
};
DEBTAB JEDEC_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE JEDEC_dev = {
"JEDEC", //name
JEDEC_unit, //units
NULL, //registers
JEDEC_mod, //modifiers
JEDEC_NUM, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&JEDEC_reset, //reset
NULL, //boot
&JEDEC_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
JEDEC_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
uint8 *JEDEC_buf[JEDEC_NUM] = { /* JEDEC buffer pointers */
NULL,
NULL,
NULL,
NULL
};
/* JEDEC functions */
/* JEDEC attach - force JEDEC reset at completion */
t_stat JEDEC_attach (UNIT *uptr, char *cptr)
{
t_stat r;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_attach: Error\n");
return r;
}
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_attach: Done\n");
return (JEDEC_reset (NULL));
}
/* JEDEC set mode = 8- or 16-bit data bus */
t_stat JEDEC_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
{
UNIT *uptr1;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_set_mode: Entered with val=%08XH, unit=%d\n", val, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds this configuration */
if (val) { /* 16-bit mode */
uptr1->u5 |= D16BIT;
} else { /* 8-bit mode */
uptr1->u5 &= ~D16BIT;
}
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("JEDEC%d->u5=%08XH\n", JEDEC_NUM - 1, uptr1->u5);
sim_printf("\tJEDEC_set_mode: Done\n");
}
/* JEDEC set type = none, 8krom, 16krom, 32krom, 8kram or 32kram */
t_stat JEDEC_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
uint32 i, basadr;
UNIT *uptr1;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_set_size: Entered with val=%d, unit=%d\n", val, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds u5 configuration */
uptr->u4 = val;
switch(val) {
case UNIT_NONE:
uptr->capac = 0;
uptr->u5 &= ~RAM; /* ROM */
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = 0; /* base address */
sim_printf("JEDEC site size set to 8KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
}
break;
case UNIT_8KROM:
uptr->capac = 0x2000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
sim_printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
sim_printf("JEDEC site size set to 8KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_16KROM:
uptr->capac = 0x4000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
sim_printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
sim_printf("JEDEC site size set to 16KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_32KROM:
uptr->capac = 0x8000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
sim_printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
sim_printf("JEDEC site size set to 32KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_8KRAM:
uptr->capac = 0x2000;
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
sim_printf("JEDEC%d cannot be SRAM\n", uptr->u6);
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
} else {
uptr->u5 |= RAM; /* RAM */
}
}
break;
case UNIT_32KRAM:
uptr->capac = 0x8000;
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
sim_printf("JEDEC%d cannot be SRAM\n", uptr->u6);
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
sim_printf("JEDEC site size precludes use of this device\n");
} else {
uptr->u5 |= RAM; /* RAM */
}
}
break;
default:
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_set_size: Error\n");
return SCPE_ARG;
}
if (JEDEC_buf[uptr->u6]) { /* any change requires a new buffer */
free (JEDEC_buf[uptr->u6]);
JEDEC_buf[uptr->u6] = NULL;
}
if (JEDEC_dev.dctrl & DEBUG_flow) {
sim_printf("\tJEDEC%d->capac=%04XH\n", uptr->u6, uptr->capac);
sim_printf("\tJEDEC%d->u3[Base addr]=%06XH\n", uptr->u6, uptr->u3);
sim_printf("\tJEDEC%d->u4[val]=%06XH\n", uptr->u6, uptr->u4);
sim_printf("\tJEDEC%d->u5[Flags]=%06XH\n", uptr->u6, uptr->u5);
sim_printf("\tJEDEC%d->u6[unit #]=%06XH\n", uptr->u6, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds u5 configuration */
sim_printf("\tJEDEC%d->u5[Flags]=%06XH\n", JEDEC_NUM - 1, uptr1->u5);
sim_printf("\tJEDEC_set_size: Done\n");
}
return SCPE_OK;
}
/* JEDEC reset */
t_stat JEDEC_reset (DEVICE *dptr)
{
int32 i, j, c;
FILE *fp;
t_stat r;
UNIT *uptr;
static int flag = 1;
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_reset: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* handle all umits */
uptr = JEDEC_dev.units + i;
if (uptr->capac == 0) { /* if not configured */
sim_printf(" JEDEC%d: Not configured\n", i);
if (flag) {
sim_printf(" ALL: \"set JEDEC3 None | 8krom | 16krom | 32krom | 8kram | 32kram\"\n");
sim_printf(" EPROM: \"att JEDEC3 <filename>\"\n");
flag = 0;
}
uptr->capac = 0;
/* assume 8KB in base address calculation */
uptr->u3 = 0xF8000 + (0x2000 * i); /* base address */
uptr->u4 = 0; /* None */
uptr->u5 = 0; /* RO */
uptr->u6 = i; /* unit number - only set here! */
}
if (uptr->capac) { /* if configured */
sim_printf(" JEDEC%d: Initializing %2XKB %s [%04X-%04XH]\n",
i,
uptr->capac / 0x400,
uptr->u5 ? "Ram" : "Rom",
uptr->u3,
uptr->u3 + uptr->capac - 1);
if (JEDEC_buf[uptr->u6] == NULL) {/* no buffer allocated */
JEDEC_buf[uptr->u6] = malloc(uptr->capac);
if (JEDEC_buf[uptr->u6] == NULL) {
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_reset: Malloc error\n");
return SCPE_MEM;
}
}
if ((uptr->u5 & 0x0001) == 0) { /* ROM - load file */
fp = fopen(uptr->filename, "rb");
if (fp == NULL) {
sim_printf("\tUnable to open ROM file %s\n", uptr->filename);
sim_printf("\tNo ROM image loaded!!!\n");
} else {
j = 0;
c = fgetc(fp);
while (c != EOF) {
*(JEDEC_buf[uptr->u6] + j++) = c & 0xFF;
c = fgetc(fp);
if (j >= JEDEC_unit[uptr->u6].capac) {
sim_printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
fclose(fp);
sim_printf("\t%d bytes of ROM image %s loaded\n", j, uptr->filename);
}
}
}
}
if (JEDEC_dev.dctrl & DEBUG_flow)
sim_printf("\tJEDEC_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
JEDEC memory read or write is issued.
Need to fix for hi/low memory operations
*/
/* get a byte from memory */
int32 JEDEC_get_mbyte(int32 addr)
{
int32 i, val, org, len;
UNIT *uptr;
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC_get_mbyte: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* test all umits for address */
uptr = JEDEC_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr <= org + len)) {
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC%d Addr=%06XH Org=%06XH Len=%06XH\n", i, addr, org, len);
val = *(JEDEC_buf[uptr->u6] + (addr - org));
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC_get_mbyte: Exit with [%0XH]\n", val & 0xFF);
return (val & 0xFF);
}
}
if (JEDEC_dev.dctrl & DEBUG_read)
sim_printf("\tJEDEC_get_mbyte: Exit - Out of range\n", addr);
return 0xFF;
}
/* put a byte into memory */
void JEDEC_put_mbyte(int32 addr, int32 val)
{
int32 i, org, len, type;
UNIT *uptr;
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC_put_mbyte: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* test all umits for address */
uptr = JEDEC_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr < org + len)) {
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC%d Org=%06XH Len=%06XH\n", i, org, len);
if (uptr->u5 & RAM) { /* can't write to ROM */
*(JEDEC_buf[uptr->u6] + (addr - org)) = val & 0xFF;
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC_put_mbyte: Exit with [%06XH]=%02XH\n", addr, val);
} else
sim_printf("\tJEDEC_put_mbyte: Write to ROM ignored\n");
}
}
if (JEDEC_dev.dctrl & DEBUG_write)
sim_printf("\tJEDEC_put_mbyte: Exit - Out of range\n");
}
/* end of iJEDEC.c */

View file

@ -1,206 +1,206 @@
/* iPATA.c: Intel i8255 PIO adapter for PATA HD
Copyright (c) 2015, 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.
NOTES:
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device. This is an extension of the i8255.c file to support
an emulated PATA IDE Hard Disk Drive.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
The Second 8255 on the iSBC 80/10 is used to connect to the IDE PATA
Hard Disk Drive. Pins are defined as shown below:
PA[0..7] High data byte
PB[0..7] Low data byte
PC[0..2] Register select
PC[3..4] CSFX select
PC[5] Read register
PC[6] Write register
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
sim_printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port A = %02X\n", pata_unit[0].u4);
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
sim_printf("PATA: 8255 Write Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port B = %02X\n", pata_unit[0].u5);
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
sim_printf("PATA: 8255 Write Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port C = %02X\n", pata_unit[0].u6);
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
sim_printf("PATA: 8255 Write Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
sim_printf(" PATA: Reset\n");
return SCPE_OK;
}
/* iPATA.c: Intel i8255 PIO adapter for PATA HD
Copyright (c) 2015, 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.
NOTES:
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device. This is an extension of the i8255.c file to support
an emulated PATA IDE Hard Disk Drive.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
The Second 8255 on the iSBC 80/10 is used to connect to the IDE PATA
Hard Disk Drive. Pins are defined as shown below:
PA[0..7] High data byte
PB[0..7] Low data byte
PC[0..2] Register select
PC[3..4] CSFX select
PC[5] Read register
PC[6] Write register
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
sim_printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port A = %02X\n", pata_unit[0].u4);
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
sim_printf("PATA: 8255 Write Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port B = %02X\n", pata_unit[0].u5);
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
sim_printf("PATA: 8255 Write Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port C = %02X\n", pata_unit[0].u6);
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
sim_printf("PATA: 8255 Write Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
sim_printf(" PATA: Reset\n");
return SCPE_OK;
}

View file

@ -1,160 +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); /* ipc_cont*/
t_stat ipc_cont_reset (DEVICE *dptr, uint16 baseport);
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* 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
};
/* Reset routine */
t_stat ipc_cont_reset(DEVICE *dptr, uint16 baseport)
{
sim_printf(" ipc_cont[%d]: Reset\n", 0);
sim_printf(" ipc_cont[%d]: Registered at %04X\n", 0, baseport);
reg_dev(ipc_cont, baseport, 0);
ipc_cont_unit[0].u3 = 0x00; /* ipc reset */
return SCPE_OK;
}
/* 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)
{
if (io == 0) { /* read status port */
sim_printf(" ipc_cont: read data=%02X ipc_cont_unit[%d].u3=%02X\n",
ipc_cont_unit[0].u3, 0, ipc_cont_unit[0].u3);
return ipc_cont_unit[0].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 (inverted)
switch(data & 0x07) {
case 5: //interrupt enable 8085 INTR
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xBF;
else //bit high
ipc_cont_unit[0].u3 |= 0x20;
break;
case 4: //*selboot ROM @ 0E800h
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xEF;
else //bit high
ipc_cont_unit[0].u3 |= 0x10;
break;
case 2: //*startup ROM @ 00000h
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xFB;
else //bit high
ipc_cont_unit[0].u3 |= 0x04;
break;
case 1: //override inhibit other multibus users
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xFD;
else //bit high
ipc_cont_unit[0].u3 |= 0x02;
break;
case 0: //aux prom enable
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xFE;
else //bit high
ipc_cont_unit[0].u3 |= 0x01;
break;
default:
break;
}
sim_printf(" ipc_cont: write data=%02X ipc_cont_unit[%d].u3=%02X\n", data, 0, ipc_cont_unit[0].u3);
}
return 0;
}
/* end of ipc-cont.c */
/* 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); /* ipc_cont*/
t_stat ipc_cont_reset (DEVICE *dptr, uint16 baseport);
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* 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
};
/* Reset routine */
t_stat ipc_cont_reset(DEVICE *dptr, uint16 baseport)
{
sim_printf(" ipc_cont[%d]: Reset\n", 0);
sim_printf(" ipc_cont[%d]: Registered at %04X\n", 0, baseport);
reg_dev(ipc_cont, baseport, 0);
ipc_cont_unit[0].u3 = 0x00; /* ipc reset */
return SCPE_OK;
}
/* 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)
{
if (io == 0) { /* read status port */
sim_printf(" ipc_cont: read data=%02X ipc_cont_unit[%d].u3=%02X\n",
ipc_cont_unit[0].u3, 0, ipc_cont_unit[0].u3);
return ipc_cont_unit[0].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 (inverted)
switch(data & 0x07) {
case 5: //interrupt enable 8085 INTR
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xBF;
else //bit high
ipc_cont_unit[0].u3 |= 0x20;
break;
case 4: //*selboot ROM @ 0E800h
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xEF;
else //bit high
ipc_cont_unit[0].u3 |= 0x10;
break;
case 2: //*startup ROM @ 00000h
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xFB;
else //bit high
ipc_cont_unit[0].u3 |= 0x04;
break;
case 1: //override inhibit other multibus users
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xFD;
else //bit high
ipc_cont_unit[0].u3 |= 0x02;
break;
case 0: //aux prom enable
if(data & 0x08) //bit low
ipc_cont_unit[0].u3 &= 0xFE;
else //bit high
ipc_cont_unit[0].u3 |= 0x01;
break;
default:
break;
}
sim_printf(" ipc_cont: write data=%02X ipc_cont_unit[%d].u3=%02X\n", data, 0, ipc_cont_unit[0].u3);
}
return 0;
}
/* end of ipc-cont.c */

View file

@ -1,186 +1,186 @@
/* ipcEPROM.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"
/* 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 */
extern UNIT ipc_cont_unit[];
/* 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 ipcEPROM.c */
/* ipcEPROM.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"
/* 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 */
extern UNIT ipc_cont_unit[];
/* 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 ipcEPROM.c */

View file

@ -1,309 +1,309 @@
/* 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);
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
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 UNIT zx200a_unit;
extern t_stat zx200a_reset(DEVICE *dptr, uint16 base);
extern t_stat isbc201_reset (DEVICE *dptr, uint16);
extern t_stat isbc202_reset (DEVICE *dptr, uint16);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern int32 isbc201_fdcnum;
extern int32 isbc202_fdcnum;
extern int32 zx200a_fdcnum;
/* 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);
sim_printf(" Multibus: Reset\n");
zx200a_fdcnum = 0;
zx200a_reset(NULL, ZX200A_BASE_DD);
// zx200a_reset(NULL, ZX200A_BASE_SD);
isbc201_fdcnum = 0;
isbc201_reset(NULL, SBC201_BASE);
isbc202_fdcnum = 0;
isbc202_reset(NULL, SBC202_BASE);
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;
};
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)
{
SET_XACK(0); /* set no XACK */
// return 0xFF;
return 0;
}
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 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 {
sim_printf("Port %04X is assigned\n", port);
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
SET_XACK(0); /* set no XACK */
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr);
return RAM_get_mbyte(addr);
}
/* 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);
RAM_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 ipcmultibus.c */
/* 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);
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
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 UNIT zx200a_unit;
extern t_stat zx200a_reset(DEVICE *dptr, uint16 base);
extern t_stat isbc201_reset (DEVICE *dptr, uint16);
extern t_stat isbc202_reset (DEVICE *dptr, uint16);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern int32 isbc201_fdcnum;
extern int32 isbc202_fdcnum;
extern int32 zx200a_fdcnum;
/* 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);
sim_printf(" Multibus: Reset\n");
zx200a_fdcnum = 0;
zx200a_reset(NULL, ZX200A_BASE_DD);
// zx200a_reset(NULL, ZX200A_BASE_SD);
isbc201_fdcnum = 0;
isbc201_reset(NULL, SBC201_BASE);
isbc202_fdcnum = 0;
isbc202_reset(NULL, SBC202_BASE);
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;
};
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)
{
SET_XACK(0); /* set no XACK */
// return 0xFF;
return 0;
}
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 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 {
sim_printf("Port %04X is assigned\n", port);
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
SET_XACK(0); /* set no XACK */
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr);
return RAM_get_mbyte(addr);
}
/* 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);
RAM_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 ipcmultibus.c */

View file

@ -1,145 +1,145 @@
/* ipcRAM8.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"
/* 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 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;
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
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);
}
/* put a byte to memory */
void RAM_put_mbyte(uint16 addr, uint8 val)
{
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
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");
}
/* end of ipcRAM8.c */
/* ipcRAM8.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"
/* 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 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;
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
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);
}
/* put a byte to memory */
void RAM_put_mbyte(uint16 addr, uint8 val)
{
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
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");
}
/* end of ipcRAM8.c */

View file

@ -1,203 +1,203 @@
/* iram.c: Intel RAM simulator for 16-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.
These functions support a simulated RAM device in low memory on an iSBC. These
SBCs do not have the capability to switch off this RAM. In most cases a portion
of the RAM is dual-ported so it also appears in the multibus memory map at
a configurable location.
Unit will support 16K SRAM sizes.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_RSIZE (UNIT_V_UF) /* RAM Size */
#define UNIT_RSIZE (0x1 << UNIT_V_RSIZE)
#define UNIT_NONE (0) /* No unit */
#define UNIT_16K (1) /* 16KB */
/* function prototypes */
t_stat RAM_svc (UNIT *uptr);
t_stat RAM_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat RAM_reset (DEVICE *dptr);
int32 RAM_get_mbyte(int32 addr);
void RAM_put_mbyte(int32 addr, int32 val);
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
MTAB RAM_mod[] = {
{ UNIT_RSIZE, UNIT_NONE, "None", "none", &RAM_set_size },
{ UNIT_RSIZE, UNIT_16K, "16KB", "16KB", &RAM_set_size },
{ 0 }
};
DEBTAB RAM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE RAM_dev = {
"RAM", //name
&RAM_unit, //units
NULL, //registers
RAM_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&RAM_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
RAM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
uint8 *RAM_buf = NULL; /* RAM buffer pointer */
/* RAM functions */
/* RAM set size = none or 16KB */
t_stat RAM_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_set_size: val=%d\n", val);
if ((val < UNIT_NONE) || (val > UNIT_16K)) {
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_set_size: Size error\n");
return SCPE_ARG;
}
RAM_unit.capac = 0x4000 * val; /* set size */
RAM_unit.u3 = 0x0000; /* base is 0 */
RAM_unit.u4 = val; /* save val */
if (RAM_buf) { /* if changed, allocate new buffer */
free (RAM_buf);
RAM_buf = NULL;
}
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_set_size: Done\n");
return (RAM_reset (NULL)); /* force reset after reconfig */
}
/* RAM reset */
t_stat RAM_reset (DEVICE *dptr)
{
int j;
FILE *fp;
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_reset: \n");
if (RAM_unit.capac == 0) { /* if undefined */
sim_printf(" RAM: defaulted for 16KB\n");
sim_printf(" \"set RAM 16KB\"\n");
RAM_unit.capac = 0x4000;
RAM_unit.u3 = 0;
RAM_unit.u4 = 1;
}
sim_printf(" RAM: Initializing [%04X-%04XH]\n",
RAM_unit.u3,
RAM_unit.u3 + RAM_unit.capac - 1);
if (RAM_buf == NULL) { /* no buffer allocated */
RAM_buf = malloc(RAM_unit.capac);
if (RAM_buf == NULL) {
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
RAM memory read or write is issued.
*/
/* get a byte from memory */
int32 RAM_get_mbyte(int32 addr)
{
int32 val, org, len;
org = RAM_unit.u3;
len = RAM_unit.capac - 1;
if (RAM_dev.dctrl & DEBUG_read)
sim_printf("RAM_get_mbyte: addr=%04X", addr);
if ((addr >= org) && (addr <= org + len)) {
val = *(RAM_buf + (addr - org));
if (RAM_dev.dctrl & DEBUG_read)
sim_printf(" val=%04X\n", val);
return (val & 0xFF);
}
if (RAM_dev.dctrl & DEBUG_read)
sim_printf(" Out of range\n", addr);
return 0xFF;
}
/* put a byte to memory */
void RAM_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
org = RAM_unit.u3;
len = RAM_unit.capac - 1;
if (RAM_dev.dctrl & DEBUG_write)
sim_printf("RAM_put_mbyte: addr=%04X, val=%02X", addr, val);
if ((addr >= org) && (addr < org + len)) {
*(RAM_buf + (addr - org)) = val & 0xFF;
if (RAM_dev.dctrl & DEBUG_write)
sim_printf("\n");
return;
}
if (RAM_dev.dctrl & DEBUG_write)
sim_printf(" Out of range\n", val);
}
/* end of iram.c */
/* iram.c: Intel RAM simulator for 16-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.
These functions support a simulated RAM device in low memory on an iSBC. These
SBCs do not have the capability to switch off this RAM. In most cases a portion
of the RAM is dual-ported so it also appears in the multibus memory map at
a configurable location.
Unit will support 16K SRAM sizes.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_RSIZE (UNIT_V_UF) /* RAM Size */
#define UNIT_RSIZE (0x1 << UNIT_V_RSIZE)
#define UNIT_NONE (0) /* No unit */
#define UNIT_16K (1) /* 16KB */
/* function prototypes */
t_stat RAM_svc (UNIT *uptr);
t_stat RAM_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat RAM_reset (DEVICE *dptr);
int32 RAM_get_mbyte(int32 addr);
void RAM_put_mbyte(int32 addr, int32 val);
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
MTAB RAM_mod[] = {
{ UNIT_RSIZE, UNIT_NONE, "None", "none", &RAM_set_size },
{ UNIT_RSIZE, UNIT_16K, "16KB", "16KB", &RAM_set_size },
{ 0 }
};
DEBTAB RAM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE RAM_dev = {
"RAM", //name
&RAM_unit, //units
NULL, //registers
RAM_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&RAM_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
RAM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
uint8 *RAM_buf = NULL; /* RAM buffer pointer */
/* RAM functions */
/* RAM set size = none or 16KB */
t_stat RAM_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_set_size: val=%d\n", val);
if ((val < UNIT_NONE) || (val > UNIT_16K)) {
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_set_size: Size error\n");
return SCPE_ARG;
}
RAM_unit.capac = 0x4000 * val; /* set size */
RAM_unit.u3 = 0x0000; /* base is 0 */
RAM_unit.u4 = val; /* save val */
if (RAM_buf) { /* if changed, allocate new buffer */
free (RAM_buf);
RAM_buf = NULL;
}
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_set_size: Done\n");
return (RAM_reset (NULL)); /* force reset after reconfig */
}
/* RAM reset */
t_stat RAM_reset (DEVICE *dptr)
{
int j;
FILE *fp;
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_reset: \n");
if (RAM_unit.capac == 0) { /* if undefined */
sim_printf(" RAM: defaulted for 16KB\n");
sim_printf(" \"set RAM 16KB\"\n");
RAM_unit.capac = 0x4000;
RAM_unit.u3 = 0;
RAM_unit.u4 = 1;
}
sim_printf(" RAM: Initializing [%04X-%04XH]\n",
RAM_unit.u3,
RAM_unit.u3 + RAM_unit.capac - 1);
if (RAM_buf == NULL) { /* no buffer allocated */
RAM_buf = malloc(RAM_unit.capac);
if (RAM_buf == NULL) {
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (RAM_dev.dctrl & DEBUG_flow)
sim_printf("RAM_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
RAM memory read or write is issued.
*/
/* get a byte from memory */
int32 RAM_get_mbyte(int32 addr)
{
int32 val, org, len;
org = RAM_unit.u3;
len = RAM_unit.capac - 1;
if (RAM_dev.dctrl & DEBUG_read)
sim_printf("RAM_get_mbyte: addr=%04X", addr);
if ((addr >= org) && (addr <= org + len)) {
val = *(RAM_buf + (addr - org));
if (RAM_dev.dctrl & DEBUG_read)
sim_printf(" val=%04X\n", val);
return (val & 0xFF);
}
if (RAM_dev.dctrl & DEBUG_read)
sim_printf(" Out of range\n", addr);
return 0xFF;
}
/* put a byte to memory */
void RAM_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
org = RAM_unit.u3;
len = RAM_unit.capac - 1;
if (RAM_dev.dctrl & DEBUG_write)
sim_printf("RAM_put_mbyte: addr=%04X, val=%02X", addr, val);
if ((addr >= org) && (addr < org + len)) {
*(RAM_buf + (addr - org)) = val & 0xFF;
if (RAM_dev.dctrl & DEBUG_write)
sim_printf("\n");
return;
}
if (RAM_dev.dctrl & DEBUG_write)
sim_printf(" Out of range\n", val);
}
/* end of iram.c */

View file

@ -1,154 +1,154 @@
/* 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"
/* function prototypes */
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 uint8 i8255_B[4]; //port B byte I/O
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
};
/* 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;
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);
} else {
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
return 0xFF;
}
}
/* put a byte to memory */
void RAM_put_mbyte(uint16 addr, uint8 val)
{
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;
} else {
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
return;
}
}
/* end of iRAM8.c */
/* 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"
/* function prototypes */
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 uint8 i8255_B[4]; //port B byte I/O
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
};
/* 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;
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);
} else {
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
return 0xFF;
}
}
/* put a byte to memory */
void RAM_put_mbyte(uint16 addr, uint8 val)
{
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;
} else {
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
return;
}
}
/* end of iRAM8.c */

View file

@ -1,174 +1,174 @@
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
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 isbc016, isbc032, isbc048 and isbc064
memory card on an Intel multibus system.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
uint8 isbc064_get_mbyte(uint16 addr);
void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 xack; /* XACK signal */
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
// &isbc064_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: ");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
isbc064_unit.capac = SBC064_SIZE;
isbc064_unit.u3 = SBC064_BASE;
sim_printf("Initializing iSBC-064 RAM Board\n");
sim_printf(" Available[%04X-%04XH]\n",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
}
if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = (uint8 *)malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
uint8 isbc064_get_mbyte(uint16 addr)
{
uint32 val, org, len;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: addr=%04X", addr);
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &isbc064_dev, "isbc064_get_mbyte: Set XACK for %04X\n", addr);
val = *((uint8 *)isbc064_unit.filebuf + (addr - org));
sim_debug (DEBUG_read, &isbc064_dev, " val=%04X\n", val);
// sim_printf ("isbc064_get_mbyte: addr=%04X, val=%02X\n", addr, val);
return (val & 0xFF);
} else {
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: Out of range\n");
return 0; /* multibus has active high pullups and inversion */
}
}
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: Disabled\n");
// sim_printf ("isbc064_get_mbyte: Disabled\n");
return 0; /* multibus has active high pullups and inversion */
}
/* put a byte into memory */
void isbc064_put_mbyte(uint16 addr, uint8 val)
{
uint32 org, len;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
// sim_printf ("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Set XACK for %04X\n", addr);
*((uint8 *)isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Return\n");
return;
} else {
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Out of range\n");
return;
}
}
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Disabled\n");
// sim_printf ("isbc064_put_mbyte: Disabled\n");
}
/* end of isbc064.c */
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
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 isbc016, isbc032, isbc048 and isbc064
memory card on an Intel multibus system.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
uint8 isbc064_get_mbyte(uint16 addr);
void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 xack; /* XACK signal */
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
// &isbc064_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: ");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
isbc064_unit.capac = SBC064_SIZE;
isbc064_unit.u3 = SBC064_BASE;
sim_printf("Initializing iSBC-064 RAM Board\n");
sim_printf(" Available[%04X-%04XH]\n",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
}
if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = (uint8 *)malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
uint8 isbc064_get_mbyte(uint16 addr)
{
uint32 val, org, len;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: addr=%04X", addr);
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &isbc064_dev, "isbc064_get_mbyte: Set XACK for %04X\n", addr);
val = *((uint8 *)isbc064_unit.filebuf + (addr - org));
sim_debug (DEBUG_read, &isbc064_dev, " val=%04X\n", val);
// sim_printf ("isbc064_get_mbyte: addr=%04X, val=%02X\n", addr, val);
return (val & 0xFF);
} else {
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: Out of range\n");
return 0; /* multibus has active high pullups and inversion */
}
}
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: Disabled\n");
// sim_printf ("isbc064_get_mbyte: Disabled\n");
return 0; /* multibus has active high pullups and inversion */
}
/* put a byte into memory */
void isbc064_put_mbyte(uint16 addr, uint8 val)
{
uint32 org, len;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
// sim_printf ("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Set XACK for %04X\n", addr);
*((uint8 *)isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Return\n");
return;
} else {
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Out of range\n");
return;
}
}
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Disabled\n");
// sim_printf ("isbc064_put_mbyte: Disabled\n");
}
/* end of isbc064.c */

View file

@ -185,8 +185,8 @@
/* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX;
extern uint16 port; //port called in dev_table[port]
extern int32 PCX;
/* external function prototypes */
@ -472,7 +472,7 @@ uint8 isbc2010(t_bool io, uint8 data)
if (io == 0) { /* read ststus*/
if (DEBUG)
sim_printf("\n isbc201-%d: 0x78 returned status=%02X PCX=%04X",
fdcnum, fdc201[fdcnum].stat, PCX);
fdcnum, fdc201[fdcnum].stat, PCX);
return fdc201[fdcnum].stat;
}
}
@ -495,7 +495,7 @@ uint8 isbc2011(t_bool io, uint8 data)
fdc201[fdcnum].iopb = data;
if (DEBUG)
sim_printf("\n isbc201-%d: 0x79 IOPB low=%02X PCX=%04X",
fdcnum, data, PCX);
fdcnum, data, PCX);
}
}
return 0;
@ -527,12 +527,12 @@ uint8 isbc2013(t_bool io, uint8 data)
if ((fdcnum = isbc201_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if (fdc201[fdcnum].rtype == 0) {
if (fdc201[fdcnum].rtype == 0) {
if (DEBUG)
sim_printf("\n isbc201-%d: 0x7B returned rbyte0=%02X PCX=%04X",
fdcnum, fdc201[fdcnum].rbyte0, PCX);
return fdc201[fdcnum].rbyte0;
} else {
} else {
if (fdc201[fdcnum].rdychg) {
if (DEBUG)
sim_printf("\n isbc201-%d: 0x7B returned rbyte1=%02X PCX=%04X",

View file

@ -495,7 +495,7 @@ uint8 isbc2020(t_bool io, uint8 data)
if (io == 0) { /* read ststus*/
if (DEBUG)
sim_printf("\n isbc202-%d: 0x78 returned status=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].stat, PCX);
fdcnum, fdc202[fdcnum].stat, PCX);
return fdc202[fdcnum].stat;
}
}
@ -535,7 +535,7 @@ uint8 isbc2022(t_bool io, uint8 data)
fdc202[fdcnum].iopb |= (data << 8);
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X",
fdcnum, fdc202[fdcnum].iopb, PCX);
fdcnum, fdc202[fdcnum].iopb, PCX);
isbc202_diskio(fdcnum);
if (fdc202[fdcnum].intff)
fdc202[fdcnum].stat |= FDCINT;
@ -550,12 +550,12 @@ uint8 isbc2023(t_bool io, uint8 data)
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if (fdc202[fdcnum].rtype == 0) {
if (fdc202[fdcnum].rtype == 0) {
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7B returned rbyte0=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rbyte0, PCX);
return fdc202[fdcnum].rbyte0;
} else {
} else {
if (fdc202[fdcnum].rdychg) {
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7B returned rbyte1=%02X PCX=%04X",
@ -567,7 +567,7 @@ uint8 isbc2023(t_bool io, uint8 data)
fdcnum, 0, PCX);
return 0;
}
}
}
} else { /* write data port */
; //stop diskette operation
}

View file

@ -1,193 +1,193 @@
/* i8255.c: Intel i8255 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.
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(int32, int32), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
sim_printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
sim_printf("PATA: 8255 Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
sim_printf("PATA: 8255 Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
sim_printf("PATA: 8255 Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
sim_printf(" PATA: Reset\n");
return SCPE_OK;
}
/* i8255.c: Intel i8255 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.
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(int32, int32), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
sim_printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
sim_printf("PATA: 8255 Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
sim_printf("PATA: 8255 Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
sim_printf("PATA: 8255 Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
sim_printf(" PATA: Reset\n");
return SCPE_OK;
}

View file

@ -520,7 +520,7 @@ uint8 zx200a0(t_bool io, uint8 data)
if (io == 0) { /* read ststus*/
if (DEBUG)
sim_printf("\n zx-200a0-%d: 0x78/88 returned status=%02X PCX=%04X",
fdcnum, zx200a[fdcnum].stat, PCX);
fdcnum, zx200a[fdcnum].stat, PCX);
return zx200a[fdcnum].stat;
}
}
@ -560,7 +560,7 @@ uint8 zx200a2(t_bool io, uint8 data)
zx200a[fdcnum].iopb |= (data << 8);
if (DEBUG)
sim_printf("\n zx-200a2-%d: 0x7A/8A IOPB=%04X PCX=%04X",
fdcnum, zx200a[fdcnum].iopb, PCX);
fdcnum, zx200a[fdcnum].iopb, PCX);
zx200a_diskio(fdcnum);
if (zx200a[fdcnum].intff)
zx200a[fdcnum].stat |= FDCINT;
@ -575,12 +575,12 @@ uint8 zx200a3(t_bool io, uint8 data)
if ((fdcnum = zx200_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if (zx200a[fdcnum].rtype == 0) {
if (zx200a[fdcnum].rtype == 0) {
if (DEBUG)
sim_printf("\n zx200a3-%d: 0x7B/8B returned rbyte0=%02X PCX=%04X",
fdcnum, zx200a[fdcnum].rbyte0, PCX);
return zx200a[fdcnum].rbyte0;
} else {
} else {
if (zx200a[fdcnum].rdychg) {
if (DEBUG)
sim_printf("\n zx200a3-%d: 0x7B/8B returned rbyte1=%02X PCX=%04X",
@ -592,7 +592,7 @@ uint8 zx200a3(t_bool io, uint8 data)
fdcnum, 0, PCX);
return 0;
}
}
}
} else { /* write data port */
; //stop diskette operation
}

View file

@ -1,85 +1,85 @@
/* 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;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_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,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* 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;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_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,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -1,148 +1,148 @@
/* 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 int32 i8251_devnum;
extern t_stat i8251_reset(DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset(DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset(DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset(DEVICE *dptr, uint16 base);
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);
extern t_stat ioc_cont_reset(DEVICE *dptr, uint16 base);
extern uint32 PCX; /* 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 Onboard Devices:\n");
i8080_reset(NULL);
i8251_devnum = 0;
i8251_reset(NULL, I8251_BASE_0);
i8251_reset(NULL, I8251_BASE_1);
i8253_devnum = 0;
i8253_reset(NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset(NULL, I8255_BASE_0);
i8255_reset(NULL, I8255_BASE_1);
i8259_devnum = 0;
i8259_reset(NULL, I8259_BASE_0);
i8259_reset(NULL, I8259_BASE_1);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
ipc_cont_reset(NULL, ICONT_BASE);
ioc_cont_reset(NULL, DBB_BASE);
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
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);
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
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, PCX);
return;
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
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 */
/* 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 int32 i8251_devnum;
extern t_stat i8251_reset(DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset(DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset(DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset(DEVICE *dptr, uint16 base);
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);
extern t_stat ioc_cont_reset(DEVICE *dptr, uint16 base);
extern uint32 PCX; /* 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 Onboard Devices:\n");
i8080_reset(NULL);
i8251_devnum = 0;
i8251_reset(NULL, I8251_BASE_0);
i8251_reset(NULL, I8251_BASE_1);
i8253_devnum = 0;
i8253_reset(NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset(NULL, I8255_BASE_0);
i8255_reset(NULL, I8255_BASE_1);
i8259_devnum = 0;
i8259_reset(NULL, I8259_BASE_0);
i8259_reset(NULL, I8259_BASE_1);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
ipc_cont_reset(NULL, ICONT_BASE);
ioc_cont_reset(NULL, DBB_BASE);
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
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);
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
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, PCX);
return;
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
RAM_put_mbyte(addr, val);
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of ipc.c */

View file

@ -1,140 +1,140 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define IPC 0
#define SET_XACK(VAL) (xack = VAL)
/* 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
#define ROM_DISABLE 1
/* set the base and size for the RAM on the MDS 225 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0xF800
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE_DD 0x78
#define ZX200A_BASE_SD 0x88
#define ZX200A_NUM 0
/* 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 */
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define IPC 0
#define SET_XACK(VAL) (xack = VAL)
/* 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
#define ROM_DISABLE 1
/* set the base and size for the RAM on the MDS 225 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0xF800
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE_DD 0x78
#define ZX200A_BASE_SD 0x88
#define ZX200A_NUM 0
/* 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 */

View file

@ -1,141 +1,141 @@
/* iSBC80-10.c: Intel iSBC 80/10 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.
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"
/* 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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
/* external function prototypes */
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 t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/10 SBC\n Onboard Devices:\n");
i8080_reset (NULL);
i8251_devnum = 0;
i8251_reset (NULL, I8251_BASE);
i8255_devnum = 0;
i8255_reset (NULL, I8255_BASE_0);
i8255_reset (NULL, I8255_BASE_1);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
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))) {
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))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
return multibus_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, I/O, and Multibus memory */
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);
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))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC80-10.c */
/* iSBC80-10.c: Intel iSBC 80/10 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.
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"
/* 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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
/* external function prototypes */
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 t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/10 SBC\n Onboard Devices:\n");
i8080_reset (NULL);
i8251_devnum = 0;
i8251_reset (NULL, I8251_BASE);
i8255_devnum = 0;
i8255_reset (NULL, I8255_BASE_0);
i8255_reset (NULL, I8255_BASE_1);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
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))) {
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))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
return multibus_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, I/O, and Multibus memory */
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);
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))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC80-10.c */

View file

@ -1,82 +1,82 @@
/* sys-8010_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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8255_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_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 System 80/10";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8255_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* sys-8010_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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8255_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_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 System 80/10";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8255_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -28,7 +28,7 @@
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
@ -57,17 +57,17 @@
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_BASE 0x88
#define SBC201_INT INT_1
#define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
@ -101,10 +101,10 @@
/* 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)
#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 */
@ -120,11 +120,11 @@
/* 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 */
#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 */

View file

@ -1,136 +1,136 @@
/* iSBC80-20.c: Intel iSBC 80/20 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.
?? ??? 10 - 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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* CPU reset routine
put here to cause a reset of the entire iSBC system */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/20\n");
i8080_reset(NULL);
i8251_reset(NULL, I8251_BASE);
i8255_reset(NULL, I8255_BASE_0);
i8255_reset(NULL, I8255_BASE_1);
i8259_reset(NULL, I8259_BASE);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM and Multibus memory */
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) && (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) && (addr < (RAM_unit.u3 + RAM_unit.capac)))
return RAM_get_mbyte(addr);
} /* otherwise, try the multibus */
return multibus_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 local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr);
return;
}
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && (addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC80-20.c */
/* iSBC80-20.c: Intel iSBC 80/20 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.
?? ??? 10 - 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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* CPU reset routine
put here to cause a reset of the entire iSBC system */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/20\n");
i8080_reset(NULL);
i8251_reset(NULL, I8251_BASE);
i8255_reset(NULL, I8255_BASE_0);
i8255_reset(NULL, I8255_BASE_1);
i8259_reset(NULL, I8259_BASE);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM and Multibus memory */
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) && (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) && (addr < (RAM_unit.u3 + RAM_unit.capac)))
return RAM_get_mbyte(addr);
} /* otherwise, try the multibus */
return multibus_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 local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr);
return;
}
} /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && (addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC80-20.c */

View file

@ -1,82 +1,82 @@
/* sys-8020_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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8259_dev;
extern DEVICE i8251_dev;
extern DEVICE i8255_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc064_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 System 80/20";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8259_dev,
&i8251_dev,
&i8255_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* sys-8020_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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8259_dev;
extern DEVICE i8251_dev;
extern DEVICE i8255_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc064_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 System 80/20";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8259_dev,
&i8251_dev,
&i8255_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -28,7 +28,7 @@
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
@ -61,17 +61,17 @@
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_BASE 0x78
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
@ -105,10 +105,10 @@
/* 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)
#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 */
@ -124,11 +124,11 @@
/* 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 */
#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 */

View file

@ -1,149 +1,149 @@
/* iSBC80-24.c: Intel iSBC 80/24 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.
MODIFICATIONS:
04 Nov 16 - Original file.
NOTES:
This software was written by Bill Beech, Nov 2016, to allow emulation of Multibus
Computer Systems.
*/
#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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
extern int32 PCX; /* External view of PC */
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/24 SBC\n Onboard Devices:\n");
i8080_reset (NULL);
i8251_devnum = 0;
i8251_reset (NULL, I8251_BASE);
i8253_devnum = 0;
i8253_reset (NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset (NULL, I8255_BASE_0);
i8255_reset (NULL, I8255_BASE_1);
i8259_devnum = 0;
i8259_reset (NULL, I8259_BASE);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
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))) {
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))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
return multibus_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, I/O, and Multibus memory */
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 from PC=%04X - ignored\n", addr, PCX);
return;
}
} /* 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))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC80-24.c */
/* iSBC80-24.c: Intel iSBC 80/24 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.
MODIFICATIONS:
04 Nov 16 - Original file.
NOTES:
This software was written by Bill Beech, Nov 2016, to allow emulation of Multibus
Computer Systems.
*/
#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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
extern int32 PCX; /* External view of PC */
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/24 SBC\n Onboard Devices:\n");
i8080_reset (NULL);
i8251_devnum = 0;
i8251_reset (NULL, I8251_BASE);
i8253_devnum = 0;
i8253_reset (NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset (NULL, I8255_BASE_0);
i8255_reset (NULL, I8255_BASE_1);
i8259_devnum = 0;
i8259_reset (NULL, I8259_BASE);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
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))) {
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))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
return multibus_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, I/O, and Multibus memory */
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 from PC=%04X - ignored\n", addr, PCX);
return;
}
} /* 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))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC80-24.c */

View file

@ -1,84 +1,84 @@
/* sys-8010_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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#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 multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc064_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 System 80/24";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&EPROM_dev,
&RAM_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* sys-8010_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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#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 multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc064_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 System 80/24";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&EPROM_dev,
&RAM_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -28,7 +28,7 @@
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
@ -65,12 +65,12 @@
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_BASE 0x78
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
@ -80,7 +80,7 @@
#define ZX200A_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
@ -109,10 +109,10 @@
/* 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)
#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 */
@ -128,11 +128,11 @@
/* 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 */
#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 */

View file

@ -1,147 +1,147 @@
/* iSBC8030.c: Intel iSBC 80/30 SBC 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:
04 Nov 16 - Original file.
NOTES:
This software was written by Bill Beech, Nov 2016, to allow emulation of Multibus
Computer Systems.
*/
#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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/24:\n");
i8080_reset (NULL);
i8251_devnum = 0;
i8251_reset (NULL, I8251_BASE);
i8253_devnum = 0;
i8253_reset (NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset (NULL, I8255_BASE);
i8259_devnum = 0;
i8259_reset (NULL, I8259_BASE);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
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))) {
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))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
return multibus_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, I/O, and Multibus memory */
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);
return;
}
} /* 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))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC8030.c */
/* iSBC8030.c: Intel iSBC 80/30 SBC 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:
04 Nov 16 - Original file.
NOTES:
This software was written by Bill Beech, Nov 2016, to allow emulation of Multibus
Computer Systems.
*/
#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 globals */
extern uint8 i8255_C[4]; //port C byte I/O
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/24:\n");
i8080_reset (NULL);
i8251_devnum = 0;
i8251_reset (NULL, I8251_BASE);
i8253_devnum = 0;
i8253_reset (NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset (NULL, I8255_BASE);
i8259_devnum = 0;
i8259_reset (NULL, I8259_BASE);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
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))) {
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))) {
return RAM_get_mbyte(addr);
}
} /* otherwise, try the multibus */
return multibus_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, I/O, and Multibus memory */
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);
return;
}
} /* 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))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
multibus_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 iSBC8030.c */

View file

@ -1,85 +1,85 @@
/* sys-8030_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.
?? ??? 10 - 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 multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_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 System 80/10";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&EPROM_dev,
&RAM_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* sys-8030_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.
?? ??? 10 - 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 multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_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 System 80/10";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&EPROM_dev,
&RAM_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -28,7 +28,7 @@
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
@ -68,12 +68,12 @@
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_BASE 0x78
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
@ -83,7 +83,7 @@
#define ZX200A_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
@ -112,10 +112,10 @@
/* 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)
#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 */
@ -131,11 +131,11 @@
/* 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 */
#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 */