Intel-Systems, IBMPC: Standardize to CRLF line endings and spaces for tabs
This commit is contained in:
parent
18efafe927
commit
a221ac4055
40 changed files with 13418 additions and 13418 deletions
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue