-
Notifications
You must be signed in to change notification settings - Fork 0
jgharston/cZ80Tube
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Z80Tube Emulator in C Version 0.28
==================================
J.G.Harston - http://www.mdfs.net/
70 Camm Street, Walkley, Sheffield, S6 3TR
Date: 31-Jan-2019
cZ80Tube emulates a Z80 coprocessor, written in C. On running, various
command line options can be given:
cZ80 [-mos file] [file [params]]
-mos Provide a MOS file to load to the top of memory. This can provide
some interface facilities between the Z80 environment and the host.
The default MOS code just passes all calls over. The MOS provided
within !Z80Tube provides some command line facilities that need to
be executed from with the Z80 environment to work properly.
If a file is given, it is loaded into the Z80's memory. Any extra parameters
are copied to the command buffer at &0080 for the loaded program to collect
and deal with. An example command line would be:
cZ80 -mos files/MOS TestProg This is a command line
This would start the emulator using the MOS file provided with cZ80Tube,
load the file TestProg into memory, copy the text 'This is a command line'
to &0080, and enter the code at the relevant entry point.
Compiling
---------
To compile cZ80Tube compile the file z80tube.c with the appropriate
identifier defined with the compiler's -D option. The identifiers checked
for are in the host.h file. There are batch files in the build directory
that compile for various platforms.
MakeCCode is a BBC BASIC program that generates the z80.c source file for
the Z80 engine. It can be run on cZ80Tube itself to create the source file
with a command such as:
cZ80 -mos files/MOS files/BBCBasic src/MakeCCode > src/z80.c
MOS Implementation
------------------
There is a limited MOS host implementation. Calls to the standard I/O
routines at &FFCE to &FFF7 provide a minimum of the following functions.
These can be expanded by added relevant code to hostio.c
OSCLI
HL=>command string to pass to system.
OSBYTE
A=0, L<>0: Return host type - L=6 - RISC OS, L=8 - Unix, L=32 - Win/DOS
A=128: Read device or buffer (ADVAL)
HL=&FFFF - returns 0 if no keyboard input pending, <>0 otherwise
HL=&007F - waits for and returns 16-bit keypress
A=129: Wait for byte from input in HL or scan for keypress (INKEY)
HL=&0000+cs - max time in centiseconds to wait, return 8-bit keypress
HL=&8000+cs - max time in centiseconds to wait, return 16-bit keypress
HL=&FExx - scan for internal keypress
HL=&FF00 - return hardware type
HL=&FFxx - scan for keypress, see keyscan table
If the input stream is the console (keyboard), then HL=&8000+cs will
return HL=&00xx for standard characters, and HL=&01xx for function
and cursor keys, as shown in the keycode table.
A=131: Return lowest address in user memory (&0100)
A=132: Return highest address in user memory (contents of &0006/7)
A=134: Return L=POS and H=VPOS
OSWORD
A=0: Read line to address at (HL,HL+1).
OSWRCH
Writes a characters to the output stream. If the output stream is not
redirected then the characters are interpreted to perform the following
console functions:
8 - left, 9 - right, 10 - down, 11 - up, 12 - CLS, 13 - CR
30 - home, 31,x,y - move to position
If cZ80Tube is built with CONVDU_ANSI defined then ANSI colour sequences
are used to select text colours with:
17,n - select text colour
20 - select default text colours
22,n - clear screen and select default text colours
OSRDCH
Waits for and returns a byte from the input stream. If the input stream is
attached to the console (keyboard), returns a keypress byte. This is the
ASCII code of the key pressed or an 8-bit top-bit set byte for function
keys and cursor keys, as shown in the keycode table.
OSFILE
Whole file operations. (HL,HL+1)=>filename
A=&FF - Load a file to address in (HL+2,3,4,5) if (HL+6)=0.
A=&00 - Save a file. (HL+2,3,4,5)=address of first byte,
(HL+6,7,8,9)=address of byte after last byte.
Console I/O
-----------
cZ80Tube uses the JGH Console I/O library. This returns keycodes ordered in a
sensible manner rather than the apparently random order of the native Windows
keycodes, and allows top-bit set function and editing keys to be distingiushed
from top-bit set characters.
Keycode Top-Bit Table
---------------------
Function and editing keys return the following codes when OSBYTE 129 or
OSRDCH is called. OSBYTE 129,&8000+cs will return the 16bit value &0180+x to
distinguish function and editing keys from normal topbit set keys, such as
accented characters. Alt plus printable characters returns &0100+x where x is
the normal character, unless the Alt-keypress already returns a top-bit-set
character.
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|18x| F0| F1| F2| F3| F4| F5| F6| F7| F8 | F9| F10 | F11 | F12| F13| F14| F15|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|19x|sF0|sF1|sF2|sF3|sF4| sF5| sF6| sF7| sF8 | sF9| sF10| sF11|sF12|sF13|sF14|sF15|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|1Ax|cF0|cF1|cF2|cF3|cF4| cF5| cF6| cF7| cF8 | cF9| cF10| cF11|cF12|cF13|cF14|cF15|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|1Bx|aF0|aF1|aF2|aF3|aF4| aF5| aF6| aF7| aF8 | aF9| aF10| aF11|aF12|aF13|aF14|aF15|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|1Cx| | | | | | | Ins| Del| Home| End| PgDn| PgUp| <- | -> | Dn | Up |
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|1Dx| | | | | |sTAB|sIns|sDel|sHome|sEnd|sPgDn|sPgUp| s<-| s->| sDn| sUp|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|1Ex| | | | | |cTAB|cIns|cDel|cHome|cEnd|cPgDn|cPgUp| c<-| c->| cDn| cUp|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
|1Fx| | | | | |aTAB|aIns|aDel|aHome|aEnd|aPgDn|aPgUp| a<-| a->| aDn| aUp|
+---+---+---+---+---+---+----+----+----+-----+----+-----+-----+----+----+----+----+
As can be seen from the table, bit 5 and bit 4 hold the state of the Shift,
Control and Alt keys.
Note that some versions of Windows don't recognise the Shift, Ctrl and Alt keys
properly, particularly with the editing keys; and some environments do not pass
on some keycodes.
Keyscan Table
-------------
When calling OSBYTE 129 with HL=&FFxx to scan for a key being pressed, the Acorn
standard values are recognised. Note that some versions of Windows do not
recognise the Shift, Ctrl and Alt keys properly.
-001 Shift -017 Q -033 F0/Print -049 1
-002 Ctrl -018 3 -034 W -050 2
-003 Alt -019 4 -035 E -051 D
-004 Left Shift -020 5 -036 T -052 R
-005 Left Ctrl -021 F4 -037 7 -053 6
-006 Left Alt -022 8 -038 I -054 U
-007 Right Shift -023 F7 -039 9 -055 O
-008 Right Ctrl -024 - -040 0 -056 P
-009 Right Alt -025 ^ -041 _ -057 [
-010 Mouse Select -026 Left -042 Down -058 Up
-011 Mouse Menu -027 Keypad 6 -043 Keypad 8 -059 Keypad +
-012 Mouse Adjust -028 Keypad 7 -044 Keypad 9 -060 Keypad -
-013 -029 F11 -045 Break -061 Keypad Enter
-014 -030 F12 -046 `,~ ',? -062 Insert
-015 -031 F10 -047 ?,Yen -063 Home
-016 -032 Scroll Lock -048 Backspace -064 PgUp
-065 Caps Lock -081 Shift Lock -097 TAB -113 Escape
-066 A -082 S -098 Z -114 F1
-067 X -083 C -099 Space -115 F2
-068 F -084 G -100 V -116 F3
-069 Y -085 H -101 B -117 F5
-070 J -086 N -102 M -118 F6
-071 K -087 L -103 , < -119 F8
-072 @ -088 ; -104 . > -120 F9
-073 : -089 ] -105 / ? -121 \,|
-074 Return -090 Delete -106 Copy/End -122 Right
-075 Keypad / -091 Keypad # #,~ -107 Keypad 0 -123 Keypad 4
-076 Keypad Del -092 Keypad * -108 Keypad 1 -124 Keypad 5
-077 Keypad . -093 Keypad , -109 Keypad 3 -125 Keypad 2
-078 Num Lock -094 =,+ -110 NoConvert -126 WinLeft
-079 PgDn -095 Left \,| -111 Convert -127 WinRight
-080 '," ',@ -096 Right \,_ -112 Kana -128 WinMenu
Notes:
-121: if keyboard has a single \ | key it is this keycode
-95: key between left Shift and Z, usually labelled \ |
-96: key between ? and right Shift, usually labelled \ _
Zero Page Locations
-------------------
0000: JP RESET Jumping to location &0000 is used to quit a program.
The emulator sets this to point to MOS_start+3, the
entry to quit the emulator, and starts running
programs with the return address &0000 on the
stack.
0003: DEFB 0 IOBYTE within CP/M
0004: DEFB 0 Drive and User within CP/M
0005: JP BDOS Jumping to location &0005 is used to call a CPM BDOS
routine. The emulator sets this to point to
MOS_start, which returns with all registers
unchanged. When CP/M is running, the BDOS points
this entry to the BDOS service routine. The value at
&0006/7, the destination of the jump can also be
used as the value of BDOS+6, the byte after the
highest byte in memory available to the user.
0008:
to These locations are not set to anything.
000D:
000E: POP HL Calling location &000E with load the HL register
with the address of the location after the call, ie
CALL &000E can be thought of as LD HL,PC, as a
complement to JP (HL) which can be thought of as
LD PC,HL.
000F: JP (HL) Calling location &000F will jump to the address in
the HL register, ie CALL &000F can be thought of as
CALL (HL) as a complement to JP (HL).
0010:
to These locations are not set to anything.
0037:
0038: Error restart. The MOS initialises this to the
to default error handler, and any foreground program
003A: will set it to its own error handler.
003B:
to These locations are not set to anything.
007F:
0080: Parameter buffer. This byte contains the length of
any passed parameter string, ie zero if no
parameters present.
0081: This buffer contains any passed parameters. Note
to that there may not be a CR at the end of this
00FF: string.
Z80 MOS Entry Points
--------------------
PRHEX &FFAA Print A in hex
On entry: A = value to be printed
On exit: A is corrupted
This routine prints out the A register in hexadecimal to two digits and
leading zeros. This routine is overwritten by the Acorn BIOS in CP/M.
PR2HEX &FFAD Print HL in hex
On entry: HL = value to be printed
On exit: A is corrupted
This routine prints out the HL register in hexadecmial to four digits and
leading zeros. This routine is overwritten by the Acorn BIOS in CP/M.
PRTEXT &FFB3 Print in-line text
On entry: -
On exit: A = 0
This routine prints out the text following the call to OSASCI. The text
needs to be terminated with a zero byte, eg:
CALL PRTEXT
DEFM "HELLO THERE":NOP
\ continue here
PRSTRING &FF9B Print text
On entry: HL = address of string to print
On exit: HL = address after &00 byte after string printed
A = 0
This routine prints out the text pointed to by HL. The text needs to be
terminated with a zero byte.
OSFIND &FFCE Open or close a file
OSGBPB &FFD1 Multiple byte file access
OSBPUT &FFD4 Put a byte to a file
OSBGET &FFD7 Get a byte from a file
OSARGS &FFDA Read or set file arguments
OSFILE &FFDD Load or save file
OSRDCH &FFE0 Input a character
OSASCI &FFE3 Print a character, with CR converted to LF,CR
OSNEWL &FFE7 Print a LF,CR sequence
OSWRCH &FFEE Print a character
OSWORD &FFF1 Do an OSWORD call
OSBYTE &FFF4 Do an OSBYTE call
OSCLI &FFF7 Interpret a command
The following three addresses hold system vectors:
BRKV &FFFA Address of error handler
EVENTV &FFFC Address of event handler
INTV &FFFE Address of primary interupt handler
CPU Implementation
------------------
All documented Zilog Z80 opcodes are implemented, as well as the unofficial
instructions SLS r, and accessing the upper or lower halves of the index
registers as a single byte register, ie IXL, IXH, IYL, IYH. Currently,
INI[R], IND[R], OTI[R] and OTD[R] are unimplemented and act as NOPs. An IN
instruction issues the Service_Z80TubeIN call and an OUT instruction issues
a Service_Z0TubeOUT call. A Reset issues a Service_Z80TubeReset call.
All indexed rotation/bit instructions manipulate (IX+n) or (IY+n), so, for
example, FDCBnn00 to FDCBnn05 and FDCBnn07 all perform as though they were
FDCBnn06, ie RLC (IY+nn). On a real Z80 the 8bit registers are stored to
after the operation. For instance, FDCBnn00 does a RLC (IY+nn) and then
stores the result in B. This is usually written as RLC (IY+nn)->B.
Sixteen extra instructions have been added to control the emulator and to
comunicate with the host, EDF0 to EDFF.
The bottom seven bits of the R register are incremented every time R is
loaded from, ie every LD A,R instruction, rather than on every instruction
cycle. Bit 7 of R remains the same value as from the last LD R,A
instruction.
The flags register is manipulated as specified. Unoffical flag effects, such
as bit 5 following bit 5 of an arithmetic result, are not implemented.
Environment
-----------
Z80Tube$Basic
The *BASIC command tries to load and enter a BASIC interpeter. If
Z80Tube$Basic points to a file, it will be loaded to &0100 and entered
there. If not, the *BASIC command has no effect.
Escape/Break/etc.
When building for Windows the Interupt character cannot be changed from
CHR$3, so it is disabled instead, and Ctrl-Break is used to generate an
Escape state. CHR$27 will generate an Escape state when read with GET or
INKEY unless disabled with *FX229,1.
When building for UNIX or RISC OS the Escape character is set to CHR$27.
Extras
------
The files directory contains a few useful extra and/or essential items:
BBCBasic BBC BASIC for Z80.
ClockSp BBC BASIC benchmark program that determines the speed of the
interpreter relative to the original BBC B. Running on an A5000
Z80Tube reports a speed of 2.48MHz. A test on a 900MHz Pentium
PC reports a speed of 77MHz. A real Z80 CoProcessor reports a
speed of 2.68MHz.
KBDTest Display keyboard keypress values.
KeyScan Display keyscan values.
KeyTest Graphically display keyscan values.
MOS Default MOS interface code.
Version History
---------------
v0.25 07-Sep-2003
v0.26 31-Aug-2004 Dave Daniels added OSWORD &7F and OSWORD &FF for CPM support.
CPI/CPD/LDI/LDD sets P/V flags correctly. I/O memory
declarations moved to main.c
v0.27 31-Dec-2018 Updated console module, supports ANSI I/O, added *FX command,
updated unix and DOS tty control.
v0.28 31-Jan-2019 Added OSBYTEs to support CP/M, corrected disk error numbers.
About
Z80Tube Emulator written in portable C
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published