1
0
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:
Bob Supnik
2002-07-14 15:20:00 -07:00
committed by Mark Pizzolato
parent 701f0fe028
commit df6475181c
179 changed files with 36441 additions and 4464 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}