mirror of
https://github.com/open-simh/simh.git
synced 2026-04-29 21:27:07 +00:00
Notes For V2.9-11
1. New Features 1.1 GRI-909 - This is a new simulator for the GRI-909. - It has been hand-tested; so far, no software has been discovered. 1.2 VAX - SET CPU CONHALT will cause a HALT instruction to return to the boot ROM console rather than to SIMH. SET CPU SIMHALT restores the default behavior. - BRB/W self at IPL 1F stops the simulator. This is the default behavior of VMS at exit. 1.3 PDP-18b - ATTACH -A PTR/PTP attaches the reader and punch in ASCII mode. In ASCII mode, the reader automatically sets the high order bit of incoming alphabetic data, and the punch clears the high order bit of outgoing data. 1.4 SCP - DO -V echoes commands from the file as they are executed. - Under Windows, execution priority is set BELOW_NORMAL when the simulator is running. 2. Release Notes 2.1 Bugs Fixed - PDP-11 CPU: fixed updating of MMR0 on a memory management error. - VAX FPA: changed function names to avoid conflict with C math library. - 1401 MT: read end of record generates group mark without word mark. - 1401 DP: fixed address generation and checking. - SCP: an EXIT within a DO command will cause the simulator to exit. 3. In Progress - Interdata 16b/32b: coded, not tested. - SDS 940: coded, not tested. - IBM 1620: coded, not tested. If you would like to help with the debugging of the untested simulators, they can be made available by special request.
This commit is contained in:
committed by
Mark Pizzolato
parent
701f0fe028
commit
df6475181c
@@ -1,5 +1,15 @@
|
||||
Altair 8800 Simulator
|
||||
=====================
|
||||
Altair 8800 Simulator with Z80 support
|
||||
======================================
|
||||
|
||||
0. Revision History
|
||||
|
||||
Original version of this document written by Charles E Owen
|
||||
- 4-May-2002, Peter Schorn (added description of MP/M II sample software)
|
||||
- 28-Apr-2002, Peter Schorn (added periodic timer interrupts and three
|
||||
additional consoles)
|
||||
- 15-Apr-2002, Peter Schorn (added memory breakpoint)
|
||||
- 7-Apr-2002, Peter Schorn (added ROM / NOROM switch)
|
||||
|
||||
|
||||
1. Background.
|
||||
|
||||
@@ -18,6 +28,7 @@ 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,
|
||||
@@ -51,10 +62,12 @@ a minimum of 24K.
|
||||
will not or not properly run on a Z80. This is mainly due to the use
|
||||
of the parity flag on the 8080 which has not always the same
|
||||
semantics on the Z80.
|
||||
|
||||
SET CPU ITRAP Causes the simulator to halt if an invalid opcode
|
||||
is detected (depending on the chosen CPU).
|
||||
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
|
||||
@@ -64,10 +77,27 @@ a minimum of 24K.
|
||||
The 2K EPROM at the high end of memory is always
|
||||
present and will always boot.
|
||||
|
||||
The BOOT EPROM card starts at address FF00. 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.
|
||||
SET CPU BANKED Enables the banked memory support. The simulated memory
|
||||
has four banks with address range 0..'common' (see registers below)
|
||||
and a common area from 'common' to 0xfff which is common to all
|
||||
banks. The currently active bank is determined by register 'bank'
|
||||
(see below). You can only switch to banked memory if the memory
|
||||
is set to 64K. The banked memory is used by CP/M 3.
|
||||
|
||||
SET CPU NONBANKED Disables banked memory support.
|
||||
|
||||
SET CPU ROM Enables the boot EPROM at address 0FF00H and prevents
|
||||
write access to the locations from 0FF00H to 0FFFFH. This is the
|
||||
default setting.
|
||||
|
||||
SET CPU NOROM Disables the boot EPROM at address 0FF00H and enables
|
||||
write access to the locations from 0FF00H to 0FFFFH.
|
||||
|
||||
The BOOT EPROM card starts at address 0FF00H. Jumping to this address
|
||||
will boot drive 0 of the floppy controller (CPU must be set to ROM or
|
||||
equivalent code must be present). 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
|
||||
@@ -109,6 +139,11 @@ CPU Registers include the following:
|
||||
keystroke so best to change this to something
|
||||
exotic such as 035 (which is Ctl-]).
|
||||
|
||||
BANK 3 The currently active memory bank (if banked memory
|
||||
is activated - see memory options above)
|
||||
COMMON 16 The starting address of common memory. Originally set
|
||||
to 0xc000 (note this setting must agree with the
|
||||
value supplied to GENCPM for CP/M 3 system generation)
|
||||
|
||||
2.2 The Serial I/O Card (2SIO)
|
||||
|
||||
@@ -134,13 +169,39 @@ simple stream of 8-bit bytes.
|
||||
|
||||
SET SIO BS Map the delete character to backspace
|
||||
SET SIO DEL Map the backspace character to delete
|
||||
|
||||
|
||||
SET SIO QUIET Do not print warning messages
|
||||
SET SIO VERBOSE Print warning messages (useful for debugging)
|
||||
The register SIOWL determines how often the same warning
|
||||
is displayed. The default is 3.
|
||||
|
||||
You can also attach the SIO to a port:
|
||||
|
||||
|
||||
ATTACH SIO 23 Console IO goes via a Telnet connection on port 23
|
||||
DETACH SIO Console IO goes via the regular SIMH console
|
||||
|
||||
2.3 The 88-DISK controller.
|
||||
2.3 The SIMH pseudo device
|
||||
|
||||
The SIMH pseudo device facilitates the communication between the simulated
|
||||
ALTAIR and the simulator environment. This device defines a number of (most R/O)
|
||||
registers (see source code) which are primarily useful for debugging purposes.
|
||||
|
||||
The SIMH pseudo device can be configured with
|
||||
|
||||
SET SIMH QUIET Do not print warning messages
|
||||
SET SIMH VERBOSE Print warning messages (useful for debugging)
|
||||
|
||||
SET SIMH TIMERON Start periodic timer interrupts
|
||||
SET SIMH TIMEROFF Stop the periodic timer interrupts
|
||||
|
||||
The following variables determine the behavior of the timer:
|
||||
|
||||
TIMD This is the delay between consecutive interrupts in milliseconds.
|
||||
Use D TIMD 20 for a 50 Hz clock.
|
||||
TIMH This is the address of the interrupt handler to call for a
|
||||
timer interrupt.
|
||||
|
||||
2.4 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
|
||||
@@ -165,9 +226,21 @@ have been defined with the following meaning:
|
||||
8 Print a message whenever the disk head appears to be waiting for a
|
||||
sector which does not show up (often an indication of an infinite
|
||||
loop)
|
||||
|
||||
For example the command "D TRACE 10" will trace options 2+8 from above.
|
||||
|
||||
|
||||
For example the command "D TRACE 10" will trace options 2+8 from above.
|
||||
|
||||
The DSK device can be configured with
|
||||
|
||||
SET DSK<n> QUIET Do not print warning messages for disk <n>
|
||||
SET DSK<n> VERBOSE Print warning messages for disk <n>
|
||||
(useful for debugging)
|
||||
The register DSKWL determines how often the
|
||||
same warning is displayed. The default is 3.
|
||||
|
||||
SET DSK<n> WRITEENABLED Allow write operations for disk <n>
|
||||
SET DSK<n> LOCKED Disk <n> is locked, i.e. no write operations
|
||||
will be allowed.
|
||||
|
||||
|
||||
3. Sample Software
|
||||
|
||||
@@ -187,10 +260,8 @@ 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 dsk altcpm.dsk
|
||||
sim> go ff00
|
||||
62K CP/M VERSION 2.2 (ALTAIR 8800)
|
||||
A>DIR
|
||||
sim> attach dsk cpm2.dsk
|
||||
sim> boot dsk
|
||||
|
||||
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
|
||||
@@ -200,60 +271,360 @@ 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.
|
||||
DECish. DDT is the debugger, DO 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".
|
||||
image (on drive A) is "SYSCPM2.SUB". To run it, type "DO SYSCPM2".
|
||||
|
||||
In order to efficiently transfer files into the CP/M environment use the
|
||||
included program READ <filename.ext>. If you have a file named foo.ext in
|
||||
included program R <filename.ext>. If you have a file named foo.ext in
|
||||
the current directory (i.e. the directory where SIMH is), executing
|
||||
READ FOO.EXT under CP/M will transfer the file onto the CP/M disk. READ will
|
||||
only run with Z80 CPU so remember to "SET CPU Z80".
|
||||
R FOO.EXT under CP/M will transfer the file onto the CP/M disk.
|
||||
Transferring a file from the CP/M environment to the SIMH environment is
|
||||
accomplished by W <filename.ext>.
|
||||
|
||||
The disk "altcpm.dsk" contains the following files:
|
||||
Name Ext Size Comment
|
||||
ABOOT62 ASM 1K Moves CP/M image from MOVCPM location to real location
|
||||
in memory
|
||||
ASM COM 8K Standard CP/M assembler
|
||||
CALC PRO 3K Prolog sample file "Calculator"
|
||||
CBIOS ASM 8K BIOS for the Altair (used for sysgen)
|
||||
COPY COM 1K ALTAIR diskette backup program
|
||||
CPM62 COM 9K CP/M binary (used for sysgen)
|
||||
DDT COM 5K Dynamic Debugging Tool (Standard CP/M)
|
||||
DDTZ COM 10K Dynamic Debugging Tool for Z80
|
||||
DUMP ASM 5K Assembler source for DUMP utility
|
||||
DUMP COM 1K Dumps the contents of a file in hex (Standard CP/M)
|
||||
ED COM 7K Line oriented editor (Standard CP/M)
|
||||
FAMILY PRO 2K Prolog sample file "Family relations"
|
||||
FORMAT COM 2K Formats a disk
|
||||
INTEGER PRO 1K Prolog sample file "Integer arithmetic"
|
||||
KNAKE PRO 2K Prolog sample file "Logic puzzle"
|
||||
LOAD COM 2K Loads a hex file and produces an executable
|
||||
(Standard CP/M)
|
||||
LS COM 3K Directory utility
|
||||
MOVCPM COM 12K Regenerates the CP/M system for a particular
|
||||
memory size (Standard CP/M)
|
||||
PINST COM 4K Terminal installer for PROLOGZ.COM
|
||||
PIP COM 8K Peripheral Interchange Program for copying files
|
||||
(Standard CP/M)
|
||||
PROLOGZ COM 17K Prolog development environment
|
||||
PROLOGZ TXT 40K PROLOGZ documentation in German
|
||||
PTD ASM 2K Writes Altair-format memory image to disk
|
||||
(used for sysgen)
|
||||
QUEEN PRO 2K Prolog sample file "N Queens problem"
|
||||
READ COM 2K Reads a file from the SIMH filesystem to CP/M
|
||||
README TXT 3K This file
|
||||
STAT COM 6K Provides information about drives, disks and
|
||||
files (Standard CP/M)
|
||||
SUBMIT COM 2K Submits a file of commands for batch processing
|
||||
(Standard CP/M)
|
||||
SURVEY COM 2K Provides information about memory and IO ports
|
||||
SYSCOPY COM 2K Copies the reserved tracks between disks
|
||||
SYSGEN SUB 2K Submit file for generating the CP/M system
|
||||
XSUB COM 2K Addition to SUBMIT such that all input is read
|
||||
from the submit file (Standard CP/M)
|
||||
The disk "cpm2.dsk" contains the following files:
|
||||
Name Ext Size Comment
|
||||
ASM .COM 8K ; CP/M assembler
|
||||
BDOS .MAC 66K ; Basic Disk Operating System assembler source code
|
||||
BOOT .COM 1K ; transfer control to boot ROM
|
||||
BOOT .MAC 2K ; source for BOOT.COM
|
||||
BOOTGEN .COM 2K ; put a program on the boot sectors
|
||||
CBIOSX .MAC 10K ; CP/M 2 BIOS source for Altair
|
||||
CCP .MAC 26K ; Console Command Processor assembler source code
|
||||
COPY .COM 1K ; copy disks
|
||||
CPMBOOT .COM 12K ; CP/M operating system
|
||||
CREF80 .COM 4K ; cross reference utility
|
||||
DDT .COM 5K ; 8080 debugger
|
||||
DDTZ .COM 10K ; Z80 debugger
|
||||
DIF .COM 3K ; determine differences between two files
|
||||
DO .COM 2K ; batch processing
|
||||
DSKBOOT .COM 1K ; code for boot ROM
|
||||
DSKBOOT .MAC 3K ; source for boot ROM
|
||||
DUMP .COM 1K ; hex dump a file
|
||||
ED .COM 7K ; line editor
|
||||
ELIZA .BAS 9K ; Elisa game in Basic
|
||||
EX8080 .COM 9K ; exercise 8080 instruction set
|
||||
EX8080 .MAC 47K ; source for EX8080.COM
|
||||
EX8080 .SUB 1K ; benchmark execution of EX8080.COM
|
||||
EXZ80 .COM 9K ; exercise Z80 instruction set
|
||||
EXZ80 .MAC 47K ; source for EXZ80.COM
|
||||
EXZ80 .SUB 1K ; benchmark execution of EXZ80.COM
|
||||
FORMAT .COM 2K ; format disks
|
||||
GO .COM 0K ; start the currently loaded program at 100H
|
||||
L80 .COM 11K ; Microsoft linker
|
||||
LADDER .COM 40K ; game
|
||||
LADDER .DAT 1K ; high score file for LADDER.COM
|
||||
LIB80 .COM 6K ; library utility
|
||||
LOAD .COM 2K ; load hex files
|
||||
LS .COM 3K ; directory utility
|
||||
LU .COM 20K ; library utility
|
||||
M80 .COM 20K ; Microsoft macro assembler
|
||||
MBASIC .COM 24K ; Microsoft Basic interpreter
|
||||
MC .SUB 1K ; assemble and link an assmbler program
|
||||
MCC .SUB 1K ; read, assemble and link an assmbler program
|
||||
MOVER .MAC 2K ; moves operating system in place
|
||||
OTHELLO .COM 12K ; Othello (Reversi) game
|
||||
PIP .COM 8K ; Peripheral Interchange Program
|
||||
R .COM 3K ; read files from SIMH environment
|
||||
RSETSIMH.COM 1K ; reset SIMH interface
|
||||
RSETSIMH.MAC 1K ; assembler source for RSETSIMH.COM
|
||||
SHOWSEC .COM 3K ; show sectors on a disk
|
||||
SID .COM 8K ; debugger for 8080
|
||||
STAT .COM 6K ; provide information about currently logged disks
|
||||
SURVEY .COM 2K ; system survey
|
||||
SURVEY .MAC 15K ; assembler source for SURVEY.COM
|
||||
SYSCOPY .COM 2K ; copy system tracks between disks
|
||||
SYSCPM2 .SUB 1K ; create CP/M 2 on drive A:
|
||||
TSHOW .COM 1K ; show split time
|
||||
TSHOW .MAC 1K ; assembler source for TSHOW.COM
|
||||
TSTART .COM 1K ; create timer and start it
|
||||
TSTART .MAC 1K ; assembler source for TSTART.COM
|
||||
TSTOP .COM 1K ; show final time and stop timer
|
||||
TSTOP .MAC 1K ; assembler source for TSTOP.COM
|
||||
UNCR .COM 7K ; un-crunch utility
|
||||
UNERA .COM 2K ; un-erase a file
|
||||
UNERA .MAC 16K ; source for UNERA.COM
|
||||
USQ .COM 2K ; un-squeeze utility
|
||||
W .COM 3K ; write files to SIMH environment
|
||||
WM .COM 11K ; word master screen editor
|
||||
WM .HLP 3K ; help file for WM.COM
|
||||
WORM .COM 4K ; worm game for VT100 terminal
|
||||
XSUB .COM 1K ; support for DO.COM
|
||||
ZSID .COM 10K ; debugger for Z80
|
||||
ZTRAN4 .COM 4K ; translate 8080 mnemonics into Z80 equivalents
|
||||
|
||||
3.2 MITS Disk Extended BASIC Version 4.1
|
||||
|
||||
3.2 CP/M Version 3 with banked memory
|
||||
CP/M 3 is the successor to CP/M 2.2. A customised BIOS (BIOS3.MAC)
|
||||
is included to facilitate modification if so desired. The defaults supplied in
|
||||
GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to
|
||||
place the CP/M loader (LDR.COM) on the boot tracks of a disk.
|
||||
|
||||
Running CP/M 3 with banked memory:
|
||||
sim> attach dsk cpm3.dsk
|
||||
sim> reset cpu
|
||||
sim> set cpu banked
|
||||
sim> set cpu itrap
|
||||
sim> boot dsk
|
||||
|
||||
Executing "DO SYSCPM3" will re-generate the banked version of CP/M 3.
|
||||
You can boot CP/M 3 with or without a Z80 CPU. The Z80 CPU is needed for
|
||||
both sysgens due to the use of BOOTGEN.COM which requires it.
|
||||
|
||||
The disk "cpm3.dsk" contains the following files:
|
||||
ASM .COM 8K ; CP/M assembler
|
||||
ASSIGN .SYS 2K
|
||||
BDOS3 .SPR 10K
|
||||
BIOS3 .MAC 28K ; CP/M 3 BIOS source for Altair SIMH
|
||||
BIOS3 .SPR 4K
|
||||
BNKBDOS3.SPR 14K
|
||||
BNKBIOS3.SPR 4K
|
||||
BOOT .COM 2K ; transfer control to boot ROM
|
||||
BOOTGEN .COM 2K ; put a program on the boot sectors
|
||||
CCP .COM 4K
|
||||
COPYSYS .COM 2K
|
||||
CPM3 .SYS 18K
|
||||
CPMLDR .MAC 38K ; CP/M 3 loader assembler source
|
||||
DATE .COM 4K ; date utility
|
||||
DDT .COM 6K ; 8080 debugger
|
||||
DDTZ .COM 10K ; Z80 debugger
|
||||
DEFS .LIB 2K ; include file for BIOS3.MAC to create banked CP/M 3
|
||||
DEVICE .COM 8K
|
||||
DIF .COM 4K ; determine differences between two files
|
||||
DIR .COM 16K ; directory utility
|
||||
DO .COM 6K ; batch processing
|
||||
DUMP .COM 2K
|
||||
ED .COM 10K
|
||||
ERASE .COM 4K
|
||||
GENCOM .COM 16K
|
||||
GENCPM .COM 22K
|
||||
GENCPM .DAT 4K ; CP/M generation information for banked version
|
||||
GENCPMNB.DAT 4K ; CP/M generation information for non-banked version
|
||||
GET .COM 8K
|
||||
HELP .COM 8K ; help utility
|
||||
HELP .HLP 62K ; help files
|
||||
HEXCOM .CPM 2K
|
||||
HIST .UTL 2K
|
||||
INITDIR .COM 32K
|
||||
L80 .COM 12K ; Microsoft linker
|
||||
LDR .COM 4K ; CP/M loader with optimised loader BIOS
|
||||
LDRBIOS3.MAC 14K ; optimised (for space) loader BIOS
|
||||
LIB .COM 8K ; Digital Research librarian
|
||||
LINK .COM 16K ; Digital Research linker
|
||||
LOAD .COM 2K
|
||||
M80 .COM 20K ; Microsoft macro assembler
|
||||
MC .SUB 2K ; assemble and link an assmbler program
|
||||
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||
PATCH .COM 4K
|
||||
PIP .COM 10K ; Peripheral Interchange Program
|
||||
PROFILE .SUB 2K ; commands to be executed at start up
|
||||
PUT .COM 8K
|
||||
R .COM 4K ; read files from SIMH environment
|
||||
RENAME .COM 4K
|
||||
RESBDOS3.SPR 2K
|
||||
RMAC .COM 14K ; Digital Research macro assembler
|
||||
RSETSIMH.COM 2K ; reset SIMH interface
|
||||
SAVE .COM 2K
|
||||
SCB .MAC 2K
|
||||
SET .COM 12K
|
||||
SETDEF .COM 6K
|
||||
SHOW .COM 10K
|
||||
SHOWSEC .COM 4K ; show sectors on a disk
|
||||
SID .COM 8K ; 8080 debugger
|
||||
SYSCOPY .COM 2K ; copy system tracks between disks
|
||||
SYSCPM3 .SUB 2K ; create banked CP/M 3 system
|
||||
TRACE .UTL 2K
|
||||
TSHOW .COM 2K ; show split time
|
||||
TSTART .COM 2K ; create timer and start it
|
||||
TSTOP .COM 2K ; show final time and stop timer
|
||||
TYPE .COM 4K
|
||||
UNERA .COM 2K ; un-erase a file
|
||||
W .COM 4K ; write files to SIMH environment
|
||||
XREF .COM 16K ; cross reference utility
|
||||
ZSID .COM 10K ; Z80 debugger
|
||||
|
||||
|
||||
3.3 MP/M II with banked memory
|
||||
|
||||
MP/M II is an acronym for MultiProgramming Monitor Control Program for
|
||||
Microprocessors. It is a multiuser operating system for an eight bit
|
||||
microcomputer. MP/M II supports multiprogramming at each terminal. This
|
||||
version supports four terminals available via Telnet. To boot:
|
||||
|
||||
sim> attach dsk mpm.dsk
|
||||
sim> set cpu itrap
|
||||
sim> set cpu z80
|
||||
sim> set cpu rom
|
||||
sim> set cpu banked
|
||||
sim> attach sio 23
|
||||
sim> boot dsk
|
||||
|
||||
Now connect a Telnet session to the simulator and type "MPM" at the "A>"
|
||||
prompt. Now you can connect up to three additional terminals via Telnet
|
||||
to the Altair running MP/M II. To re-generate the system perform
|
||||
"DO SYSMPM" in the CP/M environment (not possible under MP/M since XSUB
|
||||
is needed).
|
||||
|
||||
The disk "mpm.dsk" contains the following files:
|
||||
Name Ext Size Comment
|
||||
ABORT .PRL 2K ; abort a process
|
||||
ABORT .RSP 2K
|
||||
ASM .PRL 10K ; MP/M assembler
|
||||
BNKBDOS .SPR 12K ; banked BDOS
|
||||
BNKXDOS .SPR 2K ; banked XDOS
|
||||
BNKXIOS .SPR 4K ; banked XIOS
|
||||
BOOTGEN .COM 2K ; copy an executable to the boot section
|
||||
CONSOLE .PRL 2K ; print console number
|
||||
CPM .COM 2K ; return to CP/M
|
||||
CPM .MAC 2K ; source for CPM.COM
|
||||
DDT .COM 6K ; MP/M DDT
|
||||
DDT2 .COM 6K ; CP/M DDT
|
||||
DDTZ .COM 10K ; CP/M DDT with Z80 support
|
||||
DIF .COM 4K ; difference between two files
|
||||
DIR .PRL 2K ; directory command
|
||||
DO .COM 2K ; CP/M submit
|
||||
DSKRESET.PRL 2K ; disk reset command
|
||||
DUMP .MAC 6K ; source for DUMP.PRL
|
||||
DUMP .PRL 2K ; dump command
|
||||
ED .PRL 10K ; MP/M line editor
|
||||
ERA .PRL 2K ; erase command
|
||||
ERAQ .PRL 4K ; erase comand (verbose)
|
||||
GENHEX .COM 2K
|
||||
GENMOD .COM 2K
|
||||
GENSYS .COM 10K
|
||||
L80 .COM 12K ; Microsoft linker
|
||||
LDRBIOS .MAC 14K ; loader BIOS
|
||||
LIB .COM 8K ; library utility
|
||||
LINK .COM 16K ; linker
|
||||
LOAD .COM 2K ; loader
|
||||
M80 .COM 20K ; Microsoft macro assembler
|
||||
MC .SUB 2K ; assemble and link an assmbler program
|
||||
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||
MPM .COM 8K ; start MP/M II
|
||||
MPM .SYS 26K ; MP/M system file
|
||||
MPMD .LIB 2K ; define a banked system
|
||||
MPMLDR .COM 6K ; MP/M loader without LDRBIOS
|
||||
MPMSTAT .BRS 6K ; status of MP/M system
|
||||
MPMSTAT .PRL 6K
|
||||
MPMSTAT .RSP 2K
|
||||
MPMXIOS .MAC 26K ; XIOS for MP/M
|
||||
PIP .PRL 10K ; MP/M peripheral interchange program
|
||||
PIP2 .COM 8K ; CP/M peripheral interchange program
|
||||
PRINTER .PRL 2K
|
||||
PRLCOM .PRL 4K
|
||||
R .COM 4K ; read a file from the SIMH environment
|
||||
RDT .PRL 8K ; debugger for page relocatable programs
|
||||
REN .PRL 4K ; rename a file
|
||||
RESBDOS .SPR 4K ; non-banked BDOS
|
||||
RMAC .COM 14K ; Digital Research macro assembler
|
||||
RSETSIMH.COM 2K ; reset SIMH interface
|
||||
SCHED .BRS 2K ; schedule a job
|
||||
SCHED .PRL 4K
|
||||
SCHED .RSP 2K
|
||||
SDIR .PRL 18K ; fancy directory command
|
||||
SET .PRL 8K ; set parameters
|
||||
SHOW .PRL 8K ; show status of disks
|
||||
SPOOL .BRS 4K ; spool utility
|
||||
SPOOL .PRL 4K
|
||||
SPOOL .RSP 2K
|
||||
STAT .COM 6K ; CP/M stat command
|
||||
STAT .PRL 10K ; MP/M stat command
|
||||
STOPSPLR.PRL 2K ; stop spooler
|
||||
SUBMIT .PRL 6K ; MP/M submit
|
||||
SYSCOPY .COM 2K ; copy system tracks
|
||||
SYSMPM .SUB 2K ; do a system generation
|
||||
SYSTEM .DAT 2K ; default values for system generation
|
||||
TMP .SPR 2K
|
||||
TOD .PRL 4K ; time of day
|
||||
TSHOW .COM 2K ; show split time
|
||||
TSTART .COM 2K ; create timer and start it
|
||||
TSTOP .COM 2K ; show final time and stop timer
|
||||
TYPE .PRL 2K ; type a file on the screen
|
||||
USER .PRL 2K ; set user area
|
||||
W .COM 4K ; write a file to SIMH environment
|
||||
XDOS .SPR 10K ; XDOS
|
||||
XREF .COM 16K ; cross reference utility
|
||||
XSUB .COM 2K ; for CP/M DO
|
||||
|
||||
|
||||
3.5 CP/M application software
|
||||
|
||||
There is also a small collection of sample application software containing
|
||||
the following items:
|
||||
|
||||
- SPL: a Small Programming Language with a suite of sample programs
|
||||
- PROLOGZ: a Prolog interpreter written in SPL with sources
|
||||
- PASCFORM: a Pascal pretty printer written in Pascal
|
||||
- Pascal MT+: Pascal language system needed to compile PASCFORM
|
||||
|
||||
The sample software comes on "app.dsk" and to use it do
|
||||
|
||||
sim> attach dsk1 app.dsk
|
||||
|
||||
before booting CP/M.
|
||||
|
||||
The disk "app.dsk" contains the following files:
|
||||
Name Ext Size Comment
|
||||
BOOTGEN .COM 2K
|
||||
BOOTGEN .SPL 6K ; SPL source for BOOTGEN.COM
|
||||
C .SUB 2K ; batch file for compiling an SPL source file
|
||||
CALC .PRO 4K ; Prolog demo program calculator
|
||||
CC .SUB 2K ; compile an SPL source which is on the underlying
|
||||
file system
|
||||
DECLARAT. 12K ; common include file, SPL source
|
||||
DIF .COM 4K
|
||||
DIF .SPL 10K ; SPL source for DIF.COM
|
||||
EDIT .SPL 10K ; screen editor for PROLOGZ, SPL source
|
||||
FAMILY .PRO 4K ; Prolog demo program family relations
|
||||
INTEGER .PRO 2K ; Prolog demo program integer arithmetic
|
||||
KNAKE .PRO 2K ; Prolog demo program logic puzzle
|
||||
LINKMT .COM 12K ; Pascal MT+ 5.5 linker
|
||||
MAIN .SPL 14K ; main module for PROLOGZ, SPL source
|
||||
MOVE .MAC 4K ; helper functions for PROLOGZ in assembler
|
||||
MTERRS .TXT 6K ; Pascal MT+ error messages
|
||||
MTPLUS .000 14K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .001 12K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .002 8K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .003 8K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .004 18K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .005 8K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .006 6K ; Pascal MT+ 5.5 compiler file
|
||||
MTPLUS .COM 36K ; Pascal MT+ 5.5 compiler
|
||||
PASCFORM.COM 36K ; Pascal formatter
|
||||
PASCFORM.PAS 54K ; Pascal formatter source code
|
||||
PASCFORM.SUB 2K ; create Pascal formatter
|
||||
PASLIB .ERL 24K ; Pascal MT+ 5.5 run time library
|
||||
PINST .COM 4K ; terminal installation program for PROLOGZ
|
||||
PINST .SPL 16K ; terminal installation program for PROLOGZ,
|
||||
SPL source
|
||||
PROLOGZ .COM 18K ; PROLOGZ interpreter and screen editor
|
||||
PROLOGZ .SPL 2K ; PROLOGZ main program, SPL source
|
||||
PROLOGZ .TXT 40K ; PROLOGZ documentation in German
|
||||
PROVE .SPL 16K ; backtrack theorem prover for PROLOGZ, SPL source
|
||||
PZCLEAN .SUB 2K ; PROLOGZ: remove all created ".rel" and ".lst" files
|
||||
PZLINK .SUB 2K ; PROLOGZ: create PINST, PROLOGZ and personalise the
|
||||
serial number
|
||||
PZMAKE .SUB 2K ; compiles the sources (you can ignore any compiler
|
||||
errors)
|
||||
QUEEN .PRO 2K ; Prolog demo program n-queens problem
|
||||
READ .COM 4K
|
||||
READ .SPL 10K ; SPL source for R.COM
|
||||
SHOWSEC .COM 4K
|
||||
SHOWSEC .SPL 6K ; SPL source for SHOWSEC.COM
|
||||
SPL .COM 38K ; the SPL compiler itself
|
||||
SPL .TXT 56K ; SPL language and compiler documentation in German
|
||||
SPLERROR.DAT 12K ; error messages of the compiler (in German)
|
||||
SPLIB .REL 6K ; SPL runtime library
|
||||
STDIO . 2K ; include file for SPL programs
|
||||
SYSCOPY .COM 2K
|
||||
SYSCOPY .SPL 6K ; SPL source for SYSCOPY.COM
|
||||
TERMBDOS.SPL 2K ; terminal interface to CP/M for PROLOGZ, SPL source
|
||||
UTIL .SPL 18K ; utility functions for PROLOGZ, SPL source
|
||||
WRITE .COM 4K
|
||||
WRITE .SPL 8K ; SPL source for W.COM
|
||||
|
||||
|
||||
3.6 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
|
||||
@@ -266,22 +637,22 @@ ran under. To boot:
|
||||
sim> go ff00
|
||||
|
||||
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]
|
||||
LINEPRINTER? [C return]
|
||||
HIGHEST DISK NUMBER? [0 return] (0 here = 1 drive system)
|
||||
NUMBER OF FILES? [3 return]
|
||||
NUMBER OF RANDOM FILES? [2 return]
|
||||
|
||||
44041 BYTES FREE
|
||||
ALTAIR BASIC REV. 4.1
|
||||
[DISK EXTENDED VERSION]
|
||||
COPYRIGHT 1977 BY MITS INC.
|
||||
OK
|
||||
MOUNT 0
|
||||
[MOUNT 0]
|
||||
OK
|
||||
FILES
|
||||
[FILES]
|
||||
|
||||
|
||||
3.3 Altair DOS Version 1.0
|
||||
3.7 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
|
||||
@@ -293,27 +664,28 @@ to CP/M. To boot:
|
||||
|
||||
MEMORY SIZE? [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]
|
||||
HIGHEST DISK NUMBER? [0 return] (3 here = 4 drive system)
|
||||
HOW MANY DISK FILES? [3 return]
|
||||
HOW MANY RANDOM FILES? [2 return]
|
||||
|
||||
056449 BYTES AVAILABLE
|
||||
DOS MONITOR VER 1.0
|
||||
COPYRIGHT 1977 BY MITS INC
|
||||
.MNT 0
|
||||
.[MNT 0]
|
||||
|
||||
.DIR 0
|
||||
.[DIR 0]
|
||||
|
||||
3.4 Altair 4k Basic
|
||||
|
||||
3.8 Altair Basic 3.2 (4k)
|
||||
In order to run the famous 4k Basic, use the following commands (the trick
|
||||
is to get the Switch Register right).
|
||||
|
||||
sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU
|
||||
sim> set sio upper ;4k Basic does not like lower case letters as input
|
||||
sim> set sio ansi ;4k Basic produces 8-bit output, strip to seven bits
|
||||
sim> d sr 8 ;good setting for the Switch Register
|
||||
sim> load 4kbas.bin ;load it
|
||||
sim> go ;and go
|
||||
sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU
|
||||
sim> set sio upper ;4k Basic does not like lower case letters as input
|
||||
sim> set sio ansi ;4k Basic produces 8-bit output, strip to seven bits
|
||||
sim> d sr 8 ;good setting for the Switch Register
|
||||
sim> load 4kbas.bin 0 ;load it at 0
|
||||
sim> go 0 ;and start it
|
||||
MEMORY SIZE? [return]
|
||||
TERMINAL WIDTH? [return]
|
||||
WANT SIN? [Y]
|
||||
@@ -325,19 +697,20 @@ is to get the Switch Register right).
|
||||
|
||||
OK
|
||||
|
||||
3.5 Altair 8k Basic
|
||||
|
||||
3.9 Altair 8k Basic
|
||||
Running 8k Basic follows the procedure for 4k Basic.
|
||||
|
||||
sim> set cpu 8080 ;note 8k Basic will not run on a Z80 CPU
|
||||
sim> set sio upper ;8k Basic does not like lower case letters as input
|
||||
sim> set sio ansi ;8k Basic produces 8-bit output, strip to seven bits
|
||||
sim> d sr 8 ;good setting for the Switch Register
|
||||
sim> load 8kbas.bin ;load it
|
||||
sim> go ;and go
|
||||
sim> set cpu 8080 ;note 8k Basic will not run on a Z80 CPU
|
||||
sim> set sio upper ;8k Basic does not like lower case letters as input
|
||||
sim> set sio ansi ;8k Basic produces 8-bit output, strip to seven bits
|
||||
sim> d sr 8 ;good setting for the Switch Register
|
||||
sim> load 8kbas.bin 0 ;load it at 0
|
||||
sim> go 0 ;and start it
|
||||
MEMORY SIZE? [A]
|
||||
|
||||
|
||||
WRITTEN FOR ROYALTIES BY MICRO-SOFT
|
||||
|
||||
|
||||
MEMORY SIZE? [return]
|
||||
TERMINAL WIDTH? [return]
|
||||
WANT SIN-COS-TAN-ATN? [Y]
|
||||
@@ -348,9 +721,46 @@ is to get the Switch Register right).
|
||||
COPYRIGHT 1976 BY MITS INC.
|
||||
OK
|
||||
|
||||
4. Brief summary of all major changes to the original Altair simulator
|
||||
|
||||
3.10 Altair Basic 4.0
|
||||
Execute the following commands to run Altair Extended Basic.
|
||||
|
||||
sim> set sio upper ;Extended Basic does not like lower case letters as input
|
||||
sim> set sio ansi ;Extended Basic produces 8-bit output, strip to seven bits
|
||||
sim> d sr 8 ;good setting for the Switch Register
|
||||
sim> load exbas.bin 0 ;load it at 0
|
||||
sim> go 0 ;and start it
|
||||
16384 Bytes loaded at 0.
|
||||
|
||||
MEMORY SIZE? [return]
|
||||
WANT SIN-COS-TAN-ATN? [Y]
|
||||
|
||||
50606 BYTES FREE
|
||||
ALTAIR BASIC REV. 4.0
|
||||
[EXTENDED VERSION]
|
||||
COPYRIGHT 1977 BY MITS INC.
|
||||
OK
|
||||
|
||||
|
||||
4. Special simulator features
|
||||
In addition to the regular SIMH features such as PC queue, breakpoints
|
||||
etc., this simulator supports memory access breakpoints. A memory access
|
||||
breakpoint is triggered when a pre-defined memory location is accessed
|
||||
(read, write or update). To set a memory location breakpoint enter
|
||||
|
||||
sim> break -m <location>
|
||||
|
||||
Execution will stop whenever an operation accesses <location>. Note that
|
||||
a memory access breakpoint is not triggered by fetching code from memory
|
||||
(this is the job of regular breakpoints). This feature has been
|
||||
implemented by using the typing facility of the SIMH breakpoints.
|
||||
|
||||
|
||||
5. Brief summary of all major changes to the original Altair simulator
|
||||
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
|
||||
properly. DDTZ and PROLOGZ are included for demonstration purposes.
|
||||
- Added banked memory support.
|
||||
- PC queue implemented.
|
||||
- Full assembler and dis-assembler support for Z80 and 8080 mnemonics.
|
||||
Depending on the current setting of the CPU, the appropriate mnemonics
|
||||
are used.
|
||||
@@ -360,16 +770,27 @@ is to get the Switch Register right).
|
||||
- ROM and memory size settings are now fully honored. This means that you
|
||||
cannot write into the ROM or outside the defined RAM (e.g. when the RAM size
|
||||
was truncated with the SET CPU commands). This feature allows programs which
|
||||
check for the size of available RAM to run properly (e.g. 4k Basic).
|
||||
check for the size of available RAM to run properly (e.g. 4k Basic). In
|
||||
addition one can enable and disable the ROM which is useful in special cases
|
||||
(e.g. when testing a new version of the ROM).
|
||||
- The console can also be used via Telnet. This is useful when a terminal is
|
||||
needed which supports cursor control such as a VT100. PROLOGZ for example
|
||||
has a built-in screen editor which works under Telnet.
|
||||
- Simplified file exchange for CP/M. Using the READ program under CP/M one
|
||||
can easily import files into CP/M from the regular file system. Note that PIP
|
||||
does not work properly on non-text files on PTR.
|
||||
- The WRITE program can be used to transfer files from the CP/M environment to
|
||||
the regular environment (binary or ASCII transfer).
|
||||
- The last character read from PTR is always Control-Z (the EOF character for
|
||||
CP/M). This makes sure that PIP (Peripheral Interchange Program on CP/M) will
|
||||
terminate properly.
|
||||
- Fixed a bug in the BIOS warm boot routine which caused CP/M to crash.
|
||||
- Modified the BIOS for CP/M to support 8 disks.
|
||||
- Changed from octal to hex which is more concise.
|
||||
- Added CP/M 3 banked version as sample software
|
||||
- Changed from octal to hex
|
||||
- Made the DSK and SIO device more robust (previously malicious code could
|
||||
crash the simulator)
|
||||
- Added memory access break points
|
||||
- Added periodic timer interrupts (useful for MP/M)
|
||||
- Added additional consoles (useful for MP/M)
|
||||
- Added MP/M II banked version as sample software
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,30 +1,46 @@
|
||||
/* altairZ80_defs.h: MITS Altair simulator definitions
|
||||
Written by Peter Schorn, 2001
|
||||
Written by Peter Schorn, 2001-2002
|
||||
Based on work by Charles E Owen ((c) 1997, Commercial use prohibited)
|
||||
*/
|
||||
|
||||
#include "sim_defs.h" /* simulator definitions */
|
||||
#include "sim_defs.h" /* simulator definitions */
|
||||
|
||||
/* Memory */
|
||||
#define MAXMEMSIZE 65536 /* max memory size */
|
||||
#define KB 1024 /* kilo byte */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
|
||||
#define bootrom_size 256 /* size of boot rom */
|
||||
#define bootrom_origin 0xFF00 /* start address of boot rom */
|
||||
#define MAXMEMSIZE 65536 /* max memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
|
||||
#define bootrom_size 256 /* size of boot rom */
|
||||
#define MAXBANKS 8 /* max number of memory banks */
|
||||
#define MAXBANKSLOG2 3 /* log2 of MAXBANKS */
|
||||
#define BANKMASK (MAXBANKS-1) /* bank mask */
|
||||
|
||||
#define BACKSPACE_CHAR 0x08 /* backspace character */
|
||||
#define DELETE_CHAR 0x7f /* delete character */
|
||||
#define CONTROLZ_CHAR 26 /* control Z character */
|
||||
|
||||
/* Simulator stop codes */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_OPCODE 4
|
||||
|
||||
#define UNIT_V_OPSTOP (UNIT_V_UF) /* Stop on Invalid OP? */
|
||||
#define UNIT_V_OPSTOP (UNIT_V_UF) /* Stop on Invalid OP? */
|
||||
#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP)
|
||||
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 */
|
||||
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 */
|
||||
#define UNIT_CHIP (1 << UNIT_V_CHIP)
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* Memory Size */
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_V_BANKED (UNIT_V_UF+3) /* Banked memory is used */
|
||||
#define UNIT_BANKED (1 << UNIT_V_BANKED)
|
||||
#define UNIT_V_ROM (UNIT_V_UF+4) /* ROM exists */
|
||||
#define UNIT_ROM (1 << UNIT_V_ROM)
|
||||
|
||||
#define PCformat "\n[%04xh] "
|
||||
#define message1(p1) sprintf(messageBuffer,PCformat p1,PCX); printMessage()
|
||||
#define message2(p1,p2) sprintf(messageBuffer,PCformat p1,PCX,p2); printMessage()
|
||||
#define message3(p1,p2,p3) sprintf(messageBuffer,PCformat p1,PCX,p2,p3); printMessage()
|
||||
#define message4(p1,p2,p3,p4) sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4); printMessage()
|
||||
|
||||
/* The Default is to use "inline". In this case the wrapper functions for
|
||||
GetBYTE and PutBYTE need to be created. Otherwise they are not needed
|
||||
and the calls map to the original functions. */
|
||||
#ifdef NO_INLINE
|
||||
#define INLINE
|
||||
#define GetBYTEWrapper GetBYTE
|
||||
#define PutBYTEWrapper PutBYTE
|
||||
#else
|
||||
#if defined(__DECC) && defined(VMS)
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
/* altairZ80_dsk.c: MITS Altair 88-DISK Simulator
|
||||
Written by Charles E Owen ((c) 1997, Commercial use prohibited)
|
||||
Minor modifications by Peter Schorn, 2001
|
||||
Modifications to improve robustness by Peter Schorn, 2001-2002
|
||||
|
||||
The 88_DISK is a 8-inch floppy controller which can control up
|
||||
to 16 daisy-chained Pertec FD-400 hard-sectored floppy drives.
|
||||
Each diskette has physically 77 tracks of 32 137-byte sectors
|
||||
each.
|
||||
|
||||
|
||||
The controller is interfaced to the CPU by use of 3 I/O addreses,
|
||||
standardly, these are device numbers 10, 11, and 12 (octal).
|
||||
|
||||
|
||||
Address Mode Function
|
||||
------- ---- --------
|
||||
|
||||
|
||||
10 Out Selects and enables Controller and Drive
|
||||
10 In Indicates status of Drive and Controller
|
||||
11 Out Controls Disk Function
|
||||
11 In Indicates current sector position of disk
|
||||
12 Out Write data
|
||||
12 In Read data
|
||||
|
||||
|
||||
Drive Select Out (Device 10 OUT):
|
||||
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| C | X | X | X | Device |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
|
||||
C = If this bit is 1, the disk controller selected by 'device' is
|
||||
cleared. If the bit is zero, 'device' is selected as the
|
||||
device being controlled by subsequent I/O operations.
|
||||
X = not used
|
||||
Device = value zero thru 15, selects drive to be controlled.
|
||||
|
||||
|
||||
Drive Status In (Device 10 IN):
|
||||
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| R | Z | I | X | X | H | M | W |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
|
||||
W - When 0, write circuit ready to write another byte.
|
||||
M - When 0, head movement is allowed
|
||||
H - When 0, indicates head is loaded for read/write
|
||||
@@ -45,20 +45,20 @@
|
||||
I - When 0, indicates interrupts enabled (not used this simulator)
|
||||
Z - When 0, indicates head is on track 0
|
||||
R - When 0, indicates that read circuit has new byte to read
|
||||
|
||||
|
||||
Drive Control (Device 11 OUT):
|
||||
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| W | C | D | E | U | H | O | I |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
|
||||
I - When 1, steps head IN one track
|
||||
O - When 1, steps head OUT one track
|
||||
H - When 1, loads head to drive surface
|
||||
U - When 1, unloads head
|
||||
E - Enables interrupts (ignored this simulator)
|
||||
D - Disables interrupts (ignored this simulator)
|
||||
C - When 1 lowers head current (ignored this simulator)
|
||||
E - Enables interrupts (ignored by this simulator)
|
||||
D - Disables interrupts (ignored by this simulator)
|
||||
C - When 1 lowers head current (ignored by this simulator)
|
||||
W - When 1, starts Write Enable sequence: W bit on device 10
|
||||
(see above) will go 1 and data will be read from port 12
|
||||
until 137 bytes have been read by the controller from
|
||||
@@ -67,16 +67,16 @@
|
||||
stepped the track to the desired number, and waited until
|
||||
the right sector number is presented on device 11 IN, then
|
||||
set this bit.
|
||||
|
||||
|
||||
Sector Position (Device 11 IN):
|
||||
|
||||
|
||||
As the sectors pass by the read head, they are counted and the
|
||||
number of the current one is available in this register.
|
||||
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| X | X | Sector Number | T |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
|
||||
X = Not used
|
||||
Sector number = binary of the sector number currently under the
|
||||
head, 0-31.
|
||||
@@ -88,85 +88,207 @@
|
||||
#include <stdio.h>
|
||||
#include "altairZ80_defs.h"
|
||||
|
||||
#define UNIT_V_ENABLE (UNIT_V_UF + 0) /* Write Enable */
|
||||
#define UNIT_ENABLE (1 << UNIT_V_ENABLE)
|
||||
#define DSK_SECTSIZE 137 /* size of sector */
|
||||
#define DSK_SECT 32 /* sectors per track */
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_WLK (1 << UNIT_V_UF)
|
||||
#define UNIT_V_DSK_VERBOSE (UNIT_V_UF + 1) /* verbose mode, i.e. show error messages */
|
||||
#define UNIT_DSK_VERBOSE (1 << UNIT_V_DSK_VERBOSE)
|
||||
#define DSK_SECTSIZE 137 /* size of sector */
|
||||
#define DSK_SECT 32 /* sectors per track */
|
||||
#define TRACKS 254 /* number of tracks,
|
||||
original Altair has 77 tracks only */
|
||||
original Altair has 77 tracks only */
|
||||
#define DSK_TRACSIZE (DSK_SECTSIZE * DSK_SECT)
|
||||
#define DSK_SIZE (DSK_TRACSIZE * TRACKS)
|
||||
#define TRACE_IN_OUT 1
|
||||
#define TRACE_READ_WRITE 2
|
||||
#define TRACE_SECTOR_STUCK 4
|
||||
#define TRACE_TRACK_STUCK 8
|
||||
#define NUM_OF_DSK 8 /* NUM_OF_DSK must be power of two */
|
||||
#define NUM_OF_DSK_MASK (NUM_OF_DSK - 1)
|
||||
|
||||
t_stat dsk_svc (UNIT *uptr);
|
||||
t_stat dsk_reset (DEVICE *dptr);
|
||||
void writebuf();
|
||||
int32 dsk10(int32 port, int32 io, int32 data);
|
||||
int32 dsk11(int32 port, int32 io, int32 data);
|
||||
int32 dsk12(int32 port, int32 io, int32 data);
|
||||
int32 dskseek(UNIT *xptr);
|
||||
t_stat dsk_boot(int32 unitno);
|
||||
t_stat dsk_reset(DEVICE *dptr);
|
||||
t_stat dsk_svc(UNIT *uptr);
|
||||
void writebuf(void);
|
||||
t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
void resetDSKWarningFlags(void);
|
||||
int32 hasVerbose(void);
|
||||
char* selectInOut(int32 io);
|
||||
|
||||
extern int32 PCX;
|
||||
extern int32 saved_PC;
|
||||
extern FILE *sim_log;
|
||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
||||
extern void printMessage(void);
|
||||
extern char messageBuffer[];
|
||||
extern void install_bootrom(void);
|
||||
|
||||
/* Global data on status */
|
||||
|
||||
int32 cur_disk = 8; /* Currently selected drive */
|
||||
int32 cur_track[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0xff};
|
||||
int32 cur_sect[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0xff};
|
||||
int32 cur_byte[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0xff};
|
||||
int32 cur_flags[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 trace_flag = 0;
|
||||
int32 in9_count = 0;
|
||||
int32 in9_message = FALSE;
|
||||
int32 cur_disk = NUM_OF_DSK; /* Currently selected drive (values are 0 .. NUM_OF_DSK)
|
||||
cur_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */
|
||||
int32 cur_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 cur_sect [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 cur_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 cur_flags [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 trace_flag = 0;
|
||||
int32 in9_count = 0;
|
||||
int32 in9_message = FALSE;
|
||||
int32 dirty = 0; /* 1 when buffer has unwritten data in it */
|
||||
int32 warnLevelDSK = 3;
|
||||
int32 warnLock [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 warnAttached[NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 warnDSK10 = 0;
|
||||
int32 warnDSK11 = 0;
|
||||
int32 warnDSK12 = 0;
|
||||
int8 dskbuf[DSK_SECTSIZE]; /* Data Buffer */
|
||||
|
||||
char dskbuf[DSK_SECTSIZE]; /* Data Buffer */
|
||||
int32 dirty = 0; /* 1 when buffer has unwritten data in it */
|
||||
UNIT *dptr; /* fileref to write dirty buffer to */
|
||||
#define LDAInstruction 0x3e /* op-code for LD A,<8-bit value> instruction */
|
||||
#define unitNoOffset1 0x37 /* LD A,<unitno> */
|
||||
#define unitNoOffset2 0xb4 /* LD a,80h | <unitno> */
|
||||
|
||||
/* Altair MITS modified BOOT EPROM, fits in upper 256 byte of memory */
|
||||
int32 bootrom[bootrom_size] = {
|
||||
0xf3, 0x06, 0x80, 0x3e, 0x0e, 0xd3, 0xfe, 0x05, /* fe00-fe07 */
|
||||
0xc2, 0x05, 0xff, 0x3e, 0x16, 0xd3, 0xfe, 0x3e, /* fe08-fe0f */
|
||||
0x12, 0xd3, 0xfe, 0xdb, 0xfe, 0xb7, 0xca, 0x20, /* fe10-fe17 */
|
||||
0xff, 0x3e, 0x0c, 0xd3, 0xfe, 0xaf, 0xd3, 0xfe, /* fe18-fe1f */
|
||||
0x21, 0x00, 0x5c, 0x11, 0x33, 0xff, 0x0e, 0x88, /* fe20-fe27 */
|
||||
0x1a, 0x77, 0x13, 0x23, 0x0d, 0xc2, 0x28, 0xff, /* fe28-fe2f */
|
||||
0xc3, 0x00, 0x5c, 0x31, 0x21, 0x5d, 0x3e, 0x00, /* fe30-fe37 */
|
||||
0xd3, 0x08, 0x3e, 0x04, 0xd3, 0x09, 0xc3, 0x19, /* fe38-fe3f */
|
||||
0x5c, 0xdb, 0x08, 0xe6, 0x02, 0xc2, 0x0e, 0x5c, /* fe40-fe47 */
|
||||
0x3e, 0x02, 0xd3, 0x09, 0xdb, 0x08, 0xe6, 0x40, /* fe48-fe4f */
|
||||
0xc2, 0x0e, 0x5c, 0x11, 0x00, 0x00, 0x06, 0x08, /* fe50-fe57 */
|
||||
0xc5, 0xd5, 0x11, 0x86, 0x80, 0x21, 0x88, 0x5c, /* fe58-fe5f */
|
||||
0xdb, 0x09, 0x1f, 0xda, 0x2d, 0x5c, 0xe6, 0x1f, /* fe60-fe67 */
|
||||
0xb8, 0xc2, 0x2d, 0x5c, 0xdb, 0x08, 0xb7, 0xfa, /* fe68-fe6f */
|
||||
0x39, 0x5c, 0xdb, 0x0a, 0x77, 0x23, 0x1d, 0xc2, /* fe70-fe77 */
|
||||
0x39, 0x5c, 0xd1, 0x21, 0x8b, 0x5c, 0x06, 0x80, /* fe78-fe7f */
|
||||
0x7e, 0x12, 0x23, 0x13, 0x05, 0xc2, 0x4d, 0x5c, /* fe80-fe87 */
|
||||
0xc1, 0x21, 0x00, 0x5c, 0x7a, 0xbc, 0xc2, 0x60, /* fe88-fe8f */
|
||||
0x5c, 0x7b, 0xbd, 0xd2, 0x80, 0x5c, 0x04, 0x04, /* fe90-fe97 */
|
||||
0x78, 0xfe, 0x20, 0xda, 0x25, 0x5c, 0x06, 0x01, /* fe98-fe9f */
|
||||
0xca, 0x25, 0x5c, 0xdb, 0x08, 0xe6, 0x02, 0xc2, /* fea0-fea7 */
|
||||
0x70, 0x5c, 0x3e, 0x01, 0xd3, 0x09, 0x06, 0x00, /* fea8-feaf */
|
||||
0xc3, 0x25, 0x5c, 0x3e, 0x80, 0xd3, 0x08, 0xfb, /* feb0-feb7 */
|
||||
0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* feb8-febf */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fec0-fec7 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fec8-fecf */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fed0-fed7 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fed8-fedf */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fee0-fee7 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fee8-feef */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fef0-fef7 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fef8-feff */
|
||||
};
|
||||
|
||||
/* 88DSK Standard I/O Data Structures */
|
||||
|
||||
UNIT dsk_unit[] = {
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, DSK_SIZE) } };
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, DSK_SIZE) } };
|
||||
|
||||
REG dsk_reg[] = {
|
||||
{ DRDATA (DISK, cur_disk, 4) },
|
||||
{ ORDATA (TRACE, trace_flag, 8) },
|
||||
{ DRDATA (IN9, in9_count, 4), REG_RO },
|
||||
{ DRDATA (DISK, cur_disk, 4) },
|
||||
{ DRDATA (DSKWL, warnLevelDSK, 32) },
|
||||
{ ORDATA (TRACE, trace_flag, 8) },
|
||||
{ DRDATA (IN9, in9_count, 4), REG_RO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB dsk_mod[] = {
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||
/* quiet, no warning messages */
|
||||
{ UNIT_DSK_VERBOSE, 0, "QUIET", "QUIET", NULL },
|
||||
/* verbose, show warning messages */
|
||||
{ UNIT_DSK_VERBOSE, UNIT_DSK_VERBOSE, "VERBOSE", "VERBOSE", &dsk_set_verbose },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE dsk_dev = {
|
||||
"DSK", dsk_unit, dsk_reg, NULL,
|
||||
"DSK", dsk_unit, dsk_reg, dsk_mod,
|
||||
8, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &dsk_reset,
|
||||
NULL, NULL, NULL };
|
||||
&dsk_boot, NULL, NULL };
|
||||
|
||||
void resetDSKWarningFlags(void) {
|
||||
int32 i;
|
||||
for (i = 0; i < NUM_OF_DSK; i++) {
|
||||
warnLock[i] = 0;
|
||||
warnAttached[i] = 0;
|
||||
}
|
||||
warnDSK10 = 0;
|
||||
warnDSK11 = 0;
|
||||
warnDSK12 = 0;
|
||||
}
|
||||
|
||||
t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
resetDSKWarningFlags();
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* returns TRUE iff there exists a disk with VERBOSE */
|
||||
int32 hasVerbose(void) {
|
||||
int32 i;
|
||||
for (i = 0; i < NUM_OF_DSK; i++) {
|
||||
if (((dsk_dev.units + i) -> flags) & UNIT_DSK_VERBOSE) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char* selectInOut(int32 io) {
|
||||
return io == 0 ? "IN" : "OUT";
|
||||
}
|
||||
|
||||
/* Service routines to handle simlulator functions */
|
||||
|
||||
/* service routine - actually gets char & places in buffer */
|
||||
|
||||
t_stat dsk_svc (UNIT *uptr)
|
||||
{
|
||||
t_stat dsk_svc(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat dsk_reset (DEVICE *dptr)
|
||||
{
|
||||
cur_disk = 0;
|
||||
t_stat dsk_reset(DEVICE *dptr) {
|
||||
resetDSKWarningFlags();
|
||||
cur_disk = NUM_OF_DSK;
|
||||
trace_flag = 0;
|
||||
in9_count = 0;
|
||||
in9_message = FALSE;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* The boot routine modifies the boot ROM in such a way that subsequently
|
||||
the specified disk is used for boot purposes. The program counter will reach
|
||||
the boot ROM by executing NOP instructions starting from address 0 until
|
||||
it reaches 0xff00.
|
||||
*/
|
||||
t_stat dsk_boot(int32 unitno) {
|
||||
install_bootrom();
|
||||
/* check whether we are really modifying an LD A,<> instruction */
|
||||
if ((bootrom[unitNoOffset1 - 1] == LDAInstruction) && (bootrom[unitNoOffset2 - 1] == LDAInstruction)) {
|
||||
bootrom[unitNoOffset1] = unitno & 0xff; /* LD A,<unitno> */
|
||||
bootrom[unitNoOffset2] = 0x80 | (unitno & 0xff); /* LD a,80h | <unitno> */
|
||||
return SCPE_OK;
|
||||
}
|
||||
else { /* Attempt to modify non LD A,<> instructions is refused. */
|
||||
printf("Incorrect boot ROM offsets detected.\n");
|
||||
return SCPE_IERR;
|
||||
}
|
||||
}
|
||||
|
||||
/* I/O instruction handlers, called from the CPU module when an
|
||||
IN or OUT instruction is issued.
|
||||
|
||||
@@ -186,166 +308,176 @@ t_stat dsk_reset (DEVICE *dptr)
|
||||
simulation requirement that they are reversed in hardware.
|
||||
*/
|
||||
|
||||
int32 dsk10(int32 io, int32 data)
|
||||
{
|
||||
int32 dsk10(int32 port, int32 io, int32 data) {
|
||||
int32 cur_flag;
|
||||
in9_count = 0;
|
||||
if (io == 0) { /* IN: return flags */
|
||||
return ((~cur_flags[cur_disk]) & 0xFF); /* Return the COMPLEMENT! */
|
||||
if (io == 0) { /* IN: return flags */
|
||||
if (cur_disk >= NUM_OF_DSK) {
|
||||
if (hasVerbose() && (warnDSK10 < warnLevelDSK)) {
|
||||
warnDSK10++;
|
||||
/*01*/ message1("Attempt of IN 0x08 on unattached disk - ignored.\n");
|
||||
}
|
||||
return 0xff; /* no drive selected - can do nothing */
|
||||
}
|
||||
return (~cur_flags[cur_disk]) & 0xff; /* Return the COMPLEMENT! */
|
||||
}
|
||||
|
||||
/* OUT: Controller set/reset/enable/disable */
|
||||
if (dirty == 1)
|
||||
if (dirty == 1) {/* implies that cur_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
printf("\n[%x] OUT 08: %x", PCX, data);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] OUT 08: %x", PCX, data);
|
||||
}
|
||||
}
|
||||
cur_disk = data & 0x0F;
|
||||
if ((((dsk_dev.units + cur_disk) -> flags) & UNIT_ATT) == 0) { /* nothing attached? */
|
||||
cur_disk = 8;
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
message2("OUT 0x08: %x\n", data);
|
||||
}
|
||||
cur_disk = data & NUM_OF_DSK_MASK; /* 0 <= cur_disk < NUM_OF_DSK */
|
||||
cur_flag = (dsk_dev.units + cur_disk) -> flags;
|
||||
if ((cur_flag & UNIT_ATT) == 0) { /* nothing attached? */
|
||||
if ( (cur_flag & UNIT_DSK_VERBOSE) && (warnAttached[cur_disk] < warnLevelDSK) ) {
|
||||
warnAttached[cur_disk]++;
|
||||
/*02*/message2("Attempt to select unattached DSK%d - ignored.\n", cur_disk);
|
||||
}
|
||||
cur_disk = NUM_OF_DSK;
|
||||
}
|
||||
else {
|
||||
cur_sect[cur_disk] = 0xff; /* reset internal counters */
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
cur_flags[cur_disk] = data & 0x80 ? 0 /* Disable drive */ :
|
||||
(cur_track[cur_disk] == 0 ? 0x5A /* Enable: head move true, track 0 if there */ :
|
||||
0x1A); /* Enable: head move true */
|
||||
cur_flags[cur_disk] = data & 0x80 ? 0 /* Disable drive */ :
|
||||
(cur_track[cur_disk] == 0 ? 0x5a /* Enable: head move true, track 0 if there */ :
|
||||
0x1a); /* Enable: head move true */
|
||||
}
|
||||
return (0); /* ignored since OUT */
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
|
||||
/* Disk Drive Status/Functions */
|
||||
|
||||
int32 dsk11(int32 io, int32 data)
|
||||
{
|
||||
if (io == 0) { /* Read sector position */
|
||||
int32 dsk11(int32 port, int32 io, int32 data) {
|
||||
if (cur_disk >= NUM_OF_DSK) {
|
||||
if (hasVerbose() && (warnDSK11 < warnLevelDSK)) {
|
||||
warnDSK11++;
|
||||
/*03*/message2("Attempt of %s 0x09 on unattached disk - ignored.\n", selectInOut(io));
|
||||
}
|
||||
return 0; /* no drive selected - can do nothing */
|
||||
}
|
||||
|
||||
/* now cur_disk < NUM_OF_DSK */
|
||||
if (io == 0) { /* Read sector position */
|
||||
in9_count++;
|
||||
if ((trace_flag & TRACE_SECTOR_STUCK) && (in9_count > 2*DSK_SECT) && (!in9_message)) {
|
||||
if ((trace_flag & TRACE_SECTOR_STUCK) && (in9_count > 2 * DSK_SECT) && (!in9_message)) {
|
||||
in9_message = TRUE;
|
||||
printf("\n[%x] Looping on sector find %d.\n", PCX, cur_disk);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] Looping on sector find %d.\n", PCX, cur_disk);
|
||||
}
|
||||
message2("Looping on sector find %d.\n", cur_disk);
|
||||
}
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
printf("\n[%x] IN 09", PCX);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] IN 09", PCX);
|
||||
}
|
||||
message1("IN 0x09\n");
|
||||
}
|
||||
if (dirty == 1)
|
||||
if (dirty == 1) {/* implies that cur_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
if (cur_flags[cur_disk] & 0x04) { /* head loaded? */
|
||||
cur_sect[cur_disk]++;
|
||||
if (cur_sect[cur_disk] >= DSK_SECT)
|
||||
if (cur_sect[cur_disk] >= DSK_SECT) {
|
||||
cur_sect[cur_disk] = 0;
|
||||
}
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
return (((cur_sect[cur_disk] << 1) & 0x3E) /* return 'sector true' bit = 0 (true) */
|
||||
| 0xC0); /* set on 'unused' bits */
|
||||
return (((cur_sect[cur_disk] << 1) & 0x3e) /* return 'sector true' bit = 0 (true) */
|
||||
| 0xc0); /* set on 'unused' bits */
|
||||
} else {
|
||||
return (0); /* head not loaded - return 0 */
|
||||
return 0; /* head not loaded - return 0 */
|
||||
}
|
||||
}
|
||||
|
||||
in9_count = 0;
|
||||
/* Drive functions */
|
||||
|
||||
if (cur_disk > 7)
|
||||
return (0); /* no drive selected - can do nothing */
|
||||
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
printf("\n[%x] OUT 09: %x", PCX, data);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] OUT 09: %x", PCX, data);
|
||||
}
|
||||
message2("OUT 0x09: %x\n", data);
|
||||
}
|
||||
if (data & 0x01) { /* Step head in */
|
||||
if (data & 0x01) { /* Step head in */
|
||||
if (trace_flag & TRACE_TRACK_STUCK) {
|
||||
if (cur_track[cur_disk] == (TRACKS-1)) {
|
||||
printf("\n[%x] Unnecessary step in for disk %d", PCX, cur_disk);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] Unnecessary step in for disk %d", PCX, cur_disk);
|
||||
}
|
||||
if (cur_track[cur_disk] == (TRACKS - 1)) {
|
||||
message2("Unnecessary step in for disk %d\n", cur_disk);
|
||||
}
|
||||
}
|
||||
cur_track[cur_disk]++;
|
||||
if (cur_track[cur_disk] > (TRACKS-1) )
|
||||
cur_track[cur_disk] = (TRACKS-1);
|
||||
if (dirty == 1)
|
||||
if (cur_track[cur_disk] > (TRACKS - 1)) {
|
||||
cur_track[cur_disk] = (TRACKS - 1);
|
||||
}
|
||||
if (dirty == 1) { /* implies that cur_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
cur_sect[cur_disk] = 0xff;
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
}
|
||||
|
||||
if (data & 0x02) { /* Step head out */
|
||||
if (data & 0x02) { /* Step head out */
|
||||
if (trace_flag & TRACE_TRACK_STUCK) {
|
||||
if (cur_track[cur_disk] == 0) {
|
||||
printf("\n[%x] Unnecessary step out for disk %d", PCX, cur_disk);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] Unnecessary step out for disk %d", PCX, cur_disk);
|
||||
}
|
||||
message2("Unnecessary step out for disk %d\n", cur_disk);
|
||||
}
|
||||
}
|
||||
cur_track[cur_disk]--;
|
||||
if (cur_track[cur_disk] < 0) {
|
||||
cur_track[cur_disk] = 0;
|
||||
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
|
||||
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
|
||||
}
|
||||
if (dirty == 1)
|
||||
if (dirty == 1) { /* implies that cur_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
cur_sect[cur_disk] = 0xff;
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
}
|
||||
|
||||
if (dirty == 1)
|
||||
if (dirty == 1) { /* implies that cur_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
|
||||
if (data & 0x04) { /* Head load */
|
||||
cur_flags[cur_disk] |= 0x04; /* turn on head loaded bit */
|
||||
cur_flags[cur_disk] |= 0x80; /* turn on 'read data available */
|
||||
}
|
||||
|
||||
if (data & 0x08) { /* Head Unload */
|
||||
cur_flags[cur_disk] &= 0xFB; /* off on 'head loaded' */
|
||||
cur_flags[cur_disk] &= 0x7F; /* off on 'read data avail */
|
||||
if (data & 0x04) { /* Head load */
|
||||
cur_flags[cur_disk] |= 0x04; /* turn on head loaded bit */
|
||||
cur_flags[cur_disk] |= 0x80; /* turn on 'read data available' */
|
||||
}
|
||||
|
||||
if (data & 0x08) { /* Head Unload */
|
||||
cur_flags[cur_disk] &= 0xfb; /* turn off 'head loaded' bit */
|
||||
cur_flags[cur_disk] &= 0x7f; /* turn off 'read data available' */
|
||||
cur_sect[cur_disk] = 0xff;
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
}
|
||||
|
||||
/* Interrupts & head current are ignored */
|
||||
/* Interrupts & head current are ignored */
|
||||
|
||||
if (data & 0x80) { /* write sequence start */
|
||||
if (data & 0x80) { /* write sequence start */
|
||||
cur_byte[cur_disk] = 0;
|
||||
cur_flags[cur_disk] |= 0x01; /* enter new write data on */
|
||||
cur_flags[cur_disk] |= 0x01; /* enter new write data on */
|
||||
}
|
||||
return (0); /* ignored since OUT */
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
|
||||
/* Disk Data In/Out*/
|
||||
/* Disk Data In/Out */
|
||||
|
||||
inline int32 dskseek(UNIT *xptr) {
|
||||
INLINE int32 dskseek(UNIT *xptr) {
|
||||
return fseek(xptr -> fileref, DSK_TRACSIZE * cur_track[cur_disk] +
|
||||
DSK_SECTSIZE * cur_sect[cur_disk], SEEK_SET);
|
||||
}
|
||||
|
||||
int32 dsk12(int32 io, int32 data)
|
||||
{
|
||||
int32 dsk12(int32 port, int32 io, int32 data) {
|
||||
static int32 i;
|
||||
UNIT *uptr;
|
||||
|
||||
if (cur_disk >= NUM_OF_DSK) {
|
||||
if (hasVerbose() && (warnDSK12 < warnLevelDSK)) {
|
||||
warnDSK12++;
|
||||
/*04*/message2("Attempt of %s 0x0a on unattached disk - ignored.\n", selectInOut(io));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now cur_disk < NUM_OF_DSK */
|
||||
in9_count = 0;
|
||||
uptr = dsk_dev.units + cur_disk;
|
||||
if (io == 0) {
|
||||
if (cur_byte[cur_disk] >= DSK_SECTSIZE) {
|
||||
/* physically read the sector */
|
||||
if (trace_flag & TRACE_READ_WRITE) {
|
||||
printf("\n[%x] IN 0A (READ) D%d T%d S%d", PCX, cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] IN 0A (READ) D%d T%d S%d", PCX, cur_disk, cur_track[cur_disk],
|
||||
cur_sect[cur_disk]);
|
||||
}
|
||||
message4("IN 0x0a (READ) D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
}
|
||||
for (i = 0; i < DSK_SECTSIZE; i++) {
|
||||
dskbuf[i] = 0;
|
||||
@@ -354,55 +486,48 @@ int32 dsk12(int32 io, int32 data)
|
||||
fread(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
||||
cur_byte[cur_disk] = 0;
|
||||
}
|
||||
return (dskbuf[cur_byte[cur_disk]++] & 0xFF);
|
||||
return dskbuf[cur_byte[cur_disk]++] & 0xff;
|
||||
}
|
||||
else {
|
||||
if (cur_byte[cur_disk] >= DSK_SECTSIZE) {
|
||||
writebuf();
|
||||
writebuf(); /* from above we have that cur_disk < NUM_OF_DSK */
|
||||
}
|
||||
else {
|
||||
dirty = 1;
|
||||
dptr = uptr;
|
||||
dskbuf[cur_byte[cur_disk]++] = data & 0xFF;
|
||||
dirty = 1; /* this guarantees for the next call to writebuf that cur_disk < NUM_OF_DSK */
|
||||
dskbuf[cur_byte[cur_disk]++] = data & 0xff;
|
||||
}
|
||||
return (0); /* ignored since OUT */
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
}
|
||||
|
||||
void writebuf()
|
||||
{
|
||||
/* Precondition: cur_disk < NUM_OF_DSK */
|
||||
void writebuf(void) {
|
||||
int32 i, rtn;
|
||||
|
||||
UNIT *uptr;
|
||||
i = cur_byte[cur_disk]; /* null-fill rest of sector if any */
|
||||
while (i < DSK_SECTSIZE) {
|
||||
dskbuf[i++] = 0;
|
||||
}
|
||||
if (trace_flag & TRACE_READ_WRITE) {
|
||||
printf("\n[%x] OUT 0A (WRITE) D%d T%d S%d", PCX, cur_disk,
|
||||
cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
if (sim_log) {
|
||||
fprintf (sim_log, "\n[%x] OUT 0A (WRITE) D%d T%d S%d", PCX, cur_disk,
|
||||
cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
uptr = dsk_dev.units + cur_disk;
|
||||
if (((uptr -> flags) & UNIT_WLK) == 0) { /* write enabled */
|
||||
if (trace_flag & TRACE_READ_WRITE) {
|
||||
message4("OUT 0x0a (WRITE) D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
}
|
||||
if (dskseek(uptr)) {
|
||||
message4("fseek failed D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
}
|
||||
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
||||
if (rtn != 1) {
|
||||
message4("fwrite failed T%d S%d Return=%d\n", cur_track[cur_disk], cur_sect[cur_disk], rtn);
|
||||
}
|
||||
}
|
||||
if (dskseek(dptr)) {
|
||||
printf("\n[%x] fseek failed D%d T%d S%d", PCX, cur_disk,
|
||||
cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] fseek failed D%d T%d S%d", PCX, cur_disk,
|
||||
cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
}
|
||||
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[cur_disk] < warnLevelDSK) ) {
|
||||
/* write locked - print warning message if required */
|
||||
warnLock[cur_disk]++;
|
||||
/*05*/
|
||||
message2("Attempt to write to locked DSK%d - ignored.\n", cur_disk);
|
||||
}
|
||||
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, dptr -> fileref);
|
||||
if (rtn != 1) {
|
||||
printf("\n[%x] fwrite failed T%d S%d Return=%d", PCX, cur_track[cur_disk],
|
||||
cur_sect[cur_disk], rtn);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, "\n[%x] fwrite failed T%d S%d Return=%d", PCX, cur_track[cur_disk],
|
||||
cur_sect[cur_disk], rtn);
|
||||
}
|
||||
}
|
||||
cur_flags[cur_disk] &= 0xFE; /* ENWD off */
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
dirty = 0;
|
||||
cur_flags[cur_disk] &= 0xfe; /* ENWD off */
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
dirty = 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/* altairz80_sys.c: MITS Altair system interface
|
||||
Written by Peter Schorn, 2001
|
||||
Written by Peter Schorn, 2001-2002
|
||||
Based on work by Charles E Owen ((c) 1997 - Commercial use prohibited)
|
||||
Disassembler from Marat Fayzullin ((c) 1995, 1996, 1997 - Commercial use prohibited)
|
||||
*/
|
||||
@@ -12,19 +12,26 @@ extern DEVICE dsk_dev;
|
||||
extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern DEVICE sio_dev;
|
||||
extern DEVICE simh_device;
|
||||
extern DEVICE ptr_dev;
|
||||
extern DEVICE ptp_dev;
|
||||
extern uint8 M[];
|
||||
extern int32 saved_PC;
|
||||
extern char *get_range(char *cptr, t_addr *lo, t_addr *hi, int rdx,
|
||||
t_addr max, char term);
|
||||
extern t_value get_uint(char *cptr, int radix, t_value max, t_stat *status);
|
||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||
|
||||
int32 sim_load (FILE *fileref, char *cptr, char *fnam, int32 flag);
|
||||
int32 fprint_sym (FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
|
||||
int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag);
|
||||
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
|
||||
int32 checkbase(char ch, char *numString);
|
||||
int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 requireSign, int32 *result);
|
||||
int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, int32 *at, int32 *hat);
|
||||
int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, int32 *at,
|
||||
int32 *hat, int32 *dollar);
|
||||
int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]);
|
||||
int32 parse_sym (char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw);
|
||||
int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics);
|
||||
int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw);
|
||||
int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr);
|
||||
int32 checkXY(char xy);
|
||||
|
||||
/* SCP data structures
|
||||
sim_name simulator name string
|
||||
@@ -38,229 +45,231 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics);
|
||||
char sim_name[] = "Altair 8800 (Z80)";
|
||||
REG *sim_PC = &cpu_reg[0];
|
||||
int32 sim_emax = 4;
|
||||
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev, &ptp_dev, &dsk_dev, NULL };
|
||||
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &simh_device, &ptr_dev, &ptp_dev, &dsk_dev, NULL };
|
||||
|
||||
char memoryAccessMessage[80];
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unknown I/O Instruction",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
memoryAccessMessage,
|
||||
"Invalid Opcode" };
|
||||
|
||||
static char *Mnemonics8080[] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */
|
||||
"DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */
|
||||
"DB 10h", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */
|
||||
"DB 18h", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */
|
||||
"DB 20h", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */
|
||||
"DB 28h", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */
|
||||
"DB 30h", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */
|
||||
"DB 38h", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */
|
||||
"MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", "MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 40-47 */
|
||||
"MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", "MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 48-4f */
|
||||
"MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", "MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 50-57 */
|
||||
"MOV E,B", "MOV E,C", "MOV E,D", "MOV E,E", "MOV E,H", "MOV E,L", "MOV E,M", "MOV E,A", /* 58-5f */
|
||||
"MOV H,B", "MOV H,C", "MOV H,D", "MOV H,E", "MOV H,H", "MOV H,L", "MOV H,M", "MOV H,A", /* 60-67 */
|
||||
"MOV L,B", "MOV L,C", "MOV L,D", "MOV L,E", "MOV L,H", "MOV L,L", "MOV L,M", "MOV L,A", /* 68-6f */
|
||||
"MOV M,B", "MOV M,C", "MOV M,D", "MOV M,E", "MOV M,H", "MOV M,L", "HLT", "MOV M,A", /* 70-77 */
|
||||
"MOV A,B", "MOV A,C", "MOV A,D", "MOV A,E", "MOV A,H", "MOV A,L", "MOV A,M", "MOV A,A", /* 78-7f */
|
||||
"ADD B", "ADD C", "ADD D", "ADD E", "ADD H", "ADD L", "ADD M", "ADD A", /* 80-87 */
|
||||
"ADC B", "ADC C", "ADC D", "ADC E", "ADC H", "ADC L", "ADC M", "ADC A", /* 88-8f */
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB M", "SUB A", /* 90-97 */
|
||||
"SBB B", "SBB C", "SBB D", "SBB E", "SBB H", "SBB L", "SBB M", "SBB A", /* 98-9f */
|
||||
"ANA B", "ANA C", "ANA D", "ANA E", "ANA H", "ANA L", "ANA M", "ANA A", /* a0-a7 */
|
||||
"XRA B", "XRA C", "XRA D", "XRA E", "XRA H", "XRA L", "XRA M", "XRA A", /* a8-af */
|
||||
"ORA B", "ORA C", "ORA D", "ORA E", "ORA H", "ORA L", "ORA M", "ORA A", /* b0-b7 */
|
||||
"CMP B", "CMP C", "CMP D", "CMP E", "CMP H", "CMP L", "CMP M", "CMP A", /* b8-bf */
|
||||
"RNZ", "POP B", "JNZ #h", "JMP #h", "CNZ #h", "PUSH B", "ADI *h", "RST 0", /* c0-c7 */
|
||||
"RZ", "RET", "JZ #h", "DB CBh", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */
|
||||
"RNC", "POP D", "JNC #h", "OUT *h", "CNC #h", "PUSH D", "SUI *h", "RST 2", /* d0-d7 */
|
||||
"RC", "DB D9h", "JC #h", "IN *h", "CC #h", "DB DDh", "SBI *h", "RST 3", /* d8-df */
|
||||
"RPO", "POP H", "JPO #h", "XTHL", "CPO #h", "PUSH H", "ANI *h", "RST 4", /* e0-e7 */
|
||||
"RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "DB EDh", "XRI *h", "RST 5", /* e8-ef */
|
||||
"RP", "POP PSW", "JP #h", "DI", "CP #h", "PUSH PSW", "ORI *h", "RST 6", /* f0-f7 */
|
||||
"RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */
|
||||
"DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */
|
||||
"DB 10h", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */
|
||||
"DB 18h", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */
|
||||
"DB 20h", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */
|
||||
"DB 28h", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */
|
||||
"DB 30h", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */
|
||||
"DB 38h", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */
|
||||
"MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", "MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 40-47 */
|
||||
"MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", "MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 48-4f */
|
||||
"MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", "MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 50-57 */
|
||||
"MOV E,B", "MOV E,C", "MOV E,D", "MOV E,E", "MOV E,H", "MOV E,L", "MOV E,M", "MOV E,A", /* 58-5f */
|
||||
"MOV H,B", "MOV H,C", "MOV H,D", "MOV H,E", "MOV H,H", "MOV H,L", "MOV H,M", "MOV H,A", /* 60-67 */
|
||||
"MOV L,B", "MOV L,C", "MOV L,D", "MOV L,E", "MOV L,H", "MOV L,L", "MOV L,M", "MOV L,A", /* 68-6f */
|
||||
"MOV M,B", "MOV M,C", "MOV M,D", "MOV M,E", "MOV M,H", "MOV M,L", "HLT", "MOV M,A", /* 70-77 */
|
||||
"MOV A,B", "MOV A,C", "MOV A,D", "MOV A,E", "MOV A,H", "MOV A,L", "MOV A,M", "MOV A,A", /* 78-7f */
|
||||
"ADD B", "ADD C", "ADD D", "ADD E", "ADD H", "ADD L", "ADD M", "ADD A", /* 80-87 */
|
||||
"ADC B", "ADC C", "ADC D", "ADC E", "ADC H", "ADC L", "ADC M", "ADC A", /* 88-8f */
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB M", "SUB A", /* 90-97 */
|
||||
"SBB B", "SBB C", "SBB D", "SBB E", "SBB H", "SBB L", "SBB M", "SBB A", /* 98-9f */
|
||||
"ANA B", "ANA C", "ANA D", "ANA E", "ANA H", "ANA L", "ANA M", "ANA A", /* a0-a7 */
|
||||
"XRA B", "XRA C", "XRA D", "XRA E", "XRA H", "XRA L", "XRA M", "XRA A", /* a8-af */
|
||||
"ORA B", "ORA C", "ORA D", "ORA E", "ORA H", "ORA L", "ORA M", "ORA A", /* b0-b7 */
|
||||
"CMP B", "CMP C", "CMP D", "CMP E", "CMP H", "CMP L", "CMP M", "CMP A", /* b8-bf */
|
||||
"RNZ", "POP B", "JNZ #h", "JMP #h", "CNZ #h", "PUSH B", "ADI *h", "RST 0", /* c0-c7 */
|
||||
"RZ", "RET", "JZ #h", "DB CBh", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */
|
||||
"RNC", "POP D", "JNC #h", "OUT *h", "CNC #h", "PUSH D", "SUI *h", "RST 2", /* d0-d7 */
|
||||
"RC", "DB D9h", "JC #h", "IN *h", "CC #h", "DB DDh", "SBI *h", "RST 3", /* d8-df */
|
||||
"RPO", "POP H", "JPO #h", "XTHL", "CPO #h", "PUSH H", "ANI *h", "RST 4", /* e0-e7 */
|
||||
"RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "DB EDh", "XRI *h", "RST 5", /* e8-ef */
|
||||
"RP", "POP PSW", "JP #h", "DI", "CP #h", "PUSH PSW", "ORI *h", "RST 6", /* f0-f7 */
|
||||
"RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsZ80[256] =
|
||||
{
|
||||
"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA",
|
||||
"EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA",
|
||||
"DJNZ @h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA",
|
||||
"JR @h", "ADD HL,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA",
|
||||
"JR NZ,@h", "LD HL,#h", "LD (#h),HL", "INC HL", "INC H", "DEC H", "LD H,*h", "DAA",
|
||||
"JR Z,@h", "ADD HL,HL", "LD HL,(#h)", "DEC HL", "INC L", "DEC L", "LD L,*h", "CPL",
|
||||
"JR NC,@h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (HL)", "DEC (HL)", "LD (HL),*h", "SCF",
|
||||
"JR C,@h", "ADD HL,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF",
|
||||
"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,H", "LD B,L", "LD B,(HL)", "LD B,A",
|
||||
"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,H", "LD C,L", "LD C,(HL)", "LD C,A",
|
||||
"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,H", "LD D,L", "LD D,(HL)", "LD D,A",
|
||||
"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,H", "LD E,L", "LD E,(HL)", "LD E,A",
|
||||
"LD H,B", "LD H,C", "LD H,D", "LD H,E", "LD H,H", "LD H,L", "LD H,(HL)", "LD H,A",
|
||||
"LD L,B", "LD L,C", "LD L,D", "LD L,E", "LD L,H", "LD L,L", "LD L,(HL)", "LD L,A",
|
||||
"LD (HL),B", "LD (HL),C", "LD (HL),D", "LD (HL),E", "LD (HL),H", "LD (HL),L", "HALT", "LD (HL),A",
|
||||
"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,H", "LD A,L", "LD A,(HL)", "LD A,A",
|
||||
"ADD B", "ADD C", "ADD D", "ADD E", "ADD H", "ADD L", "ADD (HL)", "ADD A",
|
||||
"ADC B", "ADC C", "ADC D", "ADC E", "ADC H", "ADC L", "ADC (HL)", "ADC A",
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB (HL)", "SUB A",
|
||||
"SBC B", "SBC C", "SBC D", "SBC E", "SBC H", "SBC L", "SBC (HL)", "SBC A",
|
||||
"AND B", "AND C", "AND D", "AND E", "AND H", "AND L", "AND (HL)", "AND A",
|
||||
"XOR B", "XOR C", "XOR D", "XOR E", "XOR H", "XOR L", "XOR (HL)", "XOR A",
|
||||
"OR B", "OR C", "OR D", "OR E", "OR H", "OR L", "OR (HL)", "OR A",
|
||||
"CP B", "CP C", "CP D", "CP E", "CP H", "CP L", "CP (HL)", "CP A",
|
||||
"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD *h", "RST 00h",
|
||||
"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC *h", "RST 08h",
|
||||
"RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h",
|
||||
"RET C", "EXX", "JP C,#h", "IN A,(*h)", "CALL C,#h", "PFX_DD", "SBC *h", "RST 18h",
|
||||
"RET PO", "POP HL", "JP PO,#h", "EX HL,(SP)", "CALL PO,#h", "PUSH HL", "AND *h", "RST 20h",
|
||||
"RET PE", "LD PC,HL", "JP PE,#h", "EX DE,HL", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h",
|
||||
"RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h",
|
||||
"RET M", "LD SP,HL", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h"
|
||||
static char *MnemonicsZ80[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */
|
||||
"EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */
|
||||
"DJNZ $h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA", /* 10-17 */
|
||||
"JR $h", "ADD HL,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA", /* 18-1f */
|
||||
"JR NZ,$h", "LD HL,#h", "LD (#h),HL", "INC HL", "INC H", "DEC H", "LD H,*h", "DAA", /* 20-27 */
|
||||
"JR Z,$h", "ADD HL,HL", "LD HL,(#h)", "DEC HL", "INC L", "DEC L", "LD L,*h", "CPL", /* 28-2f */
|
||||
"JR NC,$h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (HL)", "DEC (HL)", "LD (HL),*h", "SCF", /* 30-37 */
|
||||
"JR C,$h", "ADD HL,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF", /* 38-3f */
|
||||
"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,H", "LD B,L", "LD B,(HL)", "LD B,A", /* 40-47 */
|
||||
"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,H", "LD C,L", "LD C,(HL)", "LD C,A", /* 48-4f */
|
||||
"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,H", "LD D,L", "LD D,(HL)", "LD D,A", /* 50-57 */
|
||||
"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,H", "LD E,L", "LD E,(HL)", "LD E,A", /* 58-5f */
|
||||
"LD H,B", "LD H,C", "LD H,D", "LD H,E", "LD H,H", "LD H,L", "LD H,(HL)", "LD H,A", /* 60-67 */
|
||||
"LD L,B", "LD L,C", "LD L,D", "LD L,E", "LD L,H", "LD L,L", "LD L,(HL)", "LD L,A", /* 68-6f */
|
||||
"LD (HL),B", "LD (HL),C", "LD (HL),D", "LD (HL),E", "LD (HL),H", "LD (HL),L", "HALT", "LD (HL),A", /* 70-77 */
|
||||
"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,H", "LD A,L", "LD A,(HL)", "LD A,A", /* 78-7f */
|
||||
"ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,H", "ADD A,L", "ADD A,(HL)", "ADD A,A", /* 80-87 */
|
||||
"ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,H", "ADC A,L", "ADC A,(HL)", "ADC A,A", /* 88-8f */
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB (HL)", "SUB A", /* 90-97 */
|
||||
"SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,H", "SBC A,L", "SBC A,(HL)", "SBC A,A", /* 98-9f */
|
||||
"AND B", "AND C", "AND D", "AND E", "AND H", "AND L", "AND (HL)", "AND A", /* a0-a7 */
|
||||
"XOR B", "XOR C", "XOR D", "XOR E", "XOR H", "XOR L", "XOR (HL)", "XOR A", /* a8-af */
|
||||
"OR B", "OR C", "OR D", "OR E", "OR H", "OR L", "OR (HL)", "OR A", /* b0-b7 */
|
||||
"CP B", "CP C", "CP D", "CP E", "CP H", "CP L", "CP (HL)", "CP A", /* b8-bf */
|
||||
"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD A,*h", "RST 00h", /* c0-c7 */
|
||||
"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC A,*h", "RST 08h", /* c8-cf */
|
||||
"RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h", /* d0-d7 */
|
||||
"RET C", "EXX", "JP C,#h", "IN A,(*h)", "CALL C,#h", "PFX_DD", "SBC A,*h", "RST 18h", /* d8-df */
|
||||
"RET PO", "POP HL", "JP PO,#h", "EX (SP),HL", "CALL PO,#h", "PUSH HL", "AND *h", "RST 20h", /* e0-e7 */
|
||||
"RET PE", "LD PC,HL", "JP PE,#h", "EX DE,HL", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h", /* e8-ef */
|
||||
"RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h", /* f0-f7 */
|
||||
"RET M", "LD SP,HL", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsCB[256] =
|
||||
{
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A",
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A",
|
||||
"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (HL)", "RL A",
|
||||
"RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (HL)", "RR A",
|
||||
"SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (HL)", "SLA A",
|
||||
"SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (HL)", "SRA A",
|
||||
"SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (HL)", "SLL A",
|
||||
"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (HL)", "SRL A",
|
||||
"BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(HL)", "BIT 0,A",
|
||||
"BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(HL)", "BIT 1,A",
|
||||
"BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(HL)", "BIT 2,A",
|
||||
"BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(HL)", "BIT 3,A",
|
||||
"BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(HL)", "BIT 4,A",
|
||||
"BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(HL)", "BIT 5,A",
|
||||
"BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(HL)", "BIT 6,A",
|
||||
"BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(HL)", "BIT 7,A",
|
||||
"RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(HL)", "RES 0,A",
|
||||
"RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(HL)", "RES 1,A",
|
||||
"RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(HL)", "RES 2,A",
|
||||
"RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(HL)", "RES 3,A",
|
||||
"RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(HL)", "RES 4,A",
|
||||
"RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(HL)", "RES 5,A",
|
||||
"RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(HL)", "RES 6,A",
|
||||
"RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(HL)", "RES 7,A",
|
||||
"SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(HL)", "SET 0,A",
|
||||
"SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(HL)", "SET 1,A",
|
||||
"SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(HL)", "SET 2,A",
|
||||
"SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(HL)", "SET 3,A",
|
||||
"SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(HL)", "SET 4,A",
|
||||
"SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(HL)", "SET 5,A",
|
||||
"SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(HL)", "SET 6,A",
|
||||
"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(HL)", "SET 7,A"
|
||||
static char *MnemonicsCB[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A", /* 00-07 */
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A", /* 08-0f */
|
||||
"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (HL)", "RL A", /* 10-17 */
|
||||
"RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (HL)", "RR A", /* 18-1f */
|
||||
"SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (HL)", "SLA A", /* 20-27 */
|
||||
"SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (HL)", "SRA A", /* 28-2f */
|
||||
"SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (HL)", "SLL A", /* 30-37 */
|
||||
"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (HL)", "SRL A", /* 38-3f */
|
||||
"BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(HL)", "BIT 0,A", /* 40-47 */
|
||||
"BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(HL)", "BIT 1,A", /* 48-4f */
|
||||
"BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(HL)", "BIT 2,A", /* 50-57 */
|
||||
"BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(HL)", "BIT 3,A", /* 58-5f */
|
||||
"BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(HL)", "BIT 4,A", /* 60-67 */
|
||||
"BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(HL)", "BIT 5,A", /* 68-6f */
|
||||
"BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(HL)", "BIT 6,A", /* 70-77 */
|
||||
"BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(HL)", "BIT 7,A", /* 78-7f */
|
||||
"RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(HL)", "RES 0,A", /* 80-87 */
|
||||
"RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(HL)", "RES 1,A", /* 88-8f */
|
||||
"RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(HL)", "RES 2,A", /* 90-97 */
|
||||
"RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(HL)", "RES 3,A", /* 98-9f */
|
||||
"RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(HL)", "RES 4,A", /* a0-a7 */
|
||||
"RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(HL)", "RES 5,A", /* a8-af */
|
||||
"RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(HL)", "RES 6,A", /* b0-b7 */
|
||||
"RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(HL)", "RES 7,A", /* b8-bf */
|
||||
"SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(HL)", "SET 0,A", /* c0-c7 */
|
||||
"SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(HL)", "SET 1,A", /* c8-cf */
|
||||
"SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(HL)", "SET 2,A", /* d0-d7 */
|
||||
"SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(HL)", "SET 3,A", /* d8-df */
|
||||
"SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(HL)", "SET 4,A", /* e0-e7 */
|
||||
"SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(HL)", "SET 5,A", /* e8-ef */
|
||||
"SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(HL)", "SET 6,A", /* f0-f7 */
|
||||
"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(HL)", "SET 7,A" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsED[256] =
|
||||
{
|
||||
"DB EDh,00h", "DB EDh,01h", "DB EDh,02h", "DB EDh,03h", "DB EDh,04h", "DB EDh,05h", "DB EDh,06h", "DB EDh,07h",
|
||||
"DB EDh,08h", "DB EDh,09h", "DB EDh,0Ah", "DB EDh,0Bh", "DB EDh,0Ch", "DB EDh,0Dh", "DB EDh,0Eh", "DB EDh,0Fh",
|
||||
"DB EDh,10h", "DB EDh,11h", "DB EDh,12h", "DB EDh,13h", "DB EDh,14h", "DB EDh,15h", "DB EDh,16h", "DB EDh,17h",
|
||||
"DB EDh,18h", "DB EDh,19h", "DB EDh,1Ah", "DB EDh,1Bh", "DB EDh,1Ch", "DB EDh,1Dh", "DB EDh,1Eh", "DB EDh,1Fh",
|
||||
"DB EDh,20h", "DB EDh,21h", "DB EDh,22h", "DB EDh,23h", "DB EDh,24h", "DB EDh,25h", "DB EDh,26h", "DB EDh,27h",
|
||||
"DB EDh,28h", "DB EDh,29h", "DB EDh,2Ah", "DB EDh,2Bh", "DB EDh,2Ch", "DB EDh,2Dh", "DB EDh,2Eh", "DB EDh,2Fh",
|
||||
"DB EDh,30h", "DB EDh,31h", "DB EDh,32h", "DB EDh,33h", "DB EDh,34h", "DB EDh,35h", "DB EDh,36h", "DB EDh,37h",
|
||||
"DB EDh,38h", "DB EDh,39h", "DB EDh,3Ah", "DB EDh,3Bh", "DB EDh,3Ch", "DB EDh,3Dh", "DB EDh,3Eh", "DB EDh,3Fh",
|
||||
"IN B,(C)", "OUT (C),B", "SBC HL,BC", "LD (#h),BC", "NEG", "RETN", "IM 0", "LD I,A",
|
||||
"IN C,(C)", "OUT (C),C", "ADC HL,BC", "LD BC,(#h)", "DB EDh,4Ch", "RETI", "DB EDh,4Eh", "LD R,A",
|
||||
"IN D,(C)", "OUT (C),D", "SBC HL,DE", "LD (#h),DE", "DB EDh,54h", "DB EDh,55h", "IM 1", "LD A,I",
|
||||
"IN E,(C)", "OUT (C),E", "ADC HL,DE", "LD DE,(#h)", "DB EDh,5Ch", "DB EDh,5Dh", "IM 2", "LD A,R",
|
||||
"IN H,(C)", "OUT (C),H", "SBC HL,HL", "LD (#h),HL", "DB EDh,64h", "DB EDh,65h", "DB EDh,66h", "RRD",
|
||||
"IN L,(C)", "OUT (C),L", "ADC HL,HL", "LD HL,(#h)", "DB EDh,6Ch", "DB EDh,6Dh", "DB EDh,6Eh", "RLD",
|
||||
"IN F,(C)", "DB EDh,71h", "SBC HL,SP", "LD (#h),SP", "DB EDh,74h", "DB EDh,75h", "DB EDh,76h", "DB EDh,77h",
|
||||
"IN A,(C)", "OUT (C),A", "ADC HL,SP", "LD SP,(#h)", "DB EDh,7Ch", "DB EDh,7Dh", "DB EDh,7Eh", "DB EDh,7Fh",
|
||||
"DB EDh,80h", "DB EDh,81h", "DB EDh,82h", "DB EDh,83h", "DB EDh,84h", "DB EDh,85h", "DB EDh,86h", "DB EDh,87h",
|
||||
"DB EDh,88h", "DB EDh,89h", "DB EDh,8Ah", "DB EDh,8Bh", "DB EDh,8Ch", "DB EDh,8Dh", "DB EDh,8Eh", "DB EDh,8Fh",
|
||||
"DB EDh,90h", "DB EDh,91h", "DB EDh,92h", "DB EDh,93h", "DB EDh,94h", "DB EDh,95h", "DB EDh,96h", "DB EDh,97h",
|
||||
"DB EDh,98h", "DB EDh,99h", "DB EDh,9Ah", "DB EDh,9Bh", "DB EDh,9Ch", "DB EDh,9Dh", "DB EDh,9Eh", "DB EDh,9Fh",
|
||||
"LDI", "CPI", "INI", "OUTI", "DB EDh,A4h", "DB EDh,A5h", "DB EDh,A6h", "DB EDh,A7h",
|
||||
"LDD", "CPD", "IND", "OUTD", "DB EDh,ACh", "DB EDh,ADh", "DB EDh,AEh", "DB EDh,AFh",
|
||||
"LDIR", "CPIR", "INIR", "OTIR", "DB EDh,B4h", "DB EDh,B5h", "DB EDh,B6h", "DB EDh,B7h",
|
||||
"LDDR", "CPDR", "INDR", "OTDR", "DB EDh,BCh", "DB EDh,BDh", "DB EDh,BEh", "DB EDh,BFh",
|
||||
"DB EDh,C0h", "DB EDh,C1h", "DB EDh,C2h", "DB EDh,C3h", "DB EDh,C4h", "DB EDh,C5h", "DB EDh,C6h", "DB EDh,C7h",
|
||||
"DB EDh,C8h", "DB EDh,C9h", "DB EDh,CAh", "DB EDh,CBh", "DB EDh,CCh", "DB EDh,CDh", "DB EDh,CEh", "DB EDh,CFh",
|
||||
"DB EDh,D0h", "DB EDh,D1h", "DB EDh,D2h", "DB EDh,D3h", "DB EDh,D4h", "DB EDh,D5h", "DB EDh,D6h", "DB EDh,D7h",
|
||||
"DB EDh,D8h", "DB EDh,D9h", "DB EDh,DAh", "DB EDh,DBh", "DB EDh,DCh", "DB EDh,DDh", "DB EDh,DEh", "DB EDh,DFh",
|
||||
"DB EDh,E0h", "DB EDh,E1h", "DB EDh,E2h", "DB EDh,E3h", "DB EDh,E4h", "DB EDh,E5h", "DB EDh,E6h", "DB EDh,E7h",
|
||||
"DB EDh,E8h", "DB EDh,E9h", "DB EDh,EAh", "DB EDh,EBh", "DB EDh,ECh", "DB EDh,EDh", "DB EDh,EEh", "DB EDh,EFh",
|
||||
"DB EDh,F0h", "DB EDh,F1h", "DB EDh,F2h", "DB EDh,F3h", "DB EDh,F4h", "DB EDh,F5h", "DB EDh,F6h", "DB EDh,F7h",
|
||||
"DB EDh,F8h", "DB EDh,F9h", "DB EDh,FAh", "DB EDh,FBh", "DB EDh,FCh", "DB EDh,FDh", "DB EDh,FEh", "DB EDh,FFh"
|
||||
static char *MnemonicsED[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"DB EDh,00h", "DB EDh,01h", "DB EDh,02h", "DB EDh,03h", "DB EDh,04h", "DB EDh,05h", "DB EDh,06h", "DB EDh,07h", /* 00-07 */
|
||||
"DB EDh,08h", "DB EDh,09h", "DB EDh,0Ah", "DB EDh,0Bh", "DB EDh,0Ch", "DB EDh,0Dh", "DB EDh,0Eh", "DB EDh,0Fh", /* 08-0f */
|
||||
"DB EDh,10h", "DB EDh,11h", "DB EDh,12h", "DB EDh,13h", "DB EDh,14h", "DB EDh,15h", "DB EDh,16h", "DB EDh,17h", /* 10-17 */
|
||||
"DB EDh,18h", "DB EDh,19h", "DB EDh,1Ah", "DB EDh,1Bh", "DB EDh,1Ch", "DB EDh,1Dh", "DB EDh,1Eh", "DB EDh,1Fh", /* 18-1f */
|
||||
"DB EDh,20h", "DB EDh,21h", "DB EDh,22h", "DB EDh,23h", "DB EDh,24h", "DB EDh,25h", "DB EDh,26h", "DB EDh,27h", /* 20-27 */
|
||||
"DB EDh,28h", "DB EDh,29h", "DB EDh,2Ah", "DB EDh,2Bh", "DB EDh,2Ch", "DB EDh,2Dh", "DB EDh,2Eh", "DB EDh,2Fh", /* 28-2f */
|
||||
"DB EDh,30h", "DB EDh,31h", "DB EDh,32h", "DB EDh,33h", "DB EDh,34h", "DB EDh,35h", "DB EDh,36h", "DB EDh,37h", /* 30-37 */
|
||||
"DB EDh,38h", "DB EDh,39h", "DB EDh,3Ah", "DB EDh,3Bh", "DB EDh,3Ch", "DB EDh,3Dh", "DB EDh,3Eh", "DB EDh,3Fh", /* 38-3f */
|
||||
"IN B,(C)", "OUT (C),B", "SBC HL,BC", "LD (#h),BC", "NEG", "RETN", "IM 0", "LD I,A", /* 40-47 */
|
||||
"IN C,(C)", "OUT (C),C", "ADC HL,BC", "LD BC,(#h)", "DB EDh,4Ch", "RETI", "DB EDh,4Eh", "LD R,A", /* 48-4f */
|
||||
"IN D,(C)", "OUT (C),D", "SBC HL,DE", "LD (#h),DE", "DB EDh,54h", "DB EDh,55h", "IM 1", "LD A,I", /* 50-57 */
|
||||
"IN E,(C)", "OUT (C),E", "ADC HL,DE", "LD DE,(#h)", "DB EDh,5Ch", "DB EDh,5Dh", "IM 2", "LD A,R", /* 58-5f */
|
||||
"IN H,(C)", "OUT (C),H", "SBC HL,HL", "LD (#h),HL", "DB EDh,64h", "DB EDh,65h", "DB EDh,66h", "RRD", /* 60-67 */
|
||||
"IN L,(C)", "OUT (C),L", "ADC HL,HL", "LD HL,(#h)", "DB EDh,6Ch", "DB EDh,6Dh", "DB EDh,6Eh", "RLD", /* 68-6f */
|
||||
"IN F,(C)", "DB EDh,71h", "SBC HL,SP", "LD (#h),SP", "DB EDh,74h", "DB EDh,75h", "DB EDh,76h", "DB EDh,77h", /* 70-77 */
|
||||
"IN A,(C)", "OUT (C),A", "ADC HL,SP", "LD SP,(#h)", "DB EDh,7Ch", "DB EDh,7Dh", "DB EDh,7Eh", "DB EDh,7Fh", /* 78-7f */
|
||||
"DB EDh,80h", "DB EDh,81h", "DB EDh,82h", "DB EDh,83h", "DB EDh,84h", "DB EDh,85h", "DB EDh,86h", "DB EDh,87h", /* 80-87 */
|
||||
"DB EDh,88h", "DB EDh,89h", "DB EDh,8Ah", "DB EDh,8Bh", "DB EDh,8Ch", "DB EDh,8Dh", "DB EDh,8Eh", "DB EDh,8Fh", /* 88-8f */
|
||||
"DB EDh,90h", "DB EDh,91h", "DB EDh,92h", "DB EDh,93h", "DB EDh,94h", "DB EDh,95h", "DB EDh,96h", "DB EDh,97h", /* 90-97 */
|
||||
"DB EDh,98h", "DB EDh,99h", "DB EDh,9Ah", "DB EDh,9Bh", "DB EDh,9Ch", "DB EDh,9Dh", "DB EDh,9Eh", "DB EDh,9Fh", /* 98-9f */
|
||||
"LDI", "CPI", "INI", "OUTI", "DB EDh,A4h", "DB EDh,A5h", "DB EDh,A6h", "DB EDh,A7h", /* a0-a7 */
|
||||
"LDD", "CPD", "IND", "OUTD", "DB EDh,ACh", "DB EDh,ADh", "DB EDh,AEh", "DB EDh,AFh", /* a8-af */
|
||||
"LDIR", "CPIR", "INIR", "OTIR", "DB EDh,B4h", "DB EDh,B5h", "DB EDh,B6h", "DB EDh,B7h", /* b0-b7 */
|
||||
"LDDR", "CPDR", "INDR", "OTDR", "DB EDh,BCh", "DB EDh,BDh", "DB EDh,BEh", "DB EDh,BFh", /* b8-bf */
|
||||
"DB EDh,C0h", "DB EDh,C1h", "DB EDh,C2h", "DB EDh,C3h", "DB EDh,C4h", "DB EDh,C5h", "DB EDh,C6h", "DB EDh,C7h", /* c0-c7 */
|
||||
"DB EDh,C8h", "DB EDh,C9h", "DB EDh,CAh", "DB EDh,CBh", "DB EDh,CCh", "DB EDh,CDh", "DB EDh,CEh", "DB EDh,CFh", /* c8-cf */
|
||||
"DB EDh,D0h", "DB EDh,D1h", "DB EDh,D2h", "DB EDh,D3h", "DB EDh,D4h", "DB EDh,D5h", "DB EDh,D6h", "DB EDh,D7h", /* d0-d7 */
|
||||
"DB EDh,D8h", "DB EDh,D9h", "DB EDh,DAh", "DB EDh,DBh", "DB EDh,DCh", "DB EDh,DDh", "DB EDh,DEh", "DB EDh,DFh", /* d8-df */
|
||||
"DB EDh,E0h", "DB EDh,E1h", "DB EDh,E2h", "DB EDh,E3h", "DB EDh,E4h", "DB EDh,E5h", "DB EDh,E6h", "DB EDh,E7h", /* e0-e7 */
|
||||
"DB EDh,E8h", "DB EDh,E9h", "DB EDh,EAh", "DB EDh,EBh", "DB EDh,ECh", "DB EDh,EDh", "DB EDh,EEh", "DB EDh,EFh", /* e8-ef */
|
||||
"DB EDh,F0h", "DB EDh,F1h", "DB EDh,F2h", "DB EDh,F3h", "DB EDh,F4h", "DB EDh,F5h", "DB EDh,F6h", "DB EDh,F7h", /* f0-f7 */
|
||||
"DB EDh,F8h", "DB EDh,F9h", "DB EDh,FAh", "DB EDh,FBh", "DB EDh,FCh", "DB EDh,FDh", "DB EDh,FEh", "DB EDh,FFh" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsXX[256] =
|
||||
{
|
||||
"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA",
|
||||
"EX AF,AF'", "ADD I%,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA",
|
||||
"DJNZ @h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA",
|
||||
"JR @h", "ADD I%,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA",
|
||||
"JR NZ,@h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%h", "DEC I%h", "LD I%h,*h", "DAA",
|
||||
"JR Z,@h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%l", "DEC I%l", "LD I%l,*h", "CPL",
|
||||
"JR NC,@h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (I%+^h)", "DEC (I%+^h)", "LD (I%+^h),*h", "SCF",
|
||||
"JR C,@h", "ADD I%,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF",
|
||||
"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%h", "LD B,I%l", "LD B,(I%+^h)", "LD B,A",
|
||||
"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%h", "LD C,I%l", "LD C,(I%+^h)", "LD C,A",
|
||||
"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%h", "LD D,I%l", "LD D,(I%+^h)", "LD D,A",
|
||||
"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%h", "LD E,I%l", "LD E,(I%+^h)", "LD E,A",
|
||||
"LD I%h,B", "LD I%h,C", "LD I%h,D", "LD I%h,E", "LD I%h,I%h", "LD I%h,I%l", "LD H,(I%+^h)", "LD I%h,A",
|
||||
"LD I%l,B", "LD I%l,C", "LD I%l,D", "LD I%l,E", "LD I%l,I%h", "LD I%l,I%l", "LD L,(I%+^h)", "LD I%l,A",
|
||||
"LD (I%+^h),B", "LD (I%+^h),C", "LD (I%+^h),D", "LD (I%+^h),E", "LD (I%+^h),H", "LD (I%+^h),L", "HALT", "LD (I%+^h),A",
|
||||
"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%h", "LD A,I%l", "LD A,(I%+^h)", "LD A,A",
|
||||
"ADD B", "ADD C", "ADD D", "ADD E", "ADD I%h", "ADD I%l", "ADD (I%+^h)", "ADD A",
|
||||
"ADC B", "ADC C", "ADC D", "ADC E", "ADC I%h", "ADC I%l", "ADC (I%+^h)", "ADC,A",
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB I%h", "SUB I%l", "SUB (I%+^h)", "SUB A",
|
||||
"SBC B", "SBC C", "SBC D", "SBC E", "SBC I%h", "SBC I%l", "SBC (I%+^h)", "SBC A",
|
||||
"AND B", "AND C", "AND D", "AND E", "AND I%h", "AND I%l", "AND (I%+^h)", "AND A",
|
||||
"XOR B", "XOR C", "XOR D", "XOR E", "XOR I%h", "XOR I%l", "XOR (I%+^h)", "XOR A",
|
||||
"OR B", "OR C", "OR D", "OR E", "OR I%h", "OR I%l", "OR (I%+^h)", "OR A",
|
||||
"CP B", "CP C", "CP D", "CP E", "CP I%h", "CP I%l", "CP (I%+^h)", "CP A",
|
||||
"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD *h", "RST 00h",
|
||||
"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC *h", "RST 08h",
|
||||
"RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h",
|
||||
"RET C", "EXX", "JP C,#h", "IN A,(*h)", "CALL C,#h", "PFX_DD", "SBC *h", "RST 18h",
|
||||
"RET PO", "POP I%", "JP PO,#h", "EX I%,(SP)", "CALL PO,#h", "PUSH I%", "AND *h", "RST 20h",
|
||||
"RET PE", "LD PC,I%", "JP PE,#h", "EX DE,I%", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h",
|
||||
"RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h",
|
||||
"RET M", "LD SP,I%", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h"
|
||||
static char *MnemonicsXX[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */
|
||||
"EX AF,AF'", "ADD I%,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */
|
||||
"DJNZ $h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA", /* 10-17 */
|
||||
"JR $h", "ADD I%,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA", /* 18-1f */
|
||||
"JR NZ,$h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%h", "DEC I%h", "LD I%h,*h", "DAA", /* 20-27 */
|
||||
"JR Z,$h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%l", "DEC I%l", "LD I%l,*h", "CPL", /* 28-2f */
|
||||
"JR NC,$h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (I%+^h)", "DEC (I%+^h)", "LD (I%+^h),*h", "SCF", /* 30-37 */
|
||||
"JR C,$h", "ADD I%,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF", /* 38-3f */
|
||||
"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%h", "LD B,I%l", "LD B,(I%+^h)", "LD B,A", /* 40-47 */
|
||||
"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%h", "LD C,I%l", "LD C,(I%+^h)", "LD C,A", /* 48-4f */
|
||||
"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%h", "LD D,I%l", "LD D,(I%+^h)", "LD D,A", /* 50-57 */
|
||||
"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%h", "LD E,I%l", "LD E,(I%+^h)", "LD E,A", /* 58-5f */
|
||||
"LD I%h,B", "LD I%h,C", "LD I%h,D", "LD I%h,E", "LD I%h,I%h", "LD I%h,I%l", "LD H,(I%+^h)", "LD I%h,A", /* 60-67 */
|
||||
"LD I%l,B", "LD I%l,C", "LD I%l,D", "LD I%l,E", "LD I%l,I%h", "LD I%l,I%l", "LD L,(I%+^h)", "LD I%l,A", /* 68-6f */
|
||||
"LD (I%+^h),B", "LD (I%+^h),C", "LD (I%+^h),D", "LD (I%+^h),E", "LD (I%+^h),H", "LD (I%+^h),L", "HALT", "LD (I%+^h),A", /* 70-77 */
|
||||
"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%h", "LD A,I%l", "LD A,(I%+^h)", "LD A,A", /* 78-7f */
|
||||
"ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,I%h", "ADD A,I%l", "ADD A,(I%+^h)", "ADD A,A", /* 80-87 */
|
||||
"ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,I%h", "ADC A,I%l", "ADC A,(I%+^h)", "ADC A,A", /* 88-8f */
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB I%h", "SUB I%l", "SUB (I%+^h)", "SUB A", /* 90-97 */
|
||||
"SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,I%h", "SBC A,I%l", "SBC A,(I%+^h)", "SBC A,A", /* 98-9f */
|
||||
"AND B", "AND C", "AND D", "AND E", "AND I%h", "AND I%l", "AND (I%+^h)", "AND A", /* a0-a7 */
|
||||
"XOR B", "XOR C", "XOR D", "XOR E", "XOR I%h", "XOR I%l", "XOR (I%+^h)", "XOR A", /* a8-af */
|
||||
"OR B", "OR C", "OR D", "OR E", "OR I%h", "OR I%l", "OR (I%+^h)", "OR A", /* b0-b7 */
|
||||
"CP B", "CP C", "CP D", "CP E", "CP I%h", "CP I%l", "CP (I%+^h)", "CP A", /* b8-bf */
|
||||
"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD A,*h", "RST 00h", /* c8-cf */
|
||||
"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC A,*h", "RST 08h", /* c8-cf */
|
||||
"RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h", /* d0-d7 */
|
||||
"RET C", "EXX", "JP C,#h", "IN A,(*h)", "CALL C,#h", "PFX_DD", "SBC A,*h", "RST 18h", /* d8-df */
|
||||
"RET PO", "POP I%", "JP PO,#h", "EX (SP),I%", "CALL PO,#h", "PUSH I%", "AND *h", "RST 20h", /* e0-e7 */
|
||||
"RET PE", "LD PC,I%", "JP PE,#h", "EX DE,I%", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h", /* e8-ef */
|
||||
"RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h", /* f0-f7 */
|
||||
"RET M", "LD SP,I%", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsXCB[256] =
|
||||
{
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (I%@h)", "RLC A",
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (I%@h)", "RRC A",
|
||||
"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (I%@h)", "RL A",
|
||||
"RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (I%@h)", "RR A",
|
||||
"SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (I%@h)", "SLA A",
|
||||
"SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (I%@h)", "SRA A",
|
||||
"SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (I%@h)", "SLL A",
|
||||
"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (I%@h)", "SRL A",
|
||||
"BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(I%@h)", "BIT 0,A",
|
||||
"BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(I%@h)", "BIT 1,A",
|
||||
"BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(I%@h)", "BIT 2,A",
|
||||
"BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(I%@h)", "BIT 3,A",
|
||||
"BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(I%@h)", "BIT 4,A",
|
||||
"BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(I%@h)", "BIT 5,A",
|
||||
"BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(I%@h)", "BIT 6,A",
|
||||
"BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(I%@h)", "BIT 7,A",
|
||||
"RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(I%@h)", "RES 0,A",
|
||||
"RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(I%@h)", "RES 1,A",
|
||||
"RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(I%@h)", "RES 2,A",
|
||||
"RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(I%@h)", "RES 3,A",
|
||||
"RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(I%@h)", "RES 4,A",
|
||||
"RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(I%@h)", "RES 5,A",
|
||||
"RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(I%@h)", "RES 6,A",
|
||||
"RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(I%@h)", "RES 7,A",
|
||||
"SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(I%@h)", "SET 0,A",
|
||||
"SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(I%@h)", "SET 1,A",
|
||||
"SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(I%@h)", "SET 2,A",
|
||||
"SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(I%@h)", "SET 3,A",
|
||||
"SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(I%@h)", "SET 4,A",
|
||||
"SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(I%@h)", "SET 5,A",
|
||||
"SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(I%@h)", "SET 6,A",
|
||||
"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(I%@h)", "SET 7,A"
|
||||
static char *MnemonicsXCB[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (I%@h)", "RLC A", /* 00-07 */
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (I%@h)", "RRC A", /* 08-0f */
|
||||
"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (I%@h)", "RL A", /* 10-17 */
|
||||
"RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (I%@h)", "RR A", /* 18-1f */
|
||||
"SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (I%@h)", "SLA A", /* 20-27 */
|
||||
"SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (I%@h)", "SRA A", /* 28-2f */
|
||||
"SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (I%@h)", "SLL A", /* 30-37 */
|
||||
"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (I%@h)", "SRL A", /* 38-3f */
|
||||
"BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(I%@h)", "BIT 0,A", /* 40-47 */
|
||||
"BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(I%@h)", "BIT 1,A", /* 48-4f */
|
||||
"BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(I%@h)", "BIT 2,A", /* 50-57 */
|
||||
"BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(I%@h)", "BIT 3,A", /* 58-5f */
|
||||
"BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(I%@h)", "BIT 4,A", /* 60-67 */
|
||||
"BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(I%@h)", "BIT 5,A", /* 68-6f */
|
||||
"BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(I%@h)", "BIT 6,A", /* 70-77 */
|
||||
"BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(I%@h)", "BIT 7,A", /* 78-7f */
|
||||
"RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(I%@h)", "RES 0,A", /* 80-87 */
|
||||
"RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(I%@h)", "RES 1,A", /* 88-8f */
|
||||
"RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(I%@h)", "RES 2,A", /* 90-97 */
|
||||
"RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(I%@h)", "RES 3,A", /* 98-9f */
|
||||
"RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(I%@h)", "RES 4,A", /* a0-a7 */
|
||||
"RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(I%@h)", "RES 5,A", /* a8-af */
|
||||
"RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(I%@h)", "RES 6,A", /* b0-b7 */
|
||||
"RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(I%@h)", "RES 7,A", /* b8-bf */
|
||||
"SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(I%@h)", "SET 0,A", /* c0-c7 */
|
||||
"SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(I%@h)", "SET 1,A", /* c8-cf */
|
||||
"SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(I%@h)", "SET 2,A", /* d0-d7 */
|
||||
"SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(I%@h)", "SET 3,A", /* d8-df */
|
||||
"SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(I%@h)", "SET 4,A", /* e0-e7 */
|
||||
"SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(I%@h)", "SET 5,A", /* e8-ef */
|
||||
"SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(I%@h)", "SET 6,A", /* f0-f7 */
|
||||
"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(I%@h)", "SET 7,A" /* f8-ff */
|
||||
};
|
||||
|
||||
/* Symbolic disassembler
|
||||
@@ -268,36 +277,36 @@ static char *MnemonicsXCB[256] =
|
||||
Inputs:
|
||||
*val = instructions to disassemble
|
||||
useZ80Mnemonics = > 0 iff Z80 mnemonics are to be used
|
||||
addr = current PC
|
||||
Outputs:
|
||||
*S = output text
|
||||
|
||||
|
||||
DAsm is Copyright (C) Marat Fayzullin 1995,1996,1997
|
||||
You are not allowed to distribute this software
|
||||
commercially.
|
||||
|
||||
*/
|
||||
|
||||
int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics)
|
||||
{
|
||||
int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) {
|
||||
char R[128], H[10], C= '\0', *T, *P;
|
||||
uint8 J = 0, Offset;
|
||||
uint16 B = 0;
|
||||
|
||||
if (useZ80Mnemonics) {
|
||||
switch(val[B]) {
|
||||
case 0xCB:
|
||||
case 0xcb:
|
||||
B++;
|
||||
T = MnemonicsCB[val[B++]];
|
||||
break;
|
||||
case 0xED:
|
||||
case 0xed:
|
||||
B++;
|
||||
T = MnemonicsED[val[B++]];
|
||||
break;
|
||||
case 0xDD:
|
||||
case 0xFD:
|
||||
C = (val[B] == 0xDD) ? 'X' : 'Y';
|
||||
case 0xdd:
|
||||
case 0xfd:
|
||||
C = (val[B] == 0xdd) ? 'X' : 'Y';
|
||||
B++;
|
||||
if (val[B] == 0xCB) {
|
||||
if (val[B] == 0xcb) {
|
||||
B++;
|
||||
Offset = val[B++];
|
||||
J = 1;
|
||||
@@ -315,8 +324,7 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics)
|
||||
T = Mnemonics8080[val[B++]];
|
||||
}
|
||||
|
||||
if (P = strchr(T, '^'))
|
||||
{
|
||||
if (P = strchr(T, '^')) {
|
||||
strncpy(R, T, P - T);
|
||||
R[P - T] = '\0';
|
||||
sprintf(H, "%02X", val[B++]);
|
||||
@@ -328,7 +336,9 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics)
|
||||
}
|
||||
if (P = strchr(R, '%')) {
|
||||
*P = C;
|
||||
if (P = strchr(P + 1, '%')) *P = C;
|
||||
if (P = strchr(P + 1, '%')) {
|
||||
*P = C;
|
||||
}
|
||||
}
|
||||
|
||||
if(P = strchr(R, '*')) {
|
||||
@@ -350,10 +360,18 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics)
|
||||
strcat(S, H);
|
||||
strcat(S, P + 1);
|
||||
}
|
||||
else if (P = strchr(R, '$')) {
|
||||
strncpy(S, R, P - R);
|
||||
S[P - R] = '\0';
|
||||
Offset = val[B++];
|
||||
sprintf(H, "%04X", addr + 2 + (Offset & 0x80 ? (Offset - 256) : Offset));
|
||||
strcat(S, H);
|
||||
strcat(S, P + 1);
|
||||
}
|
||||
else if (P = strchr(R, '#')) {
|
||||
strncpy(S, R, P - R);
|
||||
S[P - R] = '\0';
|
||||
sprintf(H, "%04X", val[B] + 256*val[B + 1]);
|
||||
sprintf(H, "%04X", val[B] + 256 * val[B + 1]);
|
||||
strcat(S, H);
|
||||
strcat(S, P + 1);
|
||||
B += 2;
|
||||
@@ -376,23 +394,22 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics)
|
||||
status = error code
|
||||
*/
|
||||
|
||||
int32 fprint_sym (FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw)
|
||||
{
|
||||
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw) {
|
||||
char disasm[128];
|
||||
int32 ch = val[0] & 0x7f;
|
||||
if (sw & (SWMASK ('A') | SWMASK ('C'))) {
|
||||
if (sw & (SWMASK('A') | SWMASK('C'))) {
|
||||
fprintf(of, ((0x20 <= ch) && (ch < 0x7f)) ? "'%c'" : "%02x", ch);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (!(sw & SWMASK ('M'))) {
|
||||
if (!(sw & SWMASK('M'))) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
ch = DAsm(disasm, val, cpu_unit.flags & UNIT_CHIP);
|
||||
ch = DAsm(disasm, val, cpu_unit.flags & UNIT_CHIP, addr);
|
||||
fprintf(of, "%s", disasm);
|
||||
return (1-ch); /* need to return additional bytes */
|
||||
return 1 - ch; /* need to return additional bytes */
|
||||
}
|
||||
|
||||
/* numString checks determines the base of the number (ch, *numString)
|
||||
/* numString checks determines the base of the number (ch, *numString)
|
||||
and returns FALSE if the number is bad */
|
||||
int32 checkbase(char ch, char *numString) {
|
||||
int32 decimal = (ch <= '9');
|
||||
@@ -431,12 +448,12 @@ int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 req
|
||||
if (toupper(ch) != 'H') {
|
||||
(*numString)--;
|
||||
}
|
||||
*result = value*sign;
|
||||
*result = value * sign;
|
||||
return (minvalue <= value) && (value <= maxvalue);
|
||||
}
|
||||
|
||||
int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star,
|
||||
int32 *at, int32 *hat) {
|
||||
int32 *at, int32 *hat, int32 *dollar) {
|
||||
char pat = *pattern++;
|
||||
char inp = *input++;
|
||||
while ((pat) && (inp)) {
|
||||
@@ -490,6 +507,14 @@ int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star,
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case '$':
|
||||
if (numok(inp, &input, 0, 65535, FALSE, dollar)) {
|
||||
pattern++; /* skip h */
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
if (numok(inp, &input, 0, 255, FALSE, hat)) {
|
||||
pattern++; /* skip h */
|
||||
@@ -512,12 +537,12 @@ int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star,
|
||||
return (pat == 0) && (inp == 0);
|
||||
}
|
||||
|
||||
inline int32 checkXY(char xy) {
|
||||
INLINE int32 checkXY(char xy) {
|
||||
if (xy == 'X') {
|
||||
return 0xDD;
|
||||
return 0xdd;
|
||||
}
|
||||
else if (xy == 'Y') {
|
||||
return 0xFD;
|
||||
return 0xfd;
|
||||
}
|
||||
else {
|
||||
printf("X or Y expected.\n");
|
||||
@@ -527,27 +552,34 @@ inline int32 checkXY(char xy) {
|
||||
|
||||
int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
||||
char xy;
|
||||
int32 op, number, star, at, hat;
|
||||
int32 op, number, star, at, hat, dollar;
|
||||
for (op = 0; op < 256; op++) {
|
||||
number = star = at = -129;
|
||||
if (match(Mnemonics[op], cptr, &xy, &number, &star, &at, &hat)) {
|
||||
number = star = at = dollar = -129;
|
||||
if (match(Mnemonics[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
val[0] = op;
|
||||
if (number >= 0) {
|
||||
val[1] = (0xff) & number;
|
||||
val[2] = (0xff) & (number >> 8);
|
||||
return (-2); /* two additional bytes returned */
|
||||
return -2; /* two additional bytes returned */
|
||||
}
|
||||
else if (star >= 0) {
|
||||
val[1] = (0xff) & star;
|
||||
return (-1); /* one additional byte returned */
|
||||
return -1; /* one additional byte returned */
|
||||
}
|
||||
else if (at > -129) {
|
||||
if (at > 127) { /* assume absolute address is meant */
|
||||
at -= addr + 2; /* translate to relative address */
|
||||
}
|
||||
if ((-128 <= at) && (at < 127)) {
|
||||
if ((-128 <= at) && (at <= 127)) {
|
||||
val[1] = (int8)(at);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
}
|
||||
else if (dollar >= 0) {
|
||||
dollar -= addr + 2; /* relative translation */
|
||||
if ((-128 <= dollar) && (dollar <= 127)) {
|
||||
val[1] = (int8)(dollar);
|
||||
return -1; /* one additional byte returned */
|
||||
}
|
||||
else {
|
||||
return SCPE_ARG;
|
||||
@@ -561,35 +593,35 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
||||
if (Mnemonics == Mnemonics8080) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
||||
|
||||
for (op = 0; op < 256; op++) {
|
||||
if (match(MnemonicsCB[op], cptr, &xy, &number, &star, &at, &hat)) {
|
||||
val[0] = 0xCB;
|
||||
if (match(MnemonicsCB[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
val[0] = 0xcb;
|
||||
val[1] = op;
|
||||
return (-1); /* one additional byte returned */
|
||||
return -1; /* one additional byte returned */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (op = 0; op < 256; op++) {
|
||||
number = -1;
|
||||
if (match(MnemonicsED[op], cptr, &xy, &number, &star, &at, &hat)) {
|
||||
val[0] = 0xED;
|
||||
if (match(MnemonicsED[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
val[0] = 0xed;
|
||||
val[1] = op;
|
||||
if (number >= 0) {
|
||||
val[2] = (0xff) & number;
|
||||
val[3] = (0xff) & (number >> 8);
|
||||
return (-3); /* three additional bytes returned */
|
||||
return -3; /* three additional bytes returned */
|
||||
}
|
||||
else {
|
||||
return (-1); /* one additional byte returned */
|
||||
return -1; /* one additional byte returned */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (op = 0; op < 256; op++) {
|
||||
number = star = hat = -1;
|
||||
xy = ' ';
|
||||
if (match(MnemonicsXX[op], cptr, &xy, &number, &star, &at, &hat)) {
|
||||
if (match(MnemonicsXX[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
if (!(val[0] = checkXY(xy))) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
@@ -597,35 +629,35 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
||||
if (number >= 0) {
|
||||
val[2] = (0xff) & number;
|
||||
val[3] = (0xff) & (number >> 8);
|
||||
return (-3); /* three additional bytes returned */
|
||||
return -3; /* three additional bytes returned */
|
||||
}
|
||||
else if ((star >= 0) && (hat >= 0)) {
|
||||
val[2] = (0xff) & hat;
|
||||
val[3] = (0xff) & star;
|
||||
return (-3); /* three additional bytes returned */
|
||||
return -3; /* three additional bytes returned */
|
||||
}
|
||||
else if (star >= 0) {
|
||||
val[2] = (0xff) & star;
|
||||
return (-2); /* two additional bytes returned */
|
||||
return -2; /* two additional bytes returned */
|
||||
}
|
||||
else if (hat >= 0) {
|
||||
val[2] = (0xff) & hat;
|
||||
return (-2); /* two additional bytes returned */
|
||||
return -2; /* two additional bytes returned */
|
||||
}
|
||||
else {
|
||||
return (-1); /* one additional byte returned */
|
||||
return -1; /* one additional byte returned */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (op = 0; op < 256; op++) {
|
||||
at = -129;
|
||||
xy = ' ';
|
||||
if (match(MnemonicsXCB[op], cptr, &xy, &number, &star, &at, &hat)) {
|
||||
if (match(MnemonicsXCB[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
if (!(val[0] = checkXY(xy))) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
val[1] = 0xCB;
|
||||
val[1] = 0xcb;
|
||||
if (at > -129) {
|
||||
val[2] = (int8) (at);
|
||||
}
|
||||
@@ -634,7 +666,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
val[3] = op;
|
||||
return (-3); /* three additional bytes returned */
|
||||
return -3; /* three additional bytes returned */
|
||||
}
|
||||
}
|
||||
return SCPE_ARG;
|
||||
@@ -652,12 +684,11 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
||||
Outputs:
|
||||
status = error status
|
||||
*/
|
||||
int32 parse_sym (char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw)
|
||||
{
|
||||
while (isspace (*cptr)) cptr++; /* absorb spaces */
|
||||
if ((sw & (SWMASK ('A') | SWMASK ('C'))) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||
int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw) {
|
||||
while (isspace(*cptr)) cptr++; /* absorb spaces */
|
||||
if ((sw & (SWMASK('A') | SWMASK('C'))) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||
if (cptr[0] == 0) {
|
||||
return SCPE_ARG; /* must have 1 char */
|
||||
return SCPE_ARG; /* must have one char */
|
||||
}
|
||||
val[0] = (uint32) cptr[0];
|
||||
return SCPE_OK;
|
||||
@@ -667,21 +698,45 @@ int32 parse_sym (char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw)
|
||||
}
|
||||
|
||||
|
||||
/* This is the binary loader. The input file is considered to be
|
||||
a string of literal bytes with no format special format. The
|
||||
load starts at the current value of the PC.
|
||||
/* This is the binary loader. The input file is considered to be
|
||||
a string of literal bytes with no format special format. The
|
||||
load starts at the current value of the PC.
|
||||
*/
|
||||
|
||||
int32 sim_load (FILE *fileref, char *cptr, char *fnam, int32 flag)
|
||||
{
|
||||
int32 i, addr = 0, cnt = 0;
|
||||
|
||||
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
|
||||
addr = saved_PC;
|
||||
while ((i = getc (fileref)) != EOF) {
|
||||
M[addr++] = i;
|
||||
cnt++;
|
||||
} /* end while */
|
||||
printf ("%d Bytes loaded.\n", cnt);
|
||||
return (SCPE_OK);
|
||||
int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) {
|
||||
int32 i, addr = 0, cnt = 0, org;
|
||||
t_addr j, lo, hi;
|
||||
char *result;
|
||||
t_stat status;
|
||||
if (flag) {
|
||||
result = get_range(cptr, &lo, &hi, 16, ADDRMASK, 0);
|
||||
if (result == NULL) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
for (j = lo; j <= hi; j++) {
|
||||
if (putc(GetBYTEWrapper(j), fileref) == EOF) {
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
}
|
||||
printf("%d Bytes dumped [%x - %x].\n", hi + 1 - lo, lo, hi);
|
||||
}
|
||||
else {
|
||||
if (*cptr == 0) {
|
||||
addr = saved_PC;
|
||||
}
|
||||
else {
|
||||
addr = get_uint(cptr, 16, ADDRMASK, &status);
|
||||
if (status != SCPE_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
org = addr;
|
||||
while ((addr < MAXMEMSIZE) && ((i = getc(fileref)) != EOF)) {
|
||||
PutBYTEWrapper(addr, i);
|
||||
addr++;
|
||||
cnt++;
|
||||
} /* end while */
|
||||
printf("%d Bytes loaded at %x.\n", cnt, org);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user