ISYS8010, ISYS8020: Cleanup Build issues for gcc and clang and g++ and clang++

Corrected declaration sizes to match for consistency across different modules.
This commit is contained in:
Bill Beech 2016-05-23 14:28:19 -07:00
parent 9d2b7ee968
commit cbdcaec162
25 changed files with 1224 additions and 2117 deletions

View file

@ -165,7 +165,7 @@ uint32 HL = 0; /* HL register pair */
uint32 SP = 0; /* Stack pointer */ uint32 SP = 0; /* Stack pointer */
uint32 saved_PC = 0; /* program counter */ uint32 saved_PC = 0; /* program counter */
uint32 IM = 0; /* Interrupt Mask Register */ uint32 IM = 0; /* Interrupt Mask Register */
uint32 xack = 0; /* XACK signal */ uint8 xack = 0; /* XACK signal */
uint32 int_req = 0; /* Interrupt request */ uint32 int_req = 0; /* Interrupt request */
int32 PCX; /* External view of PC */ int32 PCX; /* External view of PC */
@ -197,16 +197,17 @@ t_stat i8080_reset (DEVICE *dptr);
/* external function prototypes */ /* external function prototypes */
extern t_stat i8080_reset (DEVICE *dptr); extern t_stat i8080_reset (DEVICE *dptr);
extern int32 get_mbyte(int32 addr); extern uint8 get_mbyte(uint16 addr);
extern int32 get_mword(int32 addr); extern uint16 get_mword(uint16 addr);
extern void put_mbyte(int32 addr, int32 val); extern void put_mbyte(uint16 addr, uint8 val);
extern void put_mword(int32 addr, int32 val); 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 {
int32 (*routine)(int32, int32); uint8 (*routine)(t_bool, uint8, uint8);
uint8 devnum;
}; };
/* This is the I/O configuration table. There are 256 possible /* This is the I/O configuration table. There are 256 possible
@ -889,13 +890,15 @@ int32 sim_instr (void)
case 0xDB: /* IN */ case 0xDB: /* IN */
DAR = fetch_byte(1); DAR = fetch_byte(1);
A = dev_table[DAR].routine(0, 0); A = dev_table[DAR].routine(0, 0, dev_table[DAR].devnum);
A &= BYTE_R; A &= BYTE_R;
// sim_printf("\n%04X\tIN\t%02X\t;devnum=%d", PC - 1, DAR, dev_table[DAR].devnum);
break; break;
case 0xD3: /* OUT */ case 0xD3: /* OUT */
DAR = fetch_byte(1); DAR = fetch_byte(1);
dev_table[DAR].routine(1, A); dev_table[DAR].routine(1, A, dev_table[DAR].devnum);
// sim_printf("\n%04X\tOUT\t%02X\t;devnum=%d", PC - 1, DAR, dev_table[DAR].devnum);
break; break;
default: /* undefined opcode */ default: /* undefined opcode */

View file

@ -119,16 +119,18 @@
#define TXE 0x04 #define TXE 0x04
#define SD 0x40 #define SD 0x40
extern int32 reg_dev(int32 (*routine)(int32, int32), int32 port); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint8);
/* function prototypes */ /* function prototypes */
t_stat i8251_svc (UNIT *uptr); t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, int32 base); t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
int32 i8251s(int32 io, int32 data); uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
int32 i8251d(int32 io, int32 data); uint8 i8251d(t_bool io, uint8 data, uint8 devnum);
void i8251_reset1(void); void i8251_reset1(uint8 devnum);
/* i8251 Standard I/O Data Structures */ /* i8251 Standard I/O Data Structures */
/* up to 1 i8251 devices */
UNIT i8251_unit = { UNIT i8251_unit = {
UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT
@ -142,20 +144,33 @@ REG i8251_reg[] = {
{ NULL } { NULL }
}; };
DEBTAB i8251_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
MTAB i8251_mod[] = { MTAB i8251_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL }, { UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL }, { UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 } { 0 }
}; };
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8251_dev = { DEVICE i8251_dev = {
"8251", //name "8251", //name
&i8251_unit, //units &i8251_unit, //units
i8251_reg, //registers i8251_reg, //registers
i8251_mod, //modifiers i8251_mod, //modifiers
1, //numunits 1, //numunits
10, //aradix 16, //aradix
31, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -169,7 +184,7 @@ DEVICE i8251_dev = {
NULL, //ctxt NULL, //ctxt
0, //flags 0, //flags
0, //dctrl 0, //dctrl
NULL, //debflags i8251_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL //lname
}; };
@ -196,14 +211,18 @@ t_stat i8251_svc (UNIT *uptr)
/* Reset routine */ /* Reset routine */
t_stat i8251_reset (DEVICE *dptr, int32 base) t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum)
{ {
reg_dev(i8251d, base); if (devnum >= I8251_NUM) {
reg_dev(i8251s, base + 1); sim_printf("8251_reset: Illegal Device Number %d\n", devnum);
reg_dev(i8251d, base + 2); return 0;
reg_dev(i8251s, base + 3); }
i8251_reset1(); reg_dev(i8251d, base, devnum);
sim_printf(" 8251: Registered at %02X\n", base); reg_dev(i8251s, base + 1, devnum);
reg_dev(i8251d, base + 2, devnum);
reg_dev(i8251s, base + 3, devnum);
i8251_reset1(devnum);
sim_printf(" 8251-%d: Registered at %04X\n", devnum, base);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */ sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} }
@ -212,28 +231,36 @@ t_stat i8251_reset (DEVICE *dptr, int32 base)
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
int32 i8251s(int32 io, int32 data) uint8 i8251s(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8251_NUM) {
sim_printf("8251s: Illegal Device Number %d\n", devnum);
return 0;
}
// sim_printf("\nio=%d data=%04X\n", io, data); // 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.u3;
} else { /* write status port */ } else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */ if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data; i8251_unit.u5 = data;
sim_printf("8251: Command Instruction=%02X\n", data); sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */ if (data & SD) /* reset port! */
i8251_reset1(); i8251_reset1(devnum);
} else { /* set mode */ } else { /* set mode */
i8251_unit.u4 = data; i8251_unit.u4 = data;
sim_printf("8251: Mode Instruction=%02X\n", data); sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */ i8251_unit.u6 = 1; /* set cmd received */
} }
return (0); return (0);
} }
} }
int32 i8251d(int32 io, int32 data) uint8 i8251d(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8251_NUM) {
sim_printf("8251d: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR; i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf); return (i8251_unit.buf);
@ -243,7 +270,7 @@ int32 i8251d(int32 io, int32 data)
return 0; return 0;
} }
void i8251_reset1(void) void i8251_reset1(uint8 devnum)
{ {
i8251_unit.u3 = TXR + TXE; /* status */ i8251_unit.u3 = TXR + TXE; /* status */
i8251_unit.u4 = 0; /* mode instruction */ i8251_unit.u4 = 0; /* mode instruction */
@ -251,7 +278,7 @@ void i8251_reset1(void)
i8251_unit.u6 = 0; i8251_unit.u6 = 0;
i8251_unit.buf = 0; i8251_unit.buf = 0;
i8251_unit.pos = 0; i8251_unit.pos = 0;
sim_printf(" 8251: Reset\n"); sim_printf(" 8251-%d: Reset\n", devnum);
} }
/* end of i8251.c */ /* end of i8251.c */

View file

@ -76,38 +76,23 @@
*/ */
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define i8255_DEV 4 /* number of devices */
/* function prototypes */ /* function prototypes */
int32 i8255s0(int32 io, int32 data); /* i8255 0 */ uint8 i8255s0(t_bool io, uint8 data, uint8 devnum); /* i8255*/
int32 i8255a0(int32 io, int32 data); uint8 i8255a0(t_bool io, uint8 data, uint8 devnum);
int32 i8255b0(int32 io, int32 data); uint8 i8255b0(t_bool io, uint8 data, uint8 devnum);
int32 i8255c0(int32 io, int32 data); uint8 i8255c0(t_bool io, uint8 data, uint8 devnum);
int32 i8255s1(int32 io, int32 data); /* i8255 1 */ t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum);
int32 i8255a1(int32 io, int32 data);
int32 i8255b1(int32 io, int32 data);
int32 i8255c1(int32 io, int32 data);
int32 i8255s2(int32 io, int32 data); /* i8255 2 */
int32 i8255a2(int32 io, int32 data);
int32 i8255b2(int32 io, int32 data);
int32 i8255c2(int32 io, int32 data);
int32 i8255s3(int32 io, int32 data); /* i8255 3 */
int32 i8255a3(int32 io, int32 data);
int32 i8255b3(int32 io, int32 data);
int32 i8255c3(int32 io, int32 data);
t_stat i8255_reset (DEVICE *dptr, int32 base);
/* external function prototypes */ /* external function prototypes */
extern int32 reg_dev(int32 (*routine)(int32, int32), int32 port); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16 port, uint8 devnum);
/* globals */ /* globals */
int32 i8255_cnt = 0;
uint8 i8255_base[i8255_DEV];
/* i8255 Standard I/O Data Structures */ /* i8255 Standard I/O Data Structures */
/* up to 4 i8255 devices */
UNIT i8255_unit[] = { UNIT i8255_unit[] = {
{ UDATA (0, 0, 0) }, /* i8255 0 */ { UDATA (0, 0, 0) }, /* i8255 0 */
@ -116,17 +101,6 @@ UNIT i8255_unit[] = {
{ UDATA (0, 0, 0) } /* i8255 3 */ { UDATA (0, 0, 0) } /* i8255 3 */
}; };
DEBTAB i8255_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
REG i8255_reg[] = { REG i8255_reg[] = {
{ HRDATA (CONTROL0, i8255_unit[0].u3, 8) }, /* i8255 0 */ { HRDATA (CONTROL0, i8255_unit[0].u3, 8) }, /* i8255 0 */
{ HRDATA (PORTA0, i8255_unit[0].u4, 8) }, { HRDATA (PORTA0, i8255_unit[0].u4, 8) },
@ -147,6 +121,19 @@ REG i8255_reg[] = {
{ NULL } { NULL }
}; };
DEBTAB i8255_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 i8255_dev = { DEVICE i8255_dev = {
"8255", //name "8255", //name
i8255_unit, //units i8255_unit, //units
@ -154,7 +141,7 @@ DEVICE i8255_dev = {
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
32, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -177,296 +164,99 @@ DEVICE i8255_dev = {
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* i8255 0 functions */ /* i8255 functions */
int32 i8255s0(int32 io, int32 data) uint8 i8255s(t_bool io, uint8 data, uint8 devnum)
{ {
int32 bit; uint8 bit;
if (devnum >= I8255_NUM) {
sim_printf("8255s: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read status port */ if (io == 0) { /* read status port */
return i8255_unit[0].u3; return i8255_unit[devnum].u3;
} else { /* write status port */ } else { /* write status port */
if (data & 0x80) { /* mode instruction */ if (data & 0x80) { /* mode instruction */
i8255_unit[0].u3 = data; i8255_unit[0].u3 = data;
sim_printf("8255-0: Mode Instruction=%02X\n", data); 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 */
bit = (data & 0x0E) >> 1; /* get bit number */ bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */ if (data & 0x01) { /* set bit */
i8255_unit[0].u6 |= (0x01 << bit); i8255_unit[devnum].u6 |= (0x01 << bit);
} else { /* reset bit */ } else { /* reset bit */
i8255_unit[0].u6 &= ~(0x01 << bit); i8255_unit[devnum].u6 &= ~(0x01 << bit);
} }
} }
} }
return 0; return 0;
} }
int32 i8255a0(int32 io, int32 data) uint8 i8255a(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8255_NUM) {
sim_printf("8255a: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return (i8255_unit[0].u4); return (i8255_unit[devnum].u4);
} else { /* write data port */ } else { /* write data port */
i8255_unit[0].u4 = data; i8255_unit[devnum].u4 = data;
sim_printf("8255-0: Port A = %02X\n", data); sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
} }
return 0; return 0;
} }
int32 i8255b0(int32 io, int32 data) uint8 i8255b(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8255_NUM) {
sim_printf("8255b: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return (i8255_unit[0].u5); return (i8255_unit[devnum].u5);
} else { /* write data port */ } else { /* write data port */
i8255_unit[0].u5 = data; i8255_unit[devnum].u5 = data;
sim_printf("8255-0: Port B = %02X\n", data); sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
} }
return 0; return 0;
} }
int32 i8255c0(int32 io, int32 data) uint8 i8255c(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8255_NUM) {
sim_printf("8255c: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
return (i8255_unit[0].u6); return (i8255_unit[devnum].u6);
} else { /* write data port */ } else { /* write data port */
i8255_unit[0].u6 = data; i8255_unit[devnum].u6 = data;
sim_printf("8255-0: Port C = %02X\n", data); sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
}
return 0;
}
/* i8255 1 functions */
int32 i8255s1(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[1].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[1].u3 = data;
sim_printf("8255-1: Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[1].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[1].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[1].u4);
} else { /* write data port */
i8255_unit[1].u4 = data;
sim_printf("8255-1: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[1].u5);
} else { /* write data port */
i8255_unit[1].u5 = data;
sim_printf("8255-1: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[1].u6);
} else { /* write data port */
i8255_unit[1].u6 = data;
sim_printf("8255-1: Port C = %02X\n", data);
}
return 0;
}
/* i8255 2 functions */
int32 i8255s2(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[2].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[2].u3 = data;
sim_printf("8255-2: Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[2].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[2].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a2(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[2].u4);
} else { /* write data port */
i8255_unit[2].u4 = data;
sim_printf("8255-2: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b2(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[2].u5);
} else { /* write data port */
i8255_unit[2].u5 = data;
sim_printf("8255-2: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c2(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[2].u6);
} else { /* write data port */
i8255_unit[2].u6 = data;
sim_printf("8255-2: Port C = %02X\n", data);
}
return 0;
}
/* i8255 3 functions */
int32 i8255s3(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[3].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[3].u3 = data;
sim_printf("8255-3: Mode Instruction=%02X\n", data);
if (data & 0x64)
sim_printf("\n Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[3].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[3].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a3(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[3].u4);
} else { /* write data port */
i8255_unit[3].u4 = data;
sim_printf("8255-3: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b3(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[3].u5);
} else { /* write data port */
i8255_unit[3].u5 = data;
sim_printf("8255-3: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c3(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[3].u6);
} else { /* write data port */
i8255_unit[3].u6 = data;
sim_printf("8255-3: Port C = %02X\n", data);
} }
return 0; return 0;
} }
/* Reset routine */ /* Reset routine */
t_stat i8255_reset (DEVICE *dptr, int32 base) t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum)
{ {
switch (i8255_cnt) { if (devnum >= I8255_NUM) {
case 0: sim_printf("8255_reset: Illegal Device Number %d\n", devnum);
reg_dev(i8255a0, base); return 0;
reg_dev(i8255b0, base + 1);
reg_dev(i8255c0, base + 2);
reg_dev(i8255s0, base + 3);
i8255_unit[0].u3 = 0x9B; /* control */
i8255_unit[0].u4 = 0xFF; /* Port A */
i8255_unit[0].u5 = 0xFF; /* Port B */
i8255_unit[0].u6 = 0xFF; /* Port C */
sim_printf(" 8255-0: Reset\n");
break;
case 1:
reg_dev(i8255a1, base);
reg_dev(i8255b1, base + 1);
reg_dev(i8255c1, base + 2);
reg_dev(i8255s1, base + 3);
i8255_unit[1].u3 = 0x9B; /* control */
i8255_unit[1].u4 = 0xFF; /* Port A */
i8255_unit[1].u5 = 0xFF; /* Port B */
i8255_unit[1].u6 = 0xFF; /* Port C */
sim_printf(" 8255-1: Reset\n");
break;
case 2:
reg_dev(i8255a2, base);
reg_dev(i8255b2, base + 1);
reg_dev(i8255c2, base + 2);
reg_dev(i8255s2, base + 3);
i8255_unit[2].u3 = 0x9B; /* control */
i8255_unit[2].u4 = 0xFF; /* Port A */
i8255_unit[2].u5 = 0xFF; /* Port B */
i8255_unit[2].u6 = 0xFF; /* Port C */
sim_printf(" 8255-2: Reset\n");
break;
case 3:
reg_dev(i8255a3, base);
reg_dev(i8255b3, base + 1);
reg_dev(i8255c3, base + 2);
reg_dev(i8255s3, base + 3);
i8255_unit[3].u3 = 0x9B; /* control */
i8255_unit[3].u4 = 0xFF; /* Port A */
i8255_unit[3].u5 = 0xFF; /* Port B */
i8255_unit[3].u6 = 0xFF; /* Port C */
sim_printf(" 8255-3: Reset\n");
break;
default:
sim_printf(" 8255: Bad device\n");
} }
sim_printf(" 8255-%d: Registered at %02X\n", i8255_cnt, base); reg_dev(i8255a, base, devnum);
i8255_cnt++; reg_dev(i8255b, base + 1, devnum);
reg_dev(i8255c, base + 2, devnum);
reg_dev(i8255s, base + 3, devnum);
i8255_unit[devnum].u3 = 0x9B; /* control */
i8255_unit[devnum].u4 = 0xFF; /* Port A */
i8255_unit[devnum].u5 = 0xFF; /* Port B */
i8255_unit[devnum].u6 = 0xFF; /* Port C */
sim_printf(" 8255-%d: Reset\n", devnum);
sim_printf(" 8255-%d: Registered at %04X\n", devnum, base);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -34,41 +34,48 @@
*/ */
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define i8259_DEV 2 /* number of devices */
/* function prototypes */ /* function prototypes */
int32 i8259a0(int32 io, int32 data); uint8 i8259a(t_bool io, uint8 data, uint8 devnum);
int32 i8259b0(int32 io, int32 data); uint8 i8259b(t_bool io, uint8 data, uint8 devnum);
int32 i8259a1(int32 io, int32 data); void i8259_dump(uint8 devnum);
int32 i8259b1(int32 io, int32 data); t_stat i8259_reset (DEVICE *dptr, uint16 base, uint8 devnum);
void i8259_dump(int32 dev);
t_stat i8259_reset (DEVICE *dptr, int32 base);
/* external function prototypes */ /* external function prototypes */
extern int32 reg_dev(int32 (*routine)(int32, int32), int32 port); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16 port, uint8 devnum);
/* globals */ /* globals */
int32 i8259_cnt = 0; uint8 i8259_base[I8259_NUM];
uint8 i8259_base[i8259_DEV]; uint8 i8259_icw1[I8259_NUM];
uint8 i8259_icw1[i8259_DEV]; uint8 i8259_icw2[I8259_NUM];
uint8 i8259_icw2[i8259_DEV]; uint8 i8259_icw3[I8259_NUM];
uint8 i8259_icw3[i8259_DEV]; uint8 i8259_icw4[I8259_NUM];
uint8 i8259_icw4[i8259_DEV]; uint8 i8259_ocw1[I8259_NUM];
uint8 i8259_ocw1[i8259_DEV]; uint8 i8259_ocw2[I8259_NUM];
uint8 i8259_ocw2[i8259_DEV]; uint8 i8259_ocw3[I8259_NUM];
uint8 i8259_ocw3[i8259_DEV]; uint8 icw_num0 = 1, icw_num1 = 1;
int32 icw_num0 = 1, icw_num1 = 1;
/* i8255 Standard I/O Data Structures */ /* i8255 Standard I/O Data Structures */
/* up to 2 i8259 devices */
UNIT i8259_unit[] = { UNIT i8259_unit[] = {
{ UDATA (0, 0, 0) }, /* i8259 0 */ { UDATA (0, 0, 0) }, /* i8259 0 */
{ UDATA (0, 0, 0) } /* i8259 1 */ { UDATA (0, 0, 0) } /* i8259 1 */
}; };
REG i8259_reg[] = {
{ HRDATA (IRR0, i8259_unit[0].u3, 8) }, /* i8259 0 */
{ HRDATA (ISR0, i8259_unit[0].u4, 8) },
{ HRDATA (IMR0, i8259_unit[0].u5, 8) },
{ HRDATA (IRR1, i8259_unit[1].u3, 8) }, /* i8259 0 */
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
{ NULL }
};
DEBTAB i8259_debug[] = { DEBTAB i8259_debug[] = {
{ "ALL", DEBUG_all }, { "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow }, { "FLOW", DEBUG_flow },
@ -80,15 +87,7 @@ DEBTAB i8259_debug[] = {
{ NULL } { NULL }
}; };
REG i8259_reg[] = { /* address width is set to 16 bits to use devices in 8086/8088 implementations */
{ HRDATA (IRR0, i8259_unit[0].u3, 8) }, /* i8259 0 */
{ HRDATA (ISR0, i8259_unit[0].u4, 8) },
{ HRDATA (IMR0, i8259_unit[0].u5, 8) },
{ HRDATA (IRR1, i8259_unit[1].u3, 8) }, /* i8259 0 */
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
{ NULL }
};
DEVICE i8259_dev = { DEVICE i8259_dev = {
"8259", //name "8259", //name
@ -97,7 +96,7 @@ DEVICE i8259_dev = {
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
32, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -120,190 +119,116 @@ DEVICE i8259_dev = {
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* i8259 0 functions */ /* i8259 functions */
int32 i8259a0(int32 io, int32 data) uint8 i8259a(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8259_NUM) {
sim_printf("8259a: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if ((i8259_ocw3[0] & 0x03) == 0x02) if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[0].u3); /* IRR */ return (i8259_unit[devnum].u3); /* IRR */
if ((i8259_ocw3[0] & 0x03) == 0x03) if ((i8259_ocw3[devnum] & 0x03) == 0x03)
return (i8259_unit[0].u4); /* ISR */ return (i8259_unit[devnum].u4); /* ISR */
} else { /* write data port */ } else { /* write data port */
if (data & 0x10) { if (data & 0x10) {
icw_num0 = 1; icw_num0 = 1;
} }
if (icw_num0 == 1) { if (icw_num0 == 1) {
i8259_icw1[0] = data; /* ICW1 */ i8259_icw1[devnum] = data; /* ICW1 */
i8259_unit[0].u5 = 0x00; /* clear IMR */ i8259_unit[devnum].u5 = 0x00; /* clear IMR */
i8259_ocw3[0] = 0x02; /* clear OCW3, Sel IRR */ i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
} else { } else {
switch (data & 0x18) { switch (data & 0x18) {
case 0: /* OCW2 */ case 0: /* OCW2 */
i8259_ocw2[0] = data; i8259_ocw2[devnum] = data;
break; break;
case 8: /* OCW3 */ case 8: /* OCW3 */
i8259_ocw3[0] = data; i8259_ocw3[devnum] = data;
break; break;
default: default:
sim_printf("8259b-0: OCW Error %02X\n", data); sim_printf("8259a-%d: OCW Error %02X\n", devnum, data);
break; break;
} }
} }
sim_printf("8259a-0: data = %02X\n", data); sim_printf("8259a-%d: data = %02X\n", devnum, data);
icw_num0++; /* step ICW number */ icw_num0++; /* step ICW number */
} }
i8259_dump(0); i8259_dump(devnum);
return 0; return 0;
} }
int32 i8259a1(int32 io, int32 data) uint8 i8259b(t_bool io, uint8 data, uint8 devnum)
{ {
if (devnum >= I8259_NUM) {
sim_printf("8259b: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
if ((i8259_ocw3[1] & 0x03) == 0x02) if ((i8259_ocw3[devnum] & 0x03) == 0x02)
return (i8259_unit[1].u3); /* IRR */ return (i8259_unit[devnum].u3); /* IRR */
if ((i8259_ocw3[1] & 0x03) == 0x03) if ((i8259_ocw3[devnum] & 0x03) == 0x03)
return (i8259_unit[1].u4); /* ISR */ return (i8259_unit[devnum].u4); /* ISR */
} else { /* write data port */ } else { /* write data port */
if (data & 0x10) { if (data & 0x10) {
icw_num1 = 1; icw_num1 = 1;
} }
if (icw_num1 == 1) { if (icw_num1 == 1) {
i8259_icw1[1] = data; /* ICW1 */ i8259_icw1[devnum] = data; /* ICW1 */
i8259_unit[1].u5 = 0x00; /* clear IMR */ i8259_unit[devnum].u5 = 0x00; /* clear IMR */
i8259_ocw3[1] = 0x02; /* clear OCW3, Sel IRR */ i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
} else { } else {
switch (data & 0x18) { switch (data & 0x18) {
case 0: /* OCW2 */ case 0: /* OCW2 */
i8259_ocw2[1] = data; i8259_ocw2[devnum] = data;
break; break;
case 8: /* OCW3 */ case 8: /* OCW3 */
i8259_ocw3[1] = data; i8259_ocw3[devnum] = data;
break; break;
default: default:
sim_printf("8259b-1: OCW Error %02X\n", data); sim_printf("8259b-%d: OCW Error %02X\n", devnum, data);
break; break;
} }
} }
sim_printf("8259a-1: data = %02X\n", data); sim_printf("8259b-%d: data = %02X\n", devnum, data);
icw_num1++; /* step ICW number */ icw_num1++; /* step ICW number */
} }
i8259_dump(1); i8259_dump(devnum);
return 0; return 0;
} }
/* i8259 1 functions */ void i8259_dump(uint8 devnum)
int32 i8259b0(int32 io, int32 data)
{ {
if (io == 0) { /* read data port */ sim_printf("Device %d\n", devnum);
return (i8259_unit[0].u5); /* IMR */ sim_printf(" IRR = %02X\n", i8259_unit[devnum].u3);
} else { /* write data port */ sim_printf(" ISR = %02X\n", i8259_unit[devnum].u4);
if (icw_num0 >= 2 && icw_num0 < 5) { /* ICW mode */ sim_printf(" IMR = %02X\n", i8259_unit[devnum].u5);
switch (icw_num0) { sim_printf(" ICW1 = %02X\n", i8259_icw1[devnum]);
case 2: /* ICW2 */ sim_printf(" ICW2 = %02X\n", i8259_icw2[devnum]);
i8259_icw2[0] = data; sim_printf(" ICW3 = %02X\n", i8259_icw3[devnum]);
break; sim_printf(" ICW4 = %02X\n", i8259_icw4[devnum]);
case 3: /* ICW3 */ sim_printf(" OCW1 = %02X\n", i8259_ocw1[devnum]);
i8259_icw3[0] = data; sim_printf(" OCW2 = %02X\n", i8259_ocw2[devnum]);
break; sim_printf(" OCW3 = %02X\n", i8259_ocw3[devnum]);
case 4: /* ICW4 */
if (i8259_icw1[0] & 0x01)
i8259_icw4[0] = data;
else
sim_printf("8259b-0: ICW4 not enabled - data=%02X\n", data);
break;
default:
sim_printf("8259b-0: ICW Error %02X\n", data);
break;
}
icw_num0++;
} else {
i8259_ocw1[0] = data; /* OCW0 */
}
}
i8259_dump(0);
return 0;
}
int32 i8259b1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8259_unit[1].u5); /* IMR */
} else { /* write data port */
if (icw_num1 >= 2 && icw_num1 < 5) { /* ICW mode */
switch (icw_num1) {
case 2: /* ICW2 */
i8259_icw2[1] = data;
break;
case 3: /* ICW3 */
i8259_icw3[1] = data;
break;
case 4: /* ICW4 */
if (i8259_icw1[1] & 0x01)
i8259_icw4[1] = data;
else
sim_printf("8259b-1: ICW4 not enabled - data=%02X\n", data);
break;
default:
sim_printf("8259b-1: ICW Error %02X\n", data);
break;
}
icw_num1++;
} else {
i8259_ocw1[1] = data; /* OCW0 */
}
}
i8259_dump(1);
return 0;
}
void i8259_dump(int32 dev)
{
sim_printf("Device %d\n", dev);
sim_printf(" IRR = %02X\n", i8259_unit[dev].u3);
sim_printf(" ISR = %02X\n", i8259_unit[dev].u4);
sim_printf(" IMR = %02X\n", i8259_unit[dev].u5);
sim_printf(" ICW1 = %02X\n", i8259_icw1[dev]);
sim_printf(" ICW2 = %02X\n", i8259_icw2[dev]);
sim_printf(" ICW3 = %02X\n", i8259_icw3[dev]);
sim_printf(" ICW4 = %02X\n", i8259_icw4[dev]);
sim_printf(" OCW1 = %02X\n", i8259_ocw1[dev]);
sim_printf(" OCW2 = %02X\n", i8259_ocw2[dev]);
sim_printf(" OCW3 = %02X\n", i8259_ocw3[dev]);
} }
/* Reset routine */ /* Reset routine */
t_stat i8259_reset (DEVICE *dptr, int32 base) t_stat i8259_reset (DEVICE *dptr, uint16 base, uint8 devnum)
{ {
switch (i8259_cnt) { if (devnum >= I8259_NUM) {
case 0: sim_printf("8259_reset: Illegal Device Number %d\n", devnum);
reg_dev(i8259a0, base); return 0;
reg_dev(i8259b0, base + 1);
reg_dev(i8259a0, base + 2);
reg_dev(i8259b0, base + 3);
i8259_unit[0].u3 = 0x00; /* IRR */
i8259_unit[0].u4 = 0x00; /* ISR */
i8259_unit[0].u5 = 0x00; /* IMR */
sim_printf(" 8259-0: Reset\n");
break;
case 1:
reg_dev(i8259a1, base);
reg_dev(i8259b1, base + 1);
reg_dev(i8259a1, base + 2);
reg_dev(i8259b1, base + 3);
i8259_unit[1].u3 = 0x00; /* IRR */
i8259_unit[1].u4 = 0x00; /* ISR */
i8259_unit[1].u5 = 0x00; /* IMR */
sim_printf(" 8259-1: Reset\n");
break;
default:
sim_printf(" 8259: Bad device\n");
break;
} }
sim_printf(" 8259-%d: Registered at %02X\n", i8259_cnt, base); reg_dev(i8259a, base, devnum);
i8259_cnt++; reg_dev(i8259b, base + 1, devnum);
i8259_unit[devnum].u3 = 0x00; /* IRR */
i8259_unit[devnum].u4 = 0x00; /* ISR */
i8259_unit[devnum].u5 = 0x00; /* IMR */
sim_printf(" 8259-%d: Reset\n", devnum);
sim_printf(" 8259-%d: Registered at %04X\n", devnum, base);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -159,7 +159,7 @@ DEBTAB i8273_debug[] = {
}; };
DEVICE i8273_dev = { DEVICE i8273_dev = {
"8251", //name "8273", //name
&i8273_unit, //units &i8273_unit, //units
i8273_reg, //registers i8273_reg, //registers
i8273_mod, //modifiers i8273_mod, //modifiers

View file

@ -31,11 +31,11 @@
NOTES: NOTES:
These functions support a simulated i2732 EPROM device on an Intel iSBC 80/XX. 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. 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/
Unit will support a single 2708, 2716, 2732 and 2764 type EPROMs. disable the onboard ROM.
*/ */
#include "system_defs.h" #include "system_defs.h"
@ -45,10 +45,12 @@
/* function prototypes */ /* function prototypes */
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr); t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
t_stat EPROM_reset (DEVICE *dptr, int32 size); t_stat EPROM_reset (DEVICE *dptr, uint16 size);
int32 EPROM_get_mbyte(uint32 addr); uint8 EPROM_get_mbyte(uint16 addr);
extern UNIT i8255_unit; /* external function prototypes */
extern UNIT i8255_unit[];
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
/* SIMH EPROM Standard I/O Data Structures */ /* SIMH EPROM Standard I/O Data Structures */
@ -75,7 +77,7 @@ DEVICE EPROM_dev = {
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
32, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -147,7 +149,7 @@ t_stat EPROM_attach (UNIT *uptr, CONST char *cptr)
/* EPROM reset */ /* EPROM reset */
t_stat EPROM_reset (DEVICE *dptr, int32 size) t_stat EPROM_reset (DEVICE *dptr, uint16 size)
{ {
// sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=0000 size=%04X\n", size); // sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=0000 size=%04X\n", size);
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */ if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
@ -166,11 +168,11 @@ t_stat EPROM_reset (DEVICE *dptr, int32 size)
/* get a byte from memory */ /* get a byte from memory */
int32 EPROM_get_mbyte(uint32 addr) uint8 EPROM_get_mbyte(uint16 addr)
{ {
int32 val; uint8 val;
if (i8255_unit.u5 & 0x01) { /* EPROM enabled */ if (i8255_unit[0].u5 & 0x01) { /* EPROM enabled */
sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%04X\n", addr); sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%04X\n", addr);
if (addr < EPROM_unit.capac) { if (addr < EPROM_unit.capac) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */

View file

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

View file

@ -31,7 +31,9 @@
NOTES: NOTES:
These functions support a simulated i8111 or i8102 RAM devices on an iSBC-80/XX. These functions support a simulated RAM devices on an iSBC-80/XX SBCs.
These functions also support bit 2 of 8255 number 1, port B, to enable/
disable the onboard RAM.
*/ */
#include "system_defs.h" #include "system_defs.h"
@ -41,11 +43,13 @@
/* function prototypes */ /* function prototypes */
t_stat RAM_svc (UNIT *uptr); t_stat RAM_svc (UNIT *uptr);
t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size); t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
int32 RAM_get_mbyte(int32 addr); uint8 RAM_get_mbyte(uint16 addr);
void RAM_put_mbyte(int32 addr, int32 val); void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT i8255_unit; /* external function prototypes */
extern UNIT i8255_unit[];
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
/* SIMH RAM Standard I/O Data Structures */ /* SIMH RAM Standard I/O Data Structures */
@ -70,7 +74,7 @@ DEVICE RAM_dev = {
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
32, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -95,7 +99,7 @@ DEVICE RAM_dev = {
/* RAM reset */ /* RAM reset */
t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size) t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size)
{ {
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1); sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1);
if (RAM_unit.capac == 0) { /* if undefined */ if (RAM_unit.capac == 0) { /* if undefined */
@ -118,11 +122,11 @@ t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size)
/* get a byte from memory */ /* get a byte from memory */
int32 RAM_get_mbyte(int32 addr) uint8 RAM_get_mbyte(uint16 addr)
{ {
int32 val; uint8 val;
if (i8255_unit.u5 & 0x02) { /* enable RAM */ if (i8255_unit[0].u5 & 0x02) { /* enable RAM */
sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr); 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 */
@ -140,9 +144,9 @@ int32 RAM_get_mbyte(int32 addr)
/* put a byte to memory */ /* put a byte to memory */
void RAM_put_mbyte(int32 addr, int32 val) void RAM_put_mbyte(uint16 addr, uint8 val)
{ {
if (i8255_unit.u5 & 0x02) { /* enable RAM */ if (i8255_unit[0].u5 & 0x02) { /* enable RAM */
sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, 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 */

View file

@ -42,10 +42,8 @@
/* prototypes */ /* prototypes */
t_stat isbc064_reset (DEVICE *dptr); t_stat isbc064_reset (DEVICE *dptr);
int32 isbc064_get_mbyte(int32 addr); uint8 isbc064_get_mbyte(uint16 addr);
int32 isbc064_get_mword(int32 addr); void isbc064_put_mbyte(uint16 addr, uint8 val);
void isbc064_put_mbyte(int32 addr, int32 val);
void isbc064_put_mword(int32 addr, int32 val);
extern uint8 xack; /* XACK signal */ extern uint8 xack; /* XACK signal */
@ -73,7 +71,7 @@ DEVICE isbc064_dev = {
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
8, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -118,9 +116,9 @@ t_stat isbc064_reset (DEVICE *dptr)
/* get a byte from memory */ /* get a byte from memory */
int32 isbc064_get_mbyte(int32 addr) uint8 isbc064_get_mbyte(uint16 addr)
{ {
int32 val, org, len; uint32 val, org, len;
int i = 0; int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) { if ((isbc064_dev.flags & DEV_DIS) == 0) {
@ -143,22 +141,11 @@ int32 isbc064_get_mbyte(int32 addr)
return 0xFF; /* multibus has active high pullups */ return 0xFF; /* multibus has active high pullups */
} }
/* get a word from memory */
int32 isbc064_get_mword(int32 addr)
{
int32 val;
val = isbc064_get_mbyte(addr);
val |= (isbc064_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte into memory */ /* put a byte into memory */
void isbc064_put_mbyte(int32 addr, int32 val) void isbc064_put_mbyte(uint16 addr, uint8 val)
{ {
int32 org, len; uint32 org, len;
int i = 0; int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) { if ((isbc064_dev.flags & DEV_DIS) == 0) {
@ -180,12 +167,4 @@ void isbc064_put_mbyte(int32 addr, int32 val)
sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Disabled\n"); sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Disabled\n");
} }
/* put a word into memory */
void isbc064_put_mword(int32 addr, int32 val)
{
isbc064_put_mbyte(addr, val);
isbc064_put_mbyte(addr+1, val << 8);
}
/* end of isbc064.c */ /* end of isbc064.c */

View file

@ -1,256 +0,0 @@
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated isbc016, isbc032, isbc048 and isbc064 memory card
on an Intel multibus system.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_MSIZE (UNIT_V_UF) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_V_MBASE (UNIT_V_UF+1) /* Memory Base */
#define UNIT_MBASE (1 << UNIT_V_MBASE)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
t_stat isbc064_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat isbc064_set_base (UNIT *uptr, int32 val, char *cptr, void *desc);
int32 isbc064_get_mbyte(int32 addr);
int32 isbc064_get_mword(int32 addr);
void isbc064_put_mbyte(int32 addr, int32 val);
void isbc064_put_mword(int32 addr, int32 val);
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = { UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT };
MTAB isbc064_mod[] = {
{ UNIT_MSIZE, 16384, NULL, "16K", &isbc064_set_size },
{ UNIT_MSIZE, 32768, NULL, "32K", &isbc064_set_size },
{ UNIT_MSIZE, 49152, NULL, "48K", &isbc064_set_size },
{ UNIT_MSIZE, 65535, NULL, "64K", &isbc064_set_size },
{ UNIT_MBASE, 0, NULL, "B0K", &isbc064_set_base },
{ UNIT_MBASE, 16384, NULL, "B16K", &isbc064_set_base },
{ UNIT_MBASE, 32768, NULL, "B32K", &isbc064_set_base },
{ UNIT_MBASE, 49152, NULL, "B48K", &isbc064_set_base },
{ 0 }
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
isbc064_mod, //modifiers
1, //numunits
16, //aradix
8, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
&isbc064_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
uint8 *MB_buf = NULL; //pointer to memory buffer
/* Set memory size routine */
t_stat isbc064_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 mc = 0;
uint32 i;
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_set_size: val=%04X\n", val);
if ((val <= 0) || (val > MAXMEMSIZE)) {
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_set_size: Memory size error\n");
return SCPE_ARG;
}
isbc064_unit.capac = val;
for (i = isbc064_unit.capac; i < MAXMEMSIZE; i++)
isbc064_put_mbyte(i, 0);
isbc064_unit.capac = val;
isbc064_unit.u3 = 0;
if (MB_buf) {
free (MB_buf);
MB_buf = NULL;
}
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_set_size: Done\n");
return SCPE_OK;
}
/* Set memory base address routine */
t_stat isbc064_set_base (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_set_base: val=%04X\n", val);
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) {
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_set_base: Base address error\n");
return SCPE_ARG;
}
isbc064_unit.u3 = val;
if (MB_buf) {
free (MB_buf);
MB_buf = NULL;
}
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_set_base: Done\n");
return (isbc064_reset (NULL));
}
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: \n");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
sim_printf("Initializing %s [%04X-%04XH]\n", "iSBC-064",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
if (MB_buf == NULL) {
MB_buf = malloc(isbc064_unit.capac);
if (MB_buf == NULL) {
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
}
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
external memory read or write is issued.
*/
/* get a byte from memory */
int32 isbc064_get_mbyte(int32 addr)
{
int32 val, org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac - 1;
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf("isbc064_get_mbyte: addr=%04X", addr);
if ((addr >= org) && (addr <= org + len)) {
val = *(MB_buf + (addr - org));
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf(" val=%04X\n", val);
return (val & 0xFF);
} else {
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf(" Out of range\n");
return 0xFF; /* multibus has active high pullups */
}
}
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf(" Disabled\n");
return 0xFF; /* multibus has active high pullups */
}
/* get a word from memory */
int32 isbc064_get_mword(int32 addr)
{
int32 val;
val = isbc064_get_mbyte(addr);
val |= (isbc064_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte into memory */
void isbc064_put_mbyte(int32 addr, int32 val)
{
int32 org, len, type;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac - 1;
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf("isbc064_put_mbyte: addr=%04X, val=%02X", addr, val);
if ((addr >= org) && (addr < org + len)) {
*(MB_buf + (addr - org)) = val & 0xFF;
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf("\n");
return;
} else {
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf(" Out of range\n");
return;
}
}
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf("isbc064_put_mbyte: Disabled\n");
}
/* put a word into memory */
void isbc064_put_mword(int32 addr, int32 val)
{
isbc064_put_mbyte(addr, val);
isbc064_put_mbyte(addr+1, val << 8);
}
/* end of isbc064.c */

View file

@ -1,205 +0,0 @@
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated isbc016, isbc032, isbc048 and isbc064
memory card on an Intel multibus system.
?? ??? 11 - Original file.
16 Dec 12 - Modified to use system_80_10.cfg file to set base and size.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define SET_XACK(VAL) (XACK = VAL)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
int32 isbc064_get_mbyte(int32 addr);
int32 isbc064_get_mword(int32 addr);
void isbc064_put_mbyte(int32 addr, int32 val);
void isbc064_put_mword(int32 addr, int32 val);
extern uint8 XACK; /* XACK signal */
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
8, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
&isbc064_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: \n");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: Size=%04X\n", isbc064_unit.capac - 1);
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: Base address=%04X\n", isbc064_unit.u3);
sim_printf("iSBC 064: Available[%04X-%04XH]\n",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
}
if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) {
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (isbc064_dev.dctrl & DEBUG_flow)
sim_printf("isbc064_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
int32 isbc064_get_mbyte(int32 addr)
{
int32 val, org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf("isbc064_get_mbyte: addr=%04X", addr);
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack)
sim_printf("isbc064_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(isbc064_unit.filebuf + (addr - org));
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf(" val=%04X\n", val);
return (val & 0xFF);
} else {
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf(" Out of range\n");
return 0xFF; /* multibus has active high pullups */
}
}
if (isbc064_dev.dctrl & DEBUG_read)
sim_printf(" Disabled\n");
return 0xFF; /* multibus has active high pullups */
}
/* get a word from memory */
int32 isbc064_get_mword(int32 addr)
{
int32 val;
val = isbc064_get_mbyte(addr);
val |= (isbc064_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte into memory */
void isbc064_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack)
sim_printf("isbc064_put_mbyte: Set XACK for %04X\n", addr);
*(uint8 *)(isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
if (isbc064_dev.dctrl & DEBUG_xack)
sim_printf("isbc064_put_mbyte: Return\n");
return;
} else {
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf(" Out of range\n");
return;
}
}
if (isbc064_dev.dctrl & DEBUG_write)
sim_printf("isbc064_put_mbyte: Disabled\n");
}
/* put a word into memory */
void isbc064_put_mword(int32 addr, int32 val)
{
isbc064_put_mbyte(addr, val);
isbc064_put_mbyte(addr+1, val << 8);
}
/* end of isbc064.c */

File diff suppressed because it is too large Load diff

View file

@ -36,49 +36,30 @@
#include "system_defs.h" #include "system_defs.h"
/* set the base I/O address for the first 8255 */
#define I8255_BASE_0 0xE4
/* set the base I/O address for the second 8255 */
#define I8255_BASE_1 0xE8
/* set the base I/O address for the 8251 */
#define I8251_BASE 0xEC
/* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
/* set INTR for CPU */
#define INTR INT_1
/* function prototypes */ /* function prototypes */
int32 get_mbyte(int32 addr); uint8 get_mbyte(uint16 addr);
int32 get_mword(int32 addr); uint16 get_mword(uint16 addr);
void put_mbyte(int32 addr, int32 val); void put_mbyte(uint16 addr, uint8 val);
void put_mword(int32 addr, int32 val); void put_mword(uint16 addr, uint16 val);
t_stat SBC_reset (DEVICE *dptr); 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 int32 multibus_get_mbyte(int32 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(int32 addr, int32 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern int32 EPROM_get_mbyte(int32 addr); extern uint8 EPROM_get_mbyte(uint16 addr);
extern int32 RAM_get_mbyte(int32 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(int32 addr, int32 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
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 t_stat i8255_reset (DEVICE *dptr, int32 base); extern t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8251_reset (DEVICE *dptr, int32 base); extern t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat pata_reset (DEVICE *dptr, int32 base); extern t_stat pata_reset (DEVICE *dptr, uint16 base);
extern t_stat EPROM_reset (DEVICE *dptr, int32 size); extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size); extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* SBC reset routine */ /* SBC reset routine */
@ -86,9 +67,9 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing iSBC-80/10:\n"); sim_printf("Initializing iSBC-80/10:\n");
i8080_reset (NULL); i8080_reset (NULL);
i8255_reset (NULL, I8255_BASE_0); i8255_reset (NULL, I8255_BASE_0, 0);
i8255_reset (NULL, I8255_BASE_1); i8255_reset (NULL, I8255_BASE_1, 1);
i8251_reset (NULL, I8251_BASE); i8251_reset (NULL, I8251_BASE, 0);
EPROM_reset (NULL, ROM_SIZE); EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE); RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK; return SCPE_OK;
@ -96,15 +77,15 @@ t_stat SBC_reset (DEVICE *dptr)
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */ /* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
int32 get_mbyte(int32 addr) uint8 get_mbyte(uint16 addr)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if (i8255_unit.u5 & 0x01) { if (i8255_unit[0].u5 & 0x01) {
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 (i8255_unit.u5 & 0x02) { if (i8255_unit[0].u5 & 0x02) {
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);
} }
@ -114,9 +95,9 @@ int32 get_mbyte(int32 addr)
/* get a word from memory */ /* get a word from memory */
int32 get_mword(int32 addr) uint16 get_mword(uint16 addr)
{ {
int32 val; uint16 val;
val = get_mbyte(addr); val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8); val |= (get_mbyte(addr+1) << 8);
@ -125,14 +106,14 @@ int32 get_mword(int32 addr)
/* put a byte to memory - handle RAM, ROM, I/O, and Multibus memory */ /* put a byte to memory - handle RAM, ROM, I/O, and Multibus memory */
void put_mbyte(int32 addr, int32 val) void put_mbyte(uint16 addr, uint8 val)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && (addr >= EPROM_unit.u3) && ((uint16)addr <= (EPROM_unit.u3 + EPROM_unit.capac))) { if ((i8255_unit[0].u5 & 0x01) && (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 ((i8255_unit.u5 & 0x02) && (addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) { if ((i8255_unit[0].u5 & 0x02) && (addr >= RAM_unit.u3) && ((uint16)addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val); RAM_put_mbyte(addr, val);
return; return;
} /* otherwise, try the multibus */ } /* otherwise, try the multibus */
@ -141,9 +122,9 @@ void put_mbyte(int32 addr, int32 val)
/* put a word to memory */ /* put a word to memory */
void put_mword(int32 addr, int32 val) void put_mword(uint16 addr, uint16 val)
{ {
put_mbyte(addr, val); put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8); put_mbyte(addr+1, val >> 8);
} }

View file

@ -23,61 +23,39 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems. Computer Systems.
?? ??? 10 - Original file.
*/ */
#include "system_defs.h" #include "system_defs.h"
/* set the base I/O address for the 8259 */
#define I8259_BASE 0xD8
/* set the base I/O address for the first 8255 */
#define I8255_BASE_0 0xE4
/* set the base I/O address for the second 8255 */
#define I8255_BASE_1 0xE8
/* set the base I/O address for the 8251 */
#define I8251_BASE 0xEC
/* set the base and size for the EPROM on the iSBC 80/20 */
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/20 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
/* set INTR for CPU */
#define INTR INT_1
/* function prototypes */ /* function prototypes */
int32 get_mbyte(int32 addr); uint8 get_mbyte(uint16 addr);
int32 get_mword(int32 addr); uint16 get_mword(uint16 addr);
void put_mbyte(int32 addr, int32 val); void put_mbyte(uint16 addr, uint8 val);
void put_mword(int32 addr, int32 val); void put_mword(uint16 addr, uint16 val);
t_stat i80_10_reset (DEVICE *dptr); 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 int32 multibus_get_mbyte(int32 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(int32 addr, int32 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern int32 EPROM_get_mbyte(int32 addr); extern uint8 EPROM_get_mbyte(uint16 addr);
extern int32 RAM_get_mbyte(int32 addr); extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(int32 addr, int32 val); extern void RAM_put_mbyte(uint16 addr, uint8 val);
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 t_stat i8251_reset (DEVICE *dptr, int32 base); extern t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8255_reset (DEVICE *dptr, int32 base); extern t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8259_reset (DEVICE *dptr, int32 base); extern t_stat i8259_reset (DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat pata_reset (DEVICE *dptr, int32 base); extern t_stat pata_reset (DEVICE *dptr, uint16 base);
extern t_stat EPROM_reset (DEVICE *dptr, int32 size); extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size); extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* 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 */
@ -86,10 +64,10 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
sim_printf("Initializing iSBC-80/20\n"); sim_printf("Initializing iSBC-80/20\n");
i8080_reset(NULL); i8080_reset(NULL);
i8259_reset(NULL, I8259_BASE); i8259_reset(NULL, I8259_BASE, 0);
i8255_reset(NULL, I8255_BASE_0); i8255_reset(NULL, I8255_BASE_0, 0);
i8255_reset(NULL, I8255_BASE_1); i8255_reset(NULL, I8255_BASE_1, 1);
i8251_reset(NULL, I8251_BASE); i8251_reset(NULL, I8251_BASE, 0);
EPROM_reset(NULL, ROM_SIZE); EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE); RAM_reset(NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK; return SCPE_OK;
@ -97,10 +75,8 @@ t_stat SBC_reset (DEVICE *dptr)
/* get a byte from memory - handle RAM, ROM and Multibus memory */ /* get a byte from memory - handle RAM, ROM and Multibus memory */
int32 get_mbyte(int32 addr) uint8 get_mbyte(uint16 addr)
{ {
int32 val, org, len;
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && /* EPROM enabled? */ if ((i8255_unit.u5 & 0x01) && /* EPROM enabled? */
(addr >= EPROM_unit.u3) && (addr < (EPROM_unit.u3 + EPROM_unit.capac))) { (addr >= EPROM_unit.u3) && (addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
@ -115,9 +91,9 @@ int32 get_mbyte(int32 addr)
/* get a word from memory */ /* get a word from memory */
int32 get_mword(int32 addr) uint16 get_mword(uint16 addr)
{ {
int32 val; uint16 val;
val = get_mbyte(addr); val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8); val |= (get_mbyte(addr+1) << 8);
@ -126,7 +102,7 @@ int32 get_mword(int32 addr)
/* put a byte to memory - handle RAM, ROM and Multibus memory */ /* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(int32 addr, int32 val) void put_mbyte(uint16 addr, uint8 val)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && /* EPROM enabled? */ if ((i8255_unit.u5 & 0x01) && /* EPROM enabled? */
@ -144,9 +120,9 @@ void put_mbyte(int32 addr, int32 val)
/* put a word to memory */ /* put a word to memory */
void put_mword(int32 addr, int32 val) void put_mword(uint16 addr, uint16 val)
{ {
put_mbyte(addr, val); put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8); put_mbyte(addr+1, val >> 8);
} }

View file

@ -27,66 +27,78 @@
Computer Systems. Computer Systems.
?? ??? 10 - Original file. ?? ??? 10 - Original file.
17 May 16 - Modified for the iSBC 80/30 Processor Card.
*/ */
#include "system_defs.h" #include "system_defs.h"
/* set the base I/O address for the 8259 */ /* set the base I/O address for the 8259 */
#define I8259_BASE 0xD8 #define I8259_BASE 0xD8
#define I8259_NUM 1
/* set the base I/O address for the first 8255 */ /* set the base I/O address for the 8253 */
#define I8253_BASE 0xDC
#define I8253_NUM 1
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4 #define I8255_BASE_0 0xE4
/* set the base I/O address for the second 8255 */
#define I8255_BASE_1 0xE8 #define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8251 */ /* set the base I/O address for the 8251 */
#define I8251_BASE 0xEC #define I8251_BASE 0xEC
#define I8251_NUM 1
/* set the base and size for the EPROM on the iSBC 80/20 */ /* set the base and size for the EPROM */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000 #define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/20 */ /* set the base and size for the RAM */
#define RAM_BASE 0x3C00 #define RAM_BASE 0x4000
#define RAM_SIZE 0x0400 #define RAM_SIZE 0x2000
/* set INTR for CPU */ /* set INTR for CPU */
#define INTR INT_1 #define INTR INT_1
/* function prototypes */ /* function prototypes */
int32 get_mbyte(int32 addr); uint16 get_mbyte(uint16 addr);
int32 get_mword(int32 addr); uint8 get_mword(uint16 addr);
void put_mbyte(int32 addr, int32 val); void put_mbyte(uint16 addr, uint8 val);
void put_mword(int32 addr, int32 val); void put_mword(uint16 addr, uint16 val);
t_stat i80_10_reset (DEVICE *dptr); t_stat i80_10_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 8085 emulator */
extern int32 multibus_get_mbyte(int32 addr); extern int32 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(int32 addr, int32 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern int32 EPROM_get_mbyte(int32 addr); extern int32 EPROM_get_mbyte(uint16 addr);
extern int32 RAM_get_mbyte(int32 addr); extern int32 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(int32 addr, int32 val); extern void RAM_put_mbyte(uint16, uint8 val);
extern UNIT i8251_unit;
extern UNIT i8253_unit;
extern UNIT i8255_unit; extern UNIT i8255_unit;
extern UNIT i8259_unit;
extern UNIT EPROM_unit; extern UNIT EPROM_unit;
extern UNIT RAM_unit; extern UNIT RAM_unit;
extern t_stat i8251_reset (DEVICE *dptr, int32 base); extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
extern t_stat i8255_reset (DEVICE *dptr, int32 base); extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
extern t_stat i8259_reset (DEVICE *dptr, int32 base); extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
extern t_stat pata_reset (DEVICE *dptr, int32 base); extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
extern t_stat EPROM_reset (DEVICE *dptr, int32 size); extern t_stat pata_reset (DEVICE *dptr, uint16 base);
extern t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size); extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
/* 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"); sim_printf("Initializing iSBC-80/30\n");
i8080_reset(NULL); i8080_reset(NULL);
i8259_reset(NULL, I8259_BASE); i8259_reset(NULL, I8259_BASE);
i8253_reset(NULL, I8253_BASE);
i8255_reset(NULL, I8255_BASE_0); i8255_reset(NULL, I8255_BASE_0);
i8255_reset(NULL, I8255_BASE_1); i8255_reset(NULL, I8255_BASE_1);
i8251_reset(NULL, I8251_BASE); i8251_reset(NULL, I8251_BASE);
@ -97,7 +109,7 @@ t_stat SBC_reset (DEVICE *dptr)
/* get a byte from memory - handle RAM, ROM and Multibus memory */ /* get a byte from memory - handle RAM, ROM and Multibus memory */
int32 get_mbyte(int32 addr) uint8 get_mbyte(uint16 addr)
{ {
int32 val, org, len; int32 val, org, len;
@ -113,7 +125,7 @@ int32 get_mbyte(int32 addr)
/* get a word from memory */ /* get a word from memory */
int32 get_mword(int32 addr) uint16 get_mword(uint16 addr)
{ {
int32 val; int32 val;
@ -124,7 +136,7 @@ int32 get_mword(int32 addr)
/* put a byte to memory - handle RAM, ROM and Multibus memory */ /* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(int32 addr, int32 val) void put_mbyte(uint16 addr, uint8 val)
{ {
/* if local EPROM handle it */ /* if local EPROM handle it */
if ((i8255_unit.u6 & 0x01) && (addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) { if ((i8255_unit.u6 & 0x01) && (addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
@ -140,10 +152,10 @@ void put_mbyte(int32 addr, int32 val)
/* put a word to memory */ /* put a word to memory */
void put_mword(int32 addr, int32 val) void put_mword(uint16 addr, uint16 val)
{ {
put_mbyte(addr, val); put_mbyte(addr, val);
put_mbyte(addr+1, val >> 8); put_mbyte(addr+1, val >> 8);
} }
/* end of iSBC80-10.c */ /* end of iSBC80-30.c */

View file

@ -1,143 +0,0 @@
/* iSBC80-10.c: Intel iSBC 80/10 Processor simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
?? ??? 10 - Original file.
*/
#include "system_defs.h"
/* set the base I/O address for the first 8255 */
#define I8255_BASE_0 0xE4
/* set the base I/O address for the second 8255 */
#define I8255_BASE_1 0xE8
/* set the base I/O address for the 8251 */
#define I8251_BASE 0xEC
/* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
/* set INTR for CPU */
#define INTR INT_1
/* function prototypes */
int32 get_mbyte(int32 addr);
int32 get_mword(int32 addr);
void put_mbyte(int32 addr, int32 val);
void put_mword(int32 addr, int32 val);
t_stat SBC_reset (DEVICE *dptr);
/* external function prototypes */
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 multibus_get_mbyte(int32 addr);
extern void multibus_put_mbyte(int32 addr, int32 val);
extern int32 EPROM_get_mbyte(int32 addr);
extern int32 RAM_get_mbyte(int32 addr);
extern void RAM_put_mbyte(int32 addr, int32 val);
extern UNIT i8255_unit;
extern UNIT EPROM_unit;
extern UNIT RAM_unit;
extern t_stat i8255_reset (DEVICE *dptr, int32 base);
extern t_stat i8251_reset (DEVICE *dptr, int32 base);
extern t_stat pata_reset (DEVICE *dptr, int32 base);
extern t_stat EPROM_reset (DEVICE *dptr, int32 size);
extern t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing iSBC-80/10:\n");
i8080_reset (NULL);
i8255_reset (NULL, I8255_BASE_0);
i8255_reset (NULL, I8255_BASE_1);
i8251_reset (NULL, I8251_BASE);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
int32 get_mbyte(int32 addr)
{
int32 val, org, len;
/* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && (addr >= EPROM_unit.u3) && (addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr);
} /* if local RAM handle it */
if ((i8255_unit.u5 & 0x02) && (addr >= RAM_unit.u3) && (addr < (RAM_unit.u3 + RAM_unit.capac))) {
return RAM_get_mbyte(addr);
} /* otherwise, try the multibus */
return multibus_get_mbyte(addr);
}
/* get a word from memory */
int32 get_mword(int32 addr)
{
int32 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM, I/O, and Multibus memory */
void put_mbyte(int32 addr, int32 val)
{
/* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && (addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
sim_printf("Write to R/O memory address %04X - ignored\n", addr);
return;
} /* if local RAM handle it */
if ((i8255_unit.u5 & 0x02) && (addr >= RAM_unit.u3) && (addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val);
return;
} /* otherwise, try the multibus */
multibus_put_mbyte(addr, val);
}
/* put a word to memory */
void put_mword(int32 addr, int32 val)
{
put_mbyte(addr, val);
put_mbyte(addr+1, val >> 8);
}
/* end of iSBC80-10.c */

View file

@ -48,19 +48,17 @@ 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);
int32 nulldev(int32 io, int32 data); uint8 nulldev(t_bool io, uint8 data, uint8 devnum);
int32 reg_dev(int32 (*routine)(int32, int32), int32 port); uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum);
t_stat multibus_reset (DEVICE *dptr); t_stat multibus_reset (DEVICE *dptr);
int32 multibus_get_mbyte(int32 addr); uint8 multibus_get_mbyte(uint16 addr);
int32 multibus_get_mword(int32 addr); void multibus_put_mbyte(uint16 addr, uint8 val);
void multibus_put_mbyte(int32 addr, int32 val);
void multibus_put_mword(int32 addr, int32 val);
/* external function prototypes */ /* external function prototypes */
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 int32 isbc064_get_mbyte(int32 addr); extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(int32 addr, int32 val); extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern void set_cpuint(int32 int_num); extern void set_cpuint(int32 int_num);
extern t_stat SBC_reset (DEVICE *dptr); extern t_stat SBC_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr); extern t_stat isbc064_reset (DEVICE *dptr);
@ -99,7 +97,7 @@ DEVICE multibus_dev = {
NULL, //modifiers NULL, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
32, //awidth 16, //awidth
1, //aincr 1, //aincr
16, //dradix 16, //dradix
8, //dwidth 8, //dwidth
@ -163,10 +161,11 @@ void clr_irq(int32 int_num)
/* This is the I/O configuration table. There are 256 possible /* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device is available address is here, 'nulldev' means no device has been registered.
*/ */
struct idev { struct idev {
int32 (*routine)(int32, int32); uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 devnum;
}; };
struct idev dev_table[256] = { struct idev dev_table[256] = {
@ -236,7 +235,7 @@ struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */ {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
}; };
int32 nulldev(int32 flag, int32 data) uint8 nulldev(t_bool flag, uint8 data, uint8 devnum)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
if (flag == 0) /* if we got here, no valid I/O device */ if (flag == 0) /* if we got here, no valid I/O device */
@ -244,40 +243,30 @@ int32 nulldev(int32 flag, int32 data)
return 0; return 0;
} }
int32 reg_dev(int32 (*routine)(int32, int32), int32 port) uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 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 %02X is already assigned\n", port); // sim_printf("Multibus: I/O Port %02X is already assigned\n", port);
} else { } else {
// sim_printf("Port %02X is assigned\n", port); // sim_printf("Port %02X is assigned\n", port);
dev_table[port].routine = routine; dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
} }
return 0; return 0;
} }
/* get a byte from memory */ /* get a byte from memory */
int32 multibus_get_mbyte(int32 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); // sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr);
return isbc064_get_mbyte(addr); return isbc064_get_mbyte(addr);
} }
/* get a word from memory */
int32 multibus_get_mword(int32 addr)
{
int32 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */ /* put a byte to memory */
void multibus_put_mbyte(int32 addr, int32 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); // sim_printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr);
@ -285,13 +274,5 @@ void multibus_put_mbyte(int32 addr, int32 val)
// sim_printf("multibus_put_mbyte: Done XACK=%dX\n", XACK); // sim_printf("multibus_put_mbyte: Done XACK=%dX\n", XACK);
} }
/* put a word to memory */
void multibus_put_mword(int32 addr, int32 val)
{
multibus_put_mbyte(addr, val);
multibus_put_mbyte(addr+1, val << 8);
}
/* end of multibus.c */ /* end of multibus.c */

View file

@ -1,211 +0,0 @@
Altair 8800 Simulator
=====================
1. Background.
The MITS (Micro Instrumentation and Telemetry Systems) Altair 8800
was announced on the January 1975 cover of Popular Electronics, which
boasted you could buy and build this powerful computer kit for only $397.
The kit consisted at that time of only the parts to build a case, power
supply, card cage (18 slots), CPU card, and memory card with 256 *bytes* of
memory. Still, thousands were ordered within the first few months after the
announcement, starting the personal computer revolution as we know it today.
Many laugh at the small size of the that first kit, noting there
were no peripherals and the 256 byte memory size. But the computer was an
open system, and by 1977 MITS and many other small startups had added many
expansion cards to make the Altair quite a respectable little computer. The
"Altair Bus" that made this possible was soon called the S-100 Bus, later
adopted as an industry standard, and eventually became the IEE-696 Bus.
2. Hardware
We are simulating a fairly "loaded" Altair 8800 from about 1977,
with the following configuration:
device simulates
name(s)
CPU Altair 8800 with Intel 8080 CPU board, 62KB
of RAM, 2K of EPROM with start boot ROM.
2SIO MITS 88-2SIO Dual Serial Interface Board. Port 1
is assumed to be connected to a serial "glass
TTY" that is your terminal running the Simulator.
PTR Paper Tape Reader attached to port 2 of the
2SIO board.
PTP Paper Tape Punch attached to port 2 of the
2SIO board. This also doubles as a printer
port.
DSK MITS 88-DISK Floppy Disk controller with up
to eight drives.
2.1 CPU
We have 2 CPU options that were not present on the original
machine but are useful in the simulator. We also allow you to select
memory sizes, but be aware that some sample software requires the full
64K (i.e. CP/M) and the MITS Disk Basic and Altair DOS require about
a minimum of 24K.
SET CPU 8080 Simulates the 8080 CPU (normal)
SET CPU Z80 Simulates the later Z80 CPU [At the present time
this is not fully implemented and is not to be
trusted with real Z80 software]
SET CPU ITRAP Causes the simulator to halt if an invalid 8080
Opcode is detected.
SET CPU NOITRAP Does not stop on an invalid Opcode. This is
how the real 8080 works.
SET CPU 4K
SET CPU 8K
SET CPU 12K
SET CPU 16K
......
SET CPU 64K All these set various CPU memory configurations.
The 2K EPROM at the high end of memory is always
present and will always boot.
The BOOT EPROM card starts at address 177400. Jumping to this address
will always boot drive 0 of the floppy controller. If no valid bootable
software is present there the machine crashes. This is historically
accurate behavior.
The real 8080, on receiving a HLT (Halt) instruction, freezes the processor
and only an interrupt or CPU hardware reset will restore it. The simulator
is alot nicer, it will halt but send you back to the simulator command line.
CPU Registers include the following:
name size comments
PC 16 The Program Counter
A 8 The accumulator
BC 16 The BC register pair. Register B is the high
8 bits, C is the lower 8 bits
DE 16 The DE register pair. D is the top 8 bits, E is
the bottom.
HL 16 The HL register pair. H is top, L is bottom.
C 1 Carry flag.
Z 1 Zero Flag.
AC 1 Auxillary Carry flag.
P 1 Parity flag.
S 1 Sign flag.
SR 16 The front panel switches.
BREAK 16 Breakpoint address (377777 to disable).
WRU 8 The interrupt character. This starts as 005
(ctrl-E) but some Altair software uses this
keystroke so best to change this to something
exotic such as 035 (which is Ctl-]).
2.2 The Serial I/O Card (2SIO)
This simple programmed I/O device provides 2 serial ports to the
outside world, which could be hardware jumpered to support RS-232 plugs or a
TTY current loop interface. The standard I/O addresses assigned by MITS
was 20-21 (octal) for the first port, and 22-23 (octal) for the second.
We follow this standard in the Simulator.
The simulator directs I/O to/from the first port to the screen. The
second port reads from an attachable "tape reader" file on input, and writes
to an attachable "punch file" on output. These files are considered a
simple stream of 8-bit bytes.
2.3 The 88-DISK controller.
The MITS 88-DISK is a simple programmed I/O interface to the MITS
8-inch floppy drive, which was basically a Pertec FD-400 with a power
supply and buffer board builtin. The controller supports neither interrupts
nor DMA, so floppy access required the sustained attention of the CPU.
The standard I/O addresses were 10, 11, and 12 (octal), and we follow the
standard. Details on controlling this hardware are in the altair_dsk.c
source file.
3. Sample Software
Running an Altair in 1977 you would be running either MITS Disk
Extended BASIC, or the brand new and sexy CP/M Operating System from Digital
Research. Or possibly, you ordered Altair DOS back when it was promised in
1975, and are still waiting for it to be delivered in early 1977.
We have samples of all three for you to check out. We can't go into
the details of how they work, but we'll give you a few hints.
3.1 CP/M Version 2.2
This version is my own port of the standard CP/M to the Altair.
There were some "official" versions but I don't have them. None were
endorsed or sold by MITS to my knowledge, however.
To boot CP/M:
sim> attach dsk0 altcpm.dsk
sim> go 177400
62K CP/M VERSION 2.2 (ALTAIR 8800)
A>DIR
CP/M feels like DOS, sort of. DIR will work. I have included all
the standard CP/M utilities, plus a few common public-domain ones. I also
include the sources to the customized BIOS and some other small programs.
TYPE will print an ASCII file. DUMP will dump a binary one. LS is a better
DIR than DIR. ASM will assemble .ASM files to Hex, LOAD will "load" them to
binary format (.COM). ED is a simple editor, #A command will bring the
source file to the buffer, T command will "type" lines, L will move lines,
E exits the editor. 20L20T will move down 20 lines, and type 20. Very
DECish. DDT is the debugger, SUBMIT is a batch-type command processor.
A sample batch file that will assemble and write out the bootable CP/M
image (on drive A) is "SYSGEN.SUB". To run it, type "SUBMIT SYSGEN".
3.2 MITS Disk Extended BASIC Version 4.1
This was the commonly used software for serious users of the Altair
computer. It is a powerful (but slow) BASIC with some extended commands to
allow it to access and manage the disk. There was no operating system it
ran under. To boot:
sim> attach dsk0 mbasic.dsk
sim> go 177400
MEMORY SIZE? [return]
LINEPRINTER? C [return]
HIGHEST DISK NUMBER? 0 [return] (3 here = 4 drive system)
NUMBER OF FILES? 3 [return]
NUMBER OF RANDOM FILES? 2 [return]
44297 BYTES FREE
ALTAIR BASIC REV. 4.1
[DISK EXTENDED VERSION]
COPYRIGHT 1977 BY MITS INC.
OK
mount 0
OK
files
3.3 Altair DOS Version 1.0
This was long promised but not delivered until it was almost
irrelevant. A short attempted tour will reveal it to be a dog, far inferior
to CP/M. To boot:
sim> attach dsk0 altdos.dsk
sim> go 177400
MEMORY SIZE? 64 [return]
INTERRUPTS? N [return]
HIGHEST DISK NUMBER? 0 [return] (3 here = 4 drive system)
HOW MANY DISK FILES? 3 [return]
HOW MANY RANDOM FILES? 2 [return]
056769 BYTES AVAILABLE
DOS MONITOR VER 1.0
COPYRIGHT 1977 BY MITS INC
.mnt 0
.dir 0

View file

@ -1,41 +0,0 @@
/* system_80_10.cfg: Intel System 80/10 simulator definitions
This file holds the configuration for the System 80/10
boards I/O and Memory.
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.
16 Dec 12 - Original file
*/
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
/* configure interrupt request line */
#define SBC208_INT INT_1
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000

View file

@ -24,14 +24,43 @@
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file. ?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/ */
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include "isys8010_cfg.h" /* Intel System 80/10 configuration */ //#include "isys8010_cfg.h" /* Intel System 80/10 configuration */
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
/* 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 and device count for the 8251s */
#define I8251_BASE 0xEC
#define I8251_NUM 1
/* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
/* set INTR for CPU on the iSBC 80/10 */
#define INTR INT_1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
/* configure interrupt request line */
#define SBC208_INT INT_1
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000
/* multibus interrupt definitions */ /* multibus interrupt definitions */
#define INT_0 0x01 #define INT_0 0x01

View file

@ -24,14 +24,46 @@
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file. ?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/ */
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include "isys8020_cfg.h" /* Intel System 80/20 configuration */
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
/* set the base I/O address for the 8259 */
#define I8259_BASE 0xD8
#define I8259_NUM 1
/* 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 8251 */
#define I8251_BASE 0xEC
#define I8251_NUM 1
/* set the base and size for the EPROM on the iSBC 80/20 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/20 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
/* set INTR for CPU */
#define INTR INT_1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
/* configure interrupt request line */
#define SBC208_INT INT_1
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000
/* multibus interrupt definitions */ /* multibus interrupt definitions */
#define INT_0 0x01 #define INT_0 0x01

View file

@ -221,7 +221,7 @@
> >
</File> </File>
<File <File
RelativePath="..\Intel-Systems\common\iSBC80-10.c" RelativePath="..\Intel-Systems\common\isbc80-20.c"
> >
</File> </File>
<File <File