tnylpo(1) General Commands Manual tnylpo(1) NAME tnylpo - a utility to run programs written for CP/M-80 SYNOPSIS tnylpo [-abnrsw] [-c (<n> | @)] [-d <drive>] [-e [h][ b<bytes> | p<pages> | r<addr>-<addr> ] :<file> ] [-f <config-file>] [-l (<n> | @)] [-o(n|y|[y,] <fg>,<bg> )] [-t (<n> | @)] [-v <level>] [-y (n | <count>,<nanoseconds>)] [-z{a|e|i|n|s|x}] <command> [<arg> ...] tnylpo -h DESCRIPTION tnylpo allows the execution of programs written for the CP/M-80 operating system in a Unix environment. To accomplish this task, tnylpo combines an emulation of the Zilog Z80 eight-bit CPU with a software layer translating calls to the CP/M application programming interface (the BDOS and BIOS calls of CP/M-80 version 2.2 plus a few BDOS calls of CP/M 3) to Unix li- brary and system calls. tnylpo doesn't even try to re-create the look-and-feel of the CP/M-80 oper- ating system by emulating its Console Command Processor (CCP) or providing implementations of utility programs like PIP or STAT; in fact, its aim is to integrate CP/M-80 applications and compilers as much as possible into the Unix command line interface to allow their use in combination with the much more capable utilities and editors of the host operating system; tnylpo users are supposed to use cp(1) and dd(1) instead of PIP, chmod(1), df(1), and ls(1) instead of STAT, and shell scripts, here-documents, and redirections instead of SUBMIT and XSUB. Files in the CP/M environment are directly mapped to Unix files; while this comes at the cost of some minor incompatibilities with CP/M-80 (see below under NOTES), it vastly simplifies the interaction between CP/M and Unix programs compared to the alternative approach of using disk images. Thanks to its system call translation layer, tnylpo neither contains any code from the CP/M operating system nor needs any additional software apart from the actual applications it is meant to run. Since CP/M-80 programs can use eight-bit characters at best (many of them even share the firm belief of CP/M in a seven-bit ASCII world), another translation layer mediates between the internal one-byte-per-character text representation and the almost universal multibyte character (most commonly UTF-8 based) approach of contemporary Unix systems. This translation layer affects the character orientated I/O channels of CP/M only and may be dis- abled for the printer, punch, and reader devices. All screen-orientated CP/M-80 programs are unable to cope with the ability of graphical user interfaces to resize text windows (in fact, even the ability of the DEC VT100 to switch between 80 and 132 column mode overtaxes them); to alleviate this problem (and to provide the capability of running the same CP/M application on different terminal emulations or on serial terminals without reconfiguring the CP/M binaries), tnylpo includes a curses based emulation of the DEC VT52 terminal (with certain extensions in functionality) for use as CP/M console device. tnylpo gives the user the choice between this terminal emulation and a line orientated console device more suitable for programs like assemblers and compilers. True to its aim of allowing the integration of CP/M programs into the Unix environment, tnylpo happily does away with certain non-essential, rarely used, or extremely un-Unixy features of CP/M-80 (some of which --to be frank-- would be disproportionately hard to implement or integrate under Unix), among them user areas, the rudimentary character device redirection implemented by the I/O byte, file attributes, and the printer echo. Whereever some functionality has been left out, care has been taken not to offend CP/M programs unduly (programs may e.g. set the user area, and on query tnylpo will report the current value back to them, but will ignore it otherwise). As a rule, tnylpo or Unix offer better solutions to replace the omitted CP/M features, e.g. different tnylpo configurations (and drives/di- rectories) for different applications or users (user areas), shell output redirection (I/O byte), chmod(1) (file attributes), or script(1) (console protocol). CPU emulation tnylpo strives to provide a full implementation of both documented and un- documented features of the Z80 CPU; undocumented instructions and side ef- fects are supported to the best of the author's knowledge. I/O instructions are available, but are dummies; writing to I/O ports has no direct effect, and reading them always returns a null byte. Same is true for all interrupt related instructions (while the I register may be set and read and the EI and DI instructions have the expected side effects, no interrupt will ever occur). Executing a HALT instruction will end pro- gram execution (and thereby the execution of tnylpo) and is considered an error situation (see below under Program termination). Well-behaved CP/M applications should never use any of these instructions anyway. Note that the behaviour of the HALT instruction has changed from earlier versions of tnylpo, where it was simply ignored (resp. acted as if a NMI had been received immediately after entering the halt state). This change allows unused memory areas to be initialized with HALT instructions, which increases the chances of detecting and stopping a runaway application pro- gram early. The R register will be increased as expected; since application programs may use the current value of the R register for the generation of random numbers (the Randomize procedure of Turbo Pascal seems to do this), the R register is initialized with a random value (otherwise, repeated runs of the same program would always generate the same sequence of random num- bers). At the start of program execution, all unused memory (i.e. the part of the TPA not occupied by the loaded executable as well as the unused parts of the zero page and the BIOS area) are initialized with the byte value 0x76 (the HALT instruction). All registers apart from PC, SP, and R are set to zero, PC is set to 0x100, and SP points to a stack area at the top of the TPA. File name translation In translating CP/M disk operations to Unix disk operations, tnylpo has to translate CP/M file names to Unix file names and vice versa; since CP/M de facto allows almost arbitrary seven-bit characters in its file names (in- cluding null bytes and slashes), and Unix file names are not bound to the 8+3 character restriction of CP/M, tnylpo enforces a common subset: only decimal digits, the 26 letters of the alphabet, the minus (-), at (@), dol- lar ($), and hash (#) signs are allowed in file names, which are restricted to one to eight characters in length. The name may have an extension of up to three characters from the same set; the dot between name and extension may only be present if there is at least one extension character. On the Unix side, all letters appear in lower case, while tnylpo accepts (and re- turns) only upper case letters in CP/M FCBs. Unix files with names contain- ing upper case letters or otherwise not conforming to tnylpo's restrictions are not accessible to CP/M programs. (Dollar signs in Unix file names are a nuisance in shell scripts, but since they are habitually used in CP/M tem- porary file names, tnylpo could not forbid them; fortunately, CP/M programs creating files with file names containing dollar signs usually remove them before exiting.) OPTIONS Many of tnylpo's command line options have corresponding entries in the configuration file, so they will be discussed in this context below (see Configuration options). Four options have no counterparts: -a selects the alternate character set from the configuration file be- fore starting execution (see Character sets). -e [h][b<bytes>|p<pages>|r[<addr>]-<addr>]:<filename> causes tnylpo to write (parts of) the CP/M memory to the specified file after program termination (see Saving a memory image). -f <config-file> tells tnylpo to read its configuration from the named file. -h asks tnylpo to show a short command line synopsis (-h cannot be used in combination with any other command line option). Command line arguments tnylpo interprets its first positional command line argument as the name of the CP/M program (.com file) it is supposed to execute. If this argument contains a slash (/), it is interpreted as a Unix path name, otherwise it is treated as a CP/M file name, i.e. it may be prefixed by a drive specifi- cation and is interpreted as relative to the path corresponding to this drive or the default drive according to tnylpo's configuration (see below). In both cases, the suffix .com is appended if the file name does not al- ready end in .com. All further positional arguments are passed as command line arguments to the CP/M program (i.e. they are converted to upper case and copied to the default DMA area at 0x0080; additionally, the default FCB at 0x005c is ini- tialized according to the second and third positional arguments). Configuration files While some features of tnylpo can be controlled by command line options, the most convenient way to configure it is by using a configuration file; if a configuration file is explicitly specified on the command line (option -f), it will be used; otherwise, tnylpo looks for a file named .tnylpo.conf in the current working directory. If none is found, tnylpo looks for .tnylpo.conf in the user's home directory. As a last resort, tnylpo uses its built-in defaults. If conflicting options are specified in the configu- ration file and on the command line, the command line takes precedence. A tnylpo configuration file is a regular text file; empty lines and lines starting with a hash sign (#) or a semicolon (;) are ignored. All other lines have the form <keyword> [<token> ...] = <token> [<token> ...] <token> is either a keyword (a sequence of alphanumeric characters starting with a letter), a number (hexadecimal, octal or decimal using the usual Unix convention of being prefixed by 0x, 0, resp. some other digit), a string in double quotes, or a comma. Configuration options drive <drive letter> = [readonly ,] <path> Up to 16 drives can be defined by repeated use of this configuration option; <drive letter> is a single lower case letter in the range a-p, and <path> is a string containing the name of a directory on the host computer system. CP/M programs trying to create or access a file on the corresponding disk drive will create or access a file in this directory. Only regular files up to 8MB in size with names corresponding to tnylpo's idea of well-behaved file names suitable for both CP/M and Unix (see above) are visible to CP/M programs. If <path> is preceeded by the optional keyword readonly, programs run- ning on tnylpo will not be able to create new files on this drive or rename, delete, or modify existing files (any attempt to modify a read-only drive will terminate the offending CP/M program). There is no corresponding command line option. If no drive has been defined in the configuration file (or if there is no configuration file), tnylpo will use drive a = "." as default, i.e. the current working directory will be made avail- able as CP/M drive A. default drive = <drive letter> command line option -d <drive letter> define the drive identified by <drive letter> (a single lower case letter in the range a-p) as default drive, i.e. the drive all file specifications not including an explicit drive name refer to. This drive must be assigned to a host system directory, either implicitly or by the drive configuration option. If default drive is not speci- fied, tnylpo assumes drive A as default drive. close files = (true | false) command line option -n If close files is set to false (or if the -n command line option is present), files closed by the CP/M program are kept open by tnylpo, i.e. the corresponding FCBs are not invalidated. This is required by some CP/M programs (see File closing), but should be avoided if pos- sible, since otherwise tnylpo might run out of file descriptors. By default, tnylpo actually closes files closed by the CP/M program. logfile = <path> <path> is a quoted string containing the path of a file to which tnylpo appends error messages and other logging information (fatal error messages are also written to stderr). If the logfile configu- ration option is not used, no logging information will be written. There is no corresponding command line option. loglevel = <level> command line option -v <level> The amount of data written to the logfile is controlled by the loglevel configuration option resp. its command line equivalent -v. Both take a numeric argument; the higher the number, the more infor- mation is written (causing the emulation to run progressively slower). Valid log levels are: 0 write error messages only. 1 additionally, count the machine instructions executed by the emulator; at program termination, tnylpo will output tables showing which instructions have been executed how often. 2 additionally, trace FDOS functions (i.e. BDOS functions re- lated to file I/O). 3 additionally, dump FCBs for FDOS functions using a FCB. 4 additionally, dump file records read and written by the FDOS functions. 5 additionally, trace all other system calls (BDOS and BIOS functions); since all character I/O functions are traced, this will produce a lot of output. The logging facility is a leftover from the development and testing of tnylpo itself; since it may provide important clues if applica- tions do not work as expected, it has been retained. console = (full | line) command line options -s or -b tell tnylpo to use the full screen VT52 emulation (full, -s) or the line orientated (line, -b) console interface. Some other configura- tion options, e.g. lines, columns, application cursor, and screen delay are only effective in the full screen mode. By default, tnylpo uses the line orientated console interface. screen delay = (<number> | key) command line option -t (<number> | @) define the number of seconds tnylpo should wait between program ter- mination and resetting the display. If key (resp. @) is specified, tnylpo waits for a key being pressed before exiting the VT52 emula- tion. This option allows the user to see the final display of the CP/M application even if resetting the display restores the original screen contents or clears the screen. Default value is 0 (don't wait). lines = (<number> | current) columns = (<number> | current) command line options -l (<number> | @) and -c (<number> | @) define the display size used by the terminal emulation; the number of lines must be between 5 and 95, the number of columns between 20 and 95. Using the keyword current (resp. @ in case of the command line options) tells tnylpo to use the current size of the display device. If no display size is specified in the configuration file or on the command line, tnylpo defaults to 24 lines of 80 columns. application cursor = (true | false) command line option -w If application cursor is set to true (or the command line option -w is present), pressing the cursor keys up, left, right, or down will send the control characters ^E (0x05), ^S (0x13), ^D (0x04), or ^X (0x18) to the running CP/M program (i.e. the appropriate cursor mo- tion commands for programs like WordStar or Turbo Pascal). Other- wise, the cursor keys will generate the default VT52 escape se- quences, <esc> A, <esc> D, <esc> C, and <esc> B. This option is only effective in full screen console mode. exchange delete = (true | false) command line option -r If exchange delete is set to true (or the command line option -r is present), the backspace (^H, 0x08) key and the delete (0x7f) key are reversed in full screen mode. [alt] char <number> = <string> [alt] charset = (ascii | vt52 | latin1 | tnylpo) unprintable = <string> serve to define the primary and alternate character sets used by tnylpo; they have no corresponding command line options and are ex- plained below (see Character sets). (printer | punch | reader) file = <path> (printer | punch | reader) mode = (text | raw) define the path and the format of the data files representing the CP/M character I/O devices LST:, PUN:, and RDR:; there are no corre- sponding command line options. Details are explained below (see Character devices). colors = ( false | true ) [ , <fg> , <bg> ] command line options -on, -oy, -oy,<fg>,<bg> and -o<fg>,<bg> switch color support on or off in full screen mode; optionally, the default foreground and background colors (digits in the range from 0 to 7) may be selected (see Color support). cpu delay = <count> , <nanoseconds> command line options -yn and -y<count>,<nanoseconds> slow down the emulation by adding a delay (specified by <nanosec- onds>) after every <count> instructions executed by the emulated CPU. The command line option -yn disables this delay, overriding a delay specified in the configuration file. Slowing the emulation al- lows using software (e.g. interactive games) which would otherwise run much too fast on tnylpo; another application is reducing the high load tnylpo puts on the host CPU. Useful values for <count> and <nanoseconds> depend on the speed of the host CPU, on the host operating system, and on the particular application program; they need to be determined by experimentation. Please bear in mind that the minimal useful delay (i.e. the minimal value for <nanoseconds>) depends on the host operating system and may be as large as several milliseconds; since smaller delays may be rounded up to that minimum implicitly, specifying e.g. -y1,1 may give unexpected results. dump = none dump = all dump = (startup | exit | error | signal) [, ...] command line options -zn, -za, and -z{s|x|e|i} define if and when tnylpo writes a machine dump (including register values and the contents of main memory) to the log file. The key- words startup, exit, error, and signal (resp. the suboptions s, x, e, and i) request a dump at program startup (immediately before passing control to the CP/M command), at program exit, at program exit due to a fatal execution error, or at the receipt of a SIGUSR1 signal and may be arbitrarily combined (only exit and error are mu- tually exclusive). dump = all (resp. -za) is a shorthand for dump = startup, exit, signal (resp. -zsxi), and dump = none (resp. -zn) turns all dumps off (this is also the default setting). Dumps are only written if a log file has been defined by the configuration op- tion logfile. Terminal emulation tnylpo provides a curses based emulation of the DEC VT52 terminal, which can be used instead of the default line orientated console to accommodate full-screen applications; this terminal emulation is selected by the com- mand line option -s resp. by the entry console = full in the configuration file. tnylpo's terminal emulation mimicks the VT52 fairly accurately, but offers a number of extensions, among them the ability to support screen sizes of up to 95 by 95 characters (this limitation is due to the limitations of the VT52 direct cursor positioning command), eight-bit operation, a dynamically switchable alternate character set, insert and delete line commands, and bold, underlined, inverted, and blinking (i.e. everybody's favourite) char- acter rendition. To protect the CP/M application (resp. its user) from the effects of screen resizing, the terminal emulation provides a fixed size screen area (typically 80 columns by 24 lines, but this may be changed by command line or configuration file options) within the actual display (a terminal emulator like xterm(1) or the screen of an actual serial termi- nal). If the display device/window is larger than this area, there will be blank margins to the right and below the VT52 display area; if it is smaller, parts of the output from the emulator will be invisible to the user, but will (re-)appear as soon as the window is enlarged. The terminal emulation (like the VT52) does not do an automatic line wrap (i.e. the cursor will not move to the first column of the next line if a character is displayed in the last column of a line) and supports (or at least tolerates) all of the VT52 control sequences: <bel> (0x07) gives an accustic (or visual) signal. <bs> (0x08) moves the cursor left, but stops at column 1. <tab> (0x09) moves the cursor to the next tabulator stop if it is before the last tabulator stop on the current line (tabulator stops are at columns 9, 17, 25, ...); otherwise, it moves the cursor one column to the right (resp. does nothing if the cursor is already in the last col- umn). <lf> (0x0a) moves the cursor down one line and scrolls up on bottom line. <cr> (0x0d) moves the cursor to the first column of the current line. <esc> (0x1b) marks the start of an escape sequence (see below). All other characters in the ASCII control character range (0x00-0x1f, 0x7f) are ignored. The VT52 escape sequences are: <esc> ) (0x1b 0x29) and <esc> = (0x1b 0x3d) switch the keypad to application resp. to regular (numeric) mode (no effect in tnylpo). <esc> A (0x1b 0x41) moves the cursor up one line, but stops at the top line. <esc> B (0x1b 0x42) moves the cursor down one line, but stops at the bottom line. <esc> C (0x1b 0x43) moves the cursor right one column, but stops at the last column. <esc> D (0x1b 0x44) moves the cursor left one column, but stops at the first column. <esc> F (0x1b 0x46) and <esc> G (0x1b 0x47) display character codes 0x5e-0x7e as graphical resp. as ASCII char- acters (see below). <esc> H (0x1b 0x48) moves the cursor to the left top corner of the display. <esc> I (0x1b 0x49) moves the cursor up one line and scrolls down at the first line. <esc> J (0x1b 0x4a) clears the display from the current cursor position to the end of the screen. <esc> K (0x1b 0x4b) clears the display from the current cursor position to the end of the line. <esc> Y <line> <column> (0x1b 0x59 0xYY 0xXX) moves the cursor to the specified position on the display; line and column numbers are given as graphical characters in the range of 0x20 (position 1) to 0x7e (position 95). If the column number is larger than the display width, the horizontal position is not changed; a line number larger than the height of the display moves the cursor to the last line. <esc> Z (0x1b 0x5a) identifies the terminal type; the terminal emulation responds by sending the sequence <esc> / K (0x1b 0x2f 0x4b), i.e. it identifies itself as VT52 without hardcopy device. <esc> [ (0x1b 0x5b) and <esc> \ (0x1b 0x5c) enter resp. exit "hold screen" mode (see below). In addition, the terminal emulation in tnylpo supports the following exten- sions to the VT52 escape sequences: <esc> E (0x1b 0x45) clears the display, moves the cursor to the top left corner of the display. <esc> L (0x1b 0x4c) inserts a blank line at the cursor position and moves lines below down one line (the last line is lost). <esc> M (0x1b 0x4d) deletes the line at the cursor position and moves lines below up one line (an empty line will appear at the bottom of the display). <esc> N (0x1b 0x4e) inserts a blank character at the cursor position and moves charac- ters to the right one position to the right (the last character on the line is lost). <esc> O (0x1b 0x4f) deletes the character at the cursor position and moves characters to the right one position to the left (a blank character appears in the last column of the line). <esc> S <color> (0x1b 0x53 0xCC) sets the background color of subsequent output characters; the color code is described below (Color support). <esc> T <color> (0x1b 0x54 0xCC) sets the foreground color of subsequent output characters; the color code is described below (Color support). <esc> a (0x1b 0x61) and <esc> b (0x1b 0x62) make the cursor invisible resp. visible. <esc> c (0x1b 0x63) and <esc> d (0x1b 0x64) switch to the alternate resp. to the primary character set (see be- low). <esc> e (0x1b 0x65) and <esc> f (0x1b 0x66) switch on resp. off bold characters. <esc> g (0x1b 0x67) and <esc> h (0x1b 0x68) switch on resp. off underlined characters. <esc> i (0x1b 0x69) and <esc> j (0x1b 0x6a) switch on resp. off inverted characters. <esc> k (0x1b 0x6a) and <esc> l (0x1b 0x6c) switch on (arrgh!) resp. off (phew!) blinking characters. <esc> m (0x1b 0x6d) switches off bold, underlined, blinking, and inverted characters as well as standout mode (see below); resets the foreground and back- ground colors to their defaults. <esc> n (0x1b 0x6e) and <esc> o (0x1b 0x6f) switch the cursor keys to application mode resp. back to regular (VT52) mode: in regular mode, the cursor keys send the sequences <esc> A (up), <esc> B (down), <esc> C (right), and <esc> D (left); in application mode, they send WordStar-compatible commands, namely ^E (0x05, up), ^X (0x18, down), ^D (0x04, right), and ^S (0x13, left). <esc> p (0x1b 0x70) and <esc> q (0x1b 0x71) switch on resp. off standout mode; standout mode is the most visible character attribute provided by curses (this is usually inverted video, so using <esc> p and <esc> q is usually equivalent to using <esc> i and <esc> j). "Hold screen" mode is a feature of the VT52 terminal: it is entered and ex- ited either by the computer sending the relevant control sequence or by the user by pressing the "hold screen" key (in tnylpo, this is the F5 key). In "hold screen" mode, trying to scroll up the screen (by a <lf> on the bottom line of the screen) blocks further output until either "hold screen" mode is exited or the user presses the "scroll page" key (F6 in tnylpo) or the "scroll line" key (F7 in tnylpo), which allow one more screenfull resp. one more line of output. Displaying graphical characters instead of ASCII characters for the byte range 0x5e-0x7e is another feature of the VT52 terminal which allows access to certain additional shapes like subscripted digits or the +/- sign; in tnylpo, graphical mode allows displaying the shapes defined for the charac- ter positions 0x00-0x1f and 0x7f, which cannot be displayed directly. Character sets Switching between a primary and an alternate character set is an extension provided by tnylpo: two full character sets of 256 shapes (each containing a separate graphical character set in the positions 0x00-0x1f and 0x7f) may be defined in the configuration file; programs may switch between these two sets by using <esc> c resp. <esc> d. Switching character sets doesn't change characters already written to the display. This feature allows pro- grams to use e.g. a national variant of the ISO 646 seven-bit character set in parallel to standard ASCII characters. Character set definition is done in the configuration file by using the op- tion [alt] char <number> = <string> which defines <string> (a one-character string literal in double quotes) as representation of code <number> (a number in the range 0-255) in the pri- mary (or alternate, if the line is prefixed by alt) character set. Charac- ters not explicitly defined in this way are taken from a default character set, which may be selected by the option [alt] charset = (ascii | vt52 | latin1 | tnylpo) The possible values correspond to the four built-in character sets ASCII, VT52 (ASCII plus an approximation of the VT52 graphical characters), the ISO 8859-1 (Latin 1) eight-bit character set, which supplements the ASCII code by characters used in Western European languages in positions 0xa0-0xff, and finally a homespun superset of Windows code page 1252 (and thereby a superset of ISO 8859-1 and ASCII), which supports block graphics and the VT100 box drawing characters as graphical character set. If no character set is specified, tnylpo uses the VT52 character set by de- fault. By using the command line option -a, a program may be started with the al- ternate character set selected; the effect is almost identical to the pro- gram issuing <esc> c as its very first action. (There is a difference in full screen console mode: During screen initialization, tnylpo passes the blank character from the selected character set to the curses library for use as background character. Since the program itself can select the alter- nate character set only after this initialization has been done, curses will receive the blank character from the primary character set; with the -a command line option, it will receive the blank character from the alter- nate character set. This difference is mostly academic, since it is not recommended to redefine the blank character anyway, see below.) Output characters which are undefined in the currently selected character set are ignored by the terminal emulation; the configuration option unprintable = <string> substitutes undefined characters on output by the value of <string> (which must contain a single character). Function keys Apart from F5, F6, and F7, which are used to implement the "hold screen" function of the VT52 (see above), tnylpo's terminal emulation defines the function keys F1, F2, and F3 as equivalents of the three unlabeled keys of a VT52 terminal; if pressed, they return the sequences <esc> P (0x1b 0x50), <esc> Q (0x1b 0x51), and <esc> R (0x1b 0x52). F4 causes the terminal emula- tion to redraw its display, which is useful if some other program or the host operating system mess up the user's screen. F10 sends a SIGINT to tnylpo, causing the emulation to stop abruptly, but allowing tnylpo itself to exit gracefully (this key is meant as a last-resort way of stopping a CP/M program gone haywire). Color support If the underlying software and display hardware allow color output, tnylpo's terminal emulation supports the use of eight different colors, which may be selected as foreground resp. background colors of subsequently displayed characters. These colors are identified by the following numeric codes: 0 black 1 blue 2 red 3 magenta 4 green 5 cyan 6 yellow 7 white By default, color support is disabled even on color-capable displays; it must be explicitly enabled either by the configuration option colors = true or by the command line option -oy. Both colors = true and -oy may be fol- lowed by two comma-separated color codes, which specify the default fore- ground resp. background colors of tnylpo's terminal emulation, e.g. colors = true, 6, 1 (resp. -oy,6,1) will select yellow characters on a blue background. The default colors may be specified in the configuration file by colors = false, 6, 1 even if color support is disabled (since this may be overridden by -oy). The command line option -o6,1 is a shorthand form of -oy,6,1, and -on may be used to override the configuration file and disable color sup- port. If no default colors have been specified either in the configuration file or on the command line, tnylpo defaults to 7 and 0, i.e. to white text on a black background. Application programs may select colors by issuing the escape sequences <esc> S <color> and <esc> T <color> to choose the background resp. fore- ground colors of subsequently displayed characters; <color> is either a single ASCII digit in the range from 0 to 7 (0x31 to 0x37) corresponding to one of the colors supported by tnylpo, or the character = (0x3d), which will select the respective default color. To render e.g. the text Warning! in red, a program may display the character sequence <esc> T 2 W a r n i n g ! <esc> T = on the full-screen console. Both foreground and background colors will also be reset to their defaults by the escape sequence <esc> m, which resets all text attributes. On monochrome devices or if color support has been dis- abled, <esc> S and <esc> T will still be accepted but silently ignored. Character devices Besides the bidirectional console device, CP/M supports three unidirec- tional character devices, the output-only printer and paper tape punch de- vices LST: and PUN: and the input-only paper tape reader device RDR:. tnylpo represents these devices by host system files, to which the data provided by the CP/M program are written resp. from which the data pre- sented to the CP/M program are read. These files are defined by the configuration options (printer | punch | reader) file = <path> where <path> is a string in double quotes containing the Unix file path; in case of the output devices (LST: and PUN:), data written by the CP/M pro- gram are appended to the contents of the named files; RDR: input will start at the beginning of the reader file. If a CP/M program reads past the end of the reader file, tnylpo will continue to return ^Z (0x1a) bytes as end- of-file indication. tnylpo's character devices can operate in two modes, depending on the con- figuration options (printer | punch | reader) mode = (text | raw) In raw mode, bytes are written to the file exactly as they are generated by the CP/M program resp. passed to the CP/M program exactly as they are read from the file (^Z bytes are still returned as EOF indication). In text mode, tnylpo will translate the characters read resp. written using the translation table used by the console. Character set switching by the con- sole (using the escape sequences <esc> c and <esc> d) will affect this translation, but switching to graphical characters (<esc> F and <esc> G) will not. Moreover, tnylpo will convert the line end markers from CP/M (^M^J, 0x0d 0x0a) to Unix (^J, 0x0a) and vice versa in this mode. Saving a memory image The command line option -e causes tnylpo to save parts of the CP/M memory to a file after a regular program termination (i.e. one that is not caused by a fatal error or receipt of a signal); it takes as argument a string of suboptions which specify the name and the format of the output file and the range of CP/M memory addresses to save. Possible suboptions and their para- meters are h causes the memory contents to be written in Intel Hex format; if this option is absent, a binary file will be written. b<bytes> selects a number of bytes (specified as decimal number) starting from address 0x100. p<pages> selects a number of pages (units of 256 bytes, specified as decimal number) starting from address 0x100. r[<low-addr>]-<high-addr> selects a range of addresses to save (both addresses may be speci- fied as octal, hexadecimal, or decimal numbers using the Unix con- vention of prefixing them with 0, 0x, or any other digit, respec- tively); <high-addr> may not be less than <low-addr>, and if <low- addr> is missing, 0x100 will be assumed in its place. :<filename> specifies the Unix file to which the memory contents are written; this is mandatory and must be the very last suboption (in fact, everything following the first colon in the argument of the -e com- mand line option is taken as part of the file name). Individual suboptions resp. suboptions and their parameters may not be sep- arated by whitespace. The three range specifications b, p, and r may not exceed the range of the CP/M memory space (0x0000-0xffff) and are mutually exclusive; if none of them is specified, the whole TPA (starting at address 0x100 and including the last byte before the BDOS area) is saved. The command line option -e serves as a replacement for the SAVE command of CP/M, which is most often used to save an executable file after applying patches with a debugger (most CP/M debuggers don't provide a command for writing memory contents to a disk file). Invoking tnylpo with the addi- tional option -ep34:new.com is equivalent to issuing the command SAVE 34 NEW.COM immediately after termination of an executable under CP/M. Supported system calls This subsection gives a list of system calls supported by tnylpo. While there are some extensions mainly taken from the CP/M 3 BDOS interface, tnylpo prioritizes compatibilty with CP/M 2.2. All unimplemented BDOS calls (i.e. those not listed in this section) are tolerated and conform to the (admittedly suboptimal) CP/M 2.2 convention of returning 0 in registers A, B, and HL. #0 System Reset #1 Console Input #2 Console Output #3 Reader Input #4 Punch Output #5 List Output #6 Direct Console I/O #7 Get I/O Byte (dummy) #8 Set I/O Byte (dummy) #9 Print String #10 Read Console Buffer #11 Get Console Status #12 Return Version Number #13 Reset Disk System #14 Select Disk #15 Open File #16 Close File #17 Search for First #18 Search for Next #19 Delete File #20 Read Sequential #21 Write Sequential #22 Make File #23 Rename File #24 Return Log-In Vector #25 Return Current Disk #26 Set DMA Address #27 Get Addr(Alloc) (dummy) #28 Write Protect Disk #29 Get Read-Only Vector #30 Set File Attributes (dummy) #31 Get Addr(Diskparams) (dummy) #32 Get/Set User Code (dummy) #33 Read Random #34 Write Random #35 Compute File Size #36 Set Random Record #37 Reset Drive #40 Write Random with Zero Fill #49 Get/Set System Control Block (CP/M 3) #101 Return Directory Label Data (CP/M 3) #102 Read File Date Stamps and Password Mode (CP/M 3) #105 Get Date and Time (CP/M 3) #108 Get/Set Program Return Code (CP/M 3) #141 Delay (MP/M) BDOS function #49 (Get/Set System Control Block) is only partially imple- mented: Attempts to write to the SCB are silently ignored, and only the SCB offsets 0x05 (BDOS version number, always 0x22), 0x10-0x11 (program return code), 0x1a (console columns), 0x1c (console lines), 0x37 (output delim- iter, always 0x24), 0x3c-0x3d (current DMA address), 0x3e (current disk), 0x44 (current user number), and 0x4a (current multi sector count, always 1) provide meaningful information (all other byte offsets return 0). BDOS function #102 (Read File Date Stamps and Password Mode) always returns the access and modification timestamps of the underlying Unix file, and function #101 (Return Directory Label Data) correspondingly always returns a value of 0x61. BDOS function #141 (Delay) delays program execution for the number of sys- tem clock ticks passed in register DE; tnylpo defines a tick to last 20 milliseconds, i.e. it emulates a ticker frequency of 50 Hertz. In addition to the BDOS calls, tnylpo implements all BIOS calls of CP/M 2.2, but all disk related functions are dummies: BOOT System Cold Start Initialization WBOOT Warm Start CONST Console Input Status CONIN Console Character Input CONOUT Console Character Output LIST Printer Character Output PUNCH Paper Tape Punch Output READER Paper Tape Reader Input HOME Recalibrate Disk Drive (dummy) SELDSK Select Disk Drive (dummy) SETTRK Set Track Number (dummy) SETSEC Set Sector Number (dummy) SETDMA Set DMA Address (dummy) READ Read Selected Sector (dummy) WRITE Write Selected Sector (dummy) LISTST Printer Output Status SECTRAN Sector Number Translation (dummy) No additional BIOS calls from CP/M 3 have been implemented, not even as dummies, i.e. any attempt to call them will result in undefined program be- haviour. Program termination tnylpo terminates as soon as the CP/M program it executes terminates by ei- ther calling BDOS function #0 (System Reset) or BIOS function WBOOT; jump- ing to address 0x0000 or using the stack area set up by tnylpo and ending execution by a RET instruction is equivalent to calling BIOS function WBOOT directly. Finally, the user may terminate a program by pressing ^C (0x03) when prompted for console input by BDOS function #10 (Read Console Buffer). All these forms of program termination are considered regular for the pur- pose of determining the exit status from tnylpo (see below, under EXIT STA- TUS). Furthermore, a CP/M program will be terminated if it performs an action considered illegal by tnylpo, like executing a HALT instruction, trying to write to a read-only file or to a file on a disk configured as read-only, passing invalid arguments to system calls, accessing a disk drive not con- figured, or requesting an illegal sequence of operations (like trying to read from a disk file which has already been closed). When the full screen console is active, a program may be terminated by the user pressing the F10 key (see above, "Function keys"); this is equivalent to sending a SIGINT to tnylpo from another terminal/terminal window. Press- ing F10 terminates the CP/M program abruptly and should (like sending a signal to tnylpo) only be used as a last resort when dealing with a hung application. Both program termination due to an illegal action and terminating a program by pressing F10 (or sending tnylpo a signal) are considered irregular forms of program termination. EXIT STATUS tnylpo exits with status 1 if it encountered a fatal error and status 0 otherwise. Fatal errors are command line errors, configuration file errors, or an irregular termination of the CP/M program (see above). CP/M-80 version 2.2 has no concept of a program exit status, so there is no well-established way of communicating an unsuccessful CP/M program execu- tion to the Unix environment. To alleviate this deficit, tnylpo implements BDOS function #108 (Get/Put Program Return Code) from CP/M 3; if a CP/M program sets its return code to a value in the "unsuccessful return" range (0xff00-0xfffe) prior to termination, tnylpo will exit with status 1. FILES ./.tnylpo.conf The file .tnylpo.conf in the current working directory is used as configu- ration file, if it is present and no configuration file has been specified on the command line. ~/.tnylpo.conf The file .tnylpo.conf in the user's home directory is used as a configura- tion file, if it is present, if no configuration file has been specified on the command line, and if there is no file .tnylpo.conf in the current work- ing directory. Using configuration informations from a file in the current working direc- tory (./.tnylpo.conf) is convenient in many situations, but poses a poten- tial security risk; mainly for this reason, tnylpo refuses to run if its effective user ID is 0. NOTES Differences between tnylpo and CP/M-80 By design, there are some incompatibilities between CP/M-80 and the emula- tion provided by tnylpo: Direct access to the BDOS and BIOS areas Since it doesn't contain any actual CP/M code, all programs trying to patch the BDOS or otherwise make assumptions about the layout of the operating system or its internal data structures will fail while running on tnylpo. BDOS and BIOS function emulations are activated by the simulated processor executing a RET instruction fetched from one of the uppermost 19 addresses of the CP/M memory space (0xffed for the BDOS entry, 0xffee to 0xfffe for the 17 BIOS entries of CP/M-80 2.2 and 0xffff for one tnylpo-specific delay routine hiding as 18th BIOS entry); this use of "magic addresses" might confuse debuggers trying to trace system calls. The BIOS area (starting three bytes before the address stored at 0x0001) is page-aligned and contains the 17(+1)-element BIOS jump vector, the dummy disk structures (see below) and the above mentioned 19 RET instructions. The BDOS area (starting at the address stored at 0x0006) is even shorter, containing only a jump to 0xffed and the table of target addresses for the four fatal BDOS error conditions (non-existing disk, bad sector, read-only disk, and read-only file; these addresses may be modified by an application program, but are completely ignored by tnylpo). Any program expecting the BDOS or the BIOS areas to have the sizes and alignment characteristics of a real CP/M-80 environment will be disappointed. The OS serial number stored in the six bytes immediately before the BDOS area is always 0x00 0x16 0x00 0xc0 0xff 0xee, a (hopefully inoffensive) dummy indicating BDOS version 2.2. Direct access to the disk drives All programs trying to access the CP/M disk structure directly (e.g. disk editors) will not work, since there is no underlying CP/M disk structure (tnylpo translates FDOS calls into operations on Unix files); all disk re- lated BIOS calls are implemented as dummy functions (those few which can return an error indication --SELDSK, READ, and WRITE-- will do so). The BDOS functions returning disk structure related information (#27 and #31) will return dummy structures containing meaningless (but consistent) data; for example, all disk drives will be reported as having a block size of 16KB, 2048 directory entries and a capacity of 8MB, of which 8128KB (8MB less four directory blocks) are free (to save space, all drives share the same dummy allocation vector, which is of course impossible with real CP/M-80). All block information returned by the BDOS functions #17 and #18 is meaningless; regardless of the contents of the S2 field (FCB offset 14), all otherwise matching files are returned only once (as opposed to once per physical extent under CP/M-80). Likewise, all block information in the FCBs of open files (FCB byte offsets 16 to 31) is meaningless (but may not be disturbed since tnylpo stores some state information there, see below). The emulation is good enough for programs searching for file name patterns or just listing the disk directory, but will fail for those trying to analyse the block structure of the emulated disk from the returned information. Console Command Processor tnylpo doesn't emulate the CCP, so every program using its features (by e.g. creating a $$$.SUB file and expecting the CCP to execute its contents) will not work correctly. Ending a program by simply returning to the CCP is supported; tnylpo initializes an 8 level CCP stack at the end of the TPA (below the OS serial number) and pushes the address of the WBOOT entry in the BIOS vector, so a program trying to return to the CCP will terminate correctly. File attributes File attributes (read-only and system attribute resp. the four attributes available for user programs) are not supported by tnylpo; the corresponding BDOS function #30 is a dummy. File names characters will always be returned with the most significant bits reset. User areas The concept of user areas is not implemented by tnylpo; while the user code may be set by BDOS function #32 (and will be returned when queried), this has no influence on file operations. I/O byte Likewise, the I/O byte functionality is not implemented; while the I/O byte may be queried and set (by BDOS functions #7 and #8) and is stored in ad- dress 0x0003, it has no influence on the character devices. FCB structures FDOS calls are translated into Unix file operations. For this to work, tnylpo maintains a separate list of corresponding Unix files; references to the entries of this list are stored in the FCBs of open CP/M files (a 16 bit reference number is stored at offsets 16 and 17 in the FCBs, and the same number XORed by 0xafcb is stored at offsets 18 and 19). This allows programs to copy the FCBs of open files and use the copies to further ac- cess the same files (e.g. programs written in Turbo Pascal do such things). The drive and file name portions of a FCB are only referenced by BDOS func- tions #15, #17, #19, #22, #23, #30, #35, and #102, all other functions (es- pecially the read and write functions) use the file reference number to identify the relevant Unix file. The current record number in sequential I/O operations is stored in the FCB fields EX, S2, and RC (offsets 12, 14, and 32). Sparse files Since CP/M file operations are directly mapped to Unix file operations, some characteristics of Unix files are visible to CP/M programs running on tnylpo: Trying to read a record within an unwritten block in the middle of a sparse file would result in an error indication (reading unwritten data) under CP/M-80, but simply returns a record of zero bytes on tnylpo, since unallocated areas in the middle of a Unix file read as zero. Hopefully, few programs will take offence at this difference. File closing Normally, closing a file in a CP/M program (BDOS function #16) will cause tnylpo to close the corresponding Unix file and free its entry in the file list. This causes problems with certain CP/M software (e.g. dBase II), which continue to use FCBs for file operations after calling BDOS function #16. Since the close operation just writes the updated FCB data back to the disk directory (but doesn't change the FCB), this is possible in CP/M-80 (though a little dirty in my opinion). Contrarily, tnylpo (in addition to closing the corresponding Unix file) removes its file reference from the FCB, thereby marking it as invalid for further I/O, causing subsequent op- erations by the CP/M program to fail. To accommodate such programs, tnylpo provides the -n command line option (and the corresponding close files = false configuration option), which prevent closing the Unix file and removing the file reference from the FCB (effectively making BDOS function #16 a dummy operation). If many files are opened (sequentially or concurrently) by a CP/M program, this may cause tnylpo to run out of files, since the closing of all Unix files is deferred until program termination. Text file format Disk file I/O is always done untranslated, i.e. the contents of disk files written by programs running on tnylpo are always in the character set used internally by the CP/M emulation. Likewise, the line end convention in text files is that of CP/M (^M^J, 0x0d 0x0a) and text files not ending exactly at the end of a 128 byte CP/M file record will contain a ^Z (0x1a) byte as logical EOF marker (ideally, they should be padded with ^Z bytes to the next record border, but in reality they usually end in a single ^Z followed by arbitrary rubbish). This must be taken into account when using Unix utilities to process files generated by tnylpo. On the other hand, text files generated under Unix should be converted to the CP/M line end convention before processing them with programs running on tnylpo (the command set ff=dos might come handy for people using Vim!). The CP/M convention for marking the logical end of text files is honoured automatically, since tnylpo's BDOS emulation pads Unix files to the CP/M record size of 128 bytes with ^Z bytes. Text file conversion between the Unix and the CP/M formats may be done con- veniently using the companion program tnylpo-convert(1). Performance tnylpo has been optimized for portability, not for performance; some parts of the processor emulation (e.g. the addition and subtraction operations) may be ridiculously inefficient compared to a hand-optimized assembler ver- sion (or even a C version making moderate use of platform specific things like byte order or number representation). On the plus side, tnylpo should compile and run on every Unixy platform supporting ISO C99 (for wide and multibyte character support), a wide character capable version of the ncurses library and int variables with more than 16 bits. That said, I found tnylpo blindingly fast compared to the real thing even on the out- dated hardware I used for its development. The delay routine Since CP/M-80 version 2.2 offers no functions for time keeping or delays, programs are forced to use the cycle time of certain instructions in combi- nation with the CPU clock frequency if they need to delay program execu- tion; this approach is doomed under an emulator, especially if it is run- ning on a multiprogramming system. To allow CP/M programs to delay execution for a defined (wall clock) time period, tnylpo supplies a delay routine masquerading as 18th BIOS entry: it expects a single parameter, an unsigned 16-bit number in register BC, and waits this many milliseconds before returning to the caller. The benefit of this routine is at best limited, but most likely nonexis- tent; since it is an extension, no existing CP/M application (for which tnylpo has been created in the first place) uses it, and even in case some- body would develop new CP/M software, employing tnylpo's delay function would break compatibility with all other CP/M machines or emulators. As an alternative, tnylpo implements function #141 (Delay) from the MP/M BDOS; while this function is a little more standardized than tnylpo's pro- prietary extension, it is equally unavailable on real CP/M and most compat- ible systems and suffers from the additional drawback that it measures time in system timer ticks, which are implementation dependent (tnylpo emulates a tick length of 20 milliseconds, i.e. a 50 Hertz timer). The name of the program "tnylpo" is a fantasy word. Neither is it an acronym nor does it have any meaning I know of (which is the main reason I chose it). "tnylpo" is pro- nounced like a native speaker of German (e.g. I) would naively pronounce "tnulpo" (or like a speaker of Finnish would pronounce "tnylpo", provided she survives the initial consonant cluster). In its formation, "tnylpo" with its two syllables and ending in "-po" aligns nicely with other non- sense words I invented earlier (like "ilpo" or "sampo") --until I moved to Finland and discovered that most of these supposed nonsense words have cur- rency here... BUGS See the remarks under NOTES. Most of them may be interpreted as bugs in the implementation, including the program name. Character set switching A program running in full screen mode (VT52 emulation) may change its dis- play character set from the primary character set to the alternate set and back by issuing an appropriate escape sequence. This switching also affects the character set translation of the other character devices (LST:, PUN:, and RDR:), unless they are operating in raw mode. Character redefinition It is not recommended to redefine any of the characters which may appear in CP/M file names, their Unix equivalents or in the file name/file extension fields of an FCB; these include the decimal digits (0x30-0x39), the upper- and lower case characters (0x41-0x5a and 0x61-0x7a), space (0x20), dollar sign (0x24), asterisk (0x2a), minus (0x2d), dot (0x2e), colon (0x3a), and the question mark (0x3f). Host system locales tnylpo has been implemented with the intention to work with all possible Unix CTYPE locale settings (other aspects of the current locale are ig- nored); unfortunately, only ASCII based systems and locales are supported, since there is no character set independent way to represent some of the control characters relevant for CP/M (e.g. ^C and ^Z). Currently, tnylpo always assumes that the character codes 0x00-0x1f and 0x7f of the host op- erating system single- or multibyte character set correspond to the ASCII control characters. Frankly, tnylpo has only been extensively tested to work with UTF-8 based locales. File namespace clashes tnylpo tries to hide unsuitable files in host directories used as CP/M dri- ves from CP/M programs; file searches and open requests will ignore every- thing but regular files up to 8MB in size which have acceptable names. Un- fortunately, this attempt at hiding other objects is far from perfect: a CP/M program trying e.g. to create a file whose name matches the name of a (hidden) directory will mysteriously fail (a rename operation may meet sim- ilar problems). It is therefore recommended to reserve directories used as CP/M drives to conforming regular files or to give all other objects names not acceptable as CP/M file names (a leading dot may work wonders!). Color limitiations The color support in tnylpo's terminal emulation is constrained by the ca- pabilities of the ncurses library resp. of the display hardware. These may cause a limitation of the number of combinations of foreground and back- ground colors (color pairs) which may be used on the display simultane- ously. If tnylpo runs out of color pairs, the affected combinations will revert to the default foreground and background colors. This problem should only occur with pathological ("angry fruit salad") user interface designs. EXAMPLES tnylpo -f ws.conf ws hugo.txt will use the configuration file ws.conf and run the program ws.com, passing it the string hugo.txt as command line parameter. If the file ws.conf contains the following lines # # WordStar configuration # drive a = "." printer file = "./printer.txt" printer mode = text logfile = "./.tnylpo.log" loglevel = 0 # # use German character set # charset = ascii char 0x40 = "<section>" char 0x5b = "A" char 0x5c = "O" char 0x5d = "U" char 0x7b = "a" char 0x7c = "o" char 0x7d = "u" char 0x7e = "ss" unprintable = "?" console = full lines = 24 columns = 80 application cursor = true screen delay = 2 tnylpo will search for ws.com (and other files) in the local directory, which will be used as drive A in the emulation; console I/O will be handled in full screen mode by the VT52 emulation which uses a screen of 24 lines of 80 columns. The cursor keys will be translated to ^E (up), ^S (left), ^D (right), and ^X (down), and the character set will correspond to the German ISO/IEC 646 variant (umlaut characters in place of the brackets and curly braces of ASCII). Characters in the range of 0x80 to 0xff will be displayed as inverted question marks. Printer output will be written to printer.txt in the current directory, will be in the Unix character set and will follow Unix line end conventions. A log will be appended to .tnylpo.log in the current directory and will contain error messages only. After program termination, tnylpo will wait for two seconds before reset- ting the screen. Patching a CP/M executable Many CP/M applications do not supply installation programs but rely on the user applying (hopefully well-documented) binary patches to support e.g. the control sequences of a particular video terminal. Under CP/M, this is usually done using a debugger (e.g. DDT) in combination with the CCP built-in command SAVE. The following example shall demonstrate the process of patching an executable using tnylpo: $ ls -la total 72 drwxr-xr-x 7 tnylpo users 224 Sep 5 13:04 . drwxr-xr-x 39 tnylpo users 1248 Sep 5 13:04 .. -rw-r--r-- 1 tnylpo users 8192 Sep 5 13:02 asm.com -rw-r--r-- 1 tnylpo users 4864 Sep 5 13:02 ddt.com -rw-r--r-- 1 tnylpo users 2091 Sep 4 13:08 patch.asm -rw-r--r-- 1 tnylpo users 9728 Sep 5 13:02 wm.com -rw-r--r-- 1 tnylpo users 2688 Sep 5 13:02 wm.hlp wm.com is the binary to be patched (wm.hlp is an associated data file). asm.com and ddt.com are the standard CP/M absolute assembler and debugger (ASM and DDT) which will be used to prepare resp. apply the patch. patch.asm contains the assembler source file of the patch. Note the size of wm.com, which is 9728 bytes. First, the patch is assembled, which creates patch.hex, a file in the Intel Hex format. $ tnylpo asm patch CP/M ASSEMBLER - VER 2.0 01D8 000H USE FACTOR END OF ASSEMBLY Now the debugger is started, which relocates itself to the top of the TPA and loads wm.com into the TPA starting at address 0x100. The option -eb9728:wmnew.com asks tnylpo to save 9728 bytes (the size of wm.com) starting from address 0x100 to the file wmnew.com after the CP/M program (i.e. DDT) has terminated. $ tnylpo -eb9728:wmnew.com ddt wm.com DDT VERS 2.2 NEXT PC 2700 0100 DDT displays two hexadecimal numbers, the first of which is the first free memory address after the loaded program (0x2700 is decimal 9984, i.e. 0x100 plus 9728, the size of wm.com). Now DDT is used to apply the patch: The command i tells DDT the name of the patch file, and the command r reads it into memory (the Intel Hex format provides the necessary address informa- tion to apply the changes at the correct locations). Finally, g0 directs DDT to jump to adress 0, which causes it to terminate. -ipatch.hex -r NEXT PC 2700 0000 -g0 As soon as DDT terminates, tnylpo saves the memory contents as directed, creating a patched version of the executable, which can be tested and re- named. $ ls -la wmnew.com -rw-r--r-- 1 tnylpo users 9728 Sep 5 13:06 wmnew.com AUTHOR tnylpo and its manual page were written by Georg Brein (tnylpo@gmx.at), a programmer, IT systems administrator and guerrilla egyptologist. SEE ALSO tnylpo-convert(1) The implementation of the Z80 processor emulation, especially of the fea- tures not covered by the official documentation (Zilog Inc., Z80 CPU User Manual, Revision 11: August 2016 [UM008011-0816]), is heavily influenced by Sean Young's The Undocumented Z80 Documented (Version 0.91, 18th September 2005). The CP/M-80 2.2 system interface emulation is based on the CP/M Operating System Manual by Digital Research (Third Edition: September 1983). Some additional system functions are based on their descriptions in the CP/M Plus (CP/M Version 3) Operating System Programmer's Guide by Digital Research (Second Edition: April 1983). 2021-04-28 tnylpo(1)
NAME | SYNOPSIS | DESCRIPTION | OPTIONS | EXIT STATUS | FILES | NOTES | BUGS | EXAMPLES | AUTHOR | SEE ALSO
Want to link to this manual page? Use this URL:
<https://man.FreeBSD.org/cgi/man.cgi?query=tnylpo&sektion=1&manpath=FreeBSD+Ports+15.1.quarterly>