MDS-800: Initial simulator commit
This commit is contained in:
parent
cd799c9d3f
commit
4179eeb19f
34 changed files with 16359 additions and 0 deletions
44
MDS-800/MDS-800/Mds-800.cfg
Normal file
44
MDS-800/MDS-800/Mds-800.cfg
Normal 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
211
MDS-800/MDS-800/Mds-800.txt
Normal 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
BIN
MDS-800/MDS-800/Mds-800.vsd
Normal file
Binary file not shown.
BIN
MDS-800/MDS-800/functional description.vsd
Normal file
BIN
MDS-800/MDS-800/functional description.vsd
Normal file
Binary file not shown.
81
MDS-800/MDS-800/mds-800_sys.c
Normal file
81
MDS-800/MDS-800/mds-800_sys.c
Normal 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"
|
||||
};
|
||||
|
84
MDS-800/MDS-800/system_defs.h
Normal file
84
MDS-800/MDS-800/system_defs.h
Normal 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 */
|
||||
|
211
MDS-800/System_80-10/System_80-10.txt
Normal file
211
MDS-800/System_80-10/System_80-10.txt
Normal 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/System_80-10/System_80-10.vsd
Normal file
BIN
MDS-800/System_80-10/System_80-10.vsd
Normal file
Binary file not shown.
BIN
MDS-800/System_80-10/functional description.vsd
Normal file
BIN
MDS-800/System_80-10/functional description.vsd
Normal file
Binary file not shown.
41
MDS-800/System_80-10/system_80_10.cfg
Normal file
41
MDS-800/System_80-10/system_80_10.cfg
Normal 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
|
||||
|
78
MDS-800/System_80-10/system_80_10_sys.c
Normal file
78
MDS-800/System_80-10/system_80_10_sys.c
Normal 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"
|
||||
};
|
||||
|
81
MDS-800/System_80-10/system_defs.h
Normal file
81
MDS-800/System_80-10/system_defs.h
Normal 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
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
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
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
252
MDS-800/common/i8251.c
Normal 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
459
MDS-800/common/i8255.c
Normal 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
304
MDS-800/common/i8259.c
Normal 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
252
MDS-800/common/i8273.c
Normal 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
351
MDS-800/common/i8274.c
Normal 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
143
MDS-800/common/iSBC80-10.c
Normal 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
149
MDS-800/common/iSBC80-20.c
Normal 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
149
MDS-800/common/iSBC80-30.c
Normal 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
201
MDS-800/common/ieprom.c
Normal 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
486
MDS-800/common/ijedec.c
Normal 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
203
MDS-800/common/iram16.c
Normal 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
168
MDS-800/common/iram8.c
Normal 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
202
MDS-800/common/isbc064.c
Normal 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
256
MDS-800/common/isbc064b.c
Normal 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
205
MDS-800/common/isbc064x.c
Normal 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
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
288
MDS-800/common/multibus.c
Normal 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
193
MDS-800/common/pata.c
Normal 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
1382
MDS-800/makefile
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue