Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swtp6809 simulator being contributed to open-simh project (updated release candidate) #372

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
In preparation of presenting for contribution as a "pull request".
General clean up of code.
Removed unneeded test prints that were used for debugging.
Removed swtp_sbuge_bin.h which implemented BOOTROM code internally. Users should use "ATTACH BOOTROM <sbuge.bin filename>".
Added reset() routine to CPU.  If last line in INI file is "RESET CPU" then simulator goes straight into BOOTROM from reset vector at $FFFE.
Tested with several FLEX 9 DSK files.
Known issues are:
1) Backspace (BS) does not seem to work when running Flex 9.
2) When simulator starts up the PC has a value of $FFFF (and not $FFFE).
3) No DMAF1/DMAF2 disk emulation which is required for support of UniFlex.
4) No documentation has been written yet. However, I am more than willing to put something together.
Note this code was developed using Debian on Raspberry Pi 4. There may be Unix/DOS file conversion issues.
rfromafar committed Feb 21, 2024
commit 6d7bebf272229e54938c18b1887a3c80d83d1b34
179 changes: 74 additions & 105 deletions swtp6809/common/bootrom.c
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
MODIFICATIONS:

23 Apr 15 -- Modified to use simh_debug
19 Feb 24 -- Richard Lukes - Modified for swtp6809 emulator
20 Feb 24 -- Richard Lukes - Modified for swtp6809 emulator

NOTES:

@@ -50,12 +50,6 @@
#include <stdio.h>
#include "swtp_defs.h"

#define DONT_USE_INTERNAL_ROM

#if !defined(DONT_USE_INTERNAL_ROM)
#include "swtp_sbuge_bin.h"
#endif /* DONT_USE_INTERNAL_ROM */

#define UNIT_V_MSIZE (UNIT_V_UF) /* ROM Size */
#define UNIT_MSIZE (0x7 << UNIT_V_MSIZE)
#define UNIT_NONE (0 << UNIT_V_MSIZE) /* No EPROM */
@@ -69,24 +63,22 @@
#define BOOTROM_4K 0x1000
#define BOOTROM_8K 0x2000

// this value is used when referencing BOOTROM memory that is not populated (i.e. not loaded by BOOTROM attach)
#define DEFAULT_NO_ROM_BYTE_VALUE 0xFF

/* function prototypes */

t_stat BOOTROM_attach (UNIT *uptr, CONST char *cptr);
t_stat BOOTROM_config (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat BOOTROM_attach(UNIT *uptr, CONST char *cptr);
t_stat BOOTROM_config(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat BOOTROM_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches);
t_stat BOOTROM_reset (DEVICE *dptr);
//t_stat BOOTROM_svc (UNIT *uptr);
t_stat BOOTROM_reset(DEVICE *dptr);

int32 BOOTROM_get_mbyte(int32 address);

/* SIMH Standard I/O Data Structures */

UNIT BOOTROM_unit = {
#if defined(DONT_USE_INTERNAL_ROM)
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),
#else /* !defined(DONT_USE_INTERNAL_ROM) */
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+((BOOT_CODE_SIZE>>9)<<UNIT_V_MSIZE), BOOT_CODE_SIZE),
#endif
KBD_POLL_WAIT };

MTAB BOOTROM_mod[] = {
@@ -141,57 +133,89 @@ DEVICE BOOTROM_dev = {
/* Available sizes are None=0, 512B=2704, 1KB=2708, 2KB=2716, 4KB=2732, 8KB=2764 */

/* Pre-allocate 8KB array of bytes to accomodate largest BOOTROM */
uint8 BOOTROM_memory_array[BOOTROM_8K];
uint8 BOOTROM_memory[BOOTROM_8K];

t_stat BOOTROM_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches)
{
if (addr >= BOOTROM_8K) {
return SCPE_NXM;
}
if (eval_array != NULL) {
*eval_array = BOOTROM_memory_array[addr] & 0xFF;
*eval_array = BOOTROM_get_mbyte(addr);
}
return SCPE_OK;

} /* BOOTROM_examin() */
} /* BOOTROM_examine() */

/* BOOTROM_attach - attach file to EPROM unit */
t_stat BOOTROM_attach (UNIT *uptr, CONST char *cptr)
t_stat BOOTROM_attach(UNIT *uptr, CONST char *cptr)
{
t_stat r;
t_addr image_size, capac;
int i;
t_addr image_size;
int i,j;
FILE *fp;
uint8 byte_val;
size_t items_read;

if (BOOTROM_unit.filebuf == NULL) { /* no buffer allocated */
BOOTROM_unit.filebuf = BOOTROM_memory;
}
if ((BOOTROM_unit.flags & UNIT_MSIZE) == 0) { /* if none selected */
BOOTROM_unit.capac = 0; /* set EPROM size to 0 */
return SCPE_OK;
}

//RICHARD WAS HERE
printf("calling BOOTROM_attach\n");
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: Error\n");
if ((r = attach_unit(uptr, cptr)) != SCPE_OK) {
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: Error %d\n", r);
return r;
}
image_size = (t_addr)sim_fsize_ex (BOOTROM_unit.fileref);

image_size = (t_addr) sim_fsize_ex(uptr->fileref);
if (image_size <= 0) {
sim_printf("BOOTROM_attach: File error\n");
detach_unit(uptr);
return SCPE_IOERR;
}
for (capac = 0x200, i=1; capac < image_size; capac <<= 1, i++);
if (i > (UNIT_2764>>UNIT_V_MSIZE)) {
detach_unit (uptr);
return SCPE_ARG;
} else {
if (image_size > BOOTROM_8K) {
sim_printf("BOOTROM_attach: Error. File size exceeds ROM capacity\n");
detach_unit(uptr);
return SCPE_ARG;
}
}
uptr->flags &= ~UNIT_MSIZE;
uptr->flags |= (i << UNIT_V_MSIZE);

/* open EPROM file */
fp = fopen(BOOTROM_unit.filename, "rb");
if (fp == NULL) {
printf("Bootrom: Unable to open ROM file %s\n",BOOTROM_unit.filename);
printf("Bootrom: No ROM image loaded!!!\n");
return SCPE_OK;
}

/* load EPROM file */
j = 0;
items_read = sim_fread(&byte_val, (size_t)1, (size_t)1, fp);
while (items_read != 0) {
BOOTROM_memory[j++] = byte_val;
items_read = sim_fread(&byte_val, (size_t)1, (size_t)1,fp);
if (j > BOOTROM_unit.capac) {
printf("Bootrom: Image is too large - Load truncated!!!\n");
j--;
break;
}
}
fclose(fp);
printf("Bootrom: %d bytes of ROM image %s loaded\n", j, BOOTROM_unit.filename);

sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: Done\n");
//RICHARD WAS HERE
return (BOOTROM_reset (NULL));
return SCPE_OK;

} /* BOOTROM_attach() */

/* BOOTROM_config = None, 2704, 2708, 2716, 2732 or 2764 */
t_stat BOOTROM_config (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
//RICHARD WAS HERE
printf("calling BOOTROM_config\n");

sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: val=%d\n", val);
if ((val < UNIT_NONE) || (val > UNIT_2764)) { /* valid param? */
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: Parameter error\n");
@@ -201,91 +225,35 @@ printf("calling BOOTROM_config\n");
BOOTROM_unit.capac = 0; /* set EPROM size */
else
BOOTROM_unit.capac = 0x200 << ((val >> UNIT_V_MSIZE) - 1); /* set EPROM size */
if (BOOTROM_unit.filebuf) { /* free buffer */
//free (BOOTROM_unit.filebuf);
BOOTROM_unit.filebuf = NULL;

if (!BOOTROM_unit.filebuf) { /* point buffer to static array */
BOOTROM_unit.filebuf = BOOTROM_memory;
}

sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: BOOTROM_unit.capac=%d\n",
BOOTROM_unit.capac);
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: Done\n");

return SCPE_OK;
} /* BOOTROM config */

/* BOOTROM reset */
t_stat BOOTROM_reset (DEVICE *dptr)
{
t_addr i,j;
unsigned long c;
long count;
FILE *fp;
uint8 *pa;
t_addr i;

//RICHARD WAS HERE
printf("calling BOOTROM_reset\n");
/* initialize array to $FF */
for (i=0; i<BOOTROM_8K; i++) {
BOOTROM_memory_array[i] = 0xFF;
}
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: \n");

if ((BOOTROM_unit.flags & UNIT_MSIZE) == 0) { /* if none selected */
BOOTROM_unit.capac = 0; /* set EPROM size to 0 */
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: Done1\n");
return SCPE_OK;
} /* if attached */

/* allocate filebuf */
if (BOOTROM_unit.filebuf == NULL) { /* no buffer allocated */
//BOOTROM_unit.filebuf = calloc(1, BOOTROM_unit.capac); /* allocate EPROM buffer */
BOOTROM_unit.filebuf = BOOTROM_memory_array; /* allocate EPROM buffer */
BOOTROM_unit.filebuf = BOOTROM_memory;
if (BOOTROM_unit.filebuf == NULL) {
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: Malloc error\n");
return SCPE_MEM;
}
}

//RICHARD WAS HERE - need to understand INTERNAL_ROM
#if !defined(DONT_USE_INTERNAL_ROM)
if (!BOOTROM_unit.filename) {
if (BOOTROM_unit.capac < BOOT_CODE_SIZE) {
return SCPE_ARG;
}
memcpy (BOOTROM_unit.filebuf, BOOT_CODE_ARRAY, BOOT_CODE_SIZE);
return SCPE_OK;
}
#endif

//RICHARD WAS HERE - I think this needs to move to attach
fp = fopen(BOOTROM_unit.filename, "rb"); /* open EPROM file */
if (fp == NULL) {
printf("\tUnable to open ROM file %s\n",BOOTROM_unit.filename);
printf("\tNo ROM image loaded!!!\n");
return SCPE_OK;
}

j=0;
pa = BOOTROM_unit.filebuf;
count = fread( &c, 1, 1, fp);
while (count != 0) {
pa[j++] = c & 0xFF;
count = fread( &c, 1, 1, fp);

/* warn if ROM image is larger than the specified ROM size */
if (j > BOOTROM_unit.capac) {
printf("\tImage is too large - Load truncated!!!\n");
j--;
break;
}
}
fclose(fp);

/* warn if loaded ROM image is smaller than the specified ROM size */
if (j < BOOTROM_unit.capac) {
printf("\tImage is smaller than specified ROM size!!!\n");
}

printf("\t%d bytes of ROM image %s loaded\n", j, BOOTROM_unit.filename);
sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: Done2\n");
return SCPE_OK;

} /* BOOTROM_reset() */

/* get a byte from memory - from specified memory address */
@@ -296,16 +264,17 @@ int32 BOOTROM_get_mbyte(int32 address)

if (BOOTROM_unit.filebuf == NULL) {
sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: EPROM not configured\n");
return 0xFF;
return DEFAULT_NO_ROM_BYTE_VALUE;
}
sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: address=%04X\n", address);
if ((t_addr)(0xFFFF - address) > BOOTROM_unit.capac) {
sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: EPROM reference beyond ROM size\n");
return 0xFF;
return DEFAULT_NO_ROM_BYTE_VALUE;
}

pa = BOOTROM_unit.filebuf;
/* the following code is needed to calculate offsets so address $FFFF references the last byte of the ROM */
val = 0xFF;
val = DEFAULT_NO_ROM_BYTE_VALUE;
switch (BOOTROM_unit.capac) {
/* 2764 - $E000-$FFFF */
case 0x2000:
28 changes: 11 additions & 17 deletions swtp6809/common/dc-4.c
Original file line number Diff line number Diff line change
@@ -337,7 +337,6 @@ t_stat dsk_reset (DEVICE *dptr)
{
int i;

// RICHARD WAS HERE
cur_dsk = 5; /* force initial SIR read, use a drive # that can't be selected */

for (i=0; i<NUM_DISK; i++) {
@@ -361,18 +360,20 @@ t_stat dsk_reset (DEVICE *dptr)
return SCPE_OK;
}

/* I/O instruction handlers, called from the MP-B3 module when a
read or write occur to addresses 0xE004-0xE007. */
/*
I/O instruction handlers, called from the MP-B3 module when a
read or write occur to addresses 0xE004-0xE007.
*/

/* DC-4 drive select register routine - this register is not part of the 1797
/*
DC-4 drive select register routine - this register is not part of the 1797
*/

int32 fdcdrv(int32 io, int32 data)
{
static long pos;
static int32 err;

// RICHARD WAS HERE
//sim_printf("\nfdcdrv: io=%d, data=%d\n", io, data);

if (io) { /* write to DC-4 drive register */
@@ -389,7 +390,6 @@ int32 fdcdrv(int32 io, int32 data)
sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Drive NOT write protected");
}

// RICHARD WAS HERE
//sim_printf("\nfdcdrv: reading the SIR\n");
// whenever a new drive is selected - re-read the SIR
pos = 0x200; /* Read in SIR */
@@ -406,7 +406,7 @@ int32 fdcdrv(int32 io, int32 data)
sim_printf("\nfdccmd: File error read in SIR\n");
return SCPE_IOERR;
} else {
// RICHARD WAS HERE
;
//sim_printf("\nfdcdrv: SIR was read\n");
}

@@ -418,7 +418,6 @@ int32 fdcdrv(int32 io, int32 data)
trksiz = spt * SECT_SIZE;
dsksiz = trksiz * cpd;

// RICHARD WAS HERE
//sim_printf("\nfdcdrv: spt=%d heds=%d cpd=%d trksiz=%d dsksiz=%d flags=%08X u3=%08X\n", spt, heds, cpd, trksiz, dsksiz, dsk_unit[cur_dsk].flags, dsk_unit[cur_dsk].u3);

sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: spt=%d heds=%d cpd=%d trksiz=%d dsksiz=%d flags=%08X u3=%08X",
@@ -438,8 +437,6 @@ int32 fdccmd(int32 io, int32 data)
static long pos;
static int32 err;

// RICHARD WAS HERE

if ((dsk_unit[cur_dsk].flags & UNIT_ATT) == 0) { /* not attached */
dsk_unit[cur_dsk].u3 |= NOTRDY; /* set not ready flag */
sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Drive %d is not attached", cur_dsk);
@@ -449,7 +446,6 @@ int32 fdccmd(int32 io, int32 data)
}
if (io) { /* write command to fdc */

// RICHARD WAS HERE
//sim_printf("fdccmd: command = %02X\n", data);

switch(data) {
@@ -506,7 +502,6 @@ int32 fdccmd(int32 io, int32 data)
case 0x8C:
case 0x9C:

// RICHARD WAS HERE
//sim_printf("\nfdccmd: Read of disk %d, track %d, sector %d\n", cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5);

sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Read of disk %d, track %d, sector %d",
@@ -522,9 +517,10 @@ int32 fdccmd(int32 io, int32 data)
}
err = sim_fread(dsk_unit[cur_dsk].filebuf, SECT_SIZE, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
if (err != 1) {
//RICHARD WAS HERE
sim_printf("fdccmd: err = %d\n", err);
sim_printf("fdccmd: errno = %d\n", errno);

/* display error information */
sim_printf("\nfdccmd: err = %d\n", err);
sim_printf("\nfdccmd: errno = %d\n", errno);

sim_printf("\nfdccmd: File error in read command\n");
return SCPE_IOERR;
@@ -582,7 +578,6 @@ sim_printf("fdccmd: errno = %d\n", errno);

int32 fdctrk(int32 io, int32 data)
{
// RICHARD WAS HERE
//sim_printf("\nfdctrk: io=%d, data=%d\n", io, data);

if (io) {
@@ -599,7 +594,6 @@ int32 fdctrk(int32 io, int32 data)

int32 fdcsec(int32 io, int32 data)
{
// RICHARD WAS HERE
//sim_printf("\nfdcsec: io=%d, data=%d\n", io, data);

if (io) {
Loading