IBMPC: Minor cleanup and change to CRLF line endings
This commit is contained in:
parent
30556c8d78
commit
a3a1db40fe
18 changed files with 9359 additions and 9244 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,318 +1,318 @@
|
|||
/* i8251.c: Intel 8251 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 base 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"
|
||||
|
||||
/* 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 i8251_svc (UNIT *uptr);
|
||||
t_stat i8251_reset (DEVICE *dptr, uint16 base);
|
||||
void i8251_reset1(uint8 devnum);
|
||||
uint8 i8251_get_dn(void);
|
||||
uint8 i8251s(t_bool io, uint8 data);
|
||||
uint8 i8251d(t_bool io, uint8 data);
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8251_devnum = 0; //initially, no 8251 instances
|
||||
uint16 i8251_port[4]; //base port assigned to each 8251 instance
|
||||
|
||||
/* i8251 Standard I/O Data Structures */
|
||||
/* up to 1 i8251 devices */
|
||||
|
||||
UNIT i8251_unit = {
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT }
|
||||
};
|
||||
|
||||
REG i8251_reg[4] = {
|
||||
{ HRDATA (DATA0, i8251_unit[0].buf, 8) },
|
||||
{ HRDATA (STAT0, i8251_unit[0].u3, 8) },
|
||||
{ HRDATA (MODE0, i8251_unit[0].u4, 8) },
|
||||
{ HRDATA (CMD0, i8251_unit[0].u5, 8) },
|
||||
{ HRDATA (DATA1, i8251_unit[1].buf, 8) },
|
||||
{ HRDATA (STAT1, i8251_unit[1].u3, 8) },
|
||||
{ HRDATA (MODE1, i8251_unit[1].u4, 8) },
|
||||
{ HRDATA (CMD1, i8251_unit[1].u5, 8) },
|
||||
{ HRDATA (DATA2, i8251_unit[2].buf, 8) },
|
||||
{ HRDATA (STAT2, i8251_unit[2].u3, 8) },
|
||||
{ HRDATA (MODE2, i8251_unit[2].u4, 8) },
|
||||
{ HRDATA (CMD2, i8251_unit[2].u5, 8) },
|
||||
{ HRDATA (DATA3, i8251_unit[3].buf, 8) },
|
||||
{ HRDATA (STAT3, i8251_unit[3].u3, 8) },
|
||||
{ HRDATA (MOD3E, i8251_unit[3].u4, 8) },
|
||||
{ HRDATA (CMD3, i8251_unit[3].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 = {
|
||||
"8251", //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 base)
|
||||
{
|
||||
if (i8251_devnum >= I8251_NUM) {
|
||||
sim_printf("8251_reset: too many devices!\n");
|
||||
return 0;
|
||||
}
|
||||
i8251_port[i8251_devnum] = reg_dev(i8251d, base);
|
||||
reg_dev(i8251s, base + 1);
|
||||
i8251_reset1(i8251_devnum);
|
||||
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, base);
|
||||
sim_activate (&i8251_unit[i8251_devnum], i8251_unit[i8251_devnum].wait); /* activate unit */
|
||||
i8259_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: 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 %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 = i8259_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read status port */
|
||||
return i8251_unit[devnum].u3;
|
||||
} else { /* write status port */
|
||||
if (i8251_unit[devnum].u6) { /* if mode, set cmd */
|
||||
i8251_unit[devnum].u5 = data;
|
||||
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
|
||||
if (data & SD) /* reset port! */
|
||||
i8251_reset1(devnum);
|
||||
} else { /* set mode */
|
||||
i8251_unit[devnum].u4 = data;
|
||||
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
|
||||
i8251_unit[devnum].u6 = 1; /* set cmd received */
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8251d(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8259_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8251_unit[devnum].u3 &= ~RXR;
|
||||
return (i8251_unit[devnum].buf);
|
||||
} else { /* write data port */
|
||||
sim_putchar(data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8251.c */
|
||||
/* i8251.c: Intel 8251 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 base 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"
|
||||
|
||||
/* 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 i8251_svc (UNIT *uptr);
|
||||
t_stat i8251_reset (DEVICE *dptr, uint16 base);
|
||||
void i8251_reset1(uint8 devnum);
|
||||
uint8 i8251_get_dn(void);
|
||||
uint8 i8251s(t_bool io, uint8 data);
|
||||
uint8 i8251d(t_bool io, uint8 data);
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8251_devnum = 0; //initially, no 8251 instances
|
||||
uint16 i8251_port[4]; //base port assigned to each 8251 instance
|
||||
|
||||
/* i8251 Standard I/O Data Structures */
|
||||
/* up to 1 i8251 devices */
|
||||
|
||||
UNIT i8251_unit = {
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT }
|
||||
};
|
||||
|
||||
REG i8251_reg[4] = {
|
||||
{ HRDATA (DATA0, i8251_unit[0].buf, 8) },
|
||||
{ HRDATA (STAT0, i8251_unit[0].u3, 8) },
|
||||
{ HRDATA (MODE0, i8251_unit[0].u4, 8) },
|
||||
{ HRDATA (CMD0, i8251_unit[0].u5, 8) },
|
||||
{ HRDATA (DATA1, i8251_unit[1].buf, 8) },
|
||||
{ HRDATA (STAT1, i8251_unit[1].u3, 8) },
|
||||
{ HRDATA (MODE1, i8251_unit[1].u4, 8) },
|
||||
{ HRDATA (CMD1, i8251_unit[1].u5, 8) },
|
||||
{ HRDATA (DATA2, i8251_unit[2].buf, 8) },
|
||||
{ HRDATA (STAT2, i8251_unit[2].u3, 8) },
|
||||
{ HRDATA (MODE2, i8251_unit[2].u4, 8) },
|
||||
{ HRDATA (CMD2, i8251_unit[2].u5, 8) },
|
||||
{ HRDATA (DATA3, i8251_unit[3].buf, 8) },
|
||||
{ HRDATA (STAT3, i8251_unit[3].u3, 8) },
|
||||
{ HRDATA (MOD3E, i8251_unit[3].u4, 8) },
|
||||
{ HRDATA (CMD3, i8251_unit[3].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 = {
|
||||
"8251", //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 base)
|
||||
{
|
||||
if (i8251_devnum >= I8251_NUM) {
|
||||
sim_printf("8251_reset: too many devices!\n");
|
||||
return 0;
|
||||
}
|
||||
i8251_port[i8251_devnum] = reg_dev(i8251d, base);
|
||||
reg_dev(i8251s, base + 1);
|
||||
i8251_reset1(i8251_devnum);
|
||||
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, base);
|
||||
sim_activate (&i8251_unit[i8251_devnum], i8251_unit[i8251_devnum].wait); /* activate unit */
|
||||
i8259_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: 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 %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 = i8259_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read status port */
|
||||
return i8251_unit[devnum].u3;
|
||||
} else { /* write status port */
|
||||
if (i8251_unit[devnum].u6) { /* if mode, set cmd */
|
||||
i8251_unit[devnum].u5 = data;
|
||||
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
|
||||
if (data & SD) /* reset port! */
|
||||
i8251_reset1(devnum);
|
||||
} else { /* set mode */
|
||||
i8251_unit[devnum].u4 = data;
|
||||
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
|
||||
i8251_unit[devnum].u6 = 1; /* set cmd received */
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8251d(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8259_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8251_unit[devnum].u3 &= ~RXR;
|
||||
return (i8251_unit[devnum].buf);
|
||||
} else { /* write data port */
|
||||
sim_putchar(data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8251.c */
|
||||
|
|
|
@ -1,235 +1,235 @@
|
|||
/* 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 base and size.
|
||||
24 Apr 15 -- Modified to use simh_debug
|
||||
|
||||
NOTES:
|
||||
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8253_devnum = 0; //actual number of 8253 instances + 1
|
||||
uint16 i8253_port[4]; //base port registered to each instance
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat i8253_svc (UNIT *uptr);
|
||||
t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
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 = {
|
||||
"8251", //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)
|
||||
{
|
||||
int32 temp;
|
||||
|
||||
sim_activate (&i8253_unit[0], i8253_unit[0].wait); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8253_reset (DEVICE *dptr, uint16 port)
|
||||
{
|
||||
if (i8253_devnum > I8253_NUM) {
|
||||
sim_printf("i8253_reset: too many devices!\n");
|
||||
return SCPE_MEM;
|
||||
}
|
||||
i8253_port[i8253_devnum] = reg_dev(i8253t0, port);
|
||||
reg_dev(i8253t1, port + 1);
|
||||
reg_dev(i8253t2, port + 2);
|
||||
reg_dev(i8253c, port + 3);
|
||||
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_printf(" 8253-%d: Reset\n", i8253_devnum);
|
||||
sim_printf(" 8253-%d: Registered at %03X\n", i8253_devnum, port);
|
||||
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 %03X 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 */
|
||||
i8253_unit[devnum].u3 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8253t1(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8253_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8253_unit[devnum].u4 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u4;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8253t2(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8253_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8253_unit[devnum].u5 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u5;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8253c(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8253_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read status port */
|
||||
i8253_unit[devnum].u6 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u6;
|
||||
}
|
||||
}
|
||||
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 base and size.
|
||||
24 Apr 15 -- Modified to use simh_debug
|
||||
|
||||
NOTES:
|
||||
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8253_devnum = 0; //actual number of 8253 instances + 1
|
||||
uint16 i8253_port[4]; //base port registered to each instance
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat i8253_svc (UNIT *uptr);
|
||||
t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
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 = {
|
||||
"8251", //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)
|
||||
{
|
||||
int32 temp;
|
||||
|
||||
sim_activate (&i8253_unit[0], i8253_unit[0].wait); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8253_reset (DEVICE *dptr, uint16 port)
|
||||
{
|
||||
if (i8253_devnum > I8253_NUM) {
|
||||
sim_printf("i8253_reset: too many devices!\n");
|
||||
return SCPE_MEM;
|
||||
}
|
||||
i8253_port[i8253_devnum] = reg_dev(i8253t0, port);
|
||||
reg_dev(i8253t1, port + 1);
|
||||
reg_dev(i8253t2, port + 2);
|
||||
reg_dev(i8253c, port + 3);
|
||||
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_printf(" 8253-%d: Reset\n", i8253_devnum);
|
||||
sim_printf(" 8253-%d: Registered at %03X\n", i8253_devnum, port);
|
||||
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 %03X 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 */
|
||||
i8253_unit[devnum].u3 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8253t1(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8253_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8253_unit[devnum].u4 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u4;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8253t2(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8253_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8253_unit[devnum].u5 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u5;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8253c(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8253_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read status port */
|
||||
i8253_unit[devnum].u6 = data;
|
||||
return 0;
|
||||
} else { /* write data port */
|
||||
return i8253_unit[devnum].u6;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8253.c */
|
||||
|
|
|
@ -1,289 +1,289 @@
|
|||
/* 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 (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.
|
||||
|
||||
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 */
|
||||
|
||||
/* 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 i8255s(t_bool io, uint8 data);
|
||||
uint8 i8255a(t_bool io, uint8 data);
|
||||
uint8 i8255b(t_bool io, uint8 data);
|
||||
uint8 i8255c(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 = {
|
||||
"8255", //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_reset, //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 i8255_unit[devnum].u3;
|
||||
} else { /* write status port */
|
||||
if (data & 0x80) { /* mode instruction */
|
||||
i8255_unit[devnum].u3 = data;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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 (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.
|
||||
|
||||
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 */
|
||||
|
||||
/* 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 i8255s(t_bool io, uint8 data);
|
||||
uint8 i8255a(t_bool io, uint8 data);
|
||||
uint8 i8255b(t_bool io, uint8 data);
|
||||
uint8 i8255c(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 = {
|
||||
"8255", //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_reset, //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 i8255_unit[devnum].u3;
|
||||
} else { /* write status port */
|
||||
if (data & 0x80) { /* mode instruction */
|
||||
i8255_unit[devnum].u3 = data;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8255.c */
|
||||
|
|
|
@ -1,263 +1,263 @@
|
|||
/* 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 Computer Systems.
|
||||
|
||||
This program simulates up to 4 i8259 devices.
|
||||
|
||||
u3 = IRR
|
||||
u4 = ISR
|
||||
u5 = IMR
|
||||
*/
|
||||
|
||||
#include "system_defs.h" /* system header in system dir */
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
void i8259_dump(uint8 devnum);
|
||||
t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
uint8 i8259_get_dn(void);
|
||||
uint8 i8259a(t_bool io, uint8 data);
|
||||
uint8 i8259b(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8259_devnum = 0; //initially, no 8259 instances
|
||||
uint16 i8259_port[4]; //base port assigned to each 8259 instance
|
||||
uint8 i8259_ints[4]; //8 interrupt inputs for each 8259 instance
|
||||
|
||||
uint8 i8259_icw1[4];
|
||||
uint8 i8259_icw2[4];
|
||||
uint8 i8259_icw3[4];
|
||||
uint8 i8259_icw4[4];
|
||||
uint8 i8259_ocw1[4];
|
||||
uint8 i8259_ocw2[4];
|
||||
uint8 i8259_ocw3[4];
|
||||
uint8 icw_num0 = 1, icw_num1 = 1;
|
||||
|
||||
/* i8259 Standard I/O Data Structures */
|
||||
/* up to 4 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 0 */
|
||||
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
|
||||
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
|
||||
{ HRDATA (IRR2, i8259_unit[2].u3, 8) }, /* i8259 2 */
|
||||
{ HRDATA (ISR2, i8259_unit[2].u4, 8) },
|
||||
{ HRDATA (IMR2, i8259_unit[2].u5, 8) },
|
||||
{ HRDATA (IRR3, i8259_unit[3].u3, 8) }, /* i8259 3 */
|
||||
{ HRDATA (ISR3, i8259_unit[3].u4, 8) },
|
||||
{ HRDATA (IMR3, i8259_unit[3].u5, 8) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEBTAB i8259_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 i8259_dev = {
|
||||
"8259", //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
|
||||
};
|
||||
|
||||
void i8259_dump(uint8 devnum)
|
||||
{
|
||||
sim_printf("Device %d\n", devnum);
|
||||
sim_printf(" IRR = %02X\n", i8259_unit[devnum].u3);
|
||||
sim_printf(" ISR = %02X\n", i8259_unit[devnum].u4);
|
||||
sim_printf(" IMR = %02X\n", i8259_unit[devnum].u5);
|
||||
sim_printf(" ICW1 = %02X\n", i8259_icw1[devnum]);
|
||||
sim_printf(" ICW2 = %02X\n", i8259_icw2[devnum]);
|
||||
sim_printf(" ICW3 = %02X\n", i8259_icw3[devnum]);
|
||||
sim_printf(" ICW4 = %02X\n", i8259_icw4[devnum]);
|
||||
sim_printf(" OCW1 = %02X\n", i8259_ocw1[devnum]);
|
||||
sim_printf(" OCW2 = %02X\n", i8259_ocw2[devnum]);
|
||||
sim_printf(" OCW3 = %02X\n", i8259_ocw3[devnum]);
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8259_reset (DEVICE *dptr, uint16 base)
|
||||
{
|
||||
if (i8259_devnum > I8259_NUM) {
|
||||
sim_printf("i8259_reset: too many devices!\n");
|
||||
return SCPE_MEM;
|
||||
}
|
||||
i8259_port[i8259_devnum] = reg_dev(i8259a, base);
|
||||
reg_dev(i8259b, base + 1);
|
||||
i8259_unit[i8259_devnum].u3 = 0x00; /* IRR */
|
||||
i8259_unit[i8259_devnum].u4 = 0x00; /* ISR */
|
||||
i8259_unit[i8259_devnum].u5 = 0x00; /* IMR */
|
||||
sim_printf(" 8259-%d: Reset\n", i8259_devnum);
|
||||
sim_printf(" 8259-%d: Registered at %03X\n", i8259_devnum, base);
|
||||
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] + 2)
|
||||
return i;
|
||||
sim_printf("i8259_get_dn: port %03X not in 8259 device table\n", port);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* I/O instruction handlers, called from the CPU module when an
|
||||
IN or OUT instruction is issued.
|
||||
*/
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
sim_printf("8259a-%d: 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;
|
||||
}
|
||||
}
|
||||
sim_printf("8259b-%d: data = %02X\n", devnum, data);
|
||||
icw_num1++; /* step ICW number */
|
||||
}
|
||||
}
|
||||
//i8259_dump(devnum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 Computer Systems.
|
||||
|
||||
This program simulates up to 4 i8259 devices.
|
||||
|
||||
u3 = IRR
|
||||
u4 = ISR
|
||||
u5 = IMR
|
||||
*/
|
||||
|
||||
#include "system_defs.h" /* system header in system dir */
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
void i8259_dump(uint8 devnum);
|
||||
t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
uint8 i8259_get_dn(void);
|
||||
uint8 i8259a(t_bool io, uint8 data);
|
||||
uint8 i8259b(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8259_devnum = 0; //initially, no 8259 instances
|
||||
uint16 i8259_port[4]; //base port assigned to each 8259 instance
|
||||
uint8 i8259_ints[4]; //8 interrupt inputs for each 8259 instance
|
||||
|
||||
uint8 i8259_icw1[4];
|
||||
uint8 i8259_icw2[4];
|
||||
uint8 i8259_icw3[4];
|
||||
uint8 i8259_icw4[4];
|
||||
uint8 i8259_ocw1[4];
|
||||
uint8 i8259_ocw2[4];
|
||||
uint8 i8259_ocw3[4];
|
||||
uint8 icw_num0 = 1, icw_num1 = 1;
|
||||
|
||||
/* i8259 Standard I/O Data Structures */
|
||||
/* up to 4 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 0 */
|
||||
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
|
||||
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
|
||||
{ HRDATA (IRR2, i8259_unit[2].u3, 8) }, /* i8259 2 */
|
||||
{ HRDATA (ISR2, i8259_unit[2].u4, 8) },
|
||||
{ HRDATA (IMR2, i8259_unit[2].u5, 8) },
|
||||
{ HRDATA (IRR3, i8259_unit[3].u3, 8) }, /* i8259 3 */
|
||||
{ HRDATA (ISR3, i8259_unit[3].u4, 8) },
|
||||
{ HRDATA (IMR3, i8259_unit[3].u5, 8) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEBTAB i8259_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 i8259_dev = {
|
||||
"8259", //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
|
||||
};
|
||||
|
||||
void i8259_dump(uint8 devnum)
|
||||
{
|
||||
sim_printf("Device %d\n", devnum);
|
||||
sim_printf(" IRR = %02X\n", i8259_unit[devnum].u3);
|
||||
sim_printf(" ISR = %02X\n", i8259_unit[devnum].u4);
|
||||
sim_printf(" IMR = %02X\n", i8259_unit[devnum].u5);
|
||||
sim_printf(" ICW1 = %02X\n", i8259_icw1[devnum]);
|
||||
sim_printf(" ICW2 = %02X\n", i8259_icw2[devnum]);
|
||||
sim_printf(" ICW3 = %02X\n", i8259_icw3[devnum]);
|
||||
sim_printf(" ICW4 = %02X\n", i8259_icw4[devnum]);
|
||||
sim_printf(" OCW1 = %02X\n", i8259_ocw1[devnum]);
|
||||
sim_printf(" OCW2 = %02X\n", i8259_ocw2[devnum]);
|
||||
sim_printf(" OCW3 = %02X\n", i8259_ocw3[devnum]);
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8259_reset (DEVICE *dptr, uint16 base)
|
||||
{
|
||||
if (i8259_devnum > I8259_NUM) {
|
||||
sim_printf("i8259_reset: too many devices!\n");
|
||||
return SCPE_MEM;
|
||||
}
|
||||
i8259_port[i8259_devnum] = reg_dev(i8259a, base);
|
||||
reg_dev(i8259b, base + 1);
|
||||
i8259_unit[i8259_devnum].u3 = 0x00; /* IRR */
|
||||
i8259_unit[i8259_devnum].u4 = 0x00; /* ISR */
|
||||
i8259_unit[i8259_devnum].u5 = 0x00; /* IMR */
|
||||
sim_printf(" 8259-%d: Reset\n", i8259_devnum);
|
||||
sim_printf(" 8259-%d: Registered at %03X\n", i8259_devnum, base);
|
||||
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] + 2)
|
||||
return i;
|
||||
sim_printf("i8259_get_dn: port %03X not in 8259 device table\n", port);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* I/O instruction handlers, called from the CPU module when an
|
||||
IN or OUT instruction is issued.
|
||||
*/
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
sim_printf("8259a-%d: 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;
|
||||
}
|
||||
}
|
||||
sim_printf("8259b-%d: data = %02X\n", devnum, data);
|
||||
icw_num1++; /* step ICW number */
|
||||
}
|
||||
}
|
||||
//i8259_dump(devnum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8259.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 = {
|
||||
"8273", //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 = {
|
||||
"8273", //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 = {
|
||||
"8274", //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 = {
|
||||
"8274", //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,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,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,465 +1,466 @@
|
|||
/* pcbus.c: PC bus 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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of PC XT
|
||||
Computer Systems.
|
||||
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 mbirq = 0; /* set no interrupts */
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat xtbus_svc(UNIT *uptr);
|
||||
t_stat xtbus_reset(DEVICE *dptr);
|
||||
void set_irq(int32 int_num);
|
||||
void clr_irq(int32 int_num);
|
||||
uint8 nulldev(t_bool io, uint8 data);
|
||||
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port);
|
||||
void dump_dev_table(void);
|
||||
t_stat xtbus_reset (DEVICE *dptr);
|
||||
uint8 xtbus_get_mbyte(uint32 addr);
|
||||
void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat SBC_reset(DEVICE *dptr); /* reset the PC XT simulator */
|
||||
extern void set_cpuint(int32 int_num);
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern int32 int_req; /* i8088 INT signal */
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* Standard SIMH Device Data Structures */
|
||||
|
||||
UNIT xtbus_unit = {
|
||||
UDATA (&xtbus_svc, 0, 0), 20
|
||||
};
|
||||
|
||||
REG xtbus_reg[] = {
|
||||
{ HRDATA (MBIRQ, mbirq, 32) },
|
||||
};
|
||||
|
||||
DEBTAB xtbus_debug[] = {
|
||||
{ "ALL", DEBUG_all },
|
||||
{ "FLOW", DEBUG_flow },
|
||||
{ "READ", DEBUG_read },
|
||||
{ "WRITE", DEBUG_write },
|
||||
{ "LEV1", DEBUG_level1 },
|
||||
{ "LEV2", DEBUG_level2 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE xtbus_dev = {
|
||||
"PCBUS", //name
|
||||
&xtbus_unit, //units
|
||||
xtbus_reg, //registers
|
||||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
NULL, //examine
|
||||
NULL, //deposit
|
||||
&xtbus_reset, //reset
|
||||
NULL, //boot
|
||||
NULL, //attach
|
||||
NULL, //detach
|
||||
NULL, //ctxt
|
||||
DEV_DEBUG, //flags
|
||||
0, //dctrl
|
||||
xtbus_debug, //debflags
|
||||
NULL, //msize
|
||||
NULL //lname
|
||||
};
|
||||
|
||||
/* Service routines to handle simulator functions */
|
||||
|
||||
/* service routine - actually does the simulated interrupts */
|
||||
|
||||
t_stat xtbus_svc(UNIT *uptr)
|
||||
{
|
||||
switch (mbirq) {
|
||||
case INT_1:
|
||||
set_cpuint(INT_R);
|
||||
sim_printf("xtbus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
|
||||
break;
|
||||
default:
|
||||
//sim_printf("xtbus_svc: default mbirq=%04X\n", mbirq);
|
||||
break;
|
||||
}
|
||||
sim_activate (&xtbus_unit, xtbus_unit.wait); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat xtbus_reset(DEVICE *dptr)
|
||||
{
|
||||
SBC_reset(NULL);
|
||||
sim_printf(" Xtbus: Reset\n");
|
||||
sim_activate (&xtbus_unit, xtbus_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 1024 possible
|
||||
device addresses, if a device is plugged to a port it's routine
|
||||
address is here, 'nulldev' means no device has been registered.
|
||||
The actual 808X can address 65,536 I/O ports but the IBM only uses
|
||||
the first 1024. */
|
||||
|
||||
struct idev {
|
||||
uint8 (*routine)(t_bool io, uint8 data);
|
||||
};
|
||||
|
||||
struct idev dev_table[1024] = {
|
||||
{&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 */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 100H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 104H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 108H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 10CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 110H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 114H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 118H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 11CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 120H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 124H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 128H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 12CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 130H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 134H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 138H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 13CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 140H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 144H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 148H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 14CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 150H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 154H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 158H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 15CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 160H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 164H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 168H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 16CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 170H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 174H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 178H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 17CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 180H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 184H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 188H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 18CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 190H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 194H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 198H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 19CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 200H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 204H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 208H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 210H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 214H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 218H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 21CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 220H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 224H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 228H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 22CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 230H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 234H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 238H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 23CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 240H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 244H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 248H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 250H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 254H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 258H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 25CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 260H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 264H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 268H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 26CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 270H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 274H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 278H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 27CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 280H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 284H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 288H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 28CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 290H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 294H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 298H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 29CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 300H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 304H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 308H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 30CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 310H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 314H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 318H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 31CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 320H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 324H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 328H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 32CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 330H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 334H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 338H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 33CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 340H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 344H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 348H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 350H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 354H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 358H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 35CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 360H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 364H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 368H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 36CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 370H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 374H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 378H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 37CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 380H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 384H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 388H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 390H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 394H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 398H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 39CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 3FCH */
|
||||
};
|
||||
|
||||
uint8 nulldev(t_bool flag, uint8 data)
|
||||
{
|
||||
sim_printf("xtbus: I/O Port %03X is not assigned io=%d data=%02X\n",
|
||||
port, flag, data);
|
||||
if (flag == 0) /* if we got here, no valid I/O device */
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port)
|
||||
{
|
||||
if (dev_table[port].routine != &nulldev) { /* port already assigned */
|
||||
sim_printf("xtbus: I/O Port %03X is already assigned\n", port);
|
||||
} else {
|
||||
sim_printf("Port %03X is assigned\n", port);
|
||||
dev_table[port].routine = routine;
|
||||
}
|
||||
//dump_dev_table();
|
||||
return port;
|
||||
}
|
||||
|
||||
void dump_dev_table(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<1024; i++) {
|
||||
if (dev_table[i].routine != &nulldev) { /* assigned port */
|
||||
sim_printf("Port %03X is assigned\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from bus */
|
||||
|
||||
uint8 xtbus_get_mbyte(uint32 addr)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* put a byte to bus */
|
||||
|
||||
void xtbus_put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* end of pcbus.c */
|
||||
|
||||
/* pcbus.c: PC bus 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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of PC XT
|
||||
Computer Systems.
|
||||
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 mbirq = 0; /* set no interrupts */
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat xtbus_svc(UNIT *uptr);
|
||||
t_stat xtbus_reset(DEVICE *dptr);
|
||||
void set_irq(int32 int_num);
|
||||
void clr_irq(int32 int_num);
|
||||
uint8 nulldev(t_bool io, uint8 data);
|
||||
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port);
|
||||
void dump_dev_table(void);
|
||||
t_stat xtbus_reset (DEVICE *dptr);
|
||||
uint8 xtbus_get_mbyte(uint32 addr);
|
||||
void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
extern uint8 RAM_get_mbyte(uint32 addr);
|
||||
extern void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
extern t_stat SBC_reset(DEVICE *dptr); /* reset the PC XT simulator */
|
||||
extern void set_cpuint(int32 int_num);
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern int32 int_req; /* i8088 INT signal */
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* Standard SIMH Device Data Structures */
|
||||
|
||||
UNIT xtbus_unit = {
|
||||
UDATA (&xtbus_svc, 0, 0), 20
|
||||
};
|
||||
|
||||
REG xtbus_reg[] = {
|
||||
{ HRDATA (MBIRQ, mbirq, 32) },
|
||||
};
|
||||
|
||||
DEBTAB xtbus_debug[] = {
|
||||
{ "ALL", DEBUG_all },
|
||||
{ "FLOW", DEBUG_flow },
|
||||
{ "READ", DEBUG_read },
|
||||
{ "WRITE", DEBUG_write },
|
||||
{ "LEV1", DEBUG_level1 },
|
||||
{ "LEV2", DEBUG_level2 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE xtbus_dev = {
|
||||
"PCBUS", //name
|
||||
&xtbus_unit, //units
|
||||
xtbus_reg, //registers
|
||||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
NULL, //examine
|
||||
NULL, //deposit
|
||||
&xtbus_reset, //reset
|
||||
NULL, //boot
|
||||
NULL, //attach
|
||||
NULL, //detach
|
||||
NULL, //ctxt
|
||||
DEV_DEBUG, //flags
|
||||
0, //dctrl
|
||||
xtbus_debug, //debflags
|
||||
NULL, //msize
|
||||
NULL //lname
|
||||
};
|
||||
|
||||
/* Service routines to handle simulator functions */
|
||||
|
||||
/* service routine - actually does the simulated interrupts */
|
||||
|
||||
t_stat xtbus_svc(UNIT *uptr)
|
||||
{
|
||||
switch (mbirq) {
|
||||
case INT_1:
|
||||
set_cpuint(INT_R);
|
||||
sim_printf("xtbus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
|
||||
break;
|
||||
default:
|
||||
//sim_printf("xtbus_svc: default mbirq=%04X\n", mbirq);
|
||||
break;
|
||||
}
|
||||
sim_activate (&xtbus_unit, xtbus_unit.wait); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat xtbus_reset(DEVICE *dptr)
|
||||
{
|
||||
SBC_reset(NULL);
|
||||
sim_printf(" Xtbus: Reset\n");
|
||||
sim_activate (&xtbus_unit, xtbus_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 1024 possible
|
||||
device addresses, if a device is plugged to a port it's routine
|
||||
address is here, 'nulldev' means no device has been registered.
|
||||
The actual 808X can address 65,536 I/O ports but the IBM only uses
|
||||
the first 1024. */
|
||||
|
||||
struct idev {
|
||||
uint8 (*routine)(t_bool io, uint8 data);
|
||||
};
|
||||
|
||||
struct idev dev_table[1024] = {
|
||||
{&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 */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 100H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 104H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 108H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 10CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 110H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 114H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 118H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 11CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 120H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 124H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 128H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 12CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 130H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 134H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 138H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 13CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 140H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 144H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 148H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 14CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 150H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 154H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 158H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 15CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 160H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 164H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 168H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 16CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 170H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 174H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 178H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 17CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 180H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 184H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 188H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 18CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 190H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 194H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 198H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 19CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 1FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 200H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 204H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 208H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 20CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 210H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 214H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 218H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 21CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 220H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 224H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 228H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 22CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 230H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 234H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 238H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 23CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 240H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 244H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 248H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 24CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 250H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 254H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 258H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 25CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 260H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 264H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 268H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 26CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 270H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 274H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 278H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 27CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 280H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 284H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 288H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 28CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 290H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 294H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 298H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 29CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 2FCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 300H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 304H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 308H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 30CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 310H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 314H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 318H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 31CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 320H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 324H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 328H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 32CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 330H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 334H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 338H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 33CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 340H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 344H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 348H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 34CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 350H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 354H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 358H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 35CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 360H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 364H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 368H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 36CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 370H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 374H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 378H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 37CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 380H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 384H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 388H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 38CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 390H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 394H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 398H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 39CH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3A0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3B0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3C8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3CCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3D8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3DCH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3E8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3ECH */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F0H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F4H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 3F8H */
|
||||
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 3FCH */
|
||||
};
|
||||
|
||||
uint8 nulldev(t_bool flag, uint8 data)
|
||||
{
|
||||
sim_printf("xtbus: I/O Port %03X is not assigned io=%d data=%02X\n",
|
||||
port, flag, data);
|
||||
if (flag == 0) /* if we got here, no valid I/O device */
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port)
|
||||
{
|
||||
if (dev_table[port].routine != &nulldev) { /* port already assigned */
|
||||
sim_printf("xtbus: I/O Port %03X is already assigned\n", port);
|
||||
} else {
|
||||
sim_printf("Port %03X is assigned\n", port);
|
||||
dev_table[port].routine = routine;
|
||||
}
|
||||
//dump_dev_table();
|
||||
return port;
|
||||
}
|
||||
|
||||
void dump_dev_table(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<1024; i++) {
|
||||
if (dev_table[i].routine != &nulldev) { /* assigned port */
|
||||
sim_printf("Port %03X is assigned\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from bus */
|
||||
|
||||
uint8 xtbus_get_mbyte(uint32 addr)
|
||||
{
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
|
||||
/* put a byte to bus */
|
||||
|
||||
void xtbus_put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
RAM_put_mbyte(addr, val);
|
||||
}
|
||||
|
||||
/* end of pcbus.c */
|
||||
|
||||
|
|
|
@ -1,177 +1,177 @@
|
|||
/* pceprom.c: Intel EPROM simulator for 8-bit SBCs
|
||||
|
||||
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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
These functions support a simulated ROM devices on aPC XT SBC.
|
||||
This allows the attachment of the device to a binary file containing the EPROM
|
||||
code image. Unit will support a single 2764, 27128, 27256, or 27512 type EPROM.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
uint8 EPROM_get_mbyte(uint32 addr);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
/* 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 },
|
||||
{ "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=%05X unit_capac=%05X\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, uint32 base, uint32 size)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=%05X size=%05X\n", base, size);
|
||||
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
|
||||
EPROM_unit.capac = size; /* set EPROM size */
|
||||
EPROM_unit.u3 = base; /* set EPROM base addr */
|
||||
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
|
||||
sim_printf(" EPROM: Available [%05X-%05XH]\n",
|
||||
base, size);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
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(uint32 addr)
|
||||
{
|
||||
uint8 val;
|
||||
uint32 romoff;
|
||||
|
||||
romoff = addr - EPROM_unit.u3;
|
||||
sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%05X romoff=%05X\n", addr, romoff);
|
||||
if (romoff < EPROM_unit.capac) {
|
||||
val = *((uint8 *)EPROM_unit.filebuf + romoff);
|
||||
sim_debug (DEBUG_read, &EPROM_dev, " val=%02X\n", val);
|
||||
return (val & 0xFF);
|
||||
}
|
||||
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* end of pceprom.c */
|
||||
/* pceprom.c: Intel EPROM simulator for 8-bit SBCs
|
||||
|
||||
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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
These functions support a simulated ROM devices on aPC XT SBC.
|
||||
This allows the attachment of the device to a binary file containing the EPROM
|
||||
code image. Unit will support a single 2764, 27128, 27256, or 27512 type EPROM.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
uint8 EPROM_get_mbyte(uint32 addr);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
/* 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 },
|
||||
{ "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=%05X unit_capac=%05X\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, uint32 base, uint32 size)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=%05X size=%05X\n", base, size);
|
||||
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
|
||||
EPROM_unit.capac = size; /* set EPROM size */
|
||||
EPROM_unit.u3 = base; /* set EPROM base addr */
|
||||
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
|
||||
sim_printf(" EPROM: Available [%05X-%05XH]\n",
|
||||
base, size);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
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(uint32 addr)
|
||||
{
|
||||
uint8 val;
|
||||
uint32 romoff;
|
||||
|
||||
romoff = addr - EPROM_unit.u3;
|
||||
sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%05X romoff=%05X\n", addr, romoff);
|
||||
if (romoff < EPROM_unit.capac) {
|
||||
val = *((uint8 *)EPROM_unit.filebuf + romoff);
|
||||
sim_debug (DEBUG_read, &EPROM_dev, " val=%02X\n", val);
|
||||
return (val & 0xFF);
|
||||
}
|
||||
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* end of pceprom.c */
|
||||
|
|
|
@ -1,152 +1,145 @@
|
|||
/* pcram8.c: Intel RAM simulator for 8-bit SBCs
|
||||
|
||||
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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
These functions support a simulated RAM devices on a PC XT SBC.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat RAM_svc (UNIT *uptr);
|
||||
t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
uint8 RAM_get_mbyte(uint32 addr);
|
||||
void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern UNIT i8255_unit[];
|
||||
|
||||
/* 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 },
|
||||
{ "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, uint32 base, uint32 size)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%05X size=%05X\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 [%05X-%05XH]\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(uint32 addr)
|
||||
{
|
||||
uint8 val;
|
||||
|
||||
if (i8255_unit[0].u5 & 0x02) { /* enable RAM */
|
||||
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
|
||||
if ((addr >= RAM_unit.u3) && ((uint32) addr < (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3));
|
||||
sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val);
|
||||
return (val & 0xFF);
|
||||
}
|
||||
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
|
||||
return 0xFF;
|
||||
}
|
||||
sim_debug (DEBUG_read, &RAM_dev, " RAM disabled\n");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* put a byte to memory */
|
||||
|
||||
void RAM_put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
if (i8255_unit[0].u5 & 0x02) { /* enable RAM */
|
||||
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
|
||||
if ((addr >= RAM_unit.u3) && ((uint32)addr < RAM_unit.u3 + RAM_unit.capac)) {
|
||||
*((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
|
||||
sim_debug (DEBUG_write, &RAM_dev, "\n");
|
||||
return;
|
||||
}
|
||||
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
|
||||
return;
|
||||
}
|
||||
sim_debug (DEBUG_write, &RAM_dev, " RAM disabled\n");
|
||||
}
|
||||
|
||||
/* end of pcram8.c */
|
||||
/* pcram8.c: Intel RAM simulator for 8-bit SBCs
|
||||
|
||||
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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
These functions support a simulated RAM devices on a PC XT SBC.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
t_stat RAM_svc (UNIT *uptr);
|
||||
t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
uint8 RAM_get_mbyte(uint32 addr);
|
||||
void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern UNIT i8255_unit[];
|
||||
|
||||
/* 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 },
|
||||
{ "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, uint32 base, uint32 size)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%05X size=%05X\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 [%05X-%05XH]\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(uint32 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))) {
|
||||
val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3));
|
||||
sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val);
|
||||
return (val & 0xFF);
|
||||
}
|
||||
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* put a byte to memory */
|
||||
|
||||
void RAM_put_mbyte(uint32 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)) {
|
||||
*((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
|
||||
sim_debug (DEBUG_write, &RAM_dev, "\n");
|
||||
return;
|
||||
}
|
||||
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* end of pcram8.c */
|
||||
|
|
|
@ -1,203 +1,203 @@
|
|||
/* ibmpcxt.c: IBM PC Processor 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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of IBM PC
|
||||
Computer Systems.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 nmiflg = 0; //mask NMI off
|
||||
uint8 dmapagreg0, dmapagreg1, dmapagreg2, dmapagreg3;
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
uint8 get_mbyte(uint32 addr);
|
||||
uint16 get_mword(uint32 addr);
|
||||
void put_mbyte(uint32 addr, uint8 val);
|
||||
void put_mword(uint32 addr, uint16 val);
|
||||
t_stat SBC_reset (DEVICE *dptr, uint16 base);
|
||||
uint8 enbnmi(t_bool io, uint8 data);
|
||||
uint8 dmapag(t_bool io, uint8 data);
|
||||
uint8 dmapag0(t_bool io, uint8 data);
|
||||
uint8 dmapag1(t_bool io, uint8 data);
|
||||
uint8 dmapag2(t_bool io, uint8 data);
|
||||
uint8 dmapag3(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat i8088_reset (DEVICE *dptr); /* reset the 8088 emulator */
|
||||
extern uint8 xtbus_get_mbyte(uint32 addr);
|
||||
extern void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
extern uint8 EPROM_get_mbyte(uint32 addr);
|
||||
extern uint8 RAM_get_mbyte(uint32 addr);
|
||||
extern void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
extern UNIT i8255_unit[];
|
||||
extern UNIT EPROM_unit;
|
||||
extern UNIT RAM_unit;
|
||||
extern t_stat i8237_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* SBC reset routine */
|
||||
|
||||
t_stat SBC_reset (DEVICE *dptr, uint16 base)
|
||||
{
|
||||
sim_printf("Initializing IBM PC:\n");
|
||||
i8088_reset (NULL);
|
||||
i8237_reset (NULL, I8237_BASE_0);
|
||||
i8253_reset (NULL, I8253_BASE_0);
|
||||
i8255_reset (NULL, I8255_BASE_0);
|
||||
i8259_reset (NULL, I8259_BASE_0);
|
||||
EPROM_reset (NULL, ROM_BASE, ROM_SIZE);
|
||||
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
|
||||
reg_dev(enbnmi, NMI_BASE);
|
||||
reg_dev(dmapag0, DMAPAG_BASE_0);
|
||||
reg_dev(dmapag1, DMAPAG_BASE_1);
|
||||
reg_dev(dmapag2, DMAPAG_BASE_2);
|
||||
reg_dev(dmapag3, DMAPAG_BASE_3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint8 dmapag0(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg0 = data;
|
||||
//sim_printf("dmapag0: dmapagreg0=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag1(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg1 = data;
|
||||
//sim_printf("dmapag1: dmapagreg1=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag2(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg2 = data;
|
||||
//sim_printf("dmapag2: dmapagreg2=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag3(t_bool io, uint8 data)
|
||||
{
|
||||
//sim_printf("dmapag3: entered\n");
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg3 = data;
|
||||
//sim_printf("dmapag3: dmapagreg3=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 enbnmi(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
if (data & 0x80) {
|
||||
nmiflg = 1;
|
||||
//sim_printf("enbnmi: NMI enabled\n");
|
||||
} else {
|
||||
nmiflg = 0;
|
||||
//sim_printf("enbnmi: NMI disabled\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from memory - handle RAM, ROM, I/O, and pcbus memory */
|
||||
|
||||
uint8 get_mbyte(uint32 addr)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
|
||||
sim_printf("Write to R/O memory address %05X - ignored\n", addr);
|
||||
return EPROM_get_mbyte(addr);
|
||||
}
|
||||
/* if local RAM handle it */
|
||||
if ((addr >= RAM_unit.u3) && ((uint32)addr < (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
/* otherwise, try the pcbus */
|
||||
return xtbus_get_mbyte(addr);
|
||||
}
|
||||
|
||||
/* get a word from memory - handle RAM, ROM, I/O, and pcbus memory */
|
||||
|
||||
uint16 get_mword(uint32 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 pcbus memory */
|
||||
|
||||
void put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)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 ((i8255_unit[0].u5 & 0x02) && (addr >= RAM_unit.u3) && ((uint32)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
RAM_put_mbyte(addr, val);
|
||||
return;
|
||||
} /* otherwise, try the pcbus */
|
||||
xtbus_put_mbyte(addr, val);
|
||||
}
|
||||
|
||||
/* put a word to memory - handle RAM, ROM, I/O, and pcbus memory */
|
||||
|
||||
void put_mword(uint32 addr, uint16 val)
|
||||
{
|
||||
put_mbyte(addr, val & 0xff);
|
||||
put_mbyte(addr+1, val >> 8);
|
||||
}
|
||||
|
||||
/* end of ibmpc.c */
|
||||
/* ibmpcxt.c: IBM PC Processor 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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of IBM PC
|
||||
Computer Systems.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 nmiflg = 0; //mask NMI off
|
||||
uint8 dmapagreg0, dmapagreg1, dmapagreg2, dmapagreg3;
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
uint8 get_mbyte(uint32 addr);
|
||||
uint16 get_mword(uint32 addr);
|
||||
void put_mbyte(uint32 addr, uint8 val);
|
||||
void put_mword(uint32 addr, uint16 val);
|
||||
t_stat SBC_reset (DEVICE *dptr, uint16 base);
|
||||
uint8 enbnmi(t_bool io, uint8 data);
|
||||
uint8 dmapag(t_bool io, uint8 data);
|
||||
uint8 dmapag0(t_bool io, uint8 data);
|
||||
uint8 dmapag1(t_bool io, uint8 data);
|
||||
uint8 dmapag2(t_bool io, uint8 data);
|
||||
uint8 dmapag3(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat i8088_reset (DEVICE *dptr); /* reset the 8088 emulator */
|
||||
extern uint8 xtbus_get_mbyte(uint32 addr);
|
||||
extern void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
extern uint8 EPROM_get_mbyte(uint32 addr);
|
||||
extern uint8 RAM_get_mbyte(uint32 addr);
|
||||
extern void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
extern UNIT i8255_unit[];
|
||||
extern UNIT EPROM_unit;
|
||||
extern UNIT RAM_unit;
|
||||
extern t_stat i8237_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* SBC reset routine */
|
||||
|
||||
t_stat SBC_reset (DEVICE *dptr, uint16 base)
|
||||
{
|
||||
sim_printf("Initializing IBM PC:\n");
|
||||
i8088_reset (NULL);
|
||||
i8237_reset (NULL, I8237_BASE_0);
|
||||
i8253_reset (NULL, I8253_BASE_0);
|
||||
i8255_reset (NULL, I8255_BASE_0);
|
||||
i8259_reset (NULL, I8259_BASE_0);
|
||||
EPROM_reset (NULL, ROM_BASE, ROM_SIZE);
|
||||
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
|
||||
reg_dev(enbnmi, NMI_BASE);
|
||||
reg_dev(dmapag0, DMAPAG_BASE_0);
|
||||
reg_dev(dmapag1, DMAPAG_BASE_1);
|
||||
reg_dev(dmapag2, DMAPAG_BASE_2);
|
||||
reg_dev(dmapag3, DMAPAG_BASE_3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint8 dmapag0(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg0 = data;
|
||||
//sim_printf("dmapag0: dmapagreg0=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag1(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg1 = data;
|
||||
//sim_printf("dmapag1: dmapagreg1=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag2(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg2 = data;
|
||||
//sim_printf("dmapag2: dmapagreg2=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag3(t_bool io, uint8 data)
|
||||
{
|
||||
//sim_printf("dmapag3: entered\n");
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg3 = data;
|
||||
//sim_printf("dmapag3: dmapagreg3=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 enbnmi(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
if (data & 0x80) {
|
||||
nmiflg = 1;
|
||||
//sim_printf("enbnmi: NMI enabled\n");
|
||||
} else {
|
||||
nmiflg = 0;
|
||||
//sim_printf("enbnmi: NMI disabled\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from memory - handle RAM, ROM, I/O, and pcbus memory */
|
||||
|
||||
uint8 get_mbyte(uint32 addr)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
|
||||
// sim_printf("Write to R/O memory address %05X - ignored\n", addr);
|
||||
return EPROM_get_mbyte(addr);
|
||||
}
|
||||
/* if local RAM handle it */
|
||||
if ((addr >= RAM_unit.u3) && ((uint32)addr < (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
/* otherwise, try the pcbus */
|
||||
return xtbus_get_mbyte(addr);
|
||||
}
|
||||
|
||||
/* get a word from memory - handle RAM, ROM, I/O, and pcbus memory */
|
||||
|
||||
uint16 get_mword(uint32 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 pcbus memory */
|
||||
|
||||
void put_mbyte(uint32 addr, uint8 val)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)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 ((addr >= RAM_unit.u3) && ((uint32)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
RAM_put_mbyte(addr, val);
|
||||
return;
|
||||
} /* otherwise, try the pcbus */
|
||||
xtbus_put_mbyte(addr, val);
|
||||
}
|
||||
|
||||
/* put a word to memory - handle RAM, ROM, I/O, and pcbus memory */
|
||||
|
||||
void put_mword(uint32 addr, uint16 val)
|
||||
{
|
||||
put_mbyte(addr, val & 0xff);
|
||||
put_mbyte(addr+1, val >> 8);
|
||||
}
|
||||
|
||||
/* end of ibmpc.c */
|
||||
|
|
|
@ -1,111 +1,111 @@
|
|||
/* system_defs.h: IBM PC 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.
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* set the base I/O address and device count for the 8237 */
|
||||
#define I8237_BASE_0 0x000
|
||||
#define I8237_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8253 */
|
||||
#define I8253_BASE_0 0x040
|
||||
#define I8253_BASE_1 0x100
|
||||
#define I8253_NUM 2
|
||||
|
||||
/* set the base I/O address and device count for the 8255 */
|
||||
#define I8255_BASE_0 0x060
|
||||
#define I8255_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8259 */
|
||||
#define I8259_BASE_0 0x020
|
||||
#define I8259_NUM 1
|
||||
|
||||
/* set the base I/O address for the NMI mask */
|
||||
#define NMI_BASE 0x0A0
|
||||
|
||||
/* set the base I/O address and device count for the DMA page registers */
|
||||
#define DMAPAG_BASE_0 0x080
|
||||
#define DMAPAG_BASE_1 0x081
|
||||
#define DMAPAG_BASE_2 0x082
|
||||
#define DMAPAG_BASE_3 0x083
|
||||
#define DMAPAG_NUM 4
|
||||
|
||||
/* set the base and size for the EPROM on the IBM PC */
|
||||
#define ROM_BASE 0xFE000
|
||||
#define ROM_SIZE 0x02000
|
||||
|
||||
/* set the base and size for the RAM on the IBM PC */
|
||||
#define RAM_BASE 0x00000
|
||||
#define RAM_SIZE 0x40000
|
||||
|
||||
/* set INTR for CPU on the 8088 */
|
||||
#define INT_R INT_1
|
||||
|
||||
/* xtbus 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
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define ADDRMASK16 0xFFFF
|
||||
#define ADDRMASK20 0xFFFFF
|
||||
#define MAXMEMSIZE20 0xFFFFF /* 8080 max memory size */
|
||||
|
||||
#define MEMSIZE (i8088_unit.capac) /* 8088 actual memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* 8088 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_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 */
|
||||
|
||||
/* system_defs.h: IBM PC 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.
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* set the base I/O address and device count for the 8237 */
|
||||
#define I8237_BASE_0 0x000
|
||||
#define I8237_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8253 */
|
||||
#define I8253_BASE_0 0x040
|
||||
#define I8253_BASE_1 0x100
|
||||
#define I8253_NUM 2
|
||||
|
||||
/* set the base I/O address and device count for the 8255 */
|
||||
#define I8255_BASE_0 0x060
|
||||
#define I8255_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8259 */
|
||||
#define I8259_BASE_0 0x020
|
||||
#define I8259_NUM 1
|
||||
|
||||
/* set the base I/O address for the NMI mask */
|
||||
#define NMI_BASE 0x0A0
|
||||
|
||||
/* set the base I/O address and device count for the DMA page registers */
|
||||
#define DMAPAG_BASE_0 0x080
|
||||
#define DMAPAG_BASE_1 0x081
|
||||
#define DMAPAG_BASE_2 0x082
|
||||
#define DMAPAG_BASE_3 0x083
|
||||
#define DMAPAG_NUM 4
|
||||
|
||||
/* set the base and size for the EPROM on the IBM PC */
|
||||
#define ROM_BASE 0xFE000
|
||||
#define ROM_SIZE 0x02000
|
||||
|
||||
/* set the base and size for the RAM on the IBM PC */
|
||||
#define RAM_BASE 0x00000
|
||||
#define RAM_SIZE 0x40000
|
||||
|
||||
/* set INTR for CPU on the 8088 */
|
||||
#define INT_R INT_1
|
||||
|
||||
/* xtbus 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
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define ADDRMASK16 0xFFFF
|
||||
#define ADDRMASK20 0xFFFFF
|
||||
#define MAXMEMSIZE20 0xFFFFF /* 8080 max memory size */
|
||||
|
||||
#define MEMSIZE (i8088_unit.capac) /* 8088 actual memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* 8088 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_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 */
|
||||
|
||||
|
|
|
@ -1,202 +1,202 @@
|
|||
/* ibmpcxt.c: IBM PC Processor 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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of IBM PC
|
||||
Computer Systems.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 nmiflg = 0; //mask NMI off
|
||||
uint8 dmapagreg0, dmapagreg1, dmapagreg2, dmapagreg3;
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
uint8 get_mbyte(uint32 addr);
|
||||
uint16 get_mword(uint32 addr);
|
||||
void put_mbyte(uint32 addr, uint8 val);
|
||||
void put_mword(uint32 addr, uint16 val);
|
||||
t_stat SBC_reset (DEVICE *dptr);
|
||||
uint8 enbnmi(t_bool io, uint8 data);
|
||||
uint8 dmapag(t_bool io, uint8 data);
|
||||
uint8 dmapag0(t_bool io, uint8 data);
|
||||
uint8 dmapag1(t_bool io, uint8 data);
|
||||
uint8 dmapag2(t_bool io, uint8 data);
|
||||
uint8 dmapag3(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat i8088_reset (DEVICE *dptr); /* reset the 8088 emulator */
|
||||
extern uint8 xtbus_get_mbyte(uint32 addr);
|
||||
extern void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
extern uint8 EPROM_get_mbyte(uint32 addr);
|
||||
extern uint8 RAM_get_mbyte(uint32 addr);
|
||||
extern void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
extern UNIT i8255_unit[];
|
||||
extern UNIT EPROM_unit;
|
||||
extern UNIT RAM_unit;
|
||||
extern t_stat i8237_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* SBC reset routine */
|
||||
|
||||
t_stat SBC_reset (DEVICE *dptr)
|
||||
{
|
||||
sim_printf("Initializing IBM PC XT:\n");
|
||||
i8088_reset (NULL);
|
||||
i8237_reset (NULL, I8237_BASE_0);
|
||||
i8253_reset (NULL, I8253_BASE_0);
|
||||
i8255_reset (NULL, I8255_BASE_0);
|
||||
i8259_reset (NULL, I8259_BASE_0);
|
||||
EPROM_reset (NULL, ROM_BASE, ROM_SIZE);
|
||||
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
|
||||
reg_dev(enbnmi, NMI_BASE);
|
||||
reg_dev(dmapag0, DMAPAG_BASE_0);
|
||||
reg_dev(dmapag1, DMAPAG_BASE_1);
|
||||
reg_dev(dmapag2, DMAPAG_BASE_2);
|
||||
reg_dev(dmapag3, DMAPAG_BASE_3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint8 dmapag0(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg0 = data;
|
||||
//sim_printf("dmapag0: dmapagreg0=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag1(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg1 = data;
|
||||
//sim_printf("dmapag1: dmapagreg1=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag2(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg2 = data;
|
||||
//sim_printf("dmapag2: dmapagreg2=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag3(t_bool io, uint8 data)
|
||||
{
|
||||
//sim_printf("dmapag3: entered\n");
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg3 = data;
|
||||
//sim_printf("dmapag3: dmapagreg3=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 enbnmi(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
if (data & 0x80) {
|
||||
nmiflg = 1;
|
||||
//sim_printf("enbnmi: NMI enabled\n");
|
||||
} else {
|
||||
nmiflg = 0;
|
||||
//sim_printf("enbnmi: NMI disabled\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
|
||||
|
||||
uint8 get_mbyte(uint32 addr)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
|
||||
return EPROM_get_mbyte(addr);
|
||||
}
|
||||
/* if local RAM handle it */
|
||||
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
/* otherwise, try the multibus */
|
||||
return xtbus_get_mbyte(addr);
|
||||
}
|
||||
|
||||
/* get a word from memory */
|
||||
|
||||
uint16 get_mword(uint32 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(uint32 addr, uint8 val)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
|
||||
sim_printf("Write to R/O memory address %05X - ignored\n", addr);
|
||||
return;
|
||||
} /* if local RAM handle it */
|
||||
if ((i8255_unit[0].u5 & 0x02) && (addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
RAM_put_mbyte(addr, val);
|
||||
return;
|
||||
} /* otherwise, try the multibus */
|
||||
xtbus_put_mbyte(addr, val);
|
||||
}
|
||||
|
||||
/* put a word to memory */
|
||||
|
||||
void put_mword(uint32 addr, uint16 val)
|
||||
{
|
||||
put_mbyte(addr, val & 0xff);
|
||||
put_mbyte(addr+1, val >> 8);
|
||||
}
|
||||
|
||||
/* end of ibmpcxt.c */
|
||||
/* ibmpcxt.c: IBM PC Processor 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.
|
||||
|
||||
MODIFICATIONS:
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Jul 2016, to allow emulation of IBM PC
|
||||
Computer Systems.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
int32 nmiflg = 0; //mask NMI off
|
||||
uint8 dmapagreg0, dmapagreg1, dmapagreg2, dmapagreg3;
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
uint8 get_mbyte(uint32 addr);
|
||||
uint16 get_mword(uint32 addr);
|
||||
void put_mbyte(uint32 addr, uint8 val);
|
||||
void put_mword(uint32 addr, uint16 val);
|
||||
t_stat SBC_reset (DEVICE *dptr);
|
||||
uint8 enbnmi(t_bool io, uint8 data);
|
||||
uint8 dmapag(t_bool io, uint8 data);
|
||||
uint8 dmapag0(t_bool io, uint8 data);
|
||||
uint8 dmapag1(t_bool io, uint8 data);
|
||||
uint8 dmapag2(t_bool io, uint8 data);
|
||||
uint8 dmapag3(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat i8088_reset (DEVICE *dptr); /* reset the 8088 emulator */
|
||||
extern uint8 xtbus_get_mbyte(uint32 addr);
|
||||
extern void xtbus_put_mbyte(uint32 addr, uint8 val);
|
||||
extern uint8 EPROM_get_mbyte(uint32 addr);
|
||||
extern uint8 RAM_get_mbyte(uint32 addr);
|
||||
extern void RAM_put_mbyte(uint32 addr, uint8 val);
|
||||
extern UNIT i8255_unit[];
|
||||
extern UNIT EPROM_unit;
|
||||
extern UNIT RAM_unit;
|
||||
extern t_stat i8237_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint32 base, uint32 size);
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* SBC reset routine */
|
||||
|
||||
t_stat SBC_reset (DEVICE *dptr)
|
||||
{
|
||||
sim_printf("Initializing IBM PC XT:\n");
|
||||
i8088_reset (NULL);
|
||||
i8237_reset (NULL, I8237_BASE_0);
|
||||
i8253_reset (NULL, I8253_BASE_0);
|
||||
i8255_reset (NULL, I8255_BASE_0);
|
||||
i8259_reset (NULL, I8259_BASE_0);
|
||||
EPROM_reset (NULL, ROM_BASE, ROM_SIZE);
|
||||
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
|
||||
reg_dev(enbnmi, NMI_BASE);
|
||||
reg_dev(dmapag0, DMAPAG_BASE_0);
|
||||
reg_dev(dmapag1, DMAPAG_BASE_1);
|
||||
reg_dev(dmapag2, DMAPAG_BASE_2);
|
||||
reg_dev(dmapag3, DMAPAG_BASE_3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint8 dmapag0(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg0 = data;
|
||||
//sim_printf("dmapag0: dmapagreg0=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag1(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg1 = data;
|
||||
//sim_printf("dmapag1: dmapagreg1=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag2(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg2 = data;
|
||||
//sim_printf("dmapag2: dmapagreg2=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 dmapag3(t_bool io, uint8 data)
|
||||
{
|
||||
//sim_printf("dmapag3: entered\n");
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
dmapagreg3 = data;
|
||||
//sim_printf("dmapag3: dmapagreg3=%04X\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 enbnmi(t_bool io, uint8 data)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
;
|
||||
} else { /* write data port */
|
||||
if (data & 0x80) {
|
||||
nmiflg = 1;
|
||||
//sim_printf("enbnmi: NMI enabled\n");
|
||||
} else {
|
||||
nmiflg = 0;
|
||||
//sim_printf("enbnmi: NMI disabled\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
|
||||
|
||||
uint8 get_mbyte(uint32 addr)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
|
||||
return EPROM_get_mbyte(addr);
|
||||
}
|
||||
/* if local RAM handle it */
|
||||
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
/* otherwise, try the multibus */
|
||||
return xtbus_get_mbyte(addr);
|
||||
}
|
||||
|
||||
/* get a word from memory */
|
||||
|
||||
uint16 get_mword(uint32 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(uint32 addr, uint8 val)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((addr >= EPROM_unit.u3) && ((uint32)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
|
||||
sim_printf("Write to R/O memory address %05X - ignored\n", addr);
|
||||
return;
|
||||
} /* if local RAM handle it */
|
||||
if ((i8255_unit[0].u5 & 0x02) && (addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
RAM_put_mbyte(addr, val);
|
||||
return;
|
||||
} /* otherwise, try the multibus */
|
||||
xtbus_put_mbyte(addr, val);
|
||||
}
|
||||
|
||||
/* put a word to memory */
|
||||
|
||||
void put_mword(uint32 addr, uint16 val)
|
||||
{
|
||||
put_mbyte(addr, val & 0xff);
|
||||
put_mbyte(addr+1, val >> 8);
|
||||
}
|
||||
|
||||
/* end of ibmpcxt.c */
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
/* 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 XT";
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
/* 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 XT";
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
|
|
|
@ -1,110 +1,110 @@
|
|||
/* 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.
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* set the base I/O address and device count for the 8237 */
|
||||
#define I8237_BASE_0 0x000
|
||||
#define I8237_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8253 */
|
||||
#define I8253_BASE_0 0x040
|
||||
#define I8253_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8255 */
|
||||
#define I8255_BASE_0 0x060
|
||||
#define I8255_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8259 */
|
||||
#define I8259_BASE_0 0x020
|
||||
#define I8259_NUM 1
|
||||
|
||||
/* set the base I/O address for the NMI mask */
|
||||
#define NMI_BASE 0x0A0
|
||||
|
||||
/* set the base I/O address and device count for the DMA page registers */
|
||||
#define DMAPAG_BASE_0 0x080
|
||||
#define DMAPAG_BASE_1 0x081
|
||||
#define DMAPAG_BASE_2 0x082
|
||||
#define DMAPAG_BASE_3 0x083
|
||||
#define DMAPAG_NUM 4
|
||||
|
||||
/* set the base and size for the EPROM on the IBM PC XT*/
|
||||
#define ROM_BASE 0xF0000
|
||||
#define ROM_SIZE 0x10000
|
||||
|
||||
/* set the base and size for the RAM on the IBM PC XT */
|
||||
#define RAM_BASE 0x00000
|
||||
#define RAM_SIZE 0x40000
|
||||
|
||||
/* set INTR for CPU on the IBM PC XT */
|
||||
#define INT_R INT_1
|
||||
|
||||
/* xtbus 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
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define ADDRMASK16 0xFFFF
|
||||
#define ADDRMASK20 0xFFFFF
|
||||
#define MAXMEMSIZE20 0xFFFFF /* 8080 max memory size */
|
||||
|
||||
#define MEMSIZE (i8088_unit.capac) /* 8088 actual memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* 8088 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_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 */
|
||||
|
||||
/* 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.
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* set the base I/O address and device count for the 8237 */
|
||||
#define I8237_BASE_0 0x000
|
||||
#define I8237_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8253 */
|
||||
#define I8253_BASE_0 0x040
|
||||
#define I8253_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8255 */
|
||||
#define I8255_BASE_0 0x060
|
||||
#define I8255_NUM 1
|
||||
|
||||
/* set the base I/O address and device count for the 8259 */
|
||||
#define I8259_BASE_0 0x020
|
||||
#define I8259_NUM 1
|
||||
|
||||
/* set the base I/O address for the NMI mask */
|
||||
#define NMI_BASE 0x0A0
|
||||
|
||||
/* set the base I/O address and device count for the DMA page registers */
|
||||
#define DMAPAG_BASE_0 0x080
|
||||
#define DMAPAG_BASE_1 0x081
|
||||
#define DMAPAG_BASE_2 0x082
|
||||
#define DMAPAG_BASE_3 0x083
|
||||
#define DMAPAG_NUM 4
|
||||
|
||||
/* set the base and size for the EPROM on the IBM PC XT*/
|
||||
#define ROM_BASE 0xF0000
|
||||
#define ROM_SIZE 0x10000
|
||||
|
||||
/* set the base and size for the RAM on the IBM PC XT */
|
||||
#define RAM_BASE 0x00000
|
||||
#define RAM_SIZE 0x40000
|
||||
|
||||
/* set INTR for CPU on the IBM PC XT */
|
||||
#define INT_R INT_1
|
||||
|
||||
/* xtbus 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
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define ADDRMASK16 0xFFFF
|
||||
#define ADDRMASK20 0xFFFFF
|
||||
#define MAXMEMSIZE20 0xFFFFF /* 8080 max memory size */
|
||||
|
||||
#define MEMSIZE (i8088_unit.capac) /* 8088 actual memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* 8088 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_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 */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue