IBMPC: Initial check in of new experimental simulator for the IBM PC (5150)
This commit is contained in:
parent
5f1ee6ed67
commit
89a8c87e87
18 changed files with 12380 additions and 0 deletions
2002
IBMPC-Systems/common/i8008.c
Normal file
2002
IBMPC-Systems/common/i8008.c
Normal file
File diff suppressed because it is too large
Load diff
1445
IBMPC-Systems/common/i8080.c
Normal file
1445
IBMPC-Systems/common/i8080.c
Normal file
File diff suppressed because it is too large
Load diff
4750
IBMPC-Systems/common/i8088.c
Normal file
4750
IBMPC-Systems/common/i8088.c
Normal file
File diff suppressed because it is too large
Load diff
872
IBMPC-Systems/common/i8237.c
Normal file
872
IBMPC-Systems/common/i8237.c
Normal file
|
@ -0,0 +1,872 @@
|
|||
/* i8237.c: Intel 8237 DMA adapter
|
||||
|
||||
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:
|
||||
|
||||
|
||||
Default is none. Since all channel registers in the i8237 are 16-bit, transfers
|
||||
are done as two 8-bit operations, low- then high-byte.
|
||||
|
||||
Port addressing is as follows (Port offset = 0):
|
||||
|
||||
Port Mode Command Function
|
||||
|
||||
00 Write Load DMAC Channel 0 Base and Current Address Regsiters
|
||||
Read Read DMAC Channel 0 Current Address Register
|
||||
01 Write Load DMAC Channel 0 Base and Current Word Count Registers
|
||||
Read Read DMAC Channel 0 Current Word Count Register
|
||||
04 Write Load DMAC Channel 2 Base and Current Address Regsiters
|
||||
Read Read DMAC Channel 2 Current Address Register
|
||||
05 Write Load DMAC Channel 2 Base and Current Word Count Registers
|
||||
Read Read DMAC Channel 2 Current Word Count Register
|
||||
06 Write Load DMAC Channel 3 Base and Current Address Regsiters
|
||||
Read Read DMAC Channel 3 Current Address Register
|
||||
07 Write Load DMAC Channel 3 Base and Current Word Count Registers
|
||||
Read Read DMAC Channel 3 Current Word Count Register
|
||||
08 Write Load DMAC Command Register
|
||||
Read Read DMAC Status Register
|
||||
09 Write Load DMAC Request Register
|
||||
0A Write Set/Reset DMAC Mask Register
|
||||
0B Write Load DMAC Mode Register
|
||||
0C Write Clear DMAC First/Last Flip-Flop
|
||||
0D Write DMAC Master Clear
|
||||
0F Write Load DMAC Mask Register
|
||||
|
||||
Register usage is defined in the following paragraphs.
|
||||
|
||||
Read/Write DMAC Address Registers
|
||||
|
||||
Used to simultaneously load a channel's current-address register and base-address
|
||||
register with the memory address of the first byte to be transferred. (The Channel
|
||||
0 current/base address register must be loaded prior to initiating a diskette read
|
||||
or write operation.) Since each channel's address registers are 16 bits in length
|
||||
(64K address range), two "write address register" commands must be executed in
|
||||
order to load the complete current/base address registers for any channel.
|
||||
|
||||
Read/Write DMAC Word Count Registers
|
||||
|
||||
The Write DMAC Word Count Register command is used to simultaneously load a
|
||||
channel's current and base word-count registers with the number of bytes
|
||||
to be transferred during a subsequent DMA operation. Since the word-count
|
||||
registers are 16-bits in length, two commands must be executed to load both
|
||||
halves of the registers.
|
||||
|
||||
Write DMAC Command Register
|
||||
|
||||
The Write DMAC Command Register command loads an 8-bit byte into the
|
||||
DMAC's command register to define the operating characteristics of the
|
||||
DMAC. The functions of the individual bits in the command register are
|
||||
defined in the following diagram. Note that only two bits within the
|
||||
register are applicable to the controller; the remaining bits select
|
||||
functions that are not supported and, accordingly, must always be set
|
||||
to zero.
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| 0 0 0 0 0 0 |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| |
|
||||
| +---------- 0 CONTROLLER ENABLE
|
||||
| 1 CONTROLLER DISABLE
|
||||
|
|
||||
+------------------ 0 FIXED PRIORITY
|
||||
1 ROTATING PRIORITY
|
||||
|
||||
Read DMAC Status Register Command
|
||||
|
||||
The Read DMAC Status Register command accesses an 8-bit status byte that
|
||||
identifies the DMA channels that have reached terminal count or that
|
||||
have a pending DMA request.
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| 0 0 |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| | | | | |
|
||||
| | | | | +-- CHANNEL 0 TC
|
||||
| | | | +---------- CHANNEL 2 TC
|
||||
| | | +-------------- CHANNEL 3 TC
|
||||
| | +------------------ CHANNEL 0 DMA REQUEST
|
||||
| +-------------------------- CHANNEL 2 DMA REQUEST
|
||||
+------------------------------ CHANNEL 3 DMA REQUEST
|
||||
|
||||
Write DMAC Request Register
|
||||
|
||||
The data byte associated with the Write DMAC Request Register command
|
||||
sets or resets a channel's associated request bit within the DMAC's
|
||||
internal 4-bit request register.
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| X X X X X |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| | |
|
||||
| +---+-- 00 SELECT CHANNEL 0
|
||||
| 01 SELECT CHANNEL 1
|
||||
| 10 SELECT CHANNEL 2
|
||||
| 11 SELECT CHANNEL 3
|
||||
|
|
||||
+---------- 0 RESET REQUEST BIT
|
||||
1 SET REQUEST BIT
|
||||
|
||||
Set/Reset DMAC Mask Register
|
||||
|
||||
Prior to a DREQ-initiated DMA transfer, the channel's mask bit must
|
||||
be reset to enable recognition of the DREQ input. When the transfer
|
||||
is complete (terminal count reached or external EOP applied) and
|
||||
the channel is not programmed to autoinitialize, the channel's
|
||||
mask bit is automatically set (disabling DREQ) and must be reset
|
||||
prior to a subsequent DMA transfer. All four bits of the mask
|
||||
register are set (disabling the DREQ inputs) by a DMAC master
|
||||
clear or controller reset. Additionally, all four bits can be
|
||||
set/reset by a single Write DMAC Mask Register command.
|
||||
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| X X X X X |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| | |
|
||||
| +---+-- 00 SELECT CHANNEL 0
|
||||
| 01 SELECT CHANNEL 1
|
||||
| 10 SELECT CHANNEL 2
|
||||
| 11 SELECT CHANNEL 3
|
||||
|
|
||||
+---------- 0 RESET REQUEST BIT
|
||||
1 SET REQUEST BIT
|
||||
|
||||
Write DMAC Mode Register
|
||||
|
||||
The Write DMAC Mode Register command is used to define the
|
||||
operating mode characteristics for each DMA channel. Each
|
||||
channel has an internal 6-bit mode register; the high-order
|
||||
six bits of the associated data byte are written into the
|
||||
mode register addressed by the two low-order bits.
|
||||
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| | | | | | | |
|
||||
| | | | | | +---+-- 00 SELECT CHANNEL 0
|
||||
| | | | | | 01 SELECT CHANNEL 1
|
||||
| | | | | | 10 SELECT CHANNEL 2
|
||||
| | | | | | 11 SELECT CHANNEL 3
|
||||
| | | | | |
|
||||
| | | | +---+---------- 00 VERIFY TRANSFER
|
||||
| | | | 01 WRITE TRANSFER
|
||||
| | | | 10 READ TRANSFER
|
||||
| | | |
|
||||
| | | +------------------ 0 AUTOINITIALIZE DISABLE
|
||||
| | | 1 AUTOINITIALIZE ENABLE
|
||||
| | |
|
||||
| | +---------------------- 0 ADDRESS INCREMENT
|
||||
| | 1 ADDRESS DECREMENT
|
||||
| |
|
||||
+---+-------------------------- 00 DEMAND MODE
|
||||
01 SINGLE MODE
|
||||
10 BLOCK MODE
|
||||
|
||||
Clear DMAC First/Last Flip-Flop
|
||||
|
||||
The Clear DMAC First/Last Flip-Flop command initializes
|
||||
the DMAC's internal first/last flip-flop so that the
|
||||
next byte written to or re~d from the 16-bit address
|
||||
or word-count registers is the low-order byte. The
|
||||
flip-flop is toggled with each register access so that
|
||||
a second register read or write command accesses the
|
||||
high-order byte.
|
||||
|
||||
DMAC Master Clear
|
||||
|
||||
The DMAC Master Clear command clears the DMAC's command, status,
|
||||
request, and temporary registers to zero, initializes the
|
||||
first/last flip-flop, and sets the four channel mask bits in
|
||||
the mask register to disable all DMA requests (i.e., the DMAC
|
||||
is placed in an idle state).
|
||||
|
||||
Write DMAC Mask Register
|
||||
|
||||
The Write DMAC Mask Register command allows all four bits of the
|
||||
DMAC's mask register to be written with a single command.
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| X X X X X |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| | |
|
||||
| | +-- 0 CLEAR CHANNEL 0 MASK BIT
|
||||
| | 1 SET CHANNEL 0 MASK BIT
|
||||
| |
|
||||
| +---------- 0 CLEAR CHANNEL 2 MASK BIT
|
||||
| 1 SET CHANNEL 2 MASK BIT
|
||||
|
|
||||
+-------------- 0 CLEAR CHANNEL 3 MASK BIT
|
||||
1 SET CHANNEL 3 MASK BIT
|
||||
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8237_devnum = 0; //actual number of 8253 instances + 1
|
||||
uint16 i8237_port[4]; //base port registered to each instance
|
||||
|
||||
/* internal function prototypes */
|
||||
|
||||
t_stat i8237_svc (UNIT *uptr);
|
||||
t_stat i8237_reset (DEVICE *dptr, uint16 base);
|
||||
void i8237_reset1 (void);
|
||||
t_stat i8237_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
uint8 i8237_r0x(t_bool io, uint8 data);
|
||||
uint8 i8237_r1x(t_bool io, uint8 data);
|
||||
uint8 i8237_r2x(t_bool io, uint8 data);
|
||||
uint8 i8237_r3x(t_bool io, uint8 data);
|
||||
uint8 i8237_r4x(t_bool io, uint8 data);
|
||||
uint8 i8237_r5x(t_bool io, uint8 data);
|
||||
uint8 i8237_r6x(t_bool io, uint8 data);
|
||||
uint8 i8237_r7x(t_bool io, uint8 data);
|
||||
uint8 i8237_r8x(t_bool io, uint8 data);
|
||||
uint8 i8237_r9x(t_bool io, uint8 data);
|
||||
uint8 i8237_rAx(t_bool io, uint8 data);
|
||||
uint8 i8237_rBx(t_bool io, uint8 data);
|
||||
uint8 i8237_rCx(t_bool io, uint8 data);
|
||||
uint8 i8237_rDx(t_bool io, uint8 data);
|
||||
uint8 i8237_rEx(t_bool io, uint8 data);
|
||||
uint8 i8237_rFx(t_bool io, uint8 data);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* 8237 physical register definitions */
|
||||
|
||||
uint16 i8237_r0; // 8237 ch 0 address register
|
||||
uint16 i8237_r1; // 8237 ch 0 count register
|
||||
uint16 i8237_r2; // 8237 ch 1 address register
|
||||
uint16 i8237_r3; // 8237 ch 1 count register
|
||||
uint16 i8237_r4; // 8237 ch 2 address register
|
||||
uint16 i8237_r5; // 8237 ch 2 count register
|
||||
uint16 i8237_r6; // 8237 ch 3 address register
|
||||
uint16 i8237_r7; // 8237 ch 3 count register
|
||||
uint8 i8237_r8; // 8237 status register
|
||||
uint8 i8237_r9; // 8237 command register
|
||||
uint8 i8237_rA; // 8237 mode register
|
||||
uint8 i8237_rB; // 8237 mask register
|
||||
uint8 i8237_rC; // 8237 request register
|
||||
uint8 i8237_rD; // 8237 first/last ff
|
||||
uint8 i8237_rE; // 8237
|
||||
uint8 i8237_rF; // 8237
|
||||
|
||||
/* i8237 physical register definitions */
|
||||
|
||||
uint16 i8237_sr; // isbc-208 segment register
|
||||
uint8 i8237_i; // iSBC-208 interrupt register
|
||||
uint8 i8237_a; // iSBC-208 auxillary port register
|
||||
|
||||
/* i8237 Standard SIMH Device Data Structures - 1 unit */
|
||||
|
||||
UNIT i8237_unit[] = {
|
||||
{ UDATA (0, 0, 0) ,20 }, /* i8237 0 */
|
||||
{ UDATA (0, 0, 0) ,20 }, /* i8237 1 */
|
||||
{ UDATA (0, 0, 0) ,20 }, /* i8237 2 */
|
||||
{ UDATA (0, 0, 0) ,20 } /* i8237 3 */
|
||||
};
|
||||
|
||||
|
||||
REG i8237_reg[] = {
|
||||
{ HRDATA (CH0ADR, i8237_r0, 16) },
|
||||
{ HRDATA (CH0CNT, i8237_r1, 16) },
|
||||
{ HRDATA (CH1ADR, i8237_r2, 16) },
|
||||
{ HRDATA (CH1CNT, i8237_r3, 16) },
|
||||
{ HRDATA (CH2ADR, i8237_r4, 16) },
|
||||
{ HRDATA (CH2CNT, i8237_r5, 16) },
|
||||
{ HRDATA (CH3ADR, i8237_r6, 16) },
|
||||
{ HRDATA (CH3CNT, i8237_r7, 16) },
|
||||
{ HRDATA (STAT37, i8237_r8, 8) },
|
||||
{ HRDATA (CMD37, i8237_r9, 8) },
|
||||
{ HRDATA (MODE, i8237_rA, 8) },
|
||||
{ HRDATA (MASK, i8237_rB, 8) },
|
||||
{ HRDATA (REQ, i8237_rC, 8) },
|
||||
{ HRDATA (FF, i8237_rD, 8) },
|
||||
{ HRDATA (SEGREG, i8237_sr, 8) },
|
||||
{ HRDATA (AUX, i8237_a, 8) },
|
||||
{ HRDATA (INT, i8237_i, 8) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB i8237_mod[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEBTAB i8237_debug[] = {
|
||||
{ "ALL", DEBUG_all },
|
||||
{ "FLOW", DEBUG_flow },
|
||||
{ "READ", DEBUG_read },
|
||||
{ "WRITE", DEBUG_write },
|
||||
{ "LEV1", DEBUG_level1 },
|
||||
{ "LEV2", DEBUG_level2 },
|
||||
{ "REG", DEBUG_reg },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE i8237_dev = {
|
||||
"8237", //name
|
||||
i8237_unit, //units
|
||||
i8237_reg, //registers
|
||||
i8237_mod, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
32, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
NULL, //examine
|
||||
NULL, //deposit
|
||||
// &i8237_reset, //deposit
|
||||
NULL, //reset
|
||||
NULL, //boot
|
||||
NULL, //attach
|
||||
NULL, //detach
|
||||
NULL, //ctxt
|
||||
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
|
||||
0, //dctrl
|
||||
// DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
|
||||
i8237_debug, //debflags
|
||||
NULL, //msize
|
||||
NULL //lname
|
||||
};
|
||||
|
||||
/* Service routines to handle simulator functions */
|
||||
|
||||
/* service routine - actually does the simulated DMA */
|
||||
|
||||
t_stat i8237_svc(UNIT *uptr)
|
||||
{
|
||||
sim_printf("uptr=%08X\n", uptr);
|
||||
sim_activate (&i8237_unit[uptr->u6], i8237_unit[uptr->u6].wait);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8237_reset(DEVICE *dptr, uint16 base)
|
||||
{
|
||||
if (i8237_devnum > I8237_NUM) {
|
||||
sim_printf("i8237_reset: too many devices!\n");
|
||||
return SCPE_MEM;
|
||||
}
|
||||
i8237_port[i8237_devnum] = reg_dev(i8237_r0x, base);
|
||||
reg_dev(i8237_r1x, base + 1);
|
||||
reg_dev(i8237_r2x, base + 2);
|
||||
reg_dev(i8237_r3x, base + 3);
|
||||
reg_dev(i8237_r4x, base + 4);
|
||||
reg_dev(i8237_r5x, base + 5);
|
||||
reg_dev(i8237_r6x, base + 6);
|
||||
reg_dev(i8237_r7x, base + 7);
|
||||
reg_dev(i8237_r8x, base + 8);
|
||||
reg_dev(i8237_r9x, base + 9);
|
||||
reg_dev(i8237_rAx, base + 10);
|
||||
reg_dev(i8237_rBx, base + 11);
|
||||
reg_dev(i8237_rCx, base + 12);
|
||||
reg_dev(i8237_rDx, base + 13);
|
||||
reg_dev(i8237_rEx, base + 14);
|
||||
reg_dev(i8237_rFx, base + 15);
|
||||
sim_printf(" 8237 Reset\n");
|
||||
sim_printf(" 8237: Registered at %03X\n", base);
|
||||
sim_activate (&i8237_unit[i8237_devnum], i8237_unit[i8237_devnum].wait); /* activate unit */
|
||||
if ((i8237_dev.flags & DEV_DIS) == 0)
|
||||
i8237_reset1();
|
||||
i8237_devnum++;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint8 i8237_get_dn(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<I8237_NUM; i++)
|
||||
if (port >=i8237_port[i] && port <= i8237_port[i] + 16)
|
||||
return i;
|
||||
sim_printf("i8237_get_dn: port %03X not in 8237 device table\n", port);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void i8237_reset1(void)
|
||||
{
|
||||
int32 i;
|
||||
UNIT *uptr;
|
||||
static int flag = 1;
|
||||
|
||||
for (i = 0; i < 1; i++) { /* handle all units */
|
||||
uptr = i8237_dev.units + i;
|
||||
if (uptr->capac == 0) { /* if not configured */
|
||||
// sim_printf(" SBC208%d: Not configured\n", i);
|
||||
// if (flag) {
|
||||
// sim_printf(" ALL: \"set isbc208 en\"\n");
|
||||
// sim_printf(" EPROM: \"att isbc2080 <filename>\"\n");
|
||||
// flag = 0;
|
||||
// }
|
||||
uptr->capac = 0; /* initialize unit */
|
||||
uptr->u3 = 0;
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->u6 = i; /* unit number - only set here! */
|
||||
sim_activate (&i8237_unit[uptr->u6], i8237_unit[uptr->u6].wait);
|
||||
} else {
|
||||
// sim_printf(" SBC208%d: Configured, Attached to %s\n", i, uptr->filename);
|
||||
}
|
||||
}
|
||||
i8237_r8 = 0; /* status */
|
||||
i8237_r9 = 0; /* command */
|
||||
i8237_rB = 0x0F; /* mask */
|
||||
i8237_rC = 0; /* request */
|
||||
i8237_rD = 0; /* first/last FF */
|
||||
}
|
||||
|
||||
|
||||
/* i8237 set mode = 8- or 16-bit data bus */
|
||||
/* always 8-bit mode for current simulators */
|
||||
|
||||
t_stat i8237_set_mode(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
sim_debug (DEBUG_flow, &i8237_dev, " i8237_set_mode: Entered with val=%08XH uptr->flags=%08X\n", val, uptr->flags);
|
||||
sim_debug (DEBUG_flow, &i8237_dev, " i8237_set_mode: Done\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.
|
||||
*/
|
||||
|
||||
uint8 i8237_r0x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current address CH 0 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(H) read as %04X\n", i8237_r0);
|
||||
return (i8237_r0 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) read as %04X\n", i8237_r0);
|
||||
return (i8237_r0 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 0 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r0 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(H) set to %04X\n", i8237_r0);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r0 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) set to %04X\n", i8237_r0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r1x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current word count CH 0 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(H) read as %04X\n", i8237_r1);
|
||||
return (i8237_r1 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) read as %04X\n", i8237_r1);
|
||||
return (i8237_r1 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 0 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r1 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(H) set to %04X\n", i8237_r1);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r1 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) set to %04X\n", i8237_r1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r2x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current address CH 1 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(H) read as %04X\n", i8237_r2);
|
||||
return (i8237_r2 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) read as %04X\n", i8237_r2);
|
||||
return (i8237_r2 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 1 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r2 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(H) set to %04X\n", i8237_r2);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r2 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) set to %04X\n", i8237_r2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r3x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current word count CH 1 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(H) read as %04X\n", i8237_r3);
|
||||
return (i8237_r3 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(L) read as %04X\n", i8237_r3);
|
||||
return (i8237_r3 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 1 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r3 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(H) set to %04X\n", i8237_r3);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r3 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(L) set to %04X\n", i8237_r3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r4x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current address CH 2 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(H) read as %04X\n", i8237_r4);
|
||||
return (i8237_r4 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(L) read as %04X\n", i8237_r4);
|
||||
return (i8237_r4 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 2 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r4 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(H) set to %04X\n", i8237_r4);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r4 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(L) set to %04X\n", i8237_r4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r5x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current word count CH 2 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(H) read as %04X\n", i8237_r5);
|
||||
return (i8237_r5 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(L) read as %04X\n", i8237_r5);
|
||||
return (i8237_r5 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 2 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r5 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(H) set to %04X\n", i8237_r5);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r5 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(L) set to %04X\n", i8237_r5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r6x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current address CH 3 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(H) read as %04X\n", i8237_r6);
|
||||
return (i8237_r6 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(L) read as %04X\n", i8237_r6);
|
||||
return (i8237_r6 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 3 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r6 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(H) set to %04X\n", i8237_r6);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r6 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(L) set to %04X\n", i8237_r6);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r7x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read current word count CH 3 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(H) read as %04X\n", i8237_r7);
|
||||
return (i8237_r7 >> 8);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(L) read as %04X\n", i8237_r7);
|
||||
return (i8237_r7 & 0xFF);
|
||||
}
|
||||
} else { /* write base & current address CH 3 */
|
||||
if (i8237_rD) { /* high byte */
|
||||
i8237_rD = 0;
|
||||
i8237_r7 |= (data << 8);
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(H) set to %04X\n", i8237_r7);
|
||||
} else { /* low byte */
|
||||
i8237_rD++;
|
||||
i8237_r7 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(L) set to %04X\n", i8237_r7);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r8x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read status register */
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r8 (status) read as %02X\n", i8237_r8);
|
||||
return (i8237_r8);
|
||||
} else { /* write command register */
|
||||
i8237_r9 = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r9 (command) set to %02X\n", i8237_r9);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_r9x(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) {
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_r9\n");
|
||||
return 0;
|
||||
} else { /* write request register */
|
||||
i8237_rC = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rC (request) set to %02X\n", i8237_rC);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_rAx(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) {
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rA\n");
|
||||
return 0;
|
||||
} else { /* write single mask register */
|
||||
switch(data & 0x03) {
|
||||
case 0:
|
||||
if (data & 0x04)
|
||||
i8237_rB |= 1;
|
||||
else
|
||||
i8237_rB &= ~1;
|
||||
break;
|
||||
case 1:
|
||||
if (data & 0x04)
|
||||
i8237_rB |= 2;
|
||||
else
|
||||
i8237_rB &= ~2;
|
||||
break;
|
||||
case 2:
|
||||
if (data & 0x04)
|
||||
i8237_rB |= 4;
|
||||
else
|
||||
i8237_rB &= ~4;
|
||||
break;
|
||||
case 3:
|
||||
if (data & 0x04)
|
||||
i8237_rB |= 8;
|
||||
else
|
||||
i8237_rB &= ~8;
|
||||
break;
|
||||
}
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) set to %02X\n", i8237_rB);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_rBx(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) {
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rB\n");
|
||||
return 0;
|
||||
} else { /* write mode register */
|
||||
i8237_rA = data & 0xFF;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rA (mode) set to %02X\n", i8237_rA);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_rCx(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) {
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rC\n");
|
||||
return 0;
|
||||
} else { /* clear byte pointer FF */
|
||||
i8237_rD = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rD (FF) cleared\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_rDx(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read temporary register */
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rD\n");
|
||||
return 0;
|
||||
} else { /* master clear */
|
||||
i8237_reset1();
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237 master clear\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_rEx(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) {
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rE\n");
|
||||
return 0;
|
||||
} else { /* clear mask register */
|
||||
i8237_rB = 0;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) cleared\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 i8237_rFx(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8237_get_dn()) != 0xFF) {
|
||||
if (io == 0) {
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rF\n");
|
||||
return 0;
|
||||
} else { /* write all mask register bits */
|
||||
i8237_rB = data & 0x0F;
|
||||
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) set to %02X\n", i8237_rB);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* end of i8237.c */
|
318
IBMPC-Systems/common/i8251.c
Normal file
318
IBMPC-Systems/common/i8251.c
Normal file
|
@ -0,0 +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 */
|
235
IBMPC-Systems/common/i8253.c
Normal file
235
IBMPC-Systems/common/i8253.c
Normal file
|
@ -0,0 +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 */
|
288
IBMPC-Systems/common/i8255.c
Normal file
288
IBMPC-Systems/common/i8255.c
Normal file
|
@ -0,0 +1,288 @@
|
|||
/* 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 base 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 base);
|
||||
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);
|
||||
|
||||
/* globals */
|
||||
|
||||
int32 i8255_devnum = 0; //actual number of 8255 instances + 1
|
||||
uint16 i8255_port[4]; //base 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 base)
|
||||
{
|
||||
if (i8255_devnum > I8255_NUM) {
|
||||
sim_printf("i8255_reset: too many devices!\n");
|
||||
return SCPE_MEM;
|
||||
}
|
||||
i8255_port[i8255_devnum] = reg_dev(i8255a, base);
|
||||
reg_dev(i8255b, base + 1);
|
||||
reg_dev(i8255c, base + 2);
|
||||
reg_dev(i8255s, base + 3);
|
||||
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 */
|
||||
sim_printf(" 8255-%d: Reset\n", i8255_devnum);
|
||||
sim_printf(" 8255-%d: Registered at %03X\n", i8255_devnum, base);
|
||||
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 %03X 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 */
|
263
IBMPC-Systems/common/i8259.c
Normal file
263
IBMPC-Systems/common/i8259.c
Normal file
|
@ -0,0 +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 */
|
252
IBMPC-Systems/common/i8273.c
Normal file
252
IBMPC-Systems/common/i8273.c
Normal file
|
@ -0,0 +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;
|
||||
}
|
||||
|
351
IBMPC-Systems/common/i8274.c
Normal file
351
IBMPC-Systems/common/i8274.c
Normal file
|
@ -0,0 +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;
|
||||
}
|
||||
|
||||
/* end of i8274.c */
|
206
IBMPC-Systems/common/ipata.c
Normal file
206
IBMPC-Systems/common/ipata.c
Normal file
|
@ -0,0 +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;
|
||||
}
|
||||
|
193
IBMPC-Systems/common/pata.c
Normal file
193
IBMPC-Systems/common/pata.c
Normal file
|
@ -0,0 +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;
|
||||
}
|
||||
|
465
IBMPC-Systems/common/pcbus.c
Normal file
465
IBMPC-Systems/common/pcbus.c
Normal file
|
@ -0,0 +1,465 @@
|
|||
/* 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 */
|
||||
|
177
IBMPC-Systems/common/pceprom.c
Normal file
177
IBMPC-Systems/common/pceprom.c
Normal file
|
@ -0,0 +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 */
|
152
IBMPC-Systems/common/pcram8.c
Normal file
152
IBMPC-Systems/common/pcram8.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* 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 */
|
203
IBMPC-Systems/ibmpc/ibmpc.c
Normal file
203
IBMPC-Systems/ibmpc/ibmpc.c
Normal file
|
@ -0,0 +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 */
|
97
IBMPC-Systems/ibmpc/ibmpc_sys.c
Normal file
97
IBMPC-Systems/ibmpc/ibmpc_sys.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* ibmpcxt_sys.c: IBM 5160 simulator
|
||||
|
||||
Copyright (c) 2016, William A. Beech
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of William A. Beech shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from William A. Beech.
|
||||
|
||||
11 Jul 16 - Original file.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
extern DEVICE i8088_dev;
|
||||
extern REG i8088_reg[];
|
||||
extern DEVICE i8237_dev;
|
||||
extern DEVICE i8253_dev;
|
||||
extern DEVICE i8255_dev;
|
||||
extern DEVICE i8259_dev;
|
||||
extern DEVICE EPROM_dev;
|
||||
extern DEVICE RAM_dev;
|
||||
extern DEVICE xtbus_dev;
|
||||
|
||||
/* bit patterns to manipulate 8-bit ports */
|
||||
|
||||
#define i82XX_bit_0 0x01 //bit 0 of a port
|
||||
#define i82XX_bit_1 0x02 //bit 1 of a port
|
||||
#define i82XX_bit_2 0x04 //bit 2 of a port
|
||||
#define i82XX_bit_3 0x08 //bit 3 of a port
|
||||
#define i82XX_bit_4 0x10 //bit 4 of a port
|
||||
#define i82XX_bit_5 0x20 //bit 5 of a port
|
||||
#define i82XX_bit_6 0x40 //bit 6 of a port
|
||||
#define i82XX_bit_7 0x80 //bit 7 of a port
|
||||
|
||||
#define i82XX_nbit_0 ~i8255_bit_0 //bit 0 of a port
|
||||
#define i82XX_nbit_1 ~i8255_bit_1 //bit 1 of a port
|
||||
#define i82XX_nbit_2 ~i8255_bit_3 //bit 2 of a port
|
||||
#define i82XX_nbit_3 ~i8255_bit_3 //bit 3 of a port
|
||||
#define i82XX_nbit_4 ~i8255_bit_4 //bit 4 of a port
|
||||
#define i82XX_nbit_5 ~i8255_bit_5 //bit 5 of a port
|
||||
#define i82XX_nbit_6 ~i8255_bit_6 //bit 6 of a port
|
||||
#define i82XX_nbit_7 ~i8255_bit_7 //bit 7 of a port
|
||||
|
||||
/* SCP data structures
|
||||
|
||||
sim_name simulator name string
|
||||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words needed for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
*/
|
||||
|
||||
char sim_name[] = "IBM PC";
|
||||
|
||||
REG *sim_PC = &i8088_reg[0];
|
||||
|
||||
int32 sim_emax = 4;
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&i8088_dev,
|
||||
&EPROM_dev,
|
||||
&RAM_dev,
|
||||
&i8237_dev,
|
||||
&i8253_dev,
|
||||
&i8255_dev,
|
||||
&i8259_dev,
|
||||
&xtbus_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unknown I/O Instruction",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
"Invalid Opcode",
|
||||
"Invalid Memory",
|
||||
"XACK Error"
|
||||
};
|
||||
|
111
IBMPC-Systems/ibmpc/system_defs.h
Normal file
111
IBMPC-Systems/ibmpc/system_defs.h
Normal file
|
@ -0,0 +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 */
|
||||
|
Loading…
Add table
Reference in a new issue