Intel-Systems: Update and cleanup components

This commit is contained in:
Bill Beech 2019-10-16 13:41:27 -07:00 committed by Mark Pizzolato
parent fac5bc96fb
commit 6af0958209
68 changed files with 10662 additions and 3758 deletions

View file

@ -0,0 +1,275 @@
/* i3214.c: Intel i3214 PICU adapter
Copyright (c) 2019, 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:
12 OCT 19 - Original file.
NOTES:
These functions support a simulated i3214 interface device on an iSBC.
The device had three physical I/O port which could be connected
as needed. This device was replaced by the 8259.
All I/O is via programmed I/O. The i3214 has a status port
and two data port.
save for now!
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"
// 3214 status bits
/* external globals */
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* globals */
uint8 i3214_mask = 0;
uint8 i3214_cnt = 0;
uint8 i3214_ram[16];
uint8 EPROM_enable = 1;
uint8 BUS_OVERRIDE = 0;
uint8 monitor_boot = 0x00;
/* function prototypes */
t_stat i3214_cfg(uint8 base, uint8 devnum);
t_stat i3214_reset (DEVICE *dptr);
t_stat i3214_reset_dev (uint8 devnum);
t_stat i3214_svc (UNIT *uptr);
uint8 i3214_do_mask(t_bool io, uint8 data, uint8 devnum);
uint8 i3214_do_status(t_bool io, uint8 data, uint8 devnum);
uint8 i3214_cpu_bus_override(t_bool io, uint8 data, uint8 devnum);
uint8 i3214_monitor_do_boot(t_bool io, uint8 data, uint8 devnum);
/* i3214 Standard I/O Data Structures */
/* 1 i3214 device */
UNIT i3214_unit[] = {
{ UDATA (&i3214_svc, 0, 0), KBD_POLL_WAIT }
};
REG i3214_reg[] = {
{ HRDATA (MASK0, i3214_mask, 8) },
{ HRDATA (CNT0, i3214_cnt, 8) },
{ HRDATA (RAM0, i3214_ram, 8) },
{ NULL }
};
DEBTAB i3214_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i3214_mod[] = {
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i3214_dev = {
"I3214", //name
i3214_unit, //units
i3214_reg, //registers
i3214_mod, //modifiers
I3214_NUM, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i3214_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i3214_debug, //debflags
NULL, //msize
NULL //lname
};
// i3214 configuration
t_stat i3214_cfg(uint8 base, uint8 devnum)
{
sim_printf(" i3214[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i3214_do_mask, base, devnum);
reg_dev(i3214_do_status, base + 1, devnum);
reg_dev(i3214_cpu_bus_override, base + 2, devnum);
reg_dev(i3214_monitor_do_boot, base + 3, devnum);
return SCPE_OK;
}
/* Service routines to handle simulator functions */
/* i3214_svc - actually gets char & places in buffer */
t_stat i3214_svc (UNIT *uptr)
{
return SCPE_OK;
}
/* Reset routine */
t_stat i3214_reset (DEVICE *dptr)
{
uint8 devnum;
for (devnum=0; devnum<I3214_NUM; devnum++) {
i3214_reset_dev(devnum);
sim_activate (&i3214_unit[devnum], i3214_unit[devnum].wait); /* activate unit */
}
return SCPE_OK;
}
t_stat i3214_reset_dev (uint8 devnum)
{
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
// 3214 device routines
uint8 i3214_do_mask(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) /* read status port */
return i3214_mask;
else
i3214_mask = data;
return 0;
}
uint8 i3214_do_status(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0)
return 0;
else {
i3214_cnt--;
}
return 0;
}
uint8 i3214_cpu_bus_override(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) /* read status port */
return 0;
else
BUS_OVERRIDE = data & 0x01;
return 0;
}
uint8 i3214_monitor_do_boot(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) /* read status port */
return monitor_boot;
else
monitor_boot = data;
return 0;
}
/* end of i3214.c */

View file

@ -117,6 +117,8 @@
#define UNIT_8085 (1 << UNIT_V_8085) #define UNIT_8085 (1 << UNIT_V_8085)
#define UNIT_V_TRACE (UNIT_V_UF+2) /* Trace switch */ #define UNIT_V_TRACE (UNIT_V_UF+2) /* Trace switch */
#define UNIT_TRACE (1 << UNIT_V_TRACE) #define UNIT_TRACE (1 << UNIT_V_TRACE)
#define UNIT_V_XACK (UNIT_V_UF+3) /* XACK switch */
#define UNIT_XACK (1 << UNIT_V_XACK)
/* Flag values to set proper positions in PSW */ /* Flag values to set proper positions in PSW */
#define CF 0x01 #define CF 0x01
@ -166,13 +168,18 @@ uint32 saved_PC = 0; /* program counter */
uint32 IM = 0; /* Interrupt Mask Register */ uint32 IM = 0; /* Interrupt Mask Register */
uint8 xack = 0; /* XACK signal */ uint8 xack = 0; /* XACK signal */
uint32 int_req = 0; /* Interrupt request */ uint32 int_req = 0; /* Interrupt request */
uint8 INTA = 0; // interrupt acknowledge
int32 PCX; /* External view of PC */ int32 PCX; /* External view of PC */
int32 PCY; /* Internal view of PC */
int32 PC; int32 PC;
UNIT *uptr; UNIT *uptr;
uint16 port; //port used in any IN/OUT uint16 port; //port used in any IN/OUT
uint16 addr; //addr used for operand fetch
uint32 IR;
uint16 devnum = 0;
/* function prototypes */ /* function prototypes */
void set_cpuint(int32 int_num); void set_cpuint(int32 int_num);
void dumpregs(void); void dumpregs(void);
int32 fetch_byte(int32 flag); int32 fetch_byte(int32 flag);
@ -204,10 +211,9 @@ extern void put_mword(uint16 addr, uint16 val);
extern int32 sim_int_char; extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
struct idev { struct idev {
uint8 (*routine)(t_bool, uint8); uint8 (*routine)(t_bool, uint8, uint8);
uint16 port; uint8 port;
uint8 devnum; uint8 devnum;
}; };
@ -249,6 +255,8 @@ MTAB i8080_mod[] = {
{ UNIT_OPSTOP, UNIT_OPSTOP, "NOITRAP", "NOITRAP", NULL }, { UNIT_OPSTOP, UNIT_OPSTOP, "NOITRAP", "NOITRAP", NULL },
{ UNIT_TRACE, 0, "NOTRACE", "NOTRACE", NULL }, { UNIT_TRACE, 0, "NOTRACE", "NOTRACE", NULL },
{ UNIT_TRACE, UNIT_TRACE, "TRACE", "TRACE", NULL }, { UNIT_TRACE, UNIT_TRACE, "TRACE", "TRACE", NULL },
{ UNIT_XACK, 0, "NOXACK", "NOXACK", NULL },
{ UNIT_XACK, UNIT_XACK, "XACK", "XACK", NULL },
{ 0 } { 0 }
}; };
@ -277,12 +285,11 @@ DEVICE i8080_dev = {
8, //dwidth 8, //dwidth
&i8080_ex, //examine &i8080_ex, //examine
&i8080_dep, //deposit &i8080_dep, //deposit
// &i8080_reset, //reset
NULL, //reset NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //context
DEV_DEBUG, //flags DEV_DEBUG, //flags
0, //dctrl 0, //dctrl
i8080_debug, //debflags i8080_debug, //debflags
@ -356,7 +363,7 @@ const char *opcode[] = {
"CP ", "PUSH PSW", "ORI ", "RST 6", "CP ", "PUSH PSW", "ORI ", "RST 6",
"RM", "SPHL", "JM ", "EI", "RM", "SPHL", "JM ", "EI",
"CM ", "???", "CPI ", "RST 7", "CM ", "???", "CPI ", "RST 7",
}; };
int32 oplen[256] = { int32 oplen[256] = {
1,3,1,1,1,1,2,1,0,1,1,1,1,1,2,1, 1,3,1,1,1,1,2,1,0,1,1,1,1,1,2,1,
@ -374,7 +381,8 @@ int32 oplen[256] = {
1,1,3,3,3,1,2,1,1,1,3,0,3,3,2,1, 1,1,3,3,3,1,2,1,1,1,3,0,3,3,2,1,
1,1,3,2,3,1,2,1,1,0,3,2,3,0,2,1, 1,1,3,2,3,1,2,1,1,0,3,2,3,0,2,1,
1,1,3,1,3,1,2,1,1,1,3,1,3,0,2,1, 1,1,3,1,3,1,2,1,1,1,3,1,3,0,2,1,
1,1,3,1,3,1,2,1,1,1,3,1,3,0,2,1 }; 1,1,3,1,3,1,2,1,1,1,3,1,3,0,2,1
};
void set_cpuint(int32 int_num) void set_cpuint(int32 int_num)
{ {
@ -383,19 +391,24 @@ void set_cpuint(int32 int_num)
/* instruction simulator */ /* instruction simulator */
int32 sim_instr (void) int32 sim_instr(void)
{ {
extern int32 sim_interval; extern int32 sim_interval;
uint32 IR, OP, DAR, reason, adr; uint32 OP, DAR, reason, adr, onetime = 0;
PC = saved_PC & WORD_R; /* load local PC */ PC = saved_PC & WORD_R; /* load local PC */
reason = 0; reason = 0;
uptr = i8080_dev.units; uptr = i8080_dev.units;
if (onetime++ == 0) {
if (uptr->flags & UNIT_8085) if (uptr->flags & UNIT_8085)
sim_printf("CPU = 8085\n"); sim_printf("CPU = 8085\n");
else else
sim_printf("CPU = 8080\n"); sim_printf("CPU = 8080\n");
sim_printf(" i8080:\n");
}
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */
while (reason == 0) { /* loop until halted */ while (reason == 0) { /* loop until halted */
@ -437,9 +450,11 @@ int32 sim_instr (void)
} }
} else { /* 8080 */ } else { /* 8080 */
if (IM & IE) { /* enabled? */ if (IM & IE) { /* enabled? */
push_word(PC); /* do an RST 7 */ INTA = 1;
PC = 0x0038; push_word(PC); /* do an RST 2 */
int_req &= ~INT_R; PC = 0x0010;
int_req = 0;
// sim_printf("8080 Interrupt\n");
} }
} }
} /* end interrupt */ } /* end interrupt */
@ -450,18 +465,20 @@ int32 sim_instr (void)
break; break;
} }
sim_interval--; /* countdown clock */
PCX = PC;
if (uptr->flags & UNIT_TRACE) { if (uptr->flags & UNIT_TRACE) {
dumpregs(); dumpregs();
sim_printf("\n"); // sim_printf("\n");
} }
sim_interval--; /* countdown clock */
PCY = PCX = PC;
IR = OP = fetch_byte(0); /* instruction fetch */ IR = OP = fetch_byte(0); /* instruction fetch */
if (GET_XACK(1) == 0) { /* no XACK for instruction fetch */ if (GET_XACK(1) == 0) { // no XACK for instruction fetch
// reason = STOP_XACK; // reason = STOP_XACK;
sim_printf("Stopped for XACK-1 PC=%04X\n", PC); if (uptr->flags & UNIT_XACK)
sim_printf("Failed XACK for Instruction Fetch from %04X\n", PCX);
// continue; // continue;
} }
@ -509,6 +526,7 @@ int32 sim_instr (void)
DAR = A; DAR = A;
DAR -= getreg(OP & 0x07); DAR -= getreg(OP & 0x07);
setarith(DAR); setarith(DAR);
A &= BYTE_R; //required ***
goto loop_end; goto loop_end;
} }
@ -589,6 +607,7 @@ int32 sim_instr (void)
DAR = getreg((OP >> 3) & 0x07); DAR = getreg((OP >> 3) & 0x07);
DAR++; DAR++;
setinc(DAR); setinc(DAR);
DAR &= BYTE_R; //required
putreg((OP >> 3) & 0x07, DAR); putreg((OP >> 3) & 0x07, DAR);
goto loop_end; goto loop_end;
} }
@ -597,6 +616,7 @@ int32 sim_instr (void)
DAR = getreg((OP >> 3) & 0x07); DAR = getreg((OP >> 3) & 0x07);
DAR--; DAR--;
setinc(DAR); setinc(DAR);
DAR &= BYTE_R; //required
putreg((OP >> 3) & 0x07, DAR); putreg((OP >> 3) & 0x07, DAR);
goto loop_end; goto loop_end;
} }
@ -604,6 +624,7 @@ int32 sim_instr (void)
if ((OP & 0xCF) == 0x03) { /* INX */ if ((OP & 0xCF) == 0x03) { /* INX */
DAR = getpair((OP >> 4) & 0x03); DAR = getpair((OP >> 4) & 0x03);
DAR++; DAR++;
DAR &= WORD_R; //required
putpair((OP >> 4) & 0x03, DAR); putpair((OP >> 4) & 0x03, DAR);
goto loop_end; goto loop_end;
} }
@ -611,6 +632,7 @@ int32 sim_instr (void)
if ((OP & 0xCF) == 0x0B) { /* DCX */ if ((OP & 0xCF) == 0x0B) { /* DCX */
DAR = getpair((OP >> 4) & 0x03); DAR = getpair((OP >> 4) & 0x03);
DAR--; DAR--;
DAR &= WORD_R; //required
putpair((OP >> 4) & 0x03, DAR); putpair((OP >> 4) & 0x03, DAR);
goto loop_end; goto loop_end;
} }
@ -767,7 +789,6 @@ int32 sim_instr (void)
if (GET_FLAG(CF)) if (GET_FLAG(CF))
A--; A--;
A &= BYTE_R; //required A &= BYTE_R; //required
A &= BYTE_R;
break; break;
case 0x27: /* DAA */ case 0x27: /* DAA */
@ -788,41 +809,47 @@ int32 sim_instr (void)
COND_SET_FLAG(DAR & 0x10, CF); COND_SET_FLAG(DAR & 0x10, CF);
COND_SET_FLAG(A & 0x80, SF); COND_SET_FLAG(A & 0x80, SF);
COND_SET_FLAG((A & 0xFF) == 0, ZF); COND_SET_FLAG((A & 0xFF) == 0, ZF);
A &= BYTE_R; //required
parity(A); parity(A);
break; break;
case 0x07: /* RLC */ case 0x07: /* RLC */
COND_SET_FLAG(A & 0x80, CF); COND_SET_FLAG(A & 0x80, CF);
A = (A << 1) & 0xFF; A = A << 1;
if (GET_FLAG(CF)) if (GET_FLAG(CF))
A |= 0x01; A |= 0x01;
A &= BYTE_R; //required
break; break;
case 0x0F: /* RRC */ case 0x0F: /* RRC */
COND_SET_FLAG(A & 0x01, CF); COND_SET_FLAG(A & 0x01, CF);
A = (A >> 1) & 0xFF; A = A >> 1;
if (GET_FLAG(CF)) if (GET_FLAG(CF))
A |= 0x80; A |= 0x80;
A &= BYTE_R; //required
break; break;
case 0x17: /* RAL */ case 0x17: /* RAL */
DAR = GET_FLAG(CF); DAR = GET_FLAG(CF);
COND_SET_FLAG(A & 0x80, CF); COND_SET_FLAG(A & 0x80, CF);
A = (A << 1) & 0xFF; A = A << 1;
if (DAR) if (DAR)
A |= 0x01; A |= 0x01;
A &= BYTE_R; //required
break; break;
case 0x1F: /* RAR */ case 0x1F: /* RAR */
DAR = GET_FLAG(CF); DAR = GET_FLAG(CF);
COND_SET_FLAG(A & 0x01, CF); COND_SET_FLAG(A & 0x01, CF);
A = (A >> 1) & 0xFF; A = A >> 1;
if (DAR) if (DAR)
A |= 0x80; A |= 0x80;
A &= BYTE_R; //required
break; break;
case 0x2F: /* CMA */ case 0x2F: /* CMA */
A = ~A; A = ~A;
A &= BYTE_R; //required
break; break;
case 0x3F: /* CMC */ case 0x3F: /* CMC */
@ -857,15 +884,13 @@ int32 sim_instr (void)
break; break;
case 0xDB: /* IN */ case 0xDB: /* IN */
DAR = fetch_byte(1); port = fetch_byte(1);
port = DAR; A = dev_table[port].routine(0, 0, dev_table[port].devnum);
A = dev_table[DAR].routine(0, 0);
break; break;
case 0xD3: /* OUT */ case 0xD3: /* OUT */
DAR = fetch_byte(1); port = fetch_byte(1);
port = DAR; dev_table[port].routine(1, A, dev_table[port].devnum);
dev_table[DAR].routine(1, A);
break; break;
default: /* undefined opcode */ default: /* undefined opcode */
@ -876,12 +901,19 @@ int32 sim_instr (void)
break; break;
} }
loop_end: loop_end:
if (GET_XACK(1) == 0) { /* no XACK for instruction fetch */
if (GET_XACK(1) == 0) { // no XACK for operand fetch
// reason = STOP_XACK; // reason = STOP_XACK;
// sim_printf("Stopped for XACK-2 PC=%04X\n", PC); if (OP == 0xD3 || OP == 0xDB) {
if (uptr->flags & UNIT_XACK)
sim_printf("Failed XACK for Port %02X Fetch from %04X\n", port, PCX);
} else {
if (uptr->flags & UNIT_XACK)
sim_printf("Failed XACK for Operand %04X Fetch from %04X\n", addr, PCX);
// continue; // continue;
} }
} }
}
/* Simulation halted */ /* Simulation halted */
@ -892,8 +924,9 @@ loop_end:
/* dump the registers */ /* dump the registers */
void dumpregs(void) void dumpregs(void)
{ {
sim_printf(" A=%02X BC=%04X DE=%04X HL=%04X SP=%04X IM=%02X XACK=%d\n", sim_printf(" PC=%04X A=%02X BC=%04X DE=%04X HL=%04X SP=%04X IM=%02X XACK=%d",
A, BC, DE, HL, SP, IM, xack); PCY, A, BC, DE, HL, SP, IM, xack);
sim_printf(" IR=%02X addr=%04X", IR, addr);
sim_printf(" CF=%d ZF=%d AF=%d SF=%d PF=%d\n", sim_printf(" CF=%d ZF=%d AF=%d SF=%d PF=%d\n",
GET_FLAG(CF) ? 1 : 0, GET_FLAG(CF) ? 1 : 0,
GET_FLAG(ZF) ? 1 : 0, GET_FLAG(ZF) ? 1 : 0,
@ -901,24 +934,15 @@ void dumpregs(void)
GET_FLAG(SF) ? 1 : 0, GET_FLAG(SF) ? 1 : 0,
GET_FLAG(PF) ? 1 : 0); GET_FLAG(PF) ? 1 : 0);
} }
/* fetch an instruction or byte */ /* fetch an instruction or byte */
int32 fetch_byte(int32 flag) int32 fetch_byte(int32 flag)
{ {
uint32 val; uint32 val;
val = get_mbyte(PC) & 0xFF; /* fetch byte */ val = get_mbyte(PC) & 0xFF; /* fetch byte */
if (i8080_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE) { /* display source code */
switch (flag) {
case 0: /* opcode fetch */
sim_printf("OP=%02X %04X %s", val, PC, opcode[val]);
break;
case 1: /* byte operand fetch */
sim_printf("0%02XH", val);
break;
}
}
PC = (PC + 1) & ADDRMASK; /* increment PC */ PC = (PC + 1) & ADDRMASK; /* increment PC */
val &= BYTE_R; addr = val & 0xff;
return val; return val;
} }
@ -929,10 +953,11 @@ int32 fetch_word(void)
val = get_mbyte(PC) & BYTE_R; /* fetch low byte */ val = get_mbyte(PC) & BYTE_R; /* fetch low byte */
val |= get_mbyte(PC + 1) << 8; /* fetch high byte */ val |= get_mbyte(PC + 1) << 8; /* fetch high byte */
if (i8080_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE) /* display source code */ // if (i8080_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE) /* display source code */
sim_printf("0%04XH", val); // sim_printf("0%04XH", val);
PC = (PC + 2) & ADDRMASK; /* increment PC */ PC = (PC + 2) & ADDRMASK; /* increment PC */
val &= WORD_R; val &= WORD_R;
addr = val;
return val; return val;
} }
@ -1039,7 +1064,7 @@ void parity(int32 reg)
SET_FLAG(PF); SET_FLAG(PF);
} }
/* Set the <S>ign, <Z>ero amd <P>arity flags following /* Set the <S>ign, <Z>ero and <P>arity flags following
an INR/DCR operation on 'reg'. an INR/DCR operation on 'reg'.
*/ */
@ -1156,7 +1181,7 @@ int32 getpush(int32 reg)
/* Place data into the indicated register pair, in PUSH /* Place data into the indicated register pair, in PUSH
format where 3 means A& flags, not SP */ format where 3 means A & flags, not SP */
void putpush(int32 reg, int32 data) void putpush(int32 reg, int32 data)
{ {
switch (reg) { switch (reg) {
@ -1210,8 +1235,8 @@ t_stat i8080_reset (DEVICE *dptr)
saved_PC = 0; saved_PC = 0;
int_req = 0; int_req = 0;
IM = 0; IM = 0;
INTA = 0;
sim_brk_types = sim_brk_dflt = SWMASK ('E'); sim_brk_types = sim_brk_dflt = SWMASK ('E');
sim_printf(" 8080: Reset\n");
return SCPE_OK; return SCPE_OK;
} }
@ -1245,8 +1270,9 @@ int32 sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
{ {
int32 i, addr = 0, cnt = 0; int32 i, addr = 0, cnt = 0;
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; if ((*cptr != 0)) return SCPE_ARG;
addr = saved_PC; if (flag == 0) { //load
// addr = saved_PC;
while ((i = getc (fileref)) != EOF) { while ((i = getc (fileref)) != EOF) {
put_mbyte(addr, i); put_mbyte(addr, i);
addr++; addr++;
@ -1254,6 +1280,16 @@ int32 sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
} /* end while */ } /* end while */
sim_printf ("%d Bytes loaded.\n", cnt); sim_printf ("%d Bytes loaded.\n", cnt);
return (SCPE_OK); return (SCPE_OK);
} else { //dump
// addr = saved_PC;
while (addr <= 0xffff) {
i = get_mbyte(addr);
putc(i, fileref);
addr++;
cnt++;
}
}
return (SCPE_OK);
} }
/* Symbolic output - working /* Symbolic output - working

View file

@ -239,11 +239,6 @@
extern uint16 port; //port called in dev_table[port] extern uint16 port; //port called in dev_table[port]
/* globals */
int32 i8237_devnum = 0; //actual number of 8253 instances + 1
uint16 i8237_port[4]; //base port registered to each instance
/* internal function prototypes */ /* internal function prototypes */
t_stat i8237_svc (UNIT *uptr); t_stat i8237_svc (UNIT *uptr);
@ -271,32 +266,37 @@ uint8 i8237_rFx(t_bool io, uint8 data);
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16); extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
/* globals */
int32 i8237_devnum = 0; //actual number of 8253 instances + 1
uint16 i8237_port[4]; //base port registered to each instance
/* 8237 physical register definitions */ /* 8237 physical register definitions */
uint16 i8237_r0; // 8237 ch 0 address register uint16 i8237_r0[4]; // 8237 ch 0 address register
uint16 i8237_r1; // 8237 ch 0 count register uint16 i8237_r1[4]; // 8237 ch 0 count register
uint16 i8237_r2; // 8237 ch 1 address register uint16 i8237_r2[4]; // 8237 ch 1 address register
uint16 i8237_r3; // 8237 ch 1 count register uint16 i8237_r3[4]; // 8237 ch 1 count register
uint16 i8237_r4; // 8237 ch 2 address register uint16 i8237_r4[4]; // 8237 ch 2 address register
uint16 i8237_r5; // 8237 ch 2 count register uint16 i8237_r5[4]; // 8237 ch 2 count register
uint16 i8237_r6; // 8237 ch 3 address register uint16 i8237_r6[4]; // 8237 ch 3 address register
uint16 i8237_r7; // 8237 ch 3 count register uint16 i8237_r7[4]; // 8237 ch 3 count register
uint8 i8237_r8; // 8237 status register uint8 i8237_r8[4]; // 8237 status register
uint8 i8237_r9; // 8237 command register uint8 i8237_r9[4]; // 8237 command register
uint8 i8237_rA; // 8237 mode register uint8 i8237_rA[4]; // 8237 mode register
uint8 i8237_rB; // 8237 mask register uint8 i8237_rB[4]; // 8237 mask register
uint8 i8237_rC; // 8237 request register uint8 i8237_rC[4]; // 8237 request register
uint8 i8237_rD; // 8237 first/last ff uint8 i8237_rD[4]; // 8237 first/last ff
uint8 i8237_rE; // 8237 uint8 i8237_rE[4]; // 8237
uint8 i8237_rF; // 8237 uint8 i8237_rF[4]; // 8237
/* i8237 physical register definitions */ /* i8237 physical register definitions */
uint16 i8237_sr; // isbc-208 segment register uint16 i8237_sr[4]; // 8237 segment register
uint8 i8237_i; // iSBC-208 interrupt register uint8 i8237_i[4]; // 8237 interrupt register
uint8 i8237_a; // iSBC-208 auxillary port register uint8 i8237_a[4]; // 8237 auxillary port register
/* i8237 Standard SIMH Device Data Structures - 1 unit */ /* i8237 Standard SIMH Device Data Structures - 4 units */
UNIT i8237_unit[] = { UNIT i8237_unit[] = {
{ UDATA (0, 0, 0) ,20 }, /* i8237 0 */ { UDATA (0, 0, 0) ,20 }, /* i8237 0 */
@ -305,25 +305,75 @@ UNIT i8237_unit[] = {
{ UDATA (0, 0, 0) ,20 } /* i8237 3 */ { UDATA (0, 0, 0) ,20 } /* i8237 3 */
}; };
REG i8237_reg[] = { REG i8237_reg[] = {
{ HRDATA (CH0ADR, i8237_r0, 16) }, { HRDATA (CH0ADR0, i8237_r0[0], 16) }, /* i8237 0 */
{ HRDATA (CH0CNT, i8237_r1, 16) }, { HRDATA (CH0CNT0, i8237_r1[0], 16) },
{ HRDATA (CH1ADR, i8237_r2, 16) }, { HRDATA (CH1ADR0, i8237_r2[0], 16) },
{ HRDATA (CH1CNT, i8237_r3, 16) }, { HRDATA (CH1CNT0, i8237_r3[0], 16) },
{ HRDATA (CH2ADR, i8237_r4, 16) }, { HRDATA (CH2ADR0, i8237_r4[0], 16) },
{ HRDATA (CH2CNT, i8237_r5, 16) }, { HRDATA (CH2CNT0, i8237_r5[0], 16) },
{ HRDATA (CH3ADR, i8237_r6, 16) }, { HRDATA (CH3ADR0, i8237_r6[0], 16) },
{ HRDATA (CH3CNT, i8237_r7, 16) }, { HRDATA (CH3CNT0, i8237_r7[0], 16) },
{ HRDATA (STAT37, i8237_r8, 8) }, { HRDATA (STAT370, i8237_r8[0], 8) },
{ HRDATA (CMD37, i8237_r9, 8) }, { HRDATA (CMD370, i8237_r9[0], 8) },
{ HRDATA (MODE, i8237_rA, 8) }, { HRDATA (MODE0, i8237_rA[0], 8) },
{ HRDATA (MASK, i8237_rB, 8) }, { HRDATA (MASK0, i8237_rB[0], 8) },
{ HRDATA (REQ, i8237_rC, 8) }, { HRDATA (REQ0, i8237_rC[0], 8) },
{ HRDATA (FF, i8237_rD, 8) }, { HRDATA (FF0, i8237_rD[0], 8) },
{ HRDATA (SEGREG, i8237_sr, 8) }, { HRDATA (SEGREG0, i8237_sr[0], 8) },
{ HRDATA (AUX, i8237_a, 8) }, { HRDATA (AUX0, i8237_a[0], 8) },
{ HRDATA (INT, i8237_i, 8) }, { HRDATA (INT0, i8237_i[0], 8) },
{ HRDATA (CH0ADR1, i8237_r0[1], 16) }, /* i8237 1 */
{ HRDATA (CH0CNT1, i8237_r1[1], 16) },
{ HRDATA (CH1ADR1, i8237_r2[1], 16) },
{ HRDATA (CH1CNT1, i8237_r3[1], 16) },
{ HRDATA (CH2ADR1, i8237_r4[1], 16) },
{ HRDATA (CH2CNT1, i8237_r5[1], 16) },
{ HRDATA (CH3ADR1, i8237_r6[1], 16) },
{ HRDATA (CH3CNT1, i8237_r7[1], 16) },
{ HRDATA (STAT371, i8237_r8[1], 8) },
{ HRDATA (CMD371, i8237_r9[1], 8) },
{ HRDATA (MODE1, i8237_rA[1], 8) },
{ HRDATA (MASK1, i8237_rB[1], 8) },
{ HRDATA (REQ1, i8237_rC[1], 8) },
{ HRDATA (FF1, i8237_rD[1], 8) },
{ HRDATA (SEGREG1, i8237_sr[1], 8) },
{ HRDATA (AUX1, i8237_a[1], 8) },
{ HRDATA (INT1, i8237_i[1], 8) },
{ HRDATA (CH0ADR2, i8237_r0[2], 16) }, /* i8237 2 */
{ HRDATA (CH0CNT2, i8237_r1[2], 16) },
{ HRDATA (CH1ADR2, i8237_r2[2], 16) },
{ HRDATA (CH1CNT2, i8237_r3[2], 16) },
{ HRDATA (CH2ADR2, i8237_r4[2], 16) },
{ HRDATA (CH2CNT2, i8237_r5[2], 16) },
{ HRDATA (CH3ADR2, i8237_r6[2], 16) },
{ HRDATA (CH3CNT2, i8237_r7[2], 16) },
{ HRDATA (STAT372, i8237_r8[2], 8) },
{ HRDATA (CMD372, i8237_r9[2], 8) },
{ HRDATA (MODE2, i8237_rA[2], 8) },
{ HRDATA (MASK2, i8237_rB[2], 8) },
{ HRDATA (REQ2, i8237_rC[2], 8) },
{ HRDATA (FF2, i8237_rD[2], 8) },
{ HRDATA (SEGREG2, i8237_sr[2], 8) },
{ HRDATA (AUX2, i8237_a[2], 8) },
{ HRDATA (INT2, i8237_i[2], 8) },
{ HRDATA (CH0ADR3, i8237_r0[3], 16) }, /* i8237 3 */
{ HRDATA (CH0CNT3, i8237_r1[3], 16) },
{ HRDATA (CH1ADR3, i8237_r2[3], 16) },
{ HRDATA (CH1CNT3, i8237_r3[3], 16) },
{ HRDATA (CH2ADR3, i8237_r4[3], 16) },
{ HRDATA (CH2CNT3, i8237_r5[3], 16) },
{ HRDATA (CH3ADR3, i8237_r6[3], 16) },
{ HRDATA (CH3CNT3, i8237_r7[3], 16) },
{ HRDATA (STAT373, i8237_r8[3], 8) },
{ HRDATA (CMD373, i8237_r9[3], 8) },
{ HRDATA (MODE3, i8237_rA[3], 8) },
{ HRDATA (MASK3, i8237_rB[3], 8) },
{ HRDATA (REQ3, i8237_rC[3], 8) },
{ HRDATA (FF3, i8237_rD[3], 8) },
{ HRDATA (SEGREG3, i8237_sr[3], 8) },
{ HRDATA (AUX3, i8237_a[3], 8) },
{ HRDATA (INT3, i8237_i[3], 8) },
{ NULL } { NULL }
}; };
@ -347,7 +397,7 @@ DEVICE i8237_dev = {
i8237_unit, //units i8237_unit, //units
i8237_reg, //registers i8237_reg, //registers
i8237_mod, //modifiers i8237_mod, //modifiers
1, //numunits I8237_NUM, //numunits
16, //aradix 16, //aradix
32, //awidth 32, //awidth
1, //aincr 1, //aincr
@ -355,15 +405,13 @@ DEVICE i8237_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &i8237_reset, //deposit
NULL, //reset NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags 0, //flags
0, //dctrl 0, //dctrl
// DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
i8237_debug, //debflags i8237_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL //lname
@ -428,6 +476,7 @@ void i8237_reset1(void)
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
static int flag = 1; static int flag = 1;
uint8 devnum;
for (i = 0; i < 1; i++) { /* handle all units */ for (i = 0; i < 1; i++) { /* handle all units */
uptr = i8237_dev.units + i; uptr = i8237_dev.units + i;
@ -448,11 +497,12 @@ void i8237_reset1(void)
// sim_printf(" SBC208%d: Configured, Attached to %s\n", i, uptr->filename); // sim_printf(" SBC208%d: Configured, Attached to %s\n", i, uptr->filename);
} }
} }
i8237_r8 = 0; /* status */ devnum = uptr->u6;
i8237_r9 = 0; /* command */ i8237_r8[devnum] = 0; /* status */
i8237_rB = 0x0F; /* mask */ i8237_r9[devnum] = 0; /* command */
i8237_rC = 0; /* request */ i8237_rB[devnum] = 0x0F; /* mask */
i8237_rD = 0; /* first/last FF */ i8237_rC[devnum] = 0; /* request */
i8237_rD[devnum] = 0; /* first/last FF */
} }
@ -481,24 +531,24 @@ uint8 i8237_r0x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current address CH 0 */ if (io == 0) { /* read current address CH 0 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(H) read as %04X\n", i8237_r0); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[devnum](H) read as %04X\n", i8237_r0[devnum]);
return (i8237_r0 >> 8); return (i8237_r0[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) read as %04X\n", i8237_r0); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[devnum](L) read as %04X\n", i8237_r0[devnum]);
return (i8237_r0 & 0xFF); return (i8237_r0[devnum] & 0xFF);
} }
} else { /* write base & current address CH 0 */ } else { /* write base & current address CH 0 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r0 |= (data << 8); i8237_r0[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(H) set to %04X\n", i8237_r0); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[devnum](H) set to %04X\n", i8237_r0[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r0 = data & 0xFF; i8237_r0[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0(L) set to %04X\n", i8237_r0); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r0[devnum](L) set to %04X\n", i8237_r0[devnum]);
} }
return 0; return 0;
} }
@ -512,24 +562,24 @@ uint8 i8237_r1x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current word count CH 0 */ if (io == 0) { /* read current word count CH 0 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(H) read as %04X\n", i8237_r1); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[devnum](H) read as %04X\n", i8237_r1[devnum]);
return (i8237_r1 >> 8); return (i8237_r1[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) read as %04X\n", i8237_r1); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[devnum](L) read as %04X\n", i8237_r1[devnum]);
return (i8237_r1 & 0xFF); return (i8237_r1[devnum] & 0xFF);
} }
} else { /* write base & current address CH 0 */ } else { /* write base & current address CH 0 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r1 |= (data << 8); i8237_r1[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(H) set to %04X\n", i8237_r1); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[devnum](H) set to %04X\n", i8237_r1[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r1 = data & 0xFF; i8237_r1[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1(L) set to %04X\n", i8237_r1); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r1[devnum](L) set to %04X\n", i8237_r1[devnum]);
} }
return 0; return 0;
} }
@ -543,24 +593,24 @@ uint8 i8237_r2x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current address CH 1 */ if (io == 0) { /* read current address CH 1 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(H) read as %04X\n", i8237_r2); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[devnum](H) read as %04X\n", i8237_r2[devnum]);
return (i8237_r2 >> 8); return (i8237_r2[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) read as %04X\n", i8237_r2); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[devnum](L) read as %04X\n", i8237_r2[devnum]);
return (i8237_r2 & 0xFF); return (i8237_r2[devnum] & 0xFF);
} }
} else { /* write base & current address CH 1 */ } else { /* write base & current address CH 1 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r2 |= (data << 8); i8237_r2[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(H) set to %04X\n", i8237_r2); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[devnum](H) set to %04X\n", i8237_r2[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r2 = data & 0xFF; i8237_r2[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2(L) set to %04X\n", i8237_r2); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r2[devnum](L) set to %04X\n", i8237_r2[devnum]);
} }
return 0; return 0;
} }
@ -574,24 +624,24 @@ uint8 i8237_r3x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current word count CH 1 */ if (io == 0) { /* read current word count CH 1 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(H) read as %04X\n", i8237_r3); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3[devnum](H) read as %04X\n", i8237_r3[devnum]);
return (i8237_r3 >> 8); return (i8237_r3[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(L) read as %04X\n", i8237_r3); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3[devnum](L) read as %04X\n", i8237_r3[devnum]);
return (i8237_r3 & 0xFF); return (i8237_r3[devnum] & 0xFF);
} }
} else { /* write base & current address CH 1 */ } else { /* write base & current address CH 1 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r3 |= (data << 8); i8237_r3[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(H) set to %04X\n", i8237_r3); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3[devnum](H) set to %04X\n", i8237_r3[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r3 = data & 0xFF; i8237_r3[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3(L) set to %04X\n", i8237_r3); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r3[devnum](L) set to %04X\n", i8237_r3[devnum]);
} }
return 0; return 0;
} }
@ -605,24 +655,24 @@ uint8 i8237_r4x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current address CH 2 */ if (io == 0) { /* read current address CH 2 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(H) read as %04X\n", i8237_r4); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4[devnum](H) read as %04X\n", i8237_r4[devnum]);
return (i8237_r4 >> 8); return (i8237_r4[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(L) read as %04X\n", i8237_r4); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4[devnum](L) read as %04X\n", i8237_r4[devnum]);
return (i8237_r4 & 0xFF); return (i8237_r4[devnum] & 0xFF);
} }
} else { /* write base & current address CH 2 */ } else { /* write base & current address CH 2 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r4 |= (data << 8); i8237_r4[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(H) set to %04X\n", i8237_r4); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4[devnum](H) set to %04X\n", i8237_r4[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r4 = data & 0xFF; i8237_r4[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4(L) set to %04X\n", i8237_r4); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r4[devnum](L) set to %04X\n", i8237_r4[devnum]);
} }
return 0; return 0;
} }
@ -636,24 +686,24 @@ uint8 i8237_r5x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current word count CH 2 */ if (io == 0) { /* read current word count CH 2 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(H) read as %04X\n", i8237_r5); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5[devnum](H) read as %04X\n", i8237_r5[devnum]);
return (i8237_r5 >> 8); return (i8237_r5[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(L) read as %04X\n", i8237_r5); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5[devnum](L) read as %04X\n", i8237_r5[devnum]);
return (i8237_r5 & 0xFF); return (i8237_r5[devnum] & 0xFF);
} }
} else { /* write base & current address CH 2 */ } else { /* write base & current address CH 2 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r5 |= (data << 8); i8237_r5[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(H) set to %04X\n", i8237_r5); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5[devnum](H) set to %04X\n", i8237_r5[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r5 = data & 0xFF; i8237_r5[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5(L) set to %04X\n", i8237_r5); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r5[devnum](L) set to %04X\n", i8237_r5[devnum]);
} }
return 0; return 0;
} }
@ -667,24 +717,24 @@ uint8 i8237_r6x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current address CH 3 */ if (io == 0) { /* read current address CH 3 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(H) read as %04X\n", i8237_r6); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6[devnum](H) read as %04X\n", i8237_r6[devnum]);
return (i8237_r6 >> 8); return (i8237_r6[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(L) read as %04X\n", i8237_r6); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6[devnum](L) read as %04X\n", i8237_r6[devnum]);
return (i8237_r6 & 0xFF); return (i8237_r6[devnum] & 0xFF);
} }
} else { /* write base & current address CH 3 */ } else { /* write base & current address CH 3 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r6 |= (data << 8); i8237_r6[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(H) set to %04X\n", i8237_r6); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6[devnum](H) set to %04X\n", i8237_r6[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r6 = data & 0xFF; i8237_r6[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6(L) set to %04X\n", i8237_r6); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r6[devnum](L) set to %04X\n", i8237_r6[devnum]);
} }
return 0; return 0;
} }
@ -698,24 +748,24 @@ uint8 i8237_r7x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read current word count CH 3 */ if (io == 0) { /* read current word count CH 3 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(H) read as %04X\n", i8237_r7); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7[devnum](H) read as %04X\n", i8237_r7[devnum]);
return (i8237_r7 >> 8); return (i8237_r7[devnum] >> 8);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(L) read as %04X\n", i8237_r7); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7[devnum](L) read as %04X\n", i8237_r7[devnum]);
return (i8237_r7 & 0xFF); return (i8237_r7[devnum] & 0xFF);
} }
} else { /* write base & current address CH 3 */ } else { /* write base & current address CH 3 */
if (i8237_rD) { /* high byte */ if (i8237_rD[devnum]) { /* high byte */
i8237_rD = 0; i8237_rD[devnum] = 0;
i8237_r7 |= (data << 8); i8237_r7[devnum] |= (data << 8);
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(H) set to %04X\n", i8237_r7); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7[devnum](H) set to %04X\n", i8237_r7[devnum]);
} else { /* low byte */ } else { /* low byte */
i8237_rD++; i8237_rD[devnum]++;
i8237_r7 = data & 0xFF; i8237_r7[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7(L) set to %04X\n", i8237_r7); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r7[devnum](L) set to %04X\n", i8237_r7[devnum]);
} }
return 0; return 0;
} }
@ -729,11 +779,11 @@ uint8 i8237_r8x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read status register */ if (io == 0) { /* read status register */
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r8 (status) read as %02X\n", i8237_r8); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r8[devnum] (status) read as %02X\n", i8237_r8[devnum]);
return (i8237_r8); return (i8237_r8[devnum]);
} else { /* write command register */ } else { /* write command register */
i8237_r9 = data & 0xFF; i8237_r9[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_r9 (command) set to %02X\n", i8237_r9); sim_debug (DEBUG_reg, &i8237_dev, "i8237_r9[devnum] (command) set to %02X\n", i8237_r9[devnum]);
return 0; return 0;
} }
} }
@ -746,11 +796,11 @@ uint8 i8237_r9x(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { if (io == 0) {
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_r9\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_r9[devnum]\n");
return 0; return 0;
} else { /* write request register */ } else { /* write request register */
i8237_rC = data & 0xFF; i8237_rC[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rC (request) set to %02X\n", i8237_rC); sim_debug (DEBUG_reg, &i8237_dev, "i8237_rC[devnum] (request) set to %02X\n", i8237_rC[devnum]);
return 0; return 0;
} }
} }
@ -763,36 +813,36 @@ uint8 i8237_rAx(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { if (io == 0) {
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rA\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rA[devnum]\n");
return 0; return 0;
} else { /* write single mask register */ } else { /* write single mask register */
switch(data & 0x03) { switch(data & 0x03) {
case 0: case 0:
if (data & 0x04) if (data & 0x04)
i8237_rB |= 1; i8237_rB[devnum] |= 1;
else else
i8237_rB &= ~1; i8237_rB[devnum] &= ~1;
break; break;
case 1: case 1:
if (data & 0x04) if (data & 0x04)
i8237_rB |= 2; i8237_rB[devnum] |= 2;
else else
i8237_rB &= ~2; i8237_rB[devnum] &= ~2;
break; break;
case 2: case 2:
if (data & 0x04) if (data & 0x04)
i8237_rB |= 4; i8237_rB[devnum] |= 4;
else else
i8237_rB &= ~4; i8237_rB[devnum] &= ~4;
break; break;
case 3: case 3:
if (data & 0x04) if (data & 0x04)
i8237_rB |= 8; i8237_rB[devnum] |= 8;
else else
i8237_rB &= ~8; i8237_rB[devnum] &= ~8;
break; break;
} }
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) set to %02X\n", i8237_rB); sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB[devnum] (mask) set to %02X\n", i8237_rB[devnum]);
return 0; return 0;
} }
} }
@ -805,11 +855,11 @@ uint8 i8237_rBx(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { if (io == 0) {
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rB\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rB[devnum]\n");
return 0; return 0;
} else { /* write mode register */ } else { /* write mode register */
i8237_rA = data & 0xFF; i8237_rA[devnum] = data & 0xFF;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rA (mode) set to %02X\n", i8237_rA); sim_debug (DEBUG_reg, &i8237_dev, "i8237_rA[devnum] (mode) set to %02X\n", i8237_rA[devnum]);
return 0; return 0;
} }
} }
@ -822,11 +872,11 @@ uint8 i8237_rCx(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { if (io == 0) {
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rC\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rC[devnum]\n");
return 0; return 0;
} else { /* clear byte pointer FF */ } else { /* clear byte pointer FF */
i8237_rD = 0; i8237_rD[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rD (FF) cleared\n"); sim_debug (DEBUG_reg, &i8237_dev, "i8237_rD[devnum] (FF) cleared\n");
return 0; return 0;
} }
} }
@ -839,7 +889,7 @@ uint8 i8237_rDx(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { /* read temporary register */ if (io == 0) { /* read temporary register */
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rD\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rD[devnum]\n");
return 0; return 0;
} else { /* master clear */ } else { /* master clear */
i8237_reset1(); i8237_reset1();
@ -856,11 +906,11 @@ uint8 i8237_rEx(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { if (io == 0) {
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rE\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rE[devnum]\n");
return 0; return 0;
} else { /* clear mask register */ } else { /* clear mask register */
i8237_rB = 0; i8237_rB[devnum] = 0;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) cleared\n"); sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB[devnum] (mask) cleared\n");
return 0; return 0;
} }
} }
@ -873,11 +923,11 @@ uint8 i8237_rFx(t_bool io, uint8 data)
if ((devnum = i8237_get_dn()) != 0xFF) { if ((devnum = i8237_get_dn()) != 0xFF) {
if (io == 0) { if (io == 0) {
sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rF\n"); sim_debug (DEBUG_reg, &i8237_dev, "Illegal read of i8237_rF[devnum]\n");
return 0; return 0;
} else { /* write all mask register bits */ } else { /* write all mask register bits */
i8237_rB = data & 0x0F; i8237_rB[devnum] = data & 0x0F;
sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB (mask) set to %02X\n", i8237_rB); sim_debug (DEBUG_reg, &i8237_dev, "i8237_rB[devnum] (mask) set to %02X\n", i8237_rB[devnum]);
return 0; return 0;
} }
} }

View file

@ -111,50 +111,60 @@
#include "system_defs.h" #include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */ #define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI) #define UNIT_ANSI (1 << UNIT_V_ANSI)
// 8251 status bits
#define TXR 0x01 #define TXR 0x01
#define RXR 0x02 #define RXR 0x02
#define TXE 0x04 #define TXE 0x04
#define SD 0x40 #define SD 0x40
/* external globals */
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* globals */ /* globals */
int32 i8251_devnum = 0; //actual number of 8251 instances + 1
uint16 i8251_port[4]; //baseport port registered to each instance
/* function prototypes */ /* function prototypes */
t_stat i8251_cfg(uint8 base, uint8 devnum);
t_stat i8251_svc (UNIT *uptr); t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, uint16 baseport); t_stat i8251_reset (DEVICE *dptr);
uint8 i8251_get_dn(void); uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
uint8 i8251s(t_bool io, uint8 data); uint8 i8251d(t_bool io, uint8 data, uint8 devnum);
uint8 i8251d(t_bool io, uint8 data); void i8251_reset_dev(uint8 devnum);
void i8251_reset1(uint8 devnum);
/* i8251 Standard I/O Data Structures */ /* i8251 Standard I/O Data Structures */
/* up to 1 i8251 devices */ /* up to 4 i8251 devices */
UNIT i8251_unit = { UNIT i8251_unit[4] = {
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 },
{ UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT }
}; };
REG i8251_reg[] = { REG i8251_reg[] = {
{ HRDATA (DATA, i8251_unit.buf, 8) }, { HRDATA (DATA0, i8251_unit[0].buf, 8) },
{ HRDATA (STAT, i8251_unit.u3, 8) }, { HRDATA (STAT0, i8251_unit[0].u3, 8) },
{ HRDATA (MODE, i8251_unit.u4, 8) }, { HRDATA (MODE0, i8251_unit[0].u4, 8) },
{ HRDATA (CMD, i8251_unit.u5, 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 (MODE3, i8251_unit[3].u4, 8) },
{ HRDATA (CMD3, i8251_unit[3].u5, 8) },
{ NULL } { NULL }
}; };
@ -179,10 +189,10 @@ MTAB i8251_mod[] = {
DEVICE i8251_dev = { DEVICE i8251_dev = {
"I8251", //name "I8251", //name
&i8251_unit, //units i8251_unit, //units
i8251_reg, //registers i8251_reg, //registers
i8251_mod, //modifiers i8251_mod, //modifiers
1, //numunits I8251_NUM, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
1, //aincr 1, //aincr
@ -190,8 +200,7 @@ DEVICE i8251_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &i8251_reset, //reset &i8251_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
@ -203,6 +212,17 @@ DEVICE i8251_dev = {
NULL //lname NULL //lname
}; };
// i8251 configuration
t_stat i8251_cfg(uint8 base, uint8 devnum)
{
sim_printf(" i8251[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8251d, base, devnum);
reg_dev(i8251s, base + 1, devnum);
return SCPE_OK;
}
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
/* i8251_svc - actually gets char & places in buffer */ /* i8251_svc - actually gets char & places in buffer */
@ -211,101 +231,70 @@ t_stat i8251_svc (UNIT *uptr)
{ {
int32 temp; int32 temp;
sim_activate (&i8251_unit, i8251_unit.wait); /* continue poll */ sim_activate (uptr, uptr->wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */ return temp; /* no char or error? */
i8251_unit.buf = temp & 0xFF; /* Save char */ uptr->buf = temp & 0xFF; /* Save char */
i8251_unit.u3 |= RXR; /* Set status */ uptr->u3 |= RXR; /* Set status */
/* Do any special character handling here */ /* Do any special character handling here */
i8251_unit.pos++; uptr->pos++;
return SCPE_OK; return SCPE_OK;
} }
/* Reset routine */ /* Reset routine */
t_stat i8251_reset (DEVICE *dptr, uint16 baseport) t_stat i8251_reset (DEVICE *dptr)
{ {
if (i8251_devnum >= I8251_NUM) { uint8 devnum;
sim_printf("i8251_reset: too many devices!\n");
return SCPE_MEM; for (devnum=0; devnum<I8251_NUM; devnum++) {
i8251_reset_dev(devnum);
sim_activate (&i8251_unit[devnum], i8251_unit[devnum].wait); /* activate unit */
} }
sim_printf(" 8251-%d: Hardware Reset\n", i8251_devnum);
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, baseport);
i8251_port[i8251_devnum] = baseport;
reg_dev(i8251d, baseport, i8251_devnum);
reg_dev(i8251s, baseport + 1, i8251_devnum);
i8251_reset1(i8251_devnum);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
i8251_devnum++;
return SCPE_OK; return SCPE_OK;
} }
void i8251_reset1(uint8 devnum) void i8251_reset_dev(uint8 devnum)
{ {
i8251_unit.u3 = TXR + TXE; /* status */ i8251_unit[devnum].u3 = TXR + TXE; /* status */
i8251_unit.u4 = 0; /* mode instruction */ i8251_unit[devnum].u4 = 0; /* mode instruction */
i8251_unit.u5 = 0; /* command instruction */ i8251_unit[devnum].u5 = 0; /* command instruction */
i8251_unit.u6 = 0; i8251_unit[devnum].u6 = 0;
i8251_unit.buf = 0; i8251_unit[devnum].buf = 0;
i8251_unit.pos = 0; i8251_unit[devnum].pos = 0;
sim_printf(" 8251-%d: Software Reset\n", devnum);
}
uint8 i8251_get_dn(void)
{
int i;
for (i=0; i<I8251_NUM; i++)
if (port >= i8251_port[i] && port <= i8251_port[i] + 1)
return i;
sim_printf("i8251_get_dn: port %04X not in 8251 device table\n", port);
return 0xFF;
} }
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
uint8 i8251s(t_bool io, uint8 data) uint8 i8251s(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
// sim_printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */ if (io == 0) { /* read status port */
return i8251_unit.u3; return i8251_unit[devnum].u3;
} else { /* write status port */ } else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */ if (i8251_unit[devnum].u4) { /* if mode, set cmd */
i8251_unit.u5 = data; i8251_unit[devnum].u5 = data;
if (DEBUG)
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */ if (data & SD) /* reset port! */
i8251_reset1(devnum); i8251_reset_dev(devnum);
} else { /* set mode */ } else { /* set mode */
i8251_unit.u4 = data; i8251_unit[devnum].u4 = data;
if (DEBUG) i8251_unit[devnum].u6 = 1; /* set cmd received */
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */
}
} }
} }
return 0; return 0;
} }
uint8 i8251d(t_bool io, uint8 data) uint8 i8251d(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR; i8251_unit[devnum].u3 &= ~RXR;
return (i8251_unit.buf); return (i8251_unit[devnum].buf);
} else { /* write data port */ } else { /* write data port */
sim_putchar(data); sim_putchar(data);
} }
}
return 0; return 0;
} }

View file

@ -35,30 +35,23 @@
#include "system_defs.h" #include "system_defs.h"
#define DEBUG 0
/* external globals */ /* external globals */
extern uint16 port; //port called in dev_table[port]
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* globals */ /* globals */
int32 i8253_devnum = 0; //actual number of 8253 instances + 1
uint16 i8253_port[4]; //baseport port registered to each instance
/* function prototypes */ /* function prototypes */
t_stat i8253_cfg(uint8 base, uint8 devnum);
t_stat i8253_svc (UNIT *uptr); t_stat i8253_svc (UNIT *uptr);
t_stat i8253_reset (DEVICE *dptr, uint16 baseport); t_stat i8253_reset (DEVICE *dptr);
uint8 i8253_get_dn(void); uint8 i8253t0(t_bool io, uint8 data, uint8 devnum);
uint8 i8253t0(t_bool io, uint8 data); uint8 i8253t1(t_bool io, uint8 data, uint8 devnum);
uint8 i8253t1(t_bool io, uint8 data); uint8 i8253t2(t_bool io, uint8 data, uint8 devnum);
uint8 i8253t2(t_bool io, uint8 data); uint8 i8253c(t_bool io, uint8 data, uint8 devnum);
uint8 i8253c(t_bool io, uint8 data);
/* i8253 Standard I/O Data Structures */ /* i8253 Standard I/O Data Structures */
/* up to 4 i8253 devices */ /* up to 4 i8253 devices */
@ -99,11 +92,11 @@ MTAB i8253_mod[] = {
/* address width is set to 16 bits to use devices in 8086/8088 implementations */ /* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8253_dev = { DEVICE i8253_dev = {
"I8251", //name "I8253", //name
i8253_unit, //units i8253_unit, //units
i8253_reg, //registers i8253_reg, //registers
i8253_mod, //modifiers i8253_mod, //modifiers
1, //numunits I8253_NUM, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
1, //aincr 1, //aincr
@ -111,8 +104,7 @@ DEVICE i8253_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &i8253_reset, //reset i8253_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
@ -126,6 +118,19 @@ DEVICE i8253_dev = {
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
// i8253 configuration
t_stat i8253_cfg(uint8 base, uint8 devnum)
{
sim_printf(" i8253[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8253t0, base, devnum);
reg_dev(i8253t1, base + 1, devnum);
reg_dev(i8253t2, base + 2, devnum);
reg_dev(i8253c, base + 3, devnum);
return SCPE_OK;
}
/* i8253_svc - actually gets char & places in buffer */ /* i8253_svc - actually gets char & places in buffer */
t_stat i8253_svc (UNIT *uptr) t_stat i8253_svc (UNIT *uptr)
@ -136,112 +141,68 @@ t_stat i8253_svc (UNIT *uptr)
/* Reset routine */ /* Reset routine */
t_stat i8253_reset (DEVICE *dptr, uint16 baseport) t_stat i8253_reset (DEVICE *dptr)
{ {
if (i8253_devnum > I8253_NUM) { uint8 devnum;
sim_printf("i8253_reset: too many devices!\n");
return SCPE_MEM; for (devnum=0; devnum<I8251_NUM; devnum++) {
i8253_unit[devnum].u3 = 0; /* status */
i8253_unit[devnum].u4 = 0; /* mode instruction */
i8253_unit[devnum].u5 = 0; /* command instruction */
i8253_unit[devnum].u6 = 0;
} }
sim_printf(" 8253-%d: Reset\n", i8253_devnum);
sim_printf(" 8253-%d: Registered at %04X\n", i8253_devnum, baseport);
i8253_port[i8253_devnum] = baseport;
reg_dev(i8253t0, baseport, i8253_devnum);
reg_dev(i8253t1, baseport + 1, i8253_devnum);
reg_dev(i8253t2, baseport + 2, i8253_devnum);
reg_dev(i8253c, baseport + 3, i8253_devnum);
i8253_unit[i8253_devnum].u3 = 0; /* status */
i8253_unit[i8253_devnum].u4 = 0; /* mode instruction */
i8253_unit[i8253_devnum].u5 = 0; /* command instruction */
i8253_unit[i8253_devnum].u6 = 0;
// sim_activate (&i8253_unit[i8253_devnum], i8253_unit[i8253_devnum].wait); /* activate unit */
i8253_devnum++;
return SCPE_OK; return SCPE_OK;
} }
uint8 i8253_get_dn(void)
{
int i;
for (i=0; i<I8253_NUM; i++)
if (port >= i8253_port[i] && port <= i8253_port[i] + 3)
return i;
sim_printf("i8253_get_dn: port %04X not in 8253 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
uint8 i8253t0(t_bool io, uint8 data) uint8 i8253t0(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return i8253_unit[devnum].u3; return i8253_unit[devnum].u3;
} else { /* write data port */ } else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 0=%02X\n", devnum, data);
i8253_unit[devnum].u3 = data; i8253_unit[devnum].u3 = data;
//sim_activate_after (&i8253_unit[devnum], ); //sim_activate_after (&i8253_unit[devnum], );
return 0; return 0;
} }
}
return 0; return 0;
} }
//read routine: //read routine:
//sim_activate_time(&i8253_unit[devnum])/sim_inst_per_second() //sim_activate_time(&i8253_unit[devnum])/sim_inst_per_second()
uint8 i8253t1(t_bool io, uint8 data) uint8 i8253t1(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return i8253_unit[devnum].u4; return i8253_unit[devnum].u4;
} else { /* write data port */ } else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 1=%02X\n", devnum, data);
i8253_unit[devnum].u4 = data; i8253_unit[devnum].u4 = data;
return 0; return 0;
} }
}
return 0; return 0;
} }
uint8 i8253t2(t_bool io, uint8 data) uint8 i8253t2(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return i8253_unit[devnum].u5; return i8253_unit[devnum].u5;
} else { /* write data port */ } else { /* write data port */
if (DEBUG)
sim_printf(" 8253-%d: Timer 2=%02X\n", devnum, data);
i8253_unit[devnum].u5 = data; i8253_unit[devnum].u5 = data;
return 0; return 0;
} }
}
return 0; return 0;
} }
uint8 i8253c(t_bool io, uint8 data) uint8 i8253c(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8253_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */ if (io == 0) { /* read status port */
return i8253_unit[devnum].u6; return i8253_unit[devnum].u6;
} else { /* write data port */ } else { /* write data port */
i8253_unit[devnum].u6 = data; i8253_unit[devnum].u6 = data;
if (DEBUG)
sim_printf(" 8253-%d: Mode Instruction=%02X\n", devnum, data);
return 0; return 0;
} }
}
return 0; return 0;
} }

View file

@ -77,36 +77,29 @@
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
/* internal function prototypes */ /* internal function prototypes */
t_stat i8255_reset (DEVICE *dptr, uint16 baseport); t_stat i8255_cfg(uint8 base, uint8 devnum);
uint8 i8255_get_dn(void); t_stat i8255_reset (DEVICE *dptr);
uint8 i8255a(t_bool io, uint8 data); uint8 i8255a(t_bool io, uint8 data, uint8 devnum);
uint8 i8255b(t_bool io, uint8 data); uint8 i8255b(t_bool io, uint8 data, uint8 devnum);
uint8 i8255c(t_bool io, uint8 data); uint8 i8255c(t_bool io, uint8 data, uint8 devnum);
uint8 i8255s(t_bool io, uint8 data); uint8 i8255s(t_bool io, uint8 data, uint8 devnum);
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* globals */ /* 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 */ /* these bytes represent the input and output to/from a port instance */
uint8 i8255_A[4]; //port A byte I/O uint8 i8255_A[4]; //port A byte I/O
uint8 i8255_B[4]; //port B byte I/O uint8 i8255_B[4]; //port B byte I/O
uint8 i8255_C[4]; //port C byte I/O uint8 i8255_C[4]; //port C byte I/O
/* external globals */
/* i8255 Standard I/O Data Structures */ /* i8255 Standard I/O Data Structures */
/* up to 4 i8255 devices */ /* up to 4 i8255 devices */
@ -162,8 +155,7 @@ DEVICE i8255_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// i8255_reset2(), //reset i8255_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
@ -175,38 +167,32 @@ DEVICE i8255_dev = {
NULL //lname NULL //lname
}; };
/* Reset routine */ // i8255 configuration
t_stat i8255_reset (DEVICE *dptr, uint16 baseport) t_stat i8255_cfg(uint8 base, uint8 devnum)
{ {
if (i8255_devnum > I8255_NUM) { reg_dev(i8255a, base, devnum);
sim_printf("i8255_reset: too many devices!\n"); reg_dev(i8255b, base + 1, devnum);
return SCPE_MEM; reg_dev(i8255c, base + 2, devnum);
} reg_dev(i8255s, base + 3, devnum);
sim_printf(" 8255-%d: Reset\n", i8255_devnum); sim_printf(" i8255[%d]: at base port 0%02XH\n",
sim_printf(" 8255-%d: Registered at %04X\n", i8255_devnum, baseport); devnum, base & 0xFF);
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; return SCPE_OK;
} }
uint8 i8255_get_dn(void) /* Reset routine */
{
int i;
for (i=0; i<I8255_NUM; i++) t_stat i8255_reset (DEVICE *dptr)
if (port >=i8255_port[i] && port <= i8255_port[i] + 3) {
return i; uint8 devnum;
sim_printf("i8255_get_dn: port %04X not in 8255 device table\n", port);
return 0xFF; for (devnum = 0; devnum < I8255_NUM; devnum++) {
i8255_unit[devnum].u3 = 0x9B; /* control */
i8255_A[devnum] = 0xFF; /* Port A */
i8255_B[devnum] = 0xFF; /* Port B */
i8255_C[devnum] = 0xFF; /* Port C */
}
return SCPE_OK;
} }
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
@ -215,19 +201,15 @@ uint8 i8255_get_dn(void)
/* i8255 functions */ /* i8255 functions */
uint8 i8255s(t_bool io, uint8 data) uint8 i8255s(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 bit; uint8 bit;
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */ if (io == 0) { /* read status port */
return 0xFF; //undefined return 0xFF; //undefined
} else { /* write status port */ } else { /* write status port */
if (data & 0x80) { /* mode instruction */ if (data & 0x80) { /* mode instruction */
i8255_unit[devnum].u3 = data; i8255_unit[devnum].u3 = data;
if (DEBUG)
sim_printf(" 8255-%d: Mode Instruction=%02X\n", devnum, data);
if (data & 0x64) if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n"); sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */ } else { /* bit set */
@ -239,55 +221,49 @@ uint8 i8255s(t_bool io, uint8 data)
} }
} }
} }
}
return 0; return 0;
} }
uint8 i8255a(t_bool io, uint8 data) uint8 i8255a(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
//return (i8255_unit[devnum].u4);
return (i8255_A[devnum]); return (i8255_A[devnum]);
} else { /* write data port */ } else { /* write data port */
i8255_A[devnum] = data; i8255_A[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
}
} }
return 0; return 0;
} }
uint8 i8255b(t_bool io, uint8 data) uint8 i8255b(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return (i8255_B[devnum]); return (i8255_B[devnum]);
} else { /* write data port */ } else { /* write data port */
i8255_B[devnum] = data; i8255_B[devnum] = data;
if (DEBUG)
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
}
} }
return 0; return 0;
} }
uint8 i8255c(t_bool io, uint8 data) uint8 i8255c(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return (i8255_C[devnum]); return (i8255_C[devnum]);
} else { /* write data port */ } else { /* write data port */
i8255_C[devnum] = data; if (devnum == 0) {
if (DEBUG) if((i8255_C[devnum] & 0x80) != (data & 0x80)) { //change in ROM enable
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data); if (data & 0x80)
sim_printf("Onboard EPROM: Enabled\n");
else
sim_printf("Onboard EPROM: Disabled\n");
} }
if((i8255_C[devnum] & 0x20) != (data & 0x20)) { //change in RAM enable
if (data & 0x20)
sim_printf("Onboard RAM: Enabled\n");
else
sim_printf("Onboard RAM: Disabled\n");
}
}
i8255_C[devnum] = data;
} }
return 0; return 0;
} }

View file

@ -35,29 +35,22 @@
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* function prototypes */ /* function prototypes */
uint8 i8259a(t_bool io, uint8 data); t_stat i8259_cfg(uint8 base, uint8 devnum);
uint8 i8259b(t_bool io, uint8 data); uint8 i8259a(t_bool io, uint8 data, uint8 devnum);
uint8 i8259b(t_bool io, uint8 data, uint8 devnum);
void i8259_dump(uint8 devnum); void i8259_dump(uint8 devnum);
t_stat i8259_reset (DEVICE *dptr, uint16 baseport); t_stat i8259_reset (DEVICE *dptr);
uint8 i8259_get_dn(void);
/* external globals */ /* external globals */
extern uint16 port; //port called in dev_table[port]
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* globals */ /* globals */
int32 i8259_devnum = 0; //actual number of 8259 instances + 1
uint16 i8259_port[4]; //baseport port registered to each instance
/* these bytes represent the input and output to/from a port instance */ /* these bytes represent the input and output to/from a port instance */
uint8 i8259_IR[4]; //interrupt inputs (bits 0-7) uint8 i8259_IR[4]; //interrupt inputs (bits 0-7)
@ -117,7 +110,7 @@ DEVICE i8259_dev = {
i8259_unit, //units i8259_unit, //units
i8259_reg, //registers i8259_reg, //registers
NULL, //modifiers NULL, //modifiers
1, //numunits I8259_NUM, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
1, //aincr 1, //aincr
@ -125,8 +118,7 @@ DEVICE i8259_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &i8259_reset, //reset i8259_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
@ -142,44 +134,35 @@ DEVICE i8259_dev = {
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* Reset routine */ // i8259 configuration
t_stat i8259_reset (DEVICE *dptr, uint16 baseport) t_stat i8259_cfg(uint8 base, uint8 devnum)
{ {
if (i8259_devnum >= I8259_NUM) { reg_dev(i8259a, base, devnum);
sim_printf("i8255_reset: too many devices!\n"); reg_dev(i8259b, base + 1, devnum);
return SCPE_MEM; sim_printf(" i8259[%d]: at base port 0%02XH\n",
} devnum, base & 0xFF);
sim_printf(" 8259-%d: Reset\n", i8259_devnum);
sim_printf(" 8259-%d: Registered at %04X\n", i8259_devnum, baseport);
i8259_port[i8259_devnum] = baseport;
reg_dev(i8259a, baseport, i8259_devnum);
reg_dev(i8259b, baseport + 1, i8259_devnum);
i8259_unit[i8259_devnum].u3 = 0x00; /* IRR */
i8259_unit[i8259_devnum].u4 = 0x00; /* ISR */
i8259_unit[i8259_devnum].u5 = 0x00; /* IMR */
i8259_devnum++;
return SCPE_OK; return SCPE_OK;
} }
uint8 i8259_get_dn(void) /* Reset routine */
{
int i;
for (i=0; i<I8259_NUM; i++) t_stat i8259_reset (DEVICE *dptr)
if (port >= i8259_port[i] && port <= i8259_port[i] + 1) {
return i; uint8 devnum;
sim_printf("i8259_get_dn: port %04X not in 8259 device table\n", port);
return 0xFF; for (devnum=0; devnum<I8259_NUM; devnum++) {
i8259_unit[devnum].u3 = 0x00; /* IRR */
i8259_unit[devnum].u4 = 0x00; /* ISR */
i8259_unit[devnum].u5 = 0x00; /* IMR */
}
return SCPE_OK;
} }
/* i8259 functions */ /* i8259 functions */
uint8 i8259a(t_bool io, uint8 data) uint8 i8259a(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8259_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if ((i8259_ocw3[devnum] & 0x03) == 0x02) if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[devnum].u3); /* IRR */ return (i8259_unit[devnum].u3); /* IRR */
@ -206,20 +189,14 @@ uint8 i8259a(t_bool io, uint8 data)
break; break;
} }
} }
if (DEBUG)
sim_printf(" 8259-%d: A data = %02X\n", devnum, data);
icw_num0++; /* step ICW number */ icw_num0++; /* step ICW number */
} }
// i8259_dump(devnum); // i8259_dump(devnum);
}
return 0; return 0;
} }
uint8 i8259b(t_bool io, uint8 data) uint8 i8259b(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 devnum;
if ((devnum = i8259_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if ((i8259_ocw3[devnum] & 0x03) == 0x02) if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[devnum].u3); /* IRR */ return (i8259_unit[devnum].u3); /* IRR */
@ -246,12 +223,9 @@ uint8 i8259b(t_bool io, uint8 data)
break; break;
} }
} }
if (DEBUG)
sim_printf(" 8259-%d: B data = %02X\n", devnum, data);
icw_num1++; /* step ICW number */ icw_num1++; /* step ICW number */
} }
// i8259_dump(devnum); // i8259_dump(devnum);
}
return 0; return 0;
} }

View file

@ -36,49 +36,258 @@
#include "system_defs.h" #include "system_defs.h"
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
/* master status register definitions */
#define RQM 0x80 /* Request for master */
#define DIO 0x40 /* Data I/O Direction 0=W, 1=R */
#define NDM 0x20 /* Non-DMA mode */
#define CB 0x10 /* FDC busy */
#define D3B 0x08 /* FDD 3 busy */`
#define D2B 0x04 /* FDD 2 busy */`
#define D1B 0x02 /* FDD 1 busy */`
#define D0B 0x01 /* FDD 0 busy */`
/* status register 0 definitions */
#define IC 0xC0 /* Interrupt code */
#define IC_NORM 0x00 /* normal completion */
#define IC_ABNORM 0x40 /* abnormal completion */
#define IC_INVC 0x80 /* invalid command */
#define IC_RC 0xC0 /* drive not ready */
#define SE 0x20 /* Seek end */
#define EC 0x10 /* Equipment check */
#define NR 0x08 /* Not ready */
#define HD 0x04 /* Head selected */
#define US 0x03 /* Unit selected */
#define US_0 0x00 /* Unit 0 */
#define US_1 0x01 /* Unit 1 */
#define US_2 0x02 /* Unit 2 */
#define US_3 0x03 /* Unit 3 */
/* status register 1 definitions */
#define EN 0x80 /* End of cylinder */
#define DE 0x20 /* Data error */
#define OR 0x10 /* Overrun */
#define ND 0x04 /* No data */
#define NW 0x02 /* Not writable */
#define MA 0x01 /* Missing address mark */
/* status register 2 definitions */
#define CM 0x40 /* Control mark */
#define DD 0x20 /* Data error in data field */
#define WC 0x10 /* Wrong cylinder */
#define BC 0x02 /* Bad cylinder */
#define MD 0x01 /* Missing address mark in data field */
/* status register 3/fddst72 definitions */
#define FT 0x80 /* Fault */
#define WP 0x40 /* Write protect */
#define RDY 0x20 /* Ready */
#define T0 0x10 /* Track 0 */
#define TS 0x08 /* Two sided */
// dups in register 0 definitions
//#define HD 0x04 /* Head selected */
//#define US 0x03 /* Unit selected */
/* FDC command definitions */
#define READTRK 0x02
#define SPEC 0x03
#define SENDRV 0x04
#define WRITE 0x05
#define READ 0x06
#define HOME 0x07
#define SENINT 0x08
#define WRITEDEL 0x09
#define READID 0x0A
#define READDEL 0x0C
#define FMTTRK 0x0D
#define SEEK 0x0F
#define SCANEQ 0x11
#define SCANLOEQ 0x19
#define SCANHIEQ 0x1D
#define FDD_NUM 4
int32 i8272_devnum = 0; //actual number of 8272 instances + 1
uint16 i8272_port[4]; //base port registered to each instance
//disk geometry values
#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 */ /* external globals */
extern uint16 port; extern uint16 port; //port called in dev_table[port]
extern int32 PCX;
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */ /* internal function prototypes */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
/* function prototypes */
t_stat i8272_svc (UNIT *uptr); t_stat i8272_svc (UNIT *uptr);
t_stat i8272_reset (DEVICE *dptr, uint16 base); t_stat i8272_reset (DEVICE *dptr, uint16 base);
void i8272_reset1(uint8 devnum); void i8272_reset1(uint8 devnum);
uint8 i8272_get_dn(void); uint8 i8272_get_dn(void);
uint8 i8251s(t_bool io, uint8 data); t_stat i8272_attach (UNIT *uptr, CONST char *cptr);
uint8 i8251d(t_bool io, uint8 data); t_stat i8272_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 i8272_r00(t_bool io, uint8 data);
uint8 i8272_r01(t_bool io, uint8 data);
/* globals */ /* external function prototypes */
int32 i8272_devnum = 0; //initially, no 8272 instances extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
uint16 i8272_port[4]; //base port assigned to each 8272 instance extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 multibus_get_mbyte(uint16 addr);
/* i8272 Standard I/O Data Structures */ /* 8272 physical register definitions */
/* up to 4 i8282 devices */ /* 8272 command register stack*/
UNIT i8272_unit[4] = { uint8 i8272_w0[4]; // MT+MFM+SK+command
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT }, uint8 i8272_w1[4]; // HDS [HDS=H << 2] + DS1 + DS0
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT }, uint8 i8272_w2[4]; // cylinder # (0-XX)
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT }, uint8 i8272_w3[4]; // head # (0 or 1)
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT } uint8 i8272_w4[4]; // sector # (1-XX)
uint8 i8272_w5[4]; // number of bytes (128 << N)
uint8 i8272_w6[4]; // End of track (last sector # on cylinder)
uint8 i8272_w7[4]; // Gap length
uint8 i8272_w8[4]; // Data length (when N=0, size to read or write)
/* 8272 status register stack */
uint8 i8272_msr[4]; // main status
uint8 i8272_r0[4]; // ST 0
uint8 i8272_r1[4]; // ST 1
uint8 i8272_r2[4]; // ST 2
uint8 i8272_r3[4]; // ST 3
/* data obtained from analyzing command registers/attached file length */
int32 wsp72[4] = {0, 0, 0, 0}; // indexes to write stacks (8272 data)
int32 rsp72[4] = {0, 0, 0, 0}; // indexes to read stacks (8272 data)
int32 cyl[4]; // current cylinder
int32 hed[4]; // current head [ h << 2]
int32 h[4]; // current head
int32 sec[4]; // current sector
int32 drv[4]; // current drive
uint8 cmd[4], pcmd[4]; // current command
int32 secn[4]; // N 0-128, 1-256, etc
int32 spt[4]; // sectors per track
int32 ssize[4]; // sector size (128 << N)
int32 nd[4]; //non-DMA mode
uint8 *i8272_buf[4][FDD_NUM] = { /* FDD buffer pointers */
NULL,
NULL,
NULL,
NULL
}; };
REG i8272_reg[4] = { int32 fddst72[4][FDD_NUM] = { // in ST3 format
{ HRDATA (DATA, i8272_unit[0].buf, 8) }, 0, // status of FDD 0
{ HRDATA (STAT, i8272_unit[0].u3, 8) }, 0, // status of FDD 1
{ HRDATA (MODE, i8272_unit[0].u4, 8) }, 0, // status of FDD 2
{ HRDATA (CMD, i8272_unit[0].u5, 8) } 0 // status of FDD 3
};
int8 maxcyl72[4][FDD_NUM] = {
0, // last cylinder + 1 of FDD 0
0, // last cylinder + 1 of FDD 1
0, // last cylinder + 1 of FDD 2
0 // last cylinder + 1 of FDD 3
};
/* i8272 Standard I/O Data Structures */
/* up to 4 i8272 devices */
UNIT i8272_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }
};
REG i8272_reg[] = {
{ HRDATA (STAT720, i8272_msr[0], 8) },
{ HRDATA (STAT7200, i8272_r0[0], 8) },
{ HRDATA (STAT7210, i8272_r1[0], 8) },
{ HRDATA (STAT7220, i8272_r2[0], 8) },
{ HRDATA (STAT7230, i8272_r3[0], 8) },
{ HRDATA (CMD7200, i8272_w0[0], 8) },
{ HRDATA (CMD7210, i8272_w1[0], 8) },
{ HRDATA (CMD7220, i8272_w2[0], 8) },
{ HRDATA (CMD7230, i8272_w3[0], 8) },
{ HRDATA (CMD7240, i8272_w4[0], 8) },
{ HRDATA (CMD7250, i8272_w5[0], 8) },
{ HRDATA (CMD7260, i8272_w6[0], 8) },
{ HRDATA (CMD7270, i8272_w7[0], 8) },
{ HRDATA (CMD7280, i8272_w8[0], 8) },
{ HRDATA (FDC0FDD0, fddst72[0][0], 8) },
{ HRDATA (FDC0FDD1, fddst72[0][1], 8) },
{ HRDATA (FDC0FDD2, fddst72[0][2], 8) },
{ HRDATA (FDC0FDD3, fddst72[0][3], 8) },
{ HRDATA (STAT721, i8272_msr[1], 8) },
{ HRDATA (STAT7201, i8272_r0[1], 8) },
{ HRDATA (STAT7211, i8272_r1[1], 8) },
{ HRDATA (STAT7221, i8272_r2[1], 8) },
{ HRDATA (STAT7231, i8272_r3[1], 8) },
{ HRDATA (CMD7201, i8272_w0[1], 8) },
{ HRDATA (CMD7211, i8272_w1[1], 8) },
{ HRDATA (CMD7221, i8272_w2[1], 8) },
{ HRDATA (CMD7231, i8272_w3[1], 8) },
{ HRDATA (CMD7241, i8272_w4[1], 8) },
{ HRDATA (CMD7251, i8272_w5[1], 8) },
{ HRDATA (CMD7261, i8272_w6[1], 8) },
{ HRDATA (CMD7271, i8272_w7[1], 8) },
{ HRDATA (CMD7281, i8272_w8[1], 8) },
{ HRDATA (FDC1FDD0, fddst72[1][0], 8) },
{ HRDATA (FDC1FDD1, fddst72[1][1], 8) },
{ HRDATA (FDC1FDD2, fddst72[1][2], 8) },
{ HRDATA (FDC1FDD3, fddst72[1][3], 8) },
{ HRDATA (STAT722, i8272_msr[2], 8) },
{ HRDATA (STAT7202, i8272_r0[2], 8) },
{ HRDATA (STAT7212, i8272_r1[2], 8) },
{ HRDATA (STAT7222, i8272_r2[2], 8) },
{ HRDATA (STAT7232, i8272_r3[2], 8) },
{ HRDATA (CMD7202, i8272_w0[2], 8) },
{ HRDATA (CMD7212, i8272_w1[2], 8) },
{ HRDATA (CMD7222, i8272_w2[2], 8) },
{ HRDATA (CMD7232, i8272_w3[2], 8) },
{ HRDATA (CMD7242, i8272_w4[2], 8) },
{ HRDATA (CMD7252, i8272_w5[2], 8) },
{ HRDATA (CMD7262, i8272_w6[2], 8) },
{ HRDATA (CMD7272, i8272_w7[2], 8) },
{ HRDATA (CMD7282, i8272_w8[2], 8) },
{ HRDATA (FDC2FDD0, fddst72[2][0], 8) },
{ HRDATA (FDC2FDD1, fddst72[2][1], 8) },
{ HRDATA (FDC2FDD2, fddst72[2][2], 8) },
{ HRDATA (FDC2FDD3, fddst72[2][3], 8) },
{ HRDATA (STAT72_0, i8272_msr[3], 8) },
{ HRDATA (STAT720_0, i8272_r0[3], 8) },
{ HRDATA (STAT721_0, i8272_r1[3], 8) },
{ HRDATA (STAT722_0, i8272_r2[3], 8) },
{ HRDATA (STAT723_0, i8272_r3[3], 8) },
{ HRDATA (CMD7203, i8272_w0[3], 8) },
{ HRDATA (CMD7213, i8272_w1[3], 8) },
{ HRDATA (CMD7223, i8272_w2[3], 8) },
{ HRDATA (CMD7233, i8272_w3[3], 8) },
{ HRDATA (CMD7243, i8272_w4[3], 8) },
{ HRDATA (CMD7253, i8272_w5[3], 8) },
{ HRDATA (CMD7263, i8272_w6[3], 8) },
{ HRDATA (CMD7273, i8272_w7[3], 8) },
{ HRDATA (CMD7283, i8272_w8[3], 8) },
{ HRDATA (FDC3FDD0, fddst72[3][0], 8) },
{ HRDATA (FDC3FDD1, fddst72[3][1], 8) },
{ HRDATA (FDC3FDD2, fddst72[3][2], 8) },
{ HRDATA (FDC3FDD3, fddst72[3][3], 8) },
{ NULL }
}; };
DEBTAB i8272_debug[] = { DEBTAB i8272_debug[] = {
@ -93,8 +302,8 @@ DEBTAB i8272_debug[] = {
}; };
MTAB i8272_mod[] = { MTAB i8272_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL }, { UNIT_WPMODE, 0, "RW", "RW", &i8272_set_mode },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL }, { UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &i8272_set_mode },
{ 0 } { 0 }
}; };
@ -105,7 +314,7 @@ DEVICE i8272_dev = {
i8272_unit, //units i8272_unit, //units
i8272_reg, //registers i8272_reg, //registers
i8272_mod, //modifiers i8272_mod, //modifiers
1, //numunits FDD_NUM, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
1, //aincr 1, //aincr
@ -113,10 +322,9 @@ DEVICE i8272_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &i8272_reset, //reset
NULL, //reset NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach &i8272_attach, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
0, //flags 0, //flags
@ -132,94 +340,552 @@ DEVICE i8272_dev = {
t_stat i8272_svc(UNIT *uptr) t_stat i8272_svc(UNIT *uptr)
{ {
int32 temp; uint32 i;
int32 imgadr, data;
int c;
int32 bpt, bpc;
FILE *fp;
uint8 devnum;
sim_activate(&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait); /* continue poll */ devnum = uptr->u5; //get FDC instance
if (uptr->u6 >= i8272_devnum) return SCPE_OK; if ((i8272_msr[devnum] & CB) && cmd[devnum] && (uptr->u6 == drv[devnum])) { /* execution phase */
if ((temp = sim_poll_kbd()) < SCPE_KFLAG) sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Entered execution phase\n");
return temp; /* no char or error? */ switch (cmd[devnum]) {
//sim_printf("i8272_svc: received character temp=%04X devnum=%d\n", temp, uptr->u6); case READ: /* 0x06 */
i8272_unit[uptr->u6].buf = temp & 0xFF; /* Save char */ // sim_printf("READ-e: fddst72=%02X", fddst72[devnum][uptr->u6]);
i8272_unit[uptr->u6].u3 |= RXR; /* Set status */ h[devnum] = i8272_w3[devnum]; // h = 0 or 1
hed[devnum] = i8272_w3[devnum] << 2; // hed = 0 or 4 [h << 2]
sec[devnum] = i8272_w4[devnum]; // sector number (1-XX)
secn[devnum] = i8272_w5[devnum]; // N (0-5)
spt[devnum] = i8272_w6[devnum]; // sectors/track
ssize[devnum] = 128 << secn[devnum]; // size of sector (bytes)
bpt = ssize[devnum] * spt[devnum]; // bytes/track
bpc = bpt * 2; // bytes/cylinder
// sim_printf(" d=%d h=%d c=%d s=%d\n", drv[devnum], h[devnum], cyl[devnum], sec[devnum]);
sim_debug (DEBUG_flow, &i8272_dev,
"8272_svc: FDC read: h=%d, hed=%d, sec=%d, secn=%d, spt=%d, ssize=%04X, bpt=%04X, bpc=%04X\n",
h[devnum], hed[devnum], sec[devnum], secn[devnum], spt[devnum], ssize[devnum], bpt, bpc);
sim_debug (DEBUG_flow, &i8272_dev,
"8272_svc: FDC read: d=%d h=%d c=%d s=%d N=%d spt=%d fddst72=%02X\n",
drv[devnum], h[devnum], cyl[devnum], sec[devnum], secn[devnum], spt[devnum], fddst72[devnum][uptr->u6]);
sim_debug (DEBUG_read, &i8272_dev, "8272_svc: FDC read of d=%d h=%d c=%d s=%d\n",
drv[devnum], h[devnum], cyl[devnum], sec[devnum]);
if ((fddst72[devnum][uptr->u6] & RDY) == 0) { // drive not ready
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* command done - Not ready error*/
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC read: Not Ready\n");
} else { // get image addr for this d, h, c, s
imgadr = (cyl[devnum] * bpc) + (h[devnum] * bpt) + ((sec[devnum] - 1) * ssize[devnum]);
// sim_debug (DEBUG_read, &i8272_dev,
// "8272_svc: FDC read: DMA addr=%04X cnt=%04X imgadr=%04X\n",
// i8237_r0, i8237_r1, imgadr);
for (i=0; i<=ssize[devnum]; i++) { /* copy selected sector to memory */
data = *(i8272_buf[devnum][uptr->u6] + (imgadr + i));
// multibus_put_mbyte(i8237_r0 + i, data);
}
//*** need to step return results IAW table 3-11 in 143078-001
i8272_w4[devnum] = ++sec[devnum]; /* next sector */
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
}
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
i8272_w2[devnum] = cyl[devnum]; /* generate a current address mark */
i8272_w3[devnum] = h[devnum];
if (i8272_w4[devnum] > i8272_w6[devnum]) { // beyond last sector of track?
i8272_w4[devnum] = 1; // yes, set to sector 1;
if (h[devnum]) { // on head one?
i8272_w2[devnum]++; // yes, step cylinder
h[devnum] = 0; // back to head 0
}
}
i8272_w5[devnum] = secn[devnum];
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// set_irq(I8272_INT); /* set interrupt */
// sim_printf("READ-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
break;
case WRITE: /* 0x05 */
// sim_printf("WRITE-e: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
h[devnum] = i8272_w3[devnum]; // h = 0 or 1
hed[devnum] = i8272_w3[devnum] << 2; // hed = 0 or 4 [h << 2]
sec[devnum] = i8272_w4[devnum]; // sector number (1-XX)
secn[devnum] = i8272_w5[devnum]; // N (0-5)
spt[devnum] = i8272_w6[devnum]; // sectors/track
ssize[devnum] = 128 << secn[devnum]; // size of sector (bytes)
bpt = ssize[devnum] * spt[devnum]; // bytes/track
bpc = bpt * 2; // bytes/cylinder
sim_debug (DEBUG_flow, &i8272_dev,
"8272_svc: FDC write: hed=%d, sec=%d, secn=%d, spt=%d, ssize=%04X, bpt=%04X, bpc=%04X\n",
hed[devnum], sec[devnum], secn[devnum], spt[devnum], ssize[devnum], bpt, bpc);
sim_debug (DEBUG_flow, &i8272_dev,
"8272_svc: FDC write: d=%d h=%d c=%d s=%d N=%d spt=%d fddst72=%02X\n",
drv[devnum], h[devnum], cyl[devnum], sec[devnum], secn[devnum], spt[devnum], fddst72[devnum][uptr->u6]);
sim_debug (DEBUG_write, &i8272_dev, "8272_svc: FDC write of d=%d h=%d c=%d s=%d\n",
drv[devnum], h[devnum], cyl[devnum], sec[devnum]);
i8272_r1[devnum] = 0; // clear ST1
i8272_r2[devnum] = 0; // clear ST2
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC write: Not Ready\n");
// } else if (fddst72[devnum][uptr->u6] & WP) {
// i8272_r0[devnum] = IC_ABNORM + hed[devnum] + drv[devnum]; /* write protect error */
// i8272_r1[devnum] = NW; // set not writable in ST1
// i8272_r3[devnum] = fddst72[devnum][uptr->u6] + WP;
// i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
// sim_printf("\nWrite Protected fddst72[%d]=%02X\n", uptr->u6, fddst72[devnum][uptr->u6]);
// if (i8272_dev.dctrl & DEBUG_flow)
// sim_printf("8272_svc: FDC write: Write Protected\n");
} else { // get image addr for this d, h, c, s
imgadr = (cyl[devnum] * bpc) + (h[devnum] * bpt) + ((sec[devnum] - 1) * ssize[devnum]);
// sim_debug (DEBUG_write, &i8272_dev,
// "8272_svc: FDC write: DMA adr=%04X cnt=%04X imgadr=%04X\n",
// i8237_r0, i8237_r1, imgadr);
for (i=0; i<=ssize[devnum]; i++) { /* copy selected memory to image */
// data = multibus_get_mbyte(i8237_r0 + i);
*(i8272_buf[devnum][uptr->u6] + (imgadr + i)) = data;
}
//*** quick fix. Needs more thought!
// fp = fopen(uptr->filename, "wb"); // write out modified image
// for (i=0; i<uptr->capac; i++) {
// c = *(i8272_buf[devnum][uptr->u6] + i) & 0xFF;
// fputc(c, fp);
// }
// fclose(fp);
//*** need to step return results IAW table 3-11 in 143078-001
i8272_w2[devnum] = cyl[devnum]; /* generate a current address mark */
i8272_w3[devnum] = hed[devnum] >> 2;
i8272_w4[devnum] = ++sec[devnum]; /* next sector */
i8272_w5[devnum] = secn[devnum];
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
}
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// set_irq(I8272_INT); /* set interrupt */
// sim_printf("WRITE-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
break;
case FMTTRK: /* 0x0D */
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Not Ready\n");
} else if (fddst72[devnum][uptr->u6] & WP) {
i8272_r0[devnum] = IC_ABNORM + hed[devnum] + drv[devnum]; /* write protect error*/
i8272_r3[devnum] = fddst72[devnum][uptr->u6] + WP;
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Write Protected\n");
} else {
; /* do nothing for now */
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
}
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// set_irq(I8272_INT); /* set interrupt */
break;
case SENINT: /* 0x08 */
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// clr_irq(I8272_INT); /* clear interrupt */
break;
case SENDRV: /* 0x04 */
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC sense drive: d=%d fddst72=%02X\n",
drv[devnum], fddst72[devnum][uptr->u6]);
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
i8272_r3[devnum] = fddst72[devnum][drv[devnum]]; /* drv status */
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
break;
case HOME: /* 0x07 */
// sim_printf("HOME-e: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC home: d=%d fddst72=%02X\n",
drv[devnum], fddst72[devnum][uptr->u6]);
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Not Ready\n");
} else {
cyl[devnum] = 0; /* now on cylinder 0 */
fddst72[devnum][drv[devnum]] |= T0; /* set status flag */
i8272_r0[devnum] = SE + hed[devnum] + drv[devnum]; /* seek end - no error */
}
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
i8272_msr[devnum] &= ~(RQM + DIO + CB + hed[devnum] + drv[devnum]); /* execution phase done*/
i8272_msr[devnum] |= RQM; /* enter COMMAND phase */
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// set_irq(I8272_INT); /* set interrupt */
// sim_printf("HOME-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
break;
case SPEC: /* 0x03 */
fddst72[devnum][0] |= TS; //*** bad, bad, bad!
fddst72[devnum][1] |= TS;
fddst72[devnum][2] |= TS;
fddst72[devnum][3] |= TS;
// sim_printf("SPEC-e: fddst72[%d]=%02X\n", uptr->u6, fddst72[devnum][uptr->u6]);
sim_debug (DEBUG_flow, &i8272_dev,
"8272_svc: FDC specify: SRT=%d ms HUT=%d ms HLT=%d ms ND=%d\n",
16 - (drv[devnum] >> 4), 16 * (drv[devnum] & 0x0f), i8272_w2[devnum] & 0xfe, nd[devnum]);
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
// i8272_msr[devnum] &= ~(RQM + DIO + CB); /* execution phase done*/
i8272_msr[devnum] = 0; // force 0 for now, where does 0x07 come from?
i8272_msr[devnum] |= RQM + (nd[devnum] ? ND : 0); /* enter command phase */
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// sim_printf("SPEC-x: fddst72[%d]=%02X\n", uptr->u6, fddst72[devnum][uptr->u6]);
break;
case READID: /* 0x0A */
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
i8272_r0[devnum] = IC_RC + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Not Ready\n");
} else {
i8272_w2[devnum] = cyl[devnum]; /* generate a valid address mark */
i8272_w3[devnum] = hed[devnum] >> 2;
i8272_w4[devnum] = 1; /* always sector 1 */
i8272_w5[devnum] = secn[devnum];
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
i8272_msr[devnum] &= ~(RQM + DIO + CB); /* execution phase done*/
i8272_msr[devnum] |= RQM; /* enter command phase */
}
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
break;
case SEEK: /* 0x0F */
// sim_printf("SEEK-e: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC seek: d=%d c=%d fddst72=%02X\n",
drv[devnum], i8272_w2, fddst72[devnum][uptr->u6]);
if ((fddst72[devnum][uptr->u6] & RDY) == 0) { /* Not ready? */
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* error*/
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC seek: Not Ready\n");
} else if (i8272_w2[devnum] >= maxcyl72[devnum][uptr->u6]) {
i8272_r0[devnum] = IC_ABNORM + RDY + hed[devnum] + drv[devnum]; /* seek error*/
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC seek: Invalid Cylinder %d\n", i8272_w2);
} else {
i8272_r0[devnum] |= SE + hed[devnum] + drv[devnum]; /* command done - no error */
cyl[devnum] = i8272_w2[devnum]; /* new cylinder number */
if (cyl[devnum] == 0) { /* if cyl 0, set flag */
fddst72[devnum][drv[devnum]] |= T0; /* set T0 status flag */
i8272_r3[devnum] |= T0;
} else {
fddst72[devnum][drv[devnum]] &= ~T0; /* clear T0 status flag */
i8272_r3[devnum] &= ~T0;
}
}
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
i8272_msr[devnum] &= ~(RQM + DIO + CB + hed[devnum] + drv[devnum]); /* execution phase done*/
i8272_msr[devnum] |= RQM; /* enter command phase */
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
// set_irq(I8272_INT); /* set interrupt */
// sim_printf("SEEK-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
break;
default:
i8272_msr[devnum] &= ~(RQM + DIO + CB); /* execution phase done*/
i8272_msr[devnum] |= RQM; /* enter command phase */
i8272_r0[devnum] = IC_INVC + hed[devnum] + drv[devnum]; /* set bad command error */
i8272_r1[devnum] = 0;
i8272_r2[devnum] = 0;
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
break;
}
pcmd[devnum] = cmd[devnum]; /* save for result phase */
cmd[devnum] = 0; /* reset command */
sim_debug (DEBUG_flow, &i8272_dev,
"8272_svc: Exit: msr=%02X ST0=%02X ST1=%02X ST2=%02X ST3=%02X\n",
i8272_msr[devnum], i8272_r0[devnum], i8272_r1[devnum], i8272_r2[devnum], i8272_r3);
}
sim_activate (&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait);
return SCPE_OK; return SCPE_OK;
} }
/* Reset routine */ /* i8272 hardware reset routine */
t_stat i8272_reset(DEVICE *dptr, uint16 base) t_stat i8272_reset(DEVICE *dptr, uint16 base)
{ {
if (i8272_devnum >= i8272_NUM) { if (i8272_devnum >= I8272_NUM) {
sim_printf("8251_reset: too many devices!\n"); sim_printf("8272_reset: too many devices!\n");
return 0; return 0;
} }
if (I8272_NUM) {
sim_printf(" I8272-%d: Hardware Reset\n", i8272_devnum);
sim_printf(" I8272-%d: Registered at %04X\n", i8272_devnum, base);
i8272_port[i8272_devnum] = reg_dev(i8272_r00, I8272_BASE + 0);
reg_dev(i8272_r01, I8272_BASE + 1);
if ((i8272_dev.flags & DEV_DIS) == 0)
i8272_reset1(i8272_devnum); i8272_reset1(i8272_devnum);
sim_printf(" 8251-%d: Registered at %03X\n", i8272_devnum, base);
i8272_port[i8272_devnum] = reg_dev(i8251d, base);
reg_dev(i8251s, base + 1);
i8272_unit[i8272_devnum].u6 = i8272_devnum;
sim_activate(&i8272_unit[i8272_devnum], i8272_unit[i8272_devnum].wait); /* activate unit */
i8272_devnum++; i8272_devnum++;
} else {
sim_printf(" No isbc208 installed\n");
}
return SCPE_OK; return SCPE_OK;
} }
/* i8272 software reset routine */
void i8272_reset1(uint8 devnum) void i8272_reset1(uint8 devnum)
{ {
i8272_unit[devnum].u3 = TXR + TXE; /* status */ int32 i;
i8272_unit[devnum].u4 = 0; /* mode instruction */ UNIT *uptr;
i8272_unit[devnum].u5 = 0; /* command instruction */ static int flag = 1;
i8272_unit[devnum].buf = 0;
i8272_unit[devnum].pos = 0; if (flag) sim_printf("I8272: Initializing\n");
sim_printf(" 8251-%d: Reset\n", devnum); for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = i8272_dev.units + i;
if (uptr->capac == 0) { /* if not configured */
// sim_printf(" i8272%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 = devnum; // i8272 device instance - only set here!
uptr->u6 = i; /* FDD number - only set here! */
fddst72[devnum][i] = WP + T0 + i; /* initial drive status */
uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */
sim_activate (&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait);
} else {
fddst72[devnum][i] = RDY + WP + T0 + i; /* initial attach drive status */
// sim_printf(" i8272%d: Configured, Attached to %s\n", i, uptr->filename);
}
}
i8272_msr[devnum] = RQM; /* 8272 ready for start of command */
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
cmd[devnum] = 0; /* clear command */
sim_printf(" i8272-%d: Software Reset\n", i8272_devnum);
if (flag) {
sim_printf(" 8272 Reset\n");
}
flag = 0;
} }
uint8 i8272_get_dn(void) uint8 i8272_get_dn(void)
{ {
int i; int i;
for (i=0; i<i8272_NUM; i++) for (i=0; i<I8272_NUM; i++)
if (port >=i8272_port[i] && port <= i8272_port[i] + 1) if (port >= i8272_port[i] && port <= i8272_port[i] + 1)
return i; return i;
sim_printf("i8272_get_dn: port %03X not in 8251 device table\n", port); sim_printf("i8272_get_dn: port %03X not in 8272 device table\n", port);
return 0xFF; return 0xFF;
} }
/* i8272 attach - attach an .IMG file to an FDD on a FDC */
t_stat i8272_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
uint8 fdcnum, fddnum, devnum;
int i;
long flen;
sim_debug (DEBUG_flow, &i8272_dev, " i8272_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" i8272_attach: Attach error\n");
return r;
}
devnum = fdcnum = uptr->u5;
fddnum = uptr->u6;
flen = uptr->capac;
fddst72[devnum][uptr->u6] |= RDY; /* set unit ready */
for (i=0; i<fddnum; i++) { //for each disk drive
if (flen == 368640) { /* 5" 360K DSDD */
maxcyl72[devnum][uptr->u6] = 40;
fddst72[devnum][uptr->u6] |= TS; // two sided
}
else if (flen == 737280) { /* 5" 720K DSQD / 3.5" 720K DSDD */
maxcyl72[devnum][uptr->u6] = 80;
fddst72[devnum][uptr->u6] |= TS; // two sided
}
else if (flen == 1228800) { /* 5" 1.2M DSHD */
maxcyl72[devnum][uptr->u6] = 80;
fddst72[devnum][uptr->u6] |= TS; // two sided
}
else if (flen == 1474560) { /* 3.5" 1.44M DSHD */
maxcyl72[devnum][uptr->u6] = 80;
fddst72[devnum][uptr->u6] |= TS; // two sided
}
sim_printf(" Drive-%d: %d bytes of disk image %s loaded, fddst72=%02X\n",
uptr->u6, i, uptr->filename, fddst72[devnum][uptr->u6]);
}
sim_debug (DEBUG_flow, &i8272_dev, " i8272_attach: Done\n");
return SCPE_OK;
}
/* i8272 set mode */
/* Handle write protect */
t_stat i8272_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint8 devnum;
sim_debug (DEBUG_flow, &i8272_dev, " i8272_set_mode: Entered with val=%08XH uptr->flags=%08X\n",
val, uptr->flags);
devnum = uptr->u5;
if (val & UNIT_WPMODE) { /* write protect */
fddst72[devnum][uptr->u6] |= WP;
uptr->flags |= val;
} else { /* read write */
fddst72[devnum][uptr->u6] &= ~WP;
uptr->flags &= ~val;
}
// sim_printf("fddst72[%d]=%02XH uptr->flags=%08X\n", uptr->u6, fddst72[devnum][uptr->u6], uptr->flags);
sim_debug (DEBUG_flow, &i8272_dev, " i8272_set_mode: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
uint8 i8251s(t_bool io, uint8 data) uint8 i8272_r00(t_bool io, uint8 data)
{ {
uint8 devnum; uint8 devnum;
if ((devnum = i8272_get_dn()) != 0xFF) { if ((devnum = i8272_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */ if (io == 0) { /* read FDC status register */
return i8272_unit[devnum].u3; sim_debug (DEBUG_reg, &i8272_dev, "i8272_msr read as %02X\n", i8272_msr[devnum]);
} else { /* write status port */ return i8272_msr[devnum];
if (i8272_unit[devnum].u6) { /* if mode, set cmd */ } else {
i8272_unit[devnum].u5 = data; sim_debug (DEBUG_reg, &i8272_dev, "Illegal write to i8272_r0\n");
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data); return 0;
if (data & SD) /* reset port! */
i8272_reset1(devnum);
} else { /* set mode */
i8272_unit[devnum].u4 = data;
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8272_unit[devnum].u6 = 1; /* set cmd received */
}
} }
} }
return 0; return 0;
} }
uint8 i8251d(t_bool io, uint8 data) // read/write FDC data register stack
uint8 i8272_r01(t_bool io, uint8 data)
{ {
uint8 devnum; uint8 devnum;
if ((devnum = i8272_get_dn()) != 0xFF) { if ((devnum = i8272_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read FDC data register */
i8272_unit[devnum].u3 &= ~RXR; wsp72[devnum] = 0; /* clear write stack index */
return (i8272_unit[devnum].buf); switch (rsp72[devnum]) { /* read from next stack register */
} else { /* write data port */ case 0:
sim_putchar(data); sim_debug (DEBUG_reg, &i8272_dev, "i8272_r1 read as %02X\n", i8272_r1[devnum]);
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r3 read as %02X\n", i8272_r3[devnum]);
rsp72[devnum]++; /* step read stack index */
// clr_irq(I8272_INT); /* clear interrupt */
if (pcmd[devnum] == SENDRV) {
i8272_msr[devnum] = RQM; /* result phase SENDRV done */
return i8272_r1[devnum]; // SENDRV return ST1
}
return i8272_r0[devnum]; /* ST0 */
case 1:
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r2 read as %02X\n", i8272_r2[devnum]);
rsp72[devnum]++; /* step read stack index */
if (pcmd[devnum] == SENINT) {
i8272_msr[devnum] = RQM; /* result phase SENINT done */
return cyl[devnum]; // SENINT return current cylinder
}
return i8272_r1[devnum]; /* ST1 */
case 2:
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r3 read as %02X\n", i8272_r3[devnum]);
rsp72[devnum]++; /* step read stack index */
return i8272_r2[devnum]; /* ST2 */
case 3:
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w2 read as %02X\n", i8272_w2);
rsp72[devnum]++; /* step read stack index */
return i8272_w2[devnum]; /* C - cylinder */
case 4:
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w3 read as %02X\n", i8272_w3[devnum]);
rsp72[devnum]++; /* step read stack index */
return i8272_w3[devnum]; /* H - head */
case 5:
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w4 read as %02X\n", i8272_w4[devnum]);
rsp72[devnum]++; /* step read stack index */
return i8272_w4[devnum]; /* R - sector */
case 6:
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w5 read as %02X\n", i8272_w5[devnum]);
i8272_msr[devnum] = RQM; /* result phase ALL OTHERS done */
return i8272_w5[devnum]; /* N - sector size*/
}
} else { /* write FDC data register */
rsp72[devnum] = 0; /* clear read stack index */
switch (wsp72[devnum]) { /* write to next stack register */
case 0:
i8272_w0[devnum] = data; /* rws = MT + MFM + SK + cmd */
cmd[devnum] = data & 0x1F; /* save the current command */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w0 set to %02X\n", data);
if (cmd[devnum] == SENINT) {
i8272_msr[devnum] = CB; /* command phase SENINT done */
return 0;
}
wsp72[devnum]++; /* step write stack index */
break;
case 1:
i8272_w1[devnum] = data; /* rws = hed + drv */
if (cmd[devnum] != SPEC)
drv[devnum] = data & 0x03;
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w1 set to %02X\n", data);
if (cmd[devnum] == HOME || cmd[devnum] == SENDRV || cmd[devnum] == READID) {
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase HOME, READID and SENDRV done */
return 0;
}
wsp72[devnum]++; /* step write stack index */
break;
case 2:
i8272_w2[devnum] = data; /* rws = C */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w2 set to %02X\n", data);
if (cmd[devnum] == SPEC || cmd[devnum] == SEEK) {
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase SPECIFY and SEEK done */
return 0;
}
wsp72[devnum]++; /* step write stack index */
break;
case 3:
i8272_w3[devnum] = data; /* rw = H */
hed[devnum] = data;
wsp72[devnum]++; /* step write stack index */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w3 set to %02X\n", data);
break;
case 4:
i8272_w4[devnum] = data; /* rw = R */
sec[devnum] = data;
wsp72[devnum]++; /* step write stack index */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w4 set to %02X\n", data);
break;
case 5:
i8272_w5[devnum] = data; /* rw = N */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w5 set to %02X\n", data);
if (cmd[devnum] == FMTTRK) {
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase FMTTRK done */
return 0;
}
wsp72[devnum]++; /* step write stack index */
break;
case 6:
i8272_w6[devnum] = data; /* rw = last sector number */
wsp72[devnum]++; /* step write stack index */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w6 set to %02X\n", data);
break;
case 7:
i8272_w7[devnum] = data; /* rw = gap length */
wsp72[devnum]++; /* step write stack index */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w7 set to %02X\n", data);
break;
case 8:
i8272_w8[devnum] = data; /* rw = bytes to transfer */
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w8 set to %02X\n", data);
if (cmd[devnum] == READ || cmd[devnum] == WRITE)
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase all others done */
break;
}
} }
} }
return 0; return 0;

View file

@ -26,36 +26,37 @@
MODIFICATIONS: MODIFICATIONS:
?? ??? 10 - Original file. ?? ??? 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: NOTES:
These functions support a simulated ROM devices on an iSBC-80/XX SBCs. These functions support a simulated ROM devices on an iSBC-80/XX SBCs.
This allows the attachment of the device to a binary file containing the EPROM This allows the attachment of the device to a binary file containing the EPROM
code image. Unit will support a single 2708, 2716, 2732, or 2764 type EPROM. code image. Unit will support a single 2708, 2716, 2732, or 2764 type EPROM.
These functions also support bit 1 of 8255 number 1, port B, to enable/ These functions also support bit 0x80 of 8255 number 0, port C, to enable/
disable the onboard ROM. disable the onboard ROM.
*/ */
#include "system_defs.h" #include "system_defs.h"
#define DEBUG 0
/* function prototypes */ /* function prototypes */
t_stat EPROM_cfg(uint16 base, uint16 size);
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr); t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
t_stat EPROM_reset (DEVICE *dptr, uint16 size); t_stat EPROM_reset (DEVICE *dptr);
uint8 EPROM_get_mbyte(uint16 addr); uint8 EPROM_get_mbyte(uint16 addr);
/* external function prototypes */ /* external function prototypes */
//extern uint8 i8255_C[4]; //port c byte I/O /* external globals */
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
extern uint8 i8255_C[4]; //port C byte I/O
/* globals */
/* SIMH EPROM Standard I/O Data Structures */ /* SIMH EPROM Standard I/O Data Structures */
UNIT EPROM_unit = { UNIT EPROM_unit[] = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0 UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0
}; };
@ -72,7 +73,7 @@ DEBTAB EPROM_debug[] = {
DEVICE EPROM_dev = { DEVICE EPROM_dev = {
"EPROM", //name "EPROM", //name
&EPROM_unit, //units EPROM_unit, //units
NULL, //registers NULL, //registers
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
@ -83,8 +84,7 @@ DEVICE EPROM_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &EPROM_reset, //reset EPROM_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
&EPROM_attach, //attach &EPROM_attach, //attach
NULL, //detach NULL, //detach
@ -96,24 +96,23 @@ DEVICE EPROM_dev = {
NULL //lname NULL //lname
}; };
/* global variables */
/* EPROM functions */ /* EPROM functions */
// EPROM configuration
t_stat EPROM_cfg(uint16 base, uint16 size)
{
EPROM_unit->capac = size; /* set EPROM size */
EPROM_unit->u3 = base & 0xFFFF; /* set EPROM base */
sim_printf(" EPROM: 0%04XH bytes at base 0%04XH\n",
EPROM_unit->capac, EPROM_unit->u3);
return SCPE_OK;
}
/* EPROM reset */ /* EPROM reset */
t_stat EPROM_reset (DEVICE *dptr, uint16 size) t_stat EPROM_reset (DEVICE *dptr)
{ {
sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=0000 size=%04X\n", size);
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
EPROM_unit.capac = size; /* set EPROM size to 0 */
sim_printf(" EPROM: Configured, Not attached\n");
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
} else {
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, EPROM_unit.filename);
}
sim_debug (DEBUG_flow, &EPROM_dev, "Done2\n");
return SCPE_OK; return SCPE_OK;
} }
@ -123,15 +122,10 @@ t_stat EPROM_attach (UNIT *uptr, CONST char *cptr)
{ {
t_stat r; t_stat r;
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n"); sim_printf ("EPROM_attach: Error %d\n", r);
return r; return r;
} }
sim_debug (DEBUG_read, &EPROM_dev, "\tClose file\n");
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, EPROM_unit.filename);
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -141,17 +135,15 @@ uint8 EPROM_get_mbyte(uint16 addr)
{ {
uint8 val; uint8 val;
sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%04X\n", addr); if ((addr >= EPROM_unit->u3) && ((uint32) addr <= (EPROM_unit->u3 + EPROM_unit->capac))) {
if (addr < EPROM_unit.capac) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &EPROM_dev, "EPROM_get_mbyte: Set XACK for %04X\n", addr); val = *((uint8 *)EPROM_unit->filebuf + (addr - EPROM_unit->u3));
val = *((uint8 *)EPROM_unit.filebuf + addr); val &= 0xFF;
sim_debug (DEBUG_read, &EPROM_dev, " val=%04X\n", val); return val;
return (val & 0xFF);
} else { } else {
sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n"); sim_printf("EPROM: Out of range\n");
return 0;
} }
return 0;
} }
/* end of iEPROM.c */ /* end of iEPROM.c */

View file

@ -0,0 +1,150 @@
/* iEPROM1.c: Intel EPROM simulator for 8-bit SBCs
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
NOTES:
These functions support a simulated ROM devices on an iSBC-80/XX SBCs.
This allows the attachment of the device to a binary file containing the EPROM
code image. Unit will support a single 2708, 2716, 2732, or 2764 type EPROM.
These functions also support bit 1 of 8255 number 1, port B, to enable/
disable the onboard ROM.
*/
#include "system_defs.h"
/* function prototypes */
t_stat EPROM1_cfg(uint16 base, uint16 size);
t_stat EPROM1_attach (UNIT *uptr, CONST char *cptr);
t_stat EPROM1_reset (DEVICE *dptr);
uint8 EPROM1_get_mbyte(uint16 addr);
/* external function prototypes */
extern void multibus_put_mbyte(uint16 addr, uint8 val);
/* external globals */
extern uint8 xack; /* XACK signal */
/* globals */
/* SIMH EPROM Standard I/O Data Structures */
UNIT EPROM1_unit[] = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0
};
DEBTAB EPROM1_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE EPROM1_dev = {
"EPROM1", //name
EPROM1_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
NULL, //reset
NULL, //boot
&EPROM1_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
EPROM1_debug, //debflags
NULL, //msize
NULL //lname
};
/* EPROM functions */
// EPROM configuration
t_stat EPROM1_cfg(uint16 base, uint16 size)
{
EPROM1_unit->capac = size; /* set EPROM size */
EPROM1_unit->u3 = base & 0xFFFF; /* set EPROM base */
sim_printf(" EPROM1: 0%04XH bytes at base 0%04XH\n",
EPROM1_unit->capac, EPROM1_unit->u3);
return SCPE_OK;
}
/* EPROM reset */
t_stat EPROM1_reset (DEVICE *dptr)
{
return SCPE_OK;
}
/* EPROM attach */
t_stat EPROM1_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf("EPROM1_attach: Error %d\n", r);
return r;
}
return SCPE_OK;
}
/* get a byte from memory */
uint8 EPROM1_get_mbyte(uint16 addr)
{
uint8 val;
if ((addr >= EPROM1_unit->u3) && ((uint32) addr <= (EPROM1_unit->u3 + EPROM1_unit->capac))) {
SET_XACK(1); /* good memory address */
val = *((uint8 *)EPROM1_unit->filebuf + (addr - EPROM1_unit->u3));
val &= 0xFF;
return val;
} else {
sim_printf("EPROM1: Out of range\n");
}
return 0;
}
/* end of iEPROM1.c */

View file

@ -34,14 +34,18 @@
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
//dbb status flag bits //dbb status flag bits
#define OBF 1 #define OBF 1
#define IBF 2 #define IBF 2
#define F0 4 #define F0 4
#define CD 8 #define CD 8
//system status bits
#define IIM 16 //illegal interrupt mask
#define IDT 32 //illegal data transfer
#define IC 64 //illegal command
#define DE 128 //device error
//dbb command codes //dbb command codes
#define PACIFY 0x00 //Resets IOC and its devices #define PACIFY 0x00 //Resets IOC and its devices
#define ERESET 0x01 //Resets device-generated error (not used by standard devices) #define ERESET 0x01 //Resets device-generated error (not used by standard devices)
@ -67,19 +71,18 @@
/* external globals */ /* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX; extern int32 PCX;
/* function prototypes */ /* function prototypes */
uint8 ioc_cont0(t_bool io, uint8 data); /* ioc_cont*/ t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
uint8 ioc_cont1(t_bool io, uint8 data); /* ioc_cont*/ t_stat ioc_cont_reset (DEVICE *dptr);
t_stat ioc_cont_reset (DEVICE *dptr, uint16 baseport); uint8 ioc_cont0(t_bool io, uint8 data, uint8 devnum); /* ioc_cont*/
uint8 ioc_cont1(t_bool io, uint8 data, uint8 devnum); /* ioc_cont*/
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint32 saved_PC; /* program counter */
/* globals */ /* globals */
@ -123,8 +126,7 @@ DEVICE ioc_cont_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &ioc_cont_reset, //reset ioc_cont_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
@ -136,14 +138,21 @@ DEVICE ioc_cont_dev = {
NULL //lname NULL //lname
}; };
// ioc_cont configuration
t_stat ioc_cont_cfg(uint8 base, uint8 devnum)
{
sim_printf(" ioc-cont[%d]: at base 0%02XH\n",
devnum, base & 0xFF);
reg_dev(ioc_cont0, base, devnum);
reg_dev(ioc_cont1, base + 1, devnum);
return SCPE_OK;
}
/* Reset routine */ /* Reset routine */
t_stat ioc_cont_reset(DEVICE *dptr, uint16 baseport) t_stat ioc_cont_reset(DEVICE *dptr)
{ {
sim_printf(" ioc_cont[%d]: Reset\n", 0);
sim_printf(" ioc_cont[%d]: Registered at %04X\n", 0, baseport);
reg_dev(ioc_cont0, baseport, 0);
reg_dev(ioc_cont1, baseport + 1, 0);
dbb_stat = 0x00; /* clear DBB status */ dbb_stat = 0x00; /* clear DBB status */
return SCPE_OK; return SCPE_OK;
} }
@ -152,80 +161,97 @@ t_stat ioc_cont_reset(DEVICE *dptr, uint16 baseport)
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* IOC control port functions */ /* IOC data port functions */
uint8 ioc_cont0(t_bool io, uint8 data) uint8 ioc_cont0(t_bool io, uint8 data, uint8 devnum)
{ {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if (DEBUG) dbb_stat &= ~OBF; //reset OBF flag
sim_printf("\n ioc_cont0: read data returned %02X PCX=%04X", dbb_out, PCX);
return dbb_out; return dbb_out;
} else { /* write data port */ } else { /* write data port */
dbb_in = data; dbb_in = data;
dbb_stat |= IBF; dbb_stat |= IBF;
if (DEBUG)
sim_printf("\n ioc_cont0: write data=%02X port=%02X PCX=%04X", dbb_in, port, PCX);
return 0; return 0;
} }
} }
uint8 ioc_cont1(t_bool io, uint8 data) /* IOC control port functions */
uint8 ioc_cont1(t_bool io, uint8 data, uint8 devnum)
{ {
int temp; int temp;
if (io == 0) { /* read status port */ if (io == 0) { /* read status port */
if ((dbb_stat & F0) && (dbb_stat & IBF)) { if ((dbb_stat & F0) && (dbb_stat & IBF)) {
temp = dbb_stat; return dbb_stat;
if (DEBUG)
sim_printf("\n ioc_cont1: DBB status read 1 data=%02X PCX=%04X", dbb_stat, PCX);
dbb_stat &= ~IBF; //reset IBF flag
return temp;
} }
if ((dbb_stat & F0) && (dbb_stat & OBF)) { if ((dbb_stat & F0) && (dbb_stat & OBF)) {
temp = dbb_stat; temp = dbb_stat;
if (DEBUG)
sim_printf("\n ioc_cont1: DBB status read 2 data=%02X PCX=%04X", dbb_stat, PCX);
dbb_stat &= ~OBF; //reset OBF flag dbb_stat &= ~OBF; //reset OBF flag
return temp; return temp;
} }
if (dbb_stat & F0) { if (dbb_stat & F0) {
temp = dbb_stat; return dbb_stat;
if (DEBUG)
sim_printf("\n ioc_cont1: DBB status read 3 data=%02X PCX=%04X", dbb_stat, PCX);
dbb_stat &= ~F0; //reset F0 flag
return temp;
} }
// if (DEBUG)
// sim_printf(" ioc_cont1: DBB status read 4 data=%02X PCX=%04X\n", dbb_stat, PCX);
return dbb_stat; return dbb_stat;
} else { /* write command port */ } else { /* write command port */
dbb_stat |= F0;
dbb_cmd = data; dbb_cmd = data;
switch(dbb_cmd){ switch(dbb_cmd){
case PACIFY: //should delay 100 ms case PACIFY: //reset IOC and its devices
dbb_stat = 0; dbb_stat = 0;
break; break;
case SYSTAT: case ERESET: //reset device-generated error(not used by std devices)
break;
case SYSTAT: //returns subsystem status byte to master
dbb_out = 0; dbb_out = 0;
dbb_stat |= OBF; dbb_stat |= OBF;
dbb_stat &= ~CD; dbb_stat &= ~CD;
break; break;
case CRTS: case DSTAT: //returns device status to master
break;
case SRQDAK: //enables input of device int ack mask from master
break;
case SRQACK: //clears IOC subsystem int req
break;
case SRQ: //tests ability of IOC to forward an int req to master
break;
case DECHO: //tests ability of IOC to echo data byte sent by master
break;
case CSMEM: //requests IOC to checksum onboard ROM
break;
case TRAM: //requests IOC to test onboard RAM
break;
case SINT: //enables specified device int from IOC
break;
case CRTC: //requests data byte output to CRT
break;
case CRTS: //return CRT status byte to master
dbb_out = 0; dbb_out = 0;
dbb_stat |= F0; dbb_stat |= F0;
break; break;
case KSTC: case KEYC: //request data byte from KBD
dbb_out = 0;
dbb_stat |= F0;
break; break;
case RDSTS: case KSTC: //return KBD status byte to master
dbb_out = 0;
break;
case WPBC: //enables input of first 5 bytes of IOPB
break;
case WPBCC: //enables input of 4 bytes that follow WPDC
break;
case WDBC: //enables input of diskette write bytes from master
break;
case RDBC: //enables output of diskette read bytes to master.
break;
case RRSTS: //returns diskette result byte to master
break;
case RDSTS: //returns diskette device status byte to master
dbb_out = 0x80; //not ready dbb_out = 0x80; //not ready
dbb_stat |= (F0 | IBF); dbb_stat |= IBF;
break; break;
default: default:
sim_printf("\n ioc_cont1: Unknown command %02X PCX=%04X", dbb_cmd, PCX); sim_printf(" IOC-CONT: Unknown command %02X PCX=%04X\n", dbb_cmd, PCX);
} }
if (DEBUG)
sim_printf("\n ioc_cont1: DBB command write data=%02X PCX=%04X", dbb_cmd, PCX);
return 0; return 0;
} }
} }

181
Intel-Systems/common/ipb.c Normal file
View file

@ -0,0 +1,181 @@
/* ipb.c: Intel IPB Processor simulator
Copyright (c) 2017, 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.
01 Mar 18 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
t_stat SBC_reset (DEVICE *dptr);
/* external function prototypes */
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 EPROM_get_mbyte(uint16 addr);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8251_reset(DEVICE *dptr);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_reset(DEVICE *dptr);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_reset(DEVICE *dptr);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_reset(DEVICE *dptr);
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat RAM_reset(DEVICE *dptr);
extern t_stat ipc_cont_reset(DEVICE *dptr);
extern t_stat ipc_cont_cfg(uint8 base, uint8 devnum);
extern t_stat ioc_cont_reset(DEVICE *dptr);
extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
/* globals */
int onetime = 0;
/* extern globals */
extern uint32 PCX; /* program counter */
extern UNIT i8255_unit;
extern UNIT EPROM_unit;
extern UNIT RAM_unit;
extern UNIT ipc_cont_unit;
extern UNIT ioc_cont_unit;
extern DEVICE *i8080_dev;
extern DEVICE *i8251_dev;
extern DEVICE *i8253_dev;
extern DEVICE *i8255_dev;
extern DEVICE *i8259_dev;
extern DEVICE *ipc_cont_dev;
extern DEVICE *ioc_cont_dev;
t_stat SBC_config(void)
{
sim_printf("Configuring IPB SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE_0, 0);
i8251_cfg(I8251_BASE_1, 1);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
i8259_cfg(I8259_BASE_0, 0);
i8259_cfg(I8259_BASE_1, 0);
ipc_cont_cfg(ICONT_BASE, 0);
ioc_cont_cfg(DBB_BASE, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* CPU reset routine
put here to cause a reset of the entire IPC system */
t_stat SBC_reset (DEVICE *dptr)
{
if (onetime == 0) {
SBC_config();
multibus_cfg();
onetime++;
}
i8080_reset(i8080_dev);
i8251_reset(i8251_dev);
i8253_reset(i8253_dev);
i8255_reset(i8255_dev);
i8259_reset(i8259_dev);
ipc_cont_reset(ipc_cont_dev);
ioc_cont_reset(ioc_cont_dev);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
if (addr >= 0xF800) { //monitor ROM - always there
return EPROM_get_mbyte(addr - 0xF000); //top half of EPROM
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return EPROM_get_mbyte(addr); //top half of EPROM for boot
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return EPROM_get_mbyte(addr - 0xE800); //bottom half of EPROM
}
if (addr < 0x8000) //IPB RAM
return RAM_get_mbyte(addr);
else
return multibus_get_mbyte(addr); //check multibus cards
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
if (addr >= 0xF800) { //monitor ROM - always there
return;
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return;
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return;
}
if (addr < 0x8000) {
RAM_put_mbyte(addr, val); //IPB RAM
return;
}
multibus_put_mbyte(addr, val); //check multibus cards
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of ipb.c */

View file

@ -0,0 +1,373 @@
/* ipcmultibus.c: Multibus I simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
01 Mar 18 - Original file.
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
*/
#include "system_defs.h"
int32 mbirq = 0; /* set no multibus interrupts */
/* function prototypes */
t_stat multibus_cfg(void);
t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num);
void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 data, uint8 devnum);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
uint16 multibus_get_mword(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
void multibus_put_mword(uint16 addr, uint16 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num);
extern t_stat zx200a_reset(DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr);
extern t_stat isbc206_reset (DEVICE *dptr);
extern t_stat isbc464_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern DEVICE isbc464_dev;
extern DEVICE isbc064_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE zx200a_dev;
/* multibus Standard SIMH Device Data Structures */
UNIT multibus_unit = {
UDATA (&multibus_svc, 0, 0), 20
};
REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) },
{ NULL }
};
DEBTAB multibus_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE multibus_dev = {
"MBIRQ", //name
&multibus_unit, //units
multibus_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&multibus_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
multibus_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
return SCPE_OK;
}
/* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_1:
set_cpuint(INT_R);
#if NIPC
clr_irq(SBC202_INT); /***** bad, bad, bad! */
#endif
// sim_printf("multibus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
break;
default:
// sim_printf("multibus_svc: default mbirq=%04X\n", mbirq);
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
return SCPE_OK;
}
/* Reset routine */
t_stat multibus_reset(DEVICE *dptr)
{
if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n");
if (SBC064_NUM) { //device installed
isbc064_reset(&isbc064_dev);
sim_printf(" Multibus: SBC064 reset\n");
}
if (SBC464_NUM) { //unit enabled
isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
return SCPE_OK;
}
}
void set_irq(int32 int_num)
{
mbirq |= int_num;
// sim_printf("set_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
void clr_irq(int32 int_num)
{
mbirq &= ~int_num;
// sim_printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
/* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered.
*/
struct idev {
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 port;
uint8 devnum;
};
struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
};
uint8 nulldev(t_bool flag, uint8 data, uint8 devnum)
{
SET_XACK(0); /* set no XACK */
return 0; //should be 0xff, but ISIS won't boot if not 0!
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine) { /* different device? */
sim_printf(" Multibus: I/O Port %04X is already assigned to different device\n", port);
return 1;
} else
return 0;
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
uint8 val = 0;
SET_XACK(0); /* set no XACK */
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= SBC464_BASE && addr <= (SBC464_BASE + SBC464_SIZE - 1))
return(isbc464_get_mbyte(addr));
}
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= SBC064_BASE && addr <= (SBC064_BASE + SBC064_SIZE - 1))
val = isbc064_get_mbyte(addr);
}
if (xack == 0)
val = RAM_get_mbyte(addr);
return val;
}
/* get a word from memory */
uint16 multibus_get_mword(uint16 addr)
{
uint16 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= SBC064_BASE && addr <= (SBC064_BASE + SBC064_SIZE - 1))
isbc064_put_mbyte(addr, val);
}
RAM_put_mbyte(addr, val);
}
/* put a word to memory */
void multibus_put_mword(uint16 addr, uint16 val)
{
multibus_put_mbyte(addr, val & 0xff);
multibus_put_mbyte(addr+1, val >> 8);
}
/* end of ipbmultibus.c */

View file

@ -33,16 +33,15 @@
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* function prototypes */ /* function prototypes */
uint8 ipc_cont(t_bool io, uint8 data); /* ipc_cont*/ t_stat ipc_cont_cfg(uint8 base, uint8 devnum);
t_stat ipc_cont_reset (DEVICE *dptr, uint16 baseport); uint8 ipc_cont(t_bool io, uint8 data, uint8 devnum); /* ipc_cont*/
t_stat ipc_cont_reset (DEVICE *dptr);
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* globals */ /* globals */
@ -81,7 +80,6 @@ DEVICE ipc_cont_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &ipc_cont_reset, //reset
NULL, //reset NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
@ -94,13 +92,20 @@ DEVICE ipc_cont_dev = {
NULL //lname NULL //lname
}; };
// ipc_cont configuration
t_stat ipc_cont_cfg(uint8 base, uint8 devnum)
{
sim_printf(" ipc-cont[%d]: at base 0%02XH\n",
devnum, base & 0xFF);
reg_dev(ipc_cont, base, devnum);
return SCPE_OK;
}
/* Reset routine */ /* Reset routine */
t_stat ipc_cont_reset(DEVICE *dptr, uint16 baseport) t_stat ipc_cont_reset(DEVICE *dptr)
{ {
sim_printf(" ipc_cont[%d]: Reset\n", 0);
sim_printf(" ipc_cont[%d]: Registered at %04X\n", 0, baseport);
reg_dev(ipc_cont, baseport, 0);
ipc_cont_unit[0].u3 = 0x00; /* ipc reset */ ipc_cont_unit[0].u3 = 0x00; /* ipc reset */
return SCPE_OK; return SCPE_OK;
} }
@ -111,12 +116,9 @@ t_stat ipc_cont_reset(DEVICE *dptr, uint16 baseport)
/* IPC control port functions */ /* IPC control port functions */
uint8 ipc_cont(t_bool io, uint8 data) uint8 ipc_cont(t_bool io, uint8 data, uint8 devnum)
{ {
if (io == 0) { /* read status port */ if (io == 0) { /* read status port */
if (DEBUG)
sim_printf(" ipc_cont: read data=%02X ipc_cont_unit[%d].u3=%02X\n",
ipc_cont_unit[0].u3, 0, ipc_cont_unit[0].u3);
return ipc_cont_unit[0].u3; return ipc_cont_unit[0].u3;
} else { /* write control port */ } else { /* write control port */
//this simulates an 74LS259 register //this simulates an 74LS259 register
@ -155,8 +157,6 @@ uint8 ipc_cont(t_bool io, uint8 data)
default: default:
break; break;
} }
if (DEBUG)
sim_printf(" ipc_cont: write data=%02X ipc_cont_unit[%d].u3=%02X\n", data, 0, ipc_cont_unit[0].u3);
} }
return 0; return 0;
} }

View file

@ -31,10 +31,9 @@
#include "system_defs.h" #include "system_defs.h"
#define DEBUG 0
/* function prototypes */ /* function prototypes */
t_stat SBC_config(void);
uint8 get_mbyte(uint16 addr); uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr); uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val); void put_mbyte(uint16 addr, uint8 val);
@ -44,52 +43,82 @@ t_stat SBC_reset (DEVICE *dptr);
/* external function prototypes */ /* external function prototypes */
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */ extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
//extern uint8 multibus_get_mbyte(uint16 addr);
//extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 EPROM_get_mbyte(uint16 addr); extern uint8 EPROM_get_mbyte(uint16 addr);
extern uint8 RAM_get_mbyte(uint16 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8251_reset(DEVICE *dptr);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_reset(DEVICE *dptr);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_reset(DEVICE *dptr);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_reset(DEVICE *dptr);
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat RAM_reset(DEVICE *dptr);
extern t_stat ipc_cont_reset(DEVICE *dptr);
extern t_stat ipc_cont_cfg(uint8 base, uint8 devnum);
extern t_stat ioc_cont_reset(DEVICE *dptr);
extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
/* external globals */
extern uint32 PCX; /* program counter */
extern UNIT i8255_unit; extern UNIT i8255_unit;
extern UNIT EPROM_unit; extern UNIT EPROM_unit;
extern UNIT RAM_unit; extern UNIT RAM_unit;
extern UNIT ipc_cont_unit; extern UNIT ipc_cont_unit;
extern UNIT ioc_cont_unit; extern UNIT ioc_cont_unit;
extern int32 i8251_devnum; extern DEVICE *i8080_dev;
extern t_stat i8251_reset(DEVICE *dptr, uint16 base); extern DEVICE *i8251_dev;
extern int32 i8253_devnum; extern DEVICE *i8253_dev;
extern t_stat i8253_reset(DEVICE *dptr, uint16 base); extern DEVICE *i8255_dev;
extern int32 i8255_devnum; extern DEVICE *i8259_dev;
extern t_stat i8255_reset(DEVICE *dptr, uint16 base); extern DEVICE *ipc_cont_dev;
extern int32 i8259_devnum; extern DEVICE *ioc_cont_dev;
extern t_stat i8259_reset(DEVICE *dptr, uint16 base);
extern t_stat EPROM_reset(DEVICE *dptr, uint16 size); /* globals */
extern t_stat RAM_reset(DEVICE *dptr, uint16 base, uint16 size);
extern t_stat ipc_cont_reset(DEVICE *dptr, uint16 base); int onetime = 0;
extern t_stat ioc_cont_reset(DEVICE *dptr, uint16 base);
extern uint32 PCX; /* program counter */ t_stat SBC_config(void)
{
sim_printf("Configuring IPC SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE_0, 0);
i8251_cfg(I8251_BASE_1, 1);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
i8259_cfg(I8259_BASE_0, 0);
i8259_cfg(I8259_BASE_1, 0);
ipc_cont_cfg(ICONT_BASE, 0);
ioc_cont_cfg(DBB_BASE, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* CPU reset routine /* CPU reset routine
put here to cause a reset of the entire IPC system */ put here to cause a reset of the entire IPC system */
t_stat SBC_reset (DEVICE *dptr) t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing MDS-225\n Onboard Devices:\n"); if (onetime == 0) {
i8080_reset(NULL); SBC_config();
i8251_devnum = 0; multibus_cfg();
i8251_reset(NULL, I8251_BASE_0); onetime++;
i8251_reset(NULL, I8251_BASE_1); }
i8253_devnum = 0; i8080_reset(i8080_dev);
i8253_reset(NULL, I8253_BASE); i8251_reset(i8251_dev);
i8255_devnum = 0; i8253_reset(i8253_dev);
i8255_reset(NULL, I8255_BASE_0); i8255_reset(i8255_dev);
i8255_reset(NULL, I8255_BASE_1); i8259_reset(i8259_dev);
i8259_devnum = 0; ipc_cont_reset(ipc_cont_dev);
i8259_reset(NULL, I8259_BASE_0); ioc_cont_reset(ioc_cont_dev);
i8259_reset(NULL, I8259_BASE_1);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
ipc_cont_reset(NULL, ICONT_BASE);
ioc_cont_reset(NULL, DBB_BASE);
return SCPE_OK; return SCPE_OK;
} }
@ -125,18 +154,12 @@ uint16 get_mword(uint16 addr)
void put_mbyte(uint16 addr, uint8 val) void put_mbyte(uint16 addr, uint8 val)
{ {
if (addr >= 0xF800) { //monitor ROM - always there if (addr >= 0xF800) { //monitor ROM - always there
if (DEBUG)
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return; return;
} }
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
if (DEBUG)
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return; return;
} }
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
if (DEBUG)
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return; return;
} }
RAM_put_mbyte(addr, val); RAM_put_mbyte(addr, val);

View file

@ -26,7 +26,6 @@
MODIFICATIONS: MODIFICATIONS:
?? ??? 10 - Original file. ?? ??? 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 24 Apr 15 -- Modified to use simh_debug
NOTES: NOTES:
@ -41,15 +40,16 @@
#define SET_XACK(VAL) (xack = VAL) #define SET_XACK(VAL) (xack = VAL)
int32 mbirq = 0; /* set no multibus interrupts */ int32 mbirq = 0; /* set no multibus interrupts */
int32 flag = 0;
/* function prototypes */ /* function prototypes */
t_stat multibus_cfg(void);
t_stat multibus_svc(UNIT *uptr); t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr); t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num); void set_irq(int32 int_num);
void clr_irq(int32 int_num); void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 data); uint8 nulldev(t_bool flag, uint8 data, uint8 devnum);
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
t_stat multibus_reset (DEVICE *dptr); t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr); uint8 multibus_get_mbyte(uint16 addr);
uint16 multibus_get_mword(uint16 addr); uint16 multibus_get_mword(uint16 addr);
@ -60,19 +60,38 @@ void multibus_put_mword(uint16 addr, uint16 val);
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */ extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num); extern void set_cpuint(int32 int_num);
extern t_stat zx200a_reset(DEVICE *dptr, uint16 base); extern t_stat isbc064_reset (DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr, uint16); extern t_stat isbc464_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr, uint16); extern t_stat zx200a_reset(DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr);
extern t_stat isbc206_reset (DEVICE *dptr);
extern t_stat isbc208_reset (DEVICE *dptr);
extern uint8 RAM_get_mbyte(uint16 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat isbc208_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
/* external globals */ /* external globals */
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */ extern int32 int_req; /* i8080 INT signal */
extern int32 isbc201_fdcnum; extern DEVICE isbc064_dev;
extern int32 isbc202_fdcnum; extern DEVICE isbc464_dev;
extern int32 zx200a_fdcnum; extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev;
/* multibus Standard SIMH Device Data Structures */ /* multibus Standard SIMH Device Data Structures */
@ -82,7 +101,8 @@ UNIT multibus_unit = {
REG multibus_reg[] = { REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) }, { HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) } { HRDATA (XACK, xack, 8) },
{ NULL }
}; };
DEBTAB multibus_debug[] = { DEBTAB multibus_debug[] = {
@ -122,6 +142,21 @@ DEVICE multibus_dev = {
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
if (SBC208_NUM) isbc208_cfg(SBC208_BASE);
if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
return SCPE_OK;
}
/* service routine - actually does the simulated interrupts */ /* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr) t_stat multibus_svc(UNIT *uptr)
@ -146,16 +181,42 @@ t_stat multibus_svc(UNIT *uptr)
t_stat multibus_reset(DEVICE *dptr) t_stat multibus_reset(DEVICE *dptr)
{ {
SBC_reset(NULL); if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n"); sim_printf(" Multibus: Reset\n");
zx200a_fdcnum = 0; if (SBC064_NUM) { //device installed
zx200a_reset(NULL, ZX200A_BASE); isbc064_reset(&isbc064_dev);
isbc201_fdcnum = 0; sim_printf(" Multibus: SBC064 reset\n");
isbc201_reset(NULL, SBC201_BASE); }
isbc202_fdcnum = 0; if (SBC464_NUM) { //unit enabled
isbc202_reset(NULL, SBC202_BASE); isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (SBC208_NUM) { //unit enabled
isbc208_reset(&isbc208_dev);
sim_printf(" Multibus: SBC208 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */ sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
return SCPE_OK;
}
} }
void set_irq(int32 int_num) void set_irq(int32 int_num)
@ -167,7 +228,6 @@ void set_irq(int32 int_num)
void clr_irq(int32 int_num) void clr_irq(int32 int_num)
{ {
mbirq &= ~int_num; mbirq &= ~int_num;
// sim_printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
} }
/* This is the I/O configuration table. There are 256 possible /* This is the I/O configuration table. There are 256 possible
@ -175,7 +235,8 @@ device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered. address is here, 'nulldev' means no device has been registered.
*/ */
struct idev { struct idev {
uint8 (*routine)(t_bool io, uint8 data); uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 port;
uint8 devnum; uint8 devnum;
}; };
@ -246,19 +307,21 @@ struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */ {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
}; };
uint8 nulldev(t_bool flag, uint8 data) uint8 nulldev(t_bool flag, uint8 data, uint8 devnum)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
// return 0xFF; return 0; //should be 0xff, but ISIS won't boot if not 0!
return 0;
} }
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnum) uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{ {
if (dev_table[port].routine != &nulldev) { /* port already assigned */ if (dev_table[port].routine != &nulldev) { /* port already assigned */
sim_printf(" Multibus: I/O Port %04X is already assigned\n", port); if (dev_table[port].routine != routine) { /* different device? */
sim_printf(" Multibus: I/O Port %02X is already assigned to different device\n", port);
return 1;
} else
return 0;
} else { } else {
sim_printf(" Port %04X is assigned\n", port);
dev_table[port].routine = routine; dev_table[port].routine = routine;
dev_table[port].devnum = devnum; dev_table[port].devnum = devnum;
} }
@ -269,9 +332,16 @@ uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnu
uint8 multibus_get_mbyte(uint16 addr) uint8 multibus_get_mbyte(uint16 addr)
{ {
uint8 val = 0;
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr); if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
return RAM_get_mbyte(addr); if (addr >= SBC464_BASE && addr <= (SBC464_BASE + SBC464_SIZE))
return(isbc464_get_mbyte(addr));
}
if (xack == 0)
val = RAM_get_mbyte(addr);
return val;
} }
/* get a word from memory */ /* get a word from memory */
@ -290,9 +360,7 @@ uint16 multibus_get_mword(uint16 addr)
void multibus_put_mbyte(uint16 addr, uint8 val) void multibus_put_mbyte(uint16 addr, uint8 val)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
// sim_printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr);
RAM_put_mbyte(addr, val); RAM_put_mbyte(addr, val);
// sim_printf("multibus_put_mbyte: Done XACK=%dX\n", XACK);
} }
/* put a word to memory */ /* put a word to memory */

View file

@ -26,8 +26,6 @@
MODIFICATIONS: MODIFICATIONS:
?? ??? 11 - Original file. ?? ??? 11 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES: NOTES:
@ -38,17 +36,15 @@
#include "system_defs.h" #include "system_defs.h"
#define DEBUG 0
/* function prototypes */ /* function prototypes */
t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); t_stat RAM_cfg(uint16 base, uint16 size);
t_stat RAM_reset (DEVICE *dptr);
uint8 RAM_get_mbyte(uint16 addr); uint8 RAM_get_mbyte(uint16 addr);
void RAM_put_mbyte(uint16 addr, uint8 val); void RAM_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */ /* external globals */
extern uint8 i8255_B[4]; //port B byte I/O
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
/* SIMH RAM Standard I/O Data Structures */ /* SIMH RAM Standard I/O Data Structures */
@ -79,8 +75,7 @@ DEVICE RAM_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
// &RAM_reset, //reset RAM_reset, //reset
NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
@ -94,27 +89,26 @@ DEVICE RAM_dev = {
/* RAM functions */ /* RAM functions */
/* RAM reset */ // RAM configuration
t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size) t_stat RAM_cfg(uint16 base, uint16 size)
{ {
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1); RAM_unit.capac = size & 0xFFFF; /* set RAM size */
if (RAM_unit.capac == 0) { /* if undefined */ RAM_unit.u3 = base & 0xFFFF; /* set RAM base */
RAM_unit.capac = size; RAM_unit.filebuf = (uint8 *)malloc(size * sizeof(uint8));
RAM_unit.u3 = base;
}
if (RAM_unit.filebuf == NULL) { /* no buffer allocated */
RAM_unit.filebuf = malloc(RAM_unit.capac);
if (RAM_unit.filebuf == NULL) { if (RAM_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &RAM_dev, "RAM_set_size: Malloc error\n"); sim_printf (" RAM: Malloc error\n");
return SCPE_MEM; return SCPE_MEM;
} }
} sim_printf(" RAM: 0%04XH bytes at base 0%04XH\n",
if (DEBUG) size, base & 0xFFFF);
sim_printf(" RAM: Available [%04X-%04XH]\n", return SCPE_OK;
RAM_unit.u3, }
RAM_unit.u3 + RAM_unit.capac - 1);
sim_debug (DEBUG_flow, &RAM_dev, "RAM_reset: Done\n"); /* RAM reset */
t_stat RAM_reset (DEVICE *dptr)
{
return SCPE_OK; return SCPE_OK;
} }
@ -124,33 +118,26 @@ uint8 RAM_get_mbyte(uint16 addr)
{ {
uint8 val; uint8 val;
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
if ((addr >= RAM_unit.u3) && ((uint32) addr < (RAM_unit.u3 + RAM_unit.capac))) { if ((addr >= RAM_unit.u3) && ((uint32) addr < (RAM_unit.u3 + RAM_unit.capac))) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &RAM_dev, "RAM_get_mbyte: Set XACK for %04X\n", addr);
val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)); val = *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3));
sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val);
return (val & 0xFF); return (val & 0xFF);
} else { } else {
sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
return 0xFF; return 0xFF;
} }
} }
/* put a byte to memory */ /* put a byte into memory */
void RAM_put_mbyte(uint16 addr, uint8 val) void RAM_put_mbyte(uint16 addr, uint8 val)
{ {
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if ((addr >= RAM_unit.u3) && ((uint32)addr < RAM_unit.u3 + RAM_unit.capac)) { if ((addr >= RAM_unit.u3) && ((uint32)addr < RAM_unit.u3 + RAM_unit.capac)) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &RAM_dev, "RAM_put_mbyte: Set XACK for %04X\n", addr);
*((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF; *((uint8 *)RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
sim_debug (DEBUG_write, &RAM_dev, "\n");
return; return;
} else { } else {
sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
return; return;
} }
} }

View file

@ -25,8 +25,8 @@
MODIFICATIONS: MODIFICATIONS:
?? ??? 11 - Original file. ?? ??? 11 -- Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size. 16 Dec 12 -- Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug 24 Apr 15 -- Modified to use simh_debug
NOTES: NOTES:
@ -37,22 +37,42 @@
#include "system_defs.h" #include "system_defs.h"
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define SET_XACK(VAL) (xack = VAL) #define SET_XACK(VAL) (xack = VAL)
/* prototypes */ /* prototypes */
t_stat isbc064_reset (DEVICE *dptr); t_stat isbc064_cfg(uint16 base, uint16 size);
t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc064_reset(DEVICE *dptr);
uint8 isbc064_get_mbyte(uint16 addr); uint8 isbc064_get_mbyte(uint16 addr);
void isbc064_put_mbyte(uint16 addr, uint8 val); void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 xack; /* XACK signal */ /* external function prototypes */
/* isbc064 Standard I/O Data Structures */ /* local globals */
/* external globals */
extern uint32 PCX; /* program counter */
extern uint8 xack;
/* isbc064 Standard SIMH Device Data Structures */
UNIT isbc064_unit = { UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT
}; };
MTAB isbc064_mod[] = {
{ UNIT_MSIZE, 16384, "16K", "16K", &isbc064_set_size },
{ UNIT_MSIZE, 32768, "32K", "32K", &isbc064_set_size },
{ UNIT_MSIZE, 49152, "48K", "48K", &isbc064_set_size },
{ UNIT_MSIZE, 65536, "64K", "64K", &isbc064_set_size },
{ 0 }
};
DEBTAB isbc064_debug[] = { DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all }, { "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow }, { "FLOW", DEBUG_flow },
@ -68,7 +88,7 @@ DEVICE isbc064_dev = {
"SBC064", //name "SBC064", //name
&isbc064_unit, //units &isbc064_unit, //units
NULL, //registers NULL, //registers
NULL, //modifiers isbc064_mod, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
@ -76,8 +96,7 @@ DEVICE isbc064_dev = {
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposite NULL, //deposit
// &isbc064_reset, //reset
NULL, //reset NULL, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
@ -90,29 +109,40 @@ DEVICE isbc064_dev = {
NULL //lname NULL //lname
}; };
/* iSBC064 globals */ /* Service routines to handle simulator functions */
// configuration routine
t_stat isbc064_cfg(uint16 base, uint16 size)
{
sim_printf(" sbc064: 0%04XH bytes at base 0%04XH\n",
size, base);
isbc064_unit.capac = size; //set size
isbc064_unit.u3 = base; //and base
isbc064_unit.filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (isbc064_unit.filebuf == NULL) {
sim_printf (" sbc064: Malloc error\n");
return SCPE_MEM;
}
return SCPE_OK;
}
t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if ((val <= 0) || (val > MAXMEMSIZE)) {
sim_printf("Memory size error - val=%d\n", val);
return SCPE_ARG;
}
isbc064_reset(&isbc064_dev);
isbc064_unit.capac = val;
sim_printf("SBC064: Size set to %04X\n", val);
return SCPE_OK;
}
/* Reset routine */ /* Reset routine */
t_stat isbc064_reset (DEVICE *dptr) t_stat isbc064_reset (DEVICE *dptr)
{ {
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: ");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
isbc064_unit.capac = SBC064_SIZE;
isbc064_unit.u3 = SBC064_BASE;
sim_printf("Initializing iSBC-064 RAM Board\n");
sim_printf(" Available[%04X-%04XH]\n",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
}
if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = (uint8 *)malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -120,55 +150,37 @@ t_stat isbc064_reset (DEVICE *dptr)
uint8 isbc064_get_mbyte(uint16 addr) uint8 isbc064_get_mbyte(uint16 addr)
{ {
uint32 val, org, len; uint32 val;
if ((isbc064_dev.flags & DEV_DIS) == 0) { if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
org = isbc064_unit.u3; if ((addr >= isbc064_unit.u3) && (addr <= (isbc064_unit.u3 + isbc064_unit.capac))) {
len = isbc064_unit.capac;
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: addr=%04X", addr);
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
sim_debug (DEBUG_xack, &isbc064_dev, "isbc064_get_mbyte: Set XACK for %04X\n", addr); val = *((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.u3));
val = *((uint8 *)isbc064_unit.filebuf + (addr - org));
sim_debug (DEBUG_read, &isbc064_dev, " val=%04X\n", val);
// sim_printf ("isbc064_get_mbyte: addr=%04X, val=%02X\n", addr, val);
return (val & 0xFF); return (val & 0xFF);
} else { } else {
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: Out of range\n"); sim_printf("isbc064_get_mbyte: Read-Enabled Out of range addr=%04X PC=%04X\n", addr, PCX);
return 0; /* multibus has active high pullups and inversion */ return 0xff; /* multibus has active high pullups and inversion */
} }
} } //device is disabled/not installed
sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: Disabled\n"); sim_printf ("isbc064_get_mbyte: Read-Disabled addr=%04X PC=%04X\n", addr, PCX);
// sim_printf ("isbc064_get_mbyte: Disabled\n"); return 0xff; /* multibus has active high pullups and inversion */
return 0; /* multibus has active high pullups and inversion */
} }
/* put a byte into memory */ /* put a byte into memory */
void isbc064_put_mbyte(uint16 addr, uint8 val) void isbc064_put_mbyte(uint16 addr, uint8 val)
{ {
uint32 org, len; if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if ((addr >= isbc064_unit.u3) && (addr < (isbc064_unit.u3 + isbc064_unit.capac))) {
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
// sim_printf ("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Set XACK for %04X\n", addr); *((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.u3)) = val & 0xFF;
*((uint8 *)isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Return\n");
return; return;
} else { } else {
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Out of range\n"); sim_printf("isbc064_put_mbyte: Write Out of range addr=%04X PC=%04X\n", addr, PCX);
return; return;
} }
} } //device is disabled/not installed
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Disabled\n"); sim_printf ("isbc064_put_mbyte: Write-Disabled addr=%04X PC=%04X\n", addr, PCX);
// sim_printf ("isbc064_put_mbyte: Disabled\n");
} }
/* end of isbc064.c */ /* end of isbc064.c */

View file

@ -34,7 +34,7 @@
Registers: Registers:
078H - Read - Subsystem status 088H - Read - Subsystem status
bit 0 - ready status of drive 0 bit 0 - ready status of drive 0
bit 1 - ready status of drive 1 bit 1 - ready status of drive 1
bit 2 - state of channel's interrupt FF bit 2 - state of channel's interrupt FF
@ -44,16 +44,16 @@
bit 6 - zero bit 6 - zero
bit 7 - zero bit 7 - zero
079H - Read - Read result type (bits 2-7 are zero) 089H - Read - Read result type (bits 2-7 are zero)
00 - I/O complete with error(unlinked) 00 - I/O complete with error(unlinked)
01 - I/O complete with error(linked)(hi 6-bits are block num) 01 - I/O complete with error(linked)(hi 6-bits are block num)
10 - Result byte contains diskette ready status 10 - Result byte contains diskette ready status
11 - Reserved 11 - Reserved
079H - Write - IOPB address low byte. 089H - Write - IOPB address low byte.
07AH - Write - IOPB address high byte and start operation. 08AH - Write - IOPB address high byte and start operation.
07BH - Read - Read result byte 08BH - Read - Read result byte
If result type is 00H If result type is 00H
bit 0 - deleted record bit 0 - deleted record
bit 1 - CRC error bit 1 - CRC error
@ -74,7 +74,7 @@
bit 7 - drive 1 ready bit 7 - drive 1 ready
else return 0 else return 0
07FH - Write - Reset diskette system. 08FH - Write - Reset diskette system.
Operations: Operations:
NOP - 0x00 NOP - 0x00
@ -136,19 +136,35 @@
u3 - u3 -
u4 - u4 -
u5 - fdc number (board instance number). u5 -
u6 - fdd number. u6 - fdd number.
SSSD - Bootable
This is actually an IBM 3740 format disk. It has 77 tracks of 26 SD
sectors of 128 bytes each for a total of 2002 sectors. The disk layout
of the first 6 tracks of the SSSD 256256 byte disk image is as follows:
File Link Blk Addr Data Blk Addr
From To
Trk Sec Trk Sec Trk Sec
ISIS.T0 000h 018h 000h 001h 000h 017h bin file 0B80 0000 0B00
ISIS.DIR 001h 001h 001h 002h 001h 01Ah 0D00 0D80 1980
ISIS.MAP 002h 001h 002h 002h 002h 003h 1A00 1A80 1B00
ISIS.LAB 000h 019h 000h 01Ah 000h 01Ah 0C00 0C80 0C80
ISIS.BIN 002h 004h 002h 005h 004h 00Eh pkd file 1B80 1C00 3A80
004h 00Fh 004h 010h 005h 013h 3B00 3B80 4A00
ISIS.CLI 005h 014h 005h 015h 006h 00Dh reg file 4A80 4B00 5480
NEXT BLK 006h 00Eh 5500
*/ */
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */ #define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE) #define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 2 #define FDD_NUM 2
#define SECSIZ 128
//disk controoler operations //disk controoler operations
#define DNOP 0x00 //disk no operation #define DNOP 0x00 //disk no operation
@ -166,10 +182,10 @@
#define FDCPRE 0x08 //FDC board present #define FDCPRE 0x08 //FDC board present
//result type //result type
#define RERR 0x00 //FDC returned error #define ROK 0x00 //FDC OK OR ERROR
#define ROK 0x02 //FDC returned ok #define RCHG 0x02 //FDC DISK CHANGED
// If result type is RERR then rbyte is // If result type is ROK then rbyte is
#define RB0DR 0x01 //deleted record #define RB0DR 0x01 //deleted record
#define RB0CRC 0x02 //CRC error #define RB0CRC 0x02 //CRC error
#define RB0SEK 0x04 //seek error #define RB0SEK 0x04 //seek error
@ -179,57 +195,47 @@
#define RB0WE 0x40 //write error #define RB0WE 0x40 //write error
#define RB0NR 0x80 //not ready #define RB0NR 0x80 //not ready
// If result type is ROK then rbyte is // If result type is RCHG then rbyte is
#define RB1RD0 0x40 //drive 0 ready #define RB1RD0 0x40 //drive 0 ready
#define RB1RD1 0x80 //drive 1 ready #define RB1RD1 0x80 //drive 1 ready
//disk geometry values //disk geometry values
#define MDSSD 256256 //single density FDD size #define MDSSD 256256 //single density FDD size
#define MDSDD 512512 //double density FDD size
#define MAXSECSD 26 //single density last sector #define MAXSECSD 26 //single density last sector
#define MAXSECDD 52 //double density last sector
#define MAXTRK 76 //last track #define MAXTRK 76 //last track
/* external globals */ /* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX; extern int32 PCX;
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern uint16 multibus_get_mword(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 multibus_put_mword(uint16 addr, uint16 val);
/* function prototypes */ /* function prototypes */
t_stat isbc201_reset(DEVICE *dptr, uint16 base); t_stat isbc201_cfg(uint8 base);
void isbc201_reset1(uint8 fdcnum); t_stat isbc201_reset(DEVICE *dptr);
void isbc201_reset1(void);
t_stat isbc201_attach (UNIT *uptr, CONST char *cptr); t_stat isbc201_attach (UNIT *uptr, CONST char *cptr);
t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 isbc201_get_dn(void); uint8 isbc201r0(t_bool io, uint8 data, uint8 devnum); /* isbc201 0 */
uint8 isbc2010(t_bool io, uint8 data); /* isbc201 0 */ uint8 isbc201r1(t_bool io, uint8 data, uint8 devnum); /* isbc201 1 */
uint8 isbc2011(t_bool io, uint8 data); /* isbc201 1 */ uint8 isbc201r2(t_bool io, uint8 data, uint8 devnum); /* isbc201 2 */
uint8 isbc2012(t_bool io, uint8 data); /* isbc201 2 */ uint8 isbc201r3(t_bool io, uint8 data, uint8 devnum); /* isbc201 3 */
uint8 isbc2013(t_bool io, uint8 data); /* isbc201 3 */ uint8 isbc201r7(t_bool io, uint8 data, uint8 devnum); /* isbc201 7 */
uint8 isbc2017(t_bool io, uint8 data); /* isbc201 7 */ void isbc201_diskio(void); //do actual disk i/o
void isbc201_diskio(uint8 fdcnum); //do actual disk i/o
/* globals */ /* globals */
int32 isbc201_fdcnum = 0; //actual number of SBC-201 instances + 1
typedef struct { //FDD definition typedef struct { //FDD definition
int t0;
int rdy;
uint8 sec; uint8 sec;
uint8 cyl; uint8 cyl;
} FDDDEF; } FDDDEF;
typedef struct { //FDC definition typedef struct { //FDC definition
uint16 baseport; //FDC base port
uint16 iopb; //FDC IOPB uint16 iopb; //FDC IOPB
uint8 stat; //FDC status uint8 stat; //FDC status
uint8 rdychg; //FDC ready changed uint8 rdychg; //FDC ready changed
@ -240,36 +246,21 @@ typedef struct { //FDC definition
FDDDEF fdd[FDD_NUM]; //indexed by the FDD number FDDDEF fdd[FDD_NUM]; //indexed by the FDD number
} FDCDEF; } FDCDEF;
FDCDEF fdc201[4]; //indexed by the isbc-201 instance number FDCDEF fdc201;
UNIT isbc201_unit[] = { /* isbc201 Standard I/O Data Structures */
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 }, UNIT isbc201_unit[] = { //2 FDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD), 20 } { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD) }
}; };
REG isbc201_reg[] = { REG isbc201_reg[] = {
{ HRDATA (STAT0, fdc201[0].stat, 8) }, /* fdc201 0 status */ { HRDATA (STAT0, fdc201.stat, 8) }, //fdc201 0 status
{ HRDATA (RTYP0, fdc201[0].rtype, 8) }, /* fdc201 0 result type */ { HRDATA (RTYP0, fdc201.rtype, 8) }, //fdc201 0 result type
{ HRDATA (RBYT0A, fdc201[0].rbyte0, 8) }, /* fdc201 0 result byte 0 */ { HRDATA (RBYT0A, fdc201.rbyte0, 8) }, //fdc201 0 result byte 0
{ HRDATA (RBYT0B, fdc201[0].rbyte1, 8) }, /* fdc201 0 result byte 1 */ { HRDATA (RBYT0B, fdc201.rbyte1, 8) }, //fdc201 0 result byte 1
{ HRDATA (INTFF0, fdc201[0].intff, 8) }, /* fdc201 0 interrupt f/f */ { HRDATA (INTFF0, fdc201.intff, 8) }, //fdc201 0 interrupt f/f
{ HRDATA (STAT1, fdc201[1].stat, 8) }, /* fdc201 1 status */
{ HRDATA (RTYP1, fdc201[1].rtype, 8) }, /* fdc201 1 result type */
{ HRDATA (RBYT1A, fdc201[1].rbyte0, 8) }, /* fdc201 1 result byte 0 */
{ HRDATA (RBYT1B, fdc201[1].rbyte1, 8) }, /* fdc201 1 result byte 1 */
{ HRDATA (INTFF1, fdc201[1].intff, 8) }, /* fdc201 1 interrupt f/f */
{ HRDATA (STAT2, fdc201[2].stat, 8) }, /* fdc201 2 status */
{ HRDATA (RTYP2, fdc201[2].rtype, 8) }, /* fdc201 2 result type */
{ HRDATA (RBYT2A, fdc201[2].rbyte0, 8) }, /* fdc201 2 result byte 0 */
{ HRDATA (RBYT2B, fdc201[2].rbyte1, 8) }, /* fdc201 2 result byte 1 */
{ HRDATA (INTFF2, fdc201[2].intff, 8) }, /* fdc201 2 interrupt f/f */
{ HRDATA (STAT3, fdc201[3].stat, 8) }, /* fdc201 3 status */
{ HRDATA (RTYP3, fdc201[3].rtype, 8) }, /* fdc201 3 result type */
{ HRDATA (RBYT3A, fdc201[3].rbyte0, 8) }, /* fdc201 3 result byte 0 */
{ HRDATA (RBYT3B, fdc201[3].rbyte1, 8) }, /* fdc201 3 result byte 1 */
{ HRDATA (INTFF3, fdc201[3].intff, 8) }, /* fdc201 3 interrupt f/f */
{ NULL } { NULL }
}; };
@ -305,81 +296,72 @@ DEVICE isbc201_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
NULL, //reset isbc201_reset, //reset
NULL, //boot NULL, //boot
&isbc201_attach, //attach &isbc201_attach, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl 0, //dctrl
isbc201_debug, //debflags isbc201_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL //lname
}; };
/* Hardware reset routine */ // configuration routine
t_stat isbc201_reset(DEVICE *dptr, uint16 base) t_stat isbc201_cfg(uint8 base)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
sim_printf(" iSBC-201 FDC Board"); sim_printf(" sbc201: at base 0%02XH\n",
if (SBC201_NUM) { base);
sim_printf(" - Found\n"); reg_dev(isbc201r0, base, 0); //read status
sim_printf(" isbc201-%d: Hardware Reset\n", isbc201_fdcnum); reg_dev(isbc201r1, base + 1, 0); //read rslt type/write IOPB addr-l
sim_printf(" isbc201-%d: Registered at %04X\n", isbc201_fdcnum, base); reg_dev(isbc201r2, base + 2, 0); //write IOPB addr-h and start
//register base port address for this FDC instance reg_dev(isbc201r3, base + 3, 0); //read rstl byte
fdc201[isbc201_fdcnum].baseport = base; reg_dev(isbc201r7, base + 7, 0); //write reset fdc201
//register I/O port addresses for each function
reg_dev(isbc2010, base, isbc201_fdcnum); //read status
reg_dev(isbc2011, base + 1, isbc201_fdcnum); //read rslt type/write IOPB addr-l
reg_dev(isbc2012, base + 2, isbc201_fdcnum); //write IOPB addr-h and start
reg_dev(isbc2013, base + 3, isbc201_fdcnum); //read rstl byte
reg_dev(isbc2017, base + 7, isbc201_fdcnum); //write reset fdc201
// one-time initialization for all FDDs for this FDC instance // one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
uptr = isbc201_dev.units + i; uptr = isbc201_dev.units + i;
uptr->u5 = isbc201_fdcnum; //fdc device number
uptr->u6 = i; //fdd unit number uptr->u6 = i; //fdd unit number
uptr->flags |= UNIT_WPMODE; //set WP in unit flags
} }
isbc201_reset1(isbc201_fdcnum); return SCPE_OK;
isbc201_fdcnum++; }
} else /* Hardware reset routine */
sim_printf(" - Not Found\n");
t_stat isbc201_reset(DEVICE *dptr)
{
isbc201_reset1();
return SCPE_OK; return SCPE_OK;
} }
/* Software reset routine */ /* Software reset routine */
void isbc201_reset1(uint8 fdcnum) void isbc201_reset1(void)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
sim_printf(" isbc201-%d: Software Reset\n", fdcnum); fdc201.stat = 0; //clear status
fdc201[fdcnum].stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */ for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = isbc201_dev.units + i; uptr = isbc201_dev.units + i;
fdc201[fdcnum].stat |= FDCPRE; //set the FDC status fdc201.stat |= FDCPRE; //set the FDC status
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
if (uptr->capac == 0) { /* if not configured */ fdc201.rbyte0 = 0; //set no error
sim_printf(" isbc201-%d: Configured, Status=%02X Not attached\n", i, fdc201[fdcnum].stat); if (uptr->flags & UNIT_ATT) { /* if attached */
} else {
switch(i){ switch(i){
case 0: case 0:
fdc201[fdcnum].stat |= RDY0; //set FDD 0 ready fdc201.stat |= RDY0; //set FDD 0 ready
fdc201[fdcnum].rbyte1 |= RB1RD0; fdc201.rbyte1 |= RB1RD0;
break; break;
case 1: case 1:
fdc201[fdcnum].stat |= RDY1; //set FDD 1 ready fdc201.stat |= RDY1; //set FDD 1 ready
fdc201[fdcnum].rbyte1 |= RB1RD1; fdc201.rbyte1 |= RB1RD1;
break; break;
} }
fdc201[fdcnum].rdychg = 0; fdc201.rdychg = 0;
sim_printf(" isbc201-%d: Configured, Status=%02X Attached to %s\n",
i, fdc201[fdcnum].stat, uptr->filename);
} }
} }
} }
@ -389,29 +371,25 @@ void isbc201_reset1(uint8 fdcnum)
t_stat isbc201_attach (UNIT *uptr, CONST char *cptr) t_stat isbc201_attach (UNIT *uptr, CONST char *cptr)
{ {
t_stat r; t_stat r;
uint8 fdcnum, fddnum; uint8 fddnum;
sim_debug (DEBUG_flow, &isbc201_dev, " isbc201_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" isbc201_attach: Attach error\n"); sim_printf(" SBC201_attach: Attach error %d\n", r);
return r; return r;
} }
fdcnum = uptr->u5;
fddnum = uptr->u6; fddnum = uptr->u6;
switch(fddnum){ switch(fddnum){
case 0: case 0:
fdc201[fdcnum].stat |= RDY0; //set FDD 0 ready fdc201.stat |= RDY0; //set FDD 0 ready
fdc201[fdcnum].rbyte1 |= RB1RD0; fdc201.rbyte1 |= RB1RD0;
break; break;
case 1: case 1:
fdc201[fdcnum].stat |= RDY1; //set FDD 1 ready fdc201.stat |= RDY1; //set FDD 1 ready
fdc201[fdcnum].rbyte1 |= RB1RD1; fdc201.rbyte1 |= RB1RD1;
break; break;
} }
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
sim_printf(" iSBC-201%d: FDD %d Configured %d bytes, Attached to %s\n", fdc201.rbyte0 = 0;
fdcnum, fddnum, uptr->capac, uptr->filename);
sim_debug (DEBUG_flow, &isbc201_dev, " isbc201_attach: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -419,139 +397,86 @@ t_stat isbc201_attach (UNIT *uptr, CONST char *cptr)
t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc) t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
// sim_debug (DEBUG_flow, &isbc201_dev, " isbc201_set_mode: Entered with val=%08XH uptr->flags=%08X\n", if (uptr->flags & UNIT_ATT)
// val, uptr->flags); return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */ if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val; uptr->flags |= val;
} else { /* read write */ } else { /* read write */
uptr->flags &= ~val; uptr->flags &= ~val;
} }
// sim_debug (DEBUG_flow, &isbc201_dev, " isbc201_set_mode: Done\n");
return SCPE_OK; return SCPE_OK;
} }
uint8 isbc201_get_dn(void)
{
int i;
for (i=0; i<SBC201_NUM; i++)
if (port >= fdc201[i].baseport && port <= fdc201[i].baseport + 7)
return i;
sim_printf("isbc201_get_dn: port %04X not in fdc201 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* ISBC201 control port functions */ /* ISBC201 control port functions */
uint8 isbc2010(t_bool io, uint8 data) uint8 isbc201r0(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum; if (io == 0) { /* read status*/
return fdc201.stat;
if ((fdcnum = isbc201_get_dn()) != 0xFF) {
if (io == 0) { /* read ststus*/
if (DEBUG)
sim_printf("\n isbc201-%d: 0x78 returned status=%02X PCX=%04X",
fdcnum, fdc201[fdcnum].stat, PCX);
return fdc201[fdcnum].stat;
}
} }
return 0; return 0;
} }
uint8 isbc2011(t_bool io, uint8 data) uint8 isbc201r1(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc201_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
fdc201[fdcnum].intff = 0; //clear interrupt FF fdc201.intff = 0; //clear interrupt FF
fdc201[fdcnum].stat &= ~FDCINT; fdc201.stat &= ~FDCINT;
if (DEBUG) return fdc201.rtype;
sim_printf("\n isbc201-%d: 0x79 returned rtype=%02X intff=%02X status=%02X PCX=%04X",
fdcnum, fdc201[fdcnum].rtype, fdc201[fdcnum].intff, fdc201[fdcnum].stat, PCX);
return fdc201[fdcnum].rtype;
} else { /* write data port */ } else { /* write data port */
fdc201[fdcnum].iopb = data; fdc201.iopb = data;
if (DEBUG)
sim_printf("\n isbc201-%d: 0x79 IOPB low=%02X PCX=%04X",
fdcnum, data, PCX);
}
} }
return 0; return 0;
} }
uint8 isbc2012(t_bool io, uint8 data) uint8 isbc201r2(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc201_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
fdc201[fdcnum].iopb |= (data << 8); fdc201.iopb |= (data << 8);
if (DEBUG) isbc201_diskio();
sim_printf("\n isbc201-%d: 0x7A IOPB=%04X PCX=%04X", if (fdc201.intff)
fdcnum, fdc201[fdcnum].iopb, PCX); fdc201.stat |= FDCINT;
isbc201_diskio(fdcnum);
if (fdc201[fdcnum].intff)
fdc201[fdcnum].stat |= FDCINT;
}
} }
return 0; return 0;
} }
uint8 isbc2013(t_bool io, uint8 data) uint8 isbc201r3(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc201_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if (fdc201[fdcnum].rtype == 0) { if (fdc201.rtype == ROK) {
if (DEBUG) return fdc201.rbyte0;
sim_printf("\n isbc201-%d: 0x7B returned rbyte0=%02X PCX=%04X",
fdcnum, fdc201[fdcnum].rbyte0, PCX);
return fdc201[fdcnum].rbyte0;
} else { } else {
if (fdc201[fdcnum].rdychg) { if (fdc201.rdychg) {
if (DEBUG) return fdc201.rbyte1;
sim_printf("\n isbc201-%d: 0x7B returned rbyte1=%02X PCX=%04X",
fdcnum, fdc201[fdcnum].rbyte1, PCX);
return fdc201[fdcnum].rbyte1;
} else { } else {
if (DEBUG) return fdc201.rbyte0;
sim_printf("\n isbc201-%d: 0x7B returned rbytex=%02X PCX=%04X",
fdcnum, 0, PCX);
return 0;
} }
} }
} else { /* write data port */ } else { /* write data port */
; //stop diskette operation ; //stop diskette operation
} }
}
return 0; return 0;
} }
uint8 isbc2017(t_bool io, uint8 data) uint8 isbc201r7(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc201_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
isbc201_reset1(fdcnum); isbc201_reset1();
}
} }
return 0; return 0;
} }
// perform the actual disk I/O operation // perform the actual disk I/O operation
void isbc201_diskio(uint8 fdcnum) void isbc201_diskio(void)
{ {
uint8 cw, di, nr, ta, sa, bn, data, nrptr; uint8 cw, di, nr, ta, sa, bn, data, nrptr;
uint16 ba, ni; uint16 ba, ni;
@ -562,40 +487,36 @@ void isbc201_diskio(uint8 fdcnum)
uint8 *fbuf; uint8 *fbuf;
//parse the IOPB //parse the IOPB
cw = multibus_get_mbyte(fdc201[fdcnum].iopb); cw = multibus_get_mbyte(fdc201.iopb);
di = multibus_get_mbyte(fdc201[fdcnum].iopb + 1); di = multibus_get_mbyte(fdc201.iopb + 1);
nr = multibus_get_mbyte(fdc201[fdcnum].iopb + 2); nr = multibus_get_mbyte(fdc201.iopb + 2);
ta = multibus_get_mbyte(fdc201[fdcnum].iopb + 3); ta = multibus_get_mbyte(fdc201.iopb + 3);
sa = multibus_get_mbyte(fdc201[fdcnum].iopb + 4); sa = multibus_get_mbyte(fdc201.iopb + 4) & 0x1f;
ba = multibus_get_mword(fdc201[fdcnum].iopb + 5); ba = multibus_get_mbyte(fdc201.iopb + 5);
bn = multibus_get_mbyte(fdc201[fdcnum].iopb + 7); ba |= (multibus_get_mbyte(fdc201.iopb + 6) << 8);
ni = multibus_get_mword(fdc201[fdcnum].iopb + 8); bn = multibus_get_mbyte(fdc201.iopb + 7);
fddnum = (di & 0x30) >> 4; ni = multibus_get_mbyte(fdc201.iopb + 8);
ni |= (multibus_get_mbyte(fdc201.iopb + 9) << 8);
fddnum = (di & 0x10) >> 4;
uptr = isbc201_dev.units + fddnum; uptr = isbc201_dev.units + fddnum;
fbuf = (uint8 *) (isbc201_dev.units + fddnum)->filebuf; fbuf = (uint8 *) (isbc201_dev.units + fddnum)->filebuf;
if (DEBUG) {
sim_printf("\n isbc201-%d: isbc201_diskio IOPB=%04X FDD=%02X STAT=%02X",
fdcnum, fdc201[fdcnum].iopb, fddnum, fdc201[fdcnum].stat);
sim_printf("\n isbc201-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X",
fdcnum, cw, di, nr, ta, sa, ba, bn, ni);
}
//check for not ready //check for not ready
switch(fddnum) { switch(fddnum) {
case 0: case 0:
if ((fdc201[fdcnum].stat & RDY0) == 0) { if ((fdc201.stat & RDY0) == 0) {
fdc201[fdcnum].rtype = RERR; fdc201.rtype = ROK;
fdc201[fdcnum].rbyte0 = RB0NR; fdc201.rbyte0 = RB0NR;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.intff = 1; //set interrupt FF
sim_printf("\n isbc201-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n SBC201: FDD %d - Ready error", fddnum);
return; return;
} }
break; break;
case 1: case 1:
if ((fdc201[fdcnum].stat & RDY1) == 0) { if ((fdc201.stat & RDY1) == 0) {
fdc201[fdcnum].rtype = RERR; fdc201.rtype = ROK;
fdc201[fdcnum].rbyte0 = RB0NR; fdc201.rbyte0 = RB0NR;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.intff = 1; //set interrupt FF
sim_printf("\n isbc201-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n SBC201: FDD %d - Ready error", fddnum);
return; return;
} }
break; break;
@ -608,61 +529,63 @@ void isbc201_diskio(uint8 fdcnum)
(sa == 0) || (sa == 0) ||
(ta > MAXTRK) (ta > MAXTRK)
)) { )) {
fdc201[fdcnum].rtype = RERR; fdc201.rtype = ROK;
fdc201[fdcnum].rbyte0 = RB0ADR; fdc201.rbyte0 = RB0ADR;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.intff = 1; //set interrupt FF
sim_printf("\n isbc201-%d: Address error on drive %d", fdcnum, fddnum); sim_printf("\n SBC201: FDD %d - Address error at %04X", fddnum, PCX);
return; return;
} }
switch (di & 0x07) { switch (di & 0x07) {
case DNOP: case DNOP:
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
case DSEEK: case DSEEK:
fdc201[fdcnum].fdd[fddnum].sec = sa; fdc201.fdd[fddnum].sec = sa;
fdc201[fdcnum].fdd[fddnum].cyl = ta; fdc201.fdd[fddnum].cyl = ta;
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
case DHOME: case DHOME:
fdc201[fdcnum].fdd[fddnum].sec = sa; fdc201.fdd[fddnum].sec = sa;
fdc201[fdcnum].fdd[fddnum].cyl = 0; fdc201.fdd[fddnum].cyl = 0;
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
case DVCRC: case DVCRC:
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
case DFMT: case DFMT:
//check for WP //check for WP
if(uptr->flags & UNIT_WPMODE) { if(uptr->flags & UNIT_WPMODE) {
fdc201[fdcnum].rtype = RERR; fdc201.rtype = ROK;
fdc201[fdcnum].rbyte0 = RB0WP; fdc201.rbyte0 = RB0WP;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Write protect error 1 on drive %d", fdcnum, fddnum); sim_printf("\n SBC201: FDD %d - Write protect error 1", fddnum);
return; return;
} }
fmtb = multibus_get_mbyte(ba); //get the format byte fmtb = multibus_get_mbyte(ba); //get the format byte
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { for(i=0; i<=((uint32)(MAXSECSD) * SECSIZ); i++) {
*(fbuf + (dskoff + i)) = fmtb; *(fbuf + (dskoff + i)) = fmtb;
} }
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
case DREAD: case DREAD:
nrptr = 0; nrptr = 0;
while(nrptr < nr) { while(nrptr < nr) {
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
if (DEBUG)
sim_printf("\n isbc201-%d: DREAD cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X dskoff=%06X",
fdcnum, cw, di, nr, ta, sa, ba, bn, ni, dskoff);
//copy sector from image to RAM //copy sector from image to RAM
for (i=0; i<128; i++) { for (i=0; i<SECSIZ; i++) {
data = *(fbuf + (dskoff + i)); data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data); multibus_put_mbyte(ba + i, data);
} }
@ -670,26 +593,24 @@ void isbc201_diskio(uint8 fdcnum)
ba+=0x80; ba+=0x80;
nrptr++; nrptr++;
} }
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
case DWRITE: case DWRITE:
//check for WP //check for WP
if(uptr->flags & UNIT_WPMODE) { if(uptr->flags & UNIT_WPMODE) {
fdc201[fdcnum].rtype = RERR; fdc201.rtype = ROK;
fdc201[fdcnum].rbyte0 = RB0WP; fdc201.rbyte0 = RB0WP;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.intff = 1; //set interrupt FF
sim_printf("\n isbc201-%d: Write protect error on drive %d", fdcnum, fddnum); sim_printf("\n SBC201: FDD %d - Write protect error 2", fddnum);
return; return;
} }
nrptr = 0; nrptr = 0;
while(nrptr < nr) { while(nrptr < nr) {
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
if (DEBUG) for (i=0; i<SECSIZ; i++) { //copy sector from image to RAM
sim_printf("\n isbc201-%d: DWRITE cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X bn=%02X ni=%04X dskoff=%06X",
fdcnum, cw, di, nr, ta, sa, ba, bn, ni, dskoff);
for (i=0; i<128; i++) { //copy sector from image to RAM
data = multibus_get_mbyte(ba + i); data = multibus_get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data; *(fbuf + (dskoff + i)) = data;
} }
@ -697,11 +618,12 @@ void isbc201_diskio(uint8 fdcnum)
ba+=0x80; ba+=0x80;
nrptr++; nrptr++;
} }
fdc201[fdcnum].rtype = ROK; fdc201.rtype = ROK;
fdc201[fdcnum].intff = 1; //set interrupt FF fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
break; break;
default: default:
sim_printf("\n isbc201-%d: isbc201_diskio bad di=%02X", fdcnum, di & 0x07); sim_printf("\n SBC201: FDD %d - isbc201_diskio bad di=%02X", fddnum, di & 0x07);
break; break;
} }
} }

View file

@ -1,6 +1,6 @@
/* isbc202.c: Intel double density disk adapter adapter /* isbc202.c: Intel double density disk adapter
Copyright (c) 2010, William A. Beech Copyright (c) 2016, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@ -126,19 +126,18 @@
u3 - u3 -
u4 - u4 -
u5 - fdc number (board instance number). u5 -
u6 - fdd number. u6 - fdd number.
*/ */
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */ #define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE) #define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 4 #define FDD_NUM 4
#define SECSIZ 128
//disk controoler operations //disk controoler operations
#define DNOP 0x00 //disk no operation #define DNOP 0x00 //disk no operation
@ -154,15 +153,15 @@
#define RDY1 0x02 //FDD 1 ready #define RDY1 0x02 //FDD 1 ready
#define FDCINT 0x04 //FDC interrupt flag #define FDCINT 0x04 //FDC interrupt flag
#define FDCPRE 0x08 //FDC board present #define FDCPRE 0x08 //FDC board present
#define FDCDD 0x10 //fdc is DD #define FDCDD 0x10 //FDC is DD
#define RDY2 0x20 //FDD 2 ready #define RDY2 0x20 //FDD 2 ready
#define RDY3 0x40 //FDD 3 ready #define RDY3 0x40 //FDD 3 ready
//result type //result type
#define RERR 0x00 //FDC returned error #define ROK 0x00 //FDC error
#define ROK 0x02 //FDC returned ok #define RCHG 0x02 //FDC OK OR disk changed
// If result type is RERR then rbyte is // If result type is ROK then rbyte is
#define RB0DR 0x01 //deleted record #define RB0DR 0x01 //deleted record
#define RB0CRC 0x02 //CRC error #define RB0CRC 0x02 //CRC error
#define RB0SEK 0x04 //seek error #define RB0SEK 0x04 //seek error
@ -172,59 +171,50 @@
#define RB0WE 0x40 //write error #define RB0WE 0x40 //write error
#define RB0NR 0x80 //not ready #define RB0NR 0x80 //not ready
// If result type is ROK then rbyte is // If result type is RCHG then rbyte is
#define RB1RD2 0x10 //drive 2 ready #define RB1RD2 0x10 //drive 2 ready
#define RB1RD3 0x20 //drive 3 ready #define RB1RD3 0x20 //drive 3 ready
#define RB1RD0 0x40 //drive 0 ready #define RB1RD0 0x40 //drive 0 ready
#define RB1RD1 0x80 //drive 1 ready #define RB1RD1 0x80 //drive 1 ready
//disk geometry values //disk geometry values
#define MDSSD 256256 //single density FDD size
#define MDSDD 512512 //double 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 MAXSECDD 52 //double density last sector
#define MAXTRK 76 //last track #define MAXTRK 76 //last track
/* external globals */ /* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX; extern int32 PCX;
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern uint16 multibus_get_mword(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 multibus_put_mword(uint16 addr, uint16 val);
/* function prototypes */ /* function prototypes */
t_stat isbc202_reset(DEVICE *dptr, uint16 base); t_stat isbc202_cfg(uint8 base);
void isbc202_reset1(uint8 fdcnum); t_stat isbc202_reset(DEVICE *dptr);
void isbc202_reset_dev(void);
t_stat isbc202_attach (UNIT *uptr, CONST char *cptr); t_stat isbc202_attach (UNIT *uptr, CONST char *cptr);
t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 isbc202_get_dn(void); uint8 isbc202r0(t_bool io, uint8 data, uint8 devnum); /* isbc202 0 */
uint8 isbc2020(t_bool io, uint8 data); /* isbc202 0 */ uint8 isbc202r1(t_bool io, uint8 data, uint8 devnum); /* isbc202 1 */
uint8 isbc2021(t_bool io, uint8 data); /* isbc202 1 */ uint8 isbc202r2(t_bool io, uint8 data, uint8 devnum); /* isbc202 2 */
uint8 isbc2022(t_bool io, uint8 data); /* isbc202 2 */ uint8 isbc202r3(t_bool io, uint8 data, uint8 devnum); /* isbc202 3 */
uint8 isbc2023(t_bool io, uint8 data); /* isbc202 3 */ uint8 isbc202r7(t_bool io, uint8 data, uint8 devnum); /* isbc202 7 */
uint8 isbc2027(t_bool io, uint8 data); /* isbc202 7 */ void isbc202_diskio(void); //do actual disk i/o
void isbc202_diskio(uint8 fdcnum); //do actual disk i/o
/* globals */ /* globals */
int32 isbc202_fdcnum = 0; //actual number of SBC-202 instances + 1
typedef struct { //FDD definition typedef struct { //FDD definition
int t0;
int rdy;
uint8 sec; uint8 sec;
uint8 cyl; uint8 cyl;
} FDDDEF; } FDDDEF;
typedef struct { //FDC definition typedef struct { //FDC definition
uint16 baseport; //FDC base port // uint16 baseport; //FDC base port
uint16 iopb; //FDC IOPB uint16 iopb; //FDC IOPB
uint8 stat; //FDC status uint8 stat; //FDC status
uint8 rdychg; //FDC ready change uint8 rdychg; //FDC ready change
@ -235,36 +225,24 @@ typedef struct { //FDC definition
FDDDEF fdd[FDD_NUM]; //indexed by the FDD number FDDDEF fdd[FDD_NUM]; //indexed by the FDD number
} FDCDEF; } FDCDEF;
FDCDEF fdc202[4]; //indexed by the isbc-202 instance number FDCDEF fdc202; //indexed by the isbc-202 instance number
UNIT isbc202_unit[] = { /* isbc202 Standard I/O Data Structures */
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, UNIT isbc202_unit[] = { // 4 FDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 } { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ NULL }
}; };
REG isbc202_reg[] = { REG isbc202_reg[] = {
{ HRDATA (STAT0, fdc202[0].stat, 8) }, /* isbc202 0 status */ { HRDATA (STAT0, fdc202.stat, 8) }, /* isbc202 status */
{ HRDATA (RTYP0, fdc202[0].rtype, 8) }, /* isbc202 0 result type */ { HRDATA (RTYP0, fdc202.rtype, 8) }, /* isbc202 result type */
{ HRDATA (RBYT0A, fdc202[0].rbyte0, 8) }, /* isbc202 0 result byte 0 */ { HRDATA (RBYT0A, fdc202.rbyte0, 8) }, /* isbc202 result byte 0 */
{ HRDATA (RBYT0B, fdc202[0].rbyte1, 8) }, /* isbc202 0 result byte 1 */ { HRDATA (RBYT0B, fdc202.rbyte1, 8) }, /* isbc202 result byte 1 */
{ HRDATA (INTFF0, fdc202[0].intff, 8) }, /* isbc202 0 interrupt f/f */ { HRDATA (INTFF0, fdc202.intff, 8) }, /* isbc202 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 } { NULL }
}; };
@ -300,131 +278,117 @@ DEVICE isbc202_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
NULL, //reset isbc202_reset, //reset
NULL, //boot NULL, //boot
&isbc202_attach, //attach &isbc202_attach, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl 0, //dctrl
isbc202_debug, //debflags isbc202_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL //lname
}; };
/* Hardware reset routine */ // configuration routine
t_stat isbc202_reset(DEVICE *dptr, uint16 base) t_stat isbc202_cfg(uint8 base)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
sim_printf(" iSBC-202 FDC Board"); sim_printf(" sbc202: at base 0%02XH\n",
if (SBC202_NUM) { base);
sim_printf(" - Found\n"); reg_dev(isbc202r0, base, 0); //read status
sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum); reg_dev(isbc202r1, base + 1, 0); //read rslt type/write IOPB addr-l
sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base); reg_dev(isbc202r2, base + 2, 0); //write IOPB addr-h and start
//register base port address for this FDC instance reg_dev(isbc202r3, base + 3, 0); //read rstl byte
fdc202[isbc202_fdcnum].baseport = base; reg_dev(isbc202r7, base + 7, 0); //write reset fdc201
//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 // one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
uptr = isbc202_dev.units + i; uptr = isbc202_dev.units + i;
uptr->u5 = isbc202_fdcnum; //fdc device number
uptr->u6 = i; //fdd unit number uptr->u6 = i; //fdd unit number
uptr->flags |= UNIT_WPMODE; //set WP in unit flags
} }
isbc202_reset1(isbc202_fdcnum); //software reset return SCPE_OK;
isbc202_reset1(isbc202_fdcnum); }
isbc202_fdcnum++;
} else /* Hardware reset routine */
sim_printf(" - Not Found\n");
t_stat isbc202_reset(DEVICE *dptr)
{
isbc202_reset_dev(); //software reset
return SCPE_OK; return SCPE_OK;
} }
/* Software reset routine */ /* Software reset routine */
void isbc202_reset1(uint8 fdcnum) void isbc202_reset_dev(void)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
sim_printf(" isbc202-%d: Software Reset\n", fdcnum); fdc202.stat = 0; //clear status
fdc202[fdcnum].stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */ for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = isbc202_dev.units + i; uptr = isbc202_dev.units + i;
fdc202[fdcnum].stat |= FDCPRE | FDCDD; //set the FDC status fdc202.stat |= FDCPRE | FDCDD; //set the FDC status
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
if (uptr->capac == 0) { /* if not configured */ fdc202.rbyte0 = 0; //set no error
sim_printf(" SBC202%d: Configured, Status=%02X Not attached\n", i, fdc202[fdcnum].stat); if (uptr->flags & UNIT_ATT) { /* if attached */
} else {
switch(i){ switch(i){
case 0: case 0:
fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready fdc202.stat |= RDY0; //set FDD 0 ready
fdc202[fdcnum].rbyte1 |= RB1RD0; fdc202.rbyte1 |= RB1RD0;
break; break;
case 1: case 1:
fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready fdc202.stat |= RDY1; //set FDD 1 ready
fdc202[fdcnum].rbyte1 |= RB1RD1; fdc202.rbyte1 |= RB1RD1;
break; break;
case 2: case 2:
fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready fdc202.stat |= RDY2; //set FDD 2 ready
fdc202[fdcnum].rbyte1 |= RB1RD2; fdc202.rbyte1 |= RB1RD2;
break; break;
case 3: case 3:
fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready fdc202.stat |= RDY3; //set FDD 3 ready
fdc202[fdcnum].rbyte1 |= RB1RD3; fdc202.rbyte1 |= RB1RD3;
break; break;
} }
fdc202[fdcnum].rdychg = 0; fdc202.rdychg = 0;
sim_printf(" SBC202%d: Configured, Status=%02X Attached to %s\n",
i, fdc202[fdcnum].stat, uptr->filename);
} }
} }
} }
/* isbc202 attach - attach an .IMG file to a FDD */ /* isbc202 attach - attach an .IMG file to an FDD */
t_stat isbc202_attach (UNIT *uptr, CONST char *cptr) t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
{ {
t_stat r; t_stat r;
uint8 fdcnum, fddnum; uint8 fddnum;
sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Entered with cptr=%s\n", cptr);
// sim_printf(" isbc202_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" isbc202_attach: Attach error\n"); sim_printf(" isbc202_attach: Attach error %d\n", r);
return r; return r;
} }
fdcnum = uptr->u5;
fddnum = uptr->u6; fddnum = uptr->u6;
switch(fddnum){ switch(fddnum){
case 0: case 0:
fdc202[fdcnum].stat |= RDY0; //set FDD 0 ready fdc202.stat |= RDY0; //set FDD 0 ready
fdc202[fdcnum].rbyte1 |= RB1RD0; fdc202.rbyte1 |= RB1RD0;
break; break;
case 1: case 1:
fdc202[fdcnum].stat |= RDY1; //set FDD 1 ready fdc202.stat |= RDY1; //set FDD 1 ready
fdc202[fdcnum].rbyte1 |= RB1RD1; fdc202.rbyte1 |= RB1RD1;
break; break;
case 2: case 2:
fdc202[fdcnum].stat |= RDY2; //set FDD 2 ready fdc202.stat |= RDY2; //set FDD 2 ready
fdc202[fdcnum].rbyte1 |= RB1RD2; fdc202.rbyte1 |= RB1RD2;
break; break;
case 3: case 3:
fdc202[fdcnum].stat |= RDY3; //set FDD 3 ready fdc202.stat |= RDY3; //set FDD 3 ready
fdc202[fdcnum].rbyte1 |= RB1RD3; fdc202.rbyte1 |= RB1RD3;
break; break;
} }
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
sim_printf(" iSBC-202%d: FDD %d Configured %d bytes, Attached to %s\n", fdc202.rbyte0 = 0; //set no error
fdcnum, fddnum, uptr->capac, uptr->filename);
sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_attach: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -432,135 +396,88 @@ t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc) 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", if (uptr->flags & UNIT_ATT)
// val, uptr->flags); return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */ if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val; uptr->flags |= val;
} else { /* read write */ } else { /* read write */
uptr->flags &= ~val; uptr->flags &= ~val;
} }
// sim_debug (DEBUG_flow, &isbc202_dev, " isbc202_set_mode: Done\n");
return SCPE_OK; 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 */ /* iSBC202 control port functions */
uint8 isbc2020(t_bool io, uint8 data) uint8 isbc202r0(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read ststus*/ if (io == 0) { /* read ststus*/
if (DEBUG) return fdc202.stat;
sim_printf("\n isbc202-%d: 0x78 returned status=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].stat, PCX);
return fdc202[fdcnum].stat;
}
} }
return 0; return 0;
} }
uint8 isbc2021(t_bool io, uint8 data) uint8 isbc202r1(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
fdc202[fdcnum].intff = 0; //clear interrupt FF fdc202.intff = 0; //clear interrupt FF
fdc202[fdcnum].stat &= ~FDCINT; fdc202.stat &= ~FDCINT;
if (DEBUG) if (fdc202.rdychg) {
sim_printf("\n isbc202-%d: 0x79 returned rtype=%02X intff=%02X status=%02X PCX=%04X", fdc202.rtype = ROK;
fdcnum, fdc202[fdcnum].rtype, fdc202[fdcnum].intff, fdc202[fdcnum].stat, PCX); return fdc202.rtype;
return fdc202[fdcnum].rtype; } else {
} else { /* write data port */ fdc202.rtype = ROK;
fdc202[fdcnum].iopb = data; return fdc202.rtype;
if (DEBUG)
sim_printf("\n isbc202-%d: 0x79 IOPB low=%02X PCX=%04X",
fdcnum, data, PCX);
} }
} else { /* write data port */
fdc202.iopb = data;
} }
return 0; return 0;
} }
uint8 isbc2022(t_bool io, uint8 data) uint8 isbc202r2(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
fdc202[fdcnum].iopb |= (data << 8); fdc202.iopb |= (data << 8);
if (DEBUG) isbc202_diskio();
sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X", if (fdc202.intff)
fdcnum, fdc202[fdcnum].iopb, PCX); fdc202.stat |= FDCINT;
isbc202_diskio(fdcnum);
if (fdc202[fdcnum].intff)
fdc202[fdcnum].stat |= FDCINT;
}
} }
return 0; return 0;
} }
uint8 isbc2023(t_bool io, uint8 data) uint8 isbc202r3(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if (fdc202[fdcnum].rtype == 0) { if (fdc202.rtype == ROK) {
if (DEBUG) return fdc202.rbyte0;
sim_printf("\n isbc202-%d: 0x7B returned rbyte0=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rbyte0, PCX);
return fdc202[fdcnum].rbyte0;
} else { } else {
if (fdc202[fdcnum].rdychg) { if (fdc202.rdychg) {
if (DEBUG) return fdc202.rbyte1;
sim_printf("\n isbc202-%d: 0x7B returned rbyte1=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rbyte1, PCX);
return fdc202[fdcnum].rbyte1;
} else { } else {
if (DEBUG) return fdc202.rbyte0;
sim_printf("\n isbc202-%d: 0x7B returned rbytex=%02X PCX=%04X",
fdcnum, 0, PCX);
return 0;
} }
} }
} else { /* write data port */ } else { /* write data port */
; //stop diskette operation ; //stop diskette operation
} }
}
return 0; return 0;
} }
uint8 isbc2027(t_bool io, uint8 data) uint8 isbc202r7(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
isbc202_reset1(fdcnum); isbc202_reset_dev();
}
} }
return 0; return 0;
} }
// perform the actual disk I/O operation // perform the actual disk I/O operation
void isbc202_diskio(uint8 fdcnum) void isbc202_diskio(void)
{ {
uint8 cw, di, nr, ta, sa, data, nrptr; uint8 cw, di, nr, ta, sa, data, nrptr;
uint16 ba; uint16 ba;
@ -571,56 +488,51 @@ void isbc202_diskio(uint8 fdcnum)
uint8 *fbuf; uint8 *fbuf;
//parse the IOPB //parse the IOPB
cw = multibus_get_mbyte(fdc202[fdcnum].iopb); cw = multibus_get_mbyte(fdc202.iopb);
di = multibus_get_mbyte(fdc202[fdcnum].iopb + 1); di = multibus_get_mbyte(fdc202.iopb + 1);
nr = multibus_get_mbyte(fdc202[fdcnum].iopb + 2); nr = multibus_get_mbyte(fdc202.iopb + 2);
ta = multibus_get_mbyte(fdc202[fdcnum].iopb + 3); ta = multibus_get_mbyte(fdc202.iopb + 3);
sa = multibus_get_mbyte(fdc202[fdcnum].iopb + 4); sa = multibus_get_mbyte(fdc202.iopb + 4);
ba = multibus_get_mword(fdc202[fdcnum].iopb + 5); ba = multibus_get_mbyte(fdc202.iopb + 5);
ba |= (multibus_get_mbyte(fdc202.iopb + 6) << 8);
fddnum = (di & 0x30) >> 4; fddnum = (di & 0x30) >> 4;
uptr = isbc202_dev.units + fddnum; uptr = isbc202_dev.units + fddnum;
fbuf = (uint8 *) (isbc202_dev.units + fddnum)->filebuf; fbuf = (uint8 *) uptr->filebuf;
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 //check for not ready
switch(fddnum) { switch(fddnum) {
case 0: case 0:
if ((fdc202[fdcnum].stat & RDY0) == 0) { if ((fdc202.stat & RDY0) == 0) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0NR; fdc202.rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return; return;
} }
break; break;
case 1: case 1:
if ((fdc202[fdcnum].stat & RDY1) == 0) { if ((fdc202.stat & RDY1) == 0) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0NR; fdc202.rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return; return;
} }
break; break;
case 2: case 2:
if ((fdc202[fdcnum].stat & RDY2) == 0) { if ((fdc202.stat & RDY2) == 0) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0NR; fdc202.rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return; return;
} }
break; break;
case 3: case 3:
if ((fdc202[fdcnum].stat & RDY3) == 0) { if ((fdc202.stat & RDY3) == 0) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0NR; fdc202.rbyte0 = RB0NR;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return; return;
} }
break; break;
@ -633,61 +545,64 @@ void isbc202_diskio(uint8 fdcnum)
(sa == 0) || (sa == 0) ||
(ta > MAXTRK) (ta > MAXTRK)
)) { )) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0ADR; fdc202.rbyte0 = RB0ADR;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Address error on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
fddnum, sa, nr, ta, PCX);
return; return;
} }
switch (di & 0x07) { switch (di & 0x07) {
case DNOP: case DNOP:
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
case DSEEK: case DSEEK:
fdc202[fdcnum].fdd[fddnum].sec = sa; fdc202.fdd[fddnum].sec = sa;
fdc202[fdcnum].fdd[fddnum].cyl = ta; fdc202.fdd[fddnum].cyl = ta;
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
case DHOME: case DHOME:
fdc202[fdcnum].fdd[fddnum].sec = sa; fdc202.fdd[fddnum].sec = sa;
fdc202[fdcnum].fdd[fddnum].cyl = 0; fdc202.fdd[fddnum].cyl = 0;
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
case DVCRC: case DVCRC:
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
case DFMT: case DFMT:
//check for WP //check for WP
if(uptr->flags & UNIT_WPMODE) { if(uptr->flags & UNIT_WPMODE) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0WP; fdc202.rbyte0 = RB0WP;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Write protect error 1 on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Write protect error DFMT", fddnum);
return; return;
} }
fmtb = multibus_get_mbyte(ba); //get the format byte fmtb = multibus_get_mbyte(ba); //get the format byte
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * SECSIZ;
for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { for(i=0; i<=((uint32)(MAXSECDD) * SECSIZ); i++) {
*(fbuf + (dskoff + i)) = fmtb; *(fbuf + (dskoff + i)) = fmtb;
} }
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
case DREAD: case DREAD:
nrptr = 0; nrptr = 0;
while(nrptr < nr) { while(nrptr < nr) {
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * SECSIZ;
if (DEBUG) //copy sector from disk image to RAM
sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", for (i=0; i<SECSIZ; i++) {
fdcnum, cw, di, nr, ta, sa, ba, dskoff);
//copy sector from image to RAM
for (i=0; i<128; i++) {
data = *(fbuf + (dskoff + i)); data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data); multibus_put_mbyte(ba + i, data);
} }
@ -695,26 +610,25 @@ void isbc202_diskio(uint8 fdcnum)
ba+=0x80; ba+=0x80;
nrptr++; nrptr++;
} }
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
case DWRITE: case DWRITE:
//check for WP //check for WP
if(uptr->flags & UNIT_WPMODE) { if(uptr->flags & UNIT_WPMODE) {
fdc202[fdcnum].rtype = RERR; fdc202.rtype = ROK;
fdc202[fdcnum].rbyte0 = RB0WP; fdc202.rbyte0 = RB0WP;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
sim_printf("\n isbc202-%d: Write protect error 2 on drive %d", fdcnum, fddnum); sim_printf("\n SBC202: FDD %d - Write protect error DWRITE", fddnum);
return; return;
} }
nrptr = 0; nrptr = 0;
while(nrptr < nr) { while(nrptr < nr) {
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * SECSIZ;
if (DEBUG) //copy sector from RAM to disk image
sim_printf("\n isbc202-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X dskoff=%06X", for (i=0; i<SECSIZ; i++) {
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); data = multibus_get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data; *(fbuf + (dskoff + i)) = data;
} }
@ -722,11 +636,12 @@ void isbc202_diskio(uint8 fdcnum)
ba+=0x80; ba+=0x80;
nrptr++; nrptr++;
} }
fdc202[fdcnum].rtype = ROK; fdc202.rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF fdc202.rbyte0 = 0; //set no error
fdc202.intff = 1; //set interrupt FF
break; break;
default: default:
sim_printf("\n isbc202-%d: isbc202_diskio bad di=%02X", fdcnum, di & 0x07); sim_printf("\n SBC202: FDD %d - isbc202_diskio bad di=%02X", fddnum, di & 0x07);
break; break;
} }
} }

View file

@ -0,0 +1,605 @@
/* isbc206.c: Intel iSBC 206 disk adapter
Copyright (c) 2017, 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:
31 Oct 17 - Original file.
NOTES:
This controller will mount 1 Hard Disk removable and three Hard Disk fixed disk
images on drives :F0: thru :F3: addressed at ports 068H to 06FH.
Registers:
068H - 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
069H - 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
069H - Write - IOPB address low byte.
06AH - Write - IOPB address high byte and start operation.
06BH - Read - Read result byte
If result type is 00H
0x01 - ID field miscompare
0x02 - Data field CRC error
0x04 - Seek error
0x08 - Bad sector address error
0x0A - ID field CRC error
0x0B - Protocol violations
0x0C - Bad track address error
0x0E - No ID address mark or sector found
0x0F - D=Bad data field address mark
0x10 - Format error
0x20 - write protect
0x40 - write error
0x80 - not ready
06FH - 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 -
u6 - hdd number.
*/
#include "system_defs.h" /* system header in system dir */
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define HD_NUM 2 //one fixed and one removable
//disk controller operations
#define DNOP 0x00 //HDC no operation
#define DSEEK 0x01 //HDC seek
#define DFMT 0x02 //HDC format
#define DHOME 0x03 //HDC home
#define DREAD 0x04 //HDC read
#define DVCRC 0x05 //HDC verify CRC
#define DWRITE 0x06 //HDC write
//status
#define RDY0 0x01 //HDD 0 ready
#define RDY1 0x02 //HDD 1 ready
#define HDCINT 0x04 //HDC interrupt flag
#define HDCPRE 0x08 //HDC board present
//result type
#define ROK 0x00 //HDC returned error
//#define RCHG 0x02 //HDC returned ok
#define RCHG 0x01 //HDC 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 RB1RD0 0x40 //drive 0 ready
#define RB1RD1 0x80 //drive 1 ready
//disk geometry values
#define MDSHD 3796992 //hard disk HD size
#define MAXSECHD 144 //hard disk last sector (2 heads/2 tracks)
#define MAXTRKHD 206 //hard disk last track
/* external globals */
extern int32 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, 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 isbc206_cfg(uint8 base);
t_stat isbc206_reset(DEVICE *dptr);
void isbc206_reset1(void);
t_stat isbc206_attach (UNIT *uptr, CONST char *cptr);
t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 isbc206r0(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 0 */
uint8 isbc206r1(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 1 */
uint8 isbc206r2(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 2 */
uint8 isbc206r3(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 3 */
uint8 isbc206r7(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 7 */
void isbc206_diskio(void); //do actual disk i/o
/* globals */
typedef struct { //HDD definition
int t0;
int rdy;
uint8 sec;
uint8 cyl;
} HDDDEF;
typedef struct { //HDC definition
uint16 baseport; //HDC base port
uint16 iopb; //HDC IOPB
uint8 stat; //HDC status
uint8 rdychg; //HDC ready change
uint8 rtype; //HDC result type
uint8 rbyte0; //HDC result byte for type 00
uint8 rbyte1; //HDC result byte for type 10
uint8 intff; //HDC interrupt FF
HDDDEF hd[HD_NUM]; //indexed by the HDD number
} HDCDEF;
HDCDEF hdc206;
UNIT isbc206_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD), 20 },
{ NULL }
};
REG isbc206_reg[] = {
{ HRDATA (STAT0, hdc206.stat, 8) }, /* isbc206 0 status */
{ HRDATA (RTYP0, hdc206.rtype, 8) }, /* isbc206 0 result type */
{ HRDATA (RBYT0A, hdc206.rbyte0, 8) }, /* isbc206 0 result byte 0 */
{ HRDATA (RBYT0B, hdc206.rbyte1, 8) }, /* isbc206 0 result byte 1 */
{ HRDATA (INTFF0, hdc206.intff, 8) }, /* isbc206 0 interrupt f/f */
{ NULL }
};
MTAB isbc206_mod[] = {
{ UNIT_WPMODE, 0, "RW", "RW", &isbc206_set_mode },
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc206_set_mode },
{ 0 }
};
DEBTAB isbc206_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 isbc206_dev = {
"SBC206", //name
isbc206_unit, //units
isbc206_reg, //registers
isbc206_mod, //modifiers
HD_NUM, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
isbc206_reset, //reset
NULL, //boot
&isbc206_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc206_debug, //debflags
NULL, //msize
NULL //lname
};
// configuration routine
t_stat isbc206_cfg(uint8 base)
{
int32 i;
UNIT *uptr;
sim_printf(" sbc206: at base 0%02XH\n",
base);
reg_dev(isbc206r0, base, 0); //read status
reg_dev(isbc206r1, base + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc206r2, base + 2, 0); //write IOPB addr-h and start
reg_dev(isbc206r3, base + 3, 0); //read rstl byte
reg_dev(isbc206r7, base + 7, 0); //write reset fdc201
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < HD_NUM; i++) {
uptr = isbc206_dev.units + i;
uptr->u6 = i; //fdd unit number
}
return SCPE_OK;
}
/* Hardware reset routine */
t_stat isbc206_reset(DEVICE *dptr)
{
isbc206_reset1(); //software reset
return SCPE_OK;
}
/* Software reset routine */
void isbc206_reset1(void)
{
int32 i;
UNIT *uptr;
hdc206.stat = 0; //clear status
for (i = 0; i < HD_NUM; i++) { /* handle all units */
uptr = isbc206_dev.units + i;
hdc206.stat |= (HDCPRE + 0x80); //set the HDC status
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
if (uptr->flags & UNIT_ATT) { /* if attached */
switch(i){
case 0:
hdc206.stat |= RDY0; //set HDD 0 ready
hdc206.rbyte1 |= RB1RD0;
break;
case 1:
hdc206.stat |= RDY1; //set HDD 1 ready
hdc206.rbyte1 |= RB1RD1;
break;
}
hdc206.rdychg = 0;
}
}
}
/* isbc206 attach - attach an .IMG file to a HDD */
t_stat isbc206_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
uint8 hddnum;
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" isbc206_attach: Attach error %d\n", r);
return r;
}
hddnum = uptr->u6;
switch(hddnum){
case 0:
hdc206.stat |= RDY0; //set HDD 0 ready
hdc206.rbyte1 |= RB1RD0;
break;
case 1:
hdc206.stat |= RDY1; //set HDD 1 ready
hdc206.rbyte1 |= RB1RD1;
break;
}
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
return SCPE_OK;
}
/* isbc206 set mode = Write protect */
t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
} else { /* read write */
uptr->flags &= ~val;
}
return SCPE_OK;
}
/* iSBC206 control port functions */
uint8 isbc206r0(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read status*/
return hdc206.stat;
}
return 0;
}
uint8 isbc206r1(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
hdc206.intff = 0; //clear interrupt FF
hdc206.stat &= ~(HDCINT + 0x80);
if (hdc206.rdychg) {
hdc206.rtype = ROK;
return hdc206.rtype;
} else {
hdc206.rtype = ROK;
return hdc206.rtype;
}
} else { /* write data port */
hdc206.iopb = data;
}
return 0;
}
uint8 isbc206r2(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
;
} else { /* write data port */
hdc206.iopb |= (data << 8);
isbc206_diskio();
if (hdc206.intff)
hdc206.stat |= HDCINT;
}
return 0;
}
uint8 isbc206r3(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (hdc206.rtype == ROK) {
return hdc206.rbyte0;
} else {
if (hdc206.rdychg) {
return hdc206.rbyte1;
} else {
return hdc206.rbyte0;
}
}
} else { /* write data port */
; //stop diskette operation
}
return 0;
}
uint8 isbc206r7(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
;
} else { /* write data port */
isbc206_reset1();
}
return 0;
}
// perform the actual disk I/O operation
void isbc206_diskio(void)
{
uint8 cw, di, nr, ta, sa, data, nrptr;
uint16 ba;
uint32 dskoff;
uint8 hddnum, fmtb;
uint32 i;
UNIT *uptr;
uint8 *fbuf;
//parse the IOPB
cw = multibus_get_mbyte(hdc206.iopb);
di = multibus_get_mbyte(hdc206.iopb + 1);
nr = multibus_get_mbyte(hdc206.iopb + 2);
ta = multibus_get_mbyte(hdc206.iopb + 3);
sa = multibus_get_mbyte(hdc206.iopb + 4);
ba = multibus_get_mbyte(hdc206.iopb + 5);
hddnum = (di & 0x30) >> 4;
uptr = isbc206_dev.units + hddnum;
fbuf = (uint8 *) (isbc206_dev.units + hddnum)->filebuf;
//check for not ready
switch(hddnum) {
case 0:
if ((hdc206.stat & RDY0) == 0) {
hdc206.rtype = ROK;
hdc206.rbyte0 = RB0NR;
hdc206.intff = 1; //set interrupt FF
sim_printf("\n SBC206: HDD %d - Ready error", hddnum);
return;
}
break;
case 1:
if ((hdc206.stat & RDY1) == 0) {
hdc206.rtype = ROK;
hdc206.rbyte0 = RB0NR;
hdc206.intff = 1; //set interrupt FF
sim_printf("\n SBC206: HDD %d - Ready error", hddnum);
return;
}
break;
}
//check for address error
if (
((di & 0x07) != DHOME) && (
(sa > MAXSECHD) ||
((sa + nr) > (MAXSECHD + 1)) ||
(sa == 0) ||
(ta > MAXTRKHD)
)) {
hdc206.rtype = ROK;
hdc206.rbyte0 = RB0ADR;
hdc206.intff = 1; //set interrupt FF
sim_printf("\n SBC206: FDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
hddnum, sa, nr, ta, PCX);
return;
}
switch (di & 0x07) {
case DNOP:
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
case DSEEK:
hdc206.hd[hddnum].sec = sa;
hdc206.hd[hddnum].cyl = ta;
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
case DHOME:
hdc206.hd[hddnum].sec = sa;
hdc206.hd[hddnum].cyl = 0;
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
case DVCRC:
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
case DFMT:
//check for WP
if(uptr->flags & UNIT_WPMODE) {
hdc206.rtype = ROK;
hdc206.rbyte0 = RB0WP;
hdc206.intff = 1; //set interrupt FF
sim_printf("\n SBC206: HDD %d - Write protect error DFMT", hddnum);
return;
}
fmtb = multibus_get_mbyte(ba); //get the format byte
//calculate offset into disk image
dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128;
for(i=0; i<=((uint32)(MAXSECHD) * 128); i++) {
*(fbuf + (dskoff + i)) = fmtb;
}
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
case DREAD:
nrptr = 0;
while(nrptr < nr) {
//calculate offset into disk image
dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128;
//copy sector from image to RAM
for (i=0; i<128; i++) {
data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data);
}
sa++;
ba+=0x80;
nrptr++;
}
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
case DWRITE:
//check for WP
if(uptr->flags & UNIT_WPMODE) {
hdc206.rtype = ROK;
hdc206.rbyte0 = RB0WP;
hdc206.intff = 1; //set interrupt FF
sim_printf("\n SBC206: HDD %d - Write protect error DWRITE", hddnum);
return;
}
nrptr = 0;
while(nrptr < nr) {
//calculate offset into disk image
dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128;
//copy sector from image to RAM
for (i=0; i<128; i++) {
data = multibus_get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data;
}
sa++;
ba+=0x80;
nrptr++;
}
hdc206.rtype = ROK;
hdc206.rbyte0 = 0; //set no error
hdc206.intff = 1; //set interrupt FF
break;
default:
sim_printf("\n SBC206: HDD %d - isbc206_diskio bad di=%02X", hddnum, di & 0x07);
break;
}
}
/* end of isbc206.c */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,175 @@
/* isbc464.c: Intel iSBC 464 32K Byte ROM Card
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
29 Oct 17 - Original file.
NOTES:
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* prototypes */
t_stat isbc064_cfg(uint16 base, uint16 size);
t_stat isbc464_reset (DEVICE *dptr);
t_stat isbc464_attach (UNIT *uptr, CONST char *cptr);
uint8 isbc464_get_mbyte(uint16 addr);
void isbc464_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */
/* external globals */
extern uint8 xack; /* XACK signal */
/* local globals */
/* isbc464 Standard I/O Data Structures */
UNIT isbc464_unit[] = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0
};
DEBTAB isbc464_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc464_dev = {
"SBC464", //name
isbc464_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
NULL, //reset
NULL, //boot
isbc464_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc464_debug, //debflags
NULL, //msize
NULL //lname
};
/* isbc464 globals */
// configuration routine
t_stat isbc464_cfg(uint16 base, uint16 size)
{
sim_printf(" sbc464: 0%04XH bytes at base 0%04XH\n",
size, base);
isbc464_unit->capac = size; //set size
isbc464_unit->u3 = base; //and base
return SCPE_OK;
}
/* Reset routine */
t_stat isbc464_reset (DEVICE *dptr)
{
return SCPE_OK;
}
/* isbc464 attach */
t_stat isbc464_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
isbc464_reset(NULL); //odd fix, but it works
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf ("isbc464_attach: Error %d\n", r);
return r;
}
return SCPE_OK;
}
/* get a byte from memory */
uint8 isbc464_get_mbyte(uint16 addr)
{
uint32 val, org, len;
uint8 *fbuf;
if ((isbc464_dev.flags & DEV_DIS) == 0) {
org = isbc464_unit->u3;
len = isbc464_unit->capac;
fbuf = (uint8 *) isbc464_unit->filebuf;
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
val = *(fbuf + (addr - org));
return (val & 0xFF);
} else {
sim_printf("isbc464_get_mbyte: Out of range\n");
return 0; /* multibus has active high pullups and inversion */
}
}
sim_printf ("isbc464_put_mbyte: Write-Disabled addr=%04X\n", addr);
return 0; /* multibus has active high pullups and inversion */
}
/* put a byte into memory */
void isbc464_put_mbyte(uint16 addr, uint8 val)
{
uint32 org, len;
if ((isbc464_dev.flags & DEV_DIS) == 0) {
org = isbc464_unit->u3;
len = isbc464_unit->capac;
if ((addr >= org) && (addr < (org + len))) {
// SET_XACK(1); /* good memory address */
sim_printf ("isbc464_put_mbyte: Read-only Memory\n");
return;
} else {
sim_printf ("isbc464_put_mbyte: Out of range\n");
return;
}
}
sim_printf ("isbc464_put_mbyte: Disabled\n");
}
/* end of isbc464.c */

View file

@ -0,0 +1,373 @@
/* m800multibus.c: Multibus I simulator for M800/810
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
int32 mbirq = 0; /* set no multibus interrupts */
/* function prototypes */
t_stat multibus_cfg(void);
t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num);
void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 data, uint8 devnum);
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
uint16 multibus_get_mword(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
void multibus_put_mword(uint16 addr, uint16 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the IPC simulator */
extern void set_cpuint(int32 int_num);
extern t_stat zx200a_reset(DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr);
extern t_stat isbc202_reset (DEVICE *dptr);
extern t_stat isbc206_reset (DEVICE *dptr);
extern t_stat isbc208_reset (DEVICE *dptr);
extern t_stat isbc464_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr);
extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat isbc208_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev;
/* multibus Standard SIMH Device Data Structures */
UNIT multibus_unit = {
UDATA (&multibus_svc, 0, 0), 20
};
REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) },
{ NULL }
};
DEBTAB multibus_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE multibus_dev = {
"MBIRQ", //name
&multibus_unit, //units
multibus_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&multibus_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
multibus_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
if (SBC208_NUM) isbc208_cfg(SBC208_BASE);
if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
return SCPE_OK;
}
/* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_1:
set_cpuint(INT_R);
#if NIPC
clr_irq(SBC202_INT); /***** bad, bad, bad! */
#endif
// sim_printf("multibus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
break;
default:
// sim_printf("multibus_svc: default mbirq=%04X\n", mbirq);
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
return SCPE_OK;
}
/* Reset routine */
t_stat multibus_reset(DEVICE *dptr)
{
if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n");
if (SBC064_NUM) { //device installed
isbc064_reset(&isbc064_dev);
sim_printf(" Multibus: SBC064 reset\n");
}
if (SBC464_NUM) { //unit enabled
isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (SBC208_NUM) { //unit enabled
isbc208_reset(&isbc208_dev);
sim_printf(" Multibus: SBC208 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
return SCPE_OK;
}
}
void set_irq(int32 int_num)
{
mbirq |= int_num;
// sim_printf("set_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
void clr_irq(int32 int_num)
{
mbirq &= ~int_num;
// sim_printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
/* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered.
*/
struct idev {
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 port;
uint8 devnum;
};
struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
};
uint8 nulldev(t_bool flag, uint8 data, uint8 devnum)
{
SET_XACK(0); /* set no XACK */
return 0; //should be 0xff, but ISIS won't boot if not 0!
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
sim_printf(" Multibus: I/O Port %04X is already assigned\n", port);
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
uint8 val = 0;
SET_XACK(0); /* set no XACK */
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr);
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= SBC464_BASE && addr <= (SBC464_BASE + SBC464_SIZE))
return(isbc464_get_mbyte(addr));
}
if (xack == 0)
val = isbc064_get_mbyte(addr);
return val;
}
/* get a word from memory */
uint16 multibus_get_mword(uint16 addr)
{
uint16 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
// sim_printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr);
isbc064_put_mbyte(addr, val);
// sim_printf("multibus_put_mbyte: Done XACK=%dX\n", XACK);
}
/* put a word to memory */
void multibus_put_mword(uint16 addr, uint16 val)
{
multibus_put_mbyte(addr, val & 0xff);
multibus_put_mbyte(addr+1, val >> 8);
}
/* end of m800multibus.c */

View file

@ -26,28 +26,23 @@
MODIFICATIONS: MODIFICATIONS:
?? ??? 10 - Original file. ?? ??? 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 24 Apr 15 -- Modified to use simh_debug
NOTES: NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
*/ */
#include "system_defs.h" #include "system_defs.h"
int32 mbirq = 0; /* set no multibus interrupts */
/* function prototypes */ /* function prototypes */
t_stat multibus_cfg(void);
t_stat multibus_svc(UNIT *uptr); t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr); t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num); void set_irq(int32 int_num);
void clr_irq(int32 int_num); void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 data); uint8 nulldev(t_bool io, uint8 port, uint8 devnum);
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnum); uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
t_stat multibus_reset (DEVICE *dptr); t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr); uint8 multibus_get_mbyte(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val); void multibus_put_mbyte(uint16 addr, uint8 val);
@ -57,20 +52,41 @@ void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */ extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */
extern uint8 isbc064_get_mbyte(uint16 addr); extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val); extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern void set_cpuint(int32 int_num); extern void set_cpuint(int32 int_num);
extern t_stat SBC_reset (DEVICE *dptr); extern t_stat isbc064_reset (DEVICE *);
extern t_stat isbc064_reset (DEVICE *dptr); extern t_stat isbc464_reset (DEVICE *);
extern t_stat isbc201_reset (DEVICE *dptr, uint16); extern t_stat isbc201_reset (DEVICE *);
extern t_stat isbc202_reset (DEVICE *dptr, uint16); extern t_stat isbc202_reset (DEVICE *);
extern t_stat zx200a_reset(DEVICE *dptr, uint16 base); extern t_stat isbc206_reset (DEVICE *);
extern t_stat isbc208_reset (DEVICE *);
extern t_stat zx200a_reset(DEVICE *);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat isbc208_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
/* local globals */
int32 mbirq = 0; /* set no multibus interrupts */
/* external globals */ /* external globals */
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */ extern int32 int_req; /* i8080 INT signal */
extern int32 isbc201_fdcnum; extern int32 PCX;
extern int32 isbc202_fdcnum; extern DEVICE isbc064_dev;
extern int32 zx200a_fdcnum; extern DEVICE isbc464_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev;
extern UNIT isbc064_unit;
extern UNIT isbc464_unit;
/* multibus Standard SIMH Device Data Structures */ /* multibus Standard SIMH Device Data Structures */
@ -80,7 +96,8 @@ UNIT multibus_unit = {
REG multibus_reg[] = { REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) }, { HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) } { HRDATA (XACK, xack, 8) },
{ NULL }
}; };
DEBTAB multibus_debug[] = { DEBTAB multibus_debug[] = {
@ -120,21 +137,18 @@ DEVICE multibus_dev = {
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
/* service routine - actually does the simulated interrupts */ // multibus_cfg
t_stat multibus_svc(UNIT *uptr) t_stat multibus_cfg(void)
{ {
switch (mbirq) { sim_printf("Configuring Multibus Devices\n");
case INT_1: if (SBC064_NUM) isbc064_cfg(SBC064_BASE, SBC064_SIZE);
set_cpuint(INT_R); if (SBC464_NUM) isbc464_cfg(SBC464_BASE, SBC464_SIZE);
clr_irq(SBC202_INT); /***** bad, bad, bad! */ if (SBC201_NUM) isbc201_cfg(SBC201_BASE);
// sim_printf("multibus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req); if (SBC202_NUM) isbc202_cfg(SBC202_BASE);
break; if (SBC206_NUM) isbc206_cfg(SBC206_BASE);
default: if (SBC208_NUM) isbc208_cfg(SBC208_BASE);
// sim_printf("multibus_svc: default mbirq=%04X\n", mbirq); if (ZX200A_NUM) zx200a_cfg(ZX200A_BASE);
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
return SCPE_OK; return SCPE_OK;
} }
@ -142,29 +156,67 @@ t_stat multibus_svc(UNIT *uptr)
t_stat multibus_reset(DEVICE *dptr) t_stat multibus_reset(DEVICE *dptr)
{ {
SBC_reset(NULL); if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n"); sim_printf(" Multibus: Reset\n");
isbc064_reset(NULL); if (SBC064_NUM) { //device installed
isbc201_fdcnum = 0; isbc064_reset(&isbc064_dev);
isbc201_reset(NULL, SBC201_BASE); sim_printf(" Multibus: SBC064 reset\n");
isbc202_fdcnum = 0; }
isbc202_reset(NULL, SBC202_BASE); if (SBC464_NUM) { //unit enabled
zx200a_fdcnum = 0; isbc464_reset(&isbc464_dev);
zx200a_reset(NULL, ZX200A_BASE); sim_printf(" Multibus: SBC464 reset\n");
}
if (SBC201_NUM) { //unit enabled
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
}
if (SBC202_NUM) { //unit enabled
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
}
if (SBC206_NUM) { //unit enabled
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
}
if (SBC208_NUM) { //unit enabled
isbc208_reset(&isbc208_dev);
sim_printf(" Multibus: SBC208 reset\n");
}
if (ZX200A_NUM) { //unit enabled
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
}
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */ sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
return SCPE_OK;
}
}
/* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_2:
set_cpuint(INT_R);
break;
default:
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
return SCPE_OK;
} }
void set_irq(int32 int_num) void set_irq(int32 int_num)
{ {
mbirq |= int_num; mbirq |= int_num;
// sim_printf("set_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
} }
void clr_irq(int32 int_num) void clr_irq(int32 int_num)
{ {
mbirq &= ~int_num; mbirq &= ~int_num;
// sim_printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
} }
/* This is the I/O configuration table. There are 256 possible /* This is the I/O configuration table. There are 256 possible
@ -172,8 +224,8 @@ device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered. address is here, 'nulldev' means no device has been registered.
*/ */
struct idev { struct idev {
uint8 (*routine)(t_bool io, uint8 data); uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint16 port; uint8 port;
uint8 devnum; uint8 devnum;
}; };
@ -244,21 +296,18 @@ struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */ {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
}; };
//uint8 nulldev(t_bool flag, uint8 data, uint8 devnum) uint8 nulldev(t_bool io, uint8 data, uint8 devnum)
uint8 nulldev(t_bool flag, uint8 data)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
return 0xFF; return 0xff; /* multibus has active high pullups and inversion */
} }
//uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum) uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnum)
{ {
if (dev_table[port].routine != &nulldev) { /* port already assigned */ if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine) if (dev_table[port].routine != routine)
sim_printf(" I/O Port %04X is already assigned\n", port); sim_printf(" I/O Port %02X is already assigned\n", port);
} else { } else {
sim_printf(" Port %04X is assigned to dev %04X\n", port, devnum);
dev_table[port].routine = routine; dev_table[port].routine = routine;
dev_table[port].devnum = devnum; dev_table[port].devnum = devnum;
} }
@ -270,38 +319,26 @@ uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnum
uint8 multibus_get_mbyte(uint16 addr) uint8 multibus_get_mbyte(uint16 addr)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr); if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
return isbc064_get_mbyte(addr); if (addr >= isbc464_unit.u3 && addr < (isbc464_unit.u3 + isbc464_unit.capac))
return(isbc464_get_mbyte(addr));
}
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= isbc064_unit.u3 && addr < (isbc064_unit.u3 + isbc064_unit.capac))
return (isbc064_get_mbyte(addr));
}
return 0;
} }
/* get a word from memory */
uint16 multibus_get_mword(uint16 addr)
{
uint16 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(uint16 addr, uint8 val) void multibus_put_mbyte(uint16 addr, uint8 val)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
// sim_printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr); if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if (addr >= SBC064_BASE && addr <= (SBC064_BASE + SBC064_SIZE - 1))
isbc064_put_mbyte(addr, val); isbc064_put_mbyte(addr, val);
// sim_printf("multibus_put_mbyte: Done XACK=%dX\n", XACK); } else {
} return;
}
/* put a word to memory */
void multibus_put_mword(uint16 addr, uint16 val)
{
multibus_put_mbyte(addr, val & 0xff);
multibus_put_mbyte(addr+1, val >> 8);
} }
/* end of multibus.c */ /* end of multibus.c */

View file

@ -1,4 +1,4 @@
/* zx-200a.c: Intel double density disk adapter adapter /* zx-200a.c: ZENDEX single/double density disk adapter
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
@ -127,7 +127,7 @@
u3 - u3 -
u4 - u4 -
u5 - fdc number (board instance number). u5 -
u6 - fdd number. u6 - fdd number.
The ZX-200A appears to the multibus system as if there were an iSBC-201 The ZX-200A appears to the multibus system as if there were an iSBC-201
@ -139,12 +139,11 @@
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define DEBUG 0
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */ #define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE) #define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 4 #define FDD_NUM 6
//disk controoler operations //disk controoler operations
#define DNOP 0x00 //disk no operation #define DNOP 0x00 //disk no operation
@ -165,10 +164,10 @@
#define RDY3 0x40 //FDD 3 ready #define RDY3 0x40 //FDD 3 ready
//result type //result type
#define RERR 0x00 //FDC returned error #define ROK 0x00 //FDC error
#define ROK 0x02 //FDC returned ok #define RCHG 0x02 //FDC OK OR disk changed
// If result type is RERR then rbyte is // If result type is ROK then rbyte is
#define RB0DR 0x01 //deleted record #define RB0DR 0x01 //deleted record
#define RB0CRC 0x02 //CRC error #define RB0CRC 0x02 //CRC error
#define RB0SEK 0x04 //seek error #define RB0SEK 0x04 //seek error
@ -178,7 +177,7 @@
#define RB0WE 0x40 //write error #define RB0WE 0x40 //write error
#define RB0NR 0x80 //not ready #define RB0NR 0x80 //not ready
// If result type is ROK then rbyte is // If result type is RCHG then rbyte is
#define RB1RD2 0x10 //drive 2 ready #define RB1RD2 0x10 //drive 2 ready
#define RB1RD3 0x20 //drive 3 ready #define RB1RD3 0x20 //drive 3 ready
#define RB1RD0 0x40 //drive 0 ready #define RB1RD0 0x40 //drive 0 ready
@ -193,38 +192,37 @@
/* external function prototypes */ /* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern uint16 multibus_get_mword(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 multibus_put_mword(uint16 addr, uint16 val);
/* external globals */ /* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX; extern int32 PCX;
/* internal function prototypes */ /* internal function prototypes */
t_stat zx200a_reset(DEVICE *dptr, uint16 base); t_stat isbc064_cfg(uint16 base);
void zx200a_reset1(uint8); t_stat zx200a_reset(DEVICE *dptr);
void zx200a_reset1(void);
t_stat zx200a_attach (UNIT *uptr, CONST char *cptr); t_stat zx200a_attach (UNIT *uptr, CONST char *cptr);
t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 zx200a0(t_bool io, uint8 data); uint8 zx200ar0SD(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a1(t_bool io, uint8 data); uint8 zx200ar0DD(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a2(t_bool io, uint8 data); uint8 zx200ar1SD(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a3(t_bool io, uint8 data); uint8 zx200ar1DD(t_bool io, uint8 data, uint8 devnum);
uint8 zx200a7(t_bool io, uint8 data); uint8 zx200ar2SD(t_bool io, uint8 data, uint8 devnum);
void zx200a_diskio(uint8 fdcnum); uint8 zx200ar2DD(t_bool io, uint8 data, uint8 devnum);
uint8 zx200ar3(t_bool io, uint8 data, uint8 devnum);
uint8 zx200ar7(t_bool io, uint8 data, uint8 devnum);
void zx200a_diskio(void);
/* globals */ /* globals */
int32 zx200a_fdcnum = 0; //actual number of ZX-200A instances + 1
typedef struct { //FDD definition typedef struct { //FDD definition
// uint8 *buf; // uint8 *buf;
int t0; // int t0;
int rdy; // int rdy;
uint8 sec; uint8 sec;
uint8 cyl; uint8 cyl;
uint8 dd; uint8 dd;
@ -235,7 +233,8 @@ typedef struct { //FDD definition
typedef struct { //FDC definition typedef struct { //FDC definition
uint16 baseport; //FDC base port uint16 baseport; //FDC base port
uint16 iopb; //FDC IOPB uint16 iopb; //FDC IOPB
uint8 stat; //FDC status uint8 DDstat; //FDC DD status
uint8 SDstat; //FDC SD status
uint8 rdychg; //FDC ready change uint8 rdychg; //FDC ready change
uint8 rtype; //FDC result type uint8 rtype; //FDC result type
uint8 rbyte0; //FDC result byte for type 00 uint8 rbyte0; //FDC result byte for type 00
@ -244,36 +243,26 @@ typedef struct { //FDC definition
FDDDEF fdd[FDD_NUM]; //indexed by the FDD number FDDDEF fdd[FDD_NUM]; //indexed by the FDD number
} FDCDEF; } FDCDEF;
FDCDEF zx200a[4]; //indexed by the zx200a instance number FDCDEF zx200a;
/* ZX-200A Standard I/O Data Structures */
UNIT zx200a_unit[] = { UNIT zx200a_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 } { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD), 20 },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD), 20 },
}; };
REG zx200a_reg[] = { REG zx200a_reg[] = {
{ HRDATA (STAT0, zx200a[0].stat, 8) }, /* zx200a 0 status */ { HRDATA (STAT0, zx200a.SDstat, 8) }, /* zx200a 0 SD status */
{ HRDATA (RTYP0, zx200a[0].rtype, 8) }, /* zx200a 0 result type */ { HRDATA (STAT0, zx200a.DDstat, 8) }, /* zx200a 0 DD status */
{ HRDATA (RBYT0A, zx200a[0].rbyte0, 8) }, /* zx200a 0 result byte 0 */ { HRDATA (RTYP0, zx200a.rtype, 8) }, /* zx200a 0 result type */
{ HRDATA (RBYT0B, zx200a[0].rbyte1, 8) }, /* zx200a 0 result byte 1 */ { HRDATA (RBYT0A, zx200a.rbyte0, 8) }, /* zx200a 0 result byte 0 */
{ HRDATA (INTFF0, zx200a[0].intff, 8) }, /* zx200a 0 interrupt f/f */ { HRDATA (RBYT0B, zx200a.rbyte1, 8) }, /* zx200a 0 result byte 1 */
{ HRDATA (STAT1, zx200a[1].stat, 8) }, /* zx200a 1 status */ { HRDATA (INTFF0, zx200a.intff, 8) }, /* zx200a 0 interrupt f/f */
{ HRDATA (RTYP1, zx200a[1].rtype, 8) }, /* zx200a 1 result type */
{ HRDATA (RBYT1A, zx200a[1].rbyte0, 8) }, /* zx200a 1 result byte 0 */
{ HRDATA (RBYT1B, zx200a[1].rbyte1, 8) }, /* zx200a 1 result byte 1 */
{ HRDATA (INTFF1, zx200a[1].intff, 8) }, /* zx200a 1 interrupt f/f */
{ HRDATA (STAT2, zx200a[2].stat, 8) }, /* zx200a 2 status */
{ HRDATA (RTYP2, zx200a[2].rtype, 8) }, /* zx200a 2 result type */
{ HRDATA (RBYT2A, zx200a[2].rbyte0, 8) }, /* zx200a 2 result byte 0 */
{ HRDATA (RBYT2B, zx200a[2].rbyte1, 8) }, /* zx200a 2 result byte 1 */
{ HRDATA (INTFF2, zx200a[2].intff, 8) }, /* zx200a 2 interrupt f/f */
{ HRDATA (STAT3, zx200a[3].stat, 8) }, /* zx200a 3 status */
{ HRDATA (RTYP3, zx200a[3].rtype, 8) }, /* zx200a 3 result type */
{ HRDATA (RBYT3A, zx200a[3].rbyte0, 8) }, /* zx200a 3 result byte 0 */
{ HRDATA (RBYT3B, zx200a[3].rbyte1, 8) }, /* zx200a 3 result byte 1 */
{ HRDATA (INTFF3, zx200a[3].intff, 8) }, /* zx200a 3 interrupt f/f */
{ NULL } { NULL }
}; };
@ -309,13 +298,14 @@ DEVICE zx200a_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
NULL, //reset zx200a_reset, //reset
NULL, //boot NULL, //boot
&zx200a_attach, //attach &zx200a_attach, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl // DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
0, //dctrl
zx200a_debug, //debflags zx200a_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL //lname
@ -327,81 +317,90 @@ DEVICE zx200a_dev = {
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
/* Reset routine */ // configuration routine
t_stat zx200a_reset(DEVICE *dptr, uint16 base) t_stat zx200a_cfg(uint8 base)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
sim_printf(" ZX-200A FDC Board"); sim_printf(" zx200a: at base 0%02XH\n",
if (ZX200A_NUM) { base);
sim_printf(" - Found on Port %02X\n", base);
sim_printf(" ZX200A-%d: Hardware Reset\n", zx200a_fdcnum);
sim_printf(" ZX200A-%d: Registered at %04X\n", zx200a_fdcnum, base);
//register base port address for this FDC instance
zx200a[zx200a_fdcnum].baseport = base;
//register I/O port addresses for each function //register I/O port addresses for each function
reg_dev(zx200a0, base, zx200a_fdcnum); reg_dev(zx200ar0DD, base, 0); //read status
reg_dev(zx200a1, base + 1, zx200a_fdcnum); reg_dev(zx200ar1DD, base + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200a2, base + 2, zx200a_fdcnum); reg_dev(zx200ar2DD, base + 2, 0); //write IOPB addr-h and start
reg_dev(zx200a3, base + 3, zx200a_fdcnum); reg_dev(zx200ar3, base + 3, 0); //read rstl byte
reg_dev(zx200a7, base + 7, zx200a_fdcnum); reg_dev(zx200ar7, base + 7, 0); //write reset zx200a
reg_dev(zx200a0, base+16, zx200a_fdcnum); reg_dev(zx200ar0SD, base + 16, 0); //read status
reg_dev(zx200a1, base+16 + 1, zx200a_fdcnum); reg_dev(zx200ar1SD, base + 17, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200a2, base+16 + 2, zx200a_fdcnum); reg_dev(zx200ar2SD, base + 18, 0); //write IOPB addr-h and start
reg_dev(zx200a3, base+16 + 3, zx200a_fdcnum); reg_dev(zx200ar3, base + 19, 0); //read rstl byte
reg_dev(zx200a7, base+16 + 7, zx200a_fdcnum); reg_dev(zx200ar7, base + 23, 0); //write reset zx200a
// one-time initialization for all FDDs for this FDC instance // one-time initialization for all FDDs
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
uptr = zx200a_dev.units + i; uptr = zx200a_dev.units + i;
uptr->u5 = zx200a_fdcnum; //fdc device number
uptr->u6 = i; //fdd unit number uptr->u6 = i; //fdd unit number
uptr->flags |= UNIT_WPMODE; //set WP in unit flags
} }
zx200a_reset1(zx200a_fdcnum);
zx200a_fdcnum++;
} else
sim_printf(" - Not Found\n");
return SCPE_OK; return SCPE_OK;
} }
/* Reset routine */
t_stat zx200a_reset(DEVICE *dptr)
{
zx200a_reset1(); //software reset
return SCPE_OK;
}
/* Software reset routine */ /* Software reset routine */
void zx200a_reset1(uint8 fdcnum) void zx200a_reset1(void)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
sim_printf(" ZX-200A-%d: Initializing\n", fdcnum); zx200a.DDstat = 0; //clear the FDC DD status
zx200a[fdcnum].stat = 0; //clear status zx200a.SDstat = 0; //clear the FDC SD status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */ for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = zx200a_dev.units + i; uptr = zx200a_dev.units + i;
zx200a[fdcnum].stat |= FDCPRE | FDCDD; //set the FDC status zx200a.DDstat |= FDCPRE | FDCDD; //set the FDC DD status
zx200a[fdcnum].rtype = ROK; zx200a.SDstat |= FDCPRE; //set the FDC SD status
if (uptr->capac == 0) { /* if not configured */ if (i <= 3 ) { //first 4 are DD, last 2 are SD
sim_printf(" ZX-200A%d: Configured, Status=%02X Not attached\n", i, zx200a[fdcnum].stat); zx200a.fdd[i].dd = 1; //set double density
} else { } else {
zx200a.fdd[i].dd = 0; //set single density
}
zx200a.rtype = ROK;
zx200a.rbyte0 = 0; //set no error
if (uptr->flags & UNIT_ATT) { /* if attached */
switch(i){ switch(i){
case 0: case 0:
zx200a[fdcnum].stat |= RDY0; //set FDD 0 ready zx200a.DDstat |= RDY0; //set FDD 0 ready
zx200a[fdcnum].rbyte1 |= RB1RD0; zx200a.rbyte1 |= RB1RD0;
break; break;
case 1: case 1:
zx200a[fdcnum].stat |= RDY1; //set FDD 1 ready zx200a.DDstat |= RDY1; //set FDD 1 ready
zx200a[fdcnum].rbyte1 |= RB1RD1; zx200a.rbyte1 |= RB1RD1;
break; break;
case 2: case 2:
zx200a[fdcnum].stat |= RDY2; //set FDD 2 ready zx200a.DDstat |= RDY2; //set FDD 2 ready
zx200a[fdcnum].rbyte1 |= RB1RD2; zx200a.rbyte1 |= RB1RD2;
break; break;
case 3: case 3:
zx200a[fdcnum].stat |= RDY3; //set FDD 3 ready zx200a.DDstat |= RDY3; //set FDD 3 ready
zx200a[fdcnum].rbyte1 |= RB1RD3; zx200a.rbyte1 |= RB1RD3;
break;
case 4:
zx200a.SDstat |= RDY0; //set FDD 0 ready
zx200a.rbyte1 |= RB1RD0;
break;
case 5:
zx200a.SDstat |= RDY1; //set FDD 1 ready
zx200a.rbyte1 |= RB1RD1;
break; break;
} }
zx200a[fdcnum].rdychg = 0; zx200a.rdychg = 0;
sim_printf(" ZX-200A%d: Configured, Status=%02X Attached to %s\n",
i, zx200a[fdcnum].stat, uptr->filename);
} }
} }
} }
@ -411,52 +410,42 @@ void zx200a_reset1(uint8 fdcnum)
t_stat zx200a_attach (UNIT *uptr, CONST char *cptr) t_stat zx200a_attach (UNIT *uptr, CONST char *cptr)
{ {
t_stat r; t_stat r;
uint8 fdcnum, fddnum; uint8 fddnum;
sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_attach: Entered with cptr=%s\n", cptr); sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" zx200a_attach: Attach error\n"); sim_printf(" zx200a_attach: Attach error %d\n", r);
return r; return r;
} }
fdcnum = uptr->u5;
fddnum = uptr->u6; fddnum = uptr->u6;
switch(fddnum){ switch(fddnum){
case 0: case 0:
zx200a[fdcnum].stat |= RDY0; //set FDD 0 ready zx200a.DDstat |= RDY0; //set FDD 0 ready
zx200a[fdcnum].rbyte1 |= RB1RD0; zx200a.rbyte1 |= RB1RD0;
break; break;
case 1: case 1:
zx200a[fdcnum].stat |= RDY1; //set FDD 1 ready zx200a.DDstat |= RDY1; //set FDD 1 ready
zx200a[fdcnum].rbyte1 |= RB1RD1; zx200a.rbyte1 |= RB1RD1;
break; break;
case 2: case 2:
zx200a[fdcnum].stat |= RDY2; //set FDD 2 ready zx200a.DDstat |= RDY2; //set FDD 2 ready
zx200a[fdcnum].rbyte1 |= RB1RD2; zx200a.rbyte1 |= RB1RD2;
break; break;
case 3: case 3:
zx200a[fdcnum].stat |= RDY3; //set FDD 3 ready zx200a.DDstat |= RDY3; //set FDD 3 ready
zx200a[fdcnum].rbyte1 |= RB1RD3; zx200a.rbyte1 |= RB1RD3;
break;
case 4:
zx200a.SDstat |= RDY0; //set FDD 0 ready
zx200a.rbyte1 |= RB1RD0;
break;
case 5:
zx200a.SDstat |= RDY1; //set FDD 1 ready
zx200a.rbyte1 |= RB1RD1;
break; break;
} }
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
if (uptr->capac == 256256 && (fddnum == 2 || fddnum == 3)) { /* 8" 256K SSSD */ zx200a.rbyte0 = 0; //set no error
zx200a[fdcnum].fdd[fddnum].dd = 0;
// zx200a[fdcnum].fdd[fddnum].maxcyl = 77;
// zx200a[fdcnum].fdd[fddnum].maxsec = 26;
zx200a[fdcnum].fdd[fddnum].sec = 1;
zx200a[fdcnum].fdd[fddnum].cyl = 0;
}
else if (uptr->capac == 512512) { /* 8" 512K SSDD */
zx200a[fdcnum].fdd[fddnum].dd = 1;
// zx200a[fdcnum].fdd[fddnum].maxcyl = 77;
// zx200a[fdcnum].fdd[fddnum].maxsec = 52;
zx200a[fdcnum].fdd[fddnum].sec = 1;
zx200a[fdcnum].fdd[fddnum].cyl = 0;
} else
sim_printf(" ZX-200A-%d: Invalid disk image or SD on drive 0 or 1\n", fdcnum);
sim_printf(" ZX-200A-%d: Configured %d bytes, Attached to %s\n",
fdcnum, uptr->capac, uptr->filename);
sim_debug (DEBUG_flow, &zx200a_dev, " ZX-200A_attach: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -464,141 +453,134 @@ t_stat zx200a_attach (UNIT *uptr, CONST char *cptr)
t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc) t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
// sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_set_mode: Entered with val=%08XH uptr->flags=%08X\n", if (uptr->flags & UNIT_ATT)
// val, uptr->flags); return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */ if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val; uptr->flags |= val;
} else { /* read write */ } else { /* read write */
uptr->flags &= ~val; uptr->flags &= ~val;
} }
// sim_debug (DEBUG_flow, &zx200a_dev, " zx200a_set_mode: Done\n");
return SCPE_OK; return SCPE_OK;
} }
uint8 zx200_get_dn(void)
{
int i;
for (i=0; i<ZX200A_NUM; i++)
if ((port >= zx200a[i].baseport && port <= zx200a[i].baseport + 7) ||
(port >= zx200a[i].baseport+16 && port <= zx200a[i].baseport+16 + 7))
return i;
sim_printf("zx200_get_dn: port %04X not in zx200 device table\n", port);
return 0xFF;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* zx200a control port functions */ /* zx200a control port functions */
uint8 zx200a0(t_bool io, uint8 data) uint8 zx200ar0SD(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = zx200_get_dn()) != 0xFF) {
if (io == 0) { /* read ststus*/ if (io == 0) { /* read ststus*/
if (DEBUG) return zx200a.SDstat;
sim_printf("\n zx-200a0-%d: 0x78/88 returned status=%02X PCX=%04X",
fdcnum, zx200a[fdcnum].stat, PCX);
return zx200a[fdcnum].stat;
}
} }
return 0; return 0;
} }
uint8 zx200a1(t_bool io, uint8 data) uint8 zx200ar0DD(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum; if (io == 0) { /* read ststus*/
return zx200a.DDstat;
}
return 0;
}
if ((fdcnum = zx200_get_dn()) != 0xFF) { uint8 zx200ar1SD(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read operation */ if (io == 0) { /* read operation */
zx200a[fdcnum].intff = 0; //clear interrupt FF zx200a.intff = 0; //clear interrupt FF
zx200a[fdcnum].stat &= ~FDCINT; if (zx200a.intff)
if (DEBUG) zx200a.SDstat &= ~FDCINT;
sim_printf("\n zx-200a1-%d: 0x79/89 returned rtype=%02X intff=%02X status=%02X PCX=%04X", if (zx200a.rdychg) {
fdcnum, zx200a[fdcnum].rtype, zx200a[fdcnum].intff, zx200a[fdcnum].stat, PCX); zx200a.rtype = ROK;
return zx200a[fdcnum].rtype; return zx200a.rtype;
} else { /* write control port */ } else {
zx200a[fdcnum].iopb = data; zx200a.rtype = ROK;
if (DEBUG) return zx200a.rtype;
sim_printf("\n zx-200a1-%d: 0x79/88 IOPB low=%02X PCX=%04X",
fdcnum, data, PCX);
} }
} else { /* write control port */
zx200a.iopb = data;
} }
return 0; return 0;
} }
uint8 zx200a2(t_bool io, uint8 data) uint8 zx200ar1DD(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum; if (io == 0) { /* read operation */
zx200a.intff = 0; //clear interrupt FF
if (zx200a.intff)
zx200a.DDstat &= ~FDCINT;
if (zx200a.rdychg) {
zx200a.rtype = ROK;
return zx200a.rtype;
} else {
zx200a.rtype = ROK;
return zx200a.rtype;
}
} else { /* write control port */
zx200a.iopb = data;
}
return 0;
}
if ((fdcnum = zx200_get_dn()) != 0xFF) { uint8 zx200ar2SD(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
zx200a[fdcnum].iopb |= (data << 8); zx200a.iopb |= (data << 8);
if (DEBUG) zx200a_diskio();
sim_printf("\n zx-200a2-%d: 0x7A/8A IOPB=%04X PCX=%04X", if (zx200a.intff)
fdcnum, zx200a[fdcnum].iopb, PCX); zx200a.SDstat |= FDCINT;
zx200a_diskio(fdcnum);
if (zx200a[fdcnum].intff)
zx200a[fdcnum].stat |= FDCINT;
}
} }
return 0; return 0;
} }
uint8 zx200a3(t_bool io, uint8 data) uint8 zx200ar2DD(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = zx200_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if (zx200a[fdcnum].rtype == 0) { ;
if (DEBUG) } else { /* write data port */
sim_printf("\n zx200a3-%d: 0x7B/8B returned rbyte0=%02X PCX=%04X", zx200a.iopb |= (data << 8);
fdcnum, zx200a[fdcnum].rbyte0, PCX); zx200a_diskio();
return zx200a[fdcnum].rbyte0; if (zx200a.intff)
} else { zx200a.DDstat |= FDCINT;
if (zx200a[fdcnum].rdychg) { }
if (DEBUG)
sim_printf("\n zx200a3-%d: 0x7B/8B returned rbyte1=%02X PCX=%04X",
fdcnum, zx200a[fdcnum].rbyte1, PCX);
return zx200a[fdcnum].rbyte1;
} else {
if (DEBUG)
sim_printf("\n zx200a3-%d: 0x7B/8B returned rbytex=%02X PCX=%04X",
fdcnum, 0, PCX);
return 0; return 0;
}
uint8 zx200ar3(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (zx200a.rtype == 0) {
return zx200a.rbyte0;
} else {
if (zx200a.rdychg) {
return zx200a.rbyte1;
} else {
return zx200a.rbyte0;
} }
} }
} else { /* write data port */ } else { /* write data port */
; //stop diskette operation ; //stop diskette operation
} }
}
return 0; return 0;
} }
/* reset ZX-200A */ /* reset ZX-200A */
uint8 zx200a7(t_bool io, uint8 data) uint8 zx200ar7(t_bool io, uint8 data, uint8 devnum)
{ {
uint8 fdcnum;
if ((fdcnum = zx200_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
zx200a_reset1(fdcnum); zx200a_reset1();
}
} }
return 0; return 0;
} }
// perform the actual disk I/O operation // perform the actual disk I/O operation
void zx200a_diskio(uint8 fdcnum) void zx200a_diskio(void)
{ {
uint8 cw, di, nr, ta, sa, data, nrptr; uint8 cw, di, nr, ta, sa, data, nrptr;
uint16 ba; uint16 ba;
@ -609,62 +591,75 @@ void zx200a_diskio(uint8 fdcnum)
uint8 *fbuf; uint8 *fbuf;
//parse the IOPB //parse the IOPB
cw = multibus_get_mbyte(zx200a[fdcnum].iopb); cw = multibus_get_mbyte(zx200a.iopb);
di = multibus_get_mbyte(zx200a[fdcnum].iopb + 1); di = multibus_get_mbyte(zx200a.iopb + 1);
nr = multibus_get_mbyte(zx200a[fdcnum].iopb + 2); nr = multibus_get_mbyte(zx200a.iopb + 2);
ta = multibus_get_mbyte(zx200a[fdcnum].iopb + 3); ta = multibus_get_mbyte(zx200a.iopb + 3);
sa = multibus_get_mbyte(zx200a[fdcnum].iopb + 4); sa = multibus_get_mbyte(zx200a.iopb + 4);
ba = multibus_get_mword(zx200a[fdcnum].iopb + 5); ba = multibus_get_mbyte(zx200a.iopb + 5);
ba |= (multibus_get_mbyte(zx200a.iopb + 6) << 8);
fddnum = (di & 0x30) >> 4; fddnum = (di & 0x30) >> 4;
uptr = zx200a_dev.units + fddnum; uptr = zx200a_dev.units + fddnum;
fbuf = (uint8 *) (zx200a_dev.units + fddnum)->filebuf; fbuf = (uint8 *) uptr->filebuf;
if (DEBUG) {
sim_printf("\n zx200a-%d: zx200a_diskio IOPB=%04X FDD=%02X STAT=%02X",
fdcnum, zx200a[fdcnum].iopb, fddnum, zx200a[fdcnum].stat);
sim_printf("\n zx200a-%d: cw=%02X di=%02X nr=%02X ta=%02X sa=%02X ba=%04X",
fdcnum, cw, di, nr, ta, sa, ba);
}
//check for not ready //check for not ready
switch(fddnum) { switch(fddnum) {
case 0: case 0:
if ((zx200a[fdcnum].stat & RDY0) == 0) { if ((zx200a.DDstat & RDY0) == 0) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0NR; zx200a.rbyte0 = RB0NR;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n zx200a: Ready error on drive %d", fddnum);
return; return;
} }
break; break;
case 1: case 1:
if ((zx200a[fdcnum].stat & RDY1) == 0) { if ((zx200a.DDstat & RDY1) == 0) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0NR; zx200a.rbyte0 = RB0NR;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n zx200a: Ready error on drive %d", fddnum);
return; return;
} }
break; break;
case 2: case 2:
if ((zx200a[fdcnum].stat & RDY2) == 0) { if ((zx200a.DDstat & RDY2) == 0) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0NR; zx200a.rbyte0 = RB0NR;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n zx200a: Ready error on drive %d", fddnum);
return; return;
} }
break; break;
case 3: case 3:
if ((zx200a[fdcnum].stat & RDY3) == 0) { if ((zx200a.DDstat & RDY3) == 0) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0NR; zx200a.rbyte0 = RB0NR;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Ready error on drive %d", fdcnum, fddnum); sim_printf("\n zx200a: Ready error on drive %d", fddnum);
return;
}
break;
case 4:
if ((zx200a.SDstat & RDY0) == 0) {
zx200a.rtype = ROK;
zx200a.rbyte0 = RB0NR;
zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a: Ready error on drive %d", fddnum);
return;
}
break;
case 5:
if ((zx200a.SDstat & RDY1) == 0) {
zx200a.rtype = ROK;
zx200a.rbyte0 = RB0NR;
zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a: Ready error on drive %d", fddnum);
return; return;
} }
break; break;
} }
//check for address error //check for address error
if (zx200a[fdcnum].fdd[fddnum].dd == 1) { if (zx200a.fdd[fddnum].dd == 1) {
if ( if (
((di & 0x07) != DHOME) && ( ((di & 0x07) != DHOME) && (
(sa > MAXSECDD) || (sa > MAXSECDD) ||
@ -672,13 +667,14 @@ void zx200a_diskio(uint8 fdcnum)
(sa == 0) || (sa == 0) ||
(ta > MAXTRK) (ta > MAXTRK)
)) { )) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0ADR; zx200a.rbyte0 = RB0ADR;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Address error on drive %d", fdcnum, fddnum); sim_printf("\n ZX200A: FDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
fddnum, sa, nr, ta, PCX);
return; return;
} }
} else if (zx200a[fdcnum].fdd[fddnum].dd == 0) { } else {
if ( if (
((di & 0x07) != DHOME) && ( ((di & 0x07) != DHOME) && (
(sa > MAXSECSD) || (sa > MAXSECSD) ||
@ -686,45 +682,50 @@ void zx200a_diskio(uint8 fdcnum)
(sa == 0) || (sa == 0) ||
(ta > MAXTRK) (ta > MAXTRK)
)) { )) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0ADR; zx200a.rbyte0 = RB0ADR;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Address error on drive %d", fdcnum, fddnum); sim_printf("\n ZX200A: FDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
fddnum, sa, nr, ta, PCX);
return; return;
} }
} }
switch (di & 0x07) { switch (di & 0x07) {
case DNOP: case DNOP:
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
case DSEEK: case DSEEK:
zx200a[fdcnum].fdd[fddnum].sec = sa; zx200a.fdd[fddnum].sec = sa;
zx200a[fdcnum].fdd[fddnum].cyl = ta; zx200a.fdd[fddnum].cyl = ta;
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
case DHOME: case DHOME:
zx200a[fdcnum].fdd[fddnum].sec = sa; zx200a.fdd[fddnum].sec = sa;
zx200a[fdcnum].fdd[fddnum].cyl = 0; zx200a.fdd[fddnum].cyl = 0;
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
case DVCRC: case DVCRC:
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
case DFMT: case DFMT:
//check for WP //check for WP
if(uptr->flags & UNIT_WPMODE) { if(uptr->flags & UNIT_WPMODE) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0WP; zx200a.rbyte0 = RB0WP;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Write protect error 1 on drive %d", fdcnum, fddnum); sim_printf("\n zx200a: Write protect error 1 on drive %d", fddnum);
return; return;
} }
fmtb = multibus_get_mbyte(ba); //get the format byte fmtb = multibus_get_mbyte(ba); //get the format byte
if (zx200a[fdcnum].fdd[fddnum].dd == 1) { if (zx200a.fdd[fddnum].dd == 1) {
//calculate offset into DD disk image //calculate offset into DD disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) { for(i=0; i<=((uint32)(MAXSECDD) * 128); i++) {
@ -737,21 +738,19 @@ void zx200a_diskio(uint8 fdcnum)
*(fbuf + (dskoff + i)) = fmtb; *(fbuf + (dskoff + i)) = fmtb;
} }
} }
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
case DREAD: case DREAD:
nrptr = 0; nrptr = 0;
while(nrptr < nr) { while(nrptr < nr) {
//calculate offset into disk image //calculate offset into disk image
if (zx200a[fdcnum].fdd[fddnum].dd == 1) { if (zx200a.fdd[fddnum].dd == 1) {
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
} else { } else {
dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECSD) + (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);
//copy sector from image to RAM //copy sector from image to RAM
for (i=0; i<128; i++) { for (i=0; i<128; i++) {
data = *(fbuf + (dskoff + i)); data = *(fbuf + (dskoff + i));
@ -761,29 +760,27 @@ void zx200a_diskio(uint8 fdcnum)
ba+=0x80; ba+=0x80;
nrptr++; nrptr++;
} }
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
case DWRITE: case DWRITE:
//check for WP //check for WP
if(uptr->flags & UNIT_WPMODE) { if(uptr->flags & UNIT_WPMODE) {
zx200a[fdcnum].rtype = RERR; zx200a.rtype = ROK;
zx200a[fdcnum].rbyte0 = RB0WP; zx200a.rbyte0 = RB0WP;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.intff = 1; //set interrupt FF
sim_printf("\n zx200a-%d: Write protect error 2 on drive %d", fdcnum, fddnum); sim_printf("\n zx200a: Write protect error 2 on drive %d", fddnum);
return; return;
} }
nrptr = 0; nrptr = 0;
while(nrptr < nr) { while(nrptr < nr) {
//calculate offset into disk image //calculate offset into disk image
if (zx200a[fdcnum].fdd[fddnum].dd == 1) { if (zx200a.fdd[fddnum].dd == 1) {
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
} else { } else {
dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECSD) + (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 for (i=0; i<128; i++) { //copy sector from image to RAM
data = multibus_get_mbyte(ba + i); data = multibus_get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data; *(fbuf + (dskoff + i)) = data;
@ -792,11 +789,12 @@ void zx200a_diskio(uint8 fdcnum)
ba+=0x80; ba+=0x80;
nrptr++; nrptr++;
} }
zx200a[fdcnum].rtype = ROK; zx200a.rtype = ROK;
zx200a[fdcnum].intff = 1; //set interrupt FF zx200a.rbyte0 = 0; //set no error
zx200a.intff = 1; //set interrupt FF
break; break;
default: default:
sim_printf("\n zx200a-%d: zx200a_diskio bad di=%02X", fdcnum, di & 0x07); sim_printf("\n zx200a: zx200a_diskio bad di=%02X", di & 0x07);
break; break;
} }
} }

View file

@ -0,0 +1,98 @@
/* mds210_sys.c: multibus system interface
Copyright (c) 2017, 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.
28 Oct 17 - Original file.
18 May 19 - Equipment Emulated:
Model 210 chassis.
Integrated processor board (IPB).
Parallel I/O board (PIO).
ROM-resident system monitor.
Auxiliary ROM board with MCS-80/MCS-85 assembler
and text editor.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev;
//extern DEVICE isbc201_dev;
//extern DEVICE isbc202_dev;
//extern DEVICE isbc206_dev;
//extern DEVICE zx200a_dev;
extern DEVICE isbc464_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-210";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&ipc_cont_dev,
&multibus_dev,
// &isbc201_dev,
// &isbc202_dev,
// &isbc206_dev,
// &zx200a_dev,
&isbc464_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -0,0 +1,156 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2017, 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.
28 Oct 17 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define IPC 0
#define SET_XACK(VAL) (xack = VAL)
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8253 */
#define I8253_BASE 0xF0
#define I8253_NUM 1
/* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4
#define I8251_BASE_1 0xF6
#define I8251_NUM 2
/* set the base I/O address for the 8259 */
#define I8259_BASE_0 0xFA
#define I8259_BASE_1 0xFC
#define I8259_NUM 2
/* set the base I/O address for the IPC control port */
#define ICONT_BASE 0xFF
/* set the base and size for the EPROM on the MDS 210 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the MDS 210 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0x7FFF
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_1
#define ZX200A_NUM 0
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 1
/* set the base and size for the iSBC 064 RAM */
#define SBC064_BASE 0x8000
#define SBC064_SIZE 0x7FFF
#define SBC064_NUM 1
/* set INTR for CPU */
#define INTR INT_1
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupts definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */

View file

@ -0,0 +1,85 @@
/* mds220_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
01 Mar 18 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-220";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&ipc_cont_dev,
&multibus_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -0,0 +1,156 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define IPC 0
#define SET_XACK(VAL) (xack = VAL)
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8253 */
#define I8253_BASE 0xF0
#define I8253_NUM 1
/* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4
#define I8251_BASE_1 0xF6
#define I8251_NUM 2
/* set the base I/O address for the 8259 */
#define I8259_BASE_0 0xFA
#define I8259_BASE_1 0xFC
#define I8259_NUM 2
/* set the base I/O address for the IPC control port */
#define ICONT_BASE 0xFF
/* set the base and size for the EPROM on the MDS 220 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000
#define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the MDS 220 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0x8000
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_INT INT_2
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_2
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_2
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_2
#define ZX200A_NUM 1
/* set the base and size for the iSBC 064 RAM*/
#define SBC064_BASE 0x8000
#define SBC064_SIZE 0x8000
#define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* set INTR for CPU */
#define INTR INT_2
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupts definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */

View file

@ -40,6 +40,7 @@ extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev; extern DEVICE multibus_dev;
extern DEVICE isbc201_dev; extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev; extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE zx200a_dev; extern DEVICE zx200a_dev;
/* SCP data structures /* SCP data structures
@ -69,6 +70,7 @@ DEVICE *sim_devices[] = {
&multibus_dev, &multibus_dev,
&isbc201_dev, &isbc201_dev,
&isbc202_dev, &isbc202_dev,
&isbc206_dev,
&zx200a_dev, &zx200a_dev,
NULL NULL
}; };

View file

@ -30,7 +30,6 @@
#include <ctype.h> #include <ctype.h>
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
#define IPC 0
#define SET_XACK(VAL) (xack = VAL) #define SET_XACK(VAL) (xack = VAL)
/* set the base for the DBB ports */ /* set the base for the DBB ports */
@ -60,35 +59,53 @@
/* set the base and size for the EPROM on the MDS 225 */ /* set the base and size for the EPROM on the MDS 225 */
#define ROM_BASE 0x0000 #define ROM_BASE 0x0000
#define ROM_SIZE 0x1000 #define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1 #define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the MDS 225 */ /* set the base and size for the RAM on the MDS 225 */
#define RAM_BASE 0x0000 #define RAM_BASE 0x0000
#define RAM_SIZE 0xF800 #define RAM_SIZE 0xFFFF
#define RAM_DISABLE 0
//board definitions for the multibus //board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */ /* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78 #define SBC202_BASE 0x78
#define SBC202_INT INT_1 #define SBC202_INT INT_2
#define SBC202_NUM 1 #define SBC202_NUM 1
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_2
#define SBC201_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40
#define SBC208_INT INT_1 #define SBC208_INT INT_2
#define SBC208_NUM 0 #define SBC208_NUM 0
/* set the base for the zx-200a disk controller */ /* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78 #define ZX200A_BASE 0x78
#define ZX200A_INT INT_2
#define ZX200A_NUM 0 #define ZX200A_NUM 0
/* set the base and size for the iSBC 064 RAM*/
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0xFFFF
#define SBC064_NUM 0
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* set INTR for CPU */ /* set INTR for CPU */
#define INTR INT_1 #define INTR INT_2
/* multibus interrupt definitions */ /* multibus interrupt definitions */

View file

@ -0,0 +1,87 @@
/* mds220_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
01 Mar 18 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-230";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&ipc_cont_dev,
&multibus_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
&isbc064_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -0,0 +1,155 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8253 */
#define I8253_BASE 0xF0
#define I8253_NUM 1
/* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4
#define I8251_BASE_1 0xF6
#define I8251_NUM 2
/* set the base I/O address for the 8259 */
#define I8259_BASE_0 0xFA
#define I8259_BASE_1 0xFC
#define I8259_NUM 2
/* set the base I/O address for the IPC control port */
#define ICONT_BASE 0xFF
/* set the base and size for the EPROM on the MDS 220 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the MDS 220 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0x7FFF
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78
#define SBC201_INT INT_2
#define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_2
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_2
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_2
#define ZX200A_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* set the base and size for the iSBC 064 RAM */
#define SBC064_BASE 0x08000
#define SBC064_SIZE 0x7FFF
#define SBC064_NUM 1
/* set INTR for CPU */
#define INTR INT_2
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupts definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */

View file

@ -0,0 +1,142 @@
/* cpu.c: Intel MDS-800 CPU Module simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat SBC_reset (DEVICE *dptr);
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
t_stat SBC_config(void);
// globals
int onetime = 0;
/* external function prototypes */
extern t_stat monitor_reset (void);
extern t_stat monitor_cfg(void);
extern t_stat fp_reset (void);
extern t_stat fp_cfg(void);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern uint8 EPROM_get_mbyte(uint16 addr);
extern uint8 EPROM1_get_mbyte(uint16 addr);
extern t_stat multibus_cfg(void);
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat i3214_cfg(uint8 base, uint8 devnum);
// external globals
extern uint8 monitor_boot;
extern DEVICE i8080_dev;
extern uint8 i3214_mask;
extern uint8 EPROM_enable;
extern uint8 i3214_cnt;
extern uint8 i3214_ram[16];
extern uint8 BUS_OVERRIDE;
t_stat SBC_config(void)
{
sim_printf("Configuring MDS-800 CPU Card\n Onboard Devices:\n");
i3214_cfg(I3214_BASE, 0);
fp_cfg();
monitor_cfg();
return SCPE_OK;
}
/* SBC reset routine
put here to cause a reset of the entire MDS-800 system */
t_stat SBC_reset (DEVICE *dptr)
{
if (onetime == 0) {
SBC_config();
multibus_cfg();
onetime++;
}
i8080_reset(&i8080_dev);
EPROM_enable = 1;
BUS_OVERRIDE = 0;
fp_reset();
monitor_reset();
return SCPE_OK;
}
// memory operations
/* get a byte from memory - handle RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
uint8 val;
if (((monitor_boot & 0x04) == 0) && (addr >= ROM0_BASE && addr <= ROM0_BASE + ROM0_SIZE))
val = EPROM_get_mbyte(addr);
else if (ROM1_SIZE && addr >= ROM1_BASE && addr <= ROM1_BASE + ROM1_SIZE)
val = EPROM1_get_mbyte(addr);
else val = multibus_get_mbyte(addr);
val &= 0xFF;
return(val);
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
multibus_put_mbyte(addr, val);
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of cpu.c */

View file

@ -0,0 +1,64 @@
/* front_panel.c: Intel MDS-800 Front Panel Module simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat fp_reset (void);
t_stat fp_cfg(void);
/* external function prototypes */
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
/* external globals */
extern DEVICE *EPROM_dev;
t_stat fp_cfg(void)
{
sim_printf("Configuring MDS-800 Front Panel Card\n Onboard Devices:\n");
EPROM_cfg(ROM0_BASE, ROM0_SIZE);
return SCPE_OK;
}
/* CPU reset routine
put here to cause a reset of the entire IPC system */
t_stat fp_reset (void)
{
EPROM_reset(EPROM_dev);
return SCPE_OK;
}
/* end of front_panel.c */

View file

@ -0,0 +1,84 @@
/* mds-800_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
5 October 2017 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i3214_dev;
extern DEVICE EPROM_dev;
extern DEVICE EPROM1_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-800";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&EPROM1_dev,
&i8251_dev,
&i3214_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* end of mds-800_sys.c */

View file

@ -0,0 +1,77 @@
/* monitor.c: Intel MDS-800 Monitor Module simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat monitor_cfg(void);
t_stat monitor_reset (void);
/* external function prototypes */
extern t_stat i8251_reset(DEVICE *dptr);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat EPROM1_reset(DEVICE *dptr);
extern t_stat EPROM1_cfg(uint16 base, uint16 size);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 i3214_monitor_do_boot(t_bool io, uint8 data, uint8 devnum);
// external globals
extern uint32 PCX; /* program counter */
extern DEVICE *i8251_dev;
extern DEVICE *EPROM1_dev;
extern uint8 monitor_boot;
// globals
t_stat monitor_cfg(void)
{
sim_printf("Configuring MDS-800 Monitor Card\n Onboard Devices:\n");
EPROM1_cfg(ROM1_BASE, ROM1_SIZE);
i8251_cfg(I8251_BASE_0, 0);
i8251_cfg(I8251_BASE_1, 1);
return SCPE_OK;
}
/* Monitor reset routine
put here to cause a reset of the entire IPC system */
t_stat monitor_reset (void)
{
monitor_boot = 0x00;
i8251_reset(i8251_dev);
EPROM1_reset(EPROM1_dev);
return SCPE_OK;
}
/* end of monitor.c */

View file

@ -0,0 +1,140 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
5 October 2017 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
/* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4 //TTY
#define I8251_BASE_1 0xF6 //CRT
#define I8251_NUM 2
// set the base I/O address for the 3214
#define I3214_BASE 0xFC
#define I3214_NUM 1
/* set the base and size for the EPROM0 on the Monitor Module */
#define ROM0_BASE 0x0000
#define ROM0_SIZE 0x00FF
#define ROM0_DISABLE 1
/* set the base and size for the EPROM1 on the Front Panel Module */
#define ROM1_BASE 0xF800
#define ROM1_SIZE 0x07FF
#define ROM1_DISABLE 0
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_3
#define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_3
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
/* set the base for the ZX-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_2
#define ZX200A_NUM 0
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0xF7FF
#define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x47FF
#define SBC464_NUM 0
/* set INTR for CPU */
#define INTR INT_2
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupt definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */
/* end of system_defs.h */

View file

@ -0,0 +1,142 @@
/* cpu.c: Intel MDS-810 CPU Module simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
// globals
int onetime = 0;
/* external function prototypes */
extern t_stat monitor_reset (void);
extern t_stat fp_reset (void);
extern t_stat i3214_reset (DEVICE *dptr);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern uint8 EPROM_get_mbyte(uint16 addr);
extern uint8 EPROM1_get_mbyte(uint16 addr);
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat i3214_cfg(uint8 base, uint8 devnum);
extern t_stat fp_cfg(void);
extern t_stat monitor_cfg(void);
extern t_stat multibus_cfg(void);
// external globals
extern uint32 PCX; /* program counter */
extern DEVICE i3214_dev;
extern DEVICE i8080_dev;
extern uint8 EPROM_enable;
extern uint8 BUS_OVERRIDE;
t_stat SBC_config(void)
{
sim_printf("Configuring MDS-800 CPU Module\n Onboard Devices:\n");
i3214_cfg(I3214_BASE, 0);
fp_cfg();
monitor_cfg();
return SCPE_OK;
}
/* SBC reset routine
put here to cause a reset of the entire MDS-800 system */
t_stat SBC_reset (DEVICE *dptr)
{
if (onetime == 0) {
SBC_config();
multibus_cfg();
onetime++;
}
EPROM_enable = 1;
BUS_OVERRIDE = 0;
i8080_reset(&i8080_dev);
i3214_reset(&i3214_dev);
fp_reset();
monitor_reset();
return SCPE_OK;
}
// memory operations
/* get a byte from memory - handle RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
uint8 val;
if (EPROM_enable && (addr >= ROM0_BASE && addr <= ROM0_BASE + ROM0_SIZE))
val = EPROM_get_mbyte(addr);
else if (ROM1_SIZE && addr >= ROM1_BASE && addr <= ROM1_BASE + ROM1_SIZE)
val = EPROM1_get_mbyte(addr);
else val = multibus_get_mbyte(addr);
val &= 0xFF;
return(val);
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
multibus_put_mbyte(addr, val);
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of cpu.c */

View file

@ -0,0 +1,68 @@
/* front_panel.c: Intel MDS-800 Front Panel Module simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat fp_reset (void);
t_stat fp_cfg(void);
/* external function prototypes */
extern uint8 EPROM_get_mbyte(uint16 addr);
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
// external globals
extern UNIT EPROM_unit; //1702 EPROM
extern uint32 PCX; /* program counter */
// fp configuration
t_stat fp_cfg(void)
{
sim_printf("Configuring MDS-800 Front Panel Module\n Onboard Devices:\n");
EPROM_cfg(ROM0_BASE, ROM0_SIZE);
return SCPE_OK;
}
/* CPU reset routine
put here to cause a reset of the entire IPC system */
t_stat fp_reset (void)
{
return SCPE_OK;
}
/* end of front_panel.c */

View file

@ -0,0 +1,84 @@
/* mds-810_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
5 October 2017 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE EPROM_dev;
extern DEVICE i3214_dev;
extern DEVICE EPROM1_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-810";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&EPROM1_dev,
&i8251_dev,
&i3214_dev,
&multibus_dev,
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};
/* end of mds-800_sys.c */

View file

@ -0,0 +1,83 @@
/* monitor.c: Intel MDS-800 Monitor Module simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat monitor_cfg(void);
t_stat monitor_reset (void);
/* external function prototypes */
extern uint8 monitor_do_boot(t_bool io, uint8 data);
extern uint8 EPROM1_get_mbyte(uint16 addr);
extern t_stat i3214_reset(DEVICE *dptr);
extern t_stat EPROM1_reset(DEVICE *dptr);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM1_cfg(uint16 base, uint16 size);
extern t_stat i8251_reset (DEVICE *dptr);
extern t_stat i8251_cfg(uint8 base, uint8 size);
// external globals
extern uint32 PCX; /* program counter */
extern UNIT EPROM1_unit; //8316 PROM
extern DEVICE *i8251_dev;
extern DEVICE *EPROM1_dev;
// globals
extern uint8 monitor_boot;
// fp configuration
t_stat monitor_cfg(void)
{
sim_printf("Initializing MDS-800 Monitor Module\n Onboard Devices:\n");
EPROM1_cfg(ROM1_BASE, ROM1_SIZE);
i8251_cfg(I8251_BASE_0, 0);
i8251_cfg(I8251_BASE_1, 1);
return SCPE_OK;
}
/* Monitor reset routine
put here to cause a reset of the entire IPC system */
t_stat monitor_reset (void)
{
monitor_boot = 0x00;
i8251_reset(i8251_dev);
EPROM1_reset(EPROM1_dev);
return SCPE_OK;
}
/* end of monitor.c */

View file

@ -0,0 +1,140 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
5 October 2017 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
/* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4 //TTY
#define I8251_BASE_1 0xF6 //CRT
#define I8251_NUM 2
// set the base I/O address for the 3214
#define I3214_BASE 0xFC
#define I3214_NUM 1
/* set the base and size for the EPROM0 on the Monitor Module */
#define ROM0_BASE 0x0000
#define ROM0_SIZE 0x00FF
#define ROM0_DISABLE 1
/* set the base and size for the EPROM1 on the Front Panel Module */
#define ROM1_BASE 0xF800
#define ROM1_SIZE 0x07FF
#define ROM1_DISABLE 1
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_3
#define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_3
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_2
#define SBC208_NUM 0
/* set the base for the ZX-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_2
#define ZX200A_NUM 0
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0xFFFF
#define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x47FF
#define SBC464_NUM 0
/* set INTR for CPU */
#define INTR INT_3
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupt definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */
/* end of system_defs.h */

View file

@ -1,4 +1,4 @@
/* iSBC80-10.c: Intel iSBC 80/10 Processor simulator /* iSBC8010.c: Intel iSBC 80/10 Processor simulator
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
@ -38,15 +38,23 @@
/* function prototypes */ /* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
uint8 get_mbyte(uint16 addr); uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr); uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val); void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val); void put_mword(uint16 addr, uint16 val);
t_stat SBC_reset (DEVICE *dptr);
/* external globals */ /* external globals */
extern uint8 i8255_C[4]; //port C byte I/O extern uint8 i8255_C[4]; //port C byte I/O
extern DEVICE *i8080_dev;
extern DEVICE *i8251_dev;
extern DEVICE *i8255_dev;
extern DEVICE *EPROM_dev;
extern UNIT EPROM_unit;
extern DEVICE *RAM_dev;
extern UNIT RAM_unit;
/* external function prototypes */ /* external function prototypes */
@ -56,28 +64,44 @@ extern uint8 EPROM_get_mbyte(uint16 addr);
extern uint8 RAM_get_mbyte(uint16 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */ extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum; extern t_stat i8251_reset (DEVICE *dptr);
extern t_stat i8251_reset (DEVICE *dptr, uint16 base); extern t_stat i8255_reset (DEVICE *dptr);
extern int32 i8255_devnum; extern t_stat EPROM_reset (DEVICE *dptr);
extern t_stat i8255_reset (DEVICE *dptr, uint16 base); extern t_stat RAM_reset (DEVICE *dptr);
extern UNIT EPROM_unit; extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size); extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern UNIT RAM_unit; extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
/* globals */
int onetime = 0;
t_stat SBC_config(void)
{
sim_printf("Configuring iSBC-80/10 SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
EPROM_cfg(ROM_BASE, ROM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* SBC reset routine */ /* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr) t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing iSBC-80/10 SBC\n Onboard Devices:\n"); if (onetime == 0) {
i8080_reset (NULL); SBC_config();
i8251_devnum = 0; multibus_cfg();
i8251_reset (NULL, I8251_BASE); onetime++;
i8255_devnum = 0; }
i8255_reset (NULL, I8255_BASE_0); i8080_reset(i8080_dev);
i8255_reset (NULL, I8255_BASE_1); i8251_reset(i8251_dev);
EPROM_reset (NULL, ROM_SIZE); i8255_reset(i8255_dev);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK; return SCPE_OK;
} }
@ -86,7 +110,7 @@ t_stat SBC_reset (DEVICE *dptr)
uint8 get_mbyte(uint16 addr) uint8 get_mbyte(uint16 addr)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */ if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) { if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr); return EPROM_get_mbyte(addr);
} }
@ -115,14 +139,14 @@ uint16 get_mword(uint16 addr)
void put_mbyte(uint16 addr, uint8 val) void put_mbyte(uint16 addr, uint8 val)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */ if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) { if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr); sim_printf("Write to R/O memory address %04X - ignored\n", addr);
return; return;
} }
} /* if local RAM handle it */ } /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */ if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) { if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val); RAM_put_mbyte(addr, val);
return; return;
} }
@ -131,11 +155,10 @@ void put_mbyte(uint16 addr, uint8 val)
} }
/* put a word to memory */ /* put a word to memory */
void put_mword(uint16 addr, uint16 val) void put_mword(uint16 addr, uint16 val)
{ {
put_mbyte(addr, val & 0xff); put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8); put_mbyte(addr+1, val >> 8);
} }
/* end of iSBC80-10.c */ /* end of iSBC8010.c */

View file

@ -38,8 +38,11 @@ extern DEVICE RAM_dev;
extern DEVICE multibus_dev; extern DEVICE multibus_dev;
extern DEVICE isbc201_dev; extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev; extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev; extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev; extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev;
/* SCP data structures /* SCP data structures
@ -64,8 +67,11 @@ DEVICE *sim_devices[] = {
&i8255_dev, &i8255_dev,
&multibus_dev, &multibus_dev,
&isbc064_dev, &isbc064_dev,
&isbc464_dev,
&isbc201_dev, &isbc201_dev,
&isbc202_dev, &isbc202_dev,
&isbc206_dev,
&isbc208_dev,
&zx200a_dev, &zx200a_dev,
NULL NULL
}; };
@ -77,6 +83,7 @@ const char *sim_stop_messages[] = {
"Breakpoint", "Breakpoint",
"Invalid Opcode", "Invalid Opcode",
"Invalid Memory", "Invalid Memory",
"XACK Error" "XACK Error",
NULL
}; };

View file

@ -28,12 +28,13 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h>
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL) #define SET_XACK(VAL) (xack = VAL)
//chip definitions for the iSBC-80/10 //chip definitions for the iSBC-80/10
/* set the base I/O address and device count for the 8251s */ /* set the base I/O address and device count for the 8251 */
#define I8251_BASE 0xEC #define I8251_BASE 0xEC
#define I8251_NUM 1 #define I8251_NUM 1
@ -44,43 +45,54 @@
/* set the base and size for the EPROM on the iSBC 80/10 */ /* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_BASE 0x0000 #define ROM_BASE 0x0000
#define ROM_SIZE 0x1000 #define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1 #define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the iSBC 80/10 */ /* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0x3C00 #define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400 #define RAM_SIZE 0x03FF
#define RAM_DISABLE 1 #define RAM_DISABLE 1
/* set INTR for CPU on the iSBC 80/10 */ /* set INTR for CPU on the iSBC 80/10 */
#define INTR INT_1 #define INTR INT_2
//board definitions for the multibus //board definitions for the multibus
/* set the base I/O address for the iSBC 201 */ /* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88 #define SBC201_BASE 0x88
#define SBC201_INT INT_1 #define SBC201_INT INT_2
#define SBC201_NUM 0 #define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */ /* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78 #define SBC202_BASE 0x78
#define SBC202_INT INT_1 #define SBC202_INT INT_2
#define SBC202_NUM 1 #define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_2
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40
#define SBC208_INT INT_1 #define SBC208_INT INT_2
#define SBC208_NUM 0 #define SBC208_NUM 1
/* set the base for the zx-200a disk controller */ /* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78 #define ZX200A_BASE 0x78
#define ZX200A_INT INT_1 #define ZX200A_INT INT_2
#define ZX200A_NUM 0 #define ZX200A_NUM 0
/* set the base and size for the iSBC 064 */ /* set the base and size for the iSBC 064 RAM*/
#define SBC064_BASE 0x0000 #define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000 #define SBC064_SIZE 0xFFFF
#define SBC064_NUM 1 #define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* multibus interrupt definitions */ /* multibus interrupt definitions */
#define INT_0 0x01 #define INT_0 0x01

View file

@ -1,4 +1,4 @@
/* iSBC80-20.c: Intel iSBC 80/20 Processor simulator /* iSBC8020.c: Intel iSBC 80/20 Processor simulator
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
@ -31,8 +31,11 @@
#include "system_defs.h" #include "system_defs.h"
int flag = 1;
/* function prototypes */ /* function prototypes */
t_stat SBC_config(void);
uint8 get_mbyte(uint16 addr); uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr); uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val); void put_mbyte(uint16 addr, uint8 val);
@ -48,33 +51,76 @@ extern uint8 i8255_C[4]; //port C byte I/O
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */ extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum; extern DEVICE *i8080_dev;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base); extern t_stat i8251_reset (DEVICE *dptr);
extern int32 i8255_devnum; extern uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
extern t_stat i8255_reset (DEVICE *dptr, uint16 base); extern uint8 i8251d(t_bool io, uint8 data, uint8 devnum);
extern int32 i8259_devnum; extern DEVICE *i8251_dev;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base); extern t_stat i8253_reset (DEVICE *dptr);
extern uint8 i8253t0(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8253t1(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8253t2(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8253c(t_bool io, uint8 data, uint8 devnum);
extern DEVICE *i8253_dev;
extern t_stat i8255_reset (DEVICE *dptr);
extern uint8 i8255a(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8255b(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8255c(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8255s(t_bool io, uint8 data, uint8 devnum);
extern DEVICE *i8255_dev;
extern t_stat i8259_reset (DEVICE *dptr);
extern uint8 i8259a(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8259b(t_bool io, uint8 data, uint8 devnum);
extern DEVICE *i8259_dev;
extern uint8 EPROM_get_mbyte(uint16 addr); extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit; extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size); extern t_stat EPROM_reset (DEVICE *dptr);
extern uint8 RAM_get_mbyte(uint16 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit; extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); extern t_stat RAM_reset (DEVICE *dptr);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
// globals
int onetime = 0;
t_stat SBC_config(void)
{
sim_printf("Configuring iSBC-80/20 SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE, 0);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
i8259_cfg(I8259_BASE, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* CPU reset routine /* CPU reset routine
put here to cause a reset of the entire iSBC system */ put here to cause a reset of the entire iSBC system */
t_stat SBC_reset (DEVICE *dptr) t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing iSBC-80/20\n"); if (onetime == 0) {
i8080_reset(NULL); SBC_config();
i8251_reset(NULL, I8251_BASE); multibus_cfg();
i8255_reset(NULL, I8255_BASE_0); onetime++;
i8255_reset(NULL, I8255_BASE_1); }
i8259_reset(NULL, I8259_BASE); i8080_reset(i8080_dev);
EPROM_reset(NULL, ROM_SIZE); i8251_reset(i8251_dev);
RAM_reset(NULL, RAM_BASE, RAM_SIZE); i8253_reset(i8253_dev);
i8255_reset(i8255_dev);
i8255_reset(i8255_dev);
i8259_reset(i8259_dev);
return SCPE_OK; return SCPE_OK;
} }
@ -84,11 +130,11 @@ uint8 get_mbyte(uint16 addr)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */ if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && (addr < (EPROM_unit.u3 + EPROM_unit.capac))) if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac)))
return EPROM_get_mbyte(addr); return EPROM_get_mbyte(addr);
} /* if local RAM handle it */ } /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */ if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && (addr < (RAM_unit.u3 + RAM_unit.capac))) if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac)))
return RAM_get_mbyte(addr); return RAM_get_mbyte(addr);
} /* otherwise, try the multibus */ } /* otherwise, try the multibus */
return multibus_get_mbyte(addr); return multibus_get_mbyte(addr);
@ -111,13 +157,13 @@ void put_mbyte(uint16 addr, uint8 val)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */ if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) { if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr); sim_printf("Write to R/O memory address %04X - ignored\n", addr);
return; return;
} }
} /* if local RAM handle it */ } /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */ if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && (addr <= (RAM_unit.u3 + RAM_unit.capac))) { if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val); RAM_put_mbyte(addr, val);
return; return;
} }
@ -133,4 +179,4 @@ void put_mword(uint16 addr, uint16 val)
put_mbyte(addr+1, val >> 8); put_mbyte(addr+1, val >> 8);
} }
/* end of iSBC80-20.c */ /* end of iSBC8020.c */

View file

@ -33,12 +33,14 @@ extern DEVICE i8080_dev;
extern REG i8080_reg[]; extern REG i8080_reg[];
extern DEVICE i8259_dev; extern DEVICE i8259_dev;
extern DEVICE i8251_dev; extern DEVICE i8251_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev; extern DEVICE i8255_dev;
extern DEVICE EPROM_dev; extern DEVICE EPROM_dev;
extern DEVICE RAM_dev; extern DEVICE RAM_dev;
extern DEVICE multibus_dev; extern DEVICE multibus_dev;
extern DEVICE isbc201_dev; extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev; extern DEVICE isbc202_dev;
extern DEVICE isbc208_dev;
extern DEVICE isbc064_dev; extern DEVICE isbc064_dev;
/* SCP data structures /* SCP data structures
@ -62,11 +64,13 @@ DEVICE *sim_devices[] = {
&RAM_dev, &RAM_dev,
&i8259_dev, &i8259_dev,
&i8251_dev, &i8251_dev,
&i8253_dev,
&i8255_dev, &i8255_dev,
&multibus_dev, &multibus_dev,
&isbc064_dev, &isbc064_dev,
&isbc201_dev, &isbc201_dev,
&isbc202_dev, &isbc202_dev,
&isbc208_dev,
NULL NULL
}; };

View file

@ -37,6 +37,10 @@
#define I8251_BASE 0xEC #define I8251_BASE 0xEC
#define I8251_NUM 1 #define I8251_NUM 1
/* set the base I/O address for the 8253/8254 */
#define I8253_BASE 0xDC
#define I8253_NUM 1
/* set the base I/O address for the 8255 */ /* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4 #define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8 #define I8255_BASE_1 0xE8
@ -48,43 +52,54 @@
/* set the base and size for the EPROM on the iSBC 80/20 */ /* set the base and size for the EPROM on the iSBC 80/20 */
#define ROM_BASE 0x0000 #define ROM_BASE 0x0000
#define ROM_SIZE 0x1000 #define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1 #define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the iSBC 80/20 */ /* set the base and size for the RAM on the iSBC 80/20 */
#define RAM_BASE 0x3C00 #define RAM_BASE 0x3000
#define RAM_SIZE 0x0400 #define RAM_SIZE 0x0FFF
#define RAM_DISABLE 1 #define RAM_DISABLE 1
/* set INTR for CPU */ /* set INTR for CPU */
#define INTR INT_1 #define INTR INT_2
//board definitions for the multibus //board definitions for the multibus
/* set the base I/O address for the iSBC 201 */ /* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78 #define SBC201_BASE 0x78
#define SBC201_INT INT_1 #define SBC201_INT INT_2
#define SBC201_NUM 0 #define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */ /* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78 #define SBC202_BASE 0x78
#define SBC202_INT INT_1 #define SBC202_INT INT_2
#define SBC202_NUM 1 #define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_2
#define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40
#define SBC208_INT INT_1 #define SBC208_INT INT_2
#define SBC208_NUM 0 #define SBC208_NUM 0
/* set the base for the zx-200a disk controller */ /* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78 #define ZX200A_BASE 0x78
#define ZX200A_INT INT_1 #define ZX200A_INT INT_2
#define ZX200A_NUM 0 #define ZX200A_NUM 0
/* set the base and size for the iSBC 064 */ /* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000 #define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000 #define SBC064_SIZE 0xFFFF
#define SBC064_NUM 1 #define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* multibus interrupt definitions */ /* multibus interrupt definitions */
#define INT_0 0x01 #define INT_0 0x01

View file

@ -37,6 +37,7 @@
/* function prototypes */ /* function prototypes */
t_stat SBC_config(void);
uint8 get_mbyte(uint16 addr); uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr); uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val); void put_mbyte(uint16 addr, uint8 val);
@ -53,39 +54,74 @@ extern int32 PCX; /* External view of PC */
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */ extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum; extern DEVICE *i8080_dev;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base); extern t_stat i8251_reset (DEVICE *dptr);
extern int32 i8253_devnum; extern uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
extern t_stat i8253_reset (DEVICE *dptr, uint16 base); extern uint8 i8251d(t_bool io, uint8 data, uint8 devnum);
extern int32 i8255_devnum; extern DEVICE *i8251_dev;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base); extern t_stat i8253_reset (DEVICE *dptr);
extern int32 i8259_devnum; extern uint8 i8253t0(t_bool io, uint8 data, uint8 devnum);
extern t_stat i8259_reset (DEVICE *dptr, uint16 base); extern uint8 i8253t1(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8253t2(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8253c(t_bool io, uint8 data, uint8 devnum);
extern DEVICE *i8253_dev;
extern t_stat i8255_reset (DEVICE *dptr);
extern uint8 i8255a(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8255b(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8255c(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8255s(t_bool io, uint8 data, uint8 devnum);
extern DEVICE *i8255_dev;
extern t_stat i8259_reset (DEVICE *dptr);
extern uint8 i8259a(t_bool io, uint8 data, uint8 devnum);
extern uint8 i8259b(t_bool io, uint8 data, uint8 devnum);
extern DEVICE *i8259_dev;
extern uint8 EPROM_get_mbyte(uint16 addr); extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit; extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size); extern t_stat EPROM_reset (DEVICE *dptr, uint16 base, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit; extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
// globals
int onetime = 0;
t_stat SBC_config(void)
{
sim_printf("Configuring iSBC-80/24 SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE, 0);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
i8259_cfg(I8259_BASE, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* SBC reset routine */ /* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr) t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing iSBC-80/24 SBC\n Onboard Devices:\n"); if (onetime == 0) {
i8080_reset (NULL); SBC_config();
i8251_devnum = 0; multibus_cfg();
i8251_reset (NULL, I8251_BASE); onetime++;
i8253_devnum = 0; }
i8253_reset (NULL, I8253_BASE); i8080_reset(i8080_dev);
i8255_devnum = 0; i8251_reset(i8251_dev);
i8255_reset (NULL, I8255_BASE_0); i8253_reset(i8253_dev);
i8255_reset (NULL, I8255_BASE_1); i8255_reset(i8255_dev);
i8259_devnum = 0; i8255_reset(i8255_dev);
i8259_reset (NULL, I8259_BASE); i8259_reset(i8259_dev);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -52,12 +52,13 @@
/* set the base and size for the EPROM on the iSBC 80/10 */ /* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_BASE 0x0000 #define ROM_BASE 0x0000
#define ROM_SIZE 0x1000 #define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1 #define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the iSBC 80/10 */ /* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0xF000 #define RAM_BASE 0xF000
#define RAM_SIZE 0x1000 #define RAM_SIZE 0x0FFF
#define RAM_DISABLE 0 #define RAM_DISABLE 0
/* set INTR for CPU on the iSBC 80/10 */ /* set INTR for CPU on the iSBC 80/10 */
@ -74,11 +75,24 @@
#define SBC202_INT INT_1 #define SBC202_INT INT_1
#define SBC202_NUM 1 #define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_2
#define SBC206_NUM 0
/* set the base for the zx-200a disk controller */ /* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78 #define ZX200A_BASE 0x78
#define ZX200A_INT INT_1 #define ZX200A_INT INT_1
#define ZX200A_NUM 0 #define ZX200A_NUM 0
/* set the base I/O address for the iSBX 218 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
#define I8272_BASE 0xF0
#define I8272_NUM 1
#define I8272_INT INT_1
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40
#define SBC208_INT INT_1 #define SBC208_INT INT_1
@ -86,9 +100,14 @@
/* set the base and size for the iSBC 064 */ /* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000 #define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000 #define SBC064_SIZE 0xFFFF
#define SBC064_NUM 1 #define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* multibus interrupt definitions */ /* multibus interrupt definitions */
#define INT_0 0x01 #define INT_0 0x01

View file

@ -37,6 +37,7 @@
/* function prototypes */ /* function prototypes */
t_stat SBC_config(void);
uint8 get_mbyte(uint16 addr); uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr); uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val); void put_mbyte(uint16 addr, uint8 val);
@ -46,44 +47,67 @@ t_stat SBC_reset (DEVICE *dptr);
/* external globals */ /* external globals */
extern uint8 i8255_C[4]; //port C byte I/O extern uint8 i8255_C[4]; //port C byte I/O
extern int32 PCX;
/* external function prototypes */ /* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */ extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 i8251_devnum; extern DEVICE *i8080_dev;
extern t_stat i8251_reset (DEVICE *dptr, uint16 base); extern t_stat i8251_reset (DEVICE *dptr);
extern int32 i8253_devnum; extern DEVICE *i8251_dev;
extern t_stat i8253_reset (DEVICE *dptr, uint16 base); extern t_stat i8253_reset (DEVICE *dptr);
extern int32 i8255_devnum; extern DEVICE *i8253_dev;
extern t_stat i8255_reset (DEVICE *dptr, uint16 base); extern t_stat i8255_reset (DEVICE *dptr);
extern int32 i8259_devnum; extern DEVICE *i8255_dev;
extern t_stat i8259_reset (DEVICE *dptr, uint16 base); extern t_stat i8259_reset (DEVICE *dptr);
extern DEVICE *i8259_dev;
extern uint8 EPROM_get_mbyte(uint16 addr); extern uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT EPROM_unit; extern UNIT EPROM_unit;
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size); extern t_stat EPROM_reset (DEVICE *dptr, uint16 base, uint16 size);
extern uint8 RAM_get_mbyte(uint16 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit; extern UNIT RAM_unit;
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size); extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
// globals
int onetime = 0;
t_stat SBC_config(void)
{
sim_printf("Configuring iSBC-80/30 SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE, 0);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE, 0);
i8259_cfg(I8259_BASE, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* SBC reset routine */ /* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr) t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing iSBC-80/24:\n"); if (onetime == 0) {
i8080_reset (NULL); SBC_config();
i8251_devnum = 0; multibus_cfg();
i8251_reset (NULL, I8251_BASE); onetime++;
i8253_devnum = 0; }
i8253_reset (NULL, I8253_BASE); i8080_reset(i8080_dev);
i8255_devnum = 0; i8251_reset(i8251_dev);
i8255_reset (NULL, I8255_BASE); i8253_reset(i8253_dev);
i8259_devnum = 0; i8255_reset(i8255_dev);
i8259_reset (NULL, I8259_BASE); i8259_reset(i8259_dev);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK; return SCPE_OK;
} }
@ -92,12 +116,12 @@ t_stat SBC_reset (DEVICE *dptr)
uint8 get_mbyte(uint16 addr) uint8 get_mbyte(uint16 addr)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */ if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) { if ((addr >= EPROM_unit.u3) && ((uint16)addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr); return EPROM_get_mbyte(addr);
} }
} /* if local RAM handle it */ } /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x10)) || (RAM_DISABLE == 0)) { /* RAM enabled */ if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) { if ((addr >= RAM_unit.u3) && ((uint16)addr < (RAM_unit.u3 + RAM_unit.capac))) {
return RAM_get_mbyte(addr); return RAM_get_mbyte(addr);
} }
@ -121,13 +145,13 @@ uint16 get_mword(uint16 addr)
void put_mbyte(uint16 addr, uint8 val) void put_mbyte(uint16 addr, uint8 val)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((ROM_DISABLE && (i8255_C[0] & 0x20)) || (ROM_DISABLE == 0)) { /* EPROM enabled */ if ((ROM_DISABLE && (i8255_C[0] & 0x80)) || (ROM_DISABLE == 0)) { /* EPROM enabled */
if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) { if ((addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr); sim_printf("Write to R/O memory address %04X from %04X - ignored\n", addr, PCX);
return; return;
} }
} /* if local RAM handle it */ } /* if local RAM handle it */
if ((RAM_DISABLE && (i8255_C[0] & 0x10)) || (RAM_DISABLE == 0)) { /* RAM enabled */ if ((RAM_DISABLE && (i8255_C[0] & 0x20)) || (RAM_DISABLE == 0)) { /* RAM enabled */
if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) { if ((addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val); RAM_put_mbyte(addr, val);
return; return;

View file

@ -55,12 +55,13 @@
/* set the base and size for the EPROM on the iSBC 80/30 */ /* set the base and size for the EPROM on the iSBC 80/30 */
#define ROM_BASE 0x0000 #define ROM_BASE 0x0000
#define ROM_SIZE 0x1000 #define ROM_SIZE 0x0FFF
#define ROM_DISABLE 1 #define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the iSBC 80/30 */ /* set the base and size for the RAM on the iSBC 80/30 */
#define RAM_BASE 0xF000 #define RAM_BASE 0xF000
#define RAM_SIZE 0x1000 #define RAM_SIZE 0x0FFF
#define RAM_DISABLE 0 #define RAM_DISABLE 0
/* set INTR for CPU on the iSBC 80/30 */ /* set INTR for CPU on the iSBC 80/30 */
@ -77,21 +78,31 @@
#define SBC202_INT INT_1 #define SBC202_INT INT_1
#define SBC202_NUM 1 #define SBC202_NUM 1
/* set the base for the zx-200a disk controller */ /* set the base I/O address for the iSBC 206 */
#define ZX200A_BASE 0x78 #define SBC206_BASE 0x68
#define ZX200A_INT INT_1 #define SBC206_INT INT_1
#define ZX200A_NUM 0 #define SBC206_NUM 0
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40
#define SBC208_INT INT_1 #define SBC208_INT INT_1
#define SBC208_NUM 0 #define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_1
#define ZX200A_NUM 0
/* set the base and size for the iSBC 064 */ /* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000 #define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000 #define SBC064_SIZE 0xFFFF
#define SBC064_NUM 1 #define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 0
/* multibus interrupt definitions */ /* multibus interrupt definitions */
#define INT_0 0x01 #define INT_0 0x01

View file

@ -0,0 +1,92 @@
/* 1sys80XX_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8253_dev;
extern DEVICE i8255_dev;
extern DEVICE i8259_dev;
extern DEVICE EPROM_dev;
extern DEVICE sbc_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel OEM SBC System";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8253_dev,
&i8255_dev,
&i8259_dev,
&sbc_dev,
&multibus_dev,
&isbc064_dev,
&isbc464_dev,
&isbc201_dev,
&isbc202_dev,
&isbc206_dev,
&zx200a_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error",
NULL
};

View file

@ -0,0 +1,150 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL)
//chip definitions for the iSBC-80/10
/* set the base I/O address and device count for the 8251s */
#define I8251_BASE 0xEC
#define I8251_NUM 1
/* set the base I/O address for the 8253/8254 */
#define I8253_BASE 0xDC
#define I8253_NUM 1
/* set the base I/O address and device count for the 8255s */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8259 */
#define I8259_BASE 0xDA
#define I8259_NUM 1
/* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000
#define ROM_DISABLE 1
#define EPROM_NUM 1
/* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
#define RAM_DISABLE 1
/* set INTR for CPU on the iSBC 80/10 */
#define INTR INT_1
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_1
#define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68
#define SBC206_INT INT_1
#define SBC206_NUM 1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78
#define ZX200A_INT INT_1
#define ZX200A_NUM 1
/* set the base and size for the iSBC 064 RAM*/
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000
#define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800
#define SBC464_SIZE 0x4800
#define SBC464_NUM 1
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupts definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */

View file

@ -383,6 +383,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDP10-KI", "PDP10-KI.vcproj
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-210", "imds-210.vcproj", "{1BCAB163-8041-48C3-9A5C-73649D69ED5C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-220", "imds-220.vcproj", "{2532CA88-7206-44F0-97EB-927F7E7820F2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-230", "imds-230.vcproj", "{C81A7EA9-8043-45F9-AFBB-578A6DB98174}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-800", "imds-800.vcproj", "{17ADE01C-7EDC-4F11-974D-52A9F90FE1D8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-810", "imds-810.vcproj", "{0720F164-692E-4C07-BE69-41C4302062E5}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -697,6 +707,26 @@ Global
{0BA63EC5-BD4F-44FB-AE89-7DD2C84CB1D9}.Debug|Win32.Build.0 = Debug|Win32 {0BA63EC5-BD4F-44FB-AE89-7DD2C84CB1D9}.Debug|Win32.Build.0 = Debug|Win32
{0BA63EC5-BD4F-44FB-AE89-7DD2C84CB1D9}.Release|Win32.ActiveCfg = Release|Win32 {0BA63EC5-BD4F-44FB-AE89-7DD2C84CB1D9}.Release|Win32.ActiveCfg = Release|Win32
{0BA63EC5-BD4F-44FB-AE89-7DD2C84CB1D9}.Release|Win32.Build.0 = Release|Win32 {0BA63EC5-BD4F-44FB-AE89-7DD2C84CB1D9}.Release|Win32.Build.0 = Release|Win32
{1BCAB163-8041-48C3-9A5C-73649D69ED5C}.Debug|Win32.ActiveCfg = Debug|Win32
{1BCAB163-8041-48C3-9A5C-73649D69ED5C}.Debug|Win32.Build.0 = Debug|Win32
{1BCAB163-8041-48C3-9A5C-73649D69ED5C}.Release|Win32.ActiveCfg = Release|Win32
{1BCAB163-8041-48C3-9A5C-73649D69ED5C}.Release|Win32.Build.0 = Release|Win32
{2532CA88-7206-44F0-97EB-927F7E7820F2}.Debug|Win32.ActiveCfg = Debug|Win32
{2532CA88-7206-44F0-97EB-927F7E7820F2}.Debug|Win32.Build.0 = Debug|Win32
{2532CA88-7206-44F0-97EB-927F7E7820F2}.Release|Win32.ActiveCfg = Release|Win32
{2532CA88-7206-44F0-97EB-927F7E7820F2}.Release|Win32.Build.0 = Release|Win32
{C81A7EA9-8043-45F9-AFBB-578A6DB98174}.Debug|Win32.ActiveCfg = Debug|Win32
{C81A7EA9-8043-45F9-AFBB-578A6DB98174}.Debug|Win32.Build.0 = Debug|Win32
{C81A7EA9-8043-45F9-AFBB-578A6DB98174}.Release|Win32.ActiveCfg = Release|Win32
{C81A7EA9-8043-45F9-AFBB-578A6DB98174}.Release|Win32.Build.0 = Release|Win32
{17ADE01C-7EDC-4F11-974D-52A9F90FE1D8}.Debug|Win32.ActiveCfg = Debug|Win32
{17ADE01C-7EDC-4F11-974D-52A9F90FE1D8}.Debug|Win32.Build.0 = Debug|Win32
{17ADE01C-7EDC-4F11-974D-52A9F90FE1D8}.Release|Win32.ActiveCfg = Release|Win32
{17ADE01C-7EDC-4F11-974D-52A9F90FE1D8}.Release|Win32.Build.0 = Release|Win32
{0720F164-692E-4C07-BE69-41C4302062E5}.Debug|Win32.ActiveCfg = Debug|Win32
{0720F164-692E-4C07-BE69-41C4302062E5}.Debug|Win32.Build.0 = Debug|Win32
{0720F164-692E-4C07-BE69-41C4302062E5}.Release|Win32.ActiveCfg = Release|Win32
{0720F164-692E-4C07-BE69-41C4302062E5}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -0,0 +1,377 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="imds-210"
ProjectGUID="{1BCAB163-8041-48C3-9A5C-73649D69ED5C}"
RootNamespace="imds-210"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Intel-Systems/imds-210/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib pcreposixstaticd.lib SDL2-StaticD.lib SDL2_ttf-StaticD.lib freetype2412MT_D.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../Intel-Systems/imds-210/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmt.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestatic.lib pcreposixstatic.lib SDL2-Static.lib SDL2_ttf-Static.lib freetype2412MT.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\Intel-Systems\common\i8080.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8251.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8253.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8255.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8259.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-210\imds-210_sys.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ioc-cont.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipb.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipbmultibus.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipc-cont.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\iram8.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc064.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc201.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc202.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\zx200a.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-210\system_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,381 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="imds-220"
ProjectGUID="{2532CA88-7206-44F0-97EB-927F7E7820F2}"
RootNamespace="imds-220"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Intel-Systems/imds-220/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib pcreposixstaticd.lib SDL2-StaticD.lib SDL2_ttf-StaticD.lib freetype2412MT_D.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../Intel-Systems/imds-220/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmt.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestatic.lib pcreposixstatic.lib SDL2-Static.lib SDL2_ttf-Static.lib freetype2412MT.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\Intel-Systems\common\i8080.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8251.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8253.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8255.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8259.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-220\imds-220_sys.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ioc-cont.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipb.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipbmultibus.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipc-cont.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\iram8.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc064.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc201.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc202.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc208.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\zx200a.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-220\system_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -228,7 +228,7 @@
> >
</File> </File>
<File <File
RelativePath="..\Intel-Systems\imds-225\ipc.c" RelativePath="..\Intel-Systems\common\ipc.c"
> >
</File> </File>
<File <File
@ -239,6 +239,10 @@
RelativePath="..\Intel-Systems\common\iram8.c" RelativePath="..\Intel-Systems\common\iram8.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc064.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\common\isbc201.c" RelativePath="..\Intel-Systems\common\isbc201.c"
> >
@ -247,6 +251,18 @@
RelativePath="..\Intel-Systems\common\isbc202.c" RelativePath="..\Intel-Systems\common\isbc202.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc208.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File <File
RelativePath="..\scp.c" RelativePath="..\scp.c"
> >

View file

@ -0,0 +1,381 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="imds-230"
ProjectGUID="{C81A7EA9-8043-45F9-AFBB-578A6DB98174}"
RootNamespace="imds-230"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Intel-Systems/imds-230/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib pcreposixstaticd.lib SDL2-StaticD.lib SDL2_ttf-StaticD.lib freetype2412MT_D.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../Intel-Systems/imds-230/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmt.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestatic.lib pcreposixstatic.lib SDL2-Static.lib SDL2_ttf-Static.lib freetype2412MT.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\Intel-Systems\common\i8080.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8251.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8253.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8255.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8259.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-230\imds-230_sys.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ioc-cont.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipb.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipbmultibus.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ipc-cont.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\iram8.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc064.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc201.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc202.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc208.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\zx200a.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-230\system_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,373 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="imds-800"
ProjectGUID="{17ADE01C-7EDC-4F11-974D-52A9F90FE1D8}"
RootNamespace="imds-800"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Intel-Systems/imds-800/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib pcreposixstaticd.lib SDL2-StaticD.lib SDL2_ttf-StaticD.lib freetype2412MT_D.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../Intel-Systems/imds-800/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmt.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestatic.lib pcreposixstatic.lib SDL2-Static.lib SDL2_ttf-Static.lib freetype2412MT.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\Intel-Systems\imds-800\cpu.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-800\front_panel.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i3214.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8080.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8251.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom1.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-800\imds-800_sys.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc064.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc201.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc202.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc208.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\m800multibus.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-800\monitor.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\zx200a.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-800\system_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,373 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="imds-810"
ProjectGUID="{0720F164-692E-4C07-BE69-41C4302062E5}"
RootNamespace="imds-810"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Intel-Systems/imds-810/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib pcreposixstaticd.lib SDL2-StaticD.lib SDL2_ttf-StaticD.lib freetype2412MT_D.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../Intel-Systems/imds-810/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2"
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"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libcmt.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestatic.lib pcreposixstatic.lib SDL2-Static.lib SDL2_ttf-Static.lib freetype2412MT.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\Intel-Systems\imds-810\cpu.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-810\front_panel.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i3214.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8080.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\i8251.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\ieprom1.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-810\imds-810_sys.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc064.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc201.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc202.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc208.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\m800multibus.c"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-810\monitor.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
<File
RelativePath="..\Intel-Systems\common\zx200a.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
<File
RelativePath="..\Intel-Systems\imds-810\system_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -223,10 +223,18 @@
RelativePath="..\Intel-Systems\common\isbc202.c" RelativePath="..\Intel-Systems\common\isbc202.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\common\isbc208.c" RelativePath="..\Intel-Systems\common\isbc208.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\isys8010\isbc8010.c" RelativePath="..\Intel-Systems\isys8010\isbc8010.c"
> >

View file

@ -199,6 +199,10 @@
RelativePath="..\Intel-Systems\common\i8251.c" RelativePath="..\Intel-Systems\common\i8251.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\i8253.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\common\i8255.c" RelativePath="..\Intel-Systems\common\i8255.c"
> >
@ -227,10 +231,18 @@
RelativePath="..\Intel-Systems\common\isbc202.c" RelativePath="..\Intel-Systems\common\isbc202.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\common\isbc208.c" RelativePath="..\Intel-Systems\common\isbc208.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\isys8020\isbc8020.c" RelativePath="..\Intel-Systems\isys8020\isbc8020.c"
> >

View file

@ -231,10 +231,18 @@
RelativePath="..\Intel-Systems\common\isbc202.c" RelativePath="..\Intel-Systems\common\isbc202.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\common\isbc208.c" RelativePath="..\Intel-Systems\common\isbc208.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\isys8024\isbc8024.c" RelativePath="..\Intel-Systems\isys8024\isbc8024.c"
> >

View file

@ -231,10 +231,18 @@
RelativePath="..\Intel-Systems\common\isbc202.c" RelativePath="..\Intel-Systems\common\isbc202.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc206.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\common\isbc208.c" RelativePath="..\Intel-Systems\common\isbc208.c"
> >
</File> </File>
<File
RelativePath="..\Intel-Systems\common\isbc464.c"
>
</File>
<File <File
RelativePath="..\Intel-Systems\isys8030\isbc8030.c" RelativePath="..\Intel-Systems\isys8030\isbc8030.c"
> >

142
makefile
View file

@ -1731,7 +1731,9 @@ ISYS8010 = ${ISYS8010C}/i8080.c ${ISYS8010D}/isys8010_sys.c \
${ISYS8010C}/ieprom.c ${ISYS8010C}/iram8.c \ ${ISYS8010C}/ieprom.c ${ISYS8010C}/iram8.c \
${ISYS8010C}/multibus.c ${ISYS8010D}/isbc8010.c \ ${ISYS8010C}/multibus.c ${ISYS8010D}/isbc8010.c \
${ISYS8010C}/isbc064.c ${ISYS8010C}/isbc202.c \ ${ISYS8010C}/isbc064.c ${ISYS8010C}/isbc202.c \
${ISYS8010C}/isbc201.c ${ISYS8010C}/zx200a.c ${ISYS8010C}/isbc201.c ${ISYS8010C}/zx200a.c \
${ISYS8010C}/isbc206.c ${ISYS8010C}/isbc464.c \
${ISYS8010C}/isbc208.c
ISYS8010_OPT = -I ${ISYS8010D} ISYS8010_OPT = -I ${ISYS8010D}
@ -1742,8 +1744,10 @@ ISYS8020 = ${ISYS8020C}/i8080.c ${ISYS8020D}/isys8020_sys.c \
${ISYS8020C}/ieprom.c ${ISYS8020C}/iram8.c \ ${ISYS8020C}/ieprom.c ${ISYS8020C}/iram8.c \
${ISYS8020C}/multibus.c ${ISYS8020D}/isbc8020.c \ ${ISYS8020C}/multibus.c ${ISYS8020D}/isbc8020.c \
${ISYS8020C}/isbc064.c ${ISYS8020C}/i8259.c \ ${ISYS8020C}/isbc064.c ${ISYS8020C}/i8259.c \
${ISYS8010C}/isbc202.c ${ISYS8010C}/isbc201.c \ ${ISYS8020C}/isbc202.c ${ISYS8020C}/isbc201.c \
${ISYS8010C}/zx200a.c ${ISYS8020C}/isbc206.c ${ISYS8020C}/isbc464.c \
${ISYS8020C}/zx200a.c ${ISYS8020C}/i8253.c \
${ISYS8020C}/isbc208.c
ISYS8020_OPT = -I ${ISYS8020D} ISYS8020_OPT = -I ${ISYS8020D}
@ -1755,8 +1759,9 @@ ISYS8024 = ${ISYS8024C}/i8080.c ${ISYS8024D}/isys8024_sys.c \
${ISYS8024C}/ieprom.c ${ISYS8024C}/iram8.c \ ${ISYS8024C}/ieprom.c ${ISYS8024C}/iram8.c \
${ISYS8024C}/multibus.c ${ISYS8024D}/isbc8024.c \ ${ISYS8024C}/multibus.c ${ISYS8024D}/isbc8024.c \
${ISYS8024C}/isbc064.c ${ISYS8024C}/isbc208.c \ ${ISYS8024C}/isbc064.c ${ISYS8024C}/isbc208.c \
${ISYS8010C}/isbc202.c ${ISYS8010C}/isbc201.c \ ${ISYS8024C}/isbc202.c ${ISYS8024C}/isbc201.c \
${ISYS8010C}/zx200a.c ${ISYS8024C}/isbc206.c ${ISYS8024C}/isbc464.c \
${ISYS8024C}/zx200a.c
ISYS8024_OPT = -I ${ISYS8024D} ISYS8024_OPT = -I ${ISYS8024D}
@ -1767,24 +1772,95 @@ ISYS8030 = ${ISYS8030C}/i8080.c ${ISYS8030D}/isys8030_sys.c \
${ISYS8030C}/i8259.c ${ISYS8030C}/i8253.c \ ${ISYS8030C}/i8259.c ${ISYS8030C}/i8253.c \
${ISYS8030C}/ieprom.c ${ISYS8030C}/iram8.c \ ${ISYS8030C}/ieprom.c ${ISYS8030C}/iram8.c \
${ISYS8030C}/multibus.c ${ISYS8030D}/isbc8030.c \ ${ISYS8030C}/multibus.c ${ISYS8030D}/isbc8030.c \
${ISYS8010C}/isbc202.c ${ISYS8010C}/isbc201.c \ ${ISYS8030C}/isbc202.c ${ISYS8030C}/isbc201.c \
${ISYS8030C}/isbc064.c ${ISYS8010C}/zx200a.c ${ISYS8030C}/isbc206.c ${ISYS8030C}/isbc464.c \
${ISYS8030C}/isbc064.c ${ISYS8030C}/zx200a.c \
${ISYS8010C}/isbc208.c
ISYS8030_OPT = -I ${ISYS8030D} ISYS8030_OPT = -I ${ISYS8030D}
IMDS-210D = Intel-Systems/imds-210
IMDS-210C = Intel-Systems/common
IMDS-210 = ${IMDS-210C}/i8080.c ${IMDS-210D}/imds-210_sys.c \
${IMDS-210C}/i8251.c ${IMDS-210C}/i8255.c \
${IMDS-210C}/i8259.c ${IMDS-210C}/i8253.c \
${IMDS-210C}/ieprom.c ${IMDS-210C}/iram8.c \
${IMDS-210C}/ipbmultibus.c ${IMDS-210C}/ipb.c \
${IMDS-210C}/ipc-cont.c ${IMDS-210C}/ioc-cont.c \
${IMDS-210C}/isbc202.c ${IMDS-210C}/isbc201.c \
${IMDS-210C}/isbc206.c ${IMDS-210C}/isbc464.c \
${IMDS-210C}/zx200a.c ${IMDS-210C}/isbc064.c
IMDS-210_OPT = -I ${IMDS-210D}
IMDS-220D = Intel-Systems/imds-220
IMDS-220C = Intel-Systems/common
IMDS-220 = ${IMDS-220C}/i8080.c ${IMDS-220D}/imds-220_sys.c \
${IMDS-220C}/i8251.c ${IMDS-220C}/i8255.c \
${IMDS-220C}/i8259.c ${IMDS-220C}/i8253.c \
${IMDS-220C}/ieprom.c ${IMDS-220C}/iram8.c \
${IMDS-220C}/ipbmultibus.c ${IMDS-220C}/ipb.c \
${IMDS-220C}/ipc-cont.c ${IMDS-220C}/ioc-cont.c \
${IMDS-220C}/isbc202.c ${IMDS-220C}/isbc201.c \
${IMDS-220C}/isbc206.c ${IMDS-220C}/isbc464.c \
${IMDS-220C}/zx200a.c ${IMDS-220C}/isbc064.c
IMDS-220_OPT = -I ${IMDS-220D}
IMDS-225D = Intel-Systems/imds-225 IMDS-225D = Intel-Systems/imds-225
IMDS-225C = Intel-Systems/common IMDS-225C = Intel-Systems/common
IMDS-225 = ${IMDS-225C}/i8080.c ${IMDS-225D}/imds-225_sys.c \ IMDS-225 = ${IMDS-225C}/i8080.c ${IMDS-225D}/imds-225_sys.c \
${IMDS-225C}/i8251.c ${IMDS-225C}/i8255.c \ ${IMDS-225C}/i8251.c ${IMDS-225C}/i8255.c \
${IMDS-225C}/i8259.c ${IMDS-225C}/i8253.c \ ${IMDS-225C}/i8259.c ${IMDS-225C}/i8253.c \
${IMDS-225C}/ieprom.c ${IMDS-225C}/iram8.c \ ${IMDS-225C}/ieprom.c ${IMDS-225C}/iram8.c \
${IMDS-225C}/ipcmultibus.c ${IMDS-225D}/ipc.c \ ${IMDS-225C}/ipcmultibus.c ${IMDS-225C}/ipc.c \
${IMDS-225C}/ipc-cont.c ${IMDS-225C}/ioc-cont.c \ ${IMDS-225C}/ipc-cont.c ${IMDS-225C}/ioc-cont.c \
${IMDS-225C}/isbc202.c ${IMDS-225C}/isbc201.c \ ${IMDS-225C}/isbc202.c ${IMDS-225C}/isbc201.c \
${IMDS-225C}/zx200a.c ${IMDS-225C}/zx200a.c ${IMDS-225C}/isbc464.c \
${IMDS-225C}/isbc206.c
IMDS-225_OPT = -I ${IMDS-225D} IMDS-225_OPT = -I ${IMDS-225D}
IMDS-230D = Intel-Systems/imds-230
IMDS-230C = Intel-Systems/common
IMDS-230 = ${IMDS-230C}/i8080.c ${IMDS-230D}/imds-230_sys.c \
${IMDS-230C}/i8251.c ${IMDS-230C}/i8255.c \
${IMDS-230C}/i8259.c ${IMDS-230C}/i8253.c \
${IMDS-230C}/ieprom.c ${IMDS-230C}/iram8.c \
${IMDS-230C}/ipbmultibus.c ${IMDS-230C}/ipb.c \
${IMDS-230C}/ipc-cont.c ${IMDS-230C}/ioc-cont.c \
${IMDS-230C}/isbc202.c ${IMDS-230C}/isbc201.c \
${IMDS-230C}/isbc206.c ${IMDS-230C}/isbc464.c \
${IMDS-230C}/zx200a.c ${IMDS-230C}/isbc064.c
IMDS-230_OPT = -I ${IMDS-230D}
IMDS-800D = Intel-Systems/imds-800
IMDS-800C = Intel-Systems/common
IMDS-800 = ${IMDS-800C}/i8080.c ${IMDS-800D}/imds-800_sys.c \
${IMDS-800D}/cpu.c ${IMDS-800D}/front_panel.c \
${IMDS-800D}/monitor.c ${IMDS-800C}/ieprom1.c \
${IMDS-800C}/i8251.c ${IMDS-800C}/ieprom.c \
${IMDS-800C}/m800multibus.c ${IMDS-800C}/isbc064.c \
${IMDS-800C}/isbc202.c ${IMDS-800C}/isbc201.c \
${IMDS-800C}/zx200a.c ${IMDS-800C}/isbc464.c \
${IMDS-800C}/isbc206.c ${IMDS-800C}/i3214.c
IMDS-800_OPT = -I ${IMDS-800D}
IMDS-810D = Intel-Systems/imds-810
IMDS-810C = Intel-Systems/common
IMDS-810 = ${IMDS-800C}/i8080.c ${IMDS-810D}/imds-810_sys.c \
${IMDS-810D}/cpu.c ${IMDS-810D}/front_panel.c \
${IMDS-810D}/monitor.c ${IMDS-810C}/ieprom1.c \
${IMDS-810C}/i8251.c ${IMDS-810C}/ieprom.c \
${IMDS-810C}/m800multibus.c ${IMDS-810C}/isbc064.c \
${IMDS-810C}/isbc202.c ${IMDS-810C}/isbc201.c \
${IMDS-810C}/zx200a.c ${IMDS-810C}/isbc464.c \
${IMDS-810C}/isbc206.c ${IMDS-800C}/i3214.c
IMDS-810_OPT = -I ${IMDS-810D}
IBMPCD = Intel-Systems/ibmpc IBMPCD = Intel-Systems/ibmpc
IBMPCC = Intel-Systems/common IBMPCC = Intel-Systems/common
IBMPC = ${IBMPCC}/i8255.c ${IBMPCD}/ibmpc.c \ IBMPC = ${IBMPCC}/i8255.c ${IBMPCD}/ibmpc.c \
@ -2022,7 +2098,8 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \ nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \ i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \ swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \
isys8030 isys8024 imds-225 scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \ isys8030 isys8024 imds-210 imds-220 imds-225 imds-230 imds-800 imds-810 \
scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \
sigma uc15 pdp10-ka pdp10-ki pdp6 sigma uc15 pdp10-ka pdp10-ki pdp6
all : ${ALL} all : ${ALL}
@ -2516,6 +2593,24 @@ ifneq (,$(call find_test,${ISYS8030D},isys8030))
$@ $(call find_test,${ISYS8030D},isys8030) $(TEST_ARG) $@ $(call find_test,${ISYS8030D},isys8030) $(TEST_ARG)
endif endif
imds-210: ${BIN}imds-210${EXE}
${BIN}imds-210${EXE} : ${IMDS-210} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${IMDS-210} ${SIM} ${IMDS-210_OPT} $(CC_OUTSPEC) ${LDFLAGS}
ifneq (,$(call find_test,${IMDS-210D},imds-210))
$@ $(call find_test,${IMDS-210D},imds-210) $(TEST_ARG)
endif
imds-220: ${BIN}imds-220${EXE}
${BIN}imds-220${EXE} : ${IMDS-220} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${IMDS-220} ${SIM} ${IMDS-220_OPT} $(CC_OUTSPEC) ${LDFLAGS}
ifneq (,$(call find_test,${IMDS-220D},imds-220))
$@ $(call find_test,${IMDS-220D},imds-220) $(TEST_ARG)
endif
imds-225: ${BIN}imds-225${EXE} imds-225: ${BIN}imds-225${EXE}
${BIN}imds-225${EXE} : ${IMDS-225} ${SIM} ${BUILD_ROMS} ${BIN}imds-225${EXE} : ${IMDS-225} ${SIM} ${BUILD_ROMS}
@ -2525,6 +2620,33 @@ ifneq (,$(call find_test,${IMDS-225D},imds-225))
$@ $(call find_test,${IMDS-225D},imds-225) $(TEST_ARG) $@ $(call find_test,${IMDS-225D},imds-225) $(TEST_ARG)
endif endif
imds-230: ${BIN}imds-230${EXE}
${BIN}imds-230${EXE} : ${IMDS-230} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${IMDS-230} ${SIM} ${IMDS-230_OPT} $(CC_OUTSPEC) ${LDFLAGS}
ifneq (,$(call find_test,${IMDS-230D},imds-230))
$@ $(call find_test,${IMDS-230D},imds-230) $(TEST_ARG)
endif
imds-800: ${BIN}imds-800${EXE}
${BIN}imds-800${EXE} : ${IMDS-800} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${IMDS-800} ${SIM} ${IMDS-800_OPT} $(CC_OUTSPEC) ${LDFLAGS}
ifneq (,$(call find_test,${IMDS-800D},imds-800))
$@ $(call find_test,${IMDS-800D},imds-800) $(TEST_ARG)
endif
imds-810: ${BIN}imds-810${EXE}
${BIN}imds-810${EXE} : ${IMDS-810} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${IMDS-810} ${SIM} ${IMDS-810_OPT} $(CC_OUTSPEC) ${LDFLAGS}
ifneq (,$(call find_test,${IMDS-810D},imds-810))
$@ $(call find_test,${IMDS-810D},imds-810) $(TEST_ARG)
endif
ibmpc: ${BIN}ibmpc${EXE} ibmpc: ${BIN}ibmpc${EXE}
${BIN}ibmpc${EXE} : ${IBMPC} ${SIM} ${BUILD_ROMS} ${BIN}ibmpc${EXE} : ${IBMPC} ${SIM} ${BUILD_ROMS}