diff --git a/Visual Studio Projects/swtp6800mp-a.vcproj b/Visual Studio Projects/swtp6800mp-a.vcproj index ed54076c..14a0cbb6 100644 --- a/Visual Studio Projects/swtp6800mp-a.vcproj +++ b/Visual Studio Projects/swtp6800mp-a.vcproj @@ -199,6 +199,10 @@ RelativePath="..\swtp6800\common\dc-4.c" > + + diff --git a/Visual Studio Projects/swtp6800mp-a2.vcproj b/Visual Studio Projects/swtp6800mp-a2.vcproj index 85543fcd..5f0d5721 100644 --- a/Visual Studio Projects/swtp6800mp-a2.vcproj +++ b/Visual Studio Projects/swtp6800mp-a2.vcproj @@ -199,6 +199,10 @@ RelativePath="..\swtp6800\common\dc-4.c" > + + diff --git a/descrip.mms b/descrip.mms index f51d924c..482ef691 100644 --- a/descrip.mms +++ b/descrip.mms @@ -739,7 +739,7 @@ SWTP6800MP_A_LIB = $(LIB_DIR)SWTP6800MP-A-$(ARCH).OLB SWTP6800MP_A_SOURCE = $(SWTP6800MP_A_COMMON)mp-a.c,$(SWTP6800MP_A_COMMON)m6800.c,\ $(SWTP6800MP_A_COMMON)m6810.c,$(SWTP6800MP_A_COMMON)bootrom.c,$(SWTP6800MP_A_COMMON)dc-4.c,\ $(SWTP6800MP_A_COMMON)mp-s.c,$(SWTP6800MP_A_DIR)mp-a_sys.c,$(SWTP6800MP_A_COMMON)mp-b2.c,\ - $(SWTP6800MP_A_COMMON)mp-8m.c + $(SWTP6800MP_A_COMMON)mp-8m.c,$(SWTP6800MP_A_COMMON)fd400.c SWTP6800MP_A_OPTIONS = /INCL=($(SIMH_DIR),$(SWTP6800MP_A_DIR))/DEF=($(CC_DEFS)) # @@ -751,7 +751,7 @@ SWTP6800MP_A2_LIB = $(LIB_DIR)SWTP6800MP-A2-$(ARCH).OLB SWTP6800MP_A2_SOURCE = $(SWTP6800MP_A2_COMMON)mp-a2.c,$(SWTP6800MP_A2_COMMON)m6800.c,\ $(SWTP6800MP_A2_COMMON)m6810.c,$(SWTP6800MP_A2_COMMON)bootrom.c,$(SWTP6800MP_A2_COMMON)dc-4.c,\ $(SWTP6800MP_A2_COMMON)mp-s.c,$(SWTP6800MP_A2_DIR)mp-a2_sys.c,$(SWTP6800MP_A2_COMMON)mp-b2.c,\ - $(SWTP6800MP_A2_COMMON)mp-8m.c,$(SWTP6800MP_A2_COMMON)i2716.c + $(SWTP6800MP_A2_COMMON)mp-8m.c,$(SWTP6800MP_A2_COMMON)i2716.c,,$(SWTP6800MP_A_COMMON)fd400.c SWTP6800MP_A2_OPTIONS = /INCL=($(SIMH_DIR),$(SWTP6800MP_A2_DIR))/DEF=($(CC_DEFS)) # diff --git a/doc/swtp6800_doc.doc b/doc/swtp6800_doc.doc index 315e3e02..2660ed18 100644 Binary files a/doc/swtp6800_doc.doc and b/doc/swtp6800_doc.doc differ diff --git a/makefile b/makefile index aee48b36..46905a58 100644 --- a/makefile +++ b/makefile @@ -1806,11 +1806,13 @@ SDS_OPT = -I ${SDSD} -DUSE_SIM_CARD SWTP6800D = ${SIMHD}/swtp6800/swtp6800 SWTP6800C = ${SIMHD}/swtp6800/common SWTP6800MP-A = ${SWTP6800C}/mp-a.c ${SWTP6800C}/m6800.c ${SWTP6800C}/m6810.c \ - ${SWTP6800C}/bootrom.c ${SWTP6800C}/dc-4.c ${SWTP6800C}/mp-s.c ${SWTP6800D}/mp-a_sys.c \ - ${SWTP6800C}/mp-b2.c ${SWTP6800C}/mp-8m.c + ${SWTP6800C}/bootrom.c ${SWTP6800C}/dc-4.c ${SWTP6800D}/mp-a_sys.c \ + ${SWTP6800C}/mp-8m.c ${SWTP6800C}/fd400.c ${SWTP6800C}/mp-b2.c \ + ${SWTP6800C}/mp-s.c SWTP6800MP-A2 = ${SWTP6800C}/mp-a2.c ${SWTP6800C}/m6800.c ${SWTP6800C}/m6810.c \ - ${SWTP6800C}/bootrom.c ${SWTP6800C}/dc-4.c ${SWTP6800C}/mp-s.c ${SWTP6800D}/mp-a2_sys.c \ - ${SWTP6800C}/mp-b2.c ${SWTP6800C}/mp-8m.c ${SWTP6800C}/i2716.c + ${SWTP6800C}/bootrom.c ${SWTP6800C}/dc-4.c ${SWTP6800D}/mp-a2_sys.c \ + ${SWTP6800C}/mp-8m.c ${SWTP6800C}/i2716.c ${SWTP6800C}/fd400.c \ + ${SWTP6800C}/mp-s.c ${SWTP6800C}/mp-b2.c SWTP6800_OPT = -I ${SWTP6800D} INTELSYSD = ${SIMHD}/Intel-Systems diff --git a/swtp6800/common/dc-4.c b/swtp6800/common/dc-4.c index 7dad6842..64c86ff3 100644 --- a/swtp6800/common/dc-4.c +++ b/swtp6800/common/dc-4.c @@ -1,4 +1,4 @@ -/* dc4.c: SWTP DC-4 FDC Simulator +/* c: SWTP DC-4 FDC Simulator Copyright (c) 2005-2012, William A. Beech @@ -25,7 +25,8 @@ MODIFICATIONS: - 23 Apr 15 -- Modified to use simh_debug + 28 May 22 -- Roberto Sancho Villa (RSV) fixes for other disk formats + and operating systems. NOTES: @@ -186,6 +187,7 @@ Writes the 8-bit value to the data register. A FLEX disk is defined as follows: + (first sector on track is number 1) Track Sector Use 0 1 Boot sector @@ -197,7 +199,7 @@ 1 1 First available data sector last-1 last Last available data sector - System Identity Record + System Identity Record (SIR) Byte Use 0x00 Two bytes of zeroes (Clears forward link) @@ -230,15 +232,26 @@ #define NUM_DISK 4 /* standard 1797 maximum */ #define SECT_SIZE 256 /* standard FLEX sector */ -#define NUM_SECT 72 /* sectors/track */ +#define NUM_SECT 36 //sectors/track #define TRAK_SIZE (SECT_SIZE * NUM_SECT) /* trk size (bytes) */ -#define HEADS 1 /* handle as SS with twice the sectors */ -#define NUM_CYL 80 /* maximum tracks */ +#define HEADS 2 //handle as DS +#define NUM_CYL 80 /* maximum cylinders */ #define DSK_SIZE (NUM_SECT * HEADS * NUM_CYL * SECT_SIZE) /* dsk size (bytes) */ -/* SIR offsets */ -#define MAXCYL 0x26 /* last cylinder # */ -#define MAXSEC 0x27 /* last sector # */ +//SIR offsets TK 0, SEC 3 + +#define LABEL 0x10 //disk label (11 char) +#define VOLNUM 0x1B //volume number (word) +#define FSTUSRTRK 0x1D //first user track (byte) +#define FSTUSRSEC 0x1E //first user sector (byte) +#define LSTUSRTRK 0x1F //last user track (byte) +#define LSTUSRSEC 0x20 //last user sector (byte) +#define TOTSEC 0x21 //total sectors (word) +#define CREMON 0x23 //creation month (byte) +#define CREDAY 0x24 //creation day (byte) +#define CREYR 0x25 //creation year (byte) +#define MAXCYL 0x26 //last cylinder # +#define MAXSEC 0x27 //last sector # /* 1797 status bits type I commands*/ @@ -248,7 +261,7 @@ #define SEEKERR 0x10 #define CRCERR 0x08 #define LOST 0x04 -#define DRQ 0x02 +#define INDEX 0x02 #define BUSY 0x01 /* 1797 status bits type II/III commands*/ @@ -264,28 +277,34 @@ /* function prototypes */ -t_stat dsk_reset (DEVICE *dptr); +t_stat dsk_reset (DEVICE *dptr); +t_stat dsk_attach (UNIT *uptr, CONST char *cptr); /* SS-50 I/O address space functions */ -int32 fdcdrv(int32 io, int32 data); -int32 fdccmd(int32 io, int32 data); -int32 fdctrk(int32 io, int32 data); -int32 fdcsec(int32 io, int32 data); -int32 fdcdata(int32 io, int32 data); +int32 fdcdrv(int32 io, int32 data); +int32 fdccmd(int32 io, int32 data); +int32 fdctrk(int32 io, int32 data); +int32 fdcsec(int32 io, int32 data); +int32 fdcdata(int32 io, int32 data); /* Local Variables */ -int32 fdcbyte; -int32 intrq = 0; /* interrupt request flag */ -int32 cur_dsk; /* Currently selected drive */ -int32 wrt_flag = 0; /* FDC write flag */ +int32 fdcbyte; +int32 intrq; /* interrupt request flag */ +int32 cur_dsk; /* Currently selected drive */ +int32 wrt_flag; /* FDC write flag */ int32 spt; /* sectors/track */ int32 trksiz; /* trk size (bytes) */ int32 heds; /* number of heads */ int32 cpd; /* cylinders/disk */ int32 dsksiz; /* dsk size (bytes) */ +int32 sectsize; // Sector size (bytes) + +int32 multiple_sector; // multiple read-write flag +int32 index_countdown; // index countdown for type I commands +int32 sector_base; // indicates is first sector on track is sector 1 or sector 0 /* Floppy Disk Controller data structures @@ -296,21 +315,21 @@ int32 dsksiz; /* dsk size (bytes) */ */ UNIT dsk_unit[] = { - { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) }, - { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) }, - { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) }, - { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) } + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) } }; REG dsk_reg[] = { - { HRDATA (DISK, cur_dsk, 4) }, - { NULL } + { HRDATA (DISK, cur_dsk, 4) }, + { NULL } }; MTAB dsk_mod[] = { - { UNIT_ENABLE, UNIT_ENABLE, "RW", "RW", NULL }, - { UNIT_ENABLE, 0, "RO", "RO", NULL }, - { 0 } + { UNIT_ENABLE, UNIT_ENABLE, "RW", "RW", NULL }, + { UNIT_ENABLE, 0, "RO", "RO", NULL }, + { 0 } }; DEBTAB dsk_debug[] = { @@ -336,10 +355,10 @@ DEVICE dsk_dev = { NULL, //deposit &dsk_reset, //reset NULL, //boot - NULL, //attach + dsk_attach, //attach NULL, //detach NULL, //ctxt - DEV_DEBUG, //flags + DEV_DISABLE|DEV_DEBUG, //flags 0, //dctrl dsk_debug, //debflags NULL, //msize @@ -350,18 +369,18 @@ DEVICE dsk_dev = { t_stat dsk_reset (DEVICE *dptr) { - int i; + uint32 i; cur_dsk = 5; /* force initial SIR read */ - for (i=0; inumunits; i++) { + dptr->units[i].u3 = NOTRDY; /* current flags = NOTRDY*/ + dptr->units[i].u4 = 0; /* clear current cylinder # */ + dptr->units[i].u5 = 0; /* clear current sector # */ + dptr->units[i].pos = 0; /* clear current byte ptr */ + if (dptr->units[i].filebuf == NULL) { + dptr->units[i].filebuf = calloc(SECT_SIZE, sizeof(uint8)); /* allocate buffer */ + if (dptr->units[i].filebuf == NULL) { + printf("dc-4_reset: Calloc error\n"); return SCPE_MEM; } } @@ -371,11 +390,31 @@ t_stat dsk_reset (DEVICE *dptr) heds = 0; cpd = 0; dsksiz = 0; + //RSV - for hansling multiple disk formats and OSs + sectsize = SECT_SIZE; + multiple_sector=0; + index_countdown=0; + sector_base=1; + return SCPE_OK; +} + +/* dsk attach - attach an .IMG file to an FDD */ + +t_stat dsk_attach (UNIT *uptr, CONST char *cptr) +{ + t_stat r; + + if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { + sim_printf("dsk_attach: Attach error %d\n", r); + return r; + } + uptr->u3 &= ~NOTRDY; //reset FDD to ready + uptr->capac = sim_fsize(uptr->fileref); //file size return SCPE_OK; } /* I/O instruction handlers, called from the MP-B2 module when a - read or write occur to addresses 0x8004-0x8007. */ + read or write occur to addresses 0x8014-0x801B. */ /* DC-4 drive select register routine - this register is not part of the 1797 */ @@ -384,47 +423,59 @@ int32 fdcdrv(int32 io, int32 data) { static long pos; static int32 err; + uint8 *SIR; + int32 disk_image_size; - if (io) { /* write to DC-4 drive register */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Drive selected %d cur_dsk=%d", - data & 0x03, cur_dsk); - if (cur_dsk == (data & 0x03)) - return 0; /* already selected */ - cur_dsk = data & 0x03; /* only 2 drive select bits */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Drive set to %d", cur_dsk); - dsk_unit[cur_dsk].flags &= ~LOST; - if ((dsk_unit[cur_dsk].flags & UNIT_ENABLE) == 0) { - dsk_unit[cur_dsk].u3 |= WRPROT; /* set 1797 WPROT */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Drive write protected"); - } else { - dsk_unit[cur_dsk].u3 &= ~WRPROT; /* set 1797 not WPROT */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Drive NOT write protected"); - } - pos = 0x200; /* Read in SIR */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Read pos = %ld ($%04X)", - pos, (unsigned int) pos); - err = sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */ - if (err) { - sim_printf("\nfdccmd: Seek error read in SIR\n"); - return SCPE_IOERR; - } - err = sim_fread(dsk_unit[cur_dsk].filebuf, SECT_SIZE, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */ - if (err != 1) { - sim_printf("\nfdccmd: File error read in SIR\n"); - return SCPE_IOERR; - } + if (io) { // write to DC-4 drive register + if (cur_dsk == (data & 0x03)) // already selected? + return 0; //yes + cur_dsk = data & 0x03; // only 2 drive select bits/ + dsk_unit[cur_dsk].u3 &= ~LOST; //RSV - reset LOST flag + if ((dsk_unit[cur_dsk].flags & UNIT_ENABLE) == 0) //RO? + dsk_unit[cur_dsk].u3 |= WRPROT; /* Set WPROT */ + else + dsk_unit[cur_dsk].u3 &= ~WRPROT; /* SET not WPROT */ + if (dsk_unit[cur_dsk].fileref == 0) // no file attached + return 0; + /* RSV - Read in SIR */ + pos = 0x200; + sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to SIR */ + sim_fread(dsk_unit[cur_dsk].filebuf, SECT_SIZE, 1, dsk_unit[cur_dsk].fileref); /* read in SIR */ dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */ dsk_unit[cur_dsk].pos = 0; /* clear counter */ - spt = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + MAXSEC) & 0xFF; - heds = 0; - cpd = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + MAXCYL) & 0xFF; - trksiz = spt * SECT_SIZE; + SIR = (uint8 * )(dsk_unit[cur_dsk].filebuf); + // detect disk type based on image geometry or SIR record + disk_image_size = sim_fsize(dsk_unit[cur_dsk].fileref); //get actual file size + if (disk_image_size == 35 * 10 * 256) { // 89600 bytes -> FDOS image + // FDOS disc has no SIR record. + spt = 10; // 10 sectors + cpd = 35; // 35 tracks + sectsize = 256; + sector_base = 0; // first sector in track is number ZERO + } else if (disk_image_size == 35 * 18 * 128) { // 80640 bytes -> FLEX 1.0 image + spt = 18; // 18 sectors + cpd = 35; // 35 tracks + sectsize = 128; + sector_base = 1; // first sector in track is number ONE + } else if ((SIR[0] == 0) && (SIR[1] == 0)) { + // FLEX disc has SIR record. on disk image offset $200 + spt = SIR[MAXSEC]; // Highest number of tracks. As in FLEX sectors are numbered as + // 1,2,..Hi this is also the number of sectors per track + cpd = SIR[MAXCYL] + 1; // highest track number . On FLEX, first track is track zero + sectsize = 256; + sector_base = 1; // first sector in track is number ONE + } else { + spt = 18; + sectsize = 128; + cpd = disk_image_size / (spt * sectsize); + sector_base = 1; // first sector in track is number ONE + } + heds = 0; //RSV - always SS + trksiz = spt * sectsize; dsksiz = trksiz * cpd; - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: spt=%d heds=%d cpd=%d trksiz=%d dsksiz=%d flags=%08X u3=%08X", - spt, heds, cpd, trksiz, dsksiz, dsk_unit[cur_dsk].flags, dsk_unit[cur_dsk].u3); + return 0; } else { /* read from DC-4 drive register */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdrv: Drive read as %02X", intrq); return intrq; } } @@ -438,83 +489,88 @@ int32 fdccmd(int32 io, int32 data) static int32 err; 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); - return 0; + val = dsk_unit[cur_dsk].u3 |= NOTRDY; /* set not ready flag */ + return SEEKERR; // RSV - return SEEK ERROR STATUS bit } else { dsk_unit[cur_dsk].u3 &= ~(NOTRDY); /* clear not ready flag */ } if (io) { /* write command to fdc */ + // RSV - on commands type I ... + if ((data & 0x80) == 0) { + // ... set bits h V r1r0 to h=1 (home drive), V=0 (verify off), r1r0=11 (40msec track stepping) + data = ((data & 0xF0) | 0x0B); + // and starts countdown for index status bit + index_countdown = 10; + } else { + index_countdown = 0; + } + // process command switch(data) { case 0x8C: //read sector command type II case 0x9C: //read multiple sectors command type II - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Read of disk %d, track %d, sector %d", - cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5); + if ((dsk_unit[cur_dsk].u5 - sector_base >= spt) || (dsk_unit[cur_dsk].u5 < sector_base)) { + dsk_unit[cur_dsk].u3 |= RECNF; /* RSV - set RECORD NOT FOUND */ + break; + } dsk_unit[cur_dsk].u3 |= BUSY; /* set BUSY */ pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */ - pos += SECT_SIZE * (dsk_unit[cur_dsk].u5 - 1); - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Read pos = %ld ($%08X)", - pos, (unsigned int) pos); + pos += sectsize * (dsk_unit[cur_dsk].u5 - sector_base); err = sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */ if (err) { - sim_printf("\nfdccmd: Seek error in read command\n"); + sim_printf("fdccmd: Seek error in read command\n"); return SCPE_IOERR; - } - err = sim_fread(dsk_unit[cur_dsk].filebuf, SECT_SIZE, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */ + } + /* read in buffer */ + err = sim_fread(dsk_unit[cur_dsk].filebuf, sectsize, 1, dsk_unit[cur_dsk].fileref); if (err != 1) { - sim_printf("\nfdccmd: File error in read command\n"); + sim_printf("fdccmd: File error in read command\n"); return SCPE_IOERR; } dsk_unit[cur_dsk].u3 |= DRQ; /* set DRQ */ dsk_unit[cur_dsk].pos = 0; /* clear counter */ + multiple_sector = (data == 0x9C) ? 1:0; // RSV = set multiple sector TYPE II cmds break; case 0xAC: //write command type II case 0xBC: //write multiple sectors command type II - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Write of disk %d, track %d, sector %d", - cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5); if (dsk_unit[cur_dsk].u3 & WRPROT) { - printf("\nfdccmd: Drive %d is write-protected", cur_dsk); } else { dsk_unit[cur_dsk].u3 |= BUSY;/* set BUSY */ pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */ - pos += SECT_SIZE * (dsk_unit[cur_dsk].u5 - 1); - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Write pos = %ld ($%08X)", - pos, (unsigned int) pos); + pos += sectsize * (dsk_unit[cur_dsk].u5 - sector_base); err = sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */ if (err) { - sim_printf("\nfdccmd: Seek error in write command\n"); + sim_printf("fdccmd: Seek error in write command\n"); return SCPE_IOERR; } dsk_unit[cur_dsk].u3 |= DRQ;/* set DRQ */ - wrt_flag = 1; /* set write flag */ + wrt_flag = 1; /* RSV - set write flag */ dsk_unit[cur_dsk].pos = 0; /* clear counter */ } break; - case 0x18: //seek command type I case 0x1B: //seek command type I - dsk_unit[cur_dsk].u4 = fdcbyte; /* set track */ + dsk_unit[cur_dsk].u4 = fdcbyte; /* set track */ dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Seek of disk %d, track %d", - cur_dsk, fdcbyte); break; - case 0x0B: //restore command type I - dsk_unit[cur_dsk].u4 = 0; /* home the drive */ - dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Drive %d homed", cur_dsk); + case 0x0B: //restore command type I + dsk_unit[cur_dsk].u4 = 0; /* home the drive */ + dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ | RECNF); /* clear flags */ break; case 0xF0: //write track command type III case 0xF4: //write track command type III - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Write track command for drive %d", - cur_dsk); + break; + case 0xD0: //Force Interrupt - terminate current command + dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ break; default: - printf("Unknown FDC command %02XH\n\r", data); + sim_printf("Unknown FDC command %02X\n\r", data); } } else { /* read status from fdc */ val = dsk_unit[cur_dsk].u3; /* set return value */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Exit Drive %d status=%02X", - cur_dsk, val); - sim_debug (DEBUG_flow, &dsk_dev, "\n%02X", val); //even this short fails it! + if (index_countdown) { // RSV - Handle INDEX flag + index_countdown--; + // if index countdoen expires, set index flag in status returned to cpu + if (index_countdown==0) val |= INDEX; + } } return val; } @@ -524,12 +580,9 @@ int32 fdccmd(int32 io, int32 data) int32 fdctrk(int32 io, int32 data) { if (io) { - dsk_unit[cur_dsk].u4 = data & 0xFF; - sim_debug (DEBUG_flow, &dsk_dev, "\nfdctrk: Drive %d track set to %d", - cur_dsk, dsk_unit[cur_dsk].u4); + dsk_unit[cur_dsk].u3 &= ~(RECNF); /* reset RECNF flag */ + dsk_unit[cur_dsk].u4 = data & BYTEMASK; } - sim_debug (DEBUG_flow, &dsk_dev, "\nfdctrk: Drive %d track read as %d", - cur_dsk, dsk_unit[cur_dsk].u4); return dsk_unit[cur_dsk].u4; } @@ -538,14 +591,12 @@ int32 fdctrk(int32 io, int32 data) int32 fdcsec(int32 io, int32 data) { if (io) { - dsk_unit[cur_dsk].u5 = data & 0xFF; - if (dsk_unit[cur_dsk].u5 == 0) /* fix for swtp boot! */ - dsk_unit[cur_dsk].u5 = 1; - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcsec: Drive %d sector set to %d", - cur_dsk, dsk_unit[cur_dsk].u5); + dsk_unit[cur_dsk].u3 &= ~(RECNF); /* reset RECNF flag */ + dsk_unit[cur_dsk].u5 = data & BYTEMASK; + if (dsk_unit[cur_dsk].u5 < sector_base) //RSV - force to sector 1 + dsk_unit[cur_dsk].u5 = sector_base; + return 0; } - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcsec: Drive %d sector read as %d", - cur_dsk, dsk_unit[cur_dsk].u5); return dsk_unit[cur_dsk].u5; } @@ -553,38 +604,48 @@ int32 fdcsec(int32 io, int32 data) int32 fdcdata(int32 io, int32 data) { - int32 val; + int32 val, err; + if (cur_dsk >= NUM_DISK) // RSV - illegal disk + return 0; if (io) { /* write byte to fdc */ fdcbyte = data; /* save for seek */ - if (dsk_unit[cur_dsk].pos < SECT_SIZE) { /* copy bytes to buffer */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdata: Writing byte %d of %02X", - dsk_unit[cur_dsk].pos, data); + if (dsk_unit[cur_dsk].pos < (t_addr) sectsize) { /* copy bytes to buffer */ *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) = data; /* byte into buffer */ dsk_unit[cur_dsk].pos++; /* step counter */ - if (dsk_unit[cur_dsk].pos == SECT_SIZE) { + if (dsk_unit[cur_dsk].pos == sectsize) { dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); if (wrt_flag) { /* if initiated by FDC write command */ - sim_fwrite(dsk_unit[cur_dsk].filebuf, SECT_SIZE, 1, dsk_unit[cur_dsk].fileref); /* write it */ + sim_fwrite(dsk_unit[cur_dsk].filebuf, sectsize, 1, dsk_unit[cur_dsk].fileref); /* write it */ wrt_flag = 0; /* clear write flag */ } - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdata: Sector write complete"); } } return 0; } else { /* read byte from fdc */ - if (dsk_unit[cur_dsk].pos < SECT_SIZE) { /* copy bytes from buffer */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdata: Reading byte %d u3=%02X", - dsk_unit[cur_dsk].pos, dsk_unit[cur_dsk].u3); - val = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) & 0xFF; - dsk_unit[cur_dsk].pos++; /* step counter */ - if (dsk_unit[cur_dsk].pos == SECT_SIZE) { /* done? */ - dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ - sim_debug (DEBUG_flow, &dsk_dev, "\nfdcdata: Sector read complete"); + if (dsk_unit[cur_dsk].pos < (t_addr) sectsize) { /* copy bytes from buffer */ + val = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) & BYTEMASK; + dsk_unit[cur_dsk].pos++; /* step counter */ + if (dsk_unit[cur_dsk].pos == sectsize) { // sector finished + if ((multiple_sector) && (dsk_unit[cur_dsk].u5-sector_base < spt-1)) { // read multiple in progress + dsk_unit[cur_dsk].u5++; + err = sim_fread(dsk_unit[cur_dsk].filebuf, sectsize, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */ + if (err != 1) { + sim_printf("fdccmd: File error in read command\n"); + return SCPE_IOERR; + } + dsk_unit[cur_dsk].pos = 0; + } else { // RSV - handle multiple sector disk read + dsk_unit[cur_dsk].u5++; + dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ + if (multiple_sector) { + multiple_sector=0; + } + } } return val; } else - return 0; + return 0; } } diff --git a/swtp6800/common/fd400.c b/swtp6800/common/fd400.c new file mode 100644 index 00000000..31323f41 --- /dev/null +++ b/swtp6800/common/fd400.c @@ -0,0 +1,519 @@ +/* fd400.c: Percom LFD-400 FDC Simulator + + Copyright (c) 2022, Roberto Sancho + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + WILLIAM A BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Roberto Sancho shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Roberto Sancho . + + MODIFICATIONS: + + NOTES: + + The FDC-400 is a 5-1/4"-inch floppy controller which can control up + to four 5-1/4inch floppy drives. + This file only emulates the minimum functionality to interface with + the virtual disk file. + + The floppy controller is interfaced to the CPU by use of 7 memory + addreses (0xCC00-0xCC06). + + Address Mode Function + ------- ---- -------- + + 0xCC00 Read CONTROLLER STATUS + 0xCC00 Write SYNC WORD PORT + 0xCC01 Read RECEIVED DATA + 0xCC01 Write WRITE DATA PORT + 0xCC02 Read SECTOR COUNTER + 0xCC02 Write FILL WORD PORT + 0xCC03 Read DRIVE STATUS + 0xCC03 Write DRIVE AND TRACK SELECT + 0xCC04 Read RECEIVER RESTART PULSE + 0xCC04 Write WRITE PULSE + 0xCC05 Read MOTOR ON PULSE + 0xCC06 Read MOTOR OFF PULSE + + + CONTROLLER STATUS (Read 0xCC00): + + +---+---+---+---+---+---+---+---+ + | B | x | x | x | x | x | x | R | + +---+---+---+---+---+---+---+---+ + + B = Controller Ready (0=Busy, 1=Ready) + R = Read byte ready (1=can retrieve read byte) + + + RECEIVED DATA (Read 0xCC01): + WRITE DATA PORT (Write 0xCC01): + + +---+---+---+---+---+---+---+---+ + | byte | + +---+---+---+---+---+---+---+---+ + + Data byte from retrieved sector being read + Data byte to store in sector being write + + + CURRENT SECTOR (Read 0xCC02): + WRITE FILL CHAR (Write 0xCC02): + + +---+---+---+---+---+---+---+---+ + | x | Sector | + +---+---+---+---+---+---+---+---+ + + Return current Sector + Set the fill char for write sector + + + DRIVE STATUS (Read 0xCC03): + + +---+---+---+---+---+---+---+---+ + | DD | I | S | W | M | T | P | + +---+---+---+---+---+---+---+---+ + + P = Write allowed Bit (0=disk is write protected) + T = Track Zero Bit (1=head is NOT positioned in track zero) + M = Motor Test Bit (1=motor stopped) + W = Write Gate Bit (1=drive gate door is closed) + S = Sector Pulse Bit (1=head at start of sector) + I = Index Pulse bit (???) + DD = Current selected drive (0..3) + + + DRIVE AND TRACK SELECT (Write 0xCC03): + + +---+---+---+---+---+---+---+---+ + | DD | S | D | x | x | x | x | + +---+---+---+---+---+---+---+---+ + + D = Direction bit (1=Track In=increment track number) + S = Step Bit (1=Move disk head one track using direction D) + DD = Select drive (0..3) + + LFD-400 Disck supports these operating systems (1977) + + - MINIDOS: Just Load/Save ram starting at given sector in disk. + No files. No sector allocation management. Rom based + - MPX (also know as MiniDOS Plus or MiniDOS/MPX or MiniDOS-PlusX): + Based on MiniDOS, add named files, contiguos allocation management. Transient disk command + - MiniDisk+ DOS: + Based on MiniDOS, add named files, contiguos allocation management. More disk commands + + + MiniDOS files have 40 track (0..39) with 10 sectors (0..9) each with 256 bytes of data + + The following unit registers are used by this controller emulation: + + fd400_dsk_unit[cur_drv].u4 unit current track + fd400_dsk_unit[cur_drv].u5 unit current sector + fd400_dsk_unit[cur_drv].pos unit current sector byte index into buffer + fd400_dsk_unit[cur_drv].filebuf unit current sector buffer + fd400_dsk_unit[cur_drv].fileref unit current attached file reference + + At start, units discs from controller are dissabled + To use it, befor attaching the disk image, it is mecessary to do "set lfd-4000 enabled" + (for unit 0), and optionally "set lfd-4001 enabled" (for unit 1) and so on. +*/ + +#include +#include "swtp_defs.h" + +#define UNIT_V_ENABLE (UNIT_V_UF + 0) /* Write Enable */ +#define UNIT_ENABLE (1 << UNIT_V_ENABLE) + +/* emulate a Disk disk with 10 sectors and 40 tracks */ + +#define NUM_DISK 4 +#define SECT_SIZE (8+4+256) /* sector size=header (10 bytes) + data (256 bytes) + CRC (2 bytes) */ +#define NUM_SECT 10 /* sectors/track */ +#define TRAK_SIZE (SECT_SIZE * NUM_SECT) /* trk size (bytes) */ +#define HEADS 1 /* handle as SS with twice the sectors */ +#define NUM_CYL 40 /* maximum tracks */ +#define DSK_SIZE (NUM_SECT * HEADS * NUM_CYL * SECT_SIZE) /* dsk size (bytes) */ + +#define TRK fd400_dsk_unit[fd400.cur_dsk].u4 // current disk track and sector +#define SECT fd400_dsk_unit[fd400.cur_dsk].u5 + +#define BUF_SIZE (SECT_SIZE+16) // sector buffer in memory + +/* function prototypes */ + +t_stat fd400_dsk_reset (DEVICE *dptr); +t_stat fd400_attach (UNIT *, CONST char *); + +/* SS-50 I/O address space functions */ + +int32 fd400_fdcstatus(int32 io, int32 data); +int32 fd400_cstatus(int32 io, int32 data); +int32 fd400_data(int32 io, int32 data); +int32 fd400_cursect(int32 io, int32 data); +int32 fd400_startrw(int32 io, int32 data); + +/* Local Variables */ + +struct { + int32 cur_dsk; /* Currently selected drive */ + int32 SectorPulse; // Head positioned at beginning of sector + int32 StepBit; + uint8 FillChar; +} fd400 = {0}; + +/* Floppy Disk Controller data structures + + fd400_dsk_dev Disk Controller device descriptor + fd400_dsk_unit Disk Controller unit descriptor + fd400_dsk_reg Disk Controller register list + fd400_dsk_mod Disk Controller modifiers list +*/ + +UNIT fd400_dsk_unit[] = { + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, + { UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_DIS, 0) } +}; + +REG fd400_dsk_reg[] = { + { HRDATA (DISK, fd400.cur_dsk, 4) }, + { NULL } +}; + +DEBTAB fd400_dsk_debug[] = { + { "ALL", DEBUG_all, "All debug bits" }, + { "FLOW", DEBUG_flow, "Flow control" }, + { "READ", DEBUG_read, "Read Command" }, + { "WRITE", DEBUG_write, "Write Command"}, + { NULL } +}; + +DEVICE fd400_dsk_dev = { + "LFD-400", //name + fd400_dsk_unit, //units + fd400_dsk_reg, //registers + NULL, //modifiers + NUM_DISK, //numunits + 16, //aradix + 16, //awidth + 1, //aincr + 16, //dradix + 8, //dwidth + NULL, //examine + NULL, //deposit + &fd400_dsk_reset, //reset + NULL, //boot + &fd400_attach, //attach + NULL, //detach + NULL, //ctxt + DEV_DISABLE|DEV_DIS|DEV_DEBUG, //flags + 0, //dctrl + fd400_dsk_debug, //debflags + NULL, //msize + NULL //lname +}; + +/* Reset routine */ + +t_stat fd400_dsk_reset (DEVICE *dptr) +{ + int i; + + for (i=0; iflags & UNIT_ATT) == 0) { + sim_debug (DEBUG_flow, &fd400_dsk_dev, "Current Drive %d has no file attached \n", fd400.cur_dsk); + } else { + // file attached = disk inserted into unit + if ((uptr->flags & UNIT_RO) == 0) val |= 1; // unit is read/write + if (TRK!=0) val |= 2; // head is NOT in track zero + if (fd400.SectorPulse) { + val |= 16; + fd400.SectorPulse--; + } else { + // set sector pulse and incr current sector + // Simulates somewhat disk rotation whitout having to set up _svr and sim_activate + fd400.SectorPulse=2; + SECT++; if (SECT >= NUM_SECT) SECT = 0; + uptr->pos=0; // init sector read + } + if (SECT==0) val |= 32; // index pulse: head is positioned in sector zero + } + sim_debug (DEBUG_flow, &fd400_dsk_dev, "Status Returned %02X, Current Drive %d TRK %d SECT %d \n", + val, fd400.cur_dsk, TRK, SECT); + return val; + } + // io=1 -> writing data to i/o register, + fd400.cur_dsk = data >> 6; // select current disk + fd400.SectorPulse = 0; // init sector pulse + if (data & 32) { + fd400.StepBit=1; // Step bit set to one + } else if ((data & 32)==0) { // Step bit set to zero + if (fd400.StepBit==0) { + // but was already zero -> no action + } else { + // StepBit changing from 1 to 0 -> step track motot + fd400.StepBit=0; + // step track depending on direction bit + if (data & 16) TRK++; else TRK--; + if (TRK < 0) TRK=0; + if (TRK >= NUM_CYL) TRK = NUM_CYL-1; + // on changing track also incr sect num, but not issue sector pulse (landed on middle of sector) + SECT++; if (SECT >= NUM_SECT) SECT = 0; + uptr->pos=0; // init sector read + } + } + sim_debug (DEBUG_flow, &fd400_dsk_dev, "Set Drive and Track %02X, Current Drive %d TRK %d SECT %d \n", + data, fd400.cur_dsk, TRK, SECT); + return 0; +} + +/* CONTROLLER STATUS register (read $CC00)*/ + +int32 fd400_cstatus(int32 io, int32 data) +{ + // controller allways ready, byte read from sector allways ready + // writing to is set the sync byte. This is not implemented + return 128+1; +} + +/* DATA register */ + +int32 fd400_data(int32 io, int32 data) +{ + uint32 loc; + UNIT * uptr = &fd400_dsk_unit[fd400.cur_dsk]; + uint8 dsk_sect[SECT_SIZE]; // image of sector read/saved in disk image + uint8 * p = (uint8 *)(uptr->filebuf); // sector byte stream as seen by program + int i, n; + + if ((uptr->flags & UNIT_ATT) == 0) return 0; // not attached + if (io==0) { + // io=0 when reading from io register (return data read from i/o device register) + // read data from sector + if (uptr->pos==0) { + // read new sector buffer + // init buffer to zero + memset(uptr->filebuf, 0, SECT_SIZE); + // calculate location of current sector in disk image file + loc=(TRK * NUM_SECT + SECT) * SECT_SIZE; + if (loc >= uptr->capac) { + // reading past image file current size -> read as zeroes + } else { + // read sector + sim_fseek(uptr->fileref, loc, SEEK_SET); + sim_fread(dsk_sect, 1, SECT_SIZE, uptr->fileref); + // reorganize buffer to match the byte order expected by MiniDOS + // + // Data in MiniDOS MPX disk image: + // BT BS FT FS NN AH AL TY CH CL PH PL [256 data bytes] = 268 bytes + // where BT=Backward link track, DS=Backward link sector, + // FT=Forward link track, FS=Forward link sector. = 00 00 if this is last sector of file + // NN=Number of data bytes (00=256 bytes) + // AH AL=Addr in RAM where to load sector data bytes (H=High byte, L=Low byte) + // TY=file type + // CH CL=CheckSum Hi/Low byte + // PH PL=Postamble Hi/Low byte. Holds program start addr on last sector + // + // Data as expected by MiniDOS ROM when reading a sector + // SY TR SE BT BS FT FS NN AH AL TY [NN data bytes] CH CL PH PL + // where SY=Sync Byte=$FD + // TR SE=This track and sector + // BT BS FT FS NN AH AL TY=same as above + // CH CL=same as above + // + // so we create the filebuf (p pointer) reordering data read from disk image file (dsk_sect) + p[0]=0xFB; // sync byte + p[1]=TRK; p[2]=SECT; // this sector track and sector number + for (i=0; i<8; i++) p[3+i]=dsk_sect[i]; // 8 byte header with bytes BT ... TY + n=dsk_sect[4]; if (n==0) n=256; // number of data bytes + for (i=0; ipos=0; + } + // retrieve read byte from sector buffer + if (uptr->pos>=BUF_SIZE) { + sim_debug (DEBUG_write, &fd400_dsk_dev, "Sector overrun - do not read data\n"); + return 0; + } + data=p[uptr->pos]; + sim_debug (DEBUG_read, &fd400_dsk_dev, "Read byte %02X (dec=%d char='%c'), Current Drive %d TRK %d SECT %d POS %d\n", + data, data, (data < 32) ? '?':data, fd400.cur_dsk, TRK, SECT, uptr->pos); + uptr->pos++; + + return data; + } + // io=1 -> writing data to i/o register, + // write data to sector + if (uptr->flags & UNIT_RO) { + sim_debug (DEBUG_write, &fd400_dsk_dev, "Write data %02X, but Current Drive %d is Read Only\n", + data, fd400.cur_dsk); + return 0; + } + sim_debug (DEBUG_write, &fd400_dsk_dev, "Write data %02X, Current Drive %d TRK %d SECT %d POS %d\n", + data, fd400.cur_dsk, TRK, SECT, uptr->pos); + // store byte into sector buffer + if (uptr->pos==0) { + if (data==0) return 0; // ignore zero bytes before sync byte + } + if (uptr->pos >= BUF_SIZE) { + sim_debug (DEBUG_write, &fd400_dsk_dev, "Sector overrun - do not write data\n"); + return 0; + } + // save byte to buffer + p[uptr->pos]=data; + uptr->pos++; + // calculate location of current sector in disk image file + loc=(TRK * NUM_SECT + SECT) * SECT_SIZE; + if (loc >= uptr->capac) { + // writing past image file current size -> extend disk image size + uint8 buf[SECT_SIZE]; + memset(buf, 0, sizeof(buf)); + sim_fseek(uptr->fileref, uptr->capac, SEEK_SET); + while (uptr->capac <= loc) { + sim_fwrite(buf, 1, SECT_SIZE, uptr->fileref); + uptr->capac += SECT_SIZE; + } + sim_debug (DEBUG_write, &fd400_dsk_dev, "Disk image extended up to %d bytes \n", uptr->capac); + } + // convert byte stream into sector format to save to disk. + // reorganize buffer to match the byte order expected by MiniDOS + // + // Data as sent to controller by MiniDOS ROM when writing a sector + // SY TR SE BT BS FT FS NN AH AL TY [NN data bytes] CH CL PH PL + // where SY=Sync Byte=$FD + // TR SE=This track and sector + // BT BS FT FS NN AH AL TY=same as below + // CH CL=same as below + // + // Data in MiniDOS MPX disk image: + // BT BS FT FS NN AH AL TY CH CL PH PL [256 data bytes] = 268 bytes + // where BT=Backward link track, DS=Backward link sector, + // FT=Forward link track, FS=Forward link sector. = 00 00 if this is last sector of file + // NN=Number of data bytes (00=256 bytes) + // AH AL=Addr in RAM where to load sector data bytes (H=High byte, L=Low byte) + // TY=file type + // CH CL=CheckSum Hi/Low byte + // PH PL=Postamble Hi/Low byte. Holds program start addr on last sector + // + // so we create the sector to write in disk image file (dsk_sect) reordering data from filebuf (p pointer) + + memset(dsk_sect, 255, sizeof(dsk_sect)); + for (i=0; i<8; i++) dsk_sect[i]=p[3+i]; // disk sector start with 8 byte header with bytes BT BS FT FS NN AH AL TY + n=uptr->pos-11; // number of data bytes + if (n>256+4) n=256+4; + if (n>4) { + for (i=0; i<4; i++) dsk_sect[i+8]=p[3+8+n+i-4]; // copy checksum and postamble + for (i=0; ifileref, loc, SEEK_SET); + sim_fwrite(dsk_sect, 1, SECT_SIZE, uptr->fileref); + return 0; +} + +/* CURRENT SECTOR / FILL CHAR REGISTER */ + +int32 fd400_cursect(int32 io, int32 data) +{ + UNIT * uptr; + + uptr = &fd400_dsk_unit[fd400.cur_dsk]; + if ((uptr->flags & UNIT_ATT) == 0) return 0; // not attached + if (io==0) { + // io=0 when reading from io register (return data read from i/o device register) + // return current sector + sim_debug (DEBUG_flow, &fd400_dsk_dev, "Current Drive %d TRK %d SECT %d \n", + fd400.cur_dsk, TRK, SECT); + return SECT; + } + // io=1 -> writing data to i/o register, + // set fill char + fd400.FillChar=data; + return 0; +} + +/* RECEIVER RESTART / WRITE PULSE $CC00 */ + +int32 fd400_startrw(int32 io, int32 data) +{ + UNIT * uptr; + + uptr = &fd400_dsk_unit[fd400.cur_dsk]; + if ((uptr->flags & UNIT_ATT) == 0) return 0; // not attached + if (io==0) { + // io=0 when reading from io register (return data read from i/o device register) + // start read from sector -> init received so it will return sync char and tracks + uptr->pos=0; + return 0; + } + // io=1 -> writing data to i/o register, + // start write to sector + uptr->pos=0; + return 0; +} + +t_stat fd400_attach (UNIT * uptr, CONST char * file) +{ + t_stat r; + + if ((r = attach_unit(uptr, file)) != SCPE_OK) return r; + uptr->u4 = uptr->u5 = 0; + uptr->capac = sim_fsize(uptr->fileref); + uptr->pos = 0; + return SCPE_OK; +} + +/* end of fd400.c */ diff --git a/swtp6800/common/i2716.c b/swtp6800/common/i2716.c index dd5c1365..c2ac92f3 100644 --- a/swtp6800/common/i2716.c +++ b/swtp6800/common/i2716.c @@ -25,8 +25,6 @@ MODIFICATIONS: - 24 Apr 15 -- Modified to use simh_debug - NOTES: These functions support a simulated 2704 to 2764 EPROMs device on an 8-bit @@ -114,19 +112,15 @@ t_stat i2716_attach (UNIT *uptr, CONST char *cptr) t_stat r; FILE *fp; - sim_debug (DEBUG_flow, &i2716_dev, "i2716_attach: cptr=%s\n", cptr); if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { - sim_debug (DEBUG_flow, &i2716_dev, "i2716_attach: Error\n"); return r; } - sim_debug (DEBUG_read, &i2716_dev, "\tOpen file\n"); fp = fopen(uptr->filename, "rb"); /* open EPROM file */ if (fp == NULL) { printf("i2716%d: Unable to open ROM file %s\n", (int)(uptr - i2716_dev.units), uptr->filename); printf("\tNo ROM image loaded!!!\n"); return SCPE_OK; } - sim_debug (DEBUG_read, &i2716_dev, "\tRead file\n"); j = 0; /* load EPROM file */ c = fgetc(fp); while (c != EOF) { @@ -137,10 +131,7 @@ t_stat i2716_attach (UNIT *uptr, CONST char *cptr) break; } } - sim_debug (DEBUG_read, &i2716_dev, "\tClose file\n"); fclose(fp); -// printf("i2716%d: %d bytes of ROM image %s loaded\n",uptr - i2716_dev.units, j, uptr->filename); - sim_debug (DEBUG_flow, &i2716_dev, "i2716_attach: Done\n"); return SCPE_OK; } @@ -151,32 +142,21 @@ t_stat i2716_reset (DEVICE *dptr) int32 i, base; UNIT *uptr; - sim_debug (DEBUG_flow, &i2716_dev, "i2716_reset: \n"); for (i = 0; i < I2716_NUM; i++) { /* init all units */ uptr = i2716_dev.units + i; - sim_debug (DEBUG_flow, &i2716_dev, "i2716 %d unit.flags=%08X\n", - i, uptr->flags); uptr->capac = 2048; uptr->u3 = 2048 * i; base = get_base(); if (uptr->filebuf == NULL) { /* no buffer allocated */ - uptr->filebuf = malloc(2048); /* allocate EPROM buffer */ + uptr->filebuf = calloc(2048, sizeof(uint8)); /* allocate EPROM buffer */ if (uptr->filebuf == NULL) { - sim_debug (DEBUG_flow, &i2716_dev, "i2716_reset: Malloc error\n"); return SCPE_MEM; } } if (base == 0) { -// printf("i2716%d: Not enabled on MP-A2\n", i); continue; } -// printf("i2716%d: Initializing [%04X-%04XH]\n", -// i, base+uptr->u3, base+uptr->u3 + uptr->capac); -// if ((uptr->flags & UNIT_ATT) == 0) { -// printf("i2716%d: No file attached\n", i); -// } } - sim_debug (DEBUG_flow, &i2716_dev, "i2716_reset: Done\n"); return SCPE_OK; } @@ -197,16 +177,13 @@ int32 i2716_get_mbyte(int32 offset) len = uptr->capac - 1; if ((offset >= org) && (offset < (org + len))) { if (uptr->filebuf == NULL) { - sim_debug (DEBUG_read, &i2716_dev, "i2716_get_mbyte: EPROM not configured\n"); return 0xFF; } else { val = *((uint8 *)(uptr->filebuf) + (offset - org)); - sim_debug (DEBUG_read, &i2716_dev, " val=%04X\n", val); return (val & 0xFF); } } } - sim_debug (DEBUG_read, &i2716_dev, "i2716_get_mbyte: Out of range\n"); return 0xFF; } diff --git a/swtp6800/common/m6800.c b/swtp6800/common/m6800.c index a63c8635..df755638 100644 --- a/swtp6800/common/m6800.c +++ b/swtp6800/common/m6800.c @@ -25,8 +25,8 @@ MODIFICATIONS: - 23 Apr 15 -- Modified to use simh_debug - 21 Apr 20 -- Richard Brinegar numerous fixes for flag errors + 21 Apr 20 -- Richard Brinegar numerous fixes for condition code errors + 28 May 22 -- Roberto Sancho Villa (RSV)some more fixes for condition code errors NOTES: cpu Motorola M6800 CPU @@ -36,7 +36,7 @@ A<0:7> Accumulator A B<0:7> Accumulator B IX<0:15> Index Register - CC<0:7> Condition Code Register + CC<0:7> Condition Code Register HF half-carry flag IF interrupt flag NF negative flag @@ -111,23 +111,47 @@ #define COND_SET_FLAG_V(COND) \ if (COND) SET_FLAG(VF); else CLR_FLAG(VF) -/* local global variables */ +#define m6800_NAME "Motorola M6800 Processor Chip" +#define HIST_MIN 64 +#define HIST_MAX (1u << 18) +#define HIST_ILNT 3 /* max inst length */ + +typedef struct { + uint16 pc; + uint16 sp; + uint8 cc; + uint8 a; + uint8 b; + uint16 ix; + t_value inst[HIST_ILNT]; + } InstHistory; + +/* local global variables */ int32 A = 0; /* Accumulator A */ int32 B = 0; /* Accumulator B */ int32 IX = 0; /* Index register */ int32 SP = 0; /* Stack pointer */ -int32 CC = CC_ALWAYS_ON | IF; /* Condition Code Register */ -int32 saved_PC = 0; /* Program counter */ -int32 PC; /* global for the helper routines */ - -int32 mem_fault = 0; /* memory fault flag */ -int32 NMI = 0, IRQ = 0; +int32 CC = CC_ALWAYS_ON | IF; /* Condition Code Register */ +int32 saved_PC = 0xffff; /* Program counter */ +int32 PC; /* global for the helper routines */ +int32 NMI = 0, IRQ = 0; //interrupt flags +int32 hst_p = 0; /* history pointer */ +int32 hst_lnt = 0; /* history length */ +InstHistory *hst = NULL; /* instruction history */ +int32 reason; //reason for halting processor +static const char* m6800_desc(DEVICE *dptr) { + return m6800_NAME; +} /* function prototypes */ +t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat m6800_reset (DEVICE *dptr); -t_stat m6800_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches); +t_stat m6800_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); +t_stat m6800_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw); + void dump_regs(void); int32 fetch_byte(void); int32 fetch_word(void); @@ -154,70 +178,70 @@ extern int32 CPU_BD_get_mbyte(int32 addr); extern int32 CPU_BD_get_mword(int32 addr); static const char *opcode[] = { -"???", "NOP", "???", "???", //0x00 -"???", "???", "TAP", "TPA", -"INX", "DEX", "CLV", "SEV", -"CLC", "SEC", "CLI", "SEI", -"SBA", "CBA", "???", "???", //0x10 -"???", "???", "TAB", "TBA", -"???", "DAA", "???", "ABA", -"???", "???", "???", "???", -"BRA", "???", "BHI", "BLS", //0x20 -"BCC", "BCS", "BNE", "BEQ", -"BVC", "BVS", "BPL", "BMI", -"BGE", "BLT", "BGT", "BLE", -"TSX", "INS", "PULA", "PULB", //0x30 -"DES", "TXS", "PSHA", "PSHB", -"???", "RTS", "???", "RTI", -"???", "???", "WAI", "SWI", -"NEGA", "???", "???", "COMA", //0x40 -"LSRA", "???", "RORA", "ASRA", -"ASLA", "ROLA", "DECA", "???", -"INCA", "TSTA", "???", "CLRA", -"NEGB", "???", "???", "COMB", //0x50 -"LSRB", "???", "RORB", "ASRB", -"ASLB", "ROLB", "DECB", "???", -"INCB", "TSTB", "???", "CLRB", -"NEG", "???", "???", "COM", //0x60 -"LSR", "???", "ROR", "ASR", -"ASL", "ROL", "DEC", "???", -"INC", "TST", "JMP", "CLR", -"NEG", "???", "???", "COM", //0x70 -"LSR", "???", "ROR", "ASR", -"ASL", "ROL", "DEC", "???", -"INC", "TST", "JMP", "CLR", -"SUBA", "CMPA", "SBCA", "???", //0x80 -"ANDA", "BITA", "LDAA", "???", -"EORA", "ADCA", "ORAA", "ADDA", -"CPX", "BSR", "LDS", "???", -"SUBA", "CMPA", "SBCA", "???", //0x90 -"ANDA", "BITA", "LDAA", "STAA", -"EORA", "ADCA", "ORAA", "ADDA", -"CPX", "???", "LDS", "STS", -"SUBA", "CMPA", "SBCA", "???", //0xA0 -"ANDA", "BITA", "LDAA", "STAA", -"EORA", "ADCA", "ORAA", "ADDA", +"??? ", "NOP ", "??? ", "??? ", //0x00 +"??? ", "??? ", "TAP ", "TPA ", +"INX ", "DEX ", "CLV ", "SEV ", +"CLC ", "SEC ", "CLI ", "SEI ", +"SBA ", "CBA ", "??? ", "??? ", //0x10 +"??? ", "??? ", "TAB ", "TBA ", +"??? ", "DAA ", "??? ", "ABA ", +"??? ", "??? ", "??? ", "??? ", +"BRA ", "??? ", "BHI ", "BLS ", //0x20 +"BCC ", "BCS ", "BNE ", "BEQ ", +"BVC ", "BVS ", "BPL ", "BMI ", +"BGE ", "BLT ", "BGT ", "BLE ", +"TSX ", "INS ", "PUL A", "PUL B", //0x30 +"DES ", "TXS ", "PSH A", "PSH B", +"??? ", "RTS ", "??? ", "RTI ", +"??? ", "??? ", "WAI ", "SWI ", +"NEG A", "??? ", "??? ", "COM A", //0x40 +"LSR A", "??? ", "ROR A", "ASR A", +"ASL A", "ROL A", "DEC A", "??? ", +"INC A", "TST A", "??? ", "CLR A", +"NEG B", "??? ", "??? ", "COM B", //0x50 +"LSR B", "??? ", "ROR B", "ASR B", +"ASL B", "ROL B", "DEC B", "??? ", +"INC B", "TST B", "??? ", "CLR B", +"NEG ", "??? ", "??? ", "COM ", //0x60 +"LSR ", "??? ", "ROR ", "ASR ", +"ASL ", "ROL ", "DEC ", "??? ", +"INC ", "TST ", "JMP ", "CLR ", +"NEG ", "??? ", "??? ", "COM ", //0x70 +"LSR ", "??? ", "ROR ", "ASR ", +"ASL ", "ROL ", "DEC ", "??? ", +"INC ", "TST ", "JMP ", "CLR ", +"SUB A", "CMP A", "SBC A", "??? ", //0x80 +"AND A", "BIT A", "LDA A", "??? ", +"EOR A", "ADC A", "ORA A", "ADD A", +"CPX ", "BSR ", "LDS ", "??? ", +"SUB A", "CMP A", "SBC A", "??? ", //0x90 +"AND A", "BIT A", "LDA A", "STA A", +"EOR A", "ADC A", "ORA A", "ADD A", +"CPX ", "??? ", "LDS ", "STS ", +"SUB A", "CMP A", "SBC A", "??? ", //0xA0 +"AND A", "BIT A", "LDA A", "STA A", +"EOR A", "ADC A", "ORA A", "ADD A", "CPX X", "JSR X", "LDS X", "STS X", -"SUBA", "CMPA", "SBCA", "???", //0xB0 -"ANDA", "BITA", "LDAA", "STAA", -"EORA", "ADCA", "ORAA", "ADDA", -"CPX", "JSR", "LDS", "STS", -"SUBB", "CMPB", "SBCB", "???", //0xC0 -"ANDB", "BITB", "LDAB", "???", -"EORB", "ADCB", "ORAB", "ADDB", -"???", "???", "LDX", "???", -"SUBB", "CMPB", "SBCB", "???", //0xD0 -"ANDB", "BITB", "LDAB", "STAB", -"EORB", "ADCB", "ORAB", "ADDB", -"???", "???", "LDX", "STX", -"SUBB", "CMPB", "SBCB", "???", //0xE0 -"ANDB", "BITB", "LDAB", "STAB", -"EORB", "ADCB", "ORAB", "ADDB", -"???", "???", "LDX", "STX", -"SUBB", "CMPB", "SBCB", "???", //0xF0 -"ANDB", "BITB", "LDAB", "STAB", -"EORB", "ADCB", "ORAB", "ADDB", -"???", "???", "LDX", "STX", +"SUB A", "CMP A", "SBC A", "??? ", //0xB0 +"AND A", "BIT A", "LDA A", "STA A", +"EOR A", "ADC A", "ORA A", "ADD A", +"CPX ", "JSR ", "LDS ", "STS ", +"SUB B", "CMP B", "SBC B", "??? ", //0xC0 +"AND B", "BIT B", "LDA B", "??? ", +"EOR B", "ADC B", "ORA B", "ADD B", +"??? ", "??? ", "LDX ", "??? ", +"SUB B", "CMP B", "SBC B", "??? ", //0xD0 +"AND B", "BIT B", "LDA B", "STA B", +"EOR B", "AD CB", "ORA B", "ADD B", +"??? ", "??? ", "LDX ", "STX ", +"SUB B", "CMP B", "SBC B", "??? ", //0xE0 +"AND B", "BIT B", "LDA B", "STA B", +"EOR B", "ADC B", "ORA B", "ADD B", +"??? ", "??? ", "LDX ", "STX ", +"SUB B", "CMP B", "SBC B", "??? ", //0xF0 +"AND B", "BIT B", "LDA B", "STA B", +"EOR B", "ADC B", "ORA B", "ADD B", +"??? ", "??? ", "LDX ", "STX ", }; int32 oplen[256] = { @@ -256,14 +280,18 @@ REG m6800_reg[] = { { HRDATA (SP, SP, 16) }, { HRDATA (CC, CC, 8) }, { ORDATA (WRU, sim_int_char, 8) }, - { NULL } }; + { NULL } +}; MTAB m6800_mod[] = { { UNIT_OPSTOP, UNIT_OPSTOP, "ITRAP", "ITRAP", NULL }, { UNIT_OPSTOP, 0, "NOITRAP", "NOITRAP", NULL }, { UNIT_MSTOP, UNIT_MSTOP, "MTRAP", "MTRAP", NULL }, { UNIT_MSTOP, 0, "NOMTRAP", "NOMTRAP", NULL }, - { 0 } }; + { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP|MTAB_NC, 0, "HISTORY", "HISTORY=n", + &cpu_set_hist, &cpu_show_hist, NULL, "Enable/Display instruction history" }, + { 0 } +}; DEBTAB m6800_debug[] = { { "ALL", DEBUG_all, "All debug bits" }, @@ -284,8 +312,8 @@ DEVICE m6800_dev = { 1, //aincr 16, //dradix 8, //dwidth - &m6800_examine, //examine - NULL, //deposit + &m6800_ex, //examine + &m6800_dep, //deposit &m6800_reset, //reset NULL, //boot NULL, //attach @@ -295,12 +323,17 @@ DEVICE m6800_dev = { 0, //dctrl m6800_debug, //debflags NULL, //msize - NULL //lname + NULL, //lname + NULL, //help routine + NULL, //attach help routine + NULL, //help context + &m6800_desc //device description }; t_stat sim_instr (void) { - int32 IR, EA, reason, hi, lo, op1; + int32 IR, EA, hi, lo, op1, i, sw = 0; + InstHistory *hst_ent = NULL; PC = saved_PC & ADDRMASK; /* load local PC */ reason = 0; @@ -311,11 +344,6 @@ t_stat sim_instr (void) if (sim_interval <= 0) /* check clock queue */ if ((reason = sim_process_event ())) break; - //if (mem_fault) { /* memory fault? */ - //mem_fault = 0; /* reset fault flag */ - //reason = STOP_MEMORY; - //break; - //} if (NMI > 0) { //* NMI? */ push_word(PC); push_word(IX); @@ -331,6 +359,7 @@ t_stat sim_instr (void) push_byte(A); push_byte(B); push_byte(CC); + SET_FLAG(IF); //rsv fix PC = get_vec_val(0xFFF8); } } /* end IRQ */ @@ -340,13 +369,27 @@ t_stat sim_instr (void) break; } + if (hst_lnt) { /* record history? */ + hst_ent = &hst[hst_p]; + hst_ent->pc = PC; + hst_ent->sp = SP; + hst_ent->cc = CC; + hst_ent->a = A; + hst_ent->b = B; + hst_ent->ix = IX; + for (i = 0; i < HIST_ILNT; i++) + hst_ent->inst[i] = (t_value)CPU_BD_get_mbyte (PC + i); + hst_p = (hst_p + 1); + if (hst_p >= hst_lnt) + hst_p = 0; + } + sim_interval--; IR = fetch_byte(); /* fetch instruction */ /* The Big Instruction Decode Switch */ switch (IR) { - case 0x01: /* NOP */ break; case 0x06: /* TAP */ @@ -385,7 +428,7 @@ t_stat sim_instr (void) op1 = A; A = A - B; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, B); @@ -393,7 +436,7 @@ t_stat sim_instr (void) case 0x11: /* CBA */ lo = A - B; COND_SET_FLAG_C(lo); - lo &= 0xFF ; + lo &= BYTEMASK; COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); condevalVs(A, B); @@ -423,7 +466,7 @@ t_stat sim_instr (void) A = (A & 0x0F) | (EA << 4) | 0x100; } COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; @@ -431,7 +474,7 @@ t_stat sim_instr (void) op1 = A ; A += B; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, B); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -540,15 +583,15 @@ t_stat sim_instr (void) PC = get_vec_val(0xFFFA); break; case 0x40: /* NEG A */ - COND_SET_FLAG_V(A == 0x80); - A = (0 - A); - COND_SET_FLAG_C(A); - A &= 0xFF; + op1 = A; + A = (0 - A) & BYTEMASK; + condevalVs(A, op1); //RSV - fixed boundry condition + COND_SET_FLAG(A,CF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x43: /* COM A */ - A = ~A & 0xFF; + A = ~A & BYTEMASK; CLR_FLAG(VF); SET_FLAG(CF); COND_SET_FLAG_N(A); @@ -556,7 +599,7 @@ t_stat sim_instr (void) break; case 0x44: /* LSR A */ COND_SET_FLAG(A & 0x01,CF); - A = (A >> 1) & 0xFF; + A = (A >> 1) & BYTEMASK; CLR_FLAG(NF); COND_SET_FLAG_Z(A); COND_SET_FLAG_V(get_flag(NF) ^ get_flag(CF)); @@ -564,7 +607,7 @@ t_stat sim_instr (void) case 0x46: /* ROR A */ hi = get_flag(CF); COND_SET_FLAG(A & 0x01,CF); - A = (A >> 1) & 0xFF; + A = (A >> 1) & BYTEMASK; if (hi) A |= 0x80; COND_SET_FLAG_N(A); @@ -574,7 +617,7 @@ t_stat sim_instr (void) case 0x47: /* ASR A */ COND_SET_FLAG(A & 0x01,CF); lo = A & 0x80; - A = (A >> 1) & 0xFF; + A = (A >> 1) & BYTEMASK; A |= lo; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -582,7 +625,7 @@ t_stat sim_instr (void) break; case 0x48: /* ASL A */ COND_SET_FLAG(A & 0x80,CF); - A = (A << 1) & 0xFF; + A = (A << 1) & BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); COND_SET_FLAG_V(get_flag(NF) ^ get_flag(CF)); @@ -590,7 +633,7 @@ t_stat sim_instr (void) case 0x49: /* ROL A */ hi = get_flag(CF); COND_SET_FLAG(A & 0x80,CF); - A = (A << 1) & 0xFF; + A = (A << 1) & BYTEMASK; if (hi) A |= 0x01; COND_SET_FLAG_N(A); @@ -599,18 +642,18 @@ t_stat sim_instr (void) break; case 0x4A: /* DEC A */ COND_SET_FLAG_V(A == 0x80); - A = (A - 1) & 0xFF; + A = (A - 1) & BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x4C: /* INC A */ COND_SET_FLAG_V(A == 0x7F); - A = (A + 1) & 0xFF; + A = (A + 1) & BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x4D: /* TST A */ - lo = (A - 0) & 0xFF; + lo = (A - 0) & BYTEMASK; CLR_FLAG(VF); CLR_FLAG(CF); COND_SET_FLAG_N(lo); @@ -624,16 +667,16 @@ t_stat sim_instr (void) SET_FLAG(ZF); break; case 0x50: /* NEG B */ - COND_SET_FLAG_V(B == 0x80); - B = (0 - B); - COND_SET_FLAG_C(B); - B &= 0xFF; + op1 = B; + B = (0 - B) & BYTEMASK; + condevalVs(B, op1); //RSV - fixed boundry condition + COND_SET_FLAG(B,CF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0x53: /* COM B */ B = ~B; - B &= 0xFF; + B &= BYTEMASK; CLR_FLAG(VF); SET_FLAG(CF); COND_SET_FLAG_N(B); @@ -641,7 +684,7 @@ t_stat sim_instr (void) break; case 0x54: /* LSR B */ COND_SET_FLAG(B & 0x01,CF); - B = (B >> 1) & 0xFF; + B = (B >> 1) & BYTEMASK; CLR_FLAG(NF); COND_SET_FLAG_Z(B); COND_SET_FLAG_V(get_flag(NF) ^ get_flag(CF)); @@ -649,7 +692,7 @@ t_stat sim_instr (void) case 0x56: /* ROR B */ hi = get_flag(CF); COND_SET_FLAG(B & 0x01,CF); - B = (B >> 1) & 0xFF; + B = (B >> 1) & BYTEMASK; if (hi) B |= 0x80; COND_SET_FLAG_N(B); @@ -659,7 +702,7 @@ t_stat sim_instr (void) case 0x57: /* ASR B */ COND_SET_FLAG(B & 0x01,CF); lo = B & 0x80; - B = (B >> 1) & 0xFF; + B = (B >> 1) & BYTEMASK; B |= lo; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -667,7 +710,7 @@ t_stat sim_instr (void) break; case 0x58: /* ASL B */ COND_SET_FLAG(B & 0x80,CF); - B = (B << 1) & 0xFF; + B = (B << 1) & BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); COND_SET_FLAG_V(get_flag(NF) ^ get_flag(CF)); @@ -675,7 +718,7 @@ t_stat sim_instr (void) case 0x59: /* ROL B */ hi = get_flag(CF); COND_SET_FLAG(B & 0x80,CF); - B = (B << 1) & 0xFF; + B = (B << 1) & BYTEMASK; if (hi) B |= 0x01; COND_SET_FLAG_N(B); @@ -684,18 +727,18 @@ t_stat sim_instr (void) break; case 0x5A: /* DEC B */ COND_SET_FLAG_V(B == 0x80); - B = (B - 1) & 0xFF; + B = (B - 1) & BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0x5C: /* INC B */ COND_SET_FLAG_V(B == 0x7F); - B = (B + 1) & 0xFF; + B = (B + 1) & BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0x5D: /* TST B */ - lo = (B - 0) & 0xFF; + lo = (B - 0) & BYTEMASK; CLR_FLAG(VF); CLR_FLAG(CF); COND_SET_FLAG_N(lo); @@ -711,18 +754,17 @@ t_stat sim_instr (void) case 0x60: /* NEG ind */ EA = (fetch_byte() + IX) & ADDRMASK; op1 = CPU_BD_get_mbyte(EA); - COND_SET_FLAG_V(op1 == 0x80); - lo = (0 - op1); - COND_SET_FLAG_C(lo); - lo &= 0xFF; + lo = (0 - op1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); + condevalVs(lo, op1); //RSV - fixed boundry condition + COND_SET_FLAG(lo,CF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); break; case 0x63: /* COM ind */ EA = (fetch_byte() + IX) & ADDRMASK; lo = ~CPU_BD_get_mbyte(EA); - lo &= 0xFF; + lo &= BYTEMASK; CPU_BD_put_mbyte(EA, lo); CLR_FLAG(VF); SET_FLAG(CF); @@ -766,7 +808,7 @@ t_stat sim_instr (void) EA = (fetch_byte() + IX) & ADDRMASK; lo = CPU_BD_get_mbyte(EA); COND_SET_FLAG(lo & 0x80,CF); - lo = (lo << 1) & 0xFF; + lo = (lo << 1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -777,7 +819,7 @@ t_stat sim_instr (void) lo = CPU_BD_get_mbyte(EA); hi = get_flag(CF); COND_SET_FLAG(lo & 0x80,CF); - lo = (lo << 1) &0xFF; + lo = (lo << 1) &BYTEMASK; if (hi) lo |= 0x01; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); @@ -788,7 +830,7 @@ t_stat sim_instr (void) EA = (fetch_byte() + IX) & ADDRMASK; lo = CPU_BD_get_mbyte(EA); COND_SET_FLAG_V(lo == 0x80); - lo = (lo - 1) & 0xFF; + lo = (lo - 1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -797,13 +839,13 @@ t_stat sim_instr (void) EA= (fetch_byte() + IX) & ADDRMASK; lo = CPU_BD_get_mbyte(EA); COND_SET_FLAG_V(lo == 0x7F); - lo = (lo + 1) & 0xFF; + lo = (lo + 1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); break; case 0x6D: /* TST ind */ - lo = (get_indir_val() - 0) & 0xFF; + lo = (get_indir_val() - 0) & BYTEMASK; CLR_FLAG(VF); CLR_FLAG(CF); COND_SET_FLAG_N(lo); @@ -822,17 +864,19 @@ t_stat sim_instr (void) case 0x70: /* NEG ext */ EA = fetch_word(); op1 = CPU_BD_get_mbyte(EA); - COND_SET_FLAG_V(op1 == 0x80) ; - COND_SET_FLAG(op1 != 0, CF); - lo = (0 - op1) & 0xFF; + lo = (0 - op1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); + condevalVs(lo, op1); //RSV - fixed boundry condition + CLR_FLAG(CF); + if (lo) + SET_FLAG(CF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); break; case 0x73: /* COM ext */ EA = fetch_word(); lo = ~CPU_BD_get_mbyte(EA); - lo &= 0xFF; + lo &= BYTEMASK; CPU_BD_put_mbyte(EA, lo); CLR_FLAG(VF); SET_FLAG(CF); @@ -878,7 +922,7 @@ t_stat sim_instr (void) EA = fetch_word(); lo = CPU_BD_get_mbyte(EA); COND_SET_FLAG(lo & 0x80,CF); - lo = (lo << 1) & 0xFF; + lo = (lo << 1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -889,7 +933,7 @@ t_stat sim_instr (void) lo = CPU_BD_get_mbyte(EA); hi = get_flag(CF); COND_SET_FLAG(lo & 0x80,CF); - lo = (lo << 1) & 0xFF; + lo = (lo << 1) & BYTEMASK; if (hi) lo |= 0x01; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); @@ -900,7 +944,7 @@ t_stat sim_instr (void) EA = fetch_word(); lo = CPU_BD_get_mbyte(EA); COND_SET_FLAG_V(lo == 0x80); - lo = (lo - 1) & 0xFF; + lo = (lo - 1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -909,7 +953,7 @@ t_stat sim_instr (void) EA = fetch_word(); lo = CPU_BD_get_mbyte(EA); COND_SET_FLAG_V(lo == 0x7F); - lo = (lo + 1) & 0xFF; + lo = (lo + 1) & BYTEMASK; CPU_BD_put_mbyte(EA, lo); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -919,7 +963,7 @@ t_stat sim_instr (void) CLR_FLAG(VF); CLR_FLAG(CF); COND_SET_FLAG_N(lo); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0x7E: /* JMP ext */ @@ -933,81 +977,81 @@ t_stat sim_instr (void) SET_FLAG(ZF); break; case 0x80: /* SUB A imm */ - lo = fetch_byte() & 0xFF; + lo = fetch_byte(); op1 = A; A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); break; case 0x81: /* CMP A imm */ - op1 = fetch_byte() & 0xFF; + op1 = fetch_byte(); lo = A - op1; COND_SET_FLAG_C(lo); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); condevalVs(A, op1); break; case 0x82: /* SBC A imm */ - lo = fetch_byte() & 0xFF + get_flag(CF); + lo = (fetch_byte() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem op1 = A; A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); break; case 0x84: /* AND A imm */ - A = (A & fetch_byte() & 0xFF) & 0xFF; + A = (A & fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x85: /* BIT A imm */ - lo = (A & fetch_byte() & 0xFF) & 0xFF; + lo = (A & fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); break; case 0x86: /* LDA A imm */ - A = fetch_byte() & 0xFF; + A = fetch_byte(); CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x88: /* EOR A imm */ - A = (A ^ fetch_byte() & 0xFF) & 0xFF; + A = (A ^ fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x89: /* ADC A imm */ - lo = fetch_byte() & 0xFF + get_flag(CF); + lo = (fetch_byte() + get_flag(CF)) & BYTEMASK; op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVa(op1, lo); break; case 0x8A: /* ORA A imm */ - A = (A | fetch_byte() & 0xFF) & 0xFF; + A = (A | fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x8B: /* ADD A imm */ - lo = fetch_byte() & 0xFF; + lo = fetch_byte(); op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -1039,7 +1083,7 @@ t_stat sim_instr (void) op1 = A; A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); @@ -1050,27 +1094,26 @@ t_stat sim_instr (void) COND_SET_FLAG_N(lo); COND_SET_FLAG_C(lo); condevalVs(A, op1); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0x92: /* SBC A dir */ - lo = get_dir_val() + get_flag(CF); - op1 = A; + lo = (get_dir_val() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); break; case 0x94: /* AND A dir */ - A = (A & get_dir_val()) & 0xFF; + A = (A & get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x95: /* BIT A dir */ - lo = (A & get_dir_val()) & 0xFF; + lo = (A & get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -1082,30 +1125,30 @@ t_stat sim_instr (void) COND_SET_FLAG_Z(A); break; case 0x97: /* STA A dir */ - CPU_BD_put_mbyte(fetch_byte() & 0xFF, A); + CPU_BD_put_mbyte(fetch_byte(), A); CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x98: /* EOR A dir */ - A = (A ^ get_dir_val()) & 0xFF; + A = (A ^ get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0x99: /* ADC A dir */ - lo = get_dir_val() + get_flag(CF); + lo = (get_dir_val() + get_flag(CF)) & BYTEMASK; op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVa(op1, lo); break; case 0x9A: /* ORA A dir */ - A = (A | get_dir_val()) & 0xFF; + A = (A | get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -1115,26 +1158,26 @@ t_stat sim_instr (void) op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVa(op1, lo); break; case 0x9C: /* CPX dir */ - op1 = IX - CPU_BD_get_mword(fetch_byte() & 0xFF); + op1 = IX - CPU_BD_get_mword(fetch_byte()); COND_SET_FLAG_Z(op1); COND_SET_FLAG_N(op1 >> 8); COND_SET_FLAG_V(op1 & 0x10000); break; case 0x9E: /* LDS dir */ - SP = CPU_BD_get_mword(fetch_byte() & 0xFF); + SP = CPU_BD_get_mword(fetch_byte()); COND_SET_FLAG_N(SP >> 8); COND_SET_FLAG_Z(SP); CLR_FLAG(VF); break; case 0x9F: /* STS dir */ - CPU_BD_put_mword(fetch_byte() & 0xFF, SP); + CPU_BD_put_mword(fetch_byte(), SP); COND_SET_FLAG_N(SP >> 8); COND_SET_FLAG_Z(SP); CLR_FLAG(VF); @@ -1144,7 +1187,7 @@ t_stat sim_instr (void) op1 = A; A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); @@ -1155,27 +1198,26 @@ t_stat sim_instr (void) COND_SET_FLAG_N(lo); COND_SET_FLAG_C(lo); condevalVs(A, op1); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0xA2: /* SBC A ind */ - lo = get_indir_val() + get_flag(CF); - op1 = A; + lo = (get_indir_val() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); break; case 0xA4: /* AND A ind */ - A = (A & get_indir_val()) & 0xFF; + A = (A & get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0xA5: /* BIT A ind */ - lo = (A & get_indir_val()) & 0xFF; + lo = (A & get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -1193,24 +1235,24 @@ t_stat sim_instr (void) COND_SET_FLAG_Z(A); break; case 0xA8: /* EOR A ind */ - A = (A ^ get_indir_val()) & 0xFF; + A = (A ^ get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0xA9: /* ADC A ind */ - lo = get_indir_val() + get_flag(CF); + lo = (get_indir_val() + get_flag(CF)) & BYTEMASK; op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVa(op1, lo); break; case 0xAA: /* ORA A ind */ - A = (A | get_indir_val()) & 0xFF; + A = (A | get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -1220,7 +1262,7 @@ t_stat sim_instr (void) op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -1254,7 +1296,7 @@ t_stat sim_instr (void) op1 = A; A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); @@ -1265,27 +1307,27 @@ t_stat sim_instr (void) COND_SET_FLAG_N(lo); COND_SET_FLAG_C(lo); condevalVs(A, op1); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0xB2: /* SBC A ext */ - lo = get_ext_val() + get_flag(CF); + lo = (get_ext_val() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem op1 = A; A = A - lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVs(op1, lo); break; case 0xB4: /* AND A ext */ - A = (A & get_ext_val()) & 0xFF; + A = (A & get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0xB5: /* BIT A ext */ - lo = (A & get_ext_val()) & 0xFF; + lo = (A & get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -1303,24 +1345,24 @@ t_stat sim_instr (void) COND_SET_FLAG_Z(A); break; case 0xB8: /* EOR A ext */ - A = (A ^ get_ext_val()) & 0xFF; + A = (A ^ get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); break; case 0xB9: /* ADC A ext */ - lo = get_ext_val() + get_flag(CF); + lo = (get_ext_val() + get_flag(CF)) & BYTEMASK; op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); condevalVa(op1, lo); break; case 0xBA: /* ORA A ext */ - A = (A | get_ext_val()) & 0xFF; + A = (A | get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -1330,7 +1372,7 @@ t_stat sim_instr (void) op1 = A; A = A + lo; COND_SET_FLAG_C(A); - A &= 0xFF; + A &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(A); COND_SET_FLAG_Z(A); @@ -1360,81 +1402,81 @@ t_stat sim_instr (void) CLR_FLAG(VF); break; case 0xC0: /* SUB B imm */ - lo = fetch_byte() & 0xFF; + lo = fetch_byte(); op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); break; case 0xC1: /* CMP B imm */ - op1 = fetch_byte() & 0xFF; + op1 = fetch_byte(); lo = B - op1; COND_SET_FLAG_N(lo); COND_SET_FLAG_C(lo); condevalVs(B, op1); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0xC2: /* SBC B imm */ - lo = fetch_byte() & 0xFF + get_flag(CF); + lo = (fetch_byte() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); break; case 0xC4: /* AND B imm */ - B = (B & fetch_byte() & 0xFF) & 0xFF; + B = (B & fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xC5: /* BIT B imm */ - lo = (B & fetch_byte() & 0xFF) & 0xFF; + lo = (B & fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); break; case 0xC6: /* LDA B imm */ - B = fetch_byte() & 0xFF; + B = fetch_byte(); CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xC8: /* EOR B imm */ - B = (B ^ fetch_byte() & 0xFF) & 0xFF; + B = (B ^ fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xC9: /* ADC B imm */ - lo = fetch_byte() & 0xFF + get_flag(CF); + lo = (fetch_byte() + get_flag(CF)) & BYTEMASK; op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVa(op1, lo); break; case 0xCA: /* ORA B imm */ - B = (B | fetch_byte() & 0xFF) & 0xFF; + B = (B | fetch_byte()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xCB: /* ADD B imm */ - lo = fetch_byte() & 0xFF; + lo = fetch_byte(); op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -1451,7 +1493,7 @@ t_stat sim_instr (void) op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); @@ -1460,29 +1502,29 @@ t_stat sim_instr (void) lo = get_dir_val(); op1 = B - lo; COND_SET_FLAG_C(op1); - op1 &= 0xFF; + op1 &= BYTEMASK; COND_SET_FLAG_N(op1); COND_SET_FLAG_Z(op1); condevalVs(B, lo); break; case 0xD2: /* SBC B dir */ - lo = get_dir_val() + get_flag(CF); + lo = (get_dir_val() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); break; case 0xD4: /* AND B dir */ - B = (B & get_dir_val()) & 0xFF; + B = (B & get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xD5: /* BIT B dir */ - lo = (B & get_dir_val()) & 0xFF; + lo = (B & get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -1494,30 +1536,30 @@ t_stat sim_instr (void) COND_SET_FLAG_Z(B); break; case 0xD7: /* STA B dir */ - CPU_BD_put_mbyte(fetch_byte() & 0xFF, B); + CPU_BD_put_mbyte(fetch_byte(), B); CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xD8: /* EOR B dir */ - B = (B ^ get_dir_val()) & 0xFF; + B = (B ^ get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xD9: /* ADC B dir */ - lo = get_dir_val() + get_flag(CF); + lo = (get_dir_val() + get_flag(CF)) & BYTEMASK; op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVa(op1, lo); break; case 0xDA: /* ORA B dir */ - B = (B | get_dir_val()) & 0xFF; + B = (B | get_dir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -1527,20 +1569,20 @@ t_stat sim_instr (void) op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVa(op1, lo); break; case 0xDE: /* LDX dir */ - IX = CPU_BD_get_mword(fetch_byte() & 0xFF); + IX = CPU_BD_get_mword(fetch_byte()); COND_SET_FLAG_N(IX >> 8); COND_SET_FLAG_Z(IX); CLR_FLAG(VF); break; case 0xDF: /* STX dir */ - CPU_BD_put_mword(fetch_byte() & 0xFF, IX); + CPU_BD_put_mword(fetch_byte(), IX); COND_SET_FLAG_N(IX >> 8); COND_SET_FLAG_Z(IX); CLR_FLAG(VF); @@ -1550,7 +1592,7 @@ t_stat sim_instr (void) op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); @@ -1561,27 +1603,27 @@ t_stat sim_instr (void) COND_SET_FLAG_N(lo); COND_SET_FLAG_C(lo); condevalVs(B, op1); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0xE2: /* SBC B ind */ - lo = get_indir_val() + get_flag(CF); + lo = (get_indir_val() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); break; case 0xE4: /* AND B ind */ - B = (B & get_indir_val()) & 0xFF; + B = (B & get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xE5: /* BIT B ind */ - lo = (B & get_indir_val()) & 0xFF; + lo = (B & get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -1599,24 +1641,24 @@ t_stat sim_instr (void) COND_SET_FLAG_Z(B); break; case 0xE8: /* EOR B ind */ - B = (B ^ get_indir_val()) & 0xFF; + B = (B ^ get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xE9: /* ADC B ind */ - lo = get_indir_val() + get_flag(CF); + lo = (get_indir_val() + get_flag(CF)) & BYTEMASK; op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVa(op1, lo); break; case 0xEA: /* ORA B ind */ - B = (B | get_indir_val()) & 0xFF; + B = (B | get_indir_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -1626,7 +1668,7 @@ t_stat sim_instr (void) op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -1649,7 +1691,7 @@ t_stat sim_instr (void) op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); @@ -1660,27 +1702,27 @@ t_stat sim_instr (void) COND_SET_FLAG_N(lo); COND_SET_FLAG_C(lo); condevalVs(B, op1); - lo &= 0xFF; + lo &= BYTEMASK; COND_SET_FLAG_Z(lo); break; case 0xF2: /* SBC B ext */ - lo = get_ext_val() + get_flag(CF); + lo = (get_ext_val() + get_flag(CF)) & BYTEMASK; //RSV - fixed ordering problem op1 = B; B = B - lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVs(op1, lo); break; case 0xF4: /* AND B ext */ - B = (B & get_ext_val()) & 0xFF; + B = (B & get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xF5: /* BIT B ext */ - lo = (B & get_ext_val()) & 0xFF; + lo = (B & get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(lo); COND_SET_FLAG_Z(lo); @@ -1698,24 +1740,24 @@ t_stat sim_instr (void) COND_SET_FLAG_Z(B); break; case 0xF8: /* EOR B ext */ - B = (B ^ get_ext_val()) & 0xFF; + B = (B ^ get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); break; case 0xF9: /* ADC B ext */ - lo = get_ext_val() + get_flag(CF); + lo = (get_ext_val() + get_flag(CF)) & BYTEMASK; op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); condevalVa(op1, lo); break; case 0xFA: /* ORA B ext */ - B = (B | get_ext_val()) & 0xFF; + B = (B | get_ext_val()) & BYTEMASK; CLR_FLAG(VF); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -1725,7 +1767,7 @@ t_stat sim_instr (void) op1 = B; B = B + lo; COND_SET_FLAG_C(B); - B &= 0xFF; + B &= BYTEMASK; condevalHa(op1, lo); COND_SET_FLAG_N(B); COND_SET_FLAG_Z(B); @@ -1754,7 +1796,6 @@ t_stat sim_instr (void) } } /* Simulation halted - lets dump all the registers! */ - dump_regs(); saved_PC = PC; return reason; } @@ -1772,7 +1813,8 @@ int32 fetch_byte(void) { uint8 val; - val = CPU_BD_get_mbyte(PC) & 0xFF; /* fetch byte */ + val = CPU_BD_get_mbyte(PC) & BYTEMASK; /* fetch byte */ + //rsv fix on opernd order but moved the "& BYTEMASK" here PC = (PC + 1) & ADDRMASK; /* increment PC */ return val; } @@ -1783,7 +1825,7 @@ int32 fetch_word(void) uint16 val; val = CPU_BD_get_mbyte(PC) << 8; /* fetch high byte */ - val |= CPU_BD_get_mbyte(PC + 1) & 0xFF; /* fetch low byte */ + val |= CPU_BD_get_mbyte(PC + 1) & BYTEMASK; /* fetch low byte */ PC = (PC + 2) & ADDRMASK; /* increment PC */ return val; } @@ -1791,14 +1833,15 @@ int32 fetch_word(void) /* push a byte to the stack */ void push_byte(uint8 val) { - CPU_BD_put_mbyte(SP, val & 0xFF); + CPU_BD_put_mbyte(SP, val & BYTEMASK); + //rsv fix on opernd order but moved the "& BYTEMASK" here SP = (SP - 1) & ADDRMASK; } /* push a word to the stack */ void push_word(uint16 val) { - push_byte(val & 0xFF); + push_byte(val & BYTEMASK); push_byte(val >> 8); } @@ -1848,14 +1891,14 @@ int32 get_vec_val(int32 vec) int32 get_imm_val(void) { - return (fetch_byte() & 0xFF); + return fetch_byte(); } /* returns the value at the direct address pointed to by PC */ int32 get_dir_val(void) { - return CPU_BD_get_mbyte(fetch_byte() & 0xFF); + return CPU_BD_get_mbyte(fetch_byte()); } /* returns the value at the indirect address pointed to by PC */ @@ -1918,16 +1961,16 @@ void condevalHa(int32 op1, int32 op2) /* Reset routine */ -t_stat m6800_reset (DEVICE *dptr) +t_stat m6800_reset(DEVICE *dptr) { CC = CC_ALWAYS_ON | IF; NMI = 0, IRQ = 0; sim_brk_types = sim_brk_dflt = SWMASK ('E'); saved_PC = CPU_BD_get_mword(0xFFFE); -// if (saved_PC == 0xFFFF) -// printf("No EPROM image found - M6800 reset incomplete!\n"); -// else -// printf("EPROM vector=%04X\n", saved_PC); + if ((saved_PC == 0xFFFF) && ((sim_switches & SWMASK ('P')) == 0)) { + printf("No EPROM image found\n"); + reason = STOP_MEMORY; /* stop simulation - no ROM*/ + } return SCPE_OK; } @@ -1936,19 +1979,113 @@ t_stat m6800_reset (DEVICE *dptr) takes the address from the hex record or the current PC for binary. */ -t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) -{ - int32 i, addr = 0, cnt = 0; +#define HLEN 16 - if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; - addr = saved_PC; - while ((i = getc (fileref)) != EOF) { - CPU_BD_put_mbyte(addr, i); - addr++; - cnt++; - } // end while - printf ("%d Bytes loaded.\n", cnt); - return (SCPE_OK); +int32 sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) +{ + int32 i, addr = 0, addr0 = 0, cnt = 0, cnt0 = 0, start = 0x10000; + int32 addr1 = 0, end = 0, byte, chk, rtype, flag0 = 1; + char buf[128], data[128], *p; + + cnt = sscanf(cptr, " %04X %04X", &start, &end); + addr=start; + if (flag == 0) { //load + if (sim_switches & SWMASK ('H')) { //hex + if (cnt > 1) //2 arguments - error + return SCPE_ARG; + cnt = 0; + while (fgets(buf, sizeof(buf)-1, fileref)) { + sscanf(buf, " S%1d%02x%04x%s", &rtype, &cnt0, &addr, data); + if (flag0) { + addr1 = addr; + flag0 = 0; + } + if (rtype == 1) { + chk = 0; + chk += cnt0; + cnt0 -= 3; + chk += addr & BYTEMASK; + chk += addr >> 8; + p = (char *) data; + for (i=0; i 1) //2 arguments - error + return SCPE_ARG; + cnt = 0; + addr1 = addr; + while ((i = getc (fileref)) != EOF) { + CPU_BD_put_mbyte(addr, i); + addr++; cnt++; + } + } + printf ("%d Bytes loaded at %04X\n", cnt, addr1); + return (SCPE_OK); + } else { //dump + if (cnt != 2) //must be 2 arguments + return SCPE_ARG; + cnt = 0; + addr0 = addr; + if (sim_switches & SWMASK ('H')) { //hex + while((addr + HLEN) <= end) { //full records + fprintf(fileref,"S1%02X%04X", HLEN + 3, addr); + chk = 0; + chk += HLEN + 3; + chk += addr & BYTEMASK; + chk += addr >> 8; + for (i=0; i> 8; + for (i=0; i<=(end - addr); i++) { + byte = CPU_BD_get_mbyte(addr + i); + fprintf(fileref, "%02X", byte); + chk += byte; chk &= BYTEMASK; + cnt++; + } + chk = (~chk) & BYTEMASK; + fprintf(fileref, "%02X\n", chk); + addr = end; + } + fprintf(fileref,"S9\n"); //EOF record + } else { //binary + while (addr <= end) { + i = CPU_BD_get_mbyte(addr); + putc(i, fileref); + addr++; cnt++; + } + } + printf ("%d Bytes dumped from %04X\n", cnt, addr0); + } + return SCPE_OK; } /* Symbolic output @@ -1963,9 +2100,9 @@ t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) status = error code for M6800 */ -t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) +t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) { - int32 i, inst, inst1; + int i, inst, inst1; if (sw & SWMASK ('D')) { // dump memory for (i=0; i<16; i++) @@ -2018,14 +2155,94 @@ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) status = error status */ -t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) +t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) { - return (-2); + return (1); } -t_stat m6800_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches) +/* Set history */ + +t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { - return SCPE_OK; + int i, lnt; + t_stat r; + + if (cptr == NULL) { + for (i = 0; i < hst_lnt; i++) + hst[i].pc = 0; + hst_p = 0; + return SCPE_OK; + } + lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r); + if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) + return SCPE_ARG; + hst_p = 0; + if (hst_lnt) { + free (hst); + hst_lnt = 0; + hst = NULL; + } + if (lnt) { + hst = (InstHistory *) calloc (lnt, sizeof (InstHistory)); + if (hst == NULL) + return SCPE_MEM; + hst_lnt = lnt; + } + return SCPE_OK; +} + +/* Show history */ + +t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + int k, di, lnt, ir; + const char *cptr = (const char *) desc; + t_stat r; + InstHistory *h; + + if (hst_lnt == 0) /* enabled? */ + return SCPE_NOFNC; + if (cptr) { + lnt = (int32) get_uint (cptr, 10, hst_lnt, &r); + if ((r != SCPE_OK) || (lnt == 0)) + return SCPE_ARG; + } + else lnt = hst_lnt; + di = hst_p - lnt; /* work forward */ + if (di < 0) + di = di + hst_lnt; + fprintf (st, "PC SP CC A B IX Instruction\n\n"); + for (k = 0; k < lnt; k++) { /* print specified */ + h = &hst[(di++) % hst_lnt]; /* entry pointer */ + ir = h->inst[0]; + fprintf (st, "%04X %04X %02X ", h->pc , h->sp, h->cc); + fprintf (st, "%02X %02X %04X ", h->a, h->b, h->ix); + if ((fprint_sym (st, h->pc, h->inst, &m6800_unit, SWMASK ('M'))) > 0) + fprintf (st, "(undefined) %02X", h->inst[0]); + fputc ('\n', st); /* end line */ + } + return SCPE_OK; +} + +/* Memory examine */ + +t_stat m6800_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) +{ + if (addr >= MAXMEMSIZE) + return SCPE_NXM; + if (vptr != NULL) + *vptr = CPU_BD_get_mbyte(addr); + return SCPE_OK; +} + +/* Memory deposit */ + +t_stat m6800_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw) +{ + if (addr >= MAXMEMSIZE) + return SCPE_NXM; + CPU_BD_put_mbyte(addr, val); + return SCPE_OK; } /* end of m6800.c */ diff --git a/swtp6800/common/m6810.c b/swtp6800/common/m6810.c index cb50a3cc..a1af1c9b 100644 --- a/swtp6800/common/m6810.c +++ b/swtp6800/common/m6810.c @@ -25,8 +25,6 @@ MODIFICATIONS: - 24 Apr 15 -- Modified to use simh_debug - NOTES: These functions support a simulated m6810 RAM device on a CPU board. The @@ -43,13 +41,12 @@ t_stat m6810_reset (DEVICE *dptr); int32 m6810_get_mbyte(int32 offset); void m6810_put_mbyte(int32 offset, int32 val); -t_stat m6810_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches); -t_stat m6810_deposit(t_value value, t_addr addr, UNIT *uptr, int32 switches); /* SIMH RAM Standard I/O Data Structures */ -UNIT m6810_unit = { UDATA (NULL, UNIT_BINK, 128), - 0 }; +UNIT m6810_unit = { + UDATA (NULL, UNIT_BINK, 128), + 0 }; MTAB m6810_mod[] = { { 0 } @@ -74,8 +71,8 @@ DEVICE m6810_dev = { 1, //aincr 16, //dradix 8, //dwidth - &m6810_examine, //examine - &m6810_deposit, //deposit + NULL, //examine + NULL, //deposit &m6810_reset, //reset NULL, //boot NULL, //attach @@ -94,16 +91,14 @@ DEVICE m6810_dev = { t_stat m6810_reset (DEVICE *dptr) { - sim_debug (DEBUG_flow, &m6810_dev, "m6810_reset: \n"); if (m6810_unit.filebuf == NULL) { - m6810_unit.filebuf = malloc(128); + m6810_unit.filebuf = calloc(128, sizeof(uint8)); if (m6810_unit.filebuf == NULL) { - printf("m6810_reset: Malloc error\n"); + printf("m6810_reset: Calloc error\n"); return SCPE_MEM; } m6810_unit.capac = 128; } - sim_debug (DEBUG_flow, &m6810_dev, "m6810_reset: Done\n"); return SCPE_OK; } @@ -117,13 +112,10 @@ int32 m6810_get_mbyte(int32 offset) { int32 val; - sim_debug (DEBUG_read, &m6810_dev, "m6810_get_mbyte: offset=%04X\n", offset); if (((t_addr)offset) < m6810_unit.capac) { val = *((uint8 *)(m6810_unit.filebuf) + offset) & 0xFF; - sim_debug (DEBUG_read, &m6810_dev, "val=%04X\n", val); return val; } else { - sim_debug (DEBUG_read, &m6810_dev, "m6810_get_mbyte: out of range\n"); return 0xFF; } } @@ -132,30 +124,12 @@ int32 m6810_get_mbyte(int32 offset) void m6810_put_mbyte(int32 offset, int32 val) { - sim_debug (DEBUG_write, &m6810_dev, "m6810_put_mbyte: offset=%04X, val=%02X\n", - offset, val); if ((t_addr)offset < m6810_unit.capac) { *((uint8 *)(m6810_unit.filebuf) + offset) = val & 0xFF; return; - } else { - sim_debug (DEBUG_write, &m6810_dev, "m6810_put_mbyte: out of range\n"); - return; } + return; } /* end of m6810.c */ -t_stat m6810_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches) -{ - int32 i; - - for (i=0; i #include "swtp_defs.h" -#define MP_8M_NUM 6 /* number of MP-*m boards */ +#define MP_8M_NUM 6 /* number of MP-8M boards */ /* prototypes */ @@ -105,11 +103,8 @@ t_stat mp_8m_reset (DEVICE *dptr) int32 i; UNIT *uptr; - sim_debug (DEBUG_flow, &mp_8m_dev, "mp_8m_reset: \n"); for (i = 0; i < MP_8M_NUM; i++) { /* init all units */ uptr = mp_8m_dev.units + i; - sim_debug (DEBUG_flow, &mp_8m_dev, "MP-8M %d unit.flags=%08X\n", - i, uptr->flags); uptr->capac = 0x2000; if (i < 4) uptr->u3 = 0x2000 * i; @@ -121,15 +116,8 @@ t_stat mp_8m_reset (DEVICE *dptr) printf("mp_8m_reset: Calloc error\n"); return SCPE_MEM; } -// for (j=0; j<8192; j++) { /* fill pattern for testing */ -// val = (0xA0 | i); -// *((uint8 *)(uptr->filebuf) + j) = val & 0xFF; -// } } - sim_debug (DEBUG_flow, &mp_8m_dev, "MP-8M %d initialized at [%04X-%04XH]\n", - i, uptr->u3, uptr->u3 + uptr->capac - 1); } - sim_debug (DEBUG_flow, &mp_8m_dev, "mp_8m_reset: Done\n"); return SCPE_OK; } @@ -145,19 +133,16 @@ int32 mp_8m_get_mbyte(int32 addr) int32 i; UNIT *uptr; - sim_debug (DEBUG_read, &mp_8m_dev, "mp_8m_get_mbyte: addr=%04X", addr); for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */ uptr = mp_8m_dev.units + i; org = uptr->u3; len = uptr->capac - 1; if ((addr >= org) && (addr <= org + len)) { val = *((uint8 *)(uptr->filebuf) + (addr - org)); - sim_debug (DEBUG_read, &mp_8m_dev, " val=%04X\n", val); - return (val & 0xFF); + return (val & BYTEMASK); } } - sim_debug (DEBUG_read, &mp_8m_dev, "mp_8m_get_mbyte: Out of range\n"); - return 0xFF; /* multibus has active high pullups */ + return 0xFF; } /* get a word from memory */ @@ -179,19 +164,15 @@ void mp_8m_put_mbyte(int32 addr, int32 val) int32 i; UNIT *uptr; - sim_debug (DEBUG_write, &mp_8m_dev, "mp_8m_put_mbyte: addr=%04X, val=%02X", - addr, val); for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */ uptr = mp_8m_dev.units + i; org = uptr->u3; len = uptr->capac - 1; if ((addr >= org) && (addr <= org + len)) { - *((uint8 *)(uptr->filebuf) + (addr - org)) = val & 0xFF; - sim_debug (DEBUG_write, &mp_8m_dev, "\n"); + *((uint8 *)(uptr->filebuf) + (addr - org)) = val & BYTEMASK; return; } } - sim_debug (DEBUG_write, &mp_8m_dev, "mp_8m_put_mbyte: Out of range\n"); } /* put a word into memory */ diff --git a/swtp6800/common/mp-a.c b/swtp6800/common/mp-a.c index 36a3678f..d9200259 100644 --- a/swtp6800/common/mp-a.c +++ b/swtp6800/common/mp-a.c @@ -55,12 +55,10 @@ int32 CPU_BD_get_mbyte(int32 addr); int32 CPU_BD_get_mword(int32 addr); void CPU_BD_put_mbyte(int32 addr, int32 val); void CPU_BD_put_mword(int32 addr, int32 val); -t_stat mpa_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches); -t_stat mpa_deposit(t_value value, t_addr addr, UNIT *uptr, int32 switches); /* external routines */ -/* MP-B2 bus routines */ +/* MP-B2 MB routines */ extern int32 MB_get_mbyte(int32 addr); extern int32 MB_get_mword(int32 addr); extern void MB_put_mbyte(int32 addr, int32 val); @@ -114,8 +112,8 @@ DEVICE CPU_BD_dev = { 1, //aincr 16, //dradix 8, //dwidth - mpa_examine, //examine - mpa_deposit, //deposit + NULL, //examine + NULL, //deposit NULL, //reset NULL, //boot NULL, //attach @@ -132,30 +130,27 @@ DEVICE CPU_BD_dev = { int32 CPU_BD_get_mbyte(int32 addr) { - int32 val; + int32 val = 0, EA = 0, EA1 = 0; sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: addr=%04X\n", addr); switch(addr & 0xF000) { case 0xA000: if (CPU_BD_unit.flags & UNIT_RAM) { - val = m6810_get_mbyte(addr - 0xA000) & 0xFF; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: m6810 val=%02X\n", val); + val = m6810_get_mbyte(addr - 0xA000) & BYTEMASK; } else { - val = MB_get_mbyte(addr) & 0xFF; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: m6810 val=%02X\n", val); + val = MB_get_mbyte(addr) & BYTEMASK; } break; case 0xE000: - val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: EPROM=%02X\n", val); + val = BOOTROM_get_mbyte(addr - 0xE000) & BYTEMASK; break; case 0xF000: - val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: EPROM=%02X\n", val); + EA1 = 0x10000 - BOOTROM_unit.capac; + EA = addr - EA1; + val = BOOTROM_get_mbyte(EA) & BYTEMASK; break; default: - val = MB_get_mbyte(addr) & 0xFF; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: mp_b2 val=%02X\n", val); + val = MB_get_mbyte(addr) & BYTEMASK; } return val; } @@ -166,11 +161,9 @@ int32 CPU_BD_get_mword(int32 addr) { int32 val; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mword: addr=%04X\n", addr); val = (CPU_BD_get_mbyte(addr) << 8); val |= CPU_BD_get_mbyte(addr+1); val &= 0xFFFF; - sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mword: val=%04X\n", val); return val; } @@ -178,8 +171,6 @@ int32 CPU_BD_get_mword(int32 addr) void CPU_BD_put_mbyte(int32 addr, int32 val) { - sim_debug (DEBUG_write, &CPU_BD_dev, "CPU_BD_put_mbyte: addr=%04X, val=%02X\n", - addr, val); switch(addr & 0xF000) { case 0xA000: if (CPU_BD_unit.flags & UNIT_RAM) @@ -196,25 +187,8 @@ void CPU_BD_put_mbyte(int32 addr, int32 val) void CPU_BD_put_mword(int32 addr, int32 val) { - sim_debug (DEBUG_write, &CPU_BD_dev, "CPU_BD_put_mword: addr=%04X, val=%04X\n", - addr, val); CPU_BD_put_mbyte(addr, val >> 8); CPU_BD_put_mbyte(addr+1, val); } -t_stat mpa_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches) -{ - int32 i; - - for (i=0; i> 8); CPU_BD_put_mbyte(addr+1, val); } -t_stat mpa2_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches) -{ - int32 i; - - for (i=0; i> 8); MB_put_mbyte(addr+1, val); } -t_stat mpb2_examine(t_value *eval_array, t_addr addr, UNIT *uptr, int32 switches) -{ - int32 i; - - for (i=0; i