This document describes only the features of the old version yaze-1.00.
But read this document because the features which are described here are
also the features of the new yaze-ag-2.20 (this version).

If you want to read about the new features of yaze-ag-2.20 use yaze-ag.doc.


Yet Another Z80 Emulator (yaze-1.00) ==================================== Contents ======== 1. Introduction 2. Installation and Testing 3. Command-line options 4. Bootstrap file formats 5. Creating bootstrap files 6. CP/M disks 7. Benchmarks 8. Emulating embedded systems 9. Software sources 10. Why?   1. Introduction ================ The README file gives a brief overview of what yaze is and why you might want to install it. This package assumes you have a unix system and that a number of common tools are available on it.   2. Installation and Testing (yaze-1.00) ======================================== First you need to uncompress and untar the archive file, which you have probably already done if you are reading this. Go to the directory under which you want yaze to be unpacked, e.g. /usr/local/src. Then, if you have gnu-tar, type 'tar xzf yaze-1.00.tar.gz' and otherwise 'zcat yaze-1.00.tar.gz | tar xf -'. Change to the newly created directory yaze-1.00 and edit the Makefile. If GNU Readline is available on your system you will probably want to use it with yaze. Readline comes together with most interactive programs from the Free Software Foundation, such as gdb and bash. It permits command-line editing, history recall and (unix-) filename completion when used with yaze and cdm. The include files and library should be somewhere where your compiler can find them, otherwise you will have to add the paths to the Makefile. When you have customized the Makefile, try 'make'. Yaze was developed under SunOS5 and I have briefly tried it under Linux and FreeBSD. You will have to do some hacking if your system does not support the termios tty interface. You will have to do a lot of hacking if your system does not have memory mapped files via mmap() and munmap(). Once you have a clean make of yaze you can try it out. WARNING! Yaze disables all tty interrupts by default, so if you only have 1 terminal session available it may be difficult to regain control if yaze goes haywire. You may want to add the line 'interrupt ^C' (or some other character) to .yazerc to be safe (though you cannot use that character under CP/M then). Under X11 or screen this is not a problem because you can kill a runaway process from a different window. The normal way to leave yaze is to type 'sys quit' at the CP/M A> prompt. Start yaze by typing 'yaze -v'. This will use the defaults and give a verbose account of the system configuration. --------------------------------------------------------------------------- $ yaze -v Yet Another Z80 Emulator version 1.00, Copyright 1995 Frank D. Cringle. yaze comes with ABSOLUTELY NO WARRANTY; for details see the file "COPYING" in the distribution directory. Running 'yaze.boot' bootfile: /usr/local/lib/yaze.boot startup file: .yazerc basepage: d8 ccp_base: d800 bdos_base: e000 bios_base: ee00 bios_top: ee66 dptable: fd90 dirbuf: ff80 A> --------------------------------------------------------------------------- This shows the default values of various parameters which can be overridden on the command line. The bootfile will be described in more detail later. The basepage is where the CP/M ccp is placed, and the other addresses follow from that. The ccp is 800h bytes long and the bdos is 0e00h long. The bios occupies only 66h bytes in the Z80 ram, because all we need is the jump table for 17 vectors and the targets for these jumps to transfer control to the real bios executing on the host cpu. The space between bios_top and dptable is available for disk allocation vectors. Dptable has space for the maximum possible 16 disk parameter headers and disk parameter blocks. The dirbuf is shared between all disks as in standard CP/M. Yaze reads the file .yazerc when it starts up and the distributed .yazerc contains: mount a test go The first line mounts the unix directory 'test' as CP/M drive A and the second line starts the emulator. Commands such as 'mount' and 'go' can also be entered interactively when the emulator is in monitor mode. It starts out in monitor mode (unless the command line or startup file contain 'go'), and you can get back to monitor mode by executing the CP/M command 'sys'. This command is found in the file sys.com in the test directory. It is difficult to get out of the emulator if you do not keep a copy of sys.com accessible on a mounted disk. If you execute 'sys' without arguments it takes you into monitor mode, which is indicated by the $> prompt. Here a number of commands are available, including a help command. --------------------------------------------------------------------------- A>sys $>help help Display this text or give help about a command ? Synonym for `help' attach Attach CP/M device to a unix file detach Detach CP/M device from file mount Mount a unix file or directory as a CP/M disk umount Unmount a CP/M disk create Create a new disk interrupt Set user interrupt key go Start/Continue CP/M execution ! Execute a unix command quit Terminate yaze time Display elapsed time since last `time' command $> --------------------------------------------------------------------------- More information about each command is available by entering 'help command'. --------------------------------------------------------------------------- $>help help help <cmd> displays more information about <cmd> $>help attach attach without arguments lists the current attachments attach <physdev> <file> attaches <physdev> to the unix <file>, where <physdev> is one of ttyin, ttyout, crtin, crtout, uc1in, uc1out, rdr, ur1, ur2, pun, up1, up2, lpt, ul1 $>help detach detach <physdev> closes the file attached to <physdev> (see attach) $>help mount mount without arguments lists the mount table mount -v lists the mount table verbosely mount <drive> <file> mounts <file> as CP/M disk <drive> (a letter from a..p). If <file> is a plain file it must contain a CP/M filesystem. If <file> is a unix directory its contents may be accessed as a read-only CP/M disk mount -r <drive> <file> mounts the <file> read/only. $>help umount umount <drive> closes the file associated with <drive> and frees the resources $>help create create {flags} <file> {size} creates a unix <file> initialized as a CP/M disk of size {size} (default 1MB). -b <block size> default 1024 if size < 256K, else 2048 -d <# dir entries - 1> default 1023 -o <track offset> default 0 -s <sectors per track> default 26 create <file> 256256 create a raw SSSD disk image $>help interrupt interrupt <key> makes <key> interrupt CP/M back to the monitor <key> may be a 2-digit hex number or ^x where x is one of a..z[\]^_ ^@ makes CP/M uninterruptible (from the keyboard) interrupt without an argument displays the current setting $>help go Start/Continue CP/M execution $>help ! ! escape to a unix shell !cmd execute unix cmd $>help quit Terminate yaze $>help time displays elapsed, user and system time in seconds, along with simulator options --------------------------------------------------------------------------- Monitor commands can be abbreviated (e.g. 'm' for 'mount'), except 'quit' must by typed in full. The yaze-1.00/test directory contains a number of .com files (CP/M executables). The quickest way to test the installation is to execute prelim.com --------------------------------------------------------------------------- A>dir PRELIM .Z80 | ZEXLAX .PL | ZEXALL .Z80 | ZEXDOC .Z80 PRELIM .COM | ZEXALL .COM | ZEXDOC .COM | SAVAGE .PAS SAVAGE .COM | SYS .AZM | SYS .COM A>prelim Preliminary tests complete A> --------------------------------------------------------------------------- Zexall.com and zexdoc.com are both derived from zexlax.pl. They are designed to exhaustively compare Z80 implementations. This is done by executing all practicable instructions for as wide a range of operands as feasible, and calculating a 32-bit crc of the resulting machine states. If the crc values of two implementations match we can be confident that they are, for practical purposes, identical. Zexall and zexdoc differ only in that zexall tests all 8 bits in the flag register for all instruction whereas zexdoc only tests the documented flag values. The expected crc values are those produced by a Mostek MK3880-4 CPU, date code 8010, and confirmed on an Epson PX-8. Zexall and zexdoc run about 3.25 hours each on a 4MHz Z80. Savage.com is a simple benchmark compiled from savage.pas with Pascal/MT+. Its execution time depends almost exclusively on the quality of the run-time library. Also, Pascal/MT+ only uses 8080 instructions, so it does not say anything about the speed of Z80 extensions. 'make install' puts the binaries in BINDIR (default: /usr/local/bin), the manual pages in MANDIR (default: /usr/local/man/man1) and the bootstrap file in LIBDIR (default: /usr/local/lib).   3. Command-line options ======================== New command line options for yaze-ag-2.20 are described in yaze-ag.doc chapter 5. Usage: yaze {flags} {commands} -b <file> boot from this file -l <xxxx> load bootfile at given (hex) address -p <xx> base page (top 2 hex digits of ccp base) -s <file> startup file -v verbose -z <xxxx> (hex) address of z3env (if desired) If yaze is run without command-line options it loads the bootstrap file from /usr/local/lib/yaze.boot or, if that does not exist, from ./yaze.boot to address 0d800h and relocates the contents to fit that base address. It then looks for a "run control" file .yazerc in the current directory or, if not found there, $(HOME)/.yazerc. If an rc-file is found it is expected to contain a list of monitor commands, typically mount, attach and go, and these commands are executed. Finally, any remaining values on the command line are also interpreted as monitor commands and executed. If a "go" command was seen in the rc-file or on the command line the emulator is started, otherwise control is passed to the monitor. A different bootstrap file can be specified on the command line with the -b option. The base page (top 2 hex digits of the ccp location) can be specified with the -p option. The bootstrap file can be loaded at an address other than the base page with the -l option. The required contents of bootstrap files are explained in the next section. A different startup file from .yazerc can be specified with the -s option. Space (1 Kbyte) can be reserved for a Z-system environment at an address given by the -z flag. The -v flag produces a configuration summary. Any monitor commands on the command line must be quoted if they are more than one word. Example: yaze "mount b foo" "attach lpt print.out"   4. Bootstrap file formats ========================== A bootstrap file contains the Z80 machine code that is executed when the emulator starts. Yaze accepts 3 types of bootstrap file: a) arbitrary code that is loaded to a specified address and executed, b) a single (non-relocatable) copy of CCP+BDOS that is loaded to the CCP base address and started via the BIOS cold boot entry-point and, c) a double (and thus relocatable) copy of the CCP+BDOS that is loaded to the CCP base and if necessary suitably relocated before being started via the BIOS cold boot entry-point. An address given via the -l parameter on the command line indicates the first type of file. It might be a bootstrap loader which contains a clone CP/M for which extra environment data must be set up before jumping to the BIOS cold boot routine. Control is passed to the bootstrap at the address to which it was loaded, with the desired CCP base address in register HL. If no -l parameter is present on the command line the size of the boot file is used to differentiate cases b and c, and subcases. The CCP and BDOS might have been assembled from source to run at a fixed address, in which case the file should be 5632 bytes long (1600h). Alternatively, the file might have been saved after executing movcpm on a real CP/M 2.2 system. In this case it will be between 7808 and 11263 long and CCP will found at offset 880h in the file. If the input file is twice the length of CCP+BDOS, i.e. 11264 bytes long, it is assumed to contain 2 copies of the same source, assembled to run at different 1K boundaries. It does not matter what the addresses actually are, yaze takes one copy and adjusts the addresses (any bytes that differ between the 2 copies are assumed to be the high byte of an address) to fit the final location. Similarly, if the input file is longer than 17407 it is assumed to contain 2 CP/M 2.2 saves after movcpm with different system sizes.   5. Creating bootstrap files ============================ The bootstrap file distributed with yaze, yaze.boot, is a 2-copy file containing Don Kirkpatrick et al's D&J ZCPR as CCP and SUPRBDOS by Herman ten Brugge and Benjamin Ho as BDOS. These programs claim to be freely redistributable. They are both on the Walnut Creek CP/M CDROM and are also in the oak archives. I assembled both programs twice, once with P2DOS (the BDOS base address) set to 0C800H and once with it set to 0CC00H. The resulting hex files were loaded with mload and concatenated together, making sure to pad the lengths of the individual components to 800H/0E00H. I added an instruction to strip the high bit from console output characters in SUPRBDOS, because I do not think this should be done in the BIOS - a debatable position because DR's documentation is inconclusive on the issue and the original BDOS does not strip the bit. I also disabled the "delay 256 characters" feature in SUPRBDOS, because it was interfering with benchmarking when running yaze with input redirection. An easy way to make a boot file on a real CP/M system is: B>movcpm 64 * CONSTRUCTING 64k CP/M vers 2.2 READY FOR "SYSGEN" OR "SAVE 34 CPM64.COM" B>save 34 a:cpm64.com Then transfer cpm64.com as a binary file to your unix system and yaze -b cm64.com Yet Another Z80 Emulator version 1.00, Copyright 1995 Frank D. Cringle. yaze comes with ABSOLUTELY NO WARRANTY; for details see the file "COPYING" in the distribution directory. Running 'cpm64.com' A> This works because the default basepage is 0E4H and the CCP is located at 0E400H in a 64K CP/M system. You must take this into account when using other system sizes, e.g. yaze -b cpm63.com -p e0   6. CP/M disks ============== CP/M version 1.4 used single-sided single-density 8" floppy disks with 77 tracks of 26 128 byte sectors each. This format and the arrangement of data within it remained the standard distribution format for CP/M 2.2, but other formats were now also supported. This had advantages and disadvantages. Double density, double sided disks, hard disks, other floppy sizes etc. could be used, but there was no standard method of determining what the format of a particular disk was. Tables had to be built into the BIOS which matched the disk in question. Yaze does not attempt to access CP/M disks directly. It assumes that it is accessing a unix file containing a copy of a CP/M disk. The file can contain either a raw copy of a standard single-sided single-density disk (with sector skew = 6), or a de-skewed copy of any format with a descriptive header. The header is recognized when the file starts with the string "<CPM_Disk>" (a sort of "magic number"). The disk header occupies the first 128 bytes of the file and has the format: 0 - 9 <CPM_Disk> 10 - 31 a null-terminated ascii comment (may be empty) 32 - 33 sectors per track 34 block shift factor 35 block mask 36 extent mask 37 - 38 disk size max 39 - 40 directory max 41 al0 42 al1 43 - 44 check size (always zero) 45 - 46 track offset 47 - 127 unused (zeros) CP/M aficionados will recognize bytes 32 - 46 as a copy of the disk parameter block. 2-byte values are stored little-endian (low-byte first). The check size is set to zero because yaze does not allocate space for a check vector when mounting a disk. Instead sys.com resets the disk system whenever control is returned from the monitor to CP/M, in case a disk was unmounted or remounted. It is the responsibility of the user not to mess with disks from a different process, at least not without executing sys.com (or diskrst.com) before resuming a running yaze session. The raw contents of the disk follow the header. The sectors must be arranged sequentially, i.e. any sector skew must be removed when copying a real disk into a <CPM_Disk> file, because yaze sets the sector translation table address to zero in the disk parameter header. If the file does not begin with "<CPM_Disk>" and is exactly 256256 bytes long (77*26*128), it is assumed to be an exact copy of a SSSD disk. Empty disks can be created by the yaze monitor and by cdm. When a disk is created only the directory and the last sector of the disk are actually written out. This has the advantage that unallocated data does not occupy space in the unix file system. For example, if we create an 8MByte disk (the maximum size supported by standard CP/M-2.2), we can see that it only occupies 56KBytes of physical disk space. A>sys $>create disk 8m $>mount b disk $>mount -v A: r/o test/ dph=FD90, xlt=0000, dirbuf=FF80, dpb=FDA0, csv=0000, alv=FA66, spt=0100 bsh=05, blm=1F, exm=01, dsm=0100, drm=07EF, al=FFFF, cks=0000, off=0000 B: r/w disk dph=FDAF, xlt=0000, dirbuf=FF80, dpb=FDBF, csv=0000, alv=FA87, spt=001A bsh=04, blm=0F, exm=00, dsm=0FFF, drm=03FF, al=FFFF, cks=0000, off=0000 $>quit % du -sk disk 56 disk % ls -sl disk 112 -rw-rw-r-- 1 fdc grp 8388736 Oct 9 21:32 disk A disadvantage of this method is that if the unix filesystem becomes full or the user's disk quota is exceeded when yaze tries to write data into a not-yet allocated part of the file, the process will be aborted with a SIGSEGV. It might be possible to extend yaze with a signal handler and longjmp to cover this case, but that is not in version 1.00. There is no specific support in this package for transferring data from existing CP/M disks into a form suitable for use with yaze. It is highly dependent on the available hardware and interfacing possibilities. If the individual files from the disk can be got into a unix directory (maybe via serial transfer with kermit or x/y/zmodem), that directory can be mounted by yaze as a read-only pseudo disk and its contents used from there or copied into a <CPM_Disk> file. If direct access to a floppy drive is available it is probably best to write a small program to transfer the contents with a header prepended and the sectors deskewed. With luck it may be possible to use dd to copy the disk into a file. Then generate a <CPM_Disk> of the same format with yaze or cdm, chop the unused data part with tail(1) and cat(1) the disk's data onto it.   7. Benchmarks ============== SAVAGE.COM yaze/50MHz supersparc: 11.6 secs (~ 22.4 MHz) 4.0MHz Z80: 65 secs 2.5MHz Z80 (PX-8): 105 secs (~ 2.48MHz) ZEXALL.COM yaze/50MHz supersparc: 1855 secs (~ 25.2 MHz) 4.0MHz Z80: 11688 secs 2.5MHz Z80 (PX-8): 19114 secs (~ 2.45MHz)   8. Emulating embedded systems ============================== The talk up to here has been of using yaze to run CP/M. If you want to use it to emulate some other system you will have to add that system's interaction with the outsize world to the source code. The instruction set emulator is in simz80.c. I tried to make all references to memory and I/O ports via the macros that are defined in simz80.h. These could be modified or replaced by function calls to reflect the behaviour of a particular embedded system. If the target system uses interrupts, that logic would have to be added from scratch.   9. Software sources ==================== (/cdrom/cpm_cdrom is the path to the Walnut Creek CP/M CDROM on my system). SUPRDOS from /cdrom/cpm_cdrom/cpm/bdos/suprdos2.lbr (length = 90112) ZCPR from /cdrom/cpm_cdrom/demon/zcpr-d-j.com (length = 32896) (same as ftp.demon.co.uk:/pub/cpm/zcpr-d&j.com)   10. Why? ======== Here are answers to some questions that I would probably be asking if I were reading this. Q. Why did you base this on CPM-2.2 rather than CPM-3? A. I do not have access to a CPM-3 system, so I could not have tested the implementation. Q. Why did you write it all from scratch, rather than starting with one of the other free emulators? A. "Not invented here", I guess. Starting from scratch meant that I could do what I liked with the code, including putting it under the GPL, without consulting others. Also, I have been messing with this for years on and off. I was not aware of other emulators when I started. Q. Why didn't you rewrite CCP and BDOS in C and let them run on the host cpu? A. That was the original plan, particularly while I thought there was no free bdos available. Partly because I want to finally get this stuff out of the door and partly because it is a lot of work to do right, I have left it for now. Q. Why no built-in debugger? A. My main aims were emulation accuracy and speed. As it is, you can run a CP/M debugger like zsid or z8e in the emulator. If that is not enough, you can run yaze under gdb or put hooks in the yaze source to analyse particularly tricky cases. Q. What's all this perl stuff? A. I make no apology for using perl as a super-macro-processor to generate simz80.c and zexall.z80 / zexdoc.z80. You do not need perl to install yaze, because the output files are provided, but you will need it if you want to experiment. Simz80.pl includes 5 booleans which define how simz80.c is structured - see the source for more documentation. A good way to chew up machine cycles is to generate all 32 possible variants and benchmark them by running zexall.com. Zexlax.pl fills in pseudo-random initial states in the test cases. Be careful if you change anything - you will have to run the new version on a reference Z80 to find the expected CRC values.
If you want to read about the new features of yaze-ag-2.20 use yaze-ag.doc.