MDS-800: Initial simulator commit

This commit is contained in:
nj7p 2015-04-11 15:00:04 -07:00 committed by Mark Pizzolato
parent cd799c9d3f
commit 4179eeb19f
34 changed files with 16359 additions and 0 deletions

View file

@ -0,0 +1,44 @@
/* 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

211
MDS-800/MDS-800/Mds-800.txt Normal file
View file

@ -0,0 +1,211 @@
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

BIN
MDS-800/MDS-800/Mds-800.vsd Normal file

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,81 @@
/* 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

@ -0,0 +1,84 @@
/* 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

@ -0,0 +1,211 @@
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

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,41 @@
/* system_80_10.cfg: Intel System 80/10 simulator definitions
This file holds the configuration for the System 80/10
boards I/O and Memory.
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.
16 Dec 12 - Original file
*/
/* 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

View file

@ -0,0 +1,78 @@
/* 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.
*/
#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 System 80/10";
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

@ -0,0 +1,81 @@
/* 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.
*/
#include <stdio.h>
#include <ctype.h>
#include "system_80_10.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 */

2002
MDS-800/common/i8008.c Normal file

File diff suppressed because it is too large Load diff

1438
MDS-800/common/i8080.c Normal file

File diff suppressed because it is too large Load diff

4746
MDS-800/common/i8088.c Normal file

File diff suppressed because it is too large Load diff

252
MDS-800/common/i8251.c Normal file
View file

@ -0,0 +1,252 @@
/* 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 */

459
MDS-800/common/i8255.c Normal file
View file

@ -0,0 +1,459 @@
/* i8255.c: Intel i8255 PIO 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 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.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
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
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
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 */
#define i8255_DEV 4 /* number of devices */
/* function prototypes */
int32 i8255s0(int32 io, int32 data);
int32 i8255a0(int32 io, int32 data);
int32 i8255b0(int32 io, int32 data);
int32 i8255c0(int32 io, int32 data);
int32 i8255s1(int32 io, int32 data);
int32 i8255a1(int32 io, int32 data);
int32 i8255b1(int32 io, int32 data);
int32 i8255c1(int32 io, int32 data);
int32 i8255s2(int32 io, int32 data);
int32 i8255a2(int32 io, int32 data);
int32 i8255b2(int32 io, int32 data);
int32 i8255c2(int32 io, int32 data);
int32 i8255s3(int32 io, int32 data);
int32 i8255a3(int32 io, int32 data);
int32 i8255b3(int32 io, int32 data);
int32 i8255c3(int32 io, int32 data);
t_stat i8255_reset (DEVICE *dptr, int32 base);
/* external function prototypes */
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* globals */
int32 i8255_cnt = 0;
uint8 i8255_base[i8255_DEV];
/* i8255 Standard I/O Data Structures */
UNIT i8255_unit[] = {
{ UDATA (0, 0, 0) },
{ UDATA (0, 0, 0) },
{ UDATA (0, 0, 0) },
{ UDATA (0, 0, 0) }
};
DEBTAB i8255_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
REG i8255_reg[] = {
{ HRDATA (CONTROL0, i8255_unit[0].u3, 8) },
{ HRDATA (PORTA0, i8255_unit[0].u4, 8) },
{ HRDATA (PORTB0, i8255_unit[0].u5, 8) },
{ HRDATA (PORTC0, i8255_unit[0].u6, 8) },
{ HRDATA (CONTROL1, i8255_unit[1].u3, 8) },
{ HRDATA (PORTA1, i8255_unit[1].u4, 8) },
{ HRDATA (PORTB1, i8255_unit[1].u5, 8) },
{ HRDATA (PORTC1, i8255_unit[1].u6, 8) },
{ HRDATA (CONTROL1, i8255_unit[2].u3, 8) },
{ HRDATA (PORTA1, i8255_unit[2].u4, 8) },
{ HRDATA (PORTB1, i8255_unit[2].u5, 8) },
{ HRDATA (PORTC1, i8255_unit[2].u6, 8) },
{ HRDATA (CONTROL1, i8255_unit[3].u3, 8) },
{ HRDATA (PORTA1, i8255_unit[3].u4, 8) },
{ HRDATA (PORTB1, i8255_unit[3].u5, 8) },
{ HRDATA (PORTC1, i8255_unit[3].u6, 8) },
{ NULL }
};
DEVICE i8255_dev = {
"8255", //name
i8255_unit, //units
i8255_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8255_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8255_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 i8255s0(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[0].u3 = data;
printf("8255-0: Mode Instruction=%02X\n", data);
if (data & 0x64)
printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a0(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[0].u4);
} else { /* write data port */
i8255_unit[0].u4 = data;
printf("8255-0: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b0(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[0].u5);
} else { /* write data port */
i8255_unit[0].u5 = data;
printf("8255-0: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c0(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[0].u6);
} else { /* write data port */
i8255_unit[0].u6 = data;
printf("8255-0: Port C = %02X\n", data);
}
return 0;
}
int32 i8255s1(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[1].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[1].u3 = data;
printf("8255-1: Mode Instruction=%02X\n", data);
if (data & 0x64)
printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[1].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[1].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[1].u4);
} else { /* write data port */
i8255_unit[1].u4 = data;
printf("8255-1: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[1].u5);
} else { /* write data port */
i8255_unit[1].u5 = data;
printf("8255-1: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[1].u6);
} else { /* write data port */
i8255_unit[1].u6 = data;
printf("8255-1: Port C = %02X\n", data);
}
return 0;
}
int32 i8255s2(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[2].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[2].u3 = data;
printf("8255-2: Mode Instruction=%02X\n", data);
if (data & 0x64)
printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[2].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[2].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a2(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[2].u4);
} else { /* write data port */
i8255_unit[2].u4 = data;
printf("8255-2: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b2(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[2].u5);
} else { /* write data port */
i8255_unit[2].u5 = data;
printf("8255-2: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c2(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[2].u6);
} else { /* write data port */
i8255_unit[2].u6 = data;
printf("8255-2: Port C = %02X\n", data);
}
return 0;
}
int32 i8255s3(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return i8255_unit[3].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
i8255_unit[3].u3 = data;
printf("8255-3: Mode Instruction=%02X\n", data);
if (data & 0x64)
printf("\n Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
i8255_unit[3].u6 |= (0x01 << bit);
} else { /* reset bit */
i8255_unit[3].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 i8255a3(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[3].u4);
} else { /* write data port */
i8255_unit[3].u4 = data;
printf("8255-3: Port A = %02X\n", data);
}
return 0;
}
int32 i8255b3(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[3].u5);
} else { /* write data port */
i8255_unit[3].u5 = data;
printf("8255-3: Port B = %02X\n", data);
}
return 0;
}
int32 i8255c3(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8255_unit[3].u6);
} else { /* write data port */
i8255_unit[3].u6 = data;
printf("8255-3: Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat i8255_reset (DEVICE *dptr, int32 base)
{
switch (i8255_cnt) {
case 0:
reg_dev(i8255a0, base);
reg_dev(i8255b0, base + 1);
reg_dev(i8255c0, base + 2);
reg_dev(i8255s0, base + 3);
i8255_unit[0].u3 = 0x9B; /* control */
i8255_unit[0].u4 = 0xFF; /* Port A */
i8255_unit[0].u5 = 0xFF; /* Port B */
i8255_unit[0].u6 = 0xFF; /* Port C */
printf(" 8255-0: Reset\n");
break;
case 1:
reg_dev(i8255a1, base);
reg_dev(i8255b1, base + 1);
reg_dev(i8255c1, base + 2);
reg_dev(i8255s1, base + 3);
i8255_unit[1].u3 = 0x9B; /* control */
i8255_unit[1].u4 = 0xFF; /* Port A */
i8255_unit[1].u5 = 0xFF; /* Port B */
i8255_unit[1].u6 = 0xFF; /* Port C */
printf(" 8255-1: Reset\n");
break;
case 2:
reg_dev(i8255a2, base);
reg_dev(i8255b2, base + 1);
reg_dev(i8255c2, base + 2);
reg_dev(i8255s2, base + 3);
i8255_unit[2].u3 = 0x9B; /* control */
i8255_unit[2].u4 = 0xFF; /* Port A */
i8255_unit[2].u5 = 0xFF; /* Port B */
i8255_unit[2].u6 = 0xFF; /* Port C */
printf(" 8255-2: Reset\n");
break;
case 3:
reg_dev(i8255a3, base);
reg_dev(i8255b3, base + 1);
reg_dev(i8255c3, base + 2);
reg_dev(i8255s3, base + 3);
i8255_unit[3].u3 = 0x9B; /* control */
i8255_unit[3].u4 = 0xFF; /* Port A */
i8255_unit[3].u5 = 0xFF; /* Port B */
i8255_unit[3].u6 = 0xFF; /* Port C */
printf(" 8255-3: Reset\n");
break;
default:
printf(" 8255: Bad device\n");
}
printf(" 8255-%d: Registered at %02X\n", i8255_cnt, base);
i8255_cnt++;
return SCPE_OK;
}
/* end of i8255.c */

304
MDS-800/common/i8259.c Normal file
View file

@ -0,0 +1,304 @@
/* i8259.c: Intel i8259 PIC 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 i8259 interface device on an iSBC.
24 Jan 13 - Original file.
*/
#include "system_defs.h" /* system header in system dir */
#define i8259_DEV 2 /* number of devices */
/* function prototypes */
int32 i8259a0(int32 io, int32 data);
int32 i8259b0(int32 io, int32 data);
int32 i8259a1(int32 io, int32 data);
int32 i8259b1(int32 io, int32 data);
void i8259_dump(int32 dev);
t_stat i8259_reset (DEVICE *dptr, int32 base);
/* external function prototypes */
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* globals */
int32 i8259_cnt = 0;
uint8 i8259_base[i8259_DEV];
uint8 i8259_icw1[i8259_DEV];
uint8 i8259_icw2[i8259_DEV];
uint8 i8259_icw3[i8259_DEV];
uint8 i8259_icw4[i8259_DEV];
uint8 i8259_ocw1[i8259_DEV];
uint8 i8259_ocw2[i8259_DEV];
uint8 i8259_ocw3[i8259_DEV];
int32 icw_num0 = 1, icw_num1 = 1;
/* i8255 Standard I/O Data Structures */
UNIT i8259_unit[] = {
{ UDATA (0, 0, 0) },
{ UDATA (0, 0, 0) }
};
DEBTAB i8259_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
REG i8259_reg[] = {
{ HRDATA (IRR0, i8259_unit[0].u3, 8) },
{ HRDATA (ISR0, i8259_unit[0].u4, 8) },
{ HRDATA (IMR0, i8259_unit[0].u5, 8) },
{ HRDATA (IRR1, i8259_unit[1].u3, 8) },
{ HRDATA (ISR1, i8259_unit[1].u4, 8) },
{ HRDATA (IMR1, i8259_unit[1].u5, 8) },
{ NULL }
};
DEVICE i8259_dev = {
"8259", //name
i8259_unit, //units
i8259_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8259_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
i8259_debug, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 i8259a0(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read data port */
if ((i8259_ocw3[0] & 0x03) == 0x02)
return (i8259_unit[0].u3); /* IRR */
if ((i8259_ocw3[0] & 0x03) == 0x03)
return (i8259_unit[0].u4); /* ISR */
} else { /* write data port */
if (data & 0x10) {
icw_num0 = 1;
}
if (icw_num0 == 1) {
i8259_icw1[0] = data; /* ICW1 */
i8259_unit[0].u5 = 0x00; /* clear IMR */
i8259_ocw3[0] = 0x02; /* clear OCW3, Sel IRR */
} else {
switch (data & 0x18) {
case 0: /* OCW2 */
i8259_ocw2[0] = data;
break;
case 8: /* OCW3 */
i8259_ocw3[0] = data;
break;
default:
printf("8259b-0: OCW Error %02X\n", data);
break;
}
}
printf("8259a-0: data = %02X\n", data);
icw_num0++; /* step ICW number */
}
i8259_dump(0);
return 0;
}
int32 i8259b0(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8259_unit[0].u5); /* IMR */
} else { /* write data port */
if (icw_num0 >= 2 && icw_num0 < 5) { /* ICW mode */
switch (icw_num0) {
case 2: /* ICW2 */
i8259_icw2[0] = data;
break;
case 3: /* ICW3 */
i8259_icw3[0] = data;
break;
case 4: /* ICW4 */
if (i8259_icw1[0] & 0x01)
i8259_icw4[0] = data;
else
printf("8259b-0: ICW4 not enabled - data=%02X\n", data);
break;
default:
printf("8259b-0: ICW Error %02X\n", data);
break;
}
icw_num0++;
} else {
i8259_ocw1[0] = data; /* OCW0 */
}
}
i8259_dump(0);
return 0;
}
int32 i8259a1(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read data port */
if ((i8259_ocw3[1] & 0x03) == 0x02)
return (i8259_unit[1].u3); /* IRR */
if ((i8259_ocw3[1] & 0x03) == 0x03)
return (i8259_unit[1].u4); /* ISR */
} else { /* write data port */
if (data & 0x10) {
icw_num1 = 1;
}
if (icw_num1 == 1) {
i8259_icw1[1] = data; /* ICW1 */
i8259_unit[1].u5 = 0x00; /* clear IMR */
i8259_ocw3[1] = 0x02; /* clear OCW3, Sel IRR */
} else {
switch (data & 0x18) {
case 0: /* OCW2 */
i8259_ocw2[1] = data;
break;
case 8: /* OCW3 */
i8259_ocw3[1] = data;
break;
default:
printf("8259b-1: OCW Error %02X\n", data);
break;
}
}
printf("8259a-1: data = %02X\n", data);
icw_num1++; /* step ICW number */
}
i8259_dump(1);
return 0;
}
int32 i8259b1(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (i8259_unit[1].u5); /* IMR */
} else { /* write data port */
if (icw_num1 >= 2 && icw_num1 < 5) { /* ICW mode */
switch (icw_num1) {
case 2: /* ICW2 */
i8259_icw2[1] = data;
break;
case 3: /* ICW3 */
i8259_icw3[1] = data;
break;
case 4: /* ICW4 */
if (i8259_icw1[1] & 0x01)
i8259_icw4[1] = data;
else
printf("8259b-1: ICW4 not enabled - data=%02X\n", data);
break;
default:
printf("8259b-1: ICW Error %02X\n", data);
break;
}
icw_num1++;
} else {
i8259_ocw1[1] = data; /* OCW0 */
}
}
i8259_dump(1);
return 0;
}
void i8259_dump(int32 dev)
{
printf("Device %d\n", dev);
printf(" IRR = %02X\n", i8259_unit[dev].u3);
printf(" ISR = %02X\n", i8259_unit[dev].u4);
printf(" IMR = %02X\n", i8259_unit[dev].u5);
printf(" ICW1 = %02X\n", i8259_icw1[dev]);
printf(" ICW2 = %02X\n", i8259_icw2[dev]);
printf(" ICW3 = %02X\n", i8259_icw3[dev]);
printf(" ICW4 = %02X\n", i8259_icw4[dev]);
printf(" OCW1 = %02X\n", i8259_ocw1[dev]);
printf(" OCW2 = %02X\n", i8259_ocw2[dev]);
printf(" OCW3 = %02X\n", i8259_ocw3[dev]);
}
/* Reset routine */
t_stat i8259_reset (DEVICE *dptr, int32 base)
{
switch (i8259_cnt) {
case 0:
reg_dev(i8259a0, base);
reg_dev(i8259b0, base + 1);
reg_dev(i8259a0, base + 2);
reg_dev(i8259b0, base + 3);
i8259_unit[0].u3 = 0x00; /* IRR */
i8259_unit[0].u4 = 0x00; /* ISR */
i8259_unit[0].u5 = 0x00; /* IMR */
printf(" 8259-0: Reset\n");
break;
case 1:
reg_dev(i8259a1, base);
reg_dev(i8259b1, base + 1);
reg_dev(i8259a1, base + 2);
reg_dev(i8259b1, base + 3);
i8259_unit[1].u3 = 0x00; /* IRR */
i8259_unit[1].u4 = 0x00; /* ISR */
i8259_unit[1].u5 = 0x00; /* IMR */
printf(" 8259-1: Reset\n");
break;
default:
printf(" 8259: Bad device\n");
break;
}
printf(" 8259-%d: Registered at %02X\n", i8259_cnt, base);
i8259_cnt++;
return SCPE_OK;
}
/* end of i8259.c */

252
MDS-800/common/i8273.c Normal file
View file

@ -0,0 +1,252 @@
/* i8273.c: Intel i8273 UART adapter
Copyright (c) 2011, 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 i8273 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 i8273 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
+---+---+---+---+---+---+---+---+
| 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
+---+---+---+---+---+---+---+---+
| 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
+---+---+---+---+---+---+---+---+
|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 to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
uint8
wr0 = 0, /* command register */
wr1 = 0, /* enable register */
wr2 = 0, /* CH A mode register */
/* CH B interrups vector */
wr3 = 0, /* configuration register 1 */
wr4 = 0, /* configuration register 2 */
wr5 = 0, /* configuration register 3 */
wr6 = 0, /* sync low byte */
wr7 = 0, /* sync high byte */
rr0 = 0, /* status register */
rr1 = 0, /* error register */
rr2 = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8273_reset (DEVICE *dptr);
/* i8273 Standard I/O Data Structures */
UNIT i8273_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8273_reg[] = {
{ HRDATA (WR0, wr0, 8) },
{ HRDATA (WR1, wr1, 8) },
{ HRDATA (WR2, wr2, 8) },
{ HRDATA (WR3, wr3, 8) },
{ HRDATA (WR4, wr4, 8) },
{ HRDATA (WR5, wr5, 8) },
{ HRDATA (WR6, wr6, 8) },
{ HRDATA (WR7, wr7, 8) },
{ HRDATA (RR0, rr0, 8) },
{ HRDATA (RR0, rr1, 8) },
{ HRDATA (RR0, rr2, 8) },
{ NULL }
};
MTAB i8273_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8273_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8273_dev = {
"8251", //name
&i8273_unit, //units
i8273_reg, //registers
i8273_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8273_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8273_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* Reset routine */
t_stat i8273_reset (DEVICE *dptr)
{
wr0 = 0; /* command register */
wr1 = 0; /* enable register */
wr2 = 0; /* CH A mode register */
/* CH B interrups vector */
wr3 = 0; /* configuration register 1 */
wr4 = 0; /* configuration register 2 */
wr5 = 0; /* configuration register 3 */
wr6 = 0; /* sync low byte */
wr7 = 0; /* sync high byte */
rr0 = 0; /* status register */
rr1 = 0; /* error register */
rr2 = 0; /* read interrupt vector */
printf(" 8273 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
*/
int32 i8273s(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8273_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
i8273_unit.u3 = 0x05; /* status */
i8273_unit.u4 = 0; /* mode instruction */
i8273_unit.u5 = 0; /* command instruction */
i8273_unit.u6 = 0;
i8273_unit.buf = 0;
i8273_unit.pos = 0;
printf("8273 Reset\n");
} else if (i8273_unit.u6) {
i8273_unit.u5 = data;
printf("8273 Command Instruction=%02X\n", data);
} else {
i8273_unit.u4 = data;
printf("8273 Mode Instruction=%02X\n", data);
i8273_unit.u6++;
}
return (0);
}
}
int32 i8273d(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8273_unit.u3 &= 0xFD;
return (i8273_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}

351
MDS-800/common/i8274.c Normal file
View file

@ -0,0 +1,351 @@
/* i8274.c: Intel i8274 MPSC adapter
Copyright (c) 2011, 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 i8274 interface device on an iSBC.
The device had two physical I/O ports which could be connected
to any serial I/O device that would connect to an RS232 interface.
All I/O is via programmed I/O. The i8274 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 two address lines. The data port is at the
lower address and the status/command port is at the higher address for each
channel.
Minimum simulation is provided for this device. Channel A is used as a
console port for the iSBC-88/45
A write to the status port can select some options for the device:
Asynchronous Mode Instruction
+---+---+---+---+---+---+---+---+
| 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
+---+---+---+---+---+---+---+---+
| 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
+---+---+---+---+---+---+---+---+
|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 to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
/* register definitions */
/* channel A */
uint8 wr0a = 0, /* command register */
wr1a = 0, /* enable register */
wr2a = 0, /* mode register */
wr3a = 0, /* configuration register 1 */
wr4a = 0, /* configuration register 2 */
wr5a = 0, /* configuration register 3 */
wr6a = 0, /* sync low byte */
wr7a = 0, /* sync high byte */
rr0a = 0, /* status register */
rr1a = 0, /* error register */
rr2a = 0; /* read interrupt vector */
/* channel B */
uint8 wr0b = 0, /* command register */
wr1b = 0, /* enable register */
wr2b = 0, /* CH B interrups vector */
wr3b = 0, /* configuration register 1 */
wr4b = 0, /* configuration register 2 */
wr5b = 0, /* configuration register 3 */
wr6b = 0, /* sync low byte */
wr7b = 0, /* sync high byte */
rr0b = 0, /* status register */
rr1b = 0, /* error register */
rr2b = 0; /* read interrupt vector */
/* function prototypes */
t_stat i8274_svc (UNIT *uptr);
t_stat i8274_reset (DEVICE *dptr);
int32 i8274As(int32 io, int32 data);
int32 i8274Ad(int32 io, int32 data);
int32 i8274Bs(int32 io, int32 data);
int32 i8274Bd(int32 io, int32 data);
/* i8274 Standard I/O Data Structures */
UNIT i8274_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
REG i8274_reg[] = {
{ HRDATA (WR0A, wr0a, 8) },
{ HRDATA (WR1A, wr1a, 8) },
{ HRDATA (WR2A, wr2a, 8) },
{ HRDATA (WR3A, wr3a, 8) },
{ HRDATA (WR4A, wr4a, 8) },
{ HRDATA (WR5A, wr5a, 8) },
{ HRDATA (WR6A, wr6a, 8) },
{ HRDATA (WR7A, wr7a, 8) },
{ HRDATA (RR0A, rr0a, 8) },
{ HRDATA (RR0A, rr1a, 8) },
{ HRDATA (RR0A, rr2a, 8) },
{ HRDATA (WR0B, wr0b, 8) },
{ HRDATA (WR1B, wr1b, 8) },
{ HRDATA (WR2B, wr2b, 8) },
{ HRDATA (WR3B, wr3b, 8) },
{ HRDATA (WR4B, wr4b, 8) },
{ HRDATA (WR5B, wr5b, 8) },
{ HRDATA (WR6B, wr6b, 8) },
{ HRDATA (WR7B, wr7b, 8) },
{ HRDATA (RR0B, rr0b, 8) },
{ HRDATA (RR0B, rr1b, 8) },
{ HRDATA (RR0B, rr2b, 8) },
{ NULL }
};
MTAB i8274_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEBTAB i8274_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i8274_dev = {
"8274", //name
&i8274_unit, //units
i8274_reg, //registers
i8274_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
i8274_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
i8274_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* service routine - actually gets char & places in buffer in CH A*/
t_stat i8274_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&i8274_unit, i8274_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; /* no char or error? */
i8274_unit.buf = temp & 0xFF; /* Save char */
rr0a |= 0x01; /* Set rx char ready */
/* Do any special character handling here */
i8274_unit.pos++;
return SCPE_OK;
}
/* Reset routine */
t_stat i8274_reset (DEVICE *dptr)
{
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = wr6a = wr7a = rr0a = rr1a = rr2a = 0;
wr0b = wr1b = wr2b = wr3b = wr4b = wr5b = wr6b = wr7b = rr0b = rr1b = rr2b = 0;
printf(" 8274 Reset\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
The 8274 contains 2 separate channels, A and B.
*/
/* channel A command/status */
int32 i8274As(int32 io, int32 data)
{
if (io == 0) { /* read status port */
switch(wr0a & 0x7) {
case 0: /* rr0a */
return rr0a;
case 1: /* rr1a */
return rr1a;
case 2: /* rr1a */
return rr2a;
}
return 0; /* bad register select */
} else { /* write status port */
switch(wr0a & 0x7) {
case 0: /* wr0a */
wr0a = data;
if ((wr0a & 0x38) == 0x18) { /* channel reset */
wr0a = wr1a = wr2a = wr3a = wr4a = wr5a = 0;
wr6a = wr7a = rr0a = rr1a = rr2a = 0;
printf("8274 Channel A reset\n");
}
break;
case 1: /* wr1a */
wr1a = data;
break;
case 2: /* wr2a */
wr2a = data;
break;
case 3: /* wr3a */
wr3a = data;
break;
case 4: /* wr4a */
wr4a = data;
break;
case 5: /* wr5a */
wr5a = data;
break;
case 6: /* wr6a */
wr6a = data;
break;
case 7: /* wr7a */
wr7a = data;
break;
}
printf("8274 Command WR%dA=%02X\n", wr0a & 0x7, data);
return 0;
}
}
/* channel A data */
int32 i8274Ad(int32 io, int32 data)
{
if (io == 0) { /* read data port */
rr0a &= 0xFE;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* channel B command/status */
int32 i8274Bs(int32 io, int32 data)
{
if (io == 0) { /* read status port */
return i8274_unit.u3;
} else { /* write status port */
if (data == 0x40) { /* reset port! */
printf("8274 Reset\n");
} else if (i8274_unit.u6) {
i8274_unit.u5 = data;
printf("8274 Command Instruction=%02X\n", data);
} else {
i8274_unit.u4 = data;
printf("8274 Mode Instruction=%02X\n", data);
i8274_unit.u6++;
}
return (0);
}
}
/* channel B data */
int32 i8274Bd(int32 io, int32 data)
{
if (io == 0) { /* read data port */
i8274_unit.u3 &= 0xFD;
return (i8274_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
/* end of i8274.c */

143
MDS-800/common/iSBC80-10.c Normal file
View file

@ -0,0 +1,143 @@
/* 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.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
?? ??? 10 - Original file.
*/
#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 */

149
MDS-800/common/iSBC80-20.c Normal file
View file

@ -0,0 +1,149 @@
/* iSBC80-20.c: Intel iSBC 80/30 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.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
?? ??? 10 - Original file.
*/
#include "system_defs.h"
/* set the base I/O address for the 8259 */
#define I8259_BASE 0xD8
/* 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/20 */
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/20 */
#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 i80_10_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 i8251_reset (DEVICE *dptr, int32 base);
extern t_stat i8255_reset (DEVICE *dptr, int32 base);
extern t_stat i8259_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);
/* CPU reset routine
put here to cause a reset of the entire iSBC system */
t_stat SBC_reset (DEVICE *dptr)
{
printf("Initializing iSBC-80/20\n");
i8080_reset(NULL);
i8259_reset(NULL, I8259_BASE);
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 and Multibus memory */
int32 get_mbyte(int32 addr)
{
int32 val, org, len;
/* if local EPROM handle it */
if ((i8255_unit.u6 & 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.u6 & 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 and Multibus memory */
void put_mbyte(int32 addr, int32 val)
{
/* if local EPROM handle it */
if ((i8255_unit.u6 & 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.u6 & 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 */

149
MDS-800/common/iSBC80-30.c Normal file
View file

@ -0,0 +1,149 @@
/* iSBC80-30.c: Intel iSBC 80/30 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.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
?? ??? 10 - Original file.
*/
#include "system_defs.h"
/* set the base I/O address for the 8259 */
#define I8259_BASE 0xD8
/* 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/20 */
#define ROM_SIZE 0x1000
/* set the base and size for the RAM on the iSBC 80/20 */
#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 i80_10_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 i8251_reset (DEVICE *dptr, int32 base);
extern t_stat i8255_reset (DEVICE *dptr, int32 base);
extern t_stat i8259_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);
/* CPU reset routine
put here to cause a reset of the entire iSBC system */
t_stat SBC_reset (DEVICE *dptr)
{
printf("Initializing iSBC-80/20\n");
i8080_reset(NULL);
i8259_reset(NULL, I8259_BASE);
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 and Multibus memory */
int32 get_mbyte(int32 addr)
{
int32 val, org, len;
/* if local EPROM handle it */
if ((i8255_unit.u6 & 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.u6 & 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 and Multibus memory */
void put_mbyte(int32 addr, int32 val)
{
/* if local EPROM handle it */
if ((i8255_unit.u6 & 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.u6 & 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 */

201
MDS-800/common/ieprom.c Normal file
View file

@ -0,0 +1,201 @@
/* iEPROM.c: Intel EPROM simulator for 8-bit SBCs
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 i2732 EPROM device on an iSBC. This
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.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* function prototypes */
t_stat EPROM_attach (UNIT *uptr, char *cptr);
t_stat EPROM_reset (DEVICE *dptr, int32 size);
int32 EPROM_get_mbyte(int32 addr);
extern UNIT i8255_unit;
extern uint8 xack; /* XACK signal */
/* SIMH EPROM Standard I/O Data Structures */
UNIT EPROM_unit = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0), 0
};
DEBTAB EPROM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE EPROM_dev = {
"EPROM", //name
&EPROM_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &EPROM_reset, //reset
NULL, //reset
NULL, //boot
&EPROM_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
EPROM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
/* EPROM functions */
/* EPROM attach */
t_stat EPROM_attach (UNIT *uptr, char *cptr)
{
int j, c;
FILE *fp;
t_stat r;
if (EPROM_dev.dctrl & DEBUG_flow)
printf("EPROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (EPROM_dev.dctrl & DEBUG_flow)
printf("EPROM_attach: Error\n");
return r;
}
if (EPROM_dev.dctrl & DEBUG_read)
printf("\tAllocate buffer\n");
if (EPROM_unit.filebuf == NULL) { /* no buffer allocated */
EPROM_unit.filebuf = malloc(EPROM_unit.capac); /* allocate EPROM buffer */
if (EPROM_unit.filebuf == NULL) {
if (EPROM_dev.dctrl & DEBUG_flow)
printf("EPROM_attach: Malloc error\n");
return SCPE_MEM;
}
}
if (EPROM_dev.dctrl & DEBUG_read)
printf("\tOpen file %s\n", EPROM_unit.filename);
fp = fopen(EPROM_unit.filename, "rb"); /* open EPROM file */
if (fp == NULL) {
printf("EPROM: Unable to open ROM file %s\n", EPROM_unit.filename);
printf("\tNo ROM image loaded!!!\n");
return SCPE_OK;
}
if (EPROM_dev.dctrl & DEBUG_read)
printf("\tRead file\n");
j = 0; /* load EPROM file */
c = fgetc(fp);
while (c != EOF) {
*(uint8 *)(EPROM_unit.filebuf + j++) = c & 0xFF;
c = fgetc(fp);
if (j >= EPROM_unit.capac) {
printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
if (EPROM_dev.dctrl & DEBUG_read)
printf("\tClose file\n");
fclose(fp);
printf("EPROM: %d bytes of ROM image %s loaded\n", j, EPROM_unit.filename);
if (EPROM_dev.dctrl & DEBUG_flow)
printf("EPROM_attach: Done\n");
return SCPE_OK;
}
/* EPROM reset */
t_stat EPROM_reset (DEVICE *dptr, int32 size)
{
t_stat r;
// if (EPROM_dev.dctrl & DEBUG_flow) /* entry message */
printf(" EPROM_reset: base=0000 size=%04X\n", size);
if ((EPROM_unit.flags & UNIT_ATT) == 0) { /* if unattached */
EPROM_unit.capac = size; /* set EPROM size to 0 */
if (EPROM_dev.dctrl & DEBUG_flow) /* exit message */
printf("Done1\n");
// printf(" EPROM: Available [%04X-%04XH]\n",
// 0, EPROM_unit.capac - 1);
return SCPE_OK;
}
if ((EPROM_unit.flags & UNIT_ATT) == 0) {
printf("EPROM: No file attached\n");
}
if (EPROM_dev.dctrl & DEBUG_flow) /* exit message */
printf("Done2\n");
return SCPE_OK;
}
/* get a byte from memory */
int32 EPROM_get_mbyte(int32 addr)
{
int32 val;
if (i8255_unit.u6 & 0x01) { /* EPROM enabled */
if (EPROM_dev.dctrl & DEBUG_read)
printf("EPROM_get_mbyte: addr=%04X\n", addr);
if ((addr >= 0) && (addr < EPROM_unit.capac)) {
SET_XACK(1); /* good memory address */
if (EPROM_dev.dctrl & DEBUG_xack)
printf("EPROM_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(EPROM_unit.filebuf + addr);
if (EPROM_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
}
if (EPROM_dev.dctrl & DEBUG_read)
printf(" EPROM Disabled\n");
return 0xFF;
}
if (EPROM_dev.dctrl & DEBUG_read)
printf(" Out of range\n");
return 0xFF;
}
/* end of iEPROM.c */

486
MDS-800/common/ijedec.c Normal file
View file

@ -0,0 +1,486 @@
/* iJEDEC.c: Intel JEDEC Universal Site simulator for SBCs
Copyright (c) 2011, 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 i2732 JEDEC device on an iSBC. This
allows the attachment of the device to a binary file containing the JEDEC
code.
Unit will support 8, 16 and 32 KB EPROMs as well as 8 and 16 KB static
RAMs in the JEDEC sockets. Units must be configured for 8KB for 8KB
SRAM and 32KB for 32KB SRAM. If configured for 16KB, SRAM cannot be
configured. Size is set by configuring the top JEDEC site for an EPROM.
Size and spacing for the other JEDEC units is derived from the top JEDEC
site configuration. Changing the top JEDEC site will clear the
configuration of all other JEDEC sites. The JEDEC driver can be set for
either 8- or 16bit data access.
The top JEDEC site can only be configured to contain an EPROM.
It contains the reset address for the 8088, 8086, 80188, 80186,
and 80286.
For illustration 8-bit mode - 4 Sites - configured for 8KB chips
+--------+ 0xFFFFF
| |
| jedec3 | Only ROM
| |
+--------+ 0xFE000
+--------+ 0xFDFFF
| |
| jedec2 | RAM/ROM
| |
+--------+ 0xFC000
+--------+ 0xFBFFF
| |
| jedec1 | RAM/ROM
| |
+--------+ 0xFA000
+--------+ 0xF9FFF
| |
| jedec0 | RAM/ROM
| |
+--------+ 0xF8000
For illustration 16-bit mode - 4 Sites - configured for 8KB chips
Odd data byte Even data byte
High data byte Low data byte
+--------+ 0xFFFFF +--------+ 0xFFFFE
| | | |
| jedec3 | Only ROM | jedec2 | Only ROM
| | | |
+--------+ 0xFC001 +--------+ 0xFC000
+--------+ 0xFBFFF +--------+ 0xFBFFE
| | | |
| jedec3 | RAM/ROM | jedec2 | RAM/ROM
| | | |
+--------+ 0xF8001 +--------+ 0xF8000
uptr->filename - ROM image file attached to unit
uptr->capac - unit capacity in bytes
uptr->u3 - unit base address
uptr->u4 - unit device type {none|8krom|16krom|32krom|8kram|32kram}
uptr->u5 - unit flags - ROM or RAM, 8 or 16BIT (top unit only)
uptr->u6 - unit number
*/
#include <stdio.h>
#include "multibus_defs.h"
#define JEDEC_NUM 4
#define UNIT_V_DMODE (UNIT_V_UF) /* data bus mode */
#define UNIT_DMODE (1 << UNIT_V_DMODE)
#define UNIT_V_MSIZE (UNIT_V_UF+1) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_NONE 0 /* No device */
#define UNIT_8KROM 1 /* 8KB ROM */
#define UNIT_16KROM 2 /* 16KB ROM */
#define UNIT_32KROM 3 /* 32KB ROM */
#define UNIT_8KRAM 4 /* 8KB RAM */
#define UNIT_32KRAM 5 /* 32KB RAM */
#define RAM 0x00000001
#define D16BIT 0x00000002
/* function prototypes */
t_stat JEDEC_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat JEDEC_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat JEDEC_attach (UNIT *uptr, char *cptr);
t_stat JEDEC_reset (DEVICE *dptr);
int32 JEDEC_get_mbyte(int32 addr);
void JEDEC_put_mbyte(int32 addr, int32 val);
/* SIMH JEDEC Standard I/O Data Structures */
UNIT JEDEC_unit[] = {
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 },
{ UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),0 }
};
MTAB JEDEC_mod[] = {
{ UNIT_DMODE, 0, "8-Bit", "8B", &JEDEC_set_mode },
{ UNIT_DMODE, UNIT_DMODE, "16-Bit", "16B", &JEDEC_set_mode },
{ UNIT_MSIZE, UNIT_NONE, "Not configured", "NONE", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_8KROM, "8KB ROM", "8KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_16KROM, "16KB ROM", "16KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_32KROM, "32KB ROM", "32KROM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_8KRAM, "8KB RAM", "8KRAM", &JEDEC_set_size },
{ UNIT_MSIZE, UNIT_32KRAM, "32KB RAM", "32KRAM", &JEDEC_set_size },
{ 0 }
};
DEBTAB JEDEC_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE JEDEC_dev = {
"JEDEC", //name
JEDEC_unit, //units
NULL, //registers
JEDEC_mod, //modifiers
JEDEC_NUM, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&JEDEC_reset, //reset
NULL, //boot
&JEDEC_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
JEDEC_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
uint8 *JEDEC_buf[JEDEC_NUM] = { /* JEDEC buffer pointers */
NULL,
NULL,
NULL,
NULL
};
/* JEDEC functions */
/* JEDEC attach - force JEDEC reset at completion */
t_stat JEDEC_attach (UNIT *uptr, char *cptr)
{
t_stat r;
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_attach: Entered with cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_attach: Error\n");
return r;
}
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_attach: Done\n");
return (JEDEC_reset (NULL));
}
/* JEDEC set mode = 8- or 16-bit data bus */
t_stat JEDEC_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
{
UNIT *uptr1;
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_set_mode: Entered with val=%08XH, unit=%d\n", val, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds this configuration */
if (val) { /* 16-bit mode */
uptr1->u5 |= D16BIT;
} else { /* 8-bit mode */
uptr1->u5 &= ~D16BIT;
}
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("JEDEC%d->u5=%08XH\n", JEDEC_NUM - 1, uptr1->u5);
printf("\tJEDEC_set_mode: Done\n");
}
/* JEDEC set type = none, 8krom, 16krom, 32krom, 8kram or 32kram */
t_stat JEDEC_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
uint32 i, basadr;
UNIT *uptr1;
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_set_size: Entered with val=%d, unit=%d\n", val, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds u5 configuration */
uptr->u4 = val;
switch(val) {
case UNIT_NONE:
uptr->capac = 0;
uptr->u5 &= ~RAM; /* ROM */
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = 0; /* base address */
printf("JEDEC site size set to 8KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
}
break;
case UNIT_8KROM:
uptr->capac = 0x2000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
printf("JEDEC site size set to 8KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_16KROM:
uptr->capac = 0x4000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
printf("JEDEC site size set to 16KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_32KROM:
uptr->capac = 0x8000;
uptr1->u5 &= ~RAM; /* ROM */
basadr = 0x100000 - (uptr->capac * JEDEC_NUM);
printf("JEDEC site base address = %06XH\n", basadr);
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
uptr->u3 = basadr + (uptr->capac * uptr->u6); /* base address */
printf("JEDEC site size set to 32KB\n");
for (i = 0; i < JEDEC_NUM-1; i++) { /* clear all units but last unit */
uptr1 = JEDEC_dev.units + i;
uptr1->capac = 0;
}
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
printf("JEDEC site size precludes use of this device\n");
}
}
break;
case UNIT_8KRAM:
uptr->capac = 0x2000;
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
printf("JEDEC%d cannot be SRAM\n", uptr->u6);
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
printf("JEDEC site size precludes use of this device\n");
} else {
uptr->u5 |= RAM; /* RAM */
}
}
break;
case UNIT_32KRAM:
uptr->capac = 0x8000;
if (uptr->u6 == JEDEC_NUM - 1) {/* top unit ? */
printf("JEDEC%d cannot be SRAM\n", uptr->u6);
} else {
if (uptr1->capac != uptr->capac) {
uptr->capac = 0;
printf("JEDEC site size precludes use of this device\n");
} else {
uptr->u5 |= RAM; /* RAM */
}
}
break;
default:
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_set_size: Error\n");
return SCPE_ARG;
}
if (JEDEC_buf[uptr->u6]) { /* any change requires a new buffer */
free (JEDEC_buf[uptr->u6]);
JEDEC_buf[uptr->u6] = NULL;
}
if (JEDEC_dev.dctrl & DEBUG_flow) {
printf("\tJEDEC%d->capac=%04XH\n", uptr->u6, uptr->capac);
printf("\tJEDEC%d->u3[Base addr]=%06XH\n", uptr->u6, uptr->u3);
printf("\tJEDEC%d->u4[val]=%06XH\n", uptr->u6, uptr->u4);
printf("\tJEDEC%d->u5[Flags]=%06XH\n", uptr->u6, uptr->u5);
printf("\tJEDEC%d->u6[unit #]=%06XH\n", uptr->u6, uptr->u6);
uptr1 = JEDEC_dev.units + JEDEC_NUM - 1; /* top unit holds u5 configuration */
printf("\tJEDEC%d->u5[Flags]=%06XH\n", JEDEC_NUM - 1, uptr1->u5);
printf("\tJEDEC_set_size: Done\n");
}
return SCPE_OK;
}
/* JEDEC reset */
t_stat JEDEC_reset (DEVICE *dptr)
{
int32 i, j, c;
FILE *fp;
t_stat r;
UNIT *uptr;
static int flag = 1;
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_reset: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* handle all umits */
uptr = JEDEC_dev.units + i;
if (uptr->capac == 0) { /* if not configured */
printf(" JEDEC%d: Not configured\n", i);
if (flag) {
printf(" ALL: \"set JEDEC3 None | 8krom | 16krom | 32krom | 8kram | 32kram\"\n");
printf(" EPROM: \"att JEDEC3 <filename>\"\n");
flag = 0;
}
uptr->capac = 0;
/* assume 8KB in base address calculation */
uptr->u3 = 0xF8000 + (0x2000 * i); /* base address */
uptr->u4 = 0; /* None */
uptr->u5 = 0; /* RO */
uptr->u6 = i; /* unit number - only set here! */
}
if (uptr->capac) { /* if configured */
printf(" JEDEC%d: Initializing %2XKB %s [%04X-%04XH]\n",
i,
uptr->capac / 0x400,
uptr->u5 ? "Ram" : "Rom",
uptr->u3,
uptr->u3 + uptr->capac - 1);
if (JEDEC_buf[uptr->u6] == NULL) {/* no buffer allocated */
JEDEC_buf[uptr->u6] = malloc(uptr->capac);
if (JEDEC_buf[uptr->u6] == NULL) {
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_reset: Malloc error\n");
return SCPE_MEM;
}
}
if ((uptr->u5 & 0x0001) == 0) { /* ROM - load file */
fp = fopen(uptr->filename, "rb");
if (fp == NULL) {
printf("\tUnable to open ROM file %s\n", uptr->filename);
printf("\tNo ROM image loaded!!!\n");
} else {
j = 0;
c = fgetc(fp);
while (c != EOF) {
*(JEDEC_buf[uptr->u6] + j++) = c & 0xFF;
c = fgetc(fp);
if (j >= JEDEC_unit[uptr->u6].capac) {
printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
fclose(fp);
printf("\t%d bytes of ROM image %s loaded\n", j, uptr->filename);
}
}
}
}
if (JEDEC_dev.dctrl & DEBUG_flow)
printf("\tJEDEC_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
JEDEC memory read or write is issued.
Need to fix for hi/low memory operations
*/
/* get a byte from memory */
int32 JEDEC_get_mbyte(int32 addr)
{
int32 i, val, org, len;
UNIT *uptr;
if (JEDEC_dev.dctrl & DEBUG_read)
printf("\tJEDEC_get_mbyte: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* test all umits for address */
uptr = JEDEC_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr <= org + len)) {
if (JEDEC_dev.dctrl & DEBUG_read)
printf("\tJEDEC%d Addr=%06XH Org=%06XH Len=%06XH\n", i, addr, org, len);
val = *(JEDEC_buf[uptr->u6] + (addr - org));
if (JEDEC_dev.dctrl & DEBUG_read)
printf("\tJEDEC_get_mbyte: Exit with [%0XH]\n", val & 0xFF);
return (val & 0xFF);
}
}
if (JEDEC_dev.dctrl & DEBUG_read)
printf("\tJEDEC_get_mbyte: Exit - Out of range\n", addr);
return 0xFF;
}
/* put a byte into memory */
void JEDEC_put_mbyte(int32 addr, int32 val)
{
int32 i, org, len, type;
UNIT *uptr;
if (JEDEC_dev.dctrl & DEBUG_write)
printf("\tJEDEC_put_mbyte: Entered\n");
for (i = 0; i < JEDEC_NUM; i++) { /* test all umits for address */
uptr = JEDEC_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr < org + len)) {
if (JEDEC_dev.dctrl & DEBUG_write)
printf("\tJEDEC%d Org=%06XH Len=%06XH\n", i, org, len);
if (uptr->u5 & RAM) { /* can't write to ROM */
*(JEDEC_buf[uptr->u6] + (addr - org)) = val & 0xFF;
if (JEDEC_dev.dctrl & DEBUG_write)
printf("\tJEDEC_put_mbyte: Exit with [%06XH]=%02XH\n", addr, val);
} else
printf("\tJEDEC_put_mbyte: Write to ROM ignored\n");
}
}
if (JEDEC_dev.dctrl & DEBUG_write)
printf("\tJEDEC_put_mbyte: Exit - Out of range\n");
}
/* end of iJEDEC.c */

203
MDS-800/common/iram16.c Normal file
View file

@ -0,0 +1,203 @@
/* iram.c: Intel RAM simulator for 16-bit SBCs
Copyright (c) 2011, 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 RAM device in low memory on an iSBC. These
SBCs do not have the capability to switch off this RAM. In most cases a portion
of the RAM is dual-ported so it also appears in the multibus memory map at
a configurable location.
Unit will support 16K SRAM sizes.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_RSIZE (UNIT_V_UF) /* RAM Size */
#define UNIT_RSIZE (0x1 << UNIT_V_RSIZE)
#define UNIT_NONE (0) /* No unit */
#define UNIT_16K (1) /* 16KB */
/* function prototypes */
t_stat RAM_svc (UNIT *uptr);
t_stat RAM_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat RAM_reset (DEVICE *dptr);
int32 RAM_get_mbyte(int32 addr);
void RAM_put_mbyte(int32 addr, int32 val);
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
MTAB RAM_mod[] = {
{ UNIT_RSIZE, UNIT_NONE, "None", "none", &RAM_set_size },
{ UNIT_RSIZE, UNIT_16K, "16KB", "16KB", &RAM_set_size },
{ 0 }
};
DEBTAB RAM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE RAM_dev = {
"RAM", //name
&RAM_unit, //units
NULL, //registers
RAM_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&RAM_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
RAM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
uint8 *RAM_buf = NULL; /* RAM buffer pointer */
/* RAM functions */
/* RAM set size = none or 16KB */
t_stat RAM_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_set_size: val=%d\n", val);
if ((val < UNIT_NONE) || (val > UNIT_16K)) {
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_set_size: Size error\n");
return SCPE_ARG;
}
RAM_unit.capac = 0x4000 * val; /* set size */
RAM_unit.u3 = 0x0000; /* base is 0 */
RAM_unit.u4 = val; /* save val */
if (RAM_buf) { /* if changed, allocate new buffer */
free (RAM_buf);
RAM_buf = NULL;
}
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_set_size: Done\n");
return (RAM_reset (NULL)); /* force reset after reconfig */
}
/* RAM reset */
t_stat RAM_reset (DEVICE *dptr)
{
int j;
FILE *fp;
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_reset: \n");
if (RAM_unit.capac == 0) { /* if undefined */
printf(" RAM: defaulted for 16KB\n");
printf(" \"set RAM 16KB\"\n");
RAM_unit.capac = 0x4000;
RAM_unit.u3 = 0;
RAM_unit.u4 = 1;
}
printf(" RAM: Initializing [%04X-%04XH]\n",
RAM_unit.u3,
RAM_unit.u3 + RAM_unit.capac - 1);
if (RAM_buf == NULL) { /* no buffer allocated */
RAM_buf = malloc(RAM_unit.capac);
if (RAM_buf == NULL) {
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
RAM memory read or write is issued.
*/
/* get a byte from memory */
int32 RAM_get_mbyte(int32 addr)
{
int32 val, org, len;
org = RAM_unit.u3;
len = RAM_unit.capac - 1;
if (RAM_dev.dctrl & DEBUG_read)
printf("RAM_get_mbyte: addr=%04X", addr);
if ((addr >= org) && (addr <= org + len)) {
val = *(RAM_buf + (addr - org));
if (RAM_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
}
if (RAM_dev.dctrl & DEBUG_read)
printf(" Out of range\n", addr);
return 0xFF;
}
/* put a byte to memory */
void RAM_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
org = RAM_unit.u3;
len = RAM_unit.capac - 1;
if (RAM_dev.dctrl & DEBUG_write)
printf("RAM_put_mbyte: addr=%04X, val=%02X", addr, val);
if ((addr >= org) && (addr < org + len)) {
*(RAM_buf + (addr - org)) = val & 0xFF;
if (RAM_dev.dctrl & DEBUG_write)
printf("\n");
return;
}
if (RAM_dev.dctrl & DEBUG_write)
printf(" Out of range\n", val);
}
/* end of iram.c */

168
MDS-800/common/iram8.c Normal file
View file

@ -0,0 +1,168 @@
/* iRAM8.c: Intel RAM simulator for 8-bit SBCs
Copyright (c) 2011, 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 i8111 or 8102 RAM device on an iSBC.
?? ??? 11 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* function prototypes */
t_stat RAM_svc (UNIT *uptr);
t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size);
int32 RAM_get_mbyte(int32 addr);
void RAM_put_mbyte(int32 addr, int32 val);
extern UNIT i8255_unit;
extern uint8 xack; /* XACK signal */
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
DEBTAB RAM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE RAM_dev = {
"RAM", //name
&RAM_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &RAM_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
RAM_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
/* RAM functions */
/* RAM reset */
t_stat RAM_reset (DEVICE *dptr, int32 base, int32 size)
{
// if (RAM_dev.dctrl & DEBUG_flow)
printf(" RAM_reset: base=%04X size=%04X\n", base, size-1);
if (RAM_unit.capac == 0) { /* if undefined */
RAM_unit.capac = size;
RAM_unit.u3 = base;
}
if (RAM_unit.filebuf == NULL) { /* no buffer allocated */
RAM_unit.filebuf = malloc(RAM_unit.capac);
if (RAM_unit.filebuf == NULL) {
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_set_size: Malloc error\n");
return SCPE_MEM;
}
}
// printf(" RAM: Available [%04X-%04XH]\n",
// RAM_unit.u3,
// RAM_unit.u3 + RAM_unit.capac - 1);
if (RAM_dev.dctrl & DEBUG_flow)
printf("RAM_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
int32 RAM_get_mbyte(int32 addr)
{
int32 val;
if (i8255_unit.u6 & 0x02) { /* enable RAM */
if (RAM_dev.dctrl & DEBUG_read)
printf("RAM_get_mbyte: addr=%04X\n", addr);
if ((addr >= RAM_unit.u3) && (addr < (RAM_unit.u3 + RAM_unit.capac))) {
SET_XACK(1); /* good memory address */
if (RAM_dev.dctrl & DEBUG_xack)
printf("RAM_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(RAM_unit.filebuf + (addr - RAM_unit.u3));
if (RAM_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
}
if (RAM_dev.dctrl & DEBUG_read)
printf(" RAM disabled\n");
return 0xFF;
}
if (RAM_dev.dctrl & DEBUG_read)
printf(" Out of range\n");
return 0xFF;
}
/* put a byte to memory */
void RAM_put_mbyte(int32 addr, int32 val)
{
if (i8255_unit.u6 & 0x02) { /* enable RAM */
if (RAM_dev.dctrl & DEBUG_write)
printf("RAM_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if ((addr >= RAM_unit.u3) && (addr < RAM_unit.u3 + RAM_unit.capac)) {
SET_XACK(1); /* good memory address */
if (RAM_dev.dctrl & DEBUG_xack)
printf("RAM_put_mbyte: Set XACK for %04X\n", addr);
*(uint8 *)(RAM_unit.filebuf + (addr - RAM_unit.u3)) = val & 0xFF;
if (RAM_dev.dctrl & DEBUG_write)
printf("\n");
return;
}
if (RAM_dev.dctrl & DEBUG_write)
printf(" RAM disabled\n");
return;
}
if (RAM_dev.dctrl & DEBUG_write)
printf(" Out of range\n");
}
/* end of iRAM8.c */

202
MDS-800/common/isbc064.c Normal file
View file

@ -0,0 +1,202 @@
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
Copyright (c) 2011, 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 isbc016, isbc032, isbc048 and isbc064
memory card on an Intel multibus system.
?? ??? 11 - Original file.
16 Dec 12 - Modified to use system_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
#define SET_XACK(VAL) (xack = VAL)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
int32 isbc064_get_mbyte(int32 addr);
int32 isbc064_get_mword(int32 addr);
void isbc064_put_mbyte(int32 addr, int32 val);
void isbc064_put_mword(int32 addr, int32 val);
extern uint8 xack; /* XACK signal */
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
8, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
&isbc064_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: ");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
isbc064_unit.capac = SBC064_SIZE;
isbc064_unit.u3 = SBC064_BASE;
printf("iSBC 064: Available[%04X-%04XH]\n",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
}
if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) {
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
int32 isbc064_get_mbyte(int32 addr)
{
int32 val, org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_read)
printf("isbc064_get_mbyte: addr=%04X", addr);
if (isbc064_dev.dctrl & DEBUG_read)
printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack)
printf("isbc064_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(isbc064_unit.filebuf + (addr - org));
if (isbc064_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
} else {
if (isbc064_dev.dctrl & DEBUG_read)
printf(" Out of range\n");
return 0xFF; /* multibus has active high pullups */
}
}
if (isbc064_dev.dctrl & DEBUG_read)
printf(" Disabled\n");
return 0xFF; /* multibus has active high pullups */
}
/* get a word from memory */
int32 isbc064_get_mword(int32 addr)
{
int32 val;
val = isbc064_get_mbyte(addr);
val |= (isbc064_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte into memory */
void isbc064_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack)
printf("isbc064_put_mbyte: Set XACK for %04X\n", addr);
*(uint8 *)(isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
if (isbc064_dev.dctrl & DEBUG_xack)
printf("isbc064_put_mbyte: Return\n");
return;
} else {
if (isbc064_dev.dctrl & DEBUG_write)
printf(" Out of range\n");
return;
}
}
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: Disabled\n");
}
/* put a word into memory */
void isbc064_put_mword(int32 addr, int32 val)
{
isbc064_put_mbyte(addr, val);
isbc064_put_mbyte(addr+1, val << 8);
}
/* end of isbc064.c */

256
MDS-800/common/isbc064b.c Normal file
View file

@ -0,0 +1,256 @@
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
Copyright (c) 2011, 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 isbc016, isbc032, isbc048 and isbc064 memory card
on an Intel multibus system.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define UNIT_V_MSIZE (UNIT_V_UF) /* Memory Size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_V_MBASE (UNIT_V_UF+1) /* Memory Base */
#define UNIT_MBASE (1 << UNIT_V_MBASE)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
t_stat isbc064_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat isbc064_set_base (UNIT *uptr, int32 val, char *cptr, void *desc);
int32 isbc064_get_mbyte(int32 addr);
int32 isbc064_get_mword(int32 addr);
void isbc064_put_mbyte(int32 addr, int32 val);
void isbc064_put_mword(int32 addr, int32 val);
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = { UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT };
MTAB isbc064_mod[] = {
{ UNIT_MSIZE, 16384, NULL, "16K", &isbc064_set_size },
{ UNIT_MSIZE, 32768, NULL, "32K", &isbc064_set_size },
{ UNIT_MSIZE, 49152, NULL, "48K", &isbc064_set_size },
{ UNIT_MSIZE, 65535, NULL, "64K", &isbc064_set_size },
{ UNIT_MBASE, 0, NULL, "B0K", &isbc064_set_base },
{ UNIT_MBASE, 16384, NULL, "B16K", &isbc064_set_base },
{ UNIT_MBASE, 32768, NULL, "B32K", &isbc064_set_base },
{ UNIT_MBASE, 49152, NULL, "B48K", &isbc064_set_base },
{ 0 }
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
isbc064_mod, //modifiers
1, //numunits
16, //aradix
8, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
&isbc064_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
uint8 *MB_buf = NULL; //pointer to memory buffer
/* Set memory size routine */
t_stat isbc064_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 mc = 0;
uint32 i;
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_set_size: val=%04X\n", val);
if ((val <= 0) || (val > MAXMEMSIZE)) {
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_set_size: Memory size error\n");
return SCPE_ARG;
}
isbc064_unit.capac = val;
for (i = isbc064_unit.capac; i < MAXMEMSIZE; i++)
isbc064_put_mbyte(i, 0);
isbc064_unit.capac = val;
isbc064_unit.u3 = 0;
if (MB_buf) {
free (MB_buf);
MB_buf = NULL;
}
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_set_size: Done\n");
return SCPE_OK;
}
/* Set memory base address routine */
t_stat isbc064_set_base (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_set_base: val=%04X\n", val);
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) {
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_set_base: Base address error\n");
return SCPE_ARG;
}
isbc064_unit.u3 = val;
if (MB_buf) {
free (MB_buf);
MB_buf = NULL;
}
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_set_base: Done\n");
return (isbc064_reset (NULL));
}
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: \n");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
printf("Initializing %s [%04X-%04XH]\n", "iSBC-064",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
if (MB_buf == NULL) {
MB_buf = malloc(isbc064_unit.capac);
if (MB_buf == NULL) {
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
}
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
external memory read or write is issued.
*/
/* get a byte from memory */
int32 isbc064_get_mbyte(int32 addr)
{
int32 val, org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac - 1;
if (isbc064_dev.dctrl & DEBUG_read)
printf("isbc064_get_mbyte: addr=%04X", addr);
if ((addr >= org) && (addr <= org + len)) {
val = *(MB_buf + (addr - org));
if (isbc064_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
} else {
if (isbc064_dev.dctrl & DEBUG_read)
printf(" Out of range\n");
return 0xFF; /* multibus has active high pullups */
}
}
if (isbc064_dev.dctrl & DEBUG_read)
printf(" Disabled\n");
return 0xFF; /* multibus has active high pullups */
}
/* get a word from memory */
int32 isbc064_get_mword(int32 addr)
{
int32 val;
val = isbc064_get_mbyte(addr);
val |= (isbc064_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte into memory */
void isbc064_put_mbyte(int32 addr, int32 val)
{
int32 org, len, type;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac - 1;
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: addr=%04X, val=%02X", addr, val);
if ((addr >= org) && (addr < org + len)) {
*(MB_buf + (addr - org)) = val & 0xFF;
if (isbc064_dev.dctrl & DEBUG_write)
printf("\n");
return;
} else {
if (isbc064_dev.dctrl & DEBUG_write)
printf(" Out of range\n");
return;
}
}
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: Disabled\n");
}
/* put a word into memory */
void isbc064_put_mword(int32 addr, int32 val)
{
isbc064_put_mbyte(addr, val);
isbc064_put_mbyte(addr+1, val << 8);
}
/* end of isbc064.c */

205
MDS-800/common/isbc064x.c Normal file
View file

@ -0,0 +1,205 @@
/* isbc064.c: Intel iSBC064 64K Byte Memory Card
Copyright (c) 2011, 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 isbc016, isbc032, isbc048 and isbc064
memory card on an Intel multibus system.
?? ??? 11 - Original file.
16 Dec 12 - Modified to use system_80_10.cfg file to set base and size.
*/
#include <stdio.h>
#include "multibus_defs.h"
#define SET_XACK(VAL) (XACK = VAL)
/* prototypes */
t_stat isbc064_reset (DEVICE *dptr);
int32 isbc064_get_mbyte(int32 addr);
int32 isbc064_get_mword(int32 addr);
void isbc064_put_mbyte(int32 addr, int32 val);
void isbc064_put_mword(int32 addr, int32 val);
extern uint8 XACK; /* XACK signal */
/* isbc064 Standard I/O Data Structures */
UNIT isbc064_unit = {
UDATA (NULL, UNIT_FIX+UNIT_DISABLE+UNIT_BINK, 65536), KBD_POLL_WAIT
};
DEBTAB isbc064_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE isbc064_dev = {
"SBC064", //name
&isbc064_unit, //units
NULL, //registers
NULL, //modifiers
1, //numunits
16, //aradix
8, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
&isbc064_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
NULL //lname
};
/* iSBC064 globals */
/* Reset routine */
t_stat isbc064_reset (DEVICE *dptr)
{
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: \n");
if ((isbc064_dev.flags & DEV_DIS) == 0) {
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Size=%04X\n", isbc064_unit.capac - 1);
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Base address=%04X\n", isbc064_unit.u3);
printf("iSBC 064: Available[%04X-%04XH]\n",
isbc064_unit.u3,
isbc064_unit.u3 + isbc064_unit.capac - 1);
}
if (isbc064_unit.filebuf == NULL) {
isbc064_unit.filebuf = malloc(isbc064_unit.capac);
if (isbc064_unit.filebuf == NULL) {
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (isbc064_dev.dctrl & DEBUG_flow)
printf("isbc064_reset: Done\n");
return SCPE_OK;
}
/* get a byte from memory */
int32 isbc064_get_mbyte(int32 addr)
{
int32 val, org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_read)
printf("isbc064_get_mbyte: addr=%04X", addr);
if (isbc064_dev.dctrl & DEBUG_read)
printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack)
printf("isbc064_get_mbyte: Set XACK for %04X\n", addr);
val = *(uint8 *)(isbc064_unit.filebuf + (addr - org));
if (isbc064_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
} else {
if (isbc064_dev.dctrl & DEBUG_read)
printf(" Out of range\n");
return 0xFF; /* multibus has active high pullups */
}
}
if (isbc064_dev.dctrl & DEBUG_read)
printf(" Disabled\n");
return 0xFF; /* multibus has active high pullups */
}
/* get a word from memory */
int32 isbc064_get_mword(int32 addr)
{
int32 val;
val = isbc064_get_mbyte(addr);
val |= (isbc064_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte into memory */
void isbc064_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
int i = 0;
if ((isbc064_dev.flags & DEV_DIS) == 0) {
org = isbc064_unit.u3;
len = isbc064_unit.capac;
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: addr=%04X, val=%02X\n", addr, val);
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: org=%04X, len=%04X\n", org, len);
if ((addr >= org) && (addr < (org + len))) {
SET_XACK(1); /* good memory address */
if (isbc064_dev.dctrl & DEBUG_xack)
printf("isbc064_put_mbyte: Set XACK for %04X\n", addr);
*(uint8 *)(isbc064_unit.filebuf + (addr - org)) = val & 0xFF;
if (isbc064_dev.dctrl & DEBUG_xack)
printf("isbc064_put_mbyte: Return\n");
return;
} else {
if (isbc064_dev.dctrl & DEBUG_write)
printf(" Out of range\n");
return;
}
}
if (isbc064_dev.dctrl & DEBUG_write)
printf("isbc064_put_mbyte: Disabled\n");
}
/* put a word into memory */
void isbc064_put_mword(int32 addr, int32 val)
{
isbc064_put_mbyte(addr, val);
isbc064_put_mbyte(addr+1, val << 8);
}
/* end of isbc064.c */

1699
MDS-800/common/isbc208.c Normal file

File diff suppressed because it is too large Load diff

288
MDS-800/common/multibus.c Normal file
View file

@ -0,0 +1,288 @@
/* multibus.c: Multibus I 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.
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"
#define SET_XACK(VAL) (xack = VAL)
int32 mbirq = 0; /* set no multibus interrupts */
/* function prototypes */
t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num);
void clr_irq(int32 int_num);
int32 nulldev(int32 io, int32 data);
int32 reg_dev(int32 (*routine)(), int32 port);
t_stat multibus_reset (DEVICE *dptr);
int32 multibus_get_mbyte(int32 addr);
int32 multibus_get_mword(int32 addr);
void multibus_put_mbyte(int32 addr, int32 val);
void multibus_put_mword(int32 addr, int32 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */
extern int32 isbc064_get_mbyte(int32 addr);
extern void isbc064_put_mbyte(int32 addr, int32 val);
extern void set_cpuint(int32 int_num);
extern t_stat SBC_reset (DEVICE *dptr);
extern t_stat isbc064_reset (DEVICE *dptr);
extern t_stat isbc208_reset (DEVICE *dptr);
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 int_req; /* i8080 INT signal */
/* multibus Standard SIMH Device Data Structures */
UNIT multibus_unit = {
UDATA (&multibus_svc, 0, 0), 20
};
REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) }
};
DEBTAB multibus_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE multibus_dev = {
"MBIRQ", //name
&multibus_unit, //units
multibus_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&multibus_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
multibus_debug, //debflags
NULL, //msize
NULL //lname
};
/* Service routines to handle simulator functions */
/* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_1:
set_cpuint(INT_R);
clr_irq(SBC208_INT); /***** bad, bad, bad! */
// printf("multibus_svc: mbirq=%04X int_req=%04X\n", mbirq, int_req);
break;
default:
// printf("multibus_svc: default mbirq=%04X\n", mbirq);
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
}
/* Reset routine */
t_stat multibus_reset(DEVICE *dptr)
{
SBC_reset(NULL);
isbc064_reset(NULL);
isbc208_reset(NULL);
printf(" Multibus: Reset\n");
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
}
void set_irq(int32 int_num)
{
mbirq |= int_num;
// printf("set_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
void clr_irq(int32 int_num)
{
mbirq &= ~int_num;
// printf("clr_irq: int_num=%04X mbirq=%04X\n", int_num, mbirq);
}
/* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device is available
*/
struct idev {
int32 (*routine)();
};
struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
};
int32 nulldev(int32 flag, int32 data)
{
SET_XACK(0); /* set no XACK */
if (flag == 0) /* if we got here, no valid I/O device */
return (0xFF);
return 0;
}
int32 reg_dev(int32 (*routine)(), int32 port)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
// printf("Multibus: I/O Port %02X is already assigned\n", port);
} else {
// printf("Port %02X is assigned\n", port);
dev_table[port].routine = routine;
}
}
/* get a byte from memory */
int32 multibus_get_mbyte(int32 addr)
{
SET_XACK(0); /* set no XACK */
// printf("multibus_get_mbyte: Cleared XACK for %04X\n", addr);
return isbc064_get_mbyte(addr);
}
/* get a word from memory */
int32 multibus_get_mword(int32 addr)
{
int32 val;
val = multibus_get_mbyte(addr);
val |= (multibus_get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory */
void multibus_put_mbyte(int32 addr, int32 val)
{
SET_XACK(0); /* set no XACK */
// printf("multibus_put_mbyte: Cleared XACK for %04X\n", addr);
isbc064_put_mbyte(addr, val);
// printf("multibus_put_mbyte: Done XACK=%dX\n", XACK);
}
/* put a word to memory */
void multibus_put_mword(int32 addr, int32 val)
{
multibus_put_mbyte(addr, val);
multibus_put_mbyte(addr+1, val << 8);
}

193
MDS-800/common/pata.c Normal file
View file

@ -0,0 +1,193 @@
/* i8255.c: Intel i8255 PIO 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 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.
All I/O is via programmed I/O. The i8255 has a control port (PIOS)
and three data ports (PIOA, PIOB, and PIOC).
The simulated device supports a select from I/O space and two address lines.
The data ports are at the lower addresses and the control port is at
the highest.
A write to the control port can configure the device:
Control Word
+---+---+---+---+---+---+---+---+
| D7 D6 D5 D4 D3 D2 D1 D0|
+---+---+---+---+---+---+---+---+
Group B
D0 Port C (lower) 1-Input, 0-Output
D1 Port B 1-Input, 0-Output
D2 Mode Selection 0-Mode 0, 1-Mode 1
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
D7 Mode Set Flag 1=Active, 0=Bit Set
Mode 0 - Basic Input/Output
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.
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
*/
#include "system_defs.h"
extern int32 reg_dev(int32 (*routine)(), int32 port);
/* function prototypes */
t_stat pata_reset (DEVICE *dptr, int32 base);
/* i8255 Standard I/O Data Structures */
UNIT pata_unit[] = {
{ UDATA (0, 0, 0) }
};
REG pata_reg[] = {
{ HRDATA (CONTROL0, pata_unit[0].u3, 8) },
{ HRDATA (PORTA0, pata_unit[0].u4, 8) },
{ HRDATA (PORTB0, pata_unit[0].u5, 8) },
{ HRDATA (PORTC0, pata_unit[0].u6, 8) },
{ NULL }
};
DEVICE pata_dev = {
"PATA", //name
pata_unit, //units
pata_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &pata_reset, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
NULL, //debflags
NULL, //msize
NULL //lname
};
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
int32 patas(int32 io, int32 data)
{
int32 bit;
if (io == 0) { /* read status port */
return pata_unit[0].u3;
} else { /* write status port */
if (data & 0x80) { /* mode instruction */
pata_unit[0].u3 = data;
printf("PATA: 8255 Mode Instruction=%02X\n", data);
if (data & 0x64)
printf(" Mode 1 and 2 not yet implemented\n");
} else { /* bit set */
bit = (data & 0x0E) >> 1; /* get bit number */
if (data & 0x01) { /* set bit */
pata_unit[0].u6 |= (0x01 << bit);
} else { /* reset bit */
pata_unit[0].u6 &= ~(0x01 << bit);
}
}
}
return 0;
}
int32 pataa(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u4);
} else { /* write data port */
pata_unit[0].u4 = data;
printf("PATA: 8255 Port A = %02X\n", data);
}
return 0;
}
int32 patab(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u5);
} else { /* write data port */
pata_unit[0].u5 = data;
printf("PATA: 8255 Port B = %02X\n", data);
}
return 0;
}
int32 patac(int32 io, int32 data)
{
if (io == 0) { /* read data port */
return (pata_unit[0].u6);
} else { /* write data port */
pata_unit[0].u6 = data;
printf("PATA: 8255 Port C = %02X\n", data);
}
return 0;
}
/* Reset routine */
t_stat pata_reset (DEVICE *dptr, int32 base)
{
pata_unit[0].u3 = 0x9B; /* control */
pata_unit[0].u4 = 0xFF; /* Port A */
pata_unit[0].u5 = 0xFF; /* Port B */
pata_unit[0].u6 = 0xFF; /* Port C */
reg_dev(pataa, base);
reg_dev(patab, base + 1);
reg_dev(patac, base + 2);
reg_dev(patas, base + 3);
printf(" PATA: Reset\n");
return SCPE_OK;
}

1382
MDS-800/makefile Normal file

File diff suppressed because it is too large Load diff