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