Intel-Systems: Add enable/disable functionality for various option boards

This commit is contained in:
Bill Beech 2020-09-01 12:10:12 -07:00
parent 5c48229ce4
commit 782fe167ca
26 changed files with 1009 additions and 475 deletions

View file

@ -294,7 +294,11 @@ DEVICE i8080_dev = {
0, //dctrl 0, //dctrl
i8080_debug, //debflags i8080_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
}; };
/* tables for the disassembler */ /* tables for the disassembler */
@ -406,7 +410,6 @@ int32 sim_instr(void)
sim_printf(" CPU = 8085\n"); sim_printf(" CPU = 8085\n");
else else
sim_printf(" CPU = 8080\n"); sim_printf(" CPU = 8080\n");
// sim_printf(" i8080:\n");
} }
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */

View file

@ -207,11 +207,15 @@ DEVICE i8251_dev = {
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
0, //flags DEV_DISABLE, //flags
0, //dctrl 0, //dctrl
i8251_debug, //debflags i8251_debug, //debflags
NULL, //msize NULL, //memeory size change
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
}; };
// i8251 configuration // i8251 configuration

View file

@ -96,9 +96,9 @@ extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
/* these bytes represent the input and output to/from a port instance */ /* these bytes represent the input and output to/from a port instance */
uint8 i8255_A[4]; //port A byte I/O uint8 i8255_A[I8255_NUM]; //port A byte I/O
uint8 i8255_B[4]; //port B byte I/O uint8 i8255_B[I8255_NUM]; //port B byte I/O
uint8 i8255_C[4]; //port C byte I/O uint8 i8255_C[I8255_NUM]; //port C byte I/O
/* external globals */ /* external globals */
@ -173,12 +173,12 @@ DEVICE i8255_dev = {
t_stat i8255_cfg(uint8 base, uint8 devnum) t_stat i8255_cfg(uint8 base, uint8 devnum)
{ {
sim_printf(" i8255[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8255a, base, devnum); reg_dev(i8255a, base, devnum);
reg_dev(i8255b, base + 1, devnum); reg_dev(i8255b, base + 1, devnum);
reg_dev(i8255c, base + 2, devnum); reg_dev(i8255c, base + 2, devnum);
reg_dev(i8255s, base + 3, devnum); reg_dev(i8255s, base + 3, devnum);
sim_printf(" i8255[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -140,10 +140,10 @@ DEVICE i8259_dev = {
t_stat i8259_cfg(uint8 base, uint8 devnum) t_stat i8259_cfg(uint8 base, uint8 devnum)
{ {
reg_dev(i8259a, base, devnum);
reg_dev(i8259b, base + 1, devnum);
sim_printf(" i8259[%d]: at base port 0%02XH\n", sim_printf(" i8259[%d]: at base port 0%02XH\n",
devnum, base & 0xFF); devnum, base & 0xFF);
reg_dev(i8259a, base, devnum);
reg_dev(i8259b, base + 1, devnum);
return SCPE_OK; return SCPE_OK;
} }

View file

@ -62,7 +62,6 @@ extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
/* globals */ /* globals */
@ -109,7 +108,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);
@ -126,7 +124,7 @@ t_stat SBC_reset (DEVICE *dptr)
uint8 get_mbyte(uint16 addr) uint8 get_mbyte(uint16 addr)
{ {
SET_XACK(1); /* set no XACK */ SET_XACK(0); /* set XACK */
if (addr >= 0xF800) { //monitor ROM - always there if (addr >= 0xF800) { //monitor ROM - always there
return EPROM_get_mbyte(addr - 0xF000, 0); //top half of EPROM return EPROM_get_mbyte(addr - 0xF000, 0); //top half of EPROM
} }
@ -139,7 +137,6 @@ uint8 get_mbyte(uint16 addr)
if (addr < 0x8000) { //IPB RAM if (addr < 0x8000) { //IPB RAM
return RAM_get_mbyte(addr); return RAM_get_mbyte(addr);
} }
SET_XACK(0); /* set no XACK */
return multibus_get_mbyte(addr); //check multibus cards return multibus_get_mbyte(addr); //check multibus cards
} }
@ -160,13 +157,13 @@ void put_mbyte(uint16 addr, uint8 val)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there if (addr >= 0xF800) { //monitor ROM - always there
return; return; //do nothing
} }
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return; return; //do nothing
} }
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return; return; //do nothing
} }
if (addr < 0x8000) { if (addr < 0x8000) {
RAM_put_mbyte(addr, val); //IPB RAM RAM_put_mbyte(addr, val); //IPB RAM

View file

@ -65,7 +65,6 @@ extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat multibus_cfg();
/* external globals */ /* external globals */
@ -112,7 +111,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);

View file

@ -37,15 +37,15 @@
#include "system_defs.h" #include "system_defs.h"
#if defined (SBC064_NUM) && (SBC064_NUM > 0) #if defined (SBC064_NUM) && (SBC064_NUM > 0) //if board allowed with this system
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */ #define BASE_ADDR u3
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
/* prototypes */ /* prototypes */
t_stat isbc064_cfg(uint16 base, uint16 size);
t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc064_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc064_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat isbc064_reset(DEVICE *dptr); t_stat isbc064_reset(DEVICE *dptr);
uint8 isbc064_get_mbyte(uint16 addr); uint8 isbc064_get_mbyte(uint16 addr);
void isbc064_put_mbyte(uint16 addr, uint8 val); void isbc064_put_mbyte(uint16 addr, uint8 val);
@ -54,6 +54,8 @@ void isbc064_put_mbyte(uint16 addr, uint8 val);
/* local globals */ /* local globals */
int isbc064_onetime = 1;
/* external globals */ /* external globals */
extern uint8 xack; extern uint8 xack;
@ -61,14 +63,37 @@ extern uint8 xack;
/* isbc064 Standard SIMH Device Data Structures */ /* isbc064 Standard SIMH Device Data Structures */
UNIT isbc064_unit = { UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT UDATA (NULL, 0, 0)
}; };
MTAB isbc064_mod[] = { MTAB isbc064_mod[] = {
{ UNIT_MSIZE, 16384, "16K", "16K", &isbc064_set_size }, { MTAB_XTD | MTAB_VDV, /* mask */
{ UNIT_MSIZE, 32768, "32K", "32K", &isbc064_set_size }, 0, /* match */
{ UNIT_MSIZE, 49152, "48K", "48K", &isbc064_set_size }, NULL, /* print string */
{ UNIT_MSIZE, 65536, "64K", "64K", &isbc064_set_size }, "SIZE", /* match string */
&isbc064_set_size, /* validation routine */
NULL, /* display routine */
NULL, /* location descriptor */
"Sets the RAM size for iSB 064" /* help string */
},
{ MTAB_XTD | MTAB_VDV, /* mask */
0 /* match */,
NULL, /* print string */
"BASE", /* match string */
&isbc064_set_base, /* validation routine */
NULL, /* display routine */
NULL, /* location descriptor */
"Sets the RAM base for iSBC 064" /* help string */
},
{ MTAB_XTD|MTAB_VDV, /* mask */
0, /* match */
"PARAM", /* print string */
NULL, /* match string */
NULL, /* validation routine */
&isbc064_show_param, /* display routine */
NULL, /* location descriptor */
"Show current Parameters for iSBC 064" /* help string */
},
{ 0 } { 0 }
}; };
@ -96,45 +121,78 @@ DEVICE isbc064_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposit NULL, //deposit
NULL, //reset &isbc064_reset, //reset
NULL, //boot NULL, //boot
NULL, //attach NULL, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags DEV_DISABLE+DEV_DIS, //flags
0, //dctrl 0, //dctrl
isbc064_debug, //debflags isbc064_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
}; };
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
// configuration routine
t_stat isbc064_cfg(uint16 base, uint16 size) // set size parameter
{
sim_printf(" sbc064: 0%04XH bytes at base 0%04XH\n",
size, base);
isbc064_unit.capac = size; //set size
isbc064_unit.u3 = base; //and base
isbc064_unit.filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (isbc064_unit.filebuf == NULL) {
sim_printf (" sbc064: Calloc error\n");
return SCPE_MEM;
}
return SCPE_OK;
}
t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc) t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
if ((val <= 0) || (val > MAXMEMSIZE)) { uint32 size, result, i;
sim_printf("Memory size error - val=%d\n", val);
if (cptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%i%n", &size, &i);
if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) {
if (size & 0xff8f) {
sim_printf("SBC064: Size error\n");
return SCPE_ARG;
} else {
isbc064_unit.capac = (size * 1024) - 1;
sim_printf("SBC064: Size=%04XH\n", isbc064_unit.capac);
return SCPE_OK;
}
}
return SCPE_ARG; return SCPE_ARG;
} }
isbc064_reset(&isbc064_dev);
isbc064_unit.capac = val; // set base address parameter
sim_printf("SBC064: Size set to %04X\n", val);
t_stat isbc064_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result, i;
if (cptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%i%n", &size, &i);
if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) {
if (size & 0xff8f) {
sim_printf("SBC064: Base error\n");
return SCPE_ARG;
} else {
isbc064_unit.BASE_ADDR = size * 1024;
sim_printf("SBC064: Base=%04XH\n", isbc064_unit.BASE_ADDR);
return SCPE_OK;
}
}
return SCPE_ARG;
}
// show configuration parameters
t_stat isbc064_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "%s Base=%04XH Size=%04XH ",
((isbc064_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
isbc064_unit.BASE_ADDR, isbc064_unit.capac);
return SCPE_OK; return SCPE_OK;
} }
@ -142,6 +200,26 @@ t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_stat isbc064_reset (DEVICE *dptr) t_stat isbc064_reset (DEVICE *dptr)
{ {
if (dptr == NULL)
return SCPE_ARG;
if (isbc064_onetime) {
isbc064_dev.units->capac = SBC064_SIZE; //set default size
isbc064_dev.units->BASE_ADDR = SBC064_BASE; //set default base
isbc064_onetime = 0;
}
if ((dptr->flags & DEV_DIS) == 0) { //already enabled
isbc064_dev.units->filebuf = (uint8 *)calloc(isbc064_unit.capac, sizeof(uint8)); //alloc buffer
if (isbc064_dev.units->filebuf == NULL) { //CALLOC error
sim_printf (" sbc064: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" sbc064: Enabled 0%04XH bytes at base 0%04XH\n",
isbc064_dev.units->capac, isbc064_dev.units->BASE_ADDR);
} else {
if (isbc064_dev.units->filebuf)
free(isbc064_dev.units->filebuf); //return allocated memory
sim_printf(" sbc064: Disabled\n");
}
return SCPE_OK; return SCPE_OK;
} }
@ -151,7 +229,7 @@ uint8 isbc064_get_mbyte(uint16 addr)
{ {
uint8 val; uint8 val;
val = *((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.u3)); val = *((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.BASE_ADDR));
return (val & 0xFF); return (val & 0xFF);
} }
@ -159,7 +237,7 @@ uint8 isbc064_get_mbyte(uint16 addr)
void isbc064_put_mbyte(uint16 addr, uint8 val) void isbc064_put_mbyte(uint16 addr, uint8 val)
{ {
*((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.u3)) = val & 0xFF; *((uint8 *)isbc064_unit.filebuf + (addr - isbc064_unit.BASE_ADDR)) = val & 0xFF;
return; return;
} }

View file

@ -206,6 +206,8 @@
#define MAXSECSD 26 //single density last sector #define MAXSECSD 26 //single density last sector
#define MAXTRK 76 //last track #define MAXTRK 76 //last track
#define isbc201_NAME "Intel iSBC 201 Floppy Disk Controller Board"
/* external globals */ /* external globals */
extern uint16 PCX; extern uint16 PCX;
@ -213,16 +215,20 @@ extern uint16 PCX;
/* external function prototypes */ /* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 unreg_dev(uint8);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
/* function prototypes */ /* function prototypes */
t_stat isbc201_cfg(uint8 base);
t_stat isbc201_reset(DEVICE *dptr);
void isbc201_reset1(void);
t_stat isbc201_attach (UNIT *uptr, CONST char *cptr);
t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc201_set_port (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc201_set_int (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc201_set_verb (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc201_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat isbc201_reset(DEVICE *dptr);
void isbc201_reset_dev(void);
t_stat isbc201_attach (UNIT *uptr, CONST char *cptr);
uint8 isbc201r0(t_bool io, uint8 data, uint8 devnum); /* isbc201 0 */ uint8 isbc201r0(t_bool io, uint8 data, uint8 devnum); /* isbc201 0 */
uint8 isbc201r1(t_bool io, uint8 data, uint8 devnum); /* isbc201 1 */ uint8 isbc201r1(t_bool io, uint8 data, uint8 devnum); /* isbc201 1 */
uint8 isbc201r2(t_bool io, uint8 data, uint8 devnum); /* isbc201 2 */ uint8 isbc201r2(t_bool io, uint8 data, uint8 devnum); /* isbc201 2 */
@ -232,12 +238,20 @@ void isbc201_diskio(void); //do actual disk i/o
/* globals */ /* globals */
int isbc201_onetime = 1;
static const char* isbc201_desc(DEVICE *dptr) {
return isbc201_NAME;
}
typedef struct { //FDD definition typedef struct { //FDD definition
uint8 sec; uint8 sec;
uint8 cyl; uint8 cyl;
} FDDDEF; } FDDDEF;
typedef struct { //FDC definition typedef struct { //FDC definition
uint8 baseport; //FDC base port
uint8 intnum; //interrupt number
uint8 verb; //verbose flag
uint16 iopb; //FDC IOPB uint16 iopb; //FDC IOPB
uint8 stat; //FDC status uint8 stat; //FDC status
uint8 rdychg; //FDC ready changed uint8 rdychg; //FDC ready changed
@ -248,13 +262,13 @@ typedef struct { //FDC definition
FDDDEF fdd[FDD_NUM]; //indexed by the FDD number FDDDEF fdd[FDD_NUM]; //indexed by the FDD number
} FDCDEF; } FDCDEF;
FDCDEF fdc201; FDCDEF fdc201; //indexed by the isbc-202 instance number
/* isbc201 Standard I/O Data Structures */ /* isbc201 Standard I/O Data Structures */
UNIT isbc201_unit[] = { //2 FDDs UNIT isbc201_unit[] = { //2 FDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD) }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSSD) } { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) }
}; };
REG isbc201_reg[] = { REG isbc201_reg[] = {
@ -269,6 +283,14 @@ REG isbc201_reg[] = {
MTAB isbc201_mod[] = { MTAB isbc201_mod[] = {
{ UNIT_WPMODE, 0, "RW", "RW", &isbc201_set_mode }, { UNIT_WPMODE, 0, "RW", "RW", &isbc201_set_mode },
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc201_set_mode }, { UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc201_set_mode },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "VERB", &isbc201_set_verb,
NULL, NULL, "Sets the verbose mode for iSBC201"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "PORT", &isbc201_set_port,
NULL, NULL, "Sets the base port for iSBC201"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "INT", &isbc201_set_int,
NULL, NULL, "Sets the interrupt number for iSBC201"},
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, &isbc201_show_param, NULL,
"show configured parametes for iSBC201" },
{ 0 } { 0 }
}; };
@ -307,41 +329,140 @@ DEVICE isbc201_dev = {
0, //dctrl 0, //dctrl
isbc201_debug, //debflags isbc201_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&isbc201_desc //device description
}; };
// configuration routine /* fdc201 set mode = Write protect */
t_stat isbc201_cfg(uint8 base) t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
int32 i; if (uptr == NULL)
return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
if (fdc201.verb)
sim_printf(" sbc201: WP\n");
} else { /* read write */
uptr->flags &= ~val;
if (fdc201.verb)
sim_printf(" sbc201: RW\n");
}
return SCPE_OK;
}
// set base address parameter
t_stat isbc201_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc201.baseport = size;
if (fdc201.verb)
sim_printf("SBC201: Base port=%04X\n", fdc201.baseport);
return SCPE_OK;
}
// set interrupt parameter
t_stat isbc201_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc201.intnum = size;
if (fdc201.verb)
sim_printf("SBC201: Interrupt number=%04X\n", fdc201.intnum);
return SCPE_OK;
}
t_stat isbc201_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
if (cptr == NULL)
return SCPE_ARG;
if (strncasecmp(cptr, "OFF", 4) == 0) {
fdc201.verb = 0;
return SCPE_OK;
}
if (strncasecmp(cptr, "ON", 3) == 0) {
fdc201.verb = 1;
sim_printf(" SBC201: fdc201.verb=%d\n", fdc201.verb);
return SCPE_OK;
}
return SCPE_ARG;
}
// show configuration parameters
t_stat isbc201_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s Base port at %04X Interrupt # is %i %s",
((isbc201_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
fdc201.baseport, fdc201.intnum,
fdc201.verb ? "Verbose" : "Quiet"
);
return SCPE_OK;
}
/* Hardware reset routine */
t_stat isbc201_reset(DEVICE *dptr)
{
int i;
UNIT *uptr; UNIT *uptr;
sim_printf(" sbc201: at base 0%02XH\n", if (dptr == NULL)
base); return SCPE_ARG;
reg_dev(isbc201r0, base, 0); //read status if (isbc201_onetime) {
reg_dev(isbc201r1, base + 1, 0); //read rslt type/write IOPB addr-l fdc201.baseport = SBC201_BASE; //set default base
reg_dev(isbc201r2, base + 2, 0); //write IOPB addr-h and start fdc201.intnum = SBC201_INT; //set default interrupt
reg_dev(isbc201r3, base + 3, 0); //read rstl byte fdc201.verb = 0; //set verb = 0
reg_dev(isbc201r7, base + 7, 0); //write reset fdc201 isbc201_onetime = 0;
// one-time initialization for all FDDs for this FDC instance // one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
uptr = isbc201_dev.units + i; uptr = isbc201_dev.units + i;
uptr->u6 = i; //fdd unit number uptr->u6 = i; //fdd unit number
} }
return SCPE_OK;
} }
/* Hardware reset routine */ if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(isbc201r0, fdc201.baseport, 0); //read status
t_stat isbc201_reset(DEVICE *dptr) reg_dev(isbc201r1, fdc201.baseport + 1, 0); //read rslt type/write IOPB addr-l
{ reg_dev(isbc201r2, fdc201.baseport + 2, 0); //write IOPB addr-h and start
isbc201_reset1(); reg_dev(isbc201r3, fdc201.baseport + 3, 0); //read rstl byte
reg_dev(isbc201r7, fdc201.baseport + 7, 0); //write reset fdc201
isbc201_reset_dev(); //software reset
// if (fdc201.verb)
sim_printf(" sbc201: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
fdc201.baseport, fdc201.intnum, fdc201.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(fdc201.baseport); //read status
unreg_dev(fdc201.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(fdc201.baseport + 2); //write IOPB addr-h and start
unreg_dev(fdc201.baseport + 3); //read rstl byte
unreg_dev(fdc201.baseport + 7); //write reset fdc201
// if (fdc201.verb)
sim_printf(" sbc201: Disabled\n");
}
return SCPE_OK; return SCPE_OK;
} }
/* Software reset routine */ /* Software reset routine */
void isbc201_reset1(void) void isbc201_reset_dev(void)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
@ -395,20 +516,6 @@ t_stat isbc201_attach (UNIT *uptr, CONST char *cptr)
return SCPE_OK; return SCPE_OK;
} }
/* fdc201 set mode = Write protect */
t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
} else { /* read write */
uptr->flags &= ~val;
}
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
@ -471,7 +578,7 @@ uint8 isbc201r7(t_bool io, uint8 data, uint8 devnum)
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
isbc201_reset1(); isbc201_reset_dev();
} }
return 0; return 0;
} }
@ -489,16 +596,16 @@ void isbc201_diskio(void)
uint8 *fbuf; uint8 *fbuf;
//parse the IOPB //parse the IOPB
cw = multibus_get_mbyte(fdc201.iopb); cw = get_mbyte(fdc201.iopb);
di = multibus_get_mbyte(fdc201.iopb + 1); di = get_mbyte(fdc201.iopb + 1);
nr = multibus_get_mbyte(fdc201.iopb + 2); nr = get_mbyte(fdc201.iopb + 2);
ta = multibus_get_mbyte(fdc201.iopb + 3); ta = get_mbyte(fdc201.iopb + 3);
sa = multibus_get_mbyte(fdc201.iopb + 4) & 0x1f; sa = get_mbyte(fdc201.iopb + 4) & 0x1f;
ba = multibus_get_mbyte(fdc201.iopb + 5); ba = get_mbyte(fdc201.iopb + 5);
ba |= (multibus_get_mbyte(fdc201.iopb + 6) << 8); ba |= (get_mbyte(fdc201.iopb + 6) << 8);
bn = multibus_get_mbyte(fdc201.iopb + 7); bn = get_mbyte(fdc201.iopb + 7);
ni = multibus_get_mbyte(fdc201.iopb + 8); ni = get_mbyte(fdc201.iopb + 8);
ni |= (multibus_get_mbyte(fdc201.iopb + 9) << 8); ni |= (get_mbyte(fdc201.iopb + 9) << 8);
fddnum = (di & 0x10) >> 4; fddnum = (di & 0x10) >> 4;
uptr = isbc201_dev.units + fddnum; uptr = isbc201_dev.units + fddnum;
fbuf = (uint8 *) (isbc201_dev.units + fddnum)->filebuf; fbuf = (uint8 *) (isbc201_dev.units + fddnum)->filebuf;
@ -571,7 +678,7 @@ void isbc201_diskio(void)
sim_printf("\n SBC201: FDD %d - Write protect error 1", fddnum); sim_printf("\n SBC201: FDD %d - Write protect error 1", fddnum);
return; return;
} }
fmtb = multibus_get_mbyte(ba); //get the format byte fmtb = get_mbyte(ba); //get the format byte
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ; dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
for(i=0; i<=((uint32)(MAXSECSD) * SECSIZ); i++) { for(i=0; i<=((uint32)(MAXSECSD) * SECSIZ); i++) {
@ -589,7 +696,7 @@ void isbc201_diskio(void)
//copy sector from image to RAM //copy sector from image to RAM
for (i=0; i<SECSIZ; i++) { for (i=0; i<SECSIZ; i++) {
data = *(fbuf + (dskoff + i)); data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data); put_mbyte(ba + i, data);
} }
sa++; sa++;
ba+=0x80; ba+=0x80;
@ -613,7 +720,7 @@ void isbc201_diskio(void)
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ; dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
for (i=0; i<SECSIZ; i++) { //copy sector from image to RAM for (i=0; i<SECSIZ; i++) { //copy sector from image to RAM
data = multibus_get_mbyte(ba + i); data = get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data; *(fbuf + (dskoff + i)) = data;
} }
sa++; sa++;

View file

@ -27,11 +27,6 @@
27 Jun 16 - Original file. 27 Jun 16 - Original file.
NOTES:
This controller will mount 4 DD disk images on drives :F0: thru :F3: addressed
at ports 078H to 07FH.
Registers: Registers:
078H - Read - Subsystem status 078H - Read - Subsystem status
@ -129,6 +124,23 @@
u5 - u5 -
u6 - fdd number. u6 - fdd number.
NOTES:
This iSBC 202 device simulator (DEVICES) supports 4 floppy disk drives
(UNITS). It uses the SBC202_BASE and SBC202_INT from system_defs.h to
set the default base port and interrupt.
The default base port can be changed by "sim> set sbc202 port=88". The
default interrupt can be changed by "sim> set sbc202 int=5". Current
settings can be shown by "sim> show sbc202 param".
This device simulator can be enabled or disabled if SBC202_NUM in
system_defs.h is set to 1. Only one board can be simulated. It is
enabled by "sim> Sset sbc202 ena" and disabled by "sim> set sbc202 dis".
The disk images in each FDD can be set to RW or WP. They default to WP
*/ */
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
@ -184,6 +196,8 @@
#define MAXSECDD 52 //double density last sector #define MAXSECDD 52 //double density last sector
#define MAXTRK 76 //last track #define MAXTRK 76 //last track
#define isbc202_NAME "Intel iSBC 202 Floppy Disk Controller Board"
/* external globals */ /* external globals */
extern uint16 PCX; extern uint16 PCX;
@ -191,12 +205,16 @@ extern uint16 PCX;
/* external function prototypes */ /* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 unreg_dev(uint8);
extern uint8 get_mbyte(uint16 addr); extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val); extern void put_mbyte(uint16 addr, uint8 val);
/* function prototypes */ /* function prototypes */
t_stat isbc202_cfg(uint8 base); t_stat isbc202_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc202_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc202_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc202_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat isbc202_reset(DEVICE *dptr); t_stat isbc202_reset(DEVICE *dptr);
void isbc202_reset_dev(void); void isbc202_reset_dev(void);
t_stat isbc202_attach (UNIT *uptr, CONST char *cptr); t_stat isbc202_attach (UNIT *uptr, CONST char *cptr);
@ -210,13 +228,21 @@ void isbc202_diskio(void); //do actual disk i/o
/* globals */ /* globals */
int isbc202_onetime = 1;
static const char* isbc202_desc(DEVICE *dptr) {
return isbc202_NAME;
}
typedef struct { //FDD definition typedef struct { //FDD definition
uint8 sec; uint8 sec;
uint8 cyl; uint8 cyl;
} FDDDEF; } FDDDEF;
typedef struct { //FDC definition typedef struct { //FDC definition
// uint16 baseport; //FDC base port uint8 baseport; //FDC base port
uint8 intnum; //interrupt number
uint8 verb; //verbose flag
uint16 iopb; //FDC IOPB uint16 iopb; //FDC IOPB
uint8 stat; //FDC status uint8 stat; //FDC status
uint8 rdychg; //FDC ready change uint8 rdychg; //FDC ready change
@ -232,10 +258,10 @@ FDCDEF fdc202; //indexed by the isbc-202 instance number
/* isbc202 Standard I/O Data Structures */ /* isbc202 Standard I/O Data Structures */
UNIT isbc202_unit[] = { // 4 FDDs UNIT isbc202_unit[] = { // 4 FDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ NULL } { NULL }
}; };
@ -251,6 +277,14 @@ REG isbc202_reg[] = {
MTAB isbc202_mod[] = { MTAB isbc202_mod[] = {
{ UNIT_WPMODE, 0, "RW", "RW", &isbc202_set_mode }, { UNIT_WPMODE, 0, "RW", "RW", &isbc202_set_mode },
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc202_set_mode }, { UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc202_set_mode },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "VERB", &isbc202_set_verb,
NULL, NULL, "Sets the verbose mode for iSBC202"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "PORT", &isbc202_set_port,
NULL, NULL, "Sets the base port for iSBC202"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "INT", &isbc202_set_int,
NULL, NULL, "Sets the interrupt number for iSBC202"},
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, &isbc202_show_param, NULL,
"show configured parametes for iSBC202" },
{ 0 } { 0 }
}; };
@ -289,36 +323,135 @@ DEVICE isbc202_dev = {
0, //dctrl 0, //dctrl
isbc202_debug, //debflags isbc202_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&isbc202_desc //device description
}; };
// configuration routine /* isbc202 set mode = Write protect */
t_stat isbc202_cfg(uint8 base) t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
int32 i; if (uptr == NULL)
UNIT *uptr; return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
sim_printf(" sbc202: at base 0%02XH\n", return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr),
base); uptr->filename);
reg_dev(isbc202r0, base, 0); //read status if (val & UNIT_WPMODE) { /* write protect */
reg_dev(isbc202r1, base + 1, 0); //read rslt type/write IOPB addr-l uptr->flags |= val;
reg_dev(isbc202r2, base + 2, 0); //write IOPB addr-h and start if (fdc202.verb)
reg_dev(isbc202r3, base + 3, 0); //read rstl byte sim_printf(" sbc202: WP\n");
reg_dev(isbc202r7, base + 7, 0); //write reset fdc201 } else { /* read write */
// one-time initialization for all FDDs for this FDC instance uptr->flags &= ~val;
for (i = 0; i < FDD_NUM; i++) { if (fdc202.verb)
uptr = isbc202_dev.units + i; sim_printf(" sbc202: RW\n");
uptr->u6 = i; //fdd unit number
} }
return SCPE_OK; return SCPE_OK;
} }
// set base address parameter
t_stat isbc202_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc202.baseport = size;
if (fdc202.verb)
sim_printf("SBC202: Base port=%04X\n", fdc202.baseport);
return SCPE_OK;
}
// set interrupt parameter
t_stat isbc202_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc202.intnum = size;
if (fdc202.verb)
sim_printf("SBC202: Interrupt number=%04X\n", fdc202.intnum);
return SCPE_OK;
}
t_stat isbc202_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
if (cptr == NULL)
return SCPE_ARG;
if (strncasecmp(cptr, "OFF", 4) == 0) {
fdc202.verb = 0;
return SCPE_OK;
}
if (strncasecmp(cptr, "ON", 3) == 0) {
fdc202.verb = 1;
sim_printf(" SBC202: fdc202.verb=%d\n", fdc202.verb);
return SCPE_OK;
}
return SCPE_ARG;
}
// show configuration parameters
t_stat isbc202_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s Base port at %04X Interrupt # is %i %s",
((isbc202_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
fdc202.baseport, fdc202.intnum,
fdc202.verb ? "Verbose" : "Quiet"
);
return SCPE_OK;
}
/* Hardware reset routine */ /* Hardware reset routine */
t_stat isbc202_reset(DEVICE *dptr) t_stat isbc202_reset(DEVICE *dptr)
{ {
int i;
UNIT *uptr;
if (dptr == NULL)
return SCPE_ARG;
if (isbc202_onetime) {
fdc202.baseport = SBC202_BASE; //set default base
fdc202.intnum = SBC202_INT; //set default interrupt
fdc202.verb = 0; //set verb = off
isbc202_onetime = 0;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc202_dev.units + i;
uptr->u6 = i; //fdd unit number
}
}
if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(isbc202r0, fdc202.baseport, 0); //read status
reg_dev(isbc202r1, fdc202.baseport + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc202r2, fdc202.baseport + 2, 0); //write IOPB addr-h and start
reg_dev(isbc202r3, fdc202.baseport + 3, 0); //read rstl byte
reg_dev(isbc202r7, fdc202.baseport + 7, 0); //write reset fdc201
isbc202_reset_dev(); //software reset isbc202_reset_dev(); //software reset
// if (fdc202.verb)
sim_printf(" sbc202: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
fdc202.baseport, fdc202.intnum, fdc202.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(fdc202.baseport); //read status
unreg_dev(fdc202.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(fdc202.baseport + 2); //write IOPB addr-h and start
unreg_dev(fdc202.baseport + 3); //read rstl byte
unreg_dev(fdc202.baseport + 7); //write reset fdc201
// if (fdc202.verb)
sim_printf(" sbc202: Disabled\n");
}
return SCPE_OK; return SCPE_OK;
} }
@ -394,20 +527,6 @@ t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
return SCPE_OK; return SCPE_OK;
} }
/* isbc202 set mode = Write protect */
t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
} else { /* read write */
uptr->flags &= ~val;
}
return SCPE_OK;
}
/* iSBC202 control port functions */ /* iSBC202 control port functions */
uint8 isbc202r0(t_bool io, uint8 data, uint8 devnum) uint8 isbc202r0(t_bool io, uint8 data, uint8 devnum)
@ -638,7 +757,8 @@ void isbc202_diskio(void)
fdc202.intff = 1; //set interrupt FF fdc202.intff = 1; //set interrupt FF
break; break;
default: default:
sim_printf("\n SBC202: FDD %d - isbc202_diskio bad di=%02X", fddnum, di & 0x07); sim_printf("\n SBC202: FDD %d - isbc202_diskio bad command di=%02X",
fddnum, di & 0x07);
break; break;
} }
} }

View file

@ -133,7 +133,7 @@
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */ #define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE) #define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define HD_NUM 2 //one fixed and one removable #define HDD_NUM 2 //one fixed and one removable
//disk controller operations //disk controller operations
#define DNOP 0x00 //HDC no operation #define DNOP 0x00 //HDC no operation
@ -174,6 +174,8 @@
#define MAXSECHD 144 //hard disk last sector (2 heads/2 tracks) #define MAXSECHD 144 //hard disk last sector (2 heads/2 tracks)
#define MAXTRKHD 206 //hard disk last track #define MAXTRKHD 206 //hard disk last track
#define isbc206_NAME "Intel iSBC 206 Hard Disk Controller Board"
/* external globals */ /* external globals */
extern uint16 PCX; extern uint16 PCX;
@ -181,16 +183,18 @@ extern uint16 PCX;
/* external function prototypes */ /* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 unreg_dev(uint8);
extern uint16 multibus_get_mword(uint16 addr); extern uint8 get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void put_mbyte(uint16 addr, uint8 val);
extern uint8 multibus_put_mword(uint16 addr, uint16 val);
/* function prototypes */ /* function prototypes */
t_stat isbc206_cfg(uint8 base); t_stat isbc206_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc206_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc206_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc206_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat isbc206_reset(DEVICE *dptr); t_stat isbc206_reset(DEVICE *dptr);
void isbc206_reset1(void); void isbc206_reset_dev(void);
t_stat isbc206_attach (UNIT *uptr, CONST char *cptr); t_stat isbc206_attach (UNIT *uptr, CONST char *cptr);
t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 isbc206r0(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 0 */ uint8 isbc206r0(t_bool io, uint8 data, uint8 devnum); /* isbc206 port 0 */
@ -202,6 +206,11 @@ void isbc206_diskio(void); //do actual disk i/o
/* globals */ /* globals */
int isbc206_onetime = 1;
static const char* isbc206_desc(DEVICE *dptr) {
return isbc206_NAME;
}
typedef struct { //HDD definition typedef struct { //HDD definition
int t0; int t0;
int rdy; int rdy;
@ -210,7 +219,9 @@ typedef struct { //HDD definition
} HDDDEF; } HDDDEF;
typedef struct { //HDC definition typedef struct { //HDC definition
uint16 baseport; //HDC base port uint8 baseport; //HDC base port
uint8 intnum; //interrupt number
uint8 verb; //verbose flag
uint16 iopb; //HDC IOPB uint16 iopb; //HDC IOPB
uint8 stat; //HDC status uint8 stat; //HDC status
uint8 rdychg; //HDC ready change uint8 rdychg; //HDC ready change
@ -218,14 +229,15 @@ typedef struct { //HDC definition
uint8 rbyte0; //HDC result byte for type 00 uint8 rbyte0; //HDC result byte for type 00
uint8 rbyte1; //HDC result byte for type 10 uint8 rbyte1; //HDC result byte for type 10
uint8 intff; //HDC interrupt FF uint8 intff; //HDC interrupt FF
HDDDEF hd[HD_NUM]; //indexed by the HDD number HDDDEF hd[HDD_NUM]; //indexed by the HDD number
} HDCDEF; } HDCDEF;
HDCDEF hdc206; HDCDEF hdc206; //indexed by the isbc-206 instance number
UNIT isbc206_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD), 20 }, UNIT isbc206_unit[] = { // 2 HDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD) },
{ NULL } { NULL }
}; };
@ -241,6 +253,14 @@ REG isbc206_reg[] = {
MTAB isbc206_mod[] = { MTAB isbc206_mod[] = {
{ UNIT_WPMODE, 0, "RW", "RW", &isbc206_set_mode }, { UNIT_WPMODE, 0, "RW", "RW", &isbc206_set_mode },
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc206_set_mode }, { UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &isbc206_set_mode },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "VERB", &isbc206_set_verb,
NULL, NULL, "Sets the verbose mode for iSBC206"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "PORT", &isbc206_set_port,
NULL, NULL, "Sets the base port for iSBC206"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "INT", &isbc206_set_int,
NULL, NULL, "Sets the interrupt number for iSBC206"},
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, &isbc206_show_param, NULL,
"show configured parametes for iSBC206" },
{ 0 } { 0 }
}; };
@ -262,7 +282,7 @@ DEVICE isbc206_dev = {
isbc206_unit, //units isbc206_unit, //units
isbc206_reg, //registers isbc206_reg, //registers
isbc206_mod, //modifiers isbc206_mod, //modifiers
HD_NUM, //numunits HDD_NUM, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
1, //aincr 1, //aincr
@ -282,45 +302,139 @@ DEVICE isbc206_dev = {
NULL //lname NULL //lname
}; };
// configuration routine /* isbc206 set mode = Write protect */
t_stat isbc206_cfg(uint8 base) t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
int32 i; if (uptr == NULL)
UNIT *uptr; return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
sim_printf(" sbc206: at base 0%02XH\n", return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
base); if (val & UNIT_WPMODE) { /* write protect */
reg_dev(isbc206r0, base, 0); //read status uptr->flags |= val;
reg_dev(isbc206r1, base + 1, 0); //read rslt type/write IOPB addr-l if (hdc206.verb)
reg_dev(isbc206r2, base + 2, 0); //write IOPB addr-h and start sim_printf(" sbc206: WP\n");
reg_dev(isbc206r3, base + 3, 0); //read rstl byte } else { /* read write */
reg_dev(isbc206r7, base + 7, 0); //write reset fdc201 uptr->flags &= ~val;
// one-time initialization for all FDDs for this FDC instance if (hdc206.verb)
for (i = 0; i < HD_NUM; i++) { sim_printf(" sbc206: RW\n");
uptr = isbc206_dev.units + i;
uptr->u6 = i; //fdd unit number
} }
return SCPE_OK; return SCPE_OK;
} }
// set base address parameter
t_stat isbc206_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
hdc206.baseport = size;
if (hdc206.verb)
sim_printf("SBC206: Base port=%04X\n", hdc206.baseport);
return SCPE_OK;
}
// set interrupt parameter
t_stat isbc206_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
hdc206.intnum = size;
if (hdc206.verb)
sim_printf("SBC206: Interrupt number=%04X\n", hdc206.intnum);
return SCPE_OK;
}
t_stat isbc206_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
if (cptr == NULL)
return SCPE_ARG;
if (strncasecmp(cptr, "OFF", 4) == 0) {
hdc206.verb = 0;
return SCPE_OK;
}
if (strncasecmp(cptr, "ON", 3) == 0) {
hdc206.verb = 1;
sim_printf(" SBC206: hdc206.verb=%d\n", hdc206.verb);
return SCPE_OK;
}
return SCPE_ARG;
}
// show configuration parameters
t_stat isbc206_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s Base port at %04X Interrupt # is %i %s",
((isbc206_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
hdc206.baseport, hdc206.intnum,
hdc206.verb ? "Verbose" : "Quiet"
);
return SCPE_OK;
}
/* Hardware reset routine */ /* Hardware reset routine */
t_stat isbc206_reset(DEVICE *dptr) t_stat isbc206_reset(DEVICE *dptr)
{ {
isbc206_reset1(); //software reset int i;
UNIT *uptr;
if (dptr == NULL)
return SCPE_ARG;
if (isbc206_onetime) {
hdc206.baseport = SBC206_BASE; //set default base
hdc206.intnum = SBC206_INT; //set default interrupt
hdc206.verb = 0; //set verb = 0
isbc206_onetime = 0;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < HDD_NUM; i++) {
uptr = isbc206_dev.units + i;
uptr->u6 = i; //fdd unit number
}
}
if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(isbc206r0, hdc206.baseport, 0); //read status
reg_dev(isbc206r1, hdc206.baseport + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc206r2, hdc206.baseport + 2, 0); //write IOPB addr-h and start
reg_dev(isbc206r3, hdc206.baseport + 3, 0); //read rstl byte
reg_dev(isbc206r7, hdc206.baseport + 7, 0); //write reset fdc201
isbc206_reset_dev(); //software reset
if (hdc206.verb)
sim_printf(" sbc206: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
hdc206.baseport, hdc206.intnum, hdc206.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(hdc206.baseport); //read status
unreg_dev(hdc206.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(hdc206.baseport + 2); //write IOPB addr-h and start
unreg_dev(hdc206.baseport + 3); //read rstl byte
unreg_dev(hdc206.baseport + 7); //write reset fdc201
if (hdc206.verb)
sim_printf(" sbc206: Disabled\n");
}
return SCPE_OK; return SCPE_OK;
} }
/* Software reset routine */ /* Software reset routine */
void isbc206_reset1(void) void isbc206_reset_dev(void)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
hdc206.stat = 0; //clear status hdc206.stat = 0; //clear status
for (i = 0; i < HD_NUM; i++) { /* handle all units */ for (i = 0; i < HDD_NUM; i++) { /* handle all units */
uptr = isbc206_dev.units + i; uptr = isbc206_dev.units + i;
hdc206.stat |= (HDCPRE + 0x80); //set the HDC status hdc206.stat |= (HDCPRE + 0x80); //set the HDC status
hdc206.rtype = ROK; hdc206.rtype = ROK;
@ -368,20 +482,6 @@ t_stat isbc206_attach (UNIT *uptr, CONST char *cptr)
return SCPE_OK; return SCPE_OK;
} }
/* isbc206 set mode = Write protect */
t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
} else { /* read write */
uptr->flags &= ~val;
}
return SCPE_OK;
}
/* iSBC206 control port functions */ /* iSBC206 control port functions */
uint8 isbc206r0(t_bool io, uint8 data, uint8 devnum) uint8 isbc206r0(t_bool io, uint8 data, uint8 devnum)
@ -442,7 +542,7 @@ uint8 isbc206r7(t_bool io, uint8 data, uint8 devnum)
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
isbc206_reset1(); isbc206_reset_dev();
} }
return 0; return 0;
} }
@ -460,12 +560,12 @@ void isbc206_diskio(void)
uint8 *fbuf; uint8 *fbuf;
//parse the IOPB //parse the IOPB
cw = multibus_get_mbyte(hdc206.iopb); cw = get_mbyte(hdc206.iopb);
di = multibus_get_mbyte(hdc206.iopb + 1); di = get_mbyte(hdc206.iopb + 1);
nr = multibus_get_mbyte(hdc206.iopb + 2); nr = get_mbyte(hdc206.iopb + 2);
ta = multibus_get_mbyte(hdc206.iopb + 3); ta = get_mbyte(hdc206.iopb + 3);
sa = multibus_get_mbyte(hdc206.iopb + 4); sa = get_mbyte(hdc206.iopb + 4);
ba = multibus_get_mbyte(hdc206.iopb + 5); ba = get_mbyte(hdc206.iopb + 5);
hddnum = (di & 0x30) >> 4; hddnum = (di & 0x30) >> 4;
uptr = isbc206_dev.units + hddnum; uptr = isbc206_dev.units + hddnum;
fbuf = (uint8 *) (isbc206_dev.units + hddnum)->filebuf; fbuf = (uint8 *) (isbc206_dev.units + hddnum)->filebuf;
@ -539,7 +639,7 @@ void isbc206_diskio(void)
sim_printf("\n SBC206: HDD %d - Write protect error DFMT", hddnum); sim_printf("\n SBC206: HDD %d - Write protect error DFMT", hddnum);
return; return;
} }
fmtb = multibus_get_mbyte(ba); //get the format byte fmtb = get_mbyte(ba); //get the format byte
//calculate offset into disk image //calculate offset into disk image
dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128;
for(i=0; i<=((uint32)(MAXSECHD) * 128); i++) { for(i=0; i<=((uint32)(MAXSECHD) * 128); i++) {
@ -557,7 +657,7 @@ void isbc206_diskio(void)
//copy sector from image to RAM //copy sector from image to RAM
for (i=0; i<128; i++) { for (i=0; i<128; i++) {
data = *(fbuf + (dskoff + i)); data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data); put_mbyte(ba + i, data);
} }
sa++; sa++;
ba+=0x80; ba+=0x80;
@ -582,7 +682,7 @@ void isbc206_diskio(void)
dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECHD) + (sa - 1)) * 128;
//copy sector from image to RAM //copy sector from image to RAM
for (i=0; i<128; i++) { for (i=0; i<128; i++) {
data = multibus_get_mbyte(ba + i); data = get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data; *(fbuf + (dskoff + i)) = data;
} }
sa++; sa++;

View file

@ -35,9 +35,13 @@
#if defined (SBC464_NUM) && (SBC464_NUM > 0) #if defined (SBC464_NUM) && (SBC464_NUM > 0)
#define BASE_ADDR u3
/* prototypes */ /* prototypes */
t_stat isbc464_cfg(uint16 base, uint16 size); t_stat isbc464_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc464_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc464_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat isbc464_reset (DEVICE *dptr); t_stat isbc464_reset (DEVICE *dptr);
t_stat isbc464_attach (UNIT *uptr, CONST char *cptr); t_stat isbc464_attach (UNIT *uptr, CONST char *cptr);
uint8 isbc464_get_mbyte(uint16 addr); uint8 isbc464_get_mbyte(uint16 addr);
@ -50,10 +54,23 @@ extern uint8 xack; /* XACK signal */
/* local globals */ /* local globals */
int isbc464_onetime = 1;
/* isbc464 Standard I/O Data Structures */ /* isbc464 Standard I/O Data Structures */
UNIT isbc464_unit = { UNIT isbc464_unit = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0 UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+
UNIT_MUSTBUF, 0)
};
MTAB isbc464_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, NULL, "SIZE", &isbc464_set_size,
NULL, NULL, "Sets the ROM size for iSBC464" },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "BASE", &isbc464_set_base,
NULL, NULL, "Sets the ROM base for iSBC464" },
{ MTAB_XTD|MTAB_VDV, 0, "PARAM", NULL, NULL, &isbc464_show_param, NULL,
"Parameter" },
{ 0 }
}; };
DEBTAB isbc464_debug[] = { DEBTAB isbc464_debug[] = {
@ -71,7 +88,7 @@ DEVICE isbc464_dev = {
"SBC464", //name "SBC464", //name
&isbc464_unit, //units &isbc464_unit, //units
NULL, //registers NULL, //registers
NULL, //modifiers isbc464_mod, //modifiers
1, //numunits 1, //numunits
16, //aradix 16, //aradix
16, //awidth 16, //awidth
@ -80,12 +97,12 @@ DEVICE isbc464_dev = {
8, //dwidth 8, //dwidth
NULL, //examine NULL, //examine
NULL, //deposite NULL, //deposite
NULL, //reset &isbc464_reset, //reset
NULL, //boot NULL, //boot
isbc464_attach, //attach isbc464_attach, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags DEV_DISABLE+DEV_DIS, //flags
0, //dctrl 0, //dctrl
isbc464_debug, //debflags isbc464_debug, //debflags
NULL, //msize NULL, //msize
@ -94,21 +111,81 @@ DEVICE isbc464_dev = {
/* isbc464 globals */ /* isbc464 globals */
// configuration routine // set size parameter
t_stat isbc464_cfg(uint16 base, uint16 size) t_stat isbc464_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
sim_printf(" sbc464: 0%04XH bytes at base 0%04XH\n", uint32 size, result, i;
size, base);
isbc464_unit.capac = size; //set size if (cptr == NULL)
isbc464_unit.u3 = base; //and base return SCPE_ARG;
isbc464_unit.filebuf = (uint8 *)calloc(size, sizeof(uint8)); result = sscanf(cptr, "%i%n", &size, &i);
if (isbc464_unit.filebuf == NULL) { if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
sim_printf (" sbc464: Calloc error\n"); ((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) {
return SCPE_MEM; switch (size) {
case 0x10: //16K
uptr->capac = 16384;
break;
case 0x20: //32K
uptr->capac = 32768;
break;
case 0x30: //48K
uptr->capac = 49152;
break;
case 0x40: //64K
uptr->capac = 65536;
break;
default:
sim_printf("SBC464: Size error\n");
return SCPE_ARG;
} }
// sim_printf(" sbc464: 0%04XH bytes at base 0%04XH\n", sim_printf("SBC464: Size=%04X\n", uptr->capac);
// isbc464_unit.capac, isbc464_unit.u3); return SCPE_OK;
}
return SCPE_ARG;
}
// set base address parameter
t_stat isbc464_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result, i;
if (cptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%i%n", &size, &i);
if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) {
switch (size) {
case 0x00: //0K
uptr->BASE_ADDR = 0;
break;
case 0x10: //16K
uptr->BASE_ADDR = 16384;
break;
case 0x20: //32K
uptr->BASE_ADDR = 32768;
break;
case 0x30: //48K
uptr->BASE_ADDR = 49152;
break;
default:
sim_printf("SBC464: Base error\n");
return SCPE_ARG;
}
sim_printf("SBC464: Base=%04X\n", uptr->BASE_ADDR);
return SCPE_OK;
}
return SCPE_ARG;
}
// show configuration parameters
t_stat isbc464_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "%s Size=%04X Base=%04X ",
((isbc464_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
uptr->capac, uptr->BASE_ADDR);
return SCPE_OK; return SCPE_OK;
} }
@ -116,6 +193,26 @@ t_stat isbc464_cfg(uint16 base, uint16 size)
t_stat isbc464_reset (DEVICE *dptr) t_stat isbc464_reset (DEVICE *dptr)
{ {
if (isbc464_onetime) {
isbc464_dev.units->capac = SBC464_SIZE; //set default size
isbc464_dev.units->BASE_ADDR = SBC464_BASE; //set default base
isbc464_onetime = 0;
}
if (dptr == NULL)
return SCPE_ARG;
if ((dptr->flags & DEV_DIS) == 0) { //already enabled
isbc464_dev.units->filebuf = (uint8 *)calloc(isbc464_dev.units->capac, sizeof(uint8)); //alloc buffer
if (isbc464_dev.units->filebuf == NULL) { //CALLOC error
sim_printf (" sbc464: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" sbc464: Enabled 0%04XH bytes at base 0%04XH\n",
isbc464_dev.units->capac, isbc464_dev.units->BASE_ADDR);
} else {
if (isbc464_dev.units->filebuf)
free(isbc464_dev.units->filebuf); //return allocated memory
sim_printf(" sbc464: Disabled\n");
}
return SCPE_OK; return SCPE_OK;
} }
@ -137,13 +234,9 @@ t_stat isbc464_attach (UNIT *uptr, CONST char *cptr)
uint8 isbc464_get_mbyte(uint16 addr) uint8 isbc464_get_mbyte(uint16 addr)
{ {
uint32 val, org, len; uint8 val;
uint8 *fbuf;
org = isbc464_unit.u3; val = *((uint8 *)isbc464_unit.filebuf + (addr - isbc464_unit.BASE_ADDR));
len = isbc464_unit.capac;
fbuf = (uint8 *) isbc464_unit.filebuf;
val = *(fbuf + (addr - org));
return (val & 0xFF); return (val & 0xFF);
} }

View file

@ -34,15 +34,17 @@
#include "system_defs.h" #include "system_defs.h"
#define BASE_ADDR u3
/* function prototypes */ /* function prototypes */
t_stat multibus_cfg(void);
t_stat multibus_svc(UNIT *uptr); t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr); t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num); void set_irq(int32 int_num);
void clr_irq(int32 int_num); void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 port, uint8 devnum); uint8 nulldev(t_bool io, uint8 port, uint8 devnum);
uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
uint8 unreg_dev(uint8 port);
t_stat multibus_reset (DEVICE *dptr); t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr); uint8 multibus_get_mbyte(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val); void multibus_put_mbyte(uint16 addr, uint8 val);
@ -54,20 +56,6 @@ extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val); extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr); extern uint8 isbc464_get_mbyte(uint16 addr);
extern void set_cpuint(int32 int_num); extern void set_cpuint(int32 int_num);
extern t_stat isbc064_reset (DEVICE *);
extern t_stat isbc464_reset (DEVICE *);
extern t_stat isbc201_reset (DEVICE *);
extern t_stat isbc202_reset (DEVICE *);
extern t_stat isbc206_reset (DEVICE *);
extern t_stat isbc208_reset (DEVICE *);
extern t_stat zx200a_reset(DEVICE *);
extern t_stat isbc064_cfg(uint16 base, uint16 size);
extern t_stat isbc464_cfg(uint16 base, uint16 size);
extern t_stat isbc201_cfg(uint8 base);
extern t_stat isbc202_cfg(uint8 base);
extern t_stat isbc206_cfg(uint8 base);
extern t_stat isbc208_cfg(uint8 base);
extern t_stat zx200a_cfg(uint8 base);
/* local globals */ /* local globals */
@ -80,18 +68,11 @@ extern int32 int_req; /* i8080 INT signal */
extern uint16 PCX; extern uint16 PCX;
extern DEVICE isbc064_dev; extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev; extern DEVICE isbc464_dev;
extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE isbc208_dev;
extern DEVICE zx200a_dev;
extern UNIT isbc064_unit;
extern UNIT isbc464_unit;
/* multibus Standard SIMH Device Data Structures */ /* multibus Standard SIMH Device Data Structures */
UNIT multibus_unit = { UNIT multibus_unit = {
UDATA (&multibus_svc, 0, 0), 20 UDATA (&multibus_svc, 0, 0), 1
}; };
REG multibus_reg[] = { REG multibus_reg[] = {
@ -132,74 +113,21 @@ DEVICE multibus_dev = {
0, //dctrl 0, //dctrl
multibus_debug, //debflags multibus_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
}; };
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
#if defined (SBC064_NUM) && (SBC064_NUM > 0)
isbc064_cfg(SBC064_BASE, SBC064_SIZE);
#endif
#if defined (SBC464_NUM) && (SBC464_NUM > 0)
isbc464_cfg(SBC464_BASE, SBC464_SIZE);
#endif
#if defined (SBC201_NUM) && (SBC201_NUM > 0)
isbc201_cfg(SBC201_BASE);
#endif
#if defined (SBC202_NUM) && (SBC202_NUM > 0)
isbc202_cfg(SBC202_BASE);
#endif
#if defined (SBC206_NUM) && (SBC206_NUM > 0)
isbc206_cfg(SBC206_BASE);
#endif
#if defined (SBC208_NUM) && (SBC208_NUM > 0)
isbc208_cfg(SBC208_BASE);
#endif
#if defined (ZX200A_NUM) && (ZX200A_NUM > 0)
zx200a_cfg(ZX200A_BASE);
#endif
return SCPE_OK;
}
/* Reset routine */ /* Reset routine */
t_stat multibus_reset(DEVICE *dptr) t_stat multibus_reset(DEVICE *dptr)
{ {
if (SBC_reset(NULL) == 0) { if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n"); sim_printf(" Multibus: Reset\n");
#if defined (SBC064_NUM) && (SBC064_NUM > 0)
isbc064_reset(&isbc064_dev);
sim_printf(" Multibus: SBC064 reset\n");
#endif
#if defined (SBC464_NUM) && (SBC464_NUM > 0)
isbc464_reset(&isbc464_dev);
sim_printf(" Multibus: SBC464 reset\n");
#endif
#if defined (SBC201_NUM) && (SBC201_NUM > 0)
isbc201_reset(&isbc201_dev);
sim_printf(" Multibus: SBC201 reset\n");
#endif
#if defined (SBC202_NUM) && (SBC202_NUM > 0)
isbc202_reset(&isbc202_dev);
sim_printf(" Multibus: SBC202 reset\n");
#endif
#if defined (SBC208_NUM) && (SBC208_NUM > 0)
isbc206_reset(&isbc206_dev);
sim_printf(" Multibus: SBC206 reset\n");
#endif
#if defined (SBC208_NUM) && (SBC208_NUM > 0)
isbc208_reset(&isbc208_dev);
sim_printf(" Multibus: SBC208 reset\n");
#endif
#if defined (ZX200A_NUM) && (ZX200A_NUM > 0)
zx200a_reset(&zx200a_dev);
sim_printf(" Multibus: ZX200A reset\n");
#endif
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */ sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} else { } else {
@ -313,7 +241,8 @@ struct idev dev_table[256] = {
uint8 nulldev(t_bool io, uint8 data, uint8 devnum) uint8 nulldev(t_bool io, uint8 data, uint8 devnum)
{ {
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
return 0xff; /* multibus has active high pullups and inversion */ // return 0xff; /* multibus has active high pullups and inversion */
return 0; //corrects "illegal disk at port X8H" error in ISIS
} }
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum) uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
@ -324,6 +253,19 @@ uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port,
} else { } else {
dev_table[port].routine = routine; dev_table[port].routine = routine;
dev_table[port].devnum = devnum; dev_table[port].devnum = devnum;
sim_printf(" I/O Port %02X has been assigned\n", port);
}
return 0;
}
uint8 unreg_dev(uint8 port)
{
if (dev_table[port].routine == &nulldev) { /* port already free */
sim_printf(" I/O Port %02X is already free\n", port);
} else {
dev_table[port].routine = &nulldev;
dev_table[port].devnum = 0;
sim_printf(" I/O Port %02X is free\n", port);
} }
return 0; return 0;
} }
@ -335,13 +277,15 @@ uint8 multibus_get_mbyte(uint16 addr)
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
#if defined (SBC464_NUM) && (SBC464_NUM > 0) #if defined (SBC464_NUM) && (SBC464_NUM > 0)
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= isbc464_unit.u3 && addr < (isbc464_unit.u3 + isbc464_unit.capac)) if (addr >= isbc464_dev.units->BASE_ADDR && addr <
(isbc464_dev.units->BASE_ADDR + isbc464_dev.units->capac))
return(isbc464_get_mbyte(addr)); return(isbc464_get_mbyte(addr));
} }
#endif #endif
#if defined (SBC064_NUM) && (SBC064_NUM > 0) #if defined (SBC064_NUM) && (SBC064_NUM > 0)
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= isbc064_unit.u3 && addr < (isbc064_unit.u3 + isbc064_unit.capac)) if (addr >= isbc064_dev.units->BASE_ADDR && addr <
(isbc064_dev.units->BASE_ADDR + isbc064_dev.units->capac))
return (isbc064_get_mbyte(addr)); return (isbc064_get_mbyte(addr));
} }
#endif #endif
@ -353,7 +297,8 @@ void multibus_put_mbyte(uint16 addr, uint8 val)
SET_XACK(0); /* set no XACK */ SET_XACK(0); /* set no XACK */
#if defined (SBC064_NUM) && (SBC064_NUM > 0) #if defined (SBC064_NUM) && (SBC064_NUM > 0)
if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if ((addr >= SBC064_BASE) && (addr <= (SBC064_BASE + SBC064_SIZE - 1))) if (addr >= isbc064_dev.units->BASE_ADDR && addr <
(isbc064_dev.units->BASE_ADDR + isbc064_dev.units->capac))
isbc064_put_mbyte(addr, val); isbc064_put_mbyte(addr, val);
} }
#endif #endif

View file

@ -145,6 +145,7 @@
#define UNIT_WPMODE (1 << UNIT_V_WPMODE) #define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 6 #define FDD_NUM 6
#define SECSIZ 128
//disk controoler operations //disk controoler operations
#define DNOP 0x00 //disk no operation #define DNOP 0x00 //disk no operation
@ -191,21 +192,27 @@
#define MAXSECDD 52 //double density last sector #define MAXSECDD 52 //double density last sector
#define MAXTRK 76 //last track #define MAXTRK 76 //last track
/* external function prototypes */ #define zx200a_NAME "Zendex ZX-200A Floppy Disk Controller Board"
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
/* external globals */ /* external globals */
extern uint16 PCX; extern uint16 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 unreg_dev(uint8);
extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
/* internal function prototypes */ /* internal function prototypes */
t_stat isbc064_cfg(uint16 base); t_stat zx200a_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat zx200a_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat zx200a_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat zx200a_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat zx200a_reset(DEVICE *dptr); t_stat zx200a_reset(DEVICE *dptr);
void zx200a_reset1(void); void zx200a_reset_dev(void);
t_stat zx200a_attach (UNIT *uptr, CONST char *cptr); t_stat zx200a_attach (UNIT *uptr, CONST char *cptr);
t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
uint8 zx200ar0SD(t_bool io, uint8 data, uint8 devnum); uint8 zx200ar0SD(t_bool io, uint8 data, uint8 devnum);
@ -220,19 +227,21 @@ void zx200a_diskio(void);
/* globals */ /* globals */
int zx200a_onetime = 1;
static const char* zx200a_desc(DEVICE *dptr) {
return zx200a_NAME;
}
typedef struct { //FDD definition typedef struct { //FDD definition
// uint8 *buf;
// int t0;
// int rdy;
uint8 sec; uint8 sec;
uint8 cyl; uint8 cyl;
uint8 dd; uint8 dd;
// uint8 maxsec;
// uint8 maxcyl;
} FDDDEF; } FDDDEF;
typedef struct { //FDC definition typedef struct { //FDC definition
uint16 baseport; //FDC base port uint8 baseport; //FDC base port
uint8 intnum; //interrupt number
uint8 verb; //verbose flag
uint16 iopb; //FDC IOPB uint16 iopb; //FDC IOPB
uint8 DDstat; //FDC DD status uint8 DDstat; //FDC DD status
uint8 SDstat; //FDC SD status uint8 SDstat; //FDC SD status
@ -249,12 +258,13 @@ FDCDEF zx200a;
/* ZX-200A Standard I/O Data Structures */ /* ZX-200A Standard I/O Data Structures */
UNIT zx200a_unit[] = { UNIT zx200a_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD), 20 }, { UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ NULL }
}; };
REG zx200a_reg[] = { REG zx200a_reg[] = {
@ -270,6 +280,15 @@ REG zx200a_reg[] = {
MTAB zx200a_mod[] = { MTAB zx200a_mod[] = {
{ UNIT_WPMODE, 0, "RW", "RW", &zx200a_set_mode }, { UNIT_WPMODE, 0, "RW", "RW", &zx200a_set_mode },
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &zx200a_set_mode }, { UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &zx200a_set_mode },
// { UNIT_WPMODE, UNIT_WPMODE, "RO", "RO", &zx200a_set_mode },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "VERB", &zx200a_set_verb,
NULL, NULL, "Sets the verbose mode for ZX-200A"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "PORT", &zx200a_set_port,
NULL, NULL, "Sets the base port for ZX-200A"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "INT", &zx200a_set_int,
NULL, NULL, "Sets the interrupt number for ZX-200A"},
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, &zx200a_show_param, NULL,
"show configured parametes for ZX-200A" },
{ 0 } { 0 }
}; };
@ -304,59 +323,160 @@ DEVICE zx200a_dev = {
&zx200a_attach, //attach &zx200a_attach, //attach
NULL, //detach NULL, //detach
NULL, //ctxt NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags DEV_DISABLE+DEV_DIS, //flags
// DEBUG_flow + DEBUG_read + DEBUG_write, //dctrl
0, //dctrl 0, //dctrl
zx200a_debug, //debflags zx200a_debug, //debflags
NULL, //msize NULL, //msize
NULL //lname NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&zx200a_desc //device description
}; };
/* zx200a set mode = Write protect */
t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
if (zx200a.verb)
sim_printf(" sbc202: WP\n");
} else { /* read write */
uptr->flags &= ~val;
if (zx200a.verb)
sim_printf(" sbc202: RW\n");
}
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
// configuration routine // set base address parameter
t_stat zx200a_cfg(uint8 base) t_stat zx200a_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{ {
int32 i; uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
zx200a.baseport = size;
if (zx200a.verb)
sim_printf("SBC202: Base port=%04X\n", zx200a.baseport);
return SCPE_OK;
}
// set interrupt parameter
t_stat zx200a_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result;
if (uptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
zx200a.intnum = size;
if (zx200a.verb)
sim_printf("SBC202: Interrupt number=%04X\n", zx200a.intnum);
return SCPE_OK;
}
t_stat zx200a_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
if (cptr == NULL)
return SCPE_ARG;
if (strncasecmp(cptr, "OFF", 4) == 0) {
zx200a.verb = 0;
return SCPE_OK;
}
if (strncasecmp(cptr, "ON", 3) == 0) {
zx200a.verb = 1;
sim_printf(" SBC202: zx200a.verb=%d\n", zx200a.verb);
return SCPE_OK;
}
return SCPE_ARG;
}
// show configuration parameters
t_stat zx200a_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s Base port at %04X Interrupt # is %i %s",
((zx200a_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
zx200a.baseport, zx200a.intnum,
zx200a.verb ? "Verbose" : "Quiet"
);
return SCPE_OK;
}
/* Hardware reset routine */
t_stat zx200a_reset(DEVICE *dptr)
{
int i;
UNIT *uptr; UNIT *uptr;
sim_printf(" zx200a: at base 0%02XH\n", if (dptr == NULL)
base); return SCPE_ARG;
//register I/O port addresses for each function if (zx200a_onetime) {
reg_dev(zx200ar0DD, base, 0); //read status zx200a.baseport = SBC202_BASE; //set default base
reg_dev(zx200ar1DD, base + 1, 0); //read rslt type/write IOPB addr-l zx200a.intnum = SBC202_INT; //set default interrupt
reg_dev(zx200ar2DD, base + 2, 0); //write IOPB addr-h and start zx200a.verb = 0; //set verb = 0
reg_dev(zx200ar3, base + 3, 0); //read rstl byte zx200a_onetime = 0;
reg_dev(zx200ar7, base + 7, 0); //write reset zx200a // one-time initialization for all FDDs for this FDC instance
reg_dev(zx200ar0SD, base + 16, 0); //read status
reg_dev(zx200ar1SD, base + 17, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200ar2SD, base + 18, 0); //write IOPB addr-h and start
reg_dev(zx200ar3, base + 19, 0); //read rstl byte
reg_dev(zx200ar7, base + 23, 0); //write reset zx200a
// one-time initialization for all FDDs
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
uptr = zx200a_dev.units + i; uptr = zx200a_dev.units + i;
uptr->u6 = i; //fdd unit number uptr->u6 = i; //fdd unit number
} }
return SCPE_OK;
} }
if ((dptr->flags & DEV_DIS) == 0) { // enabled
/* Reset routine */ reg_dev(zx200ar0DD, zx200a.baseport, 0); //read status
reg_dev(zx200ar0DD, zx200a.baseport + 1, 0); //read rslt type/write IOPB addr-l
t_stat zx200a_reset(DEVICE *dptr) reg_dev(zx200ar0DD, zx200a.baseport + 2, 0); //write IOPB addr-h and start
{ reg_dev(zx200ar3, zx200a.baseport + 3, 0); //read rstl byte
zx200a_reset1(); //software reset reg_dev(zx200ar7, zx200a.baseport + 7, 0); //write reset fdc201
reg_dev(zx200ar0SD, zx200a.baseport + 16, 0); //read status
reg_dev(zx200ar1SD, zx200a.baseport + 17, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200ar2SD, zx200a.baseport + 18, 0); //write IOPB addr-h and start
reg_dev(zx200ar3, zx200a.baseport + 19, 0); //read rstl byte
reg_dev(zx200ar7, zx200a.baseport + 23, 0); //write reset zx200a
zx200a_reset_dev(); //software reset
if (zx200a.verb)
sim_printf(" ZX200A: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
zx200a.baseport, zx200a.intnum, zx200a.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(zx200a.baseport); //read status
unreg_dev(zx200a.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(zx200a.baseport + 2); //write IOPB addr-h and start
unreg_dev(zx200a.baseport + 3); //read rstl byte
unreg_dev(zx200a.baseport + 7); //write reset fdc201
unreg_dev(zx200a.baseport + 16); //read status
unreg_dev(zx200a.baseport + 17); //read rslt type/write IOPB addr-l
unreg_dev(zx200a.baseport + 18); //write IOPB addr-h and start
unreg_dev(zx200a.baseport + 19); //read rstl byte
unreg_dev(zx200a.baseport + 23); //write reset fdc201
if (zx200a.verb)
sim_printf(" ZX200A: Disabled\n");
}
return SCPE_OK; return SCPE_OK;
} }
/* Software reset routine */ /* Software reset routine */
void zx200a_reset1(void) void zx200a_reset_dev(void)
{ {
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
@ -450,20 +570,6 @@ t_stat zx200a_attach (UNIT *uptr, CONST char *cptr)
return SCPE_OK; return SCPE_OK;
} }
/* zx200a set mode = Write protect */
t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
} else { /* read write */
uptr->flags &= ~val;
}
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an /* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued. IN or OUT instruction is issued.
*/ */
@ -564,7 +670,7 @@ uint8 zx200ar7(t_bool io, uint8 data, uint8 devnum)
if (io == 0) { /* read data port */ if (io == 0) { /* read data port */
; ;
} else { /* write data port */ } else { /* write data port */
zx200a_reset1(); zx200a_reset_dev();
} }
return 0; return 0;
} }
@ -582,13 +688,13 @@ void zx200a_diskio(void)
uint8 *fbuf; uint8 *fbuf;
//parse the IOPB //parse the IOPB
cw = multibus_get_mbyte(zx200a.iopb); cw = get_mbyte(zx200a.iopb);
di = multibus_get_mbyte(zx200a.iopb + 1); di = get_mbyte(zx200a.iopb + 1);
nr = multibus_get_mbyte(zx200a.iopb + 2); nr = get_mbyte(zx200a.iopb + 2);
ta = multibus_get_mbyte(zx200a.iopb + 3); ta = get_mbyte(zx200a.iopb + 3);
sa = multibus_get_mbyte(zx200a.iopb + 4); sa = get_mbyte(zx200a.iopb + 4);
ba = multibus_get_mbyte(zx200a.iopb + 5); ba = get_mbyte(zx200a.iopb + 5);
ba |= (multibus_get_mbyte(zx200a.iopb + 6) << 8); ba |= (get_mbyte(zx200a.iopb + 6) << 8);
fddnum = (di & 0x30) >> 4; fddnum = (di & 0x30) >> 4;
uptr = zx200a_dev.units + fddnum; uptr = zx200a_dev.units + fddnum;
fbuf = (uint8 *) uptr->filebuf; fbuf = (uint8 *) uptr->filebuf;
@ -715,7 +821,7 @@ void zx200a_diskio(void)
sim_printf("\n zx200a: Write protect error 1 on drive %d", fddnum); sim_printf("\n zx200a: Write protect error 1 on drive %d", fddnum);
return; return;
} }
fmtb = multibus_get_mbyte(ba); //get the format byte fmtb = get_mbyte(ba); //get the format byte
if (zx200a.fdd[fddnum].dd == 1) { if (zx200a.fdd[fddnum].dd == 1) {
//calculate offset into DD disk image //calculate offset into DD disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECDD) + (sa - 1)) * 128;
@ -745,7 +851,7 @@ void zx200a_diskio(void)
//copy sector from image to RAM //copy sector from image to RAM
for (i=0; i<128; i++) { for (i=0; i<128; i++) {
data = *(fbuf + (dskoff + i)); data = *(fbuf + (dskoff + i));
multibus_put_mbyte(ba + i, data); put_mbyte(ba + i, data);
} }
sa++; sa++;
ba+=0x80; ba+=0x80;
@ -773,7 +879,7 @@ void zx200a_diskio(void)
dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128; dskoff = ((ta * MAXSECSD) + (sa - 1)) * 128;
} }
for (i=0; i<128; i++) { //copy sector from image to RAM for (i=0; i<128; i++) { //copy sector from image to RAM
data = multibus_get_mbyte(ba + i); data = get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data; *(fbuf + (dskoff + i)) = data;
} }
sa++; sa++;

View file

Before

Width:  |  Height:  |  Size: 788 KiB

After

Width:  |  Height:  |  Size: 788 KiB

View file

@ -40,6 +40,7 @@ extern DEVICE ipc_cont_dev;
extern DEVICE multibus_dev; extern DEVICE multibus_dev;
extern DEVICE isbc201_dev; extern DEVICE isbc201_dev;
extern DEVICE isbc202_dev; extern DEVICE isbc202_dev;
extern DEVICE isbc206_dev;
extern DEVICE zx200a_dev; extern DEVICE zx200a_dev;
/* SCP data structures /* SCP data structures
@ -73,6 +74,9 @@ DEVICE *sim_devices[] = {
#if defined (SBC202_NUM) && (SBC202_NUM > 0) #if defined (SBC202_NUM) && (SBC202_NUM > 0)
&isbc202_dev, &isbc202_dev,
#endif #endif
#if defined (SBC206_NUM) && (SBC206_NUM > 0)
&isbc206_dev,
#endif
#if defined (ZX200A_NUM) && (ZX200A_NUM > 0) #if defined (ZX200A_NUM) && (ZX200A_NUM > 0)
&zx200a_dev, &zx200a_dev,
#endif #endif

View file

@ -73,7 +73,7 @@
/* set the base I/O address for the iSBC 201 */ /* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x88 #define SBC201_BASE 0x88
#define SBC201_INT INT_2 #define SBC201_INT INT_2
#define SBC201_NUM 0 #define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */ /* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78 #define SBC202_BASE 0x78
@ -82,8 +82,8 @@
/* set the base I/O address for the iSBC 206 */ /* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68 #define SBC206_BASE 0x68
#define SBC206_INT INT_1 #define SBC206_INT INT_2
#define SBC206_NUM 0 #define SBC206_NUM 1
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40
@ -98,7 +98,7 @@
/* set the base and size for the iSBC 064 RAM*/ /* set the base and size for the iSBC 064 RAM*/
#define SBC064_BASE 0x8000 #define SBC064_BASE 0x8000
#define SBC064_SIZE 0x7FFF #define SBC064_SIZE 0x7FFF
#define SBC064_NUM 0 #define SBC064_NUM 1
/* set the base and size for the iSBC 464 ROM */ /* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800 #define SBC464_BASE 0xA800

View file

@ -84,7 +84,7 @@
/* set the base I/O address for the iSBC 206 */ /* set the base I/O address for the iSBC 206 */
#define SBC206_BASE 0x68 #define SBC206_BASE 0x68
#define SBC206_INT INT_1 #define SBC206_INT INT_1
#define SBC206_NUM 0 #define SBC206_NUM 1
/* set the base I/O address for the iSBC 208 */ /* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40 #define SBC208_BASE 0x40

View file

@ -27,35 +27,38 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <ctype.h> #include <ctype.h>
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
#define SET_XACK(VAL) (xack = VAL) #define SET_XACK(VAL) (xack = VAL)
// This file sets the initial stats of devices and units
#define I3214_NUM 0 #define I3214_NUM 0
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8253 */
#define I8253_BASE 0xF0
#define I8253_NUM 1
/* set the base I/O address for the 8251 */ /* set the base I/O address for the 8251 */
#define I8251_BASE_0 0xF4 #define I8251_BASE_0 0xF4
#define I8251_BASE_1 0xF6 #define I8251_BASE_1 0xF6
#define I8251_NUM 2 #define I8251_NUM 2
/* set the base I/O address for the 8253 */
#define I8253_BASE 0xF0
#define I8253_NUM 1
/* set the base I/O address for the 8255 */
#define I8255_BASE_0 0xE4
#define I8255_BASE_1 0xE8
#define I8255_NUM 2
/* set the base I/O address for the 8259 */ /* set the base I/O address for the 8259 */
#define I8259_BASE_0 0xFA #define I8259_BASE_0 0xFA
#define I8259_BASE_1 0xFC #define I8259_BASE_1 0xFC
#define I8259_NUM 2 #define I8259_NUM 2
/* set the base for the DBB ports */
#define DBB_BASE 0xC0
/* set the base I/O address for the IPC control port */ /* set the base I/O address for the IPC control port */
#define ICONT_BASE 0xFF #define ICONT_BASE 0xFF
@ -71,9 +74,9 @@
//board definitions for the multibus //board definitions for the multibus
/* set the base I/O address for the iSBC 201 */ /* set the base I/O address for the iSBC 201 */
#define SBC201_BASE 0x78 #define SBC201_BASE 0x88
#define SBC201_INT INT_2 #define SBC201_INT INT_2
#define SBC201_NUM 0 #define SBC201_NUM 1
/* set the base I/O address for the iSBC 202 */ /* set the base I/O address for the iSBC 202 */
#define SBC202_BASE 0x78 #define SBC202_BASE 0x78
@ -93,7 +96,7 @@
/* set the base for the zx-200a disk controller */ /* set the base for the zx-200a disk controller */
#define ZX200A_BASE 0x78 #define ZX200A_BASE 0x78
#define ZX200A_INT INT_2 #define ZX200A_INT INT_2
#define ZX200A_NUM 0 #define ZX200A_NUM 1
/* set the base and size for the iSBC 464 ROM */ /* set the base and size for the iSBC 464 ROM */
#define SBC464_BASE 0xA800 #define SBC464_BASE 0xA800
@ -101,7 +104,7 @@
#define SBC464_NUM 0 #define SBC464_NUM 0
/* set the base and size for the iSBC 064 RAM */ /* set the base and size for the iSBC 064 RAM */
#define SBC064_BASE 0x08000 #define SBC064_BASE 0x8000
#define SBC064_SIZE 0x7FFF #define SBC064_SIZE 0x7FFF
#define SBC064_NUM 1 #define SBC064_NUM 1

View file

@ -52,7 +52,6 @@ extern t_stat fp_reset (void);
extern t_stat fp_cfg(void); extern t_stat fp_cfg(void);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */ extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum); extern uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum);
extern t_stat multibus_cfg(void);
extern uint8 multibus_get_mbyte(uint16 addr); extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val); extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
@ -84,7 +83,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);

View file

@ -57,7 +57,6 @@ extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat i3214_cfg(uint8 base, uint8 devnum); extern t_stat i3214_cfg(uint8 base, uint8 devnum);
extern t_stat fp_cfg(void); extern t_stat fp_cfg(void);
extern t_stat monitor_cfg(void); extern t_stat monitor_cfg(void);
extern t_stat multibus_cfg(void);
// external globals // external globals
@ -83,7 +82,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
EPROM_enable = 1; EPROM_enable = 1;

View file

@ -67,7 +67,6 @@ extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_cfg(uint8 base, uint8 devnum); extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat multibus_cfg();
/* globals */ /* globals */
@ -90,7 +89,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);

View file

@ -36,14 +36,12 @@
/* function prototypes */ /* function prototypes */
t_stat multibus_cfg(void);
t_stat multibus_svc(UNIT *uptr); t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr); t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num); void set_irq(int32 int_num);
void clr_irq(int32 int_num); void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 port, uint8 devnum); uint8 nulldev(t_bool io, uint8 port, uint8 devnum);
uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr); uint8 multibus_get_mbyte(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val); void multibus_put_mbyte(uint16 addr, uint8 val);
@ -137,14 +135,6 @@ DEVICE multibus_dev = {
/* Service routines to handle simulator functions */ /* Service routines to handle simulator functions */
// multibus_cfg
t_stat multibus_cfg(void)
{
sim_printf("Configuring Multibus Devices\n");
return SCPE_OK;
}
/* Reset routine */ /* Reset routine */
t_stat multibus_reset(DEVICE *dptr) t_stat multibus_reset(DEVICE *dptr)

View file

@ -74,7 +74,6 @@ extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_cfg(uint8 base, uint8 devnum); extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat multibus_cfg();
/* globals */ /* globals */
@ -97,7 +96,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);

View file

@ -84,7 +84,6 @@ extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum); extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat multibus_cfg();
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8); extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
// globals // globals
@ -111,7 +110,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);

View file

@ -88,7 +88,6 @@ extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum); extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat multibus_cfg();
// globals // globals
@ -113,7 +112,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);

View file

@ -76,7 +76,6 @@ extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum); extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size); extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum); extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat multibus_cfg();
// globals // globals
@ -100,7 +99,6 @@ t_stat SBC_reset (DEVICE *dptr)
{ {
if (onetime == 0) { if (onetime == 0) {
SBC_config(); SBC_config();
multibus_cfg();
onetime++; onetime++;
} }
i8080_reset(&i8080_dev); i8080_reset(&i8080_dev);