ISYS80XX, IMDS-225: Extended device functions and debug cleanup

a)  Added sim_debug statements, formatted console messages.
b) Removed old debugging statements and redundant byte/word mask operations.
c) Added more device commands.
d) Added zx-200a and changed nulldev to return 0 vice 0xff.
e) Added commands and corrected RTYPE and RBYTE behavior so ISIS-II would boot.
f) Corrected device calls in SBC_reset, corrected get_mbyte and put_mbyte to
   match control bits from ipc_cont.c.
This commit is contained in:
Bill Beech 2017-01-11 16:08:14 -07:00
parent 9851a36dd8
commit 38668a25f1
21 changed files with 381 additions and 235 deletions

View file

@ -95,9 +95,9 @@
Thus, only writes need be checked against actual memory size.
4. Adding I/O devices. These modules must be modified:
altair_cpu.c add I/O service routines to dev_table
altair_sys.c add pointer to data structures in sim_devices
i8080.c - add I/O service routines to dev_table
isys80XX_sys.c - add pointer to data structures in sim_devices
system_defs.h - to define devices and addresses assigned to devices
?? ??? 11 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
@ -107,7 +107,6 @@
at the end of the routine.
17 Mar 13 - Modified to enable/disable trace based on start and stop
addresses.
*/
#include "system_defs.h"
@ -165,7 +164,7 @@ uint32 HL = 0; /* HL register pair */
uint32 SP = 0; /* Stack pointer */
uint32 saved_PC = 0; /* program counter */
uint32 IM = 0; /* Interrupt Mask Register */
uint8 xack = 0; /* XACK signal */
uint8 xack = 0; /* XACK signal */
uint32 int_req = 0; /* Interrupt request */
int32 PCX; /* External view of PC */
@ -220,7 +219,6 @@ address is here, 'nulldev' means no device is available
extern struct idev dev_table[];
/* CPU data structures
i8080_dev CPU device descriptor
i8080_unit CPU unit descriptor
i8080_reg CPU register list
@ -383,7 +381,6 @@ void set_cpuint(int32 int_num)
int_req |= int_num;
}
//FILE *fpd;
/* instruction simulator */
int32 sim_instr (void)
@ -403,10 +400,6 @@ int32 sim_instr (void)
while (reason == 0) { /* loop until halted */
// if (PC == 0x1000) { /* turn on debugging */
// i8080_dev.dctrl = DEBUG_asm + DEBUG_reg;
// reason = STOP_HALT;
// }
if (i8080_dev.dctrl & DEBUG_reg) {
dumpregs();
sim_printf("\n");
@ -418,7 +411,6 @@ int32 sim_instr (void)
}
if (int_req > 0) { /* interrupt? */
// sim_printf("\ni8080: int_req=%04X IM=%04X", int_req, IM);
if (uptr->flags & UNIT_8085) { /* 8085 */
if (int_req & ITRAP) { /* int */
push_word(PC);
@ -448,7 +440,6 @@ int32 sim_instr (void)
push_word(PC); /* do an RST 7 */
PC = 0x0038;
int_req &= ~INT_R;
// sim_printf("\ni8080: int_req=%04X", int_req);
}
}
} /* end interrupt */
@ -462,9 +453,6 @@ int32 sim_instr (void)
sim_interval--; /* countdown clock */
PCX = PC;
// fprintf(fpd, "%04X\n", PC);
// fflush(fpd);
if (uptr->flags & UNIT_TRACE) {
dumpregs();
sim_printf("\n");
@ -477,6 +465,7 @@ int32 sim_instr (void)
// continue;
}
// first instruction decode
if (OP == 0x76) { /* HLT Instruction*/
reason = STOP_HALT;
PC--;
@ -517,10 +506,9 @@ int32 sim_instr (void)
}
if ((OP & 0xF8) == 0xB8) { /* CMP */
DAR = A & 0xFF;
DAR = A;
DAR -= getreg(OP & 0x07);
setarith(DAR);
DAR &= BYTE_R;
goto loop_end;
}
@ -568,7 +556,7 @@ int32 sim_instr (void)
if ((OP & 0xF8) == 0x80) { /* ADD */
A += getreg(OP & 0x07);
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
goto loop_end;
}
@ -577,14 +565,14 @@ int32 sim_instr (void)
if (GET_FLAG(CF))
A++;
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
goto loop_end;
}
if ((OP & 0xF8) == 0x90) { /* SUB */
A -= getreg(OP & 0x07);
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
goto loop_end;
}
@ -593,7 +581,7 @@ int32 sim_instr (void)
if (GET_FLAG(CF))
A--;
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
goto loop_end;
}
@ -601,7 +589,6 @@ int32 sim_instr (void)
DAR = getreg((OP >> 3) & 0x07);
DAR++;
setinc(DAR);
// DAR &= BYTE_R;
putreg((OP >> 3) & 0x07, DAR);
goto loop_end;
}
@ -610,7 +597,6 @@ int32 sim_instr (void)
DAR = getreg((OP >> 3) & 0x07);
DAR--;
setinc(DAR);
// DAR &= BYTE_R;
putreg((OP >> 3) & 0x07, DAR);
goto loop_end;
}
@ -618,7 +604,6 @@ int32 sim_instr (void)
if ((OP & 0xCF) == 0x03) { /* INX */
DAR = getpair((OP >> 4) & 0x03);
DAR++;
// DAR &= WORD_R;
putpair((OP >> 4) & 0x03, DAR);
goto loop_end;
}
@ -626,7 +611,6 @@ int32 sim_instr (void)
if ((OP & 0xCF) == 0x0B) { /* DCX */
DAR = getpair((OP >> 4) & 0x03);
DAR--;
// DAR &= WORD_R;
putpair((OP >> 4) & 0x03, DAR);
goto loop_end;
}
@ -634,7 +618,7 @@ int32 sim_instr (void)
if ((OP & 0xCF) == 0x09) { /* DAD */
HL += getpair((OP >> 4) & 0x03);
COND_SET_FLAG(HL & 0x10000, CF);
HL &= WORD_R;
HL &= WORD_R; //required
goto loop_end;
}
@ -647,7 +631,6 @@ int32 sim_instr (void)
if ((OP & 0xF8) == 0xA8) { /* XRA */
A ^= getreg(OP & 0x07);
setlogical(A);
A &= BYTE_R;
goto loop_end;
}
@ -690,7 +673,6 @@ int32 sim_instr (void)
case 0xFE: /* CPI */
DAR = A;
DAR -= fetch_byte(1);
// DAR &= BYTE_R;
setarith(DAR);
break;
@ -701,7 +683,6 @@ int32 sim_instr (void)
case 0xEE: /* XRI */
A ^= fetch_byte(1);
// DAR &= BYTE_R;
setlogical(A);
break;
@ -734,34 +715,29 @@ int32 sim_instr (void)
case 0x32: /* STA */
DAR = fetch_word();
DAR &= WORD_R;
put_mbyte(DAR, A);
break;
case 0x3A: /* LDA */
DAR = fetch_word();
DAR &= WORD_R;
A = get_mbyte(DAR);
break;
case 0x22: /* SHLD */
DAR = fetch_word();
DAR &= WORD_R;
put_mword(DAR, HL);
break;
case 0x2A: /* LHLD */
DAR = fetch_word();
DAR &= WORD_R;
HL = get_mword(DAR);
break;
case 0xEB: /* XCHG */
DAR = HL;
HL = DE;
HL &= WORD_R;
HL &= WORD_R; //required
DE = DAR;
DE &= WORD_R;
break;
/* Arithmetic Group */
@ -769,7 +745,7 @@ int32 sim_instr (void)
case 0xC6: /* ADI */
A += fetch_byte(1);
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
break;
case 0xCE: /* ACI */
@ -777,20 +753,20 @@ int32 sim_instr (void)
if (GET_FLAG(CF))
A++;
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
break;
case 0xD6: /* SUI */
A -= fetch_byte(1);
setarith(A);
A &= BYTE_R;
A &= BYTE_R; //required
break;
case 0xDE: /* SBI */
A -= fetch_byte(1);
if (GET_FLAG(CF))
A--;
setarith(A);
A &= BYTE_R; //required
A &= BYTE_R;
break;
@ -820,7 +796,6 @@ int32 sim_instr (void)
A = (A << 1) & 0xFF;
if (GET_FLAG(CF))
A |= 0x01;
A &= BYTE_R;
break;
case 0x0F: /* RRC */
@ -828,7 +803,6 @@ int32 sim_instr (void)
A = (A >> 1) & 0xFF;
if (GET_FLAG(CF))
A |= 0x80;
A &= BYTE_R;
break;
case 0x17: /* RAL */
@ -837,7 +811,6 @@ int32 sim_instr (void)
A = (A << 1) & 0xFF;
if (DAR)
A |= 0x01;
A &= BYTE_R;
break;
case 0x1F: /* RAR */
@ -846,12 +819,10 @@ int32 sim_instr (void)
A = (A >> 1) & 0xFF;
if (DAR)
A |= 0x80;
A &= BYTE_R;
break;
case 0x2F: /* CMA */
A = ~A;
A &= BYTE_R;
break;
case 0x3F: /* CMC */
@ -871,7 +842,6 @@ int32 sim_instr (void)
DAR = pop_word();
push_word(HL);
HL = DAR;
HL &= WORD_R;
break;
case 0xF9: /* SPHL */
@ -880,29 +850,22 @@ int32 sim_instr (void)
case 0xFB: /* EI */
IM |= IE;
// sim_printf("\nEI: pc=%04X", PC - 1);
break;
case 0xF3: /* DI */
IM &= ~IE;
// sim_printf("\nDI: pc=%04X", PC - 1);
break;
case 0xDB: /* IN */
DAR = fetch_byte(1);
port = DAR;
//A = dev_table[DAR].routine(0, 0, dev_table[DAR].devnum);
A = dev_table[DAR].routine(0, 0);
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);
port = DAR;
//dev_table[DAR].routine(1, A, dev_table[DAR].devnum);
dev_table[DAR].routine(1, A);
// sim_printf("\n%04X\tOUT\t%02X\t;devnum=%d", PC - 1, DAR, dev_table[DAR].devnum);
break;
default: /* undefined opcode */
@ -913,18 +876,16 @@ int32 sim_instr (void)
break;
}
loop_end:
// if (GET_XACK(1) == 0) { /* no XACK for instruction fetch */
if (GET_XACK(1) == 0) { /* no XACK for instruction fetch */
// reason = STOP_XACK;
// sim_printf("Stopped for XACK-2 PC=%04X\n", PC);
// continue;
// }
;
}
}
/* Simulation halted */
saved_PC = PC;
// fclose(fpd);
return reason;
}
@ -1094,8 +1055,6 @@ int32 getreg(int32 reg)
{
switch (reg) {
case 0: /* reg B */
// sim_printf("reg=%04X BC=%04X ret=%04X\n",
// reg, BC, (BC >>8) & 0xff);
return ((BC >>8) & BYTE_R);
case 1: /* reg C */
return (BC & BYTE_R);
@ -1122,9 +1081,7 @@ void putreg(int32 reg, int32 val)
{
switch (reg) {
case 0: /* reg B */
// sim_printf("reg=%04X val=%04X\n", reg, val);
BC = BC & BYTE_R;
// sim_printf("BC&0x00ff=%04X val<<8=%04X\n", BC, val<<8);
BC = BC | (val <<8);
break;
case 1: /* reg C */
@ -1255,7 +1212,6 @@ t_stat i8080_reset (DEVICE *dptr)
IM = 0;
sim_brk_types = sim_brk_dflt = SWMASK ('E');
sim_printf(" 8080: Reset\n");
// fpd = fopen("trace.txt", "w");
return SCPE_OK;
}
@ -1301,7 +1257,6 @@ int32 sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
}
/* Symbolic output - working
Inputs:
*of = output stream
addr = current PC
@ -1350,7 +1305,6 @@ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC

View file

@ -205,8 +205,8 @@ BORROW CHAIN CALCULATION.
#define UNIT_V_OPSTOP (UNIT_V_UF) /* Stop on Invalid OP? */
#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP)
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8088 or 8086 */
#define UNIT_CHIP (1 << UNIT_V_CHIP)
#define UNIT_V_8088 (UNIT_V_UF+1) /* 8088 or 8086 */
#define UNIT_8088 (1 << UNIT_V_8088)
/* Flag values to set proper positions in PSW */
#define CF 0x0001
@ -429,8 +429,8 @@ REG i8088_reg[] = {
};
MTAB i8088_mod[] = {
{ UNIT_CHIP, UNIT_CHIP, "8086", "8086", NULL },
{ UNIT_CHIP, 0, "8088", "8088", NULL },
{ UNIT_8088, UNIT_8088, "8086", "8086", NULL },
{ UNIT_8088, 0, "8088", "8088", NULL },
{ UNIT_OPSTOP, UNIT_OPSTOP, "ITRAP", "ITRAP", NULL },
{ UNIT_OPSTOP, 0, "NOITRAP", "NOITRAP", NULL },
{ 0 }
@ -626,7 +626,7 @@ int32 sim_instr (void)
case 0x00: /* ADD byte - REG = REG + (EA) */
MRR = fetch_byte(1);
get_mrr_dec(MRR, &MOD, &REG, &RM);
if (MOD != 0x3) { /* based, indexed, or based indexed addressing */ /* based, indexed, or based indexed addressing */
if (MOD != 0x3) { /* based, indexed, or based indexed addressing */
EA = get_ea(MRR); /* get effective address */
VAL = add_byte(get_rbyte(REG), get_smbyte(seg_reg, EA)); /* do operation */
put_rbyte(REG, VAL); /* store result */
@ -1500,7 +1500,7 @@ int32 sim_instr (void)
VAL = add_byte(get_smbyte(seg_reg, EA), DATA); /* ADD mem8, immed8 */
break;
case 1:
VAL = or_byte(get_smbyte(seg_reg, EA), DATA); /* OR mem8, immed8 */
VAL = or_byte(get_smbyte(seg_reg, EA), DATA); /* OR mem8, immed8 */
break;
case 2:
VAL = adc_byte(get_smbyte(seg_reg, EA), DATA); /* ADC mem8, immed8 */
@ -1996,7 +1996,7 @@ int32 sim_instr (void)
break;
case 0x9A: /* CALL FAR proc */
OFF = fetch_word(); /* do operation */
OFF = fetch_word(); /* do operation */
SEG = fetch_word();
push_word(CS);
CS = SEG;
@ -3133,8 +3133,7 @@ int32 sim_instr (void)
}
}
/* Simulation halted */
/* Simulation halted */
saved_PC = IP;
return reason;
}
@ -3439,7 +3438,7 @@ void get_mrr_dec(uint32 mrr, uint32 *mod, uint32 *reg, uint32 *rm)
}
/*
Most of the primitive algorythms were pulled from the GDE Dos/IP Emulator by Jim Hudgens
Most of the primitive algorithms were pulled from the GDE Dos/IP Emulator by Jim Hudgens
*/
/* aad primitive */

View file

@ -111,6 +111,8 @@
#include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
@ -226,11 +228,11 @@ t_stat i8251_svc (UNIT *uptr)
t_stat i8251_reset (DEVICE *dptr, uint16 baseport)
{
if (i8251_devnum >= I8251_NUM) {
sim_printf("8251_reset: Illegal Device Number %d\n", i8251_devnum);
return 0;
sim_printf("i8251_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8251-%d: Hardware Reset\n", i8251_devnum);
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, baseport);
sim_printf(" 8251-%d: Hardware Reset\n", i8251_devnum);
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, baseport);
i8251_port[i8251_devnum] = baseport;
reg_dev(i8251d, baseport, i8251_devnum);
reg_dev(i8251s, baseport + 1, i8251_devnum);
@ -248,7 +250,7 @@ void i8251_reset1(uint8 devnum)
i8251_unit.u6 = 0;
i8251_unit.buf = 0;
i8251_unit.pos = 0;
sim_printf(" 8251-%d: Software Reset\n", devnum);
sim_printf(" 8251-%d: Software Reset\n", devnum);
}
uint8 i8251_get_dn(void)
@ -277,12 +279,14 @@ uint8 i8251s(t_bool io, uint8 data)
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8251_reset1(devnum);
} else { /* set mode */
i8251_unit.u4 = data;
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */
}
}

View file

@ -35,6 +35,8 @@
#include "system_defs.h"
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
@ -179,14 +181,19 @@ uint8 i8253t0(t_bool io, uint8 data)
if (io == 0) { /* read data port */
return i8253_unit[devnum].u3;
} else { /* write data port */
sim_printf(" 8253-%d: Timer 0=%02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8253-%d: Timer 0=%02X\n", devnum, data);
i8253_unit[devnum].u3 = data;
//sim_activate_after (&i8253_unit[devnum], );
return 0;
}
}
return 0;
}
//read routine:
//sim_activate_time(&i8253_unit[devnum])/sim_inst_per_second()
uint8 i8253t1(t_bool io, uint8 data)
{
uint8 devnum;
@ -195,7 +202,8 @@ uint8 i8253t1(t_bool io, uint8 data)
if (io == 0) { /* read data port */
return i8253_unit[devnum].u4;
} else { /* write data port */
sim_printf(" 8253-%d: Timer 1=%02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8253-%d: Timer 1=%02X\n", devnum, data);
i8253_unit[devnum].u4 = data;
return 0;
}
@ -211,7 +219,8 @@ uint8 i8253t2(t_bool io, uint8 data)
if (io == 0) { /* read data port */
return i8253_unit[devnum].u5;
} else { /* write data port */
sim_printf(" 8253-%d: Timer 2=%02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8253-%d: Timer 2=%02X\n", devnum, data);
i8253_unit[devnum].u5 = data;
return 0;
}
@ -228,7 +237,8 @@ uint8 i8253c(t_bool io, uint8 data)
return i8253_unit[devnum].u6;
} else { /* write data port */
i8253_unit[devnum].u6 = data;
sim_printf(" 8253-%d: Mode Instruction=%02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8253-%d: Mode Instruction=%02X\n", devnum, data);
return 0;
}
}

View file

@ -35,8 +35,8 @@
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
All I/O is via programmed I/O. The i8255 has a control port (i8255s)
and three data ports (i8255a, i8255b, and i8255c).
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
@ -77,6 +77,8 @@
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* external globals */
extern uint16 port; //port called in dev_table[port]
@ -85,10 +87,10 @@ extern uint16 port; //port called in dev_table[port]
t_stat i8255_reset (DEVICE *dptr, uint16 baseport);
uint8 i8255_get_dn(void);
uint8 i8255s(t_bool io, uint8 data);
uint8 i8255a(t_bool io, uint8 data);
uint8 i8255b(t_bool io, uint8 data);
uint8 i8255c(t_bool io, uint8 data);
uint8 i8255s(t_bool io, uint8 data);
/* external function prototypes */
@ -181,8 +183,8 @@ t_stat i8255_reset (DEVICE *dptr, uint16 baseport)
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8255-%d: Reset\n", i8255_devnum);
sim_printf(" 8255-%d: Registered at %04X\n", i8255_devnum, baseport);
sim_printf(" 8255-%d: Reset\n", i8255_devnum);
sim_printf(" 8255-%d: Registered at %04X\n", i8255_devnum, baseport);
i8255_port[i8255_devnum] = baseport;
reg_dev(i8255a, baseport, i8255_devnum);
reg_dev(i8255b, baseport + 1, i8255_devnum);
@ -220,11 +222,12 @@ uint8 i8255s(t_bool io, uint8 data)
if ((devnum = i8255_get_dn()) != 0xFF) {
if (io == 0) { /* read status port */
return i8255_unit[devnum].u3;
return 0xFF; //undefined
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[devnum].u3 = data;
sim_printf(" 8255-%d: Mode Instruction=%02X\n", devnum, data);
if (DEBUG)
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 */
@ -250,7 +253,8 @@ uint8 i8255a(t_bool io, uint8 data)
return (i8255_A[devnum]);
} else { /* write data port */
i8255_A[devnum] = data;
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8255-%d: Port A = %02X\n", devnum, data);
}
}
return 0;
@ -265,7 +269,8 @@ uint8 i8255b(t_bool io, uint8 data)
return (i8255_B[devnum]);
} else { /* write data port */
i8255_B[devnum] = data;
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8255-%d: Port B = %02X\n", devnum, data);
}
}
return 0;
@ -280,7 +285,8 @@ uint8 i8255c(t_bool io, uint8 data)
return (i8255_C[devnum]);
} else { /* write data port */
i8255_C[devnum] = data;
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8255-%d: Port C = %02X\n", devnum, data);
}
}
return 0;

View file

@ -35,6 +35,8 @@
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
/* function prototypes */
uint8 i8259a(t_bool io, uint8 data);
@ -140,8 +142,8 @@ DEVICE i8259_dev = {
t_stat i8259_reset (DEVICE *dptr, uint16 baseport)
{
if (i8259_devnum >= I8259_NUM) {
sim_printf("8259_reset: Illegal Device Number %d\n", i8259_devnum);
return 0;
sim_printf("i8255_reset: too many devices!\n");
return SCPE_MEM;
}
sim_printf(" 8259-%d: Reset\n", i8259_devnum);
sim_printf(" 8259-%d: Registered at %04X\n", i8259_devnum, baseport);
@ -199,7 +201,8 @@ uint8 i8259a(t_bool io, uint8 data)
break;
}
}
sim_printf(" 8259-%d: A data = %02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8259-%d: A data = %02X\n", devnum, data);
icw_num0++; /* step ICW number */
}
// i8259_dump(devnum);
@ -238,7 +241,8 @@ uint8 i8259b(t_bool io, uint8 data)
break;
}
}
sim_printf(" 8259-%d: B data = %02X\n", devnum, data);
if (DEBUG)
sim_printf(" 8259-%d: B data = %02X\n", devnum, data);
icw_num1++; /* step ICW number */
}
// i8259_dump(devnum);

View file

@ -61,11 +61,11 @@ uint8 i8251d(t_bool io, uint8 data);
/* globals */
int32 i8272_devnum = 0; //initially, no 8251 instances
uint16 i8272_port[4]; //base port assigned to each 8251 instance
int32 i8272_devnum = 0; //initially, no 8272 instances
uint16 i8272_port[4]; //base port assigned to each 8272 instance
/* i8251 Standard I/O Data Structures */
/* up to 1 i8251 devices */
/* i8272 Standard I/O Data Structures */
/* up to 4 i8282 devices */
UNIT i8272_unit[4] = {
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
@ -101,20 +101,20 @@ MTAB i8272_mod[] = {
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8272_dev = {
"I8272", //name
i8272_unit, //units
"I8272", //name
i8272_unit, //units
i8272_reg, //registers
i8272_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8272_reset, //reset
NULL, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
@ -128,7 +128,7 @@ DEVICE i8272_dev = {
/* Service routines to handle simulator functions */
/* i8272_svc - actually gets char & places in buffer */
/* i8272_svc - actually does FDD read and write */
t_stat i8272_svc(UNIT *uptr)
{
@ -225,4 +225,4 @@ uint8 i8251d(t_bool io, uint8 data)
return 0;
}
/* end of i8251.c */
/* end of i8272.c */

View file

@ -154,10 +154,10 @@ 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 */
EPROM_unit.capac = size; /* set EPROM size to 0 */
sim_printf(" EPROM: Configured, Not attached\n");
sim_printf(" EPROM: Configured, Not attached\n");
sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
} else {
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
sim_printf(" EPROM: Configured %d bytes, Attached to %s\n",
EPROM_unit.capac, EPROM_unit.filename);
}
sim_debug (DEBUG_flow, &EPROM_dev, "Done2\n");

View file

@ -34,9 +34,46 @@
#include "system_defs.h" /* system header in system dir */
#define DEBUG 0
//dbb status flag bits
#define OBF 1
#define IBF 2
#define F0 4
#define CD 8
//dbb command codes
#define PACIFY 0x00 //Resets IOC and its devices
#define ERESET 0x01 //Resets device-generated error (not used by standard devices)
#define SYSTAT 0x02 //Returns subsystem status byte to master
#define DSTAT 0x03 //Returns device status byte to master
#define SRQDAK 0x04 //Enables input of device interrupt acknowledge mask from master
#define SRQACK 0x05 //Clears IOC subsystem interrupt request
#define SRQ 0x06 //Tests ability of IOC to forward an interrupt request to the master
#define DECHO 0x07 //Tests ability of IOC to echo data byte sent by master
#define CSMEM 0x08 //Requests IOC to checksum on-board ROM. Returns pass/fail
#define TRAM 0x09 //Requests IOC to test on-board RAM. Returns pass/fail
#define SINT 0x0A //Enables specified device interrupt from IOC
#define CRTC 0x10 //Requests data byte output to the CRT monitor
#define CRTS 0x11 //Returns CRT status byte to master
#define KEYC 0x12 //Requests data byte input from the keyboard
#define KSTC 0x13 //Returns keyboard status byte to master
#define WPBC 0x15 //Enables input of first of five bytes that define current diskette operation
#define WPBCC 0x16 //Enables input of each of four bytes that follow WPBC
#define WDBC 0x17 //Enables input of diskette write bytes from master
#define RDBC 0x19 //Enables output of diskette read bytes to master
#define RRSTS 0x1B //Returns diskette result byte to master
#define RDSTS 0x1C //Returns diskette device status byte to master
/* external globals */
extern uint16 port; //port called in dev_table[port]
extern int32 PCX;
/* function prototypes */
uint8 ioc_cont(t_bool io, uint8 data); /* ioc_cont*/
uint8 ioc_cont0(t_bool io, uint8 data); /* ioc_cont*/
uint8 ioc_cont1(t_bool io, uint8 data); /* ioc_cont*/
t_stat ioc_cont_reset (DEVICE *dptr, uint16 baseport);
/* external function prototypes */
@ -46,6 +83,11 @@ extern uint32 saved_PC; /* program counter */
/* globals */
uint8 dbb_stat;
uint8 dbb_cmd;
uint8 dbb_in;
uint8 dbb_out;
UNIT ioc_cont_unit[] = {
{ UDATA (0, 0, 0) }, /* ioc_cont*/
};
@ -94,31 +136,97 @@ DEVICE ioc_cont_dev = {
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* Reset routine */
t_stat ioc_cont_reset(DEVICE *dptr, uint16 baseport)
{
sim_printf(" ioc_cont[%d]: Reset\n", 0);
sim_printf(" ioc_cont[%d]: Registered at %04X\n", 0, baseport);
reg_dev(ioc_cont, baseport, 0);
reg_dev(ioc_cont, baseport + 1, 0);
ioc_cont_unit[0].u3 = 0x00; /* ipc reset */
reg_dev(ioc_cont0, baseport, 0);
reg_dev(ioc_cont1, baseport + 1, 0);
dbb_stat = 0x00; /* clear DBB status */
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* IOC control port functions */
uint8 ioc_cont(t_bool io, uint8 data)
uint8 ioc_cont0(t_bool io, uint8 data)
{
if (io == 0) { /* read data port */
if (DEBUG)
sim_printf(" ioc_cont0: read data returned %02X PCX=%04X\n", dbb_out, PCX);
return dbb_out;
} else { /* write data port */
dbb_in = data;
dbb_stat |= IBF;
if (DEBUG)
sim_printf(" ioc_cont0: write data=%02X port=%02X PCX=%04X\n", dbb_in, port, PCX);
return 0;
}
}
uint8 ioc_cont1(t_bool io, uint8 data)
{
int temp;
if (io == 0) { /* read status port */
sim_printf(" ioc_cont: read data=%02X port=%02X returned 0x00 from PC=%04X\n", data, 0, saved_PC);
return 0x00;
} else { /* write control port */
sim_printf(" ioc_cont: data=%02X port=%02X\n", data, 0);
if ((dbb_stat & F0) && (dbb_stat & IBF)) {
temp = dbb_stat;
if (DEBUG)
sim_printf(" ioc_cont1: DBB status read 1 data=%02X PCX=%04X\n", dbb_stat, PCX);
dbb_stat &= ~IBF; //reset IBF flag
return temp;
}
if ((dbb_stat & F0) && (dbb_stat & OBF)) {
temp = dbb_stat;
if (DEBUG)
sim_printf(" ioc_cont1: DBB status read 2 data=%02X PCX=%04X\n", dbb_stat, PCX);
dbb_stat &= ~OBF; //reset OBF flag
return temp;
}
if (dbb_stat & F0) {
temp = dbb_stat;
if (DEBUG)
sim_printf(" ioc_cont1: DBB status read 3 data=%02X PCX=%04X\n", dbb_stat, PCX);
dbb_stat &= ~F0; //reset F0 flag
return temp;
}
// if (DEBUG)
// sim_printf(" ioc_cont1: DBB status read 4 data=%02X PCX=%04X\n", dbb_stat, PCX);
return dbb_stat;
} else { /* write command port */
dbb_cmd = data;
switch(dbb_cmd){
case PACIFY: //should delay 100 ms
dbb_stat = 0;
break;
case SYSTAT:
dbb_out = 0;
dbb_stat |= OBF;
dbb_stat &= ~CD;
break;
case CRTS:
dbb_out = 0;
dbb_stat |= F0;
break;
case KSTC:
dbb_out = 0;
dbb_stat |= F0;
break;
case RDSTS:
dbb_out = 0x80; //not ready
dbb_stat |= (F0 | IBF);
break;
default:
sim_printf(" ioc_cont1: Unknown command %02X PCX=%04X\n", dbb_cmd, PCX);
}
if (DEBUG)
sim_printf(" ioc_cont1: DBB command write data=%02X PCX=%04X\n", dbb_cmd, PCX);
return 0;
}
}

View file

@ -151,7 +151,7 @@ t_stat multibus_reset(DEVICE *dptr)
sim_printf(" Multibus: Reset\n");
zx200a_fdcnum = 0;
zx200a_reset(NULL, ZX200A_BASE_DD);
zx200a_reset(NULL, ZX200A_BASE_SD);
// zx200a_reset(NULL, ZX200A_BASE_SD);
isbc201_fdcnum = 0;
isbc201_reset(NULL, SBC201_BASE);
isbc202_fdcnum = 0;
@ -251,8 +251,7 @@ struct idev dev_table[256] = {
uint8 nulldev(t_bool flag, uint8 data)
{
SET_XACK(0); /* set no XACK */
if (flag == 0) /* if we got here, no valid I/O device */
return (0xFF);
// return 0xFF;
return 0;
}

View file

@ -96,7 +96,7 @@ DEVICE RAM_dev = {
t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size)
{
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1);
sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1);
if (RAM_unit.capac == 0) { /* if undefined */
RAM_unit.capac = size;
RAM_unit.u3 = base;
@ -108,7 +108,7 @@ t_stat RAM_reset (DEVICE *dptr, uint16 base, uint16 size)
return SCPE_MEM;
}
}
sim_printf(" RAM: Available [%04X-%04XH]\n",
sim_printf(" RAM: Available [%04X-%04XH]\n",
RAM_unit.u3,
RAM_unit.u3 + RAM_unit.capac - 1);
sim_debug (DEBUG_flow, &RAM_dev, "RAM_reset: Done\n");

View file

@ -76,13 +76,14 @@
07FH - Write - Reset diskette system.
Operations:
Recalibrate -
Seek -
Format Track -
Write Data -
Write Deleted Data -
Read Data -
Verify CRC -
NOP - 0x00
Seek - 0x01
Format Track - 0x02
Recalibrate - 0x03
Read Data - 0x04
Verify CRC - 0x05
Write Data - 0x06
Write Deleted Data - 0x07
IOPB - I/O Parameter Block
Byte 0 - Channel Word
@ -303,21 +304,21 @@ DEVICE isbc201_dev = {
t_stat isbc201_reset(DEVICE *dptr, uint16 base)
{
sim_printf("Initializing iSBC-201 FDC Board\n");
sim_printf(" iSBC-201 FDC Board");
if (SBC201_NUM) {
sim_printf(" isbc201-%d: Hardware Reset\n", isbc201_fdcnum);
sim_printf(" isbc201-%d: Registered at %04X\n", isbc201_fdcnum, base);
sim_printf(" - Found\n");
sim_printf(" isbc201-%d: Hardware Reset\n", isbc201_fdcnum);
sim_printf(" isbc201-%d: Registered at %04X\n", isbc201_fdcnum, base);
fdc201[isbc201_fdcnum].baseport = base;
reg_dev(isbc2010, base, isbc201_fdcnum); //read status
reg_dev(isbc2011, base + 1, isbc201_fdcnum); //read rslt type/write IOPB addr-l
reg_dev(isbc2012, base + 2, isbc201_fdcnum); //write IOPB addr-h and start
reg_dev(isbc2013, base + 3, isbc201_fdcnum); //read rstl byte
reg_dev(isbc2017 , base + 7, isbc201_fdcnum); //write reset isbc202
reg_dev(isbc2017, base + 7, isbc201_fdcnum); //write reset isbc202
isbc201_reset1(isbc201_fdcnum);
isbc201_fdcnum++;
} else {
sim_printf(" No isbc201 installed\n");
}
} else
sim_printf(" - Not Found\n");
return SCPE_OK;
}
@ -328,7 +329,7 @@ void isbc201_reset1(uint8 fdcnum)
int32 i;
UNIT *uptr;
sim_printf(" isbc201-%d: Software Reset\n", fdcnum);
sim_printf(" isbc201-%d: Software Reset\n", fdcnum);
fdc201[fdcnum].stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = isbc201_dev.units + i;
@ -339,7 +340,7 @@ void isbc201_reset1(uint8 fdcnum)
uptr->u5 = fdcnum; //fdc device number
uptr->u6 = i; //fdd unit number
uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */
sim_printf(" isbc201-%d: Configured, Status=%02X Not attached\n", i, fdc201[fdcnum].stat);
sim_printf(" isbc201-%d: Configured, Status=%02X Not attached\n", i, fdc201[fdcnum].stat);
} else {
switch(i){
case 0:
@ -351,7 +352,7 @@ void isbc201_reset1(uint8 fdcnum)
fdc201[fdcnum].rbyte1 |= RB1RD1;
break;
}
sim_printf(" isbc201-%d: Configured, Status=%02X Attached to %s\n",
sim_printf(" isbc201-%d: Configured, Status=%02X Attached to %s\n",
i, fdc201[fdcnum].stat, uptr->filename);
}
}
@ -517,13 +518,16 @@ uint8 isbc2013(t_bool io, uint8 data)
switch(fdc201[fdcnum].rtype) {
case 0x00:
rslt = fdc201[fdcnum].rbyte0;
fdc201[fdcnum].rtype = 0x02; //reset error
break;
case 0x02:
rslt = fdc201[fdcnum].rbyte1;
fdc201[fdcnum].rtype = 0x00; //set error
break;
}
if (DEBUG)
sim_printf("\n isbc201-%d: returned result byte=%02X", fdcnum, rslt);
sim_printf("\n isbc201-%d: 0x7B returned rtype=%02X result byte=%02X",
fdcnum, fdc201[fdcnum].rtype, rslt);
return rslt;
} else { /* write data port */
; //stop diskette operation
@ -598,6 +602,7 @@ void isbc201_diskio(uint8 fdcnum)
}
//check for address error
if (
((di & 0x07) != 0x03) ||
(sa > fdc201[fdcnum].fdd[fddnum].maxsec) ||
((sa + nr) > (fdc201[fdcnum].fdd[fddnum].maxsec + 1)) ||
(sa == 0) ||

View file

@ -63,7 +63,7 @@
bit 5 - write protect
bit 6 - write error
bit 7 - not ready
If result type is 10H
If result type is 02H
bit 0 - zero
bit 1 - zero
bit 2 - zero
@ -76,13 +76,14 @@
07FH - Write - Reset diskette system.
Operations:
Recalibrate -
Seek -
Format Track -
Write Data -
Write Deleted Data -
Read Data -
Verify CRC -
NOP - 0x00
Seek - 0x01
Format Track - 0x02
Recalibrate - 0x03
Read Data - 0x04
Verify CRC - 0x05
Write Data - 0x06
Write Deleted Data - 0x07
IOPB - I/O Parameter Block
Byte 0 - Channel Word
@ -178,7 +179,8 @@
/* external globals */
extern uint16 port; //port called in dev_table[port]
extern uint16 port; //port called in dev_table[port]
extern int32 PCX;
/* external function prototypes */
@ -210,6 +212,8 @@ typedef struct { //FDD definition
uint8 *buf;
int t0;
int rdy;
uint8 sec;
uint8 cyl;
uint8 maxsec;
uint8 maxcyl;
} FDDDEF;
@ -306,10 +310,11 @@ DEVICE isbc202_dev = {
t_stat isbc202_reset(DEVICE *dptr, uint16 base)
{
sim_printf("Initializing iSBC-202 FDC Board\n");
sim_printf(" iSBC-202 FDC Board");
if (SBC202_NUM) {
sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum);
sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base);
sim_printf(" - Found\n");
sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum);
sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base);
fdc202[isbc202_fdcnum].baseport = base;
reg_dev(isbc2020, base, isbc202_fdcnum); //read status
reg_dev(isbc2021, base + 1, isbc202_fdcnum); //read rslt type/write IOPB addr-l
@ -319,7 +324,7 @@ t_stat isbc202_reset(DEVICE *dptr, uint16 base)
isbc202_reset1(isbc202_fdcnum);
isbc202_fdcnum++;
} else
sim_printf(" No isbc202 installed\n");
sim_printf(" - Not Found\n");
return SCPE_OK;
}
@ -330,7 +335,7 @@ void isbc202_reset1(uint8 fdcnum)
int32 i;
UNIT *uptr;
sim_printf(" isbc202-%d: Software Reset\n", fdcnum);
sim_printf(" isbc202-%d: Software Reset\n", fdcnum);
fdc202[fdcnum].stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = isbc202_dev.units + i;
@ -340,7 +345,7 @@ void isbc202_reset1(uint8 fdcnum)
uptr->u5 = fdcnum; //fdc device number
uptr->u6 = i; //fdd unit number
uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */
sim_printf(" SBC202%d: Configured, Status=%02X Not attached\n", i, fdc202[fdcnum].stat);
sim_printf(" SBC202%d: Configured, Status=%02X Not attached\n", i, fdc202[fdcnum].stat);
} else {
switch(i){
case 0:
@ -360,7 +365,7 @@ void isbc202_reset1(uint8 fdcnum)
fdc202[fdcnum].rbyte1 |= RB1RD3;
break;
}
sim_printf(" SBC202%d: Configured, Status=%02X Attached to %s\n",
sim_printf(" SBC202%d: Configured, Status=%02X Attached to %s\n",
i, fdc202[fdcnum].stat, uptr->filename);
}
}
@ -432,6 +437,8 @@ t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
if (flen == 512512) { /* 8" 512K SSDD */
fdc202[fdcnum].fdd[fddnum].maxcyl = 77;
fdc202[fdcnum].fdd[fddnum].maxsec = 52;
fdc202[fdcnum].fdd[fddnum].sec = 1;
fdc202[fdcnum].fdd[fddnum].cyl = 0;
} else
sim_printf(" iSBC-202-%d: Not a DD disk image\n", fdcnum);
@ -477,7 +484,7 @@ uint8 isbc2020(t_bool io, uint8 data)
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read ststus*/
if (DEBUG)
sim_printf("\n isbc202-%d: returned status=%02X", fdcnum, fdc202[fdcnum].stat);
sim_printf("\n isbc202-%d: 0x78 returned status=%02X PCX=%04X", fdcnum, fdc202[fdcnum].stat, PCX);
return fdc202[fdcnum].stat;
}
}
@ -493,13 +500,13 @@ uint8 isbc2021(t_bool io, uint8 data)
fdc202[fdcnum].intff = 0; //clear interrupt FF
fdc202[fdcnum].stat &= ~FDCINT;
if (DEBUG)
sim_printf("\n isbc202-%d: returned rtype=%02X intff=%02X status=%02X",
fdcnum, fdc202[fdcnum].rtype, fdc202[fdcnum].intff, fdc202[fdcnum].stat);
sim_printf("\n isbc202-%d: 0x79 returned rtype=%02X intff=%02X status=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rtype, fdc202[fdcnum].intff, fdc202[fdcnum].stat, PCX);
return fdc202[fdcnum].rtype;
} else { /* write data port */
fdc202[fdcnum].iopb = data;
if (DEBUG)
sim_printf("\n isbc202-%d: IOPB low=%02X", fdcnum, data);
sim_printf("\n isbc202-%d: 0x79 IOPB low=%02X PCX=%04X", fdcnum, data, PCX);
}
}
return 0;
@ -515,7 +522,7 @@ uint8 isbc2022(t_bool io, uint8 data)
} else { /* write data port */
fdc202[fdcnum].iopb |= (data << 8);
if (DEBUG)
sim_printf("\n isbc202-%d: IOPB=%04X", fdcnum, fdc202[fdcnum].iopb);
sim_printf("\n isbc202-%d: 0x7A IOPB=%04X PCX=%04X", fdcnum, fdc202[fdcnum].iopb, PCX);
isbc202_diskio(fdcnum);
if (fdc202[fdcnum].intff)
fdc202[fdcnum].stat |= FDCINT;
@ -530,16 +537,9 @@ uint8 isbc2023(t_bool io, uint8 data)
if ((fdcnum = isbc202_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
switch(fdc202[fdcnum].rtype) {
case 0x00:
rslt = fdc202[fdcnum].rbyte0;
break;
case 0x02:
rslt = fdc202[fdcnum].rbyte1;
break;
}
if (DEBUG)
sim_printf("\n isbc202-%d: returned result byte=%02X", fdcnum, rslt);
sim_printf("\n isbc202-%d: 0x7B returned rtype=%02X result byte=%02X PCX=%04X",
fdcnum, fdc202[fdcnum].rtype, rslt, PCX);
return rslt;
} else { /* write data port */
; //stop diskette operation
@ -631,11 +631,12 @@ void isbc202_diskio(uint8 fdcnum)
}
//check for address error
if (
((di & 0x07) != 0x03) && (
(sa > fdc202[fdcnum].fdd[fddnum].maxsec) ||
((sa + nr) > (fdc202[fdcnum].fdd[fddnum].maxsec + 1)) ||
(sa == 0) ||
(ta > fdc202[fdcnum].fdd[fddnum].maxcyl)
) {
)) {
if (DEBUG)
sim_printf("\n isbc202-%d: maxsec=%02X maxcyl=%02X",
fdcnum, fdc202[fdcnum].fdd[fddnum].maxsec, fdc202[fdcnum].fdd[fddnum].maxcyl);
@ -647,8 +648,21 @@ void isbc202_diskio(uint8 fdcnum)
}
switch (di & 0x07) {
case DNOP:
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DSEEK:
fdc202[fdcnum].fdd[fddnum].sec = sa;
fdc202[fdcnum].fdd[fddnum].cyl = ta;
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DHOME:
fdc202[fdcnum].fdd[fddnum].sec = sa;
fdc202[fdcnum].fdd[fddnum].cyl = 0;
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF
break;
case DVCRC:
fdc202[fdcnum].rtype = ROK;
fdc202[fdcnum].intff = 1; //set interrupt FF

View file

@ -62,6 +62,7 @@ extern t_stat SBC_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr);
extern t_stat isbc201_reset (DEVICE *dptr, uint16);
extern t_stat isbc202_reset (DEVICE *dptr, uint16);
extern t_stat zx200a_reset(DEVICE *dptr, uint16 base);
/* external globals */
@ -69,6 +70,7 @@ extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
extern int32 isbc201_fdcnum;
extern int32 isbc202_fdcnum;
extern int32 zx200a_fdcnum;
/* multibus Standard SIMH Device Data Structures */
@ -141,12 +143,15 @@ t_stat multibus_svc(UNIT *uptr)
t_stat multibus_reset(DEVICE *dptr)
{
SBC_reset(NULL);
sim_printf("Initializing Multibus Boards\n Multibus Boards:\n");
sim_printf("Initializing The Multibus\n Multibus Boards:\n");
isbc064_reset(NULL);
isbc201_fdcnum = 0;
isbc201_reset(NULL, SBC201_BASE);
isbc202_fdcnum = 0;
isbc202_reset(NULL, SBC202_BASE);
zx200a_fdcnum = 0;
zx200a_reset(NULL, ZX200A_BASE_DD);
zx200a_reset(NULL, ZX200A_BASE_SD);
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
}
@ -244,9 +249,7 @@ struct idev dev_table[256] = {
uint8 nulldev(t_bool flag, uint8 data)
{
SET_XACK(0); /* set no XACK */
// if (flag == 0) /* if we got here, no valid I/O device */
// return (0xFF);
return 0;
return 0xFF;
}
//uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum)
@ -254,9 +257,9 @@ uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port, uint8 devnum
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine)
sim_printf(" I/O Port %04X is already assigned\n", port);
sim_printf(" I/O Port %04X is already assigned\n", port);
} else {
sim_printf(" Port %04X is assigned to dev %04X\n", port, devnum);
sim_printf(" Port %04X is assigned to dev %04X\n", port, devnum);
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
}

View file

@ -64,7 +64,7 @@
bit 5 - write protect
bit 6 - write error
bit 7 - not ready
If result type is 10H
If result type is 02H
bit 0 - zero
bit 1 - zero
bit 2 - zero
@ -77,13 +77,14 @@
07FH - Write - Reset diskette system.
Operations:
Recalibrate -
Seek -
Format Track -
Write Data -
Write Deleted Data -
Read Data -
Verify CRC -
NOP - 0x00
Seek - 0x01
Format Track - 0x02
Recalibrate - 0x03
Read Data - 0x04
Verify CRC - 0x05
Write Data - 0x06
Write Deleted Data - 0x07
IOPB - I/O Parameter Block
Byte 0 - Channel Word
@ -131,7 +132,7 @@
#include "system_defs.h" /* system header in system dir */
#define DEBUG 1
#define DEBUG 0
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
@ -312,10 +313,11 @@ DEVICE zx200a_dev = {
t_stat zx200a_reset(DEVICE *dptr, uint16 base)
{
sim_printf("Initializing ZX-200A FDC Board\n");
sim_printf(" ZX-200A FDC Board");
if (ZX200A_NUM) {
sim_printf(" ZX200A-%d: Hardware Reset\n", zx200a_fdcnum);
sim_printf(" ZX200A-%d: Registered at %04X\n", zx200a_fdcnum, base);
sim_printf(" - Found on Port %02X\n", base);
sim_printf(" ZX200A-%d: Hardware Reset\n", zx200a_fdcnum);
sim_printf(" ZX200A-%d: Registered at %04X\n", zx200a_fdcnum, base);
zx200a[zx200a_fdcnum].baseport = base;
reg_dev(zx200a0, base, zx200a_fdcnum);
reg_dev(zx200a1, base + 1, zx200a_fdcnum);
@ -326,7 +328,7 @@ t_stat zx200a_reset(DEVICE *dptr, uint16 base)
zx200a_reset1(zx200a_fdcnum);
zx200a_fdcnum++;
} else
sim_printf(" No ZX-200A installed\n");
sim_printf(" - Not Found on Port %02X\n", base);
return SCPE_OK;
}
@ -335,7 +337,7 @@ void zx200a_reset1(uint8 fdcnum)
int32 i;
UNIT *uptr;
sim_printf(" ZX-200A-%d: Initializing\n", fdcnum);
sim_printf(" ZX-200A-%d: Initializing\n", fdcnum);
zx200a[fdcnum].stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = zx200a_dev.units + i;
@ -347,7 +349,7 @@ void zx200a_reset1(uint8 fdcnum)
uptr->u5 = fdcnum; //fdc device number
uptr->u6 = i; /* unit number - only set here! */
uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */
sim_printf(" ZX-200A%d: Configured, Status=%02X Not attached\n", i, zx200a[fdcnum].stat);
sim_printf(" ZX-200A%d: Configured, Status=%02X Not attached\n", i, zx200a[fdcnum].stat);
} else {
switch(i){
case 0:
@ -367,7 +369,7 @@ void zx200a_reset1(uint8 fdcnum)
zx200a[fdcnum].rbyte1 |= RB1RD3;
break;
}
sim_printf(" ZX-200A%d: Configured, Status=%02X Attached to %s\n",
sim_printf(" ZX-200A%d: Configured, Status=%02X Attached to %s\n",
i, zx200a[fdcnum].stat, uptr->filename);
}
}
@ -546,13 +548,16 @@ uint8 zx200a3(t_bool io, uint8 data)
switch(zx200a[fdcnum].rtype) {
case 0x00:
rslt = zx200a[fdcnum].rbyte0;
zx200a[fdcnum].rtype = 0x02; //reset error
break;
case 0x02:
rslt = zx200a[fdcnum].rbyte1;
zx200a[fdcnum].rtype = 0x00; //set error
break;
}
if (DEBUG)
sim_printf("\n zx200a-%d: returned result byte=%02X", fdcnum, rslt);
sim_printf("\n zx200a-%d: 0x7B returned rtype=%02X result byte=%02X",
fdcnum, zx200a[fdcnum].rtype, rslt);
return rslt;
} else { /* write data port */
; //stop diskette operation
@ -645,6 +650,7 @@ void zx200a_diskio(uint8 fdcnum)
}
//check for address error
if (
((di & 0x07) != 0x03) ||
(sa > zx200a[fdcnum].fdd[fddnum].maxsec) ||
((sa + nr) > (zx200a[fdcnum].fdd[fddnum].maxsec + 1)) ||
(sa == 0) ||

View file

@ -38,6 +38,9 @@ extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
/* SCP data structures
@ -64,6 +67,9 @@ DEVICE *sim_devices[] = {
&i8259_dev,
&ipc_cont_dev,
&multibus_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};

View file

@ -52,34 +52,42 @@ extern UNIT EPROM_unit;
extern UNIT RAM_unit;
extern UNIT ipc_cont_unit;
extern UNIT ioc_cont_unit;
extern t_stat i8251_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8253_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8255_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat i8259_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern int32 i8251_devnum;
extern t_stat i8251_reset(DEVICE *dptr, uint16 base);
extern int32 i8253_devnum;
extern t_stat i8253_reset(DEVICE *dptr, uint16 base);
extern int32 i8255_devnum;
extern t_stat i8255_reset(DEVICE *dptr, uint16 base);
extern int32 i8259_devnum;
extern t_stat i8259_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);
extern t_stat ipc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern t_stat ioc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum);
extern uint32 saved_PC; /* program counter */
extern t_stat ipc_cont_reset(DEVICE *dptr, uint16 base);
extern t_stat ioc_cont_reset(DEVICE *dptr, uint16 base);
extern uint32 PCX; /* program counter */
/* CPU reset routine
put here to cause a reset of the entire IPC system */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("Initializing MDS-225\n");
sim_printf("Initializing MDS-225\n Onboard Devices:\n");
i8080_reset(NULL);
i8251_reset(NULL, I8251_BASE_0, 0);
i8251_reset(NULL, I8251_BASE_1, 0);
i8253_reset(NULL, I8253_BASE, 0);
i8255_reset(NULL, I8255_BASE_0, 0);
i8255_reset(NULL, I8255_BASE_1, 1);
i8259_reset(NULL, I8259_BASE_0, 0);
i8259_reset(NULL, I8259_BASE_1, 1);
i8251_devnum = 0;
i8251_reset(NULL, I8251_BASE_0);
i8251_reset(NULL, I8251_BASE_1);
i8253_devnum = 0;
i8253_reset(NULL, I8253_BASE);
i8255_devnum = 0;
i8255_reset(NULL, I8255_BASE_0);
i8255_reset(NULL, I8255_BASE_1);
i8259_devnum = 0;
i8259_reset(NULL, I8259_BASE_0);
i8259_reset(NULL, I8259_BASE_1);
EPROM_reset(NULL, ROM_SIZE);
RAM_reset(NULL, RAM_BASE, RAM_SIZE);
ipc_cont_reset(NULL, ICONT_BASE, 0);
ioc_cont_reset(NULL, DBB_BASE, 0);
ipc_cont_reset(NULL, ICONT_BASE);
ioc_cont_reset(NULL, DBB_BASE);
return SCPE_OK;
}
@ -88,15 +96,12 @@ t_stat SBC_reset (DEVICE *dptr)
uint8 get_mbyte(uint16 addr)
{
if (addr >= 0xF800) { //monitor ROM - always there
// sim_printf("get_mbyte: Monitor ROM ipc_cont=%02X\n", ipc_cont_unit.u3);
return EPROM_get_mbyte(addr - 0xF000);
return EPROM_get_mbyte(addr - 0xF000); //top half of EPROM
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x01) == 0)) { //startup
// sim_printf("get_mbyte: Startup ROM ipc_cont=%02X\n", ipc_cont_unit.u3);
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return EPROM_get_mbyte(addr);
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //diagnostic ROM
// sim_printf("get_mbyte: Diagnostic ROM ipc_cont=%02X\n", ipc_cont_unit.u3);
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return EPROM_get_mbyte(addr - 0xE800);
}
return RAM_get_mbyte(addr);
@ -118,15 +123,15 @@ uint16 get_mword(uint16 addr)
void put_mbyte(uint16 addr, uint8 val)
{
if (addr >= 0xF800) { //monitor ROM - always there
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, saved_PC);
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x01) == 0)) { //startup
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, saved_PC);
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //diagnostic ROM
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, saved_PC);
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
RAM_put_mbyte(addr, val);

View file

@ -31,10 +31,7 @@
#include "sim_defs.h" /* simulator defns */
#define IPC 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE_DD 0x78
#define ZX200A_BASE_SD 0x88
#define SET_XACK(VAL) (xack = VAL)
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
@ -64,11 +61,33 @@
/* set the base and size for the EPROM on the MDS 225 */
#define ROM_BASE 0x0000
#define ROM_SIZE 0x1000
#define ROM_DISABLE 1
/* set the base and size for the RAM on the MDS 225 */
#define RAM_BASE 0x0000
#define RAM_SIZE 0xF800
//board definitions for the multibus
/* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88
#define SBC201_INT INT_1
#define SBC201_NUM 0
/* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78
#define SBC202_INT INT_1
#define SBC202_NUM 1
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
#define SBC208_INT INT_1
#define SBC208_NUM 0
/* set the base for the zx-200a disk controller */
#define ZX200A_BASE_DD 0x78
#define ZX200A_BASE_SD 0x88
#define ZX200A_NUM 0
/* set INTR for CPU */
#define INTR INT_1

View file

@ -38,6 +38,7 @@ extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev;
/* SCP data structures
@ -65,6 +66,7 @@ DEVICE *sim_devices[] = {
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};

View file

@ -1,4 +1,4 @@
/* iSBC80-30.c: Intel iSBC 80/30 Processor simulator
/* iSBC8030.c: Intel iSBC 80/30 SBC simulator
Copyright (c) 2010, William A. Beech
@ -144,4 +144,4 @@ void put_mword(uint16 addr, uint16 val)
put_mbyte(addr+1, val >> 8);
}
/* end of iSBC80-30.c */
/* end of iSBC8030.c */

View file

@ -39,6 +39,7 @@ extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE zx200a_dev;
extern DEVICE isbc064_dev;
/* SCP data structures
@ -68,6 +69,7 @@ DEVICE *sim_devices[] = {
&isbc064_dev,
&isbc201_dev,
&isbc202_dev,
&zx200a_dev,
NULL
};