IBMPC, IBMPCXT, isys80xx: Restructure directories to eliminate redundant files

This commit is contained in:
Bill Beech 2017-04-10 10:32:43 -07:00
parent 7317645dd7
commit 2b30084a53
26 changed files with 937 additions and 2312 deletions

View file

@ -1,318 +0,0 @@
/* 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 */

View file

@ -1,233 +0,0 @@
/* 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)
{
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 */

View file

@ -1,289 +0,0 @@
/* i8255.c: Intel i8255 PIO adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
This program simulates up to 4 i8255 devices. It handles 2 i8255
devices on the iSBC 80/10 SBC. Other devices could be on other
multibus boards in the simulated system.
*/
#include "system_defs.h" /* system header in system dir */
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* function prototypes */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport);
uint8 i8255_get_dn(void);
uint8 i8255s(t_bool io, uint8 data);
uint8 i8255a(t_bool io, uint8 data);
uint8 i8255b(t_bool io, uint8 data);
uint8 i8255c(t_bool io, uint8 data);
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8255_devnum = 0; //actual number of 8255 instances + 1
uint16 i8255_port[4]; //baseport port registered to each instance
/* these bytes represent the input and output to/from a port instance */
uint8 i8255_A[4]; //port A byte I/O
uint8 i8255_B[4]; //port B byte I/O
uint8 i8255_C[4]; //port C byte I/O
/* i8255 Standard I/O Data Structures */
/* up to 4 i8255 devices */
UNIT i8255_unit[] = {
{ UDATA (0, 0, 0) }, /* i8255 0 */
{ UDATA (0, 0, 0) }, /* i8255 1 */
{ UDATA (0, 0, 0) }, /* i8255 2 */
{ UDATA (0, 0, 0) } /* i8255 3 */
};
REG i8255_reg[] = {
{ HRDATA (CS0, i8255_unit[0].u3, 8) }, /* i8255 0 */
{ HRDATA (A0, i8255_A[0], 8) },
{ HRDATA (B0, i8255_B[0], 8) },
{ HRDATA (C0, i8255_C[0], 8) },
{ HRDATA (CS1, i8255_unit[1].u3, 8) }, /* i8255 1 */
{ HRDATA (A1, i8255_A[1], 8) },
{ HRDATA (B1, i8255_B[1], 8) },
{ HRDATA (C1, i8255_C[1], 8) },
{ HRDATA (CS2, i8255_unit[2].u3, 8) }, /* i8255 2 */
{ HRDATA (A2, i8255_A[2], 8) },
{ HRDATA (B2, i8255_B[2], 8) },
{ HRDATA (C2, i8255_C[2], 8) },
{ HRDATA (CS3, i8255_unit[3].u3, 8) }, /* i8255 3 */
{ HRDATA (A3, i8255_A[3], 8) },
{ HRDATA (B3, i8255_B[3], 8) },
{ HRDATA (C3, i8255_C[3], 8) },
{ NULL }
};
DEBTAB i8255_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8255_dev = {
"8255", //name
i8255_unit, //units
i8255_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8255_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8255_debug, //debflags
NULL, //msize
NULL //lname
};
/* Reset routine */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport)
{
if (i8255_devnum > I8255_NUM) {
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8255-%d: Reset\n", i8255_devnum);
sim_printf(" 8255-%d: Registered at %04X\n", i8255_devnum, baseport);
i8255_port[i8255_devnum] = baseport;
reg_dev(i8255a, baseport, i8255_devnum);
reg_dev(i8255b, baseport + 1, i8255_devnum);
reg_dev(i8255c, baseport + 2, i8255_devnum);
reg_dev(i8255s, baseport + 3, i8255_devnum);
i8255_unit[i8255_devnum].u3 = 0x9B; /* control */
i8255_A[i8255_devnum] = 0xFF; /* Port A */
i8255_B[i8255_devnum] = 0xFF; /* Port B */
i8255_C[i8255_devnum] = 0xFF; /* Port C */
i8255_devnum++;
return SCPE_OK;
}
uint8 i8255_get_dn(void)
{
int i;
for (i=0; i<I8255_NUM; i++)
if (port >=i8255_port[i] && port <= i8255_port[i] + 3)
return i;
sim_printf("i8255_get_dn: port %04X not in 8255 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* i8255 functions */
uint8 i8255s(t_bool io, uint8 data)
{
uint8 bit;
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return i8255_unit[devnum].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[devnum].u3 = data;
sim_printf(" 8255-%d: Mode Instruction=%02X\n", devnum, data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_C[devnum] |= (0x01 << bit);
} else { /* reset bit */
i8255_C[devnum] &= ~(0x01 << bit);
}
}
}
}
return 0;
}
uint8 i8255a(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
//return (i8255_unit[devnum].u4);
return (i8255_A[devnum]);
} else { /* write data port */
i8255_A[devnum] = data;
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
}
}
return 0;
}
uint8 i8255b(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return (i8255_B[devnum]);
} else { /* write data port */
i8255_B[devnum] = data;
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
}
}
return 0;
}
uint8 i8255c(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
return (i8255_C[devnum]);
} else { /* write data port */
i8255_C[devnum] = data;
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
}
}
return 0;
}
/* end of i8255.c */

View file

@ -1,263 +0,0 @@
/* 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 */

View file

@ -1,252 +0,0 @@
/* i8273.c: Intel i8273 UART adapter
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated i8273 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8273 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
uint8
wr0 = 0, /* command register */
wr1 = 0, /* enable register */
wr2 = 0, /* CH A mode register */
/* CH B interrups vector */
wr3 = 0, /* configuration register 1 */
wr4 = 0, /* configuration register 2 */
wr5 = 0, /* configuration register 3 */
wr6 = 0, /* sync low byte */
wr7 = 0, /* sync high byte */
rr0 = 0, /* status register */
rr1 = 0, /* error register */
rr2 = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8273_reset (DEVICE *dptr);
/* i8273 Standard I/O Data Structures */
UNIT i8273_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8273_reg[] = {
{ HRDATA (WR0, wr0, 8) },
{ HRDATA (WR1, wr1, 8) },
{ HRDATA (WR2, wr2, 8) },
{ HRDATA (WR3, wr3, 8) },
{ HRDATA (WR4, wr4, 8) },
{ HRDATA (WR5, wr5, 8) },
{ HRDATA (WR6, wr6, 8) },
{ HRDATA (WR7, wr7, 8) },
{ HRDATA (RR0, rr0, 8) },
{ HRDATA (RR0, rr1, 8) },
{ HRDATA (RR0, rr2, 8) },
{ NULL }
};
MTAB i8273_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8273_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8273_dev = {
"8273", //name
&i8273_unit, //units
i8273_reg, //registers
i8273_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8273_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8273_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* Reset routine */
t_stat i8273_reset (DEVICE *dptr)
{
wr0 = 0; /* command register */
wr1 = 0; /* enable register */
wr2 = 0; /* CH A mode register */
/* CH B interrups vector */
wr3 = 0; /* configuration register 1 */
wr4 = 0; /* configuration register 2 */
wr5 = 0; /* configuration register 3 */
wr6 = 0; /* sync low byte */
wr7 = 0; /* sync high byte */
rr0 = 0; /* status register */
rr1 = 0; /* error register */
rr2 = 0; /* read interrupt vector */
sim_printf(" 8273 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
*/
int32 i8273s(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8273_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
i8273_unit.u3 = 0x05; /* status */
i8273_unit.u4 = 0; /* mode instruction */
i8273_unit.u5 = 0; /* command instruction */
i8273_unit.u6 = 0;
i8273_unit.buf = 0;
i8273_unit.pos = 0;
sim_printf("8273 Reset\n");
} else if (i8273_unit.u6) {
i8273_unit.u5 = data;
sim_printf("8273 Command Instruction=%02X\n", data);
} else {
i8273_unit.u4 = data;
sim_printf("8273 Mode Instruction=%02X\n", data);
i8273_unit.u6++;
}
return (0);
}
}
int32 i8273d(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8273_unit.u3 &= 0xFD;
return (i8273_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}

View file

@ -1,351 +0,0 @@
/* i8274.c: Intel i8274 MPSC adapter
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated i8274 interface device on an iSBC.
The device had two physical I/O ports which could be connected
to any serial I/O device that would connect to an RS232 interface.
All I/O is via programmed I/O. The i8274 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and two address lines. The data port is at the
lower address and the status/command port is at the higher address for each
channel.
Minimum simulation is provided for this device. Channel A is used as a
console port for the iSBC-88/45
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
/* register definitions */
/* channel A */
uint8 wr0a = 0, /* command register */
wr1a = 0, /* enable register */
wr2a = 0, /* mode register */
wr3a = 0, /* configuration register 1 */
wr4a = 0, /* configuration register 2 */
wr5a = 0, /* configuration register 3 */
wr6a = 0, /* sync low byte */
wr7a = 0, /* sync high byte */
rr0a = 0, /* status register */
rr1a = 0, /* error register */
rr2a = 0; /* read interrupt vector */
/* channel B */
uint8 wr0b = 0, /* command register */
wr1b = 0, /* enable register */
wr2b = 0, /* CH B interrups vector */
wr3b = 0, /* configuration register 1 */
wr4b = 0, /* configuration register 2 */
wr5b = 0, /* configuration register 3 */
wr6b = 0, /* sync low byte */
wr7b = 0, /* sync high byte */
rr0b = 0, /* status register */
rr1b = 0, /* error register */
rr2b = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8274_svc (UNIT *uptr);
t_stat i8274_reset (DEVICE *dptr);
int32 i8274As(int32 io, int32 data);
int32 i8274Ad(int32 io, int32 data);
int32 i8274Bs(int32 io, int32 data);
int32 i8274Bd(int32 io, int32 data);
/* i8274 Standard I/O Data Structures */
UNIT i8274_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8274_reg[] = {
{ HRDATA (WR0A, wr0a, 8) },
{ HRDATA (WR1A, wr1a, 8) },
{ HRDATA (WR2A, wr2a, 8) },
{ HRDATA (WR3A, wr3a, 8) },
{ HRDATA (WR4A, wr4a, 8) },
{ HRDATA (WR5A, wr5a, 8) },
{ HRDATA (WR6A, wr6a, 8) },
{ HRDATA (WR7A, wr7a, 8) },
{ HRDATA (RR0A, rr0a, 8) },
{ HRDATA (RR0A, rr1a, 8) },
{ HRDATA (RR0A, rr2a, 8) },
{ HRDATA (WR0B, wr0b, 8) },
{ HRDATA (WR1B, wr1b, 8) },
{ HRDATA (WR2B, wr2b, 8) },
{ HRDATA (WR3B, wr3b, 8) },
{ HRDATA (WR4B, wr4b, 8) },
{ HRDATA (WR5B, wr5b, 8) },
{ HRDATA (WR6B, wr6b, 8) },
{ HRDATA (WR7B, wr7b, 8) },
{ HRDATA (RR0B, rr0b, 8) },
{ HRDATA (RR0B, rr1b, 8) },
{ HRDATA (RR0B, rr2b, 8) },
{ NULL }
};
MTAB i8274_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8274_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8274_dev = {
"8274", //name
&i8274_unit, //units
i8274_reg, //registers
i8274_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8274_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8274_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* service routine - actually gets char & places in buffer in CH A*/
t_stat i8274_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8274_unit, i8274_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8274_unit.buf = temp & 0xFF; /* Save char */
rr0a |= 0x01; /* Set rx char ready */
/* Do any special character handling here */
i8274_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8274_reset (DEVICE *dptr)
{
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = wr6a = wr7a = rr0a = rr1a = rr2a = 0;
wr0b = wr1b = wr2b = wr3b = wr4b = wr5b = wr6b = wr7b = rr0b = rr1b = rr2b = 0;
sim_printf(" 8274 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
The 8274 contains 2 separate channels, A and B.
*/
/* channel A command/status */
int32 i8274As(int32 io, int32 data)
{
if (io == 0) { /* read status port */
switch(wr0a & 0x7) {
case 0: /* rr0a */
return rr0a;
case 1: /* rr1a */
return rr1a;
case 2: /* rr1a */
return rr2a;
}
return 0; /* bad register select */
} else { /* write status port */
switch(wr0a & 0x7) {
case 0: /* wr0a */
wr0a = data;
if ((wr0a & 0x38) == 0x18) { /* channel reset */
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = 0;
wr6a = wr7a = rr0a = rr1a = rr2a = 0;
sim_printf("8274 Channel A reset\n");
}
break;
case 1: /* wr1a */
wr1a = data;
break;
case 2: /* wr2a */
wr2a = data;
break;
case 3: /* wr3a */
wr3a = data;
break;
case 4: /* wr4a */
wr4a = data;
break;
case 5: /* wr5a */
wr5a = data;
break;
case 6: /* wr6a */
wr6a = data;
break;
case 7: /* wr7a */
wr7a = data;
break;
}
sim_printf("8274 Command WR%dA=%02X\n", wr0a & 0x7, data);
return 0;
}
}
/* channel A data */
int32 i8274Ad(int32 io, int32 data)
{
if (io == 0) { /* read data port */
rr0a &= 0xFE;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* channel B command/status */
int32 i8274Bs(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8274_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
sim_printf("8274 Reset\n");
} else if (i8274_unit.u6) {
i8274_unit.u5 = data;
sim_printf("8274 Command Instruction=%02X\n", data);
} else {
i8274_unit.u4 = data;
sim_printf("8274 Mode Instruction=%02X\n", data);
i8274_unit.u6++;
}
return (0);
}
}
/* channel B data */
int32 i8274Bd(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8274_unit.u3 &= 0xFD;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* end of i8274.c */

View file

@ -1,206 +0,0 @@
/* iPATA.c: Intel i8255 PIO adapter for PATA HD
Copyright (c) 2015, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
NOTES:
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device. This is an extension of the i8255.c file to support
an emulated PATA IDE Hard Disk Drive.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
The Second 8255 on the iSBC 80/10 is used to connect to the IDE PATA
Hard Disk Drive. Pins are defined as shown below:
PA[0..7] High data byte
PB[0..7] Low data byte
PC[0..2] Register select
PC[3..4] CSFX select
PC[5] Read register
PC[6] Write register
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
sim_printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port A = %02X\n", pata_unit[0].u4);
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
sim_printf("PATA: 8255 Write Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port B = %02X\n", pata_unit[0].u5);
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
sim_printf("PATA: 8255 Write Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
sim_printf("PATA: 8255 Read Port C = %02X\n", pata_unit[0].u6);
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
sim_printf("PATA: 8255 Write Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
sim_printf(" PATA: Reset\n");
return SCPE_OK;
}

View file

@ -1,193 +0,0 @@
/* i8255.c: Intel i8255 PIO adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(int32, int32), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
sim_printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
sim_printf("PATA: 8255 Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
sim_printf("PATA: 8255 Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
sim_printf("PATA: 8255 Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
sim_printf(" PATA: Reset\n");
return SCPE_OK;
}

View file

@ -41,10 +41,6 @@
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
02 Write Load DMAC Channel 1 Base and Current Address Regsiters
Read Read DMAC Channel 1 Current Address Register
03 Write Load DMAC Channel 1 Base and Current Word Count Registers
Read Read DMAC Channel 1 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
@ -248,11 +244,11 @@ extern uint16 port; //port called in dev_table[port]
int32 i8237_devnum = 0; //actual number of 8253 instances + 1
uint16 i8237_port[4]; //base port registered to each instance
/* function prototypes */
/* internal function prototypes */
t_stat i8237_svc(UNIT *uptr);
t_stat i8237_reset(DEVICE *dptr, uint16 base);
void i8237_reset1(int32 devnum);
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);
@ -277,28 +273,28 @@ extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
/* 8237 physical register definitions */
uint16 i8237_r0[4]; // 8237 ch 0 address register
uint16 i8237_r1[4]; // 8237 ch 0 count register
uint16 i8237_r2[4]; // 8237 ch 1 address register
uint16 i8237_r3[4]; // 8237 ch 1 count register
uint16 i8237_r4[4]; // 8237 ch 2 address register
uint16 i8237_r5[4]; // 8237 ch 2 count register
uint16 i8237_r6[4]; // 8237 ch 3 address register
uint16 i8237_r7[4]; // 8237 ch 3 count register
uint8 i8237_r8[4]; // 8237 status register
uint8 i8237_r9[4]; // 8237 command register
uint8 i8237_rA[4]; // 8237 mode register
uint8 i8237_rB[4]; // 8237 mask register
uint8 i8237_rC[4]; // 8237 request register
uint8 i8237_rD[4]; // 8237 first/last ff
uint8 i8237_rE[4]; // 8237
uint8 i8237_rF[4]; // 8237
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[4]; // isbc-208 segment register
uint8 i8237_i[4]; // iSBC-208 interrupt register
uint8 i8237_a[4]; // iSBC-208 auxillary port register
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 */
@ -311,9 +307,9 @@ UNIT i8237_unit[] = {
REG i8237_reg[] = {
{ HRDATA (CH0ADR, i8237_r0[devnum], 16) },
{ HRDATA (CH0CNT, i8237_r1[devnum], 16) },
{ HRDATA (CH1ADR, i8237_r2[devnum], 16) },
{ 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) },
@ -347,7 +343,7 @@ DEBTAB i8237_debug[] = {
};
DEVICE i8237_dev = {
"I8237", //name
"8237", //name
i8237_unit, //units
i8237_reg, //registers
i8237_mod, //modifiers
@ -391,8 +387,6 @@ t_stat i8237_reset(DEVICE *dptr, uint16 base)
sim_printf("i8237_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8237 Reset\n");
sim_printf(" 8237: Registered at %03X\n", base);
i8237_port[i8237_devnum] = reg_dev(i8237_r0x, base);
reg_dev(i8237_r1x, base + 1);
reg_dev(i8237_r2x, base + 2);
@ -413,7 +407,7 @@ t_stat i8237_reset(DEVICE *dptr, uint16 base)
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);
i8237_reset1();
i8237_devnum++;
return SCPE_OK;
}
@ -429,25 +423,36 @@ uint8 i8237_get_dn(void)
return 0xFF;
}
void i8237_reset1(int32 devnum)
void i8237_reset1(void)
{
int32 i;
UNIT *uptr;
static int flag = 1;
uptr = i8237_dev[devnum].units;
if (uptr->capac == 0) { /* if not configured */
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[devnum], i8237_unit[devnum].wait);
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[devnum] = 0; /* status */
i8237_r9[devnum] = 0; /* command */
i8237_rB[devnum] = 0x0F; /* mask */
i8237_rC[devnum] = 0; /* request */
i8237_rD[devnum] = 0; /* first/last FF */
i8237_r8 = 0; /* status */
i8237_r9 = 0; /* command */
i8237_rB = 0x0F; /* mask */
i8237_rC = 0; /* request */
i8237_rD = 0; /* first/last FF */
}
@ -478,26 +483,27 @@ uint8 i8237_r0x(t_bool io, uint8 data)
if (io == 0) { /* read current address CH 0 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](H) read as %04X\n", devnum, i8237_r0[devnum]);
return (i8237_r0[devnum] >> 8);
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[%d](L) read as %04X\n", devnum, i8237_r0[devnum]);
return (i8237_r0[devnum] & 0xFF);
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[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](H) set to %04X\n", devnum, i8237_r0[devnum]);
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[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](L) set to %04X\n"devnum, , i8237_r0[devnum]);
i8237_r0 = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) set to %04X\n", i8237_r0);
}
return 0;
}
}
return 0;
}
uint8 i8237_r1x(t_bool io, uint8 data)
@ -508,26 +514,27 @@ uint8 i8237_r1x(t_bool io, uint8 data)
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[%d](H) read as %04X\n", devnum, i8237_r1[devnum]);
return (i8237_r1[devnum][devnum] >> 8);
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[%d](L) read as %04X\n", devnum, i8237_r1[devnum]);
return (i8237_r1[devnum] & 0xFF);
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[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](H) set to %04X\n", devnum, i8237_r1[devnum]);
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[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](L) set to %04X\n", devnum, i8237_r1[devnum]);
i8237_r1 = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) set to %04X\n", i8237_r1);
}
return 0;
}
}
return 0;
}
uint8 i8237_r2x(t_bool io, uint8 data)
@ -538,26 +545,27 @@ uint8 i8237_r2x(t_bool io, uint8 data)
if (io == 0) { /* read current address CH 1 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](H) read as %04X\n", devnum, i8237_r2[devnum]);
return (i8237_r2[devnum] >> 8);
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[%d](L) read as %04X\n", devnum, i8237_r2[devnum]);
return (i8237_r2[devnum] & 0xFF);
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[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](H) set to %04X\n", devnum, i8237_r2[devnum]);
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[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](L) set to %04X\n", devnum, i8237_r2[devnum]);
i8237_r2 = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) set to %04X\n", i8237_r2);
}
return 0;
}
}
return 0;
}
uint8 i8237_r3x(t_bool io, uint8 data)
@ -588,6 +596,7 @@ uint8 i8237_r3x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r4x(t_bool io, uint8 data)
@ -618,6 +627,7 @@ uint8 i8237_r4x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r5x(t_bool io, uint8 data)
@ -648,6 +658,7 @@ uint8 i8237_r5x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r6x(t_bool io, uint8 data)
@ -678,6 +689,7 @@ uint8 i8237_r6x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r7x(t_bool io, uint8 data)
@ -708,6 +720,7 @@ uint8 i8237_r7x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r8x(t_bool io, uint8 data)
@ -724,6 +737,7 @@ uint8 i8237_r8x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r9x(t_bool io, uint8 data)
@ -740,6 +754,7 @@ uint8 i8237_r9x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rAx(t_bool io, uint8 data)
@ -781,6 +796,7 @@ uint8 i8237_rAx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rBx(t_bool io, uint8 data)
@ -797,6 +813,7 @@ uint8 i8237_rBx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rCx(t_bool io, uint8 data)
@ -813,6 +830,7 @@ uint8 i8237_rCx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rDx(t_bool io, uint8 data)
@ -829,6 +847,7 @@ uint8 i8237_rDx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rEx(t_bool io, uint8 data)
@ -845,6 +864,7 @@ uint8 i8237_rEx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rFx(t_bool io, uint8 data)
@ -861,6 +881,7 @@ uint8 i8237_rFx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
/* end of i8237.c */

View file

@ -41,6 +41,10 @@
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
02 Write Load DMAC Channel 1 Base and Current Address Regsiters
Read Read DMAC Channel 1 Current Address Register
03 Write Load DMAC Channel 1 Base and Current Word Count Registers
Read Read DMAC Channel 1 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
@ -244,11 +248,11 @@ extern uint16 port; //port called in dev_table[port]
int32 i8237_devnum = 0; //actual number of 8253 instances + 1
uint16 i8237_port[4]; //base port registered to each instance
/* internal function prototypes */
/* function prototypes */
t_stat i8237_svc (UNIT *uptr);
t_stat i8237_reset (DEVICE *dptr, uint16 base);
void i8237_reset1 (void);
t_stat i8237_svc(UNIT *uptr);
t_stat i8237_reset(DEVICE *dptr, uint16 base);
void i8237_reset1(int32 devnum);
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);
@ -273,28 +277,28 @@ 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
uint16 i8237_r0[4]; // 8237 ch 0 address register
uint16 i8237_r1[4]; // 8237 ch 0 count register
uint16 i8237_r2[4]; // 8237 ch 1 address register
uint16 i8237_r3[4]; // 8237 ch 1 count register
uint16 i8237_r4[4]; // 8237 ch 2 address register
uint16 i8237_r5[4]; // 8237 ch 2 count register
uint16 i8237_r6[4]; // 8237 ch 3 address register
uint16 i8237_r7[4]; // 8237 ch 3 count register
uint8 i8237_r8[4]; // 8237 status register
uint8 i8237_r9[4]; // 8237 command register
uint8 i8237_rA[4]; // 8237 mode register
uint8 i8237_rB[4]; // 8237 mask register
uint8 i8237_rC[4]; // 8237 request register
uint8 i8237_rD[4]; // 8237 first/last ff
uint8 i8237_rE[4]; // 8237
uint8 i8237_rF[4]; // 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
uint16 i8237_sr[4]; // isbc-208 segment register
uint8 i8237_i[4]; // iSBC-208 interrupt register
uint8 i8237_a[4]; // iSBC-208 auxillary port register
/* i8237 Standard SIMH Device Data Structures - 1 unit */
@ -307,9 +311,9 @@ UNIT i8237_unit[] = {
REG i8237_reg[] = {
{ HRDATA (CH0ADR, i8237_r0, 16) },
{ HRDATA (CH0CNT, i8237_r1, 16) },
{ HRDATA (CH1ADR, i8237_r2, 16) },
{ HRDATA (CH0ADR, i8237_r0[devnum], 16) },
{ HRDATA (CH0CNT, i8237_r1[devnum], 16) },
{ HRDATA (CH1ADR, i8237_r2[devnum], 16) },
{ HRDATA (CH1CNT, i8237_r3, 16) },
{ HRDATA (CH2ADR, i8237_r4, 16) },
{ HRDATA (CH2CNT, i8237_r5, 16) },
@ -343,7 +347,7 @@ DEBTAB i8237_debug[] = {
};
DEVICE i8237_dev = {
"8237", //name
"I8237", //name
i8237_unit, //units
i8237_reg, //registers
i8237_mod, //modifiers
@ -387,6 +391,8 @@ t_stat i8237_reset(DEVICE *dptr, uint16 base)
sim_printf("i8237_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8237 Reset\n");
sim_printf(" 8237: Registered at %03X\n", base);
i8237_port[i8237_devnum] = reg_dev(i8237_r0x, base);
reg_dev(i8237_r1x, base + 1);
reg_dev(i8237_r2x, base + 2);
@ -407,7 +413,7 @@ t_stat i8237_reset(DEVICE *dptr, uint16 base)
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_reset1(i8237_devnum);
i8237_devnum++;
return SCPE_OK;
}
@ -423,36 +429,25 @@ uint8 i8237_get_dn(void)
return 0xFF;
}
void i8237_reset1(void)
void i8237_reset1(int32 devnum)
{
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);
}
uptr = i8237_dev[devnum].units;
if (uptr->capac == 0) { /* if not configured */
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[devnum], i8237_unit[devnum].wait);
}
i8237_r8 = 0; /* status */
i8237_r9 = 0; /* command */
i8237_rB = 0x0F; /* mask */
i8237_rC = 0; /* request */
i8237_rD = 0; /* first/last FF */
i8237_r8[devnum] = 0; /* status */
i8237_r9[devnum] = 0; /* command */
i8237_rB[devnum] = 0x0F; /* mask */
i8237_rC[devnum] = 0; /* request */
i8237_rD[devnum] = 0; /* first/last FF */
}
@ -483,27 +478,26 @@ uint8 i8237_r0x(t_bool io, uint8 data)
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);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](H) read as %04X\n", devnum, i8237_r0[devnum]);
return (i8237_r0[devnum] >> 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);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](L) read as %04X\n", devnum, i8237_r0[devnum]);
return (i8237_r0[devnum] & 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);
i8237_r0[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](H) set to %04X\n", devnum, i8237_r0[devnum]);
} else { /* low byte */
i8237_rD++;
i8237_r0 = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) set to %04X\n", i8237_r0);
i8237_r0[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[%d](L) set to %04X\n"devnum, , i8237_r0[devnum]);
}
return 0;
}
}
return 0;
}
uint8 i8237_r1x(t_bool io, uint8 data)
@ -514,27 +508,26 @@ uint8 i8237_r1x(t_bool io, uint8 data)
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);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](H) read as %04X\n", devnum, i8237_r1[devnum]);
return (i8237_r1[devnum][devnum] >> 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);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](L) read as %04X\n", devnum, i8237_r1[devnum]);
return (i8237_r1[devnum] & 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);
i8237_r1[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](H) set to %04X\n", devnum, i8237_r1[devnum]);
} else { /* low byte */
i8237_rD++;
i8237_r1 = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) set to %04X\n", i8237_r1);
i8237_r1[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[%d](L) set to %04X\n", devnum, i8237_r1[devnum]);
}
return 0;
}
}
return 0;
}
uint8 i8237_r2x(t_bool io, uint8 data)
@ -545,27 +538,26 @@ uint8 i8237_r2x(t_bool io, uint8 data)
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);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](H) read as %04X\n", devnum, i8237_r2[devnum]);
return (i8237_r2[devnum] >> 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);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](L) read as %04X\n", devnum, i8237_r2[devnum]);
return (i8237_r2[devnum] & 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);
i8237_r2[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](H) set to %04X\n", devnum, i8237_r2[devnum]);
} else { /* low byte */
i8237_rD++;
i8237_r2 = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) set to %04X\n", i8237_r2);
i8237_r2[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[%d](L) set to %04X\n", devnum, i8237_r2[devnum]);
}
return 0;
}
}
return 0;
}
uint8 i8237_r3x(t_bool io, uint8 data)
@ -596,7 +588,6 @@ uint8 i8237_r3x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r4x(t_bool io, uint8 data)
@ -627,7 +618,6 @@ uint8 i8237_r4x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r5x(t_bool io, uint8 data)
@ -658,7 +648,6 @@ uint8 i8237_r5x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r6x(t_bool io, uint8 data)
@ -689,7 +678,6 @@ uint8 i8237_r6x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r7x(t_bool io, uint8 data)
@ -720,7 +708,6 @@ uint8 i8237_r7x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r8x(t_bool io, uint8 data)
@ -737,7 +724,6 @@ uint8 i8237_r8x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_r9x(t_bool io, uint8 data)
@ -754,7 +740,6 @@ uint8 i8237_r9x(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rAx(t_bool io, uint8 data)
@ -796,7 +781,6 @@ uint8 i8237_rAx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rBx(t_bool io, uint8 data)
@ -813,7 +797,6 @@ uint8 i8237_rBx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rCx(t_bool io, uint8 data)
@ -830,7 +813,6 @@ uint8 i8237_rCx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rDx(t_bool io, uint8 data)
@ -847,7 +829,6 @@ uint8 i8237_rDx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rEx(t_bool io, uint8 data)
@ -864,7 +845,6 @@ uint8 i8237_rEx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
uint8 i8237_rFx(t_bool io, uint8 data)
@ -881,7 +861,6 @@ uint8 i8237_rFx(t_bool io, uint8 data)
return 0;
}
}
return 0;
}
/* end of i8237.c */

View file

@ -28,7 +28,7 @@
This software was written by Bill Beech, 24 Jan 13, to allow emulation of
more complex Multibus Computer Systems.
This program simulates up to 2 i8259 devices. It handles 1 i8259
This program simulates up to 4 i8259 devices. It handles 1 i8259
device on the iSBC 80/20 and iSBC 80/30 SBCs. Other devices could be on
other multibus boards in the simulated system.
*/
@ -69,7 +69,7 @@ uint8 i8259_ocw3[I8259_NUM];
uint8 icw_num0 = 1, icw_num1 = 1;
/* i8259 Standard I/O Data Structures */
/* up to 2 i8259 devices */
/* up to 4 i8259 devices */
UNIT i8259_unit[] = {
{ UDATA (0, 0, 0) }, /* i8259 0 */
@ -99,7 +99,6 @@ DEBTAB i8259_debug[] = {
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }

View file

@ -183,6 +183,9 @@
#define RB1RD0 0x40 //drive 0 ready
#define RB1RD1 0x80 //drive 1 ready
#define MDSSD 256256 //single density FDD size
#define MDSDD 512512 //double density FDD size
/* external globals */
extern uint16 port; //port called in dev_table[port]
@ -512,7 +515,7 @@ uint8 isbc2012(t_bool io, uint8 data)
} else { /* write data port */
fdc201[fdcnum].iopb |= (data << 8);
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X",
sim_printf("\n isbc201-%d: 0x7A IOPB=%04X PCX=%04X",
fdcnum, fdc201[fdcnum].iopb, PCX);
isbc201_diskio(fdcnum);
if (fdc201[fdcnum].intff)

View file

@ -0,0 +1,736 @@
/* isbc202.c: Intel double density disk adapter 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:
27 Jun 16 - Original file.
NOTES:
This controller will mount 4 DD disk images on drives :F0: thru :F3: addressed
at ports 078H to 07FH.
Registers:
078H - Read - Subsystem status
bit 0 - ready status of drive 0
bit 1 - ready status of drive 1
bit 2 - state of channel's interrupt FF
bit 3 - controller presence indicator
bit 4 - DD controller presence indicator
bit 5 - ready status of drive 2
bit 6 - ready status of drive 3
bit 7 - zero
079H - Read - Read result type (bits 2-7 are zero)
00 - I/O complete with error
01 - Reserved
10 - Result byte contains diskette ready status
11 - Reserved
079H - Write - IOPB address low byte.
07AH - Write - IOPB address high byte and start operation.
07BH - Read - Read result byte
If result type is 00H
bit 0 - deleted record
bit 1 - CRC error
bit 2 - seek error
bit 3 - address error
bit 4 - data overrun/underrun
bit 5 - write protect
bit 6 - write error
bit 7 - not ready
If result type is 02H and ready has changed
bit 0 - zero
bit 1 - zero
bit 2 - zero
bit 3 - zero
bit 4 - drive 2 ready
bit 5 - drive 3 ready
bit 6 - drive 0 ready
bit 7 - drive 1 ready
else return 0
07FH - Write - Reset diskette system.
Operations:
NOP - 0x00
Seek - 0x01
Format Track - 0x02
Recalibrate - 0x03
Read Data - 0x04
Verify CRC - 0x05
Write Data - 0x06
Write Deleted Data - 0x07
IOPB - I/O Parameter Block
Byte 0 - Channel Word
bit 3 - data word length (=8-bit, 1=16-bit)
bit 4-5 - interrupt control
00 - I/O complete interrupt to be issued
01 - I/O complete interrupts are disabled
10 - illegal code
11 - illegal code
bit 6- randon format sequence
Byte 1 - Diskette Instruction
bit 0-2 - operation code
000 - no operation
001 - seek
010 - format track
011 - recalibrate
100 - read data
101 - verify CRC
110 - write data
111 - write deleted data
bit 3 - data word length ( same as byte-0, bit-3)
bit 4-5 - unit select
00 - drive 0
01 - drive 1
10 - drive 2
11 - drive 3
bit 6-7 - reserved (zero)
Byte 2 - Number of Records
Byte 4 - Track Address
Byte 5 - Sector Address
Byte 6 - Buffer Low Address
Byte 7 - Buffer High Address
u3 -
u4 -
u5 - fdc number (board instance number).
u6 - fdd number.
*/
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 4
//disk controoler operations
#define DNOP 0x00 //disk no operation
#define DSEEK 0x01 //disk seek
#define DFMT 0x02 //disk format
#define DHOME 0x03 //disk home
#define DREAD 0x04 //disk read
#define DVCRC 0x05 //disk verify CRC
#define DWRITE 0x06 //disk write
//status
#define RDY0 0x01 //FDD 0 ready
#define RDY1 0x02 //FDD 1 ready
#define FDCINT 0x04 //FDC interrupt flag
#define FDCPRE 0x08 //FDC board present
#define FDCDD 0x10 //fdc is DD
#define RDY2 0x20 //FDD 2 ready
#define RDY3 0x40 //FDD 3 ready
//result type
#define RERR 0x00 //FDC returned error
#define ROK 0x02 //FDC returned ok
// If result type is RERR then rbyte is
#define RB0DR 0x01 //deleted record
#define RB0CRC 0x02 //CRC error
#define RB0SEK 0x04 //seek error
#define RB0ADR 0x08 //address error
#define RB0OU 0x10 //data overrun/underrun
#define RB0WP 0x20 //write protect
#define RB0WE 0x40 //write error
#define RB0NR 0x80 //not ready
// If result type is ROK then rbyte is
#define RB1RD2 0x10 //drive 2 ready
#define RB1RD3 0x20 //drive 3 ready
#define RB1RD0 0x40 //drive 0 ready
#define RB1RD1 0x80 //drive 1 ready
#define MDSSD 256256 //single density FDD size
#define MDSDD 512512 //double density FDD size
#define MAXSECSD 26 //single density last sector
#define MAXSECDD 52 //double density last sector
#define MAXTRK 76 //last track
/* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX;
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
extern uint8 multibus_get_mbyte(uint16 addr);
extern uint16 multibus_get_mword(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 multibus_put_mword(uint16 addr, uint16 val);
/* function prototypes */
t_stat isbc202_reset(DEVICE *dptr, uint16 base);
void isbc202_reset1(uint8 fdcnum);
t_stat isbc202_attach (UNIT *uptr, CONST char *cptr);
t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 isbc202_get_dn(void);
uint8 isbc2020(t_bool io, uint8 data); /* isbc202 0 */
uint8 isbc2021(t_bool io, uint8 data); /* isbc202 1 */
uint8 isbc2022(t_bool io, uint8 data); /* isbc202 2 */
uint8 isbc2023(t_bool io, uint8 data); /* isbc202 3 */
uint8 isbc2027(t_bool io, uint8 data); /* isbc202 7 */
void isbc202_diskio(uint8 fdcnum); //do actual disk i/o
/* globals */
int32 isbc202_fdcnum = 0; //actual number of SBC-202 instances + 1
typedef struct { //FDD definition
int t0;
int rdy;
uint8 sec;
uint8 cyl;
} FDDDEF;
typedef struct { //FDC definition
uint16 baseport; //FDC base port
uint16 iopb; //FDC IOPB
uint8 stat; //FDC status
uint8 rdychg; //FDC ready change
uint8 rtype; //FDC result type
uint8 rbyte0; //FDC result byte for type 00
uint8 rbyte1; //FDC result byte for type 10
uint8 intff; //fdc interrupt FF
FDDDEF fdd[FDD_NUM]; //indexed by the FDD number
} FDCDEF;
FDCDEF fdc202[4]; //indexed by the isbc-202 instance number
UNIT isbc202_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 20 }
};
REG isbc202_reg[] = {
{ HRDATA (STAT0, fdc202[0].stat, 8) }, /* isbc202 0 status */
{ HRDATA (RTYP0, fdc202[0].rtype, 8) }, /* isbc202 0 result type */
{ HRDATA (RBYT0A, fdc202[0].rbyte0, 8) }, /* isbc202 0 result byte 0 */
{ HRDATA (RBYT0B, fdc202[0].rbyte1, 8) }, /* isbc202 0 result byte 1 */
{ HRDATA (INTFF0, fdc202[0].intff, 8) }, /* isbc202 0 interrupt f/f */
{ HRDATA (STAT1, fdc202[1].stat, 8) }, /* isbc202 1 status */
{ HRDATA (RTYP1, fdc202[1].rtype, 8) }, /* isbc202 1 result type */
{ HRDATA (RBYT1A, fdc202[1].rbyte0, 8) }, /* isbc202 1 result byte 0 */
{ HRDATA (RBYT1B, fdc202[1].rbyte1, 8) }, /* isbc202 1 result byte 1 */
{ HRDATA (INTFF1, fdc202[1].intff, 8) }, /* isbc202 1 interrupt f/f */
{ HRDATA (STAT2, fdc202[2].stat, 8) }, /* isbc202 2 status */
{ HRDATA (RTYP2, fdc202[2].rtype, 8) }, /* isbc202 2 result type */
{ HRDATA (RBYT2A, fdc202[2].rbyte0, 8) }, /* isbc202 2 result byte 0 */
{ HRDATA (RBYT2B, fdc202[2].rbyte1, 8) }, /* isbc202 2 result byte 1 */
{ HRDATA (INTFF2, fdc202[2].intff, 8) }, /* isbc202 2 interrupt f/f */
{ HRDATA (STAT3, fdc202[3].stat, 8) }, /* isbc202 3 status */
{ HRDATA (RTYP3, fdc202[3].rtype, 8) }, /* isbc202 3 result type */
{ HRDATA (RBYT3A, fdc202[3].rbyte0, 8) }, /* isbc202 3 result byte 0 */
{ HRDATA (RBYT3B, fdc202[3].rbyte1, 8) }, /* isbc202 3 result byte 1 */
{ HRDATA (INTFF3, fdc202[3].intff, 8) }, /* isbc202 3 interrupt f/f */
{ NULL }
};
MTAB isbc202_mod[] = {
{ UNIT_WPMODE, 0, "RW", "RW", &isbc202_set_mode },
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc202_set_mode },
{ 0 }
};
DEBTAB isbc202_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE isbc202_dev = {
"SBC202", //name
isbc202_unit, //units
isbc202_reg, //registers
isbc202_mod, //modifiers
FDD_NUM, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
NULL, //reset
NULL, //boot
&isbc202_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
isbc202_debug, //debflags
NULL, //msize
NULL //lname
};
/* Hardware reset routine */
t_stat isbc202_reset(DEVICE *dptr, uint16 base)
{
int32 i;
UNIT *uptr;
sim_printf(" iSBC-202 FDC Board");
if (SBC202_NUM) {
sim_printf(" - Found\n");
sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum);
sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base);
//register base port address for this FDC instance
fdc202[isbc202_fdcnum].baseport = base;
//register I/O port addresses for each function
reg_dev(isbc2020, base, isbc202_fdcnum); //read status
reg_dev(isbc2021, base + 1, isbc202_fdcnum); //read rslt type/write IOPB addr-l
reg_dev(isbc2022, base + 2, isbc202_fdcnum); //write IOPB addr-h and start
reg_dev(isbc2023, base + 3, isbc202_fdcnum); //read rstl byte
reg_dev(isbc2027, base + 7, isbc202_fdcnum); //write reset isbc202
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc202_dev.units + i;
uptr->u5 = isbc202_fdcnum; //fdc device number
uptr->u6 = i; //fdd unit number
uptr->flags |= UNIT_WPMODE; //set WP in unit flags
}
isbc202_reset1(isbc202_fdcnum); //software reset
isbc202_fdcnum++; //next FDC instance
} else
sim_printf(" - Not Found\n");
return SCPE_OK;
}
/* Software reset routine */
void isbc202_reset1(uint8 fdcnum)
{
int32 i;
UNIT *uptr;
sim_printf(" isbc202-%d: Software Reset\n", fdcnum);
fdc202[fdcnum].stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all FDDs */
uptr = isbc202_dev.units + i;
fdc202[fdcnum].stat |= FDCPRE | FDCDD; //set the FDC status
fdc202[fdcnum].rtype = ROK;
// sim_printf("FDD %d uptr->capac=%d\n", i, uptr->capac);
if (uptr->capac == 0) { /* if not configured */
sim_printf(" SBC202%d: Configured, FDC Status=%02X Not attached\n", i, fdc202[fdcnum].stat);
} else {
switch(i){
case 0:
fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready
fdc202[fdcnum].rbyte1 |= RB1RD0;
break;
case 1:
fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready
fdc202[fdcnum].rbyte1 |= RB1RD1;
break;
case 2:
fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready
fdc202[fdcnum].rbyte1 |= RB1RD2;
break;
case 3:
fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready
fdc202[fdcnum].rbyte1 |= RB1RD3;
break;
}
fdc202[fdcnum].rdychg = 0;
sim_printf(" SBC202%d: Configured, FDC Status=%02X Attached to %s\n",
i, fdc202[fdcnum].stat, uptr->filename);
}
}
}
/* isbc202 attach - attach an .IMG file to a FDD */
t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
uint8 fdcnum, fddnum;
sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" isbc202_attach: Attach error\n");
return r;
}
fdcnum = uptr->u5;
fddnum = uptr->u6;
uptr->capac = MDSDD;
switch(fddnum){
case 0:
fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready
fdc202[fdcnum].rbyte1 |= RB1RD0;
break;
case 1:
fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready
fdc202[fdcnum].rbyte1 |= RB1RD1;
break;
case 2:
fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready
fdc202[fdcnum].rbyte1 |= RB1RD2;
break;
case 3:
fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready
fdc202[fdcnum].rbyte1 |= RB1RD3;
break;
}
fdc202[fdcnum].rtype = ROK;
sim_printf(" iSBC-202%d: FDD: %d Configured %d bytes, Attached to %s\n",
fdcnum, fddnum, uptr->capac, uptr->filename);
sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Done\n");
return SCPE_OK;
}
/* isbc202 set mode = Write protect */
t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_set_mode: Entered with val=%08XH uptr->flags=%08X\n",
val, uptr->flags);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
} else { /* read write */
uptr->flags &= ~val;
}
sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_set_mode: Done\n");
return SCPE_OK;
}
uint8 isbc202_get_dn(void)
{
int i;
for (i=0; i<SBC202_NUM; i++)
if (port >= fdc202[i].baseport && port <= fdc202[i].baseport + 7)
return i;
sim_printf("isbc202_get_dn: port %04X not in isbc202 device table\n", port);
return 0xFF;
}
/* ISBC202 control port functions */
uint8 isbc2020(t_bool io, uint8 data)
{
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read ststus*/
if (DEBUG)
sim_printf("\n isbc202-%d: 0x78 returned status=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].stat, PCX);
return fdc202[fdcnum].stat;
}
}
return 0;
}
uint8 isbc2021(t_bool io, uint8 data)
{
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
fdc202[fdcnum].intff = 0; //clear interrupt FF
fdc202[fdcnum].stat &= ~FDCINT;
if (DEBUG)
sim_printf("\n isbc202-%d: 0x79 returned rtype=%02X intff=%02X status=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rtype, fdc202[fdcnum].intff, fdc202[fdcnum].stat, PCX);
return fdc202[fdcnum].rtype;
} else { /* write data port */
fdc202[fdcnum].iopb = data;
if (DEBUG)
sim_printf("\n isbc202-%d: 0x79 IOPB low=%02X PCX=%04X",
fdcnum, data, PCX);
}
}
return 0;
}
uint8 isbc2022(t_bool io, uint8 data)
{
uint8 fdcnum;
int i;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
;
} else { /* write data port */
fdc202[fdcnum].iopb |= (data << 8);
// if (DEBUG)
sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X",
fdcnum, fdc202[fdcnum].iopb, PCX);
sim_printf("\nIOPB: ");
for (i=0; i<7; i++)
sim_printf("%02X ", multibus_get_mbyte(fdc202[fdcnum].iopb + i));
sim_printf("\n");
isbc202_diskio(fdcnum);
if (fdc202[fdcnum].intff)
fdc202[fdcnum].stat |= FDCINT;
}
}
return 0;
}
uint8 isbc2023(t_bool io, uint8 data)
{
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
if (fdc202[fdcnum].rtype == 0) {
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7B returned rbyte0=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rbyte0, PCX);
return fdc202[fdcnum].rbyte0;
} else {
if (fdc202[fdcnum].rdychg) {
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7B returned rbyte1=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rbyte1, PCX);
return fdc202[fdcnum].rbyte1;
} else {
if (DEBUG)
sim_printf("\n isbc202-%d: 0x7B returned rbytex=%02X PCX=%04X",
fdcnum, 0, PCX);
return 0;
}
}
} else { /* write data port */
; //stop diskette operation
}
}
return 0;
}
uint8 isbc2027(t_bool io, uint8 data)
{
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
;
} else { /* write data port */
isbc202_reset1(fdcnum);
}
}
return 0;
}
// perform the actual disk I/O operation
void isbc202_diskio(uint8 fdcnum)
{
uint8 cw, di, nr, ta, sa, data, nrptr;
uint16 ba;
uint32 dskoff;
uint8 fddnum, fmtb;
uint32 i;
UNIT *uptr;
uint8 *fbuf = (uint8 *) (isbc202_dev.units + fddnum)->filebuf;
//parse the IOPB
cw = multibus_get_mbyte(fdc202[fdcnum].iopb);
di = multibus_get_mbyte(fdc202[fdcnum].iopb + 1);
nr = multibus_get_mbyte(fdc202[fdcnum].iopb + 2);
ta = multibus_get_mbyte(fdc202[fdcnum].iopb + 3);
sa = multibus_get_mbyte(fdc202[fdcnum].iopb + 4);
ba = multibus_get_mword(fdc202[fdcnum].iopb + 5);
fddnum = (di & 0x30) >> 4;
uptr = isbc202_dev.units + fddnum;
if (DEBUG) {
sim_printf("\n isbc202-%d: isbc202_diskio IOPB=%04X FDD=%02X STAT=%02X",
fdcnum, fdc202[fdcnum].iopb, fddnum, fdc202[fdcnum].stat);
sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X",
fdcnum, cw, di, nr, ta, sa, ba);
}
//check for not ready
switch(fddnum) {
case 0:
if ((fdc202[fdcnum].stat & RDY0) == 0) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum);
return;
}
break;
case 1:
if ((fdc202[fdcnum].stat & RDY1) == 0) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum);
return;
}
break;
case 2:
if ((fdc202[fdcnum].stat & RDY2) == 0) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum);
return;
}
break;
case 3:
if ((fdc202[fdcnum].stat & RDY3) == 0) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum);
return;
}
break;
}
//check for address error
if (
((di & 0x07) != DHOME) && (
(sa > MAXSECDD) ||
((sa + nr) > (MAXSECDD + 1)) ||
(sa == 0) ||
(ta > MAXTRK)
)) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0ADR;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Address error on drive %d", fdcnum, fddnum);
return;
}
switch (di & 0x07) { //decode disk command
case DNOP:
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DSEEK:
fdc202[fdcnum].fdd[fddnum].sec = sa;
fdc202[fdcnum].fdd[fddnum].cyl = ta;
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DHOME:
fdc202[fdcnum].fdd[fddnum].sec = sa;
fdc202[fdcnum].fdd[fddnum].cyl = 0;
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DVCRC:
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DFMT:
//check for WP
if(uptr->flags & UNIT_WPMODE) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0WP;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Write protect error 1 on drive %d", fdcnum, fddnum);
return;
}
fmtb = multibus_get_mbyte(ba); //get the format byte
//calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) {
*(fbuf + (dskoff + i)) = fmtb;
}
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DREAD:
nrptr = 0;
while(nrptr < nr) {
//calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
// if (DEBUG)
sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X",
fdcnum, cw, di, nr, ta, sa, ba, dskoff);
for (i=0; i<128; i++) { //copy sector from image to RAM
data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data);
}
sa++;
ba+=0x80;
nrptr++;
}
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DWRITE:
//check for WP
if(uptr->flags & UNIT_WPMODE) {
fdc202[fdcnum].rtype = RERR;
fdc202[fdcnum].rbyte0 = RB0WP;
fdc202[fdcnum].intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Write protect error 2 on drive %d", fdcnum, fddnum);
return;
}
nrptr = 0;
while(nrptr < nr) {
//calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
// if (DEBUG)
// sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X",
// fdcnum, cw, di, nr, ta, sa, ba, dskoff);
for (i=0; i<128; i++) { //copy sector from image to RAM
data = multibus_get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data;
}
sa++;
ba+=0x80;
nrptr++;
}
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
default:
sim_printf("\n isbc202-%d: isbc202_diskio bad di=%02X", fdcnum, di & 0x07);
break;
}
}
/* end of isbc202.c */

View file

@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../IBMPC-Systems/ibmpc/;&quot;../../windows-build/PCRE/include/&quot;"
AdditionalIncludeDirectories="./;../;../Intel-Systems/ibmpc/;&quot;../../windows-build/PCRE/include/&quot;"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
KeepComments="false"
MinimalRebuild="true"
@ -124,7 +124,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../IBMPC-Systems/ibmpc/;&quot;../../windows-build/PCRE/include/&quot;"
AdditionalIncludeDirectories="./;../;../Intel-Systems/ibmpc/;&quot;../../windows-build/PCRE/include/&quot;"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
StringPooling="true"
RuntimeLibrary="0"
@ -189,43 +189,43 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\IBMPC-Systems\common\i8088.c"
RelativePath="..\Intel-Systems\common\i8088.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8237.c"
RelativePath="..\Intel-Systems\common\i8237.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8253.c"
RelativePath="..\Intel-Systems\common\i8253.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8255.c"
RelativePath="..\Intel-Systems\common\i8255.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8259.c"
RelativePath="..\Intel-Systems\common\i8259.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\ibmpc\ibmpc.c"
RelativePath="..\Intel-Systems\ibmpc\ibmpc.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\ibmpc\ibmpc_sys.c"
RelativePath="..\Intel-Systems\ibmpc\ibmpc_sys.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\pcbus.c"
RelativePath="..\Intel-Systems\common\pcbus.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\pceprom.c"
RelativePath="..\Intel-Systems\common\pceprom.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\pcram8.c"
RelativePath="..\Intel-Systems\common\pcram8.c"
>
</File>
<File
@ -330,7 +330,7 @@
>
</File>
<File
RelativePath="..\IBMPC-Systems\ibmpc\system_defs.h"
RelativePath="..\Intel-Systems\ibmpc\system_defs.h"
>
</File>
</Filter>

View file

@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../IBMPC-Systems/ibmpcxt/;&quot;../../windows-build/PCRE/include/&quot;"
AdditionalIncludeDirectories="./;../;../Intel-Systems/ibmpcxt/;&quot;../../windows-build/PCRE/include/&quot;"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
KeepComments="false"
MinimalRebuild="true"
@ -124,7 +124,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../IBMPC-Systems/ibmpcxt/;&quot;../../windows-build/PCRE/include/&quot;"
AdditionalIncludeDirectories="./;../;../Intel-Systems/ibmpcxt/;&quot;../../windows-build/PCRE/include/&quot;"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
StringPooling="true"
RuntimeLibrary="0"
@ -189,43 +189,43 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\IBMPC-Systems\common\i8088.c"
RelativePath="..\Intel-Systems\common\i8088.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8237.c"
RelativePath="..\Intel-Systems\common\i8237.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8253.c"
RelativePath="..\Intel-Systems\common\i8253.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8255.c"
RelativePath="..\Intel-Systems\common\i8255.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\i8259.c"
RelativePath="..\Intel-Systems\common\i8259.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\ibmpcxt\ibmpcxt.c"
RelativePath="..\Intel-Systems\ibmpcxt\ibmpcxt.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\ibmpcxt\ibmpcxt_sys.c"
RelativePath="..\Intel-Systems\ibmpcxt\ibmpcxt_sys.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\pcbus.c"
RelativePath="..\Intel-Systems\common\pcbus.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\pceprom.c"
RelativePath="..\Intel-Systems\common\pceprom.c"
>
</File>
<File
RelativePath="..\IBMPC-Systems\common\pcram8.c"
RelativePath="..\Intel-Systems\common\pcram8.c"
>
</File>
<File
@ -330,7 +330,7 @@
>
</File>
<File
RelativePath="..\IBMPC-Systems\ibmpcxt\system_defs.h"
RelativePath="..\Intel-Systems\ibmpcxt\system_defs.h"
>
</File>
</Filter>

View file

@ -1408,8 +1408,8 @@ IMDS-225 = ${IMDS-225C}/i8080.c ${IMDS-225D}/imds-225_sys.c \
IMDS-225_OPT = -I ${IMDS-225D}
IBMPCD = IBMPC-Systems/ibmpc
IBMPCC = IBMPC-Systems/common
IBMPCD = Intel-Systems/ibmpc
IBMPCC = Intel-Systems/common
IBMPC = ${IBMPCC}/i8255.c ${IBMPCD}/ibmpc.c \
${IBMPCC}/i8088.c ${IBMPCD}/ibmpc_sys.c \
${IBMPCC}/i8253.c ${IBMPCC}/i8259.c \
@ -1418,8 +1418,8 @@ IBMPC = ${IBMPCC}/i8255.c ${IBMPCD}/ibmpc.c \
IBMPC_OPT = -I ${IBMPCD}
IBMPCXTD = IBMPC-Systems/ibmpcxt
IBMPCXTC = IBMPC-Systems/common
IBMPCXTD = Intel-Systems/ibmpcxt
IBMPCXTC = Intel-Systems/common
IBMPCXT = ${IBMPCXTC}/i8088.c ${IBMPCXTD}/ibmpcxt_sys.c \
${IBMPCXTC}/i8253.c ${IBMPCXTC}/i8259.c \
${IBMPCXTC}/i8255.c ${IBMPCXTD}/ibmpcxt.c \
@ -1848,22 +1848,14 @@ ${BIN}imds-225${EXE} : ${IMDS-225} ${SIM} ${BUILD_ROMS}
ibmpc: ${BIN}ibmpc${EXE}
${BIN}ibmpc${EXE} : ${IBMPC} ${SIM} ${BUILD_ROMS}
ifneq (1,$(CPP_BUILD)$(CPP_FORCE))
${MKDIRBIN}
${CC} ${IBMPC} ${SIM} ${IBMPC_OPT} $(CC_OUTSPEC) ${LDFLAGS}
else
$(info ibmpc can't be built using C++)
endif
ibmpcxt: ${BIN}ibmpcxt${EXE}
${BIN}ibmpcxt${EXE} : ${IBMPCXT} ${SIM} ${BUILD_ROMS}
ifneq (1,$(CPP_BUILD)$(CPP_FORCE))
${MKDIRBIN}
${CC} ${IBMPCXT} ${SIM} ${IBMPCXT_OPT} $(CC_OUTSPEC) ${LDFLAGS}
else
$(info ibmpcxt can't be built using C++)
endif
tx-0 : ${BIN}tx-0${EXE}