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 saved_PC = 0; /* program counter */
|
||||
uint32 IM = 0; /* Interrupt Mask Register */
|
||||
uint32 xack = 0; /* XACK signal */
|
||||
uint8 xack = 0; /* XACK signal */
|
||||
uint32 int_req = 0; /* Interrupt request */
|
||||
|
||||
int32 PCX; /* External view of PC */
|
||||
|
@ -197,16 +197,17 @@ t_stat i8080_reset (DEVICE *dptr);
|
|||
/* external function prototypes */
|
||||
|
||||
extern t_stat i8080_reset (DEVICE *dptr);
|
||||
extern int32 get_mbyte(int32 addr);
|
||||
extern int32 get_mword(int32 addr);
|
||||
extern void put_mbyte(int32 addr, int32 val);
|
||||
extern void put_mword(int32 addr, int32 val);
|
||||
extern uint8 get_mbyte(uint16 addr);
|
||||
extern uint16 get_mword(uint16 addr);
|
||||
extern void put_mbyte(uint16 addr, uint8 val);
|
||||
extern void put_mword(uint16 addr, uint16 val);
|
||||
extern int32 sim_int_char;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
|
||||
|
||||
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
|
||||
|
@ -889,13 +890,15 @@ int32 sim_instr (void)
|
|||
|
||||
case 0xDB: /* IN */
|
||||
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;
|
||||
// sim_printf("\n%04X\tIN\t%02X\t;devnum=%d", PC - 1, DAR, dev_table[DAR].devnum);
|
||||
break;
|
||||
|
||||
case 0xD3: /* OUT */
|
||||
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;
|
||||
|
||||
default: /* undefined opcode */
|
||||
|
|
|
@ -119,16 +119,18 @@
|
|||
#define TXE 0x04
|
||||
#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 */
|
||||
|
||||
t_stat i8251_svc (UNIT *uptr);
|
||||
t_stat i8251_reset (DEVICE *dptr, int32 base);
|
||||
int32 i8251s(int32 io, int32 data);
|
||||
int32 i8251d(int32 io, int32 data);
|
||||
void i8251_reset1(void);
|
||||
t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
|
||||
uint8 i8251d(t_bool io, uint8 data, uint8 devnum);
|
||||
void i8251_reset1(uint8 devnum);
|
||||
|
||||
/* i8251 Standard I/O Data Structures */
|
||||
/* up to 1 i8251 devices */
|
||||
|
||||
UNIT i8251_unit = {
|
||||
UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT
|
||||
|
@ -142,20 +144,33 @@ REG i8251_reg[] = {
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
DEBTAB i8251_debug[] = {
|
||||
{ "ALL", DEBUG_all },
|
||||
{ "FLOW", DEBUG_flow },
|
||||
{ "READ", DEBUG_read },
|
||||
{ "WRITE", DEBUG_write },
|
||||
{ "XACK", DEBUG_xack },
|
||||
{ "LEV1", DEBUG_level1 },
|
||||
{ "LEV2", DEBUG_level2 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB i8251_mod[] = {
|
||||
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
|
||||
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
|
||||
|
||||
DEVICE i8251_dev = {
|
||||
"8251", //name
|
||||
&i8251_unit, //units
|
||||
i8251_reg, //registers
|
||||
i8251_mod, //modifiers
|
||||
1, //numunits
|
||||
10, //aradix
|
||||
31, //awidth
|
||||
16, //aradix
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -169,7 +184,7 @@ DEVICE i8251_dev = {
|
|||
NULL, //ctxt
|
||||
0, //flags
|
||||
0, //dctrl
|
||||
NULL, //debflags
|
||||
i8251_debug, //debflags
|
||||
NULL, //msize
|
||||
NULL //lname
|
||||
};
|
||||
|
@ -196,14 +211,18 @@ t_stat i8251_svc (UNIT *uptr)
|
|||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8251_reset (DEVICE *dptr, int32 base)
|
||||
t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum)
|
||||
{
|
||||
reg_dev(i8251d, base);
|
||||
reg_dev(i8251s, base + 1);
|
||||
reg_dev(i8251d, base + 2);
|
||||
reg_dev(i8251s, base + 3);
|
||||
i8251_reset1();
|
||||
sim_printf(" 8251: Registered at %02X\n", base);
|
||||
if (devnum >= I8251_NUM) {
|
||||
sim_printf("8251_reset: Illegal Device Number %d\n", devnum);
|
||||
return 0;
|
||||
}
|
||||
reg_dev(i8251d, base, devnum);
|
||||
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 */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -212,28 +231,36 @@ t_stat i8251_reset (DEVICE *dptr, int32 base)
|
|||
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);
|
||||
if (io == 0) { /* read status port */
|
||||
return i8251_unit.u3;
|
||||
} else { /* write status port */
|
||||
if (i8251_unit.u6) { /* if mode, set cmd */
|
||||
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! */
|
||||
i8251_reset1();
|
||||
i8251_reset1(devnum);
|
||||
} else { /* set mode */
|
||||
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 */
|
||||
}
|
||||
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 */
|
||||
i8251_unit.u3 &= ~RXR;
|
||||
return (i8251_unit.buf);
|
||||
|
@ -243,7 +270,7 @@ int32 i8251d(int32 io, int32 data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void i8251_reset1(void)
|
||||
void i8251_reset1(uint8 devnum)
|
||||
{
|
||||
i8251_unit.u3 = TXR + TXE; /* status */
|
||||
i8251_unit.u4 = 0; /* mode instruction */
|
||||
|
@ -251,7 +278,7 @@ void i8251_reset1(void)
|
|||
i8251_unit.u6 = 0;
|
||||
i8251_unit.buf = 0;
|
||||
i8251_unit.pos = 0;
|
||||
sim_printf(" 8251: Reset\n");
|
||||
sim_printf(" 8251-%d: Reset\n", devnum);
|
||||
}
|
||||
|
||||
/* end of i8251.c */
|
||||
|
|
|
@ -76,38 +76,23 @@
|
|||
*/
|
||||
|
||||
#include "system_defs.h" /* system header in system dir */
|
||||
#define i8255_DEV 4 /* number of devices */
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
int32 i8255s0(int32 io, int32 data); /* i8255 0 */
|
||||
int32 i8255a0(int32 io, int32 data);
|
||||
int32 i8255b0(int32 io, int32 data);
|
||||
int32 i8255c0(int32 io, int32 data);
|
||||
int32 i8255s1(int32 io, int32 data); /* i8255 1 */
|
||||
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);
|
||||
uint8 i8255s0(t_bool io, uint8 data, uint8 devnum); /* i8255*/
|
||||
uint8 i8255a0(t_bool io, uint8 data, uint8 devnum);
|
||||
uint8 i8255b0(t_bool io, uint8 data, uint8 devnum);
|
||||
uint8 i8255c0(t_bool io, uint8 data, uint8 devnum);
|
||||
t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
|
||||
/* 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 */
|
||||
|
||||
int32 i8255_cnt = 0;
|
||||
uint8 i8255_base[i8255_DEV];
|
||||
|
||||
/* i8255 Standard I/O Data Structures */
|
||||
/* up to 4 i8255 devices */
|
||||
|
||||
UNIT i8255_unit[] = {
|
||||
{ UDATA (0, 0, 0) }, /* i8255 0 */
|
||||
|
@ -116,17 +101,6 @@ UNIT i8255_unit[] = {
|
|||
{ 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[] = {
|
||||
{ HRDATA (CONTROL0, i8255_unit[0].u3, 8) }, /* i8255 0 */
|
||||
{ HRDATA (PORTA0, i8255_unit[0].u4, 8) },
|
||||
|
@ -147,6 +121,19 @@ REG i8255_reg[] = {
|
|||
{ 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 = {
|
||||
"8255", //name
|
||||
i8255_unit, //units
|
||||
|
@ -154,7 +141,7 @@ DEVICE i8255_dev = {
|
|||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
32, //awidth
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -177,296 +164,99 @@ DEVICE i8255_dev = {
|
|||
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 */
|
||||
return i8255_unit[0].u3;
|
||||
return i8255_unit[devnum].u3;
|
||||
} else { /* write status port */
|
||||
if (data & 0x80) { /* mode instruction */
|
||||
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)
|
||||
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[0].u6 |= (0x01 << bit);
|
||||
i8255_unit[devnum].u6 |= (0x01 << bit);
|
||||
} else { /* reset bit */
|
||||
i8255_unit[0].u6 &= ~(0x01 << bit);
|
||||
i8255_unit[devnum].u6 &= ~(0x01 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 */
|
||||
return (i8255_unit[0].u4);
|
||||
return (i8255_unit[devnum].u4);
|
||||
} else { /* write data port */
|
||||
i8255_unit[0].u4 = data;
|
||||
sim_printf("8255-0: Port A = %02X\n", data);
|
||||
i8255_unit[devnum].u4 = data;
|
||||
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
|
||||
}
|
||||
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 */
|
||||
return (i8255_unit[0].u5);
|
||||
return (i8255_unit[devnum].u5);
|
||||
} else { /* write data port */
|
||||
i8255_unit[0].u5 = data;
|
||||
sim_printf("8255-0: Port B = %02X\n", data);
|
||||
i8255_unit[devnum].u5 = data;
|
||||
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
|
||||
}
|
||||
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 */
|
||||
return (i8255_unit[0].u6);
|
||||
return (i8255_unit[devnum].u6);
|
||||
} else { /* write data port */
|
||||
i8255_unit[0].u6 = data;
|
||||
sim_printf("8255-0: Port C = %02X\n", 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);
|
||||
i8255_unit[devnum].u6 = data;
|
||||
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8255_reset (DEVICE *dptr, int32 base)
|
||||
t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum)
|
||||
{
|
||||
switch (i8255_cnt) {
|
||||
case 0:
|
||||
reg_dev(i8255a0, base);
|
||||
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");
|
||||
if (devnum >= I8255_NUM) {
|
||||
sim_printf("8255_reset: Illegal Device Number %d\n", devnum);
|
||||
return 0;
|
||||
}
|
||||
sim_printf(" 8255-%d: Registered at %02X\n", i8255_cnt, base);
|
||||
i8255_cnt++;
|
||||
reg_dev(i8255a, base, devnum);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,41 +34,48 @@
|
|||
*/
|
||||
|
||||
#include "system_defs.h" /* system header in system dir */
|
||||
#define i8259_DEV 2 /* number of devices */
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
int32 i8259a0(int32 io, int32 data);
|
||||
int32 i8259b0(int32 io, int32 data);
|
||||
int32 i8259a1(int32 io, int32 data);
|
||||
int32 i8259b1(int32 io, int32 data);
|
||||
void i8259_dump(int32 dev);
|
||||
t_stat i8259_reset (DEVICE *dptr, int32 base);
|
||||
uint8 i8259a(t_bool io, uint8 data, uint8 devnum);
|
||||
uint8 i8259b(t_bool io, uint8 data, uint8 devnum);
|
||||
void i8259_dump(uint8 devnum);
|
||||
t_stat i8259_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
|
||||
/* 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 */
|
||||
|
||||
int32 i8259_cnt = 0;
|
||||
uint8 i8259_base[i8259_DEV];
|
||||
uint8 i8259_icw1[i8259_DEV];
|
||||
uint8 i8259_icw2[i8259_DEV];
|
||||
uint8 i8259_icw3[i8259_DEV];
|
||||
uint8 i8259_icw4[i8259_DEV];
|
||||
uint8 i8259_ocw1[i8259_DEV];
|
||||
uint8 i8259_ocw2[i8259_DEV];
|
||||
uint8 i8259_ocw3[i8259_DEV];
|
||||
int32 icw_num0 = 1, icw_num1 = 1;
|
||||
uint8 i8259_base[I8259_NUM];
|
||||
uint8 i8259_icw1[I8259_NUM];
|
||||
uint8 i8259_icw2[I8259_NUM];
|
||||
uint8 i8259_icw3[I8259_NUM];
|
||||
uint8 i8259_icw4[I8259_NUM];
|
||||
uint8 i8259_ocw1[I8259_NUM];
|
||||
uint8 i8259_ocw2[I8259_NUM];
|
||||
uint8 i8259_ocw3[I8259_NUM];
|
||||
uint8 icw_num0 = 1, icw_num1 = 1;
|
||||
|
||||
/* i8255 Standard I/O Data Structures */
|
||||
/* up to 2 i8259 devices */
|
||||
|
||||
UNIT i8259_unit[] = {
|
||||
{ UDATA (0, 0, 0) }, /* i8259 0 */
|
||||
{ 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[] = {
|
||||
{ "ALL", DEBUG_all },
|
||||
{ "FLOW", DEBUG_flow },
|
||||
|
@ -80,15 +87,7 @@ DEBTAB i8259_debug[] = {
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
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 }
|
||||
};
|
||||
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
|
||||
|
||||
DEVICE i8259_dev = {
|
||||
"8259", //name
|
||||
|
@ -97,7 +96,7 @@ DEVICE i8259_dev = {
|
|||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
32, //awidth
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -120,190 +119,116 @@ DEVICE i8259_dev = {
|
|||
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 ((i8259_ocw3[0] & 0x03) == 0x02)
|
||||
return (i8259_unit[0].u3); /* IRR */
|
||||
if ((i8259_ocw3[0] & 0x03) == 0x03)
|
||||
return (i8259_unit[0].u4); /* ISR */
|
||||
if ((i8259_ocw3[devnum] & 0x03) == 0x02)
|
||||
return (i8259_unit[devnum].u3); /* IRR */
|
||||
if ((i8259_ocw3[devnum] & 0x03) == 0x03)
|
||||
return (i8259_unit[devnum].u4); /* ISR */
|
||||
} else { /* write data port */
|
||||
if (data & 0x10) {
|
||||
icw_num0 = 1;
|
||||
}
|
||||
if (icw_num0 == 1) {
|
||||
i8259_icw1[0] = data; /* ICW1 */
|
||||
i8259_unit[0].u5 = 0x00; /* clear IMR */
|
||||
i8259_ocw3[0] = 0x02; /* clear OCW3, Sel IRR */
|
||||
i8259_icw1[devnum] = data; /* ICW1 */
|
||||
i8259_unit[devnum].u5 = 0x00; /* clear IMR */
|
||||
i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
|
||||
} else {
|
||||
switch (data & 0x18) {
|
||||
case 0: /* OCW2 */
|
||||
i8259_ocw2[0] = data;
|
||||
i8259_ocw2[devnum] = data;
|
||||
break;
|
||||
case 8: /* OCW3 */
|
||||
i8259_ocw3[0] = data;
|
||||
i8259_ocw3[devnum] = data;
|
||||
break;
|
||||
default:
|
||||
sim_printf("8259b-0: OCW Error %02X\n", data);
|
||||
sim_printf("8259a-%d: OCW Error %02X\n", devnum, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sim_printf("8259a-0: data = %02X\n", data);
|
||||
sim_printf("8259a-%d: data = %02X\n", devnum, data);
|
||||
icw_num0++; /* step ICW number */
|
||||
}
|
||||
i8259_dump(0);
|
||||
i8259_dump(devnum);
|
||||
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 ((i8259_ocw3[1] & 0x03) == 0x02)
|
||||
return (i8259_unit[1].u3); /* IRR */
|
||||
if ((i8259_ocw3[1] & 0x03) == 0x03)
|
||||
return (i8259_unit[1].u4); /* ISR */
|
||||
if ((i8259_ocw3[devnum] & 0x03) == 0x02)
|
||||
return (i8259_unit[devnum].u3); /* IRR */
|
||||
if ((i8259_ocw3[devnum] & 0x03) == 0x03)
|
||||
return (i8259_unit[devnum].u4); /* ISR */
|
||||
} else { /* write data port */
|
||||
if (data & 0x10) {
|
||||
icw_num1 = 1;
|
||||
}
|
||||
if (icw_num1 == 1) {
|
||||
i8259_icw1[1] = data; /* ICW1 */
|
||||
i8259_unit[1].u5 = 0x00; /* clear IMR */
|
||||
i8259_ocw3[1] = 0x02; /* clear OCW3, Sel IRR */
|
||||
i8259_icw1[devnum] = data; /* ICW1 */
|
||||
i8259_unit[devnum].u5 = 0x00; /* clear IMR */
|
||||
i8259_ocw3[devnum] = 0x02; /* clear OCW3, Sel IRR */
|
||||
} else {
|
||||
switch (data & 0x18) {
|
||||
case 0: /* OCW2 */
|
||||
i8259_ocw2[1] = data;
|
||||
i8259_ocw2[devnum] = data;
|
||||
break;
|
||||
case 8: /* OCW3 */
|
||||
i8259_ocw3[1] = data;
|
||||
i8259_ocw3[devnum] = data;
|
||||
break;
|
||||
default:
|
||||
sim_printf("8259b-1: OCW Error %02X\n", data);
|
||||
sim_printf("8259b-%d: OCW Error %02X\n", devnum, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sim_printf("8259a-1: data = %02X\n", data);
|
||||
sim_printf("8259b-%d: data = %02X\n", devnum, data);
|
||||
icw_num1++; /* step ICW number */
|
||||
}
|
||||
i8259_dump(1);
|
||||
i8259_dump(devnum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* i8259 1 functions */
|
||||
|
||||
int32 i8259b0(int32 io, int32 data)
|
||||
void i8259_dump(uint8 devnum)
|
||||
{
|
||||
if (io == 0) { /* read data port */
|
||||
return (i8259_unit[0].u5); /* IMR */
|
||||
} else { /* write data port */
|
||||
if (icw_num0 >= 2 && icw_num0 < 5) { /* ICW mode */
|
||||
switch (icw_num0) {
|
||||
case 2: /* ICW2 */
|
||||
i8259_icw2[0] = data;
|
||||
break;
|
||||
case 3: /* ICW3 */
|
||||
i8259_icw3[0] = data;
|
||||
break;
|
||||
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]);
|
||||
sim_printf("Device %d\n", devnum);
|
||||
sim_printf(" IRR = %02X\n", i8259_unit[devnum].u3);
|
||||
sim_printf(" ISR = %02X\n", i8259_unit[devnum].u4);
|
||||
sim_printf(" IMR = %02X\n", i8259_unit[devnum].u5);
|
||||
sim_printf(" ICW1 = %02X\n", i8259_icw1[devnum]);
|
||||
sim_printf(" ICW2 = %02X\n", i8259_icw2[devnum]);
|
||||
sim_printf(" ICW3 = %02X\n", i8259_icw3[devnum]);
|
||||
sim_printf(" ICW4 = %02X\n", i8259_icw4[devnum]);
|
||||
sim_printf(" OCW1 = %02X\n", i8259_ocw1[devnum]);
|
||||
sim_printf(" OCW2 = %02X\n", i8259_ocw2[devnum]);
|
||||
sim_printf(" OCW3 = %02X\n", i8259_ocw3[devnum]);
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat i8259_reset (DEVICE *dptr, int32 base)
|
||||
t_stat i8259_reset (DEVICE *dptr, uint16 base, uint8 devnum)
|
||||
{
|
||||
switch (i8259_cnt) {
|
||||
case 0:
|
||||
reg_dev(i8259a0, base);
|
||||
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;
|
||||
if (devnum >= I8259_NUM) {
|
||||
sim_printf("8259_reset: Illegal Device Number %d\n", devnum);
|
||||
return 0;
|
||||
}
|
||||
sim_printf(" 8259-%d: Registered at %02X\n", i8259_cnt, base);
|
||||
i8259_cnt++;
|
||||
reg_dev(i8259a, base, devnum);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ DEBTAB i8273_debug[] = {
|
|||
};
|
||||
|
||||
DEVICE i8273_dev = {
|
||||
"8251", //name
|
||||
"8273", //name
|
||||
&i8273_unit, //units
|
||||
i8273_reg, //registers
|
||||
i8273_mod, //modifiers
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
|
||||
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
|
||||
code image.
|
||||
|
||||
Unit will support a single 2708, 2716, 2732 and 2764 type EPROMs.
|
||||
code image. Unit will support a single 2708, 2716, 2732, or 2764 type EPROM.
|
||||
These functions also support bit 1 of 8255 number 1, port B, to enable/
|
||||
disable the onboard ROM.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
@ -45,10 +45,12 @@
|
|||
/* function prototypes */
|
||||
|
||||
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat EPROM_reset (DEVICE *dptr, int32 size);
|
||||
int32 EPROM_get_mbyte(uint32 addr);
|
||||
t_stat EPROM_reset (DEVICE *dptr, uint16 size);
|
||||
uint8 EPROM_get_mbyte(uint16 addr);
|
||||
|
||||
extern UNIT i8255_unit;
|
||||
/* external function prototypes */
|
||||
|
||||
extern UNIT i8255_unit[];
|
||||
extern uint8 xack; /* XACK signal */
|
||||
|
||||
/* SIMH EPROM Standard I/O Data Structures */
|
||||
|
@ -75,7 +77,7 @@ DEVICE EPROM_dev = {
|
|||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
32, //awidth
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -147,7 +149,7 @@ t_stat EPROM_attach (UNIT *uptr, CONST char *cptr)
|
|||
|
||||
/* 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);
|
||||
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 */
|
||||
|
||||
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);
|
||||
if (addr < EPROM_unit.capac) {
|
||||
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:
|
||||
|
||||
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"
|
||||
|
@ -41,11 +43,13 @@
|
|||
/* function prototypes */
|
||||
|
||||
t_stat RAM_svc (UNIT *uptr);
|
||||
t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size);
|
||||
int32 RAM_get_mbyte(int32 addr);
|
||||
void RAM_put_mbyte(int32 addr, int32 val);
|
||||
t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
|
||||
uint8 RAM_get_mbyte(uint16 addr);
|
||||
void RAM_put_mbyte(uint16 addr, uint8 val);
|
||||
|
||||
extern UNIT i8255_unit;
|
||||
/* external function prototypes */
|
||||
|
||||
extern UNIT i8255_unit[];
|
||||
extern uint8 xack; /* XACK signal */
|
||||
|
||||
/* SIMH RAM Standard I/O Data Structures */
|
||||
|
@ -70,7 +74,7 @@ DEVICE RAM_dev = {
|
|||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
32, //awidth
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -95,7 +99,7 @@ DEVICE RAM_dev = {
|
|||
|
||||
/* 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);
|
||||
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 */
|
||||
|
||||
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);
|
||||
if ((addr >= RAM_unit.u3) && ((uint32) addr < (RAM_unit.u3 + RAM_unit.capac))) {
|
||||
SET_XACK(1); /* good memory address */
|
||||
|
@ -140,9 +144,9 @@ int32 RAM_get_mbyte(int32 addr)
|
|||
|
||||
/* 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);
|
||||
if ((addr >= RAM_unit.u3) && ((uint32)addr < RAM_unit.u3 + RAM_unit.capac)) {
|
||||
SET_XACK(1); /* good memory address */
|
||||
|
|
|
@ -42,10 +42,8 @@
|
|||
/* 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);
|
||||
uint8 isbc064_get_mbyte(uint16 addr);
|
||||
void isbc064_put_mbyte(uint16 addr, uint8 val);
|
||||
|
||||
extern uint8 xack; /* XACK signal */
|
||||
|
||||
|
@ -73,7 +71,7 @@ DEVICE isbc064_dev = {
|
|||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
8, //awidth
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -118,9 +116,9 @@ t_stat isbc064_reset (DEVICE *dptr)
|
|||
|
||||
/* 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;
|
||||
|
||||
if ((isbc064_dev.flags & DEV_DIS) == 0) {
|
||||
|
@ -143,22 +141,11 @@ int32 isbc064_get_mbyte(int32 addr)
|
|||
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)
|
||||
void isbc064_put_mbyte(uint16 addr, uint8 val)
|
||||
{
|
||||
int32 org, len;
|
||||
uint32 org, len;
|
||||
int i = 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");
|
||||
}
|
||||
|
||||
/* 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,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"
|
||||
|
||||
/* 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);
|
||||
uint8 get_mbyte(uint16 addr);
|
||||
uint16 get_mword(uint16 addr);
|
||||
void put_mbyte(uint16 addr, uint8 val);
|
||||
void put_mword(uint16 addr, uint16 val);
|
||||
t_stat SBC_reset (DEVICE *dptr);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
|
||||
extern 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 uint8 multibus_get_mbyte(uint16 addr);
|
||||
extern void multibus_put_mbyte(uint16 addr, uint8 val);
|
||||
extern uint8 EPROM_get_mbyte(uint16 addr);
|
||||
extern uint8 RAM_get_mbyte(uint16 addr);
|
||||
extern void RAM_put_mbyte(uint16 addr, uint8 val);
|
||||
extern 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);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
extern t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
extern t_stat pata_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
|
||||
|
||||
/* SBC reset routine */
|
||||
|
||||
|
@ -86,9 +67,9 @@ 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);
|
||||
i8255_reset (NULL, I8255_BASE_0, 0);
|
||||
i8255_reset (NULL, I8255_BASE_1, 1);
|
||||
i8251_reset (NULL, I8251_BASE, 0);
|
||||
EPROM_reset (NULL, ROM_SIZE);
|
||||
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
|
||||
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 */
|
||||
|
||||
int32 get_mbyte(int32 addr)
|
||||
uint8 get_mbyte(uint16 addr)
|
||||
{
|
||||
/* 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))) {
|
||||
return EPROM_get_mbyte(addr);
|
||||
}
|
||||
} /* 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))) {
|
||||
return RAM_get_mbyte(addr);
|
||||
}
|
||||
|
@ -114,9 +95,9 @@ int32 get_mbyte(int32 addr)
|
|||
|
||||
/* 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+1) << 8);
|
||||
|
@ -125,14 +106,14 @@ int32 get_mword(int32 addr)
|
|||
|
||||
/* 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 ((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);
|
||||
return;
|
||||
} /* 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);
|
||||
return;
|
||||
} /* otherwise, try the multibus */
|
||||
|
@ -141,9 +122,9 @@ void put_mbyte(int32 addr, int32 val)
|
|||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,61 +23,39 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from William A. Beech.
|
||||
|
||||
NOTES:
|
||||
|
||||
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
|
||||
Computer Systems.
|
||||
|
||||
?? ??? 10 - Original file.
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
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 i80_10_reset (DEVICE *dptr);
|
||||
uint8 get_mbyte(uint16 addr);
|
||||
uint16 get_mword(uint16 addr);
|
||||
void put_mbyte(uint16 addr, uint8 val);
|
||||
void put_mword(uint16 addr, uint16 val);
|
||||
t_stat SBC_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 uint8 multibus_get_mbyte(uint16 addr);
|
||||
extern void multibus_put_mbyte(uint16 addr, uint8 val);
|
||||
extern uint8 EPROM_get_mbyte(uint16 addr);
|
||||
extern uint8 RAM_get_mbyte(uint16 addr);
|
||||
extern void RAM_put_mbyte(uint16 addr, uint8 val);
|
||||
extern UNIT i8255_unit;
|
||||
extern UNIT EPROM_unit;
|
||||
extern UNIT RAM_unit;
|
||||
extern t_stat i8251_reset (DEVICE *dptr, int32 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, int32 base);
|
||||
extern t_stat i8259_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);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
extern t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
extern t_stat i8259_reset (DEVICE *dptr, uint16 base, uint8 devnum);
|
||||
extern t_stat pata_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
|
||||
|
||||
/* CPU reset routine
|
||||
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");
|
||||
i8080_reset(NULL);
|
||||
i8259_reset(NULL, I8259_BASE);
|
||||
i8255_reset(NULL, I8255_BASE_0);
|
||||
i8255_reset(NULL, I8255_BASE_1);
|
||||
i8251_reset(NULL, I8251_BASE);
|
||||
i8259_reset(NULL, I8259_BASE, 0);
|
||||
i8255_reset(NULL, I8255_BASE_0, 0);
|
||||
i8255_reset(NULL, I8255_BASE_1, 1);
|
||||
i8251_reset(NULL, I8251_BASE, 0);
|
||||
EPROM_reset(NULL, ROM_SIZE);
|
||||
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
|
||||
return SCPE_OK;
|
||||
|
@ -97,10 +75,8 @@ t_stat SBC_reset (DEVICE *dptr)
|
|||
|
||||
/* 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 ((i8255_unit.u5 & 0x01) && /* EPROM enabled? */
|
||||
(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 */
|
||||
|
||||
int32 get_mword(int32 addr)
|
||||
uint16 get_mword(uint16 addr)
|
||||
{
|
||||
int32 val;
|
||||
uint16 val;
|
||||
|
||||
val = get_mbyte(addr);
|
||||
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 */
|
||||
|
||||
void put_mbyte(int32 addr, int32 val)
|
||||
void put_mbyte(uint16 addr, uint8 val)
|
||||
{
|
||||
/* if local EPROM handle it */
|
||||
if ((i8255_unit.u5 & 0x01) && /* EPROM enabled? */
|
||||
|
@ -144,9 +120,9 @@ void put_mbyte(int32 addr, int32 val)
|
|||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,66 +27,78 @@
|
|||
Computer Systems.
|
||||
|
||||
?? ??? 10 - Original file.
|
||||
17 May 16 - Modified for the iSBC 80/30 Processor Card.
|
||||
*/
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
/* 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 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
|
||||
|
||||
/* set the base I/O address for the second 8255 */
|
||||
#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 */
|
||||
/* set the base and size for the EPROM */
|
||||
#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 the base and size for the RAM */
|
||||
#define RAM_BASE 0x4000
|
||||
#define RAM_SIZE 0x2000
|
||||
|
||||
/* 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);
|
||||
uint16 get_mbyte(uint16 addr);
|
||||
uint8 get_mword(uint16 addr);
|
||||
void put_mbyte(uint16 addr, uint8 val);
|
||||
void put_mword(uint16 addr, uint16 val);
|
||||
t_stat i80_10_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 t_stat i8080_reset (DEVICE *dptr); /* reset the 8085 emulator */
|
||||
extern int32 multibus_get_mbyte(uint16 addr);
|
||||
extern void multibus_put_mbyte(uint16 addr, uint8 val);
|
||||
extern int32 EPROM_get_mbyte(uint16 addr);
|
||||
extern int32 RAM_get_mbyte(uint16 addr);
|
||||
extern void RAM_put_mbyte(uint16, uint8 val);
|
||||
extern UNIT i8251_unit;
|
||||
extern UNIT i8253_unit;
|
||||
extern UNIT i8255_unit;
|
||||
extern UNIT i8259_unit;
|
||||
extern UNIT EPROM_unit;
|
||||
extern UNIT RAM_unit;
|
||||
extern t_stat i8251_reset (DEVICE *dptr, int32 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, int32 base);
|
||||
extern t_stat i8259_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);
|
||||
extern t_stat i8259_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8253_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8255_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat i8251_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat pata_reset (DEVICE *dptr, uint16 base);
|
||||
extern t_stat EPROM_reset (DEVICE *dptr, uint16 size);
|
||||
extern t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size);
|
||||
|
||||
/* CPU reset routine
|
||||
put here to cause a reset of the entire iSBC system */
|
||||
|
||||
t_stat SBC_reset (DEVICE *dptr)
|
||||
{
|
||||
sim_printf("Initializing iSBC-80/20\n");
|
||||
sim_printf("Initializing iSBC-80/30\n");
|
||||
i8080_reset(NULL);
|
||||
i8259_reset(NULL, I8259_BASE);
|
||||
i8253_reset(NULL, I8253_BASE);
|
||||
i8255_reset(NULL, I8255_BASE_0);
|
||||
i8255_reset(NULL, I8255_BASE_1);
|
||||
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 */
|
||||
|
||||
int32 get_mbyte(int32 addr)
|
||||
uint8 get_mbyte(uint16 addr)
|
||||
{
|
||||
int32 val, org, len;
|
||||
|
||||
|
@ -113,7 +125,7 @@ int32 get_mbyte(int32 addr)
|
|||
|
||||
/* get a word from memory */
|
||||
|
||||
int32 get_mword(int32 addr)
|
||||
uint16 get_mword(uint16 addr)
|
||||
{
|
||||
int32 val;
|
||||
|
||||
|
@ -124,7 +136,7 @@ int32 get_mword(int32 addr)
|
|||
|
||||
/* 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 ((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 */
|
||||
|
||||
void put_mword(int32 addr, int32 val)
|
||||
void put_mword(uint16 addr, uint16 val)
|
||||
{
|
||||
put_mbyte(addr, val);
|
||||
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);
|
||||
void set_irq(int32 int_num);
|
||||
void clr_irq(int32 int_num);
|
||||
int32 nulldev(int32 io, int32 data);
|
||||
int32 reg_dev(int32 (*routine)(int32, int32), int32 port);
|
||||
uint8 nulldev(t_bool io, uint8 data, uint8 devnum);
|
||||
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum);
|
||||
t_stat multibus_reset (DEVICE *dptr);
|
||||
int32 multibus_get_mbyte(int32 addr);
|
||||
int32 multibus_get_mword(int32 addr);
|
||||
void multibus_put_mbyte(int32 addr, int32 val);
|
||||
void multibus_put_mword(int32 addr, int32 val);
|
||||
uint8 multibus_get_mbyte(uint16 addr);
|
||||
void multibus_put_mbyte(uint16 addr, uint8 val);
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */
|
||||
extern int32 isbc064_get_mbyte(int32 addr);
|
||||
extern void isbc064_put_mbyte(int32 addr, int32 val);
|
||||
extern uint8 isbc064_get_mbyte(uint16 addr);
|
||||
extern void isbc064_put_mbyte(uint16 addr, uint8 val);
|
||||
extern void set_cpuint(int32 int_num);
|
||||
extern t_stat SBC_reset (DEVICE *dptr);
|
||||
extern t_stat isbc064_reset (DEVICE *dptr);
|
||||
|
@ -99,7 +97,7 @@ DEVICE multibus_dev = {
|
|||
NULL, //modifiers
|
||||
1, //numunits
|
||||
16, //aradix
|
||||
32, //awidth
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
16, //dradix
|
||||
8, //dwidth
|
||||
|
@ -163,10 +161,11 @@ void clr_irq(int32 int_num)
|
|||
|
||||
/* This is the I/O configuration table. There are 256 possible
|
||||
device addresses, if a device is plugged to a port it's routine
|
||||
address is here, 'nulldev' means no device is available
|
||||
address is here, 'nulldev' means no device has been registered.
|
||||
*/
|
||||
struct idev {
|
||||
int32 (*routine)(int32, int32);
|
||||
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
|
||||
uint8 devnum;
|
||||
};
|
||||
|
||||
struct idev dev_table[256] = {
|
||||
|
@ -236,7 +235,7 @@ struct idev dev_table[256] = {
|
|||
{&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 */
|
||||
if (flag == 0) /* if we got here, no valid I/O device */
|
||||
|
@ -244,40 +243,30 @@ int32 nulldev(int32 flag, int32 data)
|
|||
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 */
|
||||
// sim_printf("Multibus: I/O Port %02X is already assigned\n", port);
|
||||
} else {
|
||||
// sim_printf("Port %02X is assigned\n", port);
|
||||
dev_table[port].routine = routine;
|
||||
dev_table[port].devnum = devnum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get a byte from memory */
|
||||
|
||||
int32 multibus_get_mbyte(int32 addr)
|
||||
uint8 multibus_get_mbyte(uint16 addr)
|
||||
{
|
||||
SET_XACK(0); /* set no XACK */
|
||||
// sim_printf("multibus_get_mbyte: Cleared XACK for %04X\n", 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 */
|
||||
|
||||
void multibus_put_mbyte(int32 addr, int32 val)
|
||||
void multibus_put_mbyte(uint16 addr, uint8 val)
|
||||
{
|
||||
SET_XACK(0); /* set no XACK */
|
||||
// sim_printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr);
|
||||
|
@ -285,13 +274,5 @@ void multibus_put_mbyte(int32 addr, int32 val)
|
|||
// 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 */
|
||||
|
||||
|
|
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.
|
||||
|
||||
?? ??? 10 - Original file.
|
||||
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
|
||||
*/
|
||||
|
||||
#include <stdio.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 */
|
||||
|
||||
/* 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 */
|
||||
|
||||
#define INT_0 0x01
|
||||
|
|
|
@ -24,14 +24,46 @@
|
|||
in this Software without prior written authorization from William A. Beech.
|
||||
|
||||
?? ??? 10 - Original file.
|
||||
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "isys8020_cfg.h" /* Intel System 80/20 configuration */
|
||||
#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 */
|
||||
|
||||
#define INT_0 0x01
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Intel-Systems\common\iSBC80-10.c"
|
||||
RelativePath="..\Intel-Systems\common\isbc80-20.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
|
Loading…
Add table
Reference in a new issue