25 Apr 15 mods for ISYS8010.

This commit is contained in:
Bill Beech 2015-04-25 12:12:35 -07:00 committed by Mark Pizzolato
parent 4179eeb19f
commit 8d9a379d05
50 changed files with 3329 additions and 5066 deletions

View file

@ -1,44 +0,0 @@
/* mds-800.cfg: Intel mds-800 simulator definitions
This file holds the configuration for the mds-800
boards I/O and Memory.
Copyright (c) 2015, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
16 Dec 12 - Original file
08 Apr 15 - Modified to be mds-800.cfg file to set base and size.
Changed tabs to spaces
*/
/* set the base I/O address for the iSBC 208 */
#define SBC208_BASE 0x40
/* configure interrupt request line */
#define SBC208_INT INT_1
/* set the base and size for the iSBC 064 */
#define SBC064_BASE 0x0000
#define SBC064_SIZE 0x10000

Binary file not shown.

View file

@ -1,81 +0,0 @@
/* system_80_10_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
08 Apr 15 - Modified to use mds-800.cfg file to set base and size.
Changed tabs to spaces
*/
#include "system_defs.h"
extern DEVICE i8080_dev;
extern REG i8080_reg[];
extern DEVICE i8251_dev;
extern DEVICE i8255_dev;
extern DEVICE EPROM_dev;
extern DEVICE RAM_dev;
extern DEVICE multibus_dev;
extern DEVICE isbc208_dev;
extern DEVICE isbc064_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
*/
char sim_name[] = "Intel MDS-800";
REG *sim_PC = &i8080_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&i8080_dev,
&EPROM_dev,
&RAM_dev,
&i8251_dev,
&i8255_dev,
&multibus_dev,
&isbc064_dev,
&isbc208_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory",
"XACK Error"
};

View file

@ -1,84 +0,0 @@
/* system_defs.h: Intel iSBC simulator definitions
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
08 Apr 15 - Modified to use mds-800.cfg file to set base and size.
Changed tabs to spaces
*/
#include <stdio.h>
#include <ctype.h>
#include "mds-800.cfg" /* Intel System 80/10 configuration */
#include "sim_defs.h" /* simulator defns */
/* multibus interrupt definitions */
#define INT_0 0x01
#define INT_1 0x02
#define INT_2 0x04
#define INT_3 0x08
#define INT_4 0x10
#define INT_5 0x20
#define INT_6 0x40
#define INT_7 0x80
/* CPU interrupts definitions */
#define INT_R 0x200
#define I75 0x40
#define I65 0x20
#define I55 0x10
/* Memory */
#define MAXMEMSIZE 0x10000 /* 8080 max memory size */
#define MEMSIZE (i8080_unit.capac) /* 8080 actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* 8080 address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_xack 0x0080
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4 /* Invalid Opcode */
#define STOP_IO 5 /* I/O error */
#define STOP_MEM 6 /* Memory error */
#define STOP_XACK 7 /* XACK error */

View file

@ -1,211 +0,0 @@
Altair 8800 Simulator
=====================
1. Background.
The MITS (Micro Instrumentation and Telemetry Systems) Altair 8800
was announced on the January 1975 cover of Popular Electronics, which
boasted you could buy and build this powerful computer kit for only $397.
The kit consisted at that time of only the parts to build a case, power
supply, card cage (18 slots), CPU card, and memory card with 256 *bytes* of
memory. Still, thousands were ordered within the first few months after the
announcement, starting the personal computer revolution as we know it today.
Many laugh at the small size of the that first kit, noting there
were no peripherals and the 256 byte memory size. But the computer was an
open system, and by 1977 MITS and many other small startups had added many
expansion cards to make the Altair quite a respectable little computer. The
"Altair Bus" that made this possible was soon called the S-100 Bus, later
adopted as an industry standard, and eventually became the IEE-696 Bus.
2. Hardware
We are simulating a fairly "loaded" Altair 8800 from about 1977,
with the following configuration:
device simulates
name(s)
CPU Altair 8800 with Intel 8080 CPU board, 62KB
of RAM, 2K of EPROM with start boot ROM.
2SIO MITS 88-2SIO Dual Serial Interface Board. Port 1
is assumed to be connected to a serial "glass
TTY" that is your terminal running the Simulator.
PTR Paper Tape Reader attached to port 2 of the
2SIO board.
PTP Paper Tape Punch attached to port 2 of the
2SIO board. This also doubles as a printer
port.
DSK MITS 88-DISK Floppy Disk controller with up
to eight drives.
2.1 CPU
We have 2 CPU options that were not present on the original
machine but are useful in the simulator. We also allow you to select
memory sizes, but be aware that some sample software requires the full
64K (i.e. CP/M) and the MITS Disk Basic and Altair DOS require about
a minimum of 24K.
SET CPU 8080 Simulates the 8080 CPU (normal)
SET CPU Z80 Simulates the later Z80 CPU [At the present time
this is not fully implemented and is not to be
trusted with real Z80 software]
SET CPU ITRAP Causes the simulator to halt if an invalid 8080
Opcode is detected.
SET CPU NOITRAP Does not stop on an invalid Opcode. This is
how the real 8080 works.
SET CPU 4K
SET CPU 8K
SET CPU 12K
SET CPU 16K
......
SET CPU 64K All these set various CPU memory configurations.
The 2K EPROM at the high end of memory is always
present and will always boot.
The BOOT EPROM card starts at address 177400. Jumping to this address
will always boot drive 0 of the floppy controller. If no valid bootable
software is present there the machine crashes. This is historically
accurate behavior.
The real 8080, on receiving a HLT (Halt) instruction, freezes the processor
and only an interrupt or CPU hardware reset will restore it. The simulator
is alot nicer, it will halt but send you back to the simulator command line.
CPU Registers include the following:
name size comments
PC 16 The Program Counter
A 8 The accumulator
BC 16 The BC register pair. Register B is the high
8 bits, C is the lower 8 bits
DE 16 The DE register pair. D is the top 8 bits, E is
the bottom.
HL 16 The HL register pair. H is top, L is bottom.
C 1 Carry flag.
Z 1 Zero Flag.
AC 1 Auxillary Carry flag.
P 1 Parity flag.
S 1 Sign flag.
SR 16 The front panel switches.
BREAK 16 Breakpoint address (377777 to disable).
WRU 8 The interrupt character. This starts as 005
(ctrl-E) but some Altair software uses this
keystroke so best to change this to something
exotic such as 035 (which is Ctl-]).
2.2 The Serial I/O Card (2SIO)
This simple programmed I/O device provides 2 serial ports to the
outside world, which could be hardware jumpered to support RS-232 plugs or a
TTY current loop interface. The standard I/O addresses assigned by MITS
was 20-21 (octal) for the first port, and 22-23 (octal) for the second.
We follow this standard in the Simulator.
The simulator directs I/O to/from the first port to the screen. The
second port reads from an attachable "tape reader" file on input, and writes
to an attachable "punch file" on output. These files are considered a
simple stream of 8-bit bytes.
2.3 The 88-DISK controller.
The MITS 88-DISK is a simple programmed I/O interface to the MITS
8-inch floppy drive, which was basically a Pertec FD-400 with a power
supply and buffer board builtin. The controller supports neither interrupts
nor DMA, so floppy access required the sustained attention of the CPU.
The standard I/O addresses were 10, 11, and 12 (octal), and we follow the
standard. Details on controlling this hardware are in the altair_dsk.c
source file.
3. Sample Software
Running an Altair in 1977 you would be running either MITS Disk
Extended BASIC, or the brand new and sexy CP/M Operating System from Digital
Research. Or possibly, you ordered Altair DOS back when it was promised in
1975, and are still waiting for it to be delivered in early 1977.
We have samples of all three for you to check out. We can't go into
the details of how they work, but we'll give you a few hints.
3.1 CP/M Version 2.2
This version is my own port of the standard CP/M to the Altair.
There were some "official" versions but I don't have them. None were
endorsed or sold by MITS to my knowledge, however.
To boot CP/M:
sim> attach dsk0 altcpm.dsk
sim> go 177400
62K CP/M VERSION 2.2 (ALTAIR 8800)
A>DIR
CP/M feels like DOS, sort of. DIR will work. I have included all
the standard CP/M utilities, plus a few common public-domain ones. I also
include the sources to the customized BIOS and some other small programs.
TYPE will print an ASCII file. DUMP will dump a binary one. LS is a better
DIR than DIR. ASM will assemble .ASM files to Hex, LOAD will "load" them to
binary format (.COM). ED is a simple editor, #A command will bring the
source file to the buffer, T command will "type" lines, L will move lines,
E exits the editor. 20L20T will move down 20 lines, and type 20. Very
DECish. DDT is the debugger, SUBMIT is a batch-type command processor.
A sample batch file that will assemble and write out the bootable CP/M
image (on drive A) is "SYSGEN.SUB". To run it, type "SUBMIT SYSGEN".
3.2 MITS Disk Extended BASIC Version 4.1
This was the commonly used software for serious users of the Altair
computer. It is a powerful (but slow) BASIC with some extended commands to
allow it to access and manage the disk. There was no operating system it
ran under. To boot:
sim> attach dsk0 mbasic.dsk
sim> go 177400
MEMORY SIZE? [return]
LINEPRINTER? C [return]
HIGHEST DISK NUMBER? 0 [return] (3 here = 4 drive system)
NUMBER OF FILES? 3 [return]
NUMBER OF RANDOM FILES? 2 [return]
44297 BYTES FREE
ALTAIR BASIC REV. 4.1
[DISK EXTENDED VERSION]
COPYRIGHT 1977 BY MITS INC.
OK
mount 0
OK
files
3.3 Altair DOS Version 1.0
This was long promised but not delivered until it was almost
irrelevant. A short attempted tour will reveal it to be a dog, far inferior
to CP/M. To boot:
sim> attach dsk0 altdos.dsk
sim> go 177400
MEMORY SIZE? 64 [return]
INTERRUPTS? N [return]
HIGHEST DISK NUMBER? 0 [return] (3 here = 4 drive system)
HOW MANY DISK FILES? 3 [return]
HOW MANY RANDOM FILES? 2 [return]
056769 BYTES AVAILABLE
DOS MONITOR VER 1.0
COPYRIGHT 1977 BY MITS INC
.mnt 0
.dir 0

View file

@ -1,252 +0,0 @@
/* i8251.c: Intel i8251 UART adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated i8251 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8251 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read from the data port gets the typed character, a write
to the data port writes the character to the device.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* function prototypes */
t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, int32 base);
int32 i8251s(int32 io, int32 data);
int32 i8251d(int32 io, int32 data);
void i8251_reset1(void);
/* i8251 Standard I/O Data Structures */
UNIT i8251_unit = {
UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT
};
REG i8251_reg[] = {
{ HRDATA (DATA, i8251_unit.buf, 8) },
{ HRDATA (STAT, i8251_unit.u3, 8) },
{ HRDATA (MODE, i8251_unit.u4, 8) },
{ HRDATA (CMD, i8251_unit.u5, 8) },
{ NULL }
};
MTAB i8251_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEVICE i8251_dev = {
"8251", //name
&i8251_unit, //units
i8251_reg, //registers
i8251_mod, //modifiers
1, //numunits
10, //aradix
31, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8251_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8251_svc - actually gets char & places in buffer */
t_stat i8251_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8251_unit, i8251_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8251_unit.buf = temp & 0xFF; /* Save char */
i8251_unit.u3 |= RXR; /* Set status */
/* Do any special character handling here */
i8251_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8251_reset (DEVICE *dptr, int32 base)
{
reg_dev(i8251d, base);
reg_dev(i8251s, base + 1);
reg_dev(i8251d, base + 2);
reg_dev(i8251s, base + 3);
i8251_reset1();
printf(" 8251: Registered at %02X\n", base);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 i8251s(int32 io, int32 data)
{
// printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */
return i8251_unit.u3;
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
printf("8251: Command Instruction=%02X\n", data);
if (data & SD) /* reset port! */
i8251_reset1();
} else { /* set mode */
i8251_unit.u4 = data;
printf("8251: Mode Instruction=%02X\n", data);
i8251_unit.u6 = 1; /* set cmd received */
}
return (0);
}
}
int32 i8251d(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
void i8251_reset1(void)
{
i8251_unit.u3 = TXR + TXE; /* status */
i8251_unit.u4 = 0; /* mode instruction */
i8251_unit.u5 = 0; /* command instruction */
i8251_unit.u6 = 0;
i8251_unit.buf = 0;
i8251_unit.pos = 0;
printf(" 8251: Reset\n");
}
/* end of i8251.c */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

5
build_billi.bat Normal file
View file

@ -0,0 +1,5 @@
@echo off
rem Build Intel Systems
call build_mingw.bat isys8010
pause

5
build_billm.bat Normal file
View file

@ -0,0 +1,5 @@
@echo off
rem Build swtp6800 systems
call build_mingw.bat swtp6800mp-a swtp6800mp-a2
pause

View file

@ -661,250 +661,250 @@ int32 sim_instr (void)
switch (IR) { switch (IR) {
/* 8085 instructions only */ /* 8085 instructions only */
case 0x20: /* RIM */ case 0x20: /* RIM */
if (i8080_unit.flags & UNIT_8085) { /* 8085 */ if (i8080_unit.flags & UNIT_8085) { /* 8085 */
A = IM; A = IM;
} else { /* 8080 */ } else { /* 8080 */
reason = STOP_OPCODE; reason = STOP_OPCODE;
PC--; PC--;
}
break;
case 0x30: /* SIM */
if (i8080_unit.flags & UNIT_8085) { /* 8085 */
if (A & MSE) {
IM &= 0xF8;
IM |= A & 0x07;
}
if (A & I75) { /* reset RST 7.5 FF */
}
} else { /* 8080 */
reason = STOP_OPCODE;
PC--;
}
break;
/* Logical instructions */
case 0xFE: /* CPI */
DAR = A;
DAR -= fetch_byte(1);
// DAR &= BYTE_R;
setarith(DAR);
break;
case 0xE6: /* ANI */
A &= fetch_byte(1);
setlogical(A);
break;
case 0xEE: /* XRI */
A ^= fetch_byte(1);
// DAR &= BYTE_R;
setlogical(A);
break;
case 0xF6: /* ORI */
A |= fetch_byte(1);
setlogical(A);
break;
/* Jump instructions */
case 0xC3: /* JMP */
PC = fetch_word();
break;
case 0xE9: /* PCHL */
PC = HL;
break;
case 0xCD: /* CALL */
adr = fetch_word();
push_word(PC);
PC = adr;
break;
case 0xC9: /* RET */
PC = pop_word();
break;
/* Data Transfer Group */
case 0x32: /* STA */
DAR = fetch_word();
DAR &= WORD_R;
put_mbyte(DAR, A);
break;
case 0x3A: /* LDA */
DAR = fetch_word();
DAR &= WORD_R;
A = get_mbyte(DAR);
break;
case 0x22: /* SHLD */
DAR = fetch_word();
DAR &= WORD_R;
put_mword(DAR, HL);
break;
case 0x2A: /* LHLD */
DAR = fetch_word();
DAR &= WORD_R;
HL = get_mword(DAR);
break;
case 0xEB: /* XCHG */
DAR = HL;
HL = DE;
HL &= WORD_R;
DE = DAR;
DE &= WORD_R;
break;
/* Arithmetic Group */
case 0xC6: /* ADI */
A += fetch_byte(1);
setarith(A);
A &= BYTE_R;
break;
case 0xCE: /* ACI */
A += fetch_byte(1);
if (GET_FLAG(CF))
A++;
setarith(A);
A &= BYTE_R;
break;
case 0xD6: /* SUI */
A -= fetch_byte(1);
setarith(A);
A &= BYTE_R;
break;
case 0xDE: /* SBI */
A -= fetch_byte(1);
if (GET_FLAG(CF))
A--;
setarith(A);
A &= BYTE_R;
break;
case 0x27: /* DAA */
DAR = A & 0x0F;
if (DAR > 9 || GET_FLAG(AF)) {
DAR += 6;
A &= 0xF0;
A |= DAR & 0x0F;
COND_SET_FLAG(DAR & 0x10, AF);
}
DAR = (A >> 4) & 0x0F;
if (DAR > 9 || GET_FLAG(AF)) {
DAR += 6;
if (GET_FLAG(AF)) DAR++;
A &= 0x0F;
A |= (DAR << 4);
}
COND_SET_FLAG(DAR & 0x10, CF);
COND_SET_FLAG(A & 0x80, SF);
COND_SET_FLAG((A & 0xFF) == 0, ZF);
parity(A);
break;
case 0x07: /* RLC */
COND_SET_FLAG(A & 0x80, CF);
A = (A << 1) & 0xFF;
if (GET_FLAG(CF))
A |= 0x01;
A &= BYTE_R;
break;
case 0x0F: /* RRC */
COND_SET_FLAG(A & 0x01, CF);
A = (A >> 1) & 0xFF;
if (GET_FLAG(CF))
A |= 0x80;
A &= BYTE_R;
break;
case 0x17: /* RAL */
DAR = GET_FLAG(CF);
COND_SET_FLAG(A & 0x80, CF);
A = (A << 1) & 0xFF;
if (DAR)
A |= 0x01;
A &= BYTE_R;
break;
case 0x1F: /* RAR */
DAR = GET_FLAG(CF);
COND_SET_FLAG(A & 0x01, CF);
A = (A >> 1) & 0xFF;
if (DAR)
A |= 0x80;
A &= BYTE_R;
break;
case 0x2F: /* CMA */
A = ~A;
A &= BYTE_R;
break;
case 0x3F: /* CMC */
TOGGLE_FLAG(CF);
break;
case 0x37: /* STC */
SET_FLAG(CF);
break;
/* Stack, I/O & Machine Control Group */
case 0x00: /* NOP */
break;
case 0xE3: /* XTHL */
DAR = pop_word();
push_word(HL);
HL = DAR;
HL &= WORD_R;
break;
case 0xF9: /* SPHL */
SP = HL;
break;
case 0xFB: /* EI */
IM |= IE;
// printf("\nEI: pc=%04X", PC - 1);
break;
case 0xF3: /* DI */
IM &= ~IE;
// printf("\nDI: pc=%04X", PC - 1);
break;
case 0xDB: /* IN */
DAR = fetch_byte(1);
A = dev_table[DAR].routine(0, 0);
A &= BYTE_R;
break;
case 0xD3: /* OUT */
DAR = fetch_byte(1);
dev_table[DAR].routine(1, A);
break;
default: /* undefined opcode */
if (i8080_unit.flags & UNIT_OPSTOP) {
reason = STOP_OPCODE;
PC--;
}
break;
} }
break;
case 0x30: /* SIM */
if (i8080_unit.flags & UNIT_8085) { /* 8085 */
if (A & MSE) {
IM &= 0xF8;
IM |= A & 0x07;
}
if (A & I75) { /* reset RST 7.5 FF */
}
} else { /* 8080 */
reason = STOP_OPCODE;
PC--;
}
break;
/* Logical instructions */
case 0xFE: /* CPI */
DAR = A;
DAR -= fetch_byte(1);
// DAR &= BYTE_R;
setarith(DAR);
break;
case 0xE6: /* ANI */
A &= fetch_byte(1);
setlogical(A);
break;
case 0xEE: /* XRI */
A ^= fetch_byte(1);
// DAR &= BYTE_R;
setlogical(A);
break;
case 0xF6: /* ORI */
A |= fetch_byte(1);
setlogical(A);
break;
/* Jump instructions */
case 0xC3: /* JMP */
PC = fetch_word();
break;
case 0xE9: /* PCHL */
PC = HL;
break;
case 0xCD: /* CALL */
adr = fetch_word();
push_word(PC);
PC = adr;
break;
case 0xC9: /* RET */
PC = pop_word();
break;
/* Data Transfer Group */
case 0x32: /* STA */
DAR = fetch_word();
DAR &= WORD_R;
put_mbyte(DAR, A);
break;
case 0x3A: /* LDA */
DAR = fetch_word();
DAR &= WORD_R;
A = get_mbyte(DAR);
break;
case 0x22: /* SHLD */
DAR = fetch_word();
DAR &= WORD_R;
put_mword(DAR, HL);
break;
case 0x2A: /* LHLD */
DAR = fetch_word();
DAR &= WORD_R;
HL = get_mword(DAR);
break;
case 0xEB: /* XCHG */
DAR = HL;
HL = DE;
HL &= WORD_R;
DE = DAR;
DE &= WORD_R;
break;
/* Arithmetic Group */
case 0xC6: /* ADI */
A += fetch_byte(1);
setarith(A);
A &= BYTE_R;
break;
case 0xCE: /* ACI */
A += fetch_byte(1);
if (GET_FLAG(CF))
A++;
setarith(A);
A &= BYTE_R;
break;
case 0xD6: /* SUI */
A -= fetch_byte(1);
setarith(A);
A &= BYTE_R;
break;
case 0xDE: /* SBI */
A -= fetch_byte(1);
if (GET_FLAG(CF))
A--;
setarith(A);
A &= BYTE_R;
break;
case 0x27: /* DAA */
DAR = A & 0x0F;
if (DAR > 9 || GET_FLAG(AF)) {
DAR += 6;
A &= 0xF0;
A |= DAR & 0x0F;
COND_SET_FLAG(DAR & 0x10, AF);
}
DAR = (A >> 4) & 0x0F;
if (DAR > 9 || GET_FLAG(AF)) {
DAR += 6;
if (GET_FLAG(AF)) DAR++;
A &= 0x0F;
A |= (DAR << 4);
}
COND_SET_FLAG(DAR & 0x10, CF);
COND_SET_FLAG(A & 0x80, SF);
COND_SET_FLAG((A & 0xFF) == 0, ZF);
parity(A);
break;
case 0x07: /* RLC */
COND_SET_FLAG(A & 0x80, CF);
A = (A << 1) & 0xFF;
if (GET_FLAG(CF))
A |= 0x01;
A &= BYTE_R;
break;
case 0x0F: /* RRC */
COND_SET_FLAG(A & 0x01, CF);
A = (A >> 1) & 0xFF;
if (GET_FLAG(CF))
A |= 0x80;
A &= BYTE_R;
break;
case 0x17: /* RAL */
DAR = GET_FLAG(CF);
COND_SET_FLAG(A & 0x80, CF);
A = (A << 1) & 0xFF;
if (DAR)
A |= 0x01;
A &= BYTE_R;
break;
case 0x1F: /* RAR */
DAR = GET_FLAG(CF);
COND_SET_FLAG(A & 0x01, CF);
A = (A >> 1) & 0xFF;
if (DAR)
A |= 0x80;
A &= BYTE_R;
break;
case 0x2F: /* CMA */
A = ~A;
A &= BYTE_R;
break;
case 0x3F: /* CMC */
TOGGLE_FLAG(CF);
break;
case 0x37: /* STC */
SET_FLAG(CF);
break;
/* Stack, I/O & Machine Control Group */
case 0x00: /* NOP */
break;
case 0xE3: /* XTHL */
DAR = pop_word();
push_word(HL);
HL = DAR;
HL &= WORD_R;
break;
case 0xF9: /* SPHL */
SP = HL;
break;
case 0xFB: /* EI */
IM |= IE;
// printf("\nEI: pc=%04X", PC - 1);
break;
case 0xF3: /* DI */
IM &= ~IE;
// printf("\nDI: pc=%04X", PC - 1);
break;
case 0xDB: /* IN */
DAR = fetch_byte(1);
A = dev_table[DAR].routine(0, 0);
A &= BYTE_R;
break;
case 0xD3: /* OUT */
DAR = fetch_byte(1);
dev_table[DAR].routine(1, A);
break;
default: /* undefined opcode */
if (i8080_unit.flags & UNIT_OPSTOP) {
reason = STOP_OPCODE;
PC--;
}
break;
}
loop_end: loop_end:
if (GET_XACK(1) == 0) { /* no XACK for instruction fetch */ if (GET_XACK(1) == 0) { /* no XACK for instruction fetch */
reason = STOP_XACK; reason = STOP_XACK;
@ -941,12 +941,12 @@ int32 fetch_byte(int32 flag)
val = get_mbyte(PC) & 0xFF; /* fetch byte */ val = get_mbyte(PC) & 0xFF; /* fetch byte */
if (i8080_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE) { /* display source code */ if (i8080_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE) { /* display source code */
switch (flag) { switch (flag) {
case 0: /* opcode fetch */ case 0: /* opcode fetch */
printf("OP=%02X %04X %s", val, PC, opcode[val]); printf("OP=%02X %04X %s", val, PC, opcode[val]);
break; break;
case 1: /* byte operand fetch */ case 1: /* byte operand fetch */
printf("0%02XH", val); printf("0%02XH", val);
break; break;
} }
} }
PC = (PC + 1) & ADDRMASK; /* increment PC */ PC = (PC + 1) & ADDRMASK; /* increment PC */
@ -993,32 +993,32 @@ uint16 pop_word(void)
int32 cond(int32 con) int32 cond(int32 con)
{ {
switch (con) { switch (con) {
case 0: /* NZ */ case 0: /* NZ */
if (GET_FLAG(ZF) == 0) return 1; if (GET_FLAG(ZF) == 0) return 1;
break; break;
case 1: /* Z */ case 1: /* Z */
if (GET_FLAG(ZF)) return 1; if (GET_FLAG(ZF)) return 1;
break; break;
case 2: /* NC */ case 2: /* NC */
if (GET_FLAG(CF) == 0) return 1; if (GET_FLAG(CF) == 0) return 1;
break; break;
case 3: /* C */ case 3: /* C */
if (GET_FLAG(CF)) return 1; if (GET_FLAG(CF)) return 1;
break; break;
case 4: /* PO */ case 4: /* PO */
if (GET_FLAG(PF) == 0) return 1; if (GET_FLAG(PF) == 0) return 1;
break; break;
case 5: /* PE */ case 5: /* PE */
if (GET_FLAG(PF)) return 1; if (GET_FLAG(PF)) return 1;
break; break;
case 6: /* P */ case 6: /* P */
if (GET_FLAG(SF) == 0) return 1; if (GET_FLAG(SF) == 0) return 1;
break; break;
case 7: /* M */ case 7: /* M */
if (GET_FLAG(SF)) return 1; if (GET_FLAG(SF)) return 1;
break; break;
default: default:
break; break;
} }
return 0; return 0;
} }
@ -1086,26 +1086,26 @@ void setinc(int32 reg)
int32 getreg(int32 reg) int32 getreg(int32 reg)
{ {
switch (reg) { switch (reg) {
case 0: /* reg B */ case 0: /* reg B */
// printf("reg=%04X BC=%04X ret=%04X\n", // printf("reg=%04X BC=%04X ret=%04X\n",
// reg, BC, (BC >>8) & 0xff); // reg, BC, (BC >>8) & 0xff);
return ((BC >>8) & BYTE_R); return ((BC >>8) & BYTE_R);
case 1: /* reg C */ case 1: /* reg C */
return (BC & BYTE_R); return (BC & BYTE_R);
case 2: /* reg D */ case 2: /* reg D */
return ((DE >>8) & BYTE_R); return ((DE >>8) & BYTE_R);
case 3: /* reg E */ case 3: /* reg E */
return (DE & BYTE_R); return (DE & BYTE_R);
case 4: /* reg H */ case 4: /* reg H */
return ((HL >>8) & BYTE_R); return ((HL >>8) & BYTE_R);
case 5: /* reg L */ case 5: /* reg L */
return (HL & BYTE_R); return (HL & BYTE_R);
case 6: /* reg M */ case 6: /* reg M */
return (get_mbyte(HL)); return (get_mbyte(HL));
case 7: /* reg A */ case 7: /* reg A */
return (A); return (A);
default: default:
break; break;
} }
return 0; return 0;
} }
@ -1114,39 +1114,39 @@ int32 getreg(int32 reg)
void putreg(int32 reg, int32 val) void putreg(int32 reg, int32 val)
{ {
switch (reg) { switch (reg) {
case 0: /* reg B */ case 0: /* reg B */
// printf("reg=%04X val=%04X\n", reg, val); // printf("reg=%04X val=%04X\n", reg, val);
BC = BC & BYTE_R; BC = BC & BYTE_R;
// printf("BC&0x00ff=%04X val<<8=%04X\n", BC, val<<8); // printf("BC&0x00ff=%04X val<<8=%04X\n", BC, val<<8);
BC = BC | (val <<8); BC = BC | (val <<8);
break; break;
case 1: /* reg C */ case 1: /* reg C */
BC = BC & 0xFF00; BC = BC & 0xFF00;
BC = BC | val; BC = BC | val;
break; break;
case 2: /* reg D */ case 2: /* reg D */
DE = DE & BYTE_R; DE = DE & BYTE_R;
DE = DE | (val <<8); DE = DE | (val <<8);
break; break;
case 3: /* reg E */ case 3: /* reg E */
DE = DE & 0xFF00; DE = DE & 0xFF00;
DE = DE | val; DE = DE | val;
break; break;
case 4: /* reg H */ case 4: /* reg H */
HL = HL & BYTE_R; HL = HL & BYTE_R;
HL = HL | (val <<8); HL = HL | (val <<8);
break; break;
case 5: /* reg L */ case 5: /* reg L */
HL = HL & 0xFF00; HL = HL & 0xFF00;
HL = HL | val; HL = HL | val;
break; break;
case 6: /* reg M */ case 6: /* reg M */
put_mbyte(HL, val); put_mbyte(HL, val);
break; break;
case 7: /* reg A */ case 7: /* reg A */
A = val & BYTE_R; A = val & BYTE_R;
default: default:
break; break;
} }
} }
@ -1154,16 +1154,16 @@ void putreg(int32 reg, int32 val)
int32 getpair(int32 reg) int32 getpair(int32 reg)
{ {
switch (reg) { switch (reg) {
case 0: /* reg BC */ case 0: /* reg BC */
return (BC); return (BC);
case 1: /* reg DE */ case 1: /* reg DE */
return (DE); return (DE);
case 2: /* reg HL */ case 2: /* reg HL */
return (HL); return (HL);
case 3: /* reg SP */ case 3: /* reg SP */
return (SP); return (SP);
default: default:
break; break;
} }
return 0; return 0;
} }
@ -1175,17 +1175,17 @@ int32 getpush(int32 reg)
int32 stat; int32 stat;
switch (reg) { switch (reg) {
case 0: /* reg BC */ case 0: /* reg BC */
return (BC); return (BC);
case 1: /* reg DE */ case 1: /* reg DE */
return (DE); return (DE);
case 2: /* reg HL */ case 2: /* reg HL */
return (HL); return (HL);
case 3: /* reg (A << 8) | PSW */ case 3: /* reg (A << 8) | PSW */
stat = A << 8 | PSW; stat = A << 8 | PSW;
return (stat); return (stat);
default: default:
break; break;
} }
return 0; return 0;
} }
@ -1196,21 +1196,21 @@ int32 getpush(int32 reg)
void putpush(int32 reg, int32 data) void putpush(int32 reg, int32 data)
{ {
switch (reg) { switch (reg) {
case 0: /* reg BC */ case 0: /* reg BC */
BC = data; BC = data;
break; break;
case 1: /* reg DE */ case 1: /* reg DE */
DE = data; DE = data;
break; break;
case 2: /* reg HL */ case 2: /* reg HL */
HL = data; HL = data;
break; break;
case 3: /* reg (A << 8) | PSW */ case 3: /* reg (A << 8) | PSW */
A = (data >> 8) & BYTE_R; A = (data >> 8) & BYTE_R;
PSW = data & BYTE_R; PSW = data & BYTE_R;
break; break;
default: default:
break; break;
} }
} }
@ -1219,20 +1219,20 @@ void putpush(int32 reg, int32 data)
void putpair(int32 reg, int32 val) void putpair(int32 reg, int32 val)
{ {
switch (reg) { switch (reg) {
case 0: /* reg BC */ case 0: /* reg BC */
BC = val; BC = val;
break; break;
case 1: /* reg DE */ case 1: /* reg DE */
DE = val; DE = val;
break; break;
case 2: /* reg HL */ case 2: /* reg HL */
HL = val; HL = val;
break; break;
case 3: /* reg SP */ case 3: /* reg SP */
SP = val; SP = val;
break; break;
default: default:
break; break;
} }
} }

257
isys8010/common/i8251.c Normal file
View file

@ -0,0 +1,257 @@
/* i8251.c: Intel i8251 UART adapter
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8251 interface device on an iSBC.
The device had one physical I/O port which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
selectable for each port from 110 to 9600.
All I/O is via programmed I/O. The i8251 has a status port
and a data port.
The simulated device does not support synchronous mode. The simulated device
supports a select from I/O space and one address line. The data port is at the
lower address and the status/command port is at the higher.
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| S2 S1 EP PEN L2 L1 B2 B1|
+---+---+---+---+---+---+---+---+
Baud Rate Factor
B2 0 1 0 1
B1 0 0 1 1
sync 1X 16X 64X
mode
Character Length
L2 0 1 0 1
L1 0 0 1 1
5 6 7 8
bits bits bits bits
EP - A 1 in this bit position selects even parity.
PEN - A 1 in this bit position enables parity.
Number of Stop Bits
S2 0 1 0 1
S1 0 0 1 1
invalid 1 1.5 2
bit bits bits
Command Instruction Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| EH IR RTS ER SBRK RxE DTR TxE|
+---+---+---+---+---+---+---+---+
TxE - A 1 in this bit position enables transmit.
DTR - A 1 in this bit position forces *DTR to zero.
RxE - A 1 in this bit position enables receive.
SBRK - A 1 in this bit position forces TxD to zero.
ER - A 1 in this bit position resets the error bits
RTS - A 1 in this bit position forces *RTS to zero.
IR - A 1 in this bit position returns the 8251 to Mode Instruction Format.
EH - A 1 in this bit position enables search for sync characters.
A read of the status port gets the port status:
Status Read Format
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|DSR SD FE OE PE TxE RxR TxR|
+---+---+---+---+---+---+---+---+
TxR - A 1 in this bit position signals transmit ready to receive a character.
RxR - A 1 in this bit position signals receiver has a character.
TxE - A 1 in this bit position signals transmitter has no more characters to transmit.
PE - A 1 in this bit signals a parity error.
OE - A 1 in this bit signals an transmit overrun error.
FE - A 1 in this bit signals a framing error.
SD - A 1 in this bit position returns the 8251 to Mode Instruction Format.
DSR - A 1 in this bit position signals *DSR is at zero.
A read from the data port gets the typed character, a write
to the data port writes the character to the device.
*/
#include "system_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define TXR 0x01
#define RXR 0x02
#define TXE 0x04
#define SD 0x40
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* function prototypes */
t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, int32 base);
int32 i8251s(int32 io, int32 data);
int32 i8251d(int32 io, int32 data);
void i8251_reset1(void);
/* i8251 Standard I/O Data Structures */
UNIT i8251_unit = {
UDATA (&i8251_svc, 0, 0), KBD_POLL_WAIT
};
REG i8251_reg[] = {
{ HRDATA (DATA, i8251_unit.buf, 8) },
{ HRDATA (STAT, i8251_unit.u3, 8) },
{ HRDATA (MODE, i8251_unit.u4, 8) },
{ HRDATA (CMD, i8251_unit.u5, 8) },
{ NULL }
};
MTAB i8251_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEVICE i8251_dev = {
"8251", //name
&i8251_unit, //units
i8251_reg, //registers
i8251_mod, //modifiers
1, //numunits
10, //aradix
31, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8251_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* i8251_svc - actually gets char & places in buffer */
t_stat i8251_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8251_unit, i8251_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8251_unit.buf = temp & 0xFF; /* Save char */
i8251_unit.u3 |= RXR; /* Set status */
/* Do any special character handling here */
i8251_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8251_reset (DEVICE *dptr, int32 base)
{
reg_dev(i8251d, base);
reg_dev(i8251s, base + 1);
reg_dev(i8251d, base + 2);
reg_dev(i8251s, base + 3);
i8251_reset1();
printf(" 8251: Registered at %02X\n", base);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 i8251s(int32 io, int32 data)
{
// printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */
return i8251_unit.u3;
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
printf("8251: Command Instruction=%02X\n", data);
if (data & SD) /* reset port! */
i8251_reset1();
} else { /* set mode */
i8251_unit.u4 = data;
printf("8251: Mode Instruction=%02X\n", data);
i8251_unit.u6 = 1; /* set cmd received */
}
return (0);
}
}
int32 i8251d(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
void i8251_reset1(void)
{
i8251_unit.u3 = TXR + TXE; /* status */
i8251_unit.u4 = 0; /* mode instruction */
i8251_unit.u5 = 0; /* command instruction */
i8251_unit.u6 = 0;
i8251_unit.buf = 0;
i8251_unit.pos = 0;
printf(" 8251: Reset\n");
}
/* end of i8251.c */

View file

@ -2,75 +2,81 @@
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated i8255 interface device on an iSBC. MODIFICATIONS:
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
All I/O is via programmed I/O. The i8255 has a control port (PIOS) ?? ??? 10 - Original file.
and three data ports (PIOA, PIOB, and PIOC). 16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
The simulated device supports a select from I/O space and two address lines. NOTES:
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device: These functions support a simulated i8255 interface device on an iSBC.
The device has threee physical 8-bit I/O ports which could be connected
to any parallel I/O device.
Control Word All I/O is via programmed I/O. The i8255 has a control port (PIOS)
+---+---+---+---+---+---+---+---+ and three data ports (PIOA, PIOB, and PIOC).
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B The simulated device supports a select from I/O space and two address lines.
D0 Port C (lower) 1-Input, 0-Output The data ports are at the lower addresses and the control port is at
D1 Port B 1-Input, 0-Output the highest.
D2 Mode Selection 0-Mode 0, 1-Mode 1
Group A A write to the control port can configure the device:
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
D7 Mode Set Flag 1=Active, 0=Bit Set Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Mode 0 - Basic Input/Output Group B
Mode 1 - Strobed Input/Output D0 Port C (lower) 1-Input, 0-Output
Mode 2 - Bidirectional Bus D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset Group A
D3 Port C (upper) 1-Input, 0-Output
D4 Port A 1-Input, 0-Output
D5-6 Mode Selection 00-Mode 0, 01-Mode 1, 1X-Mode 2
A read to the data ports gets the current port value, a write D7 Mode Set Flag 1=Active, 0=Bit Set
to the data ports writes the character to the device.
*** Need to modify so that multiple devices can be registered and Mode 0 - Basic Input/Output
used. Mode 1 - Strobed Input/Output
Mode 2 - Bidirectional Bus
Bit Set - D7=0, D3:1 select port C bit, D0 1=set, 0=reset
A read to the data ports gets the current port value, a write
to the data ports writes the character to the device.
*** Need to modify so that multiple devices can be registered and
used.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/ */
#include "system_defs.h" /* system header in system dir */ #include "system_defs.h" /* system header in system dir */
#define i8255_DEV 4 /* number of devices */ #define i8255_DEV 4 /* number of devices */
/* function prototypes */ /* function prototypes */
@ -403,56 +409,56 @@ int32 i8255c3(int32 io, int32 data)
t_stat i8255_reset (DEVICE *dptr, int32 base) t_stat i8255_reset (DEVICE *dptr, int32 base)
{ {
switch (i8255_cnt) { switch (i8255_cnt) {
case 0: case 0:
reg_dev(i8255a0, base); reg_dev(i8255a0, base);
reg_dev(i8255b0, base + 1); reg_dev(i8255b0, base + 1);
reg_dev(i8255c0, base + 2); reg_dev(i8255c0, base + 2);
reg_dev(i8255s0, base + 3); reg_dev(i8255s0, base + 3);
i8255_unit[0].u3 = 0x9B; /* control */ i8255_unit[0].u3 = 0x9B; /* control */
i8255_unit[0].u4 = 0xFF; /* Port A */ i8255_unit[0].u4 = 0xFF; /* Port A */
i8255_unit[0].u5 = 0xFF; /* Port B */ i8255_unit[0].u5 = 0xFF; /* Port B */
i8255_unit[0].u6 = 0xFF; /* Port C */ i8255_unit[0].u6 = 0xFF; /* Port C */
printf(" 8255-0: Reset\n"); printf(" 8255-0: Reset\n");
break; break;
case 1: case 1:
reg_dev(i8255a1, base); reg_dev(i8255a1, base);
reg_dev(i8255b1, base + 1); reg_dev(i8255b1, base + 1);
reg_dev(i8255c1, base + 2); reg_dev(i8255c1, base + 2);
reg_dev(i8255s1, base + 3); reg_dev(i8255s1, base + 3);
i8255_unit[1].u3 = 0x9B; /* control */ i8255_unit[1].u3 = 0x9B; /* control */
i8255_unit[1].u4 = 0xFF; /* Port A */ i8255_unit[1].u4 = 0xFF; /* Port A */
i8255_unit[1].u5 = 0xFF; /* Port B */ i8255_unit[1].u5 = 0xFF; /* Port B */
i8255_unit[1].u6 = 0xFF; /* Port C */ i8255_unit[1].u6 = 0xFF; /* Port C */
printf(" 8255-1: Reset\n"); printf(" 8255-1: Reset\n");
break; break;
case 2: case 2:
reg_dev(i8255a2, base); reg_dev(i8255a2, base);
reg_dev(i8255b2, base + 1); reg_dev(i8255b2, base + 1);
reg_dev(i8255c2, base + 2); reg_dev(i8255c2, base + 2);
reg_dev(i8255s2, base + 3); reg_dev(i8255s2, base + 3);
i8255_unit[2].u3 = 0x9B; /* control */ i8255_unit[2].u3 = 0x9B; /* control */
i8255_unit[2].u4 = 0xFF; /* Port A */ i8255_unit[2].u4 = 0xFF; /* Port A */
i8255_unit[2].u5 = 0xFF; /* Port B */ i8255_unit[2].u5 = 0xFF; /* Port B */
i8255_unit[2].u6 = 0xFF; /* Port C */ i8255_unit[2].u6 = 0xFF; /* Port C */
printf(" 8255-2: Reset\n"); printf(" 8255-2: Reset\n");
break; break;
case 3: case 3:
reg_dev(i8255a3, base); reg_dev(i8255a3, base);
reg_dev(i8255b3, base + 1); reg_dev(i8255b3, base + 1);
reg_dev(i8255c3, base + 2); reg_dev(i8255c3, base + 2);
reg_dev(i8255s3, base + 3); reg_dev(i8255s3, base + 3);
i8255_unit[3].u3 = 0x9B; /* control */ i8255_unit[3].u3 = 0x9B; /* control */
i8255_unit[3].u4 = 0xFF; /* Port A */ i8255_unit[3].u4 = 0xFF; /* Port A */
i8255_unit[3].u5 = 0xFF; /* Port B */ i8255_unit[3].u5 = 0xFF; /* Port B */
i8255_unit[3].u6 = 0xFF; /* Port C */ i8255_unit[3].u6 = 0xFF; /* Port C */
printf(" 8255-3: Reset\n"); printf(" 8255-3: Reset\n");
break; break;
default: default:
printf(" 8255: Bad device\n"); printf(" 8255: Bad device\n");
} }
printf(" 8255-%d: Registered at %02X\n", i8255_cnt, base); printf(" 8255-%d: Registered at %02X\n", i8255_cnt, base);
i8255_cnt++; i8255_cnt++;
return SCPE_OK; return SCPE_OK;
} }

148
isys8010/common/iSBC80-10.c Normal file
View file

@ -0,0 +1,148 @@
/* iSBC80-10.c: Intel iSBC 80/10 Processor simulator
Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
?? ??? 10 - Original file.
24 Apr 15 -- Modified to use simh_debug
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
*/
#include "system_defs.h"
/* set the base I/O address for the first 8255 */
#define I8255_BASE_0 0xE4
/* set the base I/O address for the second 8255 */
#define I8255_BASE_1 0xE8
/* set the base I/O address for the 8251 */
#define I8251_BASE 0xEC
/* set the base and size for the EPROM on the iSBC 80/10 */
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/10 */
#define RAM_BASE 0x3C00
#define RAM_SIZE 0x0400
/* set INTR for CPU */
#define INTR INT_1
/* function prototypes */
int32 get_mbyte(int32 addr);
int32 get_mword(int32 addr);
void put_mbyte(int32 addr, int32 val);
void put_mword(int32 addr, int32 val);
t_stat SBC_reset (DEVICE *dptr);
/* external function prototypes */
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern int32 multibus_get_mbyte(int32 addr);
extern void multibus_put_mbyte(int32 addr, int32 val);
extern int32 EPROM_get_mbyte(int32 addr);
extern int32 RAM_get_mbyte(int32 addr);
extern void RAM_put_mbyte(int32 addr, int32 val);
extern UNIT i8255_unit;
extern UNIT EPROM_unit;
extern UNIT RAM_unit;
extern t_stat i8255_reset (DEVICE *dptr, int32 base);
extern t_stat i8251_reset (DEVICE *dptr, int32 base);
extern t_stat pata_reset (DEVICE *dptr, int32 base);
extern t_stat EPROM_reset (DEVICE *dptr, int32 size);
extern t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size);
/* SBC reset routine */
t_stat SBC_reset (DEVICE *dptr)
{
printf("Initializing iSBC-80/10:\n");
i8080_reset (NULL);
i8255_reset (NULL, I8255_BASE_0);
i8255_reset (NULL, I8255_BASE_1);
i8251_reset (NULL, I8251_BASE);
EPROM_reset (NULL, ROM_SIZE);
RAM_reset (NULL, RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM, I/O, and Multibus memory */
int32 get_mbyte(int32 addr)
{
int32 val, org, len;
/* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && (addr >= EPROM_unit.u3) && (addr < (EPROM_unit.u3 + EPROM_unit.capac))) {
return EPROM_get_mbyte(addr);
} /* if local RAM handle it */
if ((i8255_unit.u5 & 0x02) && (addr >= RAM_unit.u3) && (addr < (RAM_unit.u3 + RAM_unit.capac))) {
return RAM_get_mbyte(addr);
} /* otherwise, try the multibus */
return multibus_get_mbyte(addr);
}
/* get a word from memory */
int32 get_mword(int32 addr)
{
int32 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM, I/O, and Multibus memory */
void put_mbyte(int32 addr, int32 val)
{
/* if local EPROM handle it */
if ((i8255_unit.u5 & 0x01) && (addr >= EPROM_unit.u3) && (addr <= (EPROM_unit.u3 + EPROM_unit.capac))) {
printf("Write to R/O memory address %04X - ignored\n", addr);
return;
} /* if local RAM handle it */
if ((i8255_unit.u5 & 0x02) && (addr >= RAM_unit.u3) && (addr <= (RAM_unit.u3 + RAM_unit.capac))) {
RAM_put_mbyte(addr, val);
return;
} /* otherwise, try the multibus */
multibus_put_mbyte(addr, val);
}
/* put a word to memory */
void put_mword(int32 addr, int32 val)
{
put_mbyte(addr, val);
put_mbyte(addr+1, val >> 8);
}
/* end of iSBC80-10.c */

View file

@ -2,35 +2,40 @@
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated i2732 EPROM device on an iSBC. This MODIFICATIONS:
allows the attachment of the device to a binary file containing the EPROM
code.
Unit will support a single 2708, 2716, 2732 and 2764 EPROM type. ?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
?? ??? 10 - Original file. NOTES:
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
These functions support a simulated i2732 EPROM device on an Intel iSBC 80/XX.
This allows the attachment of the device to a binary file containing the EPROM
code image.
Unit will support a single 2708, 2716, 2732 and 2764 type EPROMs.
*/ */
#include "system_defs.h" #include "system_defs.h"
@ -101,33 +106,27 @@ t_stat EPROM_attach (UNIT *uptr, char *cptr)
FILE *fp; FILE *fp;
t_stat r; t_stat r;
if (EPROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr);
printf("EPROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (EPROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n");
printf("EPROM_attach: Error\n");
return r; return r;
} }
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, "\tAllocate buffer\n");
printf("\tAllocate buffer\n");
if (EPROM_unit.filebuf == NULL) { /* no buffer allocated */ if (EPROM_unit.filebuf == NULL) { /* no buffer allocated */
EPROM_unit.filebuf = malloc(EPROM_unit.capac); /* allocate EPROM buffer */ EPROM_unit.filebuf = malloc(EPROM_unit.capac); /* allocate EPROM buffer */
if (EPROM_unit.filebuf == NULL) { if (EPROM_unit.filebuf == NULL) {
if (EPROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Malloc error\n");
printf("EPROM_attach: Malloc error\n");
return SCPE_MEM; return SCPE_MEM;
} }
} }
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, "\tOpen file %s\n", EPROM_unit.filename);
printf("\tOpen file %s\n", EPROM_unit.filename);
fp = fopen(EPROM_unit.filename, "rb"); /* open EPROM file */ fp = fopen(EPROM_unit.filename, "rb"); /* open EPROM file */
if (fp == NULL) { if (fp == NULL) {
printf("EPROM: Unable to open ROM file %s\n", EPROM_unit.filename); printf("EPROM: Unable to open ROM file %s\n", EPROM_unit.filename);
printf("\tNo ROM image loaded!!!\n"); printf("\tNo ROM image loaded!!!\n");
return SCPE_OK; return SCPE_OK;
} }
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, "\tRead file\n");
printf("\tRead file\n");
j = 0; /* load EPROM file */ j = 0; /* load EPROM file */
c = fgetc(fp); c = fgetc(fp);
while (c != EOF) { while (c != EOF) {
@ -138,12 +137,10 @@ t_stat EPROM_attach (UNIT *uptr, char *cptr)
break; break;
} }
} }
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, "\tClose file\n");
printf("\tClose file\n");
fclose(fp); fclose(fp);
printf("EPROM: %d bytes of ROM image %s loaded\n", j, EPROM_unit.filename); printf("EPROM: %d bytes of ROM image %s loaded\n", j, EPROM_unit.filename);
if (EPROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Done\n");
printf("EPROM_attach: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -153,12 +150,10 @@ t_stat EPROM_reset (DEVICE *dptr, int32 size)
{ {
t_stat r; t_stat r;
// if (EPROM_dev.dctrl & DEBUG_flow) /* entry message */ // sim_debug (DEBUG_flow, &EPROM_dev, " EPROM_reset: base=0000 size=%04X\n", size);
printf(" EPROM_reset: base=0000 size=%04X\n", size);
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */ if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
EPROM_unit.capac = size; /* set EPROM size to 0 */ EPROM_unit.capac = size; /* set EPROM size to 0 */
if (EPROM_dev.dctrl & DEBUG_flow) /* exit message */ sim_debug (DEBUG_flow, &EPROM_dev, "Done1\n");
printf("Done1\n");
// printf(" EPROM: Available [%04X-%04XH]\n", // printf(" EPROM: Available [%04X-%04XH]\n",
// 0, EPROM_unit.capac - 1); // 0, EPROM_unit.capac - 1);
return SCPE_OK; return SCPE_OK;
@ -166,8 +161,7 @@ t_stat EPROM_reset (DEVICE *dptr, int32 size)
if ((EPROM_unit.flags & UNIT_ATT) == 0) { if ((EPROM_unit.flags & UNIT_ATT) == 0) {
printf("EPROM: No file attached\n"); printf("EPROM: No file attached\n");
} }
if (EPROM_dev.dctrl & DEBUG_flow) /* exit message */ sim_debug (DEBUG_flow, &EPROM_dev, "Done2\n");
printf("Done2\n");
return SCPE_OK; return SCPE_OK;
} }
@ -177,24 +171,19 @@ int32 EPROM_get_mbyte(int32 addr)
{ {
int32 val; int32 val;
if (i8255_unit.u6 & 0x01) { /* EPROM enabled */ if (i8255_unit.u5 & 0x01) { /* EPROM enabled */
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, "EPROM_get_mbyte: addr=%04X\n", addr);
printf("EPROM_get_mbyte: addr=%04X\n", addr);
if ((addr >= 0) && (addr < EPROM_unit.capac)) { if ((addr >= 0) && (addr < EPROM_unit.capac)) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
if (EPROM_dev.dctrl & DEBUG_xack) sim_debug (DEBUG_xack, &EPROM_dev, "EPROM_get_mbyte: Set XACK for %04X\n", addr);
printf("EPROM_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(EPROM_unit.filebuf + addr); val = *(uint8 *)(EPROM_unit.filebuf + addr);
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, " val=%04X\n", val);
printf(" val=%04X\n", val);
return (val & 0xFF); return (val & 0xFF);
} }
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, " EPROM Disabled\n");
printf(" EPROM Disabled\n");
return 0xFF; return 0xFF;
} }
if (EPROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &EPROM_dev, " Out of range\n");
printf(" Out of range\n");
return 0xFF; return 0xFF;
} }

View file

@ -2,31 +2,36 @@
Copyright (c) 2011, William A. Beech Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated i8111 or 8102 RAM device on an iSBC. MODIFICATIONS:
?? ??? 11 - Original file. ?? ??? 11 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size. 16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated i8111 or i8102 RAM devices on an iSBC-80/XX.
*/ */
#include "system_defs.h" #include "system_defs.h"
@ -92,8 +97,7 @@ DEVICE RAM_dev = {
t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size) t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size)
{ {
// if (RAM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &RAM_dev, " RAM_reset: base=%04X size=%04X\n", base, size-1);
printf(" RAM_reset: base=%04X size=%04X\n", base, size-1);
if (RAM_unit.capac == 0) { /* if undefined */ if (RAM_unit.capac == 0) { /* if undefined */
RAM_unit.capac = size; RAM_unit.capac = size;
RAM_unit.u3 = base; RAM_unit.u3 = base;
@ -101,16 +105,14 @@ t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size)
if (RAM_unit.filebuf == NULL) { /* no buffer allocated */ if (RAM_unit.filebuf == NULL) { /* no buffer allocated */
RAM_unit.filebuf = malloc(RAM_unit.capac); RAM_unit.filebuf = malloc(RAM_unit.capac);
if (RAM_unit.filebuf == NULL) { if (RAM_unit.filebuf == NULL) {
if (RAM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &RAM_dev, "RAM_set_size: Malloc error\n");
printf("RAM_set_size: Malloc error\n");
return SCPE_MEM; return SCPE_MEM;
} }
} }
// printf(" RAM: Available [%04X-%04XH]\n", // printf(" RAM: Available [%04X-%04XH]\n",
// RAM_unit.u3, // RAM_unit.u3,
// RAM_unit.u3 + RAM_unit.capac - 1); // RAM_unit.u3 + RAM_unit.capac - 1);
if (RAM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &RAM_dev, "RAM_reset: Done\n");
printf("RAM_reset: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -121,23 +123,18 @@ int32 RAM_get_mbyte(int32 addr)
int32 val; int32 val;
if (i8255_unit.u6 & 0x02) { /* enable RAM */ if (i8255_unit.u6 & 0x02) { /* enable RAM */
if (RAM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &RAM_dev, "RAM_get_mbyte: addr=%04X\n", addr);
printf("RAM_get_mbyte: addr=%04X\n", addr);
if ((addr >= RAM_unit.u3) && (addr < (RAM_unit.u3 + RAM_unit.capac))) { if ((addr >= RAM_unit.u3) && (addr < (RAM_unit.u3 + RAM_unit.capac))) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
if (RAM_dev.dctrl & DEBUG_xack) sim_debug (DEBUG_xack, &RAM_dev, "RAM_get_mbyte: Set XACK for %04X\n", addr);
printf("RAM_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(RAM_unit.filebuf + (addr - RAM_unit.u3)); val = *(uint8 *)(RAM_unit.filebuf + (addr - RAM_unit.u3));
if (RAM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &RAM_dev, " val=%04X\n", val);
printf(" val=%04X\n", val);
return (val & 0xFF); return (val & 0xFF);
} }
if (RAM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &RAM_dev, " RAM disabled\n");
printf(" RAM disabled\n");
return 0xFF; return 0xFF;
} }
if (RAM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &RAM_dev, " Out of range\n");
printf(" Out of range\n");
return 0xFF; return 0xFF;
} }
@ -145,24 +142,19 @@ int32 RAM_get_mbyte(int32 addr)
void RAM_put_mbyte(int32 addr, int32 val) void RAM_put_mbyte(int32 addr, int32 val)
{ {
if (i8255_unit.u6 & 0x02) { /* enable RAM */ if (i8255_unit.u5 & 0x02) { /* enable RAM */
if (RAM_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &RAM_dev, "RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
printf("RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if ((addr >= RAM_unit.u3) && (addr < RAM_unit.u3 + RAM_unit.capac)) { if ((addr >= RAM_unit.u3) && (addr < RAM_unit.u3 + RAM_unit.capac)) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
if (RAM_dev.dctrl & DEBUG_xack) sim_debug (DEBUG_xack, &RAM_dev, "RAM_put_mbyte: Set XACK for %04X\n", addr);
printf("RAM_put_mbyte: Set XACK for %04X\n", addr);
*(uint8 *)(RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF; *(uint8 *)(RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
if (RAM_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &RAM_dev, "\n");
printf("\n");
return; return;
} }
if (RAM_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &RAM_dev, " RAM disabled\n");
printf(" RAM disabled\n");
return; return;
} }
if (RAM_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &RAM_dev, " Out of range\n");
printf(" Out of range\n");
} }
/* end of iRAM8.c */ /* end of iRAM8.c */

View file

@ -2,33 +2,37 @@
Copyright (c) 2011, William A. Beech Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated isbc016, isbc032, isbc048 and isbc064 MODIFICATIONS:
memory card on an Intel multibus system.
?? ??? 11 - Original file. ?? ??? 11 - Original file.
16 Dec 12 - Modified to use system_80_10.cfg file to set base and size. 16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
These functions support a simulated isbc016, isbc032, isbc048 and isbc064
memory card on an Intel multibus system.
*/ */
#include "system_defs.h" #include "system_defs.h"
@ -93,8 +97,7 @@ DEVICE isbc064_dev = {
t_stat isbc064_reset (DEVICE *dptr) t_stat isbc064_reset (DEVICE *dptr)
{ {
if (isbc064_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: ");
printf("isbc064_reset: ");
if ((isbc064_dev.flags & DEV_DIS) == 0) { if ((isbc064_dev.flags & DEV_DIS) == 0) {
isbc064_unit.capac = SBC064_SIZE; isbc064_unit.capac = SBC064_SIZE;
isbc064_unit.u3 = SBC064_BASE; isbc064_unit.u3 = SBC064_BASE;
@ -105,13 +108,11 @@ t_stat isbc064_reset (DEVICE *dptr)
if (isbc064_unit.filebuf == NULL) { if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = malloc(isbc064_unit.capac); isbc064_unit.filebuf = malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) { if (isbc064_unit.filebuf == NULL) {
if (isbc064_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Malloc error\n");
printf("isbc064_reset: Malloc error\n");
return SCPE_MEM; return SCPE_MEM;
} }
} }
if (isbc064_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &isbc064_dev, "isbc064_reset: Done\n");
printf("isbc064_reset: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -125,26 +126,20 @@ int32 isbc064_get_mbyte(int32 addr)
if ((isbc064_dev.flags & DEV_DIS) == 0) { if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3; org = isbc064_unit.u3;
len = isbc064_unit.capac; len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: addr=%04X", addr);
printf("isbc064_get_mbyte: addr=%04X", addr); sim_debug (DEBUG_read, &isbc064_dev, "isbc064_get_mbyte: org=%04X, len=%04X\n", org, len);
if (isbc064_dev.dctrl & DEBUG_read)
printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) { if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack) sim_debug (DEBUG_xack, &isbc064_dev, "isbc064_get_mbyte: Set XACK for %04X\n", addr);
printf("isbc064_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(isbc064_unit.filebuf + (addr - org)); val = *(uint8 *)(isbc064_unit.filebuf + (addr - org));
if (isbc064_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &isbc064_dev, " val=%04X\n", val);
printf(" val=%04X\n", val);
return (val & 0xFF); return (val & 0xFF);
} else { } else {
if (isbc064_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &isbc064_dev, " Out of range\n");
printf(" Out of range\n");
return 0xFF; /* multibus has active high pullups */ return 0xFF; /* multibus has active high pullups */
} }
} }
if (isbc064_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &isbc064_dev, " Disabled\n");
printf(" Disabled\n");
return 0xFF; /* multibus has active high pullups */ return 0xFF; /* multibus has active high pullups */
} }
@ -169,26 +164,20 @@ void isbc064_put_mbyte(int32 addr, int32 val)
if ((isbc064_dev.flags & DEV_DIS) == 0) { if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3; org = isbc064_unit.u3;
len = isbc064_unit.capac; len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
printf("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val); sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) { if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */ SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack) sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Set XACK for %04X\n", addr);
printf("isbc064_put_mbyte: Set XACK for %04X\n", addr);
*(uint8 *)(isbc064_unit.filebuf + (addr - org)) = val & 0xFF; *(uint8 *)(isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
if (isbc064_dev.dctrl & DEBUG_xack) sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Return\n");
printf("isbc064_put_mbyte: Return\n");
return; return;
} else { } else {
if (isbc064_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &isbc064_dev, " Out of range\n");
printf(" Out of range\n");
return; return;
} }
} }
if (isbc064_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &isbc064_dev, "isbc064_put_mbyte: Disabled\n");
printf("isbc064_put_mbyte: Disabled\n");
} }
/* put a word into memory */ /* put a word into memory */

1616
isys8010/common/isbc208.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -2,32 +2,38 @@
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus MODIFICATIONS:
Computer Systems.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/ */
#include "system_defs.h" #include "system_defs.h"
@ -285,4 +291,5 @@ void multibus_put_mword(int32 addr, int32 val)
multibus_put_mbyte(addr+1, val << 8); multibus_put_mbyte(addr+1, val << 8);
} }
/* end of multibus.c */

View file

@ -1,4 +1,4 @@
/* system_80_10_sys.c: multibus system interface /* sys-8010_sys.c: multibus system interface
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech

View file

@ -2,26 +2,26 @@
Copyright (c) 2010, William A. Beech Copyright (c) 2010, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
William A. Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
?? ??? 10 - Original file. ?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size. 16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
@ -29,8 +29,8 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include "system_80_10.cfg" /* Intel System 80/10 configuration */ #include "isys8010.cfg" /* Intel System 80/10 configuration */
#include "sim_defs.h" /* simulator defns */ #include "sim_defs.h" /* simulator defns */
/* multibus interrupt definitions */ /* multibus interrupt definitions */

View file

@ -1194,6 +1194,7 @@ SDS = ${SDSD}/sds_cpu.c ${SDSD}/sds_drm.c ${SDSD}/sds_dsk.c ${SDSD}/sds_io.c \
${SDSD}/sds_stddev.c ${SDSD}/sds_sys.c ${SDSD}/sds_stddev.c ${SDSD}/sds_sys.c
SDS_OPT = -I ${SDSD} SDS_OPT = -I ${SDSD}
SWTP6800D = swtp6800/swtp6800 SWTP6800D = swtp6800/swtp6800
SWTP6800C = swtp6800/common SWTP6800C = swtp6800/common
SWTP6800MP-A = ${SWTP6800C}/mp-a.c ${SWTP6800C}/m6800.c ${SWTP6800C}/m6810.c \ SWTP6800MP-A = ${SWTP6800C}/mp-a.c ${SWTP6800C}/m6800.c ${SWTP6800C}/m6810.c \
@ -1204,11 +1205,23 @@ SWTP6800MP-A2 = ${SWTP6800C}/mp-a2.c ${SWTP6800C}/m6800.c ${SWTP6800C}/m6810.c \
${SWTP6800C}/mp-b2.c ${SWTP6800C}/mp-8m.c ${SWTP6800C}/i2716.c ${SWTP6800C}/mp-b2.c ${SWTP6800C}/mp-8m.c ${SWTP6800C}/i2716.c
SWTP6800_OPT = -I ${SWTP6800D} SWTP6800_OPT = -I ${SWTP6800D}
ISYS8010D = isys8010/isys8010
ISYS8010C = isys8010/common
ISYS8010 = ${ISYS8010C}/i8080.c ${ISYS8010D}/isys8010_sys.c \
${ISYS8010C}/i8251.c ${ISYS8010C}/i8255.c \
${ISYS8010C}/ieprom.c ${ISYS8010C}/iram8.c \
${ISYS8010C}/multibus.c ${ISYS8010C}/isbc80-10.c \
${ISYS8010C}/isbc064.c ${ISYS8010C}/isbc208.c
ISYS8010_OPT = -I ${ISYS8010D}
TX0D = TX-0 TX0D = TX-0
TX0 = ${TX0D}/tx0_cpu.c ${TX0D}/tx0_dpy.c ${TX0D}/tx0_stddev.c \ TX0 = ${TX0D}/tx0_cpu.c ${TX0D}/tx0_dpy.c ${TX0D}/tx0_stddev.c \
${TX0D}/tx0_sys.c ${TX0D}/tx0_sys_orig.c ${DISPLAYL} ${TX0D}/tx0_sys.c ${TX0D}/tx0_sys_orig.c ${DISPLAYL}
TX0_OPT = -I ${TX0D} $(DISPLAY_OPT) TX0_OPT = -I ${TX0D} $(DISPLAY_OPT)
SSEMD = SSEM SSEMD = SSEM
SSEM = ${SSEMD}/ssem_cpu.c ${SSEMD}/ssem_sys.c SSEM = ${SSEMD}/ssem_cpu.c ${SSEMD}/ssem_sys.c
SSEM_OPT = -I ${SSEMD} SSEM_OPT = -I ${SSEMD}
@ -1301,7 +1314,7 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 vax8600 \ vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 vax8600 \
nova eclipse hp2100 i1401 i1620 s3 altair altairz80 gri \ nova eclipse hp2100 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 \ i7094 ibm1130 id16 id32 sds lgp h316 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem swtp6800mp-a swtp6800mp-a2 tx-0 ssem isys8010
all : ${ALL} all : ${ALL}
@ -1551,6 +1564,13 @@ ${BIN}swtp6800mp-a2${EXE} : ${SWTP6800MP-A2} ${SIM} ${BUILD_ROMS}
${MKDIRBIN} ${MKDIRBIN}
${CC} ${SWTP6800MP-A2} ${SIM} ${SWTP6800_OPT} $(CC_OUTSPEC) ${LDFLAGS} ${CC} ${SWTP6800MP-A2} ${SIM} ${SWTP6800_OPT} $(CC_OUTSPEC) ${LDFLAGS}
isys8010: ${BIN}isys8010${EXE}
${BIN}isys8010${EXE} : ${ISYS8010} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${ISYS8010} ${SIM} ${ISYS8010_OPT} $(CC_OUTSPEC) ${LDFLAGS}
tx-0 : ${BIN}tx-0${EXE} tx-0 : ${BIN}tx-0${EXE}
${BIN}tx-0${EXE} : ${TX0} ${SIM} ${BIN}tx-0${EXE} : ${TX0} ${SIM}

View file

@ -2,41 +2,48 @@
Copyright (c) 2010-2012, William A. Beech Copyright (c) 2010-2012, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a single simulated 2704 to 2764 EPROM device on MODIFICATIONS:
an 8-bit computer system.. This device allows the buffer to be loaded from
a binary file containing the emulated EPROM code.
These functions support a simulated 2704, 2708, 2716, 2732 or 2764 EPROM 23 Apr 15 -- Modified to use simh_debug
device on a CPU board. The byte get and put routines use an offset into
the boot EPROM image to locate the proper byte. This allows another device NOTES:
to set the base address for the boot EPROM. The device type is stored as
a binary number in the first three unit flag bits. These functions support a single simulated 2704 to 2764 EPROM device on
an 8-bit computer system.. This device allows the buffer to be loaded from
a binary file containing the emulated EPROM code.
These functions support a simulated 2704, 2708, 2716, 2732 or 2764 EPROM
device on a CPU board. The byte get and put routines use an offset into
the boot EPROM image to locate the proper byte. This allows another device
to set the base address for the boot EPROM. The device type is stored as
a binary number in the first three unit flag bits.
This device uses a dynamically allocated buffer to hold the EPROM image.
A call to BOOTROM_config will free the current buffer. A call to
BOOTROM_reset will allocate a new buffer of BOOTROM_unit.capac bytes. A
call to BOOTROM_attach will load the buffer with the EPROM image.
This device uses a dynamically allocated buffer to hold the EPROM image.
A call to BOOTROM_config will free the current buffer. A call to
BOOTROM_reset will allocate a new buffer of BOOTROM_unit.capac bytes. A
call to BOOTROM_attach will load the buffer with the EPROM image.
*/ */
#include <stdio.h> #include <stdio.h>
@ -129,11 +136,9 @@ t_stat BOOTROM_attach (UNIT *uptr, char *cptr)
t_addr image_size, capac; t_addr image_size, capac;
int i; int i;
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: cptr=%s\n", cptr);
printf("BOOTROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: Error\n");
printf("BOOTROM_attach: Error\n");
return r; return r;
} }
image_size = (t_addr)sim_fsize_ex (BOOTROM_unit.fileref); image_size = (t_addr)sim_fsize_ex (BOOTROM_unit.fileref);
@ -141,11 +146,10 @@ t_stat BOOTROM_attach (UNIT *uptr, char *cptr)
if (i > (UNIT_2764>>UNIT_V_MSIZE)) { if (i > (UNIT_2764>>UNIT_V_MSIZE)) {
detach_unit (uptr); detach_unit (uptr);
return SCPE_ARG; return SCPE_ARG;
} }
uptr->flags &= ~UNIT_MSIZE; uptr->flags &= ~UNIT_MSIZE;
uptr->flags |= (i << UNIT_V_MSIZE); uptr->flags |= (i << UNIT_V_MSIZE);
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_attach: Done\n");
printf("BOOTROM_attach: Done\n");
return (BOOTROM_reset (NULL)); return (BOOTROM_reset (NULL));
} }
@ -153,11 +157,9 @@ t_stat BOOTROM_attach (UNIT *uptr, char *cptr)
t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc) t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc)
{ {
if (BOOTROM_dev.dctrl & DEBUG_flow) /* entry message */ sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: val=%d\n", val);
printf("BOOTROM_config: val=%d\n", val);
if ((val < UNIT_NONE) || (val > UNIT_2764)) { /* valid param? */ if ((val < UNIT_NONE) || (val > UNIT_2764)) { /* valid param? */
if (BOOTROM_dev.dctrl & DEBUG_flow) /* No */ sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: Parameter error\n");
printf("BOOTROM_config: Parameter error\n");
return SCPE_ARG; return SCPE_ARG;
} }
if (val == UNIT_NONE) if (val == UNIT_NONE)
@ -168,11 +170,9 @@ t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc)
free (BOOTROM_unit.filebuf); free (BOOTROM_unit.filebuf);
BOOTROM_unit.filebuf = NULL; BOOTROM_unit.filebuf = NULL;
} }
if (BOOTROM_dev.dctrl & DEBUG_flow) /* status message */ sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: BOOTROM_unit.capac=%d\n",
printf("BOOTROM_config: BOOTROM_unit.capac=%d\n",
BOOTROM_unit.capac); BOOTROM_unit.capac);
if (BOOTROM_dev.dctrl & DEBUG_flow) /* exit message */ sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_config: Done\n");
printf("BOOTROM_config: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -184,15 +184,13 @@ t_stat BOOTROM_reset (DEVICE *dptr)
int c; int c;
FILE *fp; FILE *fp;
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: \n");
printf("BOOTROM_reset: \n");
if ((BOOTROM_unit.flags & UNIT_MSIZE) == 0) { /* if none selected */ if ((BOOTROM_unit.flags & UNIT_MSIZE) == 0) { /* if none selected */
// printf(" EPROM: Defaulted to None\n"); // printf(" EPROM: Defaulted to None\n");
// printf(" \"set eprom NONE | 2704 | 2708 | 2716 | 2732 | 2764\"\n"); // printf(" \"set eprom NONE | 2704 | 2708 | 2716 | 2732 | 2764\"\n");
// printf(" \"att eprom <filename>\"\n"); // printf(" \"att eprom <filename>\"\n");
BOOTROM_unit.capac = 0; /* set EPROM size to 0 */ BOOTROM_unit.capac = 0; /* set EPROM size to 0 */
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: Done1\n");
printf("BOOTROM_reset: Done1\n");
return SCPE_OK; return SCPE_OK;
} /* if attached */ } /* if attached */
// printf(" EPROM: Initializing [%04X-%04XH]\n", // printf(" EPROM: Initializing [%04X-%04XH]\n",
@ -200,8 +198,7 @@ t_stat BOOTROM_reset (DEVICE *dptr)
if (BOOTROM_unit.filebuf == NULL) { /* no buffer allocated */ if (BOOTROM_unit.filebuf == NULL) { /* no buffer allocated */
BOOTROM_unit.filebuf = calloc(1, BOOTROM_unit.capac); /* allocate EPROM buffer */ BOOTROM_unit.filebuf = calloc(1, BOOTROM_unit.capac); /* allocate EPROM buffer */
if (BOOTROM_unit.filebuf == NULL) { if (BOOTROM_unit.filebuf == NULL) {
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: Malloc error\n");
printf("BOOTROM_reset: Malloc error\n");
return SCPE_MEM; return SCPE_MEM;
} }
} }
@ -231,8 +228,7 @@ t_stat BOOTROM_reset (DEVICE *dptr)
} }
fclose(fp); fclose(fp);
// printf("\t%d bytes of ROM image %s loaded\n", j, BOOTROM_unit.filename); // printf("\t%d bytes of ROM image %s loaded\n", j, BOOTROM_unit.filename);
if (BOOTROM_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &BOOTROM_dev, "BOOTROM_reset: Done2\n");
printf("BOOTROM_reset: Done2\n");
return SCPE_OK; return SCPE_OK;
} }
@ -243,20 +239,16 @@ int32 BOOTROM_get_mbyte(int32 offset)
int32 val; int32 val;
if (BOOTROM_unit.filebuf == NULL) { if (BOOTROM_unit.filebuf == NULL) {
if (BOOTROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: EPROM not configured\n");
printf("BOOTROM_get_mbyte: EPROM not configured\n");
return 0xFF; return 0xFF;
} }
if (BOOTROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: offset=%04X\n", offset);
printf("BOOTROM_get_mbyte: offset=%04X\n", offset);
if ((t_addr)offset > BOOTROM_unit.capac) { if ((t_addr)offset > BOOTROM_unit.capac) {
if (BOOTROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: EPROM reference beyond ROM size\n");
printf("BOOTROM_get_mbyte: EPROM reference beyond ROM size\n");
return 0xFF; return 0xFF;
} }
val = *((uint8 *)(BOOTROM_unit.filebuf) + offset) & 0xFF; val = *((uint8 *)(BOOTROM_unit.filebuf) + offset) & 0xFF;
if (BOOTROM_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &BOOTROM_dev, "BOOTROM_get_mbyte: Normal val=%02X\n", val);
printf("BOOTROM_get_mbyte: Normal val=%02X\n", val);
return val; return val;
} }

View file

@ -2,216 +2,222 @@
Copyright (c) 2005-2012, William A. Beech Copyright (c) 2005-2012, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
The DC-4 is a 5-inch floppy controller which can control up MODIFICATIONS:
to 4 daisy-chained 5-inch floppy drives. The controller is based on
the Western Digital 1797 Floppy Disk Controller (FDC) chip. This
file only emulates the minimum DC-4 functionality to interface with
the virtual disk file.
The floppy controller is interfaced to the CPU by use of 5 memory 23 Apr 15 -- Modified to use simh_debug
addreses. These are SS-30 slot numbers 5 and 6 (0x8014-0x801B).
Address Mode Function NOTES:
------- ---- --------
0x8014 Read Returns FDC interrupt status The DC-4 is a 5-inch floppy controller which can control up
0x8014 Write Selects the drive/head/motor control to 4 daisy-chained 5-inch floppy drives. The controller is based on
0x8018 Read Returns status of FDC the Western Digital 1797 Floppy Disk Controller (FDC) chip. This
0x8018 Write FDC command register file only emulates the minimum DC-4 functionality to interface with
0x8019 Read Returns FDC track register the virtual disk file.
0x8019 Write Set FDC track register
0x801A Read Returns FDC sector register
0x801A Write Set FDC sector register
0x801B Read Read data
0x801B Write Write data
Drive Select Read (0x8014): The floppy controller is interfaced to the CPU by use of 5 memory
addreses. These are SS-30 slot numbers 5 and 6 (0x8014-0x801B).
+---+---+---+---+---+---+---+---+ Address Mode Function
| I | D | X | X | X | X | X | X | ------- ---- --------
+---+---+---+---+---+---+---+---+
I = Set indicates an interrupt request from the FDC pending. 0x8014 Read Returns FDC interrupt status
D = DRQ pending - same as bit 1 of FDC status register. 0x8014 Write Selects the drive/head/motor control
0x8018 Read Returns status of FDC
0x8018 Write FDC command register
0x8019 Read Returns FDC track register
0x8019 Write Set FDC track register
0x801A Read Returns FDC sector register
0x801A Write Set FDC sector register
0x801B Read Read data
0x801B Write Write data
Drive Select Write (0x8014): Drive Select Read (0x8014):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| M | S | X | X | X | X | Device| | I | D | X | X | X | X | X | X |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
M = If this bit is 1, the one-shot is triggered/retriggered to I = Set indicates an interrupt request from the FDC pending.
start/keep the motors on. D = DRQ pending - same as bit 1 of FDC status register.
S = Side select. If set, side one is selected otherwise side zero
is selected.
X = not used
Device = value 0 thru 3, selects drive 0-3 to be controlled.
Drive Status Read (0x8018): Drive Select Write (0x8014):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| R | P | H | S | C | L | D | B | | M | S | X | X | X | X | Device|
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
B - When 1, the controller is busy. M = If this bit is 1, the one-shot is triggered/retriggered to
D - When 1, index mark detected (type I) or data request - read data start/keep the motors on.
ready/write data empty (type II or III). S = Side select. If set, side one is selected otherwise side zero
H - When 1, track 0 (type I) or lost data (type II or III). is selected.
C - When 1, crc error detected. X = not used
S - When 1, seek (type I) or RNF (type II or III) error. Device = value 0 thru 3, selects drive 0-3 to be controlled.
H - When 1, head is currently loaded (type I) or record type/
write fault (type II or III).
P - When 1, indicates that diskette is write-protected.
R - When 1, drive is not ready.
Drive Control Write (0x8018) for type I commands: Drive Status Read (0x8018):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 0 | S2| S1| S0| H | V | R1| R0| | R | P | H | S | C | L | D | B |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
R0/R1 - Selects the step rate. B - When 1, the controller is busy.
V - When 1, verify on destination track. D - When 1, index mark detected (type I) or data request - read data
H - When 1, loads head to drive surface. ready/write data empty (type II or III).
S0/S1/S2 = 000 - home. H - When 1, track 0 (type I) or lost data (type II or III).
001 - seek track in data register. C - When 1, crc error detected.
010 - step without updating track register. S - When 1, seek (type I) or RNF (type II or III) error.
011 - step and update track register. H - When 1, head is currently loaded (type I) or record type/
100 - step in without updating track register. write fault (type II or III).
101 - step in and update track register. P - When 1, indicates that diskette is write-protected.
110 - step out without updating track register. R - When 1, drive is not ready.
111 - step out and update track register.
Drive Control Write (0x8018) for type II commands: Drive Control Write (0x8018) for type I commands:
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 1 | 0 | T | M | S | E | B | A | | 0 | S2| S1| S0| H | V | R1| R0|
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
A - Zero for read, 1 on write deleted data mark else data mark. R0/R1 - Selects the step rate.
B - When 1, shifts sector length field definitions one place. V - When 1, verify on destination track.
E - When, delay operation 15 ms, 0 no delay. H - When 1, loads head to drive surface.
S - When 1, select side 1, 0 select side 0. S0/S1/S2 = 000 - home.
M - When 1, multiple records, 0 for single record. 001 - seek track in data register.
T - When 1, write command, 0 for read. 010 - step without updating track register.
011 - step and update track register.
100 - step in without updating track register.
101 - step in and update track register.
110 - step out without updating track register.
111 - step out and update track register.
Drive Control Write (0x8018) for type III commands: Drive Control Write (0x8018) for type II commands:
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 1 | 1 | T0| T1| 0 | E | 0 | 0 | | 1 | 0 | T | M | S | E | B | A |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
E - When, delay operation 15 ms, 0 no delay. A - Zero for read, 1 on write deleted data mark else data mark.
T0/T1 - 00 - read address command. B - When 1, shifts sector length field definitions one place.
10 - read track command. E - When, delay operation 15 ms, 0 no delay.
11 - write track command. S - When 1, select side 1, 0 select side 0.
M - When 1, multiple records, 0 for single record.
T - When 1, write command, 0 for read.
Tracks are numbered from 0 up to one minus the last track in the 1797! Drive Control Write (0x8018) for type III commands:
Track Register Read (0x8019): +---+---+---+---+---+---+---+---+
| 1 | 1 | T0| T1| 0 | E | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+ E - When, delay operation 15 ms, 0 no delay.
| Track Number | T0/T1 - 00 - read address command.
+---+---+---+---+---+---+---+---+ 10 - read track command.
11 - write track command.
Reads the current 8-bit value from the track position. Tracks are numbered from 0 up to one minus the last track in the 1797!
Track Register Write (0x8019): Track Register Read (0x8019):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| Track Number | | Track Number |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
Writes the 8-bit value to the track register. Reads the current 8-bit value from the track position.
Sectors are numbers from 1 up to the last sector in the 1797! Track Register Write (0x8019):
Sector Register Read (0x801A): +---+---+---+---+---+---+---+---+
| Track Number |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+ Writes the 8-bit value to the track register.
| Sector Number |
+---+---+---+---+---+---+---+---+
Reads the current 8-bit value from the sector position. Sectors are numbers from 1 up to the last sector in the 1797!
Sector Register Write (0x801A): Sector Register Read (0x801A):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| Sector Number | | Sector Number |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
Writes the 8-bit value to the sector register. Reads the current 8-bit value from the sector position.
Data Register Read (0x801B): Sector Register Write (0x801A):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| Data | | Sector Number |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
Reads the current 8-bit value from the data register. Writes the 8-bit value to the sector register.
Data Register Write (0x801B): Data Register Read (0x801B):
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| Data | | Data |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
Writes the 8-bit value to the data register. Reads the current 8-bit value from the data register.
A FLEX disk is defined as follows: Data Register Write (0x801B):
Track Sector Use +---+---+---+---+---+---+---+---+
0 1 Boot sector | Data |
0 2 Boot sector (cont) +---+---+---+---+---+---+---+---+
0 3 Unused
0 4 System Identity Record (explained below)
0 5 Unused
0 6-last Directory - 10 entries/sector (explained below)
1 1 First available data sector
last-1 last Last available data sector
System Identity Record Writes the 8-bit value to the data register.
Byte Use A FLEX disk is defined as follows:
0x00 Two bytes of zeroes (Clears forward link)
0x10 Volume name in ASCII(11 bytes)
0x1B Volume number in binary (2 bytes)
0x1D Address of first free data sector (Track-Sector) (2 bytes)
0x1F Address of last free data sector (Track-Sector) (2 bytes)
0x21 Total number of data sectors in binary (2 bytes)
0x23 Current date (Month-Day-Year) in binary
0x26 Highest track number on disk in binary (byte)
0x27 Highest sector number on a track in binary (byte)
The following unit registers are used by this controller emulation: Track Sector Use
0 1 Boot sector
0 2 Boot sector (cont)
0 3 Unused
0 4 System Identity Record (explained below)
0 5 Unused
0 6-last Directory - 10 entries/sector (explained below)
1 1 First available data sector
last-1 last Last available data sector
dsk_unit[cur_drv].u3 unit current flags System Identity Record
dsk_unit[cur_drv].u4 unit current track
dsk_unit[cur_drv].u5 unit current sector Byte Use
dsk_unit[cur_drv].pos unit current sector byte index into buffer 0x00 Two bytes of zeroes (Clears forward link)
dsk_unit[cur_drv].filebuf unit current sector buffer 0x10 Volume name in ASCII(11 bytes)
dsk_unit[cur_drv].fileref unit current attached file reference 0x1B Volume number in binary (2 bytes)
0x1D Address of first free data sector (Track-Sector) (2 bytes)
0x1F Address of last free data sector (Track-Sector) (2 bytes)
0x21 Total number of data sectors in binary (2 bytes)
0x23 Current date (Month-Day-Year) in binary
0x26 Highest track number on disk in binary (byte)
0x27 Highest sector number on a track in binary (byte)
The following unit registers are used by this controller emulation:
dsk_unit[cur_drv].u3 unit current flags
dsk_unit[cur_drv].u4 unit current track
dsk_unit[cur_drv].u5 unit current sector
dsk_unit[cur_drv].pos unit current sector byte index into buffer
dsk_unit[cur_drv].filebuf unit current sector buffer
dsk_unit[cur_drv].fileref unit current attached file reference
*/ */
#include <stdio.h> #include <stdio.h>
@ -370,25 +376,22 @@ int32 fdcdrv(int32 io, int32 data)
static long pos; static long pos;
if (io) { /* write to DC-4 drive register */ if (io) { /* write to DC-4 drive register */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcdrv: Drive selected %d cur_dsk=%d",
printf("\nfdcdrv: Drive selected %d cur_dsk=%d", data & 0x03, cur_dsk); data & 0x03, cur_dsk);
if (cur_dsk == (data & 0x03)) if (cur_dsk == (data & 0x03))
return 0; /* already selected */ return 0; /* already selected */
cur_dsk = data & 0x03; /* only 2 drive select bits */ cur_dsk = data & 0x03; /* only 2 drive select bits */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcdrv: Drive set to %d", cur_dsk);
printf("\nfdcdrv: Drive set to %d", cur_dsk);
if ((dsk_unit[cur_dsk].flags & UNIT_ENABLE) == 0) { if ((dsk_unit[cur_dsk].flags & UNIT_ENABLE) == 0) {
dsk_unit[cur_dsk].u3 |= WRPROT; /* set 1797 WPROT */ dsk_unit[cur_dsk].u3 |= WRPROT; /* set 1797 WPROT */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcdrv: Drive write protected");
printf("\nfdcdrv: Drive write protected");
} else { } else {
dsk_unit[cur_dsk].u3 &= ~WRPROT; /* set 1797 not WPROT */ dsk_unit[cur_dsk].u3 &= ~WRPROT; /* set 1797 not WPROT */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcdrv: Drive NOT write protected");
printf("\nfdcdrv: Drive NOT write protected");
} }
pos = 0x200; /* Read in SIR */ pos = 0x200; /* Read in SIR */
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdcdrv: Read pos = %ld ($%04X)",
printf("\nfdcdrv: Read pos = %ld ($%04X)", pos, (unsigned int) pos); pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */ sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */
sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */ sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */ dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
@ -398,13 +401,11 @@ int32 fdcdrv(int32 io, int32 data)
cpd = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + MAXCYL) & 0xFF; cpd = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + MAXCYL) & 0xFF;
trksiz = spt * SECSIZ; trksiz = spt * SECSIZ;
dsksiz = trksiz * cpd; dsksiz = trksiz * cpd;
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdcdrv: spt=%d heds=%d cpd=%d trksiz=%d dsksiz=%d flags=%08X u3=%08X",
printf("\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); spt, heds, cpd, trksiz, dsksiz, dsk_unit[cur_dsk].flags, dsk_unit[cur_dsk].u3);
return 0; return 0;
} else { /* read from DC-4 drive register */ } else { /* read from DC-4 drive register */
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdcdrv: Drive read as %02X", intrq);
printf("\nfdcdrv: Drive read as %02X", intrq);
return intrq; return intrq;
} }
} }
@ -418,8 +419,7 @@ int32 fdccmd(int32 io, int32 data)
if ((dsk_unit[cur_dsk].flags & UNIT_ATT) == 0) { /* not attached */ if ((dsk_unit[cur_dsk].flags & UNIT_ATT) == 0) { /* not attached */
dsk_unit[cur_dsk].u3 |= NOTRDY; /* set not ready flag */ dsk_unit[cur_dsk].u3 |= NOTRDY; /* set not ready flag */
if (dsk_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Drive %d is not attached", cur_dsk);
printf("\nfdccmd: Drive %d is not attached", cur_dsk);
return 0; return 0;
} else { } else {
dsk_unit[cur_dsk].u3 &= ~NOTRDY; /* clear not ready flag */ dsk_unit[cur_dsk].u3 &= ~NOTRDY; /* clear not ready flag */
@ -428,29 +428,27 @@ int32 fdccmd(int32 io, int32 data)
switch(data) { switch(data) {
case 0x8C: /* read command */ case 0x8C: /* read command */
case 0x9C: case 0x9C:
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdccmd: Read of disk %d, track %d, sector %d",
printf("\nfdccmd: Read of disk %d, track %d, sector %d",
cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5); cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5);
pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */ pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */
pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1); pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdccmd: Read pos = %ld ($%08X)",
printf("\nfdccmd: Read pos = %ld ($%08X)", pos, (unsigned int) pos); pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */ sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */
sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */ sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */ dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */ dsk_unit[cur_dsk].pos = 0; /* clear counter */
break; break;
case 0xAC: /* write command */ case 0xAC: /* write command */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdccmd: Write of disk %d, track %d, sector %d",
printf("\nfdccmd: Write of disk %d, track %d, sector %d",
cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5); cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5);
if (dsk_unit[cur_dsk].u3 & WRPROT) { if (dsk_unit[cur_dsk].u3 & WRPROT) {
printf("\nfdccmd: Drive %d is write-protected", cur_dsk); printf("\nfdccmd: Drive %d is write-protected", cur_dsk);
} else { } else {
pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */ pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */
pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1); pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdccmd: Write pos = %ld ($%08X)",
printf("\nfdccmd: Write pos = %ld ($%08X)", pos, (unsigned int) pos); pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */ sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */
wrt_flag = 1; /* set write flag */ wrt_flag = 1; /* set write flag */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ;/* set DRQ & BUSY */ dsk_unit[cur_dsk].u3 |= BUSY | DRQ;/* set DRQ & BUSY */
@ -461,18 +459,17 @@ int32 fdccmd(int32 io, int32 data)
case 0x1B: case 0x1B:
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 */ dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
if (dsk_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Seek of disk %d, track %d",
printf("\nfdccmd: Seek of disk %d, track %d", cur_dsk, fdcbyte); cur_dsk, fdcbyte);
break; break;
case 0x0B: /* restore command */ case 0x0B: /* restore command */
dsk_unit[cur_dsk].u4 = 0; /* home the drive */ dsk_unit[cur_dsk].u4 = 0; /* home the drive */
dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
if (dsk_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Drive %d homed", cur_dsk);
printf("\nfdccmd: Drive %d homed", cur_dsk);
break; break;
case 0xF0: /* write track command */ case 0xF0: /* write track command */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdccmd: Write track command for drive %d",
printf("\nfdccmd: Write track command for drive %d", cur_dsk); cur_dsk);
break; break;
default: default:
printf("Unknown FDC command %02XH\n\r", data); printf("Unknown FDC command %02XH\n\r", data);
@ -481,15 +478,15 @@ int32 fdccmd(int32 io, int32 data)
val = dsk_unit[cur_dsk].u3; /* set return value */ val = dsk_unit[cur_dsk].u3; /* set return value */
/* either print below will force the val to 0x43 forever. timing problem in /* either print below will force the val to 0x43 forever. timing problem in
the 6800 disk driver software? */ the 6800 disk driver software? */
// if (dsk_dev.dctrl & DEBUG_flow) // sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Exit Drive %d status=%02X",
// printf("\nfdccmd: Exit Drive %d status=%02X", cur_dsk, val); // cur_dsk, val);
// printf("\n%02X", val); //even this short fails it! // sim_debug (DEBUG_flow, &dsk_dev, "\n%02X", val); //even this short fails it!
if (val1 == 0 && ((val & (BUSY + DRQ)) == (BUSY + DRQ))) /* delay BUSY going high */ if (val1 == 0 && ((val & (BUSY + DRQ)) == (BUSY + DRQ))) /* delay BUSY going high */
val &= ~BUSY; val &= ~BUSY;
if (val != val1) /* now allow BUSY after one read */ if (val != val1) /* now allow BUSY after one read */
val1 = val; val1 = val;
if (dsk_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &dsk_dev, "\nfdccmd: Exit Drive %d status=%02X",
printf("\nfdccmd: Exit Drive %d status=%02X", cur_dsk, val); cur_dsk, val);
} }
return val; return val;
} }
@ -500,11 +497,11 @@ int32 fdctrk(int32 io, int32 data)
{ {
if (io) { if (io) {
dsk_unit[cur_dsk].u4 = data & 0xFF; dsk_unit[cur_dsk].u4 = data & 0xFF;
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdctrk: Drive %d track set to %d",
printf("\nfdctrk: Drive %d track set to %d", cur_dsk, dsk_unit[cur_dsk].u4); cur_dsk, dsk_unit[cur_dsk].u4);
} }
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdctrk: Drive %d track read as %d",
printf("\nfdctrk: Drive %d track read as %d", cur_dsk, dsk_unit[cur_dsk].u4); cur_dsk, dsk_unit[cur_dsk].u4);
return dsk_unit[cur_dsk].u4; return dsk_unit[cur_dsk].u4;
} }
@ -516,11 +513,11 @@ int32 fdcsec(int32 io, int32 data)
dsk_unit[cur_dsk].u5 = data & 0xFF; dsk_unit[cur_dsk].u5 = data & 0xFF;
if (dsk_unit[cur_dsk].u5 == 0) /* fix for swtp boot! */ if (dsk_unit[cur_dsk].u5 == 0) /* fix for swtp boot! */
dsk_unit[cur_dsk].u5 = 1; dsk_unit[cur_dsk].u5 = 1;
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcsec: Drive %d sector set to %d",
printf("\nfdcsec: Drive %d sector set to %d", cur_dsk, dsk_unit[cur_dsk].u5); cur_dsk, dsk_unit[cur_dsk].u5);
} }
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdcsec: Drive %d sector read as %d",
printf("\nfdcsec: Drive %d sector read as %d", cur_dsk, dsk_unit[cur_dsk].u5); cur_dsk, dsk_unit[cur_dsk].u5);
return dsk_unit[cur_dsk].u5; return dsk_unit[cur_dsk].u5;
} }
@ -533,8 +530,8 @@ int32 fdcdata(int32 io, int32 data)
if (io) { /* write byte to fdc */ if (io) { /* write byte to fdc */
fdcbyte = data; /* save for seek */ fdcbyte = data; /* save for seek */
if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes to buffer */ if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes to buffer */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcdata: Writing byte %d of %02X",
printf("\nfdcdata: Writing byte %d of %02X", dsk_unit[cur_dsk].pos, data); dsk_unit[cur_dsk].pos, data);
*((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) = data; /* byte into buffer */ *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) = data; /* byte into buffer */
dsk_unit[cur_dsk].pos++; /* step counter */ dsk_unit[cur_dsk].pos++; /* step counter */
if (dsk_unit[cur_dsk].pos == SECSIZ) { if (dsk_unit[cur_dsk].pos == SECSIZ) {
@ -543,21 +540,19 @@ int32 fdcdata(int32 io, int32 data)
sim_fwrite(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* write it */ sim_fwrite(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* write it */
wrt_flag = 0; /* clear write flag */ wrt_flag = 0; /* clear write flag */
} }
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &dsk_dev, "\nfdcdata: Sector write complete");
printf("\nfdcdata: Sector write complete");
} }
} }
return 0; return 0;
} else { /* read byte from fdc */ } else { /* read byte from fdc */
if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes from buffer */ if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes from buffer */
if (dsk_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &dsk_dev, "\nfdcdata: Reading byte %d u3=%02X",
printf("\nfdcdata: Reading byte %d u3=%02X", dsk_unit[cur_dsk].pos, dsk_unit[cur_dsk].u3); dsk_unit[cur_dsk].pos, dsk_unit[cur_dsk].u3);
val = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) & 0xFF; val = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) & 0xFF;
dsk_unit[cur_dsk].pos++; /* step counter */ dsk_unit[cur_dsk].pos++; /* step counter */
if (dsk_unit[cur_dsk].pos == SECSIZ) { /* done? */ if (dsk_unit[cur_dsk].pos == SECSIZ) { /* done? */
dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */ dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
if (dsk_dev.dctrl & DEBUG_write) sim_debug (DEBUG_read, &dsk_dev, "\nfdcdata: Sector read complete");
printf("\nfdcdata: Sector read complete");
} }
return val; return val;
} else } else

View file

@ -2,40 +2,46 @@
Copyright (c) 2011-2012, William A. Beech Copyright (c) 2011-2012, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated 2704 to 2764 EPROMs device on an 8-bit MODIFICATIONS:
computer system. This device allows the attachment of the device to a binary file
containing the EPROM code.
These functions support emulation of 0 to 4 2716 EPROM devices on a CPU board. 24 Apr 15 -- Modified to use simh_debug
The byte get and put routines use an offset into the boot EPROM image to locate
the proper byte. This allows another device to set the base address for each
EPROM.
This device uses a dynamically allocated buffer to hold each EPROM image. NOTES:
A call to BOOTROM_config will free the current buffer. A call to
i2716_reset will allocate a new buffer of 2048 bytes. A These functions support a simulated 2704 to 2764 EPROMs device on an 8-bit
call to BOOTROM_attach will load the buffer with the EPROM image. computer system. This device allows the attachment of the device to a binary file
containing the EPROM code.
These functions support emulation of 0 to 4 2716 EPROM devices on a CPU board.
The byte get and put routines use an offset into the boot EPROM image to locate
the proper byte. This allows another device to set the base address for each
EPROM.
This device uses a dynamically allocated buffer to hold each EPROM image.
A call to BOOTROM_config will free the current buffer. A call to
i2716_reset will allocate a new buffer of 2048 bytes. A
call to BOOTROM_attach will load the buffer with the EPROM image.
*/ */
#include <stdio.h> #include <stdio.h>
@ -110,23 +116,19 @@ t_stat i2716_attach (UNIT *uptr, char *cptr)
t_stat r; t_stat r;
FILE *fp; FILE *fp;
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716_attach: cptr=%s\n", cptr);
printf("i2716_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) { if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716_attach: Error\n");
printf("i2716_attach: Error\n");
return r; return r;
} }
if (i2716_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &i2716_dev, "\tOpen file\n");
printf("\tOpen file\n");
fp = fopen(uptr->filename, "rb"); /* open EPROM file */ fp = fopen(uptr->filename, "rb"); /* open EPROM file */
if (fp == NULL) { if (fp == NULL) {
printf("i2716%d: Unable to open ROM file %s\n", (int)(uptr - i2716_dev.units), uptr->filename); printf("i2716%d: Unable to open ROM file %s\n", (int)(uptr - i2716_dev.units), uptr->filename);
printf("\tNo ROM image loaded!!!\n"); printf("\tNo ROM image loaded!!!\n");
return SCPE_OK; return SCPE_OK;
} }
if (i2716_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &i2716_dev, "\tRead file\n");
printf("\tRead file\n");
j = 0; /* load EPROM file */ j = 0; /* load EPROM file */
c = fgetc(fp); c = fgetc(fp);
while (c != EOF) { while (c != EOF) {
@ -137,12 +139,10 @@ t_stat i2716_attach (UNIT *uptr, char *cptr)
break; break;
} }
} }
if (i2716_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &i2716_dev, "\tClose file\n");
printf("\tClose file\n");
fclose(fp); fclose(fp);
// printf("i2716%d: %d bytes of ROM image %s loaded\n",uptr - i2716_dev.units, j, uptr->filename); // printf("i2716%d: %d bytes of ROM image %s loaded\n",uptr - i2716_dev.units, j, uptr->filename);
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716_attach: Done\n");
printf("i2716_attach: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -153,20 +153,18 @@ t_stat i2716_reset (DEVICE *dptr)
int32 i, base; int32 i, base;
UNIT *uptr; UNIT *uptr;
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716_reset: \n");
printf("i2716_reset: \n");
for (i = 0; i < I2716_NUM; i++) { /* init all units */ for (i = 0; i < I2716_NUM; i++) { /* init all units */
uptr = i2716_dev.units + i; uptr = i2716_dev.units + i;
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716 %d unit.flags=%08X\n",
printf("i2716 %d unit.flags=%08X\n", i, uptr->flags); i, uptr->flags);
uptr->capac = 2048; uptr->capac = 2048;
uptr->u3 = 2048 * i; uptr->u3 = 2048 * i;
base = get_base(); base = get_base();
if (uptr->filebuf == NULL) { /* no buffer allocated */ if (uptr->filebuf == NULL) { /* no buffer allocated */
uptr->filebuf = malloc(2048); /* allocate EPROM buffer */ uptr->filebuf = malloc(2048); /* allocate EPROM buffer */
if (uptr->filebuf == NULL) { if (uptr->filebuf == NULL) {
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716_reset: Malloc error\n");
printf("i2716_reset: Malloc error\n");
return SCPE_MEM; return SCPE_MEM;
} }
} }
@ -180,8 +178,7 @@ t_stat i2716_reset (DEVICE *dptr)
// printf("i2716%d: No file attached\n", i); // printf("i2716%d: No file attached\n", i);
// } // }
} }
if (i2716_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &i2716_dev, "i2716_reset: Done\n");
printf("i2716_reset: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -202,19 +199,16 @@ int32 i2716_get_mbyte(int32 offset)
len = uptr->capac - 1; len = uptr->capac - 1;
if ((offset >= org) && (offset < (org + len))) { if ((offset >= org) && (offset < (org + len))) {
if (uptr->filebuf == NULL) { if (uptr->filebuf == NULL) {
if (i2716_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &i2716_dev, "i2716_get_mbyte: EPROM not configured\n");
printf("i2716_get_mbyte: EPROM not configured\n");
return 0xFF; return 0xFF;
} else { } else {
val = *((uint8 *)(uptr->filebuf) + (offset - org)); val = *((uint8 *)(uptr->filebuf) + (offset - org));
if (i2716_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &i2716_dev, " val=%04X\n", val);
printf(" val=%04X\n", val);
return (val & 0xFF); return (val & 0xFF);
} }
} }
} }
if (i2716_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &i2716_dev, "i2716_get_mbyte: Out of range\n");
printf("i2716_get_mbyte: Out of range\n");
return 0xFF; return 0xFF;
} }

View file

@ -2,70 +2,75 @@
Copyright (c) 2005-2012, William Beech Copyright (c) 2005-2012, William Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
cpu Motorola M6800 CPU MODIFICATIONS:
The register state for the M6800 CPU is: 23 Apr 15 -- Modified to use simh_debug
A<0:7> Accumulator A NOTES:
B<0:7> Accumulator B cpu Motorola M6800 CPU
IX<0:15> Index Register
CCR<0:7> Condition Code Register
HF half-carry flag
IF interrupt flag
NF negative flag
ZF zero flag
VF overflow flag
CF carry flag
PC<0:15> program counter
SP<0:15> Stack Pointer
The M6800 is an 8-bit CPU, which uses 16-bit registers to address The register state for the M6800 CPU is:
up to 64KB of memory.
The 72 basic instructions come in 1, 2, and 3-byte flavors. A<0:7> Accumulator A
B<0:7> Accumulator B
IX<0:15> Index Register
CCR<0:7> Condition Code Register
HF half-carry flag
IF interrupt flag
NF negative flag
ZF zero flag
VF overflow flag
CF carry flag
PC<0:15> program counter
SP<0:15> Stack Pointer
This routine is the instruction decode routine for the M6800. The M6800 is an 8-bit CPU, which uses 16-bit registers to address
It is called from the CPU board simulator to execute up to 64KB of memory.
instructions in simulated memory, starting at the simulated PC.
It runs until 'reason' is set non-zero.
General notes: The 72 basic instructions come in 1, 2, and 3-byte flavors.
1. Reasons to stop. The simulator can be stopped by: This routine is the instruction decode routine for the M6800.
It is called from the CPU board simulator to execute
instructions in simulated memory, starting at the simulated PC.
It runs until 'reason' is set non-zero.
WAI instruction General notes:
I/O error in I/O simulator
Invalid OP code (if ITRAP is set on CPU)
Invalid mamory address (if MTRAP is set on CPU)
2. Interrupts. 1. Reasons to stop. The simulator can be stopped by:
There are 4 types of interrupt, and in effect they do a
hardware CALL instruction to one of 4 possible high memory addresses.
3. Non-existent memory. WAI instruction
On the SWTP 6800, reads to non-existent memory I/O error in I/O simulator
return 0FFH, and writes are ignored. Invalid OP code (if ITRAP is set on CPU)
Invalid mamory address (if MTRAP is set on CPU)
2. Interrupts.
There are 4 types of interrupt, and in effect they do a
hardware CALL instruction to one of 4 possible high memory addresses.
3. Non-existent memory.
On the SWTP 6800, reads to non-existent memory
return 0FFH, and writes are ignored.
*/ */
#include <stdio.h> #include <stdio.h>
@ -1734,15 +1739,13 @@ int32 fetch_byte(int32 flag)
uint8 val; uint8 val;
val = CPU_BD_get_mbyte(PC) & 0xFF; /* fetch byte */ val = CPU_BD_get_mbyte(PC) & 0xFF; /* fetch byte */
if (m6800_dev.dctrl & DEBUG_asm) { /* display source code */ switch (flag) {
switch (flag) { case 0: /* opcode fetch */
case 0: /* opcode fetch */ sim_debug (DEBUG_asm, &m6800_dev, "%04X %s\n", PC, opcode[val]);
printf("\n%04X %s", PC, opcode[val]); break;
break; case 1: /* byte operand fetch */
case 1: /* byte operand fetch */ sim_debug (DEBUG_asm, &m6800_dev, "0%02XH\n", val);
printf("0%02XH", val); break;
break;
}
} }
PC = (PC + 1) & ADDRMASK; /* increment PC */ PC = (PC + 1) & ADDRMASK; /* increment PC */
return val; return val;
@ -1755,8 +1758,7 @@ int32 fetch_word(void)
val = CPU_BD_get_mbyte(PC) << 8; /* fetch high byte */ 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) & 0xFF; /* fetch low byte */
if (m6800_dev.dctrl & DEBUG_asm) sim_debug (DEBUG_asm, &m6800_dev, "0%04XH", val);
printf("0%04XH", val);
PC = (PC + 2) & ADDRMASK; /* increment PC */ PC = (PC + 2) & ADDRMASK; /* increment PC */
return val; return val;
} }

View file

@ -2,31 +2,37 @@
Copyright (c) 2011-2012, William A. Beech Copyright (c) 2011-2012, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated m6810 RAM device on a CPU board. The MODIFICATIONS:
byte get and put routines use an offset into the RAM image to locate the
proper byte. This allows another device to set the base address for the 24 Apr 15 -- Modified to use simh_debug
M6810.
NOTES:
These functions support a simulated m6810 RAM device on a CPU board. The
byte get and put routines use an offset into the RAM image to locate the
proper byte. This allows another device to set the base address for the
M6810.
*/ */
#include <stdio.h> #include <stdio.h>
@ -88,8 +94,7 @@ DEVICE m6810_dev = {
t_stat m6810_reset (DEVICE *dptr) t_stat m6810_reset (DEVICE *dptr)
{ {
if (m6810_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &m6810_dev, "m6810_reset: \n");
printf("m6810_reset: \n");
if (m6810_unit.filebuf == NULL) { if (m6810_unit.filebuf == NULL) {
m6810_unit.filebuf = malloc(128); m6810_unit.filebuf = malloc(128);
if (m6810_unit.filebuf == NULL) { if (m6810_unit.filebuf == NULL) {
@ -98,8 +103,7 @@ t_stat m6810_reset (DEVICE *dptr)
} }
m6810_unit.capac = 128; m6810_unit.capac = 128;
} }
if (m6810_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &m6810_dev, "m6810_reset: Done\n");
printf("m6810_reset: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -113,16 +117,13 @@ int32 m6810_get_mbyte(int32 offset)
{ {
int32 val; int32 val;
if (m6810_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &m6810_dev, "m6810_get_mbyte: offset=%04X\n", offset);
printf("m6810_get_mbyte: offset=%04X\n", offset);
if (((t_addr)offset) < m6810_unit.capac) { if (((t_addr)offset) < m6810_unit.capac) {
val = *((uint8 *)(m6810_unit.filebuf) + offset) & 0xFF; val = *((uint8 *)(m6810_unit.filebuf) + offset) & 0xFF;
if (m6810_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &m6810_dev, "val=%04X\n", val);
printf("val=%04X\n", val);
return val; return val;
} else { } else {
if (m6810_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &m6810_dev, "m6810_get_mbyte: out of range\n");
printf("m6810_get_mbyte: out of range\n");
return 0xFF; return 0xFF;
} }
} }
@ -131,14 +132,13 @@ int32 m6810_get_mbyte(int32 offset)
void m6810_put_mbyte(int32 offset, int32 val) void m6810_put_mbyte(int32 offset, int32 val)
{ {
if (m6810_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &m6810_dev, "m6810_put_mbyte: offset=%04X, val=%02X\n",
printf("m6810_put_mbyte: offset=%04X, val=%02X\n", offset, val); offset, val);
if ((t_addr)offset < m6810_unit.capac) { if ((t_addr)offset < m6810_unit.capac) {
*((uint8 *)(m6810_unit.filebuf) + offset) = val & 0xFF; *((uint8 *)(m6810_unit.filebuf) + offset) = val & 0xFF;
return; return;
} else { } else {
if (m6810_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &m6810_dev, "m6810_put_mbyte: out of range\n");
printf("m6810_put_mbyte: out of range\n");
return; return;
} }
} }

View file

@ -2,33 +2,39 @@
Copyright (c) 2011-2012, William A. Beech Copyright (c) 2011-2012, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support 6 simulated MP-8M memory cards on an SS-50 system. MODIFICATIONS:
Each unit uses a dynamically allocated 8192 byte buffer to hold the data. 24 Apr 15 -- Modified to use simh_debug
Each unit contains the base address in mp_8m_unit.u3. The unit capacity is
held in mp_8m_unit.capac. Each unit can be enabled or disabled to reconfigure NOTES:
the RAM for the system.
These functions support 6 simulated MP-8M memory cards on an SS-50 system.
Each unit uses a dynamically allocated 8192 byte buffer to hold the data.
Each unit contains the base address in mp_8m_unit.u3. The unit capacity is
held in mp_8m_unit.capac. Each unit can be enabled or disabled to reconfigure
the RAM for the system.
*/ */
#include <stdio.h> #include <stdio.h>
@ -101,12 +107,11 @@ t_stat mp_8m_reset (DEVICE *dptr)
int32 i, j, val; int32 i, j, val;
UNIT *uptr; UNIT *uptr;
if (mp_8m_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &mp_8m_dev, "mp_8m_reset: \n");
printf("mp_8m_reset: \n");
for (i = 0; i < MP_8M_NUM; i++) { /* init all units */ for (i = 0; i < MP_8M_NUM; i++) { /* init all units */
uptr = mp_8m_dev.units + i; uptr = mp_8m_dev.units + i;
if (mp_8m_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &mp_8m_dev, "MP-8M %d unit.flags=%08X\n",
printf("MP-8M %d unit.flags=%08X\n", i, uptr->flags); i, uptr->flags);
uptr->capac = 0x2000; uptr->capac = 0x2000;
if (i < 4) if (i < 4)
uptr->u3 = 0x2000 * i; uptr->u3 = 0x2000 * i;
@ -123,12 +128,10 @@ t_stat mp_8m_reset (DEVICE *dptr)
*((uint8 *)(uptr->filebuf) + j) = val & 0xFF; *((uint8 *)(uptr->filebuf) + j) = val & 0xFF;
} }
} }
if (mp_8m_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &mp_8m_dev, "MP-8M %d initialized at [%04X-%04XH]\n",
printf("MP-8M %d initialized at [%04X-%04XH]\n", i, uptr->u3, i, uptr->u3, uptr->u3 + uptr->capac - 1);
uptr->u3 + uptr->capac - 1);
} }
if (mp_8m_dev.dctrl & DEBUG_flow) sim_debug (DEBUG_flow, &mp_8m_dev, "mp_8m_reset: Done\n");
printf("mp_8m_reset: Done\n");
return SCPE_OK; return SCPE_OK;
} }
@ -144,21 +147,18 @@ int32 mp_8m_get_mbyte(int32 addr)
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
if (mp_8m_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &mp_8m_dev, "mp_8m_get_mbyte: addr=%04X", addr);
printf("mp_8m_get_mbyte: addr=%04X", addr);
for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */ for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */
uptr = mp_8m_dev.units + i; uptr = mp_8m_dev.units + i;
org = uptr->u3; org = uptr->u3;
len = uptr->capac - 1; len = uptr->capac - 1;
if ((addr >= org) && (addr <= org + len)) { if ((addr >= org) && (addr <= org + len)) {
val = *((uint8 *)(uptr->filebuf) + (addr - org)); val = *((uint8 *)(uptr->filebuf) + (addr - org));
if (mp_8m_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &mp_8m_dev, " val=%04X\n", val);
printf(" val=%04X\n", val);
return (val & 0xFF); return (val & 0xFF);
} }
} }
if (mp_8m_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &mp_8m_dev, "mp_8m_get_mbyte: Out of range\n");
printf("mp_8m_get_mbyte: Out of range\n");
return 0xFF; /* multibus has active high pullups */ return 0xFF; /* multibus has active high pullups */
} }
@ -181,21 +181,19 @@ void mp_8m_put_mbyte(int32 addr, int32 val)
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
if (mp_8m_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &mp_8m_dev, "mp_8m_put_mbyte: addr=%04X, val=%02X",
printf("mp_8m_put_mbyte: addr=%04X, val=%02X", addr, val); addr, val);
for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */ for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */
uptr = mp_8m_dev.units + i; uptr = mp_8m_dev.units + i;
org = uptr->u3; org = uptr->u3;
len = uptr->capac - 1; len = uptr->capac - 1;
if ((addr >= org) && (addr < org + len)) { if ((addr >= org) && (addr < org + len)) {
*((uint8 *)(uptr->filebuf) + (addr - org)) = val & 0xFF; *((uint8 *)(uptr->filebuf) + (addr - org)) = val & 0xFF;
if (mp_8m_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &mp_8m_dev, "\n");
printf("\n");
return; return;
} }
} }
if (mp_8m_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &mp_8m_dev, "mp_8m_put_mbyte: Out of range\n");
printf("mp_8m_put_mbyte: Out of range\n");
} }
/* put a word into memory */ /* put a word into memory */

View file

@ -2,35 +2,41 @@
Copyright (c) 2011-2012, William Beech Copyright (c) 2011-2012, William Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
The MP-A CPU Board contains the following devices [mp-a.c]: MODIFICATIONS:
M6800 processor [m6800.c].
M6810 128 byte RAM at 0xA000 [m6810.c]. 24 Apr 15 -- Modified to use simh_debug
M6830, SWTBUG, or custom boot ROM at 0xE000 [bootrom.c].
Interface to the SS-50 bus and the MP-B2 Mother Board for I/O NOTES:
and memory boards [mp-b2.c].
Note: The file names of the emulator source programs for each device are The MP-A CPU Board contains the following devices [mp-a.c]:
contained in "[]". M6800 processor [m6800.c].
M6810 128 byte RAM at 0xA000 [m6810.c].
M6830, SWTBUG, or custom boot ROM at 0xE000 [bootrom.c].
Interface to the SS-50 bus and the MP-B2 Mother Board for I/O
and memory boards [mp-b2.c].
Note: The file names of the emulator source programs for each device are
contained in "[]".
*/ */
#include <stdio.h> #include <stdio.h>
@ -128,35 +134,29 @@ int32 CPU_BD_get_mbyte(int32 addr)
{ {
int32 val; int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: addr=%04X\n", addr);
printf("CPU_BD_get_mbyte: addr=%04X\n", addr);
switch(addr & 0xF000) { switch(addr & 0xF000) {
case 0xA000: case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) { if (CPU_BD_unit.flags & UNIT_RAM) {
val = m6810_get_mbyte(addr - 0xA000) & 0xFF; val = m6810_get_mbyte(addr - 0xA000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: m6810 val=%02X\n", val);
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val; return val;
} else { } else {
val = MB_get_mbyte(addr) & 0xFF; val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: m6810 val=%02X\n", val);
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val; return val;
} }
case 0xE000: case 0xE000:
val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF; val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: EPROM=%02X\n", val);
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val; return val;
case 0xF000: case 0xF000:
val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF; val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: EPROM=%02X\n", val);
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val; return val;
default: default:
val = MB_get_mbyte(addr) & 0xFF; val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: mp_b2 val=%02X\n", val);
printf("CPU_BD_get_mbyte: mp_b2 val=%02X\n", val);
return val; return val;
} }
} }
@ -167,13 +167,11 @@ int32 CPU_BD_get_mword(int32 addr)
{ {
int32 val; int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mword: addr=%04X\n", addr);
printf("CPU_BD_get_mword: addr=%04X\n", addr);
val = (CPU_BD_get_mbyte(addr) << 8); val = (CPU_BD_get_mbyte(addr) << 8);
val |= CPU_BD_get_mbyte(addr+1); val |= CPU_BD_get_mbyte(addr+1);
val &= 0xFFFF; val &= 0xFFFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mword: val=%04X\n", val);
printf("CPU_BD_get_mword: val=%04X\n", val);
return val; return val;
} }
@ -181,8 +179,8 @@ int32 CPU_BD_get_mword(int32 addr)
void CPU_BD_put_mbyte(int32 addr, int32 val) void CPU_BD_put_mbyte(int32 addr, int32 val)
{ {
if (CPU_BD_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &CPU_BD_dev, "CPU_BD_put_mbyte: addr=%04X, val=%02X\n",
printf("CPU_BD_put_mbyte: addr=%04X, val=%02X\n", addr, val); addr, val);
switch(addr & 0xF000) { switch(addr & 0xF000) {
case 0xA000: case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) { if (CPU_BD_unit.flags & UNIT_RAM) {
@ -202,8 +200,8 @@ void CPU_BD_put_mbyte(int32 addr, int32 val)
void CPU_BD_put_mword(int32 addr, int32 val) void CPU_BD_put_mword(int32 addr, int32 val)
{ {
if (CPU_BD_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &CPU_BD_dev, "CPU_BD_put_mword: addr=%04X, val=%04X\n",
printf("CPU_BD_put_mword: addr=%04X, val=%04X\n", addr, val); addr, val);
CPU_BD_put_mbyte(addr, val >> 8); CPU_BD_put_mbyte(addr, val >> 8);
CPU_BD_put_mbyte(addr+1, val); CPU_BD_put_mbyte(addr+1, val);
} }

View file

@ -2,37 +2,43 @@
Copyright (c) 2011-2012, William Beech Copyright (c) 2011-2012, William Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
The MP-A2 CPU Board contains the following devices [mp-a2.c]: MODIFICATIONS:
M6800 processor [m6800.c].
M6810 128 byte RAM at 0xA000 [m6810.c]. 24 Apr 15 -- Modified to use simh_debug
M6830, SWTBUG, or custom boot ROM at 0xE000 [bootrom.c].
4 ea 2716 EPROMs at either 0xC000, 0xC800, 0xD000 and 0xD800 (LO_PROM)or NOTES:
0xE000, 0xE800, 0xF000 and 0xF800 (HI_PROM) [eprom.c].
Interface to the SS-50 bus and the MP-B2 Mother Board for I/O The MP-A2 CPU Board contains the following devices [mp-a2.c]:
and memory boards [mp-b2.c]. M6800 processor [m6800.c].
Note: The file names of the emulator source programs for each device are M6810 128 byte RAM at 0xA000 [m6810.c].
contained in "[]". M6830, SWTBUG, or custom boot ROM at 0xE000 [bootrom.c].
4 ea 2716 EPROMs at either 0xC000, 0xC800, 0xD000 and 0xD800 (LO_PROM)or
0xE000, 0xE800, 0xF000 and 0xF800 (HI_PROM) [eprom.c].
Interface to the SS-50 bus and the MP-B2 Mother Board for I/O
and memory boards [mp-b2.c].
Note: The file names of the emulator source programs for each device are
contained in "[]".
*/ */
#include <stdio.h> #include <stdio.h>
@ -169,46 +175,39 @@ int32 CPU_BD_get_mbyte(int32 addr)
{ {
int32 val; int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: addr=%04X\n", addr);
printf("CPU_BD_get_mbyte: addr=%04X\n", addr);
switch(addr & 0xF000) { switch(addr & 0xF000) {
case 0xA000: case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) { if (CPU_BD_unit.flags & UNIT_RAM) {
val = m6810_get_mbyte(addr - 0xA000) & 0xFF; val = m6810_get_mbyte(addr - 0xA000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: m6810 val=%02X\n", val);
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val; return val;
} else { } else {
val = MB_get_mbyte(addr) & 0xFF; val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: m6810 val=%02X\n", val);
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val; return val;
} }
case 0xC000: case 0xC000:
if (CPU_BD_unit.flags & UNIT_LO_PROM) { if (CPU_BD_unit.flags & UNIT_LO_PROM) {
val = i2716_get_mbyte(addr - 0xC000) & 0xFF; val = i2716_get_mbyte(addr - 0xC000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: 2716=%02X\n", val);
printf("CPU_BD_get_mbyte: 2716=%02X\n", val);
return val; return val;
} else } else
return 0xFF; return 0xFF;
break; break;
case 0xE000: case 0xE000:
val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF; val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: EPROM=%02X\n", val);
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val; return val;
case 0xF000: case 0xF000:
if (CPU_BD_unit.flags & UNIT_MON) { if (CPU_BD_unit.flags & UNIT_MON) {
val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF; val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: EPROM=%02X\n", val);
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val; return val;
} }
default: default:
val = MB_get_mbyte(addr) & 0xFF; val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mbyte: mp_b2 val=%02X\n", val);
printf("CPU_BD_get_mbyte: mp_b2 val=%02X\n", val);
return val; return val;
} }
} }
@ -219,13 +218,11 @@ int32 CPU_BD_get_mword(int32 addr)
{ {
int32 val; int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mword: addr=%04X\n", addr);
printf("CPU_BD_get_mword: addr=%04X\n", addr);
val = (CPU_BD_get_mbyte(addr) << 8); val = (CPU_BD_get_mbyte(addr) << 8);
val |= CPU_BD_get_mbyte(addr+1); val |= CPU_BD_get_mbyte(addr+1);
val &= 0xFFFF; val &= 0xFFFF;
if (CPU_BD_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &CPU_BD_dev, "CPU_BD_get_mword: val=%04X\n", val);
printf("CPU_BD_get_mword: val=%04X\n", val);
return val; return val;
} }
@ -233,8 +230,8 @@ int32 CPU_BD_get_mword(int32 addr)
void CPU_BD_put_mbyte(int32 addr, int32 val) void CPU_BD_put_mbyte(int32 addr, int32 val)
{ {
if (CPU_BD_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &CPU_BD_dev, "CPU_BD_put_mbyte: addr=%04X, val=%02X\n",
printf("CPU_BD_put_mbyte: addr=%04X, val=%02X\n", addr, val); addr, val);
switch(addr & 0xF000) { switch(addr & 0xF000) {
case 0xA000: case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) { if (CPU_BD_unit.flags & UNIT_RAM) {
@ -254,8 +251,8 @@ void CPU_BD_put_mbyte(int32 addr, int32 val)
void CPU_BD_put_mword(int32 addr, int32 val) void CPU_BD_put_mword(int32 addr, int32 val)
{ {
if (CPU_BD_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &CPU_BD_dev, "CPU_BD_put_mword: addr=%04X, val=%04X\n",
printf("CPU_BD_put_mword: addr=%04X, val=%04X\n", addr, val); addr, val);
CPU_BD_put_mbyte(addr, val >> 8); CPU_BD_put_mbyte(addr, val >> 8);
CPU_BD_put_mbyte(addr+1, val); CPU_BD_put_mbyte(addr+1, val);
} }

View file

@ -2,26 +2,33 @@
Copyright (c) 2011-2012, William A. Beech Copyright (c) 2011-2012, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
24 Apr 15 -- Modified to use simh_debug
NOTES:
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
*/ */
#include <stdio.h> #include <stdio.h>
@ -174,13 +181,13 @@ int32 MB_get_mbyte(int32 addr)
{ {
int32 val; int32 val;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: addr=%04X\n", addr);
printf("MB_get_mbyte: addr=%04X\n", addr);
switch(addr & 0xF000) { switch(addr & 0xF000) {
case 0x0000: case 0x0000:
case 0x1000: case 0x1000:
if (MB_unit.flags & UNIT_RAM_0000) { if (MB_unit.flags & UNIT_RAM_0000) {
val = mp_8m_get_mbyte(addr) & 0xFF; val = mp_8m_get_mbyte(addr) & 0xFF;
sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: addr=%04X\n", addr);
if (MB_dev.dctrl & DEBUG_read) if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val); printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val; return val;
@ -190,8 +197,7 @@ int32 MB_get_mbyte(int32 addr)
case 0x3000: case 0x3000:
if (MB_unit.flags & UNIT_RAM_2000) { if (MB_unit.flags & UNIT_RAM_2000) {
val = mp_8m_get_mbyte(addr) & 0xFF; val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: mp_8m val=%02X\n", val);
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val; return val;
} else } else
return 0xFF; return 0xFF;
@ -199,6 +205,7 @@ int32 MB_get_mbyte(int32 addr)
case 0x5000: case 0x5000:
if (MB_unit.flags & UNIT_RAM_4000) { if (MB_unit.flags & UNIT_RAM_4000) {
val = mp_8m_get_mbyte(addr) & 0xFF; val = mp_8m_get_mbyte(addr) & 0xFF;
sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: addr=%04X\n", addr);
if (MB_dev.dctrl & DEBUG_read) if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val); printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val; return val;
@ -208,8 +215,7 @@ int32 MB_get_mbyte(int32 addr)
case 0x7000: case 0x7000:
if (MB_unit.flags & UNIT_RAM_6000) { if (MB_unit.flags & UNIT_RAM_6000) {
val = mp_8m_get_mbyte(addr) & 0xFF; val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: mp_8m val=%02X\n", val);
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val; return val;
} else } else
return 0xFF; return 0xFF;
@ -218,15 +224,14 @@ int32 MB_get_mbyte(int32 addr)
val = (dev_table[addr - 0x8000].routine(0, 0)) & 0xFF; val = (dev_table[addr - 0x8000].routine(0, 0)) & 0xFF;
else else
val = 0xFF; val = 0xFF;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: I/O addr=%04X val=%02X\n",
printf("MB_get_mbyte: I/O addr=%04X val=%02X\n", addr, val); addr, val);
return val; return val;
case 0xA000: case 0xA000:
case 0xB000: case 0xB000:
if (MB_unit.flags & UNIT_RAM_A000) { if (MB_unit.flags & UNIT_RAM_A000) {
val = mp_8m_get_mbyte(addr) & 0xFF; val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: mp_8m val=%02X\n", val);
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val; return val;
} else } else
return 0xFF; return 0xFF;
@ -234,8 +239,7 @@ int32 MB_get_mbyte(int32 addr)
case 0xD000: case 0xD000:
if (MB_unit.flags & UNIT_RAM_C000) { if (MB_unit.flags & UNIT_RAM_C000) {
val = mp_8m_get_mbyte(addr) & 0xFF; val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mbyte: mp_8m val=%02X\n", val);
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val; return val;
} else } else
return 0xFF; return 0xFF;
@ -250,14 +254,11 @@ int32 MB_get_mword(int32 addr)
{ {
int32 val; int32 val;
sim_debug (DEBUG_read, &MB_dev, "MB_get_mword: addr=%04X\n", addr);
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mword: addr=%04X\n", addr);
val = (MB_get_mbyte(addr) << 8); val = (MB_get_mbyte(addr) << 8);
val |= MB_get_mbyte(addr+1); val |= MB_get_mbyte(addr+1);
val &= 0xFFFF; val &= 0xFFFF;
if (MB_dev.dctrl & DEBUG_read) sim_debug (DEBUG_read, &MB_dev, "MB_get_mword: val=%04X\n", val);
printf("MB_get_mword: val=%04X\n", val);
return val; return val;
} }
@ -265,8 +266,8 @@ int32 MB_get_mword(int32 addr)
void MB_put_mbyte(int32 addr, int32 val) void MB_put_mbyte(int32 addr, int32 val)
{ {
if (MB_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &MB_dev, "MB_put_mbyte: addr=%04X, val=%02X\n",
printf("MB_put_mbyte: addr=%04X, val=%02X\n", addr, val); addr, val);
switch(addr & 0xF000) { switch(addr & 0xF000) {
case 0x0000: case 0x0000:
case 0x1000: case 0x1000:
@ -317,8 +318,7 @@ void MB_put_mbyte(int32 addr, int32 val)
void MB_put_mword(int32 addr, int32 val) void MB_put_mword(int32 addr, int32 val)
{ {
if (MB_dev.dctrl & DEBUG_write) sim_debug (DEBUG_write, &MB_dev, "MB_ptt_mword: addr=%04X, val=%04X\n", addr, val);
printf("MB_ptt_mword: addr=%04X, val=%04X\n", addr, val);
MB_put_mbyte(addr, val >> 8); MB_put_mbyte(addr, val >> 8);
MB_put_mbyte(addr+1, val); MB_put_mbyte(addr+1, val);
} }

View file

@ -2,53 +2,59 @@
Copyright (c) 2005-2012, William Beech Copyright (c) 2005-2012, William Beech
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the 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: Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Willaim Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER Willaim 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 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. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech. in this Software without prior written authorization from William A. Beech.
These functions support a simulated SWTP MP-S interface card. MODIFICATIONS:
The card contains one M6850 ACIA. The ACIA implements one complete
serial port. It provides 7 or 8-bit ASCII RS-232 interface to Terminals
or 20 mA current loop interface to a model 33 or 37 Teletype. It is not
compatible with baudot Teletypes. Baud rates from 110 to 1200 are
switch selectable from S! on the MP-S. The ACIA ports appear at all
4 addresses. This fact is used by SWTBUG to determine the presence of the
MP-S vice MP-C serial card. The ACIA interrupt request line can be connected
to the IRQ or NMI interrupt lines by a jumper on the MP-S.
All I/O is via either programmed I/O or interrupt controlled I/O. 24 Apr 15 -- Modified to use simh_debug
It has a status port and a data port. A write to the status port
can select some options for the device (0x03 will reset the port).
A read of the status port gets the port status:
+---+---+---+---+---+---+---+---+ NOTES:
| I | P | O | F |CTS|DCD|TXE|RXF|
+---+---+---+---+---+---+---+---+
RXF - A 1 in this bit position means a character has been received These functions support a simulated SWTP MP-S interface card.
on the data port and is ready to be read. The card contains one M6850 ACIA. The ACIA implements one complete
TXE - A 1 in this bit means the port is ready to receive a character serial port. It provides 7 or 8-bit ASCII RS-232 interface to Terminals
on the data port and transmit it out over the serial line. or 20 mA current loop interface to a model 33 or 37 Teletype. It is not
compatible with baudot Teletypes. Baud rates from 110 to 1200 are
switch selectable from S! on the MP-S. The ACIA ports appear at all
4 addresses. This fact is used by SWTBUG to determine the presence of the
MP-S vice MP-C serial card. The ACIA interrupt request line can be connected
to the IRQ or NMI interrupt lines by a jumper on the MP-S.
A read to the data port gets the buffered character, a write All I/O is via either programmed I/O or interrupt controlled I/O.
to the data port writes the character to the device. It has a status port and a data port. A write to the status port
can select some options for the device (0x03 will reset the port).
A read of the status port gets the port status:
+---+---+---+---+---+---+---+---+
| I | P | O | F |CTS|DCD|TXE|RXF|
+---+---+---+---+---+---+---+---+
RXF - A 1 in this bit position means a character has been received
on the data port and is ready to be read.
TXE - A 1 in this bit means the port is ready to receive a character
on the data port and transmit it out over the serial line.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/ */
#include <stdio.h> #include <stdio.h>