[
  {
    "path": ".gitattributes",
    "content": "# Default is to keep crlf line endings\ntext=auto\n\nREADME.md text eol=crlf\nLICENSE text eol=crlf\nMAKEFILE text eol=crlf\n*.DOC text eof=crlf\n*.AS text eol=crlf linguist-language=Assembly\n*.AS2 text eol=crlf linguist-language=Assembly\n*.AS3 text eol=crlf linguist-language=Assembly\n*.Z80 text eol=crlf linguist-language=Assembly\n*.C text eol=crlf linguist-language=C\n*.COM binary\n*.H text eol=crlf linguist-language=C\n*.HUF binary\n*.LIB binary\n*.LOG text eol=crlf\n*.LZH binary\n*.MAN text eol=crlf\n*.OBJ binary\n*.SUB text eol=crlf\n*.TXT text eol=crlf\n*.lbr binary\n*.LBR binary\n*.ARC binary\n*.RSX binary\n*.pdf binary\nOPTIONS text eol=crlf\nC280OPTS text eol=crlf\n"
  },
  {
    "path": ".gitignore",
    "content": "**/.*.swp\n**/.DS_Store\n"
  },
  {
    "path": "LICENSE",
    "content": "The HI-TECH Z80 CP/M C compiler V3.09 is provided free of charge for\r\nany use, private or commercial, strictly as-is.  No warranty or product\r\nsupport is offered or implied.\r\n\r\nYou may use this software for whatever you like, providing you\r\nacknowledge that the copyright to this software remains with\r\nHI-TECH Software.\r\n\r\n--\r\nFrom the HI-TECH Software web site (now defunct) - a copy of which\r\nis on the Wayback Machine at\r\n\r\nhttps://web.archive.org/web/20000301031041/http://www.hitech.com.au/\r\n"
  },
  {
    "path": "README.md",
    "content": "# HI-TECH Z80 C Compiler for CP/M\r\n\r\n## Introduction\r\n\r\nThis repository contains the HI-TECH C Compiler for Z80 v3.09 along with\r\nupdates and enhancements.  It runs natively on a Zilog Z80/Z180/Z280\r\nprocessor under the CP/M operating system or under emulation on your\r\nWindows/Linux/macOS system using RunCPM[^1], SIMH AltairZ80[^2] or\r\nZXCC[^3].\r\n\r\nEach release is a consolidated milestone with various updates and\r\npatches applied.  You should read this README.md file for details.\r\n\r\nThe latest release is V3.09-20 (see Modification History below).\r\n\r\nIf you only wish to download the latest binary distribution, download\r\nit from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/htc-bin.lbr\r\n\r\nand optionally the Z280 binary distribution (if you need it) from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/z280bin.lbr\r\n\r\nI welcome bug reports/fixes and additional commentry and discussion.\r\n\r\nYou can raise an issue here on GitHub or contact me directly via e-mail\r\nat <tony.nicholson@computer.org> or by posting to the USENET newsgroup\r\nforum at comp.os.cpm in the \"Consolidating Updates for HI-TECH C for\r\nZ80 CP/M v3.09\" discussion thread[^4].\r\n\r\nThe first release is a slightly modified (see below) v3.09.\r\n\r\n## Background\r\n\r\nThe HI-TECH Z80 CP/M C compiler v3.09 is provided free of charge for any\r\nuse, private or commercial, strictly as-is. No warranty or product\r\nsupport is offered or implied.\r\n\r\nYou may use this software for whatever you like, providing you acknowledge\r\nthat the copyright to this software remains with HI-TECH Software.\r\n\r\nThe *dist* folder contains the entire compiler including the original\r\ndistributed library source-code in Huffman-encoded archive files (CPM.HUF,\r\nGEN.HUF, FLOAT.HUF and STDIO.HUF). NB: I have not rebuilt the .HUF files -\r\nso please use updated run-time library source files in the following folders.\r\n\r\nThe *cpm*, *gen*, *float* and *stdio* folders contain the library\r\nsource-code that has been extracted from the .HUF archive files\r\nusing DEHUFF.COM and the updated/modified files.\r\n\r\nThe *doc* folder contains the documentation in ASCII text as HTCZ80.TXT.\r\n\r\n\r\n## Modification History\r\n\r\nIn chronological order - so be sure to check the latest updates at the\r\nend of this README file.\r\n\r\n## Release v3.09\r\n<!-- Mar 3, 2020 -->\r\n\r\nThe original HI-TECH C linker (LINK.COM) has been renamed as LINQ.COM\r\nand the main compiler front-end (C.COM) has been patched to reflect\r\nthis name change.  This was done to avoid a name clash with the Digital\r\nResearch supplied CP/M linker.  The original version is kept as C-ORIG.COM\r\nand the patched version is dist/C309.COM\r\n\r\nI've edited the documentation to remove the underlining and bolding of\r\ntext by over-printing and fixed some layout issues and typos.\r\n\r\n\r\n## Release v3.09-1\r\n<!-- Mar 4, 2020 -->\r\n\r\nAs supplied in v3.09, the LIBF.LIB produces inaccurate floating point\r\ntrigonometry results - as reported by \"Ed\" in his posting to the\r\ncomp.os.cpm USENET Newsgroup.\r\n\r\n```\r\nSince we're on the topic of Hitech-C for CP/M, below is a problem I\r\ndiscovered with the freeware release.\r\n\r\nLIBF.LIB supplied with the freeware Hitech-C v3.09 produces inaccurate trig\r\nresults.  I found that by simply recompiling the library with the existing\r\nsource files from FLOAT.HUF, it fixed the problem.  Absolutely no changes\r\nto the sources were required.\r\n```\r\n\r\nThe re-compiled LIBF.LIB from the FLOAT.HUF library sources in *float*\r\nhas been copied to the distribution files in *dist*.  A CP/M submit file to\r\nrebuild LIBF.LIB has been added to *float*.\r\n\r\nA *test* folder has been created.  In it is a TESTTRIG.C program for testing\r\nthis release.\r\n\r\n\r\n## Release v3.09-2\r\n<!-- Mar 3, 2020 -->\r\n\r\nThe late Jon Saxton (former SYSOP of the Australian Tesseract RCPM)\r\ncollected together a number of patches and updates - See Tesseract\r\nvolume 091.\r\n\r\nThese include contributions from John Elliott via\r\nhttp://www.seasip.info/Cpm/software/index.html - in particular\r\nfor PIPEMGR which is a CP/M 3 RSX that implements piping and redirection.\r\n\r\nJohn's contributions will be implemented in a later release.\r\n\r\nThis release includes updates to memset(), bios() and bdos() library\r\nroutines.  In addition the stat(), close() and sys_err() routines\r\nare updated to remove references to bdoshl() and to include CP/M 3\r\nerror messages.\r\n\r\n```\r\nmemset()\r\n\r\n     The Hi-Tech C implementation of memset() is seriously broken and is\r\n     almost guaranteed to give trouble in any program which uses it.\r\n\r\n     The original implementation simply does not agree with the function\r\n     declaration.  It now does.\r\n\r\n         void memset(void s, char c, size_t n)\r\n\r\n     Sets n bytes of memory starting at the location pointed to by s with\r\n     the character c.\r\n\r\nbios()\r\n\r\n    The original bios() routine used the function number to construct an offset\r\n    into the BIOS jump vector and from that calculated the address of the\r\n    appropriate BDOS routine.  Except for some character I/O routines, that\r\n    method of calling the BIOS is guaranteed to crash CP/M 3.\r\n\r\n    A new bios() function has been implemented which checks for CP/M 3 and if\r\n    that is the current operating system then it accesses the BIOS via the\r\n    sanctioned method, i.e. by invoking bdos(50) with an appropriately filled-\r\n    out parameter block.\r\n\r\n    The standard bios() routine takes 1, 2 or 3 parameters:\r\n\r\n        short bios(int func, int bc, int de)\r\n\r\n    and that is good enough for CP/M 2.2.  However CP/M 3 has functions which\r\n    also take inputs in A and/or HL.  The routine is smart enough to figure\r\n    out where to put the parameters.  All the C programmer needs to do is to\r\n    supply the requisite arguments in the right order.\r\n\r\n    A bug in the 2.2 bios() routine has been fixed.  The original code would\r\n    always return an 8-bit result even though there are some functions which\r\n    return 16-bit results.\r\n\r\n    Under CP/M 3 the calling of the BIOS SELMEM (function 27) is intercepted\r\n    by the BDOS (to prevent you selecting a memory bank that could change the\r\n    memory bank that you are executing from).  Also, if you're using the\r\n    Digital Research banked BDOS then when it invokes a direct BIOS call\r\n    (BDOS function 50) it makes a call to the BIOS MOVE routine to copy the\r\n    parameter block into common memory.  This means you cannot cascade a\r\n    bios() call to XMOVE (function 29) and MOVE (function 25) without\r\n    corrupting memory.  Simeon Cran's ZPM3 banked BDOS replacement does not\r\n    have this restriction.\r\n\r\nbdos()\r\n\r\n    All versions of CP/M 80 return from BDOS calls with BA = HL regardless of\r\n    whether the function is returning an 8-bit or 16-bit result.  Hi-Tech C\r\n    provided a bdos() call for 8-bit results and a bdoshl() call for 16-bit\r\n    results.  John Elliott added a third, bdose(), for disk functions which\r\n    could return extended error codes in H (and B) when running on CP/M 3.\r\n\r\n    There is now a single bdos() function.  It always returns a 16-bit result\r\n    in HL.  The bdoshl() routine still exists for compatibility with older\r\n    source files but it is simply an alias for bdos().  John Elliott's\r\n    bdose() routine no longer exists; bdos() also performs its functions.\r\n\r\n    Some BDOS functions return 255 as an error flag.  The old bdos() code\r\n    would sign-extend that to -1 (16 bit) but that is no longer done.\r\n\r\n        if (bdos(fn, data) == -1)               /* This won't work */\r\n\r\n        if (bdos(fn, data) == 255)              /* This works sometimes */\r\n\r\n        if ((bdos(fn, data) & 0xFF) == 255)     /* This always works */\r\n\r\n    Under CP/M 3 several functions return extended error information in\r\n    the upper 8 bits of the return value.  (Those functions also set the\r\n    standard errno global item.)  Always use the third form when checking\r\n    for an error result.  The compiler is quite clever and doesn't make your\r\n    program work harder ... it just uses the L register.\r\n```\r\n\r\n\r\n## Release v3.09-3\r\n<!-- Mar 4, 2020 -->\r\n\r\nThese are the Jon Saxton modified versions of John Elliott's patches.\r\n\r\n```\r\nWildcard expansion\r\n\r\n    Programs compiled with this update get wildcard expansion of the CP/M\r\n    command line automatically.  There is no longer any need to call\r\n    _getargs() explicitly.\r\n\r\n    Enclosing an argument in quote marks (' or \") supresses expansion.\r\n    This can be useful for programs like grep which may use ? and/or * in\r\n    text search patterns or for program options containing a question mark:\r\n\r\n        grep 'a.*end' *.h 2d:*.c\r\n        grep \"-?\"\r\n\r\n    _getargs() also recognises piping of stdin and stdout using the\r\n    Unix-style >filename (redirect stdout to filename) >>filename\r\n    (append stdout to file) and <filename (read stdin from file).\r\n\r\n    The -R option passed to the Hi-Tech C compiler is no longer useful.  (It\r\n    didn't work anyway.)\r\n\r\n    Implementing automatic argument expansion meant altering the order of\r\n    modules in LIBC.LIB.  That entailed rebuilding the entire library from\r\n    scratch.  A script to do that is supplied.\r\n\r\nFilename drive and user number prefixes\r\n\r\n    The format of file name prefixes indicating drive letter and/or user\r\n    number is now much more liberal.  If a file \"sample.txt\" is on drive\r\n    E: in user area 12 then depending on the current drive/user the file\r\n    may be accessed as:\r\n\r\n        sample.txt              if current DU: is E12:\r\n        12:sample.txt           if current disk is E:\r\n        e:sample.txt            if current user is 12\r\n        e12:sample.txt\r\n        12e:sample.txt\r\n        12:e:sample.txt         (Hi-Tech C format)\r\n\r\n    Note that any of these forms is acceptable for program arguments, even\r\n    those containng wildcard characters (?, *).\r\n\r\nExact file sizes (CP/M 3 and DOS+ v2.5)\r\n\r\n    Exact file sizes are supported on CP/M 3.  Under CP/M 2.2 file sizes are\r\n    always a multiple of 128 bytes but some versions of CP/M allow setting\r\n    and reading a \"last sector byte count\" field in the FCB.  The concept was\r\n    carried forward from CP/M's ancestor, ISIS, but DRI did not document the\r\n    precise meaning of the count for CP/M so two distinct interpretations were\r\n    possible:\r\n\r\n    a.  LSBC represents the number of UNUSED bytes in the last sector;\r\n\r\n    b.  LSBC contains the number of USED bytes but 0 means 128.\r\n\r\n    Both usages have appeared in the small number of CP/M 3 utilities which\r\n    support exact file lengths.  Jon Saxton's tools use the first\r\n    interpretation; John Elliott's utilities use the second.\r\n\r\n    The first interpretation is slightly simpler to implement because it\r\n    avoids any special-case handling.  It is also historically correct.\r\n    Neither of these considerations is particularly significant but we do need\r\n    to have programs which work together and interpret the last sector byte\r\n    count the same way.  After a lifetime in software development I have\r\n    learned to avoid handling special cases as far as possible.  Accordingly\r\n    I have modified John Elliott's routines to interpret the last sector byte\r\n    count as the number of unused bytes in the last sector.\r\n\r\n    With this interpretation the formula for calculating the number of bytes\r\n    in a file is always (sectors * 128) - lsbc.\r\n\r\n    (When running on CP/M 2 lsbc is always zero.)\r\n\r\nNB: This change is now detected automatically for releases v3.09-14 (and\r\n    later) by the start-up module (CRTCPM.OBJ) - see below.\r\n\r\nstrcasecmp()\r\n\r\n    The case-insensitive string comparison function strcasecmp() has been\r\n    implemented.  Its function prototype is in string.h.  It works just like\r\n    strcmp() except that upper- and lower-case letters are treated as \r\n    identical.  There is also a strncasecmp() analogue of strncmp() which\r\n    allows one to limit the comparison to a certain number of characters.\r\n\r\ntoupper() and tolower()\r\n\r\n    The functions toupper() and tolower() were implemented as macros which\r\n    added a case-shift value to the character parameter without checking to\r\n    see if the parameter was a letter.  To use these routines correctly it was\r\n    necessary to do a range check, e.g.\r\n\r\n        if (isupper(c))\r\n            c = tolower(c);\r\n\r\n    These operations now invoke the correspondingly named routines in LIBC.LIB\r\n    and it is no longer necessary to pre-test the character.\r\n\r\nSupport for read/write files\r\n\r\n    The stdio functions now allow files to be opened in modes \"r+\" and \"w+\" - \r\n    ie, reading and writing are supported on the same file.\r\n    Remember to fflush() or fseek() between a read and a write.\r\n    This code is experimental.\r\n\r\nPIPEMGR support (CP/M 3)\r\n\r\n    Programs automatically check for PIPEMGR when they load, and if it\r\n    is present the C streams stdin, stdout and stderr are routed to their\r\n    PIPEMGR counterparts - no modification of the source is required.\r\n\r\n    The special device files (CON: LST: PUN: and RDR:) are joined by RSX: \r\n    (PIPEMGR stdin/stdout streams) and ERR: (PIPEMGR stderr stream). If\r\n    PIPEMGR is not present, these files behave like CON:\r\n\r\n    The variable:\r\n\r\n        extern char _piped;\r\n\r\n    is nonzero if PIPEMGR is present.\r\n\r\n    The command \r\n\r\n        FOO <CON:\r\n\r\n    will behave differently if PIPEMGR is present. If it is not present,\r\n    then you get line-based input from the Hi-Tech C library. If PIPEMGR\r\n    is present then you get character-based input from PIPEMGR.\r\n\r\n    The line-based input in the library will now return EOF if a control-Z\r\n    is typed on a line by itself. Previously it would never return EOF on \r\n    line-based input.\r\n\r\n    Unfortunately if you're using Simeon Cran's replacement ZPM3 then it\r\n    does not allow control-Z to be typed on an input line.\r\n    I'm not yet sure how to get round this.\r\n  \r\n    Remember that when PIPEMGR has parsed the command line, you may have a \r\n    number of blank (zero-length) arguments.\r\n\r\nCP/M 3 extended error support\r\n\r\n    To enable CP/M 3 extended error support, put the line\r\n\r\n        bdos(0x2D,0xFF);\r\n\r\n    near the beginning of your program. Then errors such as read-only files \r\n    will not cause the program to terminate abruptly; instead the call which\r\n    caused the error will fail, and perror() will explain the reason. The \r\n    variable:\r\n\r\n        extern int errno;\r\n\r\n    will contain (16+x) for CP/M 3 extended error x.\r\n\r\nFile passwords (CP/M 3)\r\n\r\n    NB: This feature is disabled.  You will need to change the\r\n        PWDREC definition in the file BDOS.AS to true and rebuild\r\n        and replace the module in LIBC.LIB to enable it.\r\n\r\n    There is partial support for file passwords. To enable it, declare a \r\n    function:\r\n\r\n        #include <cpm.h>\r\n\r\n        char *mypass(struct FCB *fcb)\r\n        {\r\n        /* For the file specified by \"fcb\", a password needs to be entered.\r\n           Return a pointer to it (8 characters, uppercase, packed with\r\n           spaces) \r\n         */\r\n        }\r\n\r\n    and insert a line near the beginning of your program:\r\n\r\n        _passwd = mypass;\r\n\r\n    Then your routine (\"mypass\" in this example) will be called when\r\n    CP/M reports a password error; it will be called repeatedly until\r\n    the user enters the correct password or a it returns a NULL pointer\r\n    (ie, the user has given up).\r\n\r\nChecks for a ZCPR3 environment\r\n\r\n    The variable\r\n\r\n        extern void *_z3env;\r\n\r\n    is 0 if one is not present, or its address if one is. It also passes it\r\n    as a third parameter to main():\r\n\r\n        int main(int argc, char **argv, void *z3env);\r\n\r\n    The Z3 environment address must be passed to the program in HL.\r\n\r\nGraceful exits\r\n\r\n    Compiled programs exit gracefully if run on an 8080 or 8086 processor,\r\n    or if there is not enough memory for the program and its static data.\r\n    This is done in the CRTCPM.OBJ module.\r\n\r\nCP/M 3 compatible error system\r\n\r\n    exit(0) and _exit(0) set the CP/M 3 error code to 0.\r\n    exit(n) and _exit(n) for non-zero n set the error code to 0xFF00 | (n&0x7F).\r\n\r\n    The practical upshot is that exit(0) translates as \"OK\"; other values \r\n    translate as \"error\". You can use this in conjunction with CP/M 3's\r\n    SUBMIT features.  If the next command in a .SUB file is preceded by\r\n    a : character, it will be ignored:\r\n\r\n        CPROG \r\n        :OTHER\r\n\r\n    will only execute OTHER if CPROG exited with the value 0.\r\n\r\nExtended getenv()\r\n\r\n    Under CP/M 3, getenv() uses the search path set by SETDEF to locate the\r\n    ENVIRON file. So if you like to keep ENVIRON on a drive that isn't A:, \r\n    programs will still find it.\r\n```\r\n\r\n\r\n## Release v3.09-3b\r\n<!-- Mar 5, 2020 -->\r\n\r\nUpdated the previous release to adjust the ordering of modules in LIBC.LIB -\r\nprograms should now link correctly.  Also added the missing documentation for\r\nthe debugger in doc/DEBUGMAN.TXT (this was previously available from the\r\nnow defunct hitech.com.au web site) and scanned PDFs of the 1989\r\nvintage documentation.\r\n\r\n\r\n## Release v3.09-4\r\n<!-- Mar 8, 2020 -->\r\n\r\nSome of the string related function prototypes in STRING.H are missing from\r\nthe LIBC.LIB library.  Most of these are from an update to the MSX flavour\r\nof HI-TECH C by Arnold Metsalaar.  I've cherry-picked the following routines\r\nwhich are applicable to generic CP/M as well as MSX.\r\n\r\n```\r\nSTRING.H\r\n    The header file has been changed to reflect the available\r\n    functions in LIBC.LIB.  There are still missing routines -\r\n    namely strcoll() strcspn() strpbrk() and strspn() and these\r\n    have been commented out for now.\r\n\r\nstrchr() and strrchr()\r\n        char *strchr(char *s, int c)\r\n        char *strrchr(char *s, int c)\r\n    These functions - as well as index() and rindex() (which are identical)\r\n    previously returned a NULL for no match.  The functions now return\r\n    a pointer to the character string's ending NUL character.\r\n\r\nstricmp() and strnicmp()\r\n        char stricmp(char *s1, char *s2)\r\n        char strnicmp(char *s1, char *s2, size_t n)\r\n    Case-insensitive versions of strcmp() and strncmp() comparison routines.\r\n    Can also be referenced as strcasecmp() and strncasecmp().\r\n\r\nstrstr(), strnstr(), stristr() and strnistr()\r\n        char *strstr(char *t, char *s)\r\n        char *strnstr(char *t, char *s, unsigned int n)\r\n        char *strcasestr(char *t, char *s)\r\n        char *strncasestr(char *t, char *s, unsigned int n)\r\n    These extra functions locate the first occurrence of string s in\r\n    string t.  The functions strnstr() and strcasestr() read at most\r\n    n characters from the string t.  The functions strcasestr() and\r\n    strncasestr() use case insensitive comparisons.\r\n    All these functions return a pointer to the first character of\r\n    the first occurence of string s in string t if found, and NULL\r\n    otherwise.\r\n\r\nstrdup()\r\n        char *strdup(char *s)\r\n    Allocates a new buffer for and copies the string pointed to\r\n    by s to it.  Returns a pointer to the copy of the string or NULL\r\n    if the memory allocation failed. The memory block can be released\r\n    using free().\r\n\r\nstrtok()\r\n        char *strtok(char *s, char *tok, size_t toklen, char *brk)\r\n    Copies characters from s to tok until it encounters one of the\r\n    characters in brk or until toklen-1 characters have been copied\r\n    (whichever comes first).  It then adds a NUL character to the\r\n    end of the string.  This is a non-conforming POSIX function.\r\n\r\nTIME.H\r\n    Now includes a prototype for strftime() - see below.\r\n\r\nstrftime()\r\n        size_t strftime(char *s, size_t maxs, char *f, struct tm *t)\r\n    Converts a time value t to a string using the format string f\r\n    into the string s of size maxs (including a terminating NUL).\r\n    It acts as a sprintf() function for date/time values. The\r\n    following are valid in the format string -\r\n\r\n             %A      full weekday name (Monday)\r\n             %a      abbreviated weekday name (Mon)\r\n             %B      full month name (January)\r\n             %b      abbreviated month name (Jan)\r\n             %c      standard date and time representation\r\n             %d      day-of-month (01-31)\r\n             %H      hour (24 hour clock) (00-23)\r\n             %I      hour (12 hour clock) (01-12)\r\n             %j      day-of-year (001-366)\r\n             %M      minute (00-59)\r\n             %m      month (01-12)\r\n             %p      local equivalent of AM or PM\r\n             %S      second (00-59)\r\n             %U      week-of-year, first day sunday (00-53)\r\n             %W      week-of-year, first day monday (00-53)\r\n             %w      weekday (0-6, sunday is 0)\r\n             %X      standard time representation\r\n             %x      standard date representation\r\n             %Y      year with century\r\n             %y      year without century (00-99)\r\n             %Z      timezone name\r\n             %%      percent sign\r\n\r\n    the standard date string is equivalent to:\r\n\r\n        %a %b %d %Y\r\n\r\n    the standard time string is equivalent to:\r\n\r\n        %H:%M:%S\r\n\r\n    the standard date and time string is equivalent to:\r\n\r\n        %a %b %d %H:%M:%S %Y\r\n\r\n    strftime() returns the number of characters placed in the\r\n    buffer, not including the terminating NUL, or zero if more\r\n    than maxs characters were produced.\r\n```\r\n\r\n## Release v3.09-4-Z280\r\n<!-- Mar 8, 2020 -->\r\n\r\nThis is the first experimental release of the libraries that have been\r\nbuilt for a Zilog Z280 MPU.  Most of this work was retrieved from a\r\ndistribution of the UZI-280 operating system for the CPU280 system.\r\nIt was written by Stefan Nitschke and Alexander Schmid.\r\n\r\nTo use this on a system with a Zilog Z280 MPU, merge the files from the\r\n*dist* folder (i.e. the Z80 version) with those from the *z280dist*\r\nfolder onto a drive in the search path (usually drive A in user area 0).\r\nOn CP/M 3 the *.COM, *.H, CRTCPM.OBJ and the *.LIB files should be\r\nset with the system file attribute so they can be found from all user\r\nareas.\r\n\r\nThe *z280dist* folder contains the following files -\r\n\r\n```\r\nC280.COM\r\n    The compiler front-end for driving the HI-TECH Z80 C compiler\r\n    for CP/M to produce code to run on a Zilog Z280 MPU.  It accepts\r\n    command lines similar to the C.COM front-end from the *dist*\r\n    folder - with a modified command-line switch to perform optimisation\r\n    of generated assembly language to use the enhanced Z280 instructions.\r\n    You can optimise for size (-O2) or speed (-OF2). For example,\r\n\r\n        c280 -of2 ...\r\n\r\n    will cause the OPTIMH.COM pass to perform speed optimisation.\r\n\r\nOPTIMH.COM and OPTIMH.C\r\n    This is the Z280 assembly language optimiser (with source-code).\r\n    The following instructions are optimised -\r\n\r\n        call amul        -> multw hl,de\r\n\r\n        call lmul        -> multuw hl,de\r\n\r\n        call csv         -> push iy, push ix, lda ix,(sp+0)  (+6 bytes)\r\n\r\n        jp cret          -> ld sp,ix pop ix pop iy ret (+6 bytes)\r\n\r\n        ld  (hl),c\r\n        inc hl           -> ldw (hl),bc\r\n        ld  (hl),b       -> inc hl\r\n\r\n        ld  (hl),e\r\n        inc hl           -> ldw (hl),de\r\n        ld  (hl),d       -> inc hl\r\n\r\n        ld  c,(hl)\r\n        inc hl           -> ldw bc,(hl)\r\n        ld  b,(hl)       -> inc hl\r\n\r\n        ld  e,(hl)\r\n        inc hl           -> ldw de,(hl)\r\n        ld  d,(hl)       -> inc hl\r\n\r\n        ld  c,(ix+n)     or iy\r\n        ld  b,(ix+n+1)   -> ldw bc,(ix+n)    (2 byte)\r\n\r\n        ld  e,(ix+n)     or iy\r\n        ld  d,(ix+n+1)   -> ldw de,(ix+n)    (2 byte)\r\n\r\n        ld  l,(ix+n)     or iy\r\n        ld  h,(ix+n+1)   -> ldw hl,(ix+n)    (2 byte)\r\n\r\n        ld  (ix+n),c     or iy\r\n        ld  (ix+n+1),b   -> ldw (ix+n),bc    (2 byte)\r\n\r\n        ld  (ix+n),e     or iy\r\n        ld  (ix+n+1),d   -> ldw (ix+n),de    (2 byte)\r\n\r\n        ld  (ix+n),l     or iy\r\n        ld  (ix+n+1),h   -> ldw (ix+n),hl    (2 byte)\r\n\r\n        or  a\r\n        sbc hl,bc        -> subw hl,bc       (1 byte)\r\n\r\n        or  a\r\n        sbc hl,de        -> subw hl,de       (1 byte)\r\n\r\n        push  ix\r\n        pop   de\r\n        ld    hl,nn\r\n        add   hl,de      -> lda hl,(ix+nn)   (3 byte)\r\n\r\n        push  ix         -> ld  e,ixl\r\n        pop   de         -> ld  d,ixh\r\n\r\n        push  ix\r\n        pop   hl         -> lda hl,(ix+0)\r\n\r\n    In addition memory addressing with large offset -\r\n\r\n        push  ix\r\n        pop   de\r\n        ld    hl,nn\r\n        add   hl,de      -> lda hl,(ix+nn)   (3 byte)\r\n\r\n        push\tiy\r\n        pop\tde\r\n        ld\thl,nn\r\n        add\thl,de\t-> lda\thl,(iy+nn)  (3 byte)\r\n\r\nLIB280C.LIB and LIB280F.LIB\r\n    These are the library modules for the Z280 C run-time library\r\n    and floating point library that contain optimised Z280 routines.\r\n    These will only execute on a Z280 MPU - and not on a Z80!\r\n    They have been built from sources of the v3.09-4 release.\r\n\r\n```\r\n\r\n## Not actually a release - but including MSX-DOS 2 distribution\r\n<!-- Apr 17, 2020 -->\r\n\r\nI'm making available the raw updates for MSX-DOS 2 for those interested in\r\nthe last known updates to run HI-TECH C for Z80 under MSX2.  You'll\r\nfind the individual files in the msx2dist folder and its sub-folders.\r\n\r\nThese were extracted from files produced by Arnold Metselaar in 2013 and\r\ndistributed as LZH archives on the MSX Banzai web site at\r\nhttp://msxbanzai.tni.nl/dev/software.html\r\n\r\nOne of these archive files is known to be damaged - the one containing the\r\nI/O library for MSX-DOS 2 (LDOS2_04.LZH) and I have replaced the source\r\ncode for only one of the modules with that from an earlier version obtained\r\nfrom the Wayback machine at archive.org.  There's still \r\na missing (_UTIME.AS) that I'll try to re-assemble from the binary\r\nin the cc_01/LIBDOS2.LIB library. \r\n\r\nThe msx2dist/original folder contains the as-downloaded .LZH archives\r\n(including the previous versions from archive.org).\r\n\r\nAlso note that Yeongman Seo is currently working on a toolchain for developing\r\nMSX-DOS/DOS 2 applications using the HI-TECH Z80 C compiler under a\r\nWindows Win32 environment.  This is available on GitHub at\r\n\r\nhttps://github.com/sharksym/CPMEMU_HI-TECH_C\r\n\r\n\r\n## Fix to getenv()\r\n<!-- May 24, 2020 -->\r\n\r\nThe getenv() function was not correctly looking up the location of\r\nthe environment file under CP/M 3 for the \"default\" entry in the drive\r\nsearch chain.  It will now locate the ENVIRON file if you have set-up\r\nthe default search chain with a default entry. For example\r\n\r\n```\r\n; Set search chain to current drive, RAMdisk, C: then A:\r\nsetdef * m: c: a:\r\n```\r\n\r\nin your CP/M 3 PROFILE.SUB file (or manually entered on the command line).\r\n\r\nUpdated dist/LIBC.LIB and z280dist/LIBC280.LIB too.\r\n\r\n\r\n## General tidy-up and Overlay capability\r\n<!-- Jun 3, 2020 -->\r\n\r\nUpdates merged from @tsupplis\r\n\r\nRon Murray's overlay capabilities have been added, along with some\r\nmiscellaneous fixes - mainly to the CP/M BDOS definitions in CPM.H\r\nand to fix an incompatibility with conflicting _TIME macros in both\r\nTIME.H and CPM.H\r\n\r\n\r\n## Release V3.09-5\r\n<!-- Jun 3, 2020 -->\r\n\r\nRebuilt libraries LIBC.LIB and LIBF.LIB (as well as LIB280C.LIB and\r\nLIB280F.LIB for the Z280).  New snapshot as Release V3.09-5.\r\n\r\n\r\n## Fix CRTCPM.OBJ start-up module\r\n<!-- Jun 12, 2020 -->\r\n\r\nThe CP/M start-up module CRTCPM.OBJ was not checking the CP/M version\r\nprior to checking for the existence of the PIPEMGR RSX.  This caused\r\ncompiled programs under CP/M 2.2 to fail to initialise correctly.\r\n\r\nA new version of CRTCPM.OBJ is available (and the source-code in\r\nZCRTCPM.AS has been updated to correct this).\r\n\r\n\r\n## Add source for DEHUFF and ENHUFF\r\n<!-- Dec 13, 2020 -->\r\n\r\nAndrey Nikitin has contributed the sources for the DEHUFF and ENHUFF\r\nprograms that were used by HI-TECH Software to distribute the library\r\nsource files.  I've placed the extracted source files and the resulting\r\nbinary produced by the latest compiler in the *huff* folder. Also,\r\nthe Huffman-encoded archive containing these sources has been placed\r\nin the *dist* folder as HUFF.HUF.  There's also an original version\r\nthat produces some diagnostic errors in HUFFORIG.HUF.\r\n\r\nThese sources may be built using the HI-TECH C compiler or using the\r\ngcc compiler under Linux or macOS.  I built them natively under CP/M\r\nusing -\r\n\r\n```\r\nc -O -v enhuff.c encode.c misc.c\r\nc -O -v dehuff.c decode.c misc.c\r\n```\r\n\r\n(If you're using a Z280 use 'c280 -of2 -v ...')\r\n\r\n\r\n## Change supported string length in printf() routine\r\n<!-- Jan 5, 2021 -->\r\n\r\nMerged a minor change into stdio/DOPRNT.C from @tupplis so that various\r\nprintf() routines can now output strings greater than 255 characters.\r\n\r\nUpdated the dist/LIBC.LIB and z280dist/LIB280C.LIB libraries too\r\nand created a new v3.09-6 release to consolidate the recent updates.\r\n\r\n\r\n## Release V3.09-6\r\n<!-- Jan 6, 2021 -->\r\n\r\nUpdated the cpm/C.C source to include the V3.09-6 identifier and\r\nsupply a pre-compiled version in dist/C309-6.COM that can be copied\r\nto the CP/M system path (usually drive A in user area 0) as C.COM\r\n\r\nAlso included a version of the start-up code for the Z280 under CP/M\r\nas z280dist/CRTCPM.OBJ \r\n(with source-code in z280dist/Z280CPM.AS).  This checks whether\r\nthe compiled binary is running on a Z280 MPU.\r\n\r\n\r\n## PIPEMGR sources\r\n<!-- Jan 8, 2021 -->\r\n\r\nI've included Jon Saxton's version of the PIPEMGR RSX for handling\r\npipes under CP/M 3.\r\n\r\nThis is a modified version of the original by John Elliott that's\r\ndetected and used by each of the releases of HI-TECH C available\r\nfrom this repository.\r\n\r\nYou'll find the original PIPEMGR.ARC distribution from Tesseract\r\nvolume 089, a PIPEMGR.LBR containing the same files and individual\r\nextracted files in the *pipemgr* folder.\r\n\r\nAlso included is the source and executable for TEE which has the\r\nPIPEMGR RSX attached and behaves like its namesake in the Unix world,\r\nalong with missing files from the original Van Nuys tools\r\n(PIPEMGR.H and PIPEMGR.C).\r\n\r\nThe rest of the Van Nuys tools are available from John Elliott's\r\noriginal PIPEMGR page at\r\n\r\nhttp://www.seasip.info/Cpm/software/Pipemgr/index.html\r\n\r\n\r\n## Self-relocating .COM program PIPEMGR integration\r\n<!-- Jan 8, 2021 -->\r\n\r\n@tsupplis provided updates to the self-relocating image start-up module\r\nto support the improvements from the standard CP/M start-up (in CRTCPM.OBJ).\r\nThe source changes are in cpm/ZRRTCPM.AS and the compiled object replaces\r\ndist/RRTCPM.OBJ\r\n\r\nTo build a self-relocating image, use the -A compile option.\r\n\r\n\r\n## Minor issues\r\n<!-- Jan 10, 2021 -->\r\n\r\n* Declaration for rename() missing from dist/UNIXIO.H\r\n\r\n* Make CPU check in the start-up modules consistent.  Output\r\nmessage for Z80 (or Z280 MPU) if the incorrect processor is\r\ndetected. For example -\r\n```\r\nThis CP/M program requires a Z80 CPU.\r\n```\r\n\r\n* Include the modified floating-point version of float/DOPRNT.AS\r\nto support outputting strings greater than 255 characters by the\r\nvarious printf() routines.\r\n\r\n* With @tsupplis provided fix for the compiler front-end dist/C309-7.COM\r\nnow handles input correctly from submit files - resolving issue #9.\r\nUpdated dist/SIGNAL.H, cpm/SIGNAL.C, cpm/C.C and stdio/GETARGS.C\r\n(a mix of input from and output to the console device stream was\r\npreviously discarding input from CP/M 3 submit files). \r\n\r\n* The start-up modules have been corrected to properly\r\nreport an error when run under MS-DOS. (Previously the assembly language\r\nroutine was incorrectly being optimised - and an absolute jump was\r\nchanged to a relative branch).\r\n\r\n* Updated both dist/LIBC.LIB and dist/LIBF.LIB object libraries\r\nand the Z280 ones in z280dist/LIB280C.LIB and z280dist/LIB280F.LIB.\r\n\r\n* Include dist/STDINT.H for some standard type definitions (and referenced\r\nby the overlay support routine).\r\n\r\n\r\n## MS-DOS cross-compiler available\r\n<!-- Jan 13, 2021 -->\r\n\r\nRecently Microchip Technology Inc. (the current owners of the HI-TECH\r\nintellectual property) also released the MS-DOS version of the HI-TECH\r\nC Compiler v4.11 - a cross-compiler for building CP/M and ROM-able\r\nprograms for the Z80 using MS-DOS.  I've uploaded this version to\r\nGitHub at\r\n\r\nhttps://github.com/agn453/HI-TECH-Z80-C-Cross-Compiler\r\n\r\n\r\n## Release v3.09-7\r\n<!-- Jan 14, 2021 -->\r\n\r\nThanks to @tsupplis, the following enhancements are now available\r\nin the latest release v3.09-7.\r\n\r\n* The compiler front end now supports building CP/M programs using overlays.\r\nJust copy the dist/C309-7.COM to your system directory as C.COM, along\r\nwith the symbol table builder dist/SYMTOAS.COM and overlay support library\r\ndist/LIBOVR.LIB.\r\n\r\nTo build a program with overlays, specify the -F option when compiling\r\nthe resident part of the main program (which writes a symbol file) and -Lovr\r\nto use the ovrload() routine; and for each of the overlay segments compile\r\nusing the -Y option and specify the symbol file on the\r\ncommand line.  For example (these files are in the *test* folder too) --\r\n\r\n```\r\nFirstly the simple main program\r\n\r\nA>type TESTOVR.C\r\n#include <cpm.h>\r\n#include <stdio.h>\r\n#include <overlay.h>\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    intptr_t i;\r\n    printf(\"overlay test\\n\");\r\n    i=ovrload(\"testovr1\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    i=ovrload(\"testovr1\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    i=ovrload(\"testovr2\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    i=ovrload(\"testovr1\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    return 0;\r\n}\r\n\r\nA>type testovr1.c\r\nvoid * yop(void *a) {\r\n    printf(\"hello from overlay 01\\n\");\r\n    return 0;\r\n}\r\n\r\nA>type testovr2.c\r\nvoid * yop(void *a) {\r\n    printf(\"hello from overlay 02\\n\");\r\n    return 0;\r\n}\r\n\r\nA>c -ftestovrx.sym -o testovr.c -lovr                                         \r\nA:C        COM  (User 0)                                                        \r\nHi-Tech C Compiler (CP/M-80) V3.09-7                                            \r\nCopyright (C) 1984-87 HI-TECH SOFTWARE                                          \r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C                            \r\n                                                                                \r\nA>c -y -o testovr1.c testovrx.sym                                             \r\nA:C        COM  (User 0)                                                        \r\nHi-Tech C Compiler (CP/M-80) V3.09-7                                            \r\nCopyright (C) 1984-87 HI-TECH SOFTWARE                                          \r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C                            \r\nTESTOVR1.C                                                                      \r\nTESTOVRX.SYM\r\n\r\nA>>c -y -o testovr2.c testovrx.sym                                             \r\nA:C        COM  (User 0)                                                        \r\nHi-Tech C Compiler (CP/M-80) V3.09-7                                            \r\nCopyright (C) 1984-87 HI-TECH SOFTWARE                                          \r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C                            \r\nTESTOVR2.C                                                                      \r\nTESTOVRX.SYM                                                                    \r\n                                                                                \r\nA>testovr                                                                     \r\nA:TESTOVR  COM                                                                  \r\noverlay test                                                                    \r\nhello from overlay 01                                                           \r\noverlay return is 0                                                             \r\nhello from overlay 01                                                           \r\noverlay return is 0                                                             \r\nhello from overlay 02                                                           \r\noverlay return is 0                                                             \r\nhello from overlay 01                                                           \r\noverlay return is 0                                                             \r\n                                                                                \r\nA>\r\n```\r\n\r\n* There are additional testing programs added to the *test* folder along\r\nwith the output of a testing run in test/TEST.LOG that was generated on\r\na CP/M 3 system.\r\n\r\n* Since wildcard expansion using _getargs() has been supported since\r\nv3.09-3, it is no longer necessary to use the -R option.  This is now\r\ndeprecated and ignored if you use it on the command line.\r\n\r\n* A new -H option may be specified to obtain help with the command-line\r\noptions.  It types out the system's OPTIONS file - so be sure this is\r\ncopied from the dist folder to the system directory (usually drive A:\r\nin user area 0, and marked with the SYS and RO attributes).\r\n\r\n\r\n## Minor Updates\r\n<!-- Jan 15, 2021 -->\r\n\r\nAddressing some minor changes from issue #18 -\r\n\r\n* A description of the -E option was missing from the dist/OPTIONS help\r\nmessage file.\r\n\r\n* For CP/M emulators the options emitted by the compiler front-end have\r\nbeen adjusted to be consistently in uppercase.\r\n\r\n* Report an error if the OPTIONS file can't be found (for the -H help text).\r\n\r\nI've re-issued this as a revised v3.09-7b release too.\r\n\r\n\r\n## Release v3.09-8 (support for Z280 MPU)\r\n<!-- Jan 15, 2021 -->\r\n\r\nThe compiler front-end source in cpm/C.C has been updated so that it\r\ncan be compiled to produce a Z280 MPU version.  Co-existence with the Z80\r\nversion is now also possible due to the renaming of the various Z280 versions\r\nstart-up modules to C280CPM.OBJ, D280CPM.OBJ and R280CPM.OBJ.\r\n\r\nThe original source-code to the C280 front-end is lost (not included with the\r\nUZI-280 distribution files) - so now Z280 users (like me) have the updated\r\nversion supporting overlays etc.  The original binary from the UZI-280\r\ndistribution is in the file z280dist/C280ORIG.COM\r\n\r\nYou'll find updated Z280 files in the *z280dist* folder.  The\r\nz280dist/C280-8.COM is the new front-end and can be copied to the system\r\ndrive as C280.COM.  It tests for, and will only run on a Z280 MPU.\r\nBe sure to copy the start-up object modules (?280CPM.OBJ files) and\r\nthe z280dist/LIB280*.LIB libraries to the system drive too.\r\n\r\nThis is also a new release milestone at v3.09-8.\r\n\r\n\r\n## Minor fixes\r\n<!-- Jan 15, 2021 -->\r\n\r\n* Minor change to allow size optimization (-O2 switch) for Z280.\r\n\r\n\r\n## Easy binary download\r\n<!-- Jan 17, 2021 -->\r\n\r\nInclude an easy-download CP/M library file containing the binary\r\ndistribution (all the files you need from the *dist* folder to get it\r\nrunning under CP/M).\r\n\r\nDownload this from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/htc-bin.lbr\r\n\r\nand extract the files using one of the CP/M .LBR extraction tools, e.g.\r\n[NULU.COM](https://raw.githubusercontent.com/agn453/Z280RC/master/utilities/NULU.COM).\r\n\r\n\r\n## Minor update\r\n<!-- Jan 17, 2021 -->\r\n\r\n* Revert change defining \"Z80\" symbol back to the lowercase form \"z80\"\r\nin the main driver.  There are some inconsistencies with how this is used\r\nin the other compiler modules - and in the library sourcefiles.\r\n\r\n\r\n## Z280 optimizer speed/size\r\n<!-- Jan 18, 2021 -->\r\n\r\n* Modify z280/OPTIMH.C and the front-end driver to select between size\r\nand speed optimisations.  Previously some additional code was added to\r\nunroll calls to the csv() routine and jumps to cret() into inline-code.\r\nOPTIMH now accepts a -F option to include them (for faster code), else\r\nit omits them for reduced code-size.  This is selected by using the -OF2\r\nand -O2 option to the C280 front-end.\r\n\r\n\r\n## Old files removed\r\n<!-- Jan 19, 2021 -->\r\n\r\nUp until now, I've kept various replaced files in this repository\r\nby renaming them to include a hash (or octothorpe) \"#\" character\r\nin their names.  They have now been removed to avoid confusion.\r\nGitHub is already tracking changes for us - and comparing commits\r\nwill show them from now on!  If you need to refer to them you can\r\ndownload one of the previous releases.\r\n\r\n\r\n## Decompilation of CGEN.COM\r\n<!-- Feb 5, 2021 -->\r\n\r\nAndrey Nikitin has made available a decompilation of the HI-TECH C V3.09\r\ncode generation program CGEN.COM based on work by himself and\r\na group of Russian enthusiasts.\r\n\r\nYou'll find this at\r\n\r\nhttps://github.com/nikitinprior/dcgen\r\n\r\n\r\n## bios() routine restrictions\r\n<!-- Mar 18, 2021 -->\r\n\r\nIssue #24 raised a limitation with calling the bios() function to perform\r\ninter-bank memory moves using the CP/M 3 BIOS XMOVE and MOVE routines\r\n(function 29 and 25).  I've updated the description for bios() above to\r\ndocument this and the SELMEM (function 27) restriction.\r\n\r\n\r\n## Incomplete prototype definitions in TIME.H\r\n<!-- Mar 20, 2021 -->\r\n\r\nAs per issue #25 - corrected the function prototype definitions in\r\ndist/TIME.H for ctime(), gmtime() and localtime().  Updated the\r\nhtc-bin.lbr binary distribution library archive file too.\r\n\r\n\r\n## More work on decompiling CPP.COM\r\n<!-- Mar 29, 2021 -->\r\n\r\nAndrea Nikitin has posted some more decompiled source-code for the\r\nC pre-processor (CPP.COM) and a revised pre-processor for the compiler\r\nthat supports C++ style comments.  You can get this from his GitHub\r\nrepository at\r\n\r\nhttps://github.com/nikitinprior/dcpp\r\n\r\n\r\n## Historical version 1.3 added\r\n<!-- Jun 7, 2021 -->\r\n\r\nI've added a CP/M library format file containing the HI-TECH C COMPILER V1.3\r\nfor Z80 CP/M in the *historical* folder.  The files in\r\n[historical/HTC13.LBR](https://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/historical/HTC13.LBR)\r\ncan be extracted using one of the CP/M library utilities like\r\n[NULU.COM](https://raw.githubusercontent.com/agn453/Z280RC/master/utilities/NULU.COM),\r\nand are from the original\r\neight-inch floppy disk distribution media that I purchased in 1984.\r\n\r\nAndrey Nikitin noticed that this version has an object file dump utility that\r\ncan decode the HI-TECH C Z80 object file format.  He's done a disassembly\r\nand reconstruction of this utility that you can get from his GitHub\r\nrepository at\r\n\r\nhttps://github.com/nikitinprior/ddump\r\n\r\n\r\n## Object librarian source-code reconstructed\r\n<!-- Aug 4, 2021 -->\r\n\r\nAndrey Nikitin has managed to reconstruct the C language source for the\r\nobject-code librarian program LIBR.COM by disassembling the program.  You'll\r\nfind this in his repository at\r\n\r\nhttps://github.com/nikitinprior/dlibr\r\n\r\n\r\n## v3.09-9 update release\r\n<!-- Aug 16, 2021 -->\r\n\r\nI've added a mktime() routine to the C library (LIBC.LIB and LIB280C.LIB)\r\nand consolidated the recent updates as a release v3.09-9.\r\n\r\n\r\n```\r\nmktime()\r\n\r\n        time_t mktime(struct tm *)\r\n\r\n    A routine to convert the broken out time (in the structure pointed\r\n    to by the parameter) into a time value representing the number\r\n    of seconds since the Unix epoch (since CP/M has no knowledge of the\r\n    local timezone - the time is assumed to be respresenting Universal\r\n    Coordinated Time or UTC).  The value returned is the number of\r\n    seconds since midnight 01-Jan-1970.\r\n\r\n    This can be used (for example) to manipulate a file's time-stamp\r\n    or for computing time differences.\r\n\r\n    External declarations, as well as the tm structure definition, are\r\n    contained in the TIME.H include file.  The tm structure includes\r\n    at least the following fields:\r\n\r\n           int tm_sec;     /* seconds (0 - 60) */\r\n           int tm_min;     /* minutes (0 - 59) */\r\n           int tm_hour;    /* hours (0 - 23) */\r\n           int tm_mday;    /* day of month (1 - 31) */\r\n           int tm_mon;     /* month of year (0 - 11) */\r\n           int tm_year;    /* year - 1900 */\r\n           int tm_wday;    /* day of week (Sunday = 0) */\r\n           int tm_yday;    /* day of year (0 - 365) */\r\n           int tm_isdst;   /* is summer time in effect? */\r\n```\r\n\r\n\r\n## CPM.H header file update\r\n<!-- Aug 16, 2021 -->\r\n\r\n* Added a few missing bdos() function constants for CP/M 3, MP/M, ZSDOS\r\nand ZPM3.\r\n\r\n* I forgot to include the testing logs (in the *test* folder)\r\n\r\n* Add -Y description to dist/OPTIONS file.\r\n\r\n\r\n## Reconstructed source for OPTIM.COM\r\n<!-- Nov 12, 2021 -->\r\n\r\nAndrey Nikitin and Mark Ogden have been busy.  They've reconstructed the\r\nC source-code for the Z80 code optimiser.  You'll find it at\r\n\r\nhttps://github.com/nikitinprior/doptim\r\n\r\n\r\n## Fix to fgets routine\r\n<!-- Dec 19, 2021 -->\r\n\r\nReported by Mark Ogden, the fgets() library routine (in LIBC.LIB and\r\nLIB280C.LIB) has been updated to prevent a character string\r\nterminator (NULL) from being written to outside the buffer bounds.\r\n\r\nYou can update just the object library file, or fetch and extract the\r\nfiles from the updated binary distribution from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/htc-bin.lbr\r\n\r\n\r\n## Bundle up the Z280 distribution\r\n<!-- Dec 28, 2021 -->\r\n\r\nI've added a binary Z280 distribution library file too.  Get it from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/z280bin.lbr\r\n\r\nJust extract the contents to your system drive (A:) and set them\r\nwith the SYS file attribute (so they are accessible from all user\r\nareas and via the CP/M 3 search path).\r\n\r\n\r\n## C front-end fixes and new V3.09-10 update release\r\n<!-- Dec 30, 2021 -->\r\n\r\nMark Ogden has supplied some fixes to the C front-end so that it can process\r\nlong command lines (particularly when wildcard expanded filename are\r\nspecified).  I've also added a minor change to the Z280 front-end to use\r\nthe C280OPTS file when help (-H) is requested from the C280 command.\r\n\r\nThe new release V3.09-10 consolidates all the changes since V3.09-9.  As\r\nusual, updated binary distribution libraries are available too.\r\n\r\n\r\n## Fix to pre-processor assembly language output\r\n<!-- Jan 3, 2022 -->\r\n\r\nA long-standing bug with the generation of Z80 assembly\r\nlanguage output containing the C source-code as comments\r\n(when using the -S command-line option without optimisation)\r\nhas been fixed.  A replacement C309-10.COM (and C280-10.COM)\r\nis available - and the source-code in cpm/C390-10.C has been\r\nupdated.  Thanks to Andrey Nikitin for reporting this.\r\n\r\n\r\n## Inclusion of object-code and symbol-table documentation\r\n<!-- Jan 4, 2022 -->\r\n\r\nOn the Internet archive WayBackMachine, I found some documentation\r\ndescribing the HI-TECH object-code (.OBJ) and symbol-table (.SYM) file\r\nformats in the ZIP archive\r\n[symfiles.zip](https://web.archive.org/web/19980205193245fw_/http://www.hitech.com.au/software/tech_docs.html).\r\n\r\nI've extracted the old MS-Word format files and converted them to ASCII text\r\nin the\r\n[doc/OBJCODE.TXT](https://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/doc/OBJCODE.TXT)\r\nand\r\n[doc/SYMFILE.TXT](https://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/doc/SYMFILE.TXT)\r\nfiles.\r\n\r\n\r\n## Work-around compiler bug\r\n<!-- Jan 5, 2022 -->\r\n\r\nPassing a pointer to a function parameter can give rise to a warning\r\nor compilation failure (with both ```operation: arguments redeclared```\r\nand ```argument list conflicts with prototype``` error messages).  One\r\nsuch example is the ```qsort()``` routine which needs a pointer to a\r\ncomparison routine as one of its arguments.\r\n\r\nThe bug can be worked around by using a typedef'ed parameter.  The\r\nheader library prototype for ```qsort()``` in STDLIB.H has been updated.\r\nThanks to Andrey Nikitin for the heads up on this bug.\r\n\r\n\r\n## Redirection of error message output work-around\r\n<!-- Jan 6, 2022 -->\r\n\r\nNB: This issue has been resolved with the V3.09-11 release (see below).\r\n\r\nThe re-direction of error message output (from the C or C280 command)\r\nis currently broken.  This is a side-effect of the fix to the\r\npre-processor assembly language output.  I've temporarily added\r\na workaround to discard the error message redirect and only send\r\nerror messages to the console device CON:.  This works under CP/M\r\nand ZXCC emulation until I find a fix.\r\n\r\n\r\n## Sourcecode reconstruction for the HI-TECH C linker\r\n<!-- Jan 8, 2022 -->\r\n\r\nBoth Andrey Nikitin and Mark Ogden have reconstructed the source\r\ncode to the HI-TECH object code linker.  You'll find it at\r\n\r\nhttps://github.com/nikitinprior/dlink\r\n\r\nand it can be compiled using gcc under Linux or CLANG under macOS\r\nto produce a executable that doesn't require Z80 emulation for\r\ncross-compilation.\r\n\r\n\r\n## Code-generation issue with casting char to long\r\n<!-- Jan 8, 2022 -->\r\n\r\nMark Ogden supplied the following detail regarding an issue with\r\ncode generation when casting a ```char```/```unsigned char``` to a\r\n```long```.  The current compiler emits incorrect Z80 instructions.\r\n\r\nThe following snippet of code shows the problem and work-arounds.\r\n\r\n```\r\nvoid func(char *pia, unsigned char *pib) {\r\n    long a;\r\n    unsigned long b;\r\n \r\n    a = pia[1]; /* ok */\r\n    a = pib[1]; /* bad sets a = 0 */\r\n    b = pia[1]; /* bad sets b = 0 */\r\n    b = pib[1]; /* bad sets b = 0 */\r\n\r\n    /* work arounds */\r\n\r\n    /* for the simple assignment case use\r\n     * (int)pia[1], (unsigned)pia[1] or (unsigned)pib[1]\r\n     * dependent on whether you need sign extension\r\n     *\r\n     * for example -\r\n     */\r\n\r\n    a = (unsigned) pib[1];\r\n    b = (int) pia[1];\r\n    b = (unsigned) pib[1];\r\n\r\n    /* if used in an expression you may also need to add\r\n     * another cast to (long) or (unsigned long)\r\n     * e.g. (unsigned long)(unsigned)\r\n     */\r\n\r\n}\r\n```\r\n\r\nFor the three failing cases, the code generated is\r\n```\r\n      ld    l,(hl)      ; picks up the char from the array\r\n      ld    hl,0\r\n      ld    d,l\r\n      ld    e,l\r\n```\r\n\r\nwhereas the correct optimised code should be\r\n\r\n```\r\n      ld    e,(hl)\r\n      ld    hl,0\r\n      ld    d,l\r\n```\r\n\r\n\r\n## Fix I/O redirection start-up and V3.09-11 release\r\n<!-- Jan 11, 2022 -->\r\n\r\nWhen the PIPEMGR I/O redirection is not detected, the standard files\r\nfor stdin, stdout and stderr now default to use the console ```CON:```\r\ndevice for compiler output.  With I/O redirection, these use the\r\nPIPEMGR pseudo device names ```RSX:``` and ```ERR:```.  This fixes the\r\nissue with the compiler front-end error message output - so the temporary\r\nwork-around I made a few days ago has been removed.\r\n\r\nThis fix has changed the start-up modules ```CRTCPM.OBJ``` and\r\n```RRTCPM.OBJ``` to use a new ```_initrsx()``` routine when PIPEMGR is\r\ndetected (the source is in the cpm/CLEANUP.C module of LIBC).\r\n\r\nTo indicate this fix is included, I've bumped the release to V3.09-11\r\nand updated the binary distribution library files.\r\n\r\n\r\n## Re-order library file modules and V3.09-12 release\r\n<!-- Jan 11, 2022 -->\r\n\r\nFixed the order of modules in the C library (LIBC.LIB and LIB280C.LIB)\r\nto prevent an ```undefined symbol:``` error during linking.\r\n\r\nAlso added a new feature to the main front-end driver (C.COM) to accept\r\nan ```-N``` switch.  This causes the resulting CP/M program to be\r\nlinked with a new start-up module ```NRTCPM.OBJ```.  This provides a\r\nminimal version of _getargs() instead of the standard enhanced default\r\nversion of_getargs().  Using ```-N``` can significantly reduce\r\nthe size of the generated CP/M binary .COM file at the expense of\r\nwild-card argument processing and command-line file redirection of\r\nstdout and stdin (using the ```>file```, ```>>file``` and ```<file```\r\nmodifiers).\r\n\r\n## Backport more-accurate floating point library routines\r\n<!-- Feb 2, 2022 -->\r\n\r\nPhillip Stevens has submited updates to the floating point library\r\nroutines for ```acos()```, ```asin()```, ```atan()```, ```atan2()```,\r\n```cos()```, ```eval_poly()```, ```exp()```, ```float()```, ```log()```,\r\n```sin()``` and ```sinh()```.  These are from a backport of the\r\nroutines from the HI-TECH Z80 cross compiler V7.80pl2.\r\n\r\nThese fix -\r\n\r\n* some typos in the ```atan()``` coefficients - affecting ```acos()```\r\nand ```asin()```;\r\n\r\n* improved accuracy of the polynomial estimation for ```asin()``` and\r\n```acos()``` by restricting the range of the polynomial in use;\r\n\r\n* correct the sign of ```atan2()``` to reflect the standard usage;\r\n\r\n* allow integer powers of negative bases; and\r\n\r\n* fixes to the intrinsic ```float.as``` floating point arithmetic\r\nfunctions.\r\n\r\nThese changes seem to provide more accurate results.\r\n\r\nI've rebuilt the floating-point libraries (LIBF.LIB and LIB280F.LIB).\r\n\r\nPlease let me know if you notice any issues.\r\n\r\n\r\n## More back-porting of library source-code\r\n<!-- Feb 3, 2022 -->\r\n\r\nPhillip Stevens has back-ported some more of the V7.80pl2 library source.\r\n\r\nA summary of the updates are -\r\n\r\n* float/LTOF.AS - ```lbtof()``` and ```abtof()``` loaded wrong registers,\r\nand ```lltof()``` improved conversion of long to float accuracy by up\r\nto 7 bits.\r\n\r\n* gen/ATOL.C - recognise a ```+``` in a number constant (e.g. ```+123456L```).\r\n\r\n* gen/BRELOP.AS, gen/FRELOP.AS, gen/LRELOP.AS - avoid the use of\r\nan ```ex af af'``` op-code (some CP/M systems use the alternate \r\naccumulator and flags register for interrupts without doing a push/pop\r\nto save it).\r\n\r\n* gen/LONGJMP.AS - fixes.\r\n\r\n* gen/IDIV.AS - fixes.\r\n\r\n* plus add miscellaneous type casts and fix typos in cpm/ABORT.C,\r\ngen/RAND.C, gen/STRFTIME.C, stdio/FILBUF.C, stdio/GETW.C and stdio/UNGETC.C\r\n\r\nUpdated libraries (LIBC.LIB/LIBF.LIB and LIB280C.LIB/LIB280F.LIB) are\r\nin the dist folder and the binary distribution libraries.\r\n\r\n\r\n## Z280 assembly language optimisation\r\n<!-- Feb 7, 2022 -->\r\n\r\nThe Z280 front-end ```C280.COM``` has been modified to allow optimisation\r\nof Z80 assembly language input files when either the ```-O2``` or ```-OF2```\r\noptions are specified.  This uses the same ```OPTIMH``` optimisation\r\nrules as it uses when ```C280``` compiles C programs.\r\n\r\nThis means a command like ```C280 -O2 -C MODULE.AS``` will firstly\r\nperform a source-code optimisation pass before invoking the assember\r\n```ZAS```.  Testing this on the library build procedures squeezes\r\na few bytes from some of the modules.\r\n\r\nIf you wish to examine the result of the ```OPTIMH``` pass, you can use\r\nthe ```-S``` option to retain the optimised source in a file with\r\nthe ```.AS2``` file type.\r\n\r\nFor example -\r\n\r\n```\r\n10E>c280 -s -o2 -v execl.as                                                     \r\nA:C280     COM  (User 0)                                                        \r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-13                                      \r\nCopyright (C) 1984-87 HI-TECH SOFTWARE                                          \r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C                            \r\n0:A:OPTIMH EXECL.AS EXECL.AS2                                                   \r\n 71 bytes optimized away                                                        \r\n 122 bytes replaced                                                             \r\n0:A:ZAS -J -OEXECL.OBJ EXECL.AS2                                                \r\nERA M:$$EXEC.$$$                                                                \r\n                                                                                \r\n10E>\r\n```\r\n\r\nThere's newly optimised Z280 object libraries (LIB280C.LIB and LIB280F.LIB)\r\nand CP/M COM  files in the *z280dist* folder, including the new V3.09-13\r\ncompiler front-end as ```C280-13.COM``` (which you should copy and rename to\r\n```C280.COM``` on the drive where you install the rest of the compiler files).\r\n\r\nThe Z280 binary distribution library has been updated too. Get it from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/z280bin.lbr\r\n\r\n(If you're wondering - there's been no changes that affect the V3.09-12\r\nZ80 release files).\r\n\r\n\r\n## Interpretation of exact file sizes reverted\r\n<!-- Mar 17, 2022 -->\r\n\r\nFollowing on from Mark Ogden's consultations with John Elliott (the author\r\nof the ZXCC emulator and PIPEMGR),  I have accepted a proposal from Mark\r\nOgden to revert the interpretation of exact file sizes back to John\r\nElliott's original DOS Plus interpretation.\r\n\r\nAs mentioned in the release v3.09-3 notes (above), there are two common\r\nconventions that can be used to record exact file sizes in CP/M 3 and\r\nDOS Plus.\r\n\r\n* Record the number of bytes USED in the last sector (as used by DOS Plus)\r\n\r\nor\r\n\r\n* Record the number of UNUSED bytes in the last sector (used by ISX for\r\nISIS emulation)\r\n\r\nNB: The compiler release V3.09-13 was set to select this via\r\nan ```EXACT``` environment variable (defined in the 0:A:ENVIRON file).\r\nThis feature has been removed from the current release V3.09-14 (and\r\nsubsequent versions) and replaced with the following.\r\n\r\nThe start-up module (CRTCPM.OBJ) detects whether you are running the\r\ncompiler under CP/M 2 or CP/M 3 (or DOS Plus) and defaults a global\r\nvariable ```_exact``` to enable DOS Plus interpretation of exact file\r\nsize.\r\n\r\nTo allow you to continue with the alternative ISX/ISIS interpretation,\r\nyou can override the value of the global variable as follows -\r\n\r\n```\r\n#include <stdio.h>\r\nextern char _exact;\r\n..\r\nint main(int argc, char ** argv)\r\n{\r\n    _exact = 'I';  /* Enable ISIS exact file size */\r\n..\r\n}\r\n```\r\n\r\nThe values of ```_exact``` can also be only one of the following -\r\n\r\n```\r\n    _exact = 'C';  /* No exact file size - like CP/M 2.2 uses */\r\nor\r\n    _exact = 'D';  /* DOS Plus convention for exact file size */\r\n```\r\n\r\nThe C library close() routine uses the selected exact file size mode\r\nto write the last record USED (DOS Plus) or UNUSED (ISIS) byte value\r\nto the directory entry.\r\n\r\nNote: You need to take extra care if you're using an emulator like ZXCC\r\nwhich has been updated to only support the DOS Plus\r\nconvention or the CP/M 2.2 interpretation (as per the original version\r\nby John Elliott).  Using the wrong mode will cause the file to be\r\nextended or truncated in the last sector.  The CP/M 2.2 mode causes\r\n```Ctrl-Z``` to be written at the end of text files (as per the CP/M\r\nconvention).\r\n\r\nThe PIPEMGR source code has also been reverted to support only the\r\nDOS plus and CP/M 2.2 file size convention.  Piping a text concatenation\r\n(using the ```>>``` operator) will now write the extra text to the end\r\nof the file (and before the ```Ctrl-Z``` marker if the file has this in\r\nthe last sector).  Files written to by PIPEMGR will use the DOS Plus\r\nexact file size convention.\r\n\r\n\r\n## Fixes to longjmp() and detect underflow in floating point division\r\n<!-- May 24, 2022 -->\r\n\r\nMark Ogden has supplied a couple of fixes.\r\n\r\nThe first was a result of an incorrect assumption about a compiler\r\noptimisation from later versions of the HI-TECH Z80 cross-compiler.\r\nV3.09-x does not pass an initial function argument in the DE register.\r\nOnly the longjmp() routine (in gen/LONGJMP.AS) is affected.\r\n\r\nThe second concerns a floating point division not detecting an underflow\r\ncondition.  The fldiv() routine (in float/FLOAT.AS) now detects this\r\nand returns a zero result.\r\n\r\nUpdated LIBC.LIB and LIBF.LIB contain the fixes (as well as the Z280\r\nversions LIB280C.LIB and LIB280F.LIB), and I've bumped the release\r\nto V3.09-15.\r\n\r\n\r\n## Fixes to the compiler driver\r\n<!-- Aug 9, 2022 -->\r\n\r\nAs reported by Mark Ogden, there are a couple of bugs in the compiler\r\ndriver program.\r\n\r\n* The first is regarding the use of the self-relocating (-A) option,\r\nwhere the code compiled for the linker should use the ```cpm``` psect \r\nsegment (as per the relocatable start-up module RRTCPM.OBJ); and\r\n\r\n* If you specify a .SYM file on the command line without specifying\r\nthe overlay (-Y) option, the compiler driver tries to assemble a\r\nnon-existing temporary file.\r\n\r\nThe latest compiler driver (in cpm/C309-16.C) addresses both by passing\r\nthe ```cpm``` psect to the linker and ignores .SYM files unless the\r\noverlay (-Y) option is specified.\r\n\r\nThe binaries for the compiler driver (in dist//C309-16.COM and\r\nz280dist/C280-16.COM) have been updated as well as the binary distribution\r\nlibrary files to be release V3.09-16 (download link at the top of\r\nthis README file).\r\n\r\n## Minor LIBC ordering fix\r\n<!-- Feb 6, 2023 -->\r\n\r\nThe C library has had the ordering of modules adjusted to resolve\r\nan undefined symbol error (thanks to Mark Ogden for bringing this \r\nto my attention).\r\n\r\n## Remove temporary file\r\n<!-- Mar 22, 2023 -->\r\n\r\nWhen the compiler driver was executed without producing an output file, it\r\nleft behind a stray ```$$EXEC.$$$``` file on the current drive (or on the\r\ntemporary drive if you specified a TMP environment variable in your\r\n```0:A:ENVIRON.``` file).  This now fixed.\r\n\r\nI've also bumped the version number to be release V3.09-17.\r\n\r\n\r\n## Library containing distribution files for unmodified V3.09 release\r\n<!-- Mar 24, 2023 -->\r\n\r\nI've added a CP/M library format (.LBR) file containing the unmodified\r\nHI-TECH C COMPILER V3.09 for Z80 CP/M to the *historical* folder.\r\nThe files in\r\n[historical/Z80V309.LBR](https://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/historical/Z80V309.LBR)\r\ncan be extracted using one of the CP/M library utilities like\r\n[NULU.COM](https://raw.githubusercontent.com/agn453/Z280RC/master/utilities/NULU.COM),\r\nor a Unix tool like lar,\r\n\r\n\r\n## Z280 optimiser (OPTIMH) fixes/enhancements\r\n<!-- Nov 1, 2023 -->\r\n\r\nThe following updates have been made to the Z280 assembly language\r\noptimiser (OPTIMH.COM) -\r\n\r\n* Comments in the OPTIMH.C source file have been translated from German\r\ninto English;\r\n\r\n* The counters for the additional byte and replaced counts are now more\r\naccurate;\r\n\r\n* The processing summary output now includes \"speed\" or \"size\";\r\n\r\n* The default filetype for the output file has been changed from .ASO to .AS2\r\nto be consistent with the compiler behaviour when it optimises and saves\r\nthe output assembler source (i.e compilation using the ```-O2``` or\r\n```-OF2``` with the ```-S``` option);\r\n\r\n* Some ```call csv``` and ```jp cret``` speed optimisations were not being\r\ndetected; and\r\n\r\n* Assembly language statement labels on optimised code were being omitted\r\nin the output file.  Processing now detects them and outputs them\r\non a separate line prior to performing optimisation.\r\n\r\nI've rebuilt the Z280 optimised libraries (LIB280C.LIB, LIB280F.LIB) and\r\ncompiler frontend C280-17.COM using the updated optimiser - and these files\r\nare now available in both the *z280dist* folder and updated Z280 binary\r\ndistribution at\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/z280bin.lbr\r\n\r\nPlease raise an issue if you have any problems with them.\r\n\r\n## Update missing exact file length code in the C Library for stat() and open() routines, and fix fseek() bug.\r\n<!-- May 6, 2025 -->\r\n\r\nWhen the exact file length code was reverted back in V3.09-13 I missed\r\nupdating a couple of the C library routines to use the ```_exact```\r\nglobal variable to correctly handle the selected mode for handing\r\nDOS Plus mode (the DEFAULT).  The ```stat()``` and ```open()``` library\r\nroutines have now been updated.   These were found when looking for the\r\nresolution to issue #49. The ```fseek()``` routine was returning with an\r\noffset of the buffer size (512 bytes) for files opened in read and write (\"r+b\")\r\nmode.  The ```ftell()``` routine was the culprit in the FSEEK.C library\r\nmodule and the offset is no longer added for a file opened in this mode.\r\n(This bug appears to be a long standing one that is in the C library\r\nat least as far back as HI-TECH C V1.3).\r\n\r\nThe C libraries (LIBC.LIB and LIB280C.LIB) have been updated and the\r\ncompiler front-end processor have been updated to include the corrected\r\nmodules.  I've also bumped the version to V3.09-18 so you\r\nknow you're using the corrected modules.\r\n\r\n## OCR version of scanned manual added\r\n<!-- May 29, 2025 -->\r\n\r\nThanks to Martin Homuth-Rosemann for contributing an OCR enhanced copy of\r\nthe scanned October 1989 \"HI-TECH SOFTWARE C COMPILER (Z80) User's Manual\".\r\nYou'll find this in the\r\n[doc/Hi-Tech-Z80-1989-october_ocr.pdf](https://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/doc/Hi-Tech-Z80-1989-october_ocr.pdf)\r\nfile.  This allows you to search the document for content using your PDF\r\nreader/web browser.\r\n\r\n## Backported V4.11 STDIO routines\r\n<!-- June 3, 2025 -->\r\n\r\nIn order to resolve issue #50 concerning incorrect handling of file position\r\nand failure to flush buffers when a file is accessed for updating (in\r\n```r+b``` mode),  I have backported the stdio routines from the HI-TECH\r\nC Z80 Cross-compiler V4.11 into the C Library (LIBC.LIB and LIB280C.LIB).\r\nThe original V3.09 routines had convoluted code that was not properly\r\nhandling a file read followed by a seek and write.\r\n\r\nWhen examining the HI-TECH stdio routines from the V4.11 cross-compiler\r\nit became obvious that the problem was known and corrected using a\r\ndifferent combination of file flag status bytes.  The update adds a\r\nword to the ```FILE``` structure that permits a different file buffer size\r\nto be selected (using a newly added ```setvbuf()``` routine) whilst\r\nmaintaining the old default of 512 bytes; and replaces the old\r\n```_IOWROTE``` flag status bit with an ```_IOSEEKED``` flag to indicate\r\nthat a file seek has occurred since the last file write.\r\n\r\n```\r\nsetvbuf() and setbuf()\r\n\r\n     The setvbuf() function allows the buffering behaviour of a STDIO\r\n     stream to be altered. It supersedes the function setbuf() which is\r\n     retained for backwards compatibility.\r\n\r\n     #include <stdio.h>\r\n\r\n     int setvbuf(FILE * stream, char * buf, int mode, size_t size);\r\n\r\n     void setbuf(FILE * stream, char * buf)\r\n\r\n     The arguments to setvbuf() are as follows:\r\n\r\n     stream designates the STDIO stream to be affected; buf is a pointer\r\n     to a buffer which will be used for all subsequent I/O operations on\r\n     this stream. If buf is null, then the routine will allocate a buffer\r\n     from the heap if necessary, of size BUFSIZ as defined in ```<stdio.h>```.\r\n     mode may take the values _IONBF, to turn buffering off completely,\r\n     _IOFBF, for full buffering, or _IOLBF for line buffering. Full\r\n     buffering means that the associated buffer will only be flushed when\r\n     full, while line buffering means that the buffer will be flushed at\r\n     the end of each line or when input is requested from another STDIO\r\n     stream. size is the size of the buffer supplied. For example -\r\n\r\n     setvbuf(stdout, my_buf, _IOLBF, sizeof my_buf);\r\n\r\n     If a buffer is supplied by the caller, that buffer will remain\r\n     associated with that stream even over fclose(), fopen() calls until\r\n     another setvbuf() changes it.\r\n```\r\n\r\nThe updated binaries, libraries and header files have been included in\r\nthe *dist* and *z280dist* folders, along with source-code and build files\r\nin the *stdio*, *float* and *cpm* folders.\r\n\r\nI've also bumped the version to V3.09-19 so you know you're using the\r\nlatest library modules.  Library version information is also now included\r\nin the ```STDIO.H``` file as\r\n\r\n```\r\n#define _HTC_VERSION    \"3.09-19\"\r\n#define _HTC_MAJOR      3\r\n#define _HTC_MINOR      9\r\n#define _HTC_REV        19\r\n```\r\n\r\nand a global string can be accessed from the C libraries. This can be\r\nreferenced and printed using\r\n\r\n```\r\nextern char * _libcver; /* or _libfver for LIBF.LIB */\r\n..\r\nfprintf(stdout,\"C library version %s\\n\",_libcver);\r\n```\r\n\r\nGrab the updated V3.09-19 distribution binary .LBR file for Z80 CP/M from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/htc-bin.lbr\r\n\r\nand optionally the Z280 binary distribution (if you need it) from\r\n\r\nhttps://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/z280bin.lbr\r\n\r\n\r\n## Z280 assembly optimiser minor update\r\n<!-- June 5, 2025 -->\r\n\r\nA minor issue has been corrected with the Z280 optimiser ```OPTIMH.COM```\r\nwhere it was failing to process assembly language source files where a\r\nstatement label has no white-space (a space or tab) between the colon\r\nand the opcode.  e.g.\r\n\r\n```\r\nlabel1:ld hl,0\r\n```\r\n\r\nwas incorrectly output as\r\n\r\n```\r\nlabel1:\r\n        d hl,0\r\n```\r\n\r\nto the Z280 assembler ```.AS2``` output file.\r\n\r\nThis did not trigger with the normal compiler processing of assembler\r\nintermediate files - since all labels that the compiler produces have\r\na space after them.\r\n\r\nThe updated source ```OPTIMH.C``` and binary ```OPTIMH.COM``` are in the\r\n*z280dist* folder and the \r\n[z280bin.lbr](https://raw.githubusercontent.com/agn453/HI-TECH-Z80-C/master/z280bin.lbr)\r\nZ280 binary distribution library.\r\n\r\n\r\n## Update to support binaries running under Digital Research MP/M-II\r\n<!-- September 5, 2025 -->\r\n\r\nNB:  There is insufficient memory to run the compiler modules under\r\nMP/M due to the reduced transient program area.\r\n\r\nThe binaries produced by the compiler now run under MP/M-II following\r\na correction to the\r\nvarious start-up modules (CRTCPM.OBJ C280CPM.OBJ etc) to check for MP/M\r\nafter doing a BDOS function 12 Get Version call.  Previously it was\r\nfollowing the CP/M 3 path and trying un-implemented BDOS calls to check\r\nfor the presence of the PIPEMGR RSX and making all the wrong configuration\r\nchoices.  (As an aside -- one of the main differences\r\nbetween MP/M and CP/M is that it returns a HL=0xFFFF error code for\r\nunimplemented BDOS calls whereas CP/M returns HL=0).  Hopefully I have\r\nreviewed all the places the C Library routines do a BDOS Check Version call.\r\n\r\nAlso, I have modified the code in the ```signal()``` library routine that\r\ndetects a SIGINT to use a Direct Console I/O (BDOS function 6) call to check\r\nfor a CTRL-C while processing a stdio call.  Previously it was checking\r\nif a character had been struck using the Console Status (BDOS function 11)\r\nand fetching it using the Console Input with Echo (BDOS function 1) call.\r\nThe old way did not work correctly under MP/M since it was already\r\nintercepting the CTRL-C internally and prompting to abort the running\r\nprogram.  A side-effect of this is that now when you SIGINT a HI-TECH C\r\nprogram using CTRL-C via ```signal()```, the ```^C``` will no longer be\r\nechoed back to the console.  MP/M does not intercept characters using\r\nthe Direct Console I/O call.  HI-TECH C produced binaries will recognise\r\nand act on it though.\r\n\r\nThe version number for HI-TECH C has been bumped to V3.09-20 to reflect\r\nthese changes (in the libraries and main driver).  I've done all my testing\r\nunder MP/M V2.1 and it should work with older versions.  If not, please\r\nraise an issue on GitHub.\r\n\r\n\r\n[^1]: RunCPM is a multi-platform, portable, Z80 CP/M 2.2 emulator.  It is\r\nactively maintained and available from https://github.com/MockbaTheBorg/RunCPM\r\n\r\n[^2]: SIMH AltairZ80 is one of many computer system simulators from the\r\nOpen SIMH Project (https://opensimh.org).  It emulates 8080/Z80/8085 and\r\nMC68000 S-100 bus computers (like the MITS Altair with various interface\r\ncards and peripherals).  You can obtain source-code for over 70 different\r\nsystems from https://github.com/open-simh/simh or just the AltairZ80\r\nspecific simulator and various prebuilt CP/M operating system kits from\r\nPeter Schorn's site at https://schorn.ch/altair.html\r\n\r\n[^3]: ZXCC is a CP/M 2/3 emulator for cross compiling and running most\r\nCP/M binary command files under Linux/Unix/macOS and Microsoft Windows.\r\nIt was authored by John Elliott and with various updates may be obtained\r\nfrom https://github.com/agn453/ZXCC\r\n\r\n[^4]: The newsgroup comp.os.cpm can be accessed via a USENET\r\nprovider like www.eternal-september.org using newsreader software like\r\nMozilla Thunderbird.  An archived copy of the original thread can be\r\nread via Google Groups at\r\nhttps://groups.google.com/forum/#!topic/comp.os.cpm/V9Qwoc3--Ak - but\r\nsince February 2024 you will need to access comp.os.cpm via a USENET\r\nprovider to be able to post messages. \r\n\r\n--\r\n\r\nTony Nicholson, Friday 05-Sep-2025\r\n"
  },
  {
    "path": "cpm/ABORT.C",
    "content": "#include <cpm.h>\r\n\r\nstatic char\tmess[] = \"Fatal error - program aborted\\r\\n$\";\r\n\r\nvoid\r\nabort()\r\n{\r\n\tbdos(CPMWCOB, mess);\r\n\texit(-1);\r\n}\r\n"
  },
  {
    "path": "cpm/BDOS.AS",
    "content": ";-----------------------------------------------------------------------------\r\n;\r\n; All BDOS calls on all versions of CP/M 80 return with B = H and A = L.\r\n; Furthermore, when an 8-bit result is all that is returned then B = H = 0.\r\n;\r\n; This is a documented feature of CP/M but it seems to have been overlooked\r\n; by most programmers.  Compiler vendors in particular seem to have felt\r\n; compelled to provide two versions of the bdos() function, one for 8-bit\r\n; results and one for 16-bit results.  There is simply no need for that.\r\n;\r\n; This is a replacement for the bdos() and bdoshl() functions in the Hi-Tech\r\n; C runtime library.\r\n;\r\n; How to patch your library:\r\n;\r\n;\tzas bdos.as\r\n;\tlibr d libc.lib bdoshl.obj\r\n;\tlibr r libc.lib bdos.obj\r\n;\r\n; Jon Saxton\r\n; September 2012\r\n;\r\n;-----------------------------------------------------------------------------\r\n;\r\n; There is one caveat attached to all this.  The Hi-Tech C bdos() function\r\n; did a sign extension of the 8-bit result to convert it to a 16-bit result.\r\n; That is no longer done.  It is only going to be a problem if your code\r\n; checks 8-bit return codes for negative numbers, e.g. -1 instead of 0xFF.\r\n; The function prototype is:\r\n;\r\n;\tshort bdos(short func, ...);\r\n;\r\n; instead of:\r\n;\r\n;\tchar bdos(short func, ...);\r\n;\tshort bdoshl(short func, ...);\r\n;\r\n; When running under CP/M 3 there are several functions which can return\r\n; extended error codes.  For those functions, the error signal is A=L=0xFF\r\n; and the extended error is in B and H.  For consistency across all versions\r\n; of CP/M it is correct to test the low-order byte of the return value where\r\n; appropriate; for example:\r\n;\r\n;\tshort\trc;\r\n;\t...\r\n;\trc = bdos(fn, arg);\r\n;\tif ((rc & 0xFF) == 0xFF)\r\n;\t    [deal with error];\r\n;\telse\r\n;\t    [normal processing];\r\n;\r\n; Note that finding 0xFF in the low-order 8 bits of the return value does not\r\n; always indicate an error.  For example, functions such as 25 (return login\r\n; vector) and 31 (get DPB address) could legitimately return such a value.\r\n; When calling the BDOS one always has to be aware of the context and the\r\n; possible return value.  The prior implementation with separate calls for\r\n; for 8-bit and 16-bit results was already an expression of context awareness.\r\n;\r\n; Also be aware that an error is not always flagged by 0xFF in the low-order\r\n; byte of the return value.  For some functions any non-zero return value is\r\n; an error.\r\n;\r\n;-----------------------------------------------------------------------------\r\n;\r\n; 10 Apr 2014\r\n;\r\n; This module has been updated to incorporate John Elliott's code to set\r\n; _errno on a failed BDOS call.\r\n;\r\n; This is only possible on CP/M Plus and only meaningful for the subset of\r\n; BDOS functions which return an extended error code.  These functions can\r\n; now set errno.\r\n;\r\n; John's version of this routine is bdose() and is part of the PIPEMGR suite\r\n; found on his web site:\r\n;\r\n;\thttp://www.seasip.demon.co.uk/Cpm/software/Pipemgr/index.html\r\n;\r\n; There is no need to call bdose(); bdos() does everything.\r\n;\r\n;-----------------------------------------------------------------------------\r\n;\r\n; The password handler mechanism documented in John's LIBCNEW.DOC has been\r\n; disabled for the time being because it seems to be ineffective and I have\r\n; not yet discovered why.  It is possible that the problem lies with CP/M 3\r\n; rather than John's code.  Opening a password-protected file generates a\r\n; password error but entering a null password is sufficient to bypass the\r\n; protection!\r\n;\r\n; Passwords are probably useless anyway.  They are also easily bypassed.\r\n;\r\n; Jon Saxton [20 Apr 2014]\r\n;\r\n;-----------------------------------------------------------------------------\r\n\r\n\tglobal\tcsv,cret\r\n\r\nfalse\tequ\t0\r\ntrue\tequ\t.not. false\r\n\r\nPWDREC\tequ\tfalse\t\t; Password recovery mechanism (off)\r\n\r\nentry\tequ\t5\t\t; CP/M entry point\r\n\r\narg\tequ\t8\t\t;argument to call\r\nfunc\tequ\t6\t\t;desired function\r\n\r\n\tglobal\t_bdos, _errno\r\n\r\n\tcond\tPWDREC\r\n\tglobal\t__passwd, __dpass\r\n\tendc\r\n\r\n\tpsect\tdata\r\n\r\n\tcond\tPWDREC\r\n__passwd:\r\n\tdefw\t__dpass\r\n\tendc\r\n\r\n;-----------------------------------------------------------------------------\r\n; The following table is a bit map.  Each bit represents a BDOS function\r\n; which, under CP/M Plus, can return an extended error code.  The functions\r\n; identified in the bit map are also the ones which can set errno.\r\n;\r\n; The extended errors are consistent over all the relevant functions:\r\n;\r\n;\tError\t\tMeaning\r\n;\r\n;\t  1\t\tDisk I/O error\r\n;\t  2\t\tRead-only disk\r\n;\t  3\t\tRead-only file\r\n;\t  4\t\tInvalid drive\r\n;\t  5\r\n;\t  6\r\n;\t  7\t\tPassword error\r\n;\t  8\t\tFile exists\r\n;\t  9\t\t? in file name\r\n;\r\n; These are the functions flagged in the bitmap.\r\n;\r\n;\tBDOS function\t\t\tPossible errors \r\n;\r\n;\t14 Select disk\t\t\t1, 4\r\n;\t15 Open file\t\t\t1, 4, 7, 9\r\n;\t16 Close file\t\t\t1, 2, 4\r\n;\t17 Search for first\t\t1, 4\r\n;\t18 Search for next\t\t1, 4\r\n;\t19 Delete file\t\t\t1, 2, 3, 4, 7\r\n;\t20 Sequential read\t\t1, 4\r\n;\t21 Sequential write\t\t1, 2, 3, 4\r\n;\t22 Create file\t\t\t1, 2, 4, 8, 9\r\n;\t23 Rename file\t\t\t1, 2, 3, 4, 7, 8, 9\r\n;\t30 Set file attributes\t\t1, 2, 4, 7, 9\r\n;\t33 Random read\t\t\t1, 4\r\n;\t34 Random write\t\t\t1, 2, 3, 4\r\n;\t35 Compute file size\t\t1, 4\r\n;\t40 Random write with zero fill\t1, 2, 3, 4\r\n;\t46 Get disk free space\t\t1, 4\r\n;\t48 Flush buffers\t\t1, 2, 4\r\n;\t59 Load overlay\t\t\t1, 4\r\n;\t60 Call RSX\t\t\tdepends on RSX\r\n;\t98 Free blocks\t\t\t4\r\n;\t99 Truncate file\t\t1, 2, 3, 4, 7, 9\r\n;      100 Set directory label\t\t1, 2, 4, 7\r\n;      101 Return directory label data\t1, 4\r\n;      102 File datestamps/pwd mode\t1, 4, 9\r\n;      103 Write file XFCB\t\t1, 2, 4, 7, 9\r\n;-----------------------------------------------------------------------------\r\n \r\nfuncmap:\r\n\tdefb\t00000000B\t;   0\r\n\tdefb\t11000000B\t;   8\t\t14,15\r\n\tdefb\t11111111B\t;  16\t\t16-23\r\n\tdefb\t01000000B\t;  24\t\t30\r\n\tdefb\t00001110B\t;  32\t\t33-35\r\n\tdefb\t01000001B\t;  40\t\t40,46\r\n\tdefb\t00000001B\t;  48\t\t48\r\n\tdefb\t00011000B\t;  56\t\t59,60\r\n\tdefb\t00000000B\t;  64\r\n\tdefb\t00000000B\t;  72\r\n\tdefb\t00000000B\t;  80\r\n\tdefb\t00000000B\t;  88\r\n\tdefb\t11111100B\t;  96\t\t98-103\r\n\tdefb\t00000000B\t; 104\r\n\tdefb\t00000000B\t; 112\r\n\tdefb\t00000000B\t; 120\r\n\tdefb\t00000000B\t; 128\r\n\tdefb\t00000000B\t; 136\r\n\tdefb\t00000000B\t; 144\r\n\tdefb\t00000000B\t; 152\r\n\r\n\tpsect\ttext\r\n\r\n\tcond\tPWDREC\r\n__dpass:\r\n\tld\thl,0\r\n\tret\r\n\tendc\r\n\r\n_bdos:\r\n\tcall\tcsv\t\t; Establish pointer to parameters\r\nretry:\r\n\tld\te,(ix+arg)\r\n\tld\td,(ix+arg+1)\r\n\tld\tc,(ix+func)\r\n\tpush\tiy\t\t; Save IY for caller\r\n\tpush\tix\t\t; Save stack pointer over BDOS call\r\n\tcall\tentry\t\t; Call BDOS\r\n\tpop\tix\t\t; Recover stack pointer\r\n\tld\ta,(ix+func)\t; Get BDOS function number\r\n\tcp\t160\t\t; Check range\r\n\tjr\tnc,2f\t\t; Skip extended processing if out of range\r\n\tpush\thl\t\t; Save BDOS return code\r\n\tld\tc,12\t\t; Get CP/M version\r\n\tcall\tentry\r\n\tdec\tl\t\t; set Z bit if MP/M\r\n\tpop\thl\t\t; Restore BDOS result before checking version\r\n\tjr\tz,2f\t\t; No return codes for MP/M\r\n\tcp\t30h\t\t; Need at least 3.x\r\n\tjr\tc,2f\t\t; No extended error processing if not CP/M+\r\n\tld\tiy,instruction\t; Prepare to modify code\r\n\tld\ta,(ix+func)\t; Get function number again\r\n\tpush\taf\t\t; Save it for a moment\r\n\tand\t7\t\t; Isolate bit number\r\n\tadd\ta,a\t\t; Shift left 3 positions\r\n\tadd\ta,a\t\t;  /\r\n\tadd\ta,a\t\t; /\r\n\tor\t46h\t\t; Form BIT sub-instruction\r\n\tld\t(iy+3),a\t; Store it\r\n\tpop\taf\t\t; Recover function number\r\n\tsrl\ta\t\t; Shift right 3 positions to form byte index\r\n\tsrl\ta\t\t;  /\r\n\tsrl\ta\t\t; /\r\n\tld\t(iy+2),a\t; Store offset\r\n\tld\tiy,funcmap\t; Point at function bitmap\r\ninstruction:\r\n\tbit\t0,(iy+0)\t; This gets modified by foregoing code\r\n\tjr\tz,2f\t\t; Not a function returning an extended error\r\n\tld\ta,l\t\t; Check for error\r\n\tinc\ta\t\t; Only 0xFF indicates an extended error\r\n\tld\ta,-16\t\t; Pre-condition for a zero\r\n\tjr\tnz,0f\t\t; Skip if extended error is not possible\r\n\tld\ta,h\t\t; Get extended error code\r\n\r\n;-----------------------------------------------------------------------------\r\n; The following code exists to support a user-supplied password routine.\r\n\r\n\tcond\tPWDREC\r\n\tcp\t7\t\t; Password error?\r\n\tjr\tnz,0f\t\t; If not then just set _errno and exit\r\n\tld\tbc,pwret\r\n\tpush\tbc\t\t; Set return address\r\n\tld\thl,(__passwd)\t; Possible user-supplied password handler\r\n\tjp\t(hl)\t\t; Execute default or user-supplied handler\r\npwret:\r\n\tld\ta,h\t\t; Check to see if a password came back\r\n\tor\tl\r\n\tld\ta,7\t\t; Prepare a password error code\r\n\tjr\tz,0f\t\t; Exit with errno=23 if no password\r\n\tex\tde,hl\t\t; DE = password address\r\n\tld\tc,26\t\t; Set DMA\r\n\tpush\tix\r\n\tcall\tentry\t\t; Point DMA at the password\r\n\tpop\tix\r\n\tpop\tiy\r\n\tjp\tretry\t\t; DE is still on the stack!\r\n\tendc\r\n;-----------------------------------------------------------------------------\r\n\r\n0:\r\n\tadd\ta,16\r\n\tld\t(_errno),a\r\n2:\r\n\tpop\tiy\r\n\tjp\tcret\r\n"
  },
  {
    "path": "cpm/BIOS.AS",
    "content": ";------------------------------------------------------------------------------\r\n;\r\n; Modified bios() function for Hi-Tech C.\r\n;\r\n; The original code simply acessed the jump table at the start of the CP/M\r\n; BIOS.  That is unsupported (and potentially dangerous) under CP/M 3.x with\r\n; banked memory.\r\n;\r\n; The sanctioned method on CP/M 3.x is to use BDOS function 50.  Since that\r\n; won't work on CP/M 2.2 this version of bios() tests the operating system\r\n; version and acts according to the answer it receives.\r\n;\r\n; But that is not all.  CP/M 2.2 BIOS calls take 0, 1 or 2 inputs.  Single\r\n; inputs go in BC or C, double inputs go in BC and DE.  CP/M 3.x has BDOS\r\n; functions which take inputs in other registers.  The bios() function is\r\n; smart enough to figure out where the arguments go.\r\n;\r\n; Since some functions return 16-bit results, mask the return when expecting\r\n; an 8-bit result.\r\n;\r\n; Examples:\r\n;\trc = bios(2) & 0xFF;\t\t/* Get console input status */\r\n;\tbios(4,'K');\t\t\t/* Write a K to the console */\r\n;\trc = bios(16, sector, trntbl);\t/* Get translated sector number */\r\n;\tbios(len, src, dst);\t\t/* Copy len bytes from src to dst */s\r\n;\r\n; There was a problem with bios() calls under CP/M 2.2.  The original code\r\n; always returned the A register contents.  In other words it NEVER returned\r\n; a 16-bit result.  That has been fixed.k\r\n;\r\n; Jon Saxton\r\n; (ex-)sysop of the long-defunct Tesseract RCPM+\r\n; 2010-01-30\r\n;\r\n;------------------------------------------------------------------------------\r\n\r\n\tpsect\ttext\r\n\r\n\tglobal\t_bios, csv, cret\r\n\tglobal\texit22\r\n\r\ncpm\tequ\t 5\t\t\t;bdos entry point\r\nCPMVERS\tequ\t12\t\t\t; Get Version function\r\nCPMBIOS\tequ\t50\t\t\t; CP/M+ Call BIOS function\r\n\r\narg\tequ\t 6\t\t\t;offset of 1st arg on stack\r\n\r\nSELDSK\tequ\t 9\r\nSECTRN\tequ\t16\r\nDEVTBL\tequ\t20\r\nDRVTBL\tequ\t22\r\nMOVE\tequ\t25\r\nUSERF\tequ\t30\r\n\r\n_bios:\r\n\tcall\tcsv\r\n\tld\tc,CPMVERS\r\n\tcall\tcpm\r\n\tdec\th\t\t\t; if running under MP/M\r\n\tjr\tz,1f\t\t\t;  treat it like CP/M 2.2\r\n\tcp\t30h\r\n\tjr\tnc,30f\r\n\r\n;==============================================================================\r\n;\t\t\t   BIOS call for CP/M 2.2\r\n;==============================================================================\r\n\r\n1:\tld\thl,21f\t\t\t;set up return address\r\n\tpush\thl\r\n\tld\tl,(ix+arg+0)\t\t;get bios index\r\n\tdec\tl\t\t\t;adjust\r\n\tld\te,l\r\n\tld\th,0\r\n\tld\td,0\r\n\tadd\thl,hl\t\t\t;triple it\r\n\tadd\thl,de\r\n\tld\tde,(1)\t\t\t;get warm boot address\r\n\tadd\thl,de\t\t\t;now have transfer address\r\n\tpush\thl\t\t\t;put on stack\r\n\tld\tc,(ix+arg+2)\t\t;get 1st arg\r\n\tld\tb,(ix+arg+3)\r\n\tld\te,(ix+arg+4)\t\t;get 2nd arg\r\n\tld\td,(ix+arg+5)\r\n\tret\t\t\t\t;do bios call\r\n21:\r\n\t; Check for 16-bit or 8-bit result.  For CP/M 2.2 the only functions\r\n\t; which return 16-bit results are SELDSK (9) and SECTRAN (16).\r\n\t; This code is shared with CP/M 3 and that operating system has a few\r\n\t; more calls which may return a 16-bit result.\r\nexit22:\r\n\tld\tc,a\t\t\t; Save possible 8-bit return code\r\n\tld\ta,(ix+arg+0)\t\t; Get function\r\n\tcp\tSELDSK\t\t\t; Test for 16-bit return\r\n\tjr\tz,23f\r\n\tcp\tSECTRN\r\n\tjr\tz,23f\r\n\tcp\tDEVTBL\r\n\tjr\tz,23f\r\n\tcp\tDRVTBL\r\n\tjr\tz,23f\r\n\tcp\tMOVE\r\n\tjr\tz,23f\r\n\tcp\tUSERF\r\n\tjr\tnc,23f\r\n\tld\tl,c\t\t\t;return value in a (copied to C)\r\n\tld\th,0\r\n23:\r\n\tjp\tcret\r\n\r\n;==============================================================================\r\n;\t\t\t    BIOS call for CP/M 3.x\r\n;==============================================================================\r\n\r\n30:\r\n\tpush\tiy\r\n\tld\tiy,biospb\t\t; Point at BIOS parameter block\r\n\tld\te,(ix+arg+0)\t\t; Get function number\r\n\tld\t(iy+0),e\t\t; Store in BPB\r\n\tld\thl,rutable\t\t; Point at table\r\n\tld\td,0\r\n\tsrl\te\t\t\t; Halve the index, low order bit to CF\r\n\tpush\taf\t\t\t; Save carry\r\n\tadd\thl,de\t\t\t; Point at function bits\r\n\tpop\taf\t\t\t; Restore carry flag\r\n\tld\ta,(hl)\t\t\t; Get register usage flags\r\n\tjr\tnc,31f\t\t\t; Skip if index was even\r\n\trrca\t\t\t\t; Index was odd, move high nybble down\r\n\trrca\r\n\trrca\r\n\trrca\r\n31:\r\n\tpush\tix\t\t\t; Stack frame to HL\r\n\tpop\thl\r\n\tld\tde,arg+2\t\t; Point at first argument\r\n\tadd\thl,de\r\n\tld\te,(hl)\t\t\t; Load first argument\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\trra\t\t\t\t; Low bit of register flags to carry\r\n\tjr\tnc,34f\t\t\t; Skip if A register not used\r\n\tld\t(iy+1),e\t\t; Store argument in BPB.A\r\n\tld\te,(hl)\t\t\t; Get next argument\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n34:\r\n\tld\tb,3\t\t\t; Shift counter\r\n35:\r\n\tinc\tiy\t\t\t; Step the BPB to the next register\r\n\tinc\tiy\t\t\t;  slot\r\n\trra\t\t\t\t; Register usage bit to carry\r\n\tjr\tnc,36f\t\t\t; Skip if unused\r\n\tld\t(iy+0),e\t\t; Store argument in BPB.XX\r\n\tld\t(iy+1),d\t\t;  where XX is BC, DE or HL\r\n\tld\te,(hl)\t\t\t; Get next argument\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n36:\r\n\tdjnz\t35b\r\n\r\n\tpop\tiy\t\t\t; Restore caller's IY\r\n\tld\tde,biospb\t\t; Recover BPB address\r\n\tld\tc,CPMBIOS\t\t; BIOS call via BDOS\r\n\tcall\tcpm\r\n\tjr\t21b\t\t\t; Exit with 8- or 16-bit result\r\n\r\n;==============================================================================\r\n\r\n\tpsect\tdata\r\nbiospb:\r\n\tdefs\t8\t\t\t; BIOS parameter block\r\n\r\n;------------------------------------------------------------------------------\r\n; The following table defines input register usage for BIOS functions.\r\n;\r\n;\tBit 0 is set if A is used\r\n;\tBit 1 is set if BC is used\r\n;\tBit 2 is set if DE is used\r\n;\tBit 3 is set if HL is used\r\n;\r\n; Each entry in the table represents two functions.  The lower nybble holds\r\n; the register usage bits for an even-numbered function and the upper nybble\r\n; holds the bits for the next (odd-numbered) function.\r\n;------------------------------------------------------------------------------\r\n\r\nrutable:\r\n\tdefb\t00h\t\t\t;  0 - Cold boot\r\n\t\t\t\t\t;  1 - Warm boot\r\n\tdefb\t00h\t\t\t;  2 - Console input status\r\n\t\t\t\t\t;  3 - Console input\r\n\tdefb\t22h\t\t\t;  4 - Console output\r\n\t\t\t\t\t;  5 - List device output\r\n\tdefb\t02h\t\t\t;  6 - Auxiliary device output\r\n\t\t\t\t\t;  7 - Auxiliary device input\r\n\tdefb\t60h\t\t\t;  8 - Home disk\r\n\t\t\t\t\t;  9 - Select disk\r\n\tdefb\t22h\t\t\t; 10 - Set track\r\n\t\t\t\t\t; 11 - Set sector\r\n\tdefb\t02h\t\t\t; 12 - Set DMA\r\n\t\t\t\t\t; 13 - Read\r\n\tdefb\t02h\t\t\t; 14 - Write\r\n\t\t\t\t\t; 15 - List device status\r\n\tdefb\t06h\t\t\t; 16 - Sector translate\r\n\t\t\t\t\t; 17 - Console output status\r\n\tdefb\t00h\t\t\t; 18 - Auxiliary input status\r\n\t\t\t\t\t; 19 - Auxiliary output status\r\n\tdefb\t20h\t\t\t; 20 - Get device table address\r\n\t\t\t\t\t; 21 - Initialise device\r\n\tdefb\t20h\t\t\t; 22 - Drive table\r\n\t\t\t\t\t; 23 - Multi sector I/O\r\n\tdefb\t0E0h\t\t\t; 24 - Flush buffers\r\n\t\t\t\t\t; 25 - Move\r\n\tdefb\t12h\t\t\t; 26 - Time\r\n\t\t\t\t\t; 27 - Select memory bank\r\n\tdefb\t21h\t\t\t; 28 - Set bank for I/O\r\n\t\t\t\t\t; 29 - XMove\r\n\tdefb\t0FFh\t\t\t; 30 - UserF\r\n\t\t\t\t\t; 31 - Reserved 1\r\n\tdefb\t0Fh\t\t\t; 32 - Reserved 2\r\n\r\n;==============================================================================\r\n;\tBIOS call summary for C programs\r\n;==============================================================================\r\n;\r\n;\tbios(0);\t\t\tCold boot\r\n;\tbios(1);\t\t\tWarm boot\r\n;\trc = bios(2);\t\t\tConsole input status\r\n;\trc = bios(3);\t\t\tConsole input\r\n;\tbios(4, chr);\t\t\tConsole output\r\n;\tbios(5,\tchr);\t\t\tList device output\r\n;\tbios(6, chr);\t\t\tAuxiliary device output (PUN)\r\n;\trc = bios(7);\t\t\tAuxiliary device input (RDR)\r\n;\tbios(8);\t\t\tHome disk\r\n;\trc = bios(9, drv, init);\tSelect disk\r\n;\tbios(10, track);\t\tSet track\r\n;\tbios(11, sector);\t\tSet sector\r\n;\tbios(12, pDMA);\t\t\tSet DMA\r\n;\trc = bios(13);\t\t\tRead\r\n;\trc = bios(14, deblock);\t\tWrite\r\n;\trc = bios(15);\t\t\tList device status\r\n;\trc = bios(16, sector, txtbl);\tSector translate\r\n;\r\n;-------------------------- CP/M 2.2 - 3.1 boundary ---------------------------\r\n;\r\n;\trc = bios(17);\t\t\tConsole output status\r\n;\trc = bios(18);\t\t\tAuxiliary input status\r\n;\trc = bios(19);\t\t\tAuxiliary output status\r\n;\trc = bios(20);\t\t\tGet device table address\r\n;\trc = bios(21, devno);\t\tInitialise device\r\n;\trc = bios(22);\t\t\tDrive table\r\n;\tbios(23, sectors);\t\tMulti sector I/O\r\n;\trc = bios(24);\t\t\tFlush buffers\r\n;\tbios(25, len, src, dest);\tMove\r\n;\tbios(26, getorset);\t\tTime\r\n;\tbios(27, bank);\t\t\tSelect memory bank\r\n;\tbios(28, iobank);\t\tSet bank for I/O\r\n;\tbios(29, srcBank+destBank*256);\tXMove\r\n;\trc = bios(30, a, bc, de, hl);\tUserF (implementor defined)\r\n;\trc = bios(31, a, bc, de, hl);\tReserved\r\n;\trc = bios(32, a, bc, de, hl);\tReserved\r\n;==============================================================================\r\n"
  },
  {
    "path": "cpm/BUILD-C.LOG",
    "content": "\r\n10E>;\r\n10E>date\r\nA:DATE     COM  (User 0)\r\n\rFri 05/09/2025 13:20:24\r\n10E>;\r\n10E>; Build Z80 version\r\n10E>c -o -v c309-20.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: C309-20.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OC309-20.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OC309-20.COM 0:A:CRTCPM.OBJ C309-20.OBJ 0:A:LIBC.LIB\r\nERA C309-20.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>;\r\n10E>; Now build Z280 version\r\n10E>;\r\n10E>; First a Z280 version using the Z80 LIBC.LIB (runs on Z80)\r\n10E>c309-20 -o -v -ec280z80.com -dZ280 c309-20.c\r\nE:C309-20  COM\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: C309-20.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OC309-20.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OC280Z80.COM 0:A:CRTCPM.OBJ C309-20.OBJ 0:A:LIBC.LIB\r\nERA C309-20.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>;\r\n10E>; and the Z280 optimized version from it (only runs on a Z280)\r\n10E>c280z80 -of2 -v -ec280-20.com c309-20.c\r\nE:C280Z80  COM\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: C309-20.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM -F M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH -F M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 496 bytes speed optimised away\r\n 1643 bytes replaced\r\n0:A:ZAS -N -OC309-20.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OC280-20.COM 0:A:C280CPM.OBJ C309-20.OBJ 0:A:LIB280C.LIB\r\nERA C309-20.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>;\r\n10E>; plus a Z80 version of the Z280 optimisation program in case\r\n10E>; we need to bootstrap a new LIB280C.LIB using the Z80 C280Z80\r\n10E>; compiler front end on a Z80\r\n10E>c280z80 -o2 -v -eoptimh80.com optimh.c\r\nE:C280Z80  COM\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: OPTIMH.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 244 bytes size optimised away\r\n 442 bytes replaced\r\n0:A:ZAS -J -N -OOPTIMH.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OOPTIMH80.COM 0:A:C280CPM.OBJ OPTIMH.OBJ 0:A:LIB280C.LIB\r\nERA OPTIMH.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>;\r\n10E>; Build the optimiser with the Z280 compiler front-end (may fail\r\n10E>; if the LIB280C.LIB library is not present or compatible with\r\n10E>; the latest updates - use C280Z80 and OPTIMH80 instead.\r\n10E>c280-20 -o2 -v optimh.c\r\nE:C280-20  COM\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: OPTIMH.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 244 bytes size optimised away\r\n 442 bytes replaced\r\n0:A:ZAS -J -N -OOPTIMH.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OOPTIMH.COM 0:A:C280CPM.OBJ OPTIMH.OBJ 0:A:LIB280C.LIB\r\nERA OPTIMH.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>;\r\n10E>dir c*.com [fu\r\nA:DIR      COM  (User 0)\r\n\r\nScanning Directory...\r\n\r\nSorting  Directory...\r\n\r\nDirectory For Drive E:  User 10\r\n\r\n    Name     Bytes   Recs   Attributes   Prot      Update          Create    \r\n------------ ------ ------ ------------ ------ --------------  --------------\r\n\r\nC280-20  COM    28k    198 Dir RW       None   05/09/25 13:30  05/09/25 13:30\r\nC280Z80  COM    28k    215 Dir RW       None   05/09/25 13:26  05/09/25 13:26\r\nC309-20  COM    28k    209 Dir RW       None   05/09/25 13:23  05/09/25 13:23\r\n\r\nTotal Bytes     =     84k  Total Records =     622  Files Found =    3\r\nTotal 1k Blocks =     79   Used/Max Dir Entries For Drive E: 1129/2048\r\n\r\n10E>dir optimh.com [fu\r\nA:DIR      COM  (User 0)\r\n\r\nScanning Directory...\r\n\r\nDirectory For Drive E:  User 10\r\n\r\n    Name     Bytes   Recs   Attributes   Prot      Update          Create    \r\n------------ ------ ------ ------------ ------ --------------  --------------\r\n\r\nOPTIMH   COM    20k    151 Dir RW       None   05/09/25 13:36  05/09/25 13:36\r\n\r\nTotal Bytes     =     20k  Total Records =     151  Files Found =    1\r\nTotal 1k Blocks =     19   Used/Max Dir Entries For Drive E: 1129/2048\r\n\r\n10E>;\r\n10E>; Done\r\n10E>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "cpm/BUILD-C.SUB",
    "content": "era build-c.log\r\nput console output to file build-c.log [system]\r\n;\r\ndate\r\n;\r\n; Build Z80 version\r\nc -o -v c309-20.c\r\n;\r\n; Now build Z280 version\r\n;\r\n; First a Z280 version using the Z80 LIBC.LIB (runs on Z80)\r\nc309-20 -o -v -ec280z80.com -dZ280 c309-20.c\r\n;\r\n; and the Z280 optimized version from it (only runs on a Z280)\r\nc280z80 -of2 -v -ec280-20.com c309-20.c\r\n;\r\n; plus a Z80 version of the Z280 optimisation program in case\r\n; we need to bootstrap a new LIB280C.LIB using the Z80 C280Z80\r\n; compiler front end on a Z80\r\nc280z80 -o2 -v -eoptimh80.com optimh.c\r\n;\r\n; Build the optimiser with the Z280 compiler front-end (may fail\r\n; if the LIB280C.LIB library is not present or compatible with\r\n; the latest updates - use C280Z80 and OPTIMH80 instead.\r\nc280-20 -o2 -v optimh.c\r\n;\r\ndir c*.com [fu\r\ndir optimh.com [fu\r\n;\r\n; Done\r\nput console to console\r\n"
  },
  {
    "path": "cpm/BUILDCPM.SUB",
    "content": "c\r\n<-c -o start1.as open.c read.c write.c chmod.c seek.c \\\r\n<fcbname.c rename.c creat.c time.c convtime.c timezone.c \\\r\n<stat.c isatty.c cleanup.c close.c unlink.c dup.c getfcb.c \\\r\n<srand1.c getch.c signal.c getuid.as abort.c execl.as bdos.as \\\r\n<bios.as _exit.as exit.as fakeclea.as fakecpcl.as sys_err.c \\\r\n<mktime.c\r\n\r\n"
  },
  {
    "path": "cpm/BUILDCRT.SUB",
    "content": ";\r\n; Build the start-up modules\r\n;\r\nc -c -o zcrtcpm.as zdrtcpm.as zrrtcpm.as znrtcpm.as\r\nc280 -c -o zc280cpm.as zd280cpm.as zr280cpm.as zn280cpm.as\r\n"
  },
  {
    "path": "cpm/C-ORIG.C",
    "content": "/*\r\n *\tCopyright (C) 1984-1897 HI-TECH SOFTWARE\r\n *\r\n *\tThis software remains the property of HI-TECH SOFTWARE and is\r\n *\tsupplied under licence only. The use of this software is\r\n *\tpermitted under the terms of that licence only. Copying of\r\n *\tthis software except for the purpose of making backup or\r\n *\tworking copies for the use of the licensee on a single\r\n *\tprocessor is prohibited.\r\n */\r\n#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n#include\t<cpm.h>\r\n#include\t<exec.h>\r\n#include\t<stat.h>\r\n\r\n/*\r\n *\tC command\r\n *\tCP/M-80 version\r\n *\r\n *\tC [-C] [-O] [-I] [-F] [-U] [-D] [-S] [-X] [-P] [-W] [-M] files {-Llib}\r\n */\r\n\r\n#define\tDFCB\t((struct fcb *)0x5C)\r\n\r\n#define\tMAXLIST\t60\t\t/* max arg list */\r\n#define\tBIGLIST\t120\t\t/* room for much more */\r\n\r\n#define\tHITECH\t\"HITECH\"\r\n#define\tPROMPT\t\"c\"\r\n#define\tTEMP\t\"TMP\"\r\n#define\tDEFPATH\t\"0:A:\"\r\n#define\tDEFTMP\t\"\"\r\n\r\n#define\tLIBSUFF\t\".LIB\"\t\t/* library suffix */\r\n\r\n#define\tLFLAGS\t\t\"-Z\"\r\n#define\tSTDLIB\t\t\"C\"\r\n#define\tGETARGS\t\t\"-U__getargs\"\r\n\r\nstatic char\tkeep,\t\t/* retain .obj files, don't link */\r\n\t\tkeepas,\t\t/* retain .as files, don't assemble */\r\n\t\tverbose,\t/* verbose - echo all commands */\r\n\t\toptimize,\t/* invoke optimizer */\r\n\t\tspeed,\t\t/* optimize for speed */\r\n\t\treloc,\t\t/* auto-relocate program at run time */\r\n\t\txref,\t\t/* generate cross reference listing */\r\n\t\tnolocal;\t/* strip local symbols */\r\n\r\nstatic char *\tiuds[MAXLIST],\t/* -[IUD] args to preprocessor */\r\n\t    *\tobjs[MAXLIST],\t/* .obj files and others for linker */\r\n\t    *\tflgs[BIGLIST],\t/* flags etc for linker */\r\n\t    *\tlibs[MAXLIST],\t/* .lib files for linker */\r\n\t    *\tc_as[MAXLIST];\t/* .c files to compile or .as to assemble */\r\n\r\nstatic uchar\tiud_idx,\t/* index into uids[] */\r\n\t\tobj_idx,\t/*   \"     \"  objs[] */\r\n\t\tflg_idx,\t/*   \"     \"  flgs[] */\r\n\t\tlib_idx,\t/*   \"     \"  libs[] */\r\n\t\tc_as_idx;\t/*   \"     \"  c_as[] */\r\nstatic char *\tpaths[] =\r\n{\r\n\t\"LINQ\",\r\n\t\"OBJTOHEX\",\r\n\t\"CGEN\",\r\n\t\"OPTIM\",\r\n\t\"CPP\",\r\n\t\"ZAS\",\r\n\t\"LIB\",\r\n\t\"P1\",\r\n\t\"CRTCPM.OBJ\",\r\n\t\"$EXEC\",\r\n\t\"CREF\",\r\n};\r\n\r\n#define\tlinker\tpaths[0]\r\n#define\tobjto\tpaths[1]\r\n#define\tcgen\tpaths[2]\r\n#define\toptim\tpaths[3]\r\n#define\tcpp\tpaths[4]\r\n#define\tassem\tpaths[5]\r\n#define\tlibpath\tpaths[6]\r\n#define\tpass1\tpaths[7]\r\n#define\tstrtoff\tpaths[8]\r\n#define\texecprg\tpaths[9]\r\n#define\tcref\tpaths[10]\r\n\r\n#define\tRELSTRT\tstrtoff[plen]\r\n\r\nstatic char *\ttemps[] =\r\n{\r\n\t\"$CTMP1.$$$\",\r\n\t\"$CTMP2.$$$\",\r\n\t\"$CTMP3.$$$\",\r\n\t\"$CTMP4.$$$\",\r\n\t\"L.OBJ\",\r\n\t\"$$EXEC.$$$\",\r\n\t\"CREF.TMP\",\r\n};\r\n\r\n#define\ttmpf1\ttemps[0]\r\n#define\ttmpf2\ttemps[1]\r\n#define\ttmpf3\ttemps[2]\r\n#define\tredname\ttemps[3]\r\n#define\tl_dot_obj\ttemps[4]\r\n#define\texecmd\ttemps[5]\r\n#define\tcrtmp\ttemps[6]\r\n\r\nstatic char *\tcppdef[] = { \"-DCPM\", \"-DHI_TECH_C\", \"-Dz80\" };\r\nstatic char *\tcpppath = \"-I\";\r\n\r\n\r\nstatic char\ttmpbuf[128];\t/* gen. purpose buffer */\r\nstatic char\tsingle[40];\t/* single object file to be deleted */\r\nstatic short\tnfiles;\t\t/* number of source or object files seen */\r\nstatic char *\toutfile;\t/* output file name for objtohex */\r\nstatic FILE *\tcmdfile;\t/* command file */\r\nstatic short\tplen;\t\t/* length of path */\r\nstatic char\tebuf[22];\t/* error listing file */\r\nstatic char *\txrname;\r\nstatic struct stat\tstatbuf;\r\n\r\nextern char *\tmalloc(),\r\n\t    *\tgetenv(),\r\n\t    *\tfcbname(),\r\n\t    *\trindex(),\r\n\t    *\tstrcat(),\r\n\t    *\tstrcpy();\r\nextern char **\t_getargs();\r\nextern int\tstrlen(),\r\n\t\tstrcmp(),\r\n\t\tdup();\r\n\r\nstatic char *\txalloc();\r\n\r\nmain(argc, argv)\r\nchar **\targv;\r\n{\r\n\tregister char *\tcp, * xp;\r\n\tshort\t\ti;\r\n\r\n\tfprintf(stderr, \"HI-TECH C COMPILER (CP/M-80) V3.09\\n\");\r\n\tfprintf(stderr, \"Copyright (C) 1984-87 HI-TECH SOFTWARE\\n\");\r\n#if\tEDUC\r\n\tfprintf(stderr, \"Licensed for Educational purposes only\\n\");\r\n#endif\tEDUC\r\n\tif(argc == 1)\r\n\t\targv = _getargs((char *)0, PROMPT);\r\n\tsetup();\r\n\twhile(*++argv) {\r\n\t\tif((argv)[0][0] == '-') {\r\n\t\t\tif(islower(i = argv[0][1]))\r\n\t\t\t\targv[0][1] = i = toupper(i);\r\n\t\t\tswitch(i) {\r\n\r\n\t\t\tcase 'A':\r\n\t\t\t\treloc = 1;\r\n\t\t\t\tRELSTRT = 'R';\r\n\t\t\t\tflgs[flg_idx++] = \"-L\";\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'R':\r\n\t\t\t\tflgs[flg_idx++] = GETARGS;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'V':\r\n\t\t\t\tverbose = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'S':\r\n\t\t\t\tkeepas = 1;\r\n\r\n\t\t\tcase 'C':\r\n\t\t\t\tif(argv[0][2] == 'r' || argv[0][2] == 'R') {\r\n\t\t\t\t\txref = 1;\r\n\t\t\t\t\tif(argv[0][3]) {\r\n\t\t\t\t\t\txrname = &argv[0][1];\r\n\t\t\t\t\t\txrname[0] = '-';\r\n\t\t\t\t\t\txrname[1] = 'o';\r\n\t\t\t\t\t} else\r\n\t\t\t\t\t\txrname = (char *)0;\r\n\t\t\t\t} else\r\n\t\t\t\t\tkeep = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'O':\r\n\t\t\t\toptimize = 1;\r\n\t\t\t\tif(argv[0][2] == 'F' || argv[0][2] == 'f')\r\n\t\t\t\t\tspeed = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'I':\r\n\t\t\tcase 'U':\r\n\t\t\tcase 'D':\r\n\t\t\t\tiuds[iud_idx++] = argv[0];\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'L':\r\n\t\t\t\taddlib(&argv[0][2]);\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'F':\r\n\t\t\t\targv[0][1] = 'D';\r\n\t\t\t\tflgs[flg_idx++] = argv[0];\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'X':\r\n\t\t\t\tnolocal = 1;\r\n\r\n\t\t\tcase 'P':\r\n\t\t\tcase 'M':\r\n\t\t\tcase 'W':\r\n\t\t\t\tflgs[flg_idx++] = argv[0];\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\tfprintf(stderr, \"Unknown flag %s\\n\", argv[0]);\r\n\t\t\t\texit(1);\r\n\t\t\t}\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tnfiles++;\r\n\t\tcp = argv[0];\r\n\t\twhile(*cp) {\r\n\t\t\tif(islower(*cp))\r\n\t\t\t\t*cp = toupper(*cp);\r\n\t\t\tcp++;\r\n\t\t}\r\n\t\tcp = rindex(argv[0], '.');\r\n\t\tif(cp && (strcmp(cp, \".C\") == 0 || strcmp(cp, \".AS\") == 0)) {\r\n\t\t\tc_as[c_as_idx++] = argv[0];\r\n\t\t\tif(xp = rindex(argv[0], ':'))\r\n\t\t\t\txp++;\r\n\t\t\telse\r\n\t\t\t\txp = argv[0];\r\n\t\t\t*cp = 0;\r\n\t\t\tstrcat(strcpy(tmpbuf, xp), \".OBJ\");\r\n\t\t\taddobj(tmpbuf);\r\n\t\t\tstrcpy(single, tmpbuf);\r\n\t\t\t*cp = '.';\r\n\t\t} else\r\n\t\t\taddobj(argv[0]);\r\n\t}\r\n\tdoit();\r\n}\r\n\r\nsetup()\r\n{\r\n\tregister char *\tcp;\r\n\tshort\t\ti, len;\r\n\r\n\tif(!(cp = getenv(HITECH)))\r\n\t\tif(stat(\"P1.COM\", &statbuf) >= 0)\r\n\t\t\tcp = \"\";\r\n\t\telse\r\n\t\t\tcp = DEFPATH;\r\n\tplen = strlen(cp);\r\n\tcpppath = strcat(strcpy(xalloc(plen+strlen(cpppath)+1), cpppath), cp);\r\n\tfor(i = 0 ; i < sizeof paths/sizeof paths[0] ; i++)\r\n\t\tpaths[i] = strcat(strcpy(xalloc(plen+strlen(paths[i])+1), cp), paths[i]);\r\n\tif(cp = getenv(TEMP)) {\r\n\t\tlen = strlen(cp);\r\n\t\tfor(i = 0 ; i < sizeof temps/sizeof temps[0] ; i++)\r\n\t\t\ttemps[i] = strcat(strcpy(xalloc(len+strlen(temps[i])+1), cp), temps[i]);\r\n\t}\r\n\tif(strcmp(fcbname(fileno(stdout)), \"CON:\")) {\t/* redirect errors */\r\n\t\tstrcat(strcpy(ebuf, \"-E\"), fcbname(fileno(stdout)));\r\n\t\tclose(fileno(stdout));\r\n\t\tstdout->_file = dup(fileno(stderr));\r\n\t}\r\n\tobjs[0] = strtoff;\r\n\tobj_idx = 1;\r\n\tflgs[0] = LFLAGS;\r\n\tflg_idx = 1;\r\n\tfor(i = 0 ; i < sizeof cppdef/sizeof cppdef[0] ; i++)\r\n\t\tiuds[i] = cppdef[i];\r\n\tiud_idx = i;\r\n}\r\n\r\ndoit()\r\n{\r\n\tregister char *\tcp;\r\n\tregister uchar\ti;\r\n\r\n\tif(xref)\r\n\t\tclose(creat(crtmp, 0600));\r\n\tiuds[iud_idx++] = cpppath;\r\n\tif(!(cmdfile = fopen(execmd, \"wb\")))\r\n\t\terror(\"Can't create temporary file %s\", execmd);\r\n\tput_cmd(SKP_ERR);\r\n\tif(verbose)\r\n\t\tput_cmd(ECHO);\r\n\tfor(i = 0 ; i < c_as_idx ; i++) {\r\n\t\tcp = rindex(c_as[i], '.');\r\n\t\tif(strcmp(cp, \".C\") == 0)\r\n\t\t\tcompile(c_as[i]);\r\n\t\telse\r\n\t\t\tassemble(c_as[i]);\r\n\t\tput_cmd(TRAP);\r\n\t}\r\n\trm(RM_FILE, tmpf1);\r\n\trm(RM_FILE, tmpf2);\r\n\trm(RM_FILE, tmpf3);\r\n\tif(!keep) {\r\n\t\tflgs[flg_idx++] = \"-Ptext=0,data,bss\";\r\n\t\tif(reloc)\r\n\t\t\tflgs[flg_idx++] = strcat(strcpy(xalloc(strlen(l_dot_obj)+3), \"-o\"), l_dot_obj);\r\n\t\telse {\r\n\t\t\tflgs[flg_idx++] = \"-C100H\";\r\n\t\t\tflgs[flg_idx++] = strcat(strcpy(xalloc(strlen(outfile)+3), \"-O\"), outfile);\r\n\t\t}\r\n\t\tfor(i = 0 ; i < obj_idx ; i++)\r\n\t\t\tflgs[flg_idx++] = objs[i];\r\n\t\taddlib(STDLIB);\r\n\t\tfor(i = 0 ; i < lib_idx ; i++)\r\n\t\t\tflgs[flg_idx++] = libs[i];\r\n\t\tflgs[flg_idx] = 0;\r\n\t\tput_cmd(IF_NERR);\r\n\t\tdoexec(linker, flgs);\r\n\t\tif(reloc) {\r\n\t\t\tflgs[0] = \"-R\";\r\n\t\t\tflgs[1] = \"-B100H\";\r\n\t\t\tflgs[2] = l_dot_obj;\r\n\t\t\tflgs[3] = outfile;\r\n\t\t\tflgs[4] = (char *)0;\r\n\t\t\tdoexec(objto, flgs);\r\n\t\t\trm(RM_FILE, l_dot_obj);\r\n\t\t}\r\n\t\tif(c_as_idx == 1 && nfiles == 1)\r\n\t\t\trm(RM_FILE, single);\r\n\t}\r\n\tif(xref)\r\n\t\tif(xrname) {\r\n\t\t\tflgs[0] = xrname;\r\n\t\t\tstrcat(strcpy(tmpbuf, \"-h\"), outfile);\r\n\t\t\tif(cp = rindex(tmpbuf, '.'))\r\n\t\t\t\tstrcpy(cp, \".CRF\");\r\n\t\t\telse\r\n\t\t\t\tstrcat(tmpbuf, \".CRF\");\r\n\t\t\tflgs[1] = tmpbuf;\r\n\t\t\tflgs[2] = crtmp;\r\n\t\t\tflgs[3] = 0;\r\n\t\t\tput_cmd(IF_NERR);\r\n\t\t\tdoexec(cref, flgs);\r\n\t\t\trm(RM_FILE, crtmp);\r\n\t\t} else {\r\n\t\t\tsprintf(tmpbuf, \"Cross reference info left in %s: run CREF to produce listing\\n\", crtmp);\r\n\t\t\tprint(tmpbuf);\r\n\t\t}\r\n\tput_cmd(TRAP);\r\n\trm(RM_EXIT, execmd);\r\n\tfclose(cmdfile);\r\n\tfclose(stdout);\r\n\tfclose(stdin);\r\n\tsetfcb(DFCB, execmd);\r\n\texecl(execprg, execprg, execmd, (char *)0);\r\n\terror(\"Can't execute %s\", execprg);\r\n}\r\n\r\nrm(type, file)\r\nchar *\tfile;\r\n{\r\n\tchar\tbuf[40];\r\n\r\n\tif(verbose) {\r\n\t\tstrcat(strcpy(buf, \"ERA \"), file);\r\n\t\tprint(buf);\r\n\t}\r\n\tsetfcb(DFCB, file);\r\n\tputc(type, cmdfile);\r\n\tputc(16, cmdfile);\r\n\tfwrite(DFCB, 1, 16, cmdfile);\r\n}\r\n\r\nprint(s)\r\nchar *\ts;\r\n{\r\n\tputc(PRINT, cmdfile);\r\n\tputc(strlen(s), cmdfile);\r\n\tfputs(s, cmdfile);\r\n}\r\n\r\nput_cmd(i)\r\n{\r\n\tputc(i, cmdfile);\r\n\tputc(0, cmdfile);\r\n}\r\n\r\naddobj(s)\r\nchar *\ts;\r\n{\r\n\tchar *\tcp;\r\n\tuchar\tlen;\r\n\tstatic char\toname;\r\n\r\n\tif(oname == 0) {\r\n\t\toname = 1;\r\n\t\tif(cp = rindex(s, '.'))\r\n\t\t\tlen = cp - s;\r\n\t\telse\r\n\t\t\tlen = strlen(s);\r\n\t\tcp = xalloc(len + strlen(\"-O.COM\") + 1);\r\n\t\tstrncat(strcpy(cp, \"-O\"), s, len);\r\n\t\tstrcpy(cp+len+2, \".COM\");\r\n\t\toutfile = cp+2;\r\n\t}\r\n\tcp = xalloc(strlen(s)+1);\r\n\tstrcpy(cp, s);\r\n\tobjs[obj_idx++] = cp;\r\n}\r\n\r\naddlib(s)\r\nchar *\ts;\r\n{\r\n\tchar *\tcp;\r\n\r\n\tstrcpy(tmpbuf, libpath);\r\n\tstrcat(strcat(tmpbuf, s), LIBSUFF);\r\n\tcp = xalloc(strlen(tmpbuf)+1);\r\n\tstrcpy(cp, tmpbuf);\r\n\tlibs[lib_idx++] = cp;\r\n}\r\n\r\nerror(s, a)\r\nchar *\ts;\r\n{\r\n\tfprintf(stderr, s, a);\r\n\texit(1);\r\n}\r\n\r\nstatic char *\r\nxalloc(s)\r\nshort\ts;\r\n{\r\n\tregister char *\tcp;\r\n\r\n\tif(!(cp = malloc(s)))\r\n\t\terror(\"Out of memory\");\r\n\treturn cp;\r\n}\r\n\r\nupcase(s)\r\nregister char *\ts;\r\n{\r\n\twhile(*s) {\r\n\t\tif(*s >= 'a' && *s <= 'z')\r\n\t\t\t*s -= 'a'-'A';\r\n\t\ts++;\r\n\t}\r\n}\r\n\r\ndoexec(name, vec)\r\nchar *\tname;\r\nchar **\tvec;\r\n{\r\n\tuchar\tlen;\r\n\tchar **\tpvec;\r\n\tchar *\tredir[2];\r\n\tchar\tredbuf[20];\r\n\tFILE *\tcfile;\r\n\tstatic short\tredno;\r\n\tchar\txbuf[130];\r\n\r\n\tpvec = vec;\r\n\tlen = 0;\r\n\tredbuf[0] = 0;\r\n\twhile(*pvec)\r\n\t\tlen += strlen(*pvec++)+1;\r\n\tif(len > 124) {\r\n\t\tsprintf(xbuf, redname, ++redno);\r\n\t\tif(!(cfile = fopen(xbuf, \"w\")))\r\n\t\t\terror(\"Can't create %s\", xbuf);\r\n\t\tlen = 0;\r\n\t\twhile(*vec) {\r\n\t\t\tlen += strlen(*vec);\r\n\t\t\tfprintf(cfile, \"%s \", *vec++);\r\n\t\t\tif(len > 126) {\r\n\t\t\t\tlen = 0;\r\n\t\t\t\tfprintf(cfile, \"\\\\\\n\");\r\n\t\t\t}\r\n\t\t}\r\n\t\tfputc('\\n', cfile);\r\n\t\tfclose(cfile);\r\n\t\tredir[1] = (char *)0;\r\n\t\tsprintf(redbuf, \"<%s\", xbuf);\r\n\t\tredir[0] = redbuf;\r\n\t\tvec = redir;\r\n\t}\r\n\txbuf[0] = 0;\r\n\twhile(*vec)\r\n\t\tstrcat(strcat(xbuf, \" \"), *vec++);\r\n\tlen = strlen(xbuf);\r\n\tputc(EXEC, cmdfile);\r\n\tputc(len+50, cmdfile);\r\n\tsetfcb(DFCB, name);\r\n\tstrcpy(DFCB->ft, \"COM\");\r\n\tDFCB->nr = 0;\r\n\tputc(DFCB->uid, cmdfile);\r\n\tfwrite(DFCB, 1, 16, cmdfile);\r\n\tsetfcb(DFCB, &xbuf[1]);\r\n\tDFCB->nr = 0;\r\n\tfwrite(DFCB, 1, 32, cmdfile);\r\n\tputc(len, cmdfile);\r\n\tfwrite(xbuf, 1, len, cmdfile);\r\n\tif(redbuf[0])\r\n\t\trm(RM_FILE, &redbuf[1]);\r\n}\r\n\r\nassemble(s)\r\nchar *\ts;\r\n{\r\n\tchar *\tvec[5];\r\n\tchar\tbuf[80];\r\n\tchar *\tcp;\r\n\tuchar\ti;\r\n\r\n\tif(c_as_idx > 1)\r\n\t\tprint(s);\r\n\ti = 0;\r\n\tif(optimize && !speed)\r\n\t\tvec[i++] = \"-J\";\r\n\tif(nolocal)\r\n\t\tvec[i++] = \"-X\";\r\n\tif(cp = rindex(s, ':'))\r\n\t\tcp++;\r\n\telse\r\n\t\tcp = s;\r\n\tstrcat(strcpy(buf, \"-O\"), cp);\r\n\tif(rindex(buf, '.'))\r\n\t\t*rindex(buf, '.') = 0;\r\n\tstrcat(buf, \".OBJ\");\r\n\tvec[i++] = buf;\r\n\tvec[i++] = s;\r\n\tvec[i] = (char *)0;\r\n\tdoexec(assem, vec);\r\n}\r\n\r\ncompile(s)\r\nchar *\ts;\r\n{\r\n\tregister char *\tcp;\r\n\tuchar\ti, j;\r\n\tchar *\tvec[MAXLIST];\r\n\tchar\tcbuf[50];\r\n\r\n\tif(c_as_idx > 1)\r\n\t\tprint(s);\r\n\tfor(j = 0; j < iud_idx ; j++)\r\n\t\tvec[j] = iuds[j];\r\n\tvec[j++] = s;\r\n\tvec[j++] = tmpf1;\r\n\tvec[j] = (char *)0;\r\n\tdoexec(cpp, vec);\r\n\tif(cp = rindex(s, ':'))\r\n\t\ts = cp+1;\r\n\t*rindex(s, '.') = 0;\r\n\ti = 0;\r\n\tif(keepas && !optimize)\r\n\t\tvec[i++] = \"-S\";\r\n\tif(xref)\r\n\t\tvec[i++] = strcat(strcpy(cbuf, \"-c\"), crtmp);\r\n\tif(ebuf[0])\t\t/* error redirection */\r\n\t\tvec[i++] = ebuf;\r\n\tvec[i++] = tmpf1;\r\n\tvec[i++] = tmpf2;\r\n\tvec[i++] = tmpf3;\r\n\tvec[i++] = (char *)0;\r\n\tdoexec(pass1, vec);\r\n\tvec[0] = tmpf2;\r\n\tvec[1] = keepas && !optimize ? strcat(strcpy(tmpbuf, s), \".AS\") : tmpf1;\r\n\tvec[2] = (char *)0;\r\n\tdoexec(cgen, vec);\r\n\tif(keepas && !optimize)\r\n\t\treturn;\r\n\tcp = tmpf1;\r\n\tif(optimize) {\r\n\t\ti = 0;\r\n\t\tif(speed)\r\n\t\t\tvec[i++] = \"-F\";\r\n\t\tvec[i++] = tmpf1;\r\n\t\tif(keepas)\r\n\t\t\tvec[i++] = strcat(strcpy(tmpbuf, s), \".AS\");\r\n\t\telse\r\n\t\t\tvec[i++] = tmpf2;\r\n\t\tvec[i] = (char *)0;\r\n\t\tdoexec(optim, vec);\r\n\t\tif(keepas)\r\n\t\t\treturn;\r\n\t\tcp = tmpf2;\r\n\t}\r\n\ti = 0;\r\n\tif(nolocal)\r\n\t\tvec[i++] = \"-X\";\r\n\tif(optimize && !speed)\r\n\t\tvec[i++] = \"-J\";\r\n\tvec[i++] = \"-N\";\r\n\tvec[i++] = strcat(strcat(strcpy(tmpbuf, \"-o\"), s), \".OBJ\");\r\n\tvec[i++] = cp;\r\n\tvec[i] = (char *)0;\r\n\tdoexec(assem, vec);\r\n}\r\n"
  },
  {
    "path": "cpm/C309-20.C",
    "content": "/*\r\n *  Copyright (C) 1984-1987 HI-TECH SOFTWARE\r\n *\r\n *  This software remains the property of HI-TECH SOFTWARE and is\r\n *  supplied under licence only. The use of this software is\r\n *  permitted under the terms of that licence only. Copying of\r\n *  this software except for the purpose of making backup or\r\n *  working copies for the use of the licensee on a single\r\n *  processor is prohibited.\r\n */\r\n\r\n/*----------------------------------------------------------------------*\\\r\n | Note by Jon Saxton, 3 May 2014.\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | It appears that the source file C.C distributed with Hi-Tech C 3.09\t|\r\n | for CP/M-80 does not quite match the C.COM in the same distribution.\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | This is a slightly modified version of C.C which yields a C.COM that\t|\r\n | seems to work and so could probably replace the standard compiler\t|\r\n | driver.  I use this version but just in case there is a bug which I\t|\r\n | have not yet discovered, I am leaving the original C.COM unchanged.\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Updates by Tony Nicholson (@agn453) and Thierry Supplisson\t\t|\r\n | (@tsupplis), 14 January 2021.\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Revised to better support building self-relocating .COM files and\t|\r\n | overlays by automating the building of the resident and overlay\t|\r\n | portions (new -Y compiler flag).\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | For new features, re-implement Z280 version (original sources lost)\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Now has an -N option to select minimal _getargs() support (the\t|\r\n | previous -R option is the default - and is ignored if specified)\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | This version also attempts assembly language optimisation for the\t|\r\n | Z280 MPU via OPTIMH to allow the libraries to be optimised.\t\t|\r\n\\*----------------------------------------------------------------------*/\r\n\r\n#include    <stdio.h>\r\n#include    <ctype.h>\r\n#include    <string.h>\r\n#include    <cpm.h>\r\n#include    <exec.h>\r\n#include    <stat.h>\r\n#include    <sys.h>\r\n#include    <stdlib.h>\r\n#include    <unixio.h>\r\n#include    <signal.h>\r\n\r\n/*\r\n * C command\r\n * CP/M-80 version\r\n *\r\n * C [-C] [-O] [-I] [-F] [-U] [-D] [-S] [-X] [-P] \\\r\n *\t[-W] [-N] [-M] [-V] [-Y] files {-Llib}\r\n */\r\n\r\n#define DFCB    ((struct fcb *)0x5C)\r\n\r\n#define MAXLIST 60      /* max arg list */\r\n#define BIGLIST 120     /* room for much more */\r\n\r\n#define HITECH  \"HITECH\"\r\n#define PROMPT  \"c\"\r\n#define TEMP    \"TMP\"\r\n#define DEFPATH \"0:A:\"\r\n#define DEFTMP  \"\"\r\n\r\n#define LIBSUFF \".LIB\"      /* library suffix */\r\n\r\n#define LFLAGS      \"-Z\"\r\n#define STDLIB      \"C\"\r\n\r\nstatic char\r\n    keep,       /* retain .obj files, don't link */\r\n    keepas,     /* retain .as files, don't assemble */\r\n    verbose,    /* verbose - echo all commands */\r\n    optimize,   /* invoke optimizer */\r\n    speed,      /* optimize for speed */\r\n    reloc,      /* auto-relocate program at run time */\r\n    xref,       /* generate cross reference listing */\r\n    nolocal,    /* strip local symbols */\r\n#ifdef Z280\r\n    z280optim,  /* Z280 code optimization */\r\n#endif\r\n    overlay=0;  /* build with overlays */\r\n\r\nstatic char\r\n    *iuds[MAXLIST],  /* -[IUD] args to preprocessor */\r\n    *objs[MAXLIST],  /* .obj files and others for linker */\r\n    *flgs[BIGLIST],  /* flags etc for linker */\r\n    *libs[MAXLIST],  /* .lib files for linker */\r\n    *c_as[MAXLIST];  /* .c files to compile or .as to assemble */\r\n\r\nstatic uchar\r\n    iud_idx,    /* index into uids[] */\r\n    obj_idx,    /*   \"     \"  objs[] */\r\n    flg_idx,    /*   \"     \"  flgs[] */\r\n    lib_idx,    /*   \"     \"  libs[] */\r\n    c_as_idx;   /*   \"     \"  c_as[] */\r\n\r\nstatic char *paths[] =\r\n{\r\n    \"LINQ\",\t/* Renamed from LINK to avoid conflict with DRI's LINK-80 */\r\n    \"OBJTOHEX\",\r\n    \"CGEN\",\r\n    \"OPTIM\",\r\n    \"CPP\",\r\n#ifdef USE_Z80AS\r\n    \"Z80AS\",\r\n#else\r\n    \"ZAS\",\r\n#endif\r\n#ifdef Z280\r\n    \"LIB280\",\r\n#else\r\n    \"LIB\",\r\n#endif\r\n    \"P1\",\r\n#ifdef Z280\r\n    \"C280CPM.OBJ\",\r\n#else\r\n    \"CRTCPM.OBJ\",\r\n#endif\r\n    \"$EXEC\",\r\n    \"CREF\",\r\n    \"SYMTOAS\",\r\n#ifdef Z280\r\n    \"C280OPTS\",\r\n    \"OPTIMH\",\r\n#else\r\n    \"OPTIONS\",\r\n#endif\r\n};\r\n\r\n#define linker  paths[0]\r\n#define objto   paths[1]\r\n#define cgen    paths[2]\r\n#define optim   paths[3]\r\n#define cpp     paths[4]\r\n#define assem   paths[5]\r\n#define libpath paths[6]\r\n#define pass1   paths[7]\r\n#define strtoff paths[8]\r\n#define execprg paths[9]\r\n#define cref    paths[10]\r\n#define symtoas paths[11]\r\n#define options\tpaths[12]\r\n#ifdef Z280\r\n#define optimh  paths[13]\r\n#endif\r\n\r\n#define RELSTRT strtoff[plen]\r\n\r\nstatic char *temps[] =\r\n{\r\n    \"$CTMP1.$$$\",\r\n    \"$CTMP2.$$$\",\r\n    \"$CTMP3.$$$\",\r\n    \"$CTMP4.$$$\",\r\n    \"$L.OBJ\",\r\n    \"$$EXEC.$$$\",\r\n    \"CREF.TMP\",\r\n    \"$CTMP5.$$$\",\r\n};\r\n\r\nstatic char *tempm[] =\r\n{\r\n    \"-Ptext=0%xh,data\",\r\n    \"-Ptext=0,data,bss\",\r\n    \"-Pcpm=0,text,data,bss,stack\",\r\n};\r\n\r\n#define tmpf1       temps[0]\r\n#define tmpf2       temps[1]\r\n#define tmpf3       temps[2]\r\n#define redname     temps[3]\r\n#define l_dot_obj   temps[4]\r\n#define execmd      temps[5]\r\n#define crtmp       temps[6]\r\n#define tmpf5       temps[7]\r\n\r\n#define osegs       tempm[0]\r\n#define nsegs       tempm[1]\r\n#define rsegs       tempm[2]\r\n\r\nstatic int      cbase = 0x0100;\r\n\r\nstatic char    *cppdef[] = {\r\n    \"-DCPM\",\r\n    \"-DHI_TECH_C\",\r\n    \"-Dz80\",\r\n#ifdef Z280\r\n    \"-DZ280\",\r\n#endif\r\n};\r\nstatic char    *cpppath = \"-I\";\r\n\r\nstatic char     tmpbuf[128];    /* gen. purpose buffer */\r\nstatic char     single[40];     /* single object file to be deleted */\r\nstatic short    nfiles;         /* number of source or object files seen */\r\nstatic char    *outfile;        /* output file name for objtohex */\r\nstatic FILE    *cmdfile;        /* command file */\r\nstatic short    plen;           /* length of path */\r\nstatic char     ebuf[22];       /* error listing file */\r\nstatic char    *xrname;\r\nstatic struct stat  statbuf;\r\n\r\nextern char\r\n   **_getargs();\t\t/* explicit for prompt mode */\r\n\r\nstatic char\r\n   *xalloc(short);\r\n\r\nint\r\n    sym2as(char * iname);\r\n\r\nvoid\r\n    doexec(char * name, char ** vec),\r\n    addobj(char * s, int p),\r\n    addlib(char * s),\r\n    setup(),\r\n    error(char * s, char * a),\r\n    doit(),\r\n    assemble(char * s),\r\n#ifdef Z280\r\n    optassemble(char * s),\r\n#endif\r\n    compile(char * s),\r\n    print(char * s),\r\n    put_cmd(int i),\r\n    rm(int type, char * file),\r\n    assemble_sym(char * s),\r\n    viewfile(char * s);\r\n\r\nint main(int argc, char **argv)\r\n{\r\n    register char *cp, *xp;\r\n    short       i;\r\n\r\n    /* Do not swallow queued stream input while writing to the console */\r\n    signal_t prev_sig;\r\n    prev_sig=signal(SIGINT,SIG_IGN);\r\n\r\n#ifdef Z280\r\n    fprintf(stderr, \"Hi-Tech Z280 C Compiler (CP/M-80) V%s\",_HTC_VERSION);\r\n#else\r\n    fprintf(stderr, \"Hi-Tech Z80 C Compiler (CP/M-80) V%s\",_HTC_VERSION);\r\n#endif\r\n    fprintf(stderr, \"\\nCopyright (C) 1984-87 HI-TECH SOFTWARE\\n\");\r\n    fprintf(stderr, \"Updated from https://github.com/agn453/HI-TECH-Z80-C\\n\");\r\n#if EDUC\r\n    fprintf(stderr, \"Licensed for Educational purposes only\\n\");\r\n#endif  EDUC\r\n\r\n    signal(SIGINT,prev_sig);\r\n\r\n    if (argc == 1)\r\n        argv = _getargs((char *)0, PROMPT);\r\n\r\n    setup();\r\n\r\n    while (*++argv)\r\n    {\r\n        if ((argv)[0][0] == '-')\r\n        {\r\n            if (islower(i = argv[0][1]))\r\n                argv[0][1] = i = toupper(i);\r\n\r\n            switch(i)\r\n            {\r\n            case 'A':\r\n                reloc = 1;\r\n                RELSTRT = 'R';\r\n                flgs[flg_idx++] = \"-L\";\r\n                break;\r\n\r\n            case 'R':\r\n                /* Wildcard expansion from the command line now built-in */\r\n                /* flgs[flg_idx++] = GETARGS; */\r\n                break;\r\n\r\n            case 'V':\r\n                verbose = 1;\r\n                break;\r\n\r\n            case 'S':\r\n                keepas = 1;\r\n\r\n            case 'C':\r\n                if (argv[0][2] == 'r' || argv[0][2] == 'R')\r\n                {\r\n                    xref = 1;\r\n                    if (argv[0][3])\r\n                    {\r\n                        xrname = &argv[0][1];\r\n                        xrname[0] = '-';\r\n                        xrname[1] = 'o';\r\n                    }\r\n                    else\r\n                        xrname = (char *)0;\r\n                }\r\n                else\r\n                    keep = 1;\r\n                break;\r\n\r\n            case 'E':\r\n                outfile = &argv[0][2];\r\n                break;\r\n\r\n            case 'O':\r\n                optimize = 1;\r\n                if(argv[0][2] == 'F' || argv[0][2] == 'f')\r\n                {\r\n                    speed = 1;\r\n#ifdef Z280\r\n                    if (argv[0][3] == '2')\r\n                        z280optim = 1;\r\n#endif\r\n                }\r\n#ifdef Z280\r\n                else if( argv[0][2] == '2' )\r\n                    z280optim = 1;\r\n#endif\r\n                break;\r\n\r\n            case 'I':\r\n            case 'U':\r\n            case 'D':\r\n                iuds[iud_idx++] = argv[0];\r\n                break;\r\n\r\n            case 'L':\r\n                addlib(&argv[0][2]);\r\n                break;\r\n\r\n            case 'F':\r\n                argv[0][1] = 'D';\r\n                flgs[flg_idx++] = argv[0];\r\n                break;\r\n\r\n            case 'X':\r\n                nolocal = 1;\r\n\r\n            case 'P':\r\n            case 'M':\r\n            case 'W':\r\n                flgs[flg_idx++] = argv[0];\r\n                break;\r\n\r\n            case 'Y':\r\n                overlay = 1;\r\n                break;\r\n\r\n\t    case 'H':\r\n                viewfile(options);\r\n                exit(0); /* Ignore all other options for HELP */\r\n\r\n\t    case 'N':\r\n                RELSTRT = 'N'; /* Use minimal getargs */\r\n                break;\r\n\r\n            default:\r\n                error(\"Unknown flag %s - use -H for HELP\", argv[0]);\r\n            }\r\n            continue;\r\n        }\r\n\r\n        if (overlay && reloc)\r\n        {\r\n            fprintf(stderr, \"-Y and -A options are incompatible, ignoring -Y\\n\");\r\n            overlay = 0;\r\n        }\r\n\r\n        ++nfiles;\r\n        cp = argv[0];\r\n        while (*cp)\r\n        {\r\n            if (islower(*cp))\r\n                *cp = toupper(*cp);\r\n            ++cp;\r\n        }\r\n        cp = rindex(argv[0], '.');\r\n        if (cp && (strcmp(cp, \".C\") == 0 || strcmp(cp, \".AS\") == 0))\r\n        {\r\n            c_as[c_as_idx++] = argv[0];\r\n            if (xp = rindex(argv[0], ':'))\r\n                ++xp;\r\n            else\r\n                xp = argv[0];\r\n            *cp = 0;\r\n            strcat(strcpy(tmpbuf, xp), \".OBJ\");\r\n            addobj(tmpbuf, 1);\r\n            strcpy(single, tmpbuf);\r\n            *cp = '.';\r\n        }\r\n        else if (cp && (strcmp(cp, \".SYM\")==0 ))\r\n            {\r\n                if (overlay)\r\n                    {\r\n                        c_as[c_as_idx++] = argv[0];\r\n                        if (xp = rindex(argv[0], ':'))\r\n                            xp++;\r\n                        else\r\n                            xp = argv[0];\r\n                        *cp = 0;\r\n                        strcat(strcpy(tmpbuf, xp), \".OBJ\");\r\n                        addobj(tmpbuf, 1);\r\n                        strcpy(single, tmpbuf);\r\n                        *cp = '.';\r\n                    }\r\n                else\r\n                    fprintf(stderr,\"%s ignored as -Y option missing\\n\",argv[0]);\r\n            }\r\n        else\r\n            addobj(argv[0], 0);\r\n    }\r\n    doit();\r\n}\r\n\r\nvoid setup()\r\n{\r\n    register char * cp;\r\n    short       i, len;\r\n\r\n    if (!(cp = getenv(HITECH)))\r\n        if (stat(\"P1.COM\", &statbuf) >= 0)\r\n            cp = \"\";\r\n        else\r\n            cp = DEFPATH;\r\n    plen = strlen(cp);\r\n    cpppath = strcat(strcpy(xalloc(plen+strlen(cpppath)+1), cpppath), cp);\r\n    for (i = 0 ; i < sizeof paths/sizeof paths[0] ; i++)\r\n        paths[i] = strcat(strcpy(xalloc(plen+strlen(paths[i])+1), cp),\r\n                          paths[i]);\r\n    if (cp = getenv(TEMP))\r\n    {\r\n        len = strlen(cp);\r\n        for (i = 0; i < sizeof temps/sizeof temps[0]; ++i)\r\n            temps[i] = strcat(strcpy(xalloc(len+strlen(temps[i])+1), cp),\r\n                              temps[i]);\r\n    }\r\n    if (strcmp(fcbname(fileno(stdout)), \"CON:\"))   /* redirect errors */\r\n    {\r\n        strcat(strcpy(ebuf, \"-E\"), fcbname(fileno(stdout)));\r\n        close(fileno(stdout));\r\n        stdout->_file = dup(fileno(stderr));\r\n    }\r\n    objs[0] = strtoff;\r\n    obj_idx = 1;\r\n    flgs[0] = LFLAGS;\r\n    flg_idx = 1;\r\n    for (i = 0; i < sizeof cppdef/sizeof cppdef[0]; ++i)\r\n        iuds[i] = cppdef[i];\r\n    iud_idx = i;\r\n}\r\n\r\nvoid doit()\r\n{\r\n    register char * cp;\r\n    register uchar  i;\r\n\r\n    if (xref)\r\n        close(creat(crtmp, 0600));\r\n    iuds[iud_idx++] = cpppath;\r\n    if (!(cmdfile = fopen(execmd, \"wb\")))\r\n        error(\"Can't create temporary file %s\", execmd);\r\n    put_cmd(SKP_ERR);\r\n    if (verbose)\r\n        put_cmd(ECHO);\r\n    for (i = 0 ; i < c_as_idx ; i++)\r\n    {\r\n        cp = rindex(c_as[i], '.');\r\n        if (strcmp(cp, \".C\") == 0)\r\n            compile(c_as[i]);\r\n        else if (strcmp(cp, \".AS\") == 0)\r\n        {\r\n#ifdef Z280\r\n            if (z280optim)\r\n                optassemble(c_as[i]);\r\n            else\r\n                assemble(c_as[i]);\r\n#else\r\n            assemble(c_as[i]);\r\n#endif\r\n        }\r\n        else if (strcmp(cp, \".SYM\") == 0)\r\n            assemble_sym(c_as[i]);\r\n        put_cmd(TRAP);\r\n    }\r\n    rm(RM_FILE, tmpf1);\r\n    rm(RM_FILE, tmpf2);\r\n    rm(RM_FILE, tmpf3);\r\n    rm(RM_FILE, tmpf5);\r\n    if (!keep)\r\n    {\r\n        char * segopt = 0;\r\n        if (overlay)\r\n        {\r\n            segopt = xalloc(strlen(osegs)+10);\r\n            sprintf(segopt, osegs, cbase);\r\n        }\r\n        else\r\n        {\r\n            if (reloc)\r\n                segopt = rsegs;\r\n            else\r\n                segopt = nsegs;\r\n        }\r\n        flgs[flg_idx++] = segopt;\r\n        if (!outfile)\r\n        {\r\n            fprintf(stderr,\"No output file specified\\n\");\r\n            fclose(cmdfile); /* remove the $$EXEC.$$$ file */\r\n            remove(execmd);\r\n            exit(-1);\r\n        }\r\n        if (reloc)\r\n            flgs[flg_idx++] = strcat(strcpy(xalloc(strlen(l_dot_obj)+3), \"-O\"),\r\n                                     l_dot_obj);\r\n        else\r\n        {\r\n            char *cb = xalloc(10);\r\n            sprintf(cb, \"-C%xH\", cbase);\r\n            flgs[flg_idx++] = cb;\r\n            if (overlay)\r\n            {\r\n                strcpy(outfile+strlen(outfile)-3,\"OVR\");\r\n            }\r\n            flgs[flg_idx++] = strcat(strcpy(xalloc(strlen(outfile)+3), \"-O\"),\r\n                                     outfile);\r\n        }\r\n        for (i = 0 ; i < obj_idx ; i++)\r\n        {\r\n            if (overlay && strcmp(objs[i], strtoff) == 0)\r\n                continue;\r\n            flgs[flg_idx++] = objs[i];\r\n        }\r\n        if (!overlay)\r\n            addlib(STDLIB);\r\n        for(i = 0 ; i < lib_idx ; i++)\r\n            flgs[flg_idx++] = libs[i];\r\n        flgs[flg_idx] = 0;\r\n        put_cmd(IF_NERR);\r\n        doexec(linker, flgs);\r\n        if (reloc)\r\n        {\r\n            flgs[0] = \"-R\";\r\n            flgs[1] = \"-B100H\";\r\n            flgs[2] = l_dot_obj;\r\n            flgs[3] = outfile;\r\n            flgs[4] = (char *)0;\r\n            doexec(objto, flgs);\r\n            rm(RM_FILE, l_dot_obj);\r\n        }\r\n        if (c_as_idx == 1 && nfiles == 1)\r\n            rm(RM_FILE, single);\r\n    }\r\n    if (xref)\r\n        if (xrname)\r\n        {\r\n            flgs[0] = xrname;\r\n            strcat(strcpy(tmpbuf, \"-H\"), outfile);\r\n            if(cp = rindex(tmpbuf, '.'))\r\n                strcpy(cp, \".CRF\");\r\n            else\r\n                strcat(tmpbuf, \".CRF\");\r\n            flgs[1] = tmpbuf;\r\n            flgs[2] = crtmp;\r\n            flgs[3] = 0;\r\n            put_cmd(IF_NERR);\r\n            doexec(cref, flgs);\r\n            rm(RM_FILE, crtmp);\r\n        }\r\n        else\r\n        {\r\n            sprintf(tmpbuf, \"Cross reference info left in %s: \"\r\n                            \"; run CREF to produce listing\\n\", crtmp);\r\n            print(tmpbuf);\r\n        }\r\n    put_cmd(TRAP);\r\n    rm(RM_EXIT, execmd);\r\n    fclose(cmdfile);\r\n    fclose(stdout);\r\n    fclose(stdin);\r\n    setfcb(DFCB, execmd);\r\n    execl(execprg, execprg, execmd, (char *)0);\r\n    error(\"Can't execute %s\", execprg);\r\n}\r\n\r\nvoid rm(int type, char *file)\r\n{\r\n    char    buf[40];\r\n\r\n    if (verbose)\r\n    {\r\n        strcat(strcpy(buf, \"ERA \"), file);\r\n        print(buf);\r\n    }\r\n    setfcb(DFCB, file);\r\n    putc(type, cmdfile);\r\n    putc(16, cmdfile);\r\n    fwrite(DFCB, 1, 16, cmdfile);\r\n}\r\n\r\nvoid print(char *s)\r\n{\r\n    putc(PRINT, cmdfile);\r\n    putc(strlen(s), cmdfile);\r\n    fputs(s, cmdfile);\r\n}\r\n\r\nvoid put_cmd(int i)\r\n{\r\n    putc(i, cmdfile);\r\n    putc(0, cmdfile);\r\n}\r\n\r\nvoid addobj(char *s, int p)\r\n{\r\n    char *  cp;\r\n    uchar   len;\r\n    static char oname;\r\n\r\n    if (oname == 0 && outfile == 0)\r\n    {\r\n        if (p)\r\n        {\r\n            oname = 1;\r\n        }\r\n        if(cp = rindex(s, '.'))\r\n            len = cp - s;\r\n        else\r\n            len = strlen(s);\r\n        cp = xalloc(len + strlen(\"-O.COM\") + 1);\r\n        strncat(strcpy(cp, \"-O\"), s, len);\r\n        strcpy(cp+len+2, \".COM\");\r\n        outfile = cp+2;\r\n    }\r\n    cp = xalloc(strlen(s)+1);\r\n    strcpy(cp, s);\r\n    objs[obj_idx++] = cp;\r\n}\r\n\r\nvoid addlib(char *s)\r\n{\r\n    char *  cp;\r\n\r\n    strcpy(tmpbuf, libpath);\r\n    strcat(strcat(tmpbuf, s), LIBSUFF);\r\n    cp = xalloc(strlen(tmpbuf)+1);\r\n    strcpy(cp, tmpbuf);\r\n    libs[lib_idx++] = cp;\r\n}\r\n\r\nvoid error(char *s, char *a)\r\n{\r\n    fprintf(stderr, s, a);\r\n    exit(1);\r\n}\r\n\r\nstatic char *xalloc(short s)\r\n{\r\n    register char * cp;\r\n\r\n    if (!(cp = malloc(s)))\r\n        error(\"Out of memory\", NULL);\r\n    return cp;\r\n}\r\n\r\nvoid upcase(char *s)\r\n{\r\n    while (*s)\r\n    {\r\n        if (*s >= 'a' && *s <= 'z')\r\n            *s -= 'a'-'A';\r\n        ++s;\r\n    }\r\n}\r\n\r\nvoid doexec(char *name, char **vec)\r\n{\r\n    uchar           len;\r\n    char          **pvec;\r\n    char           *redir[2];\r\n    char            redbuf[20];\r\n    FILE           *cfile;\r\n    static short    redno;\r\n    char            xbuf[130];\r\n\r\n    pvec = vec;\r\n    len = 0;\r\n    redbuf[0] = 0;\r\n    /* PMO: bug fix we could overrun 255 length\r\n     * as we are only interested in creating a redir\r\n     * for > 124 chars we can quit early\r\n     */\r\n\twhile(*pvec && len <= 124)\r\n        len += strlen(*pvec++)+1;\r\n    if (len > 124)\r\n    {\r\n        sprintf(xbuf, redname, ++redno);\r\n        if (!(cfile = fopen(xbuf, \"w\")))\r\n            error(\"Can't create %s\", xbuf);\r\n        len = 0;\r\n        while (*vec)\r\n        {\r\n            /* PMO: bug fix, check if we will\r\n             * overrun the buffer with this item\r\n             * also space between tokens was not\r\n             * counted\r\n             */\r\n\t\t\tlen += strlen(*vec) + 1;    /* account for space */\r\n\t\t\tif(len > 126) {             /* test if it will overrun */\r\n\t\t\t\tfprintf(cfile, \"\\\\\\n\"); /* put continuation \\ */\r\n\t\t\t\tlen = strlen(*vec) + 1; /* reset len */\r\n\t\t\t}\r\n\t\t\tfprintf(cfile, \"%s \", *vec++);\r\n        }\r\n        fputc('\\n', cfile);\r\n        fclose(cfile);\r\n        redir[1] = (char *)0;\r\n        sprintf(redbuf, \"<%s\", xbuf);\r\n        redir[0] = redbuf;\r\n        vec = redir;\r\n    }\r\n    xbuf[0] = 0;\r\n    while(*vec)\r\n        strcat(strcat(xbuf, \" \"), *vec++);\r\n    len = strlen(xbuf);\r\n    putc(EXEC, cmdfile);\r\n    putc(len+50, cmdfile);\r\n    setfcb(DFCB, name);\r\n    strcpy(DFCB->ft, \"COM\");\r\n    DFCB->nr = 0;\r\n    putc(DFCB->uid, cmdfile);\r\n    fwrite(DFCB, 1, 16, cmdfile);\r\n    setfcb(DFCB, &xbuf[1]);\r\n    DFCB->nr = 0;\r\n    fwrite(DFCB, 1, 32, cmdfile);\r\n    putc(len, cmdfile);\r\n    fwrite(xbuf, 1, len, cmdfile);\r\n    if (redbuf[0])\r\n        rm(RM_FILE, &redbuf[1]);\r\n}\r\n\r\nvoid assemble_sym(char *s)\r\n{\r\n    char  *vec[5];\r\n    char   buf[80];\r\n    char  *cp;\r\n    uchar  i;\r\n\r\n    if (overlay)\r\n    {\r\n        cbase = sym2as(s);\r\n        vec[0] = s;\r\n        vec[1] = tmpf5;\r\n        vec[2] = 0;\r\n        doexec(symtoas, vec);\r\n        put_cmd(TRAP);\r\n    }\r\n    if (c_as_idx > 1)\r\n        print(s);\r\n    i = 0;\r\n  /* Commented out - for symbols there's no code to optimize\r\n    if (optimize && !speed)\r\n        vec[i++] = \"-J\";\r\n  */\r\n    if (nolocal)\r\n        vec[i++] = \"-X\";\r\n    if (cp = rindex(s, ':'))\r\n        cp++;\r\n    else\r\n        cp = s;\r\n    strcat(strcpy(buf, \"-O\"), cp);\r\n    if (rindex(buf, '.'))\r\n        *rindex(buf, '.') = 0;\r\n    strcat(buf, \".OBJ\");\r\n    vec[i++] = buf;\r\n    vec[i++] = tmpf5;\r\n    vec[i] = (char *)0;\r\n    doexec(assem, vec);\r\n}\r\n\r\nvoid assemble(char *s)\r\n{\r\n    char  *vec[5];\r\n    char   buf[80];\r\n    char  *cp;\r\n    uchar  i;\r\n\r\n    if (c_as_idx > 1)\r\n        print(s);\r\n    i = 0;\r\n    if (optimize && !speed)\r\n        vec[i++] = \"-J\";\r\n    if (nolocal)\r\n        vec[i++] = \"-X\";\r\n    if (cp = rindex(s, ':'))\r\n        ++cp;\r\n    else\r\n        cp = s;\r\n    strcat(strcpy(buf, \"-O\"), cp);\r\n    if (rindex(buf, '.'))\r\n        *rindex(buf, '.') = 0;\r\n    strcat(buf, \".OBJ\");\r\n    vec[i++] = buf;\r\n    vec[i++] = s;\r\n    vec[i] = (char *)0;\r\n    doexec(assem, vec);\r\n}\r\n\r\n#ifdef Z280\r\n\r\n/* Optimize then assemble for Z280 */\r\nvoid optassemble(char *s)\r\n{\r\n    char  *vec[5];\r\n    char   buf[80];\r\n    char  *cp, *as2;\r\n    uchar  i;\r\n\r\n    if (c_as_idx > 1)\r\n        print(s);\r\n\r\n    cp = s;\r\n\r\n    /* Try to optimize into Z280 assembler */\r\n    i = 0;\r\n    if (speed)\r\n        vec[i++] = \"-F\";\r\n    vec[i++] = cp;\r\n    if (keepas)\r\n        as2 = strcat(strcpy(tmpbuf, s), \"2\"); /* save as .AS2 */\r\n    else\r\n        as2 = tmpf5;\r\n    vec[i++] = as2;\r\n    vec[i] = (char *)0;\r\n    doexec(optimh, vec);\r\n    put_cmd(TRAP);\r\n\r\n    i = 0;\r\n    if (optimize && !speed)\r\n        vec[i++] = \"-J\";\r\n    if (nolocal)\r\n        vec[i++] = \"-X\";\r\n\r\n    if (cp = rindex(s,':'))\r\n        ++cp;\r\n    else\r\n        cp = s;\r\n    strcat(strcpy(buf, \"-O\"), cp);\r\n    if (rindex(buf, '.'))\r\n        *rindex(buf, '.') = 0;\r\n    strcat(buf, \".OBJ\");\r\n\r\n    vec[i++] = buf;\r\n    vec[i++] = as2;\r\n    vec[i] = (char *)0;\r\n    doexec(assem, vec);\r\n}\r\n\r\n#endif /* Z280 */\r\n\r\nvoid compile(char *s)\r\n{\r\n    register char *cp;\r\n    short          i, j;\r\n    char          *vec[MAXLIST];\r\n    char           cbuf[50];\r\n\r\n    if (c_as_idx > 1)\r\n        print(s);\r\n    for (j = 0; j < iud_idx ; ++j)\r\n        vec[j] = iuds[j];\r\n    vec[j++] = s;\r\n    vec[j++] = tmpf1;\r\n    vec[j] = (char *)0;\r\n    doexec(cpp, vec);\r\n\r\n    if (cp = rindex(s, ':'))\r\n        s = cp+1;\r\n    *rindex(s, '.') = 0;\r\n    i = 0;\r\n    if (keepas && !optimize)\r\n        vec[i++] = \"-S\";\r\n    if (xref)\r\n        vec[i++] = strcat(strcpy(cbuf, \"-C\"), crtmp);\r\n    /* error redirection */\r\n    if (ebuf[0])\r\n        vec[i++] = ebuf;\r\n    vec[i++] = tmpf1;\r\n    vec[i++] = tmpf2;\r\n    vec[i++] = tmpf3;\r\n    vec[i++] = (char *)0;\r\n    doexec(pass1, vec);\r\n\r\n    vec[0] = tmpf2;\r\n    vec[1] = keepas && !optimize ? strcat(strcpy(tmpbuf, s), \".AS\") : tmpf1;\r\n    vec[2] = (char *)0;\r\n    doexec(cgen, vec);\r\n    if (keepas && !optimize)\r\n        return;\r\n    cp = tmpf1;\r\n    if (optimize)\r\n    {\r\n        i = 0;\r\n        if (speed)\r\n            vec[i++] = \"-F\";\r\n        vec[i++] = tmpf1;\r\n#ifdef Z280\r\n        if (keepas && !z280optim)\r\n#else\r\n        if (keepas)\r\n#endif\r\n            vec[i++] = strcat(strcpy(tmpbuf, s), \".AS\");\r\n        else\r\n            vec[i++] = tmpf2;\r\n        vec[i] = (char *)0;\r\n        doexec(optim, vec);\r\n\r\n        cp = tmpf2;\r\n#ifdef Z280\r\n        if (z280optim)\r\n        {\r\n            i = 0;\r\n            if (speed)\r\n                vec[i++] = \"-F\";\r\n            vec[i++] = cp;\r\n            if (keepas)\r\n                vec[i++] = strcat(strcpy(tmpbuf, s), \".AS\");\r\n            else\r\n                vec[i++] = tmpf5;\r\n            vec[i] = (char *)0;\r\n            doexec(optimh, vec);\r\n            cp = tmpf5;\r\n        }\r\n#endif\r\n        if (keepas)\r\n            return;\r\n    }\r\n    i = 0;\r\n    if (nolocal)\r\n        vec[i++] = \"-X\";\r\n    if (optimize && !speed)\r\n        vec[i++] = \"-J\";\r\n    vec[i++] = \"-N\";\r\n    vec[i++] = strcat(strcat(strcpy(tmpbuf, \"-O\"), s), \".OBJ\");\r\n    vec[i++] = cp;\r\n    vec[i] = (char *)0;\r\n    doexec(assem, vec);\r\n}\r\n\r\n#define MAXLINE 200\r\n#define START (\"__ovrbgn\")\r\n\r\nint sym2as(char * fname)\r\n{\r\n    static char line[MAXLINE+1];\r\n    char       *addr = line;\r\n    char       *sym = line+5;\r\n    register int i = 0;\r\n    register int j = 0;\r\n    int         c = 0;\r\n    char       *r = 0;\r\n    int         base = 0x100;\r\n    FILE       *in;\r\n\r\n    in = fopen(fname,\"rt\");\r\n    if (!in)\r\n        return -1;\r\n\r\n    while (!feof(in) && !ferror(in))\r\n    {\r\n        i = 0;\r\n        while (i < MAXLINE)\r\n        {\r\n            c = fgetc(in);\r\n            if (isspace(c) && (i==0))\r\n                continue;\r\n            if (c == EOF || c == '\\n' || c == '\\r')\r\n                break;\r\n            line[i++] = c;\r\n        }\r\n        line[i] = 0;\r\n        r = index(line, ' ');\r\n        if (!r)\r\n            continue;\r\n        *r = 0;\r\n        addr = line;\r\n        sym = r+1;\r\n        while (*sym && isspace(*sym))\r\n            sym++;\r\n        if (strlen(addr) > 4)\r\n        {\r\n            addr += strlen(addr);\r\n            addr -= 4;\r\n        }\r\n        for (j=strlen(sym)-1; j>=0; j--)\r\n        {\r\n            if (isspace(sym[j]))\r\n                sym[j] = 0;\r\n        }\r\n        if (!strcmp(sym, START))\r\n            sscanf(addr,\"%x\", &base);\r\n    }\r\n    if (ferror(in))\r\n        fclose(in);\r\n    fclose(in);\r\n    return base;\r\n}\r\n\r\nvoid viewfile(char *fn)\r\n{\r\n    FILE  *f;\r\n    char  *bp, buf[200];\r\n\r\n    if (!(f = fopen(fn, \"r\")))\r\n        error(\"Unable to open help file %s\", fn);\r\n    while (bp=fgets(buf, 200, f))\r\n        printf(\"%s\", bp);\r\n    fclose(f);\r\n}\r\n"
  },
  {
    "path": "cpm/CHMOD.C",
    "content": "#include\t<cpm.h>\r\n#include\t<stat.h>\r\n\r\nchmod(name, mode)\r\nregister char *\tname;\r\n{\r\n\tstruct fcb \tfc;\r\n\tregister short\tluid;\r\n\r\n\tif(!setfcb(&fc, name)) {\r\n\t\tluid = getuid();\r\n\t\tsetuid(fc.uid);\r\n\t\tif(!(mode & S_IWRITE))\r\n\t\t\tfc.ft[0] |= (char) 0x80;\r\n\t\tif(mode & S_SYSTEM)\r\n\t\t\tfc.ft[1] |= (char) 0x80;\r\n\t\tif(mode & S_ARCHIVE)\r\n\t\t\tfc.ft[2] |= (char) 0x80;\r\n\t\tmode = bdos(CPMSATT, &fc);\r\n\t\tsetuid(luid);\r\n\t\treturn mode;\r\n\t}\r\n\treturn -1;\r\n}\r\n"
  },
  {
    "path": "cpm/CLEANUP.C",
    "content": "#include\t\"cpm.h\"\r\n\r\n#define\tFILL\t0, \"        \", \"   \", 0, {0}, 0, {0}, 0, {0}, 0\r\n\r\n/*\r\n\r\n   Default stdin, stdout and stderr to the console.\r\n\r\n   If PIPEMGR is detected by the start-up routine,\r\n   then it changes these to RSX:, RSX: and ERR: by\r\n   calling the _initrsx function.\r\n\r\n */\r\n\r\nstruct fcb\t_fcb[MAXFILE] =\r\n{\r\n    { FILL, U_CON },\t/* stdin */\r\n    { FILL, U_CON },\t/* stdout */\r\n    { FILL, U_CON },\t/* stderr */\r\n};\r\n\r\nvoid _cpm_clean()\r\n{\r\n    uchar\ti;\r\n\r\n    i = 0;\r\n    do\r\n        close(i);\r\n    while (++i < MAXFILE);\r\n}\r\n\r\nvoid _putrno(uchar *where, long rno)\r\n{\r\n    where[0] = rno & 0xFF;\r\n    where[1] = (rno >> 8) & 0xFF;\r\n    where[2] = (rno >> 16) & 0xFF;\r\n}\r\n\r\nvoid _initrsx()\r\n{\r\n    /* Use PIPEMGR for stdin, stdout and stderr redirection */\r\n    _fcb[0].use = U_RSX;\t/* stdin */\r\n    _fcb[1].use = U_RSX;\t/* stdout */\r\n    _fcb[2].use = U_ERR;\t/* stderr */\r\n}\r\n"
  },
  {
    "path": "cpm/CLOSE.C",
    "content": "#include    <cpm.h>\r\n#include    <stdlib.h>\r\n#include    <ctype.h>\r\n/*\r\n    This is a modified version of close.c to support exact file sizes.\r\n\r\n    Unfortunately there are two common conventions used to record the\r\n    exact size in CP/M.\r\n\r\n    1) Record the bytes used in the last sector - used by DOSPLUS\r\n    2) Record the bytes unused in the last sector - used by ISX for\r\n       ISIS emulation\r\n\r\n    A previous version of this file only supported convention 2.\r\n\r\n    To support both of these variants, a global variable _exact is\r\n    set-up by the start-up module.\r\n\r\n    The values for _exact are noted below\r\n\r\n    'D' for DOSPLUS     This uses convention 1 above\r\n    'I' for ISIS/ISX    This uses convention 2 above\r\n    'C' for CP/M 2      Exact file size is not used\r\n\r\n    Under CP/M 3 this defaults to 'D' DOSplus mode.  If you wish\r\n    to use ISIS mode, you must set _exact to 'I' prior to using\r\n    file I/O routines - e.g.\r\n\r\n        extern char _exact;\r\n\r\n        _exact = 'I';\r\n\r\n    Note you need to take extra care with _exact if you are using an\r\n    emulator that can access host files and truncates files to match\r\n    the exact size.  Using the wrong mode will mean that the value\r\n    this function passes to the emulator will be wrong and could\r\n    result in data losss. If in doubt I recommend exact size isn't used.\r\n\r\n    For the ZXCC emulator, using _exact as 'D' is safe.\r\n*/\r\n\r\nextern char _exact;  /* Exact file size hint for last sector\r\n\t\t\t'C' = not used (old CP/M),\r\n                        'D' = DOSPLUS mode (count is USED bytes),\r\n\t\t\t'I' = ISX mode (count is UNUSED bytes)\r\n                      */\r\n\r\nint close(uchar fd)\r\n{\r\n    register struct fcb *fc;\r\n    uchar       luid;\r\n\r\n    if (fd >= MAXFILE)\r\n        return -1;\r\n    fc = &_fcb[fd];\r\n    luid = getuid();\r\n    setuid(fc->uid);\r\n    if (fc->use == U_WRITE || fc->use == U_RDWR\r\n                           || bdos(CPMVERS)&(MPM|CCPM) && fc->use == U_READ)\r\n        bdos(CPMCLS, fc);\r\n    if (_exact != 'C') { /* skip if old CP/M mode */\r\n        fc->nr = (_exact == 'D' ? fc->fsize : -fc->fsize) & 0x7f; /* Set exact file size */\r\n        fc->name[5] |= (char) 0x80;\r\n        if (fc->use == U_WRITE || fc->use == U_RDWR)\r\n            bdos(CPMSATT, fc);\r\n    }\r\n    fc->use = 0;\r\n    setuid(luid);\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "cpm/CONVTIME.C",
    "content": "\r\n#include\t<time.h>\r\n\r\n/*\r\n *\tThis routine converts the date and time in CP/M-86 format\r\n *\tto Unix style date and time - seconds since 00:00:00 Jan  1 1970\r\n */\r\n\r\n#define\tEPOCH\t2922-1\t\t/* difference between 1970 and 1978 - note\r\n\t\t\t\t   adjustment since CP/M numbers days from\r\n\t\t\t\t   1 and Unix numbers them from 0 */\r\n\r\nstruct tod\r\n{\r\n\tint\tdays;\t\t/* since 1 Jan 1978 */\r\n\tchar\thour;\t\t/* 2 digit BCD!! */\r\n\tchar\tmin;\t\t/* ditto */\r\n\tchar\tsec;\t\t/* ditto */\r\n};\r\n\r\nfrmbcd(c)\r\nunsigned char\tc;\r\n{\r\n\treturn (c & 0xF) + ((c >> 4) & 0xF) * 10;\r\n}\r\n\r\ntime_t\r\nconvtime(tod)\r\nstruct tod *\ttod;\r\n{\r\n\ttime_t\tt;\r\n\r\n\tt = tod->days+EPOCH;\r\n\tt *= 24;\t\t/* now have hours */\r\n\tt += frmbcd(tod->hour);\t/* add in hours from the time */\r\n\tt *= 60;\t\t/* now minutes */\r\n\tt += frmbcd(tod->min);\t/* add minutes */\r\n\tt *= 60;\t\t/* Seconds! */\r\n\tt += frmbcd(tod->sec);\r\n\treturn t;\r\n}\r\n"
  },
  {
    "path": "cpm/CREAT.C",
    "content": "#include    <cpm.h>\r\n#include    <unixio.h>\r\n\r\nint creat(char *name, int mode)\r\n{\r\n    register struct fcb *   fc;\r\n    uchar           luid;\r\n\r\n    if (!(fc = getfcb()))\r\n        return -1;\r\n    luid = getuid();\r\n    if (!setfcb(fc, name))\r\n    {\r\n        if (unlink(name) == -1 && errno > 16)\r\n            return -1;\r\n        setuid(fc->uid);\r\n        if ((bdos(CPMMAKE, fc) & 0xFF) == 0xFF)\r\n        {\r\n            setuid(luid);\r\n            fc->use = 0;\r\n            return -1;\r\n        }\r\n        setuid(luid);\r\n        fc->use = U_WRITE;\r\n        fc->fsize = 0L;\r\n    }\r\n#if 0\r\n    fc->dm[0] = 0;\r\n    bmove((char *)fc->dm, (char *)&fc->dm[1], sizeof fc->dm - 1);\r\n#endif  0\r\n    return fc - _fcb;\r\n}\r\n"
  },
  {
    "path": "cpm/CSV.AS",
    "content": "; CSV.AS\tModified version from Tesseract vol 91\r\n;\r\n\tglobal\tcsv,cret,indir, ncsv\r\n\tpsect\ttext\r\ncsv:\tpop\thl\t\t;return address\r\n\tpush\tiy\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\t\t;new frame pointer\r\n\tjp\t(hl)\r\n\r\ncret:\tld\tsp,ix\r\n\tpop\tix\r\n\tpop\tiy\r\n\tret\r\n\r\nindir:\tjp\t(hl)\r\n\r\n;\tNew csv: allocates space for stack based on word following\r\n;\tcall ncsv\r\n\r\nncsv:\r\n\tpop\thl\r\n\tpush\tiy\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tex\tde,hl\r\n\tadd\thl,sp\r\n\tld\tsp,hl\r\n\tex\tde,hl\r\n\tjp\t(hl)\r\n"
  },
  {
    "path": "cpm/DUP.C",
    "content": "#include\t\"cpm.h\"\r\n\r\ndup(fd)\r\nuchar\tfd;\r\n{\r\n\tregister struct fcb *\tfp;\r\n\r\n\tif(_fcb[fd].use && (fp = getfcb())) {\r\n\t\t*fp = _fcb[fd];\r\n\t\treturn fp - _fcb;\r\n\t}\r\n\treturn -1;\r\n}\r\n"
  },
  {
    "path": "cpm/EXEC-BLD.SUB",
    "content": "; Build $$EXEC.COM from source\r\nera exec.com\r\nzas -j exec.as\r\nlinq\r\n<-l -ptext=0,bss exec.obj\r\nobjtohex -R -b100h l.obj exec.com\r\nera l.obj\r\nera exec.obj\r\n"
  },
  {
    "path": "cpm/EXEC.AS",
    "content": "*Title\tIndirect command execution\r\n*Head\tDescription\r\n\r\n;\tCopyright (C) 1984 HI-TECH SOFTWARE\r\n\r\n;This is the indirect command processor\r\n;It is invoked with one argument which is the name of an indirect\r\n;command file, normally created by the C command or a similar\r\n;command processor, and executes the commands in the file. See\r\n;exec.doc for a description of the command syntax in the file.\r\n\r\n\r\n*Heading\tCommand values and BDOS calls\r\nBASE\tequ\t80h\t\t;base of command values\r\n\r\nEXIT\tequ\tBASE+0\t\t;Exit command file\r\nEXEC\tequ\tBASE+1\t\t;Execute a transient command\r\nIGN_ERR\tequ\tBASE+2\t\t;Ignore errors\r\nDEF_ERR\tequ\tBASE+3\t\t;Exit on error\r\nSKP_ERR\tequ\tBASE+4\t\t;Skip on error to next TRAP\r\nTRAP\tequ\tBASE+5\t\t;Trap for error skips\r\nIF_ERR\tequ\tBASE+6\t\t;Execute the next command if any error\r\nIF_NERR\tequ\tBASE+7\t\t;Execute the next command if no error\r\nECHO\tequ\tBASE+8\t\t;Echo all EXEC commands \r\nPRINT\tequ\tBASE+9\t\t;Print buffer on console\r\nRM_FILE\tequ\tBASE+10\t\t;Remove file\r\nRM_EXIT\tequ\tBASE+11\t\t;Remove file and exit\r\n\r\nWBOOT\tequ\t0\t\t;Address for warm boot\r\nENTRY\tequ\t5\t\t;Bdos entry\r\nDFCB\tequ\t5CH\t\t;Default FCB\r\nDBUF\tequ\t80H\t\t;Default buffer\r\nTPA\tequ\t100H\t\t;Transient area\r\nSECSIZE\tequ\t128\t\t;CP/M record size\r\nFCBSIZ\tequ\t33\t\t;Size of non-random FCB\r\n\r\nCONIN\tequ\t1\t\t;Console get char\r\nCONOUT\tequ\t2\t\t;Console out char\r\nCONST\tequ\t11\t\t;Get console status\r\nRDSK\tequ\t13\t\t;reset disk system\r\nSELDSK\tequ\t14\t\t;select drive\r\nOPEN\tequ\t15\t\t;Open file\r\nDELETE\tequ\t19\t\t;Delete file\r\nREAD\tequ\t20\t\t;Read record\r\nGETLOG\tequ\t25\t\t;Get current disk\r\nSDMA\tequ\t26\t\t;Set DMA address\r\nUID\tequ\t32\t\t;Set/get user ID\r\n\r\n\tmacro\tbdos,fun,arg\t;Macro for bdos calls\r\n\tld\tde,arg\r\n\tld\tc,fun\r\n\tcall\tENTRY\r\n\tendm\r\n\r\n\tmacro\tbdosx,fun\t;bdos calls with no arg\r\n\tld\tc,fun\r\n\tcall\tENTRY\r\n\tendm\r\n\r\nCR\tequ\t0DH\t\t;Carriage return\r\nLF\tequ\t0AH\t\t;Line feed\r\n\r\n*Head\tMain program\r\n\tpsect\ttext\r\n\r\n\tglobal\t__Lbss\r\n\r\n\tdefs\tTPA\t\t;relocate to start of TPA\r\nstart:\r\n\tld\tsp,(ENTRY+1)\t;Set up stack pointer\r\n\tbdosx\tGETLOG\r\n\tld\t(curdsk),a\r\n\tbdos\tUID, 0FFh\r\n\tld\t(curuid),a\r\n\tld\thl,DFCB\r\n\tld\tde,cfcb\r\n\tld\tbc,16\r\n\tldir\t\t\t;set up command FCB\r\n\tbdos\tOPEN,cfcb\r\n\tinc\ta\r\n\tjr\tnz,1f\r\n\tld\thl,nofile\r\n\tcall\tprint\r\n\tjp\tdoexit\r\n1:\r\n\tld\thl,(ENTRY+1)\t;top of code after relocation\r\n\tld\tde,stack\t;top before relocation\r\n\tscf\t\t\t;set carry flag\r\n\tsbc\thl,de\t\t;gives distance\r\n\tex\tde,hl\r\n\tld\tbc,(__Lbss)\t;reloc count\r\n\tld\thl,__Lbss+2\t;start of addresses\r\n1:\r\n\tld\ta,c\r\n\tor\tb\t\t;check for count zero\r\n\tjr\tz,3f\t\t;start if so\r\n\tdec\tbc\r\n\tld\ta,(hl)\t\t;get address\r\n\tinc\thl\r\n\tpush\thl\t\t;save it\r\n\tld\th,(hl)\r\n\tld\tl,a\r\n\tpush\thl\t\t;save it\r\n\tpush\tde\t\t;and it\r\n\tld\tde,5f\t\t;check for legal modify\r\n\tor\ta\r\n\tsbc\thl,de\r\n\tpop\tde\t\t;restore regs\r\n\tpop\thl\r\n\tjr\tc,4f\r\n\tld\ta,(hl)\t\t;get value\r\n\tinc\thl\r\n\tpush\thl\r\n\tld\th,(hl)\r\n\tld\tl,a\r\n\tadd\thl,de\t\t;add difference\r\n\tex\tde,hl\t\t;put in de\r\n\tex\t(sp),hl\t\t;restore pointer\r\n\tld\t(hl),d\t\t;store new value\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tpop\tde\t\t;restore difference\r\n4:\r\n\tpop\thl\t\t;restore list pointer\r\n\tinc\thl\t\t;point to next\r\n\tjr\t1b\r\n3:\r\n\tld\thl,stack-1\r\n\tadd\thl,de\t\t;add in difference\r\n\tex\tde,hl\t\t;put dest in de\r\n\tld\thl,stack-1\t;source in hl\r\n\tld\tbc,stack-cmdstart\t;amount to move\r\n\tlddr\r\n5:\r\n\tjp\tcmdstart\t;jump to it\r\n\r\ncmdstart:\r\n\tld\thl,(ENTRY+1)\r\n\tld\t(cmdstart-2),hl\r\n\tld\ta,jp\r\n\tld\t(cmdstart-3),a\r\n\tld\thl,cmdstart-3\r\n\tld\t(ENTRY+1),hl\r\n\tld\thl,(WBOOT+1)\r\n\tld\t(bootsave),hl\r\n\tld\thl,loop\r\n\tld\t(WBOOT+1),hl\r\n\tld\thl,0\r\n\tld\t(DBUF),hl\t;initially no error\r\nloop:\r\n\tld\tsp,stack\r\n\tld\thl,(DBUF)\r\n\tld\ta,h\r\n\tor\tl\r\n\tjr\tz,1f\t\t;no error, nothing required\r\n\tld\t(errors),a\t;update flag\r\n\tld\ta,(erract)\r\n\tdec\ta\t\t;set flags\t\t;default action?\r\n\tjp\tm,doexit\t;default, exit pronto\r\n\tjr\tz,1f\t\t;ignore errors\r\n\tcall\tskipto\t\t;skip to next trap command\r\n1:\r\n\tld\thl,0\r\n\tld\t(DBUF),hl\r\n\tcall\tdocmd\r\n\tjr\tloop\r\n\r\ndocmd:\r\n\tcall\tgetch\r\n\tsub\tBASE\t\t;Check for legal range\r\n\tjp\tc,cerr\t\t;too small\r\n\tcp\tNCMDS\t\t;Check other end of range\r\n\tjp\tnc,cerr\r\n\tld\thl,ctable\r\n\tld\tc,a\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tadd\thl,bc\r\n\tld\ta,(hl)\r\n\tinc\thl\r\n\tld\th,(hl)\r\n\tld\tl,a\r\n\tpush\thl\t\t;push the address\r\n\tcall\tgetch\r\n\tld\t(length),a\t;store the length\r\n\tret\t\t\t;dispatch to the routine\r\n\r\nctable:\r\n\tdefw\tdoexit\t\t;EXIT\r\n\tdefw\tdoexec\t\t;EXEC\r\n\tdefw\tignerr\t\t;IGN_ERR\r\n\tdefw\tdeferr\t\t;DEF_ERR\r\n\tdefw\tskperr\t\t;SKPERR\r\n\tdefw\ttrap\t\t;TRAP\r\n\tdefw\tiferr\t\t;IF_ERR\r\n\tdefw\tifnerr\t\t;IF_NERR\r\n\tdefw\techo\t\t;ECHO\r\n\tdefw\txprint\t\t;PRINT\r\n\tdefw\trm\t\t;RM_FILE\r\n\tdefw\trm_exit\t\t;RM_EXIT\r\n\r\nNCMDS\tequ\t$-ctable\t;number of legal commands\r\n\r\ncerr:\tld\thl,errms\r\n\tcall\tprint\t\r\n\tjp\tdoexit\r\n\r\nerrms:\tdefb\t7\r\n\tdefm\t'Fmt err'\r\n\r\ndoexit:\r\n\tld\thl,(bootsave)\r\n\tld\t(WBOOT+1),hl\r\n\tjp\t(hl)\r\n\r\ndoexec:\r\n\tld\thl,DFCB\r\n\tld\tde,DFCB+1\r\n\tld\tbc,FCBSIZ-1\r\n\tld\t(hl),0\r\n\tldir\r\n\tcall\tgetch\r\n\tld\t(newuid),a\r\n\tld\thl,DFCB\r\n\tld\tb,16\r\n\tcall\trdbytes\r\n9:\r\n\tld\ta,(echflg)\r\n\tor\ta\r\n\tjr\tz,2f\r\n\tld\ta,(newuid)\r\n\tinc\ta\r\n\tjr\tz,4f\r\n\tadd\ta,'0'-1\r\n\tcall\tputch\r\n\tld\ta,':'\r\n\tcall\tputch\r\n4:\r\n\tld\ta,(DFCB)\r\n\tor\ta\r\n\tjr\tz,4f\r\n\tadd\ta,'A'-1\r\n\tcall\tputch\r\n\tld\ta,':'\r\n\tcall\tputch\r\n4:\r\n\tld\thl,DFCB+1\r\n\tld\tb,8\r\n1:\r\n\tld\ta,(hl)\r\n\tcp\t' '\r\n\tjr\tz,2f\r\n\tpush\thl\r\n\tpush\tbc\r\n\tcall\tputch\r\n\tpop\tbc\r\n\tpop\thl\r\n\tinc\thl\r\n\tdjnz\t1b\r\n2:\r\n\tld\ta,(newuid)\r\n\tld\te,a\r\n\tbdosx\tUID\r\n\tbdos\tOPEN,DFCB\t;open the file\r\n\tinc\ta\t\t;-1 is error on return\r\n\tjr\tnz,1f\t\t;skip if found\r\nfilerr:\r\n\tld\ta,(curuid)\r\n\tld\te,a\r\n\tbdosx\tUID\r\n\tld\thl,notfnd\r\n\tcall\tprint\r\n\tbdosx\tCONIN\r\n\tbdosx\tRDSK\r\n\tbdos\tSELDSK,(curdsk)\r\n\tjr\t9b\r\n\r\n1:\r\n\tld\tde,TPA\t\t;read into transient area\r\n1:\r\n\tpush\tde\t\t;save ptr\r\n\tbdosx\tSDMA\t\t;set buffer address\r\n\tbdos\tREAD,DFCB\t;read sector\r\n\tpop\thl\t\t;pop ptr\r\n\tld\tde,SECSIZE\r\n\tadd\thl,de\r\n\tex\tde,hl\r\n\tor\ta\r\n\tjr\tz,1b\t\t;loop if more\r\n\r\n\tld\ta,(curuid)\t;restore uid\r\n\tld\te,a\r\n\tbdosx\tUID\r\n\tld\thl,DFCB\r\n\tld\tb,32\r\n\tcall\trdbytes\r\n\r\n\tcall\tgetch\r\n\tld\thl,DBUF\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tld\tb,a\r\n\tcall\trdbytes\r\n\r\n\tld\ta,(echflg)\r\n\tor\ta\r\n\tjr\tz,1f\r\n\tld\thl,DBUF\t\t;just print for now\r\n\tcall\tprint\r\n1:\r\n\tjp\tTPA\t\t;execute program\r\n\r\nrdbytes:\r\n\tcall\tgetch\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tdjnz\trdbytes\r\n\tret\r\n\r\nxprint:\r\n\tld\tb,a\t\t;a has the length already\r\n\tld\thl,TPA\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tcall\trdbytes\r\n\tld\thl,TPA\r\n\r\nprint:\r\n\tld\tb,(hl)\r\n\tinc\thl\r\n1:\r\n\tld\ta,(hl)\r\n\tinc\thl\r\n\tpush\thl\r\n\tpush\tbc\r\n\tcall\tputch\r\n\tpop\tbc\r\n\tpop\thl\r\n\tdjnz\t1b\r\n\tld\ta,CR\r\n\tcall\tputch\r\n\tld\ta,LF\r\nputch:\r\n\tld\te,a\r\n\tbdosx\tCONOUT\r\n\tret\r\n\r\nignerr:\r\n\tld\ta,1\r\n1:\r\n\tld\t(erract),a\r\n\tret\r\n\r\ndeferr:\r\n\txor\ta\r\n\tjr\t1b\r\n\r\nskperr:\r\n\tld\ta,2\r\n\tjr\t1b\r\n\r\nskip:\r\n\tcall\tgetch\t\t;get the command byte\r\n\tpush\taf\t\t;save it\r\n\tcall\tgetch\t\t;length\r\n\tld\tb,a\t\t;put into counter\r\n\tld\thl,TPA\t\t;s suitable place to read into\r\n\tor\ta\t\t;check for zero count\r\n\tcall\tnz,rdbytes\t;read if any to read\r\n\tpop\taf\r\n\tret\t\t\t;return with command byte in A\r\n\r\n\r\n;\tSkip up to the next trap\r\n\r\nskipto:\r\n\tcall\tskip\r\n\tcp\tEXIT\t\t;End?\r\n\tjp\tz,doexit\t;yes, return to CP/M\r\n\tcp\tTRAP\t\t;got a trap yet?\r\n\tjr\tnz,skipto\t;loop for more\r\n\tret\r\n\r\nrm:\r\n\tld\tb,16\r\n\tld\thl,DFCB\r\n\tcall\trdbytes\r\n\tbdos\tDELETE,DFCB\r\n\tret\r\n\r\nrm_exit:\r\n\tcall\trm\r\n\tjp\tdoexit\r\n\r\ngetch:\r\n\tpush\thl\r\n\tld\thl,(cptr)\r\n\tld\tde,cbuf+SECSIZE\r\n\tor\ta\r\n\tsbc\thl,de\r\n\tjr\tnz,1f\r\n\tpush\tbc\r\n\tbdos\tSDMA,cbuf\r\n\tbdos\tREAD,cfcb\r\n\tpop\tbc\r\n\tor\ta\r\n\tjp\tnz,doexit\t\t;exit on EOF\r\n\tld\thl,cbuf\r\n\tld\t(cptr),hl\r\n1:\r\n\tld\thl,(cptr)\r\n\tld\ta,(hl)\r\n\tinc\thl\r\n\tld\t(cptr),hl\r\n\tpop\thl\r\n\tret\r\n\r\ntrap:\r\n\tret\r\n\r\necho:\r\n\tld\ta,1\r\n\tld\t(echflg),a\r\n\tret\r\n\r\niferr:\r\n\tld\ta,(errors)\t;check for errors\r\n\tor\ta\t\t;set flags\r\n\tjp\tz,skip\t\t;skip next command if no error\r\n\tret\r\n\r\nifnerr:\r\n\tld\ta,(errors)\r\n\tor\ta\t\t;any error?\r\n\tjp\tnz,skip\t\t;skip if not\r\n\tret\r\n\r\nnotfnd:\r\n\tdefb\t40\r\n\tdefm\t': Not found - change disks, hit a key'\r\n\tdefb\t7,0Dh,0Ah\r\nnofile:\r\n\tdefb\t7\r\n\tdefm\t'No file'\r\n\r\n*Heading\tData areas\r\n\r\ncfcb:\tdefs\tFCBSIZ\t\t;Command file FCB\r\ncbuf:\tdefs\tSECSIZE\t\t;Command file buffer\r\ncptr:\tdefw\tcbuf+SECSIZE\t;Pointer to command input\r\nerrst:\tdefb\t0\t\t;error status\r\nerract:\tdefb\t0\t\t;action on error\r\nechflg:\tdefb\t0\r\ncurdsk:\tdefs\t1\r\nlength:\r\n\tdefs\t1\t\t;command length\r\nerrors:\r\n\tdefs\t1\t\t;cumulative error flag\r\ncuruid:\r\n\tdefs\t1\t\t;current uid\r\nnewuid:\r\n\tdefs\t1\t\t;user id for EXEC command\r\nbootsave:\r\n\tdefs\t2\r\n\tdefs\t40\t\t;small stack\r\nstack:\r\n\r\n\tpsect\tbss\t\t;for reloc info\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/EXECL.AS",
    "content": ";\tEXECV(), EXECL() - hand crafted from the C\r\n\r\n;\t#include\t<cpm.h>\r\n;\t\r\n;\t#define\tsetuid(x)\tbdos(CPMSUID, x)\r\n;\t#define\tgetuid()\tbdos(CPMSUID, 0xFF)\r\n;\t#define\tTPA\t\t0x100\r\n;\t#define\tDBUF\t\t0x80\r\n;\t#define\tDFCB\t\t0x5C\r\n;\t\r\n;\tstatic void\r\n;\tdoexec(fc, luid)\r\n;\tregister struct fcb *\tfc;\r\n;\tuchar\t\t\tluid;\r\n;\t{\r\n;\t\tchar *\tdma;\r\n;\t\r\n;\t\tdma = (char *)TPA;\r\n;\t\tdo {\r\n;\t\t\tbdos(CPMSDMA, dma);\r\n;\t\t\tdma += SECSIZE;\r\n;\t\t} while(bdos(CPMREAD, fc) == 0);\r\n;\t\tsetuid(luid);\r\n;\t\tbdos(CPMSDMA, DBUF);\r\n;\t\t(*(void (*)())TPA)();\r\n;\t}\r\n;\t\r\n;\t\r\n;\texecl(name, arg1)\r\n;\tchar *\tname, arg1;\r\n;\t{\r\n;\t\texecv(name, &arg1);\r\n;\t}\r\n;\t\r\n;\texecv(name, arg)\r\n;\tchar *\tname, ** arg;\r\n;\t{\r\n;\t\tstruct fcb\tfc;\r\n;\t\tuchar\t\tluid;\r\n;\t\tshort\t\ti, j;\r\n;\t\tregister char *\tcp;\r\n;\t\tchar\t\tprogbuf[128];\t/* storage for the code */\r\n;\t\r\n;\t\tfor(i = 1, j = 0 ; arg[i] ; i++)\r\n;\t\t\tj += strlen(arg[i])+1;\r\n;\t\tif(j >= 126)\r\n;\t\t\treturn -1;\t\t/* arg list too big */\r\n;\t\tif(i > 1)\r\n;\t\t\tsetfcb(DFCB, arg[1]);\r\n;\t\telse\r\n;\t\t\tsetfcb(DFCB, \"\");\r\n;\t\tcp = (char *)DBUF;\r\n;\t\t*cp++ = j;\r\n;\t\t*cp = 0;\r\n;\t\tfor(i = 0 ; arg[i] ; i++) {\r\n;\t\t\tstrcat(cp, \" \");\r\n;\t\t\tstrcat(cp, arg[i]);\r\n;\t\t}\r\n;\t\tsetfcb(&fc, name);\r\n;\t\tif(fc.ft[0] != ' ')\r\n;\t\t\treturn -1;\r\n;\t\tstrncpy(fc.ft, \"COM\", 3);\r\n;\t\tluid = getuid();\r\n;\t\tsetuid(fc.uid);\r\n;\t\tif(bdos(CPMOPN, &fc) == -1) {\r\n;\t\t\tsetuid(luid);\r\n;\t\t\treturn -1;\r\n;\t\t}\r\n;\t\tbmove(doexec, progbuf, sizeof progbuf);\r\n;\t\t(*(void (*)())progbuf)(&fc, luid);\r\n;\t}\r\n*Title HI-TECH C: EXECV.C\r\n\r\nentry\tequ\t5\t\t; CP/M bdos call entry point\r\nglobal\tindir\r\n\r\npsect\ttext\r\n_doexec:\r\npush\tiy\r\npush\tix\r\nld\tix,0\r\nadd\tix,sp\r\npush\tbc\r\nld\tc,(ix+6)\r\nld\tb,(ix+7)\r\npush\tbc\r\npop\tiy\r\nld\t(ix+-2),0\r\nld\t(ix+-1),1\r\nl5:\r\nld\te,(ix+-2)\r\nld\td,(ix+-1)\r\nld\tc,26\r\npush\tix\r\npush\tiy\r\ncall\tentry\r\npop\tiy\r\npop\tix\r\nld\tde,128\r\nld\tl,(ix+-2)\r\nld\th,(ix+-1)\r\nadd\thl,de\r\nld\t(ix+-2),l\r\nld\t(ix+-1),h\r\npush\tiy\r\npop\tde\r\nld\tc,20\r\npush\tix\r\npush\tiy\r\ncall\tentry\r\npop\tiy\r\npop\tix\r\nor\ta\r\njr\tz,l5\r\nld\te,(ix+8)\r\nld\tc,32\r\ncall\tentry\r\nld\tde,128\r\nld\tc,26\t\t;SETDMA\r\ncall\tentry\r\ncall\t256\t\t;go execute at TPA base\r\njp\t0\t\t;if it returned\r\nglobal\t_execl\r\nglobal\t_execv\r\n_execl:\r\npush\tiy\r\npush\tix\r\nld\tix,0\r\nadd\tix,sp\r\npush\tix\r\npop\tde\r\nld\thl,8\r\nadd\thl,de\r\npush\thl\r\nld\tl,(ix+6)\r\nld\th,(ix+7)\r\npush\thl\r\ncall\t_execv\r\nld\tsp,ix\r\npop\tix\r\npop\tiy\r\nret\r\nglobal\t_strlen\r\nglobal\t_setfcb\r\nglobal\t_strcat\r\nglobal\t_strncpy\r\nglobal\t_bmove\r\n_execv:\r\npush\tiy\r\npush\tix\r\nld\tix,0\r\nadd\tix,sp\r\nld\thl,-175\r\nadd\thl,sp\r\nld\tsp,hl\r\nld\t(ix+-45),1\r\nld\t(ix+-44),0\r\nld\t(ix+-47),0\r\nld\t(ix+-46),0\r\njp\tl11\r\nl8:\r\nld\te,(ix+8)\r\nld\td,(ix+9)\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\nadd\thl,hl\r\nadd\thl,de\r\nld\tc,(hl)\r\ninc\thl\r\nld\tb,(hl)\r\npush\tbc\r\ncall\t_strlen\r\npop\tbc\r\nex\tde,hl\r\ninc\tde\r\nld\tl,(ix+-47)\r\nld\th,(ix+-46)\r\nadd\thl,de\r\nld\t(ix+-47),l\r\nld\t(ix+-46),h\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\ninc\thl\r\nld\t(ix+-45),l\r\nld\t(ix+-44),h\r\nl11:\r\nld\te,(ix+8)\r\nld\td,(ix+9)\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\nadd\thl,hl\r\nadd\thl,de\r\nld\ta,(hl)\r\ninc\thl\r\nor\t(hl)\r\njp\tnz,l8\r\nld\tde,126\r\nld\tl,(ix+-47)\r\nld\th,(ix+-46)\r\nor\ta\r\nsbc\thl,de\r\njp\tm,l12\r\nL2:\r\nld\thl,-1\r\nld\tsp,ix\r\npop\tix\r\npop\tiy\r\nret\r\nl12:\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\nld\tde,1\r\nor\ta\r\nsbc\thl,de\r\njp\tm,l13\r\nld\tl,(ix+8)\r\nld\th,(ix+9)\r\ninc\thl\r\ninc\thl\r\nld\tc,(hl)\r\ninc\thl\r\nld\tb,(hl)\r\npush\tbc\r\nld\thl,92\r\npush\thl\r\ncall\t_setfcb\r\npop\tbc\r\npop\tbc\r\njp\tl14\r\nl13:\r\nld\thl,19f\r\npush\thl\r\nld\thl,92\r\npush\thl\r\ncall\t_setfcb\r\npop\tbc\r\npop\tbc\r\nl14:\r\nld\tiy,128\r\nld\ta,(ix+-47)\r\nld\t(iy+0),a\r\ninc\tiy\r\nld\t(iy+0),0\r\nld\t(ix+-45),0\r\nld\t(ix+-44),0\r\njp\tl18\r\nl15:\r\nld\thl,39f\r\npush\thl\r\npush\tiy\r\ncall\t_strcat\r\npop\tbc\r\npop\tbc\r\nld\te,(ix+8)\r\nld\td,(ix+9)\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\nadd\thl,hl\r\nadd\thl,de\r\nld\tc,(hl)\r\ninc\thl\r\nld\tb,(hl)\r\npush\tbc\r\npush\tiy\r\ncall\t_strcat\r\npop\tbc\r\npop\tbc\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\ninc\thl\r\nld\t(ix+-45),l\r\nld\t(ix+-44),h\r\nl18:\r\nld\te,(ix+8)\r\nld\td,(ix+9)\r\nld\tl,(ix+-45)\r\nld\th,(ix+-44)\r\nadd\thl,hl\r\nadd\thl,de\r\nld\ta,(hl)\r\ninc\thl\r\nor\t(hl)\r\njp\tnz,l15\r\nld\tl,(ix+6)\r\nld\th,(ix+7)\r\npush\thl\r\npush\tix\r\npop\tde\r\nld\thl,-42\r\nadd\thl,de\r\npush\thl\r\ncall\t_setfcb\r\npop\tbc\r\npop\tbc\r\npush\tix\r\npop\tde\r\nld\thl,-33\r\nadd\thl,de\r\nld\ta,(hl)\r\ncp\t32\r\njp\tnz,L2\r\nld\thl,3\r\npush\thl\r\nld\thl,29f\r\npush\thl\r\npush\tix\r\npop\tde\r\nld\thl,-33\r\nadd\thl,de\r\npush\thl\r\ncall\t_strncpy\r\npop\tbc\r\npop\tbc\r\npop\tbc\r\nld\te,255\r\nld\tc,32\r\npush\tix\r\npush\tiy\r\ncall\tentry\r\npop\tiy\r\npop\tix\r\nld\t(ix+-43),a\r\nld\te,(ix+-1)\t;get fc.uid\r\nld\tc,32\t\t; CPMSUID\r\npush\tix\r\npush\tiy\r\ncall\tentry\r\npop\tiy\r\npop\tix\r\npush\tix\r\npop\tde\r\nld\thl,-42\r\nadd\thl,de\r\nex\tde,hl\r\nld\tc,15\r\npush\tix\r\npush\tiy\r\ncall\tentry\r\npop\tiy\r\npop\tix\r\ncp\t255\r\njp\tnz,l20\r\nld\te,(ix+-43)\r\nld\tc,32\r\npush\tix\r\npush\tiy\r\ncall\tentry\r\npop\tiy\r\npop\tix\r\njp\tL2\r\nl20:\r\nld\thl,128\r\npush\thl\r\npush\tix\r\npop\tde\r\nld\thl,-175\r\nadd\thl,de\r\npush\thl\r\nld\thl,_doexec\r\npush\thl\r\ncall\t_bmove\r\npop\tbc\r\npop\tbc\r\npop\tbc\r\nld\tl,(ix+-43)\r\nld\th,0\r\npush\thl\r\npush\tix\r\npop\tde\r\nld\thl,-42\r\nadd\thl,de\r\npush\thl\r\npush\tix\r\npop\tde\r\nld\thl,-175\r\nadd\thl,de\r\ncall\tindir\r\nld\tsp,ix\r\npop\tix\r\npop\tiy\r\nret\r\npsect\tdata\r\n19:\r\ndefb\t0\r\n29:\r\ndefb\t67,79,77,0\r\n39:\r\ndefb\t32,0\r\n"
  },
  {
    "path": "cpm/EXIT.AS",
    "content": "\tglobal\t_exit, __cpm_clean\r\n\r\nBDOS\tequ\t00005h\r\nCPMVERS\tequ\t12\r\nCPMRCOD\tequ\t108\t\t; CP/M+ Get/Set Error Return Code \r\n\r\n\tpsect\ttext\r\n_exit:\tld\t(80h),hl\r\n\tcall\t__cpm_clean\r\n\tld\tc,CPMVERS\r\n\tcall\tBDOS\t\t;Get version\r\n\tdec\th\t\t; set Z if MP/M\r\n\tjp\tz,0\t\t; Warm boot if MP/M\r\n\tcp\t30h\t      \r\n\tjp\tc,0\t\t;Warm boot CP/M if < CP/M 3\r\n\tld\thl,(80h)\r\n\tld\ta,l\t\t;For compatibility with conditionals system,\r\n\t\t\t\t;use 7-bit CP/M 3 error codes.\r\n\tand\t7fh\r\n\tld\te,a\r\n\tld\ta,h\t\t;Set D=0FFh for error\r\n\tor\tl\t\t;or 0 for all clear.\r\n\tjr\tz,exit0\r\n\tld\ta,0ffh\r\nexit0:\tld\td,a\r\n\tld\tc,CPMRCOD\r\n\tcall\tBDOS\t\t;Report error.\r\n\trst\t0\r\n"
  },
  {
    "path": "cpm/FAKECLEA.AS",
    "content": "\tglobal\t__cleanup\r\n\r\n\tpsect\ttext\r\n__cleanup:\r\n\tret\r\n"
  },
  {
    "path": "cpm/FAKECPCL.AS",
    "content": "\tglobal\t__cpm_clean\r\n\r\n\tpsect\ttext\r\n__cpm_clean:\r\n\tret\r\n"
  },
  {
    "path": "cpm/FCBNAME.C",
    "content": "#include    <cpm.h>\r\n#include    <string.h>\r\n\r\n/*\r\n *  char *  fcbname(i);\r\n *  short   i;\r\n *\r\n *  Returns a character string which is the name of the file currently\r\n *  open on file descriptor i. The name is extracted from the corresponding\r\n *  fcb.\r\n */\r\n\r\nchar *fcbname(short i)\r\n{\r\n    register struct fcb *fc;\r\n    static char          abuf[20];\r\n    register char       *cp, *xp;\r\n\r\n\r\n    fc = &_fcb[i];\r\n    switch(fc->use)\r\n    {\r\n    case U_CON:\r\n        return \"CON:\";\r\n\r\n    case U_RDR:\r\n        if ((bdos(CPMVERS)&0xFF) < 0x30)\r\n            return \"RDR:\";\r\n        else\r\n            return \"AUXIN:\";\r\n    case U_PUN:\r\n        if ((bdos(CPMVERS)&0xFF) < 0x30)\r\n            return \"PUN:\";\r\n        else\r\n            return \"AUXOUT:\";\r\n    case U_LST:\r\n        return \"LST:\";\r\n\r\n    case U_READ:\r\n    case U_WRITE:\r\n    case U_RDWR:\r\n        cp = abuf;\r\n        if (fc->dr)\r\n            *cp++ = 'A' + fc->dr - 1;\r\n        sprintf(cp, \"%d:\", fc->uid);\r\n        cp += strlen(cp);\r\n        for (xp = fc->name ; *xp > ' ' && xp < fc->name+sizeof fc->name;)\r\n            *cp++ = (*xp++) & 0x7F;\r\n        *cp++ = '.';\r\n        for (xp = fc->ft ; *xp > ' ' && xp < fc->ft+sizeof fc->ft ;)\r\n            *cp++ = (*xp++) & 0x7F;\r\n        *cp = 0;\r\n        return abuf;\r\n\r\n\tcase U_RSX:\r\n\t\treturn \"RSX:\";\r\n\tcase U_ERR:\r\n\t\treturn \"ERR:\";\r\n\r\n    default:\r\n        return (char *)0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "cpm/GETCH.C",
    "content": "#include\t<cpm.h>\r\n\r\nstatic short\tpushback;\r\n\r\ngetch()\r\n{\r\n\tshort\tc;\r\n\r\n\tif(c = pushback) {\r\n\t\tpushback = 0;\r\n\t\treturn c;\r\n\t}\r\n\twhile(!(c = bdos(CPMDCIO, 0xFF)))\r\n\t\tcontinue;\r\n\treturn c;\r\n}\r\n\r\n\r\ngetche()\r\n{\r\n\tshort\tc;\r\n\r\n\tif(c = pushback) {\r\n\t\tpushback = 0;\r\n\t\treturn c;\r\n\t}\r\n\treturn bdos(CPMRCON) & 0xFF;\r\n}\r\n\r\nungetch(c)\r\nunsigned char\tc;\r\n{\r\n\tpushback = c;\r\n}\r\n\r\nputch(c)\r\nunsigned char\tc;\r\n{\r\n\tif(c == '\\n')\r\n\t\tbdos(CPMWCON, '\\r');\r\n\tbdos(CPMWCON, c);\r\n}\r\n\r\nkbhit()\r\n{\r\n\treturn (bdos(CPMICON) & 0xFF) != 0;\r\n}\r\n"
  },
  {
    "path": "cpm/GETFCB.C",
    "content": "#include    <cpm.h>\r\n#include    <ctype.h>\r\n#include    <sys.h>\r\n\r\n/*\r\n *  Syntax of CP/M file names is:\r\n *\r\n *  [[0-9]+[:]][[a-pA-P]:]name[.ext] | [[a-pA-p][[0-9]+]:]name[.ext]\r\n *\r\n *  E.g.\r\n *      file.txt\r\n *      a:file\r\n *      10:b:READ-ME.doc\r\n */\r\n\r\n\r\n#define DNAMLEN 4   /* length of device names */\r\n\r\nstatic char dnames[][DNAMLEN] =\r\n{\r\n    \"CON:\",\r\n    \"RDR:\",\r\n    \"PUN:\",\r\n    \"LST:\",\r\n    \"RSX:\",\r\n    \"ERR:\"\r\n};\r\n\r\n#define NDNAMES 6\r\n\r\nextern int  atoi(char *);\r\nstatic void fc_parse(struct fcb *, char *);\r\n\r\nstruct fcb *getfcb()\r\n{\r\n    register struct fcb *fp;\r\n\r\n    for (fp = _fcb ; fp < &_fcb[MAXFILE] ; fp++)\r\n        if (!fp->use)\r\n        {\r\n            fp->use = U_READ;\r\n            fp->rwp = 0;\r\n            return fp;\r\n        }\r\n    return (struct fcb *)0;\r\n}\r\n\r\nvoid putfcb(struct fcb *fc)\r\n{\r\n    fc->use = 0;\r\n}\r\n\r\nuchar setfcb(struct fcb *fc, char *name)\r\n{\r\n    uchar           i,j;\r\n\r\n    while (isspace(*name))\r\n        ++name;\r\n    /* Check device names */\r\n    for (i = 0 ; i < NDNAMES ; ++i)\r\n        for (j = 0; ;)\r\n            if (dnames[i][j] != toupper(name[j]))\r\n                break;\r\n            else if (++j == DNAMLEN)\r\n            {\r\n                fc->use = i+U_CON;\r\n                return 1;\r\n            }\r\n    /* Not a device; could be a file. */\r\n    fc_parse(fc, name);\r\n    return 0;\r\n}\r\n\r\nstatic void fc_parse(struct fcb *fc, char *name)\r\n{\r\n    char\r\n        *cp,\r\n        *np,\r\n         c,\r\n         num[3];\r\n\r\n    fc->dr = 0;\r\n    fc->uid = getuid();\r\n\r\n    cp = name;\r\n    if (cp[1]==':'  || cp[2]==':' || cp[3]==':')  /* Drive/user */\r\n    {\r\n        np = num;\r\n        while (*cp != ':')\r\n        {\r\n            if (isdigit(*cp)) \r\n                *np++ = *cp;\r\n            else if (fc->dr == 0)\r\n                fc->dr = toupper(*cp) - 'A' + 1;  \r\n            ++cp;\r\n        }\r\n        *np = 0;\r\n        if (num[0])\r\n            fc->uid=atoi(num);\r\n        ++cp;\r\n    }\r\n    if (cp[1]==':' && fc->dr == 0 && !isdigit(cp[0]))  /* u:d: */\r\n    {\r\n        fc->dr=toupper(*cp) - 'A' + 1;\r\n        cp += 2;\r\n    }\r\n    name = cp;\r\n    cp = fc->name;\r\n    while (*name != '.' && *name != '*' && *name > ' ' && cp < &fc->name[8])\r\n        *cp++ = toupper(*name++);\r\n    if (*name == '*')\r\n        c = '?';\r\n    else\r\n        c = ' ';\r\n    while (cp < &fc->name[8])\r\n        *cp++ = c;\r\n    while (*name && *name++ != '.')\r\n        continue;\r\n    while (*name > ' ' && *name != '*' && cp < &fc->ft[3])\r\n        *cp++ = toupper(*name++);\r\n    if (*name == '*')\r\n        c = '?';\r\n    else\r\n        c = ' ';\r\n    while (cp < &fc->ft[3])\r\n        *cp++ = c;\r\n    fc->ex = fc->nr = 0;\r\n}\r\n"
  },
  {
    "path": "cpm/GETUID.AS",
    "content": ";\tSet/get uid for CP/M\r\n\r\n\tglobal\t_getuid, _setuid, csv, cret\r\n\r\n\tentry\tequ\t5\t\t;CP/M system call entry\r\n\tsguid\tequ\t32\t\t;set/get user number\r\n\targ\tequ\t6\t\t;offset of 1st arg\r\n\r\n\tpsect\ttext\r\n_getuid:\r\n\tcall\tcsv\r\n\tld\te,0FFh\t\t\t;to get rather than set\r\n\tjr\t4f\t\t\t;Go to common code\r\n_setuid:\r\n\tcall\tcsv\r\n\tld\te,(ix+arg)\t\t;get argument\r\n4:\r\n\tld\tc,sguid\r\n\tpush\tix\r\n\tcall\tentry\r\n\tpop\tix\r\n\tjp\tcret\r\n"
  },
  {
    "path": "cpm/ISATTY.C",
    "content": "#include    \"cpm.h\"\r\n\r\nint isatty(uchar f)\r\n{\r\n    switch(_fcb[f].use)\r\n    {\r\n    case U_CON:\r\n    case U_RDR:\r\n    case U_PUN:\r\n    case U_LST:\r\n    case U_RSX:\r\n    case U_ERR:\r\n        return 1;\r\n    }\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "cpm/MAKEFILE",
    "content": ".SUFFIXES:\t.c .obj .as .lib\r\n\r\nBIN\t= /usr/hitech/bin\r\nLIB\t= ../lib\r\nPACK\t= ../pack\r\nLIBR\t= $(BIN)/libr\r\nAS\t= $(BIN)/zas\r\nCC\t= $(BIN)/zc\r\nLINK\t= $(BIN)/link\r\nOBJHEX\t= $(BIN)/objtohex\r\nENHUFF\t= ../bin/enhuff\r\nCFLAGS\t= -O -x $(DEFS) -Uunix\r\nASFLAGS\t= -j\r\n\r\n.c.obj:\t;\t$(CC) $(CFLAGS) -c $*.c\r\n.as.obj: ;\t$(AS) $(ASFLAGS) $*.as\r\n\r\nOBJS\t= start1.obj start2.obj open.obj read.obj write.obj chmod.obj seek.obj \\\r\n\t  fcbname.obj rename.obj creat.obj time.obj convtime.obj timezone.obj \\\r\n\t  stat.obj isatty.obj cleanup.obj close.obj unlink.obj dup.obj getfcb.obj \\\r\n\t  srand1.obj getch.obj signal.obj getuid.obj \\\r\n\t  abort.obj execl.obj bdos.obj bdoshl.obj \\\r\n\t  bios.obj _exit.obj exit.obj fakeclean.obj fakecpcln.obj sys_err.obj\r\n\r\nall:\tzcrtcpm.obj zdrtcpm.obj zrrtcpm.obj  zlibcpm.lib c.com\r\n\r\ninstall:\tall\r\n\tcp zcrtcpm.obj zdrtcpm.obj zrrtcpm.obj  zlibcpm.lib $(LIB)\r\n\tchmod og+r $(LIB)/zcrtcpm.obj $(LIB)/zdrtcpm.obj $(LIB)/zrrtcpm.obj \\\r\n\t\t $(LIB)/zlibcpm.lib\r\n\ttouch install\r\n\r\nzlibcpm.lib:\t$(OBJS)\r\n\t$(LIBR) r zlibcpm.lib $(OBJS)\r\n\r\nc.com:\tc.obj\r\n\tzc -mmap -f c.obj\r\n\r\nexec.com:\texec.obj\r\n\t$(LINK) -l -ptext=0,bss exec.obj\r\n\t$(OBJHEX) -R -B100H l.obj exec.com\r\n\t-rm l.obj\r\n\r\nclean:\r\n\t-rm -f zlibcpm.lib *.obj\r\n\r\nhuff:\r\n\t-rm cpm.huf\r\n\t$(ENHUFF) -a cpm.huf Makefile \\\r\n\tcleanup.c close.c convtime.c creat.c dup.c getch.c \\\r\n\tfcbname.c getfcb.c isatty.c open.c stat.c chmod.c \\\r\n\tread.c rename.c seek.c signal.c srand1.c sys_err.c \\\r\n\ttime.c timezone.c unlink.c write.c _exit.as bdos.as bdoshl.as \\\r\n\tbios.as csv.as exec.as exit.as fakeclean.as getuid.as srand.as \\\r\n\tstart1.as start2.as zcrtcpm.as zdrtcpm.as zrrtcpm.as execl.as \\\r\n\tabort.c c.c fakecpcln.as\r\n\r\nprint:\r\n\tprint Makefile *.h *.c *.as\r\n"
  },
  {
    "path": "cpm/MKTIME.C",
    "content": "/* Convert structure to time value */\r\n\r\n#include <time.h>\r\n\r\n/* leap year calculator expects year argument as years offset from 1900 */\r\n#define LEAP_YEAR(Y)  ( ((1900+(Y))>0) && !((1900+(Y))%4) && ( ((1900+(Y))%100) || !((1900+(Y))%400) ) )\r\n\r\n#define SECS_PER_DAY  (86400l)\r\n#define SECS_PER_HOUR (3600l)\r\n#define SECS_PER_MIN  (60l)\r\n\r\nstatic unsigned char monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};\r\n \r\ntime_t mktime(struct tm *ptm){   \r\n  \r\n   int i;\r\n   time_t seconds;\r\n\r\n   /* seconds from 1970 till 1 jan 00:00:00 of the given year */\r\n   seconds= (ptm->tm_year-70)*(SECS_PER_DAY * 365);\r\n   for (i = 70; i < ptm->tm_year; i++) {\r\n      if (LEAP_YEAR(i)) {\r\n         seconds += SECS_PER_DAY;   /* add extra days for leap years */\r\n      }\r\n   }\r\n  \r\n   /* add days for this year */\r\n   for (i = 0; i < ptm->tm_mon; i++) {\r\n      if ( (i == 1) && LEAP_YEAR(ptm->tm_year)) { \r\n         seconds += SECS_PER_DAY * 29;\r\n      } else {\r\n         seconds += SECS_PER_DAY * (int)monthDays[i];\r\n      }\r\n   }\r\n   seconds += (ptm->tm_mday-1) * SECS_PER_DAY;\r\n   seconds += ptm->tm_hour * SECS_PER_HOUR;\r\n   seconds += ptm->tm_min * SECS_PER_MIN;\r\n   seconds += ptm->tm_sec;\r\n   seconds += time_zone * SECS_PER_MIN;\r\n   return (time_t)seconds; \r\n}\r\n"
  },
  {
    "path": "cpm/OPEN.C",
    "content": "#include    \"cpm.h\"\r\n\r\nextern int errno;\r\n\r\nextern char _exact;  /* Exact file size hint for last sector\r\n\t\t\t'C' = not used (old CP/M),\r\n                        'D' = DOSPLUS mode (count is USED bytes),\r\n\t\t\t'I' = ISX mode (count is UNUSED bytes)\r\n                      */\r\n\r\nlong _fsize(uchar fd)\r\n{\r\n    register struct fcb *fc;\r\n    long            tmp;\r\n    uchar           d, luid, buf[SECSIZE];\r\n\r\n    if (fd >= MAXFILE)\r\n        return -1;\r\n    fc = &_fcb[fd];\r\n    luid = getuid();\r\n    setuid(fc->uid);\r\n    bdos(CPMCFS, fc);\r\n/*\r\n    tmp = (long)fc->ranrec[0] + ((long)fc->ranrec[1] << 8)\r\n                              + ((long)fc->ranrec[2] << 16);\r\n    tmp *= SECSIZE;\r\n\r\n    A slightly more efficient but more obscure coding ... */\r\n    tmp = (*(long *)(&fc->ranrec[-1]) & 0xFFFFFF00) / 2;\r\n\r\n    bdos(CPMSDMA,buf);\r\n    /* Account for CP/M3 bytewise file sizes in last sector */\r\n    if ((d = bdos(CPMFFST, fc) & 0xFF) < 4)\r\n    {\r\n        d = (buf[13 + (d << 5)] & 0x7F); /* Count of UNUSED bytes */\r\n        if ((_exact == 'D') && (d != 0)) /* DOS Plus has count of USED bytes */\r\n            d = 0x80 - d;\r\n        tmp -= d;\r\n    }\r\n    setuid(luid);\r\n    return tmp;\r\n}\r\n\r\n\r\nint open(char *name, int mode)\r\n{\r\n    register struct fcb *fc;\r\n    uchar           luid;\r\n\r\n    if (++mode > U_RDWR)\r\n        mode = U_RDWR;\r\n    if (!(fc = getfcb()))\r\n        return -1;\r\n    if (!setfcb(fc, name))\r\n   {\r\n        if (mode == U_READ && (bdos(CPMVERS)&0x7F) >= 0x30)\r\n            fc->name[5] |= (char) 0x80;    /* read-only mode */\r\n        luid = getuid();\r\n        setuid(fc->uid);\r\n        if ((bdos(CPMOPN, fc) & 0xFF)  == 0xFF)\r\n        {\r\n            putfcb(fc);\r\n            setuid(luid);\r\n            if (errno == 16)\r\n                errno = 7; /* File not found */\r\n            return -1;\r\n        }\r\n        fc->fsize = _fsize(fc - _fcb);    /* Set file size */\r\n        setuid(luid);\r\n        fc->use = mode;\r\n    }\r\n    return fc - _fcb;\r\n}\r\n"
  },
  {
    "path": "cpm/READ.C",
    "content": "#include    \"cpm.h\"\r\n\r\nextern char _piped; /* PIPEMGR loaded? */\r\n\r\n#define CPMEOF 0x1A         /* Control-Z */\r\n\r\nstatic char RSXPB[] = {0x7C,0};\r\n\r\nint read(uchar fd, char *buf, ushort nbytes)\r\n{\r\n    register struct fcb *   fc;\r\n    uchar   size, offs, luid;\r\n    ushort  cnt;\r\n    ushort  pipev;\r\n    char    buffer[SECSIZE+2];\r\n\r\n    cnt = 0;\r\n    if (fd >= MAXFILE)\r\n        return -1;\r\n    fc = &_fcb[fd];\r\n    switch(fc->use)\r\n    {\r\n    case U_RDR:\r\n        cnt = nbytes;\r\n        while(nbytes)\r\n        {\r\n            --nbytes;\r\n            if ((*buf++ = (bdos(CPMRRDR) & 0x7f)) == '\\n')\r\n                break;\r\n        }\r\n        return cnt - nbytes;\r\n\r\n    case U_RSX:       /* PIPEMGR RSX : input */\r\n        if (_piped)\r\n        {\r\n            cnt = nbytes;\r\n            while (nbytes) \r\n            {\r\n                pipev = bdos(CPMRSX, &RSXPB);\r\n                if (pipev < 0x100) \r\n                    break;\r\n                else\r\n                    *buf++ = (pipev & 0xFF);\r\n                --nbytes; /* Only decrement if the read worked*/\r\n                if ((pipev & 0xFF) == '\\n') \r\n                    break;\r\n            }\r\n            return cnt - nbytes;\r\n        }\r\n\r\n    case U_CON:\r\n        if (nbytes > SECSIZE)\r\n            nbytes = SECSIZE;\r\n        buffer[0] = nbytes;\r\n        bdos(CPMRCOB, buffer);\r\n        cnt = (uchar)buffer[1];\r\n\r\n        /* [JCE] Return EOF for Ctrl-Z on a line by itself. */\r\n        if (cnt == 1 && buffer[2] == CPMEOF)\r\n            return 0;\r\n\r\n        if(cnt < nbytes)\r\n        {\r\n            bdos(CPMWCON, '\\n');\r\n            buffer[cnt+2] = '\\n';\r\n            ++cnt;\r\n        }\r\n        bmove(&buffer[2], buf, cnt);\r\n        return cnt;\r\n\r\n    case U_READ:\r\n    case U_RDWR:\r\n        if (nbytes + fc->rwp > fc->fsize)   /* Limit length */\r\n            nbytes = fc->fsize - fc->rwp;\r\n        luid = getuid();\r\n        cnt = nbytes;\r\n        while(nbytes)\r\n        {\r\n            _sigchk();\r\n            setuid(fc->uid);\r\n            offs = fc->rwp%SECSIZE;\r\n            if ((size = SECSIZE - offs) > nbytes)\r\n                size = nbytes;\r\n            _putrno(fc->ranrec, fc->rwp/SECSIZE);\r\n            if (size == SECSIZE)\r\n            {\r\n                bdos(CPMSDMA, buf);\r\n#ifdef  LARGE_MODEL\r\n                bdos(CPMDSEG, (int)((long)buf >> 16));  /* set DMA segment */\r\n#endif\r\n                if (bdos(CPMRRAN, fc))\r\n                    break;\r\n            }\r\n            else\r\n            {\r\n                bdos(CPMSDMA, buffer);\r\n#ifdef  LARGE_MODEL\r\n                bdos(CPMDSEG, (int)((long)buffer >> 16)); /* set DMA segment */\r\n#endif\r\n                if (bdos(CPMRRAN, fc))\r\n                    break;\r\n                bmove(buffer+offs, buf, size);\r\n            }\r\n            buf += size;\r\n            fc->rwp += size;\r\n            nbytes -= size;\r\n            setuid(luid);\r\n        }\r\n        setuid(luid);\r\n        return cnt - nbytes;\r\n\r\n    default:\r\n        return -1;\r\n    }\r\n}\r\n"
  },
  {
    "path": "cpm/RELIBCPM.SUB",
    "content": "libr \r\n<r libc3.lib \\\r\n<start1.obj open.obj read.obj write.obj chmod.obj seek.obj \\\r\n<fcbname.obj rename.obj creat.obj time.obj convtime.obj timezone.obj \\\r\n<stat.obj isatty.obj cleanup.obj close.obj unlink.obj dup.obj getfcb.obj \\\r\n<srand1.obj getch.obj signal.obj getuid.obj <abort.obj execl.obj bdos.obj \\\r\n<bios.obj _exit.obj exit.obj fakeclean.obj fakecpcln.obj sys_err.obj\r\n"
  },
  {
    "path": "cpm/RENAME.C",
    "content": "#include    \"cpm.h\"\r\n\r\nint rename(char *n1, char *n2)\r\n{\r\n    struct fcb  fc[2];\r\n\r\n    unlink(n2);\r\n    if (!(setfcb(&fc[0], n1) || setfcb((struct fcb *)(fc[0].dm), n2))\r\n      && (bdos(CPMREN, &fc[0]) & 0xFF) >= 0)\r\n        return 0;\r\n    return -1;\r\n}\r\n"
  },
  {
    "path": "cpm/SEEK.C",
    "content": "#include\t\"cpm.h\"\r\n\r\nlong\r\nlseek(fd, offs, whence)\r\nuchar\tfd, whence;\r\nlong\toffs;\r\n{\r\n\tregister struct fcb *\tfc;\r\n\tlong\t\t\tpos;\r\n\r\n\tif(fd >= MAXFILE)\r\n\t\treturn -1;\r\n\tfc = &_fcb[fd];\r\n\tswitch(whence) {\r\n\r\n\tdefault:\r\n\t\tpos = offs;\r\n\t\tbreak;\r\n\r\n\tcase 1:\r\n\t\tpos = fc->rwp + offs;\r\n\t\tbreak;\r\n\r\n\tcase 2:\r\n\t\tif (fc->rwp > fc->fsize)\r\n\t\t\tpos = fc->rwp   + offs;\r\n\t\telse\tpos = fc->fsize + offs;\r\n\t\tbreak;\r\n\t}\r\n\tif(pos >= 0) {\r\n\t\tfc->rwp = pos;\r\n\t\treturn fc->rwp;\r\n\t}\r\n\treturn -1;\r\n}\r\n"
  },
  {
    "path": "cpm/SIGNAL.C",
    "content": "#include\t\"cpm.h\"\r\n#include\t<signal.h>\r\n\r\nstatic signal_t where;\r\n\r\nsignal_t signal(int sig, signal_t action) \r\n{\r\n\tsignal_t prev;\r\n\r\n\tif(sig != SIGINT)\r\n\t\treturn (signal_t)-1;\r\n\tprev = where;\r\n\twhere = action;\r\n\treturn prev;\r\n}\r\n\r\nvoid\r\n_sigchk()\r\n{\r\n\tchar\tc;\r\n\r\n\tif(where == SIG_IGN || (c = bdos(CPMDCIO,0xFF)) == 0)\r\n\t\treturn;\r\n\tif(c != CPMRBT)\r\n\t\treturn;\r\n\tif(where == SIG_DFL)\r\n\t\texit(-SIGINT);\r\n\t((int(*)())where)(SIGINT);\r\n}\r\n"
  },
  {
    "path": "cpm/SRAND.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_randomiz, _srand\r\n\r\n_randomiz:\r\n\tld\ta,r\r\n\tld\tl,a\r\n\tld\th,0\r\n\tpush\thl\r\n\tcall\t_srand\r\n\tpop\thl\r\n\tret\r\n"
  },
  {
    "path": "cpm/SRAND1.C",
    "content": "#include <conio.h>\r\n\r\nsrand1(s)\r\nchar *\ts;\r\n{\r\n\tint\ti;\r\n\twhile(*s)\r\n\t\tputchar(*s++);\r\n\twhile(!kbhit())\r\n\t\ti++;\r\n\tsrand(i);\r\n}\r\n"
  },
  {
    "path": "cpm/START1.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t__getargs, startup, __argc_\r\n\r\nstartup:\r\n\tjp\t__getargs\r\n\r\n\tpsect\tbss\r\n__argc_:\r\n\tdefs\t2\r\n"
  },
  {
    "path": "cpm/START2.AS",
    "content": "\tglobal\t__getargs, __argc_\r\n\tpsect\ttext\r\n\r\n__getargs:\r\n\tpop\thl\t\t;return address\r\n\texx\r\n\tpop\thl\r\n\tpop\thl\t\t;unjunk stack\r\n\tld\ta,(80h)\t\t;get buffer length\r\n\tinc\ta\t\t;allow for null byte\r\n\tneg\r\n\tld\tl,a\r\n\tld\th,-1\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t\t;allow space for args\r\n\tld\tbc,0\t\t;flag end of args\r\n\tpush\tbc\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tld\tc,(hl)\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\tpush\thl\r\n\tinc\tc\r\n4:\tld\ta,(de)\t\t;remove extra spaces\r\n\tcp\t' '\r\n\tjr\tnz,5f\r\n\tdec\tde\r\n\tjr\t4b\r\n5:\r\n\txor\ta\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\t(__argc_),bc\t\t;store argcount\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\texx\r\n\tpush\tde\t\t;junk the stack again\r\n\tpush\tde\r\n\tpush\thl\t\t;return address\r\n\texx\r\n\tret\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n"
  },
  {
    "path": "cpm/STAT.C",
    "content": "#include    <stat.h>\r\n#include    <cpm.h>\r\n#include    <time.h>\r\n\r\nextern char _exact;  /* Exact file size hint for last sector\r\n\t\t\t'C' = not used (old CP/M),\r\n                        'D' = DOSPLUS mode (count is USED bytes),\r\n\t\t\t'I' = ISX mode (count is UNUSED bytes)\r\n                      */\r\n\r\n/*\r\n *  int stat(char * s, struct stat * b);\r\n *\r\n *  Fills  in the supplied struct stat with modification and\r\n *  access time and file size.\r\n */\r\n\r\nstruct tod\r\n{\r\n    int days;\r\n    int hoursmins;\r\n    char    secs;\r\n};\r\n\r\nextern time_t convtime();\r\n\r\nint stat(register char * s, register struct stat * b)\r\n{\r\n    short       c,d;\r\n    struct fcb  fc;\r\n    struct tod  td;\r\n    uchar       buf[SECSIZE+1];    /* For bytewise lengths */\r\n\r\n    c = getuid();\r\n    if (setfcb(&fc, s))\r\n        return -1;      /* A device ! */\r\n    setuid(fc.uid);\r\n    if (!bdos(CPMCFS, &fc) || bdos(CPMVERS) < 0x30)\r\n    {\r\n        /* get size */\r\n        b->st_size = fc.ranrec[0]\r\n                   + ((long)fc.ranrec[1] << 8)\r\n                   + ((long)fc.ranrec[2] << 16);\r\n        b->st_size *= SECSIZE;\r\n        if (fc.ft[0] & 0x80)\r\n            b->st_mode = S_IREAD|S_IFREG;\r\n        else\r\n            b->st_mode = S_IREAD|S_IFREG|S_IWRITE;\r\n        if (fc.ft[1] & 0x80)\r\n            b->st_mode |= S_SYSTEM;\r\n        if (fc.ft[2] & 0x80)\r\n            b->st_mode |= S_ARCHIVE;\r\n        td.secs = 0;\r\n        td.days = td.hoursmins = 0;\r\n        bdos(CPMSDMA,buf);\r\n        if ((d = bdos(CPMFFST,&fc)) < 4)\r\n        {\r\n            /* Account for CP/M3 bytewise file sizes */\r\n            d = (buf[13 + (d << 5)] & 0x7F); /* count of UNUSED bytes */\r\n            if (( _exact == 'D') && (d != 0)) /* DOS Plus has USED bytes */\r\n                d=0x80-d;\r\n            b->st_size-=d;\r\n        }\r\n\t/* Corrected to account for directory code return [jrs 2014-04-20] */\r\n        if ((bdos(CPMGFTS, &fc) & 0xFF) < 4) /* Get file date stamp */\r\n        {\r\n            td.days = ((int *)&fc)[24/sizeof(int)];\r\n            td.hoursmins = ((int *)&fc)[26/sizeof(int)];\r\n            b->st_atime = convtime(&td);\r\n            td.secs = 0;\r\n            td.days = ((int *)&fc)[28/sizeof(int)];\r\n            td.hoursmins = ((int *)&fc)[30/sizeof(int)];\r\n            b->st_mtime = convtime(&td);\r\n        }\r\n        setuid(c);\r\n        return 0;\r\n    }\r\n    setuid(c);\r\n    return -1;\r\n}\r\n"
  },
  {
    "path": "cpm/SYS_ERR.C",
    "content": "short   errno;\r\n\r\nstatic char uerr[]=\"Unknown error\";\r\n\r\nchar *  sys_err[] =\r\n{\r\n    uerr,                           /* 0 */\r\n    \"Reading empty space\",          /* 1 */\r\n    \"Disc is full\",                 /* 2 */\r\n    \"Can't close extent\",           /* 3 */\r\n    \"Unwritten extent\",             /* 4 */\r\n    \"Directory full\",               /* 5 */\r\n    \"File pointer out of range\",    /* 6 */\r\n    \"File not found\",               /* 7 */\r\n    uerr,                           /* 8 */\r\n    \"Invalid FCB\",                  /* 9 */\r\n    \"Disc has been changed\",        /* 10 */\r\n    uerr,uerr,uerr,uerr,uerr,uerr,  /* 11-16 - Below are CP/M-3 errors */\r\n    \"Disc I/O error\",               /* 17 */\r\n    \"Disc is read-only\",            /* 18 */\r\n    \"File is read-only\",            /* 19 */\r\n    \"Invalid drive\",                /* 20 */\r\n    \"File already open\",            /* 21 */\r\n    uerr,                           /* 22 */\r\n    \"Password error\",               /* 23 */\r\n    \"File exists\",                  /* 24 */\r\n    \"Ambiguous filename\",           /* 25 */\r\n    \"File is wheel protected\",      /* 26 */ \r\n    uerr    \r\n};\r\nshort   sys_ner = sizeof sys_err / sizeof sys_err[0];\r\n"
  },
  {
    "path": "cpm/TIME.C",
    "content": "/*\r\n *  time() for CP/M-86 type machines\r\n */\r\n\r\n#include    <cpm.h>\r\n#include    <time.h>\r\n\r\nstruct tod\r\n{\r\n    short   days;\r\n    char    hours;\r\n    char    mins;\r\n    char    secs;\r\n};\r\n\r\nextern time_t   convtime();\r\n\r\ntime_t time(time_t *tp)\r\n{\r\n    struct tod  tod;\r\n    time_t      t;\r\n\r\n    tod.hours = tod.mins = tod.secs = tod.days = 0;\r\n    tod.secs = bdos(CPMGDAT, &tod);\r\n    t = convtime(&tod);\r\n    if (tp)\r\n        *tp = t;\r\n    return t;\r\n}\r\n"
  },
  {
    "path": "cpm/TIMEZONE.C",
    "content": "#include\t<time.h>\r\n\r\nint\ttime_zone = 0;\r\n"
  },
  {
    "path": "cpm/UNLINK.C",
    "content": "#include    \"cpm.h\"\r\n\r\nunlink(char *name)\r\n{\r\n    struct fcb  fc;\r\n    uchar       luid;\r\n    short       retval;\r\n\r\n    if (setfcb(&fc, name))\r\n        return -1;\r\n    luid = getuid();\r\n    setuid(fc.uid);\r\n    retval = bdos(CPMDEL, &fc);\r\n    if ((retval & 0xFF) == 0xFF && errno == 16)\r\n        errno = 7; /* file not found */\r\n    setuid(luid);\r\n    return retval;\r\n}\r\n"
  },
  {
    "path": "cpm/WRITE.C",
    "content": "#include    \"cpm.h\"\r\n\r\nextern char _piped; /* PIPEMGR loaded? */\r\n\r\nwrite(uchar fd, char *buf, ushort nbytes)\r\n{\r\n    register struct fcb *fc;\r\n    uchar   size, offs, luid;\r\n    short   c;\r\n    ushort  count;\r\n    char    RSXPB[4];\r\n    char    buffer[SECSIZE];\r\n\r\n    if (fd >= MAXFILE)\r\n        return -1;\r\n    fc = &_fcb[fd];\r\n    offs = CPMWCON;\r\n    RSXPB[0]=0x7D;\r\n    RSXPB[1]=0;\r\n    RSXPB[3]=0;\r\n    count = nbytes;\r\n    switch (fc->use)\r\n    {\r\n    case U_PUN:\r\n        while (nbytes--)\r\n        {\r\n            _sigchk();\r\n            bdos(CPMWPUN, *buf++);\r\n        }\r\n        return count;\r\n\r\n    case U_LST:\r\n        offs = CPMWLST;\r\n\r\n    case U_CON:\r\n        while (nbytes--)\r\n        {\r\n            _sigchk();\r\n            c = *buf++;\r\n            bdos(offs, c);\r\n        }\r\n        return count;\r\n\r\n    case U_ERR:\r\n        RSXPB[0]=0x7A;\r\n    case U_RSX:\r\n        while (nbytes--)\r\n        {\r\n            _sigchk();\r\n            RSXPB[2]= *buf++;\r\n            if (_piped)\r\n                bdos(CPMRSX,RSXPB);\r\n            else\r\n                bdos(CPMWCON,RSXPB[2]);\r\n        }\r\n        return count;   \r\n    case U_WRITE:\r\n    case U_RDWR:\r\n        luid = getuid();\r\n        while (nbytes)\r\n        {\r\n            _sigchk();\r\n            setuid(fc->uid);\r\n            offs = fc->rwp%SECSIZE;\r\n            if ((size = SECSIZE - offs) > nbytes)\r\n                size = nbytes;\r\n            _putrno(fc->ranrec, fc->rwp/SECSIZE);\r\n            if (size == SECSIZE)\r\n            {\r\n                bdos(CPMSDMA, buf);\r\n#ifdef  LARGE_MODEL\r\n                bdos(CPMDSEG, (int)((long)buf >> 16));  /* set DMA segment */\r\n#endif\r\n            }\r\n            else\r\n            {\r\n                bdos(CPMSDMA, buffer);\r\n#ifdef  LARGE_MODEL\r\n                bdos(CPMDSEG, (int)((long)buffer >> 16));   /* set DMA segment */\r\n#endif\r\n                buffer[0] = CPMETX;\r\n                bmove(buffer, buffer+1, SECSIZE-1);\r\n                bdos(CPMRRAN, fc);\r\n                bmove(buf, buffer+offs, size);\r\n            }\r\n            if (bdos(CPMWRAN, fc))\r\n                break;\r\n            buf += size;\r\n            fc->rwp += size;\r\n            if (fc->fsize < fc->rwp)\r\n                fc->fsize = fc->rwp;\r\n            nbytes -= size;\r\n            setuid(luid);\r\n        }\r\n        setuid(luid);\r\n        return count-nbytes;\r\n\r\n    default:\r\n        return -1;\r\n    }\r\n}\r\n"
  },
  {
    "path": "cpm/ZC280CPM.AS",
    "content": "; This is ZCRTCPM for the Z280 MPU\r\n;\r\n\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\r\n\tglobal\tstart,_main,_exit,__Hbss, __Lbss, __argc_, __z3env, startup\r\n        global  __piped,__initrsx,__exact\r\n\r\n;\tStart with MS-DOS x86 detection\r\nstart:\t\t; DOS Protection\t8080/Z80\tx86\r\n\t\t\t\t;\t---------  --------------------\r\n\tdefb\t0EBh,04h\t;\tEX DE,HL   JMPS LABE\r\n\t\t\t\t;\tINC B\r\n\r\n\tex\tde,hl\t\t;\tEX DE,HL\r\n\tdefb\t0C3h\t\t;\tJP BEGIN\r\n\tdefw\tbegin\t\t; (We don't want the assembler optimising\r\n\t\t\t\t;  this to a relative branch)\r\n\r\nlabe:\tdefb\t0B8h,0,09h\t;\t\t   MOV AX,9 ; print string\r\n\r\n\tdefb\t0BAh\t\t;\t\t   MOV DX,OFFSET BVMES\r\n\tdefw\tbvmes\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\r\n\tdefb\t0B8h,01h,4Ch\t;\t\t   MOV AX,4C01h ; terminate\r\n\t\t\t\t;\t\t   ; with CTRL-BREAK code (1)\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\t\t\t\t\t\t   ; we never return here\r\n\r\n\tdefb\t13\r\n\tdefm\t'Compiled with Hi-Tech C'\r\n\tdefb\t13,10,26\r\n\r\n\tpsect\tdata\r\nz3ecst:\tdefm\t'Z3ENV'\r\nbvmes:\tdefm\t'This CP/M program requires a Z280 MPU.'\r\n\tdefb\t13,10,'$'\r\nmemmes:\tdefm\t'Not enough memory to run.'\r\n\tdefb\t13,10,'$'\r\n\tpsect\ttext\r\n\r\nbegin:\r\n\tsub\ta\t\t;Stop 8080 processors running this.\r\n\tjp\tpo,okver\r\n\r\nbadcpu:\tld\tde,bvmes\r\n\tld\tc,9\t\t;Print error message\r\n\tjp\t5\r\n\r\nokver:\tld\ta,40h\t\t;Check for Z280 MPU\r\n;\ttset\ta\t\t; (this instruction will set the S flag\r\n\tdefb\t0CBh,037h\r\n\tjp\tm,badcpu\t; on a Z80 and clear it on a Z280)\r\n\r\n;Check if HL holds a valid Z-System environment descriptor\r\n\r\n\tld\tl,0\t\t;Start of the page\r\n\tld\ta,(hl)\r\n\tcp\t0c3h\t\t;Must start with a jump\r\n\tjr\tnz,noz3\r\n\tld\tl,1bh\r\n\tld\ta,(hl)\t\t;Must refer to itself\r\n\tor\ta\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tld\ta,(hl)\r\n\tcp\th\r\n\tjr\tnz,noz3\r\n\tld\tl,3\t\t;Must contain the string \"Z3ENV\"\r\n\tld\tde,z3ecst\r\n\tld\tb,5\t\t;Check 5 characters\r\nz3ecmp:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tz3ecmp\r\n\tld\tl,0\r\n\tdefb\t3eh\t\t;Swallow the LD HL\r\nnoz3:\tld\thl,0\r\nyesz3:\tld\t(__z3env),hl\r\n\tld\thl,(6)\t\t;Base of FDOS\r\n\tpush\thl\r\n\tdec\th\t\t;Allow 128 stack levels at least\r\n\tld\tde,__Hbss\t;Last address used by the program\r\n\tand\ta\r\n\tsbc\thl,de\r\n\tjr\tnc,memok\r\n\tld\tde,memmes\t;Bss segment hits the BDOS.\r\n\tld\tc,9\r\n\tcall\t5\r\n\trst\t0\r\n\r\nmemok:\t\r\n\tld\tc,12\r\n\tcall\t5\t\t;Check CP/M version\r\n\tld\ta,h\r\n\tdec\ta\t\t; MP/M (H == 1) has no RSX\r\n\tjr\tz,norsx\r\n\tld\ta,l\r\n\tcp\t30h\t\t; CP/M Plus (L >= 30h)?\r\n\tjr\tnc,iscpm3\r\n\txor\ta\t\t; CP/M 2.2 has no RSX\r\n\tjr\tnorsx\r\n\r\niscpm3:\tld\thl,__exact\t; Default exact file size\r\n\tinc\t(hl)\t\t;  to DOSplus mode ('C' becomes 'D')\r\n\r\n;If the PIPEMGR RSX is loaded, initialise it.\r\n\r\n\tld\tc,60\t\t; RSX call\r\n\tld\tde,rsxpb\t; RSX data\r\n\tcall\t5\r\n\tld\ta,h\r\n\tinc\tl\t\t;HL=00FFh if no PIPEMGR present.\r\n\tor\tl\r\nnorsx:\tld\t(__piped),a\r\n\tcall\tnz,__initrsx\t;use PIPEMGR for stdin, stdout and stderr\r\n        pop\thl\t\t;base address of fdos\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Lbss\t;Start of BSS segment\r\n\tor\ta\t\t;clear carry\r\n\tld\thl,__Hbss\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,80h\t\t;argument buffer\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\t(hl),0\t\t;zero terminate it\r\n\tld\thl,81h\r\n\tpush\thl\r\n\tcall\tstartup\r\n\tpop\tbc\t\t;unjunk stack\r\n\tpop\tbc\r\n\tld\tbc,(__z3env)\t;main (argc,argv,z3env)\r\n\tpush\tbc\r\n\tpush\thl\r\n\tld\thl,(__argc_)\r\n\tpush\thl\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\trst\t0\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n__z3env:\r\n\tdefw\t0\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nrsxpb:\tdefb\t79h,1\r\n\tdefw\tpipesgn\r\npipesgn:\r\n\tdefm\t'PIPEMGR '\r\n\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/ZCRTCPM.AS",
    "content": "\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\r\n\tglobal\tstart,_main,_exit,__Hbss, __Lbss, __argc_, __z3env, startup\r\n        global  __piped,__initrsx,__exact\r\n\r\nstart:\t\t; DOS Protection\t8080/Z80\tx86\r\n\t\t\t\t;\t---------  --------------------\r\n\tdefb\t0EBh,04h\t;\tEX DE,HL   JMPS LABE\r\n\t\t\t\t;\tINC B\r\n\r\n\tex\tde,hl\t\t;\tEX DE,HL\r\n\tdefb\t0C3h\t\t;\tJP BEGIN\r\n\tdefw\tbegin\t\t; (We don't want the assembler optimising\r\n\t\t\t\t;  this to a relative branch)\r\n\r\nlabe:\tdefb\t0B8h,0,09h\t;\t\t   MOV AX,9 ; print string\r\n\r\n\tdefb\t0BAh\t\t;\t\t   MOV DX,OFFSET BVMES\r\n\tdefw\tbvmes\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\r\n\tdefb\t0B8h,01h,4Ch\t;\t\t   MOV AX,4C01h ; terminate\r\n\t\t\t\t;\t\t   ; with CTRL-BREAK code (1)\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\t\t\t\t\t\t   ; we never return here\r\n\r\n\t; Some text for viewing if typed\r\n\r\n\tdefm\t'Compiled with Hi-Tech C'\r\n\tdefb\t13,10,26\r\n\r\n\tpsect\tdata\r\nz3ecst:\tdefm\t'Z3ENV'\r\nbvmes:\tdefm\t'This CP/M program requires a Z80 CPU.'\r\n\tdefb\t13,10,'$'\r\nmemmes:\tdefm\t'Not enough memory to run.'\r\n\tdefb\t13,10,'$'\r\n\tpsect\ttext\r\n\r\nbegin:\tsub\ta\t\t;Stop 8080 processors running this.\r\n\tjp\tpo,okver\r\n\r\n\tld\tde,bvmes\r\n\tld\tc,9\t\t;Print error message\r\n\tjp\t5\r\n\r\n;Check if HL holds a valid Z-System environment descriptor\r\n\r\nokver:\tld\tl,0\t\t;Start of the page\r\n\tld\ta,(hl)\r\n\tcp\t0c3h\t\t;Must start with a jump\r\n\tjr\tnz,noz3\r\n\tld\tl,1bh\r\n\tld\ta,(hl)\t\t;Must refer to itself\r\n\tor\ta\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tld\ta,(hl)\r\n\tcp\th\r\n\tjr\tnz,noz3\r\n\tld\tl,3\t\t;Must contain the string \"Z3ENV\"\r\n\tld\tde,z3ecst\r\n\tld\tb,5\t\t;Check 5 characters\r\nz3ecmp:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tz3ecmp\r\n\tld\tl,0\r\n\tdefb\t3eh\t\t;Swallow the LD HL\r\nnoz3:\tld\thl,0\r\nyesz3:\tld\t(__z3env),hl\r\n\tld\thl,(6)\t\t;Base of FDOS\r\n\tpush\thl\r\n\tdec\th\t\t;Allow 128 stack levels at least\r\n\tld\tde,__Hbss\t;Last address used by the program\r\n\tand\ta\r\n\tsbc\thl,de\r\n\tjr\tnc,memok\r\n\tld\tde,memmes\t;Bss segment hits the BDOS.\r\n\tld\tc,9\r\n\tcall\t5\r\n\trst\t0\r\n\r\nmemok:\t\r\n\tld\tc,12\r\n\tcall\t5\t\t;Check CP/M version\r\n\tld\ta,h\r\n\tdec\ta\t\t; MP/M (H == 1) has no RSX\r\n\tjr\tz,norsx\t\t;  Z bit is set and A=0\r\n\tld\ta,l\r\n\tcp\t30h\t\t; CP/M Plus (L >= 30h)?\r\n\tjr\tnc,iscpm3\r\n\txor\ta\t\t; CP/M 2.2 has no RSX\r\n\tjr\tnorsx\t\t;  Z bit is set and A=0\r\n\r\niscpm3:\tld\thl,__exact\t; Default exact file size\r\n\tinc\t(hl)\t\t;  to DOSplus mode ('C' becomes 'D')\r\n\r\n;If the PIPEMGR RSX is loaded, initialise it.\r\n\r\n\tld\tc,60\t\t; RSX call\r\n\tld\tde,rsxpb\t; RSX data\r\n\tcall\t5\r\n\tld\ta,h\r\n\tinc\tl\t\t;HL=00FFh if no PIPEMGR present.\r\n\tor\tl\r\nnorsx:\tld\t(__piped),a\r\n\tcall\tnz,__initrsx\t;use PIPEMGR for stdin, stdout and stderr\r\n        pop\thl\t\t;base address of fdos\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Lbss\t;Start of BSS segment\r\n\tor\ta\t\t;clear carry\r\n\tld\thl,__Hbss\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,80h\t\t;argument buffer\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\t(hl),0\t\t;zero terminate it\r\n\tld\thl,81h\r\n\tpush\thl\r\n\tcall\tstartup\r\n\tpop\tbc\t\t;unjunk stack\r\n\tpop\tbc\r\n\tld\tbc,(__z3env)\t;main (argc,argv,z3env)\r\n\tpush\tbc\r\n\tpush\thl\r\n\tld\thl,(__argc_)\r\n\tpush\thl\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\trst\t0\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n__z3env:\r\n\tdefw\t0\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nrsxpb:\tdefb\t79h,1\r\n\tdefw\tpipesgn\r\npipesgn:\r\n\tdefm\t'PIPEMGR '\r\n\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/ZD280CPM.AS",
    "content": "; This is ZDRTCPM for the Z280 MPU\r\n;\r\n\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\tglobal\tstart,_main,_exit,__Hdata, __trap, __piped,__exact\r\nstart:\tld\thl,(6)\t\t;base address of fdos\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Hdata\t;end of initialized data\r\n\tscf\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,-80h\t\t;allow room for args\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tld\tbc,0\t\t;flag end of args\r\n\tpush\tbc\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tld\tc,(hl)\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\txor\ta\r\n\tpush\thl\r\n\tinc\tc\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\tpush\thl\r\n\tpush\tbc\r\n\tld\thl,__trap\r\n\tld\t(39h),hl\r\n\tld\ta,0c3h\r\n\tld\t(38h),a\r\n\trst\t38h\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\tjp\tp,0\r\n\r\n\tpsect\tdata\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nnularg:\tdefm\t'main'\r\n\tdefb\t0\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/ZDRTCPM.AS",
    "content": "\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\tglobal\tstart,_main,_exit,__Hdata, __trap, __piped, __exact\r\nstart:\tld\thl,(6)\t\t;base address of fdos\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Hdata\t;end of initialized data\r\n\tscf\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,-80h\t\t;allow room for args\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tld\tbc,0\t\t;flag end of args\r\n\tpush\tbc\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tld\tc,(hl)\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\txor\ta\r\n\tpush\thl\r\n\tinc\tc\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\tpush\thl\r\n\tpush\tbc\r\n\tld\thl,__trap\r\n\tld\t(39h),hl\r\n\tld\ta,0c3h\r\n\tld\t(38h),a\r\n\trst\t38h\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\tjp\tp,0\r\n\r\n\tpsect\tdata\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nnularg:\tdefm\t'main'\r\n\tdefb\t0\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/ZN280CPM.AS",
    "content": "; This is ZNRTCPM for the Z280 MPU (with minimal getargs)\r\n;\r\n\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\r\n\tglobal\tstart,_main,_exit,__Hbss, __Lbss, __argc_, __z3env, startup\r\n        global  __piped,__initrsx,__exact\r\n\tglobal\t__getargs\r\n\r\n;\tStart with MS-DOS x86 detection\r\nstart:\t\t; DOS Protection\t8080/Z80\tx86\r\n\t\t\t\t;\t---------  --------------------\r\n\tdefb\t0EBh,04h\t;\tEX DE,HL   JMPS LABE\r\n\t\t\t\t;\tINC B\r\n\r\n\tex\tde,hl\t\t;\tEX DE,HL\r\n\tdefb\t0C3h\t\t;\tJP BEGIN\r\n\tdefw\tbegin\t\t; (We don't want the assembler optimising\r\n\t\t\t\t;  this to a relative branch)\r\n\r\nlabe:\tdefb\t0B8h,0,09h\t;\t\t   MOV AX,9 ; print string\r\n\r\n\tdefb\t0BAh\t\t;\t\t   MOV DX,OFFSET BVMES\r\n\tdefw\tbvmes\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\r\n\tdefb\t0B8h,01h,4Ch\t;\t\t   MOV AX,4C01h ; terminate\r\n\t\t\t\t;\t\t   ; with CTRL-BREAK code (1)\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\t\t\t\t\t\t   ; we never return here\r\n\r\n\tdefb\t13\r\n\tdefm\t'Compiled with Hi-Tech C'\r\n\tdefb\t13,10,26\r\n\r\n\tpsect\tdata\r\nz3ecst:\tdefm\t'Z3ENV'\r\nbvmes:\tdefm\t'This CP/M program requires a Z280 MPU.'\r\n\tdefb\t13,10,'$'\r\nmemmes:\tdefm\t'Not enough memory to run.'\r\n\tdefb\t13,10,'$'\r\n\tpsect\ttext\r\n\r\nbegin:\r\n\tsub\ta\t\t;Stop 8080 processors running this.\r\n\tjp\tpo,okver\r\n\r\nbadcpu:\tld\tde,bvmes\r\n\tld\tc,9\t\t;Print error message\r\n\tjp\t5\r\n\r\nokver:\tld\ta,40h\t\t;Check for Z280 MPU\r\n;\ttset\ta\t\t; (this instruction will set the S flag\r\n\tdefb\t0CBh,037h\r\n\tjp\tm,badcpu\t; on a Z80 and clear it on a Z280)\r\n\r\n;Check if HL holds a valid Z-System environment descriptor\r\n\r\n\tld\tl,0\t\t;Start of the page\r\n\tld\ta,(hl)\r\n\tcp\t0c3h\t\t;Must start with a jump\r\n\tjr\tnz,noz3\r\n\tld\tl,1bh\r\n\tld\ta,(hl)\t\t;Must refer to itself\r\n\tor\ta\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tld\ta,(hl)\r\n\tcp\th\r\n\tjr\tnz,noz3\r\n\tld\tl,3\t\t;Must contain the string \"Z3ENV\"\r\n\tld\tde,z3ecst\r\n\tld\tb,5\t\t;Check 5 characters\r\nz3ecmp:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tz3ecmp\r\n\tld\tl,0\r\n\tdefb\t3eh\t\t;Swallow the LD HL\r\nnoz3:\tld\thl,0\r\nyesz3:\tld\t(__z3env),hl\r\n\tld\thl,(6)\t\t;Base of FDOS\r\n\tpush\thl\r\n\tdec\th\t\t;Allow 128 stack levels at least\r\n\tld\tde,__Hbss\t;Last address used by the program\r\n\tand\ta\r\n\tsbc\thl,de\r\n\tjr\tnc,memok\r\n\tld\tde,memmes\t;Bss segment hits the BDOS.\r\n\tld\tc,9\r\n\tcall\t5\r\n\trst\t0\r\n\r\nmemok:\t\r\n\tld\tc,12\r\n\tcall\t5\t\t;Check CP/M version\r\n\tld\ta,h\r\n\tdec\ta\t\t; MP/M (H == 1) has no RSX\r\n\tjr\tz,norsx\r\n\tld\ta,l\r\n\tcp\t30h\t\t; CP/M Plus (L >= 30h)?\r\n\tjr\tnc,iscpm3\r\n\txor\ta\t\t; CP/M 2.2 has no RSX\r\n\tjr\tnorsx\r\n\r\niscpm3:\tld\thl,__exact\t; Default exact file size\r\n\tinc\t(hl)\t\t;  to DOSplus mode ('C' becomes 'D')\r\n\r\n;If the PIPEMGR RSX is loaded, initialise it.\r\n\r\n\tld\tc,60\t\t; RSX call\r\n\tld\tde,rsxpb\t; RSX data\r\n\tcall\t5\r\n\tld\ta,h\r\n\tinc\tl\t\t;HL=00FFh if no PIPEMGR present.\r\n\tor\tl\r\nnorsx:\tld\t(__piped),a\r\n\tcall\tnz,__initrsx\t;use PIPEMGR for stdin, stdout and stderr\r\n        pop\thl\t\t;base address of fdos\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Lbss\t;Start of BSS segment\r\n\tor\ta\t\t;clear carry\r\n\tld\thl,__Hbss\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,80h\t\t;argument buffer\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\t(hl),0\t\t;zero terminate it\r\n\tld\thl,81h\r\n\tpush\thl\r\n\tcall\tstartup\r\n\tpop\tbc\t\t;unjunk stack\r\n\tpop\tbc\r\n\tld\tbc,(__z3env)\t;main (argc,argv,z3env)\r\n\tpush\tbc\r\n\tpush\thl\r\n\tld\thl,(__argc_)\r\n\tpush\thl\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\trst\t0\r\n\r\n;\r\n; This is a substitute getargs() function that is of minimal\r\n; size and does not perform wildcard argument expansion and\r\n; redirection.\r\n;\r\n\r\n__getargs:\r\n\tpop\thl\t\t;return address\r\n\texx\r\n\tpop\thl\r\n\tpop\thl\t\t;unjunk stack\r\n\tld\ta,(80h)\t\t;get buffer length\r\n\tinc\ta\t\t;allow for null byte\r\n\tneg\r\n\tld\tl,a\r\n\tld\th,-1\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tld\tbc,0\t\t;flag end of args\r\n\tpush\tbc\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tld\tc,(hl)\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\tpush\thl\r\n\tinc\tc\r\n4:\tld\ta,(de)\t\t;remove extra spaces\r\n\tcp\t' '\r\n\tjr\tnz,5f\r\n\tdec\tde\r\n\tjr\t4b\r\n5:\r\n\txor\ta\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\t(__argc_),bc\t\t;store argcount\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\texx\r\n\tpush\tde\t\t;junk the stack again\r\n\tpush\tde\r\n\tpush\thl\t\t;return address\r\n\texx\r\n\tret\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n__z3env:\r\n\tdefw\t0\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nrsxpb:\tdefb\t79h,1\r\n\tdefw\tpipesgn\r\npipesgn:\r\n\tdefm\t'PIPEMGR '\r\n\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/ZNRTCPM.AS",
    "content": "; This is ZNRTCPM for the Z80 (with minimal getargs)\r\n\r\n\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\r\n\tglobal\tstart,_main,_exit,__Hbss, __Lbss, __argc_, __z3env, startup\r\n        global  __piped,__initrsx,__exact\r\n\tglobal\t__getargs\r\n\r\nstart:\t\t; DOS Protection\t8080/Z80\tx86\r\n\t\t\t\t;\t---------  --------------------\r\n\tdefb\t0EBh,04h\t;\tEX DE,HL   JMPS LABE\r\n\t\t\t\t;\tINC B\r\n\r\n\tex\tde,hl\t\t;\tEX DE,HL\r\n\tdefb\t0C3h\t\t;\tJP BEGIN\r\n\tdefw\tbegin\t\t; (We don't want the assembler optimising\r\n\t\t\t\t;  this to a relative branch)\r\n\r\nlabe:\tdefb\t0B8h,0,09h\t;\t\t   MOV AX,9 ; print string\r\n\r\n\tdefb\t0BAh\t\t;\t\t   MOV DX,OFFSET BVMES\r\n\tdefw\tbvmes\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\r\n\tdefb\t0B8h,01h,4Ch\t;\t\t   MOV AX,4C01h ; terminate\r\n\t\t\t\t;\t\t   ; with CTRL-BREAK code (1)\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\t\t\t\t\t\t   ; we never return here\r\n\r\n\t; Some text for viewing if typed\r\n\r\n\tdefm\t'Compiled with Hi-Tech C'\r\n\tdefb\t13,10,26\r\n\r\n\tpsect\tdata\r\nz3ecst:\tdefm\t'Z3ENV'\r\nbvmes:\tdefm\t'This CP/M program requires a Z80 CPU.'\r\n\tdefb\t13,10,'$'\r\nmemmes:\tdefm\t'Not enough memory to run.'\r\n\tdefb\t13,10,'$'\r\n\tpsect\ttext\r\n\r\nbegin:\tsub\ta\t\t;Stop 8080 processors running this.\r\n\tjp\tpo,okver\r\n\r\n\tld\tde,bvmes\r\n\tld\tc,9\t\t;Print error message\r\n\tjp\t5\r\n\r\n;Check if HL holds a valid Z-System environment descriptor\r\n\r\nokver:\tld\tl,0\t\t;Start of the page\r\n\tld\ta,(hl)\r\n\tcp\t0c3h\t\t;Must start with a jump\r\n\tjr\tnz,noz3\r\n\tld\tl,1bh\r\n\tld\ta,(hl)\t\t;Must refer to itself\r\n\tor\ta\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tld\ta,(hl)\r\n\tcp\th\r\n\tjr\tnz,noz3\r\n\tld\tl,3\t\t;Must contain the string \"Z3ENV\"\r\n\tld\tde,z3ecst\r\n\tld\tb,5\t\t;Check 5 characters\r\nz3ecmp:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tz3ecmp\r\n\tld\tl,0\r\n\tdefb\t3eh\t\t;Swallow the LD HL\r\nnoz3:\tld\thl,0\r\nyesz3:\tld\t(__z3env),hl\r\n\tld\thl,(6)\t\t;Base of FDOS\r\n\tpush\thl\r\n\tdec\th\t\t;Allow 128 stack levels at least\r\n\tld\tde,__Hbss\t;Last address used by the program\r\n\tand\ta\r\n\tsbc\thl,de\r\n\tjr\tnc,memok\r\n\tld\tde,memmes\t;Bss segment hits the BDOS.\r\n\tld\tc,9\r\n\tcall\t5\r\n\trst\t0\r\n\r\nmemok:\t\r\n\tld\tc,12\r\n\tcall\t5\t\t;Check CP/M version\r\n\tld\ta,h\r\n\tdec\ta\t\t; MP/M (H == 1) has no RSX\r\n\tjr\tz,norsx\r\n\tld\ta,l\r\n\tcp\t30h\t\t; CP/M Plus (L >= 30h)?\r\n\tjr\tnc,iscpm3\r\n\txor\ta\t\t; CP/M 2.2 has no RSX\r\n\tjr\tnorsx\r\n\r\niscpm3:\tld\thl,__exact\t; Default exact file size\r\n\tinc\t(hl)\t\t;  to DOSplus mode ('C' becomes 'D')\r\n\r\n;If the PIPEMGR RSX is loaded, initialise it.\r\n\r\n\tld\tc,60\t\t; RSX call\r\n\tld\tde,rsxpb\t; RSX data\r\n\tcall\t5\r\n\tld\ta,h\r\n\tinc\tl\t\t;HL=00FFh if no PIPEMGR present.\r\n\tor\tl\r\nnorsx:\tld\t(__piped),a\r\n\tcall\tnz,__initrsx\t;use PIPEMGR for stdin, stdout and stderr\r\n        pop\thl\t\t;base address of fdos\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Lbss\t;Start of BSS segment\r\n\tor\ta\t\t;clear carry\r\n\tld\thl,__Hbss\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,80h\t\t;argument buffer\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\t(hl),0\t\t;zero terminate it\r\n\tld\thl,81h\r\n\tpush\thl\r\n\tcall\tstartup\r\n\tpop\tbc\t\t;unjunk stack\r\n\tpop\tbc\r\n\tld\tbc,(__z3env)\t;main (argc,argv,z3env)\r\n\tpush\tbc\r\n\tpush\thl\r\n\tld\thl,(__argc_)\r\n\tpush\thl\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\trst\t0\r\n;\r\n; This is a substitute getargs() function that is of minimal\r\n; size and does not perform wildcard argument expansion and\r\n; redirection.\r\n;\r\n\r\n__getargs:\r\n\tpop\thl\t\t;return address\r\n\texx\r\n\tpop\thl\r\n\tpop\thl\t\t;unjunk stack\r\n\tld\ta,(80h)\t\t;get buffer length\r\n\tinc\ta\t\t;allow for null byte\r\n\tneg\r\n\tld\tl,a\r\n\tld\th,-1\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tld\tbc,0\t\t;flag end of args\r\n\tpush\tbc\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tld\tc,(hl)\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\tpush\thl\r\n\tinc\tc\r\n4:\tld\ta,(de)\t\t;remove extra spaces\r\n\tcp\t' '\r\n\tjr\tnz,5f\r\n\tdec\tde\r\n\tjr\t4b\r\n5:\r\n\txor\ta\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\t(__argc_),bc\t\t;store argcount\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\texx\r\n\tpush\tde\t\t;junk the stack again\r\n\tpush\tde\r\n\tpush\thl\t\t;return address\r\n\texx\r\n\tret\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n__z3env:\r\n\tdefw\t0\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nrsxpb:\tdefb\t79h,1\r\n\tdefw\tpipesgn\r\npipesgn:\r\n\tdefm\t'PIPEMGR '\r\n\r\n\tend\tstart\r\n"
  },
  {
    "path": "cpm/ZR280CPM.AS",
    "content": "; This is ZRRTCPM for the Z280 MPU\r\n;\r\n\r\n;\tSelf relocating startup for CP/M\r\n\r\n\tpsect\tcpm,global\r\n\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\tpsect\tstack,global\r\n\r\n\tdefs\t256\t\t;a minimal stack\r\n\r\n\r\n\tpsect\tcpm\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\tglobal\tstart,_main,_exit,__Lbss,__Hstack, __z3env\r\n\tglobal\t__piped,__initrsx,__exact\r\n\r\nreloc:\t\t; DOS Protection\t8080/Z80\tx86\r\n\t\t\t\t;\t---------  --------------------\r\n\tdefb\t0EBh,04h\t;\tEX DE,HL   JMPS LABE\r\n\t\t\t\t;\tINC B\r\n\r\n\tex\tde,hl\t\t;\tEX DE,HL\r\n\tdefb\t0C3h\t\t;\tJP BEGIN\r\n\tdefw\tbegin\t\t; (We don't want the assembler optimising\r\n\t\t\t\t;  this to a relative branch)\r\n\r\nlabe:\tdefb\t0B8h,0,09h\t;\t\t   MOV AX,9 ; print string\r\n\r\n\tdefb\t0BAh\t\t;\t\t   MOV DX,OFFSET BVMES\r\n\tdefw\tbvmes\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\r\n\tdefb\t0B8h,01h,4Ch\t;\t\t   MOV AX,4C01h ; terminate\r\n\t\t\t\t;\t\t   ; with CTRL-BREAK code (1)\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\t\t\t\t\t\t   ; we never return here\r\n\r\n\tdefb\t13\r\n\tdefm\t'Compiled with Hi-Tech C [Relocatable]'\r\n\tdefb\t13,10,26\r\n\r\n\tpsect\tdata\r\nz3ecst:\tdefm\t'Z3ENV'\r\nbvmes:\tdefm\t'This CP/M program requires a Z80 CPU.'\r\n\tdefb\t13,10,'$'\r\nmemmes:\tdefm\t'Not enough memory to run.'\r\n\tdefb\t13,10,'$'\r\n\tpsect\tcpm\r\n\r\nbegin:\tsub\ta\t\t;Stop 8080 processors running this.\r\n\tjp\tpo,okver\r\n;\r\nbadcpu:\tld\tde,bvmes\r\n\tld\tc,9\t\t;Print error message\r\n\tjp\t5\r\n\r\nokver:\tld\ta,40h\t\t;Check for Z280 MPU\r\n;\ttset\ta\t\t; (this instruction will set the S flag\r\n\tdefb\t0CBh,037h\r\n\tjp\tm,badcpu\t; on a Z80 and clear it on a Z280)\r\n\r\n\tpush\thl\t\t;HL holds possible Z3ENV address\r\n\tld\thl,(6)\t\t;get base of fdos\r\n\tld\tde,__Hstack\r\n\tor\ta\r\n\tsbc\thl,de\t\t;get distance to move\r\n\tld\tc,l\t\t;save it in bc\r\n\tld\tb,h\r\n1:\r\n\tld\thl,(__Lbss)\t;get count\r\n\tld\ta,l\t\t;zero?\r\n\tor\th\r\n\tjr\tz,2f\r\n\tdec\thl\r\n\tld\t(__Lbss),hl\r\n\tld\thl,(addr)\t;get address\r\n\tld\te,(hl)\t\t;pick up value\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\t(addr),hl\t;save for next\r\n\tex\tde,hl\r\n\tld\t(where),hl\t;save it\r\n\tld\tde,3f\t\t;dont relocate any of our addresses\r\n\tor\ta\r\n\tsbc\thl,de\t\t;check for range\r\n\tjr\tc,1b\t\t;skip if less than 3f\r\n\tld\thl,(where)\r\n\tld\te,(hl)\t\t;get value to relocate\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tex\tde,hl\r\n\tadd\thl,bc\t\t;add difference\r\n\tex\tde,hl\r\n\tld\t(hl),d\t\t;put relocated value back\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tjr\t1b\t\t;loop for more\r\n\r\naddr:\tdefw\t__Lbss+2\t;start of addresses\r\nwhere:\tdefs\t2\t\t;temp storage\r\n\r\n2:\r\n\tld\thl,__Lbss\t;now find how much to move\r\n\tld\tde,start\r\n\tor\ta\r\n\tsbc\thl,de\r\n\tld\tc,l\t\t;save in bc\r\n\tld\tb,h\r\n\tld\thl,__Hstack\t;top of memory\r\n\tld\tde,__Lbss\t;top of code and data\r\n\tsbc\thl,de\t\t;room to leave at top of mem\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tscf\t\t\t;discount it\r\n\tsbc\thl,de\r\n\tex\tde,hl\t\t;destination into de\r\n\tld\thl,__Lbss-1\t;source in hl - count is already in bc\r\n\tld\ta,c\t\t;check for zero\r\n\tor\tb\r\n\tjr\tz,3f\r\n\tlddr\t\t\t;move it\r\n\tpop\thl\r\n3:\r\n\tjp\tstart\t\t;go to it\r\n\r\n\tpsect\ttext\r\nstart:\tld\tl,0\t\t;Start of the page\r\n\tld\ta,(hl)\r\n\tcp\t0c3h\t\t;Must start with a jump\r\n\tjr\tnz,noz3\r\n\tld\tl,1bh\r\n\tld\ta,(hl)\t\t;Must refer to itself\r\n\tor\ta\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tld\ta,(hl)\r\n\tcp\th\r\n\tjr\tnz,noz3\r\n\tld\tl,3\t\t;Must contain the string \"Z3ENV\"\r\n\tld\tde,z3ecst\r\n\tld\tb,5\t\t;Check 5 characters\r\nz3ecmp:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tz3ecmp\r\n\tld\tl,0\r\n\tdefb\t3eh\t\t;Swallow the LD HL\r\nnoz3:\tld\thl,0\r\nyesz3:\tld\t(__z3env),hl\r\n;\r\nmemok:\t\r\n \r\n\tld\tc,12\r\n \tcall    5\t\t;Check CP/M version\r\n\tld\ta,h\r\n\tdec\ta\t\t; MP/M (H == 1) has no RSX\r\n\tjr\tz,norsx\r\n\tld\ta,l\r\n\tcp\t30h\t\t; CP/M Plus (L >= 30h)?\r\n \tjr\tnc,iscpm3\r\n \txor\ta\t\t; CP/M 2.2 has no RSX\r\n \tjr\tnorsx\r\n\r\niscpm3:\tld\thl,__exact\t; Default exact file size\r\n\tinc\t(hl)\t\t;  to DOSplus mode ('C' becomes 'D')\r\n\r\n;If the PIPEMGR RSX is loaded, initialise it.\r\n\r\n\tld\tc,3Ch\r\n\tld\tde,rsxpb\r\n\tcall\t5\r\n\tld\ta,h\r\n\tinc\tl\t;HL=00FFh if no PIPEMGR present.\r\n\tor\tl\r\nnorsx:\r\n\tld\t(__piped),a\r\n\tcall\tnz,__initrsx\t;use PIPEMGR for stdin, stdout and stderr\r\n\tld\thl,(6)\t\t;base address of fdos\r\n\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Lbss\t;end of initialized data\r\n\tscf\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,80h\t\t;arg buf\r\n\tld\tc,(hl)\t\t;size of buffer\r\n\tld\tb,0\r\n\tld\thl,0\r\n\tscf\t\t\t;one for the road\r\n\tsbc\thl,bc\t\t;negate it\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tld\tde,0\t\t;flag end of args\r\n\tpush\tde\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tadd\thl,bc\t\t;bc has size of arg buffer\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\txor\ta\r\n\tpush\thl\r\n\tinc\tc\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\tpush\thl\r\n\tpush\tbc\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\tjp\tp,0\r\n\r\n\tpsect\tdata\r\nnularg:\tdefm\t'main'\r\n\tdefb\t0\r\n__z3env:\r\n\tdefw\t0\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nrsxpb:\tdefb\t79h,1\r\n\tdefw\tpipesgn\r\npipesgn:\r\n\tdefm\t'PIPEMGR '\r\n\r\n\tend\treloc\r\n"
  },
  {
    "path": "cpm/ZRRTCPM.AS",
    "content": ";\tSelf relocating startup for CP/M\r\n\r\n\tpsect\tcpm,global\r\n\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\tpsect\tstack,global\r\n\r\n\tdefs\t256\t\t;a minimal stack\r\n\r\n\r\n\tpsect\tcpm\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\tglobal\tstart,_main,_exit,__Lbss,__Hstack, __z3env\r\n\tglobal\t__piped,__initrsx,__exact\r\n\r\n\r\nreloc:\t\t; DOS Protection\t8080/Z80\tx86\r\n\t\t\t\t;\t---------  --------------------\r\n\tdefb\t0EBh,04h\t;\tEX DE,HL   JMPS LABE\r\n\t\t\t\t;\tINC B\r\n\r\n\tex\tde,hl\t\t;\tEX DE,HL\r\n\tdefb\t0C3h\t\t;\tJP BEGIN\r\n\tdefw\tbegin\t\t; (We don't want the assembler optimising\r\n\t\t\t\t;  this to a relative branch)\r\n\r\nlabe:\tdefb\t0B8h,0,09h\t;\t\t   MOV AX,9 ; print string\r\n\r\n\tdefb\t0BAh\t\t;\t\t   MOV DX,OFFSET BVMES\r\n\tdefw\tbvmes\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\r\n\tdefb\t0B8h,01h,4Ch\t;\t\t   MOV AX,4C01h ; terminate\r\n\t\t\t\t;\t\t   ; with CTRL-BREAK code (1)\r\n\r\n\tdefb\t0CDh,021h\t;\t\t   INT 21h  ; call DOS\r\n\t\t\t\t\t\t   ; we never return here\r\n\r\n\tdefb\t13\r\n\tdefm\t'Compiled with Hi-Tech C [Relocatable]'\r\n\tdefb\t13,10,26\r\n\r\n\tpsect\tdata\r\nz3ecst:\tdefm\t'Z3ENV'\r\nbvmes:\tdefm\t'This CP/M program requires a Z80 CPU.'\r\n\tdefb\t13,10,'$'\r\nmemmes:\tdefm\t'Not enough memory to run.'\r\n\tdefb\t13,10,'$'\r\n\tpsect\tcpm\r\n\r\nbegin:\tsub\ta\t\t;Stop 8080 processors running this.\r\n\tjp\tpo,okver\r\n;\r\n\tld\tde,bvmes\r\n\tld\tc,9\t\t;Print error message\r\n\tjp\t5\r\n\r\nokver:\t\r\n\tpush\thl\t\t;HL holds possible Z3ENV address\r\n\tld\thl,(6)\t\t;get base of fdos\r\n\tld\tde,__Hstack\r\n\tor\ta\r\n\tsbc\thl,de\t\t;get distance to move\r\n\tld\tc,l\t\t;save it in bc\r\n\tld\tb,h\r\n1:\r\n\tld\thl,(__Lbss)\t;get count\r\n\tld\ta,l\t\t;zero?\r\n\tor\th\r\n\tjr\tz,2f\r\n\tdec\thl\r\n\tld\t(__Lbss),hl\r\n\tld\thl,(addr)\t;get address\r\n\tld\te,(hl)\t\t;pick up value\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\t(addr),hl\t;save for next\r\n\tex\tde,hl\r\n\tld\t(where),hl\t;save it\r\n\tld\tde,3f\t\t;dont relocate any of our addresses\r\n\tor\ta\r\n\tsbc\thl,de\t\t;check for range\r\n\tjr\tc,1b\t\t;skip if less than 3f\r\n\tld\thl,(where)\r\n\tld\te,(hl)\t\t;get value to relocate\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tex\tde,hl\r\n\tadd\thl,bc\t\t;add difference\r\n\tex\tde,hl\r\n\tld\t(hl),d\t\t;put relocated value back\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tjr\t1b\t\t;loop for more\r\n\r\naddr:\tdefw\t__Lbss+2\t;start of addresses\r\nwhere:\tdefs\t2\t\t;temp storage\r\n\r\n2:\r\n\tld\thl,__Lbss\t;now find how much to move\r\n\tld\tde,start\r\n\tor\ta\r\n\tsbc\thl,de\r\n\tld\tc,l\t\t;save in bc\r\n\tld\tb,h\r\n\tld\thl,__Hstack\t;top of memory\r\n\tld\tde,__Lbss\t;top of code and data\r\n\tsbc\thl,de\t\t;room to leave at top of mem\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tscf\t\t\t;discount it\r\n\tsbc\thl,de\r\n\tex\tde,hl\t\t;destination into de\r\n\tld\thl,__Lbss-1\t;source in hl - count is already in bc\r\n\tld\ta,c\t\t;check for zero\r\n\tor\tb\r\n\tjr\tz,3f\r\n\tlddr\t\t\t;move it\r\n\tpop\thl\r\n3:\r\n\tjp\tstart\t\t;go to it\r\n\r\n\tpsect\ttext\r\nstart:\tld\tl,0\t\t;Start of the page\r\n\tld\ta,(hl)\r\n\tcp\t0c3h\t\t;Must start with a jump\r\n\tjr\tnz,noz3\r\n\tld\tl,1bh\r\n\tld\ta,(hl)\t\t;Must refer to itself\r\n\tor\ta\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tld\ta,(hl)\r\n\tcp\th\r\n\tjr\tnz,noz3\r\n\tld\tl,3\t\t;Must contain the string \"Z3ENV\"\r\n\tld\tde,z3ecst\r\n\tld\tb,5\t\t;Check 5 characters\r\nz3ecmp:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,noz3\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tz3ecmp\r\n\tld\tl,0\r\n\tdefb\t3eh\t\t;Swallow the LD HL\r\nnoz3:\tld\thl,0\r\nyesz3:\tld\t(__z3env),hl\r\n;\r\nmemok:\t\r\n \r\n\tld\tc,12\r\n \tcall    5\t\t;Check CP/M version\r\n\tld\ta,h\r\n\tdec\ta\t\t; MP/M (H == 1) has no RSX\r\n\tjr\tz,norsx\r\n\tld\ta,l\r\n\tcp\t30h\t\t; CP/M Plus (L >= 30h)?\r\n\tjr\tnc,iscpm3\r\n \txor\ta\t\t; CP/M 2.2 has no RSX\r\n \tjr\tnorsx\r\n\r\n    ;If the PIPEMGR RSX is loaded, initialise it.\r\niscpm3:\r\n\tld\tc,3Ch\r\n\tld\tde,rsxpb\r\n\tcall\t5\r\n\tld\ta,h\r\n\tinc\tl\t\t;HL=00FFh if no PIPEMGR present.\r\n\tor\tl\r\nnorsx:\r\n\tld\t(__piped),a\r\n\tcall\tnz,__initrsx\t;use PIPEMGR for stdin, stdout and stderr\r\n\tld\thl,(6)\t\t;base address of fdos\r\n\r\n\tld\tsp,hl\t\t;stack grows downwards\r\n\tld\tde,__Lbss\t;end of initialized data\r\n\tscf\r\n\tsbc\thl,de\t\t;size of uninitialized data area\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tdec\tbc\t\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,80h\t\t;arg buf\r\n\tld\tc,(hl)\t\t;size of buffer\r\n\tld\tb,0\r\n\tld\thl,0\r\n\tscf\t\t\t;one for the road\r\n\tsbc\thl,bc\t\t;negate it\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tld\tde,0\t\t;flag end of args\r\n\tpush\tde\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tadd\thl,bc\t\t;bc has size of arg buffer\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tld\thl,(6)\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\txor\ta\r\n\tpush\thl\r\n\tinc\tc\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\tpush\thl\r\n\tpush\tbc\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\tjp\tp,0\r\n\r\n\tpsect\tdata\r\nnularg:\tdefm\t'main'\r\n\tdefb\t0\r\n__z3env:\r\n\tdefw\t0\r\n__piped:\r\n        defw    0\r\n__exact:\t\t; Exact file size mode\r\n\tdefb\t'C',0\t; 'C' is CP/M 2 (none), 'I' is ISIS, 'D' is DOSPLUS\r\nrsxpb:\tdefb\t79h,1\r\n\tdefw\tpipesgn\r\npipesgn:\r\n\tdefm\t'PIPEMGR '\r\n\r\n\tend\treloc\r\n"
  },
  {
    "path": "cpm/_EXIT.AS",
    "content": "EXITSTS\tequ\t80h\t\t;where to store exit status [CP/M 2]\r\n\r\nBDOS\tequ\t00005h\r\n\r\nCPMVERS\tequ\t12\t\t; Get CP/M Version number\r\nCPMRCOD\tequ\t108\t\t; CP/M+ Get/Set Error Return Code \r\n\r\n\tglobal\t__exit, __cpm_clean\r\n\r\n\tpsect\ttext\r\n__exit:\r\n\tcall\t__cpm_clean\r\n\tpop\thl\t\t;return address\r\n\tld\tc,CPMVERS\r\n\tcall\tBDOS\t\t;Get version\r\n\tdec\th\t\t;sets Z flag if MP/M\r\n\tpop\thl\t\t;exit status\r\n\tjp\tz,0\t\t;Warm boot if MP/M\r\n\tcp\t30h\t      \r\n\tld\t(EXITSTS),hl\r\n\tjp\tc,0\t\t;Warm boot CP/M if < CP/M 3\r\n\tld\ta,l\t\t;For compatibility with conditionals system,\r\n\t\t\t\t;use 7-bit CP/M 3 error codes.\r\n\tand\t7fh\r\n\tld\te,a\r\n\tld\ta,h\t\t;Set D=0FFh for error\r\n\tor\tl\t\t;or 0 for all clear.\r\n\tjr\tz,exit0\r\n\tld\ta,0ffh\r\nexit0:\tld\td,a\r\n\tld\tc,CPMRCOD\r\n\tcall\tBDOS\t\t;Report error.\r\n\trst\t0\r\n\r\n\tend\r\n"
  },
  {
    "path": "dist/ASSERT.H",
    "content": "#ifndef _HTC_ASSERT_H\r\n#define _HTC_ASSERT_H\r\n\r\n/*\r\n *\tAssertion - use liberally for debugging. Defining NDEBUG\r\n *\tturns assertions off.\r\n *\tassert(exp) where exp is non-zero does nothing, while\r\n *\tassert(exp) where exp evaluates to zero aborts the program\r\n *\twith a message like\r\n *\r\n *\tAssertion failed: prog.c line 123: \"exp\"\r\n *\r\n */\r\n\r\n#ifndef\tNDEBUG\r\nextern void\t_fassert(int, char *, char *);\r\n#define\tassert(exp)\tif(!(exp)) {_fassert(__LINE__, __FILE__, \"exp\");}\r\n#else\r\n#define\tassert(exp)\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/CONIO.H",
    "content": "#ifndef _HTC_CONIO_H\r\n#define _HTC_CONIO_H\r\n\r\n/*\r\n *\tLow-level console I/O functions\r\n */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\nextern char\tgetch(void);\r\nextern char\tgetche(void);\r\nextern void\tputch(int);\r\nextern void\tungetch(int);\r\nextern int\tkbhit(void);\r\nextern char *\tcgets(char *);\r\nextern void\tcputs(char *);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/CPM.H",
    "content": "#ifndef _HTC_CPM_H\r\n#define _HTC_CPM_H\r\n\r\n/* Header file for CP/M routines for Z-80 C */\r\n\r\n/* get basic definitions */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n#endif\t_STDDEF\r\n\r\n/*\thitech.h has definitions for uchar, ushort etc */\r\n\r\n#include\t<hitech.h>\r\n#if\tz80\r\n#define\tMAXFILE\t\t8\t/* max number of files open */\r\n#else\tz80\r\n#define\tMAXFILE\t\t15\t/* max number of files open */\r\n#endif\tz80\r\n#define\tSECSIZE\t\t128\t/* no. of bytes per sector */\r\n\r\nextern struct\tfcb\r\n{\r\n    uchar\tdr;\t\t/*  0: drive code */\r\n    char\tname[8];\t/*  1: file name */\r\n    char\tft[3];\t\t/*  9: file type */\r\n    uchar\tex;\t\t/* 12: file extent */\r\n    char\tfil[2];\t\t/* 13: not used */\r\n    char\trc;\t\t/* 15: number of records in present extent */\r\n    char\tdm[16];\t\t/* 16: CP/M disk map */\r\n    char\tnr;\t\t/* 32: next record to read or write */\r\n    uchar\tranrec[3];\t/* 35: random record number (24 bit no.) */\r\n    long\trwp;\t\t/* 38: read/write pointer in bytes */\r\n    uchar\tuse;\t\t/* 42: use flag */\r\n    uchar\tuid;\t\t/* 43: user id belonging to this file */\r\n    long\tfsize;\t\t/* 44: file length in bytes */\r\n}  _fcb[MAXFILE];\r\n\r\nextern short\t   bdos(int, ...);\r\n#define bdoshl\t   bdos\r\n#define bdose\t   bdos\r\nextern struct fcb* getfcb(void);\r\nextern char *      fcbname(short i);\r\nextern short\t   getuid(void);\r\nextern short\t   setuid(short);\r\nextern uchar\t   setfcb(struct fcb *, char *);\r\nextern char\t*  (*_passwd)(struct fcb *);\r\nextern short\t   bios(short fn, ...);\r\n#define bios3 bios\r\n\r\n/*   flag values in fcb use */\r\n\r\n#define\tU_READ\t1\t\t/* file open for reading */\r\n#define\tU_WRITE\t2\t\t/* file open for writing */\r\n#define\tU_RDWR\t3\t\t/* open for read and write */\r\n#define\tU_CON\t4\t\t/* device is console */\r\n#define\tU_RDR\t5\t\t/* device is reader */\r\n#define\tU_PUN\t6\t\t/* device is punch */\r\n#define\tU_LST\t7\t\t/* list device */\r\n#define U_RSX   8               /* PIPEMGR RSX */\r\n#define U_ERR   9               /* PIPEMGR stderr channel */\r\n\r\n/*\tspecial character values */\r\n\r\n#define\tCPMETX\t032\t\t/* ctrl-Z, CP/M end of file for text */\r\n#define\tCPMRBT\t003\t\t/* ctrl-C, reboot CPM */\r\n\r\n/*\toperating systems\t*/\r\n\r\n#define\tMPM\t0x100\t\t/* bit to test for MP/M */\r\n#define\tCCPM\t0x400\t\t/* bit to test for CCP/M */\r\n\r\n#define\tISMPM()\t(bdoshl(CPMVERS)&MPM)\t/* macro to test for MPM */\r\n\r\n/*\t what to do after you hit return */\r\n\r\n#define\tEXIT\t(*(int (*)())0)\t/* where to go to reboot CP/M */\r\n\r\n/*\t BDOS calls etc. */\r\n\r\n#define\tCPMRCON   1\t\t/* read console */\r\n#define\tCPMWCON   2\t\t/* write console */\r\n#define\tCPMRRDR   3\t\t/* read reader */\r\n#define\tCPMWPUN   4\t\t/* write punch */\r\n#define\tCPMWLST   5\t\t/* write list */\r\n#define\tCPMDCIO   6\t\t/* direct console I/O */\r\n#define\tCPMGIOB   7\t\t/* get I/O byte */\r\n#define\tCPMSIOB   8\t\t/* set I/O byte */\r\n#define\tCPMWCOB\t  9\t\t/* write console buffered */\r\n#define\tCPMRCOB  10\t\t/* read console buffered */\r\n#define\tCPMICON\t 11\t\t/* interrogate console ready */\r\n#define\tCPMVERS  12\t\t/* return version number */\r\n#define\tCPMRDS   13\t\t/* reset disk system */\r\n#define\tCPMLGIN\t 14\t\t/* log in and select disk */\r\n#define\tCPMOPN\t 15\t\t/* open file */\r\n#define\tCPMCLS\t 16\t\t/* close file */\r\n#define\tCPMFFST\t 17\t\t/* find first */\r\n#define\tCPMFNXT\t 18\t\t/* find next */\r\n#define\tCPMDEL\t 19\t\t/* delete file */\r\n#define\tCPMREAD\t 20\t\t/* read next record */\r\n#define\tCPMWRIT\t 21\t\t/* write next record */\r\n#define\tCPMMAKE\t 22\t\t/* create file */\r\n#define\tCPMREN\t 23\t\t/* rename file */\r\n#define\tCPMILOG\t 24\t\t/* get bit map of logged in disks */\r\n#define\tCPMIDRV\t 25\t\t/* interrogate drive number */\r\n#define\tCPMSDMA\t 26\t\t/* set DMA address for i/o */\r\n#define CPMGALL  27\t\t/* get allocation vector address */\r\n#define CPMWPRD  28\t\t/* write protect disk */\r\n#define CPMGROV  29\t\t/* get read-only vector */\r\n#define CPMSATT  30\t\t/* set file attributes */\r\n#define CPMDPB\t 31\t\t/* get disk parameter block */\r\n#define\tCPMSUID\t 32\t\t/* set/get user id */\r\n#define\tCPMRRAN\t 33\t\t/* read random record */\r\n#define\tCPMWRAN\t 34\t\t/* write random record */\r\n#define\tCPMCFS\t 35\t\t/* compute file size */\r\n#define CPMSRAN  36\t\t/* set random record */\r\n#define CPMRDRV  37\t\t/* reset drive */\r\n#define CPMACDV  38\t\t/* MP/M access drive */\r\n#define CPMFRDV  39\t\t/* MP/M free drive */\r\n#define CPMWRZF  40\t\t/* write random with zero fill */\r\n#define CPMTWR   41\t\t/* MP/M test and write record */\r\n#define CPMLOKR  42\t\t/* MP/M lock record */\r\n#define CPMUNLR  43\t\t/* MP/M unlock record */\r\n#define CPMSMSC  44\t\t/* CP/M+ set multi-sector count */\r\n#define CPMERRM  45\t\t/* CP/M+ set BDOS error mode */\r\n#define CPMDFS   46\t\t/* CP/M+ get disk free space */\r\n#define CPMCHN   47\t\t/* CP/M+ chain to program */\r\n#define CPMFLSH  48\t\t/* CP/M+ flush buffers */\r\n#define CPMGZSD  48\t\t/* ZSDOS get ZSDOS/ZDDOS version */\r\n#define CPMSCB\t 49\t\t/* access CP/M+ system control block */\r\n#define CPMBIOS  50\t\t/* CP/M+ direct BIOS call */\r\n#define\tCPMDSEG\t 51\t\t/* set DMA segment */\r\n#define CPMGFTM  54\t\t/* Z80DOS/ZPM3 get file time-stamp */\r\n#define CPMSFTM  55\t\t/* Z80DOS/ZPM3 set file time-stamp */\r\n#define CPMLDOV  59\t\t/* CP/M+ Load Overlay - requires LOADER RSX */\r\n#define CPMRSX\t 60\t\t/* CP/M+ call RSX */\r\n#define CPMLGI   64\t\t/* CP/Net login */\r\n#define CPMLGO   65\t\t/* CP/Net logout */\r\n#define CPMSMSG  66\t\t/* CP/Net send message */\r\n#define CPMRMSG  67\t\t/* CP/Net receive message */\r\n#define CPMNETS  68\t\t/* CP/Net get network status */\r\n#define CPMGCFT  69\t\t/* CP/Net get configuration table address */\r\n#define CPMSCAT  70\t\t/* CP/Net set compatibility attributes */\r\n#define CPMGSVC  71\t\t/* CP/Net get server configuration */\r\n#define CPMFRBL  98\t\t/* CP/M+ free blocks */\r\n#define CPMTRNC  99\t\t/* CP/M+ truncate file */\r\n#define CPMSLBL 100\t\t/* CP/M+ set directory label */\r\n#define CPMDLD  101\t\t/* CP/M+ get directory label data */\r\n#define CPMGFTS 102\t\t/* CP/M+ get file timestamp and password mode */\r\n#define CPMWXFC 103\t\t/* CP/M+ write file XFCB */\r\n#define CPMSDAT 104\t\t/* CP/M+ set date and time */\r\n#define CPMGDAT 105\t\t/* CP/M+ get date and time */\r\n#define CPMSPWD 106\t\t/* CP/M+ set default password */\r\n#define CPMGSER 107\t\t/* CP/M+ get serial number */\r\n#define CPMRCOD 108\t\t/* CP/M+ get/set return code */\r\n#define CPMCMOD 109\t\t/* CP/M+ get/set console mode */\r\n#define CPMODEL 110\t\t/* CP/M+ get/set output delimiter */\r\n#define CPMPBLK 111\t\t/* CP/M+ print block */\r\n#define CPMLBLK 112\t\t/* CP/M+ list block */\r\n#define CPMPARS 152\t\t/* CP/M+ parse filename */\r\n\r\n/* CP/M BIOS functions.  Numbers above 16 pertain to CP/M 3 only.  */\r\n\r\nenum BIOSfns\r\n{\r\n    _BOOT\t=  0,\r\n    _WBOOT\t=  1,\r\n\r\n    _CONST\t=  2,\r\n    _CONIN\t=  3,\r\n    _CONOUT\t=  4,\r\n    _LIST\t=  5,\r\n    _PUNOUT\t=  6,\t/* CP/M 2.2 name */\r\n    _AUXOUT\t=  6,\t/* CP/M 3.1 name */\r\n    _RDRIN\t=  7,\t/* CP/M 2.2 name */\r\n    _AUXIN\t=  7,\t/* CP/M 3.1 name */\r\n    _LISTST\t= 15,\r\n    _CONOST\t= 17,\r\n    _AUXIST\t= 18,\r\n    _AUXOST\t= 19,\r\n\r\n    _DEVTBL\t= 20,\r\n    _DEVINI\t= 21,\r\n    _DRVTBL\t= 22,\r\n\r\n    _HOME\t=  8,\r\n    _SELDSK\t=  9,\r\n    _SETTRK\t= 10,\r\n    _SETSEC\t= 11,\r\n    _SETDMA\t= 12,\r\n    _READ\t= 13,\r\n    _WRITE\t= 14,\r\n    _SECTRN\t= 16,\r\n    _MULTIO\t= 23,\r\n    _FLUSH\t= 24,\r\n\r\n    _MOVE\t= 25,\r\n    _SELMEM\t= 27,\r\n    _SETBNK\t= 28,\r\n    _XMOVE\t= 29,\r\n\r\n    _TIME\t= 26,\r\n    _USERF\t= 30\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/CTYPE.H",
    "content": "#ifndef _HTC_CTYPE_H\r\n#define _HTC_CTYPE_H\r\n\r\n#define\t_U\t0x01\r\n#define\t_L\t0x02\r\n#define\t_N\t0x04\r\n#define\t_S\t0x08\r\n#define _P\t0x10\r\n#define _C\t0x20\r\n#define\t_X\t0x40\r\n\r\nextern\tunsigned char\t_ctype_[];\t/* in libc.lib */\r\n\r\n#define\tisalpha(c)\t((_ctype_+1)[c]&(_U|_L))\r\n#define\tisupper(c)\t((_ctype_+1)[c]&_U)\r\n#define\tislower(c)\t((_ctype_+1)[c]&_L)\r\n#define\tisdigit(c)\t((_ctype_+1)[c]&_N)\r\n#define\tisxdigit(c)\t((_ctype_+1)[c]&(_N|_X))\r\n#define\tisspace(c)\t((_ctype_+1)[c]&_S)\r\n#define ispunct(c)\t((_ctype_+1)[c]&_P)\r\n#define isalnum(c)\t((_ctype_+1)[c]&(_U|_L|_N))\r\n#define isprint(c)\t((_ctype_+1)[c]&(_P|_U|_L|_N|_S))\r\n#define isgraph(c)\t((_ctype_+1)[c]&(_P|_U|_L|_N))\r\n#define iscntrl(c)\t((_ctype_+1)[c]&_C)\r\n#define isascii(c)\t(!((c)&0xFF80))\r\n/*--------------------------------------*\\\r\n |    Changed  2014-07-04 (Jon Saxton)\t|\r\n |--------------------------------------|\r\n |\tOriginal macro definitions\t|\r\n | #define toupper(c)\t((c)-'a'+'A')\t|\r\n | #define tolower(c)\t((c)-'A'+'a')\t|\r\n |--------------------------------------|\r\n |\t  Use functions instead\t\t|\r\n\\*--------------------------------------*/\r\nextern int toupper(int);\t/* in LIBC.LIB */\r\nextern int tolower(int);\t/* in LIBC.LIB */\r\n\r\n#define toascii(c)\t((c)&0x7F)\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/EXEC.H",
    "content": "#ifndef _HTC_EXEC_H\r\n#define _HTC_EXEC_H\r\n\r\n/*\r\n *\tDefinitions of the EXEC format\r\n */\r\n\r\n#define\tEXITIT\t0x80\r\n#define\tEXEC\t0x81\r\n#define\tIGN_ERR\t0x82\r\n#define\tDEF_ERR\t0x83\r\n#define\tSKP_ERR\t0x84\r\n#define\tTRAP\t0x85\r\n#define\tIF_ERR\t0x86\r\n#define\tIF_NERR\t0x87\r\n#define\tECHO\t0x88\r\n#define\tPRINT\t0x89\r\n#define\tRM_FILE\t0x8A\r\n#define\tRM_EXIT\t0x8B\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/FLOAT.H",
    "content": "#ifndef _HTC_FLOAT_H\r\n#define _HTC_FLOAT_H\r\n\r\n/*\tCharacteristics of floating types */\r\n\r\n#define\tDBL_RADIX\t2\t\t/* radix of exponent for a double */\r\n#define\tDBL_ROUNDS\t1\t\t/* doubles round when converted to int */\r\n#define\tFLT_RADIX\t2\t\t/* radix of float exponent */\r\n#define\tFLT_ROUNDS\t1\t\t/* float also rounds to int */\r\n\r\n#if\tz80\r\n#define\tFLT_MANT_DIG\t24\t\t/* 24 bits in mantissa */\r\n#define\tDBL_MANT_DIG\t24\t\t/* ditto for double */\r\n#define\tDBL_MANT_DIG\t24\t\t/* ditto long double */\r\n#define\tFLT_EPSILON\t-1.192093\t/* smallest x, x+1.0 != 1.0 */\r\n#define\tDBL_EPSILON\t-1.192093\t/* smallest x, x+1.0 != 1.0 */\r\n#define\tFLT_DIG\t\t6\t\t/* decimal significant digs */\r\n#define\tDBL_DIG\t\t6\r\n#define\tFLT_MIN_EXP\t-62\t\t/* min binary exponent */\r\n#define\tDBL_MIN_EXP\t-62\r\n#define\tFLT_MIN\t\t1.084202e-19\t/* smallest floating number */\r\n#define\tDBL_MIN\t\t1.084202e-19\r\n#define\tFLT_MIN_10_EXP\t-18\r\n#define\tDBL_MIN_10_EXP\t-18\r\n#define\tFLT_MAX_EXP\t64\t\t/* max binary exponent */\r\n#define\tDBL_MAX_EXP\t64\r\n#define\tFLT_MAX\t\t1.84467e19\t/* max floating number */\r\n#define\tDBL_MAX\t\t1.84467e19\r\n#define\tFLT_MAX_10_EXP\t19\t\t/* max decimal exponent */\r\n#define\tDBL_MAX_10_EXP\t19\r\n#endif\tz80\r\n\r\n#if\ti8086 || m68k\r\n\r\n/*\tThe 8086 and 68000 use IEEE 32 and 64 bit floats */\r\n\r\n#define\tFLT_RADIX\t2\r\n#define\tFLT_MANT_DIG\t24\r\n#define\tFLT_EPSILON\t1.19209290e-07\r\n#define\tFLT_DIG\t\t6\r\n#define\tFLT_MIN_EXP\t-125\r\n#define\tFLT_MIN\t\t1.17549435e-38\r\n#define\tFLT_MIN_10_EXP\t-37\r\n#define\tFLT_MAX_EXP\t128\r\n#define\tFLT_MAX\t\t3.40282347e+38\r\n#define\tFLT_MAX_10_EXP\t38\r\n#define\tDBL_MANT_DIG\t53\r\n#define\tDBL_EPSILON\t2.2204460492503131e-16\r\n#define\tDBL_DIG\t\t15\r\n#define\tDBL_MIN_EXP\t-1021\r\n#define\tDBL_MIN\t\t2.225073858507201e-308\r\n#define\tDBL_MIN_10_EXP\t-307\r\n#define\tDBL_MAX_EXP\t1024\r\n#define\tDBL_MAX\t\t1.797693134862316e+308\r\n#define\tDBL_MAX_10_EXP\t308\r\n#endif\ti8086 || m68k\r\n\r\n\r\n/*\tlong double equates to double */\r\n\r\n\r\n#define\tLDBL_MANT_DIG\tDBL_MANT_DIG\r\n#define\tLDBL_EPSILON\tDBL_EPSILON\r\n#define\tLDBL_DIG\tDBL_DIG\r\n#define\tLDBL_MIN_EXP\tDBL_MIN_EXP\r\n#define\tLDBL_MIN\tDBL_MIN\r\n#define\tLDBL_MIN_10_EXP\tDBL_MIN_10_EXP\r\n#define\tLDBL_MAX_EXP\tDBL_MAX_EXP\r\n#define\tLDBL_MAX\tDBL_MAX\r\n#define\tLDBL_MAX_10_EXP\tDBL_MAX_10_EXP\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/HITECH.H",
    "content": "#ifndef _HTC_HITECH_H\r\n#define _HTC_HITECH_H\r\n\r\n/*\tStandard types for HI-TECH Software code\r\n\tThese types may need to be tuned for different\r\n\tmachines/compilers. Notes with each one indicate assumptions\r\n\tthat should be maintained for each type.\r\n */\r\n\r\n\r\n/*\r\n\tTurn ANSI on if the compiler supports function prototypes and\r\n\thas the ANSI header files\r\n\t\t<stdlib.h>\r\n\t\t<string.h>\r\n */\r\n\r\n#if\tHI_TECH_C\r\n#define\tANSI\t1\r\n#endif\tHI_TECH_C\r\n\r\n/*\tshorthand types */\r\n\r\n#define\tuchar\tunsigned char\r\n#define\tulong\tunsigned long\r\n#define\tushort\tunsigned short\r\n\r\n/* useful, tuneable types. Change only if:\r\n\r\n\t1) compiler does not support type, e.g. unsigned char.\r\n\t2) compiler generates bad code for a particular type.\r\n\t3) a larger type would generate faster code, e.g. byte counters\r\n\t   on the 65816 are inefficient code-wise.\r\n */\r\n\r\n#define\tBOOL\tunsigned char\t\t/* boolean variable. Any integral type\r\n\t\t\t\t\t   will do. */\r\n#define\tFAST\tchar\t\t\t/* fast, small counter. Must permit\r\n\t\t\t\t\t   values -128 to 127 but may be larger. */\r\n#define\tUFAST\tunsigned char\t\t/* fast, small unsigned counter. Must\r\n\t\t\t\t\t   permit values 0-255 at least */\r\n#define\tBYTE\tunsigned char\t\t/* sizeof(BYTE) must == 1 */\r\n#define\tINT_16\tshort\t\t\t/* signed, >= 16 bits */\r\n#define\tUINT_16\tunsigned short\t\t/* unsigned, >= 16 bits */\r\n#define\tINT_32\tlong\t\t\t/* signed, >= 32 bits */\r\n#define\tUINT_32\tunsigned long\t\t/* unsigned, >= 32 bits */\r\n\r\n\r\n/*\tRegister variable selectors; REG1 is for things that must go\r\n\tin registers at all costs, REG2 for things that should, REG3 for\r\n\tthings that could go in registers if there are any left over.\r\n\tOrdering of declarations will of course come into it too.\r\n */\r\n\r\n#if\tz80\t\t/* only has one register variable */\r\n#define\tREG1\tregister\r\n#define\tREG2\tauto\r\n#define\tREG3\tauto\r\n#endif\tz80\r\n\r\n#if\ti8086\t\t/* only has two register variable */\r\n#define\tREG1\tregister\r\n#define\tREG2\tregister\r\n#define\tREG3\tauto\r\n#endif\ti8086\r\n\r\n#if\ti8096 || m68k\t/* lots of registers! */\r\n#define\tREG1\tregister\r\n#define\tREG2\tregister\r\n#define\tREG3\tregister\r\n#endif\ti8096 || m68k\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/LIMITS.H",
    "content": "#ifndef _HTC_LIMITS_H\r\n#define _HTC_LIMITS_H\r\n\r\n/*\tCharacteristics of integral types */\r\n\r\n#define\tCHAR_BIT\t8\t\t/* bits per char */\r\n#define\tCHAR_MAX\t127\t\t/* max value of a char */\r\n#define\tCHAR_MIN\t-128\t\t/* min value */\r\n#define\tSCHAR_MAX\tCHAR_MAX\t/* chars are signed */\r\n#define\tSCHAR_MIN\tCHAR_MIN\r\n#define\tUCHAR_MAX\t255\t\t/* for unsigned chars */\r\n#define\tSHRT_MAX\t32767\t\t/* max value of a short */\r\n#define\tSHRT_MIN\t-32768\r\n#define\tUSHRT_MAX\t65535\t\t/* unsigned short */\r\n#define\tINT_MAX\t\t32767\t\t/* max for int */\r\n#define\tINT_MIN\t\t-32768\t\t/* min for int */\r\n#define\tUINT_MAX\t65535\t\t/* unsigned int */\r\n#define\tLONG_MAX\t2147483647\t/* max value of long */\r\n#define\tLONG_MIN\t-2147483648\t/* min value */\r\n#define\tULONG_MAX\t4294967295\t/* unsigned long */\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/MATH.H",
    "content": "#ifndef _HTC_MATH_H\r\n#define _HTC_MATH_H\r\n\r\nextern double fabs(double), floor(double), ceil(double), modf(double, double *);\r\nextern double sqrt(double), atof(char *);\r\nextern double sin(double), cos(double), tan(double);\r\nextern double asin(double), acos(double), atan(double), atan2(double, double);\r\nextern double frexp(double, int *), ldexp(double, int);\r\nextern double log(double), log10(double), pow(double, double), exp(double);\r\nextern double sinh(double), cosh(double), tanh(double);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/OPTIONS",
    "content": "HI-TECH Z80 CP/M C compiler options:\r\n\r\n-A\tGenerate a self-relocating .COM program.\r\n-C\tGenerate object code only; don't link.\r\n-CR     Produce a cross-reference listing e.g. -CRfile.crf\r\n-D\tDefine a symbol, e.g. -DDEBUG=1\r\n-E\tSpecify executable output filename, e.g. -Efile.com\r\n-Ffile\tGenerate a symbol file for debug.com or overlay build (default L.SYM)\r\n-H      Output help (the OPTIONS file) and exit.\r\n-I\tSpecify an include directory, e.g. -I1:B:\r\n-L\tScan a library, e.g. -LF scans the floating point library.\r\n-M\tGenerate a map file, e.g. -Mfile.map\r\n-N\tUse the NRTCPM.OBJ start-up with minimal _getargs().\r\n-O\tInvoke the peephole optimizer (reduced code-size)\r\n-OF\tInvoke the optimizer for speed (Fast)\r\n-S\tGenerate assembler code in a .AS file; don't assemble or link.\r\n-U\tUndefine a predefined symbol, e.g. -UDEBUG\r\n-V\tBe verbose during compilation.\r\n-W\tSet warning level, e.g. -w5 or -w-2\r\n-X\tSuppress local symbols in symbol tables.\r\n-Y\tGenerate an overlay output file (.OVR file-type)\r\n"
  },
  {
    "path": "dist/OVERLAY.H",
    "content": "#ifndef _HTC_OVERLAY_H\r\n#define _HTC_OVERLAY_H\r\n\r\n#include <stdint.h>\r\nintptr_t ovrload(char *ovr_name,intptr_t args);\r\n#endif\r\n"
  },
  {
    "path": "dist/SETJMP.H",
    "content": "#ifndef _HTC_SETJMP_H\r\n#define _HTC_SETJMP_H\r\n\r\n#if\tz80\r\ntypedef\tint\tjmp_buf[4];\r\n#endif\r\n\r\n#if\ti8086\r\ntypedef\tint\tjmp_buf[8];\r\n#endif\r\n\r\n#if\ti8096\r\ntypedef\tint\tjmp_buf[10];\r\n#endif\r\n\r\n#if\tm68k\r\ntypedef\tint\tjmp_buf[10];\r\n#endif\r\n\r\nextern\tint\tsetjmp(jmp_buf);\r\nextern void\tlongjmp(jmp_buf, int);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/SIGNAL.H",
    "content": "#ifndef _HTC_SIGNAL_H\r\n#define _HTC_SIGNAL_H\r\n\r\n/*\r\n *\tSignal definitions for CP/M\r\n */\r\n#ifdef\tunix\r\n#define NSIG 17\r\n#define\tSIGHUP\t1\t/* hangup    (not used by terminal driver) */\r\n#define\tSIGINT\t2\t/* interrupt (^C or BREAK) */\r\n#define\tSIGQUIT\t3\t/* quit      (^\\) */\r\n#define\tSIGILL\t4\t/* illegal instruction (not reset when caught) */\r\n#define\tSIGTRAP\t5\t/* trace trap (not reset when caught) */\r\n#define\tSIGIOT\t6\t/* IOT instruction */\r\n#define\tSIGEMT\t7\t/* EMT instruction */\r\n#define\tSIGFPE\t8\t/* floating point exception */\r\n#define\tSIGKILL\t9\t/* kill (cannot be caught or ignored) */\r\n#define\tSIGBUS\t10\t/* bus error */\r\n#define\tSIGSEGV\t11\t/* segmentation violation */\r\n#define\tSIGSYS\t12\t/* bad argument to system call */\r\n#define\tSIGPIPE\t13\t/* write on a pipe with no one to read it */\r\n#define\tSIGALRM\t14\t/* alarm clock */\r\n#define\tSIGTERM\t15\t/* software termination signal from kill */\r\n#else\r\n#define NSIG 1\r\n#define\tSIGINT\t1\t\t/* control-C */\r\n#endif\r\n\r\ntypedef void* signal_t;\r\n#define\tSIG_DFL\t((signal_t)0)\t/* default action is to exit */\r\n#define\tSIG_IGN\t((signal_t)1)\t/* ignore them */\r\n\r\nsignal_t signal(int sig, signal_t action);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/STAT.H",
    "content": "#ifndef _HTC_STAT_H\r\n#define _HTC_STAT_H\r\n\r\nstruct stat\r\n{\r\n\tshort\tst_mode;\t/* flags */\r\n\tlong\tst_atime;\t/* access time */\r\n\tlong\tst_mtime;\t/* modification time */\r\n\tlong\tst_size;\t/* file size in bytes */\r\n};\r\n\r\n/* Flag bits in st_mode */\r\n\r\n#define\tS_IFMT\t\t0x600\t/* type bits */\r\n#define\t\tS_IFDIR\t0x400\t/* is a directory */\r\n#define\t\tS_IFREG\t0x200\t/* is a regular file */\r\n#define\tS_IREAD\t\t0400\t/* file can be read */\r\n#define\tS_IWRITE\t0200\t/* file can be written */\r\n#define\tS_IEXEC\t\t0100\t/* file can be executed */\r\n#define\tS_HIDDEN\t0x1000\t/* file is hidden */\r\n#define\tS_SYSTEM\t0x2000\t/* file is marked system */\r\n#define\tS_ARCHIVE\t0x4000\t/* file has been written to */\r\n\r\n\r\nextern int\tstat(char *, struct stat *);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/STDARG.H",
    "content": "#ifndef _HTC_STDARG_H\r\n#define _HTC_STDARG_H\r\n\r\n/*\tMacros for accessing variable arguments */\r\n\r\ntypedef void *\tva_list[1];\r\n\r\n#define\tva_start(ap, parmn)\t*ap = (char *)&parmn + sizeof parmn\r\n\r\n#define\tva_arg(ap, type)\t(*(*(type **)ap)++)\r\n\r\n#define\tva_end(ap)\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/STDDEF.H",
    "content": "#ifndef _HTC_STDDEF_H\r\n#define _HTC_STDDEF_H\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/STDINT.H",
    "content": "#ifndef _HTC_STDINT_H\r\n#define _HTC_STDINT_H\r\n\r\n#if z80||i8086||i8096||m68k\r\ntypedef unsigned char uint8_t;\r\ntypedef char int8_t;\r\ntypedef unsigned short uint16_t;\r\ntypedef short int16_t;\r\ntypedef unsigned long uint32_t;\r\ntypedef long int32_t;\r\ntypedef unsigned short intptr_t;\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/STDIO.H",
    "content": "#ifndef _HTC_STDIO_H\r\n#define _HTC_STDIO_H\r\n\r\n/*\r\n * STDIO.H\tHI-TECH C standard I/O for V3.09-xx\r\n *\r\n *\t\tThis version incorporates changes to stdio routines\r\n *\t\tresulting from backporting features from V4.11\r\n */\r\n\r\n#define _HTC_VERSION\t\"3.09-20\"\r\n#define _HTC_MAJOR\t3\r\n#define _HTC_MINOR\t9\r\n#define _HTC_REV\t20\r\n\r\n#if\tz80\r\n#define\tBUFSIZ\t\t512\r\n#define\t_NFILE\t\t8\r\n#else\tz80\r\n#define\tBUFSIZ\t\t1024\r\n#define\t_NFILE\t\t20\r\n#endif\tz80\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\r\ntypedef\tunsigned\tsize_t;\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef FILE\r\n#define\tuchar\t\tunsigned char\r\n\r\nextern\tstruct\t_iobuf\r\n{\r\n\tchar\t\t*_ptr;\r\n\tint\t\t _cnt;\r\n\tchar\t\t*_base;\r\n\tunsigned short\t _flag;\r\n\tchar\t\t _file;\r\n\tsize_t\t\t _size;\r\n} _iob[_NFILE];\r\n\r\n#define\tFILE\t\tstruct _iobuf\r\n#endif\tFILE\r\n\r\n#ifndef SEEK_SET\r\n#define SEEK_SET 0\r\n#define SEEK_CUR 1\r\n#define SEEK_END 2\r\n#endif\r\n\r\n/* I/O status flag word bits */\r\n#define\t_IOREAD\t\t01\t/* Allow file reading */\r\n#define\t_IOWRT\t\t02\t/* Allow file writing */\r\n#define\t_IORW\t\t03\t/* Mask for reading or writing */\r\n#define\t_IONBF\t\t04\t/* Not being buffered */\r\n#define\t_IOMYBUF\t010\t/* Using buffer */\r\n#define\t_IOEOF\t\t020\t/* At end-of-file */\r\n#define\t_IOERR\t\t040\t/* An I/O error has occurred */\r\n#define\t_IOSTRG\t\t0100\t/* End of string reached */\r\n#define\t_IOBINARY\t0200\t/* Binary mode */\r\n#define\t_IOLBF\t\t0400\t/* Using line buffering */\r\n#define\t_IODIRN\t\t01000\t/* Direction - writing to a R/W file */\r\n#define _IOAPPEND\t02000\t/* Append mode */\r\n#define _IOSEEKED\t04000\t/* A seek has occurred since last write */\r\n#define\t_IOFBF\t\t010000\t/* Using full buffering */\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\n#define\tEOF\t\t(-1)\r\n\r\n#define\tstdin\t\t(&_iob[0])\r\n#define\tstdout\t\t(&_iob[1])\r\n#define\tstderr\t\t(&_iob[2])\r\n#define\tgetchar()\tgetc(stdin)\r\n#define\tputchar(x)\tputc(x,stdout)\r\n\r\n/*\r\n *\tgetc() and putc() must be functions for CP/M to allow the special\r\n *\thandling of '\\r', '\\n' and '\\032'. The same for MSDOS except that\r\n *\tit at least knows the length of a file.\r\n */\r\n\r\n#if\tUNIX\r\n#define\tgetc(p)   (--(p)->_cnt>=0?(unsigned)*(p)->_ptr++:_filbuf(p))\r\n#define\tputc(x,p) (--(p)->_cnt>=0?((unsigned)(*(p)->_ptr++=x)):_flsbuf((unsigned)(x),p))\r\n#else\tUNIX\r\n#define\tgetc(p)\t\tfgetc(p)\r\n#define\tputc(x,p)\tfputc(x,p)\r\n#endif\tUNIX\r\n\r\n#define\tfeof(p)\t\t(((p)->_flag&_IOEOF)!=0)\r\n#define\tferror(p)\t(((p)->_flag&_IOERR)!=0)\r\n#define\tfileno(p)\t((uchar)p->_file)\r\n#define\tclrerr(p)\tp->_flag &= ~_IOERR\r\n#define\tclreof(p)\tp->_flag &= ~_IOEOF\r\n\r\nextern int\t fclose(FILE *);\r\nextern int\t fflush(FILE *);\r\nextern int\t fgetc(FILE *);\r\nextern int\t ungetc(int, FILE *);\r\nextern int\t fputc(int, FILE *);\r\nextern int\t getw(FILE *);\r\nextern int\t putw(int, FILE *);\r\nextern char\t*gets(char *);\r\nextern int\t puts(char *);\r\nextern int\t fputs(char *, FILE *);\r\nextern int\t fread(void *, unsigned, unsigned, FILE *);\r\nextern int\t fwrite(void *, unsigned, unsigned, FILE *);\r\nextern int\t fseek(FILE *, long, int);\r\nextern int\t rewind(FILE *);\r\nextern void\t setbuf(FILE *, char *);\r\nextern int\t setvbuf(FILE *, char *, int, size_t);\r\nextern int\t printf(char *, ...);\r\nextern int\t fprintf(FILE *, char *, ...);\r\nextern int\t sprintf(char *, char *, ...);\r\nextern int\t scanf(char *, ...);\r\nextern int\t fscanf(FILE *, char *, ...);\r\nextern int\t sscanf(char *, char *, ...);\r\nextern int\t remove(char *);\r\nextern FILE\t*fopen(char *, char *);\r\nextern FILE\t*freopen(char *, char *, FILE *);\r\nextern FILE\t*fdopen(int, char *);\r\nextern long\t ftell(FILE *);\r\nextern char\t*fgets(char *, int, FILE *);\r\nextern char\t*_bufallo(void);\r\n\r\n#endif _HTC_STDIO_H\r\n"
  },
  {
    "path": "dist/STDLIB.H",
    "content": "#ifndef _HTC_STDLIB_H\r\n#define _HTC_STDLIB_H\r\n\r\n/*\tStandard utility functions */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n\r\n#define\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n#endif\t_STDDEF\r\n\r\n#define\tRAND_MAX\t32767\t\t/* max value returned by rand() */\r\n\r\nextern double\t atof(char *);\r\nextern int\t atoi(char *);\r\nextern long\t atol(char *);\r\nextern int\t rand(void);\r\nextern void\t srand(unsigned int);\r\nextern void\t*calloc(size_t, size_t);\r\nextern void\t free(void *);\r\nextern void\t*malloc(size_t);\r\nextern void\t*realloc(void *, size_t);\r\nextern void\t abort(void);\r\nextern void\t exit(int);\r\nextern char\t*getenv(char *);\r\nextern int\t system(char *);\r\ntypedef int (*__qsort_compf)(void *, void *);  /* workaround compiler bug */\r\nextern void\t qsort(void *, size_t, size_t, __qsort_compf);\r\nextern int\t abs(int);\r\nextern long\t labs(long);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/STRING.H",
    "content": "#ifndef _HTC_STRING_H\r\n#define _HTC_STRING_H\r\n\r\n/*\tString functions v3.09-4 */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\nextern void\t*memcpy(void *, void *, size_t);\r\nextern void\t*memmove(void *, void *, size_t);\r\nextern char\t*strcpy(char *, char *);\r\nextern char\t*strncpy(char *, char *, size_t);\r\nextern char\t*strcat(char *, char *);\r\nextern char\t*strncat(char *, char *, size_t);\r\nextern int\t memcmp(void *, void *, size_t);\r\nextern int\t strcmp(char *, char *);\r\nextern int\t strcasecmp(char *, char *);\r\n#define stricmp strcasecmp\r\nextern int\t strncmp(char *, char *, size_t);\r\nextern int\t strncasecmp(char *, char *, size_t);\r\n#define strnicmp strncasecmp\r\n/* extern size_t\t strcoll(char *, size_t, char *); */ /* missing */\r\nextern void\t*memchr(void *, int, size_t);\r\n/* extern size_t\t strcspn(char *, char *); */ /* missing */\r\n/* extern char\t*strpbrk(char *, char *); */ /* missing */\r\n/* extern size_t\t strspn(char *, char *); *//* missing */\r\nextern char\t*strstr(char *, char *);\r\nextern char\t*strtok(char *, char *);\r\nextern void\t*memset(void *, int, size_t);\r\nextern char\t*strerror(int);\r\nextern size_t\t strlen(char *);\r\nextern char\t*strchr(char *, int);\r\n/* #define index\tstrchr */\t/* these are equivalent */\r\nextern char\t*index(char *, int);\r\nextern char\t*strrchr(char *, int);\r\n/* #define\trindex\t*strrchr */\t/* these are equivalent */\r\nextern char\t*rindex(char *, int);\r\nextern char\t*strcasestr(char *, char *);\r\n#define stristr\tstrcasestr\r\nextern char\t*strncasestr(char *, char *, size_t);\r\n#define\tstrnistr strncasestr\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/SYS.H",
    "content": "#ifndef _HTC_SYS_H\r\n#define _HTC_SYS_H\r\n\r\n/*\r\n *\tSystem-dependent functions.\r\n */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\nextern int\texecl(char *, char *, char *, ...);\r\nextern int\texecv(char *, char **);\r\nextern int\tspawnl(char *, char *, char *, ...);\r\nextern int\tspawnv(char *, char **);\r\nextern int\tspawnle(char *, char *, char *, char *, ...);\r\nextern int\tspawnve(char *, char **, char *);\r\nextern short\tgetuid(void);\r\nextern short\tsetuid(short);\r\nextern int\tchdir(char *);\r\nextern int\tmkdir(char *);\r\nextern int\trmdir(char *);\r\nextern int\tgetcwd(int);\r\nextern char   **_getargs(char *, char *);\r\nextern int\t_argc_;\r\nextern int\tinp(int);\r\nextern void\toutp(int, int);\r\nextern void *\tsbrk(size_t);\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/TIME.H",
    "content": "#ifndef _HTC_TIME_H\r\n#define _HTC_TIME_H\r\n\r\n/* time.h for HI-TECH C Z80 v3.09-4*/\r\n\r\n#ifndef\t_HTC_TIME_T\r\n\r\ntypedef\tlong\ttime_t;\t\t/* for representing times in seconds */\r\nstruct tm {\r\n\tint\ttm_sec;\r\n\tint\ttm_min;\r\n\tint\ttm_hour;\r\n\tint\ttm_mday;\r\n\tint\ttm_mon;\r\n\tint\ttm_year;\r\n\tint\ttm_wday;\r\n\tint\ttm_yday;\r\n\tint\ttm_isdst;\r\n};\r\n#define\t_HTC_TIME_T\r\n#endif\t_HTC_TIME_T\r\n\r\n#ifndef _STDDEF\r\ntypedef int\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef unsigned size_t;\t/* type yielded by sizeof */\r\n#define _STDDEF\r\n#define offsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\r\n\r\nextern int\ttime_zone;\t/* minutes WESTWARD of Greenwich */\r\n\t\t\t\t/* this value defaults to 0 since with\r\n\t\t\t\t   operating systems like MS-DOS there is\r\n\t\t\t\t   no time zone information available */\r\n\r\nextern time_t\ttime(time_t *);\t\t/* seconds since 00:00:00 Jan 1 1970 */\r\nextern char *\tasctime(struct tm *);\t/* converts struct tm to ascii time */\r\nextern char *\tctime(time_t *);\t/* current local time in ascii form */\r\nextern struct tm *\tgmtime(time_t *);\t/* Universal time */\r\nextern struct tm *\tlocaltime(time_t *);\t/* local time */\r\nextern size_t strftime(char *s, size_t maxs, char *f, struct tm *t);\r\nextern time_t\tmktime(struct tm *);\t/* convert struct tm to time value */\r\n\r\n#endif\r\n"
  },
  {
    "path": "dist/UNIXIO.H",
    "content": "#ifndef _HTC_UNIXIO_H\r\n#define _HTC_UNIXIO_H\r\n\r\n/*\r\n *\tDeclarations for Unix style low-level I/O functions.\r\n */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\nextern int\topen(char *, int);\r\nextern int\tclose(int);\r\nextern int\tcreat(char *, int);\r\nextern int\tdup(int);\r\nextern long\tlseek(int, long, int);\r\nextern int\tread(int, void *, int);\r\nextern int\trename(char *, char *);\r\nextern int\tunlink(char *);\r\nextern int\twrite(int, void *, int);\r\nextern int\tisatty(int);\r\nextern int\tchmod(char *, int);\r\n\r\n#endif\r\n"
  },
  {
    "path": "doc/DEBUGMAN.TXT",
    "content": "\r\n\r\n\r\n\r\n\r\n       1. Debugger Reference Manual\r\n\r\n\r\n            HI-TECH C is supplied  with  an  interactive  debugging\r\n       tool  oriented toward C programs. It is not a \"source level\"\r\n       debugger, i.e. it has no knowledge of  the  C  source  code,\r\n       however it does have the facility to handle C symbols and to\r\n       show the C function calling sequence.\r\n\r\n            The command structure is modelled on that of  the  Unix\r\n       debugger  known  as  adb.  It provides facilities to display\r\n       memory in various radices or as  instructions,  to  set  and\r\n       remove  breakpoints,  which may have a repeat count and/or a\r\n       command associated with them. It is possible to set a break-\r\n       point which will stop only if a certain condition is true.\r\n\r\n            The debugger may be used on any .COM file,  however  in\r\n       order  to  take  advantage of the symbolic facilities, it is\r\n       necessary to generate a symbol file,  usually  with  the  -F\r\n       option  to the C command. This file consists of one line per\r\n       symbol, with the hexadecimal value of the  symbol  preceding\r\n       the symbol on the line.\r\n\r\n       1.1. Invoking Debug\r\n\r\n            The debugger is invoked by the command  DEBUG.  It  may\r\n       have  zero, one or two file arguments. The first argument is\r\n       the name of a file in .COM format to be be debugged, and the\r\n       second  a symbol file name. If the symbol file name is omit-\r\n       ted, no symbols will be available. If the .COM  format  file\r\n       is omitted, no code will be loaded. Some examples:\r\n\r\n            DEBUG fred.com\r\n            DEBUG bill.com l.sym\r\n\r\n\r\n       1.2. Run Time Organization\r\n\r\n            DEBUG relocates itself below the  BDOS  when  executed,\r\n       allowing  the  debugee to be loaded at the start of the TPA,\r\n       as usual. The symbol table, if loaded, grows downwards  from\r\n       the  base of the relocated debugger. The BDOS entry at loca-\r\n       tion 5 is changed to reflect the base of  the  symbol  table\r\n       rather  than the base of the BDOS. Thus the symbol table and\r\n       the debugger are not owerwritten by the debugee's stack.\r\n\r\n            Breakpoints are inserted in the code as RST 8  instruc-\r\n       tions. A jump is placed at location 8 to the debugger's trap\r\n       handler. This is unfortunate if your system happens  to  use\r\n       RST  8  for  interrupts, but this is probably no more likely\r\n       than that it uses any other restart location.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 2         HI-TECH C (Z80) USER'S MANUAL\r\n\r\n\r\n   1.3. Commands\r\n\r\n        The basic debugger command syntax is:\r\n\r\n        address , count command modifier extrastuff\r\n\r\n\r\n        This may seem a little obscure, so read on. Address and\r\n   count are expressions, in their simplest form simply hexade-\r\n   cimal numbers. Both address and count are optional,  but  if\r\n   count  is  to  be  specified with no address, the comma must\r\n   appear.\r\n\r\n        Command is a single character specifying what the  com-\r\n   mand  should  do. Modifier is another character which deter-\r\n   mines more specifically what the command is.  Extrastuff  is\r\n   dependent on the particular command, and is usually omitted.\r\n\r\n   1.3.1. Expressions\r\n\r\n        Expressions may consist of:\r\n\r\n   .    The value of the current location (not necessarily  the\r\n        current  PC  or  last  breakpoint,  this is an internal\r\n        current value).\r\n\r\n   SYMBOL\r\n        The value of a symbol,  as  looked  up  in  the  symbol\r\n        table.   If  the  symbol  is not found, the same symbol\r\n        prepended by and underscore will be  looked  for.  This\r\n        allows  C symbols to be referred to without the leading\r\n        underscore tacked on by the compiler.\r\n\r\n   INTEGER\r\n        A hexadecimal integer. It must start with a digit, oth-\r\n        erwise the debugger will think it is a symbol.\r\n\r\n   <REGNAME\r\n        This yields the contents of the specified Z80 register.\r\n        The  register  names  are the usual Z80 names, in lower\r\n        case only. See the $r command below.\r\n\r\n   (EXPR)\r\n        Parentheses may be uses to enclose expressions to force\r\n        evaluation order.\r\n\r\n   *EXPR\r\n        The contents of the  word  at  address  EXPR.  This  is\r\n        indirection analogous to the C indirection operator.\r\n\r\n   -EXPR\r\n        The negation of EXPR.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n                      HI-TECH C (Z80) USER'S MANUAL          Page 3\r\n\r\n\r\n       ~EXPR\r\n            The bitwise complement of EXPR.\r\n\r\n       E1+E2\r\n            The sum of E1 and E2.\r\n\r\n       E1-E2\r\n            The value of E1 less the value of E2.\r\n\r\n       E1*E2\r\n            The value of E1 multiplied by E2.\r\n\r\n       E1%E2\r\n            E1 divided by E2.\r\n\r\n       E1&E2\r\n            E1 anded with E2.\r\n\r\n            The usual precedence relationships  apply;  parentheses\r\n       may be used to alter the order of evaluation.\r\n\r\n       1.3.2. Command Characters\r\n\r\n            The main command character used is /. This is  used  to\r\n       display  memory  in  various radices or as instructions. The\r\n       exact format is determined by the modifier character, or the\r\n       previous  format  used if the modifier character is omitted.\r\n       The modifiers are:\r\n\r\n       i    Print as Z80 instructions\r\n\r\n       h or b\r\n            Print as hexadecimal bytes.\r\n\r\n       o    Print as octal bytes.\r\n\r\n       d    Print as decimal bytes.\r\n\r\n       H or W\r\n            Print as hexadecimal words.\r\n\r\n       O    Octal words.\r\n\r\n       D    Decimal words.\r\n\r\n       c    Print each byte as an ascii character.\r\n\r\n       C    Print as ascii characters if printable, as @x  if  not,\r\n            where x is the corresponding alphabetic character, e.g.\r\n            @C for 3.\r\n\r\n       s    Print a string of characters up to a null.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 4         HI-TECH C (Z80) USER'S MANUAL\r\n\r\n\r\n   a    Print the address as a symbolic value.\r\n\r\n        If address is specified, the display  starts  from  the\r\n   specified address. Count bytes, instructions, words, strings\r\n   or whatever will be printed, or 1 if count is  omitted.  For\r\n   example:\r\n\r\n        fred,10/b\r\n        123/i\r\n\r\n   The first command prints 16 bytes from the  address  of  the\r\n   symbol fred.  The second displays one instruction from loca-\r\n   tion 123H.\r\n\r\n        When such a command is issued, the value of dot is tem-\r\n   porarily incremented by the total number of bytes displayed.\r\n   A subsequent command consisting solely of a RETURN  or  LINE\r\n   FEED will make the temporary increment of dot permanent, and\r\n   execute a / command. Thus RETURN may be used to  step  along\r\n   in  memory, displaying memory in the same format as the last\r\n   / command.\r\n\r\n        The / command may also be used to alter memory. /w EXPR\r\n   will  write  the  value  of  expr into memory at the current\r\n   location (dot). Either a word or  a  byte  will  be  written\r\n   depending on the last format used for a / command. A /w com-\r\n   mand may not be issued if the current format is not  a  byte\r\n   or  word type. Thus memory may not be modified in the i for-\r\n   mat. One day there will be an in-line  assembler  built  in,\r\n   but not yet.\r\n\r\n        The ] command is like the /  command,  except  that  it\r\n   displays  I/O  ports rather than memory. It may be used with\r\n   only the h, b, o or d formats.  In addition, ]w may be  used\r\n   to write to an I/O port.\r\n\r\n        The $ command has various modifiers as described below:\r\n\r\n   c    Print a C stack backtrace. Note that this is not  reli-\r\n        able when used on an optimized program since the optim-\r\n        izer changes stack manipulation code. There may  appear\r\n        to be fewer arguments than there really are. Long argu-\r\n        ments will always appear as two integer arguments.\r\n\r\n   b    Display currently set breakpoints\r\n\r\n   s    Set the limit for symbol matches to the given  address.\r\n        This determines the maximum value of offset when print-\r\n        ing out a value as sym+offset.\r\n\r\n   w    Set the terminal width to address. The  default  is  80\r\n        decimal.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n                      HI-TECH C (Z80) USER'S MANUAL          Page 5\r\n\r\n\r\n       r    Display the contents of all Z80 registers.\r\n\r\n            The : command has the following modifiers:\r\n\r\n       r    Run the program from address. If  address  is  omitted,\r\n            try  for  the  symbol  start.  If  it is not found, the\r\n            debugger will complain. With this  command,  extrastuff\r\n            will  be supplied as an argument string to the program,\r\n            i.e. in the default buffer at 80H.  You  should  ensure\r\n            there is a space between the r and extrastuff. E.g.:\r\n\r\n                        100:r arg1 arg2\r\n\r\n       c    Continue the program from address, or the  contents  of\r\n            PC if address is omitted. Used after a breakpoint.\r\n\r\n       s    As for c, but execute only count instructions, or 1  if\r\n            count is omitted. Thus this single steps the debugee.\r\n\r\n       b    Set a breakpoint at address. If count is supplied,  the\r\n            breakpoint  will  not  stop until it has been hit count\r\n            times. Extrastuff may be a  command  to  execute  every\r\n            time  the breakpoint is hit. If the command sets dot to\r\n            zero, then the breakpoint will stop even  if  count  is\r\n            not zero.\r\n\r\n       .    Set a temporary breakpoint at address and continue exe-\r\n            cution.   When the next breakpoint is encountered, this\r\n            temporary breakpoint will be removed.\r\n\r\n       d    Clear the breakpoint at address.\r\n\r\n            The command > allows the  values  of  registers  to  be\r\n       changed.  Both word and byte registers may be specified. The\r\n       interrupt flag may also be changed.  0 means  off,  1  means\r\n       on.\r\n\r\n       1.4. Example\r\n\r\n            An example of the use of the debugger follows:\r\n\r\n\r\n\r\n       A>type tst.c\r\n       main()\r\n       {\r\n           int     i, j;\r\n\r\n           scanf(\"%d\", &i);\r\n           printf(\"%d\\n\", j); Note the error - j should be i\r\n       }\r\n\r\n       A>c -f tst.c      Compile requesting a symbol file\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 6         HI-TECH C (Z80) USER'S MANUAL\r\n\r\n\r\n   A>debug tst.com l.sym Default symbol file name is l.sym\r\n   ZDEBUG\r\n   : printf/i     Disassemble at printf\r\n   _printf:        call    csv\r\n   :              Step down with RETURN\r\n   _printf+3:      push    ix\r\n   : :b           Set a breakpoint here\r\n   : :r           Run the program - no arguments\r\n   123             Scanf waits for input - enter 123\r\n   Breakpoint      _printf+3\r\n   _printf+3:      push    ix  Stopped at the breakpoint\r\n   : $c           Get a stack trace\r\n   _printf(1872,0)      1872 is the format string \"d\\n\"\r\n   _main()\r\n   : main/i       Look at main() now\r\n   _main:          call    csv\r\n   :              Step down with RETURN\r\n   _main+3:        ld      hl,FFFC\r\n   :\r\n   _main+6:        add     hl,sp\r\n   : ,10          Disassemble 16 instructions\r\n   _main+7:        ld      sp,hl\r\n   _main+8:        push    ix\r\n   _main+A:        pop     hl\r\n   _main+B:        dec     hl\r\n   _main+C:        dec     hl\r\n   _main+D:        push    hl\r\n   _main+E:        ld      hl,186F\r\n   _main+11:       push    hl\r\n   _main+12:       call    _scanf\r\n   _main+15:       ld      hl,4\r\n   _main+18:       add     hl,sp\r\n   _main+19:       ld      sp,hl\r\n   _main+1A:       ld      l,(ix+-4) here j is loaded\r\n   _main+1D:       ld      h,(ix+-3)\r\n   _main+20:       push    hl    And pushed onto the stack\r\n   _main+21:       ld      hl,1872\r\n   : main+1a/i\r\n   _main+1A:       ld      l,(ix+-4)\r\n   : /h           Look at the bytes as hex\r\n   _main+1A:       DD        Indexing prefix byte\r\n   :              Step down with RETURN\r\n   _main+1B:       6E\r\n   :\r\n   _main+1C:       FC        The index offset = -4\r\n   : /w 0fe       Change to -2\r\n   :\r\n   _main+1D:       DD\r\n   :\r\n   _main+1E:       66\r\n   :\r\n   _main+1F:       FD\r\n   : /w 0ff   Change the hi byte to -1 to address i instead of j\r\n   : :r       Run it again\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n                      HI-TECH C (Z80) USER'S MANUAL          Page 7\r\n\r\n\r\n       123        Enter the same number again\r\n       Breakpoint      _printf+3\r\n       _printf+3:      push    ix\r\n       : $c\r\n       _printf(1872,7B)\r\n       _main()\r\n       : 7b=d        7b was the argument above\r\n        123          Now we have the correct value\r\n       : :c        Continue the program\r\n       123          Which prints the correct value\r\n\r\n       A>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "doc/HTCZ80.TXT",
    "content": "\r\n       HI-TECH C USER'S MANUAL                                    i\r\n\r\n       CONTENTS\r\n\r\n\r\n\r\n       1. Introduction                                            1\r\n         1.1. Features                                            1\r\n         1.2. System Requirements                                 2\r\n         1.3. Using this Manual                                   2\r\n\r\n       2. Getting Started                                         3\r\n\r\n       3. Compiler Structure                                      5\r\n\r\n       4. Operating Details                                       7\r\n\r\n       5. Specific Features                                      13\r\n         5.1. ANSI C Standard Compatibility                      13\r\n         5.2. Type Checking                                      13\r\n         5.3. Member Names                                       13\r\n         5.4. Unsigned Types                                     14\r\n         5.5. Arithmetic Operations                              14\r\n         5.6. Structure Operations                               15\r\n         5.7. Enumerated Types                                   16\r\n         5.8. Initialization Syntax                              16\r\n         5.9. Function Prototypes                                17\r\n         5.10. Void and Pointer to Void                          18\r\n         5.11. Type qualifiers                                   19\r\n         5.12. In-line Assembler                                 20\r\n         5.13. Pragma Directives                                 20\r\n\r\n       6. Machine Dependencies                                   21\r\n         6.1. Predefined Macros                                  21\r\n\r\n       7. Error Checking and Reporting                           23\r\n\r\n       8. Standard Libraries                                     25\r\n         8.1. Standard I/O                                       25\r\n         8.2. Compatibility                                      25\r\n         8.3. Libraries for Embedded Systems                     25\r\n         8.4. Binary I/O                                         26\r\n         8.5. Floating Point Library                             27\r\n\r\n       9. Stylistic Considerations                               29\r\n         9.1. Member Names                                       29\r\n         9.2. Use of Int                                         30\r\n         9.3. Extern Declarations                                30\r\n\r\n       10. Memory Models                                         31\r\n\r\n       11. What Went Wrong                                       33\r\n\r\n       12. Z80 Assembler Reference Manual                        35\r\n         12.1. Introduction                                      35\r\n         12.2. Usage                                             35\r\n         12.3. The Assembly Language                             36\r\n           12.3.1. Symbols                                       36\r\n             12.3.1.1. Temporary Labels                          37\r\n           12.3.2. Constants                                     37\r\n             12.3.2.1. Character Constants                       38\r\n\r\n\r\n\r\n\r\n\r\n   ii                                    HI-TECH C USER'S MANUAL\r\n\r\n         12.3.2.2. Floating Constants                        38\r\n         12.3.2.3. Opcode Constants                          38\r\n       12.3.3. Expressions                                   38\r\n         12.3.3.1. Operators                                 38\r\n         12.3.3.2. Relocatability                            39\r\n       12.3.4. Pseudo-ops                                    40\r\n         12.3.4.1. DEFB, DB                                  40\r\n         12.3.4.2. DEFF                                      41\r\n         12.3.4.3. DEFW                                      41\r\n         12.3.4.4. DEFS                                      41\r\n         12.3.4.5. EQU                                       41\r\n         12.3.4.6. DEFL                                      41\r\n         12.3.4.7. DEFM                                      42\r\n         12.3.4.8. END                                       42\r\n         12.3.4.9. COND, IF, ELSE, ENDC                      42\r\n         12.3.4.10. ELSE                                     42\r\n         12.3.4.11. ENDC                                     42\r\n         12.3.4.12. ENDM                                     43\r\n         12.3.4.13. PSECT                                    43\r\n         12.3.4.14. GLOBAL                                   43\r\n         12.3.4.15. ORG                                      44\r\n         12.3.4.16. MACRO                                    44\r\n         12.3.4.17. LOCAL                                    45\r\n         12.3.4.18. REPT                                     46\r\n       12.3.5. IRP and IRPC                                  47\r\n       12.3.6. Extended Condition Codes                      48\r\n     12.4. Assembler Directives                              48\r\n     12.5. Diagnostics                                       49\r\n     12.6. Z80/Z180/64180 Instruction Set                    50\r\n\r\n   13. Linker Reference Manual                               69\r\n     13.1. Relocation and Psects                             69\r\n       13.1.1. Program Sections                              69\r\n       13.1.2. Local Psects and the Large Model              70\r\n     13.2. Global Symbols                                    70\r\n     13.3. Operation                                         71\r\n     13.4. Examples                                          74\r\n     13.5. Invoking the Linker                               74\r\n\r\n   14. Librarian                                             75\r\n     14.1. The Library Format                                75\r\n     14.2. Using                                             75\r\n     14.3. Examples                                          76\r\n     14.4. Supplying Arguments                               77\r\n     14.5. Listing Format                                    77\r\n     14.6. Ordering of Libraries                             77\r\n     14.7. Error Messages                                    78\r\n\r\n   15. Objtohex                                              79\r\n\r\n   16. Cref                                                  83\r\n   APPENDIX 1 Error Messages                                 85\r\n\r\n   APPENDIX 2 Standard Library Functions                     99\r\n\r\n\r\n   INDEX                                                    165\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n                            HI-TECH C COMPILER\r\n\r\n                              User's Manual\r\n\r\n                                March 1989\r\n\r\n\r\n\r\n\r\n       1. Introduction\r\n\r\n\r\n            The HI-TECH C Compiler  is  a  set  of  software  which\r\n       translates  programs written in the C language to executable\r\n       machine code programs. Versions are available which  compile\r\n       programs  for  operation under the host operating system, or\r\n       which produce programs for  execution  in  embedded  systems\r\n       without an operating system.\r\n\r\n       1.1. Features\r\n\r\n            Some of HI-TECH C's features are:\r\n\r\n            A single command will compile, assemble and link entire\r\n            programs.\r\n\r\n            The compiler performs strong type checking  and  issues\r\n            warnings  about  various constructs which may represent\r\n            programming errors.\r\n\r\n            The generated code is extremely small and fast in  exe-\r\n            cution.\r\n\r\n            A full run-time library is  provided  implementing  all\r\n            standard C input/output and other functions.\r\n\r\n            The source code for all run-time routines is provided.\r\n\r\n            A powerful general purpose macro assembler is included.\r\n\r\n            Programs may be generated to  execute  under  the  host\r\n            operating  system,  or  customized  for installation in\r\n            ROM.\r\n\r\n                 PC-DOS/MS-DOS\r\n                 CP/M-86\r\n                 Concurrent DOS\r\n                 Atari ST\r\n                 Xenix\r\n                 Unix\r\n                 CP/M-80\r\n\r\n\r\n                         Table 1. Supported Hosts\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 2                               HI-TECH C USER'S MANUAL\r\n\r\n   1.2. System Requirements\r\n\r\n        The HI-TECH C Compilers  operate  under  the  operating\r\n   systems listed  in  table  1. Ensure that the version of the\r\n   compiler you have matches the system you have.  Note that in\r\n   general  you  must  have  a hard disk or two floppy disks on\r\n   your system (it is possible to use one floppy disk  of  800K\r\n   or  more).   A  hard disk is strongly recommended. Note that\r\n   the CP/M-80 native compiler does not have all  the  features\r\n   described  in  this manual, as it has not been upgraded past\r\n   V3.09 due to memory limitations.   The  Z80  cross  compiler\r\n   does  support  all of the features described here and can be\r\n   used to generate programs to execute under CP/M-80.\r\n\r\n   1.3. Using this Manual\r\n\r\n        The documentation supplied with the HI-TECH C  compiler\r\n   comprises  two  separate  manuals within the one binder. The\r\n   manual you are reading now covers all versions of  the  com-\r\n   piler  (reflecting  the  portable nature of the compiler). A\r\n   separate manual covers machine  dependent  aspects  of  your\r\n   compiler, e.g. installation.\r\n\r\n        This  manual  assumes  you  are  familiar  with  the  C\r\n   language  already.  If you are not, you should have at least\r\n   one reference book covering C, of which a large  number  are\r\n   available  from most computer bookstores, e.g. \"A Book on C\"\r\n   by Kelley and Pohl. Other suitable texts are \"Programming in\r\n   ANSI  C\"  by  S. Kochan and \"The C Programming Language\", by\r\n   Kernighan and Ritchie. You should read the \"Getting Started\"\r\n   chapter  in  this  manual, and the \"Installation\" chapter in\r\n   the machine-specific manual.  This  will  provide  you  with\r\n   sufficient  information  to  work  through  the introductory\r\n   examples in the C reference you are using.\r\n\r\n        Once you have a basic grasp  of  the  C  language,  the\r\n   remainder  of  this manual will provide you with information\r\n   to enable you to explore the more advanced aspects of C.\r\n\r\n        Most of the manual covers all  implementations  of  the\r\n   HI-TECH  C  compiler.  A separate manual is provided for the\r\n   macro assembler  for  your  particular  machine,  and  other\r\n   machine-dependent information.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                               Page 3\r\n\r\n\r\n       2. Getting Started\r\n\r\n\r\n            If using the compiler on a hard disk  system  you  will\r\n       need  to  install  the  compiler  before  using  it. See the\r\n       \"Installation\" chapter for more details.  If using a  floppy\r\n       disk  based system, in general you should have a copy of the\r\n       distribution disk #1 in drive A: and maintain your files  on\r\n       a disk in the B: drive. Again see the \"Installation\" chapter\r\n       for more information.\r\n\r\n            main()\r\n            {\r\n                    printf(\"Hello, world\\n\");\r\n            }\r\n\r\n\r\n                         Fig. 1. Sample C Program\r\n\r\n\r\n            Before compiling your program it must be contained in a\r\n       file  with an extension (or file type, i.e. that part of the\r\n       name after the '.') of .C.  For example  you  may  type  the\r\n       program shown in fig. 1 into a file called HELLO.C. You will\r\n       need a text editor to do this.  Generally  any  text  editor\r\n       that can create a straight ASCII file (i.e. not a \"word pro-\r\n       cessor\" type file) will be suitable. If using  editors  such\r\n       as  Wordstar,  you should use the \"non-document mode\".  Once\r\n       you have the program in such a file all that is required  to\r\n       compile  it  is  to  issue  the  C  command, e.g. to compile\r\n       HELLO.C simply type the command\r\n\r\n            C -V HELLO.C\r\n\r\n       Cross compilers (i.e. compilers that operate on  one  system\r\n       but  produce  code for a separate target system) will have a\r\n       compiler driver named slightly differently, e.g. the  68HC11\r\n       cross compiler driver is called C68.\r\n\r\n            If you are using a floppy disk based system (or a  CP/M\r\n       system)  it  may be necessary to specify where to find the C\r\n       command, e.g. if the C command is on a disk in drive A:  and\r\n       you are working on B:, type the command\r\n\r\n            A:C -V HELLO.C\r\n\r\n\r\n            The compiler will issue a sign on message, then proceed\r\n       to execute the various passes of the compiler in sequence to\r\n       compile the program. If you are using a  floppy  disk  based\r\n       system  where the compiler will not fit on a single disk you\r\n       will be prompted to change disks whenever the compiler  can-\r\n       not  find  a  pass. In this case you should insert a copy of\r\n       the next distribution disk in drive A: and press RETURN.\r\n\r\n            As each pass of the compiler is about to be executed, a\r\n       command  line  to that pass will be displayed on the screen.\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 4                               HI-TECH C USER'S MANUAL\r\n\r\n   This is because the -V option has been used. This stands for\r\n   Verbose,  and  had  it  not been given the compilation would\r\n   have been silent except for the sign on message.  Error mes-\r\n   sages can be redirected to a file by using the standard out-\r\n   put redirection notation, e.g. > somefile.\r\n\r\n        After completion of compilation, the compiler will exit\r\n   to  command  level.   You will notice that several temporary\r\n   files created during compilation will have been deleted, and\r\n   all  that  will be left on the disk (apart from the original\r\n   source file HELLO.C) will be an executable file. The name of\r\n   this executable file will be HELLO.EXE for MS-DOS, HELLO.PRG\r\n   for the Atari ST, HELLO.COM for CP/M-80  and  HELLO.CMD  for\r\n   CP/M-86.  For cross compilers it will be called HELLO.HEX or\r\n   HELLO.BIN depending on the default  output  format  for  the\r\n   particular compiler.  To execute this program, simply type\r\n\r\n        HELLO\r\n\r\n   and you should be rewarded with the message \"Hello,  world!\"\r\n   on  your screen.  If you are using a cross compiler you will\r\n   need to put the program into EPROM or download to the target\r\n   system  to  execute  it. Cross compilers do not produce pro-\r\n   grams executable on the host system.\r\n\r\n        There are other options that may be  used  with  the  C\r\n   command,  but  you will not need to use them unless you wish\r\n   to do so. If you are new to the C language it will be advis-\r\n   able  to enter and compile a few simple programs (e.g. drawn\r\n   from one of the C reference texts  mentioned  above)  before\r\n   exploring other capabilities of the HI-TECH C compiler.\r\n\r\n        There is one exception to the above; if you  compile  a\r\n   program  which  uses  floating  point  arithmetic (i.e. real\r\n   numbers) you MUST specify to the compiler that the  floating\r\n   point  library  should  be searched. This is done with a -LF\r\n   option at the END of the command line, e.g.\r\n\r\n        C -V FLOAT.C -LF\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                               Page 5\r\n\r\n\r\n       3. Compiler Structure\r\n\r\n\r\n            The compiler is made up of several passes; each pass is\r\n       implemented  as  a  separate  program.  Note  that it is not\r\n       necessary for the user to invoke each pass individually,  as\r\n       the  C  command runs each pass automatically.  Note that the\r\n       machine dependent passes are named differently for each pro-\r\n       cessor,  for example those with 86 in their name are for the\r\n       8086 and those with 68K in their name are for the 68000.\r\n\r\n            The passes are:\r\n\r\n       CPP  The pre-processor - handles macros and conditional com-\r\n            pilation\r\n\r\n       P1   The syntax and  semantic  analysis  pass.  This  writes\r\n            intermediate code for the code generator to read.\r\n\r\n       CGEN, CG86 etc.\r\n            The code generator - produces assembler code.\r\n\r\n       OPTIM, OPT86 etc.\r\n            The code improver - may optionally be omitted, reducing\r\n            compilation  time at a cost of larger, slower code pro-\r\n            duced.\r\n\r\n       ZAS, AS86 etc.\r\n            The assembler - in fact a general purpose macro  assem-\r\n            bler.\r\n\r\n       LINK\r\n            The link editor - links object files with libraries.\r\n\r\n       OBJTOHEX\r\n            This utility converts  the  output  of  LINK  into  the\r\n            appropriate  executable  file format (e.g. .EXE or .PRG\r\n            or .HEX).\r\n\r\n            The passes are invoked in the order  given.  Each  pass\r\n       reads  a  file  and writes a file for its successor to read.\r\n       Each intermediate file has a particular format; CPP produces\r\n       C code without the macro definitions and with uses of macros\r\n       expanded; P1 writes a file containing a program in an inter-\r\n       mediate code; CGEN translates this to assembly code; AS pro-\r\n       duces object code, a binary  format  containing  code  bytes\r\n       along  with relocation and symbol information.  LINK accepts\r\n       object files  and  libraries  of  object  files  and  writes\r\n       another  object file; this may be in absolute form or it may\r\n       preserve relocation information and be input to another LINK\r\n       command.\r\n\r\n            There are also other utility programs:\r\n\r\n       LIBR\r\n            Creates and maintains libraries of object modules\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 6                               HI-TECH C USER'S MANUAL\r\n\r\n   CREF\r\n        Produces cross-reference listings  of  C  or  assembler\r\n        programs.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                               Page 7\r\n\r\n\r\n       4. Operating Details\r\n\r\n\r\n            HI-TECH C was designed for ease of use; a  single  com-\r\n       mand will compile, assemble and link a C program. The syntax\r\n       of the C command is as follows:\r\n\r\n            C [ options ] files [ libraries ]\r\n\r\n            The options are zero or more options,  each  consisting\r\n       of  a dash ('-'), a single key letter, and possibly an argu-\r\n       ment following the key letter with no intervening space. The\r\n       files  are  one  or  more  C  source files, assembler source\r\n       files, or object  files.  Libraries  may  be  zero  or  more\r\n       library  names, or the abbreviated form -lname which will be\r\n       expanded to the library name libname.lib.\r\n\r\n            The C command will,  as  determined  by  the  specified\r\n       options,  compile  any  C  source files given, assemble them\r\n       into object code unless requested  otherwise,  assemble  any\r\n       assembler  source  files specified, then link the results of\r\n       the assemblies with any object or library files specified.\r\n\r\n            If the C command is invoked without arguments, then  it\r\n       will  prompt  for a command line to be entered. This command\r\n       line may be extended by typing a backslash ('\\') on the  end\r\n       of  the  line.  Another  line will then be requested. If the\r\n       standard input of the command is from a file (e.g. by typing\r\n       C  <  afile)  then  the command lines will be read from that\r\n       file. Within the file more than one line  may  be  given  if\r\n       each line but the last ends with a backslash. Note that this\r\n       mechanism does not work in MS-DOS batch file, i.e. the  com-\r\n       mand  file for the C command must be a separate file. MS-DOS\r\n       has no mechanism for providing long command lines  or  stan-\r\n       dard input from inside a batch file.\r\n\r\n            The options recognized by the C command are as follows:\r\n\r\n       -S   Leave the results of compilation  of  any  C  files  as\r\n            assembler output. C source code will be interspersed as\r\n            comments in the assembler code.\r\n\r\n       -C   Leave the results of all  compiles  and  assemblies  as\r\n            object files; do not invoke the linker. This allows the\r\n            linker to be invoked separately, or via the  C  command\r\n            at a later stage.\r\n\r\n       -CR  Produce a cross reference listing. -CR on its own  will\r\n            leave  the  raw  cross-reference  information in a tem-\r\n            porary file, allowing the user to run CREF  explicitly,\r\n            while  supplying  a  file  name,  e.g. -CRFRED.CRF will\r\n            cause CREF to be invoked to process the raw information\r\n            into the specified file, in this case FRED.CRF.\r\n\r\n       -CPM\r\n            For the Z80 cross compiler only,  produce  CP/M-80  COM\r\n            files.   Unless the -CPM option is given, the Z80 cross\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 8                               HI-TECH C USER'S MANUAL\r\n\r\n        compiler uses the ROM runtime startoff module and  pro-\r\n        duces  hex  or  binary  images.   If the -CPM option is\r\n        given, CP/M-80 runtime startoff code is linked used and\r\n        a CP/M-80 COM file is produced.\r\n\r\n   -O   Invoke  the  optimizer  on  all  compiled  code;   also\r\n        requests the assembler to perform jump optimization.\r\n\r\n   -OOUTFILE\r\n        Specify a name for the executable file to  be  created.\r\n        By  default the name for the executable file is derived\r\n        from the name of the first source or object file speci-\r\n        fied to the compiler. This option allows the default to\r\n        be overridden. If no dot ('.')  appears  in  the  given\r\n        file  name, an extension appropriate for the particular\r\n        operating system will be added, e.g. -OFRED  will  gen-\r\n        erate a file FRED.EXE on MS-DOS or FRED.CMD on CP/M-86.\r\n        For cross compilers this  also  provides  a  means  for\r\n        specifying the output format, e.g. specifying an output\r\n        file PROG.BIN will make the compiler generate a  binary\r\n        file, while specifying PROG.HEX will make it generate a\r\n        hexadecimal file.\r\n\r\n   -V   Verbose: each step of the compilation will be echoed as\r\n        it is executed.\r\n\r\n   -I   Specify an additional filename prefix to use in search-\r\n        ing  for #include files. For CP/M the default prefix is\r\n        0:A: (user number 0, disk  drive  A).  For  MS-DOS  the\r\n        default  prefix is A:\\HITECH\\. Under Unix and Xenix the\r\n        default prefix is /usr/hitech/include/.  Note  that  on\r\n        MS-DOS  a  trailing  backslash  must be appended to any\r\n        directory  name  given  as  an  argument  to  -I;  e.g.\r\n        -I\\FRED\\  not  -I\\FRED.  Under  Unix  a  trailing slash\r\n        should be added.\r\n\r\n   -D   Define a symbol to the preprocessor:  e.g.  -DCPM  will\r\n        define the symbol CPM as though via #define CPM 1.\r\n\r\n   -U   Undefine a pre-defined symbol. The complement of -D.\r\n\r\n   -F   Request the linker to produce a symbol  file,  for  use\r\n        with the debugger.\r\n\r\n   -R   For the Z80 CP/M compiler only this option will link in\r\n        code  to  perform command line I/O redirection and wild\r\n        card expansion in file names.  See the  description  of\r\n        _getargs()  in  appendix 5 for details of the syntax of\r\n        the redirections.\r\n\r\n   -X   Strip local symbols from any files compiled,  assembled\r\n        or linked. Only global symbols will remain.\r\n\r\n   -M   Request the linker to produce a link map.\r\n\r\n   -A   This option, for the Z80 only, will cause the  compiler\r\n        to  produce  an executable program that will, on execu-\r\n        tion, self-relocate  itself  to  the  top  of  the  TPA\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                               Page 9\r\n\r\n            (Transient  Program  Area).  This allows the writing of\r\n            programs which may execute other programs  under  them-\r\n            selves.   Note that a program compiled in such a manner\r\n            will not automatically reset the bdos address at  loca-\r\n            tion 6 in order to protect itself. This must be done by\r\n            the program itself.\r\n\r\n            For cross compilers this provides a way  of  specifying\r\n            to  the  linker the addresses that the compiled program\r\n            is to be  linked  at.  The  format  of  the  option  is\r\n            -AROMADR,RAMADR,RAMSIZE.  ROMADR  is the address of the\r\n            ROM in the system, and is where the executable code and\r\n            initialized  data  will  be placed. RAMADR is the start\r\n            address of RAM, and is where  the  bss  psect  will  be\r\n            placed,  i.e.  uninitialized data.  RAMSIZE is the size\r\n            of RAM available to the program, and is used to set the\r\n            top of the stack.\r\n\r\n            For the 6801/6301/68HC11 compiler, the -A option  takes\r\n            a  fourth  value  which  is  the address of a four byte\r\n            direct page area called ctemp which the  compiled  code\r\n            uses as a scratch pad.  If the ctemp address is omitted\r\n            from the -A option, it defaults to address 0.  Normally\r\n            this  will  be  acceptable,  however some 6801 variants\r\n            (like the 6303) have memory mapped I/O ports at address\r\n            0 and start their direct page RAM at address $80.\r\n\r\n            For the large memory model of the 8051 compiler, the -A\r\n            option  takes  the form -AROMADR,INTRAM,EXTRAM,EXTSIZE.\r\n            ROMADR is the address of ROM in the system.  INTRAM  is\r\n            the  start  address  of  internal RAM, and is where the\r\n            rbss psect will be placed.   The  8051  internal  stack\r\n            will  start after the end of the rbss psect.  EXTRAM is\r\n            the start address of external RAM, and is where the bss\r\n            psect  will be placed.  EXTSIZE is the size of external\r\n            RAM available to the program, and is used  to  set  the\r\n            top of the external stack.\r\n\r\n       -B   For compilers  which  support  more  than  one  \"memory\r\n            model\",  this  option  is  used  to select which memory\r\n            model code is to be generated for.  The format of  this\r\n            option is -Bx where x is one or more letters specifying\r\n            which memory model to use.  For the 8086,  this  option\r\n            is  used  to  select  which  one  of five memory models\r\n            (Tiny, Small, Medium, Compact or Large) is to be used.\r\n\r\n            For the 8051 compiler  this  this  option  is  used  to\r\n            select  which  one  of  the three memory models (Small,\r\n            Medium or Large) is to be used.  For the 8051  compiler\r\n            only,  this  option  can  also be used to select static\r\n            allocation of auto variables by appending an A  to  the\r\n            end  of  the -B option.  For example, -Bsa would select\r\n            small model with static allocation  of  all  variables,\r\n            while -Bm would select medium model with auto variables\r\n            dynamically allocated on the stack.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 10                              HI-TECH C USER'S MANUAL\r\n\r\n   -E   By default the 8086 compiler will initialize  the  exe-\r\n        cutable  file  header  to request a 64K data segment at\r\n        run time. This may be overridden by the -E  option.  It\r\n        takes  an  argument (usually in hexadecimal representa-\r\n        tion) which is the number of BYTES (not paragraphs)  to\r\n        be  allocated  to  the program at run time. For example\r\n        -E0ffff0h will request a megabyte. Since this much will\r\n        not be available, the operating system will allocate as\r\n        much as it can.\r\n\r\n   -W   This options sets the warning level, i.e. it determines\r\n        how  picky the compiler is about legal but dubious type\r\n        conversions etc. -W0 will allow  all  warning  messages\r\n        (default),   -W1  will  suppress  the  message  \"Func()\r\n        declared implicit int\". -W3 is recommended for  compil-\r\n        ing  code  originally  written with other, less strict,\r\n        compilers. -W9 will suppress all warning messages.\r\n\r\n   -H   This option  generates  a  symbol  file  for  use  with\r\n        debuggers.  The  format of the symbol file is described\r\n        elsewhere. The default  name  of  the  symbol  file  is\r\n        l.sym.  An  alternate  name  may  be  specfied with the\r\n        option, e.g. -Hsymfile.abc.\r\n\r\n   -G   Like -H, -G also generates a symbol file, but one  that\r\n        contains  line and file number information for a source\r\n        level debugger. Like -H a file name may  be  specified.\r\n        When  used in conjunction with -O, only partial optimi-\r\n        zation  will  be  performed  to  avoid  confusing   the\r\n        debugger.\r\n\r\n   -P   Execution profiling is available  on  native  compilers\r\n        running  under  DOS,  CP/M-86 and on the Atari ST. This\r\n        option generates code to turn  on  execution  profiling\r\n        when  the  program  is  run. A -H option should also be\r\n        specified to provide a symbol table  for  the  profiler\r\n        EPROF.\r\n\r\n   -Z   For version 5.xx compilers only, the -Z option is  used\r\n        to  select  global  optimization of the code generated.\r\n        For the 8086 and 6801/6301/68HC11  compilers  the  only\r\n        valid  -Z  option  is  -Zg.  For the 8051 compiler, the\r\n        valid -Z options are -Zg which invokes global optimiza-\r\n        tion,  -Zs  which  optimizes  for  space, and -Zf which\r\n        optimizes for speed.  The s and f options may  be  used\r\n        with  the  g option, thus the options -Zgf and -Zgs are\r\n        valid.   Speed  and  space  optimization  are  mutually\r\n        exclusive,  i.e.  the  s  and  f options cannot be used\r\n        together.\r\n\r\n   -1   For the 8086 compiler only, request the  generation  of\r\n        code which takes advantage of the extra instructions of\r\n        the 80186 processor. A program compiled  with  -1  will\r\n        not execute on an 8086 or 8088 processor. For the 68000\r\n        compiler, generate instructions for the  68010  proces-\r\n        sor.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 11\r\n\r\n       -2   Like -1 but for the 80286 and 68020.\r\n\r\n       -11  For the 6801/HC11 compiler, this  option  will  request\r\n            generation  of instructions specific to the 68HC11 pro-\r\n            cessor.\r\n\r\n       -6301\r\n            For the 6801/HC11 compiler, this  option  will  request\r\n            generation  of  instructions  specific to the 6301/6303\r\n            processors.\r\n\r\n            Some examples of the use of the C command are:\r\n\r\n       c prog.c\r\n\r\n       c -mlink.map prog.c x.obj -lx\r\n\r\n       c -S prog.c\r\n\r\n       c -O -C -CRprog.crf prog.c prog2.c\r\n\r\n       c -v -Oxfile.exe afile.obj anfile.c -lf\r\n\r\n\r\n            Upper and lower case has been used in the  above  exam-\r\n       ples for emphasis: the compiler does not distinguish between\r\n       cases, although arguments specifying  names,  e.g.  -D,  are\r\n       inherently case sensitive.\r\n\r\n            Taking the above examples in order; the first  compiles\r\n       and  links  the  C  source  file  prog.c with the standard C\r\n       library. The second example will compile the file prog.c and\r\n       link it with the object file x.obj and the library libx.lib;\r\n       a link map will be written to the file link.map.\r\n\r\n            The third example compiles the file prog.c, leaving the\r\n       assembler  output  in  a  file prog.as. It does not assemble\r\n       this file or invoke the linker.  The next  example  compiles\r\n       both  prog.c  and  prog2.c,  invoking  the optimizer on both\r\n       files, but does not perform any linking. A  cross  reference\r\n       listing will be left in the file prog.crf.\r\n\r\n            The last example pertains to the 8086  version  of  the\r\n       compiler,  It runs the compiler with the verbose option, and\r\n       will cause anfile.c to be compiled without  optimization  to\r\n       object   code,   yielding  anfile.obj,  then  afile.obj  and\r\n       anfile.obj will be linked together with the  floating  point\r\n       library  (from  the  -LF option) and the standard library to\r\n       yield the executable program  xfile.exe  (assuming  this  is\r\n       performed  on an MS-DOS system).  One would expect this pro-\r\n       gram to use floating point, if  it  did  not  then  the  -LF\r\n       option would have been required.\r\n\r\n            If more than one C or assembler source file is given to\r\n       the  C command, the name of each file will be printed on the\r\n       console as it is processed.  If any fatal errors occur  dur-\r\n       ing  the  compilation  or  assembly of source files, further\r\n       source files will be processed, but the linker will  not  be\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 12                              HI-TECH C USER'S MANUAL\r\n\r\n   invoked.\r\n\r\n\r\n        Other commands which may be issued by the user,  rather\r\n   than automatically by the C command, are:\r\n\r\n   ZAS  The Z80 assembler.\r\n\r\n   AS86\r\n        The 8086 assembler.\r\n\r\n   LINK\r\n        The linker\r\n\r\n   LIBR\r\n        The library maintainer\r\n\r\n   OBJTOHEX\r\n        Object to hex converter\r\n\r\n   CREF\r\n        Cross reference generator.\r\n\r\n        In general, these commands accept the same type of com-\r\n   mand line as the C command, i.e. zero or more options (indi-\r\n   cated by a leading '-') followed by one or more  file  argu-\r\n   ments.  If  the  linker  or the librarian is invoked with no\r\n   arguments, it wll prompt for a  command  line.  This  allows\r\n   command  lines  of more than 128 bytes to be entered.  Input\r\n   may also be taken from a file by using the redirection capa-\r\n   blities  (see  _getargs()  in the library function listing).\r\n   See the discussion above of the C command.   These  commands\r\n   are described in further detail in their respective manuals.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 13\r\n\r\n\r\n       5. Specific Features\r\n\r\n\r\n            The HI-TECH C compiler has a number of features,  which\r\n       while  largely compatible with other C compilers, contribute\r\n       to more reliable programming methods.\r\n\r\n       5.1. ANSI C Standard Compatibility\r\n\r\n            At the time of writing the Draft ANSI Standard for  the\r\n       C Language was at an advanced stage, though not yet an offi-\r\n       cial standard. Accordingly it is not possible to claim  com-\r\n       pliance  with  that standard, however HI-TECH C includes the\r\n       majority of the new and altered features in the  draft  ANSI\r\n       standard.  Thus  it  is in the sense that most people under-\r\n       stand it \"ANSI compatible\".\r\n\r\n       5.2. Type Checking\r\n\r\n            Previous C compilers have adopted  a  lax  approach  to\r\n       type  checking.  This  is  typified  by the Unix C compiler,\r\n       which allows almost arbritary mixing  of  types  in  expres-\r\n       sions. The HI-TECH C compiler performs much more strict type\r\n       checking, although in most cases only warning  messages  are\r\n       issued,  allowing  compilation  to proceed if the user knows\r\n       that the errors are harmless. This would occur, for example,\r\n       when  an  integer  value was assigned to a pointer variable.\r\n       The generated code would almost certainly be what  the  user\r\n       intended,  however if in fact it represented an error in the\r\n       source code, the user is prompted to check  and  correct  it\r\n       where necessary.\r\n\r\n       5.3. Member Names\r\n\r\n            In early C compilers member names in  different  struc-\r\n       tures were required to be distinct except under certain cir-\r\n       cumstances. HI-TECH C, like most recent  implementations  of\r\n       C, allows member names in different structures and unions to\r\n       overlap.  A member name is recognized only in the context of\r\n       an  expression  whose type is that of the structure in which\r\n       the member is defined.  In practice this means that a member\r\n       name  will  be recognized only to the right of a '.' or '->'\r\n       operator, where the expression to the left of  the  operator\r\n       is  of  type  structure  or pointer to structure the same as\r\n       that in which the member name was declared.  This  not  only\r\n       allows  structure  names  to  be re-used without conflict in\r\n       more than one structure, it permits strict checking  of  the\r\n       usage  of  members; a common error with other C compilers is\r\n       the use of a member name with a  structure  pointer  of  the\r\n       wrong type, or worse with a variable which is a pointer to a\r\n       simple type.\r\n\r\n            There is however an escape from this,  where  the  user\r\n       desires to use as a structure pointer something which is not\r\n       declared as such. This is via the use  of  a  typecast.  For\r\n       example, suppose it is desired to access a memory-mapped i/o\r\n       device, consisting of several  registers.  The  declarations\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 14                              HI-TECH C USER'S MANUAL\r\n\r\n   and use may look something like the code fragment in fig. 2.\r\n\r\n   struct io_dev\r\n   {\r\n           short   io_status;    /* status */\r\n           char    io_rxdata;    /* rx data */\r\n           char    io_txdata;    /* tx data */\r\n   };\r\n\r\n   #define RXRDY   01           /* rx ready */\r\n   #define TXRDY   02           /* tx ready */\r\n\r\n   /* define the (absolute) device address */\r\n\r\n   #define DEVICE  ((struct io_dev *)0xFF00)\r\n\r\n   send_byte(c)\r\n   char c;\r\n   {\r\n           /* wait till transmitter ready */\r\n           while(!(DEVICE->io_status & TXRDY))\r\n                   continue;\r\n           /* send the data byte */\r\n           DEVICE->io_txdata = c;\r\n   }\r\n\r\n          Fig. 2. Use of Typecast on an Absolute Address\r\n\r\n\r\n        In this example, the device in question has  a  16  bit\r\n   status  port,  and  two 8 bit data ports. The address of the\r\n   device (i.e. the address of its status  port)  is  given  as\r\n   (hex)0FF00.  This address is typecast to the required struc-\r\n   ture pointer type to enable  use  of  the  structure  member\r\n   names.  The  code generated by this will use absolute memory\r\n   references to access the device, as required.\r\n\r\n        Some examples of right and wrong usage of member  names\r\n   are shown in fig. 3.\r\n\r\n   5.4. Unsigned Types\r\n\r\n        HI-TECH C implements unsigned versions of all  integral\r\n   types;  i.e.   unsigned  char,  short,  int and long.  If an\r\n   unsigned quantity is shifted right, the shift will  be  per-\r\n   formed  as  a  logical  shift,  i.e. bringing zeros into the\r\n   rightmost bits. Similarly right shifts of a signed  quantity\r\n   will sign extend the rightmost bits.\r\n\r\n   5.5. Arithmetic Operations\r\n\r\n        On machines where arithmetic  operations  may  be  per-\r\n   formed   more  efficiently  in  lengths  shorter  than  int,\r\n   operands shorter than int will not be extended to int length\r\n   unless necessary.\r\n\r\n        For example, if two characters are added and the result\r\n   stored  into  another  character,  it  is  only necessary to\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 15\r\n\r\n\r\n       struct fred\r\n       {\r\n             char      a;\r\n             int       b;\r\n       }     s1, * s2;\r\n\r\n       struct bill\r\n       {\r\n               float   c;\r\n               long    b;\r\n       }       x1, * x2;\r\n\r\n       main()\r\n       {\r\n               /* wrong - c is not a member of fred */\r\n               s1.c = 2;\r\n\r\n               /* correct */\r\n               s1.a = 2;\r\n\r\n               /* wrong - s2 is a pointer */\r\n               s2.a = 2;\r\n\r\n               /* correct */\r\n               x2->b = 24L;\r\n\r\n               /* right, but note type conversion\r\n                       from long to int */\r\n               s2->b = x2->b;\r\n       }\r\n\r\n                     Fig. 3. Examples of Member Usage\r\n\r\n       perform arithmetic in 8 bits, since any  overflow  into  the\r\n       top  8 bits will be lost. However, if the sum of two charac-\r\n       ters is stored into an int, the addition should be  done  in\r\n       16 bits to ensure the correct result.\r\n\r\n            In accordance with the draft ANSI standard,  operations\r\n       on  float rather than double quantities will be performed in\r\n       the shorter precision rather than being converted to  double\r\n       precision then back again.\r\n\r\n       5.6. Structure Operations\r\n\r\n            HI-TECH C implements structure  assignments,  structure\r\n       arguments  and structure-valued functions in their full gen-\r\n       erality. The example in fig. 4 is  a  function  returning  a\r\n       structure. Some legal (and illegal) uses of the function are\r\n       also shown.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 16                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n   struct bill\r\n   {\r\n           char    a;\r\n           int     b;\r\n   }\r\n   afunc()\r\n   {\r\n           struct bill     x;\r\n\r\n           return x;\r\n   }\r\n\r\n   main()\r\n   {\r\n           struct bill     a;\r\n\r\n           a = afunc();            /* ok */\r\n           pf(\"%d\", afunc().a);    /* ok */\r\n\r\n           /* illegal, afunc() cannot be assigned\r\n                   to, therefore neither can\r\n                   afunc().a */\r\n           afunc().a = 1;\r\n\r\n           /* illegal, same reason */\r\n           afunc().a++;\r\n   }\r\n\r\n       Fig. 4. Example of a Function Returning a Structure\r\n\r\n   5.7. Enumerated Types\r\n\r\n        HI-TECH C supports enumerated types;  these  provide  a\r\n   structured way of defining named constants.\r\n\r\n        The uses of enumerated types are more  restricted  than\r\n   that  allowed by the Unix C compiler, yet more flexible than\r\n   permitted  by  LINT.  In  particular,   an   expression   of\r\n   enumerated type may be used to dimension arrays, as an array\r\n   index or as the operand of a switch  statement.   Arithmetic\r\n   may  be  performed  on enumerated types, and enumerated type\r\n   expressions may be compared, both for equality and with  the\r\n   relation  operators.  An example of the use of an enumerated\r\n   type is given in fig. 5.\r\n\r\n   5.8. Initialization Syntax\r\n\r\n        Kernighan and Ritchie in \"The C  Programming  Language\"\r\n   state  that  pairs of braces may be omitted from an initial-\r\n   izer in certain contexts; the draft ANSI  standard  provides\r\n   that  a  conforming C program must either include all braces\r\n   in an initializer, or leave them all out. HI-TECH  C  allows\r\n   any  pairs  of braces to be omitted providing that the front\r\n   end of the compiler can determine the  size  of  any  arrays\r\n   being  initialized, and providing that there is no ambiguity\r\n   as to which braces have been omitted. To avoid ambiguity  if\r\n   any  pairs of braces are present then any braces which would\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 17\r\n\r\n\r\n       /* a represents 0, b -> 1 */\r\n       enum fred { a, b, c = 4 };\r\n\r\n       main()\r\n       {\r\n               enum fred       x, y, z;\r\n\r\n               x = z;\r\n               if(x < z)\r\n                       func();\r\n               x = (enum fred)3;\r\n               switch(z) {\r\n               case a:\r\n               case b:\r\n               default:\r\n               }\r\n       }\r\n\r\n                    Fig. 5. Use of an Enumerated Type\r\n\r\n       enclose those braces must also be present. The compiler will\r\n       complain  (\"initialization  syntax\")  if  any  ambiguity  is\r\n       present.\r\n\r\n       5.9. Function Prototypes\r\n\r\n            A new feature of C included in the proposed ANSI for C,\r\n       known  as \"function prototypes\", provides C with an argument\r\n       checking facility, i.e. it allows the compiler to  check  at\r\n       compile  time  that  actual arguments supplied to a function\r\n       invocation  are  consistent  with  the   formal   parameters\r\n       expected  by the function. The feature allows the programmer\r\n       to include in a function  declaration  (either  an  external\r\n       declaration or an actual definition) the types of the param-\r\n       eters to that function.   For  example,  the  code  fragment\r\n       shown in fig. 6 shows two function prototypes.\r\n\r\n            void fred(int, long, char *);\r\n\r\n            char *\r\n            bill(int a, short b, ...)\r\n            {\r\n                    return a;\r\n            }\r\n\r\n                       Fig. 6. Function Prototypes\r\n\r\n\r\n            The first prototype is an external declaration  of  the\r\n       function  fred(),  which  accepts  one integer argument, one\r\n       long argument, and one argument which is a pointer to  char.\r\n       Any  usage  of  fred() while the prototype declaration is in\r\n       scope will cause the actual parameters  to  be  checked  for\r\n       number  and  type  against  the  prototype, e.g. if only two\r\n       arguments were supplied or an integral  value  was  supplied\r\n       for the third argument the compiler would report an error.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 18                              HI-TECH C USER'S MANUAL\r\n\r\n        In the second example, the function bill() expects  two\r\n   or more arguments. The first and second will be converted to\r\n   int and short respectively, while the remainder (if present)\r\n   may  be  of any type. The ellipsis symbol (...) indicates to\r\n   the compiler that zero or more arguments  of  any  type  may\r\n   follow the other arguments. The ellipsis symbol must be last\r\n   in the argument list, and may not appear as the  only  argu-\r\n   ment in a prototype.\r\n\r\n        All prototypes for a function must agree exactly,  how-\r\n   ever  it  is legal for a definition of a function in the old\r\n   style,  i.e.  with  just  the  parameter  names  inside  the\r\n   parentheses,  to follow a prototype declaration provided the\r\n   number and type of the arguments agree. In this case  it  is\r\n   essential  that  the  function definition is in scope of the\r\n   prototype declaration.\r\n\r\n        Access to unspecified arguments  (i.e.  arguments  sup-\r\n   plied where an ellipsis appeared in a prototype) must be via\r\n   the macros defined  in  the  header  file  <stdarg.h>.  This\r\n   defines the macros va_start, va_arg and va_end. See va_start\r\n   in the library function listing for more information.\r\n\r\n        NOTE that is is a grave error to use a  function  which\r\n   has  an  associated  prototype  unless  that prototype is in\r\n   scope, i.e. the prototype MUST be declared  (possibly  in  a\r\n   header  file)  before  the  function is invoked.  Failure to\r\n   comply with this rule may result in strange behaviour of the\r\n   program.  HI-TECH  C  will  issue a warning message (\"func()\r\n   declared  implicit  int\")  whenever  a  function  is  called\r\n   without  an  explicit  declaration.   It is good practice to\r\n   declare all functions and global variables in  one  or  more\r\n   header  files  which are included wherever the functions are\r\n   defined or referenced.\r\n\r\n   5.10. Void and Pointer to Void\r\n\r\n        The void type may be used to indicate to  the  compiler\r\n   that  a  function  does not return a value. Any usage of the\r\n   return value from a void function  will  be  flagged  as  an\r\n   error.\r\n\r\n        The type void *, i.e. pointer to void, may be used as a\r\n   \"universal\"  pointer type. This is intended to assist in the\r\n   writing of general purpose storage allocators and the  like,\r\n   where a pointer is returned which may be assigned to another\r\n   variable of some other pointer type.  The  compiler  permits\r\n   without  typecasting  and  without  reporting  an  error the\r\n   conversion of void * to any  other  pointer  type  and  vice\r\n   versa.  The programmer is advised to use this facility care-\r\n   fully and ensure that any  void  *  value  is  usable  as  a\r\n   pointer  to  any  other type, e.g. the alignment of any such\r\n   pointer should be suitable for storage of any object.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 19\r\n\r\n       5.11. Type qualifiers\r\n\r\n            The ANSI C standard  introduced  the  concept  of  type\r\n       qualifiers to C; these are keywords that qualify the type to\r\n       which they are applied.  The type qualifiers defined by ANSI\r\n       C are const and volatile.  HI-TECH C also implements several\r\n       other type qualifiers.  The extra qualifiers include:\r\n\r\n            far\r\n            near\r\n            interrupt\r\n            fast interrupt\r\n            port\r\n\r\n       Not all versions of the compilers implement all of the extra\r\n       qualifiers.  See  the  machine dependent section for further\r\n       information.\r\n\r\n            When constructing declarations using  type  qualifiers,\r\n       it  is very easy to be confused as to the exact semantics of\r\n       the declaration. A couple of rules-of-thumb will  make  this\r\n       easier.  Firstly, where a type qualifier appears at the left\r\n       of a declaration  it  may  appear  with  any  storage  class\r\n       specifier and the basic type in any order, e.g.\r\n\r\n            static void interrupt   func();\r\n\r\n       is semantically the same as\r\n\r\n            interrupt static void   func();\r\n\r\n\r\n            Where a qualifier appears in this context,  it  applies\r\n       to  the  basic  type  of  the declaration. Where a qualifier\r\n       appears to the right of  one  or  more  '*'  (star)  pointer\r\n       modifiers,  then  you should read the declaration from right\r\n       to left, e.g.\r\n\r\n            char * far fred;\r\n\r\n       should be read as \"fred is a  far  pointer  to  char\".  This\r\n       means  that  fred is qualified by far, not the char to which\r\n       it points. On the other hand,\r\n\r\n            char far * bill;\r\n\r\n       should be read as \"bill is a pointer to a  far  char\",  i.e.\r\n       the  char to which bill points is located in the far address\r\n       space. In the context of the 8086 compiler  this  will  mean\r\n       that  bill  is  a  32  bit  pointer  while  fred is a 16 bit\r\n       pointer. You will hear bill referred to as a \"far  pointer\",\r\n       however the terminology \"pointer to far\" is preferred.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 20                              HI-TECH C USER'S MANUAL\r\n\r\n   5.12. In-line Assembler\r\n\r\n        There are two methods provided  for  in-line  assembler\r\n   code  in  C  programs.   The  first  allows several lines of\r\n   assembler anywhere in a program. This is via  the  #asm  and\r\n   #endasm  preprocessor  directives.   Any lines between these\r\n   two directives will be copied straight through to the assem-\r\n   bler  file  produced  by the compiler. Alternatively you can\r\n   use the asm(\"string\"); construct anywhere a C  statement  is\r\n   expected. The string will be copied through to the assembler\r\n   file. Care should be  taken  with  using  in-line  assembler\r\n   since it may interact with compiler generated code.\r\n\r\n   5.13. Pragma Directives\r\n\r\n        The draft  ANSI  C  standard  provides  for  a  #pragma\r\n   preprocessor  directive that allows compiler implementations\r\n   to control  various  aspects  of  the  compilation  process.\r\n   Currently  HI-TECH  C  only  supports  one  pragma, the pack\r\n   directive. This allows control  over  the  manner  in  which\r\n   members  are  allocated inside a structure. By default, some\r\n   of the compilers (especially the 8086 and  68000  compilers)\r\n   will  align structure members onto even boundaries to optim-\r\n   ize machine accesses. It is sometimes  desired  to  override\r\n   this  to achieve a particular layout inside a structure. The\r\n   pack pragma allows specification of a maximum  packing  fac-\r\n   tor.  For  example,  #pragma pack1(1) will instruct the com-\r\n   piler that no additional padding be inserted between  struc-\r\n   ture  members,  i.e.  that  all members should be aligned on\r\n   boundaries divisible by 1. Similarly  #pragma  pack(2)  will\r\n   allow  alignment  on  boundaries  divisible by 2. In no case\r\n   will use of the pack pragma force a greater  alignment  than\r\n   would have been used for that data type anyway.\r\n\r\n        More that one pack pragma may be used in a program. Any\r\n   use  will  remain  in force until changed by another pack or\r\n   until the end of the file. Do not use a pack  pragma  before\r\n   include files such as <stdio.h> as this will cause incorrect\r\n   declarations of run-time library data structures.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 21\r\n\r\n\r\n       6. Machine Dependencies\r\n\r\n\r\n            HI-TECH C eliminates  many  of  the  machine  dependent\r\n       aspects of C, since it uniformly implements such features as\r\n       unsigned char. There are however certain areas where machine\r\n       dependencies  are  inherent  in  the C language; programmers\r\n       should be aware of these and take  them  into  account  when\r\n       writing portable code.\r\n\r\n            The most obvious of these machine dependencies  is  the\r\n       varying  size of C types; on some machines an int will be 16\r\n       bits, on others it may be 32 bits. HI-TECH C conforms to the\r\n       following  rules,  which represent common practice in most C\r\n       compilers.\r\n\r\n            char    is at least 8 bits\r\n            short   is at least 16 bits\r\n            long    is at least 32 bits\r\n            int     is the same as either short or long\r\n            float   is at least 32 bits\r\n            double  is at least as wide as float\r\n\r\n\r\n            Because of the variable width of an int, it  is  recom-\r\n       mended  that  short  or  long  be  used wherever possible in\r\n       preference to int. The exception to this is where a quantity\r\n       is  required  to  correspond to the natural word size of the\r\n       machine.\r\n\r\n            Another area of machine differences  is  that  of  byte\r\n       ordering;  the ordering of bytes in a short or long can vary\r\n       significantly between machines. There is no easy approach to\r\n       this  problem  other  than  to avoid code which depends on a\r\n       particular ordering. In particular you should avoid  writing\r\n       out  whole  structures  to  a file (via fwrite()) unless the\r\n       file is only to be read by the same  program  then  deleted.\r\n       Different compilers use different amounts of padding between\r\n       structure members, though  this  can  be  modified  via  the\r\n       #pragma pack(n) construct.\r\n\r\n       6.1. Predefined Macros\r\n\r\n            One technique through which machine unavoidable machine\r\n       dependencies  may  be  managed is the predefined macros pro-\r\n       vided by each compiler to identify the target processor  and\r\n       operating system (if any). These are defined by the compiler\r\n       driver  and  may  be  tested  with  conditional  compilation\r\n       preprocessor directives.\r\n\r\n            The macros defined by various compilers are  listed  in\r\n       table 2. These can be used as shown in the example in fig .\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 22                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n           ___________________________________________\r\n          | Macro    Defined_for                     |\r\n          | i8051    8051 processor family           |\r\n          | i8086    8086 processor family           |\r\n          | i8096    8096 processor family           |\r\n          | z80      Z80 processor and derivatives   |\r\n          | m68000   68000 processor family          |\r\n          | m6800    6801, 68HC11 and 6301 processors|\r\n          | m6809    6809 processor                  |\r\n          | DOS      MS-DOS and PC-DOS               |\r\n          | CPM      CP/M-80 and CP/M-86             |\r\n          | TOS      Atari ST                        |\r\n          |__________________________________________|\r\n\r\n\r\n                    Table 2. Predefined Macros\r\n\r\n\r\n        #if     DOS\r\n        char *  filename = \"c:file\";\r\n        #endif  /* DOS */\r\n        #if     CPM\r\n        char *  filename = \"0:B:afile\";\r\n        #endif  /* CPM */\r\n\r\n\r\n\r\n\r\n                     Use this page for notes\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 23\r\n\r\n\r\n       7. Error Checking and Reporting\r\n\r\n\r\n            Errors may be reported by any  pass  of  the  compiler,\r\n       however  in  practice  the  assembler and optimizer will not\r\n       encounter any errors in the generated  code.  The  types  of\r\n       errors  produced by each pass are summarized below.  In gen-\r\n       eral any error will be indentified by the name of the source\r\n       file  in  which  it  was encountered, and the line number at\r\n       which it was detected.  P1 will also nominate  the  name  of\r\n       the function inside which the error was detected.\r\n\r\n            Errors may be redirected to a file with the usual  syn-\r\n       tax, i.e. a 'greater than' symbol ('>') followed by the name\r\n       of a file into which the errors should be written. The  file\r\n       name  may of course be a device name, e.g.  LST: for CP/M or\r\n       PRN for MS-DOS.\r\n\r\n            CPP will report errors relating  to  macro  definitions\r\n       and expansions, as well as conditional compilation.\r\n\r\n            P1 is the pass which reports most errors;  it  performs\r\n       syntax  and  semantic checking of the input, and will report\r\n       both fatal  and  warning  errors  when  encountered.  Syntax\r\n       errors  will  normally  be expressed as \"symbol expected\" or\r\n       \"symbol unexpected\". Semantic errors  may  relate  to  unde-\r\n       clared,  redeclared  or misdeclared variables.  P1 will also\r\n       report variable definitons which are unused or unreferenced.\r\n       These errors are warnings, as are most type checking errors.\r\n\r\n            When P1 encounters errors it will list the source  line\r\n       containing  the  error on the screen, and underneath display\r\n       the error message and an up arrow pointing to the  point  at\r\n       which  the  compiler  detected  the error. In some cases the\r\n       actual cause of the error may be earlier in the line or even\r\n       on previous line.\r\n\r\n            CGEN may occasionally report errors, usually  warnings,\r\n       and  mostly  related  to  unusual combinations of types with\r\n       constants, for example testing if an  unsigned  quantity  is\r\n       less  than  zero. One fatal error produced by CGEN is \"can't\r\n       generate code  for  this  expression\"  and  means  that  the\r\n       expression  currently being compiled is in some way too com-\r\n       plicated to produce code for. This can usually  be  overcome\r\n       by  rewriting the source code. Such errors are rare and will\r\n       occur only for unusual constructs.\r\n\r\n            The linker will report undefined  or  multiply  defined\r\n       symbols.  Note  that  variable  declarations inside a header\r\n       file which is included in more than one source file must  be\r\n       declared as extern, to avoid multiply defined symbol errors.\r\n       These symbols must then be  defined  in  one  and  one  only\r\n       source file.\r\n\r\n            A comprehensive list of error messages is  included  in\r\n       an appendix.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 24                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n                     Use this page for notes\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 25\r\n\r\n\r\n       8. Standard Libraries\r\n\r\n\r\n       8.1. Standard I/O\r\n\r\n            C is a language which does not specify the  I/O  facil-\r\n       ites in the language itself; rather all I/O is performed via\r\n       library routines. In practice this results in  I/O  handling\r\n       which  is  no  less convenient than any other language, with\r\n       the added possibility of customising the I/O for a  specific\r\n       application. For example it is possible to provide a routine\r\n       to replace the standard getchar() (which gets one  character\r\n       from  the  standard input) with a special getchar(). This is\r\n       particulary useful when writing code which is to  run  on  a\r\n       special  hardware  configuration,  while  maintaining a high\r\n       level of compatibility with \"standard\" C I/O.\r\n\r\n            There is in fact a Standard I/O library  (STDIO)  which\r\n       defines  a  portable set of I/O routines. These are the rou-\r\n       tines which are normally used by any C application  program.\r\n       These  routines,  along with other non-I/O library routines,\r\n       are listed in detail in a subsequent section of the manual.\r\n\r\n       8.2. Compatibility\r\n\r\n            The libraries supplied with HI-TECH C are highly compa-\r\n       tible  with  the  ANSI  libraries,  as  well  as the V7 UNIX\r\n       libraries, both at the Standard I/O level and the UNIX  sys-\r\n       tem  call  level.  The Standard I/O library is complete, and\r\n       conforms in all respects with the UNIX Standard I/O library.\r\n       The  library  routines  implementing  UNIX  system call like\r\n       functions are as close as possible to  those  system  calls,\r\n       however  there  are  some  UNIX  system calls that cannot be\r\n       simulated on other systems, e.g.  the link() operation. How-\r\n       ever  the  basic  low  level I/O routines, i.e. open, close,\r\n       read, write and lseek are identical to the UNIX equivalents.\r\n       This  means  that many programs written to run on UNIX, even\r\n       if they do not use Standard I/O, will run with little modif-\r\n       ication when compiled with HI-TECH C.\r\n\r\n       8.3. Libraries for Embedded Systems\r\n\r\n            The cross compilers, designed to produce code for  tar-\r\n       get  systems  without  operating  systems, are supplied with\r\n       libraries implementing a subset of the STDIO functions.  Not\r\n       provided  are  those  functions dealing with files. Included\r\n       are printf(), scanf() etc. These operate by calling two  low\r\n       level  functions  putch and getch() which typically send and\r\n       receive characters via a serial port. Where the compiler  is\r\n       aimed  at  a  single-chip  micro  with on-board UART this is\r\n       used.  The source code for all these functions  is  supplied\r\n       enabling the user to modify it to address a different serial\r\n       port.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 26                              HI-TECH C USER'S MANUAL\r\n\r\n   8.4. Binary I/O\r\n\r\n        On some operating  systems,  notably  CP/M,  files  are\r\n   treated  differently according to whether they contain ASCII\r\n   (i.e. printable) or binary data.  MD-DOS also  suffers  from\r\n   this  problem,  not  due to any lack in the operating system\r\n   itself, but rather because of the hangover from  CP/M  which\r\n   results  in  many programs putting a redundant ctrl-Z at the\r\n   end of files.  Unfortunately there is no  way  to  determine\r\n   which  type  of  data a file contains (except perhaps by the\r\n   name or type of the file, and  this  is  not  reliable).  To\r\n   overcome  this difficulty, there is an extra character which\r\n   may be included in the MODE string to  a  fopen()  call.  To\r\n   open a file for ASCII I/O, the form of the fopen() call is:\r\n\r\n   fopen(\"filename.ext\", \"r\")      /* for reading */\r\n   fopen(\"filename.ext\", \"w\")      /* for writing */\r\n\r\n   To open a file for binary I/O,  the  character  'b'  may  be\r\n   appended to the\r\n\r\n   fopen(\"filename.ext\", \"rb\")\r\n   fopen(\"filename.ext\", \"wb\")\r\n\r\n\r\n        The additional character instructs  the  STDIO  library\r\n   that  this file is to be handled in a strict binary fashion.\r\n   On CP/M or MS-DOS, a file opened in ASCII mode will have the\r\n   following  special character handling performed by the STDIO\r\n   routines:\r\n\r\n   newline\r\n        ('\\n') converted to carriage return/newline on output.\r\n\r\n   return\r\n        ('\\r') ignored on input\r\n\r\n   Ctrl-Z\r\n        interpreted as End-Of-File on input and, for CP/M only,\r\n        appended when closing the file.\r\n\r\n        The special actions performed  on  ASCII  files  ensure\r\n   that  the  file is written in a format compatible with other\r\n   programs handling text files, while eliminating the require-\r\n   ment for any special handling by the user program - the file\r\n   appears to the user program as though it  were  a  UNIX-like\r\n   text file.\r\n\r\n        None of these special actions are performed on  a  file\r\n   opened  in  binary mode.  This is required when handling any\r\n   kind of binary data, to ensure that spurious bytes  are  not\r\n   inserted, and premature EOF's are not seen.\r\n\r\n        Since the binary mode character is  additional  to  the\r\n   normal  mode  character, this usage is quite compatible with\r\n   UNIX C. When compiled on UNIX, the additional character will\r\n   be ignored.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 27\r\n\r\n            A mention here of the  term  `stream'  is  appropriate;\r\n       stream  is used in relation to the STDIO library routines to\r\n       mean the source or sink of bytes (characters) manipulated by\r\n       those  routines.  Thus the FILE pointer supplied as an argu-\r\n       ment to the STDIO routines may be regarded as  a  handle  on\r\n       the  corresponding  stream.   A  stream  may  be viewed as a\r\n       featureless sequence of bytes,  originating  from  or  being\r\n       sent  to  a  device or file or even some other indeterminate\r\n       source. A FILE pointer should not be confused with the 'file\r\n       descriptors'  used  with the low-level I/O functions open(),\r\n       close(), read() and write(). These form an independent group\r\n       of  I/O  functions which perform unbuffered reads and writes\r\n       to files.\r\n\r\n       8.5. Floating Point Library\r\n\r\n            HI-TECH C  supports  floating  point  as  part  of  the\r\n       language,  however  the  Z80  implementation provides single\r\n       precision only; double floats are permitted but are no  dif-\r\n       ferent   to  floats.  In  addition,  the  standard  library,\r\n       LIBC.LIB, does not  contain  any  floating  point  routines.\r\n       These   have   been  separated  out  into  another  library,\r\n       LIBF.LIB. This means that if this library is not searched no\r\n       floating  point  support  routines  will  be linked in, thus\r\n       avoiding any size penalty for the floating point support  if\r\n       it is not used. This is particulary important for printf and\r\n       scanf, and thus LIBF.LIB contains  versions  of  printf  and\r\n       scanf that do support floating point formats.\r\n\r\n            Thus, if floating point is used, a -LF option should be\r\n       used  AFTER the source and/or object files to the C command.\r\n       E.g.:\r\n\r\n            C -V -O x.c y.c z.obj -LF\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 28                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n                     Use this page for notes\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 29\r\n\r\n\r\n       9. Stylistic Considerations\r\n\r\n\r\n            Although it is not the purpose of this  manual  to  set\r\n       out  a coding standard for C, some comments regarding use of\r\n       some of the features of HI-TECH C may be useful.\r\n\r\n       9.1. Member Names\r\n\r\n            Although HI-TECH C allows the same structure  or  union\r\n       member  name to be used in more than one structure or union,\r\n       this may not be allowed  by  another  C  compiler.  To  help\r\n       ensure  portability  of  the  code,  it  is recommended that\r\n       member names all be distinct, and a useful way  of  ensuring\r\n       this  is  to prefix each member name with one or two letters\r\n       derived from the name of the structure itself. An example is\r\n       given in fig. 7.\r\n\r\n       struct tree_node\r\n       {\r\n               struct tree_node *      t_left;\r\n               struct tree_node *      t_right;\r\n               short                   t_operator;\r\n       };\r\n\r\n\r\n                          Fig. 7. Member Naming\r\n\r\n\r\n            Because HI-TECH C insists on use  of  all  intermediate\r\n       names when referencing a member nested inside several struc-\r\n       tures, some simple macro definitions can serve as  a  short-\r\n       hand. An example is given in fig. 8.\r\n\r\n       struct tree_node\r\n       {\r\n           short       t_operator;\r\n           union\r\n           {\r\n               struct tree_node *  t_un_sub[2];\r\n               char *              t_un_name;\r\n               long                t_un_val;\r\n           }   t_un;\r\n       };\r\n\r\n       #define t_left  t_un.t_un_sub[0]\r\n       #define t_right t_un.t_un_sub[1]\r\n       #define t_name  t_un.t_un_name\r\n       #define t_val   t_un.t_un_val\r\n\r\n\r\n                      Fig. 8. Member Name Shorthand\r\n\r\n\r\n            This enables the variant components of the structure to\r\n       be  referred to by short names, while guaranteeing portabil-\r\n       ity and presenting a clean definition of the structure.\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 30                              HI-TECH C USER'S MANUAL\r\n\r\n   9.2. Use of Int\r\n\r\n        It is recommended that the type int be avoided wherever\r\n   possible,  in preference to the types short or long. This is\r\n   because of the variable size of int, whereas short  is  com-\r\n   monly 16 bits and long 32 bits in most C implementations.\r\n\r\n   9.3. Extern Declarations\r\n\r\n        Some compilers permit a non-initialized global variable\r\n   to  be  declared  in  more than one place, with the multiple\r\n   definitions being resolved by the linker as all defining the\r\n   same  thing. HI-TECH C specifically disallows this, since it\r\n   may lead to subtle bugs. Instead, global  variables  may  be\r\n   declared  extern  in as many places as you wish, and must be\r\n   defined in one and one only place. Typically this will  mean\r\n   declaring  global  variables in a header file as extern, and\r\n   defining each variable in the file most  closely  associated\r\n   with that variable.\r\n\r\n        This usage will be portable to  virually  all  other  C\r\n   implementations.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 31\r\n\r\n\r\n       10. Memory Models\r\n\r\n\r\n            With many of the processors supported by the HI-TECH  C\r\n       compilers  there  are more than one address space accessible\r\n       to a program. Typically one address space is more economical\r\n       to  access  than  another,  larger address space. Thus it is\r\n       desirable to be able to tailor a prorgram's use of memory to\r\n       achieve  the greatest economy in addressing (thus minimizing\r\n       program size and maximizing speed) while allowing access  to\r\n       as much memory as the program requires.\r\n\r\n            This concept of different address spaces is not catered\r\n       for  by either K&R or ANSI C (except to recognize the possi-\r\n       bility of  separate  address  spaces  for  code  and  data).\r\n       Without any extensions to the language itself it is possible\r\n       to devise more than one memory model for a given  processor,\r\n       selected  at  compile time. This has the effect of selecting\r\n       one addressing method for all data and/or code. This permits\r\n       the model for a particular program to be chosen depending on\r\n       that program's memory requirements.\r\n\r\n            In many programs, however, only one or two data  struc-\r\n       tures  are  large  enough to need to be placed in the larger\r\n       address space. Selection of a \"large\" memory model  for  the\r\n       whole  of  the  program  makes  the whole program larger and\r\n       slower just to allow a few large data structures.  This  can\r\n       be  overcome by allowing individual selection of the address\r\n       space for each data structure.  Unfortunately  this  entails\r\n       extensions  to  the language, never a desirable approach. To\r\n       minimize the effect of such extensions they  should  satisfy\r\n       the following criteria:\r\n\r\n       1.   As far as possible the extensions should be  consistent\r\n            with common practice.\r\n\r\n       2.   The extensions should fit a  machine-independent  model\r\n            to maximize portability across processors and operating\r\n            systems.\r\n\r\n            These goals have been  achieved  within  HI-TECH  C  by\r\n       means of the following model:\r\n\r\n            Each memory model  defines  three  address  spaces\r\n            each  for code and data.  These address spaces are\r\n            known as the near, far  and  default  spaces.  Any\r\n            object  qualified  by  the  near  keyword  will be\r\n            placed in the near address space, any object qual-\r\n            ified  by  the  far keyword shall be placed in the\r\n            far address space, and all other objects shall  be\r\n            placed  in  the  default  address  space. The near\r\n            address space shall be a (possibly improper)  sub-\r\n            space  of  the  default  address  space, while the\r\n            default  address  space  shall  be   a   (possibly\r\n            improper) subspace of the far address space. There\r\n            shall be up to three kinds of pointers correspond-\r\n            ing  to  the three address spaces, each capable of\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 32                              HI-TECH C USER'S MANUAL\r\n\r\n        addressing an object in its own address space or a\r\n        subspace of that address space.\r\n\r\n        This implies that the address of an object may be  con-\r\n   verted to a pointer into a larger address space, e.g. a near\r\n   object may have its address converted to a pointer  to  far,\r\n   but  a  far  object  may  not  be  able to be addressed by a\r\n   pointer to near.\r\n\r\n        In practice the  default  address  space  will  usually\r\n   correspond exactly to either the near or far address spaces.\r\n   If all three address spaces correspond to  the  same  memory\r\n   then  there  is  only one memory model possible. This occurs\r\n   with the 68000 processor. Where the default  code  and  data\r\n   spaces may each correspond to either the near or far address\r\n   spaces then there will be a total  of  four  memory  models.\r\n   This is the case with the 8086 processor.\r\n\r\n        The keywords far and near are supported by all the  HI-\r\n   TECH  C  compilers,  but the exact correspondence of address\r\n   spaces is determined by the  individual  characteristics  of\r\n   each processor and the choice of memory model (if there is a\r\n   choice). However code written using these keywords  will  be\r\n   portable  providing  it  obeys  the constraints of the model\r\n   described above.\r\n\r\n        This model also corresponds well with other implementa-\r\n   tions  using the near and far keywords, although such imple-\r\n   mentations do not appear to have been designed around a for-\r\n   mal, portable model.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 33\r\n\r\n\r\n       11. What Went Wrong\r\n\r\n\r\n            There are numerous error messages that the compiler may\r\n       produce.  Most  of these relate to errors in the source code\r\n       (syntax errors of various  kinds  and  so  forth)  but  some\r\n       represent  limitations,  particularly  of  memory.  The  two\r\n       passes most likely to be affected by memory limitations  are\r\n       the  code  generator  and  the optimizer. The code generator\r\n       will issue the message \"No room\" if it runs out  of  dynamic\r\n       memory.  This  can  usually be eliminated by simplifying the\r\n       expression at the line nominated in the error  message.  The\r\n       more  complex the expression, the more memory is required to\r\n       store the tree representing it. Reducing the number of  sym-\r\n       bols used in the program will also help.\r\n\r\n            Note that this error  is  different  from  the  message\r\n       \"Can't  generate  code  for this expression\" which indicates\r\n       that the expression is in some way  too  difficult  for  the\r\n       code  generator  to handle. This message will be encountered\r\n       very infrequently, and can be  eliminated  by  changing  the\r\n       expression in some way, e.g. computing an intermediate value\r\n       into a temporary variable.\r\n\r\n            The optimizer reads the  assembler  code  for  a  whole\r\n       function  into memory at one time. Very large functions will\r\n       not fit, giving the error message \"Optim: out of  memory  in\r\n       _func\"  where  func is the name of the function responsible.\r\n       In this case the function should be broken up  into  smaller\r\n       functions.  This will only occur with functions with several\r\n       hundred lines of C source code. Good  coding  practice  will\r\n       normally limit functions to less than 50 lines each.\r\n\r\n            If a pass exits with the message \"Error closing  file\",\r\n       or  \"Write error on file\", this usually indicates that there\r\n       is insufficient room on the current disk.\r\n\r\n            If you use a wordprocessing editor  such  as  Wordstar,\r\n       ensure  that you use the \"non-document\" mode or whatever the\r\n       corresponding mode is. The edited file  should  not  contain\r\n       any  characters  with the high bit set, and the line feed at\r\n       the end of the line must be present.  Lines  should  be  not\r\n       more than 255 characters long.\r\n\r\n            When using floating point, ensure that you  use  a  -LF\r\n       flag  at  the END of the command line, to cause the floating\r\n       point library to be searched. This will cause floating  ver-\r\n       sions  of  printf  and  scanf  to  be  linked in, as well as\r\n       specific floating point routines.\r\n\r\n            If the non-floating version of printf is  used  with  a\r\n       floating  format  such  as  %f then it will simply print the\r\n       letter f.\r\n\r\n            If the linker gives an \"Undefined symbol\"  message  for\r\n       some  symbol  which  you  know nothing about, it is possible\r\n       that it is a library routine which was not found during  the\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 34                              HI-TECH C USER'S MANUAL\r\n\r\n   library  search  due  to incorrect library ordering. In this\r\n   case you can search the library twice, e.g.  for  the  stan-\r\n   dard  library add a -LC to the end of the C command line, or\r\n   -LF for the floating library.  If  you  have  specified  the\r\n   library by name simply repeat its name.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 35\r\n\r\n\r\n       12. Z80 Assembler Reference Manual\r\n\r\n\r\n       12.1. Introduction\r\n\r\n            The assembler incorporated in the  HI-TECH  C  compiler\r\n       system is a full-featured relocating macro assembler accept-\r\n       ing Zilog mnemonics. These mnemonics and the syntax  of  the\r\n       Z80  assembly  language  are  described in the \"Z80 Assembly\r\n       Language Handbook\" published by Zilog and  are  included  at\r\n       the  end of this manual as a reference. The assembler imple-\r\n       ments certain extensions to the operands allowed,  and  cer-\r\n       tain  additional  pseudo-ops, which are described here.  The\r\n       assembler also accepts the additional opcodes for the  Hita-\r\n       chi 64180 and Z180 processors.\r\n\r\n       12.2. Usage\r\n\r\n            The assembler is named zas, and is invoked as follows:\r\n\r\n            ZAS options files ...\r\n\r\n\r\n            The files are one or more assembler source files  which\r\n       will be assembled, but note that all the files are assembled\r\n       as one, not as separate files.  To assemble separate  files,\r\n       the  assembler  must be invoked on each file separately. The\r\n       options are zero or more options from the following list:\r\n\r\n       -N   Ignore arithmetic  overflow  in  expressions.   The  -N\r\n            option suppresses the normal check for arithmetic over-\r\n            flow. The assembler follows the \"Z80 Assembly  Language\r\n            Handbook\"  in its treatment of overflow, and in certain\r\n            instances this can lead to an error where in  fact  the\r\n            expression  does  evaluate  to  what the user intended.\r\n            This option may be used to override the overflow check-\r\n            ing.\r\n\r\n       -J   Attempt to optimize jumps to branches.  The  -J  option\r\n            will request the assembler to attempt to assemble jumps\r\n            and conditional jumps as relative branches where possi-\r\n            ble.   Only   those   conditional   jumps  with  branch\r\n            equivalents will be optimized, and jumps will  only  be\r\n            optimized  to  branches  where  the target is in branch\r\n            range. Note that the  use  of  this  option  slows  the\r\n            assembly  down,  due to the necessity for the assembler\r\n            to make an additional pass over the input code.\r\n\r\n       -U   Treat undefined symbols as  external.   The  -U  option\r\n            will suppress error messages relating to undefined sym-\r\n            bols. Such symbols are  treated  as  externals  in  any\r\n            case.  The use of this option will not alter the object\r\n            code generated, but merely serves to suppress the error\r\n            messages.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 36                              HI-TECH C USER'S MANUAL\r\n\r\n   -Ofile\r\n        Place the object code in file.  The default object file\r\n        name  is  constructed from the name of the first source\r\n        file. Any suffix or file type (i.e. anything  following\r\n        the  rightmost  dot  ('.') in the name is stripped, and\r\n        the suffix .obj appended. Thus the command\r\n\r\n             ZAS file1.as file2.z80\r\n\r\n        will produce an object file called file1.obj.  The  use\r\n        of the -O option will override this default convention,\r\n        allowing the object file to be arbitrarily  named.  For\r\n        example:\r\n\r\n             ZAS -ox.obj file1.obj\r\n\r\n        will place the object code in x.obj.\r\n\r\n   -Llist\r\n        Place an assembly listing in the file list, or on stan-\r\n        dard  output if list is null A listfile may be produced\r\n        with the -L option. If a file name is supplied  to  the\r\n        option,  the  list file will be created with that name,\r\n        otherwise the listing will be written to standard  out-\r\n        put  (i.e.  the  console). List file names such as CON:\r\n        and LST: are acceptable.\r\n\r\n   -Wwidth\r\n        The listing is to be formatted for a printer  of  given\r\n        width  The  -W  option specifies the width to which the\r\n        listing is to be formatted. E.g.\r\n\r\n             ZAS -Llst: -W80 x.as\r\n\r\n        will output  a  listing  formatted  for  an  80  column\r\n        printer to the list device.\r\n\r\n   -C   This options requests ZAS to  produce  cross  reference\r\n        information  in a file. The file will be called xxx.crf\r\n        where xxx is the base part of  the  first  source  file\r\n        name. It will then be necessary to run the CREF utility\r\n        to turn this information into a formatted listing.\r\n\r\n   12.3. The Assembly Language\r\n\r\n        As mentioned above, the assembly language  accepted  by\r\n   zas  is  based  on the Zilog mnemonics. You should have some\r\n   reference book such as the \"Z80 Assembly Language Handbook\".\r\n   Described below are those areas in which zas differs, or has\r\n   extensions,  compared  to  the   standard   Zilog   assembly\r\n   language.\r\n\r\n   12.3.1. Symbols\r\n\r\n        The symbols (labels) accepted by the assembler  may  be\r\n   of any length, and all characters are significant. The char-\r\n   acters used to form a symbol may be chosen  from  the  upper\r\n   and  lower case alphabetics, the digits 0-9, and the special\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 37\r\n\r\n       symbols underscore ('_'), dollar  ('$')  and  question  mark\r\n       ('?').  The  first  character  may not be numeric. Upper and\r\n       lower case are distinct. The following  are  all  legal  and\r\n       distinct symbols.\r\n\r\n            An_identifier\r\n            an_identifier\r\n            an_identifier1\r\n            $$$\r\n            ?$_123455\r\n\r\n\r\n            Note that the symbol $  is  special  (representing  the\r\n       current  location)  and  may not be used as a label. Nor may\r\n       any opcode or pseudo-op mnemonic, register name or condition\r\n       code  name.   You  should note the additional condition code\r\n       names described later.\r\n\r\n       12.3.1.1. Temporary Labels\r\n\r\n            The assembler implements a system of temporary  labels,\r\n       useful  for  use  within  a localized section of code. These\r\n       help eliminate the need to generate names for  labels  which\r\n       are  referenced  only  in  the  immediate  vicinity of their\r\n       definition, for example where a loop is implemented.\r\n\r\n            A temporary label takes the form of a digit  string.  A\r\n       reference  to  such  a label requires the same digit string,\r\n       plus an appended b or f to signify  a  backward  or  forward\r\n       reference  respectively.  Here  is  an example of the use of\r\n       such labels.\r\n\r\n       entry_point:   ;This is referenced from far away\r\n           ld   b,10\r\n       1:  dec  c\r\n           jr   nz,2f ;if zero, branch forward to 2:\r\n           ld   c,8\r\n           djnz 1b    ;decrement and branch back to 1:\r\n           jr   1f    ;this does not branch to the\r\n                      ;same label as the djnz\r\n       2:  call fred  ;get here from the jr nz,2f\r\n       1:  ret        ;get here from the jr 1f\r\n\r\n\r\n            The digit string may be any positive decimal  number  0\r\n       to  65535. A temporary label value may be re-used any number\r\n       of times. Where a reference to e.g.  1b is made,  this  will\r\n       reference  the  closest  label 1: found by looking backwards\r\n       from the current point  in  the  file.  Similarly  23f  will\r\n       reference the first label 23: found by looking forwards from\r\n       the current point in the file.\r\n\r\n       12.3.2. Constants\r\n\r\n            Constants may be entered in one of the radices 2, 8, 10\r\n       or 16. The default is 10. Constants in the other radices may\r\n       be denoted by a trailing character drawn from the  following\r\n       set:\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 38                              HI-TECH C USER'S MANUAL\r\n\r\n                 Character   Radix   Name\r\n\r\n                 B           2       binary\r\n                 O           8       octal\r\n                 Q           8       octal\r\n                 o           8       octal\r\n                 q           8       octal\r\n                 H           16      hexadecimal\r\n                 h           16      hexadecimal\r\n\r\n\r\n        Hexadecimal constants may also be specified in C style,\r\n   for  example LD A,0x21.  Note that a lower case b may not be\r\n   used to indicate a binary number, since  1b  is  a  backward\r\n   reference to a temporary label 1:.\r\n\r\n   12.3.2.1. Character Constants\r\n\r\n        A character constant is a single character enclosed  in\r\n   single  quotes  (').  Multi  character constants may be used\r\n   only as an operand to a DEFM pseudo-op.\r\n\r\n   12.3.2.2. Floating Constants\r\n\r\n        A floating constant in the usual notation  (e.g.  1.234\r\n   or 1234e-3) may be used as the operand to a DEFF pseudo-op.\r\n\r\n   12.3.2.3. Opcode Constants\r\n\r\n        Any z80 opcode may be used as a constant in an  expres-\r\n   sion.  The  value  of the opcode in this context will be the\r\n   byte that the opcode would have assembled to if used in  the\r\n   normal  way. If the opcode is a 2-byte opcode (CB or ED pre-\r\n   fix byte) only the second byte of the opcode will  be  used.\r\n   This  is  particularly  useful when setting up jump vectors.\r\n   For example:\r\n\r\n   ld   a,jp         ;a jump instruction\r\n   ld   (0),a        ;0 is jump to warm boot\r\n   ld   hl,boot      ;done here\r\n   ld   (1),hl\r\n\r\n\r\n   12.3.3. Expressions\r\n\r\n        Expressions are constructed largely as described in the\r\n   \"Z80 Assembly Language Handbook\".\r\n\r\n   12.3.3.1. Operators\r\n\r\n        The following operators may be used in expressions:\r\n\r\n                 Operator   Meaning\r\n\r\n                 &          Bitwise AND\r\n                 *          Multiplication\r\n                 +          Addition\r\n                 -          Subtraction\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 39\r\n\r\n                     .and.      Bitwise AND\r\n                     .eq.       Equality test\r\n                     .gt.       Signed greater than\r\n                     .high.     Hi byte of operand\r\n                     .low.      Low byte of operand\r\n                     .lt.       Signed less than\r\n                     .mod.      Modulus\r\n                     .not.      Bitwise complement\r\n                     .or.       Bitwise or\r\n                     .shl.      Shift left\r\n                     .shr.      Shift right\r\n                     .ult.      Unsigned less than\r\n                     .ugt.      Unsigned greater than\r\n                     .xor.      Exclusive or\r\n                     /          Divison\r\n                     <          Signed less than\r\n                     =          Equality\r\n                     >          Signed greater than\r\n                     ^          Bitwise or\r\n\r\n\r\n            Operators starting with a dot \".\" should  be  delimited\r\n       by  spaces,  thus  label .and. 1 is valid but label.and.1 is\r\n       not.\r\n\r\n       12.3.3.2. Relocatability\r\n\r\n            Zas produces object code  which  is  relocatable;  this\r\n       means  that  it  is  not  necessary to specify assembly time\r\n       where the code is to be located in memory. It is possible to\r\n       do  so,  by  use of the ORG pseudo-op, however the preferred\r\n       approach is to use program sections or psects. A psect is  a\r\n       named  section  of the program, in which code or data may be\r\n       defined at assembly time. All  parts  of  a  psect  will  be\r\n       loaded  contiguously  into memory, even if they were defined\r\n       in separate files, or in the same file but separated by code\r\n       for another psect. For example, the following code will load\r\n       some executable instructions into the psect named text,  and\r\n       some data bytes into the data psect.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 40                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n            psect text, global\r\n\r\n        alabel:\r\n            ld    hl,astring\r\n            call  putit\r\n            ld    hl,anotherstring\r\n\r\n            psect data, global\r\n        astring:\r\n            defm  'A string of chars'\r\n            defb  0\r\n        anotherstring:\r\n            defm  'Another string'\r\n            defb  0\r\n\r\n            psect text\r\n\r\n        putit:\r\n            ld    a,(hl)\r\n            or    a\r\n            ret   z\r\n            call  outchar\r\n            inc   hl\r\n            jr    putit\r\n\r\n\r\n        Note that even though the two blocks  of  code  in  the\r\n   text  psect  are separated by a block in the data psect, the\r\n   two text psect blocks will be contiguous when loaded by  the\r\n   linker.  The  instruction  \"ld  hl,anotherstring\"  will fall\r\n   through to the label \"putit:\" during execution.  The  actual\r\n   location  in  memory of the two psects will be determined by\r\n   the linker. See the linker manual  for  information  on  how\r\n   psect addresses are determined.\r\n\r\n        A label defined in a psect is said to  be  relocatable,\r\n   that  is,  its  actual  memory  address is not determined at\r\n   assembly time. Note that this does not apply if the label is\r\n   in the default (unnamed) psect, or in a psect declared abso-\r\n   lute (see  the  PSECT  pseudo-op  description  below).   Any\r\n   labels  declared in an absolute psect will be absolute, that\r\n   is their address will be determined by the assembler.\r\n\r\n        With the version of ZAS  supplied  with  version  7  or\r\n   later  of HI-TECH C, relocatable expressions may be combined\r\n   freely in expressions.  Older versions of ZAS  allowed  only\r\n   limited arithmetic on relocatable expressions.\r\n\r\n   12.3.4. Pseudo-ops\r\n\r\n        The pseudo-ops are based on those described in the \"Z80\r\n   Assembly Language Handbook\", with some additions.\r\n\r\n   12.3.4.1. DEFB, DB\r\n\r\n        This pseudo-op should be followed by a  comma-separated\r\n   list of expressions, which will be assembled into sequential\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 41\r\n\r\n       byte locations. Each expression must have  a  value  between\r\n       -128  and  255  inclusive.   DB can be used as a synonym for\r\n       DEFB.  Example:\r\n\r\n           DEFB  10, 20, 'a', 0FFH\r\n           DB    'hello world',13,10,0\r\n\r\n\r\n\r\n       12.3.4.2. DEFF\r\n\r\n            This pseudo-op assembles floating point constants  into\r\n       32 bit HI-TECH C format floating point constants.  For exam-\r\n       ple:\r\n\r\n       pi: DEFF  3.14159\r\n\r\n\r\n\r\n       12.3.4.3. DEFW\r\n\r\n            This operates in a similar fashion to DEFB, except that\r\n       it  assembles expressions into words, without the value res-\r\n       triction.  Example:\r\n\r\n           DEFW  -1, 3664H, 'A', 3777Q\r\n\r\n\r\n\r\n       12.3.4.4. DEFS\r\n\r\n            Defs reserves  memory  locations  without  initializing\r\n       them.  Its  operand  is an absolute expression, representing\r\n       the number of bytes to  be  reserved.   This  expression  is\r\n       added  to  the  current  location counter. Note however that\r\n       locations reserved by DEFS may be initialized to zero by the\r\n       linker  if  the  reserved locations are in the middle of the\r\n       program.  Example:\r\n\r\n           DEFS  20h   ;reserve 32 bytes of memory\r\n\r\n\r\n\r\n       12.3.4.5. EQU\r\n\r\n            Equ sets the value of a symbol on the left  of  EQU  to\r\n       the  expression on the right. It is illegal to set the value\r\n       of a symbol which is already defined.  Example:\r\n\r\n       SIZE      equ   46\r\n\r\n\r\n\r\n       12.3.4.6. DEFL\r\n\r\n            This is identical to EQU except that  it  may  redefine\r\n       existing symbols.  Example:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 42                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n   SIZE      defl  48\r\n\r\n\r\n\r\n   12.3.4.7. DEFM\r\n\r\n        Defm should be followed  by  a  string  of  characters,\r\n   enclosed  in single quotes.  The ASCII values of these char-\r\n   acters  are  assembled  into  successive  memory  locations.\r\n   Example:\r\n\r\n       DEFM  'A string of funny *@$ characters'\r\n\r\n\r\n\r\n   12.3.4.8. END\r\n\r\n        The end of an assembly is signified by the end  of  the\r\n   source  file,  or  the  END pseudo-op. The END pseudo-op may\r\n   optionally be followed by an expression  which  will  define\r\n   the  start address of the program. This is not actually use-\r\n   ful for CP/M. Only one start address may be defined per pro-\r\n   gram, and the linker will complain if there are more.  Exam-\r\n   ple:\r\n\r\n       END   somelabel\r\n\r\n\r\n\r\n   12.3.4.9. COND, IF, ELSE, ENDC\r\n\r\n        Conditional assembly is introduced by the COND  pseudo-\r\n   op.  The  operand to COND must be an absolute expression. If\r\n   its value is false (zero) the code following the COND up  to\r\n   the  corresponding  ENDC  pseudo-op  will  not be assembled.\r\n   COND/ENDC pairs may be nested.  IF may be used as a  synonym\r\n   for  COND.  The ELSE pseudo operation may be included within\r\n   a COND/ENDC block, for example:\r\n\r\n       IF    CPM\r\n       call  5\r\n       ELSE\r\n       call  os_func\r\n       ENDC\r\n\r\n\r\n\r\n   12.3.4.10. ELSE\r\n\r\n        See COND.\r\n\r\n   12.3.4.11. ENDC\r\n\r\n        See COND.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 43\r\n\r\n       12.3.4.12. ENDM\r\n\r\n            See MACRO.\r\n\r\n       12.3.4.13. PSECT\r\n\r\n            This pseudo-op allows specification of relocatable pro-\r\n       gram  sections.  Its  arguments are a psect name, optionally\r\n       followed by a list of psect flags.  The psect name is a sym-\r\n       bol  constructed  according to the same rules as for labels,\r\n       however a psect may have the same name as  a  label  without\r\n       conflict.  Psect  names  are  recognized  only after a PSECT\r\n       pseudo-op.  The psect flags are as follows:\r\n\r\n            ABS       Psect is absolute\r\n\r\n            GLOBAL    Psect is global\r\n\r\n            LOCAL           Psect is not global\r\n\r\n            OVRLD     Psect is to be overlapped by linker\r\n\r\n            PURE            Psect is to be read-only\r\n\r\n\r\n            If a psect is global, the linker will merge it with any\r\n       other  global  psects  of  the same name from other modules.\r\n       Local psects will be treated  as  distinct  from  any  other\r\n       psect from another module. Psects are global by default.\r\n\r\n            By default the linker concatenates code within a  psect\r\n       from  various modules. If a psect is specified as OVRLD, the\r\n       linker will  overlap  each  module's  contribution  to  that\r\n       psect.  This  is  particularly  useful  when linking modules\r\n       which initialize e.g. interrupt vectors.\r\n\r\n            The PURE flag instructs the linker that the psect is to\r\n       be  made  read-only at run time. The usefulness of this flag\r\n       depends on the ability of the linker to enforce the require-\r\n       ment. CP/M fails miserably in this regard.\r\n\r\n            The ABS flag makes a psect absolute. The psect will  be\r\n       loaded  at zero.  This is useful for statically initializing\r\n       interrupt vectors and jump tables.  Examples:\r\n\r\n\r\n            PSECT     text, global, pure\r\n            PSECT     data, global\r\n            PSECT     vectors, ovrld\r\n\r\n\r\n\r\n       12.3.4.14. GLOBAL\r\n\r\n            Global should be followed by one  more  symbols  (comma\r\n       separated)  which will be treated by the assembler as global\r\n       symbols, either internal or external  depending  on  whether\r\n       they are defined within the current module or not.  Example:\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 44                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n       GLOBAL      label1, putchar, _printf\r\n\r\n\r\n\r\n   12.3.4.15. ORG\r\n\r\n        An ORG pseudo-op sets the current psect to the  default\r\n   (absolute)  psect,  and the location counter to its operand,\r\n   which must be an absolute expression.  Example:\r\n\r\n       ORG   100H\r\n\r\n\r\n\r\n   12.3.4.16. MACRO\r\n\r\n        This pseudo-op defines a macro.  It  should  be  either\r\n   preceded or followed by the macro name, then optionally fol-\r\n   lowed by a comma-separated list of formal  parameters.   The\r\n   lines  of  code following the MACRO pseudo-op up to the next\r\n   ENDM pseudo-op will be stored as the body of the macro.  The\r\n   macro name may subsequently be used in the opcode part of an\r\n   assembler statement, followed by actual parameters. The text\r\n   of  the body of the macro will be substituted at that point,\r\n   with any use of the formal parameters substituted  with  the\r\n   corresponding actual parameter. For example:\r\n\r\n   print     MACRO string\r\n       psect data\r\n   999:      db    string,'$'\r\n       psect text\r\n       ld    de,999b\r\n       ld    c,9\r\n       call  5\r\n       ENDM\r\n\r\n\r\n\r\n        When used, this macro will expand to the 3 instructions\r\n   in the body of the macro, with the actual parameters substi-\r\n   tuted for func and arg. Thus\r\n\r\n       print 'hello world'\r\n\r\n\r\n   expands to\r\n\r\n       psect data\r\n   999:      db    'hello world','$'\r\n       psect text\r\n       ld    de,999b\r\n       ld    c,9\r\n       call  5\r\n\r\n\r\n\r\n        Macro arguments can be enclosed in angle brackets  ('<'\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 45\r\n\r\n       and  '>') to pass arbitrary text including delimiter charac-\r\n       ters like commas as a single argument.  For example, suppose\r\n       you  wanted  to use the print macro defined above to print a\r\n       string which includes the carriage return and linefeed char-\r\n       acters.  The macro invocation:\r\n\r\n           print 'hello world',13,10\r\n\r\n\r\n       would fail because 13 and 10 are treated as extra  arguments\r\n       and ignored. In order to pass a string which includes commas\r\n       as a single argument, you could write:\r\n\r\n           print <'hello world',13,10>\r\n\r\n\r\n       which would cause the text 'hello world',13,10 to be  passed\r\n       through as a single argument.  This would expand to the fol-\r\n       lowing code:\r\n\r\n           psect data\r\n       999:      db    'hello world',13,10,'$'\r\n           psect text\r\n           ld    de,999b\r\n           ld    c,9\r\n           call  5\r\n\r\n\r\n\r\n            ZAS supports two forms of macro declaration for  compa-\r\n       tibility  with  older  versions  of ZAS and other Z80 assem-\r\n       blers.  The macro name may be declared either in  the  label\r\n       field  before  the  MACRO pseudo-op, or in the operand field\r\n       after the MACRO pseudo-op.  Thus these  two  MACRO  declara-\r\n       tions are equivalent:\r\n\r\n       bdos      MACRO func,arg\r\n           ld    de,arg\r\n           ld    c,func\r\n           call  5\r\n           ENDM\r\n\r\n       and\r\n\r\n           MACRO bdos,func,arg\r\n           ld    de,arg\r\n           ld    c,func\r\n           call  5\r\n           ENDM\r\n\r\n\r\n\r\n       12.3.4.17. LOCAL\r\n\r\n            The LOCAL pseudo-op allows unique labels to be  defined\r\n       for each expansion of a macro.  Any symbols listed after the\r\n       LOCAL directive will have a unique assembler-generated  sym-\r\n       bol  substituted  for  them when the macro is expanded.  For\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 46                              HI-TECH C USER'S MANUAL\r\n\r\n   example:\r\n\r\n   copy      MACRO source,dest,count\r\n       LOCAL nocopy\r\n       push  af\r\n       push  bc\r\n       ld    bc,source\r\n       ld    a,b\r\n       or    c\r\n       jr    z,nocopy\r\n       push  de\r\n       push  hl\r\n       ld    de,dest\r\n       ld    hl,source\r\n       ldir\r\n       pop   hl\r\n       pop   de\r\n   nocopy:   pop   bc\r\n       pop   af\r\n       ENDM\r\n\r\n\r\n   when expanded will  include  a  unique  assembler  generated\r\n   label    in    place   of   nocopy.    For   example,   copy\r\n   (recptr),buf,(recsize) will expand to:\r\n\r\n       push  af\r\n       push  bc\r\n       ld    bc,(recsize)\r\n       ld    a,b\r\n       or    c\r\n       jr    z,??0001\r\n       push  de\r\n       push  hl\r\n       ld    de,buf\r\n       ld    hl,(recptr)\r\n       ldir\r\n       pop   hl\r\n       pop   de\r\n   ??0001:   pop   bc\r\n       pop   af\r\n\r\n   if invoked a second time, the label nocopy would  expand  to\r\n   ??0002.\r\n\r\n   12.3.4.18. REPT\r\n\r\n        The REPT pseudo-op defines a temporary macro  which  is\r\n   then  expanded a number of times, as determined by its argu-\r\n   ment.  For example:\r\n\r\n       REPT  3\r\n       ld    (hl),0\r\n       inc   hl\r\n       ENDM\r\n\r\n\r\n   will expand to\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 47\r\n\r\n\r\n           ld    (hl),0\r\n           inc   hl\r\n           ld    (hl),0\r\n           inc   hl\r\n           ld    (hl),0\r\n           inc   hl\r\n\r\n\r\n\r\n       12.3.5. IRP and IRPC\r\n\r\n            The IRP and IRPC directives are similar to  REPT,  how-\r\n       ever  instead of repeating the block a fixed number of times\r\n       it is repeated once for each member of an argument list.  In\r\n       the  case  of  IRP the list is a conventional macro argument\r\n       list, in the case of IRPC it is successive characters from a\r\n       string.  For example:\r\n\r\n           IRP   string,<'hello world',13,10>,'arg2'\r\n           LOCAL str\r\n           psect data\r\n       str:      db    string,'$'\r\n           psect text\r\n           ld    c,9\r\n           ld    de,str\r\n           call  5\r\n           ENDM\r\n\r\n\r\n       would expand to\r\n\r\n           psect data\r\n       ??0001:   db    'hello world',13,10,'$'\r\n           psect text\r\n           ld    c,9\r\n           ld    de,??0001\r\n           call  5\r\n           psect data\r\n       ??0002:   db    'arg2','$'\r\n           psect text\r\n           ld    c,9\r\n           ld    de,??0002\r\n           call  5\r\n\r\n\r\n       Note the use of LOCAL labels and angle brackets in the  same\r\n       manner as with conventional macros.\r\n\r\n            IRPC is best demonstrated using the following example:\r\n\r\n           IRPC  char,ABC\r\n           ld    c,2\r\n           ld    e,'char'\r\n           call  5\r\n           ENDM\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 48                              HI-TECH C USER'S MANUAL\r\n\r\n   will expand to:\r\n\r\n       ld    c,2\r\n       ld    e,'A'\r\n       call  5\r\n       ld    c,2\r\n       ld    e,'B'\r\n       call  5\r\n       ld    c,2\r\n       ld    e,'C'\r\n       call  5\r\n\r\n\r\n\r\n   12.3.6. Extended Condition Codes\r\n\r\n        The assembler recognizes several  additional  condition\r\n   codes. These are:\r\n\r\n        _________________________________________________\r\n       | Code|  Equivalent|  Meaning                    |\r\n       | alt |  m         |  Arithmetic less than       |\r\n       | llt |  c         |  Logical less than          |\r\n       | age |  p         |  Arithmetic greater or equal|\r\n       | lge |  nc        |  Logical greater or equal   |\r\n       | di  |            |  Use after ld a,i for  test-|\r\n       | ei  |            |  ing   state   of  interrupt|\r\n       |     |            |  enable flag  -  enabled  or|\r\n       |_____|____________|__disabled_respectively._____|\r\n\r\n\r\n   12.4. Assembler Directives\r\n\r\n        An assembler directive is a line  in  the  source  file\r\n   which  produces  no  code,  but  rather  which  modifies the\r\n   behaviour of the assembler. Each directive is recognized  by\r\n   the presence of an asterisk in the first column of the line,\r\n   followed immediately by a word, only the first character  of\r\n   which is looked at. the line containing the directive itself\r\n   is never listed.  The directives are:\r\n\r\n   *Title\r\n        Use the text following the directive as a title for the\r\n        listing.\r\n\r\n   *Heading\r\n        Use the text following the directive as a subtitle  for\r\n        the listing; also causes an *Eject.\r\n\r\n   *List\r\n        May be followed by ON or OFF to turn listing on or  off\r\n        respectively.  Note  that  this  directive  may be used\r\n        inside a macro or include file to  control  listing  of\r\n        that macro or include file.  The previous listing state\r\n        will be restored on exit  from  the  macro  or  include\r\n        file.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 49\r\n\r\n       *Include\r\n            The file named following the directive will be included\r\n            in the assembly at that point.\r\n\r\n       *Eject\r\n            A new page will be  started  in  the  listing  at  that\r\n            point.  A  form  feed character in the source will have\r\n            the same effect.\r\n\r\n            Some examples of the use of these directives:\r\n\r\n\r\n            *Title Widget Control Program\r\n            *Heading Initialization Phase\r\n\r\n            *Include widget.i\r\n\r\n\r\n\r\n       12.5. Diagnostics\r\n\r\n            An error message will be written on the standard  error\r\n       stream for each error encountered in the assembly. This mes-\r\n       sage identifies the file name and line number and  describes\r\n       the  error.  In  addition  the line in the listing where the\r\n       error occurred will be flagged with a  single  character  to\r\n       indicate  the  error.  The  characters and the corresponding\r\n       messages are:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 50                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n        A:   Absolute expression required\r\n\r\n        B:   Bad arg to *L\r\n             Bad arg to IM\r\n             Bad bit number\r\n             Bad character constant\r\n             Bad jump condition\r\n\r\n        D:   Directive not recognized\r\n             Digit out of range\r\n\r\n        E:   EOF inside conditional\r\n             Expression error\r\n\r\n        G:   Garbage after operands\r\n             Garbage on end of line\r\n\r\n        I:   Index offset too large\r\n\r\n        J:   Jump target out of range\r\n\r\n        L:   Lexical error\r\n\r\n        M:   Multiply defined symbol\r\n\r\n        O:   Operand error\r\n\r\n        P:   Phase error\r\n             Psect may not be local and global\r\n\r\n        R:   Relocation error\r\n\r\n        S:   Size error\r\n             Syntax error\r\n\r\n        U:   Undefined symbol\r\n             Undefined temporary label\r\n             Unterminated string\r\n\r\n\r\n   12.6. Z80/Z180/64180 Instruction Set\r\n\r\n        The remainder of this chapter is devoted to a  complete\r\n   instruction  set listing for the Z80, Z180, 64180 and NSC800\r\n   processors.   The  Z180  and  64180  will  execute  all  Z80\r\n   instructions, although the timing is different.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 51\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 52                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 53\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 54                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 55\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 56                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 57\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 58                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 59\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 60                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 61\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 62                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 63\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 64                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 65\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 66                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 67\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 68                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 69\r\n\r\n\r\n       13. Linker Reference Manual\r\n\r\n\r\n            HI-TECH  C  incorporates  a  relocating  assembler  and\r\n       linker  to  permit  separate  compilation of C source files.\r\n       This means that a program may be divided into several source\r\n       files,  each  of  which may be kept to a manageable size for\r\n       ease of editing and compilation, then each object file  com-\r\n       piled  separately  and  finally  all the object files linked\r\n       together into a single executable program.\r\n\r\n            The assembler  is  described  in  the  machine-specific\r\n       manual.   This  appendix describes the theory behind and the\r\n       usage of the linker.\r\n\r\n       13.1. Relocation and Psects\r\n\r\n            The fundamental  task  of  the  linker  is  to  combine\r\n       several  relocatable object files into one. The object files\r\n       are said to be relocatable since the files  have  sufficient\r\n       information  in  them  so  that any references to program or\r\n       data addresses (e.g. the address of a function)  within  the\r\n       file  may  be  adjusted according to where the file is ulti-\r\n       mately located in memory after the linkage process. Thus the\r\n       file  is  said  to  be  relocatable. Relocation may take two\r\n       basic forms; relocation by  name,  i.e.  relocation  by  the\r\n       ultimate  value  of a global symbol, or relocation by psect,\r\n       i.e. relocation by the base address of a particular  section\r\n       of  code,  for  example  the  section of code containing the\r\n       actual excutable instructions.\r\n\r\n       13.1.1. Program Sections\r\n\r\n            Any object file may  contain  bytes  to  be  stored  in\r\n       memory  in  one  or  more  program  sections,  which will be\r\n       referred to as psects. These psects represent logical group-\r\n       ings  of  certain  types  of code bytes in the program.  The\r\n       section of the program containing executable instructions is\r\n       normally  referred  to as the text psect. Other sections are\r\n       the initialized data psect, called simply  the  data  psect,\r\n       and the uninitialized data psect, called the bss psect.\r\n\r\n            In fact the linker will handle any  number  of  psects,\r\n       and  in  fact more may be used in special applications. How-\r\n       ever the C compiler uses only the three mentioned,  and  the\r\n       names  text,  data and bss are simply chosen for identifica-\r\n       tion; the linker assigns no special significance to the name\r\n       of a psect.\r\n\r\n            The difference between the data and bss psects  may  be\r\n       exemplified  by  considering  two external variables; one is\r\n       initialized to the value 1, and the other  is  not  initial-\r\n       ized.  The first will be placed into the data psect, and the\r\n       second in the bss psect. The bss psect is always cleared  to\r\n       zeros  on  startup  of the program, thus the second variable\r\n       will be initialized at run time to zero. The first will how-\r\n       ever occupy space in the program file, and will maintain its\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 70                              HI-TECH C USER'S MANUAL\r\n\r\n   initialized value of 1 at startup. It is quite  possible  to\r\n   modify the value of a variable in the data psect during exe-\r\n   cution, however it is better practice not to  do  so,  since\r\n   this  leads  to more consistent use of variables, and allows\r\n   for restartable and romable programs.\r\n\r\n        The text psect is the section into which all executable\r\n   instructions are placed. On CP/M-80 the text psect will nor-\r\n   mally start at the base of the TPA, which is where execution\r\n   commences.  The  data  psect  will  normally follow the text\r\n   psect, and the bss will be last. The  bss  does  not  occupy\r\n   space  in  the  program (.COM) file. This ordering of psects\r\n   may be overridden by an option to the linker. This is  espe-\r\n   cially useful when producing code for special hardware.\r\n\r\n        For MS-DOS and CP/M-86 the psects are  ordered  in  the\r\n   same way, but since the 8086 processor has segment registers\r\n   providing relocation, both the text and data psects start at\r\n   0,  even  though  they will be loaded one after the other in\r\n   memory. This allows 64k code and 64k data and stack.  Suffi-\r\n   cient  information is placed in the executable file (.EXE or\r\n   .CMD) for the  operating  system  to  load  the  program  in\r\n   memory.\r\n\r\n   13.1.2. Local Psects and the Large Model\r\n\r\n        Since for practical purposes the psects are limited  to\r\n   64K  on  the  8086, to allow more than 64K code the compiler\r\n   makes use of local psects. A psect is  considered  local  if\r\n   the  .psect  directive has a LOCAL flag. Any number of local\r\n   psects may be linked from different  modules  without  being\r\n   combined  even if they have the same name. Note however that\r\n   no local psect may have the same name as a global psect.\r\n\r\n        All references to a local psect within the same  module\r\n   (or  within  the same library) will be treated as references\r\n   to the same psect. Between modules however two local  psects\r\n   of the same name are treated as distinct.  In order to allow\r\n   collective referencing of local psects  via  the  -P  option\r\n   (described  later) a local psect may have a class name asso-\r\n   ciated with it. This is achieved witht the CLASS flag on the\r\n   .psect directive.\r\n\r\n   13.2. Global Symbols\r\n\r\n        The  linker  handles  only  symbols  which  have   been\r\n   declared  as  global  to  the  assembler.  From the C source\r\n   level, this means all names which have storage class  exter-\r\n   nal  and which are not declared as static. These symbols may\r\n   be referred to by modules other than the one in  which  they\r\n   are  defined. It is the linker's job to match up the defini-\r\n   tion of a global symbol with the references to it.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 71\r\n\r\n       13.3. Operation\r\n\r\n            A command to the linker takes the following form:\r\n\r\n            LINK options files ...\r\n\r\n\r\n            Options is zero or more linker options, each  of  which\r\n       modifies  the  behaviour of the linker in some way. Files is\r\n       one or more object files, and zero or  more  library  names.\r\n       The  options  recognized  by the linker are as follows: they\r\n       will be recognized in upper or lower case.\r\n\r\n       -R   Leave the output relocatable.\r\n\r\n       -L   Retain absolute relocation info. -LM will  retain  only\r\n            segement relocation information.\r\n\r\n       -I   Ignore undefined symbols.\r\n\r\n       -N   Sort symbols by address.\r\n\r\n       -Caddr\r\n            Produce a binary output file offset by addr.\r\n\r\n       -S   Strip symbol information from the output file.\r\n\r\n       -X   Suppress local symbols in the output file.\r\n\r\n       -Z   Suppress trivial (compiler-generated)  symbols  in  the\r\n            output file.\r\n\r\n       -Oname\r\n            Call the output file name.\r\n\r\n       -Pspec\r\n            Spec is a psect location specification.\r\n\r\n       -Mname\r\n            Write a link map to the file name.\r\n\r\n       -Usymbol\r\n            Make symbol initially undefined.\r\n\r\n       -Dfile\r\n            Write a symbol file.\r\n\r\n       -Wwidth\r\n            Specify map width.\r\n\r\n            Taking each of these in turn:\r\n\r\n            The -R option will instruct the  linker  to  leave  the\r\n       output  file  (as named by a -O option, or l.obj by default)\r\n       relocatable. This is  normally  because  there  are  further\r\n       files  to  be linked in, and the output of this link will be\r\n       used as input  to  the  linker  subsequently.  Without  this\r\n       option,  the linker will make the output file absolute, that\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 72                              HI-TECH C USER'S MANUAL\r\n\r\n   is with all relocatable addresses made into absolute  refer-\r\n   ences.   This  option  may  not  be  used  with the -L or -C\r\n   options.\r\n\r\n        The -L option will cause  the  linker  to  output  null\r\n   relocation  information  even  though the file will be abso-\r\n   lute. This information allows  self-relocating  programs  to\r\n   know  what  addresses  must  be  relocated at run time. This\r\n   option is not usable with the -C option. In order to  create\r\n   an  executable  file (i.e. a .COM file) the program objtohex\r\n   must be used.  If a -LM option is used, only segment reloca-\r\n   tion  information will be retained.  This is used in conjuc-\r\n   tion with the large memory  model.  Objtohex  will  use  the\r\n   relocation  information  (when  invoked  with  a -L flag) to\r\n   insert segment  relocation  addresses  into  the  executable\r\n   file.\r\n\r\n        The -I option is used when it is desired to  link  code\r\n   which  contains symbols which are not defined in any module.\r\n   This is normally only used during top-down program  develop-\r\n   ment,  when  routines  are referenced in code written before\r\n   the routines themselves have been coded.\r\n\r\n        When obtaining a link map via the -M option, the symbol\r\n   table  is by default sorted in order of symbol name. To sort\r\n   in order of address, the -N option may be used.\r\n\r\n        The output of the linker is by default an object  file.\r\n   To create an executable program, this must be converted into\r\n   an executable image. For CP/M this is a .COM file, which  is\r\n   simply  an  image  of  the  executable  program as it should\r\n   appear in memory, starting at location 100H. The linker will\r\n   produce such a file with the -C100H option. File formats for\r\n   other applications requiring an image binary file  may  also\r\n   be  produced  with the -C option.  The address following the\r\n   -C may be given in decimal (default), octal (by using o or O\r\n   suffix) or hexadecimal (by using an h or H suffix).\r\n\r\n        Note that because of the complexity of  the  executable\r\n   file  formats  for MS-DOS and CP/M-86, LINK will not produce\r\n   these (.EXE and .CMD resp.) formats directly.  The  compiler\r\n   automatically runs OBJTOHEX with appropriate options to gen-\r\n   erate the correct file format.\r\n\r\n        The -S, -X and -Z options, which are  meaningless  when\r\n   the  -C option is used, will strip respectively all symbols,\r\n   all local symbols or all trivial local symbols from the out-\r\n   put  file.  Trivial symbols are symbols produced by the com-\r\n   piler, and have the form of one of a set of alphabetic char-\r\n   acters followed by a digit string.\r\n\r\n        The default output file name is l.obj,  or  l.bin  when\r\n   the -C option is used.  This may be overridden by the -Oname\r\n   option.  The  output  file  will  be  called  name  in  this\r\n   instance.  Note  that no suffix is appended to the name; the\r\n   file will be called exactly the argument to the option.\r\n\r\n        For certain specialized  applications,  e.g.  producing\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 73\r\n\r\n       code  for  an  embedded  microprocessor,  it is necessary to\r\n       specify to the linker at what  address  the  various  psects\r\n       should  be located. This is accomplished with the -P option.\r\n       It is followed by a specification  consisting  of  a  comma-\r\n       separated list of psect names, each with an optional address\r\n       specification. In the absence of  an  address  specification\r\n       for  a psect listed, it will be concatenated with the previ-\r\n       ous psect. For example\r\n\r\n            -Ptext=0c000h,data,bss=8000h\r\n\r\n\r\n            This will cause the text psect to be located at 0C000H,\r\n       the  data  psect  to start at the end of the text psect, and\r\n       the bss psect to start at 8000H. This may be for a processor\r\n       with ROM at 0C000H and RAM at 8000H.\r\n\r\n            Where the link address, that is the  address  at  which\r\n       the  code  will be addressed at execution time, and the load\r\n       address, that is the address offset within the output  file,\r\n       are  different  (e.g for the 8086) it is possible to specify\r\n       the load address separately from the link address. For exam-\r\n       ple:\r\n\r\n            -Ptext=100h/0,data=0C000h/\r\n\r\n\r\n            This specification will cause the text  segment  to  be\r\n       linked  for execution at 100h, but loaded in the output file\r\n       at 0, while the data segment will be linked for 0C000h,  but\r\n       loaded  contiguously  with the text psect in the file.  Note\r\n       that if the slash (`/') is omitted, the load address is  the\r\n       same  as  the  link address, while if the slash is supplied,\r\n       but not followed by an address, the  psect  will  be  loaded\r\n       after the previous psect.\r\n\r\n            In order to specify link and load addresses  for  local\r\n       psects,  the  group  name  to which the psects belong may be\r\n       used in place of a global psect name. The local psects  will\r\n       then  have a link address as specified in the -P option, and\r\n       load addresses incrementing upwards from the specified  load\r\n       address.\r\n\r\n            The -Mname option requests a link map, containing  sym-\r\n       bol  table and module load address information to be written\r\n       onto the file name. If name is  omitted,  the  map  will  be\r\n       written  to  standard  output. -W may be used to specify the\r\n       desired width of the map.\r\n\r\n            The -U option allows the specification to the linker of\r\n       a  symbol  which  is to be initially entered into the symbol\r\n       table as undefined. This is  useful  when  loading  entirely\r\n       from libraries. More than one -U flag may be used.\r\n\r\n            If it is desired to use the  debugger  on  the  program\r\n       being  linked,  it  is  useful to produce a symbol file. The\r\n       -Dfile option will write such a symbol file onto  the  named\r\n       file, or l.sym if no file is given. The symbol file consists\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 74                              HI-TECH C USER'S MANUAL\r\n\r\n   of a list of addresses and symbols, one per line.\r\n\r\n   13.4. Examples\r\n\r\n        Here are some examples of using the linker.  Note  how-\r\n   ever  that  in the normal case it is not necessary to invoke\r\n   the linker explicitly, since it is invoked automatically  by\r\n   the C command.\r\n\r\n   LINK -MMAP -C100H START.OBJ MAIN.OBJ A:LIBC.LIB\r\n\r\n\r\n        This command links the  files  start.obj  and  main.obj\r\n   with  the  library  a:libc.lib.  Only those modules that are\r\n   required from the library will be in  fact  linked  in.  The\r\n   output  is  to be in .COM format, placed in the default file\r\n   l.bin. A map is to be written to the file of the  name  map.\r\n   Note  that  the  file start.obj should contain startup code,\r\n   and in fact the lowest address code in  that  file  will  be\r\n   executed when the program is run, since it will be at 100H.\r\n\r\n        LINK -X -R -OX.OBJ FILE1.OBJ FILE2.OBJ A:LIBC.LIB\r\n\r\n\r\n        The files file1.obj and file2.obj will be  linked  with\r\n   any  necessary routines from a:libc.lib and left in the file\r\n   x.obj.  This file will remain relocatable. Undefined symbols\r\n   will not cause an error.  The file x.obj will probably later\r\n   be the object of another link invocation.  All local symbols\r\n   will be stripped from the output file, thus saving space.\r\n\r\n   13.5. Invoking the Linker\r\n\r\n        The linker is called LINK, and normally resides on  the\r\n   A:  drive,  under CP/M, or in the directory A:\\HITECH\\ under\r\n   MS-DOS. It may be invoked with no arguments, in  which  case\r\n   it  will  prompt for input from standard input. If the stan-\r\n   dard input is a file, no prompts will be printed.  The input\r\n   supplied in this manner may contain lower case, whereas CP/M\r\n   converts the entire command line to upper case  by  default.\r\n   This  is useful with the -U  and -P options.  This manner of\r\n   invocation is generally useful if the number of arguments to\r\n   LINK  is large. Even if the list of files is too long to fit\r\n   on one line, continuation lines may be included by leaving a\r\n   backslash  ('\\')  at  the end of the preceding line. In this\r\n   fashion, LINK commands of almost  unlimited  length  may  be\r\n   issued.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 75\r\n\r\n\r\n       14. Librarian\r\n\r\n\r\n            The librarian program, LIBR, has the function  of  com-\r\n       bining  several  object  files into a single file known as a\r\n       library. The  purposes  of  combining  several  such  object\r\n       modules are several.\r\n\r\n            a.   fewer files to link\r\n            b.   faster access\r\n            c.   uses less disk space\r\n\r\n\r\n            In order to make the  library  concept  useful,  it  is\r\n       necessary  for the linker to treat modules in a library dif-\r\n       ferently from object files. If an object file  is  specified\r\n       to  the  linker,  it  will  be  linked into the final linked\r\n       module. A module in a library, however, will only be  linked\r\n       in  if  it defines one or more symbols previously known, but\r\n       not defined, to the linker. Thus modules in a  library  will\r\n       be  linked  only if required. Since the choice of modules to\r\n       link is made on the  first  pass  of  the  linker,  and  the\r\n       library  is  searched in a linear fashion, it is possible to\r\n       order the modules in a library to  produce  special  effects\r\n       when linking.  More will be said about this later.\r\n\r\n       14.1. The Library Format\r\n\r\n            The modules  in  a  library  are  basically  just  con-\r\n       catenated, but at the beginning of a library is maintained a\r\n       directory of the modules and symbols in the  library.  Since\r\n       this  directory  is smaller than the sum of the modules, the\r\n       linker is speeded up when searching a library since it  need\r\n       read only the directory and not all the modules on the first\r\n       pass. On the second pass it need  read  only  those  modules\r\n       which are required, seeking over the others. This all minim-\r\n       izes disk i/o when linking.\r\n\r\n            It should be noted that the library  format  is  geared\r\n       exclusively toward object modules, and is not a general pur-\r\n       pose archiving mechanism as is used by some  other  compiler\r\n       systems.  This  has  the  advantage  that  the format may be\r\n       optimized toward speeding up the linkage process.\r\n\r\n       14.2. Using\r\n\r\n            The librarian program is called LIBR, and the format of\r\n       commands to it is as follows:\r\n\r\n            LIBR k file.lib file.obj ...\r\n\r\n\r\n            Interpreting this, LIBR is the name of the  program,  k\r\n       is  a  key  letter  denoting  the  function requested of the\r\n       librarian (replacing, extracting or deleting modules,  list-\r\n       ing modules or symbols), file.lib is the name of the library\r\n       file to be operated on, and file.obj is zero or more  object\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 76                              HI-TECH C USER'S MANUAL\r\n\r\n   file names.\r\n\r\n        The key letters are:\r\n\r\n        r       replace modules\r\n        d       delete modules\r\n        x       extract modules\r\n        m       list module names\r\n        s       list modules with symbols\r\n\r\n\r\n        When replacing  or  extracting  modules,  the  file.obj\r\n   arguments  are  the  names  of the modules to be replaced or\r\n   extracted. If  no  such  arguments  are  supplied,  all  the\r\n   modules in the library will be replaced or extracted respec-\r\n   tively.  Adding a file to a library is performed by request-\r\n   ing  the librarian to replace it in the library. Since it is\r\n   not present, the module will be appended to the library.  If\r\n   the r key is used and the library does not exist, it will be\r\n   created.\r\n\r\n        Under the d keyletter, the named object files  will  be\r\n   deleted  from the library.  In this instance, it is an error\r\n   not to give any object file names.\r\n\r\n        The m and s keyletters will list the named modules and,\r\n   in  the  case  of  the  s  keyletter, the symbols defined or\r\n   referenced within (global symbols only are  handled  by  the\r\n   librarian). As with the r and x keyletters, an empty list of\r\n   modules means all the modules in the library.\r\n\r\n   14.3. Examples\r\n\r\n        Here are some examples of usage of the librarian.\r\n\r\n   LIBR m file.lib\r\n        List all modules in the library file.lib.\r\n\r\n   LIBR s file.lib a.obj b.obj c.obj\r\n        List the global symbols in the modules a.obj, b.obj and\r\n        c.obj\r\n\r\n   LIBR r file.lib 1.obj 2.obj\r\n        Replace the module 1.obj in the file file.lib with  the\r\n        contents  of  the  object  file  1.obj,  and repeat for\r\n        2.obj. If the object module is not already  present  in\r\n        the library, append it to the end.\r\n\r\n   LIBR x file.lib\r\n        Extract, without deletion, all the modules in  file.lib\r\n        and write them as object files on disk.\r\n\r\n   LIBR d file.lib a.obj b.obj 2.obj\r\n        Delete the object modules a.obj, b.obj and  2.obj  from\r\n        the library file.lib.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 77\r\n\r\n       14.4. Supplying Arguments\r\n\r\n            Since it is often necessary to supply many object  file\r\n       arguments  to  LIBR, and command lines are restricted to 127\r\n       characters by CP/M and MS-DOS,  LIBR  will  accept  commands\r\n       from  standard input if no command line arguments are given.\r\n       If the standard input is attached to the console, LIBR  will\r\n       prompt.  Multiple  line  input  may  be  given  by  using  a\r\n       backslash as a continuation character on the end of a  line.\r\n       If  standard input is redirected from a file, LIBR will take\r\n       input from the file, without prompting. For example:\r\n\r\n            LIBR\r\n            libr> r file.lib 1.obj 2.obj 3.obj \\\r\n            libr> 4.obj 5.obj 6.obj\r\n\r\n       will perform much the same as if the  .obj  files  had  been\r\n       typed on the command line. The libr> prompts were printed by\r\n       LIBR itself, the remainder of the text was typed as input.\r\n\r\n            LIBR <lib.cmd\r\n\r\n\r\n            Libr will read input from lib.cmd, and execute the com-\r\n       mand found therein. This allows a virtually unlimited length\r\n       command to be given to LIBR.\r\n\r\n       14.5. Listing Format\r\n\r\n            A request to LIBR to list module names will simply pro-\r\n       duce  a list of names, one per line, on standard output. The\r\n       s keyletter will produce the same, with a  list  of  symbols\r\n       after  each module name. Each symbol will be preceded by the\r\n       letter D or U, representing a definition or reference to the\r\n       symbol  respectively. The -W option may be used to determine\r\n       the width of the paper for this operation. For example  LIBR\r\n       -w80 s file.lib will list all modules in file.lib with their\r\n       global symbols, with the output formatted for an  80  column\r\n       printer or display.\r\n\r\n       14.6. Ordering of Libraries\r\n\r\n            The librarian creates libraries with the modules in the\r\n       order  in  which  they  were given on the command line. When\r\n       updating a library the order of the  modules  is  preserved.\r\n       Any new modules added to a library after it has been created\r\n       will be appended to the end.\r\n\r\n            The ordering of the modules in a library is significant\r\n       to  the  linker. If a library contains a module which refer-\r\n       ences a  symbol  defined  in  another  module  in  the  same\r\n       library,  the  module  defining the symbol should come after\r\n       the module referencing the symbol.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 78                              HI-TECH C USER'S MANUAL\r\n\r\n   14.7. Error Messages\r\n\r\n        Libr issues  various  error  messages,  most  of  which\r\n   represent  a  fatal  error,  while some represent a harmless\r\n   occurence which will nonetheless be reported unless  the  -w\r\n   option  was  used. In this case all warning messages will be\r\n   suppressed.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 79\r\n\r\n\r\n       15. Objtohex\r\n\r\n\r\n            The HI-TECH  linker  is  capable  of  producing  simple\r\n       binary  files,  or  object files as output. Any other format\r\n       required must be produced by  running  the  utility  program\r\n       OBJTOHEX.   This  allows  conversion of object files as pro-\r\n       duced by the linker into a  variety  of  different  formats,\r\n       including various hex formats. The program is invoked thus:\r\n\r\n            OBJTOHEX options inputfile outputfile\r\n\r\n\r\n            All of the arguments are  optional.  If  outputfile  is\r\n       ommitted  it defaults to l.hex or l.bin depending on whether\r\n       the -b option is used. The inputfile defaults to l.obj.\r\n\r\n            The options are:\r\n\r\n       -Baddr\r\n            Produce a binary image output. This is similar  to  the\r\n            -C  option  of  the  linker.   If addr is supplied, the\r\n            start of the image file will be offset by addr. If addr\r\n            is  omitted,  the  first  byte  in the file will be the\r\n            lowest byte initialized. Addr may be given in  decimal,\r\n            octal or hexadecimal. The default radix is decimal, and\r\n            suffix letters of o or O indicate octal,  and  h  or  H\r\n            indicate  hex.  Thus -B100H will produce a file in .COM\r\n            format.\r\n\r\n       -I   Include symbol records in the Intel format hex  output.\r\n            Each  symbol  record  has  a  form similar to an object\r\n            record, but with a  different  record  type.  The  data\r\n            bytes  in  the  record  are  the  symbol  name, and the\r\n            address is the value of the symbol.  This is useful for\r\n            downloading to ROM debuggers.\r\n\r\n       -C   Read a checksum specification from the standard  input.\r\n            The  checksum  specification  is described below. Typi-\r\n            cally the specification will be in a file.\r\n\r\n       -Estack\r\n            This option produces an MS-DOS .EXE  format  file.  The\r\n            optional  stack  argument  will  determine  the maximum\r\n            stack size the program will be allocated on  execution.\r\n            By  default  the  program will be allocated the maximum\r\n            stack available, up to the limit  of  64K  data.  If  a\r\n            stack  argument  is  supplied,  the stack size will not\r\n            exceed the argument. This is useful to limit the amount\r\n            of  memory a program will use. The stack argument takes\r\n            the same form as the argument to -B above.\r\n\r\n       -8stack\r\n            This option will produce a CP/M-86 .CMD file. The stack\r\n            argument is the same as for the -E option.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 80                              HI-TECH C USER'S MANUAL\r\n\r\n   -Astack\r\n        This is used when producing a.out format files for unix\r\n        systems  (specifically Venix-86). If the stack argument\r\n        is zero, the size of the data segment will be 64k, oth-\r\n        erwise the stack will be placed below the data segment,\r\n        and its size set to stack.  This must  be  co-ordinated\r\n        with  appropriate  arguments  to  the  -p option of the\r\n        linker.\r\n\r\n   -M   This flag will instruct objtohex  to  produce  Motorola\r\n        'S' format hex output.\r\n\r\n   -L   This option is used when  producing  large  model  pro-\r\n        grams;  the  linker  will  have  been used with the -LM\r\n        option to retain segment relocation information in  the\r\n        object  file.  Use  of  the  -L option to objtohex will\r\n        cause it to convert that segment relocation information\r\n        into  appropriate  data  in the executable file for use\r\n        when the program is loaded. Either the operating system\r\n        or  the  run-time  startup code will use the relocation\r\n        data to adjust segment references  based  on  where  in\r\n        memory  the  program  is  actually  loaded.   If the -L\r\n        option is followed by a symbol name, then  the  reloca-\r\n        tion   information   will  be  stored  at  the  address\r\n        represented by that symbol in  the  output  file,  e.g.\r\n        -L__Bbss  will cause it to be stored at the base of the\r\n        bss psect (__Bbss is defined by the linker  to  be  the\r\n        load  address  of the bss psect). If the special symbol\r\n        Dos_hdr is used then the relocation information will be\r\n        stored  in the .EXE file header.  This is only valid in\r\n        conjunction with the -E option.\r\n\r\n   -S   The -S option instructs  objtohex  to  write  a  symbol\r\n        file.  The symbol file name is given after the -S, e.g.\r\n        -Sxx.sym.\r\n\r\n        Unless  another  format  is   specifically   requested,\r\n   objtohex  will  produce  a file in Intel hex format. This is\r\n   suitable for down-line loading, PROM programming  etc.   The\r\n   HP  format is useful for transferring code to an HP64000 for\r\n   emulation or PROM programming.\r\n\r\n        The checksum specification  allows  automated  checksum\r\n   calculation.  The  checksum  specification takes the form of\r\n   several lines, each line describing one checksum. The syntax\r\n   of a checksum line is:\r\n\r\n        addr1-addr2 where1-where2 +offset\r\n\r\n\r\n        All of addr1, addr2, where1, where2 and offset are  hex\r\n   numbers,  without  the  usual H suffix. Such a specification\r\n   says that the bytes at  addr1  through  to  addr2  inclusive\r\n   should  be summed and the sum placed in the locations where1\r\n   through where2 inclusive. For an 8 bit  checksum  these  two\r\n   addresses should be the same. For a checksum stored low byte\r\n   first, where1 should be less than where2,  and  vice  versa.\r\n   The  +offset  is optional, but if supplied, the value offset\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 81\r\n\r\n       will be used to initialize the  checksum.  Otherwise  it  is\r\n       initialized to zero. For example:\r\n\r\n            0005-1FFF 3-4 +1FFF\r\n\r\n\r\n            This will sum the bytes in 5 through  1FFFH  inclusive,\r\n       then  add  1FFFH  to  the  sum.  The 16 bit checksum will be\r\n       placed in locations 3 and 4, low byte in 3. The checksum  is\r\n       initialized  with 1FFFH to provide protection against an all\r\n       zero rom, or a rom misplaced in memory. A run time check  of\r\n       this  checksum  would  add the last address of the rom being\r\n       checksummed into the checksum. For the rom in question, this\r\n       should  be 1FFFH.  The initialization value may, however, be\r\n       used in any desired fashion.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 82                              HI-TECH C USER'S MANUAL\r\n\r\n\r\n\r\n\r\n                     Use this page for notes\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 83\r\n\r\n\r\n       16. Cref\r\n\r\n\r\n            The cross reference list utility CREF is used to format\r\n       raw  cross-reference information produced by the compiler or\r\n       the assembler into a sorted listing.  A raw  cross-reference\r\n       file  is  produced  with the -CR option to the compiler. The\r\n       assembler will generate a raw cross-reference file with a -C\r\n       option  (Z80  or  8086  assemblers)  or  by using an OPT CRE\r\n       directive (6800 series assemblers) or  a  REF  control  line\r\n       (8096 assembler)..  The general form of the CREF command is:\r\n\r\n            CREF options files\r\n\r\n       where options is zero or more options as described below and\r\n       files  is one or more raw cross-reference files.  CREF takes\r\n       the following options:\r\n\r\n       -Ooutfile\r\n            Allows  specification  of  the  output  file  name.  By\r\n            default  the  listing  will  be written to the standard\r\n            output and may  be  redirected  in  the  usual  manner.\r\n            Alternatively  using  the -O option an output file name\r\n            may be specified, e.g. -Oxxx.lst.\r\n\r\n       -Pwidth\r\n            This option allows the specification of  the  width  to\r\n            which  the  listing is to be formatted, e.g. -P132 will\r\n            format the  listing  for  a  132  column  printer.  The\r\n            default is 80 columns.\r\n\r\n       -Llength\r\n            Specify the length of the paper on which the listing is\r\n            to  be  produced, e.g.  if the listing is to be printed\r\n            on 55 line paper you  would  use  a  -L55  option.  The\r\n            default is 66 lines.\r\n\r\n       -Xprefix\r\n            The -X option allows the exclusion of symbols from  the\r\n            listing, based on a prefix given as argument to -X. For\r\n            example if it was desired to exclude all symbols start-\r\n            ing  with  the  character  sequence xyz then the option\r\n            -Xxyz would be used. If a digit appears in the  charac-\r\n            ter sequence then this will match any digit in the sym-\r\n            bol, e.g. -XX0 would exclude any symbols starting  with\r\n            the letter X followed by a digit.\r\n\r\n       -F   -F will exclude from the listing  any  references  from\r\n            files  with  a  full  path name. A full path name means\r\n            either: a file name starting  with  a  slash  ('/')  or\r\n            backslash  ('\\')  or  a  file name starting with a CP/M\r\n            user number/drive letter prefix,  e.g.  0:A:.  This  is\r\n            intended to force omission from the listing of any sym-\r\n            bol references derived from standard header files, e.g.\r\n            using -F would omit any references from the header file\r\n            STDIO.H.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 84                              HI-TECH C USER'S MANUAL\r\n\r\n   -Hstring\r\n        The -H option takes a string as an argument which  will\r\n        be used as a header in the listing. The default heading\r\n        is the name of the first raw cross-ref information file\r\n        specified.\r\n\r\n   -Sstoplist\r\n        The -S option should have as its argument the name of a\r\n        file  containing  a list of symbols not to be listed in\r\n        the cross-reference. Multiple stoplists may be supplied\r\n        with multiple -S options.\r\n\r\n        Cref will accept wild card filenames and  I/O  redirec-\r\n   tion.  Long  command  lines may be supplied by invoking CREF\r\n   with no arguments and typing the command line in response to\r\n   the cref> prompt. A backslash at the end of the line will be\r\n   interpreted to mean that more command lines follow.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 85\r\n\r\n                                APPENDIX 1\r\n\r\n                             Error Messages\r\n\r\n\r\n\r\n            Error Messages produced  by  the  compiler  are  listed\r\n       below.  Each  message is followed by the name of the program\r\n       which produces it, and  some  further  description  of  what\r\n       causes the message or what to do about it.\r\n\r\n\r\n\r\n       '.' expected after '..'      P1\r\n            The ellipsis symbol must have three dots\r\n\r\n       actuals too long      CPP\r\n            Reduce length of macro arguments\r\n\r\n       argument list conflicts with prototype      P1\r\n            The argument list in a function definition  must  agree\r\n            with a prototype if one exists\r\n\r\n       argument redeclared      P1\r\n            This argument has been declared twice\r\n\r\n       arithmetic overflow in constant expression      CGEN\r\n            Evaluation of  this  constant  expression  produced  an\r\n            arithmetic  overflow.  This  may or may not represent a\r\n            true error.\r\n\r\n       array index out of bounds      P1\r\n            An array index expression evaluates to a constant which\r\n            is  less  than  zero  or  greater  than or equal to the\r\n            dimension of the array\r\n\r\n       Assertion      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       attempt to modify const object      P1\r\n            An attempt has been made  to  assign  to  or  otherwise\r\n            modify an object designated as 'const'\r\n\r\n       bad bitfield type      P1\r\n            Bitfields must be of type 'int'\r\n\r\n       Bad conval      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       Bad dimensions      CGEN\r\n            An array has bad dimensions - probably zero\r\n\r\n       Bad element count expr      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       bad formal      CPP\r\n            Check macro defintion syntax\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 86                              HI-TECH C USER'S MANUAL\r\n\r\n   bad include syntax      CPP\r\n        Use only \"\" and <> for include files\r\n\r\n   Bad int. code      CGEN\r\n        The intermediate code file has been corrupted - can  be\r\n        caused by running out of disk space\r\n\r\n   Bad -M option      CGEN\r\n        A -M option passed to the code generator is unknown\r\n\r\n   Bad mod '+' for how = c      CGEN\r\n        Internal error - contact HI-TECH\r\n\r\n   bad object code format      LINK\r\n        This file is either corrupted or  not  a  valid  object\r\n        file\r\n\r\n   Bad op d to swaplog      CGEN\r\n        Internal error - contact HI-TECH\r\n\r\n   Bad op n to revlog      CGEN\r\n        Internal error - contact HI-TECH\r\n\r\n   bad origin format in spec      LINK\r\n        An address in a -p option is invalid\r\n\r\n   bad '-p' format      LINK\r\n        The -p option provided is invalid\r\n\r\n   Bad pragma c      CGEN\r\n        The code generator has been passed a pragma it does not\r\n        know about\r\n\r\n   Bad putwsize      CGEN\r\n        Internal error - contact HI-TECH\r\n\r\n   bad storage class      P1, CGEN\r\n        The speficied storage class is illegal\r\n\r\n   Bad U usage      CGEN\r\n        Internal error - contact HI-TECH\r\n\r\n   Bit field too large (n bits)      CGEN\r\n        A bit field may not be larger than an int\r\n\r\n   Cannot get memory      LINK\r\n        The linker has run out of dynamic memory\r\n\r\n   Can't be both far and near      P1\r\n        The 'far' and 'near' keywords cannot appear in the same\r\n        type specifier\r\n\r\n   can't be long      P1\r\n        Chars and shorts cannot be long\r\n\r\n   can't be register      P1\r\n        An extern or static variable may not be register\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 87\r\n\r\n       can't be short      P1\r\n            Float and char cannot be short\r\n\r\n       can't be unsigned      P1\r\n            Float cannot be unsigned\r\n\r\n       can't call an interrupt function      P1\r\n            A function qualified 'interrupt' can only be called  by\r\n            hardware, not by an ordinary function call\r\n\r\n       Can't create filename      CGEN\r\n            The file specified could not be created\r\n\r\n       Can't create xref file      P1\r\n            The cross reference file specified could not be created\r\n\r\n       Can't create      CPP\r\n            Output file could not be created\r\n\r\n       Can't create      LINK\r\n            The linker cannot create a file\r\n\r\n       Can't find include file      CPP\r\n            Check and correct the include file name  -  spaces  are\r\n            not allowed in file names\r\n\r\n       Can't find register for bits      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       Can't generate code for this expression      CGEN\r\n            The code generator is unable to generate code for  this\r\n            expression - simplifying the expression (e.g. computing\r\n            values into temporary variables) will  usually  correct\r\n            it, otherwise contact HI-TECH\r\n\r\n       can't have array of functions      P1\r\n            You cannot have an array of functions - you can have an\r\n            array of pointers to functions\r\n\r\n       Can't have 'port' variable      CGEN\r\n            You cannot declare a variable to be qualified 'port'  -\r\n            you  can  only use port to qualify pointers or typecast\r\n            constant values\r\n\r\n       can't have storage class      P1\r\n            A storage class may not appear in a prototype argument\r\n\r\n       can't initialise auto aggregates      P1\r\n            You cannot initialise a structure  or  array  inside  a\r\n            function unless it is static\r\n\r\n       can't initialize arg      P1\r\n            An argument cannot have an initializer\r\n\r\n       can't mix proto and non-proto args      P1\r\n            You cannot mix prototype  and  non-prototype  arguments\r\n            even in a function definition\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 88                              HI-TECH C USER'S MANUAL\r\n\r\n   Can't open filename      CGEN\r\n        The file specified could not be opened for reading\r\n\r\n   Can't open      LINK\r\n        The linker cannot open a file\r\n\r\n   Can't seek      LINK\r\n        The linker could not seek in file\r\n\r\n   can't take address of register variable      P1\r\n        You can't take the address of a variable in a register\r\n\r\n   can't take sizeof func      CGEN\r\n        You can't take the size of a function. You can take the\r\n        size of a function call\r\n\r\n   can't take this address      P1\r\n        The expression does not have an address\r\n\r\n   'case' not in switch      P1\r\n        A 'case' label is permitted only inside a switch\r\n\r\n   char const too long      P1\r\n        A character constant may have only one character in it\r\n\r\n   close error (disk space?)      P1\r\n        Probably out of disk space\r\n\r\n   common symbol psect conflict      LINK\r\n        A common symbol is defined to be in more than one psect\r\n\r\n   constant conditional branch      CGEN\r\n        You have a program structure testing a constant expres-\r\n        sion, e.g. while(1). You should substitute for this the\r\n        more efficient for(;;)\r\n\r\n   constant expression required      P1\r\n        A constant expression is  required  in  e.g.  an  array\r\n        dimension\r\n\r\n   constant operand to || or &&      CGEN\r\n        A logical operator has a  constant  operand  which  has\r\n        been optimized out\r\n\r\n   declarator too complex      P1\r\n        This declaration is too complex  for  the  compiler  to\r\n        handle\r\n\r\n   default case redefined      P1\r\n        Only one default case is permitted in a switch\r\n\r\n   'default' not in switch      P1\r\n        A 'default' label is permitted only inside a switch\r\n\r\n   digit out of range      P1\r\n        An octal constant may not contain 7 or 8, and a decimal\r\n        constant may not contain A-F\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 89\r\n\r\n       dimension required      P1\r\n            A dimension is required for all except the most  signi-\r\n            ficant in an array declaration\r\n\r\n       Division by zero      CGEN\r\n            Attempt to divide by zero in this expression\r\n\r\n       Duplicate case label n      CGEN\r\n            There are two case labels in this switch that have  the\r\n            same value\r\n\r\n       Duplicate -d flag      LINK\r\n            Only one -d flag is allowed to the linker\r\n\r\n       duplicate label      P1\r\n            This label is defined twice\r\n\r\n       Duplicate -m flag      LINK\r\n            Only one -m flag is allowed to the linker\r\n\r\n       duplicate qualifier      P1\r\n            The same qualifier appears more than once in this  type\r\n            specifier\r\n\r\n       entry point multiply defined      LINK\r\n            A program can only have one entry point (start address)\r\n\r\n       EOF in #asm      P1\r\n            End of file was encounterd  after  #asm  and  before  a\r\n            #endasm was seen\r\n\r\n       Error closing output file      CGEN,CPP\r\n            Probably means you have run out of disk space\r\n\r\n       excessive -I file ignored      CPP\r\n            Use fewer -I options\r\n\r\n       expand - bad how      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       expand - bad which      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       exponent expected      P1\r\n            An exponent is expected after  the  'e'  or  'E'  in  a\r\n            floating point constant. The exponent must contain only\r\n            +, - and digits 0-9\r\n\r\n       Expression error      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       expression generates no code      CGEN\r\n            This expression has no side effects and thus  generates\r\n            no code. It has been optimized out\r\n\r\n       expression syntax      P1\r\n            The expression is badly formed\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 90                              HI-TECH C USER'S MANUAL\r\n\r\n   expression too complex      P1\r\n        The expression has too many nested parantheses or other\r\n        nested constructs\r\n\r\n   Fixup overflow referencing      LINK\r\n        The linker has relocated a reference to a psect or sym-\r\n        bol  and  the  relocated address is too big to fit into\r\n        the space, e.g. a relocated one  byte  address  exceeds\r\n        256 or a relocated 16 bit address exceeds 65536\r\n\r\n   float param coerced to double      P1\r\n        This float parameter has been converted to double  -  a\r\n        prototype will override this coercion\r\n\r\n   function() declared implicit int      P1\r\n        This function  has  been  called  without  an  explicit\r\n        declaration. It is wise to explicitly declare all func-\r\n        tions, preferably with a  prototype.  This  will  avoid\r\n        many potential errors where your program comprises more\r\n        than one source file\r\n\r\n   function does not take arguments      P1\r\n        The prototype for this function indicates it  takes  no\r\n        arguments\r\n\r\n   function or function pointer required      P1\r\n        A  function  identifier  or  pointer  to  function   is\r\n        required for a function call.\r\n\r\n   functions can't return arrays      P1\r\n        A function cannot return an array -  it  can  return  a\r\n        pointer\r\n\r\n   functions can't return functions      P1\r\n        A function cannot return a function - it can  return  a\r\n        pointer to function\r\n\r\n   hex digit expected      P1\r\n        A hex digit is expected after '0x'\r\n\r\n   identifier is a structure tag      P1\r\n        A structure tag  has  been  used  in  a  context  where\r\n        another  kind  of  tag  is expected, e.g. saying struct\r\n        fred where fred has previously been declared  as  union\r\n        fred.\r\n\r\n   identifier is a union tag      P1\r\n        Similar to the above error\r\n\r\n   identifier is an enum tag      P1\r\n        Similar to the above error\r\n\r\n   identifier: large offset      CGEN\r\n        Z80 only: This identifier has a large offset  from  the\r\n        stack  frame and thus access to it is inefficient. In a\r\n        function any arrays should be declared after any simple\r\n        variables\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 91\r\n\r\n       identifier redeclared      P1\r\n            The  identifier  has  been  redeclared  with  different\r\n            attributes\r\n\r\n       identifier redefined      P1\r\n            An identifier has been defined twice\r\n\r\n       If-less else      CPP\r\n            Check #if usage\r\n\r\n       If-less endif      CPP\r\n            Check #if usage\r\n\r\n       illegal '#' directive      P1\r\n            A # directive passed through to the first pass is  unk-\r\n            nown.  If  this occurs with a #include it may be caused\r\n            by a previous include file not  having  a  <CR><LF>  or\r\n            newline on the last line.\r\n\r\n       Illegal character in preprocessor if      CPP\r\n            Check for strange character\r\n\r\n       illegal character      P1\r\n            A character unknown to the compiler  has  been  encoun-\r\n            tered.  The value given is the octal value of the char-\r\n            acter\r\n\r\n       illegal conversion between pointer types      P1\r\n            The expression causes one pointer type to be  converted\r\n            to another incompatible type\r\n\r\n       illegal conversion of integer to pointer      P1\r\n            An integer is used where a pointer is expected\r\n\r\n       illegal conversion of pointer to integer      P1\r\n            A pointer is used where an integer is expected\r\n\r\n       illegal conversion      P1\r\n            The type conversion here is illegal\r\n\r\n       Illegal flag      LINK\r\n            This option is illegal\r\n\r\n       illegal function qualifier(s)      P1\r\n            A function cannot have 'const' qualification\r\n\r\n       illegal initialisation      P1\r\n            The initialisation of this variable is illegal\r\n\r\n       Illegal number      CPP\r\n            Check number syntax\r\n\r\n       illegal type for array dimension      P1\r\n            An array dimension must be an integral quantity\r\n\r\n       illegal type for index expression      P1\r\n            An array index must be a simple integral expression\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 92                              HI-TECH C USER'S MANUAL\r\n\r\n   illegal type for switch expression      P1\r\n        The expression in a 'switch' must be integral\r\n\r\n   illegal use of void expression      P1\r\n        Void expressions may not be used in any way\r\n\r\n   implicit conversion of float to integer      P1\r\n        A floating point value has been converted to integer  -\r\n        truncation may occur\r\n\r\n   implicit return at end of non-void function      P1\r\n        A function with a non-void type has returned without  a\r\n        return statement\r\n\r\n   implict signed to unsigned conversion      P1\r\n        Unwanted sign extension may occur here. Add an explicit\r\n        typecast to force exactly the conversion you want\r\n\r\n   inappropriate break/continue      P1\r\n\r\n   inappropriate 'else'      P1\r\n        An 'else' has appeared without a matching 'if'\r\n\r\n   inconsistent storage class      P1\r\n        Only one storage class may be specified in  a  declara-\r\n        tion\r\n\r\n   inconsistent type      P1\r\n        Only one basic type may be specified in a declaration\r\n\r\n   initialisation illegal in arg list      P1\r\n        You cannot initialise a function parameter\r\n\r\n   initialisation syntax      P1\r\n        The syntax of this initialisation is illegal\r\n\r\n   initializer in 'extern' declaration      P1\r\n        A declaration with the 'extern' keyword has an initial-\r\n        izer;  this  is not permitted as the extern declaration\r\n        reserves no storage\r\n\r\n   integer constant expected      P1\r\n        An integer constant was expected here\r\n\r\n   integer expression required      P1\r\n        An integral expression is required here\r\n\r\n   integral type required      P1\r\n        An integral type is required here\r\n\r\n   large offset      CGEN\r\n        Z80 only: This identifier has a large offset  from  the\r\n        stack  frame and thus access to it is inefficient. In a\r\n        function any arrays should be declared after any simple\r\n        variables\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 93\r\n\r\n       Line too long      P1\r\n            The source line  is  too  long,  or  does  not  have  a\r\n            <CR><LF> or newline at the end\r\n\r\n       local  psect  conflicts  with  global  psect  of  same  name\r\n            LINK\r\n            A local psect cannot have the same  name  as  a  global\r\n            psect\r\n\r\n       logical type required      P1\r\n            A logical type (i.e. an integral type) is  required  as\r\n            the subject of a conditional expression\r\n\r\n       lvalue required      P1\r\n            An lvalue, i.e. something which can be assigned to,  is\r\n            required after an '&' or on the left hand of an assign-\r\n            ment\r\n\r\n       macro recursion      CPP\r\n            A preprocessor macro has attempted  to  expand  itself.\r\n            This would create infinite recursion\r\n\r\n       member is not a member of the struct/union      P1\r\n            This member is not in the structure or union with which\r\n            it is used\r\n\r\n       members cannot be functions      P1\r\n            A member cannot be a function - it can be a pointer  to\r\n            function\r\n\r\n       Missing arg to -u      LINK\r\n            -u requires an argument\r\n\r\n       Missing arg to -w      LINK\r\n            -w requires an argument\r\n\r\n       missing )      CPP\r\n            Put correct ) in expression\r\n\r\n       Missing number after % in -p option      LINK\r\n            After % in a -p option there must be a number\r\n\r\n       Missing number after pragma 'pack'      P1\r\n            The correct syntax is #pragma pack(n) where n is  1,  2\r\n            or 4.\r\n\r\n       module has code below file base      LINK\r\n            A -C option was specified  but  the  program  has  code\r\n            below  the  address specified as the base of the binary\r\n            file\r\n\r\n       multiply defined symbol      LINK\r\n            A symbol is defined more than once\r\n\r\n       name is a union, struct or enum      P1\r\n            A union, struct or enum tag has been re-used in a  dif-\r\n            ferent context\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 94                              HI-TECH C USER'S MANUAL\r\n\r\n   No case labels      CGEN\r\n        This switch has no case labels\r\n\r\n   no identifier in declaration      P1\r\n        This declaration should have an identifier in it\r\n\r\n   No room      CGEN\r\n        The code generator has run out of dynamic  memory.  You\r\n        will  need  to  reduce the number of symbols and/or the\r\n        complexity of expressions\r\n\r\n   No source file      CPP\r\n        Source file could not be found - check spelling, direc-\r\n        tory paths etc.\r\n\r\n   no space      CPP\r\n        Reduce number/size of macro definitions\r\n\r\n   no start record: entry point defaults to zero      LINK\r\n        No start address has been specified  for  the  program;\r\n        the linker has set the start address to 0\r\n\r\n   Non-constant case label      CGEN\r\n        This case label does not evaluate to an  integral  con-\r\n        stant\r\n\r\n   non-void function returns no value      P1\r\n        A function which should return a value has  a  'return'\r\n        statement with no value\r\n\r\n   not a variable identifier      P1\r\n        The identifier is not a variable - it  may  be  e.g.  a\r\n        label or structure tag\r\n\r\n   not an argument      P1\r\n        This identifier is not in the argument  list  for  this\r\n        function\r\n\r\n   only functions may be qualified interrupt      P1\r\n        The type qualifier 'interrupt' may be applied  only  to\r\n        functions, not variables.\r\n\r\n   only functions may be void      P1\r\n        Only functions, not variables, may be declared void\r\n\r\n   only lvalues may be assigned to or modified      P1\r\n        You have attempted to modify an expression  which  does\r\n        not identify a storage location\r\n\r\n   only register storage class allowed      P1\r\n        A parameter may only be auto or register\r\n\r\n   operands of operator not same pointer type      P1\r\n        The operands to the named operator  in  the  expression\r\n        are both pointers but are not the same pointer type\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 95\r\n\r\n       operands of operator not same type      P1\r\n            The operands to the named operator  in  the  expression\r\n            are incompatible types\r\n\r\n       pointer required      P1\r\n            A pointer is required after a '*' (indirection)  opera-\r\n            tor\r\n\r\n       popreg - bad reg      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       portion of expression has no effect      CGEN\r\n            A portion of this expression has no effect on its value\r\n            and no side effects\r\n\r\n       probable missing '}' in previous block      P1\r\n            A declaration has been encountered where an  expression\r\n            was expected. The likely cause of this is that you have\r\n            omitted a closing '}' in the function above this point.\r\n\r\n       psect cannot be in classes a and b      LINK\r\n            A psect can only be in one class\r\n\r\n       psect exceeds max size      LINK\r\n            This psect is larger than a specified maximum size\r\n\r\n       psect is absolute      LINK\r\n            This psect is absolute and cannot have a  link  address\r\n            specified in a -p option\r\n\r\n       Psect not loaded on 0xhexnum boundary       LINK\r\n            This psect must be loaded on a specific boundary\r\n\r\n       Psect not relocated on 0xhexnum boundary      LINK\r\n            This psect must be linked on a specific boundary\r\n\r\n       psect origin multiply defined      LINK\r\n            This psect has its link address defined more than once\r\n\r\n       pushreg - bad reg      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       redundant & applied to array      P1\r\n            An array type has an '&' operator applied to it. It has\r\n            been ignored since use of an array implicitly gives its\r\n            address\r\n\r\n       regused - bad arg to G      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n       signatures do not matchLINK\r\n            An extern function has been declared with an  incorrect\r\n            prototype.  For example if an argument is declared as a\r\n            long in an extern declaration, but is really an int,  a\r\n            signature mismatch will occur.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 96                              HI-TECH C USER'S MANUAL\r\n\r\n   signed bitfields not supported      P1\r\n        Only unsigned bitfields are supported\r\n\r\n   simple type required      P1\r\n        An array or structure type cannot be used here\r\n\r\n   Sizeof yields 0      CGEN\r\n        The size of an object has evaluated to zero in  a  con-\r\n        text where this is illegal, e.g. incrementing a pointer\r\n        to a zero length object.\r\n\r\n   storage class illegal      P1\r\n        A storage class may not be specified here\r\n\r\n   struct/union member expected      P1\r\n        A structure or union member is required after a  '.  or\r\n        '->'\r\n\r\n   struct/union redefined      P1\r\n        This structure or union has been defined twice\r\n\r\n   struct/union required      P1\r\n        A structure or union identifier is  required  before  a\r\n        '.'\r\n\r\n   Switch on long!      CGEN\r\n        Switching on a long expression is not supported\r\n\r\n   symbol cannot be global      LINK\r\n        Stack, filename or line number symbols cannot be global\r\n\r\n   Syntax error in checksum list      LINK\r\n        The checksum list provided is invalid\r\n\r\n   token too long      CPP\r\n        Shorten token (e.g. identifier)\r\n\r\n   too few arguments      P1\r\n        The protype for this function lists more arguments than\r\n        have been supplied\r\n\r\n   too many arguments      P1\r\n        More arguments have been supplied than  listed  in  the\r\n        prototype for this function\r\n\r\n   Too many cases in switch      CGEN,P1\r\n        There are too many cases in this switch\r\n\r\n   too many -D options      CPP\r\n        Use fewer -D options\r\n\r\n   too many defines      CPP\r\n        Reduce number of macro definitions\r\n\r\n   Too many errors      CGEN\r\n        CGEN has given up because there were too many errors.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 97\r\n\r\n       too many formals      CPP\r\n            Reduce number of parameters to this macro definition\r\n\r\n       Too many initializers      CGEN\r\n            There are too many initializers for this object\r\n\r\n       Too many psects      LINK\r\n            There are too many psects for the symbol table\r\n\r\n       Too many symbols      LINK\r\n            There are too many symbols for the linker symbol table\r\n\r\n       too many -U options      CPP\r\n            Use fewer -U options\r\n\r\n       too much defining      CPP\r\n            Reduce number/size of macros\r\n\r\n       too much indirection      P1\r\n            Too many '*'s in this declaration\r\n\r\n       too much pushback      CPP\r\n            Simplify macro usage\r\n\r\n       type conflict      P1\r\n            There is a conflict of types in this  expression,  e.g.\r\n            attempting to assign a structure to a simple type\r\n\r\n       type specifier reqd. for proto arg      P1\r\n            A prototype argument must have a basic type\r\n\r\n       undefined control      CPP\r\n            Check use of #\r\n\r\n       undefined enum tag      P1\r\n            This enumerated type tag has not been defined\r\n\r\n       undefined identifier      P1\r\n            This identifier has not been defined before use\r\n\r\n       undefined struct/union      P1\r\n            The structure or union used has not been defined\r\n\r\n       undefined symbol      LINK\r\n            A list of undefined symbols follows.  If  some  of  the\r\n            symbols should be in a library which was linked, it may\r\n            be caused by a library ordering problem. In  this  case\r\n            rebuild  the  library  with  the  correct  ordering  or\r\n            specify the library more than once in the link command\r\n\r\n       unexpected EOF      P1\r\n            End of file was encountered in the middle of a  C  con-\r\n            struct.  This is commonly caused by omission of a clos-\r\n            ing '}' earlier in the program.\r\n\r\n       Unknown predicate      CGEN\r\n            Internal error - contact HI-TECH\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 98                              HI-TECH C USER'S MANUAL\r\n\r\n   unknown psect      LINK\r\n        The psect specifed in a -p option is not present in the\r\n        program.  Check the spelling and check the case - upper\r\n        case does not match lower case\r\n\r\n   unreachable code      P1\r\n        This section of code can never be executed as there  is\r\n        no possible path to reach it\r\n\r\n   Unreasonable include nesting      CPP\r\n        Reduce number of include files\r\n\r\n   Unreasonable matching depth      CGEN\r\n        Internal error - contact HI-TECH\r\n\r\n   unterminated macro call      CPP\r\n        Probably missing )\r\n\r\n   void function cannot return value      P1\r\n        A function declared void cannot return a value\r\n\r\n   Write error (out of disk space?)      LINK\r\n        Probably means the disk is full\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                              Page 99\r\n\r\n                                  APPENDIX 2\r\n\r\n                          Standard Library Functions\r\n\r\n\r\n\r\n            The functions accessible to user programs in the  stan-\r\n       dard  library  libc.lib are listed below, by category with a\r\n       short comment, then alphabetically with  a  longer  descrip-\r\n       tion.  In  the  detailed  description  of each function, the\r\n       SYNOPSIS section  describes  the  function  in  roughly  the\r\n       manner in which the function would be declared in the source\r\n       file defining it.  Where an  include  file  is  shown,  this\r\n       implies  that  that  include  file  must  be included in any\r\n       source file using that function.\r\n\r\n            Where an include file is not provided, it will normally\r\n       be necessary for an extern declaration of the function to be\r\n       included in any source module using it, to ensure  that  the\r\n       type  of the function is correct.  For example, if the func-\r\n       tion lseek() was to be used, a declaration of the form\r\n\r\n            extern long  lseek();\r\n\r\n       should be in either the source file  itself  or  an  include\r\n       file included in the source file. This ensures that the com-\r\n       piler knows that lseek() returns a long value  and  not  the\r\n       default int.\r\n\r\n            Where reference is made to STDIO, this means the  group\r\n       of functions under the heading STANDARD I/O below. These all\r\n       have one thing in common; they  operate  on  pointers  to  a\r\n       defined  data  type  called  FILE.  Such  a pointer is often\r\n       referred to as a stream pointer. The concept of a stream  is\r\n       central  to these routines. Essentially a stream is a source\r\n       or sink of data bytes. To the operating system  and  library\r\n       routines  this  stream is featureless, i.e. no record struc-\r\n       ture is implied or assumed. Some routines do however  recog-\r\n       nize end of line characters.\r\n\r\n\r\n\r\n                                   STANDARD I/O\r\n\r\n       fopen(name, mode)                  Open file for I/O\r\n       freopen(name, mode, stream)        Re-open existing stream\r\n       fdopen(fd, mode)                   Associate a  stream  with  a  file\r\n                                          descriptor\r\n       fclose(stream)                     Close open file\r\n       fflush(stream)                     Flush buffered data\r\n       getc(stream)                       Read byte from stream\r\n       fgetc(stream)                      Same as getc\r\n       ungetc(c, stream)                  Push char back onto stream\r\n       putc(c, stream)                    Write byte to stream\r\n       fputc(c, stream)                   Same as putc()\r\n       getchar()                          Read byte from standard input\r\n       putchar(c)                         Write byte to standard output\r\n       getw(stream)                       Read word from stream\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 100                             HI-TECH C USER'S MANUAL\r\n\r\n   putw(w, stream)                    Write word to stream\r\n   gets(s)                            Read line from standard input\r\n   fgets(s, n, stream)                Read string from stream\r\n   puts(s)                            Write string to standard output\r\n   fputs(s, stream)                   Write string to stream\r\n   fread(buf, size, cnt, stream)      Binary read from stream\r\n   fwrite(buf, size, cnt, stream)     Binary write to stream\r\n   fseek(stream, offs, wh)            Random access positioning\r\n   ftell(stream)                      Current file read/write position\r\n   rewind(stream)                     Reposition file pointer to start\r\n   setvbuf(stream, buf, mode, size)   Enable/disable buffering of stream\r\n   fprintf(stream, fmt, args)         Formatted output on stream\r\n   printf(fmt, args)                  Formatted standard output\r\n   sprintf(buf, fmt, args)            Formatted output to a string\r\n   vfprintf(stream, fmt, va_ptr)      Formatted output on stream\r\n   vprintf(fmt, va_ptr)               Formatted standard output\r\n   vsprintf(buf, fmt, va_ptr)         Formatted output to a string\r\n   fscanf(stream, fmt, args)          Formatted input from stream\r\n   scanf(fmt, args)                   Formatted standard input\r\n   sscanf(buf, fmt, va_ptr)           Formatted input from a string\r\n   vfscanf(stream, fmt, va_ptr)       Formatted input from stream\r\n   vscanf(fmt, args)                  Formatted standard input\r\n   vsscanf(buf, fmt, va_ptr)          Formatted input from a string\r\n   feof(stream)                       True if stream at EOF\r\n   ferror(stream)                     True if error on stream\r\n   clrerr(stream)                     Reset error status on stream\r\n   fileno(stream)                     Return fd from stream\r\n   remove(name)                       Remove (delete) file\r\n\r\n\r\n\r\n                           STRING HANDLING\r\n\r\n   atoi(s)              Convert ASCII decimal to integer\r\n   atol(s)              Convert ASCII decimal to long integer\r\n   atof(s)              Convert ASCII decimal to float\r\n   xtoi(s)              Convert ASCII hexadecimal to integer\r\n   memchr(s, c, n)      Find char in memory block\r\n   memcmp(s1, s2, n)    Compare n bytes of memory\r\n   memcpy(s1, s2, n)    Copy n bytes from s2 to s1\r\n   memmove(s1, s2, n)   Copy n bytes from s2 to s1\r\n   memset(s, c, n)      Set n bytes at s to c\r\n   strcat(s1, s2)       Append string 2 to string 1\r\n   strncat(s1, s2, n)   Append at most n chars to string 1\r\n   strcmp(s1, s2)       Compare strings\r\n   strncmp(s1, s2, n)   Compare n bytes of strings\r\n   strcpy(s1, s2)       Copy s2 to s1\r\n   strncpy(s1, s2, n)   Copy at most n bytes of s2\r\n   strerror(errnum)     Map errnum to an error message string\r\n   strlen(s)            Length of string\r\n   strchr(s, c)         Find char in string\r\n   strrchr(s, c)        Find rightmost char in string\r\n   strspn(s1, s2)       Length of s1 composed of chars from s2\r\n   strcspn(s1, s2)      Length of s2 composed of chars not from  s2\r\n   strstr(s1, s2)       Locate the first occurence of s2 in s1\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 101\r\n\r\n                              LOW LEVEL I/O\r\n\r\n       open(name, mode)        Open a file\r\n       close(fd)               Close a file\r\n       creat(name)             Create a file\r\n       dup(fd)                 Duplicate file descriptor\r\n       lseek(fd, offs, wh)     Random access positioning\r\n       read(fd, buf, cnt)      Read from file\r\n       rename(name1, name2)    Rename file\r\n       unlink(name)            Remove file from directory\r\n       write(fd, buf, cnt)     Write to file\r\n       isatty(fd)              True if fd refers to tty-like device\r\n       stat(name, buf)         Get information about a file\r\n       chmod(name, mode)       Set file attributes\r\n\r\n\r\n\r\n                            CHARACTER TESTING\r\n\r\n       isalpha(c)           True if c is a letter\r\n       isupper(c)           Upper case letter\r\n       islower(c)           Lower case letter\r\n       isdigit(c)           Digit\r\n       isalnum(c)           Alphnumeric character\r\n       isspace(c)           Space, tab, newline, return or formfeed\r\n       ispunct(c)           Punctuation character\r\n       isprint(c)           Printable character\r\n       isgraph(c)           Printable non-space character\r\n       iscntrl(c)           Control character\r\n       isascii(c)           Ascii character (0-127)\r\n\r\n\r\n\r\n                              FLOATING POINT\r\n\r\n       cos(f)                      Cosine function\r\n       sin(f)                      Sine function\r\n       tan(f)                      Tangent function\r\n       acos(f)                     Arc cosine function\r\n       asin(f)                     Arc sine function\r\n       atan(f)                     Arc tangent function\r\n       exp(f)                      Exponential of f\r\n       log(f)                      Natural log of f\r\n       log10(f)                    Base 10 log of f\r\n       pow(x,y)                    X to the y'th power\r\n       sqrt(f)                     Square root\r\n       fabs(f)                     Floating absolute value\r\n       ceil(f)                     Smallest integral value >= f\r\n       floor(f)                    Largest integral value <= f\r\n       sinh(f)                     Hyperbolic sine\r\n       cosh(f)                     Hyperbolic cosine\r\n       tanh(f)                     Hyperbolic tangent\r\n       frexp(y, p)                 Split into mantissa and exponent\r\n       ldexp(y, i)                 Load new exponent\r\n\r\n\r\n\r\n                               CONSOLE I/O\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 102                             HI-TECH C USER'S MANUAL\r\n\r\n\r\n   getch()                       Get single character\r\n   getche()                      Get single character with echo\r\n   putch(c)                      Put single character\r\n   ungetch(c)                    Push character back\r\n   kbhit()                       Test for key pressed\r\n   cgets(s)                      Get line from console\r\n   cputs(s)                      Put string to console\r\n\r\n\r\n\r\n\r\n                     DATE AND TIME FUNCTIONS\r\n\r\n   time(p)                    Get current date/time\r\n   gmtime(p)                  Get broken down Universal time\r\n   localtime(p)               Get broken down local time\r\n   asctime(t)                 Convert broken down time to ascii\r\n   ctime(p)                   Convert time to ascii\r\n\r\n\r\n\r\n                                 MISCELLANEOUS\r\n\r\n   execl(name, args)               Execute another program\r\n   execv(name, argp)               Execute another program\r\n   spawnl(name, arg, ...)          Execute a subprogram\r\n   spawnv(name, argp)              Execute a subprogram\r\n   system(s)                       Execute system command\r\n   atexit(func)                    Install func to be executed on termination\r\n   exit(status)                    Terminate execution\r\n   _exit(status)                   Terminate execution immediately\r\n   getuid()                        Get user id (CP/M)\r\n   setuid(uid)                     Set user id (CP/M)\r\n   chdir(s)                        Change directory (MS-DOS)\r\n   mkdir(s)                        Create directory (MS-DOS)\r\n   rmdir(s)                        Remove directory (MS-DOS)\r\n   getcwd(drive)                   Get current working directory (MS-DOS)\r\n   signal(sig, func)               Set trap for interrupt condition\r\n   brk(addr)                       Set memory allocation\r\n   sbrk(incr)                      Adjust memory allocation\r\n   malloc(cnt)                     Dynamic memory allocation\r\n   free(ptr)                       Dynamic memory release\r\n   realloc(ptr, cnt)               Dynamic memory reallocation\r\n   calloc(cnt, size)               Dynamic memory allocation zeroed\r\n   perror(s)                       Print error message\r\n   qsort(base, nel, width, func)   Quick sort\r\n   srand(seed)                     Initialize random number generator\r\n   rand()                          Get next random number\r\n   setjmp(buf)                     Setup for non-local goto\r\n   longjmp(buf, val)               Non-local goto\r\n   _getargs(buf, name)             Wild card expansion and i/o redirection\r\n   inp(port)                       Read port\r\n   outp(port, data)                Write data to port\r\n   bdos(func, val)                 Perform bdos call (CP/M)\r\n   msdos(func, val, val, ...)      Perform msdos call\r\n   msdoscx(func, val, val, ...)    Alternate msdos call\r\n   intdos(ip, op)                  Execute DOS interrupt\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 103\r\n\r\n       intdosx(ip, op, sp)             Execute DOS interrupt\r\n       segread(sp)                     Get segment register values\r\n       int86(int, ip, op)              Execute software interrupt\r\n       int86x(int, ip, op, sp)         Execute software interrupt\r\n       bios(n, c)                      Call bios entry (CP/M)\r\n       ei()                            Enable interrupts\r\n       di()                            Disable interrupts\r\n       set_vector(vec, func)           Set an interrupt vector\r\n       assert(e)                       Run time assertion\r\n       getenv(s)                       Get environment string (MS-DOS)\r\n\r\n\r\n\r\n\r\n\r\n                         ACOS, ASIN, ATAN, ATAN2\r\n       SYNOPSIS\r\n\r\n            #include  <math.h>\r\n\r\n            double    acos(double f)\r\n            double    asin(double f)\r\n            double    atan(double f)\r\n\r\n            double    atan2(double x, double y)\r\n\r\n\r\n       DESCRIPTION\r\n            These functions are the converse  of  the  trignometric\r\n            functions cos, sin and tan. Acos and asin are undefined\r\n            for arguments whose absolute value is greater than 1.0.\r\n            The  returned  value  is  in radians, and always in the\r\n            range -pi/2 to +pi/2, except for cos(), which returns a\r\n            value  in  the  range  0  to  pi.   Atan2() returns the\r\n            inverse tan of x/y but uses the signs of its  arguments\r\n            to return a value in the range -pi to +pi.\r\n\r\n       SEE ALSO\r\n\r\n            sin, cos, tan\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 104                             HI-TECH C USER'S MANUAL\r\n\r\n                              ATEXIT\r\n   SYNOPSIS\r\n\r\n        #include  <stdlib.h>\r\n\r\n        int atexit(void (*func)(void));\r\n\r\n\r\n   DESCRIPTION\r\n        The atexit() function registers the function pointed to\r\n        by  func, to be called without arguments at normal pro-\r\n        gram termination.  Ateixt() returns zero if the  regis-\r\n        tration succeeds, nonzero if it fails.  On program ter-\r\n        mination, all  functions  registered  by  atexit()  are\r\n        called, in the reverse order of their registration.\r\n\r\n   SEE ALSO\r\n\r\n        exit\r\n\r\n\r\n\r\n\r\n\r\n                             ASCTIME\r\n   SYNOPSIS\r\n\r\n        #include  <time.h>\r\n\r\n        char *    asctime(time_t t)\r\n\r\n\r\n   DESCRIPTION\r\n        Asctime() takes the broken down time pointed to by  its\r\n        argument,  and returns a 26 character string describing\r\n        the current date and time in the format\r\n\r\n             Sun Sep 16 01:03:52 1973\\n\\0\r\n\r\n        Note the newline at the end of the string. The width of\r\n        each field in the string is fixed.\r\n\r\n   SEE ALSO\r\n\r\n        ctime, time, gmtime, localtime\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 105\r\n\r\n                                  ASSERT\r\n       SYNOPSIS\r\n\r\n            #include  <assert.h>\r\n\r\n            void      assert(int e)\r\n\r\n\r\n       DESCRIPTION\r\n            This macro is used for debugging  purposes;  the  basic\r\n            method  of  usage  is  to  place  assertions  liberally\r\n            throughout your code at points where correct  operation\r\n            of  the code depends upon certain conditions being true\r\n            initially. An assert() may be used  to  ensure  at  run\r\n            time  that that assumption holds. For example, the fol-\r\n            lowing statement asserts that the pointer  tp  is  non-\r\n            null:\r\n\r\n                 assert(tp);\r\n\r\n            If at run time the expression evaluates to  false,  the\r\n            program  will  abort  with  a  message  identifying the\r\n            source file and line number of the assertion,  and  the\r\n            expression  used as an argument to it. A fuller discus-\r\n            sion of the uses of assert  is  impossible  in  limited\r\n            space,  but  it is closely linked to methods of proving\r\n            program correctness.\r\n\r\n\r\n\r\n\r\n                             ATOF, ATOI, ATOL\r\n       SYNOPSIS\r\n\r\n            #include  <math.h>\r\n\r\n            double    atof(char * s)\r\n            int atoi(char * s)\r\n\r\n            #include  <stdlib.h>\r\n\r\n            long      atol(char * s)\r\n\r\n\r\n       DESCRIPTION\r\n            These routines convert a decimal number in the argument\r\n            string  s  into a double float, integer or long integer\r\n            respectively. Leading blanks are skipped over.  In  the\r\n            case  of  atof(), the number may be in scientific nota-\r\n            tion.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 106                             HI-TECH C USER'S MANUAL\r\n\r\n                         BDOS (CP/M only)\r\n   SYNOPSIS\r\n\r\n        #include  <cpm.h>\r\n\r\n        char      bdos(int func, int arg)\r\n\r\n        short bdoshl(int func, int arg)(CP/M-80 only)\r\n\r\n\r\n   DESCRIPTION\r\n        Bdos() calls the CP/M BDOS with func in register C  (CL\r\n        for  CP/M-86)  and  arg in register DE (DX). The return\r\n        value is the byte returned by the BDOS  in  register  A\r\n        (AX).   Bdoshl()  is  the  same, except that the return\r\n        value is the value returned by the BDOS  in  HL.   Con-\r\n        stant  values  for the various BDOS function values are\r\n        defined in cpm.h.\r\n\r\n        These functions should be avoided  except  in  programs\r\n        which  are not intended to be used on an operating sys-\r\n        tem other than CP/M. The standard I/O routines  are  to\r\n        be preferred, since they are portable.\r\n\r\n   SEE ALSO\r\n\r\n        bios, msdos\r\n\r\n\r\n\r\n\r\n\r\n                         BIOS (CP/M only)\r\n   SYNOPSIS\r\n\r\n        #includ   <cpm.h>\r\n\r\n        char bios(int n, int a1, int a2)\r\n\r\n\r\n   DESCRIPTION\r\n        This function will call the n'th bios entry point (cold\r\n        boot  =  0,  warm boot = 1, etc.) with register BC (CX)\r\n        set to the argument a1 and DE (DX) set to the  argument\r\n        a2. The return value is the contents of register A (AX)\r\n        after the bios call. On CP/M-86, bdos  function  50  is\r\n        used  to  perform  the bios call.  This function should\r\n        not be used unless  unavoidable,  since  it  is  highly\r\n        non-portable. There is even no guarantee of portability\r\n        of bios calls between differing CP/M systems.\r\n\r\n   SEE ALSO\r\n\r\n        bdos\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 107\r\n\r\n                                  CALLOC\r\n       SYNOPSIS\r\n\r\n            #include  <stdlib.h>\r\n\r\n            char * calloc(size_t cnt, size_t size)\r\n\r\n\r\n       DESCRIPTION\r\n            Calloc() attempts  to  obtain  a  contiguous  block  of\r\n            dynamic  memory  which  will  hold cnt objects, each of\r\n            length size.  The  block  is  filled  with  zeroes.   A\r\n            pointer  to  the  block is returned, or 0 if the memory\r\n            could not be allocated.\r\n\r\n       SEE ALSO\r\n\r\n            brk, sbrk, malloc, free\r\n\r\n\r\n\r\n\r\n\r\n                               CGETS, CPUTS\r\n       SYNOPSIS\r\n\r\n            #include  <conio.h>\r\n\r\n            char *    cgets(char * s)\r\n\r\n            void      cputs(char * s)\r\n\r\n\r\n       DESCRIPTION\r\n            Cputs() will read one line of input  from  the  console\r\n            into  the  buffer  passed as an argument. It does so by\r\n            repeated calls to getche().  Cputs() writes  its  argu-\r\n            ment string to the console, outputting carriage returns\r\n            before each newline in the  string.  It  calls  putch()\r\n            repeatedly.\r\n\r\n       SEE ALSO\r\n\r\n            getch, getche, putch\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 108                             HI-TECH C USER'S MANUAL\r\n\r\n                              CHDIR\r\n   SYNOPSIS\r\n\r\n        #include  <sys.h>\r\n\r\n        int chdir(char * s)\r\n\r\n\r\n   DESCRIPTION\r\n        This function is availble only under MS-DOS. It changes\r\n        the current working directory to the path name supplied\r\n        as argument. This path  name  be  be  absolute,  as  in\r\n        A:\\FRED, or relative, as in ..\\SOURCES.  A return value\r\n        of -1 indicates that the requested change could not  be\r\n        performed.\r\n\r\n   SEE ALSO\r\n\r\n        mkdir, rmdir, getcwd\r\n\r\n\r\n\r\n\r\n\r\n                              CHMOD\r\n   SYNOPSIS\r\n\r\n        #include  <stat.h>\r\n\r\n        int chmod(char * name, int )\r\n        char *    name;\r\n        int mode;\r\n\r\n\r\n   DESCRIPTION\r\n        This function changes the file attributes (or modes) of\r\n        the  named  file.   The  argument name may be any valid\r\n        file name. The  mode  argument  may  include  all  bits\r\n        defined  in stat.h except those relating to the type of\r\n        the file, e.g. S_IFDIR. Note however that not all  bits\r\n        may  be  changed under all operating systems, e.g. nei-\r\n        ther DOS nor CP/M permit a file to be made  unreadable,\r\n        thus  even  if  mode  does not include S_IREAD the file\r\n        will still be readable (and stat()  will  still  return\r\n        S_IREAD in flags).\r\n\r\n   SEE ALSO\r\n\r\n        stat, creat\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 109\r\n\r\n                                  CLOSE\r\n       SYNOPSIS\r\n\r\n            #include  <unixio.h>\r\n\r\n            int close(int fd)\r\n\r\n\r\n       DESCRIPTION\r\n            This routine closes the file associated with  the  file\r\n            descriptor fd, which will have been previously obtained\r\n            from a call to open(). Close() returns 0 for a success-\r\n            ful close, or -1 otherwise.\r\n\r\n       SEE ALSO\r\n\r\n            open, read, write, seek\r\n\r\n\r\n\r\n\r\n\r\n                              CLRERR, CLREOF\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n            void clrerr(FILE * stream)\r\n            void clreof(FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            These are macros, defined in stdio.h, which  reset  the\r\n            error and end of file flags respectively for the speci-\r\n            fied stream. They should be used with care;  the  major\r\n            valid use is for clearing an EOF status on input from a\r\n            terminal-like device, where it may be valid to continue\r\n            to read after having seen an end-of-file indication.\r\n\r\n       SEE ALSO\r\n\r\n            fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 110                             HI-TECH C USER'S MANUAL\r\n\r\n                               COS\r\n   SYNOPSIS\r\n\r\n        #include  <math.h>\r\n\r\n        double    cos(double f)\r\n\r\n\r\n   DESCRIPTION\r\n        This function yields the cosine of its argument.\r\n\r\n   SEE ALSO\r\n\r\n        sin, tan, asin, acos, atan\r\n\r\n\r\n\r\n\r\n\r\n                         COSH, SINH, TANH\r\n   SYNOPSIS\r\n\r\n        #include  <math.h>\r\n\r\n        double    cosh(double f)\r\n        double    sinh(double f)\r\n        double    tanh(double f)\r\n\r\n\r\n   DESCRIPTION\r\n        These functions implement  the  hyperbolic  trig  func-\r\n        tions.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 111\r\n\r\n                                  CREAT\r\n       SYNOPSIS\r\n\r\n            #include  <stat.h>\r\n\r\n            int creat(char * name, int mode)\r\n\r\n\r\n       DESCRIPTION\r\n            This routine attempts to create the file named by name.\r\n            If the file exists and is writeable, it will be removed\r\n            and re-created. The return value is -1  if  the  create\r\n            failed, or a small non-negative number if it succeeded.\r\n            This number is a valuable token which must be  used  to\r\n            write  to or close the file subsequently.  Mode is used\r\n            to initialize the attributes of the created file.   The\r\n            allowable  bits  are  the  same as for chmod(), but for\r\n            Unix compatibility it is recommended  that  a  mode  of\r\n            0666  or 0600 be used. Under CP/M the mode is ignored -\r\n            the only way to set  a  files  attributes  is  via  the\r\n            chmod() function.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, read, write, seek, stat, chmod\r\n\r\n\r\n\r\n\r\n\r\n                                  CTIME\r\n       SYNOPSIS\r\n\r\n            #include  <time.h>\r\n\r\n            char *    ctime(time_t t)\r\n\r\n\r\n       DESCRIPTION\r\n            Ctime() converts the time in seconds pointed to by  its\r\n            argument  to a string of the same form as described for\r\n            asctime.  Thus the following program prints the current\r\n            time and date:\r\n\r\n\r\n                 #include  <time.h>\r\n\r\n                 main()\r\n                 {\r\n                     time_t      t;\r\n\r\n                     time(&t);\r\n                     printf(\"%s\", ctime(&t));\r\n                 }\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 112                             HI-TECH C USER'S MANUAL\r\n\r\n   SEE ALSO\r\n\r\n        gmtime, localtime, asctime, time\r\n\r\n\r\n\r\n\r\n\r\n                            DIV, LDIV\r\n   SYNOPSIS\r\n\r\n        #include  <stdlib.h>\r\n\r\n        div_t     div(int numer, int denom)\r\n        ldiv_t    ldiv(long numer, long denom)\r\n\r\n\r\n   DESCRIPTION\r\n        The div() function computes the quotient and  remainder\r\n        of  the  divison of numer by denom.  The div() function\r\n        returns a structure of type div_t, containing both  the\r\n        quotient  and  remainder.   ldiv()  is similar to div()\r\n        except it takes arguments of type long  and  returns  a\r\n        structure  of  type ldiv_t.  The types div_t and ldiv_t\r\n        are defined in <stdlib.h> as follows:\r\n\r\n        typedef struct {\r\n             intquot, rem;\r\n        } div_t;\r\n\r\n        typedef struct {\r\n             longquot, rem;\r\n        } ldiv_t;\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 113\r\n\r\n                                  DI, EI\r\n       SYNOPSIS\r\n\r\n            void ei(void);\r\n            void di(void);\r\n\r\n\r\n       DESCRIPTION\r\n            Ei() and di() enable  and  disable  interrupts  respec-\r\n            tivly.\r\n\r\n\r\n\r\n\r\n                                   DUP\r\n       SYNOPSIS\r\n\r\n            #include  <unixio.h>\r\n\r\n            int dup(int fd)\r\n\r\n\r\n       DESCRIPTION\r\n            Given a file descriptor, such as  returned  by  open(),\r\n            this  routine will return another file descriptor which\r\n            will refer to the same open file.  -1  is  returned  if\r\n            the  fd  argument is a bad descriptor or does not refer\r\n            to an open file.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, creat, read, write\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 114                             HI-TECH C USER'S MANUAL\r\n\r\n                           EXECL, EXECV\r\n   SYNOPSIS\r\n\r\n        #include  <sys.h>\r\n\r\n        int execl(char * name, pname, ...)\r\n        int execv(char * name, ppname)\r\n\r\n\r\n   DESCRIPTION\r\n        Execl() and execv() load and execute the program speci-\r\n        fied  by  the  string name. Execl() takes the arguments\r\n        for the program from the zero-terminated list of string\r\n        arguments.  Execv()  is passed a pointer to an array of\r\n        strings.  The array must  be  zero-terminated.  If  the\r\n        named  program  is found and can be read, the call does\r\n        not return. Thus any return from these routines may  be\r\n        treated as an error.\r\n\r\n   SEE ALSO\r\n\r\n        spawnl, spawnv, system\r\n\r\n\r\n\r\n\r\n\r\n                               EXIT\r\n   SYNOPSIS\r\n\r\n        #include  <stdlib.h>\r\n\r\n        void      exit(int status)\r\n\r\n\r\n   DESCRIPTION\r\n        This call will close all open files and exit  from  the\r\n        program.  On  CP/M,  this  means a return to CCP level.\r\n        Status will be stored in a known place for  examination\r\n        by  other  programs. This is only useful if the program\r\n        executing was actually invoked by another program which\r\n        is trapping warm boots. The status value will be stored\r\n        on CP/M at 80H.  This call will never return.\r\n\r\n   SEE ALSO\r\n\r\n        atexit\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 115\r\n\r\n                                  _EXIT\r\n       SYNOPSIS\r\n\r\n            #include  <stdlib.h>\r\n            void      _exit(int status)\r\n\r\n\r\n       DESCRIPTION\r\n            This function will cause an  immediate  exit  from  the\r\n            program,  without  the normal flushing of stdio buffers\r\n            that is performed by exit().\r\n\r\n       SEE ALSO\r\n\r\n            exit\r\n\r\n\r\n\r\n\r\n\r\n                           EXP, LOG, LOG10, POW\r\n       SYNOPSIS\r\n\r\n            #include  <math.h>\r\n\r\n            double    exp(double f)\r\n            double    log(double f)\r\n            double    log10(double f)\r\n            double    pow(double x, y)\r\n\r\n\r\n       DESCRIPTION\r\n            Exp() returns the exponential function of its argument,\r\n            log() the natural logarithm of f, and log10() the loga-\r\n            rithm to base 10. Pow() returns the value of  x  raised\r\n            to the y'th power.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 116                             HI-TECH C USER'S MANUAL\r\n\r\n                        FABS, CEIL, FLOOR\r\n   SYNOPSIS\r\n\r\n        #include  <math.h>\r\n\r\n        double    fabs(double f)\r\n        double    ceil(double f)\r\n        double    floor(double f)\r\n\r\n\r\n   DESCRIPTION\r\n        These routines return respectively the  absolute  value\r\n        of  f, the smallest integral value not less than f, and\r\n        the largest integral value not greater than f.\r\n\r\n\r\n\r\n\r\n                              FCLOSE\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int fclose(FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        This routine closes the specified  i/o  stream.  Stream\r\n        should  be  a  token  returned  by  a  previous call to\r\n        fopen().  NULL is returned on a successful  close,  EOF\r\n        otherwise.\r\n\r\n   SEE ALSO\r\n\r\n        fopen, fread, fwrite\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 117\r\n\r\n                               FEOF, FERROR\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            feof(FILE * stream)\r\n            ferror(FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            These macros test the status of the EOF and ERROR  bits\r\n            respectively  for  the  specified  stream. Each will be\r\n            true if the corresponding flag is set. The  macros  are\r\n            defined  in stdio.h. Stream must be a token returned by\r\n            a previous fopen() call.\r\n\r\n       SEE ALSO\r\n\r\n            fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n                                  FFLUSH\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int fflush(FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            Fflush() will output to the disk file or  other  device\r\n            currently  open on the specified stream the contents of\r\n            the associated  buffer.  This  is  typically  used  for\r\n            flushing buffered standard output in interactive appli-\r\n            cations.\r\n\r\n       SEE ALSO\r\n\r\n            fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 118                             HI-TECH C USER'S MANUAL\r\n\r\n                              FGETC\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int fgetc(FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Fgetc() returns  the  next  character  from  the  input\r\n        stream.   If  end-of-file  is  encountered  EOF will be\r\n        returned instead. It is for this reason that the  func-\r\n        tion is declared as int. The integer EOF is not a valid\r\n        byte, thus end-of-file is distinguishable from  reading\r\n        a  byte  of  all  1 bits from the file.  Fgetc() is the\r\n        non-macro version of getc().\r\n\r\n   SEE ALSO\r\n\r\n        fopen, fclose, fputc, getc, putc\r\n\r\n\r\n\r\n\r\n\r\n                              FGETS\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        char * fgets(char * s, size_t n, char * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Fgets() places in the buffer s  up  to  n-1  characters\r\n        from  the  input  stream.  If  a newline is seen in the\r\n        input before the correct number of characters is  read,\r\n        then  fgets() will return immediately. The newline will\r\n        be left in the buffer. The buffer  will  be  null  ter-\r\n        minated  in any case.  A successful fgets() will return\r\n        its first argument; NULL is returned on end-of-file  or\r\n        error.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 119\r\n\r\n                                  FILENO\r\n       SYNOPSIS\r\n\r\n            fileno(FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            Fileno() is a macro from stdio.h which yields the  file\r\n            descriptor  associated  with  stream. It is mainly used\r\n            when it is desired to perform some low-level  operation\r\n            on a file opened as a stdio stream.\r\n\r\n       SEE ALSO\r\n\r\n            fopen, fclose, open, close\r\n\r\n\r\n\r\n\r\n\r\n                                  FOPEN\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            FILE * fopen(char * name, char * mode);\r\n\r\n\r\n       DESCRIPTION\r\n\r\n\r\n       DESCRIPTION\r\n            Fopen() attempts to open file for  reading  or  writing\r\n            (or  both)  according to the mode string supplied.  The\r\n            mode string is interpreted as follows:\r\n\r\n       r    The file is opend for reading if it exists. If the file\r\n            does not exist the call fails.\r\n\r\n       r+   If the file exists it is opened for reading  and  writ-\r\n            ing. If the file does not already exist the call fails.\r\n\r\n       w    The file is created if it does not exist, or  truncated\r\n            if it does. It is then opened for writing.\r\n\r\n       w+   The file is created if it does not  already  exist,  or\r\n            truncated  if  it does.  The file is opened for reading\r\n            and writing.\r\n\r\n       a    The file is created if it does not already  exist,  and\r\n            opened  for  writing.   All  writes will be dynamically\r\n            forced to the end of file, thus this mode is  known  as\r\n            append mode.\r\n\r\n       a+   The file is created if it does not already  exist,  and\r\n            opened  for reading and writing. All writes to the file\r\n            will be dynamically forced to the end of the file, i.e.\r\n            while  any  portion of the file may be read, all writes\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 120                             HI-TECH C USER'S MANUAL\r\n\r\n        will take place at the end of the  file  and  will  not\r\n        overwrite  any  existing  data.   Calling fseek() in an\r\n        attempt to write at any other place in  the  file  will\r\n        not be effective.\r\n\r\n        The \"b\" modifier may be appended to any  of  the  above\r\n   modes,  e.g.  \"r+b\"  or \"rb+\" are equivalent. Adding the \"b\"\r\n   modifier will cause the file to be opened in  binary  rather\r\n   than  ASCII  mode.  Opening  in ASCII mode ensures that text\r\n   files are read in a manner compatible with the  Unix-derived\r\n   conventions  for  C  programs,  i.e. that text files contain\r\n   lines delimited by newline characters.  The  special  treat-\r\n   ment of read or written characters varies with the operating\r\n   system, but includes some or all of the following:\r\n\r\n   NEWLINE (LINE FEED)\r\n        Converted to carriage return, line feed on output.\r\n\r\n   RETURN\r\n        Ignored on input, inserted before NEWLINE on output.\r\n\r\n   CTRL-Z\r\n        Signals EOF on input, appended on fclose on  output  if\r\n        necessary on CP/M.\r\n\r\n        Opening a file in binary mode will allow each character\r\n        to  be read just as written, but because the exact size\r\n        of a file is not known to CP/M, the  file  may  contain\r\n        more  bytes  than were written to it.  See open() for a\r\n        description of what constitutes a file name.\r\n\r\n        When using one of the  read/write  modes  (with  a  '+'\r\n   character  in the string), although they permits reading and\r\n   writing on the same stream, it  is  not  possible  to  arbi-\r\n   trarily  mix  input  and output calls to the same stream. At\r\n   any given time a stream opened with a \"+\" mode  will  be  in\r\n   either  an  input  or  output  state.  The state may only be\r\n   changed when the associated buffer is empty, which  is  only\r\n   guaranteed  immediately  after  a call to fflush() or one of\r\n   the file positioning  functions  fseek()  or  rewind().  The\r\n   buffer will also be empty after encountering EOF while read-\r\n   ing a binary stream, but it is recommended that an  explicit\r\n   call  to  fflush()  be  used  to ensure this situation. Thus\r\n   after reading from a stream  you  should  call  fflush()  or\r\n   fseek()  before attempting to write on that stream, and vice\r\n   versa.\r\n\r\n   SEE ALSO\r\n\r\n        fclose, fgetc, fputc, freopen\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 121\r\n\r\n                                 FPRINTF\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            fprintf(FILE * stream, char * fmt, ...);\r\n            vfprintf(FILE * stream, va_list va_arg);\r\n\r\n\r\n       DESCRIPTION\r\n            Fprintf() performs formatted printing on the  specified\r\n            stream. Refer to printf() for the details of the avail-\r\n            able formats.  Vfprintf() is similar to  fprintf()  but\r\n            takes  a  variable  argument list pointer rather than a\r\n            list of arguments. See the  description  of  vastart()\r\n            for more information on variable argument lists.\r\n\r\n       SEE ALSO\r\n\r\n            printf, fscanf, sscanf\r\n\r\n\r\n\r\n\r\n\r\n                                  FPUTC\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int fputc(int c, FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            The character c is written to the supplied stream. This\r\n            is  the  non-macro  version of putc(). The character is\r\n            returned  if  it  was  successfully  written,  EOF   is\r\n            returned  otherwise.  Note that \"written to the stream\"\r\n            may mean only placing the character in the buffer asso-\r\n            ciated with the stream.\r\n\r\n       SEE ALSO\r\n\r\n            putc, fgetc, fopen, fflush\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 122                             HI-TECH C USER'S MANUAL\r\n\r\n                              FPUTS\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int fputs(char * s, FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        The null-terminated string s is written to the  stream.\r\n        No  newline is appended (cf. puts() ). The error return\r\n        is EOF.\r\n\r\n   SEE ALSO\r\n\r\n        puts, fgets, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n                              FREAD\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int fread(void * buf, size_t size, size_t cnt,\r\n                 FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Up to cnt objects, each of length size, are  read  into\r\n        memory  at buf from the stream. The return value is the\r\n        number of objects read. If none  is  read,  0  will  be\r\n        returned.   Note that a return value less than cnt, but\r\n        greater  than  0,  may  not  represent  an  error  (cf.\r\n        fwrite() ).  No word alignment in the stream is assumed\r\n        or necessary. The read is done via successive getc()'s.\r\n\r\n   SEE ALSO\r\n\r\n        fwrite, fopen, fclose, getc\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 123\r\n\r\n                                   FREE\r\n       SYNOPSIS\r\n\r\n            #include  <stdlib.h>\r\n\r\n            void      free(void * ptr)\r\n\r\n\r\n       DESCRIPTION\r\n            Free() deallocates the block of memory  at  ptr,  which\r\n            must have been obtained from a call to malloc() or cal-\r\n            loc().\r\n\r\n       SEE ALSO\r\n\r\n            malloc, calloc\r\n\r\n\r\n\r\n\r\n\r\n                                 FREOPEN\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            FILE * freopen(char * name, char * mode, FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            Freopen() closes the given stream (if  open)  then  re-\r\n            opens  the  stream  attached  to  the file described by\r\n            name. The mode of opening is given by mode.  It  either\r\n            returns  the stream argument, if successful, or NULL if\r\n            not. See fopen() for more information.\r\n\r\n       SEE ALSO\r\n\r\n            fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 124                             HI-TECH C USER'S MANUAL\r\n\r\n                           FREXP, LDEXP\r\n   SYNOPSIS\r\n\r\n        #include  <math.h>\r\n\r\n        double    frexp(double f, int * p)\r\n\r\n        double    ldexp(double f, int i)\r\n\r\n\r\n   DESCRIPTION\r\n        Frexp() breaks a floating point number into  a  normal-\r\n        ized  fraction  and an integral power of 2. The integer\r\n        is stored into the int object pointed  to  by  p.   Its\r\n        return  value  x is in the interval [0.5, 1.0) or zero,\r\n        and f equals x times 2 raised to the  power  stored  in\r\n        *p.   If  f is zero, both parts of the result are zero.\r\n        Ldexp() performs the reverse operation; the  integer  i\r\n        is  added  to  the exponent of the floating point f and\r\n        the resultant value returned.\r\n\r\n\r\n\r\n\r\n                              FSCANF\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int fscanf(FILE * stream, char * fmt, ...)\r\n\r\n\r\n   DESCRIPTION\r\n        This routine performs formatted input from  the  speci-\r\n        fied  stream. See scanf() for a full description of the\r\n        behaviour of the  routine.   Vfscanf()  is  similar  to\r\n        fscanf()  but  takes  a  variable argument list pointer\r\n        rather than a list of arguments. See the description of\r\n        va_start()  for  more  information on variable argument\r\n        lists.\r\n\r\n   SEE ALSO\r\n\r\n        scanf, sscanf, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 125\r\n\r\n                                  FSEEK\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int fseek(FILE * stream, long offs, int wh)\r\n\r\n\r\n       DESCRIPTION\r\n            Fseek() positions the \"file pointer\" (i.e. a pointer to\r\n            the next character to be read or written) of the speci-\r\n            fied stream as follows:\r\n\r\n                         _____________________________\r\n                        |_wh|____resultant_location__|\r\n                        | 0 |  offs                  |\r\n                        | 1 |  offs+previous location|\r\n                        | 2 |  offs+length of file   |\r\n                        |___|________________________|\r\n\r\n\r\n            It should be noted that offs is a  signed  value.  Thus\r\n            the  3  allowed  modes  give postioning relative to the\r\n            beginning of the file, the current file pointer and the\r\n            end  of  the  file respectively. EOF is returned if the\r\n            positioning request could not be satisfied.  Note  how-\r\n            ever  that  positioning  beyond  the end of the file is\r\n            legal, but will result  in  an  EOF  indication  if  an\r\n            attempt  is  made  to  read  data there. It is quite in\r\n            order to write data beyond the previous  end  of  file.\r\n            Fseek() correctly accounts for any buffered data.\r\n\r\n       SEE ALSO\r\n\r\n            lseek, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 126                             HI-TECH C USER'S MANUAL\r\n\r\n                              FTELL\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        long      ftell(FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        This function returns the current position of the  con-\r\n        ceptual  read/write  pointer  associated  with  stream.\r\n        This is the position relative to the beginning  of  the\r\n        file of the next byte to be read from or written to the\r\n        file.\r\n\r\n   SEE ALSO\r\n\r\n        fseek\r\n\r\n\r\n\r\n\r\n\r\n                              FWRITE\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int fwrite(void * buf, size_t size, size_t cnt,\r\n                FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Cnt objects of length size bytes will be  written  from\r\n        memory  at  buf, to the specified stream. The number of\r\n        whole objects written will be returned, or  0  if  none\r\n        could  be  written.  Any  return value not equal to cnt\r\n        should be treated as an error (cf. fread() ).\r\n\r\n   SEE ALSO\r\n\r\n        fread, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 127\r\n\r\n                                 _GETARGS\r\n       SYNOPSIS\r\n\r\n            #include  <sys.h>\r\n\r\n            char ** _getargs(char * buf, char * name)\r\n            extern int _argc_;\r\n\r\n\r\n       DESCRIPTION\r\n            This routine performs I/O redirection (CP/M  only)  and\r\n            wild  card  expansion.  Under MS-DOS I/O redirection is\r\n            performed by the operating system. It  is  called  from\r\n            startup  code  to operate on the command line if the -R\r\n            option is used to the C command, but may also be called\r\n            by  user-written  code. If the buf argument is null, it\r\n            will read lines of text from  standard  input.  If  the\r\n            standard  input is a terminal (usually the console) the\r\n            name argument will be written  to  the  standard  error\r\n            stream as a prompt. If the buf argument is not null, it\r\n            will be used as the source of the  string  to  be  pro-\r\n            cessed.  The returned value is a pointer to an array of\r\n            strings, exactly as would be pointed  to  by  the  argv\r\n            argument  to the main() function. The number of strings\r\n            in the array may be obtained from  the  global  _argc_.\r\n            For example, a typical use of this function would be:\r\n\r\n            #include  <sys.h>\r\n\r\n            main(argc, argv)\r\n            char ** argv;\r\n            {\r\n                extern char ** _getargs();\r\n                extern int  _argc_;\r\n\r\n                if(argc == 1) {/* no arguments */\r\n                argv = _getargs(0, \"myname\");\r\n                argc = _argc_;\r\n                }\r\n                .\r\n                .\r\n                .\r\n            }\r\n\r\n            There will be one string in the array for each word  in\r\n            the  buffer  processed.   Quotes,  either single (') or\r\n            double (\") may  be  used  to  include  white  space  in\r\n            \"words\". If any wild card characters (? or *) appear in\r\n            a non-quoted word, it will be expanded into a string of\r\n            words,  one  for each file matching the word. The usual\r\n            CP/M conventions are followed for  this  expansion.  On\r\n            CP/M  any occurence of the redirection characters > and\r\n            < outside quotes  will  be  handled  in  the  following\r\n            manner:\r\n\r\n       > name\r\n            will cause standard output to be redirected to the file\r\n            name.\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 128                             HI-TECH C USER'S MANUAL\r\n\r\n   < name\r\n        will cause standard input to  be  redirected  from  the\r\n        file name.\r\n\r\n   >> name\r\n        will cause standard output to append to file name.\r\n\r\n        White space is optional between the >  or  <  character\r\n        and  the  file  name,  however  it  is  an  error for a\r\n        redirection character not to  be  followed  by  a  file\r\n        name.   It  is also an error if a file cannot be opened\r\n        for input or created for output.  An append redirection\r\n        (>>) will create the file if it does not exist.  If the\r\n        source of text  to  be  processed  is  standard  input,\r\n        several  lines  may  be  supplied  by  ending each line\r\n        (except the last) with a backslash (\\).  This serves as\r\n        a continuation character. Note that the newline follow-\r\n        ing the backslash is ignored, and not treated as  white\r\n        space.\r\n\r\n\r\n\r\n\r\n                               GETC\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int getc(FILE * stream)\r\n        FILE * stream;\r\n\r\n\r\n   DESCRIPTION\r\n        One character is read from  the  specified  stream  and\r\n        returned. EOF will be returned on end-of-file or error.\r\n        This is the macro version of fgetc(), and is defined in\r\n        stdio.h.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 129\r\n\r\n                      GETCH, GETCHE, UNGETCH, PUTCH\r\n       SYNOPSIS\r\n\r\n            #include  <conio.h>\r\n\r\n            char      getch(void)\r\n            char      getche(void)\r\n            void      putch(int c)\r\n\r\n\r\n       DESCRIPTION\r\n            Getch() reads a single character from the console  key-\r\n            board  and  returns  it  without  echoing.  Getche() is\r\n            similar but does echo the character  typed.   Ungetch()\r\n            will push back one character such that the next call to\r\n            getch()  or  getche()  will  return   that   character.\r\n            Putch()  outputs the character c to the console screen,\r\n            prepending a carriage return if the character is a new-\r\n            line.\r\n\r\n       SEE ALSO\r\n\r\n            cgets, cputs\r\n\r\n\r\n\r\n\r\n\r\n                                 GETCHAR\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int getchar(void)\r\n\r\n\r\n       DESCRIPTION\r\n            Getchar() is a getc(stdin) operation.  It  is  a  macro\r\n            defined   in  stdio.h.  Note  that  under  normal  cir-\r\n            cumstances getchar() will NOT return unless a  carriage\r\n            return  has  been typed on the console. To get a single\r\n            character immediately from the console, use the routine\r\n            getch().\r\n\r\n       SEE ALSO\r\n\r\n            getc, fgetc, freopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 130                             HI-TECH C USER'S MANUAL\r\n\r\n                       GETCWD (MS-DOS only)\r\n   SYNOPSIS\r\n\r\n        #include  <sys.h>\r\n\r\n        char *    getcwd(int drive)\r\n\r\n\r\n   DESCRIPTION\r\n        Getcwd() returns the path name of the  current  working\r\n        directory  on  the  specified  drive,  where drive == 0\r\n        represents the current drive, drive == 1 represents A:,\r\n        drive  ==  2  represents B: etc.  The return value is a\r\n        pointer to a  static  area  of  memory  which  will  be\r\n        overwritten on the next call to getcwd().\r\n\r\n   SEE ALSO\r\n\r\n        chdir\r\n\r\n\r\n\r\n\r\n\r\n                              GETENV\r\n   SYNOPSIS\r\n\r\n        #include  <stdlib.h>\r\n\r\n        char *    getenv(char * s)\r\n        extern char **  environ;\r\n\r\n\r\n   DESCRIPTION\r\n        Getenv() will search the vector of environment  strings\r\n        for  one matching the argument supplied, and return the\r\n        value part of that environment string. For example,  if\r\n        the environment contains the string\r\n\r\n             COMSPEC=A:\\COMMAND.COM\r\n\r\n        then getenv(\"COMSPEC\") will return A:\\COMMAND.COM.  The\r\n        global  variable  environ  is  a pointer to an array of\r\n        pointers to environment strings, terminated by  a  null\r\n        pointer.  This  array  is  initialized  at startup time\r\n        under MS-DOS from the environment pointer supplied when\r\n        the  program was executed.  Under CP/M no such environ-\r\n        ment is supplied, so the first call  to  getenv()  will\r\n        attempt  to  open  a file in the current user number on\r\n        the current drive called ENVIRON. This file should con-\r\n        tain  definitions for any environment variables desired\r\n        to be accessible to the program, e.g.\r\n\r\n        HITECH=0:C:\r\n\r\n        Each variable definition should be on a separate  line,\r\n        consisting  of the variable name (conventionally all in\r\n        upper case) followed without intervening white space by\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 131\r\n\r\n            an  equal  sign  ('=') then the value to be assigned to\r\n            that variable.\r\n\r\n\r\n\r\n\r\n                                   GETS\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            char * gets(char * s)\r\n\r\n\r\n       DESCRIPTION\r\n            Gets() reads a line from standard input into the buffer\r\n            at  s,  deleting the newline (cf. fgets() ). The buffer\r\n            is null terminated. It returns its argument, or NULL on\r\n            end-of-file.\r\n\r\n       SEE ALSO\r\n\r\n            fgets, freopen\r\n\r\n\r\n\r\n\r\n\r\n                            GETUID (CP/M only)\r\n       SYNOPSIS\r\n\r\n            #include  <sys.h>\r\n\r\n            int getuid(void)\r\n\r\n\r\n       DESCRIPTION\r\n            Getuid() returns the current user number.  On CP/M, the\r\n            current  user number determines the user number associ-\r\n            ated with an opened or created file, unless  overridden\r\n            by an explicit user number prefix in the file name.\r\n\r\n       SEE ALSO\r\n\r\n            setuid, open\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 132                             HI-TECH C USER'S MANUAL\r\n\r\n                               GETW\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int getw(FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Getw() returns one word (16 bits for the Z80 and  8086)\r\n        from  the  nominated stream. EOF is returned on end-of-\r\n        file, but since this is  a  perfectly  good  word,  the\r\n        feof()  macro  should  be  used for testing for end-of-\r\n        file.  When reading the word, no special  alignment  in\r\n        the  file is necessary, as the read is done by two con-\r\n        secutive getc()'s.  The byte ordering is however  unde-\r\n        fined.  The word read should in general have been writ-\r\n        ten by putw().\r\n\r\n   SEE ALSO\r\n\r\n        putw, getc, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n                        GMTIME, LOCALTIME\r\n   SYNOPSIS\r\n\r\n        #include  <time.h>\r\n\r\n        struct tm *     gmtime(time_t * t)\r\n        struct tm *     localtime(time_t * t)\r\n\r\n\r\n   DESCRIPTION\r\n        These functions convert the time pointed to by t  which\r\n        is  in  seconds  since  00:00:00 on Jan 1, 1970, into a\r\n        broken down time stored in a structure  as  defined  in\r\n\ttime.h.  Gmtime() performs a straight conversion, while\r\n\tlocaltime() takes into account the contents of the glo-\r\n        bal  integer time_zone.  This should contain the number\r\n        of minutes that the local  time  zone  is  WESTWARD  of\r\n        Greenwich.  Since there is no way under MS-DOS of actu-\r\n        ally pre-determining this value, by default localtime()\r\n        will return the same result as gmtime().\r\n\r\n   SEE ALSO\r\n\r\n        ctime, asctime, time\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 133\r\n\r\n                                INP, OUTP\r\n       SYNOPSIS\r\n\r\n            char inp(unsigned port)\r\n\r\n            void outp(unsigned, unsigned data)\r\n\r\n\r\n       DESCRIPTION\r\n            These routines read and write bytes  to  and  from  I/O\r\n            ports.   Inp()  returns  the  data  byte  read from the\r\n            specified port, and outp() outputs the data byte to the\r\n            specified port.\r\n\r\n\r\n\r\n\r\n                      INT86, INT86X, INTDOS, INTDOSX\r\n       SYNOPSIS\r\n\r\n            #include  <dos.h>\r\n\r\n            int int86(int intno, union REGS * inregs,\r\n                union REGS * outregs)\r\n            int int86x(int intno, union REGS inregs,\r\n                union REGS outregs, struct SREGS * segregs)\r\n            int intdos(union REGS * inregs, union REGS * outregs)\r\n            int intdosx(union REGS * inregs, union REGS * outregs,\r\n                struct SREGS * segregs)\r\n\r\n\r\n       DESCRIPTION\r\n            These functions allow calling  of  software  interrupts\r\n            from  C  programs.   Int86()  and  int86x() execute the\r\n            software interrupt specified by  intno  while  intdos()\r\n            and  intdosx()  execute interrupt 21(hex), which is the\r\n            MS-DOS  system  call  interrupt.   The  inregs  pointer\r\n            should  point  to a union containing values for each of\r\n            the general purpose registers to be set when  executing\r\n            the  interrupt,  and  the  values  of  the registers on\r\n            return are copied into the union pointed to by outregs.\r\n            The  x  versions  of the calls also take a pointer to a\r\n            union defining the segment register values to be set on\r\n            execution  of  the interrupt, though only ES and DS are\r\n            actually set from this structure.\r\n\r\n       SEE ALSO\r\n\r\n            segread\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 134                             HI-TECH C USER'S MANUAL\r\n\r\n            ISALNUM, ISALPHA, ISDIGIT, ISLOWER et. al.\r\n   SYNOPSIS\r\n\r\n        #include <ctype.h>\r\n\r\n        isalnum(char c)\r\n        isalpha(char c)\r\n        isascii(char c)\r\n        iscntrl(char c)\r\n        isdigit(char c)\r\n        islower(char c)\r\n        isprint(char c)\r\n        isgraph(char c)\r\n        ispunct(char c)\r\n        isspace(char c)\r\n        isupper(char c)\r\n        char c;\r\n\r\n\r\n   DESCRIPTION\r\n        These macros, defined in  ctype.h,  test  the  supplied\r\n        character  for membership in one of several overlapping\r\n        groups of characters. Note that all except isascii  are\r\n        defined for c iff isascii(c) is true.\r\n\r\n             isalnum(c)      c is alphanumeric\r\n             isalpha(c)      c is in A-Z or a-z\r\n             isascii(c)      c is a 7 bit ascii character\r\n             iscntrl(c)      c is a control character\r\n             isdigit(c)      c is a decimal digit\r\n             islower(c)      c is in a-z\r\n             isprint(c)      c is a printing char\r\n             isgraph(c)      c is a non-space printable character\r\n             ispunct(c)      c is not alphanumeric\r\n             isspace(c)      c is a space, tab or newline\r\n             isupper(c)      c is in A-Z\r\n             isxdigit(c)     c is in 0-9 or a-f or A-F\r\n\r\n\r\n   SEE ALSO\r\n\r\n        toupper, tolower, toascii\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 135\r\n\r\n                                  ISATTY\r\n       SYNOPSIS\r\n\r\n            #include  <unixio.h>\r\n\r\n            int isatty(int fd)\r\n\r\n\r\n       DESCRIPTION\r\n            This tests the type of the file associated with fd.  It\r\n            returns true if the file is attached to a tty-like dev-\r\n            ice. This would normally be used for testing  if  stan-\r\n            dard  input  is  coming from a file or the console. For\r\n            testing STDIO streams, use isatty(fileno(stream)).\r\n\r\n\r\n\r\n\r\n                                  KBHIT\r\n       SYNOPSIS\r\n\r\n            #include  <conio.h>\r\n\r\n            int kbhit(void)\r\n\r\n\r\n       DESCRIPTION\r\n            This function returns 1 if a character has been pressed\r\n            on  the  console  keyboard,  0  otherwise. Normally the\r\n            character would then be read via getch().\r\n\r\n       SEE ALSO\r\n\r\n            getch, getche\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 136                             HI-TECH C USER'S MANUAL\r\n\r\n                             LONGJMP\r\n   SYNOPSIS\r\n\r\n        #include <setjmp.h>\r\n\r\n        void      longjmp(jmp_buf buf, int val)\r\n\r\n\r\n   DESCRIPTION\r\n        Longjmp(), in conjunction  with  setjmp(),  provides  a\r\n        mechanism  for  non-local  gotos. To use this facility,\r\n        setjmp() should be called with a  jmp_buf  argument  in\r\n        some  outer level function. The call from setjmp() will\r\n        return  0.  To  return  to  this  level  of  execution,\r\n        longjmp() may  be called with the same jmp_buf argument\r\n        from an inner level of execution. Note however that the\r\n        function  which  called  setjmp()  must still be active\r\n        when longjmp() is called.  Breach  of  this  rule  will\r\n        cause  disaster,  due  to the use of a stack containing\r\n        invalid data. The val argument to longjmp() will be the\r\n        value  apparently  returned  from  the  setjmp().  This\r\n        should normally be non-zero, to distinguish it from the\r\n        genuine setjmp() call. For example:\r\n\r\n        #include <setjmp.h>\r\n\r\n        static jmp_buf  jb_err;\r\n\r\n        main()\r\n        {\r\n            if(setjmp(jb_err)) {\r\n            printf(\"An error occured0);\r\n            exit(1);\r\n            }\r\n            a_func();\r\n        }\r\n\r\n        a_func()\r\n        {\r\n            if(do_whatever() != 0)\r\n            longjmp(jb_err, 1);\r\n            if(do_something_else() != 0)\r\n            longjmp(jb_err, 2);\r\n        }\r\n\r\n\r\n        The calls to longjmp() above will never return;  rather\r\n        the  call to setjmp() will appear to return, but with a\r\n        return  value  equal  to  the  argument   supplied   to\r\n        longjmp().\r\n\r\n   SEE ALSO\r\n\r\n        setjmp\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 137\r\n\r\n                                  LSEEK\r\n       SYNOPSIS\r\n\r\n            #include  <unixio.h>\r\n\r\n            long lseek(int fd, long offs, int wh)\r\n\r\n\r\n       DESCRIPTION\r\n            This  function  operates  in  an  analogous  manner  to\r\n            fseek(), however it does so on unbuffered low-level i/o\r\n            file descriptors, rather than on STDIO streams. It also\r\n            returns  the resulting pointer location. Thus lseek(fd,\r\n            0L, 1) returns the  current  pointer  location  without\r\n            moving it.  -1 is returned on error.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, read, write\r\n\r\n\r\n\r\n\r\n\r\n                                  MALLOC\r\n       SYNOPSIS\r\n\r\n            #include  <stdlib.h>\r\n\r\n            void * malloc(size_t cnt)\r\n\r\n\r\n       DESCRIPTION\r\n            Malloc() attempts to allocate cnt bytes of memory  from\r\n            the \"heap\", the dynamic memory allocation area. If suc-\r\n            cessful, it returns a pointer to the block, otherwise 0\r\n            is  returned. The memory so allocated may be freed with\r\n            free(), or changed  in  size  via  realloc().  Malloc()\r\n            calls sbrk() to obtain memory, and is in turn called by\r\n            calloc().  Malloc()  does  not  clear  the  memory   it\r\n            obtains.\r\n\r\n       SEE ALSO\r\n\r\n            calloc, free, realloc\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 138                             HI-TECH C USER'S MANUAL\r\n\r\n                 MEMSET, MEMCPY, MEMCMP, MEMMOVE\r\n   SYNOPSIS\r\n\r\n        #include  <string.h>\r\n\r\n        void      memset(void s, char c, size_t n)\r\n        void *    memcpy(void * d, void * s, size_t n)\r\n        int memcmp(void * s1, void * s2, size_t n)\r\n        void *    memmove(void * s1, void * s2, size_t n)\r\n        void *    memchr(void * s, int c, size_t n)\r\n\r\n\r\n   DESCRIPTION\r\n        Memset() initializes n bytes of memory starting at  the\r\n        location pointed to by s with the character c. Memcpy()\r\n        copies n bytes of memory  starting  from  the  location\r\n        pointed to by s to the block of memory pointed to by d.\r\n        The result of copying overlapping blocks is  undefined.\r\n        Memcmp()  compares  two  blocks of memory, of length n,\r\n        and returns a signed value similar to strncmp(). Unlike\r\n        strncmp() the comparision does not stop on a null char-\r\n        acter. The ascii collating sequence  is  used  for  the\r\n        comparision,  but  the  effect  of  including non-ascii\r\n        characters in the memory blocks on  the  sense  of  the\r\n        return  value is indeterminate. Memmove() is similar to\r\n        memcpy() except copying of overlapping blocks  is  han-\r\n        dled correctly. The memchr() function locates the first\r\n        occurence of c (converted to unsigned char) in the ini-\r\n        tial n characters of the object pointed to by s.\r\n\r\n   SEE ALSO\r\n\r\n        strncpy, strncmp, strchr\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 139\r\n\r\n                               MKDIR, RMDIR\r\n       SYNOPSIS\r\n\r\n            #include  <sys.h>\r\n\r\n            int mkdir(char * s)\r\n            int rmdir(char * s)\r\n\r\n\r\n       DESCRIPTION\r\n            These functions allow the creation (mkdir()) and  dele-\r\n            tion  (rmdir())  of  sub-directories  under  the MS-DOS\r\n            operating system. The argument s may  be  an  arbitrary\r\n            pathname,  and the return value will be -1 if the crea-\r\n            tion or removal was unsuccessful.\r\n\r\n       SEE ALSO\r\n\r\n            chdir\r\n\r\n\r\n\r\n\r\n\r\n                              MSDOS, MSDOSCX\r\n       SYNOPSIS\r\n\r\n            #include  <dos.h>\r\n\r\n            long      msdos(int ax, int dx, int cx,\r\n                int bx, int si, int di)\r\n            long      msdoscx(int ax, int dx, int cx,\r\n                int bx, int si, int di)\r\n\r\n\r\n       DESCRIPTION\r\n            These functions allow direct access  to  MS-DOS  system\r\n            calls.  The  arguments  will be placed in the registers\r\n            implied by their names, while the return value will  be\r\n            the contents of AX and DX (for msdos()) or the contents\r\n            of DX and CX (for msdoscx()).  Only as  many  arguments\r\n            as  necessary  need be supplied, e.g. if only AH and DX\r\n            need have specified valued, then only 2 argument  would\r\n            be  required.  The  following  piece  of code outputs a\r\n            form-feed to the printer.\r\n\r\n                 msdos(0x500, '\\f');\r\n\r\n            Note that the system call number (in this case 5)  must\r\n            be  multiplied  by  0x100 since MS-DOS expects the call\r\n            number in AH, the high byte of AX.\r\n\r\n       SEE ALSO\r\n\r\n            intdos, intdosx, int86, int86x\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 140                             HI-TECH C USER'S MANUAL\r\n\r\n                               OPEN\r\n   SYNOPSIS\r\n\r\n        #include  <unixio.h>\r\n\r\n        int open(char * name, int mode)\r\n\r\n\r\n   DESCRIPTION\r\n        Open() is the fundamental means of  opening  files  for\r\n        reading  and  writing.   The  file specified by name is\r\n        sought, and if found is opened for reading, writing  or\r\n        both. Mode is encoded as follows:\r\n\r\n             Mode      Meaning\r\n             0   Open for reading only\r\n             1   Open for writing only\r\n             2   Open for both reading and writing\r\n\r\n\r\n        The file must already exist - if it does  not,  creat()\r\n        should  be  used to create it.  On a successful open, a\r\n        file descriptor is returned.  This  is  a  non-negative\r\n        integer  which  may  be  used to refer to the open file\r\n        subsequently.  If the open fails, -1 is returned.   The\r\n        syntax of a CP/M filename is:\r\n\r\n             [uid:][drive:]name.type\r\n\r\n\r\n        where uid is a decimal number  0  to  15,  drive  is  a\r\n        letter  A to P or a to p, name is 1 to 8 characters and\r\n        type is  0  to  3  characters.  Though  there  are  few\r\n        inherent restrictions on the characters in the name and\r\n        type, it is recommended that they be restricted to  the\r\n        alphanumerics and standard printing characters.  Use of\r\n        strange characters  may  cause  problems  in  accessing\r\n        and/or deleting the file.\r\n\r\n        One or both of uid: and drive: may be omitted; if  both\r\n        are supplied, the uid: must come first. Note that the [\r\n        and ] are meta-symbols only. Some examples are:\r\n\r\n             fred.dat\r\n             file.c\r\n             0:xyz.com\r\n             0:a:file1.p\r\n             a:file2.\r\n\r\n\r\n        If the uid: is omitted, the file will  be  sought  with\r\n        uid  equal  to  the current user number, as returned by\r\n        getuid(). If drive: is omitted, the file will be sought\r\n        on  the currently selected drive. The following special\r\n        file names are recognized:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 141\r\n\r\n\r\n                 lst:      Accesses the list device - write only\r\n                 pun:      Accesses the punch device - write only\r\n                 rdr:      Accesses the reader device - read only\r\n                 con:      Accesses the system console - read/write\r\n\r\n\r\n            File names may be in any case - they are  converted  to\r\n            upper case during processing of the name.\r\n\r\n            MS-DOS filenames may be any valid MS-DOS 2.xx filename,\r\n            e.g.\r\n\r\n                 fred.nrk\r\n                 A:\\HITECH\\STDIO.H\r\n\r\n\r\n            The special device  names  (e.g.  CON,  LST)  are  also\r\n            recognized.  These do not require (and should not have)\r\n            a trailing colon.\r\n\r\n       SEE ALSO\r\n\r\n            close, fopen, fclose, read, write, creat\r\n\r\n\r\n\r\n\r\n\r\n                                  PERROR\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            void      perror(char * s)\r\n\r\n\r\n       DESCRIPTION\r\n            This routine will print on the stderr stream the  argu-\r\n            ment s, followed by a descriptive message detailing the\r\n            last error returned from an open, close read  or  write\r\n            call.  Unfortunately  CP/M  does not provide definitive\r\n            information relating to the error, except in  the  case\r\n            of a random read or write. Thus this routine is of lim-\r\n            ited usefulness under CP/M. MS-DOS provides  much  more\r\n            information  however,  and use of perror() after MS-DOS\r\n            file handling calls will certainly give useful diagnos-\r\n            tics.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, read, write\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 142                             HI-TECH C USER'S MANUAL\r\n\r\n                         PRINTF, VPRINTF\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int printf(char * fmt, ...)\r\n        int vprintf(char * fmt, va_list va_arg)\r\n\r\n\r\n   DESCRIPTION\r\n        Printf() is a formatted output  routine,  operating  on\r\n        stdout. There are corresponding routines operating on a\r\n        given  stream  (fprintf())  or  into  a  string  buffer\r\n        (sprintf()).  Printf()  is passed a format string, fol-\r\n        lowed by a list of zero or more arguments. In the  for-\r\n        mat string are conversion specifications, each of which\r\n        is used to print out one of the argument  list  values.\r\n        Each  conversion  specification  is  of  the form %m.nc\r\n        where the percent symbol  %  introduces  a  conversion,\r\n        followed by an optional width specification m.  n is an\r\n        optional precision  specification  (introduced  by  the\r\n        dot)  and  c  is  a  letter  specifying the type of the\r\n        conversion.  A minus sign ('-') preceding  m  indicates\r\n        left  rather  than  right  adjustment  of the converted\r\n        value in the field. Where the  field  width  is  larger\r\n        than required for the conversion, blank padding is per-\r\n        formed at the left or right as specified.  Where  right\r\n        adjustment  of  a  numeric conversion is specified, and\r\n        the first digit of m is 0, then padding  will  be  per-\r\n        formed with zeroes rather than blanks.\r\n\r\n        If the character * is used in place of a  decimal  con-\r\n        stant,  e.g.  in the format %*d, then one integer argu-\r\n        ment will be taken from the list to provide that value.\r\n        The types of conversion are:\r\n\r\n   f    Floating point - m is the total  width  and  n  is  the\r\n        number  of  digits  after  the  decimal point.  If n is\r\n        omitted it defaults to 6.\r\n\r\n   e    Print the corresponding argument  in  scientific  nota-\r\n        tion. Otherwise similar to f.\r\n\r\n   g    Use e or f format, whichever gives maximum precision in\r\n        minimum width.\r\n\r\n   o x X u d\r\n        Integer conversion -  in  radices  8,  16,  10  and  10\r\n        respectively.  The  conversion is signed in the case of\r\n        d, unsigned otherwise. The precision value is the total\r\n        number  of  digits  to  print, and may be used to force\r\n        leading zeroes. E.g. %8.4x will print at  least  4  hex\r\n        digits  in  an  8 wide field.  Preceding the key letter\r\n        with an l indicates that the value argument is  a  long\r\n        integer  or  unsigned  value.   The letter X prints out\r\n        hexadecimal numbers using the upper  case  letters  A-F\r\n        rather than a-f as would be printed when using x.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 143\r\n\r\n       s    Print a string - the value argument is assumed to be  a\r\n            character pointer. At most n characters from the string\r\n            will be printed, in a field m characters wide.\r\n\r\n       c    The argument is assumed to be a single character and is\r\n            printed literally.\r\n\r\n            Any other characters used as conversion  specifications\r\n            will  be printed. Thus %% will produce a single percent\r\n            sign.  Some examples:\r\n\r\n            printf(\"Total = %4d%%\", 23)\r\n                yields 'Total =23%'\r\n            printf(\"Size is %lx\" , size)\r\n                where size is a long, prints size\r\n                as hexadecimal.\r\n            printf(\"Name = %.8s\", \"a1234567890\")\r\n                yields 'Name = a1234567'\r\n            printf(\"xx%*d\", 3, 4)\r\n                yields 'xx  4'\r\n\r\n\r\n            Printf returns EOF on error, 0 otherwise.  Vprintf() is\r\n            similar  to printf() but takes a variable argument list\r\n            pointer rather  than  a  list  of  arguments.  See  the\r\n            description of va_start() for more information on vari-\r\n            able argument lists.\r\n\r\n       SEE ALSO\r\n\r\n            fprintf, sprintf\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 144                             HI-TECH C USER'S MANUAL\r\n\r\n                               PUTC\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int putc(int c, FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Putc() is the macro version of fputc() and  is  defined\r\n        in  stdio.h.  See  fputc()  for  a  description  of its\r\n        behaviour.\r\n\r\n   SEE ALSO\r\n\r\n        fputc, getc, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n                             PUTCHAR\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int putchar(int c)\r\n\r\n\r\n   DESCRIPTION\r\n        Putchar() is a putc() operation on stdout,  defined  in\r\n        stdio.h.\r\n\r\n   SEE ALSO\r\n\r\n        putc, getc, freopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 145\r\n\r\n                                   PUTS\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int puts(char * s)\r\n\r\n\r\n       DESCRIPTION\r\n            Puts() writes  the  string  s  to  the  stdout  stream,\r\n            appending a newline. The null terminating the string is\r\n            not copied.  EOF is returned on error.\r\n\r\n       SEE ALSO\r\n\r\n            fputs, gets, freopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n                                   PUTW\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int putw(int w, FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            Putw() copies the  word  w  to  the  given  stream.  It\r\n            returns  w,  except  on  error,  in  which  case EOF is\r\n            returned. Since this is a good integer, ferror() should\r\n            be used to check for errors.\r\n\r\n       SEE ALSO\r\n\r\n            getw, fopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 146                             HI-TECH C USER'S MANUAL\r\n\r\n                              QSORT\r\n   SYNOPSIS\r\n\r\n        #include  <stdlib.h>\r\n\r\n        void      qsort(void * base, size_t nel,\r\n            size_t width, int (*func)())\r\n\r\n\r\n   DESCRIPTION\r\n        Qsort() is an implementation  of  the  quicksort  algo-\r\n        rithm.  It  sorts an array of nel items, each of length\r\n        width bytes, located contiguously in  memory  at  base.\r\n        Func is a pointer to a function used by qsort() to com-\r\n        pare items. It calls func with pointers to two items to\r\n        be  compared.   If  the  first item is considered to be\r\n        greater than, equal to or less  than  the  second  then\r\n        func()  should  return a value greater than zero, equal\r\n        to zero or less than zero respectively.\r\n\r\n        static short    array[100];\r\n\r\n        #define SIZE  sizeof array/sizeof array[0]\r\n        a_func(p1, p2)\r\n        short * p1, * p2;\r\n        {\r\n            return *p1 - *p2;\r\n        }\r\n\r\n        sort_em()\r\n        {\r\n            qsort(array, SIZE,\r\n                  sizeof array[0], a_func);\r\n        }\r\n\r\n\r\n        This will sort the array into  ascending  values.  Note\r\n        the  use  of sizeof to make the code independent of the\r\n        size of a short, or  the  number  of  elements  in  the\r\n        array.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 147\r\n\r\n                                   RAND\r\n       SYNOPSIS\r\n\r\n            #include  <stdlib.h>\r\n\r\n            int rand(void)\r\n\r\n\r\n       DESCRIPTION\r\n            Rand() is a pseudo-random number generator. It  returns\r\n            an  integer in the range 0 to 32767, which changes in a\r\n            pseudo-random fashion on each call.\r\n\r\n       SEE ALSO\r\n\r\n            srand\r\n\r\n\r\n\r\n\r\n\r\n                                   READ\r\n       SYNOPSIS\r\n\r\n            #include  <unixio.h>\r\n\r\n            int read(int fd, void * buf, size_t cnt)\r\n\r\n\r\n       DESCRIPTION\r\n            Read() will read from the file associated with fd up to\r\n            cnt  bytes into a buffer located at buf. It returns the\r\n            number of bytes actually read. A zero return  indicates\r\n            end-of-file.  A  negative  return  indicates  error. Fd\r\n            should have been  obtained  from  a  previous  call  to\r\n            open().  It is possible for read() to return less bytes\r\n            than requested, e.g. when reading from the console,  in\r\n            which case read() will read one line of input.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, write\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 148                             HI-TECH C USER'S MANUAL\r\n\r\n                             REALLOC\r\n   SYNOPSIS\r\n\r\n        void * realloc(void * ptr, size_t cnt)\r\n\r\n\r\n   DESCRIPTION\r\n        Realloc() frees the  block  of  memory  at  ptr,  which\r\n        should  have  been  obtained by a previous call to mal-\r\n        loc(), calloc() or realloc(), then attempts to allocate\r\n        cnt  bytes  of dynamic memory, and if successful copies\r\n        the contents of the block of memory located at ptr into\r\n        the new block.  At most, realloc() will copy the number\r\n        of bytes which were in the old block, but  if  the  new\r\n        block  is  smaller,  will  only copy cnt bytes.  If the\r\n        block could not be allocated, 0 is returned.\r\n\r\n   SEE ALSO\r\n\r\n        malloc, calloc, realloc\r\n\r\n\r\n\r\n\r\n\r\n                              REMOVE\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int remove(char * s)\r\n\r\n\r\n   DESCRIPTION\r\n        Remove() will attempt to remove the file named  by  the\r\n        argument  s  from  the  directory. A return value of -1\r\n        indicates that the attempt failed.\r\n\r\n   SEE ALSO\r\n\r\n        unlink\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 149\r\n\r\n                                  RENAME\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int rename(char * name1, char * name2)\r\n\r\n\r\n       DESCRIPTION\r\n            The file named by name1 will be renamed  to  name2.  -1\r\n            will be returned if the rename was not successful. Note\r\n            that renames across user numbers or drives are not per-\r\n            mitted.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, unlink\r\n\r\n\r\n\r\n\r\n\r\n                                  REWIND\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int rewind(FILE * stream)\r\n\r\n\r\n       DESCRIPTION\r\n            This  function  will   attempt   to   re-position   the\r\n            read/write  pointer  of  the  nominated  stream  to the\r\n            beginning of the file. A return value of  -1  indicates\r\n            that  the  attempt  was not successful, perhaps because\r\n            the stream is associated with a non-random access  file\r\n            such as a character device.\r\n\r\n       SEE ALSO\r\n\r\n            fseek, ftell\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 150                             HI-TECH C USER'S MANUAL\r\n\r\n                               SBRK\r\n   SYNOPSIS\r\n\r\n        char *    sbrk(int incr)\r\n\r\n\r\n   DESCRIPTION\r\n        Sbrk() increments the current highest  memory  location\r\n        allocated  to  the program by incr bytes.  It returns a\r\n        pointer to the previous highest location. Thus  sbrk(0)\r\n        returns  a  pointer  to  the  current highest location,\r\n        without altering its value.  If there  is  insufficient\r\n        memory to satisfy the request, -1 is returned.\r\n\r\n   SEE ALSO\r\n\r\n        brk, malloc, calloc, realloc, free\r\n\r\n\r\n\r\n\r\n\r\n                              SCANF\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int scanf(char * fmt, ...)\r\n        int vscanf(char *, va_list ap);\r\n\r\n\r\n   DESCRIPTION\r\n        Scanf() performs formatted  input  (\"de-editing\")  from\r\n        the  stdin  stream. Similar functions are available for\r\n        streams in general,  and  for  strings.   The  function\r\n        vscanf() is similar, but takes a pointer to an argument\r\n        list rather than a series of additional arguments. This\r\n        pointer  should  have been initialized with va_start().\r\n        The input conversions are performed  according  to  the\r\n        fmt string; in general a character in the format string\r\n        must match a character in the input;  however  a  space\r\n        character  in the format string will match zero or more\r\n        \"white space\" characters in  the  input,  i.e.  spaces,\r\n        tabs or newlines.  A conversion specification takes the\r\n        form of the character  %,  optionally  followed  by  an\r\n        assignment suppression character ('*'), optionally fol-\r\n        lowed by a numerical maximum field width, followed by a\r\n        conversion  specification  character.  Each  conversion\r\n        specification, unless it  incorporates  the  assignment\r\n        suppression character, will assign a value to the vari-\r\n        able pointed at by the next argument. Thus if there are\r\n        two  conversion specifications in the fmt string, there\r\n        should  be  two  additional  pointer  arguments.    The\r\n        conversion characters are as follows:\r\n\r\n   o x d\r\n        Skip white space, then convert a number in base  8,  16\r\n        or   10  radix  respectively.  If  a  field  width  was\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 151\r\n\r\n            supplied, take at most that many  characters  from  the\r\n            input. A leading minus sign will be recognized.\r\n\r\n       f    Skip white space, then convert  a  floating  number  in\r\n            either  conventional or scientific notation.  The field\r\n            width applies as above.\r\n\r\n       s    Skip white space, then copy a maximal  length  sequence\r\n            of  non-white-space  characters.  The  pointer argument\r\n            must be a pointer to char.  The field width will  limit\r\n            the  number  of characters copied. The resultant string\r\n            will be null-terminated.\r\n\r\n       c    Copy the next character from  the  input.  The  pointer\r\n            argument is assumed to be a pointer to char. If a field\r\n            width is specified, then  copy  that  many  characters.\r\n            This differs from the s format in that white space does\r\n            not terminate the character sequence.\r\n\r\n            The conversion characters o, x, u, d and f may be  pre-\r\n            ceded  by  an  l  to  indicate  that  the corresponding\r\n            pointer argument is a pointer  to  long  or  double  as\r\n            appropriate.  A  preceding  h  will  indicate  that the\r\n            pointer argument is a pointer to short rather than int.\r\n\r\n            Scanf() returns the number of  successful  conversions;\r\n            EOF  is  returned  if  end-of-file  was seen before any\r\n            conversions were performed. Some examples are:\r\n\r\n                 scanf(\"%d %s\", &a, &s)\r\n                     with input \"12s\"\r\n                 will assign 12 to a, and \"s\" to s.\r\n\r\n                 scanf(\"%4cd %lf\", &c, &f)\r\n                     with input \" abcd -3.5\"\r\n                 will assign \" abc\" to c, and -3.5 to f.\r\n\r\n\r\n       SEE ALSO\r\n\r\n            fscanf, sscanf, printf, va_arg\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 152                             HI-TECH C USER'S MANUAL\r\n\r\n                             SEGREAD\r\n   SYNOPSIS\r\n\r\n        #include  <dos.h>\r\n        int segread(struct SREGS * segregs)\r\n\r\n\r\n   DESCRIPTION\r\n        Segread() copies the values of  the  segment  registers\r\n        into the structure pointed to by segregs.\r\n\r\n   SEE ALSO\r\n\r\n        int86, int86x, intdos, intdosx\r\n\r\n\r\n\r\n\r\n\r\n                              SETJMP\r\n   SYNOPSIS\r\n\r\n        #include <setjmp.h>\r\n        int setjmp(jmp_buf buf)\r\n\r\n\r\n   DESCRIPTION\r\n        Setjmp() is used with longjmp()  for  non-local  gotos.\r\n        See longjmp() for further information.\r\n\r\n   SEE ALSO\r\n\r\n        longjmp\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 153\r\n\r\n                            SETUID (CP/M only)\r\n       SYNOPSIS\r\n\r\n            #include  <sys.h>\r\n\r\n            void setuid(int uid)\r\n\r\n\r\n       DESCRIPTION\r\n            Setuid() will set the current user number to  uid.  Uid\r\n            should be a number in the range 0-15.\r\n\r\n       SEE ALSO\r\n\r\n            getuid\r\n\r\n\r\n\r\n\r\n\r\n                             SETVBUF, SETBUF\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int setvbuf(FILE * stream, char * buf,\r\n                int mode, size_t size);\r\n            void      setbuf(FILE * stream, char * buf)\r\n\r\n\r\n       DESCRIPTION\r\n            The setvbuf() function allows the  buffering  behaviour\r\n            of  a  STDIO  stream  to  be altered. It supersedes the\r\n            function setbuf() which is retained for backwards  com-\r\n            patibility.  The arguments to setvbuf() are as follows:\r\n            stream designates the STDIO stream to be affected;  buf\r\n            is  a  pointer  to  a buffer which will be used for all\r\n            subsequent I/O operations on this  stream.  If  buf  is\r\n            null,  then the routine will allocate a buffer from the\r\n            heap  if  necessary,  of  size  BUFSIZ  as  defined  in\r\n            <stdio.h>.   mode  may  take the values _IONBF, to turn\r\n            buffering off completely, _IOFBF, for  full  buffering,\r\n            or _IOLBF for line buffering. Full buffering means that\r\n            the associated buffer will only be flushed  when  full,\r\n            while  line  buffering  means  that  the buffer will be\r\n            flushed at the end  of  each  line  or  when  input  is\r\n            requested  from  another STDIO stream. size is the size\r\n            of the buffer supplied. For example:\r\n\r\n              setvbuf(stdout, my_buf, _IOLBF, sizeof my_buf);\r\n\r\n            If a buffer is supplied by the caller, that buffer will\r\n            remain associated  with that stream even over fclose(),\r\n            fopen() calls until another setvbuf() changes it.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 154                             HI-TECH C USER'S MANUAL\r\n\r\n   SEE ALSO\r\n\r\n        fopen, freopen, fclose\r\n\r\n\r\n\r\n\r\n\r\n                            SET_VECTOR\r\n   SYNOPSIS\r\n\r\n        #include  <intrpt.h>\r\n        typedef interrupt void (*isr)();\r\n        isr set_vector(isr * vector, isr func);\r\n\r\n\r\n   DESCRIPTION\r\n        This routine allows an interrupt vector to be  initial-\r\n        ized.  The  first argument should be the address of the\r\n        interrupt vector (not the vector number but the  actual\r\n        address) cast to a pointer to isr, which is a typedef'd\r\n        pointer to an interrupt function. The  second  argument\r\n        should  be  the  function  which you want the interrupt\r\n        vector to point to. This must  be  declared  using  the\r\n        interrupt   type   qualifier.   The   return  value  of\r\n        set_vector() is the previous contents of the vector.\r\n\r\n   SEE ALSO\r\n\r\n        di(), ei()\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 155\r\n\r\n                                  SIGNAL\r\n       SYNOPSIS\r\n\r\n            #include <signal.h>\r\n            void (* signal)(int sig, void (*func)());\r\n\r\n\r\n       DESCRIPTION\r\n            Signal() provides a mechanism for catching  control-C's\r\n            (ctrl-BREAK  for  MS-DOS)  typed  on the console during\r\n            I/O. Under CP/M the console is polled whenever  an  I/O\r\n            call is performed, while for MS-DOS the polling depends\r\n            on the setting of the BREAK command.  If a control-C is\r\n            detected  certain action will be performed. The default\r\n            action is to exit summarily; this may be modified  with\r\n            signal(). The sig argument to signal may at the present\r\n            time be only SIGINT, signifying an interrupt condition.\r\n            The  func  argument may be one of SIG_DFL, representing\r\n            the default action, SIG_IGN, to ignore control-C's com-\r\n            pletely,  or  the  address  of a function which will be\r\n            called with one argument,  the  number  of  the  signal\r\n            caught,  when  a  control-C is seen. As the only signal\r\n            supported is SIGINT, this will always be the  value  of\r\n            the argument to the called function.\r\n\r\n       SEE ALSO\r\n\r\n            exit\r\n\r\n\r\n\r\n\r\n\r\n                                   SIN\r\n       SYNOPSIS\r\n\r\n            #include  <math.h>\r\n\r\n            double    sin(double f);\r\n\r\n\r\n       DESCRIPTION\r\n            This function returns the sine function  of  its  argu-\r\n            ment.\r\n\r\n       SEE ALSO\r\n\r\n            cos, tan, asin, acos, atan\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 156                             HI-TECH C USER'S MANUAL\r\n\r\n                     SPAWNL, SPAWNV, SPAWNVE\r\n   SYNOPSIS\r\n\r\n        int spawnl(char * n, char * argv0, ...);\r\n        int spawnv(cahr * n, char ** v)\r\n        int spawnve(char * n, char ** v, char ** e)\r\n\r\n\r\n   DESCRIPTION\r\n        These functions will load and  execute  a  sub-program,\r\n        named  by  the  argument n. The calling conventions are\r\n        similar to  the  functions  execl()  and  execv(),  the\r\n        difference being that the spawn functions return to the\r\n        calling program after termination of  the  sub-program,\r\n        while  the  exec  functions  return only if the program\r\n        could not be executed.  Spawnve() takes an  environment\r\n        list in the same format as the argument list which will\r\n        be supplied to the executed program as its environment.\r\n\r\n   SEE ALSO\r\n\r\n        execl, execv\r\n\r\n\r\n\r\n\r\n\r\n                             SPRINTF\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int sprintf(char * buf, char * fmt, ...);\r\n        int vsprintf(char * buf, char * fmt, va_list ap);\r\n\r\n\r\n   DESCRIPTION\r\n        Sprintf() operates in a similar  fashion  to  printf(),\r\n        except  that instead of placing the converted output on\r\n        the stdout stream, the characters  are  placed  in  the\r\n        buffer  at  buf.  The  resultant  string  will be null-\r\n        terminated, and the number of characters in the  buffer\r\n        will  be  returned.  Vsprintf takes an argument pointer\r\n        rather than a list of arguments.\r\n\r\n   SEE ALSO\r\n\r\n        printf, fprintf, sscanf\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 157\r\n\r\n                                   SQRT\r\n       SYNOPSIS\r\n\r\n            #include  <math.h>\r\n\r\n            double    sqrt(double f)\r\n\r\n\r\n       DESCRIPTION\r\n            Sqrt() implements a square root function using Newton's\r\n            approximation.\r\n\r\n       SEE ALSO\r\n\r\n            exp\r\n\r\n\r\n\r\n\r\n\r\n                                  SSCANF\r\n       SYNOPSIS\r\n\r\n            #include  <stdio.h>\r\n\r\n            int sscanf(char * buf, char * fmt, ...);\r\n            int vsscanf(char * buf, char * fmt, va_list ap);\r\n\r\n\r\n       DESCRIPTION\r\n            Sscanf() operates  in  a  similar  manner  to  scanf(),\r\n            except that instead of the conversions being taken from\r\n            stdin, they are taken from the string at buf.\r\n\r\n       SEE ALSO\r\n\r\n            scanf, fscanf, sprintf\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 158                             HI-TECH C USER'S MANUAL\r\n\r\n                              SRAND\r\n   SYNOPSIS\r\n\r\n        #include  <stdlib.h>\r\n\r\n        void srand(int seed)\r\n\r\n\r\n   DESCRIPTION\r\n        Srand()  initializes  the   random   number   generator\r\n        accessed by rand() with the given seed. This provides a\r\n        mechanism  for  varying  the  starting  point  of   the\r\n        pseudo-random sequence yielded by rand(). On the z80, a\r\n        good place to get a  truly  random  seed  is  from  the\r\n        refresh  register. Otherwise timing a response from the\r\n        console will do.\r\n\r\n   SEE ALSO\r\n\r\n        rand\r\n\r\n\r\n\r\n\r\n\r\n                               STAT\r\n   SYNOPSIS\r\n\r\n        #include  <stat.h>\r\n\r\n        int stat(char * name, struct stat * statbuf)\r\n\r\n\r\n   DESCRIPTION\r\n        This routine returns  information  about  the  file  by\r\n        name.  The  information  returned  is  operating system\r\n        dependent, but may include file attributes (e.g.   read\r\n        only), file size in bytes, and file modification and/or\r\n        access times.  The argument name should be the name  of\r\n        the  file,  and  may include path names under DOS, user\r\n        numbers under CP/M, etc.  The argument  statbuf  should\r\n        be  the  address  of  a  structure as defined in stat.h\r\n        which will be filled in with the information about  the\r\n        file. The structure of struct stat is as follows:\r\n\r\n        struct stat\r\n        {\r\n         short    st_mode;  /* flags */\r\n         long     st_atime; /* access time */\r\n         long     st_mtime; /* modification time */\r\n         long     st_size;  /* file size */\r\n        };\r\n\r\n\r\n        The access and modification times (under DOS these\r\n        are  both  set  to  the  modification time) are in\r\n        seconds since 00:00:00 Jan 1  1970.  The  function\r\n        ctime()  may be used to convert this to a readable\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 159\r\n\r\n            value.  The file size  is  self  explanatory.  The\r\n            flag bits are as follows:\r\n\r\n                     Flag              Meaning\r\n                   ____________________________________\r\n                   S_IFMT      mask for file type\r\n                   S_IFDIR     file is a directory\r\n                   S_IFREG     file is a regular file\r\n                   S_IREAD     file is readable\r\n                   S_IWRITE    file is writeable\r\n                   S_IEXEC     file is executable\r\n                   S_HIDDEN    file is hidden\r\n                   S_SYSTEM    file is marked system\r\n                   S_ARCHIVE   file has been written to\r\n\r\n\r\n            Stat returns 0 on success, -1 on failure, e.g.  if\r\n            the file could not be found.\r\n\r\n       SEE ALSO\r\n\r\n            ctime, creat, chmod\r\n\r\n\r\n\r\n\r\n\r\n                  STRCAT, STRCMP, STRCPY, STRLEN et. al.\r\n       SYNOPSIS\r\n\r\n            #include  <string.h>\r\n\r\n            char *    strcat(char * s1, char * s2);\r\n            int strcmp(char * s1, char * s2);\r\n            char *    strcpy(char * s1, char * s2);\r\n            int strlen(char * s);\r\n            char *    strncat(char * s1, char * s2, size_t n);\r\n            int strncmp(char * s1, char * s2, size_t n);\r\n            char *    strncpy(char * s1, char * s2, size_t n);\r\n\r\n\r\n       DESCRIPTION\r\n            These functions provide operations  on  null-terminated\r\n            strings.  Strcat()  appends the string s2 to the end of\r\n            the string s1.  The string at  s1  will  be  null  ter-\r\n            minated.  Needless  to say the buffer at s1 must be big\r\n            enough. Strcmp() compares the two strings and returns a\r\n            number  greater  than  0,  0  or  a  number less than 0\r\n            according to whether s1 is greater than,  equal  to  or\r\n            less  than s2. The comparision is via the ascii collat-\r\n            ing order, with the first character the  most  signifi-\r\n            cant.   Strcpy()  copies s2 into the buffer at s1, null\r\n            terminating it.  Strlen() returns the length of s1, not\r\n            including  the  terminating null.  Strncat(), strncmp()\r\n            and strncpy() will catenate, compare and copy s2 and s1\r\n            in  the  same  manner as their similarly named counter-\r\n            parts above, but involving at most  n  characters.  For\r\n            strncpy(),  the  resulting  string may not be null ter-\r\n            minated.\r\n\r\n\r\n\r\n\r\n\r\n   Page 160                             HI-TECH C USER'S MANUAL\r\n\r\n                         STRCHR, STRRCHR\r\n   SYNOPSIS\r\n\r\n        #include  <string.h>\r\n\r\n        char *    strchr(char * s, int c)\r\n        char *    strrchr(char * s, int c)\r\n\r\n\r\n   DESCRIPTION\r\n        These functions locate an instance of the  character  c\r\n        in the string s. In the case of strchr() a pointer will\r\n        be returned to the  first  instance  of  the  character\r\n        found  be  searching  from the beginning of the string,\r\n        while strrchr() searches backwards from the end of  the\r\n        string.  A  null  pointer  is returned if the character\r\n        does not exist in the string.\r\n\r\n   SEE ALSO\r\n\r\n\r\n\r\n\r\n\r\n\r\n                              SYSTEM\r\n   SYNOPSIS\r\n\r\n        #include  <sys.h>\r\n\r\n        int system(char * s)\r\n\r\n\r\n   DESCRIPTION\r\n        When executed under MS-DOS system() will pass the argu-\r\n        ment  string  to the command processor, located via the\r\n        environment string COMSPEC,  for  execution.  The  exit\r\n        status  of  the command processor will be returned from\r\n        the call to system().  For example,  to  set  the  baud\r\n        rate on the serial port on an MS-DOS machine:\r\n\r\n             system(\"MODE COM1:96,N,8,1,P\");\r\n\r\n        This function will not work on CP/M-86  since  it  does\r\n        not  have  an invokable command interpreter. Under Con-\r\n        current CP/M the CLI system call is used.\r\n\r\n   SEE ALSO\r\n\r\n        spawnl, spawnv\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 161\r\n\r\n                                   TAN\r\n       SYNOPSIS\r\n\r\n            #include  <math.h>\r\n\r\n            double    tan(double f);\r\n\r\n\r\n       DESCRIPTION\r\n            This is the tangent function.\r\n\r\n       SEE ALSO\r\n\r\n            sin, cos, asin, acos, atan\r\n\r\n\r\n\r\n\r\n\r\n                                   TIME\r\n       SYNOPSIS\r\n\r\n            #include  <time.h>\r\n\r\n            time_t    time(time_t * t)\r\n\r\n\r\n       DESCRIPTION\r\n            This function returns the current time in seconds since\r\n            00:00:00  on  Jan  1,  1970.  If the argument t is non-\r\n            null, the same value is stored into the object  pointed\r\n            to  by  t.   The accuracy of this function is naturally\r\n            dependent on the operating system  having  the  correct\r\n            time. This function does not work under CP/M-86 or CP/M\r\n            2.2 but does work under Concurrent-CP/M and CP/M+.\r\n\r\n       SEE ALSO\r\n\r\n            ctime, gmtime, localtime, asctime\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 162                             HI-TECH C USER'S MANUAL\r\n\r\n                    TOUPPER, TOLOWER, TOASCII\r\n   SYNOPSIS\r\n\r\n        #include  <ctype.h>\r\n        char toupper(int c);\r\n        char tolower(int c);\r\n        char toascii(int c);\r\n        char      c;\r\n\r\n\r\n   DESCRIPTION\r\n        Toupper() converts its lower case  alphabetic  argument\r\n        to  upper  case, tolower() performs the reverse conver-\r\n        sion, and toascii() returns a result that is guaranteed\r\n        in the range 0-0177. Toupper() and tolower return their\r\n        arguments if it is not an alphabetic character.\r\n\r\n   SEE ALSO\r\n\r\n        islower, isupper, isascii et. al.\r\n\r\n\r\n\r\n\r\n\r\n                              UNGETC\r\n   SYNOPSIS\r\n\r\n        #include  <stdio.h>\r\n\r\n        int ungetc(int c, FILE * stream)\r\n\r\n\r\n   DESCRIPTION\r\n        Ungetc() will attempt to push back the character c onto\r\n        the  named stream, such that a subsequent getc() opera-\r\n        tion will return the character. At most  one  level  of\r\n        pushback will be allowed, and if the stream is not buf-\r\n        fered, even this may not be possible. EOF  is  returned\r\n        if the ungetc() could not be performed.\r\n\r\n   SEE ALSO\r\n\r\n        getc\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 163\r\n\r\n                                  UNLINK\r\n       SYNOPSIS\r\n\r\n            int unlink(char * name)\r\n\r\n\r\n       DESCRIPTION\r\n            Unlink() will remove (delete) the named file,  that  is\r\n            erase  the  file  from  its directory. See open() for a\r\n            description of the file name construction.   Zero  will\r\n            be returned if successful, -1 if the file did not exist\r\n            or it could not be removed.\r\n\r\n       SEE ALSO\r\n\r\n            open, close, rename, remove\r\n\r\n\r\n\r\n\r\n\r\n                         VA_START, VA_ARG, VA_END\r\n       SYNOPSIS\r\n\r\n            #include  <stdarg.h>\r\n\r\n            void      va_start(va_list ap, parmN);\r\n            type      va_arg(ap, type);\r\n            void      va_end(va_list ap);\r\n\r\n\r\n       DESCRIPTION\r\n            These macros are provided to give access in a  portable\r\n            way to parameters to a function represented in a proto-\r\n            type by the  ellipsis  symbol  (...),  where  type  and\r\n            number  of  arguments  supplied to the function are not\r\n            known at compile time. The rightmost parameter  to  the\r\n            function  (shown  as  parmN) plays an important role in\r\n            these macros, as it is the starting point for access to\r\n            further  parameters.  In  a  function  taking  variable\r\n            numbers of arguments, a variable of type va_list should\r\n            be  declared, then the macro va_start invoked with that\r\n            variable and the name of parmN.  This  will  initialize\r\n            the  variable  to  allow  subsequent calls of the macro\r\n            va_arg to access successive parameters.  Each  call  to\r\n            va_arg  requires two arguments; the variable previously\r\n            defined and a type name which is the type that the next\r\n            parameter  is  expected  to be. Note that any arguments\r\n            thus accessed will have been  widened  by  the  default\r\n            conventions  to int, unsigned int or double.  For exam-\r\n            ple if a character argument has been passed, it  should\r\n            be accessed by va_arg(ap, int) since the char will have\r\n            been widened to int.  An example is given  below  of  a\r\n            function  taking  one  integer parameter, followed by a\r\n            number of other parameters. In this example  the  func-\r\n            tion  expects  the subsequent parameters to be pointers\r\n            to char, but note that the compiler  is  not  aware  of\r\n            this,  and  it  is  the  programmers  responsibility to\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 164                             HI-TECH C USER'S MANUAL\r\n\r\n        ensure that correct arguments are supplied.\r\n\r\n        #include  <stdarg.h>\r\n        prf(int n, ...)\r\n        {\r\n            va_list         ap;\r\n\r\n            va_start(ap, n);\r\n            while(n--)\r\n            puts(va_arg(ap, char *));\r\n            va_end(ap);\r\n        }\r\n\r\n\r\n\r\n\r\n\r\n                              WRITE\r\n   SYNOPSIS\r\n\r\n        #include  <unixio.h>\r\n\r\n        int write(int fd, void * buf, size_t cnt)\r\n\r\n\r\n   DESCRIPTION\r\n        Write() will write from the buffer at  buf  up  to  cnt\r\n        bytes  to  the file associated with the file descriptor\r\n        fd. The  number  of  bytes  actually  written  will  be\r\n        returned. EOF or a value less than cnt will be returned\r\n        on error.  In any case, any return value not  equal  to\r\n        cnt should be treated as an error (cf. read() ).\r\n\r\n   SEE ALSO\r\n\r\n        open, close, read\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 165\r\n\r\n                                  INDEX\r\n\r\n\r\n       8086 70                         CP/M 26,106,131,155\r\n       absolute value 116              CP/M-80 compiler 2\r\n       acos() 103                      cputs() 107\r\n       address                         creat() 111\r\n           link 73                     creating a library 76\r\n           load 73                     CREF 83\r\n       ANSI Standard 13,17             cross compilers 3\r\n       array                           cross reference 36,83\r\n           dimension 16                ctime() 111\r\n           index 16                    ctrl-Z 26,120\r\n           size 16                     date and time 104\r\n       ASCII 26                        debugging 10,105\r\n       asctime() 104                   device name as file 23\r\n       asin() 103                      device\r\n       assembler                           as file 141\r\n           in C programs 20            di() 113\r\n       assert() 105                    directory 108,139\r\n       atan() 103                          current 130\r\n       atan2() 103                     disk changing on floppy disk\r\n       Atari ST 3                          systems 3\r\n       atexit() 104                    disk space 33\r\n       atof() 105                      div() 112\r\n       atoi() 105                      div_t 112\r\n       atol() 105                      dup() 113\r\n       bdos() 106                      editor 3,33\r\n       binary output file 8            ei() 113\r\n       bios() 106                      entering long commands 7\r\n       braces                          Enumerated Types 16\r\n           omission of 16              environment 130\r\n       byte ordering 21                error message:\r\n       C command 3,7                       Can't generate code 33\r\n       C reference books 2                 Error closing file 33\r\n       calloc() 107                        No room 33\r\n       carriage return 26,120              out of memory 33\r\n       ceil() 116                          Undefined symbol 33\r\n       cgets() 107                         Write error 33\r\n       change file attributes 108      error messages 23,33\r\n       character testing 134               format of 23\r\n       chdir() 108                         LIBR 78\r\n       checksum 79,80                      list of 23,85\r\n       chmod() 108                         redirection of 23\r\n       class name 70                   execl() 114\r\n       close() 109                     executing a sub-program 156\r\n       clreof() 109                    executing  system   commands\r\n       clrerr() 109                        160\r\n       command line 7,12,77,160        execution profiling 10\r\n       Compatibility 25                execv() 114\r\n       compiler driver 3               exit() 114\r\n       Compiler Structure 5            exp() 115\r\n       console I/O 107,129,135         exponentional functions 115\r\n       control-C handling 155          Extern Declarations 30\r\n       converting ascii  to  binary    fabs() 116\r\n           105                         fclose() 116\r\n       cos() 110                       feof() 117\r\n       cosh() 110                      ferror() 117\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 166                             HI-TECH C USER'S MANUAL\r\n\r\n   fflush() 117                    getw() 132\r\n   fgetc() 118                     global variables 30\r\n   fgets() 118                     gmtime() 132\r\n   FILE 99                         hex output file 8\r\n   file descriptor 27,111,119      I/O redirection 127\r\n       duplicating 113             I/O\r\n   FILE pointer 27                     ASCII 26\r\n   file                                Binary 26\r\n       access time 158                 standard 25,99\r\n       attributes 108,158          in-line assembler 20\r\n       closing a 109,116           Initialization Syntax 16\r\n       creating a 111              initializer 16\r\n       deleting a 148,163          inp() 133\r\n       flushing buffer to a 117    int86() 133\r\n       information about a 158     int86x() 133\r\n       modification time 158       intdos() 133\r\n       opening a 119,123,140       intdosx() 133\r\n       random   access   to   a    Intel hex format 79\r\n       125,137                     interrupt 133\r\n       reading from a 122,147      interrupt handling 155\r\n       renaming a 149              interrupt vector\r\n       size 158                        setting 154\r\n       type of a 135               isalnul() 134\r\n       writing to a 126,164        isalnum() 134\r\n   fileno() 119                    isalpha() 134\r\n   floating point                  isascii() 134\r\n       library 27                  isatty() 135\r\n       options required to  use    iscntrl() 134\r\n       4                           isdigit() 134\r\n   floor() 116                     isgraph() 134\r\n   fopen() 26,119                  islower() 134\r\n   formatted input 124,150         ispunct() 134\r\n   formatted printing 121,142      isspace() 134\r\n   fprintf() 121                   isupper() 134\r\n   fputc() 121                     kbhit() 135\r\n   fputs() 122                     Kernighan and Ritchie 2,16\r\n   fread() 122                     large model 70,80\r\n   free() 123                      ldexp() 124\r\n   freopen() 123                   ldiv() 112\r\n   frexp() 124                     LIBR 75\r\n   fscanf() 124                    librarian 75\r\n   fseek() 125                     libraries 7\r\n   ftell() 126                     library manager 75\r\n   function parameter 163          library ordering 77\r\n   function                        library\r\n       declaration 17                  creating 76\r\n       large 33                        floating point 33\r\n       parameters 17                   ordering 33\r\n       prototype 17,163            line number symbols 10\r\n   fwrite() 126                    linker 69\r\n   getc() 128                      LINT 16\r\n   getch() 129                     localtime 132\r\n   getchar() 25,129                log() 115\r\n   getche() 129                    log10() 115\r\n   getcwd() 130                    logarithmic functions 115\r\n   getenv() 130                    long 30\r\n   gets() 131                      longjmp() 136\r\n   getuid() 131                    lseek() 137\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 167\r\n\r\n       Machine Dependencies 21         pack pragma 20\r\n       macros                          parameter\r\n           predefined 21                   type 17\r\n       malloc() 137                    perror() 141\r\n       Member Names 13,29              portable code 21\r\n       memcmp() 138                    pow() 115\r\n       memcpy() 138                    pragma 20,21\r\n       memory            allocation    printf 33\r\n           107,148,150                 printf() 142\r\n           releasing 123               program execution 156\r\n       memory model 31                 psect\r\n       memory requirements 2               linking 69\r\n       memset() 138                        local 70\r\n       mkdir() 139                     putc() 144\r\n       Motorola hex format 80          putch() 129\r\n       MS-DOS 108,133,139,155          putchar() 144\r\n       msdos() 139                     puts() 145\r\n       msdoscx() 139                   putw() 145\r\n       multiple definitions 30         qsort() 146\r\n       newline 26                      rand() 147\r\n       Newton's approximation 157      random numbers 147,158\r\n       non-local goto 136,152          read() 147\r\n       objtohex 72,79                  realloc() 148\r\n       open() 140                      relocation 69\r\n       Operating Details 7             remove() 148\r\n       options 7                       rename() 149\r\n           -1 10                       return 26,120\r\n           -11 11                      rewind() 149\r\n           -2 11                       rmdir() 139\r\n           -6301 11                    S format hex 80\r\n           -A 8                        sbrk() 150\r\n           -B 9                        scanf 33\r\n           -C 7                        scanf() 150\r\n           -CPM 7                      segment registers 152\r\n           -CR 7                       segread() 152\r\n           -D 8                        self relocation 72\r\n           -E 10                       setbuf() 153\r\n           -F 8                        setjmp() 152\r\n           -G 10                       setuid() 153\r\n           -H 10                       setvbuf() 153\r\n           -I 8                        set_vector() 154\r\n           -LF 4,27,33                 shift\r\n           -M 8                            signed 14\r\n           -O 8                            unsigned 14\r\n           -Ooutfile 8                 short 21,30\r\n           -P 10                       signal() 155\r\n           -R 8                        sin() 155\r\n           -S 7                        sinh() 110\r\n           -U 8                        size of data types 21\r\n           -V 3,8                      sorting 146\r\n           -W 10                       source file naming 3\r\n           -X 8                        source level debugging 10\r\n           -Z 10                       spawnl() 156\r\n           linker 71                   spawnv() 156\r\n       outp() 133                      spawnve() 156\r\n       pack 21                         Specific Features 13\r\n                                       sprintf() 156\r\n                                       sqrt() 157\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 168                             HI-TECH C USER'S MANUAL\r\n\r\n   square root function 157        Unsigned Types 14\r\n   srand() 158                     user ID 131,153\r\n   sscanf() 157                    V3.09 2\r\n   Standard Libraries 25           va_arg 18,163\r\n   Standard  Library  Functions    va_end 163\r\n       99                          va_start 163\r\n   stat() 158                      void 18\r\n   stdarg.h 18,163                     Pointer to 18\r\n   STDIO 25,27,99                  warning level 10\r\n   storage allocator 18            warning messages\r\n   strcat() 159                        suppressing 10\r\n   strchr() 160                    wild card expansion 127\r\n   strcmp() 159                    Wordstar 33\r\n   strcpy() 159                    write() 164\r\n   stream 27,99                    Z180 MMU 68\r\n   string manipulation 159             Bank Base Register 68\r\n   strlen() 159                        BBR 68\r\n   strncat() 159                       CBAR 68\r\n   strncmp() 159                       CBR 68\r\n   strncpy() 159                       Common Base Register 68\r\n   strrchr() 160                       Common/Bank Area  Regis-\r\n   Structure Operations 15             ter 68\r\n   structure packing 20            Z180 Registers 68\r\n   structures                          ASCI 68\r\n       as function argument 15         Bank Base Register 68\r\n       assignment 15                   BBR 68\r\n       functions returning 15          BCR0H 68\r\n   Stylistic Considerations 29         BCR0L 68\r\n   symbol file 10,80                   BCR1H 68\r\n   symbols                             BCR1L 68\r\n       cross reference 83              CBAR 68\r\n       global 70,76                    CBR 68\r\n   System Requirements 2               CNTLA0 68\r\n   system() 160                        CNTLA1 68\r\n   tan() 161                           CNTLB0 68\r\n   tanh() 110                          CNTLB1 68\r\n   temporary files 4                   CNTR 68\r\n   text editor 3                       Common Base Register 68\r\n   time and date 104                   Common/Bank Area  Regis-\r\n   time() 161                          ter 68\r\n   toascii() 162                       CSI/0 68\r\n   tolower() 162                       DAR0B 68\r\n   toupper() 162                       DAR0H 68\r\n   trigonometric      functions        DAR0L 68\r\n       103,110                         DCNTL 68\r\n       hyperbolic 110                  DMA 68\r\n   Type Checking 13                    DMA Byte Count 68\r\n   type qualifiers 19                  DMA Desitination Address\r\n   typecast 13                         68\r\n   typecasting 18                      DMA Mode Register 68\r\n   ungetc() 162                        DMA Source Address 68\r\n   ungetch() 129                       DMA Status Register 68\r\n   Unix                                DMODE 68\r\n       C compiler 16                   DSTAT 68\r\n       V7 25                           FRC 68\r\n   unlink() 163                        Free Running Counter 68\r\n   unsigned 23                         IAR1H 68\r\n   unsigned char 21                    IAR1L 68\r\n\r\n\r\n\r\n\r\n\r\n\r\n       HI-TECH C USER'S MANUAL                             Page 169\r\n\r\n           ICR 68                          INC 55\r\n           IL 68                           IND 55\r\n           Interrupt Vector  Regis-        INDR 56\r\n           ter 68                          INI 56\r\n           ITC 68                          INIR 56\r\n           MAR1B 68                        JP 56\r\n           MAR1H 68                        JR 56\r\n           MAR1L 68                        LD 56,57,58,59\r\n           MMU 68                          LDD 59\r\n           OMCR 68                         LDDR 59\r\n           RCR 68                          LDI 59\r\n           Refresh Control Register        LDIR 59\r\n           68                              MLT 59\r\n           RLDR0H 68                       NEG 59\r\n           RLDR0L 68                       NOP 59\r\n           RLDR1H 68                       OR 59,60\r\n           RLDR1L 68                       OTDM 61\r\n           SAR0B 68                        OTDMR 60\r\n           SAR0H 68                        OTDR 60\r\n           SAR0L 68                        OTIM 61\r\n           STAT0 68                        OTIMR 60\r\n           STAT1 68                        OTIR 60\r\n           TCR 68                          OUT 60\r\n           TDR0 68                         OUT0 60\r\n           TDR1 68                         OUTD 60\r\n           TIMER 0 68                      OUTI 61\r\n           TIMER 1 68                      POP 61\r\n           TMDR0H 68                       PUSH 61\r\n           TMDR0L 68                       RES 61,62,63\r\n           TMDR1H 68                       RET 63\r\n           TMDR1L 68                       RETI 63\r\n           TRDR 68                         RETN 63\r\n           TSR0 68                         RL 63\r\n           TSR1 68                         RLA 63\r\n       Z80 Instructions 50                 RLC 63\r\n           ADC 51                          RLCA 63\r\n           ADD 51                          RLD 63\r\n           AND 51                          RR 63,64\r\n           BIT 52,53                       RRA 64\r\n           CALL 53                         RRC 64\r\n           CCF 53                          RRCA 64\r\n           CP 53,54                        RRD 64\r\n           CPD 54                          RST 64\r\n           CPDR 54                         SBC 64\r\n           CPI 54                          SCF 64\r\n           CPIR 54                         SET 64,65,66\r\n           CPL 54                          SLA 66\r\n           DAA 54                          SLP 66\r\n           DEC 54                          SRA 66\r\n           DI 54                           SRL 67\r\n           DJNZ 54                         SUB 67\r\n           EI 54                           TST 67\r\n           EX 55                           TSTIO 67\r\n           EXX 55                          XOR 67\r\n           HALT 55                     Z80 pseudo ops\r\n           IM 55                           IRP 47\r\n           IN 55                           IRPC 47\r\n           IN0 55                      ZAS directives 48\r\n\r\n\r\n\r\n\r\n\r\n\r\n   Page 170                             HI-TECH C USER'S MANUAL\r\n\r\n       title 48                        operators 38\r\n   ZAS options                         program sections 39\r\n       -J 35                           PSECT 43\r\n       -L 36                           psects 39,43\r\n       -N 35                           pseudo ops 40\r\n       -O 36                           relocatable object  code\r\n       -U 35                           39\r\n       -W 36                           temporary labels 37\r\n   ZAS psect flags                     Z180 35\r\n       ABS 43                          Zilog 35\r\n       GLOBAL 43                   _exit() 115\r\n       LOCAL 43                    _getargs() 127\r\n       OVRLD 43\r\n       PURE 43\r\n   ZAS pseudo ops 40\r\n       COND 42\r\n       DB 40\r\n       DEFB 40\r\n       DEFF 41\r\n       DEFL 41\r\n       DEFM 42\r\n       DEFS 41\r\n       DEFW 41\r\n       ELSE 42\r\n       END 42\r\n       ENDC 42\r\n       ENDM 44\r\n       EQU 41\r\n       GLOBAL 43\r\n       IF 42\r\n       LOCAL 45\r\n       MACRO 44\r\n       ORG 44\r\n       PSECT 43\r\n       REPT 46\r\n   ZAS\r\n       64180 35\r\n       arithmetic overflow 35\r\n       binary constants 37\r\n       character constants 38\r\n       condition codes 48\r\n       conditional assembly 42\r\n       constants 37\r\n       directives 48\r\n       extended condition codes\r\n       48\r\n       external symbols 35\r\n       floating point constants\r\n       38\r\n       hexadecimal constants 37\r\n       jump optimization 35\r\n       jumps 35\r\n       labels 36\r\n       listing 36\r\n       macros 44\r\n       mnemonics 35\r\n       octal constants 37\r\n       opcode constants 38\r\n\r\n\r\n\r\n\r\n\r\n\u001a\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
  },
  {
    "path": "doc/OBJCODE.TXT",
    "content": "\r\nHI-TECH Software\r\nObject Code Format\r\n\r\n1.  Introduction\r\n\r\n\tThis describes the format of the object code recognized by the \r\nlinker \"link\". Note that later versions of the object code have \r\nidentifying  version  numbers  in  IDENT  records. Early  version of the \r\nobject code did not have these version numbers. The presence of the \r\nversion number  can  be  determined  from the length of the ident record. \r\nCertain features will be identified as being present in versions greater \r\nthan some value by the notation (>=m.n) where m is the major version \r\nnumber and n is the minor version number, e.g. (>=2.1).\r\n\r\n2.  Object Code Structure\r\n\r\n\tThe object code (OCODE) is essentially binary, comprising a sequence \r\nof records, each with an outer envelope thus:\r\n\r\n| Length (16 bits) | Record type (8 bits) | Data (Length*8 bits) |\r\n\r\ni.e. a 16 bit length, followed by an 8 bit type, then a sequence of \r\n8 bit bytes.  The length is the number of bytes, exluding the length and \r\ntype.  In practice, the length of the data portion of any record will\r\nnot exceed 512 bytes. This places an upper limit on the size of the\r\nbuffer required to hold any record.\r\n\r\n2.1.  TEXT Record\r\n\r\n\tThe major record type is TEXT (== 1). Its format (i.e. the data \r\npart of the basic record envelope) is thus:\r\n\r\n| Offset (32 bits) | Psect name (null term.) | data bytes |\r\n\r\n\tThe Offset is the offset (in bytes) within the named psect (i.e. \r\nprogram section) at which the data bytes are to be placed.  The name, \r\nlike all names in this OCODE, is null terminated.  The number of data \r\nbytes is found by subtracting the length of the name + 4 from the record \r\nlength in the outer envelope.\r\n\r\n2.2.  PSECT Record\r\n\r\n\tThe PSECT (== 2) record is used to define program sections. Each \r\nPSECT record describes one psect.\r\n\r\n| Psect flags (16 bits) | psect name (null terminated) |\r\n\r\n\tNote that as a consistency check, the null byte terminating the \r\nname must be the last byte in the record. The flag bits are:\r\n\r\nGLOBAL  020\tPsect is global\r\nPURE\t040\tPsect is to be read-only\r\nOVRLD\t0100\tEach modules data for this psect starts at\r\n\t\trelative location 0. The default is concatenation. ABS\r\n\t0200\tThis psect is to be loaded at absolute 0.\r\nBIGSEG  0400\tMeans the relocatibility of this psect is\r\n\t\tmultiplied by 65535\r\nBPAGE\t01000\tThis is a base page psect - ignore overflows in\r\n\t\trelocations\r\n\r\n2.3.  RELOC Record\r\n\r\n\tThe RELOC (== 3) type record contains relocation information \r\nrelating to the last TEXT record. It consists of a sequence of \r\noffset/descriptor pairs, the offset being a 16 bit offset within the \r\nlast TEXT record, and the descriptor providing the relocation \r\ninformation. The type of the relocation may be simple relocation \r\nwithin a psect, relocation by the value of an external name, or whatever. \r\nComplex relocations may also appear, which are a sequence of operators \r\nand operands, to be evaluated by a stack machine. Each simple relocation \r\nrecord will appear as:\r\n\r\n| Offset (16 bits) | Reloc. type (8 bits) | Psect or external name |\r\n\r\n\tThe name is, as usual, null terminated. The actual RELOC record\r\nconsists of an arbitrary number of these entries.  The relocation type\r\nbyte is interpreted as follows:\r\n\r\nbits\t\t|7    4|3    0|\r\n\t\t| type | size |\r\n\r\nThe size is the size in bytes of the quantity to be relocated. The type \r\nis one of:\r\n\r\nRABS\t0\tAbsolute - no relocation (i.e. no change)\r\nRPSECT  1\tRelocation within named psect\r\nRNAME\t2\tRelocation by value of name\r\nRRPSECT 5\tRelocation within psect, less the current pc.\r\n\t\tThis is required for machines using relative addressing. \r\n\t\tval = val + psect.base - code.location\r\nRRNAME  6\tAs for RRPSECT, but relative to a symbol rather than a\r\n\t\tpsect.\r\nRSPSECT 9\tRelocation by the segment value for the psect\r\nRSNAME  10\tRelocation by the segment value for the symbol\r\nRCPLX\t48\tComplex relocation follows\r\n\r\n\tA complex relocation entry has, in place of the name, a sequence of \r\noperator bytes and operand bytes with further information. Where binary \r\noperations are performed, the top stack entry is the left hand operand,\r\nand the next to top stack value is the right hand operand.  Both values\r\nare removed from the stack and the result pushed back on.  Unary operators\r\nact on the top stack value.  Operands like RC_VAL and RPSECT push their\r\nvalue onto the stack.  The possible type bytes are as follows:\r\n\r\nRC_END  0\tEnd of complex relocations\r\nRC_LOW  1\tAnd with 0xFF\r\nRC_HI\t2\tRight shift 8 bits, and with 0xFF\r\nRC_VAL  3\t32 bit constant follows\r\nRC_ADD  4\tAddition\r\nRC_SUB  5\tSubtraction\r\nRC_MUL  6\tMultiplication\r\nRC_DIV  7\tDivision\r\nRC_SHL  8\tShift left\r\nRC_SHR  9\tShift right\r\nRC_AND  10\tBitwise AND\r\nRC_OR\t11\tBitwise OR\r\nRC_XOR  12\tBitwise XOR\r\nRC_CPL  13\tBitwise complement\r\nRC_NEG  14\tNegate\r\nRC_BITF 15\tBitfield extract - operands are\r\n\t\tvalue, bit offset, and length \r\nRPSECT  16\tValue of psect - null-terminated name follows\r\nRC_MOD  17\tModulus\r\nRNAME\t32\tValue of symbol - null-terminated name follows\r\nRSPSECT 144\tSegment selector of psect\r\nRSNAME  160\tSegment selector of symbol\r\n\r\n2.4.  SYM Record\r\n\r\n\tThe SYM (== 4) record defines external and internal names.  It \r\nconsists of a sequence of name definitions. Note that it is not essential \r\nto mention an external name here if it is referenced in a RELOC record. \r\nEach entry is as follows:\r\n\r\n| Value (32 bits) | flags (16 bits) | psect name | symbol name |\r\n\r\nNote that the psect name will be null if the symbol is not being \r\ndefined.  That is, the psect name will be a single null byte.  The \r\nflag word contains the same flags as defined above for PSECT records. \r\nIn the low order 4 bits is one of the following values:\r\n\r\nNULL\t0\tThe normal case when defining local or global symbols\r\nSTACK\t1\tSymbol is a stack (auto variable) symbol\r\nCOMM\t2\tSymbol is a common symbol - if it is defined elsewhere\r\n\t\tthen this is the same as EXTERN, otherwise the linker \r\n\t\twill allocate space in the psect named, of size equal to \r\n\t\tthe maximum value of any instance of this symbol \r\n\t\tencountered.\r\nREGNAM  3\tSymbol refers to a register\r\nLINENO  4\tThis is a line number in the source code\r\nFILNAM  5\tThis is the name of a source file\r\nEXTERN  6\tThis is a reference to an externally defined symbol\r\n\t\tThe psect name must be null.\r\n\r\n\tSTACK, REGNAM, FILNAM and LINENO symbols are purely for\r\nuse by a debugger.  These symbols are not handled by the linker at  \r\nall (other than to correctly relocate their values) but will be \r\npassed through to a symbol table unless suppressed with a -x option.\r\n\r\n2.5.  START Record\r\n\r\n\tThe START (== 5) record defines a start address.  Only one START \r\nrecord may appear in a module.\r\n\r\n| offset (32 bits) | psect name (null term) |\r\n\r\nThis defines the start address to be at the specified offset\r\nin the named psect.\r\n\r\n2.6.  END Record\r\n\r\n\tThe END (== 6) record is as follows:\r\n\r\n| flags (16 bits) |\r\n\r\nThe flag value is currently unused.\r\n\r\n2.7.  IDENT Record\r\n\r\n\tThe IDENT (= 7) record identifies the target machine and \r\nspecifies the ordering of bytes in 32 and 16 bit quantities. This \r\naffects both offset and symbol values as well as relocatable values in \r\nTEXT records. The IDENT record is optional, and the default ordering \r\nis strictly low byte first.  If the IDENT record is present, it must \r\nbe the first record in the file. The length field in every record's \r\nouter envelope is always stored low byte first, irrespective of the \r\ncontent of any IDENT record.\r\n\r\n| byte order (32 bits) | byte order (16 bits) | machine name | version \r\n\t\tnumber (16 bits) |\r\n\r\n\tThe byte order fields list the relative position of successively \r\nmore significant bytes within fields of 32 and 16 bits respectively. For \r\nexample, the ident record for a PDP11 would look like this:\r\n\r\n| 02 03 00 01 | 00 01 | PDP11  |\r\n\r\n\tThe machine name is null terminated. The ident record need not be \r\npresent, if more than one ident record is encountered, all records \r\nmust have identical byte ordering. The version number (>=2.0) \r\noccupies 2 bytes after the machine name.  This is present only if the \r\nrecord length is long enough to contain these extra 2 bytes. If \r\nabsent, the version number may be assumed to be 1.0.  If present, the \r\nfirst byte is the major version number, and the second the minor \r\nversion number.\r\n\r\n2.8.  XPSECT Record\r\n\r\nThe XPSECT (==8) record contains further information about a psect. \r\nSome object files may not contain any XPSECT records. The layout is as \r\nfollows:\r\n\r\n| max size (32 bits) | relocatability (16 bits) | selector (16 bits) | \r\n\t\treserved (24 bits) | type (8 bits) | psect name |\r\n\r\n\tThe max size field is a long integer specifying the maximum size of \r\nthis psect. The relocatability field, if non-zero, specifies a boundary\r\n on which the psect must start, e.g. for the 8086 this field is usually\r\n16, since 8086 segment must start on a 16 byte boundary.\r\n\r\n\tThe reserved field should be all zeros. The psect name is the \r\nnull terminated name of the psect. The selector (>=2.0) is non-zero \r\nif there is a segment selector to be associated with this psect. \r\nThis feature is normally only used with segmented architecture processors \r\nlike the 8086. In object code versions prior to 2.0 this field was \r\nalways\r\nzero.\r\n\tThe type field (>=2.1) allows the linker to verify that all \r\nmodule's contributions to a given psect are of the same type. This field \r\nmust match in all modules for this psect. This is typically used by \r\nthe 8086 assembler to encode the state of the USE32 flag for a psect.\r\n\r\n2.9.  SEGMENT Record\r\n\r\n\tThe SEGMENT (== 9) record (>= 2.0) is present in fully linked \r\nobject files only, i.e. those produced by the linker. This defines a \r\nsegment, which is a contiguous set of psects. The record structure is as \r\nfollows:\r\n\r\n| size (32 bits) | base address (32 bits) | selector (16 bits) \r\n\t| reserved (16 bits) | origin (32 bits) | segment name |\r\n\r\n\tThe size field is the size of the segment in bytes. The base \r\naddress is the physical base address of the segment. This is not \r\nnecessarily the same as the origin, which is the addresse used when \r\nreferences to this segment were relocated. These correspond to the \r\nload and link addresses respectively of the psects comprising the \r\nsegment.\r\n\tThe selector is the segment selector value used in referring \r\nto this segment. This is of relevance mainly for 8086 family processors. \r\nThe segment name is the name of the first psect comprising this segment.\r\n\r\n2.10.  XSYM Record\r\n\r\n\tThe XSYM (== 10) record (>= 2.1) is similar to the SYM record but \r\nalso defines a selector value for the symbol. The record layout is as \r\nfollows:\r\n\r\n| value (32 bits) | flags (16 bits) | selector (16 bits) | name |\r\n\r\nThe selector value is the selector of the segment\r\nwithin which the symbol is located.\r\n\r\n2.11.  SIGNAT Record\r\n\r\n\tThe SIGNAT (== 11) record (>=2.1) defines a signature for a \r\nsymbol. At link time all signatures for a symbol are compared and must be \r\nidentical. If a signature is not the same, an error message is \r\nissued. The record layout is as follows:\r\n\r\n| signature (16 bits) | symbol name |\r\n\r\n2.12.  FNINFO Record\r\n\r\n\tThe FNINFO (== 12) record (>= 2.3) provides information necessary \r\nfor call-graphing and local data allocation for non-reentrant \r\nfunctions. Within a record are concatenated one or more instances \r\nof the following layouts.  Each instance is variable length, depending \r\non name lengths.\r\n\r\n| FNCALL (1)  | caller name | callee name |\r\n| FNARG (2)   | caller name | callee name |\r\n| FNINDIR (3) | caller name | callee signature (16 bits) |\r\n| FNADDR (4)  | function name | signature (16 bits) |\r\n| FNSIZE (5)  | func name | local size (32 bits) | arg size (32 bits) |\r\n| FNROOT (6)  | func name |\r\n\r\n\tThe FNCALL instance specifies that one function directly \r\ncalls another.  The FNARG instance specifies that one function will have \r\narguments built while another is called. The FNINDIR instance \r\nspecifies that a function calls indirectly another (unknown) function, \r\nwhose signature is as specified.  The FNADDR instance specifies that the \r\nfunction has its address taken (and is thus a candidate for being \r\ncalled indirectly) and its signature.\r\n\tThe FNSIZE instance specifies the local variable block size and \r\nthe argument block size for a function. The FNROOT instance specifies \r\nthat this function is the root of a call graph (either the main function \r\nor an interrupt function).\r\n\r\n2.13.  FNCONF Record\r\n\r\n\tThe FNCONF (== 13) record (>=2.3) provides environmental \r\ninformation for call-graphing and local data allocation purposes. The \r\nlayout comprises three null-terminated strings as follows:\r\n| psect name | local data prefix | argument prefix |\r\nThe psect name is the name of the psect in which local data and \r\nargument blocks should be allocated by the linker. The local data and \r\nargument prefixes are the strings which should be prepended to a \r\nfunction name to derive the names for the local data and argument blocks \r\nfor a given function.\r\n\r\n3.  NOTES\r\n\r\n\tNo padding or fill bytes are stored in the object file, i.e. no \r\nalignment of the records is done. Do not attempt to read or write \r\nobject files using structures,  i.e. all records must be built up \r\nbyte-by-byte in a char array.\r\n"
  },
  {
    "path": "doc/SYMFILE.TXT",
    "content": "HI-TECH C\r\n\r\nSymbol File Format\r\n\r\nIntroduction\r\n\r\nThe symbol files produced by the HI-TECH linker using the -h option are\r\nascii files, organized as one symbol per line. Other lines provide\r\ninformation about modules etc.\r\n \r\nGlobal Symbols\r\n\r\nThe first part of the file comprises global symbols, i.e symbols visible\r\nthroughout the entire program. Each line has the symbol name, a space\r\nthen one or two hex numbers separated by a space.\r\n\r\nThe first hex number is the link value of the symbol, i.e. the value\r\nthat will be substituted whenever the symbol is referenced in the code.\r\nIf the symbol is absolute, this will be the only number on the line.\r\nIf a second value appears, this is the difference between the link and\r\nload addresses of the symbol. The load address of a symbol is the\r\naddress at which it appears in the code image produced by the linker.\r\nIf the link and load addresses are the same, this value will be zero.\r\nSome examples:\r\n\r\n_main 100 0\r\n\r\nThis line defines a symbol _main (note that the C compiler prepends an\r\nunderscore to all C symbols) with a link address of 100 hex and the\r\nsame load address.\r\n\r\n_bios_ram 0 400\r\n\r\nThis symbol has a link address of 0, and a load address of 400 hex. In\r\nthe context of an 8086 processor this would be interpreted as a\r\nsegemented address of 40:0 (the load address is a linear address).\r\n\r\nPsect Limits\r\n\r\nWithin the global symbols will appear some symbols generated by the\r\nlinker which give information about the limits of psects (program\r\nsections, sometimes called segments). Every psect in the program\r\nwill have at least two symbols defined for it. The names of these\r\nsymbols are formed by prepending the strings __L and __H to the psect\r\nname. The values of these are the low and high bounds of the psect\r\nrespectively. For example, the psect \"text\" would have the symbols\r\n__Ltext and __Htext defined.  These may appear as follows:\r\n\r\n__Ltext 100 0\r\n__Htext 157 0\r\n\r\nThis specifies that the text psect starts at 100 hex and has a length\r\nof 57 hex bytes. Its load and link addresses are the same. \r\nAnother example:\r\n\r\n__Lbss 560 270\r\n__Hbss 840 270\r\n\r\nThis indicates that the bss psect starts at 560 hex and extends to\r\n83F hex. Note the non-zero second number. This means that the link\r\nand load addresses are different. In 8086 real mode the segmented\r\naddress 27:560 could be used to refer to the base of this bss psect\r\n(though numerous other addresses would also refer to the same\r\nlocation).  If the link and load addresses for a psect are different,\r\nthere will also be another symbol defined, formed by prefixing __B\r\nto the psect name. This symbol will be given a value equal to the\r\nload address of the psect less the base of the psect. In the above\r\nexample, __Bbss would be set to 270.\r\n\r\nLocal Symbols\r\n\r\nThe end of the global symbol list is flagged by the line\r\n\r\n%locals\r\n\r\nAll symbols after this line are local symbols, i.e. they are visible\r\nonly to the module in which they are defined. Symbol lines will\r\ngenerally be the same in form as global symbols, i.e. a name\r\nfollowed by one or two hex numbers. In addition, lines will appear\r\nwith a file name and no hex numbers, e.g.\r\n\r\nfred.obj\r\n\r\nwould appear immediately before the symbols defined in the module\r\nfred. Within the module fred there will be one or more source files.\r\nThe names of these source files may also appear, e.g.\r\n\r\nfred.obj\r\nfred.c\r\n_fred 0 A0\r\n_bill 140 A0\r\ngeorge.c\r\n_george 276 A0\r\n\r\nThis example indicates that the source file fred.c defined the two\r\nsymbols _fred and _bill, then included another file george.c which\r\ndefined the symbol _george. Absolute symbols may also appear in the\r\nlocal symbol area. The order of symbols and modules is preserved.\r\n\r\nLine Numbers\r\n\r\nIf line numbers are included in the object code, these appear in the\r\nsame form as described above, but the symbol name is a number, e.g.\r\n\r\nfred.obj\r\nfred.c\r\n10 4 D0\r\n11 8 D0\r\n12 10 D0\r\n\r\ndefines a module fred.obj, derived from the file fred.c, and with\r\nlines 10, 11 and 12 producing code. The addresses are the addresses\r\nof the first executable code from that line.\r\n\r\nA Full Example\r\n\r\nAn example is given here of a small C source file, and the resultant\r\nsymbol file and link map. The C source is test.c, as follows:\r\n\r\n#include\t<stdio.h>\r\n#include\t<conio.h>\r\n\r\nstatic int\tfred;\r\nmain()\r\n{\r\n\tfred = 23;\r\n\tputch('x');\r\n\treturn 1;\r\n}\r\n\r\n\r\n\r\nThe resultant symbol file is:\r\n\r\n\r\n_main E01C 0\r\n_exit E019 0\r\nstart E000 0\r\n__Hbss 8006 0\r\n__Lbss 8004 0\r\n_getch E06D 0\r\n_kbhit E063 0\r\n_putch E047 0\r\n__Hdata E093 0\r\n__Ldata E093 0\r\n__Htemp 8004 0\r\n__Ltemp 8000 0\r\n__Htext E093 0\r\n_getche E084 0\r\n__Ltext E000 0\r\n__Hstack 8800 0\r\n__Lstack 8800 0\r\n__Hvectors 10000 0\r\n__Lvectors 0 0\r\n_init_uart E031 0\r\n%locals\r\ntest.c\r\n6 E01C 0\r\n7 E01E 0\r\n8 E024 0\r\n9 E029 0\r\n10 E02E 0\r\n_fred 8004 0\r\nctemp 8000 0\r\n\r\n\r\nThe link map generated at the same time is:\r\n\r\n Linker command line:\r\n\r\n-w80 -z -H -Mmap -ptext=0e000h,data,temp=08000h,bss,stack=08800h \\\r\n  -o/usr/tmp/eaaa20022 /usr/hitech/lib/crt09.obj \\\r\n  test.obj \\\r\n  /usr/hitech/lib/09libc.lib \r\n\r\nMachine type is 6809\r\n\r\n/usr/hitech/lib/crt09.obj\r\n\t\tvectors         0        0    10000\r\n\t\ttext         E000     E000       1C\r\ntest.obj\ttext         E01C     E01C       15\r\n\t\tbss          8004     8004        2\r\n\t\ttemp         8000     8000        4\r\n\r\n/usr/hitech/lib/09libc.lib\r\ngetch.obj\ttext         E031     E031       62\r\n\t\ttemp         8000     8000        4\r\n\r\nTOTAL\tName         Link     Load   Length\r\n\t\tvectors         0        0    10000\r\n\t\ttext         E000     E000       93\r\n\t\tbss          8004     8004        2\r\n\t\ttemp         8000     8000        4\r\n\r\n\r\nSEGMENTS\tName\t\tLoad\tLength\tSelector\r\n\r\n\t\ttext            00E000\t000093\t  E000\r\n\t\ttemp            008000\t000006\t  8000\r\n\t\tstack           008800\t000000\t  8800\r\n\r\n                                  Symbol Table\r\n\r\n__Hbss     bss     08006  __Hdata    data    0E093  __Hstack   stack   08800\r\n__Htemp    temp    08004  __Htext    text    0E093  __Hvectors vectors 10000\r\n__Lbss     bss     08004  __Ldata    data    0E093  __Lstack   stack   08800\r\n__Ltemp    temp    08000  __Ltext    text    0E000  __Lvectors vectors 00000\r\n_exit      text    0E019  _getch     text    0E06D  _getche    text    0E084\r\n_init_uart text    0E031  _kbhit     text    0E063  _main      text    0E01C\r\n_putch     text    0E047  start      text    0E000  \r\n\r\n\r\n\r\n"
  },
  {
    "path": "float/ACOS.C",
    "content": "#include\t<math.h>\r\n\r\n#define\tPI\t3.14159265358979\r\n#define\tTWO_PI\t6.28318530717958\r\n#define\tHALF_PI\t1.570796326794895\r\n\r\ndouble\r\nacos(x)\r\ndouble\tx;\r\n{\r\n\treturn HALF_PI - asin(x);\r\n}\r\n"
  },
  {
    "path": "float/ASFLOAT.AS",
    "content": "\tglobal\tasfladd, asflsub, asflmul, asfldiv\r\n\tglobal\tfladd, flsub, flmul, fldiv\r\n\tglobal \tiregset, iregstore\r\n\tpsect\ttext\r\n\r\nasfladd:\r\n\tcall\tiregset\r\n\tcall\tfladd\r\n\tjp\tiregstore\r\nasflsub:\r\n\tcall\tiregset\r\n\tcall\tflsub\r\n\tjp\tiregstore\r\nasflmul:\r\n\tcall\tiregset\r\n\tcall\tflmul\r\n\tjp\tiregstore\r\nasfldiv:\r\n\tcall\tiregset\r\n\tcall\tfldiv\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "float/ASIN.C",
    "content": "#include\t<math.h>\r\n\r\n#define\tPI\t3.14159265358979\r\n#define\tTWO_PI\t6.28318530717958\r\n#define\tHALF_PI\t1.570796326794895\r\n\r\ndouble\r\nasin(x)\r\ndouble\tx;\r\n{\r\n\tdouble\ty;\r\n\tdouble\tsgn;\r\n\r\n\tif(fabs(x) > 1.0)\r\n\t\treturn 0.0;\r\n\tsgn = 1.0;\r\n\ty = sqrt(1.0 - x*x);\r\n\tif(fabs(x) < 0.71)\r\n\t\treturn atan(x/y);\r\n\tif(x < 0.0)\r\n\t\treturn -(HALF_PI - atan(-y/x));\r\n\treturn (HALF_PI - atan(y/x));\r\n}\r\n"
  },
  {
    "path": "float/ATAN.C",
    "content": "#include\t<math.h>\r\n\r\n#define\tPI\t3.14159265358979\r\n#define\tTWO_PI\t6.28318530717958\r\n#define\tHALF_PI\t1.570796326794895\r\n\r\ndouble\r\natan(f)\r\ndouble\tf;\r\n{\r\n\tstatic /* const */ double\tcoeff_a[] =\r\n\t{\r\n\t\t33.058618473989548,\r\n\t\t58.655751569001961,\r\n\t\t32.390974856200445,\r\n\t\t5.8531952112628600,\r\n\t\t0.19523741936234277,\r\n\t\t-.0024346033004411264\r\n\t};\r\n\tstatic /* const */ double\tcoeff_b[] =\r\n\t{\r\n\t\t33.058618473992416,\r\n\t\t69.675291059524653,\r\n\t\t49.004348218216250,\r\n\t\t12.975578862709239,\r\n\t\t1.0\r\n\t};\r\n\tint\trecip;\r\n\textern double\teval_poly(), fabs();\r\n\tdouble\t\tval, val_squared;\r\n\r\n\tif((val = fabs(f)) == 0.0)\r\n\t\treturn 0.0;\r\n\tif(recip = (val > 1.0))\r\n\t\tval = 1.0/val;\r\n\tval_squared = val * val;\r\n\tval *= eval_poly(val_squared, coeff_a, 5)/eval_poly(val_squared, coeff_b, 4);\r\n\tif(recip)\r\n\t\tval = HALF_PI - val;\r\n\treturn f < 0.0 ? -val : val;\r\n}\r\n"
  },
  {
    "path": "float/ATAN2.C",
    "content": "#include\t<math.h>\r\n\r\n#define\tPI\t3.14159265358979\r\n#define\tTWO_PI\t6.28318530717958\r\n#define\tHALF_PI\t1.570796326794895\r\n\r\ndouble\r\natan2(x, y)\r\ndouble\tx, y;\r\n{\r\n\tdouble\tv;\r\n\r\n\tif(fabs(y) >= fabs(x)) {\r\n\t\tv = atan(x/y);\r\n\t\tif( y < 0.0)\r\n\t\t\tif(x >= 0.0)\r\n\t\t\t\tv += PI;\r\n\t\t\telse\r\n\t\t\t\tv -= PI;\r\n\t\treturn v;\r\n\t}\r\n\tv = -atan(y/x);\r\n\tif(x < 0.)\r\n\t\tv -= HALF_PI;\r\n\telse\r\n\t\tv += HALF_PI;\r\n\treturn v;\r\n}\r\n"
  },
  {
    "path": "float/ATOF.C",
    "content": "#include\t<ctype.h>\r\n\r\ndouble\r\natof(s)\r\nregister char *\ts;\r\n{\r\n\tchar\tsign;\r\n\tdouble\tl;\r\n\tshort\texp;\r\n\tshort\teexp;\r\n\tchar\texpsign;\r\n\tdouble\tten;\r\n\r\n\tten = 10.0;\r\n\twhile(isspace(*s))\r\n\t\ts++;\r\n\texpsign = sign = 0;\r\n\tif(*s == '-') {\r\n\t\ts++;\r\n\t\tsign = 1;\r\n\t}\r\n\tl = 0;\r\n\texp = 0;\r\n\twhile(isdigit(*s))\r\n\t\tl = ten*l + (double)(*s++ - '0');\r\n\tif(*s == '.')\r\n\t\twhile(isdigit(*++s)) {\r\n\t\t\texp--;\r\n\t\t\tl = ten*l + (double)(*s - '0');\r\n\t\t}\r\n\teexp = 0;\r\n\tif(*s == 'e' || *s == 'E') {\r\n\t\tif(*++s == '-') {\r\n\t\t\texpsign = 1;\r\n\t\t\ts++;\r\n\t\t}\r\n\t\tif(*s == '+')\r\n\t\t\ts++;\r\n\t\twhile(isdigit(*s))\r\n\t\t\teexp = eexp*10 + *s++ - '0';\r\n\t\tif(expsign)\r\n\t\t\teexp = -eexp;\r\n\t}\r\n\texp += eexp;\r\n\twhile(exp < 0) {\r\n\t\tl = l / ten;\r\n\t\texp++;\r\n\t}\r\n\twhile(exp > 0) {\r\n\t\tl = l * ten;\r\n\t\texp--;\r\n\t}\r\n\tif(sign)\r\n\t\treturn -l;\r\n\treturn l;\r\n}\r\n"
  },
  {
    "path": "float/CEIL.C",
    "content": "\r\n#include\t<math.h>\r\n\r\nextern double\t_frndint();\r\n\r\ndouble\r\nceil(x)\r\ndouble\tx;\r\n{\r\n\tdouble\ti;\r\n\r\n\ti = _frndint(x);\r\n\tif(i < x)\r\n\t\treturn i + 1.0;\r\n\treturn i;\r\n}\r\n"
  },
  {
    "path": "float/COS.C",
    "content": "#include\t<math.h>\r\n\r\n#define\tPI\t3.14159265358979\r\n#define\tTWO_PI\t6.28318530717958\r\n#define\tHALF_PI\t1.570796326794895\r\n\r\ndouble\r\ncos(f)\r\ndouble\tf;\r\n{\r\n\t/* cos is pi/2 out of phase with sin, so ... */\r\n\r\n\tif(f > PI)\r\n\t\treturn sin(f - (PI+HALF_PI));\r\n\treturn sin(f + HALF_PI);\r\n}\r\n"
  },
  {
    "path": "float/COSH.C",
    "content": "\r\n#include\t<math.h>\r\n\r\ndouble\r\ncosh(x)\r\ndouble\tx;\r\n{\r\n\tx = exp(x);\r\n\treturn 0.5*(x+1.0/x);\r\n}\r\n"
  },
  {
    "path": "float/DOPRNT.C",
    "content": "#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n\r\n\r\n/*\r\n *\tdoprnt for 8086\r\n */\r\n\r\nstatic uchar\tival;\r\nstatic char *\tx;\r\nstatic FILE *\tffile;\r\nextern int\tatoi(char *);\r\nextern int\tstrlen(char *);\r\n\r\nstatic\r\npputc(c)\r\nint\tc;\r\n{\r\n\tputc(c, ffile);\r\n}\r\n\r\nstatic char *\r\nicvt(cp)\r\nregister char *\tcp;\r\n{\r\n\tival = atoi(cp);\r\n\twhile(isdigit((unsigned)*cp))\r\n\t\tcp++;\r\n\treturn cp;\r\n}\r\n\r\n_doprnt(file, f, a)\r\nFILE *\tfile;\r\nregister char *\t\tf;\r\nint *\t\ta;\r\n{\r\n\tchar\tc, prec;\r\n\tuchar\tfill, left;\r\n\tunsigned int i, len;\r\n\tuchar\tbase, width, sign;\r\n\tuchar\tftype;\r\n\textern\tshort _pnum(), _fnum();\r\n\r\n\tffile = file;\r\n\twhile(c = *f++)\r\n\t\tif(c != '%')\r\n\t\t\tpputc(c);\r\n\t\telse {\r\n\t\t\tbase = 10;\r\n\t\t\twidth = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tleft = 0;\r\n\t\t\tftype = 0;\r\n\t\t\tlen = sizeof(int)/sizeof *a;\r\n\t\t\tif(*f == '-') {\r\n\t\t\t\tf++;\r\n\t\t\t\tleft++;\r\n\t\t\t}\r\n\t\t\tfill = *f == '0';\r\n\t\t\tif(isdigit((unsigned)*f)) {\r\n\t\t\t\tf = icvt(f);\r\n\t\t\t\twidth = ival;\r\n\t\t\t} else if(*f == '*') {\r\n\t\t\t\twidth = *a++;\r\n\t\t\t\tf++;\r\n\t\t\t}\r\n\t\t\tif(*f == '.')\r\n\t\t\t\tif(*++f == '*') {\r\n\t\t\t\t\tprec = *a++;\r\n\t\t\t\t\tf++;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tf = icvt(f);\r\n\t\t\t\t\tprec = ival;\r\n\t\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tprec = fill ? width : -1;\r\n\t\t\tif(*f == 'l') {\r\n\t\t\t\tf++;\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\t}\r\n\t\t\tswitch(c = *f++) {\r\n\r\n\t\t\tcase 0:\r\n\t\t\t\treturn;\r\n\t\t\tcase 'o':\r\n\t\t\tcase 'O':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'd':\r\n\t\t\tcase 'D':\r\n\t\t\t\tsign = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'x':\r\n\t\t\tcase 'X':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\tx = *(char **)a;\r\n\t\t\t\ta += sizeof(char *)/sizeof *a;\r\n\t\t\t\tif(!x)\r\n\t\t\t\t\tx = \"(null)\";\r\n\t\t\t\ti = strlen(x);\r\ndostring:\r\n\t\t\t\tif(prec < 0)\r\n\t\t\t\t\tprec = 0;\r\n\t\t\t\tif(prec && prec < i)\r\n\t\t\t\t\ti = prec;\r\n\t\t\t\tif(width > i)\r\n\t\t\t\t\twidth -= i;\r\n\t\t\t\telse\r\n\t\t\t\t\twidth = 0;\r\n\t\t\t\tif(!left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\twhile(i--)\r\n\t\t\t\t\tpputc(*x++);\r\n\t\t\t\tif(left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\tcontinue;\r\n\t\t\tcase 'c':\r\n\t\t\t\tc = *a++;\r\n\t\t\tdefault:\r\n\t\t\t\tx = &c;\r\n\t\t\t\ti = 1;\r\n\t\t\t\tgoto dostring;\r\n\r\n\t\t\tcase 'u':\r\n\t\t\tcase 'U':\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'e':\r\n\t\t\tcase 'E':\r\n\t\t\t\tsign++;\r\n\r\n\t\t\tcase 'g':\r\n\t\t\tcase 'G':\r\n\t\t\t\tsign++;\r\n\r\n\t\t\tcase 'f':\r\n\t\t\tcase 'F':\r\n\t\t\t\tif(prec < 0)\r\n\t\t\t\t\tprec = 6;\r\n\t\t\t\tftype = 1;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tif(left) {\r\n\t\t\t\tleft = width;\r\n\t\t\t\twidth = 0;\r\n\t\t\t}\r\n\t\t\tif(isupper(c))\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\tif(prec < 0)\r\n\t\t\t\tprec = 0;\r\n\t\t\tif(ftype) {\r\n\t\t\t\twidth = _fnum(*(double *)a, prec, width, sign, pputc);\r\n\t\t\t\ta += sizeof(double)/sizeof(*a);\r\n\t\t\t} else {\r\n\t\t\t\twidth = _pnum((len == sizeof(int)/sizeof *a ? (sign ? (long)*a : (unsigned long)*a) : *(long *)a), prec, width, sign, base, pputc);\r\n\t\t\t\ta += len;\r\n\t\t\t}\r\n\t\t\twhile(left-- > width)\r\n\t\t\t\tpputc(' ');\r\n\t\t}\r\n}\r\n"
  },
  {
    "path": "float/DOSCAN.C",
    "content": "/*\r\n *\t_doscan - implement scanf, fscanf, sscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include \t<ctype.h>\r\n\r\n\r\nstatic FILE *\tfp;\r\nextern double\tatof(char *);\r\nextern int\tatoi(char *);\r\n\r\nstatic\r\nrange(c, base)\r\nint\tc;\r\nuchar\tbase;\r\n{\r\n\tif(isdigit(c))\r\n\t\tc -= '0';\r\n\telse\r\n\t\t{\r\n\t\tif (isupper(c))\r\n\t\t\tc = tolower(c) ;\r\n\t\tif (isalpha(c))\r\n\t\t\tc = c - 'a' + 10 ;\r\n\t\telse\r\n\t\t\treturn -1 ;\r\n\t\t}\r\n\tif (c >= base)\r\n\t\treturn -1 ;\r\n\treturn c ;\r\n}\r\n\r\nstatic\r\nwspace()\r\n{\r\n\tint\tc;\r\n\r\n\twhile(isspace(c = getc(fp)))\r\n\t\tcontinue;\r\n\tif(c != EOF)\r\n\t\tungetc(c, fp);\r\n}\r\n\r\n_doscan(file, fmt, args)\r\nFILE *\t\tfile;\r\nregister char *\tfmt;\r\nint **\t\targs;\r\n{\r\n\tuchar\tc, sign, base, n, noass,len;\r\n\tchar\twidth ;\r\n\tchar *\tsptr;\r\n\tint\tch;\r\n\tlong\tval;\r\n\tchar\tbuf[60];\r\n\r\n\tfp = file;\r\n\tn = 0;\r\n\twhile(c = *fmt++) {\r\n\r\n\t\tlen = 0 ;\r\n\t\tif(isspace(c)) {\r\n\t\t\twspace();\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif(c == '%') {\r\n\t\t\tnoass = 0;\r\n\t\t\twidth = 0;\r\nloop:\r\n\t\t\tswitch(c = *fmt++) {\r\n\r\n\t\t\tcase '\\0':\r\n\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\r\n\t\t\tcase '*':\r\n\t\t\t\tnoass++;\r\n\t\t\t\tgoto loop;\r\n\r\n\t\t\tcase 'F':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'f':\r\n\t\t\t\twspace();\r\n\t\t\t\tsptr = buf;\r\n\t\t\t\tif(width == 0)\r\n\t\t\t\t\twidth = sizeof buf - 1;\r\n\t\t\t\tsign = 0;\t/* really decimal point seen */\r\n\t\t\t\tch = getc(fp);\r\n\t\t\t\tif(ch == '-') {\r\n\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t\twidth--;\r\n\t\t\t\t}\r\n\t\t\t\twhile(width && isdigit(ch) || !sign && ch == '.') {\r\n\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\tif(ch == '.')\r\n\t\t\t\t\t\tsign++;\r\n\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t\twidth--;\r\n\t\t\t\t}\r\n\t\t\t\tif(width && (ch == 'e' || ch == 'E')) {\r\n\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t\twidth--;\r\n\t\t\t\t\tif(width && (ch == '-' || ch == '+')) {\r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t\t\twidth--;\r\n\t\t\t\t\t}\r\n\t\t\t\t\twhile(width && isdigit(ch)) {\r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t\t\twidth--;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t*sptr = 0;\r\n\t\t\t\tif(ch != EOF)\r\n\t\t\t\t\tungetc(ch, fp);\r\n\t\t\t\tif(sptr == buf)\r\n\t\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\t\t\t\tn++;\r\n\t\t\t\tif(!noass)\r\n\t\t\t\t\tif(len)\r\n\t\t\t\t\t\t*(double *)*args++ = atof(buf);\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\t*(float *)*args++ = atof(buf);\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tcase 'l':\r\n\t\t\t\tlen++;\r\n\t\t\t\tgoto loop;\r\n\r\n\t\t\tcase 'D':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'd':\r\n\t\t\t\tbase = 10;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'O':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'o':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'X':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'x':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak ;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\twspace();\r\n\t\t\t\tif ( !noass )\r\n\t\t\t\t\tsptr = (char *)*args++;\r\n\t\t\t\tif ((ch = getc(fp)) == EOF )\r\n\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\twhile(ch && ch != EOF && !isspace(ch)) {\r\n\t\t\t\t\tif(ch == *fmt) {\r\n\t\t\t\t\t\tfmt++;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif ( !noass ) \r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\tif(--width == 0)\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t}\r\n\t\t\t\tn++;\r\n\t\t\t\tif(!noass)\r\n\t\t\t\t\t*sptr = 0;\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tcase 'c':\r\n\t\t\t\tif ( !noass )\r\n\t\t\t\t\tsptr = (char *)*args++;\r\n\t\t\t\tdo {\r\n\t\t\t\t\tif ((ch = getc(fp)) == EOF) \r\n\t\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\t\tif ( !noass )\r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t} while(--width > 0);\r\n\t\t\t\tn++;\r\n\t\t\t\tcontinue;\r\n\t\t\tdefault:\r\n\t\t\t\tif(isdigit(c)) {\r\n\t\t\t\t\twidth = atoi(fmt-1);\r\n\t\t\t\t\twhile(isdigit(*fmt))\r\n\t\t\t\t\t\tfmt++;\r\n\t\t\t\t\tgoto loop;\r\n\t\t\t\t}\r\n\t\t\t\tif(c != (ch = getc(fp)))\r\n\t\t\t\t\tif(ch == EOF)\r\n\t\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tungetc(ch, fp);\r\n\t\t\t\t\t\treturn n;\r\n\t\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\twspace();\r\n\t\t\tval = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tch = getc(fp);\r\n\t\t\tif(ch == '-') {\r\n\t\t\t\tsign++;\r\n\t\t\t\tch = getc(fp);\r\n\t\t\t}\r\n\t\t\tif(range(ch, base) == -1) {\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\t\t\t}\r\n\t\t\tdo {\r\n\t\t\t\tval = val * base + range(ch, base);\r\n\t\t\t} while (( --width != 0 ) && ( range(ch = getc(fp),base) != -1 )) ;\r\n\t\t\tn++;\r\n\t\t\tif (range(ch,base) == -1)\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\tif(sign)\r\n\t\t\t\tval = -val;\r\n\t\t\tif ( !noass )\r\n\t\t\t\tif(len)\r\n\t\t\t\t\t*(long *)*args++ = val;\r\n\t\t\t\telse\r\n\t\t\t\t\t**args++ = val;\r\n\t\t\tcontinue;\r\n\t\t} else if(c != (ch = getc(fp))) {\r\n\t\t\tif(ch != EOF) {\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\t\treturn n;\r\n\t\t\t} else\r\n\t\t\t\treturn n ? n : EOF;\r\n\t\t}\r\n\t}\r\n\treturn n;\r\n}\r\n"
  },
  {
    "path": "float/EVALPOLY.C",
    "content": "double\r\neval_poly(x, d, n)\r\ndouble\tx;\r\n/* const */ double * d;\r\nint\tn;\r\n{\r\n\tint\ti;\r\n\tdouble\tres;\r\n\r\n\tres = d[i = n];\r\n\twhile(i)\r\n\t\tres = x * res + d[--i];\r\n\treturn res;\r\n}\r\n"
  },
  {
    "path": "float/EXP.C",
    "content": "#include\t<math.h>\r\n\r\nextern double\teval_poly();\r\ndouble\r\nexp(x)\r\ndouble x;\r\n{\r\n\tint\texp;\r\n\tchar\tsign;\r\n\r\n\t/* const */ static double coeff[] =\r\n\t{\r\n\t\t1.0000000000e+00,\r\n\t\t6.9314718056e-01,\r\n\t\t2.4022650695e-01,\r\n\t\t5.5504108945e-02,\r\n\t\t9.6181261779e-03,\r\n\t\t1.3333710529e-03,\r\n\t\t1.5399104432e-04,\r\n\t\t1.5327675257e-05,\r\n\t\t1.2485143336e-06,\r\n\t\t1.3908092221e-07,\r\n\t};\r\n\r\n\tif(x == 0.0)\r\n\t\treturn 1.0;\r\n\tsign = x < 0.0;\r\n\tif(sign)\r\n\t\tx = -x;\r\n\tx *= 1.4426950409;\t\t/* convert to log2 */\r\n\texp = (int)floor(x);\r\n\tx -= (double)exp;\r\n\tx = ldexp(eval_poly(x, coeff, sizeof coeff/sizeof coeff[0] - 1), exp);\r\n\tif(sign)\r\n\t\treturn 1.0/x;\r\n\treturn x;\r\n}\r\n\r\ndouble\r\npow(x, y)\r\ndouble\tx, y;\r\n{\r\n\tunsigned char\tsign = 0;\r\n\tunsigned long\tyi;\r\n\t\r\n\tif(x == 0.0)\r\n\t\treturn 0.0;\r\n\tif(y == 0.0)\r\n\t\treturn 1.0;\r\n\tif(x < 0.0) {\r\n\t\tyi = (unsigned long)y;\r\n\t\tif(yi != y)\r\n\t\t\treturn 0.0;\r\n\t\tsign = yi & 1;\r\n\t\tx = -x;\r\n\t}\r\n\tx = exp(log(x) * y);\r\n\tif(sign)\r\n\t\treturn -x;\r\n\treturn x;\r\n}\r\n"
  },
  {
    "path": "float/FABS.C",
    "content": "double\r\nfabs(d)\r\ndouble\td;\r\n{\r\n\tif(d < 0.0)\r\n\t\treturn -d;\r\n\treturn d;\r\n}\r\n"
  },
  {
    "path": "float/FBCD.AS",
    "content": ";\tlong\t_fbcd(x, exp, buf)\r\n;\tdouble\tx;\r\n;\tint *\texp;\r\n;\tchar *\tbuf;\r\n\r\n;\tsplit x into mantissa and decimal exponent parts\r\n;\treturn value is the (long) mantissa part, exponent part is\r\n;\tstored in *exp as two's complement. Mantissa is stored into buf\r\n;\tas an ascii string.\r\n\r\nargx\tequ\t6\t\t;offset of x argument\r\nargexp\tequ\t10\t\t;offset of exp argument\r\nargbuf\tequ\t12\t\t;offset of buf argument\r\nexptmp\tequ\t-1\t\t;offset of exp temp byte\r\nsgntmp\tequ\t-2\t\t;offset of sign byte\r\n\r\nNDIG\tequ\t8\t\t;number of decimal digits\r\n\r\n\tglobal\t__fbcd, rcsv, cret, flmul, negmant,lldiv,llmod\r\n\tpsect\ttext\r\n\r\nhasfrac:\r\n\tld\tc,0\t\t;zero number\r\n\tld\ta,e\t\t;check low 8 bits\r\n\tor\ta\r\n\tjr\tnz,1f\t\t;non zero bit in low 8 bits\r\n\tld\tc,8\t\t;bump count\r\n\tld\ta,d\t\t;check next 8 bits\r\n\tor\ta\t\t;is there a bit there?\r\n\tjr\tnz,1f\t\t;yup\r\n\tld\tc,16\r\n\tld\ta,h\t\t;now check next 8 bits\r\n1:\r\n\trra\t\t\t;shift bottom bit out\r\n\tjr\tc,2f\t\t;found a bit!\r\n\tinc\tc\t\t;increment count\r\n\tjr\t1b\t\t;and loop\r\n\r\n2:\r\n\tld\ta,h\t\t;get exponent\r\n\tres\t7,a\t\t;clear sign bit - should be zero anyway\r\n\tsub\t64+24\t\t;normalize - remove bias\r\n\tadd\ta,c\t\t;add in bit position\r\n\tret\t\t\t;return with value in a and flags set\r\n\r\n__fbcd:\r\n\tcall\trcsv\t\t;get x into hlde, exp into bc\r\n\tdec\tsp\t\t;make room for exponent\r\n\tdec\tsp\t\t;and sign flag\r\n\txor\ta\r\n\tld\t(ix+exptmp),a\t;zero it\r\n\tld\t(ix+sgntmp),a\r\n\tld\t(bc),a\t\t;and the returned exp value\r\n\tex\tde,hl\t\t;put hi word into hl as required\r\n\tld\ta,h\t\t;check for zero exponent\r\n\tand\t7Fh\t\t;zero exponent means 0.0\r\n\tjp\tnz,1f\t\t;return if x == 0.0\r\n\tld\tl,a\t\t;zero mantissa just in case\r\n\tld\te,a\r\n\tld\td,a\r\n\tld\th,a\t\t;and sign/exponent\r\n\tjp\tsbcd\t\t;return with mantissa = 0, exponent = 0\r\n1:\r\n\tres\t7,h\t\t;test mantissa sign\r\n2:\r\n\tcall\thasfrac\t\t;any fractional part?\r\n\tjp\tm,1f\t\t;negative if there is fractional part\r\n\tpush\thl\t\t;put x on stack\r\n\tpush\tde\r\n\tld\thl,(tenth+2)\r\n\tld\tde,(tenth)\r\n\tcall\tflmul\t\t;returns with value in hlde\r\n\tinc\t(ix+exptmp)\t;increment exponent\r\n\tjr\t2b\t\t;now check again\r\n1:\r\n\tpush\thl\r\n\tpush\tde\t\t;pass x as argument\r\n\tld\thl,(ten+2)\r\n\tld\tde,(ten)\r\n\tcall\tflmul\t\t;multiply it\r\n\tdec\t(ix+exptmp)\t;and decrement exponent\r\n\tcall\thasfrac\t\t;check for fractional part\r\n\tjp\tm,1b\t\t;loop if still fractional\r\n\tld\ta,h\t\t;get exponent\r\n\tld\th,0\t\t;zero top byte\r\n\tsub\t64+24\t\t;offset exponent\r\n2:\r\n\tor\ta\t\t;check for zero\r\n\tjr\tz,3f\t;return if finished\r\n\tjp\tp,4f\r\n\tsrl\tl\t\t;shift l down\r\n\trr\td\t\t;rotate the rest\r\n\trr\te\r\n\tinc\ta\t\t;increment count\r\n\tjr\t2b\r\n\r\n4:\r\n\tsla\te\r\n\trl\td\r\n\trl\tl\r\n\trl\th\r\n\tdec\ta\r\n\tjr\t2b\r\n\r\n3:\r\n\tld\ta,(ix+exptmp)\r\n\tld\tc,(ix+argexp)\t;get exp pointer\r\n\tld\tb,(ix+argexp+1)\r\n\tld\t(bc),a\t\t;store exponent\r\n\tinc\tbc\r\n\trla\r\n\tsbc\ta,a\r\n\tld\t(bc),a\t\t;sign extend it\r\n\tbit\t0,(ix+sgntmp)\t;test sign\r\n\tjp\tz,sbcd\t\t;return if no negation needed\r\n\tpush\thl\t\t;push hi word\r\n\tld\thl,0\t\t;get a zero\r\n\tor\ta\t\t;reset carry\r\n\tsbc\thl,de\t\t;do low subtraction\r\n\tex\tde,hl\t\t;put into de again\r\n\tld\thl,0\t\t;get another zero\r\n\tpop\tbc\t\t;get hi word\r\n\tsbc\thl,bc\t\t;subtract again\r\n\r\nsbcd:\t\t\t\t;now store as ascii\r\n\tld\tc,(ix+argbuf)\r\n\tld\tb,(ix+argbuf+1)\r\n\tpush\tbc\r\n\tpop\tiy\r\n\tld\tbc,NDIG\r\n\tadd\tiy,bc\t\t;point to end of buffer\r\n\tld\tb,c\r\n\tld\t(iy+0),0\t;null terminate\r\n\tpush\thl\r\n\tpush\tde\t\t;save return value\r\n1:\r\n\tpush\tbc\t\t;save count\r\n\tpush\thl\t\t;save value\r\n\tpush\tde\r\n\tld\tbc,0\r\n\tpush\tbc\t\t;pass 10 on stack\r\n\tld\tbc,10\r\n\tpush\tbc\r\n\tcall\tllmod\r\n\tld\ta,e\t\t;get remainder\r\n\tadd\ta,'0'\t\t;asciize\r\n\tdec\tiy\r\n\tld\t(iy+0),a\r\n\tpop\tde\r\n\tpop\thl\t\t;restore value\r\n\tld\tbc,0\t\t;now divide by 10\r\n\tpush\tbc\r\n\tld\tbc,10\r\n\tpush\tbc\r\n\tcall\tlldiv\r\n\tpop\tbc\t\t;restore count\r\n\tdjnz\t1b\t\t;loop if more to do\r\n\tpop\tde\r\n\tpop\thl\r\n\tjp\tcret\t\t;all done\r\n\t\r\n\r\n\r\n\tpsect\tdata\r\nten:\tdeff\t10.0\r\ntenth:\tdeff\t0.1\r\n"
  },
  {
    "path": "float/FINC.AS",
    "content": ";\tlfinc - floating increment\r\n;\tlfdec - floating decrement\r\n\r\n\tpsect\ttext\r\n\tglobal\tlfinc, lfdec, asfladd\r\n\r\nlfinc:\r\n\texx\r\n\tld\thl,one\r\nincdec:\r\n\texx\t\t\t;restore original hl\r\n\tld\te,(hl)\t\t;get left operand original value\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\r\n\tpush\tde\t\t;save on the stack for 'ron\r\n\tdec\thl\t\t;restore pointer value\r\n\tdec\thl\r\n\tdec\thl\r\n\texx\t\t\t;now pointer to right op\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\t\t;hi order word first\r\n\tpush\tde\t\t;low order word second\r\n\texx\t\t\t;restore pointer to left op\r\n\tcall\tasfladd\t\t;perform the addition\r\n\tpop\tde\t\t;pop original lo word\r\n\tpop\thl\t\t;and high word\r\n\tret\t\t\t;and return with it in the right place\r\n\r\nlfdec:\r\n\texx\r\n\tld\thl,mone\t\t;get a minus one\r\n\tjp\tincdec\r\n\r\n\tpsect\tdata\r\none:\r\n\tdeff\t1.0\r\nmone:\r\n\tdeff\t-1.0\r\n"
  },
  {
    "path": "float/FLOAT.AS",
    "content": ";\tThis is a set of routines for floating point handling for C\r\n\r\n;\tThe format of a floating point number is as follows:\r\n;\r\n;\t\t\t------------\r\n;\t\t\t*   sign   *\t1 bit\r\n;\t\t\t*----------*\r\n;\t\t\t* exponent *\t7 bits\r\n;\t\t\t*----------*\r\n;\t\t\t* mantissa *\t24 bits, normalized\r\n;\t\t\t------------\r\n;\r\n;\t\tNote that the number is stored with the mantissa in the\r\n;\t\tlow order bytes, i.e. the sign is the most significant\r\n;\t\tbit of the most significant byte.\r\n\r\n\tglobal\tfpnorm, fladd, flsub, flmul, fldiv, negmant\r\n\r\n\tpsect\ttext\r\n\r\n\r\n;\tfpnorm\t- passed a floating point number in HLDE (sign and exponent\r\n;\t\tin H) - returns with it normalized.\r\n;\r\n;\tPoints to note:\r\n;\t\tNormalization consists of shifting the mantissa until there\r\n;\t\tis a 1 bit in the MSB of the mantissa.\r\n;\r\n\r\nfpnorm:\r\n\tld\ta,l\t\t;check for zero mantissa\r\n\tor\td\r\n\tor\te\r\n\tjp\tz,fpzero\t;make it a clean zero\r\n\tpush\thl\t\t;save exponent and sign\r\n\tpop\tbc\t\t;get the exponent into b\r\n\tld\tc,b\t\t;copy into c\r\n\tres\t7,c\t\t;reset the sign bit\r\n2:\r\n\tbit\t7,l\t\t;test the MSB of the mantissa\r\n\tjr\tnz,3f\t\t;set, no more shifting required\r\n\tdec\tc\t\t;decrement exponent\r\n\tjp\tm,fpovrflw\t;underflow - set flag and return 0\r\n\tex\tde,hl\t\t;get low word in hl\r\n\tadd\thl,hl\t\t;shift left\r\n\tex\tde,hl\t\t;hi word back again\r\n\tadc\thl,hl\t\t;shift bit in\r\n\tjr\t2b\t\t;loop and test again\r\n\r\n3:\r\n\tbit\t7,b\t\t;test sign\r\n\tjr\tz,4f\t\t;skip if clear\r\n\tset\t7,c\t\t;set the new sign bit\r\n4:\r\n\tld\th,c\t\t;put exponent and sign back where it belongs\r\n\tret\t\t\t;finished\r\n\r\n;\tSet the floating overflow flag and return zero. Floating execptions\r\n;\tmay be caught in which case the appropriate routine will be called.\r\n\r\nfpovrflw:\r\n\tld\ta,1\r\n\tld\t(fperr),a\r\nfpzero:\r\n\tld\thl,0\r\n\tld\te,l\r\n\tld\td,h\r\n\tret\r\n\r\n;\tNegate the mantissa in LDE.\r\n\r\nnegmant:\r\n\tpush\thl\t\t;save hi byte and sign\r\n\tld\thl,0\r\n\tld\ta,l\t\t;zero a as well\r\n\tor\ta\t\t;reset carry\r\n\tsbc\thl,de\t\t;negate low word\r\n\tex\tde,hl\t\t;put back in de\r\n\tpop\thl\t\t;restore hi byte\r\n\tsbc\ta,l\t\t;negate the hi byte\r\n\tld\tl,a\t\t;put back\r\n\tret\t\t\t;and return\r\n\r\n;\tFloating subtraction. The value on the stack is subtracted from the\r\n;\tvalue in HLDE. To simplify matters, we do it thus:\r\n;\r\n;\tA-B == A+-B\r\n\r\nflsub:\r\n\tpop\tbc\t\t;return address\r\n\texx\t\t\t;get some other regs\r\n\tpop\tde\t\t;low word\r\n\tpop\thl\t\t;hi word\r\n\tld\ta,h\t\t;get sign/exponent\r\n\tor\ta\r\n\tjr\tz,1f\r\n\txor\t80h\t\t;toggle sign\r\n\tld\th,a\t\t;put back\r\n1:\r\n\tpush\thl\t\t;put back on stack\r\n\tpush\tde\r\n\texx\t\t\t;get other operand back\r\n\tpush\tbc\t\t;and return address\r\n\r\n\t;fall through to fladd\r\n\r\n\r\n;\tFloating addition:\r\n;\t\tAdd the value in HLDE to the value on the stack (under the\r\n;\t\treturn address, and return with the argument removed from\r\n;\t\tthe stack.\r\n\r\nfladd:\r\n\tld\ta,l\t\t;check 1st operand for zero\r\n\tor\td\r\n\tor\te\t\t;only need to check mantissa\r\n\texx\t\t\t;get some spare registers\r\n\tpop\tbc\t\t;return address\r\n\tpop\tde\t\t;low word of 2nd operand\r\n\tpop\thl\t\t;hi word\r\n\tpush\tbc\t\t;put return address back on stack\r\n\tret\tz\t\t;if 1st operand 0, just return 2nd\r\n\tld\ta,l\t\t;check for zero 2nd arg\r\n\tor\td\r\n\tor\te\t\t;if zero, just return the 1st operand\r\n\tld\ta,h\t\t;put exponent in a\r\n\texx\t\t\t;restore 1st operand\r\n\tret\tz\r\n\tres\t7,a\t\t;clear sign\r\n\tld\tc,h\t\t;get exponent\r\n\tres\t7,c\t\t;and clear sign\r\n\tsub\tc\t\t;find difference\r\n\tjr\tnc,1f\t\t;if negative,\r\n\texx\t\t\t; switch operands\r\n\tneg\t\t\t;and make it positive\r\n1:\r\n\tcp\t24\t\t;if less than 24 bits difference,\r\n\tjr\tc,2f\t\t;we can do the add\r\n\texx\t\t\t;otherwise just return the larger value\r\n\tret\r\n2:\r\n\tor\ta\t\t;check for zero difference\r\n\tcall\tnz,fpadjust\t;adjust till equal\r\n\tld\tc,h\t\t;save exponent of result\r\n\tbit\t7,h\t\t;test sign, do we need to negate?\r\n\tld\th,0\t\t;zero fill in case +ve\r\n\tjr\tz,1f\t\t;no\r\n\tcall\tnegmant\t\t;yes\r\n\tld\th,0ffh\t\t;1 fill top byte\r\n1:\r\n\tpush\tde\t\t;get low word\r\n\texx\t\t\t;select other bank\r\n\tbit\t7,h\t\t;test sign, do we need to negate?\r\n\tld\th,0\t\t;zero fill in case +ve\r\n\tjr\tz,1f\t\t;no\r\n\tcall\tnegmant\t\t;yes\r\n\tld\th,0ffh\t\t;1 fill top byte\r\n1:\r\n\tpop\tbc\t\t;get low word of other operand\r\n\tex\tde,hl\t\t;exchange hi/low\r\n\tadd\thl,bc\r\n\tex\tde,hl\t\t;restore\r\n\texx\t\t\t;get other bank again\r\n\tpush\thl\t\t;and hi word\r\n\tld\ta,c\t\t;and exponent\r\n\texx\r\n\tpop\tbc\r\n\tadc\thl,bc\t\t;add it in\r\n\tres\t7,a\t\t;clear sign from exponent\r\n\tjr\tc,hm3\r\n\tinc\th\r\n\tdec\th\t\t;zero in h?\r\n\tjr\tz,hm2\r\nhm3:\r\n\tsra\th\t\t;now shift down 1 bit to compensate\r\n\trr\tl\t\t;propogate the shift\r\n\trr\td\r\n\trr\te\r\n\tinc\ta\t\t;increment to compensate for shift above\r\nhm2:\r\n\tpush\taf\t\t;save carry flag\r\n\tld\tc,a\t\t;save exponent\r\n\tld\ta,h\r\n\tand\t80h\t\t;mask off low bits\r\n\tor\tc\t\t;or in exponent\r\n\tld\th,a\t\t;now have it!\r\n\tcall\tm,negmant\t;restore mantissa to positive if required\r\n\tpop\taf\t\t;restore carry flag\r\n\tcall\tc,round\t\t;round up if necessary\r\n\tjp\tfpnorm\t\t;normalize and return!!\r\n\r\n;\tRound the number in HLDE up by one, because of a shift of bits out\r\n;\tearlier\r\n\r\nround:\r\n\tld\tbc,1\t\t;add in 1 extra bit\r\n\tex\tde,hl\r\n\tadd\thl,bc\r\n\tex\tde,hl\r\n\tpush\thl\t\t;save exponent/sign\r\n\tld\th,0\r\n\tld\tc,h\r\n\tadc\thl,bc\t\t;add in carry\r\n\tpop\tbc\t\t;get exponent/sign back\r\n\tbit\t0,h\t\t;did it cause carry out of l?\r\n\tjr\tz,2f\r\n\tsrl\th\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\tld\ta,b\t\t;get exponent/sign\r\n\tand\t7fh\t\t;get exponent only\r\n\tinc\ta\t\t;add one\r\n\tld\tc,a\r\n\tld\ta,b\r\n\tand\t80h\r\n\tor\tc\t\t;now exponent and sign again\r\n\tld\tb,a\r\n2:\r\n\tld\th,b\t\t;restore sign/exponent\r\n\tret\r\n\r\n;\tAdjust the floating number in HLDE by increasing the exponent by the\r\n;\tcontents of A. The mantissa must be shifted right to compensate.\r\n\r\nfpadjust:\r\n\tand\t31\t\t;mask of hi bits - irrelevant\r\n\tld\tb,a\t\t;put in a suitable register for loop count\r\n1:\r\n\tsrl\tl\r\n\trr\td\r\n\trr\te\r\n\tinc\th\t\t;increment exponent - it will not overflow\r\n\tdjnz\t1b\t\t;loop if more\r\n\tret\t\t\t;finito\r\n\r\n;\tGet the right operand into HLDE', leave the left operand\r\n;\twhere it is in HLDE, but make both of them +ve. The original\r\n;\texponents/signs are left in C and B, left and right operands\r\n;\trespectively.\r\n\r\nfsetup:\r\n\tpop\tbc\t\t;top return address\r\n\texx\r\n\tpop\tbc\t\t;outer return address\r\n\tpop\tde\t\t;low word\r\n\tpop\thl\t\t;hi word of right operand\r\n\tpush\tbc\t\t;put return address back\r\n\tld\tc,h\t\t;get exponent\r\n\tres\t7,h\t\t;clear sign\r\n\tld\ta,c\t\t;exponent again\r\n\texx\r\n\tpush\tbc\t\t;inner return address\r\n\tld\tb,a\t\t;other exponent\r\n\tld\tc,h\t\t;this exponent\r\n\tres\t7,h\t\t;make positive\r\n\tret\r\n\r\n;\tFloating multiplication. The number in HLDE is multiplied by the\r\n;\tnumber on the stack under the return address. The stack is cleaned\r\n;\tup and the result returned in HLDE.\r\n\r\nflmul:\r\n\tcall\tfsetup\t\t;get operands, make them +ve.\r\n\tpush\tbc\t\t;save exponents etc.\r\n\tld\th,0\t\t;zero top byte\r\n\tpush\thl\t\t;push hi word\r\n\tld\thl,0\t\t;zero product\r\n\texx\r\n\tld\th,0\t\t;zero top byte\r\n\tpush\thl\t\t;push hi word\r\n\tpop\tbc\t\t;put it into bc\r\n\tpop\thl\t\t;hi word of multplicand\r\n\tex\tde,hl\t\t;get it into de\r\n\tpush\thl\t\t;low word of multiplier\r\n\tld\thl,0\t\t;zero product\r\n\texx\r\n\tpop\tbc\t\t;low word of multiplier\r\n\tld\ta,c\t\t;get low 8 bits of multiplier\r\n\tld\tc,b\t\t;save next 8 bits\r\n\tcall\tmult26\t\t;do 8 bits of multiply\r\n\tld\ta,c\r\n\tcall\tmult8\t\t;next 8 bits\r\n\texx\r\n\tld\ta,c\t\t;next 8 bits\r\n\texx\r\n\tcall\tmult8\t\t;do next chunk\r\n\texx\t\t\t;get hi words\r\n\tpush\thl\t\t;product hi word\r\n\texx\r\n\tpop\tde\r\n\tex\tde,hl\t\t;hi word in hl, lo in de\r\n\tld\ta,h\t\t;get hi byte\r\n\tld\th,0\r\n\tld\tc,h\t\t;zero lower byte\r\n\tjr\t1f\t\t;skip forward\r\n2:\r\n\tsrl\ta\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\trr\tc\t\t;save carry bit in c\r\n\tinc\th\r\n1:\r\n\tor\ta\t\t;hi byte zero yet?\r\n\tjr\tnz,2b\t\t;no, keep shifting down\r\n\tex\taf,af'\r\n\tld\ta,c\t\t;copy shifted-out bits\r\n\tex\taf,af'\r\n\tpop\tbc\t\t;get exponents\r\n\tbit\t7,l\t\t;check for zero mantissa\r\n\tjp\tz,fpzero\t;return a clean zero if so\r\n\tld\ta,c\r\n\tres\t7,a\t\t;mask off sign\r\n\tsub\t41h\t\t;remove bias, allow one bit shift\r\n\tadd\ta,h\t\t;add in shift count\r\n\tsub\t6\t\t;compensate for shift up earlier\r\n\tld\th,b\t\t;the other\r\n\tres\t7,h\t\t;mask off signs\r\n\tadd\ta,h\t\t;add them together\r\n\tjp\tm,fpovrflw\t;overflow in exponent\r\n\tld\th,a\t\t;put exponent in\r\n\tld\ta,c\t\t;now check signs\r\n\txor\tb\r\n\tjp\tp,1f\r\n\tset\t7,h\t\t;set sign flag\r\n1:\r\n\tex\taf,af'\r\n\trla\t\t\t;shift top bit out\r\n\tret\tnc\t\t;return if no carry\r\n\tjp\tround\t\t;round it\r\n\r\nmult26:\r\n\tld\tb,6\r\n3:\r\n\tsrl\ta\t\t;shift LSB of multiplier into carry\r\n\tjp\tnc,1f\r\n\tadd\thl,de\r\n\texx\r\n\tadc\thl,de\r\n\texx\r\n1:\r\n\tex\tde,hl\r\n\tadd\thl,hl\r\n\tex\tde,hl\r\n\texx\r\n\tex\tde,hl\r\n\tadc\thl,hl\r\n\tex\tde,hl\r\n\texx\t\t\t;shift multiplicand up one bit\r\n\tdjnz\t3b\t\t;more?\r\n\tld\tb,2\t\t;do remaining two bits\r\n\tjr\t4f\r\n\r\nmult8:\r\n\tld\tb,8\r\n3:\r\n\texx\r\n\tsrl\th\r\n\trr\tl\t\t;shift product down 1 bit\r\n\texx\r\n\trr\th\r\n\trr\tl\r\n4:\r\n\tsrl\ta\t\t;shift LSB into carry\r\n\tjp\tnc,1f\r\n\tadd\thl,de\r\n\texx\r\n\tadc\thl,de\r\n\texx\r\n1:\r\n\tdjnz\t3b\t\t;more?\r\n\tret\t\t\t;no, return as is\r\n\r\n\r\n;\tFloating division. The number in HLDE is divided by the\r\n;\tnumber on the stack under the return address. The stack is cleaned\r\n;\tup and the result returned in HLDE.\r\n\r\nfldiv:\r\n\tcall\tfsetup\t\t;get operands, make them +ve.\r\n\tpush\tbc\t\t;save exponents etc.\r\n\tld\th,0\t\t;zero top byte of dividend\r\n\tpush\tde\t\t;push lo word\r\n\tld\tbc,0\t\t;zero quotient\r\n\texx\r\n\tld\th,0\t\t;zero top byte of divisor\r\n\tex\t(sp),hl\t\t;get lo word of dividend into hl\r\n\tld\tbc,0\t\t;zero low word of quotient\r\n\texx\r\n\tpop\tde\t\t;hi word of divisor\r\n\tld\ta,24+6\t\t;number of bits in dividend and then some\r\n\r\n3:\r\n\tpush\thl\t\t;save dividend\r\n\texx\r\n\tpush\thl\t\t;low word\r\n\tor\ta\t\t;reset carry\r\n\tsbc\thl,de\t\t;try a subtraction\r\n\texx\r\n\tsbc\thl,de\t\t;now the hi word\r\n\texx\r\n\tjr\tnc,4f\t\t;skip if no carry\r\n\tpop\thl\t\t;restore dividend\r\n\texx\r\n\tpop\thl\r\n\texx\r\n\tjr\t5f\r\n\r\n4:\r\n\tinc\tsp\t\t;unjunk stack\r\n\tinc\tsp\r\n\tinc\tsp\r\n\tinc\tsp\r\n\r\n5:\r\n\tccf\t\t\t;complement carry bit\r\n\trl\tc\t\t;shift into quotient\r\n\trl\tb\r\n\texx\r\n\trl\tc\r\n\trl\tb\r\n\texx\t\t\t;low words again\r\n\tadd\thl,hl\t\t;shift dividend left\r\n\texx\r\n\tadc\thl,hl\t\t;upper shift\r\n\tdec\ta\t\t;decrement loop count\r\n\tjr\tnz,3b\r\n\r\n\texx\r\n\tpush\tbc\t\t;get low word of quotient\r\n\texx\r\n\tpop\tde\r\n\tpush\tbc\t\t;hi word\r\n\tpop\thl\r\n\tld\ta,h\t\t;get hi byte\r\n\tld\th,0\r\n\tld\tc,h\t\t;zero lower byte\r\n\tjr\t1f\t\t;skip forward\r\n2:\r\n\tsrl\ta\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\trr\tc\t\t;save carry bit in c\r\n\tinc\th\r\n1:\r\n\tor\ta\t\t;hi byte zero yet?\r\n\tjr\tnz,2b\t\t;no, keep shifting down\r\n\tex\taf,af'\r\n\tld\ta,c\t\t;copy shifted-out bits\r\n\tex\taf,af'\r\n\tpop\tbc\t\t;restore exponents\r\n\tpush\tbc\t\t;save signs\r\n\tld\ta,c\r\n\tres\t7,a\r\n\tres\t7,b\r\n\tsub\tb\r\n\tadd\ta,41h-6\t\t;compensate\r\n\tadd\ta,h\r\n\tld\th,a\r\n\tpop\tbc\r\n    jp  m,fpovrflw  ;PMO catch under/overflow\r\n\tld\ta,c\r\n\txor\tb\t\t;get sign\r\n\tjp\tp,1f\r\n\tset\t7,h\r\n1:\t\r\n\tex\taf,af'\t\t;get shifted out bit back again\r\n\trla\r\n\tcall\tc,round\t\t;round if necessary\r\n\tjp\tfpnorm\t\t;normalize it and return\r\n\r\n\tpsect\tbss\r\n\r\nfperr:\r\n\tdefs\t1\t\t;floating over/underflow flag\r\n"
  },
  {
    "path": "float/FLOOR.C",
    "content": "#include\t<math.h>\r\n\r\nextern double\t_frndint();\r\n\r\ndouble\r\nfloor(x)\r\ndouble\tx;\r\n{\r\n\tdouble\ti;\r\n\r\n\ti = _frndint(x);\r\n\tif(i > x)\r\n\t\treturn i - 1.0;\r\n\treturn i;\r\n}\r\n"
  },
  {
    "path": "float/FNUM.C",
    "content": "/*\r\n *\t_fnum() - converts floating numbers to ascii decimal\r\n *\trepresentations.\r\n */\r\n\r\n\r\n#define\tuchar\tunsigned char\r\n#define\tputc(c)\t(*pputc)(c)\r\n#define\tbuf\t(xbuf+2)\r\n\r\nextern double\t_frndint();\r\nextern int\tstrlen(char *);\r\nextern int\tabs(int);\r\n\r\n_fnum(val, prec, width, efmt, pputc)\r\ndouble\tval;\r\nchar\twidth, prec, efmt;\r\nvoid (*\tpputc)();\r\n{\r\n\tregister char *\tcp, * xp;\r\n\tint\t\texp;\r\n\tchar\t\tdigs;\r\n\tshort\t\ttwid;\r\n\tuchar\t\tsign;\r\n\tchar\t\txbuf[60];\r\n\r\n\tif(prec < 0)\r\n\t\tprec = 6;\r\n\ttwid = 0;\r\n\tif(val < 0.0) {\r\n\t\tval = -val;\r\n\t\tsign = 1;\r\n\t} else\r\n\t\tsign = 0;\r\n\texp = 0;\r\n/*\r\n\tif(efmt == 0 && prec == 0)\r\n\t\tval = _frndint(val);\t\t/* round to integer */\r\n\t_fbcd(val, &exp, buf);\r\n\tcp = buf;\r\n\twhile(*cp == '0')\r\n\t\tcp++;\r\n\tif(*cp == 0)\t\t/* all zero */\r\n\t\tcp--;\r\n\tif(strlen(cp) > 1) {\r\n\t\txp = cp+strlen(cp)-1;\r\n\t\twhile(*xp == '0') {\t\t\t/* remove traiing zeros */\r\n\t\t\t*xp-- = 0;\r\n\t\t\texp++;\r\n\t\t}\r\n\t} else if(*cp == '0')\r\n\t\texp = 0;\r\n\tcp[-1] = '0';\r\n\tdigs = strlen(cp);\t/* number of significant digits */\r\n\tif(efmt == 0 && prec == 0 || efmt == 1 && exp >= 0 && exp <= 5+prec) {\r\n\t\t/* use d format */\r\n\t\tif(exp  < 0) {\t/* too much precision */\r\n\t\t\tchar\tc;\r\n\t\r\n\t\t\txp = cp+digs+exp;\r\n\t\t\tc = *xp;\r\n\t\t\t*xp = 0;\r\n\t\t\tif(c >= '5')\r\n\t\t\t\tfor(;;)\r\n\t\t\t\t\tif((*--xp += 1) == '9'+1)\r\n\t\t\t\t\t\t*xp = '0';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tbreak;\r\n\t\t\tif(xp < cp)\r\n\t\t\t\tcp = xp;\r\n\t\t\tdigs = strlen(cp);\r\n\t\t\texp = 0;\r\n\t\t}\r\n\t\twidth -= (twid = digs + exp + sign);\r\n\t\twhile(width > 0) {\r\n\t\t\tputc(' ');\r\n\t\t\twidth--;\r\n\t\t\ttwid++;\r\n\t\t}\r\n\t\tif(sign)\r\n\t\t\tputc('-');\r\n\t\twhile(*cp)\r\n\t\t\tputc(*cp++);\r\n\t\twhile(exp > 0) {\r\n\t\t\tputc('0');\r\n\t\t\texp--;\r\n\t\t}\r\n\t\treturn twid;\r\n\t}\r\n\tif(efmt == 1 && exp >= 5 || exp + digs < -4)\r\n\t\tefmt++;\r\n\tif(efmt >= 2) {\t\t/* use e format */\r\n\t\twidth -= (twid = sign + prec + 6);\r\n\t\tif(digs > prec+1) {\t/* need to round it */\r\n\t\t\tchar\tc;\r\nloop:\r\n\t\t\txp = cp+prec+1;\r\n\t\t\texp += digs-(prec+1);\r\n\t\t\tc = *xp;\r\n\t\t\t*xp = 0;\r\n\t\t\tif(c >= '5')\r\n\t\t\t\tfor(;;)\r\n\t\t\t\t\tif((*--xp += 1) == '9'+1)\r\n\t\t\t\t\t\t*xp = '0';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tbreak;\r\n\t\t\tif(xp < cp)\r\n\t\t\t\tcp = xp;\r\n\t\t\tdigs = strlen(cp);\r\n\t\t\tif(digs > prec+1)\r\n\t\t\t\tgoto loop;\r\n\t\t}\r\n\t\texp += digs - 1;\t\t/* allow for moving dec. pt. */\r\n\t\tif(abs(exp) >= 100)\t\t/* 3 digit exponent */\r\n\t\t\twidth--;\r\n\t\tprec -= digs - 1;\r\n\t\twhile(width > 0) {\r\n\t\t\tputc(' ');\r\n\t\t\twidth--;\r\n\t\t\ttwid++;\r\n\t\t}\r\n\t\tif(sign)\r\n\t\t\tputc('-');\r\n\t\tputc(*cp++);\r\n\t\tputc('.');\r\n\t\twhile(*cp)\r\n\t\t\tputc(*cp++);\r\n\t\twhile(prec > 0) {\r\n\t\t\tputc('0');\r\n\t\t\tprec--;\r\n\t\t}\r\n\t\tputc('e');\r\n\t\tif(exp < 0) {\r\n\t\t\texp = -exp;\r\n\t\t\tputc('-');\r\n\t\t} else\r\n\t\t\tputc('+');\r\n\t\tif(exp >= 100) {\r\n\t\t\tputc(exp / 100 + '0');\r\n\t\t\texp %= 100;\r\n\t\t}\r\n\t\tputc(exp / 10 + '0');\r\n\t\tputc(exp % 10 + '0');\r\n\t\treturn twid;\r\n\t}\r\n\t/* here for f format */\r\n\tif(exp + prec < 0) {\t/* too much precision */\r\n\t\tchar\tc;\r\n\r\n\t\txp = cp+digs+exp+prec;\r\n\t\tc = *xp;\r\n\t\t*xp = 0;\r\n\t\tif(c >= '5')\r\n\t\t\tfor(;;)\r\n\t\t\t\tif((*--xp += 1) == '9'+1)\r\n\t\t\t\t\t*xp = '0';\r\n\t\t\t\telse\r\n\t\t\t\t\tbreak;\r\n\t\tif(xp < cp)\r\n\t\t\tcp = xp;\r\n\t\tdigs = strlen(cp);\r\n\t\texp = -prec;\r\n\t}\r\n\tprec += exp;\r\n\ttwid = 1 + prec + sign + digs;\r\n\tdigs = -digs;\r\n\tif(exp <= digs)\r\n\t\ttwid += digs - exp + 1;\r\n\twidth -= twid;\r\n\twhile(width > 0) {\r\n\t\tputc(' ');\r\n\t\twidth--;\r\n\t}\r\n\tif(sign)\r\n\t\tputc('-');\r\n\tif(exp <= digs) {\r\n\t\tputc('0');\r\n\t\tputc('.');\r\n\t\twhile(exp < digs) {\r\n\t\t\tputc('0');\r\n\t\t\texp++;\r\n\t\t}\r\n\t}\r\n\twhile(*cp) {\r\n\t\tputc(*cp++);\r\n\t\tif(++digs == exp)\r\n\t\t\tputc('.');\r\n\t}\r\n\twhile(exp > 0) {\r\n\t\tputc('0');\r\n\t\tprec--;\r\n\t\tif(--exp == 0)\r\n\t\t\tputc('.');\r\n\t}\r\n\twhile(prec > 0) {\r\n\t\tputc('0');\r\n\t\tprec--;\r\n\t}\r\n\treturn twid;\r\n}\r\n"
  },
  {
    "path": "float/FPRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern int\t_doprnt();\r\n\r\nfprintf(file, f, a)\r\nFILE *\tfile;\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\treturn(_doprnt(file, f, &a));\r\n}\r\n"
  },
  {
    "path": "float/FREXP.AS",
    "content": ";\tThese functions allow the mantissa and exponent of floating\r\n;\tnumbers to be manipulate separately.\r\n\r\n\r\n\tpsect\ttext\r\n\tglobal\t_frexp, _ldexp\r\n\r\n;\tdouble frexp(value, eptr)\r\n;\tdouble value;\r\n;\tint *  eptr;\r\n\r\n_frexp:\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\r\n\tld\ta,(ix+7)\t\t;get old exponent\r\n\tld\tb,a\t\t\t;save sign bit\r\n\tand\t80h\t\t\t;mask it out\r\n\tadd\ta,64\t\t\t;add in bias\r\n\tld\td,a\t\t\t;store new exponent back\r\n\tld\ta,b\t\t\t;now get exponent\r\n\tand\t7Fh\t\t\t;clea sign bit\r\n\tsub\t64\t\t\t;remove bias\r\n\tld\tl,(ix+8)\t\t;get pointer\r\n\tld\th,(ix+9)\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\trla\r\n\tsbc\ta,a\r\n\tld\t(hl),a\t\t\t;store upper byte\r\n\tld\tl,(ix+4)\t\t;now get value to return\r\n\tld\th,(ix+5)\r\n\tld\te,(ix+6)\r\n\tex\tde,hl\t\t\t;already have sign in d\r\n\tpop\tix\r\n\tret\r\n\r\n_ldexp:\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\r\n\tld\ta,(ix+8)\r\n\tand\t7Fh\r\n\tld\tc,a\r\n\tld\ta,(ix+7)\r\n\tld\th,a\r\n\tand\t80h\r\n\tld\tb,a\r\n\tld\ta,h\r\n\tadd\ta,c\r\n\tand\t7Fh\r\n\tor\tb\r\n\tld\th,a\r\n\tld\tl,(ix+6)\r\n\tld\td,(ix+5)\r\n\tld\te,(ix+4)\r\n\tpop\tix\r\n\tret\r\n"
  },
  {
    "path": "float/FRNDINT.AS",
    "content": "\tpsect\ttext\r\n\r\n;\tdouble\tfrndint(val)\r\n;\tdouble\tval;\r\n\r\n;\tRound the argument to an integral value, return as a double\r\n\r\n\tglobal\t__frndint, altof, ftol\r\n\r\n__frndint:\r\n\tpop\tbc\t;return addr\r\n\tpop\tde\r\n\tpop\thl\t;float val\r\n\tpush\thl\r\n\tpush\tde\r\n\tpush\tbc\r\n\tcall\tftol\r\n\tjp\taltof\r\n"
  },
  {
    "path": "float/FSCANF.C",
    "content": "/*\r\n *\tStdio fscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\nextern int\t_doscan();\r\n\r\nfscanf(file, fmt, args)\r\nFILE *\tfile;\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\treturn _doscan(file, fmt, &args);\r\n}\r\n"
  },
  {
    "path": "float/FTOL.AS",
    "content": ";\tftol - convert floating to long, by using lower bits can also\r\n;\tbe used to convert from float to int or char\r\n\r\n\tpsect\ttext\r\n\tglobal\tftol\r\n\tglobal\talrsh, allsh, negmant\r\n\r\nftol:\r\n\tbit\t7,h\t\t;test sign\r\n\tcall\tnz,negmant\t;negate mantissa if required\r\n\tld\ta,h\t\t;get exponent\r\n\tres\t7,a\t\t;mask sign off\r\n\tsub\t64+24\t\t;remove offset\r\n\tld\tb,a\t\t;save shift count\r\n\tld\ta,h\t\t;get exponent, sign\r\n\trla\r\n\tsbc\ta,a\t\t;sign extend\r\n\tld\th,a\t\t;put back\r\n\tbit\t7,b\t\t;test sign\r\n\tjp\tz,allsh\t\t;shift it left\r\n\tld\ta,b\t\t;get the count\r\n\tneg\t\t\t;make +ve\r\n\tdec\ta\t\t;and reduce it one\r\n\tld\tb,a\t\t;put back in b\r\n\tcall\tnz,alrsh\t;shift right\r\n\tex\tde,hl\r\n\tld\tbc,1\t\t;add one for rounding\r\n\tadd\thl,bc\r\n\tld\tb,c\r\n\tex\tde,hl\r\n\tjp\tnc,alrsh\t;and shift down one more\r\n\tinc\thl\t\t;add in carry first\r\n\tjp\talrsh\r\n"
  },
  {
    "path": "float/LIBFVER.C",
    "content": "#include <stdio.h>\r\n\r\nchar *_libfver =\r\n#ifdef Z280\r\n \"LIB280F \" _HTC_VERSION;\r\n#else\r\n \"LIBF \" _HTC_VERSION;\r\n#endif\r\n"
  },
  {
    "path": "float/LOG.C",
    "content": "#include\t<math.h>\r\n\r\nextern double\teval_poly();\r\ndouble\r\nlog(x)\r\ndouble\tx;\r\n{\r\n\tint\texp;\r\n\r\n\tstatic /* const */ double coeff[] =\r\n\t{\r\n\t\t 0.0000000000,\t/* a0 */\r\n\t\t 0.9999964239,\t/* a1 */\r\n\t\t-0.4998741238,\t/* a2 */\r\n\t\t 0.3317990258,\t/* a3 */\r\n\t\t-0.2407338084,\t/* a4 */\r\n\t\t 0.1676540711,\t/* a5 */\r\n\t\t-0.0953293897,\t/* a6 */\r\n\t\t 0.0360884937,\t/* a7 */\r\n\t\t-0.0064535442,\t/* a8 */\r\n\t};\r\n\r\n\t/* zero or -ve arguments are not defined */\r\n\r\n\tif(x <= 0.0)\r\n\t\treturn 0.0;\r\n\tx = frexp(x, &exp) * 2.0 - 1.0;\r\n\texp--;\r\n\tx = eval_poly(x, coeff, sizeof coeff/sizeof coeff[0] - 1);\r\n\treturn x + 0.69314718055995 * exp;\r\n}\r\n\r\ndouble\r\nlog10(x)\r\ndouble\tx;\r\n{\r\n\treturn log(x) * 0.4342944819;\r\n}\r\n"
  },
  {
    "path": "float/LTOF.AS",
    "content": ";\tConversion of integer type things to floating. Uses routines out\r\n;\tof float.as.\r\n\r\n\tpsect\ttext\r\n\r\n\tglobal\taltof, lltof, aitof, litof, abtof, lbtof\r\n\tglobal\tfpnorm\r\n\r\nlbtof:\r\n\tld\tl,a\r\n\tld\th,0\r\nlitof:\r\n\tex\tde,hl\t\t;put arg in de\r\n\tld\tl,0\t\t;zero top byte\r\nb3tof:\r\n\tld\th,64+24\r\n\tjp\tfpnorm\r\n\r\nabtof:\r\n\tld\tl,a\r\n\trla\r\n\tsbc\ta,a\r\n\tld\th,a\r\n\r\naitof:\r\n\tbit\t7,h\t\t;negative?\r\n\tjp\tz,litof\t\t;no, treat as unsigned\r\n\tex\tde,hl\r\n\tld\thl,0\r\n\tor\ta\r\n\tsbc\thl,de\t\t;negate it\r\n\tcall\tlitof\r\n\tset\t7,h\t\t;set sign flag\r\n\tret\r\n\r\nlltof:\r\n\tld\ta,h\t\t;anything in top byte?\r\n\tor\ta\r\n\tjr\tz,b3tof\t\t;no, just do 3 bytes\r\n\tld\tc,0\r\n;\tDo it the hard way\r\nslop:\r\n\tld\ta,h\r\n\tcp\t1\t\t;last shift coming up?\r\n\tjr\tz,slop2\r\n\tsrl\th\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\tinc\tc\r\n\tjr\tslop\r\nslop2:\r\n\tinc\te\r\n\tjr\tnz,slop3\r\n\tinc\td\r\n\tjr\tnz,slop3\r\n\tinc\tl\r\n\tjr\tnz,slop3\r\n\tinc\th\r\nslop3:\r\n\tsrl\th\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\tld\ta,h\r\n\tor\ta\r\n\tjr\tz,slop4\r\n\tsrl\th\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\tinc\tc\r\nslop4:\r\n\tld\ta,c\r\n\tadd\ta,64+25\r\n\tld\th,a\r\n\tjp\tfpnorm\t\t;and normalize it\r\n\r\naltof:\r\n\tbit\t7,h\t\t;negative?\r\n\tjr\tz,lltof\t\t;no, treat as unsigned\r\n\tpush\thl\t\t;negate it now\r\n\tld\thl,0\r\n\tor\ta\r\n\tsbc\thl,de\r\n\tex\tde,hl\r\n\tpop\tbc\r\n\tld\thl,0\r\n\tsbc\thl,bc\r\n\tcall\tlltof\r\n\tset\t7,h\t\t;set sign flag\r\n\tret\r\n"
  },
  {
    "path": "float/M280LIBF.LOG",
    "content": "\r\n10D>date\r\nA:DATE     COM  (User 0)\r\n\rMon 01/09/2025 13:28:32\r\n10D>;----------  M280LIBF.SUB  ----------\r\n10D>; Assumes DEHUFF -X FLOAT.HUF has extracted\r\n10D>; all sources to the default drive\r\n10D>;------------------------------------\r\n10D>m:\r\n10M>era m:*.obj\r\nERASE M:*.OBJ (Y/N)? Y\r\n10M>;\r\n10M>c280\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -v -c -o2 \\\r\nc> d:LIBFVER.C \\\r\nc> d:PRINTF.C \\\r\nc> d:FPRINTF.C \\\r\nc> d:SPRINTF.C \\\r\nc> d:SCANF.C \\\r\nc> d:FSCANF.C \\\r\nc> d:SSCANF.C \\\r\nc> d:DOPRNT.C \\\r\nc> d:DOSCAN.C \\\r\nc> d:ATOF.C \\\r\nc> d:FNUM.C \\\r\nc> d:FBCD.AS \\\r\nc> d:TAN.C \\\r\nc> d:ACOS.C \\\r\nc> d:ASIN.C \\\r\nc> d:ATAN2.C \\\r\nc> d:ATAN.C \\\r\nc> d:COS.C \\\r\nc> d:SIN.C \\\r\nc> d:SINH.C \\\r\nc> d:COSH.C \\\r\nc> d:TANH.C \\\r\nc> d:EXP.C \\\r\nc> d:LOG.C \\\r\nc> d:EVALPOLY.C \\\r\nc> d:SQRT.C \\\r\nc> d:FREXP.AS \\\r\nc> d:FABS.C \\\r\nc> d:CEIL.C \\\r\nc> d:FLOOR.C \\\r\nc> d:FINC.AS \\\r\nc> d:ASFLOAT.AS \\\r\nc> d:FRNDINT.AS \\\r\nc> d:FTOL.AS \\\r\nc> d:LTOF.AS \\\r\nc> d:FLOAT.AS\r\nD:LIBFVER.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:LIBFVER.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OLIBFVER.OBJ $CTMP5.$$$\r\nD:PRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:PRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 5 bytes size optimised away\r\n 6 bytes replaced\r\n0:A:ZAS -J -N -OPRINTF.OBJ $CTMP5.$$$\r\nD:FPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:FPRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 7 bytes size optimised away\r\n 10 bytes replaced\r\n0:A:ZAS -J -N -OFPRINTF.OBJ $CTMP5.$$$\r\nD:SPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:SPRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -OSPRINTF.OBJ $CTMP5.$$$\r\nD:SCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:SCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 5 bytes size optimised away\r\n 6 bytes replaced\r\n0:A:ZAS -J -N -OSCANF.OBJ $CTMP5.$$$\r\nD:FSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:FSCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 7 bytes size optimised away\r\n 10 bytes replaced\r\n0:A:ZAS -J -N -OFSCANF.OBJ $CTMP5.$$$\r\nD:SSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:SSCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 18 bytes size optimised away\r\n 28 bytes replaced\r\n0:A:ZAS -J -N -OSSCANF.OBJ $CTMP5.$$$\r\nD:DOPRNT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:DOPRNT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 51 bytes size optimised away\r\n 122 bytes replaced\r\n0:A:ZAS -J -N -ODOPRNT.OBJ $CTMP5.$$$\r\nD:DOSCAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:DOSCAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 201 bytes size optimised away\r\n 410 bytes replaced\r\n0:A:ZAS -J -N -ODOSCAN.OBJ $CTMP5.$$$\r\nD:ATOF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:ATOF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 92 bytes size optimised away\r\n 185 bytes replaced\r\n0:A:ZAS -J -N -OATOF.OBJ $CTMP5.$$$\r\nD:FNUM.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:FNUM.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 187 bytes size optimised away\r\n 420 bytes replaced\r\n0:A:ZAS -J -N -OFNUM.OBJ $CTMP5.$$$\r\nD:FBCD.AS\r\n0:A:OPTIMH D:FBCD.AS $CTMP5.$$$\r\n 5 bytes size optimised away\r\n 10 bytes replaced\r\n0:A:ZAS -J -OFBCD.OBJ $CTMP5.$$$\r\nD:TAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:TAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 8 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -OTAN.OBJ $CTMP5.$$$\r\nD:ACOS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:ACOS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 4 bytes size optimised away\r\n 8 bytes replaced\r\n0:A:ZAS -J -N -OACOS.OBJ $CTMP5.$$$\r\nD:ASIN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:ASIN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 40 bytes size optimised away\r\n 80 bytes replaced\r\n0:A:ZAS -J -N -OASIN.OBJ $CTMP5.$$$\r\nD:ATAN2.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:ATAN2.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 45 bytes size optimised away\r\n 108 bytes replaced\r\n0:A:ZAS -J -N -OATAN2.OBJ $CTMP5.$$$\r\nD:ATAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:ATAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 55 bytes size optimised away\r\n 106 bytes replaced\r\n0:A:ZAS -J -N -OATAN.OBJ $CTMP5.$$$\r\nD:COS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:COS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 12 bytes size optimised away\r\n 24 bytes replaced\r\n0:A:ZAS -J -N -OCOS.OBJ $CTMP5.$$$\r\nD:SIN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:SIN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 57 bytes size optimised away\r\n 102 bytes replaced\r\n0:A:ZAS -J -N -OSIN.OBJ $CTMP5.$$$\r\nD:SINH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:SINH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 16 bytes size optimised away\r\n 32 bytes replaced\r\n0:A:ZAS -J -N -OSINH.OBJ $CTMP5.$$$\r\nD:COSH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:COSH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 12 bytes size optimised away\r\n 24 bytes replaced\r\n0:A:ZAS -J -N -OCOSH.OBJ $CTMP5.$$$\r\nD:TANH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:TANH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 16 bytes size optimised away\r\n 32 bytes replaced\r\n0:A:ZAS -J -N -OTANH.OBJ $CTMP5.$$$\r\nD:EXP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:EXP.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 70 bytes size optimised away\r\n 132 bytes replaced\r\n0:A:ZAS -J -N -OEXP.OBJ $CTMP5.$$$\r\nD:LOG.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:LOG.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 27 bytes size optimised away\r\n 60 bytes replaced\r\n0:A:ZAS -J -N -OLOG.OBJ $CTMP5.$$$\r\nD:EVALPOLY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:EVALPOLY.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 32 bytes size optimised away\r\n 68 bytes replaced\r\n0:A:ZAS -J -N -OEVALPOLY.OBJ $CTMP5.$$$\r\nD:SQRT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:SQRT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 95 bytes size optimised away\r\n 186 bytes replaced\r\n0:A:ZAS -J -N -OSQRT.OBJ $CTMP5.$$$\r\nD:FREXP.AS\r\n0:A:OPTIMH D:FREXP.AS $CTMP5.$$$\r\n 4 bytes size optimised away\r\n 8 bytes replaced\r\n0:A:ZAS -J -OFREXP.OBJ $CTMP5.$$$\r\nD:FABS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:FABS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 8 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -OFABS.OBJ $CTMP5.$$$\r\nD:CEIL.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:CEIL.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 24 bytes size optimised away\r\n 48 bytes replaced\r\n0:A:ZAS -J -N -OCEIL.OBJ $CTMP5.$$$\r\nD:FLOOR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: D:FLOOR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 20 bytes size optimised away\r\n 40 bytes replaced\r\n0:A:ZAS -J -N -OFLOOR.OBJ $CTMP5.$$$\r\nD:FINC.AS\r\n0:A:OPTIMH D:FINC.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 8 bytes replaced\r\n0:A:ZAS -J -OFINC.OBJ $CTMP5.$$$\r\nD:ASFLOAT.AS\r\n0:A:OPTIMH D:ASFLOAT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASFLOAT.OBJ $CTMP5.$$$\r\nD:FRNDINT.AS\r\n0:A:OPTIMH D:FRNDINT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OFRNDINT.OBJ $CTMP5.$$$\r\nD:FTOL.AS\r\n0:A:OPTIMH D:FTOL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OFTOL.OBJ $CTMP5.$$$\r\nD:LTOF.AS\r\n0:A:OPTIMH D:LTOF.AS $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OLTOF.OBJ $CTMP5.$$$\r\nD:FLOAT.AS\r\n0:A:OPTIMH D:FLOAT.AS $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OFLOAT.OBJ $CTMP5.$$$\r\nERA $CTMP1.$$$\r\nERA $CTMP2.$$$\r\nERA $CTMP3.$$$\r\nERA $CTMP5.$$$\r\nERA $$EXEC.$$$\r\n\r\n10M>;\r\n10M>era m:lib280f.lib\r\nNo File\r\n10M>;\r\n10M>LIBR\r\nA:LIBR     COM  (User 0)\r\nlibr> R m:lib280f.LIB \\\r\nlibr> LIBFVER.OBJ \\\r\nlibr> PRINTF.OBJ \\\r\nlibr> FPRINTF.OBJ \\\r\nlibr> SPRINTF.OBJ \\\r\nlibr> SCANF.OBJ \\\r\nlibr> FSCANF.OBJ \\\r\nlibr> SSCANF.OBJ \\\r\nlibr> DOPRNT.OBJ \\\r\nlibr> DOSCAN.OBJ \\\r\nlibr> ATOF.OBJ \\\r\nlibr> FNUM.OBJ \\\r\nlibr> FBCD.OBJ \\\r\nlibr> TAN.OBJ \\\r\nlibr> ACOS.OBJ \\\r\nlibr> ASIN.OBJ \\\r\nlibr> ATAN2.OBJ \\\r\nlibr> ATAN.OBJ \\\r\nlibr> COS.OBJ \\\r\nlibr> SIN.OBJ \\\r\nlibr> SINH.OBJ \\\r\nlibr> COSH.OBJ \\\r\nlibr> TANH.OBJ \\\r\nlibr> EXP.OBJ \\\r\nlibr> LOG.OBJ \\\r\nlibr> EVALPOLY.OBJ \\\r\nlibr> SQRT.OBJ \\\r\nlibr> FREXP.OBJ \\\r\nlibr> FABS.OBJ \\\r\nlibr> CEIL.OBJ \\\r\nlibr> FLOOR.OBJ \\\r\nlibr> FINC.OBJ \\\r\nlibr> ASFLOAT.OBJ \\\r\nlibr> FRNDINT.OBJ \\\r\nlibr> FTOL.OBJ \\\r\nlibr> LTOF.OBJ \\\r\nlibr> FLOAT.OBJ\r\n\r\n10M>;\r\n10M>pip d:=m:lib280f.lib\r\nA:PIP      COM  (User 0)\r\n\r\n10M>;\r\n10M>dir m:*.obj[fu,length=65535]\r\nA:DIR      COM  (User 0)\r\n\r\nScanning Directory...\r\n\r\nSorting  Directory...\r\n\r\nDirectory For Drive M:  User 10\r\n\r\n    Name     Bytes   Recs   Attributes   Prot      Update          Create    \r\n------------ ------ ------ ------------ ------ --------------  --------------\r\n\r\nACOS     OBJ     4k      3 Dir RW       None   01/09/25 13:32  01/09/25 13:32\r\nASFLOAT  OBJ     4k      3 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nASIN     OBJ     4k      8 Dir RW       None   01/09/25 13:32  01/09/25 13:32\r\nATAN     OBJ     4k      8 Dir RW       None   01/09/25 13:33  01/09/25 13:33\r\nATAN2    OBJ     4k      8 Dir RW       None   01/09/25 13:33  01/09/25 13:33\r\nATOF     OBJ     4k     10 Dir RW       None   01/09/25 13:31  01/09/25 13:31\r\nCEIL     OBJ     4k      3 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nCOS      OBJ     4k      5 Dir RW       None   01/09/25 13:33  01/09/25 13:33\r\nCOSH     OBJ     4k      3 Dir RW       None   01/09/25 13:34  01/09/25 13:34\r\nDOPRNT   OBJ     4k     20 Dir RW       None   01/09/25 13:30  01/09/25 13:30\r\nDOSCAN   OBJ     4k     31 Dir RW       None   01/09/25 13:31  01/09/25 13:31\r\nEVALPOLY OBJ     4k      3 Dir RW       None   01/09/25 13:34  01/09/25 13:34\r\nEXP      OBJ     4k     13 Dir RW       None   01/09/25 13:34  01/09/25 13:34\r\nFABS     OBJ     4k      3 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nFBCD     OBJ     4k      6 Dir RW       None   01/09/25 13:32  01/09/25 13:32\r\nFINC     OBJ     4k      2 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nFLOAT    OBJ     4k      9 Dir RW       None   01/09/25 13:36  01/09/25 13:36\r\nFLOOR    OBJ     4k      3 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nFNUM     OBJ     4k     29 Dir RW       None   01/09/25 13:32  01/09/25 13:32\r\nFPRINTF  OBJ     4k      2 Dir RW       None   01/09/25 13:29  01/09/25 13:29\r\nFREXP    OBJ     4k      2 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nFRNDINT  OBJ     4k      1 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nFSCANF   OBJ     4k      2 Dir RW       None   01/09/25 13:29  01/09/25 13:29\r\nFTOL     OBJ     4k      2 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nLIBFVER  OBJ     4k      1 Dir RW       None   01/09/25 13:28  01/09/25 13:28\r\nLOG      OBJ     4k      7 Dir RW       None   01/09/25 13:34  01/09/25 13:34\r\nLTOF     OBJ     4k      4 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nPRINTF   OBJ     4k      2 Dir RW       None   01/09/25 13:28  01/09/25 13:28\r\nSCANF    OBJ     4k      2 Dir RW       None   01/09/25 13:29  01/09/25 13:29\r\nSIN      OBJ     4k     10 Dir RW       None   01/09/25 13:33  01/09/25 13:33\r\nSINH     OBJ     4k      3 Dir RW       None   01/09/25 13:33  01/09/25 13:33\r\nSPRINTF  OBJ     4k      3 Dir RW       None   01/09/25 13:29  01/09/25 13:29\r\nSQRT     OBJ     4k      9 Dir RW       None   01/09/25 13:35  01/09/25 13:35\r\nSSCANF   OBJ     4k      2 Dir RW       None   01/09/25 13:29  01/09/25 13:29\r\nTAN      OBJ     4k      2 Dir RW       None   01/09/25 13:32  01/09/25 13:32\r\nTANH     OBJ     4k      4 Dir RW       None   01/09/25 13:34  01/09/25 13:34\r\n\r\nTotal Bytes     =    144k  Total Records =     228  Files Found =   36\r\nTotal 1k Blocks =     49   Used/Max Dir Entries For Drive M:  101/ 512\r\n\r\n10M>era d:libf2obj.lbr\r\n10M>nulu d:libf2obj.lbr -a m:*.obj -x\r\nA:NULU     COM  (User 0)\r\n^Z\rNULU 1.52  (07/12/87)\r\nCopyright (C) 1984, 1985 & 1987 by Martin Murray\r\nBug fixes in version 1.52 by Mick Waters\r\n\r\nTYPE -H FOR HELP\r\n\r\n\r\nSYSIN58 .$$$ | STDIO   .I   | LIB280F .LIB | LIBFVER .OBJ | PRINTF  .OBJ\r\nFPRINTF .OBJ | SPRINTF .OBJ | SCANF   .OBJ | FSCANF  .OBJ | SSCANF  .OBJ\r\nDOPRNT  .OBJ | DOSCAN  .OBJ | ATOF    .OBJ | FNUM    .OBJ | FBCD    .OBJ\r\nTAN     .OBJ | ACOS    .OBJ | ASIN    .OBJ | ATAN2   .OBJ | ATAN    .OBJ\r\nCOS     .OBJ | SIN     .OBJ | SINH    .OBJ | COSH    .OBJ | TANH    .OBJ\r\nEXP     .OBJ | LOG     .OBJ | EVALPOLY.OBJ | SQRT    .OBJ | FREXP   .OBJ\r\nFABS    .OBJ | CEIL    .OBJ | FLOOR   .OBJ | FINC    .OBJ | ASFLOAT .OBJ\r\nFRNDINT .OBJ | FTOL    .OBJ | LTOF    .OBJ | FLOAT   .OBJ | LIB280C .LIB\r\nDrive M: Total 1520k, Used 268k, Free 1252k\r\n\r\nLibrary D10:LIBF2OBJ.LBR^G not found.\r\n  To make it, enter the number of entries to allow.\r\n  Press RETURN now to abort making the library.\r\nAllow how many entries: 36\r\nLibrary D10:LIBF2OBJ.LBR open.\r\n(Buffer size: 281 sectors)\r\nActive entries: 1, Deleted: 0, Free: 39, Total: 40.\r\nAdding:    M10:LIBFVER .OBJ\r\nAdding:    M10:PRINTF  .OBJ\r\nAdding:    M10:FPRINTF .OBJ\r\nAdding:    M10:SPRINTF .OBJ\r\nAdding:    M10:SCANF   .OBJ\r\nAdding:    M10:FSCANF  .OBJ\r\nAdding:    M10:SSCANF  .OBJ\r\nAdding:    M10:DOPRNT  .OBJ\r\nAdding:    M10:DOSCAN  .OBJ\r\nAdding:    M10:ATOF    .OBJ\r\nAdding:    M10:FNUM    .OBJ\r\nAdding:    M10:FBCD    .OBJ\r\nAdding:    M10:TAN     .OBJ\r\nAdding:    M10:ACOS    .OBJ\r\nAdding:    M10:ASIN    .OBJ\r\nAdding:    M10:ATAN2   .OBJ\r\nAdding:    M10:ATAN    .OBJ\r\nAdding:    M10:COS     .OBJ\r\nAdding:    M10:SIN     .OBJ\r\nAdding:    M10:SINH    .OBJ\r\nAdding:    M10:COSH    .OBJ\r\nAdding:    M10:TANH    .OBJ\r\nAdding:    M10:EXP     .OBJ\r\nAdding:    M10:LOG     .OBJ\r\nAdding:    M10:EVALPOLY.OBJ\r\nAdding:    M10:SQRT    .OBJ\r\nAdding:    M10:FREXP   .OBJ\r\nAdding:    M10:FABS    .OBJ\r\nAdding:    M10:CEIL    .OBJ\r\nAdding:    M10:FLOOR   .OBJ\r\nAdding:    M10:FINC    .OBJ\r\nAdding:    M10:ASFLOAT .OBJ\r\nAdding:    M10:FRNDINT .OBJ\r\nAdding:    M10:FTOL    .OBJ\r\nAdding:    M10:LTOF    .OBJ\r\nAdding:    M10:FLOAT   .OBJ\r\nActive entries: 37, Deleted: 0, Free: 3, Total: 40.\r\n\r\nClosing D10:LIBF2OBJ.LBR...\r\n\r\n\r\n10M>d:\r\n10D>;----------  done  ---------- \r\n10D>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "float/M280LIBF.SUB",
    "content": "era m280libf.log\r\nput console output to file m280libf.log [system]\r\ndate\r\n;----------  M280LIBF.SUB  ----------\r\n; Assumes DEHUFF -X FLOAT.HUF has extracted\r\n; all sources to the default drive\r\n;------------------------------------\r\nm:\r\nera m:*.obj\r\n<Y\r\n;\r\nc280\r\n<-v -c -o2 \\\r\n<d:LIBFVER.C \\\r\n<d:PRINTF.C \\\r\n<d:FPRINTF.C \\\r\n<d:SPRINTF.C \\\r\n<d:SCANF.C \\\r\n<d:FSCANF.C \\\r\n<d:SSCANF.C \\\r\n<d:DOPRNT.C \\\r\n<d:DOSCAN.C \\\r\n<d:ATOF.C \\\r\n<d:FNUM.C \\\r\n<d:FBCD.AS \\\r\n<d:TAN.C \\\r\n<d:ACOS.C \\\r\n<d:ASIN.C \\\r\n<d:ATAN2.C \\\r\n<d:ATAN.C \\\r\n<d:COS.C \\\r\n<d:SIN.C \\\r\n<d:SINH.C \\\r\n<d:COSH.C \\\r\n<d:TANH.C \\\r\n<d:EXP.C \\\r\n<d:LOG.C \\\r\n<d:EVALPOLY.C \\\r\n<d:SQRT.C \\\r\n<d:FREXP.AS \\\r\n<d:FABS.C \\\r\n<d:CEIL.C \\\r\n<d:FLOOR.C \\\r\n<d:FINC.AS \\\r\n<d:ASFLOAT.AS \\\r\n<d:FRNDINT.AS \\\r\n<d:FTOL.AS \\\r\n<d:LTOF.AS \\\r\n<d:FLOAT.AS\r\n;\r\nera m:lib280f.lib\r\n;\r\nLIBR\r\n<R m:lib280f.LIB \\\r\n<LIBFVER.OBJ \\\r\n<PRINTF.OBJ \\\r\n<FPRINTF.OBJ \\\r\n<SPRINTF.OBJ \\\r\n<SCANF.OBJ \\\r\n<FSCANF.OBJ \\\r\n<SSCANF.OBJ \\\r\n<DOPRNT.OBJ \\\r\n<DOSCAN.OBJ \\\r\n<ATOF.OBJ \\\r\n<FNUM.OBJ \\\r\n<FBCD.OBJ \\\r\n<TAN.OBJ \\\r\n<ACOS.OBJ \\\r\n<ASIN.OBJ \\\r\n<ATAN2.OBJ \\\r\n<ATAN.OBJ \\\r\n<COS.OBJ \\\r\n<SIN.OBJ \\\r\n<SINH.OBJ \\\r\n<COSH.OBJ \\\r\n<TANH.OBJ \\\r\n<EXP.OBJ \\\r\n<LOG.OBJ \\\r\n<EVALPOLY.OBJ \\\r\n<SQRT.OBJ \\\r\n<FREXP.OBJ \\\r\n<FABS.OBJ \\\r\n<CEIL.OBJ \\\r\n<FLOOR.OBJ \\\r\n<FINC.OBJ \\\r\n<ASFLOAT.OBJ \\\r\n<FRNDINT.OBJ \\\r\n<FTOL.OBJ \\\r\n<LTOF.OBJ \\\r\n<FLOAT.OBJ\r\n;\r\npip d:=m:lib280f.lib\r\n;\r\ndir m:*.obj[fu,length=65535]\r\nera d:libf2obj.lbr\r\nnulu d:libf2obj.lbr -a m:*.obj -x\r\nd:\r\n;----------  done  ---------- \r\nput console to console\r\n"
  },
  {
    "path": "float/MAKEFILE",
    "content": ".SUFFIXES:\t.c .obj .as\r\nBIN\t= /usr/hitech/bin\r\nPACK\t= ../../pack\r\nLIB\t= ../../lib\r\nAR\t= $(BIN)/libr r\r\nC\t= $(BIN)/zc\r\nCFLAGS\t= -O -x\r\nASFLAGS\t= -x\r\nLD\t= $(BIN)/link\r\nAS\t= $(BIN)/zas\r\nPACKUP\t= $(BIN)/packup\r\nENHUFF\t= $(BIN)/enhuff\r\n\r\n.c.obj:\r\n\t$(C) $(CFLAGS) -c $<\r\n.as.obj:\r\n\t$(AS) $(ASFLAGS) $<\r\n\r\nSRCS\t= printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c \\\r\n\t  atof.c doprnt.c doscan.c ltof.as ftol.as asfloat.as finc.as \\\r\n\t  fbcd.as fnum.c frndint.as tan.c acos.c asin.c \\\r\n\t  atan2.c atan.c cos.c sin.c sinh.c cosh.c tanh.c exp.c \\\r\n\t  log.c evalpoly.c sqrt.c frexp.as fabs.c ceil.c floor.c float.as\r\n\r\nOBJS\t= printf.obj fprintf.obj sprintf.obj scanf.obj fscanf.obj \\\r\n\t  sscanf.obj doprnt.obj doscan.obj atof.obj fnum.obj \\\r\n\t  fbcd.obj tan.obj acos.obj asin.obj \\\r\n\t  atan2.obj atan.obj cos.obj sin.obj sinh.obj \\\r\n\t  cosh.obj tanh.obj exp.obj log.obj evalpoly.obj \\\r\n\t  sqrt.obj frexp.obj fabs.obj ceil.obj floor.obj finc.obj asfloat.obj \\\r\n\t  frndint.obj ftol.obj ltof.obj float.obj\r\n\r\nzlibf.lib:\t$(OBJS)\r\n\t\t$(AR) zlibf.lib $?\r\n\r\ninstall:\t$(LIB)/zlibf.lib\r\n\r\n$(LIB)/zlibf.lib:\tzlibf.lib\r\n\tcp zlibf.lib $(LIB)/zlibf.lib\r\n\tchmod og+r $(LIB)/zlibf.lib\r\n\r\nfloat-m.huf:\t$(SRCS)\r\n\t-rm *.obj\r\n\t$(C) -M -O -c -x $(SRCS)\r\n\t-rm float-m.huf\r\n\t$(ENHUFF) float-m.huf *.obj\r\n\t-rm *.obj\r\n\r\nclean:\r\n\t-rm -f zlibf.lib *.obj\r\n\r\npack:\r\n\t$(PACKUP) $(SRCS) >float.pak\r\n\r\nhuff:\r\n\t-rm float.huf\r\n\t$(ENHUFF) -a float.huf Makefile $(SRCS)\r\n\r\nprint:\r\n\tprint Makefile *.h *.c *.i *.as\r\n"
  },
  {
    "path": "float/MAKELIBF.LOG",
    "content": "\r\n10D>date\r\nA:DATE     COM  (User 0)\r\n\rMon 01/09/2025 12:08:16\r\n10D>;----------  MAKELIBF.SUB  ----------\r\n10D>; Assumes DEHUFF -X FLOAT.HUF has extracted\r\n10D>; all sources to the default drive\r\n10D>;------------------------------------\r\n10D>m:\r\n10M>era *.obj\r\nERASE *.OBJ (Y/N)? Y\r\nNo File\r\n10M>;\r\n10M>C\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-19\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -O -V -C d:LIBFVER.C \\\r\nc> d:PRINTF.C \\\r\nc> d:FPRINTF.C \\\r\nc> d:SPRINTF.C \\\r\nc> d:SCANF.C \\\r\nc> d:FSCANF.C \\\r\nc> d:SSCANF.C \\\r\nc> d:DOPRNT.C \\\r\nc> d:DOSCAN.C \\\r\nc> d:ATOF.C \\\r\nc> d:FNUM.C \\\r\nc> d:FBCD.AS \\\r\nc> d:TAN.C \\\r\nc> d:ACOS.C \\\r\nc> d:ASIN.C \\\r\nc> d:ATAN2.C \\\r\nc> d:ATAN.C \\\r\nc> d:COS.C \\\r\nc> d:SIN.C \\\r\nc> d:SINH.C \\\r\nc> d:COSH.C \\\r\nc> d:TANH.C \\\r\nc> d:EXP.C \\\r\nc> d:LOG.C \\\r\nc> d:EVALPOLY.C \\\r\nc> d:SQRT.C \\\r\nc> d:FREXP.AS \\\r\nc> d:FABS.C \\\r\nc> d:CEIL.C \\\r\nc> d:FLOOR.C \\\r\nc> d:FINC.AS \\\r\nc> d:ASFLOAT.AS \\\r\nc> d:FRNDINT.AS \\\r\nc> d:FTOL.AS \\\r\nc> d:LTOF.AS \\\r\nc> d:FLOAT.AS\r\nD:LIBFVER.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:LIBFVER.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OLIBFVER.OBJ $CTMP2.$$$\r\nD:PRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:PRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OPRINTF.OBJ $CTMP2.$$$\r\nD:FPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:FPRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OFPRINTF.OBJ $CTMP2.$$$\r\nD:SPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:SPRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OSPRINTF.OBJ $CTMP2.$$$\r\nD:SCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:SCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OSCANF.OBJ $CTMP2.$$$\r\nD:FSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:FSCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OFSCANF.OBJ $CTMP2.$$$\r\nD:SSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:SSCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OSSCANF.OBJ $CTMP2.$$$\r\nD:DOPRNT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:DOPRNT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -ODOPRNT.OBJ $CTMP2.$$$\r\nD:DOSCAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:DOSCAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -ODOSCAN.OBJ $CTMP2.$$$\r\nD:ATOF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:ATOF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OATOF.OBJ $CTMP2.$$$\r\nD:FNUM.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:FNUM.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OFNUM.OBJ $CTMP2.$$$\r\nD:FBCD.AS\r\n0:A:ZAS -J -OFBCD.OBJ D:FBCD.AS\r\nD:TAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:TAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OTAN.OBJ $CTMP2.$$$\r\nD:ACOS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:ACOS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OACOS.OBJ $CTMP2.$$$\r\nD:ASIN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:ASIN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OASIN.OBJ $CTMP2.$$$\r\nD:ATAN2.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:ATAN2.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OATAN2.OBJ $CTMP2.$$$\r\nD:ATAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:ATAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OATAN.OBJ $CTMP2.$$$\r\nD:COS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:COS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OCOS.OBJ $CTMP2.$$$\r\nD:SIN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:SIN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OSIN.OBJ $CTMP2.$$$\r\nD:SINH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:SINH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OSINH.OBJ $CTMP2.$$$\r\nD:COSH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:COSH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OCOSH.OBJ $CTMP2.$$$\r\nD:TANH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:TANH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OTANH.OBJ $CTMP2.$$$\r\nD:EXP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:EXP.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OEXP.OBJ $CTMP2.$$$\r\nD:LOG.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:LOG.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OLOG.OBJ $CTMP2.$$$\r\nD:EVALPOLY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:EVALPOLY.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OEVALPOLY.OBJ $CTMP2.$$$\r\nD:SQRT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:SQRT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OSQRT.OBJ $CTMP2.$$$\r\nD:FREXP.AS\r\n0:A:ZAS -J -OFREXP.OBJ D:FREXP.AS\r\nD:FABS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:FABS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OFABS.OBJ $CTMP2.$$$\r\nD:CEIL.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:CEIL.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OCEIL.OBJ $CTMP2.$$$\r\nD:FLOOR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: D:FLOOR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:ZAS -J -N -OFLOOR.OBJ $CTMP2.$$$\r\nD:FINC.AS\r\n0:A:ZAS -J -OFINC.OBJ D:FINC.AS\r\nD:ASFLOAT.AS\r\n0:A:ZAS -J -OASFLOAT.OBJ D:ASFLOAT.AS\r\nD:FRNDINT.AS\r\n0:A:ZAS -J -OFRNDINT.OBJ D:FRNDINT.AS\r\nD:FTOL.AS\r\n0:A:ZAS -J -OFTOL.OBJ D:FTOL.AS\r\nD:LTOF.AS\r\n0:A:ZAS -J -OLTOF.OBJ D:LTOF.AS\r\nD:FLOAT.AS\r\n0:A:ZAS -J -OFLOAT.OBJ D:FLOAT.AS\r\nERA $CTMP1.$$$\r\nERA $CTMP2.$$$\r\nERA $CTMP3.$$$\r\nERA $CTMP5.$$$\r\nERA $$EXEC.$$$\r\n\r\n10M>;\r\n10M>era m:libf.lib\r\nNo File\r\n10M>libr\r\nA:LIBR     COM  (User 0)\r\nlibr> r m:LIBF.LIB \\\r\nlibr> LIBFVER.OBJ \\\r\nlibr> PRINTF.OBJ \\\r\nlibr> FPRINTF.OBJ \\\r\nlibr> SPRINTF.OBJ \\\r\nlibr> SCANF.OBJ \\\r\nlibr> FSCANF.OBJ \\\r\nlibr> SSCANF.OBJ \\\r\nlibr> DOPRNT.OBJ \\\r\nlibr> DOSCAN.OBJ \\\r\nlibr> ATOF.OBJ \\\r\nlibr> FNUM.OBJ \\\r\nlibr> FBCD.OBJ \\\r\nlibr> TAN.OBJ \\\r\nlibr> ACOS.OBJ \\\r\nlibr> ASIN.OBJ \\\r\nlibr> ATAN2.OBJ \\\r\nlibr> ATAN.OBJ \\\r\nlibr> COS.OBJ \\\r\nlibr> SIN.OBJ \\\r\nlibr> SINH.OBJ \\\r\nlibr> COSH.OBJ \\\r\nlibr> TANH.OBJ \\\r\nlibr> EXP.OBJ \\\r\nlibr> LOG.OBJ \\\r\nlibr> EVALPOLY.OBJ \\\r\nlibr> SQRT.OBJ \\\r\nlibr> FREXP.OBJ \\\r\nlibr> FABS.OBJ \\\r\nlibr> CEIL.OBJ \\\r\nlibr> FLOOR.OBJ \\\r\nlibr> FINC.OBJ \\\r\nlibr> ASFLOAT.OBJ \\\r\nlibr> FRNDINT.OBJ \\\r\nlibr> FTOL.OBJ \\\r\nlibr> LTOF.OBJ \\\r\nlibr> FLOAT.OBJ\r\n\r\n10M>;\r\n10M>pip d:=m:LIBF.LIB\r\nA:PIP      COM  (User 0)\r\n\r\n10M>;\r\n10M>dir m:*.obj[fu,length=65535]\r\nA:DIR      COM  (User 0)\r\n\r\nScanning Directory...\r\n\r\nSorting  Directory...\r\n\r\nDirectory For Drive M:  User 10\r\n\r\n    Name     Bytes   Recs   Attributes   Prot      Update          Create    \r\n------------ ------ ------ ------------ ------ --------------  --------------\r\n\r\nACOS     OBJ     4k      3 Dir RW       None   01/09/25 12:11  01/09/25 12:11\r\nASFLOAT  OBJ     4k      3 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nASIN     OBJ     4k      9 Dir RW       None   01/09/25 12:11  01/09/25 12:11\r\nATAN     OBJ     4k      9 Dir RW       None   01/09/25 12:12  01/09/25 12:12\r\nATAN2    OBJ     4k      9 Dir RW       None   01/09/25 12:12  01/09/25 12:12\r\nATOF     OBJ     4k     11 Dir RW       None   01/09/25 12:10  01/09/25 12:10\r\nCEIL     OBJ     4k      4 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nCOS      OBJ     4k      5 Dir RW       None   01/09/25 12:12  01/09/25 12:12\r\nCOSH     OBJ     4k      4 Dir RW       None   01/09/25 12:12  01/09/25 12:12\r\nDOPRNT   OBJ     4k     21 Dir RW       None   01/09/25 12:09  01/09/25 12:09\r\nDOSCAN   OBJ     4k     32 Dir RW       None   01/09/25 12:10  01/09/25 12:10\r\nEVALPOLY OBJ     4k      3 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\nEXP      OBJ     4k     14 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\nFABS     OBJ     4k      3 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\nFBCD     OBJ     4k      6 Dir RW       None   01/09/25 12:11  01/09/25 12:11\r\nFINC     OBJ     4k      2 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nFLOAT    OBJ     4k      9 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nFLOOR    OBJ     4k      4 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nFNUM     OBJ     4k     31 Dir RW       None   01/09/25 12:11  01/09/25 12:11\r\nFPRINTF  OBJ     4k      2 Dir RW       None   01/09/25 12:08  01/09/25 12:08\r\nFREXP    OBJ     4k      2 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\nFRNDINT  OBJ     4k      1 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nFSCANF   OBJ     4k      2 Dir RW       None   01/09/25 12:09  01/09/25 12:09\r\nFTOL     OBJ     4k      2 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nLIBFVER  OBJ     4k      1 Dir RW       None   01/09/25 12:08  01/09/25 12:08\r\nLOG      OBJ     4k      8 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\nLTOF     OBJ     4k      4 Dir RW       None   01/09/25 12:14  01/09/25 12:14\r\nPRINTF   OBJ     4k      2 Dir RW       None   01/09/25 12:08  01/09/25 12:08\r\nSCANF    OBJ     4k      2 Dir RW       None   01/09/25 12:08  01/09/25 12:08\r\nSIN      OBJ     4k     10 Dir RW       None   01/09/25 12:12  01/09/25 12:12\r\nSINH     OBJ     4k      4 Dir RW       None   01/09/25 12:12  01/09/25 12:12\r\nSPRINTF  OBJ     4k      3 Dir RW       None   01/09/25 12:08  01/09/25 12:08\r\nSQRT     OBJ     4k     10 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\nSSCANF   OBJ     4k      3 Dir RW       None   01/09/25 12:09  01/09/25 12:09\r\nTAN      OBJ     4k      2 Dir RW       None   01/09/25 12:11  01/09/25 12:11\r\nTANH     OBJ     4k      4 Dir RW       None   01/09/25 12:13  01/09/25 12:13\r\n\r\nTotal Bytes     =    144k  Total Records =     244  Files Found =   36\r\nTotal 1k Blocks =     52   Used/Max Dir Entries For Drive M:   52/ 512\r\n\r\n10M>era d:libf-obj.lbr\r\n10M>nulu d:libf-obj.lbr -a m:*.obj -x\r\nA:NULU     COM  (User 0)\r\n^Z\rNULU 1.52  (07/12/87)\r\nCopyright (C) 1984, 1985 & 1987 by Martin Murray\r\nBug fixes in version 1.52 by Mick Waters\r\n\r\nTYPE -H FOR HELP\r\n\r\n\r\nSYSIN58 .$$$ | LIBF    .LIB | LIBFVER .OBJ | PRINTF  .OBJ | FPRINTF .OBJ\r\nSPRINTF .OBJ | SCANF   .OBJ | FSCANF  .OBJ | SSCANF  .OBJ | DOPRNT  .OBJ\r\nDOSCAN  .OBJ | ATOF    .OBJ | FNUM    .OBJ | FBCD    .OBJ | TAN     .OBJ\r\nACOS    .OBJ | ASIN    .OBJ | ATAN2   .OBJ | ATAN    .OBJ | COS     .OBJ\r\nSIN     .OBJ | SINH    .OBJ | COSH    .OBJ | TANH    .OBJ | EXP     .OBJ\r\nLOG     .OBJ | EVALPOLY.OBJ | SQRT    .OBJ | FREXP   .OBJ | FABS    .OBJ\r\nCEIL    .OBJ | FLOOR   .OBJ | FINC    .OBJ | ASFLOAT .OBJ | FRNDINT .OBJ\r\nFTOL    .OBJ | LTOF    .OBJ | FLOAT   .OBJ | \r\nDrive M: Total 1520k, Used 180k, Free 1340k\r\n\r\nLibrary D10:LIBF-OBJ.LBR^G not found.\r\n  To make it, enter the number of entries to allow.\r\n  Press RETURN now to abort making the library.\r\nAllow how many entries: 36\r\nLibrary D10:LIBF-OBJ.LBR open.\r\n(Buffer size: 281 sectors)\r\nActive entries: 1, Deleted: 0, Free: 39, Total: 40.\r\nAdding:    M10:LIBFVER .OBJ\r\nAdding:    M10:PRINTF  .OBJ\r\nAdding:    M10:FPRINTF .OBJ\r\nAdding:    M10:SPRINTF .OBJ\r\nAdding:    M10:SCANF   .OBJ\r\nAdding:    M10:FSCANF  .OBJ\r\nAdding:    M10:SSCANF  .OBJ\r\nAdding:    M10:DOPRNT  .OBJ\r\nAdding:    M10:DOSCAN  .OBJ\r\nAdding:    M10:ATOF    .OBJ\r\nAdding:    M10:FNUM    .OBJ\r\nAdding:    M10:FBCD    .OBJ\r\nAdding:    M10:TAN     .OBJ\r\nAdding:    M10:ACOS    .OBJ\r\nAdding:    M10:ASIN    .OBJ\r\nAdding:    M10:ATAN2   .OBJ\r\nAdding:    M10:ATAN    .OBJ\r\nAdding:    M10:COS     .OBJ\r\nAdding:    M10:SIN     .OBJ\r\nAdding:    M10:SINH    .OBJ\r\nAdding:    M10:COSH    .OBJ\r\nAdding:    M10:TANH    .OBJ\r\nAdding:    M10:EXP     .OBJ\r\nAdding:    M10:LOG     .OBJ\r\nAdding:    M10:EVALPOLY.OBJ\r\nAdding:    M10:SQRT    .OBJ\r\nAdding:    M10:FREXP   .OBJ\r\nAdding:    M10:FABS    .OBJ\r\nAdding:    M10:CEIL    .OBJ\r\nAdding:    M10:FLOOR   .OBJ\r\nAdding:    M10:FINC    .OBJ\r\nAdding:    M10:ASFLOAT .OBJ\r\nAdding:    M10:FRNDINT .OBJ\r\nAdding:    M10:FTOL    .OBJ\r\nAdding:    M10:LTOF    .OBJ\r\nAdding:    M10:FLOAT   .OBJ\r\nActive entries: 37, Deleted: 0, Free: 3, Total: 40.\r\n\r\nClosing D10:LIBF-OBJ.LBR...\r\n\r\n\r\n10M>d:\r\n10D>;----------  done  ---------- \r\n10D>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "float/MAKELIBF.SUB",
    "content": "era makelibf.log\r\nput console output to file makelibf.log [system]\r\ndate\r\n;----------  MAKELIBF.SUB  ----------\r\n; Assumes DEHUFF -X FLOAT.HUF has extracted\r\n; all sources to the default drive\r\n;------------------------------------\r\nm:\r\nera *.obj\r\n<Y\r\n;\r\nC\r\n<-O -V -C d:LIBFVER.C \\\r\n<d:PRINTF.C \\\r\n<d:FPRINTF.C \\\r\n<d:SPRINTF.C \\\r\n<d:SCANF.C \\\r\n<d:FSCANF.C \\\r\n<d:SSCANF.C \\\r\n<d:DOPRNT.C \\\r\n<d:DOSCAN.C \\\r\n<d:ATOF.C \\\r\n<d:FNUM.C \\\r\n<d:FBCD.AS \\\r\n<d:TAN.C \\\r\n<d:ACOS.C \\\r\n<d:ASIN.C \\\r\n<d:ATAN2.C \\\r\n<d:ATAN.C \\\r\n<d:COS.C \\\r\n<d:SIN.C \\\r\n<d:SINH.C \\\r\n<d:COSH.C \\\r\n<d:TANH.C \\\r\n<d:EXP.C \\\r\n<d:LOG.C \\\r\n<d:EVALPOLY.C \\\r\n<d:SQRT.C \\\r\n<d:FREXP.AS \\\r\n<d:FABS.C \\\r\n<d:CEIL.C \\\r\n<d:FLOOR.C \\\r\n<d:FINC.AS \\\r\n<d:ASFLOAT.AS \\\r\n<d:FRNDINT.AS \\\r\n<d:FTOL.AS \\\r\n<d:LTOF.AS \\\r\n<d:FLOAT.AS\r\n;\r\nera m:libf.lib\r\nlibr\r\n<r m:LIBF.LIB \\\r\n<LIBFVER.OBJ \\\r\n<PRINTF.OBJ \\\r\n<FPRINTF.OBJ \\\r\n<SPRINTF.OBJ \\\r\n<SCANF.OBJ \\\r\n<FSCANF.OBJ \\\r\n<SSCANF.OBJ \\\r\n<DOPRNT.OBJ \\\r\n<DOSCAN.OBJ \\\r\n<ATOF.OBJ \\\r\n<FNUM.OBJ \\\r\n<FBCD.OBJ \\\r\n<TAN.OBJ \\\r\n<ACOS.OBJ \\\r\n<ASIN.OBJ \\\r\n<ATAN2.OBJ \\\r\n<ATAN.OBJ \\\r\n<COS.OBJ \\\r\n<SIN.OBJ \\\r\n<SINH.OBJ \\\r\n<COSH.OBJ \\\r\n<TANH.OBJ \\\r\n<EXP.OBJ \\\r\n<LOG.OBJ \\\r\n<EVALPOLY.OBJ \\\r\n<SQRT.OBJ \\\r\n<FREXP.OBJ \\\r\n<FABS.OBJ \\\r\n<CEIL.OBJ \\\r\n<FLOOR.OBJ \\\r\n<FINC.OBJ \\\r\n<ASFLOAT.OBJ \\\r\n<FRNDINT.OBJ \\\r\n<FTOL.OBJ \\\r\n<LTOF.OBJ \\\r\n<FLOAT.OBJ\r\n;\r\npip d:=m:LIBF.LIB\r\n;\r\ndir m:*.obj[fu,length=65535]\r\nera d:libf-obj.lbr\r\nnulu d:libf-obj.lbr -a m:*.obj -x\r\nd:\r\n;----------  done  ---------- \r\nput console to console\r\n"
  },
  {
    "path": "float/PRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern int\t_doprnt();\r\n\r\nprintf(f, a)\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\treturn(_doprnt(stdout, f, &a));\r\n}\r\n"
  },
  {
    "path": "float/SCANF.C",
    "content": "/*\r\n *\tStdio scanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\t_doscan();\r\n\r\nscanf(fmt, args)\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\treturn _doscan(stdin, fmt, &args);\r\n}\r\n"
  },
  {
    "path": "float/SIN.C",
    "content": "#include\t<math.h>\r\n\r\n#define\tPI\t3.14159265358979\r\n#define\tTWO_PI\t6.28318530717958\r\n#define\tHALF_PI\t1.570796326794895\r\n\r\ndouble\r\nsin(f)\r\ndouble\tf;\r\n{\r\n\t/* const */ static double\tcoeff_a[] =\r\n\t{\r\n\t\t 207823.68416961012,\r\n\t\t-76586.415638846949,\r\n\t\t 7064.1360814006881,\r\n\t\t-237.85932457812158,\r\n\t\t 2.8078274176220686\r\n\t};\r\n\t/* const */ static double\tcoeff_b[] =\r\n\t{\r\n\t\t 132304.66650864931,\r\n\t\t 5651.6867953169177,\r\n\t\t 108.99981103712905,\r\n\t\t 1.0\r\n\t};\r\n\tdouble\tx2;\r\n\tint\tsgn;\r\n\textern double\teval_poly();\r\n\r\n\tsgn = 0;\r\n\tif(f < 0.0) {\r\n\t\tf = -f;\r\n\t\tsgn = 1;\r\n\t}\r\n\tf *= 1.0/TWO_PI;\r\n\tf = 4.0 * (f - floor(f));\r\n\tif(f > 2.0) {\r\n\t\tf -= 2.0;\r\n\t\tsgn = !sgn;\r\n\t}\r\n\tif( f > 1.0)\r\n\t\tf = 2.0 - f;\r\n\tx2 = f * f;\r\n\tf *= eval_poly(x2, coeff_a, 4) / eval_poly(x2, coeff_b, 3);\r\n\tif(sgn)\r\n\t\treturn -f;\r\n\treturn f;\r\n}\r\n\r\n\r\n"
  },
  {
    "path": "float/SINH.C",
    "content": "\r\n#include\t<math.h>\r\n\r\ndouble\r\nsinh(x)\r\ndouble\tx;\r\n{\r\n\tx = exp(x);\r\n\treturn 0.5*(x-1.0/x);\r\n}\r\n"
  },
  {
    "path": "float/SPRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nstatic\tFILE\tspf;\r\n\r\nsprintf(wh, f, a)\r\nchar *\twh;\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\tspf._size = 32767;\r\n\tspf._cnt = 0;\r\n\tspf._base = spf._ptr = wh;\r\n\tspf._flag = _IOWRT|_IOBINARY|_IOSTRG;\r\n\t_doprnt(&spf, f, &a);\r\n\t*spf._ptr = 0;\r\n\treturn spf._ptr - wh;\r\n}\r\n"
  },
  {
    "path": "float/SQRT.C",
    "content": "#include\t<math.h>\r\n\r\ndouble\r\nsqrt(x)\r\ndouble\tx;\r\n{\r\n\tdouble\tog, ng;\r\n\tshort\tniter;\r\n\tint\texp;\r\n\r\n\tif(x <= 0.0)\r\n\t\treturn 0.0;\r\n\tog = x;\r\n\tif(og < 1.0)\r\n\t\tog = 1.0/og;\r\n\tog = frexp(og, &exp);\r\n\tog = ldexp(og, exp/2);\t\t/* make an educated guess */\r\n\tif(x < 1.0)\r\n\t\tog = 1.0/og;\r\n\tfor(niter = 0 ; niter < 20 ; niter++) {\r\n\t\tng = (x/og + og)/2.0;\r\n\t\tif(ng == og)\r\n\t\t\tbreak;\r\n\t\tog = ng;\r\n\t}\r\n\treturn og;\r\n}\r\n"
  },
  {
    "path": "float/SSCANF.C",
    "content": "/*\r\n *\tStdio sscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<string.h>\r\n\r\nextern int\t_doscan();\r\n\r\nsscanf(str, fmt, args)\r\nchar *\tstr;\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\tFILE\tfile;\r\n\r\n\tfile._base = file._ptr = str;\r\n\tfile._size = file._cnt = strlen(str);\r\n\tfile._flag = _IOSTRG|_IOBINARY|_IOREAD;\r\n\treturn _doscan(&file, fmt, &args);\r\n}\r\n"
  },
  {
    "path": "float/TAN.C",
    "content": "#include\t<math.h>\r\n\r\ndouble\r\ntan(x)\r\ndouble\tx;\r\n{\r\n\treturn sin(x)/cos(x);\r\n}\r\n"
  },
  {
    "path": "float/TANH.C",
    "content": "\r\n#include\t<math.h>\r\n\r\ndouble\r\ntanh(x)\r\ndouble\tx;\r\n{\r\n\tx = exp(x);\r\n\treturn (x-1.0/x)/(x+1.0/x);\r\n}\r\n"
  },
  {
    "path": "gen/ABS.AS",
    "content": ";\tabs(i) returns the absolute value of i\r\n\r\n\tglobal\t_abs\r\n\r\n\tpsect\ttext\r\n_abs:\r\n\tpop\tde\t\t;Return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tbit\t7,h\t\t;Negative?\r\n\tret\tz\t\t;no, leave alone\r\n\tex\tde,hl\r\n\tld\thl,0\r\n\tor\ta\t\t;Clear carry\r\n\tsbc\thl,de\r\n\tret\r\n"
  },
  {
    "path": "gen/ALLSH.AS",
    "content": ";\tarithmetic long left shift\r\n;\tvalue in HLDE, count in B\r\n\r\n\tglobal\tallsh, lllsh\r\n\tpsect\ttext\r\n\r\nallsh:\r\nlllsh:\r\n\tld\ta,b\t\t;check for zero shift\r\n\tor\ta\r\n\tret\tz\r\n\tcp\t33\r\n\tjr\tc,1f\t\t;limit shift to 32 bits\r\n\tld\tb,32\r\n1:\r\n\tex\tde,hl\r\n\tadd\thl,hl\r\n\tex\tde,hl \r\n\tadc\thl,hl\r\n\tdjnz\t1b\r\n\tret\r\n"
  },
  {
    "path": "gen/ALRSH.AS",
    "content": ";\tarithmetic long right shift\r\n;\tvalue in HLDE, count in B\r\n\r\n\tglobal\talrsh\r\n\tpsect\ttext\r\n\r\nalrsh:\r\n\tld\ta,b\t\t;check for zero shift\r\n\tor\ta\r\n\tret\tz\r\n\tcp\t33\r\n\tjr\tc,1f\t\t;limit shift to 32 bits\r\n\tld\tb,32\r\n1:\r\n\tsra\th\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\tdjnz\t1b\r\n\tret\r\n"
  },
  {
    "path": "gen/ASALLSH.AS",
    "content": ";\tASsign Arithmetic Long Left  SHift\r\n;\tASsign Logical Long Left SHift\r\n\r\n\tpsect\ttext\r\n\tglobal\tasallsh, aslllsh, allsh, iregstore\r\n\r\nasallsh:\r\naslllsh:\r\n\tpush\tbc\t\t;save the count\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tex\t(sp),hl\t\t;save pointer, restore count\r\n\tpush\tbc\t\t;hi word\r\n\tex\t(sp),hl\r\n\tpop\tbc\r\n\tcall\tallsh\t\t;do the shift\r\n\tjp\tiregstore\t;go store the value and return\r\n"
  },
  {
    "path": "gen/ASALRSH.AS",
    "content": ";\tASsign Arithmetic Long Right  SHift\r\n\r\n\tpsect\ttext\r\n\tglobal\tasalrsh, alrsh, iregstore\r\n\r\nasalrsh:\r\n\tpush\tbc\t\t;save the count\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tex\t(sp),hl\t\t;save pointer, restore count\r\n\tpush\tbc\t\t;hi word\r\n\tex\t(sp),hl\r\n\tpop\tbc\r\n\tcall\talrsh\t\t;do the shift\r\n\tjp\tiregstore\t;go store the value and return\r\n"
  },
  {
    "path": "gen/ASAR.AS",
    "content": ";\tShift operations - the count is always in B,\r\n;\tthe quantity to be shifted is in HL, except for the assignment\r\n;\ttype operations, when it is in the memory location pointed to by\r\n;\tHL\r\n\r\n\tglobal\tasar\t;assign shift arithmetic right\r\n\tpsect\ttext\r\n\tglobal\tshar\r\n\r\n\r\nasar:\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tpush\thl\t\t;save for the store\r\n\tex\tde,hl\r\n\tcall\tshar\r\n\tex\tde,hl\r\n\tpop\thl\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n"
  },
  {
    "path": "gen/ASDIV.AS",
    "content": ";\tAssign versions of divide\r\n\r\n\tglobal\tasadiv, asldiv, adiv, ldiv\r\n\r\n\tpsect\ttext\r\n\r\nasadiv:\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\tcall\tadiv\r\n\tex\t(sp),hl\r\n\tpop\tde\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n\r\nasldiv:\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\tcall\tldiv\r\n\tex\t(sp),hl\r\n\tpop\tde\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n\r\n"
  },
  {
    "path": "gen/ASLADD.AS",
    "content": "\tpsect\ttext\r\n\tglobal\tiregset, iregstore, asaladd, aslladd, aladd\r\n\r\nasaladd:\r\naslladd:\r\n\tcall\tiregset\r\n\tcall\taladd\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "gen/ASLAND.AS",
    "content": "\tpsect\ttext\r\n\tglobal\tiregset, iregstore, asaland, aslland, aland\r\n\r\nasaland:\r\naslland:\r\n\tcall\tiregset\r\n\tcall\taland\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "gen/ASLL.AS",
    "content": ";\tShift operations - the count is always in B,\r\n;\tthe quantity to be shifted is in HL, except for the assignment\r\n;\ttype operations, when it is in the memory location pointed to by\r\n;\tHL\r\n\r\n\tglobal\tasll,asal\t;assign shift left (logical or arithmetic)\r\n\tpsect\ttext\r\n\tglobal\tshal\r\n\r\n\r\nasll:\r\nasal:\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tpush\thl\t\t;save for the store\r\n\tex\tde,hl\r\n\tcall\tshal\r\n\tex\tde,hl\r\n\tpop\thl\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n"
  },
  {
    "path": "gen/ASLLRSH.AS",
    "content": ";\tASsign Logical Long Right  SHift\r\n\r\n\tpsect\ttext\r\n\tglobal\tasllrsh, llrsh, iregstore\r\n\r\nasllrsh:\r\n\tpush\tbc\t\t;save the count\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tex\t(sp),hl\t\t;save pointer, restore count\r\n\tpush\tbc\t\t;hi word\r\n\tex\t(sp),hl\r\n\tpop\tbc\r\n\tcall\tllrsh\t\t;do the shift\r\n\tjp\tiregstore\t;go store the value and return\r\n"
  },
  {
    "path": "gen/ASLMUL.AS",
    "content": "\tpsect\ttext\r\n\tglobal\tiregset, iregstore, asalmul, asllmul, almul\r\n\r\nasalmul:\r\nasllmul:\r\n\tcall\tiregset\r\n\tcall\talmul\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "gen/ASLOR.AS",
    "content": "\tpsect\ttext\r\n\tglobal\tiregset, iregstore, asalor, asllor, alor\r\n\r\nasalor:\r\nasllor:\r\n\tcall\tiregset\r\n\tcall\talor\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "gen/ASLR.AS",
    "content": ";\tShift operations - the count is always in B,\r\n;\tthe quantity to be shifted is in HL, except for the assignment\r\n;\ttype operations, when it is in the memory location pointed to by\r\n;\tHL\r\n\r\n\tglobal\taslr\t;assign shift logical right\r\n\tpsect\ttext\r\n\tglobal\tshlr\r\n\r\n\r\naslr:\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tpush\thl\t\t;save for the store\r\n\tex\tde,hl\r\n\tcall\tshlr\r\n\tex\tde,hl\r\n\tpop\thl\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n"
  },
  {
    "path": "gen/ASLSUB.AS",
    "content": "\tpsect\ttext\r\n\tglobal\tiregset, iregstore, asalsub, asllsub, alsub\r\n\r\nasalsub:\r\nasllsub:\r\n\tcall\tiregset\r\n\tcall\talsub\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "gen/ASLXOR.AS",
    "content": "\tpsect\ttext\r\n\tglobal\tiregset, iregstore, asalxor, asllxor, alxor\r\n\r\nasalxor:\r\nasllxor:\r\n\tcall\tiregset\r\n\tcall\talxor\r\n\tjp\tiregstore\r\n"
  },
  {
    "path": "gen/ASMOD.AS",
    "content": ";\tAssign versions of modulus\r\n\r\n\tglobal\tasamod, aslmod, amod, lmod\r\n\r\n\tpsect\ttext\r\n\r\nasamod:\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\tcall\tamod\r\n\tex\t(sp),hl\r\n\tpop\tde\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n\r\naslmod:\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\tcall\tlmod\r\n\tex\t(sp),hl\r\n\tpop\tde\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n\r\n"
  },
  {
    "path": "gen/ASMUL.AS",
    "content": ";\tAssign versions of multiply\r\n\r\n\tglobal\tasamul, aslmul, amul\r\n\r\n\tpsect\ttext\r\n\r\nasamul:\r\naslmul:\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\tcall\tamul\r\n\tex\t(sp),hl\r\n\tpop\tde\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tex\tde,hl\t\t;return value in hl\r\n\tret\r\n\r\n"
  },
  {
    "path": "gen/ATOI.AS",
    "content": "\tpsect\ttext\r\ndigit:\tsub\t'0'\r\n\tret\tc\r\n\tcp\t10\r\n\tccf\r\n\tret\r\n\r\n\tglobal\t_atoi\r\n_atoi:\tpop\tbc\t;return address\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\tbc\r\n\tld\thl,0\r\n1:\r\n\tld\ta,(de)\r\n\tinc\tde\r\n\tcp\t' '\r\n\tjr\tz,1b\r\n\tcp\t'\t'\t;tab\r\n\tjr\tz,1b\r\n\tdec\tde\t\t;point to 1st non blank char\r\n\tcp\t'-'\r\n\tjr\tz,3f\r\n\tcp\t'+'\r\n\tjr\tnz,2f\r\n\tor\ta\t\t;reset zero flag\r\n3:\r\n\tinc\tde\r\n2:\tex\taf,af'\r\n1:\r\n\tld\ta,(de)\r\n\tinc\tde\r\n\tcall\tdigit\r\n\tjr\tc,3f\r\n\tadd\thl,hl\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tadd\thl,hl\r\n\tadd\thl,hl\r\n\tadd\thl,bc\r\n\tld\tc,a\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tjr\t1b\r\n\r\n3:\r\n\tex\taf,af'\r\n\tret\tnz\r\n\tex\tde,hl\r\n\tld\thl,0\r\n\tsbc\thl,de\r\n\tret\r\n"
  },
  {
    "path": "gen/ATOL.C",
    "content": "#include\t<ctype.h>\r\n\r\nlong\r\natol(s)\r\nregister char *\ts;\r\n{\r\n\tlong\ta;\r\n\tunsigned char\tsign;\r\n\r\n\twhile(*s == ' ' || *s == '\\t')\r\n\t\ts++;\r\n\ta = 0;\r\n\tsign = 0;\r\n\tif(*s == '-') {\r\n\t\tsign++;\r\n\t\ts++;\r\n\t} else if(*s == '+')\r\n\t\ts++;\r\n\twhile(isdigit(*s))\r\n\t\ta = a*10L + (*s++ - '0');\r\n\tif(sign)\r\n\t\treturn -a;\r\n\treturn a;\r\n}\r\n"
  },
  {
    "path": "gen/BITFIELD.AS",
    "content": ";\tFunctions to implement bitfields:\r\n\r\n;\tthe width and offset (in bits) of the bitfield concerned\r\n;\tappear in the code immediately after the call, packed into one byte\r\n;\tlike this:\r\n\r\n;\t\tbit\t|7    4|3   0|\r\n;\t\t\t|offset|width|\r\n\r\n;\tbfext: called with a value in HL, returns with extracted\r\n;\tbitfield value in HL\r\n\r\n\tpsect\ttext\r\n\tglobal\tbfext, bfins\r\nbfext:\r\n\tpop\tbc\t\t;get return address\r\n\tld\ta,(bc)\t\t;pick up width and offset\r\n\tinc\tbc\r\n\tpush\tbc\r\n\tpush\taf\r\n\trra\r\n\trra\r\n\trra\r\n\trra\r\n\tand\t0Fh\t\t;get offset\r\n\tjr\tz,1f\t\t;skip if zero\r\n\tld\tb,a\r\n2:\r\n\tsrl\th\r\n\trr\tl\r\n\tdjnz\t2b\r\n1:\r\n\tpop\taf\r\n\tpush\tde\t\t;don't touch de\r\n\tld\tde,1\t\t;start with a 1\r\n\tand\t0Fh\t\t;get width\r\n\tld\tb,a\t\t;put in counter\r\n2:\r\n\tsll\te\r\n\trl\td\t\t;shift up one bit\r\n\tdjnz\t2b\r\n\tdec\tde\t\t;decrement by one\r\n\tld\ta,l\r\n\tand\te\t\t;mask appropriately\r\n\tld\tl,a\r\n\tld\ta,h\r\n\tand\td\r\n\tld\th,a\t\t;all done!\r\n\tpop\tde\r\n\tret\r\n\r\n;\tInsert the data in de into the data at (hl). Size and offset\r\n;\tare in the following byte as usual\r\n\r\nbfins:\r\n\tpop\tbc\t\t;get return address\r\n\tld\ta,(bc)\t\t;get info byte\r\n\tinc\tbc\r\n\tpush\tbc\r\n\tpush\thl\t\t;save address\r\n\tpush\taf\t\t;save for ron\r\n\tld\thl,1\r\n\tand\t0Fh\r\n\tld\tb,a\r\n2:\r\n\tsll\tl\r\n\trl\th\t\t;shift up one bit\r\n\tdjnz\t2b\r\n\tdec\thl\t\t;convert to a mask\r\n\tld\ta,e\r\n\tand\tl\r\n\tld\te,a\r\n\tld\ta,d\r\n\tand\th\r\n\tld\td,a\t\t;masked it\r\n\tpop\taf\t\t;get byte again\r\n\tpush\tde\t\t;save value\r\n\trra\r\n\trra\r\n\trra\r\n\trra\r\n\tand\t0Fh\t\t;mask out offset\r\n\tjr\tz,1f\t\t;skip if zero\r\n\tld\tb,a\r\n2:\r\n\tsll\tl\t\t;shift it up\r\n\trl\th\r\n\tsll\te\r\n\trl\td\r\n\tdjnz\t2b\t\t;loop for more\r\n1:\r\n\tex\t(sp),hl\t\t;save mask, get value\r\n\tpop\tbc\t\t;mask in bc\r\n\tex\t(sp),hl\t\t;address in hl, save value\r\n\tld\ta,c\t\t;complement mask\r\n\tcpl\r\n\tand\t(hl)\t\t;and with memory data\r\n\tor\te\t\t;or with shifted value\r\n\tld\t(hl),a\t\t;put back\r\n\tinc\thl\r\n\tld\ta,b\r\n\tcpl\r\n\tand\t(hl)\r\n\tor\td\r\n\tld\t(hl),a\r\n\tpop\thl\t\t;get value back\r\n\tret\t\t\t;finito!\r\n"
  },
  {
    "path": "gen/BLKCLR.AS",
    "content": ";\tblkclr(ptr, size)\r\n;\tchar *\tptr; unsigned short size;\r\n\r\n;\tFills memory with size null bytes\r\n\r\n\tpsect\ttext\r\n\tglobal\t_blkclr\r\n\r\n_blkclr:\r\n\tpop\tde\t;return address\r\n\tpop\thl\t;pointer\r\n\tpop\tbc\t;count\r\n\tpush\tbc\t;adjust stack\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\te,0\r\n\r\n1:\r\n\tld\ta,c\t;check for finished\r\n\tor\tb\r\n\tret\tz\r\n\tld\t(hl),e\r\n\tinc\thl\r\n\tdec\tbc\r\n\tjr\t1b\r\n"
  },
  {
    "path": "gen/BLKCPY.C",
    "content": "blkcpy(dp, sp, n)\r\n\tregister char *dp, *sp;\r\n\tregister unsigned n;\r\n{\r\n\twhile (n--)\r\n\t\t*dp++ = *sp++;\r\n}\r\n"
  },
  {
    "path": "gen/BMOVE.AS",
    "content": ";\tbmove(from, to, count)\r\n\r\n\tglobal\t_bmove, _movmem\r\n\tpsect\ttext\r\n\r\n_movmem:\r\n_bmove:\r\n\tpop\thl\t\t;return address\r\n\texx\r\n\tpop\thl\t\t;from\r\n\tpop\tde\t\t;to\r\n\tpop\tbc\t\t;count\r\n\tld\ta,b\r\n\tor\tc\r\n\tjr\tz,1f\r\n\tldir\r\n1:\r\n\tpush\tbc\t\t;stack is as it was\r\n\tpush\tde\r\n\tpush\thl\r\n\texx\r\n\tjp\t(hl)\r\n"
  },
  {
    "path": "gen/BRELOP.AS",
    "content": ";\tbyte relational\toperation - returns flags correctly for\r\n;\tcomparision of words in a and b\r\n\r\n\tpsect\ttext\r\n\tglobal\tbrelop\r\n\r\nbrelop:\r\n\tpush\tde\r\n\tld\te,a\r\n\txor\tb\t\t;compare signs\r\n\tjp\tm,1f\t\t;if different, return sign of lhs\r\n\tld\ta,e\r\n\tsbc\ta,b\r\n\tpop\tde\r\n\tret\r\n1:\r\n\tld\ta,e\t\t;get sign of lhs\r\n\tand\t80h\t\t;mask out sign flag\r\n\tld\td,a\r\n\tld\ta,e\r\n\tsbc\ta,b\t\t;set carry flag if appropriate\r\n\tld\ta,d\r\n\tinc\ta\t\t;set sign flag as appropriate and reset Z flag\r\n\tpop\tde\r\n\tret\r\n"
  },
  {
    "path": "gen/BUILDGEN.SUB",
    "content": "c\r\n<-o -c \\\r\n<abs.as allsh.as alrsh.as asallsh.as asalrsh.as asar.as \\\r\n<asdiv.as asladd.as asland.as asll.as asllrsh.as \\\r\n<aslmul.as aslor.as aslr.as aslsub.as aslxor.as \\\r\n<asmod.as asmul.as atoi.as atol.c bitfield.as \\\r\n<blkclr.as blkcpy.c bmove.as brelop.as calloc.c csv.as \\\r\n<ctype.c ctype_.c frelop.as getsp.as idiv.as imul.as \\\r\n<index.as inout.as iregset.as isalpha.as isdigit.as \\\r\n<islower.as isspace.as isupper.as ladd.as land.as ldiv.as \\\r\n<linc.as llrsh.as lmul.as longjmp.as lor.as lrelop.as \\\r\n<lsub.as lxor.as malloc.c max.as memcmp.c memcpy.c \\\r\n<memset.c pnum.c qsort.c rand.c rcsv.as \\\r\n<rindex.as sbrk.as shar.as shll.as shlr.as strcat.as \\\r\n<strchr.as strcmp.as strcpy.as strlen.as strncat.as \\\r\n<strncmp.as strncpy.as strrchr.as swap.as tolower.as \\\r\n<toupper.as wrelop.as xtoi.as"
  },
  {
    "path": "gen/CALLOC.C",
    "content": "/*\r\n *\tcalloc - alloc space for n items of size s, and clear it to nulls\r\n */\r\n\r\nextern char * malloc();\r\nextern void\tfree(void *);\r\n\r\nchar *\r\ncalloc(n, s)\r\nregister int n, s;\r\n{\r\n\tregister char *cp;\r\n\r\n\tcp = malloc(n *= s);\r\n\tif(cp == (char *)0)\r\n\t\treturn((char *)0);\r\n\tif(n) {\r\n\t\t*cp = 0;\r\n\t\tif(--n)\r\n\t\t\tbmove(cp, &cp[1], n);\r\n\t}\r\n\treturn(cp);\r\n}\r\n\r\ncfree(s)\r\nvoid *\ts;\r\n{\r\n\tfree(s);\r\n}\r\n"
  },
  {
    "path": "gen/CSV.AS",
    "content": "\tglobal\tcsv,cret,indir, ncsv\r\n\tpsect\ttext\r\ncsv:\tpop\thl\t\t;return address\r\n\tpush\tiy\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\t\t;new frame pointer\r\n\tjp\t(hl)\r\n\r\ncret:\tld\tsp,ix\r\n\tpop\tix\r\n\tpop\tiy\r\n\tret\r\n\r\nindir:\tjp\t(hl)\r\n\r\n;\tNew csv: allocates space for stack based on word following\r\n;\tcall ncsv\r\n\r\nncsv:\r\n\tpop\thl\r\n\tpush\tiy\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tex\tde,hl\r\n\tadd\thl,sp\r\n\tld\tsp,hl\r\n\tex\tde,hl\r\n\tjp\t(hl)\r\n"
  },
  {
    "path": "gen/CTYPE.C",
    "content": "isdig(c)\r\n{\r\n\treturn(c >= '0' && c <= '9');\r\n}\r\n\r\n"
  },
  {
    "path": "gen/CTYPE_.C",
    "content": "#include\t<ctype.h>\r\n\r\nunsigned char _ctype_[] = {\r\n\t0,\r\n\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\r\n\t_C,\t_S,\t_S,\t_S,\t_S,\t_S,\t_C,\t_C,\r\n\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\r\n\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\t_C,\r\n\t_S,\t_P,\t_P,\t_P,\t_P,\t_P,\t_P,\t_P,\r\n\t_P,\t_P,\t_P,\t_P,\t_P,\t_P,\t_P,\t_P,\r\n\t_N,\t_N,\t_N,\t_N,\t_N,\t_N,\t_N,\t_N,\r\n\t_N,\t_N,\t_P,\t_P,\t_P,\t_P,\t_P,\t_P,\r\n\t_P,\t_U|_X,\t_U|_X,\t_U|_X,\t_U|_X,\t_U|_X,\t_U|_X,\t_U,\r\n\t_U,\t_U,\t_U,\t_U,\t_U,\t_U,\t_U,\t_U,\r\n\t_U,\t_U,\t_U,\t_U,\t_U,\t_U,\t_U,\t_U,\r\n\t_U,\t_U,\t_U,\t_P,\t_P,\t_P,\t_P,\t_P,\r\n\t_P,\t_L|_X,\t_L|_X,\t_L|_X,\t_L|_X,\t_L|_X,\t_L|_X,\t_L,\r\n\t_L,\t_L,\t_L,\t_L,\t_L,\t_L,\t_L,\t_L,\r\n\t_L,\t_L,\t_L,\t_L,\t_L,\t_L,\t_L,\t_L,\r\n\t_L,\t_L,\t_L,\t_P,\t_P,\t_P,\t_P,\t_C\r\n};\r\n"
  },
  {
    "path": "gen/FRELOP.AS",
    "content": ";\tfloating relational operation - returns flags as though\r\n;\ta floating subtract was done.\r\n\r\n\tpsect\ttext\r\n\tglobal\tfrelop\r\n\r\nfrelop:\r\n\texx\t\t\t;select\talternate reg set\r\n\tpop\thl\t\t;return\taddress\r\n\texx\t\t\t;get other set again\r\n\tpop\tbc\t\t;low word of 2nd arg\r\n\tex\tde,hl\t\t;put hi\tword of\t1st in de\r\n\tex\t(sp),hl\t\t;get hi\tword of\t2nd in hl\r\n\tex\tde,hl\t\t;hi word of 1st\tback in\thl\r\n\tld\ta,h\t\t;test for differing signs\r\n\txor\td\r\n\tjp\tp,2f\t\t;the same, so ok\r\n\tld\ta,h\t\t;get the sign of the LHS\r\n\tor\t1\t\t;ensure zero flag is reset, set sign flag\r\n\tpop\tbc\t\t;unjunk stack\r\n\tjr\t1f\t\t;return\twith sign of LHS\r\n2:\r\n\tld\ta,d\t\t;preserve sign flag\r\n\tres\t7,d\t\t;clear sign flag\r\n\tres\t7,h\t\t;and the other\r\n\tand\t80h\t\t;mask out sign flag\r\n\tsbc\thl,de\t\t;set the flags\r\n\tpop\thl\t\t;low word of 1st into hl again\r\n\tjr\tnz,togs\t\t;go fixup sign flag if different\r\n\tsbc\thl,bc\t\t;now set flags on basis\tof low word\r\n\tjr\tz,1f\t\t;if zero, all ok\r\ntogs:\r\n\trr\th\t\t;rotate\tcarry into sign\r\n\txor\th\t\t;toggle sign if necessary\r\n\tor\t1\t\t;reset zero flag\r\n1:\r\n\texx\t\t\t;get return address\r\n\tjp\t(hl)\t\t;and return with stack clean\r\n"
  },
  {
    "path": "gen/GETSP.AS",
    "content": ";\tReturn value of the stack pointer\r\n\r\n\tpsect\ttext\r\n\tglobal\t__getsp\r\n__getsp:\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\tret\r\n"
  },
  {
    "path": "gen/IDIV.AS",
    "content": ";\t16 bit divide and modulus routines\r\n\r\n;\tcalled with dividend in hl and divisor in de\r\n\r\n;\treturns with result in hl.\r\n\r\n;\tadiv (amod) is signed divide (modulus), ldiv (lmod) is unsigned\r\n\r\n\tglobal\tadiv,ldiv,amod,lmod\r\n\tpsect\ttext\r\n\r\namod:\r\n\tcall\tadiv\r\n\tex\tde,hl\t\t;put modulus in hl\r\n\tret\r\n\r\nlmod:\r\n\tcall\tldiv\r\n\tex\tde,hl\r\n\tret\r\n\r\nldiv:\r\n\txor\ta\r\n\tpush\taf\r\n\tex\tde,hl\r\n\tjr\tdv1\r\n\r\n\r\nadiv:\r\n\tld\ta,h\r\n\txor\td\t\t;set sign flag for quotient\r\n\tld\ta,h\t\t;get sign of dividend\r\n\tpush\taf\r\n\tcall\tnegif\r\n\tex\tde,hl\r\n\tcall\tnegif\r\ndv1:\tld\tb,1\r\n\tld\ta,h\r\n\tor\tl\r\n\tjr\tnz,dv8\r\n\tpop\taf\r\n\tret\r\n\r\ndv8:\tpush\thl\r\n\tadd\thl,hl\r\n\tjr\tc,dv2\r\n\tld\ta,d\r\n\tcp\th\r\n\tjr\tc,dv2\r\n\tjp\tnz,dv6\r\n\tld\ta,e\r\n\tcp\tl\r\n\tjr\tc,dv2\r\ndv6:\tpop\taf\r\n\tinc\tb\r\n\tjp\tdv8\r\n\r\ndv2:\tpop\thl\r\n\tex\tde,hl\r\n\tpush\thl\r\n\tld\thl,0\r\n\tex\t(sp),hl\r\n\r\ndv4:\tld\ta,h\r\n\tcp\td\r\n\tjr\tc,dv3\r\n\tjp\tnz,dv5\r\n\tld\ta,l\r\n\tcp\te\r\n\tjr\tc,dv3\r\n\r\ndv5:\tsbc\thl,de\r\ndv3:\tex\t(sp),hl\r\n\tccf\r\n\tadc\thl,hl\r\n\tsrl\td\r\n\trr\te\r\n\tex\t(sp),hl\r\n\tdjnz\tdv4\r\n\tpop\tde\r\n\tex\tde,hl\r\n\tpop\taf\r\n\tcall\tm,negat\r\n\tex\tde,hl\r\n\tor\ta\t\t\t;test remainder sign bit\r\n\tcall\tm,negat\r\n\tex\tde,hl\r\n\tret\r\n\r\nnegif:\tbit\t7,h\r\n\tret\tz\r\nnegat:\tld\tb,h\r\n\tld\tc,l\r\n\tld\thl,0\r\n\tor\ta\r\n\tsbc\thl,bc\r\n\tret\r\n"
  },
  {
    "path": "gen/IMUL.AS",
    "content": ";\t16 bit integer multiply\r\n\r\n;\ton entry, left operand is in hl, right operand in de\r\n\r\n\tpsect\ttext\r\n\tglobal\tamul,lmul\r\namul:\r\nlmul:\r\n\tld\ta,e\r\n\tld\tc,d\r\n\tex\tde,hl\r\n\tld\thl,0\r\n\tld\tb,8\r\n\tcall\tmult8b\r\n\tex\tde,hl\r\n\tjr\t3f\r\n2:\tadd\thl,hl\r\n3:\r\n\tdjnz\t2b\r\n\tex\tde,hl\r\n1:\r\n\tld\ta,c\r\nmult8b:\r\n\tsrl\ta\r\n\tjp\tnc,1f\r\n\tadd\thl,de\r\n1:\tex\tde,hl\r\n\tadd\thl,hl\r\n\tex\tde,hl\r\n\tret\tz\r\n\tdjnz\tmult8b\r\n\tret\r\n"
  },
  {
    "path": "gen/INDEX.AS",
    "content": "\tpsect\ttext\r\n\tglobal\trcsv, cret, _index\r\n\r\n_index:\tcall\trcsv\r\n\r\n\tjr\t3f\r\n1:\r\n\tinc\thl\r\n3:\r\n\tld\ta,(hl)\r\n\tor\ta\r\n\tjr\tz,2f\r\n\tcp\te\r\n\tjr\tnz,1b\r\n4:\tjp\tcret\r\n\r\n2:\tld\thl,0\r\n\tjp\t4b\r\n"
  },
  {
    "path": "gen/INOUT.AS",
    "content": "\tglobal\t_in, _out, _inp, _outp\r\n\tpsect\ttext\r\n\r\n_in:\r\n_inp:\r\n\tpop\thl\t\t;return address\r\n\tpop\tbc\t\t;port address\r\n\tpush\tbc\r\n\tpush\thl\r\n\tin\tl,(c)\t\t;read port\r\n\tld\th,0\t\t;zero extend it\r\n\tret\r\n\r\n_out:\r\n_outp:\r\n\tpop\thl\t\t;return address\r\n\tpop\tbc\t\t;port address\r\n\tpop\tde\t\t;data\r\n\tpush\tde\r\n\tpush\tbc\r\n\tpush\thl\r\n\tout\t(c),e\t\t;output the data\r\n\tld\tl,c\t\t;return value in hl also\r\n\tld\th,0\r\n\tret\r\n"
  },
  {
    "path": "gen/IREGSET.AS",
    "content": ";\troutines to support the assignment versions of the long operations\r\n\r\n\tpsect\ttext\r\n\tglobal\tiregset, iregstore\r\n\r\niregset:\r\n\tld\te,(hl)\t;pick up arg\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tex\t(sp),hl\t;save pointer, get return address\r\n\tpush\tbc\t;now put the hi word into hl\r\n\tex\t(sp),hl\t;saving return address on stack again\r\n\tpop\tbc\t;now return address in bc\r\n\texx\r\n\tpop\thl\t;the pointer\r\n\tpop\tbc\t;the final return address\r\n\tpop\tde\t;now the low word of arg2\r\n\tex\t(sp),hl\t;get the hi word, save pointer\r\n\tpush\tbc\t;this is the return address again\r\n\tex\t(sp),hl\t;into hl again\r\n\tpop\tbc\t;hi word now in bc\r\n\tex\t(sp),hl\t;AHA! got return address on stack, ptr in hl\r\n\tpush\thl\t;now its easy, save pointer\r\n\tpush\tbc\t;hi word\r\n\tpush\tde\t;low word\r\n\texx\r\n\tpush\tbc\t;immediate return address\r\n\tret\t\t;finito\r\n\r\niregstore:\r\n\tex\t(sp),hl\t;get pointer into hl\r\n\tpop\tbc\t;hi word in bc\r\n\tld\t(hl),b\r\n\tdec\thl\r\n\tld\t(hl),c\r\n\tdec\thl\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\t\t;all done\r\n\tpush\tbc\t;restore to hl\r\n\tpop\thl\r\n\tret\t\t;and return with value in hl\r\n"
  },
  {
    "path": "gen/ISALPHA.AS",
    "content": "\tglobal\t_isalpha\r\n\r\n\tpsect\ttext\r\n_isalpha:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tjr\tnz,nix\r\n\tld\ta,l\r\n\tcp\t'A'\r\n\tjr\tc,nix\r\n\tcp\t'z'+1\r\n\tjr\tnc,nix\r\n\tcp\t'a'\r\n\tcp\t'Z'+1\r\n\tjr\tc,yes\r\n\tcp\t'a'\r\n\tjr\tc,nix\r\nyes:\r\n\tld\thl,1\t\t;yes\r\n\tret\r\nnix:\tld\thl,0\r\n\tret\r\n"
  },
  {
    "path": "gen/ISDIGIT.AS",
    "content": "\tglobal\t_isdigit, _isdig\r\n\r\n\tpsect\ttext\r\n_isdigit:\r\n_isdig:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tjr\tnz,nix\r\n\tld\ta,l\r\n\tcp\t'0'\r\n\tjr\tc,nix\r\n\tcp\t'9'+1\r\n\tjr\tnc,nix\r\n\tld\thl,1\t\t;yes\r\n\tret\r\nnix:\tld\thl,0\r\n\tret\r\n"
  },
  {
    "path": "gen/ISLOWER.AS",
    "content": "\tglobal\t_islower\r\n\r\n\tpsect\ttext\r\n_islower:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tjr\tnz,nix\r\n\tld\ta,l\r\n\tcp\t'a'\r\n\tjr\tc,nix\r\n\tcp\t'z'+1\r\n\tjr\tnc,nix\r\n\tld\thl,1\t\t;yes\r\n\tret\r\nnix:\tld\thl,0\r\n\tret\r\n"
  },
  {
    "path": "gen/ISSPACE.AS",
    "content": "\tglobal\t_isspace\r\n\r\n\tpsect\ttext\r\n_isspace:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tjr\tnz,nix\r\n\tld\ta,l\r\n\tcp\t' '\r\n\tjr\tz,yes\r\n\tcp\t12\t\t;newline\r\n\tjr\tz,yes\r\n\tcp\t9\t\t;tab\r\n\tjr\tnz,nix\r\nyes:\r\n\tld\thl,1\t\t;yes\r\n\tret\r\nnix:\tld\thl,0\r\n\tret\r\n"
  },
  {
    "path": "gen/ISUPPER.AS",
    "content": "\tglobal\t_isupper\r\n\r\n\tpsect\ttext\r\n_isupper:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tjr\tnz,nix\r\n\tld\ta,l\r\n\tcp\t'A'\r\n\tjr\tc,nix\r\n\tcp\t'Z'+1\r\n\tjr\tnc,nix\r\n\tld\thl,1\t\t;yes\r\n\tret\r\nnix:\tld\thl,0\r\n\tret\r\n"
  },
  {
    "path": "gen/LADD.AS",
    "content": "\tpsect\ttext\r\n\tglobal\taladd, lladd\r\n\r\naladd:\r\nlladd:\r\n\texx\r\n\tpop\thl\r\n\texx\r\n\tpop\tbc\r\n\tex\tde,hl\r\n\tadd\thl,bc\r\n\tex\tde,hl\r\n\tpop\tbc\r\n\tadc\thl,bc\r\n\texx\r\n\tpush\thl\r\n\texx\r\n\tret\r\n"
  },
  {
    "path": "gen/LAND.AS",
    "content": "\tpsect\ttext\r\n\tglobal\taland, lland\r\n\r\naland:\r\nlland:\r\n\texx\r\n\tpop\thl\r\n\texx\r\n\tpop\tbc\r\n\tld\ta,c\r\n\tand\te\r\n\tld\te,a\r\n\tld\ta,b\r\n\tand\td\r\n\tld\td,a\r\n\tpop\tbc\r\n\tld\ta,c\r\n\tand\tl\r\n\tld\tl,a\r\n\tld\ta,b\r\n\tand\th\r\n\tld\th,a\r\n\texx\r\n\tpush\thl\r\n\texx\r\n\tret\r\n"
  },
  {
    "path": "gen/LDIV.AS",
    "content": ";\tLong division routines for Z80\r\n\r\n\r\n\r\n\tglobal\tlldiv,aldiv,almod,llmod,aslldiv,asaldiv,asllmod,asalmod\r\n\r\n\tpsect\ttext\r\n\r\n;\tCalled with dividend in HLDE, divisor on stack under 2 return\r\n;\taddresses. Returns with dividend in HL/HL', divisor in DE/DE'\r\n;\ton return the HIGH words are selected.\r\n\r\nlregset:\r\n\tpop\tbc\t\t\t;get top return address\r\n\texx\t\t\t\t;select other bank\r\n\tpop\tbc\t\t\t;return address of call to this module\r\n\tpop\tde\t\t\t;get low word of divisor\r\n\texx\t\t\t\t;select hi bank\r\n\tex\tde,hl\t\t\t;dividend.low -> hl\r\n\tex\t(sp),hl\t\t\t;divisor.high -> hl\r\n\tex\tde,hl\t\t\t;dividend.high -> hl\r\n\texx\t\t\t\t;back to low bank\r\n\tpush\tbc\t\t\t;put outer r.a. back on stack\r\n\tpop\thl\t\t\t;return address\r\n\tex\t(sp),hl\t\t\t;dividend.low -> hl\r\n\texx\r\n\tpush\tbc\t\t\t;top return address\r\n\tret\r\n\r\n;\tMuch the same as lregset, except that on entry the dividend\r\n;\tis pointed to by HL.\r\n;\tThe pointer is saved in iy for subsequent updating of memory\r\n\r\niregset:\r\n\tpop\tde\t\t\t;immediate return address\r\n\tcall\tlregset\t\t\t;returns with hi words selected\r\n\tpush\thl\t\t\t;save a copy for 'ron\r\n\tex\t(sp),iy\t\t\t;get it in iy, saving old iy\r\n\tld\th,(iy+3)\t\t;high order byte\r\n\tld\tl,(iy+2)\t\t;byte 2\r\n\texx\t\t\t\t;back to low bank\r\n\tpush\thl\t\t\t;return address\r\n\tld\th,(iy+1)\t\t;byte 1\r\n\tld\tl,(iy+0)\t\t;and LSB\r\n\texx\t\t\t\t;restore hi words\r\n\tret\t\t\t\t;now return\r\n\r\n;\tCalled with hi words selected, performs division on the absolute\r\n;\tvalues of the dividend and divisor. Quotient is positive\r\n\r\nsgndiv:\r\n\tcall\tnegif\t\t\t;make dividend positive\r\n\texx\r\n\tex\tde,hl\t\t\t;put divisor in HL/HL'\r\n\texx\r\n\tex\tde,hl\r\n\tcall\tnegif\t\t\t;make divisor positive\r\n\tex\tde,hl\t\t\t;restore divisor to DE/DE'\r\n\texx\r\n\tex\tde,hl\r\n\texx\t\t\t\t;select high words again\r\n\tjp\tdivide\t\t\t;do division\r\n\r\nasaldiv:\r\n\tcall\tiregset\r\n\tcall\tdosdiv\r\nstore:\r\n\tld\t(iy+0),e\r\n\tld\t(iy+1),d\r\n\tld\t(iy+2),l\r\n\tld\t(iy+3),h\r\n\tpop\tiy\t\t\t;restore old iy\r\n\tret\r\n\r\naldiv:\tcall\tlregset\t\t\t;get args\r\n\r\n;\tCalled with high words selected, performs signed division by\r\n;\tthe rule that the quotient is negative iff the signs of the dividend\r\n;\tand divisor differ\r\n;\treturns quotient in HL/DE\r\n\r\ndosdiv:\r\n\tld\ta,h\r\n\txor\td\r\n\tex\taf,af'\t\t\t;sign bit is now sign of quotient\r\n\tcall\tsgndiv\t\t\t;do signed division\r\n\tex\taf,af'\t\t\t;get sign flag back\r\n\tpush\tbc\t\t\t;high word\r\n\texx\r\n\tpop\thl\r\n\tld\te,c\t\t\t;low word of quotient\r\n\tld\td,b\r\n\tjp\tm,negat\t\t\t;negate quotient if necessary\r\n\tret\r\n\r\nlldiv:\tcall\tlregset\r\n\r\n;\tCalled with high words selected, performs unsigned division\r\n;\treturns with quotient in HL/DE\r\n\r\ndoudiv:\r\n\tcall\tdivide\t\t\t;unsigned division\r\n\tpush\tbc\t\t\t;high word of quotien\r\n\texx\r\n\tpop\thl\r\n\tld\te,c\t\t\t;low word\r\n\tld\td,b\r\n\tret\r\n\r\naslldiv:\r\n\tcall\tiregset\r\n\tcall\tdoudiv\r\n\tjp\tstore\r\n\r\n\r\nalmod:\r\n\tcall\tlregset\r\n\r\n;\tCalled with high words selected, performs signed modulus - the rule\r\n;\tis that the sign of the remainder is the sign of the dividend\r\n\r\ndosrem:\r\n\tld\ta,h\t\t\t;get sign of dividend\r\n\tex\taf,af'\t\t\t;save it\r\n\tcall\tsgndiv\t\t\t;do signed division\r\n\tpush\thl\t\t\t;high word\r\n\texx\r\n\tpop\tde\r\n\tex\tde,hl\t\t\t\t;put high word in hl\r\n\tex\taf,af'\t\t\t\t;get sign bit back\r\n\tor\ta\r\n\tjp\tm,negat\t\t\t;negate if necessary\r\n\tret\r\n\r\nasalmod:\r\n\tcall\tiregset\r\n\tcall\tdosrem\r\n\tjp\tstore\r\n\r\nllmod:\r\n\tcall\tlregset\r\n\r\n;\tCalled with high words selected, perform unsigned modulus\r\n\r\ndourem:\r\n\tcall\tdivide\r\n\tpush\thl\t\t\t;high word of remainder\r\n\texx\r\n\tpop\tde\r\n\tex\tde,hl\t\t\t\t;high word in hl\r\n\tret\r\n\r\nasllmod:\r\n\tcall\tiregset\r\n\tcall\tdourem\r\n\tjp\tstore\r\n\r\n;\tNegate the long in HL/DE\r\n\r\nnegat:\tpush\thl\t\t\t;save high word\r\n\tld\thl,0\r\n\tor\ta\r\n\tsbc\thl,de\r\n\tex\tde,hl\r\n\tpop\tbc\t\t\t;get high word back\r\n\tld\thl,0\r\n\tsbc\thl,bc\r\n\tret\t\t\t\t;finito\r\n\r\nnegif:\t;called with high word in HL, low word in HL'\r\n\t;returns with positive value\r\n\r\n\tbit\t7,h\t\t\t;check sign\r\n\tret\tz\t\t\t;already positive\r\n\texx\t\t\t\t;select low word\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tld\thl,0\r\n\tor\ta\r\n\tsbc\thl,bc\r\n\texx\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tld\thl,0\r\n\tsbc\thl,bc\r\n\tret\t\t\t\t;finito\r\n\r\n;\tCalled with dividend in HL/HL', divisor in DE/DE', high words in\r\n;\tselected register set\r\n;\treturns with quotient in BC/BC', remainder in HL/HL', high words\r\n;\tselected\r\n\r\ndivide:\r\n\tld\tbc,0\t\t\t;initialize quotient\r\n\tld\ta,e\t\t\t;check for zero divisor\r\n\tor\td\r\n\texx\r\n\tld\tbc,0\r\n\tor\te\r\n\tor\td\r\n\texx\t\t\t\t;restor high words\r\n\tret\tz\t\t\t;return with quotient == 0\r\n\tld\ta,1\t\t\t;loop count\r\n\tjp\t3f\t\t\t;enter loop in middle\r\n1:\r\n\tpush\thl\t\t\t;save divisor\r\n\texx\r\n\tpush\thl\t\t\t;low word\r\n\tor\ta\t\t\t;clear carry\r\n\tsbc\thl,de\t\t\t;subtract low word\r\n\texx\r\n\tsbc\thl,de\t\t\t;sbutract hi word\r\n\texx\r\n\tpop\thl\t\t\t;restore dividend\r\n\texx\r\n\tpop\thl\t\t\t;and hi word\r\n\tjr\tc,2f\t\t\t;finished - divisor is big enough\r\n\texx\r\n\tinc\ta\t\t\t;increment count\r\n\tex\tde,hl\t\t\t;put divisor in hl - still low word\r\n\tadd\thl,hl\t\t\t;shift left\r\n\tex\tde,hl\t\t\t\t;put back in de\r\n\texx\t\t\t\t;get hi word\r\n\tex\tde,hl\r\n\tadc\thl,hl\t\t\t;shift with carry\r\n\tex\tde,hl\r\n3:\r\n\tbit\t7,d\t\t\t;test for max divisor\r\n\tjp\tz,1b\t\t\t;loop if msb not set\r\n\r\n2:\t;arrive here with shifted divisor, loop count in a, and low words\r\n\t;selected\r\n\r\n\t\r\n3:\r\n\tpush\thl\t\t\t;save dividend\r\n\texx\r\n\tpush\thl\t\t\t;low word\r\n\tor\ta\t\t\t;clear carry\r\n\tsbc\thl,de\r\n\texx\r\n\tsbc\thl,de\r\n\texx\t\t\t\t;restore low word\r\n\tjp\tnc,4f\r\n\tpop\thl\t\t\t;restore low word of dividend\r\n\texx\r\n\tpop\thl\t\t\t;hi word\r\n\texx\t\t\t\t;restore low word\r\n\tjr\t5f\r\n4:\r\n\tinc\tsp\t\t\t;unjunk stack\r\n\tinc\tsp\r\n\tinc\tsp\r\n\tinc\tsp\r\n5:\r\n\tccf\t\t\t\t;complement carry bit\r\n\trl\tc\t\t\t;shift in carry bit\r\n\trl\tb\t\t\t;next byte\r\n\texx\t\t\t\t;hi word\r\n\trl\tc\r\n\trl\tb\r\n\tsrl\td\t\t\t;now shift divisor right\r\n\trr\te\r\n\texx\t\t\t\t;get low word back\r\n\trr\td\r\n\trr\te\r\n\texx\t\t\t\t;select hi word again\r\n\tdec\ta\t\t\t;decrement loop count\r\n\tjr\tnz,3b\r\n\tret\t\t\t\t;finished\r\n"
  },
  {
    "path": "gen/LIBCVER.C",
    "content": "#define VERSION \"3.09-18\"\r\n\r\nchar *_libcver =\r\n#ifdef Z280\r\n \"LIB280C \" VERSION;\r\n#else\r\n \"LIBC \" VERSION;\r\n#endif\r\n"
  },
  {
    "path": "gen/LINC.AS",
    "content": ";\tLong increment\r\n\r\n\tpsect\ttext\r\n\r\n\tglobal\tlainc, llinc, ladec, lldec\r\n\r\ngval:\r\n\texx\r\n\tpop\thl\t\t;return address\r\n\texx\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n\tpush\tde\t\t;lo word\r\n\tpush\tbc\t\t;hi word\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\texx\r\n\tpush\thl\t\t;return address\r\n\texx\r\n\tret\r\n\r\nlainc:\r\nllinc:\r\n\tcall\tgval\r\n\tld\tbc,1\r\n\tex\tde,hl\r\n\tadd\thl,bc\r\n\tex\tde,hl\r\n\tld\tc,0\r\n\tadc\thl,bc\r\n\r\nsval:\r\n\tex\t(sp),hl\r\n\tpop\tbc\r\n\tld\t(hl),b\r\n\tdec\thl\r\n\tld\t(hl),c\r\n\tdec\thl\r\n\tld\t(hl),d\r\n\tdec\thl\r\n\tld\t(hl),e\r\n\tpop\thl\t\t;restore original value\r\n\tpop\tde\r\n\tret\r\n\r\nlldec:\r\nladec:\r\n\tcall\tgval\r\n\tld\tbc,-1\r\n\tex\tde,hl\r\n\tadd\thl,bc\r\n\tex\tde,hl\r\n\tadc\thl,bc\r\n\tjr\tsval\r\n"
  },
  {
    "path": "gen/LLRSH.AS",
    "content": ";\tlogical long right shift\r\n;\tvalue in HLDE, count in B\r\n\r\n\tglobal\tllrsh\r\n\tpsect\ttext\r\n\r\nllrsh:\r\n\tld\ta,b\t\t;check for zero shift\r\n\tor\ta\r\n\tret\tz\r\n\tcp\t33\r\n\tjr\tc,1f\t\t;limit shift to 32 bits\r\n\tld\tb,32\r\n1:\r\n\tsrl\th\r\n\trr\tl\r\n\trr\td\r\n\trr\te\r\n\tdjnz\t1b\r\n\tret\r\n"
  },
  {
    "path": "gen/LMUL.AS",
    "content": ";\tLong multiplication for Z80\r\n\r\n;\tCalled with 1st arg in HLDE, 2nd arg on stack. Returns with\r\n;\tresult in HLDE, other argument removed from stack\r\n\r\n\tglobal\talmul, llmul\r\n\r\n\tpsect\ttext\r\nalmul:\r\nllmul:\r\n\tex\tde,hl\r\n\tex\t(sp),hl\t\t;return address now in hl\r\n\texx\r\n\tpop\tde\t\t;low word in de\r\n\tpop\tbc\t\t;low word of multiplier in bc\r\n\texx\r\n\tpop\tbc\t\t;hi word of multiplier\r\n\tpush\thl\t\t;restore return address\r\n\tld\thl,0\t\t;initialize product\r\n\texx\t\t\t;get lo words back\r\n\tld\thl,0\r\n\tld\ta,c\r\n\tld\tc,b\r\n\tcall\tmult8b\r\n\tld\ta,c\r\n\tcall\tmult8b\r\n\texx\r\n\tld\ta,c\r\n\texx\r\n\tcall\tmult8b\r\n\texx\r\n\tld\ta,b\r\n\texx\r\n\tcall\tmult8b\r\n\tpush\thl\t\t;low word\r\n\texx\r\n\tpop\tde\r\n\tret\r\n\r\nmult8b:\tld\tb,8\r\n3:\r\n\tsrl\ta\r\n\tjp\tnc,1f\r\n\tadd\thl,de\r\n\texx\r\n\tadc\thl,de\r\n\texx\r\n1:\tex\tde,hl\r\n\tadd\thl,hl\r\n\tex\tde,hl\r\n\texx\r\n\tex\tde,hl\r\n\tadc\thl,hl\r\n\tex\tde,hl\r\n\texx\r\n\tdjnz\t3b\r\n\tret\r\n"
  },
  {
    "path": "gen/LONGJMP.AS",
    "content": ";\tsetjump, longjump - non local goto\r\n\r\n\tpsect\ttext\r\n\tglobal\t_longjmp, _setjmp\r\n\r\n_setjmp:\r\n\tpop\tbc\t\t;return address\r\n\tex\t(sp),iy\t\t;jmp_buf ptr to IY\r\n\tpop\tde\t\t;old IY to DE\r\n\tpush\tde\t\t;keep stack balanced for return\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\tld\t(iy+0),l\t;save SP in jmp_buf\r\n\tld\t(iy+1),h\r\n\tpush\tix\r\n\tpop\thl\r\n\tld\t(iy+2),l\t;save IX (frame ptr) in jmp_buf\r\n\tld\t(iy+3),h\r\n\tld\t(iy+4),c\t;return address to jmp_buf\r\n\tld\t(iy+5),b\r\n\tld\t(iy+6),e\t;save IY in jmp_buf\r\n\tld\t(iy+7),d\r\n\tld\thl,0\t\t;setjmp returns 0\r\n\tpush\tde\t\t;restore IY\r\n\tpop\tiy\r\n\tpush\tbc\t\t;return address -> BC\r\n\tret\r\n\r\n_longjmp:\r\n\tpop\tbc\t\t; return address - junk now\r\n\tpop\tiy\t\t;jmp_buf ptr to IY\r\n\tpop\tde\t\t; return val in de as stack will change\r\n\tld\tl,(iy+0)\t;restore SP from jmp_buf\r\n\tld\th,(iy+1)\r\n\tld\tsp,hl\r\n\tld\tl,(iy+2)\t;restore IX (frame ptr) from jmp_buf\r\n\tld\th,(iy+3)\r\n\tpush\thl\r\n\tpop\tix\r\n\tld\tl,(iy+4)\t;return address\r\n\tld\th,(iy+5)\r\n\tpush\thl\r\n\tld\tc,(iy+6)\t;restore IY from jmp_buf\r\n\tld\tb,(iy+7)\r\n\tpush\tbc\r\n\tpop\tiy\r\n\tex\tde,hl\t\t;get arg into hl\r\n\tld\ta,l\r\n\tor\th\r\n\tret\tnz\t\t;not allowed to return 0\r\n\tinc\tl\r\n\tret\r\n"
  },
  {
    "path": "gen/LOR.AS",
    "content": "\tpsect\ttext\r\n\tglobal\talor, llor\r\n\r\nalor:\r\nllor:\r\n\texx\r\n\tpop\thl\r\n\texx\r\n\tpop\tbc\r\n\tld\ta,c\r\n\tor\te\r\n\tld\te,a\r\n\tld\ta,b\r\n\tor\td\r\n\tld\td,a\r\n\tpop\tbc\r\n\tld\ta,c\r\n\tor\tl\r\n\tld\tl,a\r\n\tld\ta,b\r\n\tor\th\r\n\tld\th,a\r\n\texx\r\n\tpush\thl\r\n\texx\r\n\tret\r\n"
  },
  {
    "path": "gen/LRELOP.AS",
    "content": ";\tlong relational\toperation - returns flags as though\r\n;\ta long subtract\twas done.\r\n\r\n\tpsect\ttext\r\n\tglobal\tlrelop,arelop\r\n\r\narelop:\r\nlrelop:\r\n\texx\t\t\t;select\talternate reg set\r\n\tpop\thl\t\t;return\taddress\r\n\texx\t\t\t;get other set again\r\n\tpop\tbc\t\t;low word of 2nd arg\r\n\tex\tde,hl\t\t;put hi\tword of\t1st in de\r\n\tex\t(sp),hl\t\t;get hi\tword of\t2nd in hl\r\n\tex\tde,hl\t\t;hi word of 1st\tback in\thl\r\n\tld\ta,h\t\t;test for differing signs\r\n\txor\td\r\n\tjp\tp,2f\t\t;the same, so ok\r\n\tld\ta,h\t\t;get the sign of the LHS\r\n\tor\t2\t\t;ensure zero flag is reset, set sign flag\r\n\tld\ta,d\t\t;get RHS\r\n\trla\t\t\t;rotate hi bit into carry - Z and S unchanged\r\n\tpop\thl\t\t;unjunk stack\r\n\tjp\t1f\t\t;return\twith sign of LHS\r\n2:\r\n\tor\ta\r\n\tsbc\thl,de\t\t;set the flags\r\n\tpop\thl\t\t;low word of 1st into hl again\r\n\tjr\tnz,1f\t\t;go return if not zero\r\n\tsbc\thl,bc\t\t;now set flags on basis\tof low word\r\n\tjr\tz,1f\t\t;if zero, all ok\r\n\tld\ta,2\t\t;make non-zero\r\n\trra\t\t\t;rotate\tcarry into sign\r\n\tor\ta\t\t;set minus flag\r\n\trlca\t\t\t;put carry flag\tback\r\n\r\n1:\r\n\texx\t\t\t;get return address\r\n\tjp\t(hl)\t\t;and return with stack clean\r\n"
  },
  {
    "path": "gen/LSUB.AS",
    "content": "\tpsect\ttext\r\n\tglobal\talsub, llsub\r\n\r\nalsub:\r\nllsub:\r\n\texx\r\n\tpop\thl\r\n\texx\r\n\tpop\tbc\r\n\tex\tde,hl\r\n\tor\ta\r\n\tsbc\thl,bc\r\n\tex\tde,hl\r\n\tpop\tbc\r\n\tsbc\thl,bc\r\n\texx\r\n\tpush\thl\r\n\texx\r\n\tret\r\n"
  },
  {
    "path": "gen/LXOR.AS",
    "content": "\tpsect\ttext\r\n\tglobal\talxor, llxor\r\n\r\nalxor:\r\nllxor:\r\n\texx\r\n\tpop\thl\r\n\texx\r\n\tpop\tbc\r\n\tld\ta,c\r\n\txor\te\r\n\tld\te,a\r\n\tld\ta,b\r\n\txor\td\r\n\tld\td,a\r\n\tpop\tbc\r\n\tld\ta,c\r\n\txor\tl\r\n\tld\tl,a\r\n\tld\ta,b\r\n\txor\th\r\n\tld\th,a\r\n\texx\r\n\tpush\thl\r\n\texx\r\n\tret\r\n"
  },
  {
    "path": "gen/MAKEFILE",
    "content": ".SUFFIXES:\t.c .as .obj\r\n\r\nCC\t= /usr/hitech/bin/zc\r\nAS\t= /usr/hitech/bin/zas\r\nLIBR\t= /usr/hitech/bin/libr\r\nCFLAGS\t= -O -x\r\nASFLAGS\t= -j -x\r\nLIB\t= ../../lib\r\nENHUFF\t= /usr/hitech/bin/enhuff\r\n\r\n.c.obj:\r\n\t$(CC) -c $(CFLAGS) $*.c\r\n.as.obj:\r\n\t$(AS) $(ASFLAGS) $*.as\r\n\r\nSRCS\t= abs.as allsh.as alrsh.as asallsh.as asalrsh.as asar.as \\\r\n\t  asdiv.as asladd.as asland.as asll.as asllrsh.as aslmul.as \\\r\n\t  aslor.as aslr.as aslsub.as aslxor.as asmod.as asmul.as \\\r\n\t  atoi.as atol.c bitfield.as blkclr.as blkcpy.c bmove.as \\\r\n\t  calloc.c csv.as ctype.c ctype_.c brelop.as wrelop.as frelop.as \\\r\n\t  getsp.as idiv.as imul.as index.as inout.as \\\r\n\t  iregset.as isalpha.as isdigit.as islower.as isspace.as isupper.as \\\r\n\t  ladd.as land.as ldiv.as linc.as llrsh.as lmul.as \\\r\n\t  longjmp.as lor.as lrelop.as lsub.as lxor.as malloc.c \\\r\n\t  max.as memcmp.c memcpy.c memset.c pnum.c  \\\r\n\t  qsort.c swap.as rand.c rcsv.as rindex.as sbrk.as shar.as \\\r\n\t  shll.as shlr.as strcat.as strchr.as strcmp.as strcpy.as \\\r\n\t  strlen.as strncat.as strncmp.as strncpy.as strrchr.as \\\r\n\t  tolower.as toupper.as xtoi.as\r\n\r\nOBJS\t= memcpy.obj memcmp.obj memset.obj \\\r\n\t  abs.obj asallsh.obj allsh.obj asalrsh.obj asar.obj \\\r\n\t  asdiv.obj asladd.obj asland.obj asll.obj asllrsh.obj \\\r\n\t  aslmul.obj aslor.obj aslsub.obj aslxor.obj asmod.obj \\\r\n\t  atoi.obj atol.obj bitfield.obj blkclr.obj blkcpy.obj calloc.obj \\\r\n\t  asmul.obj ctype_.obj getsp.obj index.obj strchr.obj \\\r\n\t  inout.obj iregset.obj isalpha.obj isdigit.obj \\\r\n\t  islower.obj isspace.obj isupper.obj ladd.obj land.obj \\\r\n\t  linc.obj llrsh.obj longjmp.obj lor.obj lrelop.obj frelop.obj \\\r\n\t  brelop.obj wrelop.obj lsub.obj lxor.obj malloc.obj idiv.obj max.obj \\\r\n\t  pnum.obj ldiv.obj qsort.obj swap.obj aslr.obj bmove.obj \\\r\n\t  imul.obj rand.obj alrsh.obj lmul.obj rindex.obj strrchr.obj \\\r\n\t  sbrk.obj shar.obj shll.obj shlr.obj strcat.obj \\\r\n\t  strcmp.obj strcpy.obj strlen.obj strncat.obj strncmp.obj \\\r\n\t  strncpy.obj csv.obj rcsv.obj sys.obj tolower.obj \\\r\n\t  toupper.obj xtoi.obj\r\n\r\nzlibc.lib:\t$(OBJS)\r\n\t\t-rm -f zlibc.lib\r\n\t\t$(LIBR) r zlibc.lib $(OBJS)\r\n\r\ninstall:\t$(LIB)/zlibc.lib\r\n\r\n$(LIB)/zlibc.lib:\tzlibc.lib\r\n\t\tcp zlibc.lib $(LIB)/zlibc.lib\r\n\r\nhuff:\r\n\t-rm gen.huf\r\n\t$(ENHUFF) -a gen.huf Makefile $(SRCS)\r\n"
  },
  {
    "path": "gen/MALLOC.C",
    "content": "#ifdef debug\r\n#define ASSERT(p) if(!(p))botch(\"p\");else\r\nbotch(s)\r\nchar *s;\r\n{\r\n\tprintf(\"assertion botched: %s\\n\",s);\r\n\tabort();\r\n}\r\n#else\r\n#define ASSERT(p)\r\n#endif\r\n\r\n/*\tC storage allocator for Z80 and other 8 bit machines\r\n *\tcircular first-fit strategy\r\n *\tworks with noncontiguous, but monotonically linked, arena\r\n *\teach block is preceded by a ptr to the (pointer of) \r\n *\tthe next following block and a busy flag\r\n *\tbit in flag is 1 for busy, 0 for idle\r\n *\tgaps in arena are merely noted as busy blocks\r\n *\tlast block of arena (pointed to by alloct) is empty and\r\n *\thas a pointer to first\r\n *\tidle blocks are coalesced during space search\r\n *\r\n*/\r\n#define\tBLOCK\t(85*sizeof(struct store))\t/* 255 bytes */\r\n#define BUSY 1\r\n#define NULL 0\r\n#define\ttestbusy(p)\t((p).flag & BUSY)\r\n#define\tsbusy(p)\t(p).flag |= BUSY\r\n#define\tcbusy(p)\t(p).flag &= ~BUSY\r\n\r\nstruct store\r\n{\r\n\tstruct store *\tptr;\r\n\tchar\t\tflag;\r\n};\r\n\r\nstatic struct store\tallocs[2];\t/*initial arena*/\r\nstatic struct store *\tallocp;\t\t/*search ptr*/\r\nstatic struct store *\talloct;\t\t/*arena top*/\r\nstatic struct store\tallocx;\t\t/* for realloc */\r\nchar *\t\t\tsbrk();\r\n\r\nchar *\r\nmalloc(nw)\r\nunsigned nw;\r\n{\r\n\tregister struct store *p, *q;\r\n\tstatic unsigned temp;\t/*coroutines assume no auto*/\r\n\r\n\tif(allocs[0].ptr==(struct store *)0) {\t/*first time*/\r\n\t\talloct = allocs[0].ptr = &allocs[1];\r\n\t\tallocp = allocs[1].ptr = &allocs[0];\r\n\t\tsbusy(allocs[0]);\r\n\t\tsbusy(allocs[1]);\r\n\t}\r\n\tnw = ((nw - 1 + sizeof(struct store)*2)/sizeof(struct store)) * sizeof(struct store);\r\n\tASSERT(allocp>=allocs && allocp<=alloct);\r\n\tASSERT(allock());\r\n\tfor(p=allocp; ; ) {\r\n\t\tfor(temp=0; ; ) {\r\n\t\t\tif(!testbusy(*p)) {\r\n\t\t\t\twhile(!testbusy(*(q=p->ptr))) {\r\n\t\t\t\t\tASSERT(q>p&&q<alloct);\r\n\t\t\t\t\tp->ptr = q->ptr;\r\n\t\t\t\t}\r\n\t\t\t\tif(q>=(struct store *)((char *)p+nw) && (struct store *)((char *)p+nw)>=p)\r\n\t\t\t\t\tgoto found;\r\n\t\t\t}\r\n\t\t\tq = p;\r\n\t\t\tp = p->ptr;\r\n\t\t\tif(p>q)\r\n\t\t\t\tASSERT(p<=alloct);\r\n\t\t\telse if(q!=alloct || p!=allocs) {\r\n\t\t\t\tASSERT(q==alloct&&p==allocs);\r\n\t\t\t\treturn(NULL);\r\n\t\t\t} else if(++temp>1)\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\ttemp = ((nw+sizeof(struct store)-1+BLOCK)/BLOCK)*BLOCK;\r\n\t\tq = (struct store *)sbrk(0);\r\n\t\tif((struct store *)((char *)q+temp) < q) {\r\n\t\t\treturn(NULL);\r\n\t\t}\r\n\t\tq = (struct store *)sbrk(temp);\r\n\t\tif((int)q == -1) {\r\n\t\t\treturn(NULL);\r\n\t\t}\r\n\t\tASSERT(q>alloct);\r\n\t\talloct->ptr = q;\r\n\t\tif(q!=alloct+1)\r\n\t\t\tsbusy(*alloct);\r\n\t\telse\r\n\t\t\tcbusy(*alloct);\r\n\t\talloct = q->ptr = (struct store *)((char *)q+temp-sizeof(struct store));;\r\n\t\talloct->ptr = allocs;\r\n\t\tsbusy(*alloct);\r\n\t\tcbusy(*q);\r\n\t}\r\nfound:\r\n\tallocp = (struct store *)((char *)p + nw);\r\n\tASSERT(allocp<=alloct);\r\n\tif(q>allocp) {\r\n\t\tallocx = *allocp;\r\n\t\tallocp->ptr = p->ptr;\r\n\t\tallocp->flag = 0;\r\n\t}\r\n\tp->ptr = allocp;\r\n\tsbusy(*p);\r\n\treturn((char *)(p+1));\r\n}\r\n\r\n/*\tfreeing strategy tuned for LIFO allocation\r\n*/\r\nfree(ap)\r\nchar *ap;\r\n{\r\n\tregister struct store *p;\r\n\r\n\tp = ((struct store *)ap)-1;\r\n\tASSERT(p>allocs[1].ptr&&p<=alloct);\r\n\tASSERT(allock());\r\n\tallocp = p;\r\n\tASSERT(testbusy(*p));\r\n\tcbusy(*p);\r\n\tASSERT(p->ptr > allocp && p->ptr <= alloct);\r\n}\r\n\r\nchar *\r\nrealloc(p, nbytes)\r\nchar *\t\tp;\r\nunsigned short\tnbytes;\r\n{\r\n\tregister struct store *\txp, * q;\r\n\tunsigned short\t\tons;\r\n\tunsigned short\t\tns;\r\n\r\n\txp = (struct store *)p;\r\n\tns = (nbytes + sizeof(struct store) - 1)/sizeof(struct store);\r\n\tons = xp[-1].ptr - xp;\r\n\tif(testbusy(xp[-1]))\r\n\t\tfree((char *)xp);\r\n\tif(!(q = (struct store *)malloc(nbytes)) || q == xp)\r\n\t\treturn (char *)q;\r\n\tns = q[-1].ptr - q;\r\n\tif(ons > ns)\r\n\t\tons = ns;\r\n\tbmove((char *)xp, (char *)q, ons * sizeof(struct store));\r\n\tif(q < xp && q+ns > xp)\r\n\t\tq[q+ns-xp] = allocx;\r\n\treturn (char *)q;\r\n}\r\n\r\n\r\n#ifdef\tdebug\r\nshowall()\r\n{\r\n\tstruct store *p, *q;\r\n\tint i, used = 0, free = 0;\r\n\r\n\tfor(p = &allocs[0] ; p && p!= alloct ; p = q) {\r\n\t\tq = p->ptr;\r\n\t\tprintf(\"%4.4x %5d %s\\n\", p, i = (unsigned)q - (unsigned)p,\r\n\t\t\ttestbusy(*p) ? \"BUSY\" : \"FREE\");\r\n\t\tif(testbusy(*p))\r\n\t\t\tused += i;\r\n\t\telse\r\n\t\t\tfree += i;\r\n\t}\r\n\tprintf(\"%d used, %d free, %4.4x end\\n\", used, free, alloct);\r\n}\r\n#endif\r\n"
  },
  {
    "path": "gen/MAX.AS",
    "content": "\tglobal\t_max\r\n\tpsect\ttext\r\n\r\n_max:\r\n\tpop\tbc\t\t;return address\r\n\tpop\tde\t\t;arg 1\r\n\tpop\thl\t\t;arg 2\r\n\tpush\thl\r\n\tpush\tde\r\n\tpush\tbc\r\n\tpush\thl\t\t;save it\r\n\tor\ta\t\t;clear carry\r\n\tsbc\thl,de\t\t;compare\r\n\tpop\thl\t\t;restore\r\n\tret\tnc\t\t;return if greater or equal\r\n\tex\tde,hl\t\t;otherwise returnt the other\r\n\tret\r\n"
  },
  {
    "path": "gen/MEMCMP.C",
    "content": "\r\nmemcmp(s1, s2, n)\r\nregister char *\ts1, * s2;\r\nregister int\tn;\r\n{\r\n\tshort\ti;\r\n\r\n\twhile(n--)\r\n\t\tif(i = *s1++ - *s2++)\r\n\t\t\treturn i;\r\n\treturn 0;\r\n}\r\n"
  },
  {
    "path": "gen/MEMCPY.C",
    "content": "memcpy(d, s, n)\r\nregister char *\td, * s;\r\nregister int\tn;\r\n{\r\n\twhile(n--)\r\n\t\t*d++ = *s++;\r\n}\r\n"
  },
  {
    "path": "gen/MEMSET.C",
    "content": "/*------------------------------------------------------------------------*\\\r\n | memset()\r\n |\r\n |\tThis is the original Hi-Tech code for memset():\r\n |\r\n |\t\tmemset(p, n, c)\r\n |\t\tregister char *\tp;\r\n |\t\tregister int\tn;\r\n |\t\tchar\t\tc;\r\n |\t\t{\r\n |\t\t\twhile(n--)\r\n |\t\t\t\t*p++ = c;\r\n |\t\t}\r\n |\r\n |\tThe declaration of memset() in string.h is:\r\n |\r\n |\t\tvoid *memset(void *, int, size_t);\r\n |\r\n |\twhich is correct but which does not agree with the implementation.\r\n |\tThe problem with the Hi-Tech code is that the parameters are in the\r\n |\twrong order and that causes serious problems.\r\n |\r\n |\tHerewith an implementation which matches the declaration and which\r\n |\tconforms to the standard definition for memset().\r\n |\r\n |\tJon Saxton\r\n |\tSeptember 2012\r\n\\*-------------------------------------------------------------------------*/\r\n\r\n#include <string.h>\r\n\r\nvoid *memset(void *mem, int fill, size_t bytes)\r\n{\r\n\tunsigned char\r\n\t\t*v = (unsigned char *)mem;\r\n\twhile (bytes--)\r\n\t\t*v++ = fill;\r\n\treturn mem;\r\n}\r\n \r\n \r\n"
  },
  {
    "path": "gen/PNUM.C",
    "content": "/*\r\n *\tFormatted number printing for Z80 printf and debugger\r\n */\r\n#define\tNDIG\t30\t\t/* max number of digits to be printed */\r\n#define\tputch(x)\t(*pputch)(x)\r\n\r\n_pnum(i, f, w, s, base, pputch)\r\nunsigned long\ti;\r\nunsigned char\tbase;\r\nvoid\t(*pputch)();\r\nunsigned char\ts;\r\nchar\tf, w;\r\n{\r\n\tregister char *\tcp;\r\n\tunsigned char\tfw;\r\n\tchar\t\tbuf[NDIG];\r\n\r\n\tif(f > NDIG)\r\n\t\tf = NDIG;\r\n\r\n\tif(s && (long)i < 0)\r\n\t\ti = -i;\r\n\telse\r\n\t\ts = 0;\r\n\tif(f == 0 && i == 0)\r\n\t\tf++;\r\n\r\n\tcp = &buf[NDIG];\r\n\twhile(i || f > 0) {\r\n\t\t*--cp = \"0123456789ABCDEF\"[i%base];\r\n\t\ti /= base;\r\n\t\tf--;\r\n\t}\r\n\tfw = f = (&buf[NDIG] - cp) + s;\r\n\tif(fw < w)\r\n\t\tfw = w;\r\n\twhile(w-- > f)\r\n\t\tputch(' ');\r\n\tif(s) {\r\n\t\tputch('-');\r\n\t\tf--;\r\n\t}\r\n\twhile(f--)\r\n\t\tputch(*cp++);\r\n\treturn fw;\r\n}\r\n"
  },
  {
    "path": "gen/QSORT.C",
    "content": "/*\r\n *\tQuicksort based on the algorithm given in\r\n *\t\"Algorithms + Data Structures = Programs\" by N. Wirth.\r\n */\r\n\r\nqsort(base, nel, width, compar)\r\nchar *base; int (*compar)();\r\nunsigned width,nel;\r\n{\r\n\tregister char *\tx;\r\n\textern char *\tmalloc();\r\n\tregister int\ti,j,l,r;\r\n\tstruct\r\n\t{\r\n\t\tint\tl,r;\r\n\t}\tstack[20];\r\n\tint\ts;\r\n\tchar\txbuf[800];\r\n\r\n\tif(width < sizeof xbuf)\r\n\t\tx = xbuf;\r\n\telse if(!(x = malloc(width+1)))\r\n\t\treturn;\t\t\t/* can't do much */\r\n\tx[width] = 0;\r\n\ts = 0;\r\n\tstack[0].l = 0;\r\n\tstack[0].r = nel-1;\r\n\tdo {\r\n\t\t/* take top request from stack */\r\n\t\tl = stack[s].l;\r\n\t\tr = stack[s--].r;\r\n\r\n\t\tdo {\r\n\t\t\ti = l;\r\n\t\t\tj = r;\r\n\t\t\tbmove(base+width*((i+j)/2), x, width);\r\n\t\t\tdo {\r\n\t\t\t\twhile((*compar)(base+i*width, x) < 0)\r\n\t\t\t\t\ti++;\r\n\t\t\t\twhile((*compar)(x, base+j*width) < 0)\r\n\t\t\t\t\tj--;\r\n\t\t\t\tif(i <= j) {\r\n\t\t\t\t\t_swap(width, base+i*width, base+j*width);\r\n\t\t\t\t\ti++;\r\n\t\t\t\t\tj--;\r\n\t\t\t\t}\r\n\t\t\t} while(i <= j);\r\n\t\t\tif(j-l < r-i) {\r\n\t\t\t\tif(i < r) {\t/* stack right partition */\r\n\t\t\t\t\tstack[++s].l = i;\r\n\t\t\t\t\tstack[s].r = r;\r\n\t\t\t\t}\r\n\t\t\t\tr = j;\t\t/* continue with left */\r\n\t\t\t} else {\r\n\t\t\t\tif(l < j) {\r\n\t\t\t\t\tstack[++s].l = l;\r\n\t\t\t\t\tstack[s].r = j;\r\n\t\t\t\t}\r\n\t\t\t\tl = i;\r\n\t\t\t}\r\n\t\t} while(l < r);\r\n\t} while(s >= 0);\r\n\tif(x != xbuf)\r\n\t\tfree(x);\r\n}\r\n"
  },
  {
    "path": "gen/RAND.C",
    "content": "static\tlong\trandx = 1;\r\n\r\nsrand(x)\r\nunsigned x;\r\n{\r\n\trandx = x;\r\n}\r\n\r\nrand()\r\n{\r\n\treturn(((randx = randx*1103515245L + 12345)>>16) & 077777);\r\n}\r\n"
  },
  {
    "path": "gen/RCSV.AS",
    "content": "\tglobal\trcsv\r\n\r\nARG\tequ\t6\t\t;offset of 1st arg\r\n\tpsect\ttext\r\nrcsv:\r\n\tex\t(sp),iy\t\t;save iy, get return address\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\t\t;new frame pointer\r\n\tld\tl,(ix+ARG+0)\r\n\tld\th,(ix+ARG+1)\r\n\tld\te,(ix+ARG+2)\r\n\tld\td,(ix+ARG+3)\r\n\tld\tc,(ix+ARG+4)\r\n\tld\tb,(ix+ARG+5)\r\n\tjp\t(iy)\r\n"
  },
  {
    "path": "gen/RINDEX.AS",
    "content": "\tpsect\ttext\r\n\tglobal\trcsv, cret, _rindex\r\n\r\n_rindex:\r\n\tcall\trcsv\r\n\r\n\tld\tbc,0\r\n\tjr\t5f\r\n6:\r\n\tinc\thl\r\n\tinc\tbc\r\n5:\r\n\tld\ta,(hl)\r\n\tor\ta\r\n\tjr\tnz,6b\r\n1:\r\n\tdec\thl\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,2f\r\n\tdec\tbc\r\n\tld\ta,(hl)\r\n\tcp\te\r\n\tjr\tnz,1b\r\n4:\tjp\tcret\r\n\r\n2:\tld\thl,0\r\n\tjp\t4b\r\n"
  },
  {
    "path": "gen/SBRK.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_sbrk,__Hbss, _brk, _checksp\r\n\r\n;\tNB This brk() does not check that the argument is reasonable.\r\n\r\n_brk:\r\n\tpop\thl\t;return address\r\n\tpop\tde\t;argument\r\n\tld\t(memtop),de\t;store it\r\n\tpush\tde\t\t;adjust stack\r\n\tjp\t(hl)\t;return\r\n_sbrk:\r\n\tpop\tbc\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\tbc\r\n\tld\thl,(memtop)\r\n\tld\ta,l\r\n\tor\th\r\n\tjr\tnz,1f\r\n\tld\thl,__Hbss\r\n\tld\t(memtop),hl\r\n1:\r\n\tadd\thl,de\r\n\tjr\tc,2f\t\t;if overflow, no room\r\n\tld\tbc,1024\t\t;allow 1k bytes stack overhead\r\n\tadd\thl,bc\r\n\tjr\tc,2f\t\t;if overflow, no room\r\n\tsbc\thl,sp\r\n\tjr\tc,1f\r\n2:\r\n\tld\thl,-1\t\t;no room at the inn\r\n\tret\r\n\r\n1:\tld\thl,(memtop)\r\n\tpush\thl\r\n\tadd\thl,de\r\n\tld\t(memtop),hl\r\n\tpop\thl\r\n\tret\r\n\r\n_checksp:\r\n\tld\thl,(memtop)\r\n\tld\tbc,128\r\n\tadd\thl,bc\r\n\tsbc\thl,sp\r\n\tld\thl,1\t\t;true if ok\r\n\tret\tc\t\t;if carry, sp > memtop+128\r\n\tdec\thl\t\t;make into 0\r\n\tret\r\n\r\n\tpsect\tbss\r\nmemtop:\tdefs\t2\r\n"
  },
  {
    "path": "gen/SHAR.AS",
    "content": ";\tShift operations - the count is always in B,\r\n;\tthe quantity to be shifted is in HL, except for the assignment\r\n;\ttype operations, when it is in the memory location pointed to by\r\n;\tHL\r\n\r\n\tglobal\tshar\t;shift arithmetic right\r\n\tpsect\ttext\r\n\r\n\r\nshar:\r\n\tld\ta,b\t\t;check for zero shift\r\n\tor\ta\r\n\tret\tz\r\n\tcp\t16\t\t;16 bits is maximum shift\r\n\tjr\tc,1f\t\t;is ok\r\n\tld\tb,16\r\n1:\r\n\tsra\th\r\n\trr\tl\r\n\tdjnz\t1b\r\n\tret\r\n"
  },
  {
    "path": "gen/SHLL.AS",
    "content": ";\tShift operations - the count is always in B,\r\n;\tthe quantity to be shifted is in HL, except for the assignment\r\n;\ttype operations, when it is in the memory location pointed to by\r\n;\tHL\r\n\r\n\tglobal\tshll,shal\t;shift left, arithmetic or logical\r\n\tpsect\ttext\r\n\r\n\r\nshll:\r\nshal:\r\n\tld\ta,b\t\t;check for zero shift\r\n\tor\ta\r\n\tret\tz\r\n\tcp\t16\t\t;16 bits is maximum shift\r\n\tjr\tc,1f\t\t;is ok\r\n\tld\tb,16\r\n1:\r\n\tadd\thl,hl\t\t;shift left\r\n\tdjnz\t1b\r\n\tret\r\n"
  },
  {
    "path": "gen/SHLR.AS",
    "content": ";\tShift operations - the count is always in B,\r\n;\tthe quantity to be shifted is in HL, except for the assignment\r\n;\ttype operations, when it is in the memory location pointed to by\r\n;\tHL\r\n\r\n\tglobal\tshlr\t;shift logical right\r\n\tpsect\ttext\r\n\r\n\r\nshlr:\r\n\tld\ta,b\t\t;check for zero shift\r\n\tor\ta\r\n\tret\tz\r\n\tcp\t16\t\t;16 bits is maximum shift\r\n\tjr\tc,1f\t\t;is ok\r\n\tld\tb,16\r\n1:\r\n\tsrl\th\r\n\trr\tl\r\n\tdjnz\t1b\r\n\tret\r\n"
  },
  {
    "path": "gen/STRCAT.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strcat\r\n\r\n_strcat:\r\n\tpop\tbc\r\n\tpop\tde\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tpush\tbc\r\n\tld\tc,e\t\t;save destination pointer\r\n\tld\tb,d\r\n\r\n1:\tld\ta,(de)\r\n\tor\ta\r\n\tjr\tz,2f\r\n\tinc\tde\r\n\tjr\t1b\r\n\r\n2:\tld\ta,(hl)\r\n\tld\t(de),a\r\n\tor\ta\r\n\tjr\tz,3f\r\n\tinc\tde\r\n\tinc\thl\r\n\tjr\t2b\r\n\r\n3:\r\n\tld\tl,c\t;restore destination\r\n\tld\th,b\r\n\tret\r\n"
  },
  {
    "path": "gen/STRCHR.AS",
    "content": "; strchr(char *s, int c)\r\n; version that can find the closing \\0 by Arnold M\r\n\r\n\tpsect\ttext\r\n\tglobal\trcsv, cret, _strchr\t; also equivalent to _index\r\n\r\n_strchr:\r\n\tpop\tbc\r\n\tpop\thl\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\thl\r\n\tpush\tbc\r\n\r\n\tjr\t3f\r\n1:\r\n\tinc\thl\r\n3:\r\n\tld\ta,(hl)\r\n\tcp\te ; check for a match first, e may be zero\r\n\tret\tz\r\n\r\n\tor\ta\r\n\tjr\tnz,1b\r\n\tld\thl,0\r\n\tret\r\n"
  },
  {
    "path": "gen/STRCMP.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strcmp\r\n\r\n_strcmp:\tpop\tbc\r\n\tpop\tde\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tpush\tbc\r\n\r\n1:\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,2f\r\n\tinc\tde\r\n\tinc\thl\r\n\tor\ta\r\n\tjr\tnz,1b\r\n\tld\thl,0\r\n\tret\r\n\r\n2:\tld\thl,1\r\n\tret\tnc\r\n\tdec\thl\r\n\tdec\thl\r\n\tret\r\n"
  },
  {
    "path": "gen/STRCPY.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strcpy\r\n\r\n_strcpy:\tpop\tbc\r\n\tpop\tde\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tpush\tbc\r\n\tld\tc,e\r\n\tld\tb,d\t\t;save destination pointer\r\n\r\n1:\tld\ta,(hl)\r\n\tld\t(de),a\r\n\tinc\tde\r\n\tinc\thl\r\n\tor\ta\r\n\tjr\tnz,1b\r\n\tld\tl,c\r\n\tld\th,b\r\n\tret\r\n"
  },
  {
    "path": "gen/STRDUP.C",
    "content": "#include <string.h>\r\nextern char *malloc();\r\n\r\nchar * strdup(char * str)\r\n{\r\n  char *dup;\r\n\r\n  if ( (dup = malloc(strlen(str)+1)) ) /* add one for the closing \\0 */\r\n    return strcpy(dup, str);\r\n  return (dup);\r\n}\r\n"
  },
  {
    "path": "gen/STRFTIME.C",
    "content": "/**\r\n *\r\n * strftime.c\r\n *\r\n * implements the ansi c function strftime()\r\n *\r\n * written 6 september 1989 by jim nutt\r\n * released into the public domain by jim nutt\r\n *\r\n * modified 21-Oct-89 by Rob Duff\r\n *\r\n**/\r\n\r\n#ifndef TZNAME\r\n#define TZNAME \"GMT\"    /* define TZNAME to override to your timezone */\r\n#endif\r\n\r\n#include <stddef.h>     /* for size_t */\r\n#include <stdarg.h>     /* for va_arg */\r\n#include <time.h>       /* for struct tm */\r\n\r\n/*\r\n** The following line should be appended to TIME.H.\r\n** Also copy size_t define from STRING.H.\r\n*/\r\n/* \r\nextern size_t strftime(char *s, size_t maxs, char *f, struct tm *t);\r\n*/\r\n\r\nstatic char *aday[] = {\r\n    \"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"\r\n};\r\n\r\nstatic char *day[] = {\r\n    \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\",\r\n    \"Thursday\", \"Friday\", \"Saturday\"\r\n};\r\n\r\nstatic char *amonth[] = {\r\n    \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\r\n    \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"\r\n};\r\n\r\nstatic char *month[] = {\r\n    \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\r\n    \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"\r\n};\r\n\r\nstatic char buf[26];\r\n\r\nstatic void strfmt(char *str, char *fmt, ...);\r\n\r\n/**\r\n *\r\n * size_t strftime(char *str,\r\n *                 size_t maxs,\r\n *                 const char *fmt,\r\n *                 const struct tm *t)\r\n *\r\n *      this functions acts much like a sprintf for time/date output.\r\n *      given a pointer to an output buffer, a format string and a\r\n *      time, it copies the time to the output buffer formatted in\r\n *      accordance with the format string.  the parameters are used\r\n *      as follows:\r\n *\r\n *          str is a pointer to the output buffer, there should\r\n *          be at least maxs characters available at the address\r\n *          pointed to by str.\r\n *\r\n *          maxs is the maximum number of characters to be copied\r\n *          into the output buffer, included the '\\0' terminator\r\n *\r\n *          fmt is the format string.  a percent sign (%) is used\r\n *          to indicate that the following character is a special\r\n *          format character.  the following are valid format\r\n *          characters:\r\n *\r\n *              %A      full weekday name (Monday)\r\n *              %a      abbreviated weekday name (Mon)\r\n *              %B      full month name (January)\r\n *              %b      abbreviated month name (Jan)\r\n *              %c      standard date and time representation\r\n *              %d      day-of-month (01-31)\r\n *              %H      hour (24 hour clock) (00-23)\r\n *              %I      hour (12 hour clock) (01-12)\r\n *              %j      day-of-year (001-366)\r\n *              %M      minute (00-59)\r\n *              %m      month (01-12)\r\n *              %p      local equivalent of AM or PM\r\n *              %S      second (00-59)\r\n *              %U      week-of-year, first day sunday (00-53)\r\n *              %W      week-of-year, first day monday (00-53)\r\n *              %w      weekday (0-6, sunday is 0)\r\n *              %X      standard time representation\r\n *              %x      standard date representation\r\n *              %Y      year with century\r\n *              %y      year without century (00-99)\r\n *              %Z      timezone name\r\n *              %%      percent sign\r\n *\r\n *      the standard date string is equivalent to:\r\n *\r\n *          %a %b %d %Y\r\n *\r\n *      the standard time string is equivalent to:\r\n *\r\n *          %H:%M:%S\r\n *\r\n *      the standard date and time string is equivalent to:\r\n *\r\n *          %a %b %d %H:%M:%S %Y\r\n *\r\n *      strftime returns the number of characters placed in the\r\n *      buffer, not including the terminating \\0, or zero if more\r\n *      than maxs characters were produced.\r\n *\r\n**/\r\n\r\nsize_t strftime(char *s, size_t maxs, char *f, struct tm *t)\r\n{\r\n      int w;\r\n      char *p, *q, *r;\r\n\r\n      p = s;\r\n      q = s + maxs - 1;\r\n      while ((*f != '\\0'))\r\n      {\r\n            if (*f++ == '%')\r\n            {\r\n                  r = buf;\r\n                  switch (*f++)\r\n                  {\r\n                  case '%' :\r\n                        r = \"%\";\r\n                        break;\r\n\r\n                  case 'a' :\r\n                        r = aday[t->tm_wday];\r\n                        break;\r\n\r\n                  case 'A' :\r\n                        r = day[t->tm_wday];\r\n                        break;\r\n\r\n                  case 'b' :\r\n                        r = amonth[t->tm_mon];\r\n                        break;\r\n\r\n                  case 'B' :\r\n                        r = month[t->tm_mon];\r\n                        break;\r\n\r\n                  case 'c' :\r\n                        strfmt(r, \"%0 %0 %2 %2:%2:%2 %4\",\r\n                              aday[t->tm_wday], amonth[t->tm_mon],\r\n                              t->tm_mday,t->tm_hour, t->tm_min,\r\n                              t->tm_sec, t->tm_year+1900);\r\n                        break;\r\n\r\n                  case 'd' :\r\n                        strfmt(r,\"%2\",t->tm_mday);\r\n                        break;\r\n\r\n                  case 'H' :\r\n                        strfmt(r,\"%2\",t->tm_hour);\r\n                        break;\r\n\r\n                  case 'I' :\r\n                        strfmt(r,\"%2\",(t->tm_hour%12)?t->tm_hour%12:12);\r\n                        break;\r\n\r\n                  case 'j' :\r\n                        strfmt(r,\"%3\",t->tm_yday+1);\r\n                        break;\r\n\r\n                  case 'm' :\r\n                        strfmt(r,\"%2\",t->tm_mon+1);\r\n                        break;\r\n\r\n                  case 'M' :\r\n                        strfmt(r,\"%2\",t->tm_min);\r\n                        break;\r\n\r\n                  case 'p' :\r\n                        r = (t->tm_hour>11)?\"PM\":\"AM\";\r\n                        break;\r\n\r\n                  case 'S' :\r\n                        strfmt(r,\"%2\",t->tm_sec);\r\n                        break;\r\n\r\n                  case 'U' :\r\n                        w = t->tm_yday/7;\r\n                        if (t->tm_yday%7 > t->tm_wday)\r\n                              w++;\r\n                        strfmt(r, \"%2\", w);\r\n                        break;\r\n\r\n                  case 'W' :\r\n                        w = t->tm_yday/7;\r\n                        if (t->tm_yday%7 > (t->tm_wday+6)%7)\r\n                              w++;\r\n                        strfmt(r, \"%2\", w);\r\n                        break;\r\n\r\n                  case 'w' :\r\n                        strfmt(r,\"%1\",t->tm_wday);\r\n                        break;\r\n\r\n                  case 'x' :\r\n                        strfmt(r, \"%3s %3s %2 %4\", aday[t->tm_wday],\r\n                              amonth[t->tm_mon], t->tm_mday, t->tm_year+1900);\r\n                        break;\r\n\r\n                  case 'X' :\r\n                        strfmt(r, \"%2:%2:%2\", t->tm_hour,\r\n                              t->tm_min, t->tm_sec);\r\n                        break;\r\n\r\n                  case 'y' :\r\n                        strfmt(r,\"%2\",t->tm_year%100);\r\n                        break;\r\n\r\n                  case 'Y' :\r\n                        strfmt(r,\"%4\",t->tm_year+1900);\r\n                        break;\r\n\r\n                  case 'Z' :\r\n\t\t\tr = TZNAME;\r\n                        break;\r\n\r\n                  default:\r\n                        buf[0] = '%';     /* reconstruct the format */\r\n                        buf[1] = f[-1];\r\n                        buf[2] = '\\0';\r\n                        if (buf[1] == 0)\r\n                              f--;        /* back up if at end of string */\r\n                  }\r\n                  while (*r)\r\n                  {\r\n                        if (p == q)\r\n                        {\r\n                              *q = '\\0';\r\n                              return 0;\r\n                        }\r\n                        *p++ = *r++;\r\n                  }\r\n            }\r\n            else\r\n            {\r\n                  if (p == q)\r\n                  {\r\n                        *q = '\\0';\r\n                        return 0;\r\n                  }\r\n                  *p++ = f[-1];\r\n            }\r\n      }\r\n      *p = '\\0';\r\n      return p - s;\r\n}\r\n\r\n/*\r\n *  stdarg.h\r\n *\r\ntypedef void *va_list;\r\n#define va_start(vp,v) (vp=((char*)&v)+sizeof(v))\r\n#define va_arg(vp,t) (*((t*)(vp))++)\r\n#define va_end(vp)\r\n *\r\n */\r\n\r\nstatic int pow[5] = { 1, 10, 100, 1000, 10000 };\r\n\r\n/**\r\n * static void strfmt(char *str, char *fmt);\r\n *\r\n * simple sprintf for strftime\r\n *\r\n * each format descriptor is of the form %n\r\n * where n goes from zero to four\r\n *\r\n * 0    -- string %s\r\n * 1..4 -- int %?.?d\r\n *\r\n**/\r\n\r\nstatic void strfmt(char *str, char *fmt, ...)\r\n{\r\n      int ival, ilen;\r\n      char *sval;\r\n      va_list vp;\r\n\r\n      va_start(vp, fmt);\r\n      while (*fmt)\r\n      {\r\n            if (*fmt++ == '%')\r\n            {\r\n                  ilen = *fmt++ - '0';\r\n                  if (ilen == 0)                /* zero means string arg */\r\n                  {\r\n                        sval = va_arg(vp, char*);\r\n                        while (*sval)\r\n                              *str++ = *sval++;\r\n                  }\r\n                  else                          /* always leading zeros */\r\n                  {\r\n                        ival = va_arg(vp, int);\r\n                        while (ilen)\r\n                        {\r\n                              ival %= pow[ilen--];\r\n                              *str++ = (char)('0' + ival / pow[ilen]);\r\n                        }\r\n                  }\r\n            }\r\n            else  *str++ = fmt[-1];\r\n      }\r\n      *str = '\\0';\r\n      va_end(vp);\r\n}\r\n\r\n#ifdef TEST\r\n\r\n#include <stdio.h>      /* for printf */\r\n#include <time.h>       /* for strftime */\r\n\r\nchar test[80];\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n      int len;\r\n      char *fmt;\r\n      time_t now;\r\n\r\n      time(&now);\r\n\r\n      fmt = (argc == 1) ? \"%I:%M %p\\n%c\\n\" : argv[1];\r\n      len = strftime(test,sizeof test, fmt, localtime(&now));\r\n      printf(\"%d: %s\\n\", len, test);\r\n      return !len;\r\n}\r\n\r\n#endif /* TEST */\r\n"
  },
  {
    "path": "gen/STRICMP.AS",
    "content": "; int strcasecmp(const char *s1, const char *s2)\r\n; return a value less than 0, 0 or greater than 0 if s1 is found, respectively, \r\n;   to be less than equal or greater than s2 ignoring case\r\n; by Arnold M\r\n\r\npsect text\r\n\r\nmacro tolower\r\n  cp 'A'\r\n  jr c, 10f\r\n  cp 'Z'+1\r\n  jr nc, 10f\r\n  add  a, 'a'-'A'\r\n10: \r\nendm\r\n\r\nglobal _strcasecmp\r\n_strcasecmp:\r\n\r\npop bc\r\npop hl ; s1\r\npop de ; s2\r\npush de\r\npush hl\r\npush bc\r\n\r\n1:\r\nld a,(de) ;*s2\r\ntolower\r\nld c,a\r\nld a,(hl) ;*s1 \r\ntolower\r\ncp c\r\njr nz,2f\r\ninc hl\r\ninc de\r\nor a\r\njp nz,1b\r\nld h,a\r\nld l,a\r\nret\r\n\r\n2:\r\nsbc hl,hl\r\nret c\r\ninc hl\r\nret\r\n"
  },
  {
    "path": "gen/STRISTR.C",
    "content": "/*\r\n * char * strcasestr (char *t, char *s) \r\n * \r\n * Find string s in string t, disregarding the case of letters.\r\n *\r\n * Return \r\n *    -\tThe smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\n#include <ctype.h>\r\n\r\nchar * strcasestr (char *t, char *s) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n\r\n   do \r\n     {\r\n       t1 = t;\r\n       s1 = s;\r\n       while(*s1) {\r\n         if (toupper(*s1) != toupper(*(t1++))) \r\n\t    break;\r\n\t else\r\n\t    ++s1;\r\n       }\r\n       if (!*s1) return t;\r\n     } \r\n   while (*(t++));\r\n\r\n   return (char *) 0;\r\n}\r\n"
  },
  {
    "path": "gen/STRLEN.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strlen\r\n_strlen:\tpop\thl\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\thl\r\n\tld\thl,0\r\n\r\n1:\tld\ta,(de)\r\n\tor\ta\r\n\tret\tz\r\n\tinc\thl\r\n\tinc\tde\r\n\tjr\t1b\r\n"
  },
  {
    "path": "gen/STRNCAT.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strncat, rcsv, cret\r\n\r\n_strncat:\r\n\tcall\trcsv\r\n\tpush\thl\r\n\r\n\tjr\t3f\r\n4:\r\n\tinc\thl\r\n3:\r\n\tld\ta,(hl)\r\n\tor\ta\r\n\tjr\tnz,4b\r\n\r\n1:\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,3f\r\n\tdec\tbc\r\n\tld\ta,(de)\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tor\ta\r\n\tjr\tz,2f\r\n\tinc\tde\r\n\tjr\t1b\r\n3:\r\n\tld\t(hl),0\r\n\r\n2:\tpop\thl\r\n\tjp\tcret\r\n"
  },
  {
    "path": "gen/STRNCMP.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strncmp, rcsv, cret\r\n\r\n\r\n_strncmp:\r\n\tcall\trcsv\r\n\r\n1:\tld\ta,c\r\n\tor\tb\r\n\tjp\tz,3f\r\n\tdec\tbc\r\n\tld\ta,(de)\r\n\tcp\t(hl)\r\n\tjr\tnz,2f\r\n\tinc\tde\r\n\tinc\thl\r\n\tor\ta\r\n\tjr\tnz,1b\r\n3:\r\n\tld\thl,0\r\n\tjp\tcret\r\n\r\n2:\tld\thl,1\r\n\tjp\tc,cret\r\n\tdec\thl\r\n\tdec\thl\r\n\tjp\tcret\r\n"
  },
  {
    "path": "gen/STRNCPY.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_strncpy, rcsv, cret\r\n\r\n_strncpy:\r\n\tcall\trcsv\r\n\tpush\thl\r\n\r\n1:\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,2f\r\n\tdec\tbc\r\n\tld\ta,(de)\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tor\ta\r\n\tjr\tz,1b\r\n\tinc\tde\r\n\tjr\t1b\r\n\r\n2:\tpop\thl\r\n\tjp\tcret\r\n"
  },
  {
    "path": "gen/STRNICMP.AS",
    "content": "; int strncasecmp(const char *s1, const char *s2, size_t n)\r\n; return a value less than 0, 0 or greater than 0 if s1 is found, respectively, \r\n;   to be less than equal or greater than s2 ignoring case\r\n; by Arnold M\r\n\r\npsect text\r\n\r\nmacro tolower\r\n  cp 'A'\r\n  jr c, 10f\r\n  cp 'Z'+1\r\n  jr nc, 10f\r\n  add  a, 'a'-'A'\r\n10: \r\nendm\r\n\r\nglobal _strncasecmp, rcsv, cret\r\n\r\n_strncasecmp:\r\n call rcsv ; hl=s1, de=s2, bc=n\r\n ld b,c ; keep low part of n in reg b,  reg c is used as scratch\r\n ld a,b\r\n or a\r\n jr z,bzero\r\nloop:\r\n ld a,(de) ;*s2\r\n tolower\r\n ld c,a\r\n ld a,(hl) ;*s1 \r\n tolower\r\n cp c\r\n jr nz,diff\r\n or a\r\n jr z, equal\r\n inc hl\r\n inc de\r\n djnz loop\r\nbzero:\r\n dec (ix+6+5) ; n / 0x100\r\n jp p,loop ; dec m does not affect the carry flag\r\n ld a,(ix+6+5)\r\n inc a\r\n jr nz,loop\r\n\r\nequal:\r\n ld h,a\r\n ld l,a\r\n jp cret\r\n\r\ndiff:\r\n sbc hl,hl\r\n jp c,cret\r\n inc hl\r\n jp cret\r\n"
  },
  {
    "path": "gen/STRNISTR.C",
    "content": "/*\r\n * char * strncasestr (char *t, char *s, unsigned int n) \r\n * \r\n * Find string s in string t, disregarding the case of letters.\r\n * At most n characters from t are used. \r\n *\r\n * Returns \r\n *    -\tA smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p and strictly before t+n, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\n#include <ctype.h>\r\n\r\nchar * strncasestr (char *t, char *s, unsigned int n) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n   unsigned int n1;\r\n\r\n   if (!*s) return t;\r\n   while (*t && n) {\r\n       t1 = t;\r\n       n1 = n;\r\n       s1 = s;\r\n       while (*s1) {\r\n           if (toupper(*s1) != toupper(*(t1++))) break;\r\n           else {\r\n               ++s1;\r\n               if (!--n1) break;\r\n           }\r\n       }\r\n       if (!*s1) return t;\r\n       --n;\r\n       ++t;\r\n     }\r\n   return (char *) 0;\r\n}\r\n"
  },
  {
    "path": "gen/STRNSTR.C",
    "content": "/*\r\n * char * strnstr (char *t, char *s, unsigned int n) \r\n * \r\n * Find string s in string t, using at most n characters from t. \r\n *\r\n * Returns \r\n *    -\tA smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p and strictly before t+n, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\nchar * strnstr (char *t, char *s, unsigned int n) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n   unsigned int n1;\r\n\r\n   if (!*s) return t;\r\n   while (*t && n) {\r\n       t1 = t;\r\n       n1 = n;\r\n       s1 = s;\r\n       while (*s1) {\r\n           if (*s1 != *(t1++)) break;\r\n           else {\r\n               ++s1;\r\n               if (!--n1) break;\r\n           }\r\n       }\r\n       if (!*s1) return t;\r\n       --n;\r\n       ++t;\r\n     }\r\n   return (char *) 0;\r\n}\r\n"
  },
  {
    "path": "gen/STRRCHR.AS",
    "content": "; strrchr(char *s, int c)\r\n; version that can find the closing \\0 by Arnold M\r\n\r\n\tpsect\ttext\r\n\tglobal\trcsv, cret, _strrchr\t; also equivalent to _rindex\r\n\r\n_strrchr:\r\n\tpop\tbc\r\n\tpop\thl\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\thl\r\n\tpush\tbc\r\n\r\n\tld\tbc,1 ; the closing nul is considered part of the string here\r\n\tjr\t5f\r\n6:\r\n\tinc\thl\r\n\tinc\tbc\r\n5:\r\n\tld\ta,(hl)\r\n\tor\ta\r\n\tjr\tnz,6b\r\n1:\r\n\tld \ta,e\r\n\tcpdr\r\n\tinc\thl\r\n\tret\tz\r\n\tld\tl,c\r\n\tld\th,b\r\n\tret\r\n"
  },
  {
    "path": "gen/STRSTR.C",
    "content": "/*\r\n * char * strstr (char *t, char *s) \r\n * \r\n * Find string s in string t.\r\n *\r\n * Return \r\n *    -\tThe smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\nchar * strstr (char *t, char *s) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n\r\n   do \r\n     {\r\n       t1 = t;\r\n       s1 = s;\r\n       while(*s1) {\r\n         if (*s1 != *(t1++)) \r\n\t    break;\r\n\t else\r\n\t    ++s1;\r\n       }\r\n       if (!*s1) return t;\r\n     } \r\n   while (*(t++));\r\n\r\n   return (char *) 0;\r\n}\r\n"
  },
  {
    "path": "gen/STRTOK.C",
    "content": "/*\r\n**  strtok() -- public domain by Ray Gardner, modified by Bob Stout\r\n**              not modified for Hi-Tech C by Pierre Gielen :-)\r\n**              comment corrected by Arnold Metselaar\r\n**\r\n**   You pass this function a string to parse, a buffer to receive the\r\n**   \"token\" that gets scanned, the length of the buffer, and a string of\r\n**   \"break\" characters that stop the scan.  It will copy the string into\r\n**   the buffer up to any of the break characters, or until the buffer is\r\n**   full, and will always leave the buffer null-terminated.  It will\r\n**   return a pointer to the first character from s that was not copied to\r\n**   tok.\r\n*/\r\n\r\n#include <stddef.h>\r\n\r\nchar *strtok(char *s, char *tok, size_t toklen, char *brk)\r\n{\r\n      char *lim, *b;\r\n\r\n      if (!*s)\r\n            return NULL;\r\n\r\n      lim = tok + toklen - 1;\r\n      while (*s && (tok<lim))\r\n      {\r\n            for (b=brk;*b;b++)\r\n            {\r\n                  if (*s==*b)\r\n                  {\r\n                        *tok=0;\r\n                        return(s);\r\n                  }\r\n            }\r\n            *tok++ = *s++;\r\n      }\r\n      *tok = 0;\r\n      return(s);\r\n}\r\n"
  },
  {
    "path": "gen/SWAP.AS",
    "content": ";\t_swap(width, s1, s2)\r\n\r\n;\texchange the two byte arrays\r\n\r\n\tpsect\ttext\r\n\tglobal\t__swap, rcsv, cret\r\n__swap:\r\n\tcall\trcsv\r\n\tpush\tbc\r\n\tex\t(sp),hl\r\n\tpop\tbc\r\n\tjr\t1f\r\n2:\r\n\tld\ta,(hl)\r\n\tex\taf,af'\r\n\tld\ta,(de)\r\n\tld\t(hl),a\r\n\tex\taf,af'\t\r\n\tld\t(de),a\r\n\tinc\thl\r\n\tinc\tde\r\n\tdec\tbc\r\n1:\r\n\tld\ta,b\r\n\tor\tc\r\n\tjr\tnz,2b\r\n\tjp\tcret\r\n"
  },
  {
    "path": "gen/TOLOWER.AS",
    "content": "\tglobal\t_tolower\r\n\r\n\tpsect\ttext\r\n_tolower:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tret\tnz\r\n\tld\ta,l\r\n\tcp\t'A'\r\n\tret\tc\t\t;Less than a\r\n\tcp\t'Z'+1\r\n\tret\tnc\t\t;More than z\r\n\tsub\t'A'-'a'\r\n\tld\tl,a\r\n\tret\r\n"
  },
  {
    "path": "gen/TOUPPER.AS",
    "content": "\tglobal\t_toupper\r\n\r\n\tpsect\ttext\r\n_toupper:\r\n\tpop\tde\t\t;return address\r\n\tpop\thl\r\n\tpush\thl\r\n\tpush\tde\r\n\tld\ta,h\t\t;check for a char\r\n\tor\ta\r\n\tret\tnz\r\n\tld\ta,l\r\n\tcp\t'a'\r\n\tret\tc\t\t;Less than a\r\n\tcp\t'z'+1\r\n\tret\tnc\t\t;More than z\r\n\tsub\t'a'-'A'\r\n\tld\tl,a\r\n\tret\r\n"
  },
  {
    "path": "gen/WRELOP.AS",
    "content": ";\tword relational\toperation - returns flags correctly for\r\n;\tcomparision of words in hl and de\r\n\r\n\tpsect\ttext\r\n\tglobal\twrelop\r\n\r\nwrelop:\r\n\tld\ta,h\r\n\txor\td\t\t;compare signs\r\n\tjp\tm,1f\t\t;if different, return sign of lhs\r\n\tsbc\thl,de\t\t;just set flags as normal\r\n\tret\r\n1:\r\n\tld\ta,h\t\t;get sign of lhs\r\n\tand\t80h\t\t;mask out sign flag\r\n\tsbc\thl,de\t\t;set carry flag if appropriate\r\n\tinc\ta\t\t;set sign flag as appropriate and reset Z flag\r\n\tret\r\n"
  },
  {
    "path": "gen/XTOI.AS",
    "content": "\tglobal\t_xtoi, _ishex\r\n\tpsect\ttext\r\nhexdig:\tcp\t'0'\r\n\tret\tc\r\n\tcp\t'9'+1\r\n\tjr\tnc,1f\r\n\tsub\t'0'\r\n\tret\r\n\r\n1:\tcp\t'A'\r\n\tret\tc\r\n\tcp\t'F'+1\r\n\tjr\tnc,2f\r\n\tsub\t'A'-0Ah\r\n\tret\r\n\r\n2:\tcp\t'a'\r\n\tret\tc\r\n\tcp\t'f'+1\r\n\tccf\r\n\tret\tc\r\n\tsub\t'a'-0ah\r\n\tret\r\n\r\n_xtoi:\tpop\tbc\t;return address\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\tbc\r\n\tld\thl,0\r\n1:\r\n\tld\ta,(de)\r\n\tinc\tde\r\n\tcall\thexdig\r\n\tret\tc\r\n\tadd\thl,hl\r\n\tadd\thl,hl\r\n\tadd\thl,hl\r\n\tadd\thl,hl\r\n\tld\tc,a\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tjr\t1b\r\n\r\n_ishex:\tpop\thl\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\thl\r\n\tld\ta,e\r\n\tld\thl,0\r\n\tcall\thexdig\r\n\tret\tc\r\n\tinc\thl\r\n\tret\r\n"
  },
  {
    "path": "huff/DECODE.C",
    "content": "#include\t<stdlib.h>\r\n#include\t\"huff.h\"\r\n\r\nchar\tcl[ALFSIZ];\r\nshort\talfused;\r\nstatic\tshort\tclidx;\r\nstatic\tshort\tg_bit;\r\nstatic\tshort\tg_char;\r\nnode *\troot;\r\n\r\nvoid   bld_tree(void);\r\nnode * get_tree(void);\r\nvoid   align(void);\r\nint    get_bit(void);\r\nint    gethch(void);\r\nextern void error(char *fmt, ...);\r\n\r\nvoid bld_tree(void) {\r\n\tshort i;\r\n\r\n\tfor(i = 0 ; i < alfused ; i++)\r\n\t\tcl[i] = getchar();\r\n\talign();\r\n\tclidx = 0;\r\n\troot = get_tree();\r\n}\r\n\r\nnode * get_tree(void) {\r\n\tregister node *\ttp;\r\n\r\n\tif(!(tp = (node *)calloc(sizeof(node), 1)))\r\n\t\terror(\"Out of memory\");\r\n\tif(get_bit()) {\r\n\t\ttp->n_left  = get_tree();\r\n\t\ttp->n_right = get_tree();\r\n\t} else\r\n\t\ttp->n_c = cl[clidx++];\r\n\treturn tp;\r\n}\r\n\r\nvoid align(void) {\r\n\tg_char = 0;\r\n\tg_bit = CHAR_BIT;\r\n}\r\n\r\nint get_bit(void) {\r\n\tif(g_bit == CHAR_BIT)\r\n\t\tif((g_char = getchar()) == EOF)\r\n\t\t\terror(\"Read error or EOF on huf file\");\r\n\t\telse\r\n\t\t\tg_bit = 0;\r\n\treturn g_char & (1 << g_bit++);\r\n}\r\n\r\nint gethch(void) {\r\n\tregister node *\ttp;\r\n\r\n\ttp = root;\r\n\twhile(tp->n_left)\r\n\t\ttp = get_bit() ? tp->n_left : tp->n_right;\r\n\treturn tp->n_c & 0xFF;\r\n}\r\n"
  },
  {
    "path": "huff/DEHUF.C",
    "content": "#include <stdlib.h>\r\n#include \"huff.h\"\r\n\r\n\thdr\thd;\r\nstatic\tshort\tindent;\r\nstatic\tuchar\tlistflg;\r\nstatic\tuchar\txtractflg;\r\nstatic\tuchar\tdebug;\r\nstatic\tchar **\tav;\r\n\r\nextern void align(void);\r\nextern void bld_tree(void);\r\nextern void error(char *fmt, ...);\r\nextern int casecmp(register char *, char *);\r\nextern int gethch(void);\r\nint\t   isarg(char * s);\r\nchar * getname(short i);\r\nvoid   list(short i);\r\nvoid   extract(short i);\r\nvoid   prtree(register node * np);\r\n\r\n#if\t!unix\r\nextern\tchar **\t_getargs();\r\nextern\tint\t_argc_;\r\n#endif\t/* unix */\r\n/*\r\n *\r\n */\r\nint main(int argc, char **\targv) {\r\n\tshort i;\r\n\r\n#if\t!unix\r\n\tif(argc == 1) {\r\n\t\targv = _getargs(0, \"dehuff\");\r\n\t\targc = _argc_;\r\n\t}\r\n#endif\t/* unix */\r\n\r\n\targc--;\r\n\targv++;\r\n\twhile(argc && **argv == '-') {\r\n\t\tswitch(argv[0][1]) {\r\n\r\n\t\tcase 'l':\r\n\t\tcase 'L':\r\n\t\t\tlistflg++;\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'x':\r\n\t\tcase 'X':\r\n\t\t\txtractflg++;\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'd':\r\n\t\tcase 'D':\r\n\t\t\tdebug++;\r\n\t\t\tbreak;\r\n\r\n\t\tdefault:\r\n\t\t\tfprintf(stderr, \"Unrecognized flag %s ignored\\n\", argv[0]);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\targc--;\r\n\t\targv++;\r\n\t}\r\n\tif(argc < 1) {\r\n\t\tprintf(\"Usage of dehuff:\\n\\nTo list the contents of a .HUF file:\\n\");\r\n\t\tprintf(\"\\n\tdehuff file.huf\\n\\nTo extract files from a .HUF file:\\n\");\r\n\t\tprintf(\"\\n\tdehuff -x file.huf\\n\\nIf no extra arguments are supplied, then the entire contents\\n\");\r\n\t\tprintf(\"of the .HUF file will be listed or extracted, otherwise only files\\n\");\r\n\t\tprintf(\"matching an argument will be listed or extracted, e.g.\\n\\n\");\r\n\t\tprintf(\"\tdehuff -x xyz.huf afile.c\\n\\nwould extract only the file afile.c.\\n\");\r\n\t\tprintf(\"The number reported for each file is its length in bytes\\n\");\r\n\t\texit(1);\r\n\t}\r\n\tav = argv+1;\r\n\tif(!freopen(*argv, \"rb\", stdin))\r\n\t\terror(\"Can't open file %s\", *argv);\r\n\thd.hd_magic = get2();\r\n\tif(hd.hd_magic != MAGIC)\r\n\t\terror(\"%s is not a huf file\", *argv);\r\n\thd.hd_nfiles = get2();\r\n\talfused = hd.hd_alfsiz = get2();\r\n\thd.hd_hpos = get4();\r\n\tbld_tree();\r\n\tif(debug)\r\n\t\tprtree(root);\r\n\tfor(i = 0 ; i < hd.hd_nfiles ; i++)\r\n\t\tif(isarg(getname(i)))\r\n\t\t\tif(xtractflg)\r\n\t\t\t\textract(i);\r\n\t\t\telse\r\n\t\t\t\tlist(i);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nint isarg(char * s) {\r\n\tregister char ** p;\r\n\r\n\tif(*av == 0)\t\t/* default is all members */\r\n\t\treturn 1;\r\n\tfor(p = av ; *p ; p++)\r\n\t\tif(casecmp(*p, s) == 0)\r\n\t\t\treturn 1;\r\n\treturn 0;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nchar * getname(short i) {\r\n\tstatic   char\tfbuf[100];\r\n\tregister char *\tcp;\r\n\tfilent\t\t\thf;\r\n\r\n\tfseek(stdin, hd.hd_hpos+i*FSIZE, 0);\r\n\thf.f_npos  = get4();\r\n\thf.f_nchrs = get4();\r\n\thf.f_pos = get4();\r\n\thf.f_asc = getchar();\r\n\tfseek(stdin, hf.f_npos, 0);\r\n\talign();\r\n\tfor(cp = fbuf ; (*cp++ = gethch()) ; )\r\n\t\tcontinue;\r\n\treturn fbuf;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid list(short i) {\r\n\tregister char *\tcp;\r\n\tfilent\t\t\thf;\r\n\tchar\t\t\tfbuf[100];\r\n\r\n\tfseek(stdin, hd.hd_hpos+i*FSIZE, 0);\r\n\thf.f_npos  = get4();\r\n\thf.f_nchrs = get4();\r\n\thf.f_pos = get4();\r\n\thf.f_asc = getchar();\r\n\tfseek(stdin, hf.f_npos, 0);\r\n\talign();\r\n\tfor(cp = fbuf ; (*cp++ = gethch()) ; )\r\n\t\tcontinue;\r\n\tfprintf(stderr, \"%-20.20s    %ld\\n\", fbuf, hf.f_nchrs);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid extract(short i) {\r\n\tregister char *\tcp;\r\n\tfilent\t\t\thf;\r\n\tFILE *\t\t\tfp;\r\n\tchar\t\t\tfbuf[100];\r\n\r\n\tfseek(stdin, hd.hd_hpos+i*FSIZE, 0);\r\n\thf.f_npos  = get4();\r\n\thf.f_nchrs = get4();\r\n\thf.f_pos = get4();\r\n\thf.f_asc = getchar();\r\n\tfseek(stdin, hf.f_npos, 0);\r\n\talign();\r\n\tfor(cp = fbuf ; (*cp++ = gethch()) ; )\r\n\t\tcontinue;\r\n\tif(!(fp = fopen(fbuf, hf.f_asc ? \"w\" : \"wb\"))) {\r\n\t\tfprintf(stderr, \"Can't create %s\\n\", fbuf);\r\n\t\treturn;\r\n\t}\r\n\tfprintf(stderr, \"%-20.20s    %ld\\n\", fbuf, hf.f_nchrs);\r\n\tfseek(stdin, hf.f_pos, 0);\r\n\talign();\r\n\twhile(hf.f_nchrs--)\r\n\t\tputc(gethch(), fp);\r\n\tfclose(fp);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid prtree(register node * np) {\r\n\tshort i;\r\n\r\n\tfor(i = indent ; i-- ; )\r\n\t\tfputc(' ', stderr);\r\n\tif(np->n_left) {\r\n\t\tfprintf(stderr, \"X\\n\");\r\n\t\tindent += 4;\r\n\t\tprtree(np->n_left);\r\n\t\tprtree(np->n_right);\r\n\t\tindent -= 4;\r\n\t} else\r\n\t\tif(np->n_c >= ' ' && np->n_c <= 0176)\r\n\t\t\tfprintf(stderr, \"'%c'\\n\", np->n_c);\r\n\t\telse\r\n\t\t\tfprintf(stderr, \"%03o\\n\", np->n_c);\r\n}\r\n"
  },
  {
    "path": "huff/DEHUFF.C",
    "content": "#include <stdlib.h>\r\n#include \"huff.h\"\r\n\r\n\thdr\thd;\r\nstatic\tshort\tindent;\r\nstatic\tuchar\tlistflg;\r\nstatic\tuchar\txtractflg;\r\nstatic\tuchar\tdebug;\r\nstatic\tchar **\tav;\r\n\r\nextern void align(void);\r\nextern void bld_tree(void);\r\nextern void error(char *fmt, ...);\r\nextern int casecmp(register char *, char *);\r\nextern int gethch(void);\r\nint\t   isarg(char * s);\r\nchar * getname(short i);\r\nvoid   list(short i);\r\nvoid   extract(short i);\r\nvoid   prtree(register node * np);\r\n\r\n#if\t!unix\r\nextern\tchar **\t_getargs();\r\nextern\tint\t_argc_;\r\n#endif\t/* unix */\r\n/*\r\n *\r\n */\r\nint main(int argc, char **\targv) {\r\n\tshort i;\r\n\r\n#if\t!unix\r\n\tif(argc == 1) {\r\n\t\targv = _getargs(0, \"dehuff\");\r\n\t\targc = _argc_;\r\n\t}\r\n#endif\t/* unix */\r\n\r\n\targc--;\r\n\targv++;\r\n\twhile(argc && **argv == '-') {\r\n\t\tswitch(argv[0][1]) {\r\n\r\n\t\tcase 'l':\r\n\t\tcase 'L':\r\n\t\t\tlistflg++;\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'x':\r\n\t\tcase 'X':\r\n\t\t\txtractflg++;\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'd':\r\n\t\tcase 'D':\r\n\t\t\tdebug++;\r\n\t\t\tbreak;\r\n\r\n\t\tdefault:\r\n\t\t\tfprintf(stderr, \"Unrecognized flag %s ignored\\n\", argv[0]);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\targc--;\r\n\t\targv++;\r\n\t}\r\n\tif(argc < 1) {\r\n\t\tprintf(\"Usage of dehuff:\\n\\nTo list the contents of a .HUF file:\\n\");\r\n\t\tprintf(\"\\n\tdehuff file.huf\\n\\nTo extract files from a .HUF file:\\n\");\r\n\t\tprintf(\"\\n\tdehuff -x file.huf\\n\\nIf no extra arguments are supplied, then the entire contents\\n\");\r\n\t\tprintf(\"of the .HUF file will be listed or extracted, otherwise only files\\n\");\r\n\t\tprintf(\"matching an argument will be listed or extracted, e.g.\\n\\n\");\r\n\t\tprintf(\"\tdehuff -x xyz.huf afile.c\\n\\nwould extract only the file afile.c.\\n\");\r\n\t\tprintf(\"The number reported for each file is its length in bytes\\n\");\r\n\t\texit(1);\r\n\t}\r\n\tav = argv+1;\r\n\tif(!freopen(*argv, \"rb\", stdin))\r\n\t\terror(\"Can't open file %s\", *argv);\r\n\thd.hd_magic = get2();\r\n\tif(hd.hd_magic != MAGIC)\r\n\t\terror(\"%s is not a huf file\", *argv);\r\n\thd.hd_nfiles = get2();\r\n\talfused = hd.hd_alfsiz = get2();\r\n\thd.hd_hpos = get4();\r\n\tbld_tree();\r\n\tif(debug)\r\n\t\tprtree(root);\r\n\tfor(i = 0 ; i < hd.hd_nfiles ; i++)\r\n\t\tif(isarg(getname(i)))\r\n\t\t\tif(xtractflg)\r\n\t\t\t\textract(i);\r\n\t\t\telse\r\n\t\t\t\tlist(i);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nint isarg(char * s) {\r\n\tregister char ** p;\r\n\r\n\tif(*av == 0)\t\t/* default is all members */\r\n\t\treturn 1;\r\n\tfor(p = av ; *p ; p++)\r\n\t\tif(casecmp(*p, s) == 0)\r\n\t\t\treturn 1;\r\n\treturn 0;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nchar * getname(short i) {\r\n\tstatic   char\tfbuf[100];\r\n\tregister char *\tcp;\r\n\tfilent\t\t\thf;\r\n\r\n\tfseek(stdin, hd.hd_hpos+i*FSIZE, 0);\r\n\thf.f_npos  = get4();\r\n\thf.f_nchrs = get4();\r\n\thf.f_pos = get4();\r\n\thf.f_asc = getchar();\r\n\tfseek(stdin, hf.f_npos, 0);\r\n\talign();\r\n\tfor(cp = fbuf ; (*cp++ = gethch()) ; )\r\n\t\tcontinue;\r\n\treturn fbuf;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid list(short i) {\r\n\tregister char *\tcp;\r\n\tfilent\t\t\thf;\r\n\tchar\t\t\tfbuf[100];\r\n\r\n\tfseek(stdin, hd.hd_hpos+i*FSIZE, 0);\r\n\thf.f_npos  = get4();\r\n\thf.f_nchrs = get4();\r\n\thf.f_pos = get4();\r\n\thf.f_asc = getchar();\r\n\tfseek(stdin, hf.f_npos, 0);\r\n\talign();\r\n\tfor(cp = fbuf ; (*cp++ = gethch()) ; )\r\n\t\tcontinue;\r\n\tfprintf(stderr, \"%-20.20s    %ld\\n\", fbuf, hf.f_nchrs);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid extract(short i) {\r\n\tregister char *\tcp;\r\n\tfilent\t\t\thf;\r\n\tFILE *\t\t\tfp;\r\n\tchar\t\t\tfbuf[100];\r\n\r\n\tfseek(stdin, hd.hd_hpos+i*FSIZE, 0);\r\n\thf.f_npos  = get4();\r\n\thf.f_nchrs = get4();\r\n\thf.f_pos = get4();\r\n\thf.f_asc = getchar();\r\n\tfseek(stdin, hf.f_npos, 0);\r\n\talign();\r\n\tfor(cp = fbuf ; (*cp++ = gethch()) ; )\r\n\t\tcontinue;\r\n\tif(!(fp = fopen(fbuf, hf.f_asc ? \"w\" : \"wb\"))) {\r\n\t\tfprintf(stderr, \"Can't create %s\\n\", fbuf);\r\n\t\treturn;\r\n\t}\r\n\tfprintf(stderr, \"%-20.20s    %ld\\n\", fbuf, hf.f_nchrs);\r\n\tfseek(stdin, hf.f_pos, 0);\r\n\talign();\r\n\twhile(hf.f_nchrs--)\r\n\t\tputc(gethch(), fp);\r\n\tfclose(fp);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid prtree(register node * np) {\r\n\tshort i;\r\n\r\n\tfor(i = indent ; i-- ; )\r\n\t\tfputc(' ', stderr);\r\n\tif(np->n_left) {\r\n\t\tfprintf(stderr, \"X\\n\");\r\n\t\tindent += 4;\r\n\t\tprtree(np->n_left);\r\n\t\tprtree(np->n_right);\r\n\t\tindent -= 4;\r\n\t} else\r\n\t\tif(np->n_c >= ' ' && np->n_c <= 0176)\r\n\t\t\tfprintf(stderr, \"'%c'\\n\", np->n_c);\r\n\t\telse\r\n\t\t\tfprintf(stderr, \"%03o\\n\", np->n_c);\r\n}\r\n"
  },
  {
    "path": "huff/ENCODE.C",
    "content": "#include\t\"huff.h\"\r\n#include\t<stdio.h>\r\n#include\t<stdlib.h>\r\ntypedef struct {\r\n\tnode *\tnp_node;\r\n\tuchar\tnp_len;\r\n}\tnp;\r\n\r\nnode *\troot;\r\nchent\tclist[ALFSIZ];\r\nfilent\tflist[MAXFILENT];\r\nshort\talfused;\r\nchent *\tcptrs[ALFSIZ];\r\nstatic\tnp\tnptrs[ALFSIZ];\r\nstatic\tuchar\tp_bit;\r\nstatic\tuchar\tp_char;\r\nstatic\tuchar\tlevel;\r\nstatic\tshort\tnidx;\r\n\r\n/* extern\tchar *\tcalloc(); */\r\nextern  void error(char *fmt, ...);\r\n\r\nvoid   make_tree(char **);\r\nnode * newnode(void);\r\nnode * bld(short, short);\r\nint    cmpr(chent **, chent **);\r\nint    cmpnp(np *, np *);\r\nvoid   bld_bits(node *, h_char);\r\nvoid   pinit(void);\r\nvoid   align(void);\r\nvoid   put_bit(int);\r\nvoid   puthch(uchar);\r\nvoid   put_tchrs(node *);\r\nvoid   walk_tree(node *);\r\nvoid   put_tree(void);\r\n\r\n/*\r\n *\r\n */\r\nvoid make_tree(char ** namlist) {\r\n\tFILE *\tfp;\r\n\tint\tc,  fno;\r\n\th_char\ttch;\r\n\tregister char *\tcp;\r\n\r\n\tfno = 0;\r\n\twhile(*namlist) {\r\n\t\tif(**namlist == '-')\r\n\t\t\tswitch(namlist[0][1]) {\r\n\r\n\t\t\tcase 'a':\r\n\t\t\tcase 'A':\r\n\t\t\t\tascii = 1;\r\n\t\t\t\tnamlist++;\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tcase 'b':\r\n\t\t\tcase 'B':\r\n\t\t\t\tascii = 0;\r\n\t\t\t\tnamlist++;\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\tif(!(fp = fopen(*namlist, ascii ? \"r\" : \"rb\"))) {\r\n\t\t\tfprintf(stderr, \"Can't open %s\\n\", *namlist++);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tflist[fno].f_name = *namlist;\r\n\t\tflist[fno].f_asc = ascii;\r\n\t\twhile((c = getc(fp)) != EOF) {\r\n\t\t\tclist[c & (ALFSIZ-1)].c_freq++;\r\n\t\t\tflist[fno].f_nchrs++;\r\n\t\t}\r\n\t\tfclose(fp);\r\n\t\tfor(cp = *namlist ; *cp ; )\r\n\t\t\tclist[*cp++ & (ALFSIZ-1)].c_freq++;\r\n\t\tclist[0].c_freq++;\r\n\t\tnamlist++;\r\n\t\tfno++;\r\n\t}\r\n\tfor(c =0 ; c < ALFSIZ ; c++) {\r\n\t\tcptrs[c] = clist+c;\r\n\t\tclist[c].c_chr = c;\r\n\t}\r\n\tqsort(cptrs, ALFSIZ, sizeof cptrs[0], cmpr);\r\n\tfor(alfused = 0 ; alfused < ALFSIZ && cptrs[alfused]->c_freq ; alfused++)\r\n\t\tcontinue;\r\n\tlevel = 0;\r\n\tnidx = 0;\r\n\troot = bld(0, alfused-1);\r\n\tqsort(nptrs, alfused, sizeof nptrs[0], cmpnp);\r\n\tfor(c = 0 ; c < alfused ; c++)\r\n\t\tnptrs[c].np_node->n_c = cptrs[c]->c_chr;\r\n\ttch.h_nbits = 0;\r\n\tbld_bits(root, tch);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nnode * newnode(void) {\r\n\tregister node *\tnp;\r\n\r\n\tif(!(np = (node *)calloc(1, sizeof(node))))\r\n\t\terror(\"Out of memory\");\r\n\treturn np;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nnode * bld(short first, short last) {\r\n\tint\ti;\r\n\tlong\ttot, run;\r\n\tregister node *\tl, * np;\r\n\r\n\tif(first == last) {\r\n\t\tl = newnode();\r\n\t\tnptrs[nidx].np_node = l;\r\n\t\tnptrs[nidx++].np_len = level+1;\r\n\t\tl->n_left = l->n_right = (node *)0;\r\n\t\treturn l;\r\n\t}\r\n\tlevel++;\r\n\tfor(i = first, tot = 0 ; i <= last ; i++)\r\n\t\ttot += cptrs[i]->c_freq;\r\n\ttot /= factor;\r\n\trun = cptrs[i = first]->c_freq;\r\n\twhile(run < tot && i != last)\r\n\t\trun += cptrs[++i]->c_freq;\r\n\tif(i == last)\r\n\t\ti = (first+last)/2;\r\n\tif(i == first) {\r\n\t\tl = newnode();\r\n\t\tnptrs[nidx].np_node = l;\r\n\t\tnptrs[nidx++].np_len = level+1;\r\n\t\tl->n_left = l->n_right = (node *)0;\r\n\t} else\r\n\t\tl = bld(first, i);\r\n\tnp = newnode();\r\n\tnp->n_left = l;\r\n\tnp->n_right = bld(i+1, last);\r\n\tlevel--;\r\n\treturn np;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nint cmpr(register chent ** p1, chent ** p2) {\r\n\tlong\ti;\r\n\r\n\ti = (*p2)->c_freq - (*p1)->c_freq;\r\n\tif(i > 0)\r\n\t\treturn 1;\r\n\tif(i < 0)\r\n\t\treturn -1;\r\n\treturn 0;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nint cmpnp(np * p1, np * p2) {\r\n\r\n\treturn p1->np_len - p2->np_len;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid bld_bits(register node * nodep, h_char tch) {\r\n\r\n\tif(!nodep->n_left) {\t/* leaf node */\r\n\t\tclist[nodep->n_c].c_bits = tch;\r\n\t\treturn;\r\n\t}\r\n\tSET(tch.h_cbits, tch.h_nbits);\r\n\ttch.h_nbits++;\r\n\tbld_bits(nodep->n_left, tch);\r\n\tCLR(tch.h_cbits, tch.h_nbits-1);\r\n\tbld_bits(nodep->n_right, tch);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid pinit(void) {\r\n\r\n\tp_char = 0;\r\n\tp_bit = 0;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid align(void) {\r\n\r\n\tif(p_bit)\r\n\t\tputchar(p_char);\r\n\tpinit();\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid put_bit(int i) {\r\n\r\n\tif(i)\r\n\t\tp_char |= 1 << p_bit;\r\n\tif(++p_bit == CHAR_BIT) {\r\n\t\tputchar(p_char);\r\n\t\tp_char = 0;\r\n\t\tp_bit = 0;\r\n\t}\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid puthch(uchar c) {\r\n\th_char\ttch;\r\n\tshort\ti;\r\n\r\n\ttch = clist[c].c_bits;\r\n\tfor(i = 0 ; i < tch.h_nbits ; i++) {\r\n\t\tif(TST(tch.h_cbits, i))\r\n\t\t\tp_char |= 1 << p_bit;\r\n\t\tif(++p_bit == CHAR_BIT) {\r\n\t\t\tputchar(p_char);\r\n\t\t\tp_char = 0;\r\n\t\t\tp_bit = 0;\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid put_tchrs(register node * tp) {\r\n\r\n\tif(tp->n_left) {\r\n\t\tput_tchrs(tp->n_left);\r\n\t\tput_tchrs(tp->n_right);\r\n\t} else\r\n\t\tputchar(tp->n_c);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid walk_tree(register node * tp) {\r\n\r\n\tif(tp->n_left) {\r\n\t\tput_bit(1);\r\n\t\twalk_tree(tp->n_left);\r\n\t\tput_bit(0);\r\n\t\twalk_tree(tp->n_right);\r\n\t}\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid put_tree(void) {\r\n\r\n\tput_tchrs(root);\r\n\twalk_tree(root);\r\n\tput_bit(0);\t\t/* a safeguard */\r\n}\r\n"
  },
  {
    "path": "huff/ENHUFF.C",
    "content": "#include\t<stdlib.h>\r\n#include\t\"huff.h\"\r\n\r\nuchar\tascii;\r\nshort\tfactor;\r\nstatic\tint\t\tindent;\r\nstatic\tuchar\tdebug;\r\nstatic\tchar *\toutfile;\r\nstatic\tshort\tfilecnt;\r\nstatic\tlong\ttotchrs;\r\nstatic\tlong\ttotsize;\r\n\r\nstatic\thdr\t\thd;\r\nextern\tlong\tftell();\r\nextern  void\terror(char *fmt, ...);\r\nextern  void\tmake_tree(char **);\r\nvoid putnames(void);\r\nvoid putfiles(void);\r\nvoid puthdr(void);\r\nvoid prtree(register node *);\r\nvoid prchars(void);\r\nvoid putbch(h_char);\r\nextern void put_tree(void);\r\n#if\t!unix\r\nextern\tchar **\t_getargs();\r\nextern\tint\t_argc_;\r\n#endif\t/* unix */\r\nextern void align(void);\r\nextern void puthch(uchar);\r\nextern void put2(unsigned short);\r\nextern void put4(unsigned long);\r\nint main(int argc, char ** argv) {\r\n\tlong pc;\r\n\tchar buf[10];\r\n\r\n#if\t!unix\r\n\tif(argc == 1) {\r\n\t\targv = _getargs(0, \"enhuff\");\r\n\t\targc = _argc_;\r\n\t}\r\n#endif\r\n\r\n\targc--;\r\n\targv++;\r\n\twhile(argc && **argv == '-') {\r\n\t\tswitch(argv[0][1]) {\r\n\r\n\t\tcase 'f':\r\n\t\tcase 'F':\r\n\t\t\tfactor = atoi(&argv[0][2]);\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'a':\r\n\t\tcase 'A':\r\n\t\t\tascii = 1;\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'b':\r\n\t\tcase 'B':\r\n\t\t\tascii = 0;\r\n\t\t\tbreak;\r\n\r\n\t\tcase 'd':\r\n\t\tcase 'D':\r\n\t\t\tdebug++;\r\n\t\t\tbreak;\r\n\r\n\t\tdefault:\r\n\t\t\tfprintf(stderr, \"Unrecognized flag %s ignored\\n\", *argv);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\targv++;\r\n\t\targc--;\r\n\t}\r\n\tif(factor == 0)\r\n\t\tfactor = 2;\r\n\tif(argc < 2)\r\n\t\terror(\"USAGE: enhuff [options] outfile file1 file2 ...\");\r\n\toutfile = *argv++;\r\n\tif(freopen(outfile, \"r\", stdout)) {\r\n\t\tfprintf(stderr, \"File %s exists; want to overwrite it? \", outfile);\r\n\t\tfgets(buf, sizeof buf, stdin);\r\n\t\tif(buf[0] != 'y' && buf[0] != 'Y')\r\n\t\t\texit(1);\r\n\t}\r\n\tif(!freopen(outfile, \"wb\", stdout))\r\n\t\terror(\"Can't create %s\", outfile);\r\n\tmake_tree(argv);\r\n\tif(debug)\r\n\t\tprchars();\r\n\tif(debug > 1)\r\n\t\tprtree(root);\r\n\tfor(filecnt = 0 ; flist[filecnt].f_name ; filecnt++)\r\n\t\tcontinue;\r\n\tfseek(stdout, (long)HSIZE, 0);\r\n\tput_tree();\r\n\thd.hd_alfsiz = alfused;\r\n\talign();\r\n\thd.hd_hpos = ftell(stdout);\r\n\tputnames();\r\n\tputfiles();\r\n\tputhdr();\r\n\tif(fclose(stdout) == EOF)\r\n\t\terror(\"Error closing output file - out of disk space?\");\r\n\tpc = (totchrs-totsize)*100;\r\n\tpc /= totchrs;\r\n\tfprintf(stderr, \"Source bytes %ld, enhuff'ed bytes %ld, compression %d%%\\n\", totchrs, totsize, (int)pc);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid putnames(void) {\r\n\tregister filent *\tfp;\r\n\tregister char *\t\tcp;\r\n\r\n\t\tfseek(stdout, (long)FSIZE * filecnt + hd.hd_hpos, 0);\r\n\t\tfor(fp = flist ; fp->f_name ; fp++) {\r\n\t\t\tfp->f_npos = ftell(stdout);\r\n\t\t\tfor(cp = fp->f_name ; *cp ;)\r\n\t\t\t\tputhch(*cp++);\r\n\t\t\tputhch(0);\r\n\t\t\talign();\r\n\t\t}\r\n\t}\r\n\r\n/*\r\n *\r\n */\r\nvoid putfiles(void) {\r\n\tint\t\t\tc;\r\n\tregister filent *\tfp;\r\n\r\n\tfor(fp = flist ; fp->f_name ; fp++) {\r\n\t\tfprintf(stderr, \"%-20.20s    %ld\\n\", fp->f_name, fp->f_nchrs);\r\n\t\tfp->f_pos = ftell(stdout);\r\n\t\ttotchrs += fp->f_nchrs;\r\n\t\tif(!freopen(fp->f_name, fp->f_asc ? \"r\" : \"rb\", stdin))\r\n\t\t\terror(\"Can't re-open file %s\", fp->f_name);\r\n\t\twhile((c = getchar()) != EOF)\r\n\t\t\tputhch(c);\r\n\t\talign();\r\n\t}\r\n\ttotsize = ftell(stdout);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid puthdr(void) {\r\n\tregister filent * fp;\r\n\r\n\thd.hd_magic = MAGIC;\r\n\thd.hd_nfiles = filecnt;\r\n\tfseek(stdout, 0L, 0);\r\n\tput2(hd.hd_magic);\r\n\tput2(hd.hd_nfiles);\r\n\tput2(hd.hd_alfsiz);\r\n\tput4(hd.hd_hpos);\r\n\tfseek(stdout, hd.hd_hpos, 0);\r\n\tfor(fp = flist ; fp->f_name ; fp++) {\r\n\t\tput4(fp->f_npos);\r\n\t\tput4(fp->f_nchrs);\r\n\t\tput4(fp->f_pos);\r\n\t\tputchar(fp->f_asc);\r\n\t}\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid prtree(register node * np) {\r\n\tshort\ti;\r\n\r\n\tfor(i = indent ; i-- ; )\r\n\t\tfputc(' ', stderr);\r\n\tif(np->n_left) {\r\n\t\tfprintf(stderr, \"X\\n\");\r\n\t\tindent += 4;\r\n\t\tprtree(np->n_left);\r\n\t\tprtree(np->n_right);\r\n\t\tindent -= 4;\r\n\t} else\r\n\t\tif(np->n_c >= ' ' && np->n_c <= 0176)\r\n\t\t\tfprintf(stderr, \"'%c'\\n\", np->n_c);\r\n\t\telse\r\n\t\t\tfprintf(stderr, \"%03o\\n\", np->n_c);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid prchars(void) {\r\n\tshort\ti;\r\n\tlong\tnchars, nbits, xx;\r\n\r\n\tnchars = nbits = 0;\r\n\tfor(i = 0 ; i < alfused ; i++) {\r\n\t\tnchars += cptrs[i]->c_freq;\r\n\t\tnbits += cptrs[i]->c_freq * cptrs[i]->c_bits.h_nbits;\r\n\t\tif(cptrs[i]->c_chr >= ' ' && cptrs[i]->c_chr <= 0176)\r\n\t\t\tfprintf(stderr, \"'%c'\\t\", cptrs[i]->c_chr);\r\n\t\telse\r\n\t\t\tfprintf(stderr, \"%03o\\t\", cptrs[i]->c_chr);\r\n\t\tfprintf(stderr, \"%7ld\\t\", cptrs[i]->c_freq);\r\n\t\tputbch(cptrs[i]->c_bits);\r\n\t\tfputc('\\n', stderr);\r\n\t}\r\n\tnbits /= CHAR_BIT;\r\n\txx = (nchars - nbits)*100;\r\n\ti = xx/nchars;\r\n\tfprintf(stderr, \"%ld chars reduced to %ld - %d%% compression\\n\", nchars, nbits, i);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid putbch(h_char tch) {\r\n\tshort\ti;\r\n\r\n\tfor(i = 0 ; i < tch.h_nbits ; i++)\r\n\t\tif(TST(tch.h_cbits, i))\r\n\t\t\tputc('1', stderr);\r\n\t\telse\r\n\t\t\tputc('0', stderr);\r\n}\r\n"
  },
  {
    "path": "huff/HUFF.H",
    "content": "/*\r\n *\tDefinitions for the Huffman encoded file structure\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\n#ifndef\tuchar\r\n#define\tuchar\tunsigned char\r\n#endif\r\n\r\n#ifndef\tCHAR_BIT\r\n#define\tCHAR_BIT\t8\r\n#endif\t/* CHAR_BIT */\r\n\r\n#define\tALFSIZ\t\t(1<<CHAR_BIT)\t/* max no. of distinct characters */\r\n#define\tMAXFILENT\t500\t\t/* maximum number of files */\r\n#define\tMAGIC\t\t0x01BD\r\n#define\tHSIZE\t\t10\t\t/* length of header in file */\r\n#define\tFSIZE\t\t13\t\t/* length of file entry */\r\n\r\n#define\tSET(ar, bit)\t(ar[(bit)/CHAR_BIT] |= (1<<((bit)%CHAR_BIT)))\r\n#define\tCLR(ar, bit)\t(ar[(bit)/CHAR_BIT] &= ~(1<<((bit)%CHAR_BIT)))\r\n#define\tTST(ar, bit)\t((ar[(bit)/CHAR_BIT] & (1<<((bit)%CHAR_BIT)))!=0)\r\n\r\n#if\tunix\r\n#define\tcasecmp\tstrcmp\r\n#endif\r\n\r\ntypedef struct node {\r\n\tuchar\t\tn_c;\r\n\tlong\t\tn_f;\r\n\tstruct node *\tn_left, * n_right;\r\n}\tnode;\r\n\r\ntypedef\tstruct {\r\n\tuchar\t\th_nbits;\r\n\tuchar\t\th_cbits[ALFSIZ/CHAR_BIT];\r\n}\th_char;\r\n\r\ntypedef struct {\r\n\tuchar\t\tc_chr;\r\n\tlong\t\tc_freq;\r\n\th_char\t\tc_bits;\r\n}\tchent;\r\n\r\ntypedef\tstruct {\r\n\tchar *\t\tf_name;\r\n\tlong\t\tf_npos;\r\n\tlong\t\tf_nchrs;\r\n\tlong\t\tf_pos;\r\n\tchar\t\tf_asc;\r\n}\tfilent;\r\n\r\ntypedef struct {\r\n\tshort\t\thd_magic;\t/* magic number */\r\n\tshort\t\thd_nfiles;\t/* no of files */\r\n\tshort\t\thd_alfsiz;\t/* size of alphabet */\r\n\tlong\t\thd_hpos;\t/* start pos of file hdrs */\r\n}\thdr;\r\n\r\n\r\nextern node *\t\troot;\r\nextern chent\t\tclist[ALFSIZ];\r\nextern filent\t\tflist[MAXFILENT];\r\nextern short\t\talfused;\r\nextern uchar\t\tascii;\r\nextern unsigned long get4(void);\r\nextern unsigned short get2(void);\r\nextern chent *\t\tcptrs[ALFSIZ];\r\nextern short\t\tfactor;\r\n"
  },
  {
    "path": "huff/MAKEFILE",
    "content": ".PHONY: clean\r\n\r\nall: dehuff enhuff\r\n\r\ndehuff:\tdehuff.o decode.o misc.o\r\n\t\tcc -O -Dunix -o dehuff dehuff.o decode.o misc.o\r\nenhuff:\tenhuff.o encode.o misc.o\r\n\t\tcc -O -Dunix -o enhuff enhuff.o encode.o misc.o\r\n\r\ndehuff.o:\tdehuff.c huff.h\r\n\t\tcc -c dehuff.c\r\ndecode.o:\tdecode.c huff.h\r\n\t\tcc -c decode.c\r\nmisc.o:\t\tmisc.c\r\n\t\tcc -c misc.c\r\n\r\nclean:\r\n\trm dehuff enhuff *.o\r\ncompress:\r\n\tenhuff -a HUFF.HUF dehuff.c decode.c enhuff.c encode.c misc.c huff.h Makefile\r\n"
  },
  {
    "path": "huff/MISC.C",
    "content": "#include <stdlib.h>\r\n#include <stdio.h>\r\n#include <stdarg.h>\r\n\r\n#if\t! unix\r\n/* this is a kludge for a bug in the Venix cpp */\r\n#endif\r\n\r\nvoid\t\t\terror(char *fmt, ...);\r\nvoid\t\t\tput2(unsigned short i);\r\nvoid\t\t\tput4(unsigned long i);\r\nunsigned long\tget4(void);\r\nunsigned short\tget2(void);\r\n\r\n#if\t! unix\r\n#include <ctype.h>\r\n\r\nint casecmp(register char *, char *);\r\n\r\nint casecmp(register char * s1, char * s2) {\r\n\tchar a, b;\r\n\r\n\twhile((a = *s1++)) {\r\n\t\tb = *s2++;\r\n\t\tif(isupper(a))\r\n\t\t\ta = tolower(a);\r\n\t\tif(isupper(b))\r\n\t\t\tb = tolower(b);\r\n\t\tif(a != b)\r\n\t\t\treturn 1;\r\n\t}\r\n\treturn 0;\r\n}\r\n#endif\t/* unix */\r\n\r\n/*========================================\r\nvoid error(char *s, char* a1, char* a2) {\r\n\r\n\tfprintf(stderr, \"huff: fatal error: \");\r\n\tfprintf(stderr, s, a1, a2);\r\n\tfputc('\\n', stderr);\r\n\texit(1);\r\n}\r\n ========================================*/\r\nvoid error(char *fmt, ...) {\r\n\tva_list ap;\t\t\t/* points to the next unnamed argument */\r\n\tchar *p, *sval;\r\n\r\n\tfprintf(stderr, \"huff: fatal error: \");\r\n\tva_start(ap, fmt);\t/* set ap to 1st unnamed argument */\r\n\r\n\tfor(p=fmt; *p; p++) {\r\n\t\tif(*p !='%') {\r\n\t\t\tputchar(*p);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tswitch(*++p) {\r\n\t\t  case 's':\r\n\t\t\tfor(sval = va_arg(ap, char *); *sval; sval++) fputc(*sval, stderr);\r\n\t    \tbreak;\r\n\t\t  default:\r\n\t\t\tfputc(*p, stderr);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n \tva_end(ap); \t\t/* cleaning when done */\r\n \tfputc('\\n', stderr);\r\n \texit(1);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid put2(unsigned short i) {\r\n\r\n\tputchar(i & 0xFF);\r\n\tputchar(i >> 8);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nvoid put4(unsigned long i) {\r\n\tput2(i & 0xFFFFL);\r\n\tput2(i >> 16);\r\n}\r\n\r\n/*\r\n *\r\n */\r\nunsigned long get4(void) {\r\n\tunsigned long i;\r\n\r\n\ti =  (unsigned long)getchar();\r\n\ti += (unsigned long)getchar() << 8;\r\n\ti += (unsigned long)getchar() << 16;\r\n\ti += (unsigned long)getchar() << 24;\r\n\tif(feof(stdin))\r\n\t\terror(\"EOF on input file\");\r\n\treturn i;\r\n}\r\n\r\n/*\r\n *\r\n */\r\nunsigned short get2(void) {\r\n\tunsigned short i;\r\n\r\n\ti =  (unsigned short)getchar();\r\n\ti += (unsigned short)getchar() << 8;\r\n\tif(feof(stdin))\r\n\t\terror(\"EOF on input file\");\r\n\treturn i;\r\n}\r\n"
  },
  {
    "path": "msx2dist/cc_01/CC.C",
    "content": "/*\r\n *   Copyright (C) 1984-1987 HI-TECH SOFTWARE\r\n *\r\n *   MSXDOS modifications by Pierre Gielen 1993:\r\n *\r\n *   - Replaced EXECL routines (C produces a batch file now)\r\n *   - Added -Q switch to write batch file without executing\r\n *   - Changed object file types to .O and temporary file\r\n *     types to .T to allow more commands per line (note:\r\n *     crt.o = crtcpm.obj). Changed library types back to .LIB.\r\n *   - Commented out calls to GETENV (for now) because it locks up\r\n *     the computer (still to be changed in the standard library)\r\n *\r\n *   Modifications by Arnold Metselaar:\r\n *\r\n *   - Append \".C\" _only_ if no filetype at all\r\n *   - Fixed bug with \"-R\" switch\r\n *   - Put object and program files in the same place as their sources \r\n *   - Switched back from producing $exec.bat to _spawn\r\n *   - removed -Q switch\r\n *   - Use APPEND environment item to find include files (and libs)\r\n *   - Added -N switch to link without crt.o , the user should provide\r\n *\r\n *   HITECH C is almost ANSI C compatible, but it does not recognize\r\n *   the '#pragma nonrec' directive.\r\n *\r\n *\r\n *   HITECH SOFTWARE has given kind permission to copy this\r\n *   software for personal use.\r\n *\r\n */\r\n\r\n#include    <stdio.h>\r\n#include    <string.h>\r\n#include    <ctype.h>\r\n\r\nvoid stack_trace();\r\n\r\n/*\r\n * CC command  MSX-DOS2 version\r\n *\r\n * CC [-C] [-O] [-I] [-F] [-U] [-D] [-S] [-X] [-P] [-W] [-M] [-N] files {-Llib}\r\n */\r\n\r\n#define   MAXLIST   60      /* max arg list */\r\n#define   BIGLIST   120      /* room for much more */\r\n\r\n#define   HITECH   \"HITECH\"\r\n#define PROMPT   \"c\"\r\n#define   TEMP   \"TMP\"\r\n#define DEFPATH \"\"\r\n#define   DEFTMP   \"\"\r\n\r\n#define LIBSUFF \".LIB\"          /* library suffix */\r\n\r\n#define   LFLAGS      \"-Z\"\r\n#define   STDLIB      \"C\"\r\n/* originally \"-U__getargs\", but the -u option to link is broken, so I made\r\n * a small object file with the same effect */\r\n#define REDIR_O    \"redir.obj\"\r\n\r\n\r\nstatic char   \r\n      keep,      /* retain .obj files, don't link */\r\n      keepas,    /* retain .as files, don't assemble */\r\n      verbose,   /* verbose - echo all commands */\r\n      optimize,  /* invoke optimizer */\r\n      speed,     /* optimize for speed */\r\n      reloc,     /* auto-relocate program at run time */\r\n      xref,      /* generate cross reference listing */\r\n      nolocal,   /* strip local symbols */\r\n      redir,\t /* AM - link code for redirectioning and globbing */\r\n      nocrto;    /* AM - do not link standard crt.o */\r\n\r\nstatic char *   iuds[MAXLIST],   /* -[IUD] args to preprocessor */\r\n       *   objs[MAXLIST],   /* .obj files and others for linker */\r\n       *   flgs[BIGLIST],   /* flags etc for linker */\r\n       *   libs[MAXLIST],   /* .lib files for linker */\r\n       *   c_as[MAXLIST];   /* .c files to compile or .as to assemble */\r\n\r\nstatic uchar   iud_idx,   /* index into iuds[] */\r\n      obj_idx,   /*   \"     \"  objs[] */\r\n      flg_idx,   /*   \"     \"  flgs[] */\r\n      lib_idx,   /*   \"     \"  libs[] */\r\n      c_as_idx;   /*   \"     \"  c_as[] */\r\nstatic char *   paths[] =\r\n{\r\n   \"~LINK\",\r\n   \"OBJTOHEX\",\r\n   \"~CGEN\",\r\n   \"~OPTIM\",\r\n   \"~CPP\",\r\n   \"~ZAS\",\r\n   \"LIB\",\r\n   \"~P1\",\r\n   \"~CREF\",\r\n   \"CRT.O\",\r\n};\r\n\r\n#define   linker   paths[0]\r\n#define   objto   paths[1]\r\n#define   cgen   paths[2]\r\n#define   optim   paths[3]\r\n#define   cpp   paths[4]\r\n#define   assem   paths[5]\r\n#define   libpath   paths[6]\r\n#define   pass1   paths[7]\r\n#define   cref   paths[8]\r\n#define   strtoff   paths[9]\r\n\r\n#define   RELSTRT   strtoff[plen]\r\n\r\nstatic char *   temps[] =\r\n{\r\n   \"$C1.T\",\r\n   \"$C2.T\",\r\n   \"$C3.T\",\r\n   \"$C4.T\",\r\n   \"L.O\",\r\n   \"CREF.T\"\r\n};\r\n\r\n#define   tmpf1     temps[0]\r\n#define   tmpf2     temps[1]\r\n#define   tmpf3     temps[2]\r\n#define   redname   temps[3]\r\n#define l_dot_obj   temps[4]\r\n#define   crtmp     temps[5]\r\n\r\nstatic char   * cppdef[] = { \"-DCPM\", \"-DHI_TECH_C\", \"-Dz80\" };\r\nstatic char   * cpppath = \"-I\";\r\nstatic char   * old_append, * new_append;\r\n\r\n\r\nstatic char    tmpbuf[128]; /* gen. purpose buffer */\r\nstatic char    single[40];  /* single object file to be deleted */\r\nstatic short   nfiles;      /* number of source or object files seen */\r\nstatic char  * outfile;     /* output file name for objtohex */\r\nstatic short   plen;        /* length of path */\r\nstatic char    ebuf[22];    /* error listing file */\r\nstatic char  * xrname;\r\n\r\n/*static struct stat   statbuf;*/\r\n\r\nextern char *   malloc(),\r\n       *   getenv(),\r\n       *   rindex();\r\n       *   realloc(char *, int);\r\nextern char **   _getargs();\r\nextern int   dup(int);\r\n\r\nstatic char *   xalloc(short);\r\n\r\nvoid setup();\r\nint doit();\r\n\r\nint\r\nmain(argc, argv)\r\nchar **   argv;\r\n{\r\n   register char *   cp, * xp;\r\n   short      i;\r\n\r\n   fprintf(stderr, \"HI-TECH C COMPILER (MSXDOS) V3.09\\n\");\r\n   fprintf(stderr, \"Copyright (C) 1993 HI-TECH SOFTWARE\\n\");\r\n   if (argc == 1)\r\n      argv = _getargs((char *)0, PROMPT);\r\n   setup();\r\n   while(*++argv) {\r\n      if((argv)[0][0] == '-') {\r\n         if(islower(i = argv[0][1]))\r\n            argv[0][1] = i = toupper(i);\r\n         switch(i) {\r\n\r\n         case 'A':\r\n            reloc = 1;\r\n            RELSTRT = 'R';\r\n            flgs[flg_idx++] = \"-L\";\r\n            break;\r\n\r\n\t case 'N':       /* AM */\r\n\t    nocrto = 1;\r\n\t    break;\r\n\r\n         case 'R':\r\n            redir=1;\r\n            break;\r\n\r\n         case 'V':\r\n            verbose = 1;\r\n            break;\r\n\r\n         case 'S':\r\n            keepas = 1;\r\n\t    keep = 1;\r\n\t    break;\r\n\r\n         case 'C':\r\n            if(argv[0][2] == 'r' || argv[0][2] == 'R') {\r\n               xref = 1;\r\n               if(argv[0][3]) {\r\n                  xrname = &argv[0][1];\r\n                  xrname[0] = '-';\r\n                  xrname[1] = 'o';\r\n               } else\r\n                  xrname = (char *)0;\r\n            } else\r\n               keep = 1;\r\n            break;\r\n\r\n         case 'O':\r\n\t    if (strlen(argv[0])>3)\r\n\t      outfile=argv[0]+2;\r\n\t    else {\r\n              optimize = 1;\r\n              if(argv[0][2] == 'F' || argv[0][2] == 'f')\r\n                 speed = 1;\r\n\t    }\r\n            break;\r\n\r\n         case 'I':  \r\n\t /* APPEND does not work as desired\r\n          * if (strlen(new_append)+strlen(argv[0]+1)<256) {\r\n          *    cp=(char*)realloc(new_append,\r\n\t  *\t\t\t strlen(new_append)+strlen(argv[0]+1));\r\n\t  *    if (cp) {\r\n          *       strcat(strcat(cp,\"; \"),argv[0]+2);\r\n\t  *\t  new_append=cp;\r\n\t  *    }\r\n          *    else \r\n          *\t  fprintf(stderr, \"Excessive -I options\\n\");\r\n          * }\r\n          * else \r\n\t  *   fprintf(stderr, \"Excessive -I options\\n\");\r\n          * break; */\r\n\r\n         case 'U':\r\n         case 'D':\r\n            iuds[iud_idx++] = argv[0];\r\n            break;\r\n\r\n         case 'L':\r\n            addlib(&argv[0][2]);\r\n            break;\r\n\r\n         case 'F':\r\n            argv[0][1] = 'D';\r\n            flgs[flg_idx++] = argv[0];\r\n            break;\r\n\r\n         case 'X':\r\n            nolocal = 1;\r\n\r\n         case 'P':\r\n         case 'M':\r\n         case 'W':\r\n            flgs[flg_idx++] = argv[0];\r\n            break;\r\n\r\n         default:\r\n            fprintf(stderr, \"Unknown flag %s\\n\", argv[0]);\r\n            exit(1);\r\n         }\r\n         continue;\r\n      }\r\n      nfiles++;\r\n      cp = argv[0];\r\n      while(*cp) {\r\n         if(islower(*cp))\r\n            *cp = toupper(*cp);\r\n         cp++;\r\n      }\r\n\r\n/* PG: */\r\n      if (strchr(argv[0],'.')==NULL)   /* if no filetype at all */\r\n         argv[0]=strcat(strcpy(xalloc(strlen(argv[0])+3),argv[0]),\".C\");\r\n         /* make it .C */\r\n/* */      \r\n                cp = rindex(argv[0], '.');\r\n      if(cp && (strcmp(cp, \".C\") == 0 || strcmp(cp, \".AS\") == 0)) {\r\n         c_as[c_as_idx++] = argv[0];\r\n/* AM: put object files in the same place as their sources\r\n *     maybe there should be an option controlling this\r\n *       if(xp = rindex(argv[0], ':'))\r\n *          xp++;\r\n *       else  */\r\n            xp = argv[0];\r\n         *cp = 0;\r\n         strcat(strcpy(tmpbuf, xp), \".O\");\r\n         addobj(tmpbuf);\r\n         strcpy(single, tmpbuf);\r\n         *cp = '.';\r\n      } else\r\n         addobj(argv[0]);\r\n   }\r\n   if (outfile && keep && (c_as_idx>1)) {\r\n     fprintf(stderr, \r\n             \"-Oname used while keeping more than one %sfile. (Error)\\n\",\r\n\t     keepas?\"assembly language \":\"object\");\r\n     exit(2);\r\n   }\r\n   if (redir) addobj(REDIR_O);\r\n   setenv(\"APPEND\", new_append);\r\n   i=doit();\r\n   setenv(\"APPEND\", old_append);\r\n   return i;\r\n}\r\n\r\nvoid\r\nsetup()\r\n{\r\n   register char *   cp;\r\n   short      i, len;\r\n\r\n   if (!(cp = getenv(\"PROGRAM\")))\r\n      cp=DEFPATH;\r\n   else\r\n      if (strrchr(cp,'\\\\')) strrchr(cp,'\\\\')[1]='\\0';\r\n   old_append = getenv(\"APPEND\"); if (!old_append) old_append=\"\";\r\n   new_append = strcpy(xalloc(strlen(cp)+1), cp);\r\n   plen=strlen(cp);\r\n   for (i = 0 ; i < sizeof paths/sizeof paths[0] ; i++)\r\n      if (paths[i][0]=='~') \r\n\t paths[i] = strcat(strcat(strcpy(xalloc(plen+strlen(paths[i])+4), \r\n\t\t\t\t\t cp), paths[i]+1), \".COM\");\r\n   if (cp!=DEFPATH) free(cp);\r\n   if (cp = getenv(TEMP)) {\r\n      len = strlen(cp);\r\n      for(i = 0 ; i < sizeof temps/sizeof temps[0] ; i++)\r\n         temps[i]=strcat(strcpy(xalloc(len+strlen(temps[i])+1),cp),temps[i]);\r\n      free(cp);\r\n   }\r\n\r\n   objs[0] = strtoff;\r\n   obj_idx = 1;\r\n   flgs[0] = LFLAGS;\r\n   flg_idx = 1;\r\n   for(i = 0 ; i < sizeof cppdef/sizeof cppdef[0] ; i++)\r\n      iuds[i] = cppdef[i];\r\n   iud_idx = i;\r\n   outfile = NULL;\r\n}\r\n\r\nint  compile(char *, char *);\r\nint assemble(char *, char *);\r\nint doexec(char *, char **);\r\nchar * set_ext(char*, char*, char*, int);\r\n\r\nint\r\ndoit()\r\n{\r\n   register char *   cp;\r\n   register uchar   i;\r\n   char *outf, buf[20];\r\n   int res;\r\n\r\n   if(xref)\r\n      close(creat(crtmp, 0600));\r\n   iuds[iud_idx++] = cpppath;\r\n   for(i = res = 0 ; (i < c_as_idx) && (res == 0) ; i++) {\r\n      if ( verbose && (c_as_idx > 1) )\r\n         printf(\"Working on: '%s'.\\n\",c_as[i]);\r\n      cp = rindex(c_as[i], '.');\r\n      if(strcmp(cp, \".C\") == 0) {\r\n\t outf=(keep && outfile) ? outfile\r\n\t                        : set_ext(buf, c_as[i], keepas?\".AS\":\".O\", 20);\t\r\n         res = compile(c_as[i], outf);\r\n      }\r\n      else {\r\n\t outf=(keep && outfile) ? outfile\r\n\t                        : set_ext(buf, c_as[i], \".O\", 20);\t\r\n         res = assemble(c_as[i], outf);\r\n      }\r\n   }\r\n   remove(tmpf1);\r\n   remove(tmpf2);\r\n   remove(tmpf3);\r\n   if (!keep && !res && (obj_idx>1)) {\r\n      if (!outfile)\r\n\t outfile=set_ext(buf,objs[nocrto?2:1],\".COM\",20);\r\n      flgs[flg_idx++] = \"-Ptext=0,data,bss\";\r\n      if (reloc) {\r\n         flgs[flg_idx++] = strcat(strcpy(xalloc(strlen(l_dot_obj)+3), \r\n\t\t\t\t\t\t\"-o\"), l_dot_obj);\r\n      } \r\n      else {\r\n         flgs[flg_idx++] = \"-C100H\";\r\n         flgs[flg_idx++] = strcat(strcpy(xalloc(strlen(outfile)+3), \r\n\t\t\t\t\t \"-O\"), outfile);\r\n      }\r\n      /* skip standard startoff file if desired - AM */\r\n      for (i = (nocrto?1:0) ; i < obj_idx ; i++) {\r\n         flgs[flg_idx++] = objs[i];\r\n      }\r\n      addlib(STDLIB);\r\n      for (i = 0 ; i < lib_idx ; i++) {\r\n         flgs[flg_idx++] = libs[i];\r\n      }\r\n      flgs[flg_idx] = 0;\r\n      res = doexec(linker, flgs);\r\n      if (reloc && !res) {\r\n         flgs[0] = \"-R\";\r\n         flgs[1] = \"-B100H\";\r\n         flgs[2] = l_dot_obj;\r\n         flgs[3] = outfile;\r\n         flgs[4] = (char *)0;\r\n         res = doexec(objto, flgs);\r\n         remove(l_dot_obj);\r\n      }\r\n      if (c_as_idx == 1 && nfiles == 1)\r\n         remove(single);\r\n   }\r\n   if (xref && !res)\r\n      if (xrname) {\r\n         flgs[0] = xrname;\r\n         strcat(strcpy(tmpbuf, \"-h\"), outfile);\r\n         if(cp = rindex(tmpbuf, '.'))\r\n            strcpy(cp, \".CRF\");\r\n         else\r\n            strcat(tmpbuf, \".CRF\");\r\n         flgs[1] = tmpbuf;\r\n         flgs[2] = crtmp;\r\n         flgs[3] = 0;\r\n         res = doexec(cref, flgs);\r\n            remove(crtmp);\r\n      } else\r\n         fprintf(stderr, \"Cross reference info left in %s:\\\r\n run CREF to produce listing\\n\", crtmp);\r\n\r\n   return res;\r\n}\r\n\r\naddobj(s)\r\nchar *   s;\r\n{\r\n   char *   cp;\r\n\r\n   cp = xalloc(strlen(s)+1);\r\n   strcpy(cp, s);\r\n   objs[obj_idx++] = cp;\r\n}\r\n\r\naddlib(s)\r\nchar *   s;\r\n{\r\n   char *   cp;\r\n\r\n   strcpy(tmpbuf, libpath);\r\n   strcat(strcat(tmpbuf, s), LIBSUFF);\r\n   cp = xalloc(strlen(tmpbuf)+1);\r\n   strcpy(cp, tmpbuf);\r\n   libs[lib_idx++] = cp;\r\n}\r\n\r\nvoid \r\nerror(s, a)\r\nchar *   s;\r\n{\r\n   fprintf(stderr, s, a);\r\n   stack_trace();\r\n   exit(1);\r\n}\r\n\r\n\r\nstatic char *\r\nxalloc(s)\r\nshort   s;\r\n{\r\n   register char *   cp;\r\n\r\n   if(!(cp = malloc(s)))\r\n      error(\"Out of memory\");\r\n   return cp;\r\n}\r\n\r\nupcase(s)\r\nregister char *   s;\r\n{\r\n   while(*s) {\r\n      if(*s >= 'a' && *s <= 'z')\r\n         *s -= 'a'-'A';\r\n      s++;\r\n   }\r\n}\r\n\r\nint _spawn(char *, char *, char fds[3]);\r\n\r\nint\r\ndoexec(name, vec)\r\nchar *   name;\r\nchar **   vec;\r\n{\r\n   uchar   len;\r\n   int res;\r\n   char **   pvec;\r\n   char *   redir[2];\r\n   FILE *   cfile;\r\n   char   redbuf[20];\r\n   char   xbuf[130];\r\n   static char fds[3] = { 0, 1, 2 };\r\n\r\n   pvec = vec;\r\n\r\n   len = 0;\r\n   redbuf[0] = 0;\r\n   while (*pvec)\r\n      len += strlen(*pvec++)+1;\r\n\r\n   if (len > 124) {\r\n      if(!(cfile = fopen(redname, \"w\"))) {\r\n\t perror(redname);\r\n         fputs(\", can't create file to pass options.\\n\",stderr);\r\n         return 1;\r\n      }\r\n      len = 0;\r\n      while(*vec) {\r\n         len += strlen(*vec)+1;\r\n         if (len > 126) {\r\n            len = strlen(*vec)+1;\r\n            fprintf(cfile, \"\\\\\\n\");\r\n         }\r\n\t if (verbose) printf(\"%s \",*vec);\r\n         fprintf(cfile, \"%s \", *vec++);\r\n      }\r\n      fputc('\\n', cfile);\r\n      putchar('\\n');\r\n      fclose(cfile);\r\n      redir[1] = (char *)0;\r\n      sprintf(redbuf, \"<%s\", redname);\r\n      redir[0] = redbuf;\r\n      vec = redir;\r\n   }\r\n\r\n   xbuf[0] = 0;\r\n   while(*vec)\r\n      strcat(strcat(xbuf, \" \"), *vec++);\r\n\r\n   if (verbose) printf(\"[CC] %s %s\\n\", name, xbuf);\r\n   res=_spawn(name, xbuf, fds);\r\n\r\n   if (*redbuf)\r\n      remove(redbuf+1);\r\n   return res;\r\n}\r\n\r\nint\r\nassemble(s,d)\r\nchar * s;\r\nchar * d;\t\r\n{\r\n   char *   vec[5];\r\n   char   buf[80];\r\n   uchar   i;\r\n\r\n   i = 0;\r\n   if (optimize && !speed)\r\n      vec[i++] = \"-J\";\r\n   if (nolocal)\r\n      vec[i++] = \"-X\";\r\n/* AM: put object files in the same place as their sources\r\n *     maybe there should be an option controlling this\r\n * if(cp = rindex(s, ':'))\r\n *    cp++;\r\n * else\r\n *    cp = d; */\r\n   strcat(strcpy(buf, \"-O\"), d);\r\n\r\n   vec[i++] = buf;\r\n   vec[i++] = s;\r\n   vec[i] = (char *)0;\r\n   return doexec(assem, vec);\r\n}\r\n\r\nint\r\ncompile(s,d)\r\nchar * s;\r\nchar * d;\r\n{\r\n   register char *   cp;\r\n   uchar   i, j;\r\n   int res;\r\n   char *   vec[MAXLIST];\r\n   char   cbuf[50];\r\n\r\n   for(j = 0; j < iud_idx ; j++)\r\n      vec[j] = iuds[j];\r\n   vec[j++] = s;\r\n   vec[j++] = tmpf1;\r\n   vec[j] = (char *)0;\r\n   res=doexec(cpp, vec);\r\n   if (res) {\r\n      fprintf(stderr,\"CPP failed on '%s'.\\n\",s);\r\n      return res;\r\n   }\r\n/* AM: put object files in the same place as their sources\r\n *     maybe there should be an option controlling this\r\n * if(cp = rindex(s, ':'))\r\n *    s = cp+1; */\r\n   *rindex(s, '.') = 0;\r\n   i = 0;\r\n   if(keepas && !optimize)\r\n      vec[i++] = \"-S\";\r\n   if(xref)\r\n      vec[i++] = strcat(strcpy(cbuf, \"-c\"), crtmp);\r\n   if(ebuf[0])      /* error redirection */\r\n      vec[i++] = ebuf;\r\n   vec[i++] = tmpf1;\r\n   vec[i++] = tmpf2;\r\n   vec[i++] = tmpf3;\r\n   vec[i++] = (char *)0;\r\n   res=doexec(pass1, vec);\r\n   if (res) {\r\n      fprintf(stderr,\"Pass1 failed while processing '%s'.\\n\",s);\r\n      return res;\r\n   }\r\n   vec[0] = tmpf2;\r\n   vec[1] = keepas && !optimize ? d : tmpf1;\r\n   vec[2] = (char *)0;\r\n   res=doexec(cgen, vec);\r\n   if (res) {\r\n      fprintf(stderr,\"Code generator failed while processing '%s'.\\n\",s);\r\n      return res;\r\n   }\r\n   if(keepas && !optimize)\r\n      return res;\r\n   cp = tmpf1;\r\n   if(optimize) {\r\n      i = 0;\r\n      if (speed)\r\n         vec[i++] = \"-F\";\r\n      vec[i++] = tmpf1;\r\n      if (keepas)\r\n         vec[i++] = d;\r\n      else\r\n         vec[i++] = tmpf2;\r\n      vec[i] = (char *)0;\r\n      res=doexec(optim, vec);\r\n      if (res) {\r\n         fprintf(stderr,\"Optimiser failed while processing '%s'.\\n\",s);\r\n         return res;\r\n      }\r\n      if (keepas)\r\n         return res;\r\n      cp = tmpf2;\r\n   }\r\n   i = 0;\r\n   if (nolocal)\r\n      vec[i++] = \"-X\";\r\n   if (optimize && !speed)\r\n      vec[i++] = \"-J\";\r\n   vec[i++] = \"-N\";\r\n   vec[i++] = strcat(strcpy(tmpbuf, \"-o\"), d);\r\n   vec[i++] = cp;\r\n   vec[i] = (char *)0;\r\n   res=doexec(assem, vec);\r\n   if (res)\r\n      fprintf(stderr,\"Assembler failed while processing '%s'.\\n\",s);\r\n   return res;\r\n}\r\n\r\nchar * set_ext(char *buf, char *nm, char *ex, int len)\r\n{\r\n  char *p;\r\n  \r\n  strncpy(buf, nm, len-strlen(ex)-2);\r\n  buf[len-strlen(ex)-1]=0;\r\n  p=strrchr(buf, '.');\r\n  if (p) *p=0;\r\n  strcat(buf, ex);\r\n  return buf;\r\n}\r\n\r\n/* printf debugging: */\r\n\r\ntypedef struct sf {\r\n  struct sf * up;\r\n  int \tiy;\r\n  char\t* pc;\r\n} frame ;\r\n\r\nvoid stack_trace()\r\n{\r\n  int i;\r\n  frame *fp;\r\n\r\n  fp=(frame *)((&i)+1);\r\n  while ( (unsigned int) (fp->up)>(unsigned int) fp ) {\r\n    fprintf(stderr, \"Called from %04x  (fp=%04x),\\n\", fp->pc-3, fp);\r\n    fp = fp->up;\r\n  }\r\n  fprintf(stderr, \"Called from %04x.\\n\", fp->pc-3);\r\n}\r\n/* end of source *****************************************************/\r\n\u001a"
  },
  {
    "path": "msx2dist/cc_01/CC.TXT",
    "content": "*** CC - improved control program for HiTech-C and msx-dos2\r\n\r\nThe program cc.com executes the passes to compile a  C-program  with\r\nHiTech-C automatically. The c.com from Hi-Tech does  the  same,  but\r\ncc.com has the following advantages:\r\n\r\n - cc.com does not use a batchfile and stops if a pass has failed\r\n - cc.com sets the append-variable so that your source can  be  in  a\r\n   different directory than the compiler.\r\n\r\n* How to install\r\n\r\nFirst you need to install MSX-DOS2. Then get the HI-TECH Z80 CP/M  C\r\nCompiler from  ftp://ftp.funet.fi/pub/msx/programming/c/hitech-?.pma\r\nand unpack with pmext. HiTech has been so kind to  grant  permission\r\nto   use   their   C-compiler   free    of    charge,    see    also\r\nhttp://www.htsoft.com/products/CPM.php . \r\n\r\nUnpack cc.lzh to the directory that contains the C-compiler.\r\n\r\nYou should get the following files:\r\n\r\ncc.com\t\t- replacement for c.com\r\nlibdos2.lib\t- IO-library using msx-dos2, source is in libdos.lzh \r\nvsh1.o\t\t)   variants of crt.o for\r\nvsh2.o          ) - programs executing other programs\r\nvsh3.o\t\t)   see vsh.txt for details\r\nvsh.txt\t\t- text about vsh?.o\r\nredir.obj\t- used in a work-around for -U bug in link.com \r\ncc.txt\t\t- this text \r\ncc.c \t\t- source for cc.com\r\nvshrt.as \t- source for vsh?.o\r\nredir.as\t- source for redir.obj\r\nmakefile\r\npack.bat\r\n\r\n* Using cc\r\n\r\nYou can invoke CC with:\r\n\r\ncc <options> <files>\r\n\r\nThe following options are recognised:\r\n\r\n-C\t       : keep the object file; do not link\r\n-CR[file]      : produce cross refenerence file\r\n-O             : optimise assembly code generated by CGEN with OPTIM\r\n-O<file>       : put output in <file>\r\n-I<dir>        : passed to CPP  as  extra  search-path  for  include\r\n                 files, only works for drives, the  directory  where\r\n                 cc.com is stored  is  always  searched  via  APPEND\r\n                 environment variable\r\n-V\t       : verbose mode, print out commands of subprocesses\r\n-F<file>       : write symbol file\r\n-U<sym>        : undefine symbol for CPP\r\n-D<sym>[=<def>]: define symbol for CPP\r\n-S             : keep assembly file; do not assemble or link\r\n-X             : strip local symbols, also passed to LINK\r\n-P<pspec>      : define order of psect (not normally needed)\r\n-M<file>       : write map file\r\n-W<n>          : width for map file\r\n-l<xx>\t       : pass lib<xx>.lib to LINK, order is important\r\n\r\nAll options are case insensitive.\r\n\r\nfiles:\r\n\r\nFiles with no extension get the extension \".c\". Files with extension\r\n\".c\" are treated as C language  sourcefiles.  Files  with  extension\r\n\".as\" are treated as assembly assembly language  source  files.  All\r\nother files are passed directly to the linker.\r\n\r\n* Environment item\r\n\r\nVSHTOP: If set, VSHTOP specifies the first page of video memory that\r\n\twill not be used or probed by CC. Pages  0..7  are  ordinary\r\n\tvideo memory, pages 8..11 are  the  extended  video  memory.\r\n\tLegal values are 2..12, default  is  12.  Other  values  are\r\n\tsilently ignored. If VSHTOP is 2, CC will not work.\r\n\tYou can use this to protect data in higher pages. \r\n\tSome emulators may need vshtop=8.\r\n\r\n* Notes\r\n\r\nCC.COM uses video memory for temporary storage, so it  will  corrupt\r\nthe contents of a ramdisk that also uses video memory. \r\nThe screen will flash between the  compilation  steps,  this  is  to\r\nimprove reliability of  reading/writing  from/to  video  memory  and\r\nshould not be cause for concern. \r\n\r\nHiTech-C cannot handle large C-files. This is not a  real  problem;\r\njust split your program in to C-files of about 6 or 7 kB. The  MAKE\r\nprogram by Arnold metselaar can be used with CC.com to compile only\r\nthose modules that need to be recompiled. \r\n\r\n* See also: \r\n\tThe documantation that comes with HiTech-C\r\n\tDocumentation about the C language in general\r\n\tvsh.txt\r\n\r\n* Authors\r\n\r\nCC.C is based on work by HiTech and Pierre Gielen. Arnold Metselaar\r\nadded the code to execute a subprogram and then continue  the  main\r\nprogram.\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/cc_01/MAKEFILE",
    "content": "# makefile for a:\\hitech\r\n\r\nDIST = cc_01.lzh\r\nSRC = cc.c vshrt.as redir.as makefile\r\nBIN = cc.com vsh1.o vsh2.o vsh3.o redir.obj\r\nXTRA = cc.txt vsh.txt libdos2.lib\r\n\r\n..all : cc.com vsh1.o vsh2.o vsh3.o redir.obj\r\n\r\ncc_new.com : cc.o vsh2.o libdos2.lib\r\n\tcc -Occ_new.com -R -Mcc.map -N vsh2.o cc.o libdos2.lib\r\n\r\ncc.o : cc.c\r\n\tcc -c -o -v cc\r\n\r\nvsh1.o : vshrt.as\r\n\techo mypages equ 1 > mypages.as\r\n\tzas -N -Ovsh1.o vshrt.as\r\n\t:del mypages.as\r\n\r\nvsh2.o : vshrt.as\r\n\techo mypages equ 2 > mypages.as\r\n\tzas -N -Ovsh2.o vshrt.as\r\n\t:del mypages.as\r\n\r\nvsh3.o : vshrt.as\r\n\techo mypages equ 3 > mypages.as\r\n\tzas -N -Ovsh3.o vshrt.as\r\n\t:del mypages.as\r\n\r\nredir.obj : redir.as\r\n\tzas -N -Oredir.obj redir.as\r\n\r\ndistribution : $(DIST)\r\n\r\n$(DIST) : $(SRC) $(BIN) $(XTRA)\r\n\techo del $(DIST) > pack.bat\r\n\txargs >>pack.bat <<EOF  -b lhpack $(DIST)\r\n\t$(SRC)\r\n\t$(BIN)\r\n\t$(XTRA)\r\n\tEOF\r\n\techo lhpack can not be run from make,\r\n\techo please run pack.bat from the command prompt\r\n\r\ncc.com : cc_new.com\r\n\techo new version of cc.com left in cc_new.com, check before copying.\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/cc_01/REDIR.AS",
    "content": "; work-around for bug in LINK.COMs -U option\r\nglobal __getargs \r\n\u001a"
  },
  {
    "path": "msx2dist/cc_01/VSH.TXT",
    "content": "*** VSH - use video memory as stack for executing sub-programs\r\n\r\nThe file vshrt.as contains code to start a sub-program and continue\r\nthe original program afterwards. It  is  assembled  to  3  variants\r\nvshN.o, with N in {1,2,3}. These object files are  intended  to  be\r\nused in stead of the standard crt.o, use CCs -N option to  suppress\r\nlinking of crt.o, and mention vsh[123].o as the first file  on  the\r\ncommand line. \r\n\r\nNote that vshN.o sets the highest address that can be used  by  the\r\nprogram to N*0x4000, make  sure  this  is  large  enough  for  your\r\nprogram; no checks are done during linking or startup.\r\n\r\nAnother program can be called from the C-program with the function:\r\n\r\nint _mspawn(char * subprogram, char * args)\r\n\r\nWhere subprogram is the full name of the program file, which should\r\nnormally end in \".COM\". This program will arrange for the state  of\r\nthe calling program to be stored in the N highest  available  block\r\nof video memory, where extended memory is  considered  higher  than\r\nnormal memory. The file named subprogram will be executed as if  it\r\nwere run from the command prompt  with  arguments  args.  When  the\r\nsubprogram finishes, the state of the calling program  is  restored\r\nand _mspawn returns the exit code from subprogram. \r\nThe exit code can be given with the DOS2 function _TERM (0x62),  or\r\nby storing at address 0x80. The value at 0x80 is only  used  if  it\r\nhas been changed by the subprogram and DOS2  reports  a  zero  exit\r\ncode. \r\nIf starting the subprogram fails, _spawn will return -1, and  errno\r\nwill be set. \r\n\r\nNote that _spawn changes  the  environment  variables  PROGRAM  and\r\nPARAMETERS, you may want to store them before calling _spawn().\r\n\r\nCare should be taken when running large subprograms as they may  be\r\nloaded only partially.\r\n\r\n* How things work\r\n\r\nBefore doing anything else a program linked with  vshN.o  uses  the\r\nDOS2 mapper support routines to complete a piece of code to restore\r\nthe settings in the slotselect and mapper registers, for which  the\r\nstack must be in page 3, then it sets the stackpointer to N*0x4000.\r\n\r\nWhen _spawn is called it first searches the file subprogram and its\r\nfull path is stored in the environment variable PROGRAM and args is\r\ncopied to 0x81 and the environment variable PARAMETERS. \r\nNext it checks whether the launch/restore code is already installed\r\nat the top of the TPA and installs it, if it is  not.  This  allows\r\nnesting of _spawn()s. The launch/restore code costs  256  bytes  of\r\nTPA. \r\nWhen  the  launch/restore  code  is  installed  vsh  looks  at   the\r\nenvironment item VSHTOP, If set, VSHTOP specifies the first page  of\r\nvideo memory that will not be used or probed by VSH. Pages 0..7  are\r\nordinary video memory, pages 8..11 are the  extended  video  memory.\r\nLegal values are 2..12, default is 12.  Other  values  are  silently\r\nignored. You can use this to protect data in higher pages. Emulators\r\nneed vshtop=8 at present.\r\n\r\nFinally _spawn forks a subprocess and opens the file subprogram. It\r\ncalls the launch-code with the file handle the number of  pages  to\r\nstore and a pointer to 'stage-2' of the restore code.\r\nThe launch code checks whether  there  is  enough  space  left  and\r\nupdates an internal 'pointer' to the lowest video  memory  page  in\r\nuse. It stores 256 bytes of 'stage-2' restore code followed by  the\r\ncontents of the area 100h--(#pages*4000h)-1 into the video memory.\r\nFinally it reads the program into memory and passes control to it.\r\n\r\nThe warm boot entry is deflected to 'stage 1' of the  restore  code\r\nat the top of the TPA. Stage-1 copies 256 bytes from  video  memory\r\nto the area just below  itself  and  then  passes  control  to  the\r\n'stage-2' just read from video memory. \r\nStage-2 restores the mapper and slotselect settings  saved  at  the\r\nstart of the program and  and  continues  with  copying  the  video\r\nmemory to the start of the TPA.\r\nFinally the parent process is joined and _spawn() returns the  exit\r\ncode of the subprogram as described above.\r\n\r\nScreen display is turned off during transfers between  normal  and\r\nvideo memory, to enhance reliability. The flickering this produces\r\nshould not be cause for alarm. \r\n\u001a"
  },
  {
    "path": "msx2dist/cc_01/VSHRT.AS",
    "content": "\tpsect\ttext,global,pure\r\n\tpsect\tdata,global\r\n\tpsect\tbss,global\r\n\r\n\tpsect\ttext\r\n\tdefs\t100h\t\t;Base of CP/M's TPA\r\n\r\n\tglobal\tstart,_main,_exit,__Hbss, __Lbss, __argc_, startup, bDos\r\n; get value for mypages:\r\n*include mypages.as \r\n; mypages equ\tPAGES\r\n\r\nstart:\r\n; store data vram code, sp must be in page 3 to use extbio\r\nhokvld\tequ\t0FB20h\r\nextbio\tequ\t0FFCAh\r\nglobal\tindir\r\n\r\n; check dos version\r\n\r\n\tld\tc, 6Fh ; _DOSVER\r\n\tcall\tbDos\r\n\tor\ta\r\n\tjp      nz,nodos2\r\n\tld\ta,b\r\n\tcp\t2\r\n\tjp\tc,nodos2\r\n\r\n\tld\thl,03F00h\r\n\tadd\thl,sp\r\n\tjr\tnc,noram\t; fail if sp < 0C100h\r\n\tld\ta,(hokvld)\r\n\tand\t01h\r\n\tjr\tz,noram\r\n\tld\tde, 0401h ; mapper support, get variable table address\r\n\txor\ta\r\n\tcall\textbio\r\n\tld\t(ramsltp),a\r\n\tinc\te ; [mapper support], get jump table address\r\n\tcall\textbio\r\n\tld\tde,018h ; offset for put_p0\r\n\tadd\thl,de\r\n\tld\tde,3\t; sizeof(jp nn)\r\n\tld\t(putp0p),hl\r\n\tadd\thl,de\r\n\tcall\tindir\t; get_p0\r\n\tld\t(map0p),a ; mapper segment for page 0\r\n\tadd\thl,de\r\n\tld\t(putp1p),hl\r\n\tadd\thl,de\r\n\tcall\tindir\t; get_p1\r\n\tld\t(map1p),a ; mapper segment for page 1\r\n\tadd\thl,de\r\n\tld\t(putp2p),hl\r\n\tadd\thl,de\r\n\tcall\tindir\t; get_p2\r\n\tld\t(map2p),a ; mapper segment for page 2\r\n\r\n; move stack to keep everything we need to restore in <mypages> pages\r\n\tld\tsp,mypages * 4000h\r\n; the rest is standard\r\n\tld\tde,__Lbss\t;Start of BSS segment\r\n\tscf\t\t\t;set carry\r\n\tld\thl,__Hbss\r\n\tsbc\thl,de\t\t;<size of uninitialized data area>-1\r\n\tld\tc,l\r\n\tld\tb,h\r\n\tld\tl,e\r\n\tld\th,d\r\n\tinc\tde\r\n\tld\t(hl),0\r\n\tldir\t\t\t;clear memory\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,80h\t\t;argument buffer\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tld\t(hl),0\t\t;zero terminate it\r\n\tld\thl,81h\r\n\tpush\thl\r\n\tcall\tstartup\r\n\tpop\tbc\t\t;unjunk stack\r\n\tpop\tbc\r\n\tpush\thl\r\n\tld\thl,(__argc_)\r\n\tpush\thl\r\n\tcall\t_main\r\n\tpush\thl\r\n\tcall\t_exit\r\n\tjp\t0\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n\r\n\tpsect\ttext\r\nnoram:\r\n\tld\tde,noramm\r\n\tld\thl,0DEh ; .NORAM\r\n\tpush\thl\r\n\tjr\t1f\r\nnodos2:\r\n\tld\tde,nodos2m\r\n\tld\thl,085h ; .BADVER\r\n\tpush\thl\r\n1:\r\n\tld\tc,9 ; _STROUT\r\n\tcall\tbDos\r\n\tjp\t_exit\r\n\r\n\tpsect\tdata\r\nnoramm:\r\n\tdefm\t'*** Not enough memory; need 48KiB in TPA'\r\n\tdefb\t13,10,'$'\r\nnodos2m:\r\n\tdefm\t'*** Wrong version of MSX-DOS'\r\n\tdefb\t13,10,'$'\r\n\r\n\r\n;De onderstaande code is gebaseerd op code uit MCCM 65, pp 12--15\r\n;ipv MemMan wordt echter video RAM (en evt EXT. RAM) gebruikt\r\n\r\n; int _spawn (char * program, char *args, char fds[3])\r\n\r\n \tpsect\ttext\r\n__spawn: \r\nglobal csv, cret, indir, __spawn, _errno\r\n \tcall\tcsv\r\n\r\n        ld\te,(ix+6)\r\n        ld\td,(ix+7) ; program\r\n\tpush\tix\r\n\tld\tbc,0640h ; _FFIRST, attr hidden/system\r\n\tld\tix,80h\r\n\tcall\tbDos ; DOS2\r\n\tjr\tz,1f\r\n\tpop\tix\r\n\tld\t(_errno),a\r\n\tld\thl,-1\r\n\tjp cret\r\n1:\r\n        ld\ta,(ix+25) ; drive nr.\r\n\tadd\ta,'A'-1\t\t\r\n        ld\thl,mypages*4000h\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tld\t(hl),':'\r\n\tinc\thl\r\n\tld\t(hl),'\\'\r\n\tinc\thl\r\n\tex\tde,hl\r\n\tld\tc,5Eh ; _WPATH\r\n\tcall\tbDos ; DOS2\r\n\tdec\tde\r\n\tdec\tde\r\n\tdec\tde\r\n\tld\thl, program\r\n\tld\tc,6Ch ; _SENV\r\n\tcall\tbDos ; DOS2\r\n\tpop\tix\r\n        ld\thl,81h\r\n        ld\t(hl),' '\r\n        inc\thl\r\n        ex\tde,hl\r\n        ld\tl,(ix+8)\r\n        ld\th,(ix+9) ; args\r\n        ld\tbc,7eh\r\n12: \r\n        ld\ta,(hl)\r\n        ldi\r\n        jp\tpo, 11f\r\n        or\ta\r\n        jr\tnz, 12b\r\n11: \r\n        dec\tde\r\n \txor\ta\r\n \tld\t(de),a\r\n        ld\ta,e\r\n        sub\t81h\r\n        ld\t(80h),a\r\n\tld\t(lenp),a\r\n\t\r\n        ld\tde,81h\r\n\tld\thl,param\r\n\tld\tc,6Ch\t; _SENV\r\n\tcall\tbDos \t; DOS2\r\n\r\n\tpsect\tdata\r\nprogram:\r\n\tdefm\t'PROGRAM'\r\n\tdefb\t0\r\nparam:\r\n\tdefm\t'PARAMETERS'\r\n\tdefb\t0\r\n\r\n\tpsect\ttext\r\n \tcall\tis_vsh ; is de vshell opgezet ?\r\n        call\tnz, setvsh ; zo niet neerzetten,\r\n        ; vshell is nu opgezet en iy is exitcode - 9\r\n\r\n        ld\tc,60h ; _FORK\r\n        call\tbDos\r\n\tjr\tz,2f\r\n1:\r\n\tld \t(_errno),a\r\n\tld\thl,-1\r\n\tjp\tcret\r\n2:\r\n\tld\ta,b\r\n\tld\t(ppidp),a\r\n\r\n\r\n; The handles in fds[] are used for the stdin/stdout/stderr of the program we\r\n;  start, works only if these handles are inheritable!\r\n\tld\t(ixp),ix\r\n\tld\tl,(ix+10)\r\n\tld\th,(ix+11) ; fds\r\n\txor\ta\r\n4:\r\n\tcp\t(hl)\r\n\tld\tb,a\r\n\tjr\tz,5f\r\n\tpush\taf\r\n\tld\tc,45h ; _CLOSE\r\n\tpush\thl\r\n\tcall\tbDos\r\n\tpop\thl\r\n\tld\tb,(hl)\r\n\tld\tc,47h ; _DUP\r\n\tpush\thl\r\n\tcall\tbDos\r\n\tpop\thl\r\n\tld\te,a\r\n\tpop\taf\r\n5:\t\t\r\n        cp\tb\r\n\tjr\tnz,reopen_err\r\n\tinc\thl\r\n\tinc\ta\r\n\tcp\t3\r\n\tjr\tc,4b\r\n\r\n \tld\tc,43h ; _OPEN\r\n \tld\tde,mypages * 4000h \r\n        ld\ta,1 ; no write\r\n        call\tbDos\r\n        jr\tnz,open_err ; unlikely, file is known to exist\r\n\t; handle in b\r\n        ld\tc,mypages   ; # pages\r\n\tld\tde,vramcode\r\n        ld\thl,(6)\r\n        inc\thl\r\n        inc\thl\r\n        inc\thl\r\n        call\tindir ; do_push, only returns on faillure\r\n;        jr\tc, novram\r\n\r\nnovram:\r\n \tld\te,0DEh\r\nreopen_err:\r\n\tld\ta,e\r\nopen_err:\r\n \tld\t(_errno),a\r\n\tld\tbc,(ppidp-1) ; pid in b\r\n\tld\tc,061h ; _JOIN\r\n\tcall\tbDos ; DOS2\r\n\tld\tix,(ixp)\r\n\tld\thl,-1\r\n        jp\tcret\r\n\r\npsect\ttext\r\n; kijkt of de exitcode in het geheugen staat\r\n; UIT:\tZ vlag aan -> de code staat er, iy = exitcode-9\r\n;\tZ vlag uit -> de code staat er niet, iy ongewijzigd\r\nis_vsh:\r\n \tld\thl,(6)\r\n        ld\tl, .low. (magic-exitcode+9) ; jp nn en jr do_push overslaan\r\n        ld\tde,magic\r\n        ld\tb,3\r\n2:\r\n        ld\ta,(de)\r\n        cp\t(hl)\r\n        ret\tnz ; vshell niet aanwezig\r\n        inc\thl\r\n        inc\tde\r\n        djnz\t2b\r\n\tld\tl,0\r\n\tpush\thl\r\n        pop\tiy\r\n        ret\r\n\r\n; zet de code voor een shell aan de top van het TPA\r\n; UIT: iy - adres kopie exitcode - 9\r\nsetvsh: \r\n; look for VSHTOP in environment\r\n; if it exists, stop testing for videomemory pages at its value \r\npsect\tdata\r\nvshtopn:\r\n\tdefm\t'VSHTOP'\r\n\tdefb\t0\r\npsect\tbss\r\nvshtopv:\r\n\tdefs\t4\r\n\r\npsect\ttext\r\n\tld\thl, vshtopn\r\n\tld\tde, vshtopv\r\n\tld\tbc,046Bh ; 4 bytes buffer space, _GENV\r\n\tcall\tbDos ; DOS2\r\n\tjr\tnz,3f ; too long\r\n\tpush\tde\r\nglobal\t_atoi\r\n\tcall\t_atoi\r\n\tpop\tde\r\n\tld\ta,h\r\n\tor\ta\r\n\tjr\tnz,3f\t; way too high\r\n\tld\ta,l\r\n\tcp\t12\r\n\tjr\tnc,3f\t; too high\r\n\tcp\t2\r\n\tjr\tc,3f\t; too small\r\n\tadd\ta,070q\r\n\tld\t(topp),a\r\n3:\r\n        ld\thl,6\r\n\tld\ta,(0fcc1h) ; exptbl : slotadres bios\r\n        call\t0Ch ; RDSLT\r\n        ld\t(vdprd_),a ; poortnr lezen Vram/Xram\r\n        inc\thl\r\n\tld\ta,(0fcc1h) ; exptbl : slotadres bios\r\n        call\t0Ch ; RDSLT\r\n        inc\ta\r\n        ld\t(vdpcmd_),a ; poortnr vdp commando's\r\n\r\n; turn off interrupts while working with jump addresses and the vdp\r\n\tdi\r\n \tld\ta,(0007h)\r\n        ld\th,a\r\n        dec\ta\r\n        ld\t(0007h),a ; msB nieuwe top van TPA\r\n        ld\td,a\r\n        ld\tbc,09h\r\n        ld\tl,b\r\n        ld\te,b\r\n\tpush\tde\r\n\tpop\tiy\r\n        ldir\t; negen bytes vanaf oude top van TPA\r\n        ld\thl,exitcode\r\n        ld\tbc,lenexit \r\n        ldir\t; eigen exitcode kopieren\r\n\tpush\tde\r\n        ld\tbc,setvdpoff-lenexit-exitcode\r\n        ex\tde,hl\r\n        add\thl,bc ; positie kopie setvdpoff\r\n        ex\tde,hl ; naar de\r\n        ld\thl,setoff0+1-setvdpoff\r\n        add\thl,de\r\n12:\r\n        ld\tc,(hl)\r\n        ld\t(hl),e\r\n        inc\thl\r\n        ld\tb,(hl)\r\n        ld\t(hl),d\r\n        add\thl,bc\r\n        jr\tnc, 12b\r\n\r\n\tpop\tde        \r\n        ld\tbc,setvdpon-lenexit-exitcode\r\n        ex\tde,hl\r\n        add\thl,bc ; positie kopie setvdpon\r\n        ex\tde,hl ; naar de\r\n        ld\thl,seton0+1-setvdpon\r\n        add\thl,de\r\n13:\r\n        ld\tc,(hl)\r\n        ld\t(hl),e\r\n        inc\thl\r\n        ld\tb,(hl)\r\n        ld\t(hl),d\r\n        add\thl,bc\r\n        jr\tnc, 13b\r\n        \r\n        ld\thl,(0001); pointer naar BIOS-Jump vector\r\n        inc\tl ; skip c3h, l wordt 4\r\n        ld\tc,(hl)\r\n        ld\t(iy+old_wb),c\r\n        ld\t(hl), .low. (new_wb-exitcode+9); nieuwe pos. exitcode\r\n        inc\tl\r\n        ld\tb,(hl)\r\n        ld\t(iy+old_wb+1),b\r\n        ld\t(hl),a ; bevat nog steeds msB nieuwe top TPA\r\n\r\n; tel het video geheugen\r\n \tld\ta,071q\r\n2:\r\n        call\tvramtest\r\n        jr\tnz, 1f\r\n        inc\ta\r\n        cp\t104q\r\ntopp\tequ\t$-1\r\n        jr\tnz,2b\r\n1:\r\n \tld\t(iy+top),a\r\n        ld\t(iy+shsp),a\r\n        ld\tde,0\r\n        jp\tsetvdpon ; adresregisters vdp terugzetten, scherm aan\r\n\r\nvramtest:\r\n \tld\td,a\r\n        ld\te,0 ; lezen\r\n        call\tsetvdpoff\r\n        ld\tc,(iy+vdprd)\r\n        in\tl,(c)\r\n        ld\te,40h ; schrijven\r\n        in\th,(c)\r\n        call\tsetvdpoff\r\n        dec\tc\r\n        ld\ta,l\r\n        cpl\r\n        out\t(c),a\r\n        ld\ta,h\r\n        cpl\r\n        out\t(c),a\r\n        ld\te,0 ; lezen\r\n        call\tsetvdpoff\r\n        ld\tc,(iy+vdprd)\r\n        in\ta,(c)\r\n        cpl\r\n        sub\tl\r\n        ld\tb,a\r\n        in\ta,(c)\r\n        cpl\r\n        sub\th\r\n        or\tb\r\n        ld\te,40h ; schrijven\r\n        call\tsetvdpoff\r\n        dec\tbc\t; dec c verandert F, daarom dec bc\r\n        out\t(c),l\r\n        ld\ta,d\r\n        out\t(c),h\r\n        ret\r\n\r\nglobal __cpm_clean        \r\n__cpm_clean:\r\n \tcall\tis_vsh\r\n        ret\tnz ; geen vshell, dan niks weg te halen\r\n        ld\ta,(iy+top)\r\n        cp\t(iy+shsp)\r\n        ret\tnz ; iets op de stack, dan vshell laten staan\r\n; nu hebben we dus iets op te ruimen...\r\n \tdi\r\n \tld\thl,0007h\r\n        inc\t(hl)\r\n        ld\thl,(0001h)\r\n        inc\tl\r\n        ld\ta,(iy+old_wb)\r\n        ld\t(hl),a\r\n        inc\tl\r\n        ld\ta,(iy+old_wb+1)\r\n        ld\t(hl),a\r\n        ei\r\n        ret\r\n\r\n; ===========================================================================\r\n; ==== code die in het videogeheugen wordt opgeslagen en door de         ====\r\n; ==== exitcode vlak onder de exitcode wordt in geladen en uitgevoerd    ====\r\n; ===========================================================================\r\n\r\nvramcode:\r\n\r\n; herstel slotselectie en mapper registers\r\n; ---\r\nenaslt\tequ\t024h\r\n\r\n\tld\ta, 08Bh ; slotadres van mapper, wordt overschreven\r\nramsltp\tequ\t$-1\r\n\tpush\taf\r\n\tld\th, 0\r\n\tcall\tenaslt\r\n\tld\ta,3 \t; segment in page 0, wordt overschreven\r\nmap0p\tequ\t$-1\r\n\tcall\t03050h\t; adres van put_p0 komt hier\r\nputp0p\tequ\t$-2 \r\n\tpop\taf\r\n\t \r\n\tpush\taf\r\n\tld\th, 40h\r\n\tcall\tenaslt\r\n\tld\ta,2 \t; segment in page 1, wordt overschreven\r\nmap1p\tequ\t$-1\r\n\tcall\t03150h\t; adres van put_p1 komt hier\r\nputp1p\tequ\t$-2 \r\n\tpop\taf\r\n\t \r\n\tld\th, 80h\r\n\tcall\tenaslt\r\n\tld\ta,1 \t; segment in page 2, wordt overschreven\r\nmap2p\tequ\t$-1\r\n\tcall\t03250h\t; adres van put_p2 komt hier\r\nputp2p\tequ\t$-2\r\n\r\n; lees de inhoud van de eigen pagina's terug\r\n; ---\r\n\tld\ta,mypages\r\n        ld\td,(iy+shsp)\r\n\tld\te,3Fh\r\n        ld\thl,100h\r\n        jr\trdblk\r\npglus:\r\n\tcall\tsetvdpoff ; e is 0 again -> read\r\n\t\t\t  ;  page 0 has been restored by the time we get here\r\n        ld\te,40h\r\nrdblk:\r\n        ld\tc,(iy+vdprd)\r\n \tld\tb,0\r\n \tinir\r\n \tdec\te\r\n        jr\tnz,rdblk\r\n \tinc\td\r\n        dec\ta\r\n        jr\tnz,pglus\r\n        ld\t(iy+shsp),d\r\n        ld\td,e ; de wordt 0\r\n\tcall\tsetvdpon ; vdp adresregisters terugzetten, scherm aan\r\n\tei\r\n\r\n\tld\tb,1 ; ppid, wordt overschreven\r\nppidp\tequ\t$-1\r\n\tld\tix, 05849h ; ix, wordt overschreven\r\nixp\tequ\t$-2\r\n\r\n; -- this part can also be executed while still in page 0\r\nspwnret:\r\n        ld\tc,61h ; _JOIN\r\n        ld\ta,b ; ppid\r\n        or\ta\r\n        call\tnz,5 ; DOS2\r\n        ld\ta,b ; primary error code\r\n        or\ta\r\n        ld\tl,b\r\n        jr\tnz,errset\r\n        ld\ta,(80h) ; try value at, 80h if none given via DOS\r\n\tcp\t04Fh ; old value of (80h), will be filled in by _spawn()\r\nlenp\tequ\t$-1\r\n\tjr\tz,errset ; probably not set by program\r\n\tld\tl,a\t\r\nerrset:\r\n        xor\ta\r\n        ld\th,a\r\n \tjp\tcret\r\n\r\nlenvram\tequ\t$-vramcode\r\n\r\n; ===========================================================================\r\n; ==== code die naar de bovenkant van het TPA in page 3 gekopieerd wordt ====\r\n; ===========================================================================\r\n\r\npsect\ttext\r\nexitcode: ;  --> xx09h\r\n \tjr\tdo_push\r\nmagic:  ; ..b\r\n \tdefm\t'vsh'\r\njump:\r\n\tdefb\t0C3h ; jp\r\ndata:\t; ..f\r\n \tdefw\t0 ; overschreven door hoofdprog.\r\n \tdefb\t0104q, 0104q\r\nvdprd_:\r\n\tdefb\t98h\r\nvdpcmd_:\r\n\tdefb\t99h\r\n\r\n\r\nold_wb\tequ\tdata-exitcode+9\r\nshsp\tequ\told_wb+2\r\ntop\tequ\tshsp+1\r\nvdprd\tequ\tshsp+2\r\nvdpcmd\tequ\tshsp+3\r\n        \r\nnew_wb: ; --> xx15h\r\n \tld\thl,(0006h)\r\n\tld\tl,0\r\n\tpush\thl\r\n\tpop\tiy\r\n        ld\td,(iy+shsp)\r\n        ld\ta,(iy+top)\r\n        cp\td\r\n        jr\tnz, do_pop\r\n        ld\tl, .low. (jump-exitcode+9)\r\n        jp\t(hl)\r\ndo_pop:\r\n\tdec\th\r\n        ld\tsp,hl\r\n        di\r\n        ld\te,0 ; lezen in vram, pagenr. in d\r\nsetoff0:call\tsetoff2-setoff0-1 ; offset naar volgende plek waar het adres\r\n\t\t\t\t  ; \tvan de kopie van setvdpoff moet worden\r\n\t\t\t\t  ;\tingevuld\r\n        ld\tc,(iy+vdprd)\r\n\tld\tb,0\r\n\tinir\r\n\tdec\th\r\n\tjp\t(hl)\r\n\r\n; bewaart het werkgeheugen in video geheugen en laadt en runt dan \r\n; het programma waarvan de filehandle in D staat.\r\n; Return via new_wb. De stackpointer wordt niet bewaard omdat\r\n; deze toch al wordt hersteld bij een jp cret\r\n; \r\n; IN:\r\n;\t(sp) -\treturn adres indien vram vol\r\n;\tiy   -\tadres exitcode -9\r\n;\tde   -\tadres van terugkeercode, wordt door new_wb geladen op iy-100h\r\n;\t\ten daar uitgevoerd\r\n;\tb    -\tfilehandle voor _READ\r\n;\tc    -\taantal pages om op te slaan\r\ndo_push:\r\n \tld\ta,(iy+shsp)\r\n        sub\tc\r\n        cp\t071q\r\n        ret\tc ; not enough space\r\n        \r\nmem_ok:\r\n \tdi\r\n        ld\tsp,iy ; switch to new stack\r\n        push\tbc ; handle, #pages\r\n        ld\t(iy+shsp),a\r\n\tex\tde,hl\r\n        ld\td,a\r\n\tld\ta,c     ; #pages\r\n        ld\te,40h\t; schrijven\r\nsetoff2:call\tsetoff3-setoff2-1 ; nog een stap verder ...\r\n        dec\tc\t; vdpwr\r\n\tld\tb,0\r\n\totir\t; store 100h bytes with code to restore calling program in vram\r\n\r\n        ld\thl,100h ; TPA starts at 100h\r\n        jr\tblkdone\r\nwpglus:\r\n \tinc\td\r\n        ld\te,40h ; schrijven, 40h maal 100h bytes\r\nsetoff3:call\t-1 ; de laatste stap\r\n        dec\tc\r\nwrblk:\r\n \tld\tb,0\r\n \totir\r\nblkdone:\r\n \tdec\te\r\n        jr\tnz,wrblk\r\n        dec\ta\r\n        jr\tnz,wpglus\r\n        ld\td,e ; e=0; adresregisters goed te zetten\r\nseton0:\tcall\t-1  ; add hl,-1 geeft carry -> stoppen met invullen\r\n        ei\r\n        pop\tbc ; file handle in b\r\n\tpush\tde ; 0: return adres voor het te laden programma \r\n        ld\tde,100h\r\n        push\tde ; save load address as start adress\r\n        push\tbc\r\n        ld\thl,-500h ; keep at least 1KiB space for stack\r\n        add\thl,sp\r\n        ld\tc,48h ; _READ\r\n        call\tbDos\r\n        jp\tnz,0 ; als het fout gaat, return via new_wb\r\n        pop\tbc\r\n        ld\tc,45h ; _CLOSE\r\n        call\tbDos\r\n\tld\ta,1\r\n\tld\t(37h),a ; set load flag; PROGRAM and PARAMETERS set in _spawn\r\n\tret\t; to 100h\r\n\r\n; stelt vdp in voor lezen of schrijven\r\n; IN \t- d= 0xyz octaal \r\n; \t\tx=1: external ram, x=0: video ram\r\n;\t\tz = bit 17..15 van adres (bit 14..0 zijn nul)\r\n;\t- e=0h: lezen, e=40h: schrijven, \r\n;\t- iy = exitcode-9\r\n; OUT\t- c=vdp write-adr+1\r\n; WIJZIGT: bc, af'\r\nsetvdpon:\r\n\tex\taf,af'\r\n\tld\ta,(RG1SAV)\r\n\tdefb\t01h ; ld bc, \r\nsetvdpoff:\r\n \tex\taf,af' ;   0x..08\r\n\txor\ta      ;  +0xaf..\r\n        ld\tc,(iy+vdpcmd)\r\n\tout\t(c),a\r\n\tld\ta,81h\r\n\tout\t(c),a ; schrijf reg 1: scherm aan/uit\r\n\trrca\t; a wordt 0300q\r\n        and\td ; a wordt 0100q (ext. ram) of 0 (norm. vram)\r\n        out\t(c),a\r\n        ld\ta,80h+45\r\n        out\t(c),a ; reg. 45 schrijven\r\n        ld\ta,7\r\n        and\td\r\n        out\t(c),a\r\n        ld\ta,80h+14\r\n        out\t(c),a ; reg. 14 schrijven\r\n        xor\ta\r\n        out\t(c),a\r\n        out\t(c),e ; stel adres en mode in\r\n        ex\taf,af'\r\n        ret\r\n \t\r\nlenexit equ\t$-exitcode\r\n; ===== eind van gekopieerde code\r\n\r\nRG1SAV equ      0F3E0h\r\n\r\n\tend\tstart\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/ACT_FILE.AS",
    "content": "global\t__act_file\r\nglobal\tncsv, cret, indir, bDos\r\nglobal\t__flip\r\nglobal\tamod\r\nglobal\t_errno, cret\r\npsect\ttext\r\n; int _act_file(char * name, short mode, short bc)\r\n__act_file:\r\ncall ncsv\r\ndefw -67\r\nld\thl,67\r\npush\thl\r\nld\tl,(ix+6)\r\nld\th,(ix+7)\r\npush\thl\r\npush\tix\r\npop\tde\r\nld\thl,-67\r\nadd\thl,de\r\npush\thl\r\ncall\t__flip\r\npop\tbc\r\npop\tbc\r\npop\tbc\r\nld\ta,l\r\nor\th\r\njp\tnz,l2\r\nL2:\r\nld\thl,-1\r\njp\tcret\r\nl2:\r\n; #asm\r\nglobal _errno, cret\r\npush\tix\r\npop\thl\r\nld\tde,-67\r\nadd\thl,de\r\nex\tde,hl \r\n; ld\ta, (ix+8)\r\nld\tc, (ix+8)\r\nld\tb,0 ; 8 bits is enough\r\nld\thl, modtab\r\nadd\thl,bc\r\nld\ta,(hl)\r\npsect\tdata\r\nmodtab:\r\ndefb\t1,2,0,3,5,6,4,7, 10h ; translate mode to dos2 conventions\r\npsect\ttext\r\nld\tc, (ix+10) ; bdos function code\r\nld\tb, (ix+11) ; attributes (for create) \r\nld\tl,b ; attributes (for chmod)\r\ncall\tbDos\r\njr\tz,1f\r\nld\t(_errno),a\r\nxor\ta\r\nld\t(_errno+1),a\r\nld\thl,-1\r\njp\tcret ; return -1\r\n1:\r\nld\thl,0\r\nld\ta,(ix+10) ; function code\r\ncp\t45h\r\njp\tnc,cret ; return 0 (success) if called by chmod, unlink or rmdir  \r\nld\tl,b ; file handle/descriptor, called by open, creat or mkdir\r\n; #endasm\r\njp\tcret\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/ASSERT.C",
    "content": "#include\t<assert.h>\r\n#include\t<stdio.h>\r\n\r\nvoid\r\n_fassert(line, file, exp)\r\nchar *\tfile, * exp;\r\nint\tline;\r\n{\r\n\tfprintf(stderr, \"Assertion failed: %s line %d: \\\"%s\\\"\\n\", file, line, exp);\r\n\tabort();\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/BUF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern char *\tsbrk();\r\n\r\nstatic union stdbuf\r\n{\r\n\tchar\t\tbufarea[BUFSIZ];\r\n\tunion stdbuf *\tlink;\r\n} *\tfreep;\r\n\r\nchar *\r\n_bufallo()\r\n{\r\n\tregister union stdbuf *\tpp;\r\n\r\n\tif(pp = freep)\r\n\t\tfreep = pp->link;\r\n\telse\r\n\t\tpp = (union stdbuf *)sbrk(BUFSIZ);\r\n\treturn pp->bufarea;\r\n}\r\n\r\n_buffree(pp)\r\nchar *\tpp;\r\n{\r\n\tregister union stdbuf *\tup;\r\n\r\n\tup = (union stdbuf *)pp;\r\n\tup->link = freep;\r\n\tfreep = up;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CGETS.C",
    "content": "extern int\tgetche();\r\n\r\nchar *\r\ncgets(s)\r\nchar *\ts;\r\n{\r\n\tchar *\ts1 = s;\r\n\tint\tc;\r\n\r\n\twhile((c = getche()) != '\\r' &&  c != '\\n')\r\n\t\t*s++ = c;\r\n\t*s = 0;\r\n\tif(s == s1)\r\n\t\treturn((char *)0);\r\n\treturn(s1);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CHANGES",
    "content": "2013-08-10  Arnold Metselaar (arnold.metselaar@planet.nl)\r\n\t* Include makefile in package.\r\n\t* rename.c: set C register before calling bDos\r\n\t* stat.c: new file\r\n\t* perror.c: slight changes so that we can ...\r\n\t* makefile (stat.c, perror.c, rename.c): ... use optim\r\n        * stat.h: new file\r\n\t* dirent.h: declare rmdir and mkdir\r\n\t*\u0001@utime.c, _utime.as: new files\r\n\r\n2006-08-29  Arnold Metselaar (arnold.metselaar@planet.nl)\r\n\t* unixio.h: Added to distribution, define O_INHER and\r\n\tfriends.\r\n\t* libdos2.txt: explain constants for open().\r\n\r\n2006-04-15  Arnold Metselaar (arnold.metselaar@planet.nl)\r\n\t* readdir.as: Fully support \".\" as a shorthand for the current \r\n\tdirectory, allow to open root directories.\r\n\r\n2006-04-15  Arnold Metselaar (arnold.metselaar@planet.nl)\r\n\t* flip.c: Removed and replaced by ...\r\n\t* flip.as: new file.\r\n\t* rmdir.c: New file. \r\n\t* mkdir.c: New file.\r\n\t* dirent.h: New file.\r\n\t* opendir.as: New file.\r\n\t* readdir.as: New file.\r\n        * closedir.as: New file.\r\n\t* rewnddir.as: New file.\r\n\t* lib.cmd: Removed.\r\n\t* makefile (libdos2.lib): Use a here-document with smart substitutions\r\n\tinstead of lib.cmd. \r\n\t* makefile (unlink.obj): enable optimiser.\r\n\t* makefile: Added new files, some reordering.\r\n\t* libdos2.txt: Added documentation for new functions.\r\n\r\n2006-04-14  Arnold Metselaar (arnold.metselaar@planet.nl) \r\n\t* libdos2.txt: added a remark about libc.lib still being needed.\r\n\r\n2006-01-29  Arnold Metselaar (arnold.metselaar@planet.nl)\r\n\t* doprnt.c(ival, doprnt): Use unsigned int for string lengths, this\r\n\tfixes errors when printing long strings (make.com)\r\n\t* time.c, ctime.c: No longer in libdos2; both work under msxdos1 and\r\n\tare still available as part of the patched libc.lib.\r\n\t* lib.cmd: time.obj and ctime.obj removed. \r\n\t* makefile: Simplified using new features in make.\r\n\t* pack.bat: Removed from the package, generated on demand by make.\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CHDIR.C",
    "content": "/*\r\n * file: chdir.c\r\n * author Arnold Metselaar\r\n */\r\nint _act_file(char * name, short mode, short bc);\r\n\r\nint chdir(char * pad)\r\n{\r\n  return _act_file(pad, 0, 0x0059);\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CHMOD.C",
    "content": "#include\t<stat.h>\r\n\r\nextern int errno;\r\nextern int _act_file(char*, short, short);\r\n\r\nchmod(name, mode)\r\nregister char *\tname;\r\n{\r\n  int bc;\r\n  \r\n  bc=0x50;\r\n  if ((mode & S_IWRITE) == 0) bc|=0x100;\r\n  if (mode & S_HIDDEN) bc|=0x200;\r\n  if (mode & S_SYSTEM) bc|=0x400;\r\n  if (mode & S_ARCHIVE) bc|=0x2000;\r\n  \r\n  return _act_file (name, 0, bc);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CLOSE.C",
    "content": "#include\t\"cpm.h\"\r\n\r\nclose(fd)\r\nint\tfd;\r\n{\r\n#asm\r\nglobal _errno, cret, bDos\r\n  ld c,045h\r\n  ld b,(ix+6) ; fd\r\n  call bDos\r\n  ld hl,0\r\n  jp z, cret\r\n  dec hl\r\n  ld (_errno),a\r\n  xor a\r\n  ld (_errno+1),a\r\n#endasm\r\n  /* implicit return hl; */\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CLOSEDIR.AS",
    "content": "; closedir.as\r\n\r\n; int closedir (DIR * dir)\r\n; {\r\n;   free(dir);\r\n;   return 0;\r\n; }\r\n \r\nglobal _closedir\r\nglobal _free\r\npsect text\r\n\r\n_closedir:\r\npop hl\r\npop de ; dir\r\npush de\r\npush hl\r\npush de\r\ncall _free\r\npop de\r\nld hl,0\r\nret\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CPUTS.C",
    "content": "cputs(s)\r\nregister char *\ts;\r\n{\r\n\twhile(*s)\r\n\t\tputch(*s++);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/CREAT.C",
    "content": "/* \r\n * creat(name, mode)\r\n *\r\n * creates a file with the given name, and opens it for reading and writing\r\n * mode: ignored\r\n *\r\n */\r\nextern int _act_file(char*, int, int);\r\n\r\ncreat(name, mode)\r\nchar *\tname;\r\n{ \r\n  return _act_file(name, 2, 0x0044);\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/DIRENT.H",
    "content": "/* dirent.h */\r\n/* Declarations for directory access in libdos2. */\r\n\r\n#define NAME_MAX 12\r\n\r\nstruct dirent /* A dos2 file information block. */\r\n{\r\n  char d_valid;\r\n  char d_name[NAME_MAX+1];\r\n  char d_attribute;\r\n  unsigned short int d_mtime; \r\n  unsigned short int d_mdate;\r\n  unsigned short int d_cluster; \r\n  unsigned long int d_size;\r\n  char d_drive;\r\n  char d_private[64-26]; /* for use by dos2, do not change */ \r\n} ;\r\n\r\nstruct _dir {\r\n  struct dirent dir_dir;\r\n  struct dirent dir_file;\r\n} ;\r\n\r\ntypedef struct _dir DIR;\r\n\r\nextern DIR * opendir (char * name);\r\nextern struct dirent * readdir (DIR * dir);\r\nextern int closedir (DIR * dir);\r\nextern void rewinddir (DIR * dir);\r\nextern int mkdir (char *);\r\nextern int rmdir (char *);\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/DOPRNT.C",
    "content": "#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n#include\t<string.h>\r\n\r\n\r\n/*\r\n *\tdoprnt for Z80\r\n */\r\n\r\nextern int\tatoi(char *);\r\nextern int\t_pnum();\r\n\r\n/* Routines for formatted output must be able to cope with \r\n   strings longer than 255 bytes.  -  Arnold M */\r\nstatic unsigned int ival;\r\nstatic char *\tx;\r\nstatic FILE *\tffile;\r\n\r\nstatic\r\npputc(c)\r\nchar\tc;\r\n{\r\n\tputc(c, ffile);\r\n}\r\n\r\nstatic char *\r\nicvt(cp)\r\nregister char *\tcp;\r\n{\r\n\tival = atoi(cp);\r\n\twhile(isdigit((unsigned)*cp))\r\n\t\tcp++;\r\n\treturn cp;\r\n}\r\n\r\n_doprnt(file, f, a)\r\nFILE *\tfile;\r\nregister char *\t\tf;\r\nint *\t\ta;\r\n{\r\n\tchar\tc;\r\n\tuchar\tfill, left;\r\n\tunsigned int i, prec, width; /* Allow for long strings.  - Arnold M */ \r\n\tuchar\tbase, sign, len;\r\n\r\n\tffile = file;\r\n\twhile(c = *f++)\r\n\t\tif(c != '%')\r\n\t\t\tpputc(c);\r\n\t\telse {\r\n\t\t\tbase = 10;\r\n\t\t\twidth = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tleft = 0;\r\n\t\t\tlen = sizeof(int)/sizeof *a;\r\n\t\t\tif(*f == '-') {\r\n\t\t\t\tf++;\r\n\t\t\t\tleft++;\r\n\t\t\t}\r\n\t\t\tfill = *f == '0';\r\n\t\t\tif(isdigit((unsigned)*f)) {\r\n\t\t\t\tf = icvt(f);\r\n\t\t\t\twidth = ival;\r\n\t\t\t} else if(*f == '*') {\r\n\t\t\t\twidth = *a++;\r\n\t\t\t\tf++;\r\n\t\t\t}\r\n\t\t\tif(*f == '.')\r\n\t\t\t\tif(*++f == '*') {\r\n\t\t\t\t\tprec = *a++;\r\n\t\t\t\t\tf++;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tf = icvt(f);\r\n\t\t\t\t\tprec = ival;\r\n\t\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tprec = fill ? width : 0;\r\n\t\t\tif(*f == 'l') {\r\n\t\t\t\tf++;\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\t}\r\n\t\t\tswitch(c = *f++) {\r\n\r\n\t\t\tcase 0:\r\n\t\t\t\treturn;\r\n\t\t\tcase 'o':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'd':\r\n\t\t\t\tsign = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'x':\r\n\t\t\t\tsign = 1; /* a-f in lower case */ \r\n\t\t\tcase 'X':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\tx = *(char **)a;\r\n\t\t\t\ta += sizeof(char *)/sizeof *a;\r\n\t\t\t\tif(!x)\r\n\t\t\t\t\tx = \"(null)\";\r\n\t\t\t\ti = strlen(x);\r\ndostring:\r\n\t\t\t\tif(prec && prec < i)\r\n\t\t\t\t\ti = prec;\r\n\t\t\t\tif(width > i)\r\n\t\t\t\t\twidth -= i;\r\n\t\t\t\telse\r\n\t\t\t\t\twidth = 0;\r\n\t\t\t\tif(!left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\twhile(i--)\r\n\t\t\t\t\tpputc(*x++);\r\n\t\t\t\tif(left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\tcontinue;\r\n\t\t\tcase 'c':\r\n\t\t\t\tc = *a++;\r\n\t\t\tdefault:\r\n\t\t\t\tx = &c;\r\n\t\t\t\ti = 1;\r\n\t\t\t\tgoto dostring;\r\n\r\n\t\t\tcase 'u':\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tif(left) {\r\n\t\t\t\tleft = width;\r\n\t\t\t\twidth = 0;\r\n\t\t\t}\r\n\t\t\twidth = _pnum((len == sizeof(int)/sizeof *a ? (sign ? (long)*a : (unsigned long)*a) : *(long *)a), prec, width, sign, base, pputc);\r\n\t\t\ta += len;\r\n\t\t\twhile(left-- > width)\r\n\t\t\t\tpputc(' ');\r\n\t\t}\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/DOSCAN.C",
    "content": "/*\r\n *\t_doscan - implement scanf, fscanf, sscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include \t<ctype.h>\r\n\r\nextern int\tatoi();\r\n\r\nstatic FILE *\tfp;\r\n\r\nstatic\r\nrange(c, base)\r\nint\tc;\r\nuchar\tbase;\r\n{\r\n\tif(isdigit(c))\r\n\t\tc -= '0';\r\n\telse\r\n\t\t{\r\n\t\tif (isupper(c))\r\n\t\t\tc = tolower(c) ;\r\n\t\tif (isalpha(c))\r\n\t\t\tc = c - 'a' + 10 ;\r\n\t\telse\r\n\t\t\treturn -1 ;\r\n\t\t}\r\n\tif (c >= base)\r\n\t\treturn -1 ;\r\n\treturn c ;\r\n}\r\n\r\nstatic\r\nwspace()\r\n{\r\n\tint\tc;\r\n\r\n\twhile(isspace(c = getc(fp)))\r\n\t\tcontinue;\r\n\tif(c != EOF)\r\n\t\tungetc(c, fp);\r\n}\r\n\r\n_doscan(file, fmt, args)\r\nFILE *\t\tfile;\r\nregister char *\tfmt;\r\nint **\t\targs;\r\n{\r\n\tuchar\tc, sign, base, n, noass,len;\r\n\tchar\twidth ;\r\n\tchar *\tsptr;\r\n\tint\tch;\r\n\tlong\tval;\r\n\r\n\tfp = file;\r\n\tn = 0;\r\n\twhile(c = *fmt++) {\r\n\r\n\t\tlen = 0 ;\r\n\t\tif(isspace(c)) {\r\n\t\t\twspace();\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif(c == '%') {\r\n\t\t\tnoass = 0;\r\n\t\t\twidth = 0;\r\nloop:\r\n\t\t\tswitch(c = *fmt++) {\r\n\r\n\t\t\tcase '\\0':\r\n\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\r\n\t\t\tcase '*':\r\n\t\t\t\tnoass++;\r\n\t\t\t\tgoto loop;\r\n\r\n\t\t\tcase 'l':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'h':\r\n\t\t\t\tgoto loop;\r\n\r\n\t\t\tcase 'D':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'd':\r\n\t\t\t\tbase = 10;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'O':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'o':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'X':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'x':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak ;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\twspace();\r\n\t\t\t\tif ( !noass )\r\n\t\t\t\t\tsptr = (char *)*args++;\r\n\t\t\t\tif ((ch = getc(fp)) == EOF )\r\n\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\twhile(ch && ch != EOF && !isspace(ch)) {\r\n\t\t\t\t\tif(ch == *fmt) {\r\n\t\t\t\t\t\tfmt++;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif ( !noass ) \r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\tif(--width == 0)\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t}\r\n\t\t\t\tn++;\r\n\t\t\t\tif ( !noass ) \r\n\t\t\t\t\t*sptr = 0;\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tcase 'c':\r\n\t\t\t\tif ( !noass )\r\n\t\t\t\t\tsptr = (char *)*args++;\r\n\t\t\t\tdo {\r\n\t\t\t\t\tif ((ch = getc(fp)) == EOF) \r\n\t\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\t\tif ( !noass )\r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t} while(--width > 0);\r\n\t\t\t\tn++;\r\n\t\t\t\tcontinue;\r\n\t\t\tdefault:\r\n\t\t\t\tif(isdigit(c)) {\r\n\t\t\t\t\twidth = atoi(fmt-1);\r\n\t\t\t\t\twhile(isdigit(*fmt))\r\n\t\t\t\t\t\tfmt++;\r\n\t\t\t\t\tgoto loop;\r\n\t\t\t\t}\r\n\t\t\t\tif(c != (ch = getc(fp)))\r\n\t\t\t\t\tif(ch == EOF)\r\n\t\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tungetc(ch, fp);\r\n\t\t\t\t\t\treturn n;\r\n\t\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\twspace();\r\n\t\t\tval = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tch = getc(fp);\r\n\t\t\tif(ch == '-') {\r\n\t\t\t\tsign++;\r\n\t\t\t\tch = getc(fp);\r\n\t\t\t}\r\n\t\t\tif(range(ch, base) == -1)\r\n\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\t\t\tdo {\r\n\t\t\t\tval = val * base + range(ch, base);\r\n\t\t\t} while (( --width != 0 ) && ( range(ch = getc(fp),base) != -1 )) ;\r\n\t\t\tn++;\r\n\t\t\tif (range(ch,base) == -1)\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\tif(sign)\r\n\t\t\t\tval = -val;\r\n\t\t\tif ( !noass )\r\n\t\t\t\tif(len)\r\n\t\t\t\t\t*(long *)*args++ = val;\r\n\t\t\t\telse\r\n\t\t\t\t\t**args++ = val;\r\n\t\t\tcontinue;\r\n\t\t} else if(c != (ch = getc(fp))) {\r\n\t\t\tif(ch != EOF) {\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\t\treturn n;\r\n\t\t\t} else\r\n\t\t\t\treturn n ? n : EOF;\r\n\t\t}\r\n\t}\r\n\treturn n;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/DUP.C",
    "content": "/* Duplicate file descriptor */\r\n\r\ndup(fd)\r\nint\tfd;\r\n{\r\n#asm\r\nglobal _errno, bDos\r\n  ld c,047h ; _DUP\r\n  ld b,(ix+6) ; fd\r\n  call bDos\r\n  jr z,1f\r\n  ld (_errno), a\r\n  xor a\r\n  ld (_errno+1),a\r\n1:\r\n  ld l,b\r\n  rl b\r\n  sbc a,a\r\n  ld h,a\r\n#endasm\r\n/* implicit return hl; */\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/ERRNO.C",
    "content": "int errno;\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/EXIT.AS",
    "content": "\tglobal\t_exit, __cpm_clean, bDos\r\n\r\n\tpsect\ttext\r\n_exit:\r\n\tcall\t__cpm_clean\r\n        pop\thl ; return address \r\n        pop\thl ; exit status\r\n\tld\t(80h),hl\t;store exit status\r\n        ld\tb,l\r\n        ld\tc,062h ; _TERM\r\n        call\tbDos\t; should not return\r\n\tjp\t0\t; Warm boot CP/M\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FAKECPCL.AS",
    "content": "\tglobal\t__cpm_clean\r\n\r\n\tpsect\ttext\r\n__cpm_clean:\r\n\tret\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FCLOSE.C",
    "content": "/*\r\n *\tfclose - for CP/M stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\tclose(int);\r\n\r\nfclose(f)\r\nregister FILE *\tf;\r\n{\r\n\tif(!(f->_flag & (_IOREAD|_IOWRT)))\r\n\t\treturn(EOF);\r\n\tfflush(f);\r\n\tf->_flag &= ~(_IOREAD|_IOWRT|_IONBF);\r\n\tif(f->_base && !(f->_flag & _IOMYBUF)) {\r\n\t\t_buffree(f->_base);\r\n\t\tf->_base = (char *)NULL;\r\n\t}\r\n\tif(close(fileno(f)) == -1 || f->_flag & _IOERR)\r\n\t\treturn EOF;\r\n\telse\r\n\t\treturn 0;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FFLUSH.C",
    "content": "/*\r\n *\tfflush for Zios stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\twrite(int, void *, int);\r\n\r\nfflush(f)\r\nregister FILE *\tf;\r\n{\r\n\tunsigned\tcnt;\r\n\r\n\tif(!(f->_flag & _IOWRT) || f->_base == (char *)NULL || (cnt = BUFSIZ - f->_cnt) == 0)\r\n\t\treturn 0;\r\n\tif(write(fileno(f), f->_base, cnt) != cnt)\r\n\t\tf->_flag |= _IOERR;\r\n\tf->_cnt = BUFSIZ;\r\n\tf->_ptr = f->_base;\r\n\tif(f->_flag & _IOERR)\r\n\t\treturn(EOF);\r\n\treturn 0;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FGETC.AS",
    "content": ";\t/*\r\n;\t *\tfgetc for Zios stdio\r\n;\t */\r\n;\t\r\n;\t#include\t<stdio.h>\r\n;\t\r\n;\t#define\tCPMEOF\t032\t\t/* ctrl-Z */\r\n;\t\r\n;\tfgetc(f)\r\n;\tregister FILE *\tf;\r\n;\t{\r\n;\t\tint\tc;\r\n;\t\r\n;\t\tif(f->_flag & _IOEOF || !(f->_flag & _IOREAD)) {\r\n;\treteof:\r\n;\t\t\tf->_flag |= _IOEOF;\r\n;\t\t\treturn EOF;\r\n;\t\t}\r\n;\tloop:\r\n;\t\tif(f->_cnt > 0) {\r\n;\t\t\tc = (unsigned)*f->_ptr++;\r\n;\t\t\tf->_cnt--;\r\n;\t\t} else if(f->_flag & _IOSTRG)\r\n;\t\t\tgoto reteof;\r\n;\t\telse\r\n;\t\t\tc = _filbuf(f);\r\n;\t\tif(f->_flag & _IOBINARY)\r\n;\t\t\treturn c;\r\n;\t\tif(c == '\\r')\r\n;\t\t\tgoto loop;\r\n;\t\tif(c == CPMEOF) {\r\n;\t\t\tf->_cnt++;\r\n;\t\t\tf->_ptr--;\r\n;\t\t\tgoto reteof;\r\n;\t\t}\r\n;\t\treturn c;\r\n;\t}\r\n\r\n;\tThe assembler version of the above routine\r\n\r\n*Include\tstdio.i\r\n\tglobal\t_fgetc, __filbuf\r\n\tpsect\ttext\r\n\r\n_fgetc:\r\n\tpop\tde\t\t\t;get return address off stack\r\n\tex\t(sp),iy\t\t\t;save iy and get arguement into iy\r\n\tld\ta,(iy+flag)\t\t;get flag bits\r\n\tbit\t_IOREAD_BIT,a\r\n\tjr\tz,reteof\t\t;return EOF if not open for read\r\n\tbit\t_IOEOF_BIT,a\t\t;Already seen EOF?\r\n\tjr\tnz,reteof\t\t;yes, repeat ourselves\r\n\r\nloop:\r\n\tld\tl,(iy+cnt)\r\n\tld\th,(iy+cnt+1)\r\n\tld\ta,l\r\n\tor\th\t\t\t;any bytes left?\r\n\tjr\tz,1f\t\t\t;no, go get some more\r\n\tdec\thl\r\n\tld\t(iy+cnt),l\t\t;update count\r\n\tld\t(iy+cnt+1),h\r\n\tld\tl,(iy+ptr)\t\t;get the pointer\r\n\tld\th,(iy+ptr+1)\r\n\tld\ta,(hl)\r\n\tinc\thl\r\n\tld\t(iy+ptr),l\t\t;update pointer\r\n\tld\t(iy+ptr+1),h\r\n2:\r\n\tbit\t_IOBINARY_BIT,(iy+flag)\t;Binary mode?\r\n\tjr\tz,3f\t\t\t;no, check for EOF etc\r\nretch:\r\n\tld\tl,a\t\t\t;return the character in a\r\n\tld\th,0\r\n\tex\t(sp),iy\t\t\t;restore iy\r\n\tpush\tde\t\t\t;put return address back\r\n\tret\t\t\t\t;with char in hl\r\n\r\n3:\r\n\tcp\tRETURN\t\t\t;carriage return\r\n\tjr\tz,loop\t\t\t;yes, get another instead\r\n\tcp\tCPMEOF\t\t\t;end of file?\r\n\tjr\tnz,retch\t\t;no, return it!\r\n\tld\ta,(iy+base)\t\t;buffered?\r\n\tor\t(iy+base+1)\r\n\tjr\tz,reteof\t\t;yup, leave count alone\r\n\tld\tl,(iy+cnt)\r\n\tld\th,(iy+cnt+1)\r\n\tinc\thl\t\t\t;reset count\r\n\tld\t(iy+cnt),l\r\n\tld\t(iy+cnt+1),h\r\n\tld\tl,(iy+ptr)\r\n\tld\th,(iy+ptr+1)\r\n\tdec\thl\t\t\t;reset pointer\r\n\tld\t(iy+ptr),l\r\n\tld\t(iy+ptr+1),h\r\nreteof:\r\n\tset\t_IOEOF_BIT,(iy+flag)\t;note EOF\r\n\tld\thl,EOF\r\n\tex\t(sp),iy\t\t\t;restore iy\r\n\tpush\tde\r\n\tret\t\t\t\t;return with EOF in hl\r\n\r\n1:\r\n\tbit\t_IOSTRG_BIT,(iy+flag)\t;end of string?\r\n\tjr\tnz,reteof\t\t;yes, return EOF\r\n\tpush\tde\t\t\t;save de\r\n\tpush\tiy\t\t\t;pass iy as argument\r\n\tcall\t__filbuf\t\t;refill the buffer\r\n\tld\ta,l\t\t\t;the returned value\r\n\tpop\tbc\r\n\tpop\tde\t\t\t;return address in de again\r\n\tbit\t7,h\r\n\tjr\tnz,reteof\t\t;returned EOF\r\n\tjr\t2b\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FILBUF.C",
    "content": "/*\r\n *\t_filbuf for Zios stdio\r\n */\r\n\r\nextern int\tread(int, void *, int);\r\n\r\n#include\t<stdio.h>\r\n_filbuf(f)\r\nregister FILE *\tf;\r\n{\r\n\tf->_cnt = 0;\r\n\tif(!(f->_flag & _IOREAD))\r\n\t\treturn(EOF);\r\n\tif(f->_base == (char *)NULL) {\r\n\t\tuchar\tc;\r\n\t\tf->_cnt = 0;\r\n\t\tif(read(fileno(f), &c, 1) == 1)\r\n\t\t\treturn(c);\r\n\t\tf->_flag |= _IOEOF;\r\n\t\treturn(EOF);\r\n\t}\r\n\tif((f->_cnt = read(fileno(f), f->_base, BUFSIZ)) <= 0) {\r\n\t\tif(f->_cnt == 0)\r\n\t\t\tf->_flag |= _IOEOF;\r\n\t\telse\r\n\t\t\tf->_flag |= _IOERR;\r\n\t\treturn(EOF);\r\n\t}\r\n\tf->_ptr = f->_base;\r\n\tf->_cnt--;\r\n\treturn((unsigned)*f->_ptr++);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FLSBUF.C",
    "content": "/*\r\n *\t_flsbuf for Zios stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\twrite(int, void *, int);\r\n\r\n_flsbuf(c, f)\r\nregister FILE *\tf;\r\nuchar\tc;\r\n{\r\n\tif(f->_flag & _IOWRT) {\r\n\t\tif(f->_base == (char *)NULL) {\r\n\t\t\tf->_cnt = 0;\r\n\t\t\tif(write(fileno(f), &c, 1) == 1)\r\n\t\t\t\treturn(c);\r\n\t\t\tf->_flag |= _IOERR;\r\n\t\t\treturn(EOF);\r\n\t\t}\r\n\t\tif(write(fileno(f), f->_base, BUFSIZ) != BUFSIZ)\r\n\t\t\tf->_flag |= _IOERR;\r\n\t\tf->_cnt = BUFSIZ-1;\r\n\t\t*f->_base = c;\r\n\t\tf->_ptr = f->_base+1;\r\n\t} else {\r\n\t\tf->_flag |= _IOERR;\r\n\t\tf->_cnt = 0;\r\n\t}\r\n\tif(f->_flag & _IOERR)\r\n\t\treturn(EOF);\r\n\treturn(c);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FOPEN.C",
    "content": "/*\r\n *\tfopen.c - stdio fopen \r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\n\r\nFILE *\r\nfopen(name, mode)\r\nchar *\tname, * mode;\r\n{\r\n\tregister FILE *\tf;\r\n\r\n\tfor(f = _iob ; f != &_iob[_NFILE] ; f++)\r\n\t\tif(!(f->_flag & (_IOREAD|_IOWRT)))\r\n\t\t\tbreak;\r\n\tif(f == &_iob[_NFILE])\r\n\t\treturn((FILE *)NULL);\r\n\treturn freopen(name, mode, f);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FPRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern int\t_doprnt();\r\n\r\nfprintf(file, f, a)\r\nFILE *\tfile;\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\treturn(_doprnt(file, f, &a));\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FREAD.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tfread for Zios\r\n */\r\n\r\nfread(buf, size, nitems, stream)\r\nvoid *\tbuf;\r\nregister FILE *\tstream;\r\nunsigned\tsize, nitems;\r\n{\r\n\tregister char *\t\tptr;\r\n\tregister unsigned\tcount;\r\n\tshort\t\t\tc;\r\n\r\n\tcount = size * nitems;\r\n\tptr = buf;\r\n\twhile(count)\r\n\t\tif((c = getc(stream)) == EOF)\r\n\t\t\tbreak;\r\n\t\telse {\r\n\t\t\t--count;\r\n\t\t\t*ptr++ = c;\r\n\t\t}\r\n\treturn(nitems - (count+size-1)/size);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FREOPEN.C",
    "content": "/*\r\n *\tfreopen.c - stdio freopen \r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\topen(char *, int), creat(char *, int);\r\n\r\nFILE *\r\nfreopen(name, mode, iob)\r\nchar *\tname, * mode;\r\nregister FILE *\tiob;\r\n{\r\n\tuchar\t\tc;\r\n\r\n\tfclose(iob);\r\n\tc = 0;\r\n\tiob->_flag &= _IONBF;\r\n\tswitch(*mode) {\r\n\r\n\tcase 'w':\r\n\t\tc++;\r\n\tcase 'a':\r\n\t\tc++;\r\n\tcase 'r':\r\n\t\tif(mode[1] == 'b')\r\n\t\t\tiob->_flag = _IOBINARY;\r\n\t\tbreak;\r\n\r\n\t}\r\n\tswitch(c) {\r\n\r\n\tcase 0:\r\n\t\tiob->_file = open(name, 0);\r\n\t\tbreak;\r\n\r\n\tcase 1:\r\n\t\tif((iob->_file = open(name, 1)) >= 0)\r\n\t\t\tbreak;\r\n\t\t/* else fall through */\r\n\tcase 2:\r\n\t\tiob->_file = creat(name, 0666);\r\n\t\tbreak;\r\n\t}\r\n\tif(iob->_file < 0)\r\n\t\treturn (FILE *)NULL;\r\n\tif(!(iob->_flag & (_IONBF|_IOMYBUF)))\r\n\t\tiob->_base = _bufallo();\r\n\tif(iob->_base == (char *)-1) {\r\n\t\tiob->_base = (char *)0;\r\n\t\tclose(iob->_file);\r\n\t\tiob->_flag = 0;\r\n\t\treturn (FILE *)NULL;\r\n\t}\r\n\tiob->_ptr = iob->_base;\r\n\tiob->_cnt = 0;\r\n\tif(c)\r\n\t\tiob->_flag |= _IOWRT;\r\n\telse\r\n\t\tiob->_flag |= _IOREAD;\r\n\tif(iob->_base && c)\r\n\t\tiob->_cnt = BUFSIZ;\r\n\tif(c == 1)\r\n\t\tfseek(iob, 0L, 2);\r\n\treturn iob;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FSCANF.C",
    "content": "/*\r\n *\tStdio fscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\nextern int\t_doscan();\r\n\r\nfscanf(file, fmt, args)\r\nFILE *\tfile;\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\treturn _doscan(file, fmt, &args);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FSEEK.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern long\tlseek(int, long, int), ftell(FILE *);\r\n\r\nfseek(f, offs, ptr)\r\nregister FILE *\tf;\r\nlong\t\toffs;\r\nint\t\tptr;\r\n{\r\n  return lseek(fileno(f), offs, ptr);\r\n}\r\n\r\nlong\r\nftell(FILE * f)\r\n{\r\n   return lseek(fileno(f),0L,1);\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/FWRITE.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tfwrite\r\n */\r\n\r\nfwrite(buf, size, nitems, stream)\r\nvoid *\tbuf;\r\nregister FILE *\tstream;\r\nunsigned\tsize, nitems;\r\n{\r\n\tregister unsigned\tcount;\r\n\tregister char *\t\tptr;\r\n\r\n\tcount = size * nitems;\r\n\tptr = buf;\r\n\twhile(count)\r\n\t\tif(putc(*ptr++, stream) == EOF)\r\n\t\t\tbreak;\r\n\t\telse\r\n\t\t\t--count;\r\n\treturn(nitems - (count+size-1)/size);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/GETARGS.C",
    "content": "/*\r\n *\t_getargs(str, name) - process string into argument buffer.\r\n *\r\n *\tIf str is null, read lines from standard input instead, using name as a\r\n *\tprompt.\r\n *\tContinuation lines are recognized by a \\ as the last character on the\r\n *\tline.\r\n *\r\n *\tThe redirections recognized are:\r\n *\r\n *\t\t>\t>>\t<\r\n *\r\n *\tRedirections of the form >& and >>& are not yet supported.\r\n *\tNote that the >> redirections depend on fseek working correctly\r\n *\ton text files, when seeking relative to the end of the file.\r\n *\r\n *\tWildcards (? and *) are expanded in the usual way.\r\n *\r\n *\tThe quotes \" and ' may be used to enclose arguments which contain\r\n *\twhite space the wild characters and > or <.\r\n *\r\n *\tThe argument buffer is sbrk'ed and a pointer to it is returned.\r\n *\tThe count of arguments is left in the global _argc_. The count\r\n *\tmay also be found by counting the arguments; the last one is a null\r\n *\tpointer.\r\n *\tThe zero'th argument is set to the name parameter.\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n#include\t<string.h>\r\n#include\t<cpm.h>\r\n\r\n\r\n#define\tMAXARGS\t200\t\t/* max number of arguments */\r\n#define\tMAXLEN\t100\t\t/* max length of an argument */\r\n#define\tQUOTE\t0x80\t\t/* quoted bit in args */\r\n\r\n#define\tisterminator(c)\t((c) == 0)\r\n#define\tlook()\t\t(*str)\r\n\r\nextern int\t_argc_;\r\nextern char *\tsbrk();\r\nextern int\tisatty(int);\r\nstatic char *\tname, * str, * bp;\r\nstatic char\tinteractive;\r\nstatic char\tredone[3];\r\nstatic void\tsputs(), error();\r\nstatic void\tredirect();\r\nstatic char *\talloc();\r\nstatic char\tnxtch();\r\nstatic char\tiswild(), isspecial(), isseparator();\r\nextern int\t_glob(char *, char*);\r\n\r\nchar **\r\n_getargs(_str, _name)\r\nchar *\t_str, * _name;\r\n{\r\n   char **\t\targv;\r\n   register char *\tap;\r\n   char *\t\tcp;\r\n   short\t\targc;\r\n   char\t\t\tc, quote;\r\n   unsigned short\ti, j;\r\n   char *\t\targbuf[MAXARGS];\r\n   char\t\t\tfibbuf[64];\r\n   char\t\t\tbuf[MAXLEN];\r\n\r\n   bp = (char *)0;\r\n   quote = redone[0] = redone[1] = redone[2] = 0;\r\n   name = _name;\r\n   str = _str;\r\n   if (interactive = (str==(char *)0))  str = \"\\\\\";\r\n   argbuf[0] = name;\r\n   argc = 1;\r\n\r\n   /* first step - process arguments and do globbing */\r\n\r\n   while (look()) {\r\n      if (argc == MAXARGS)\r\n         error(\"too many arguments\", 0);\r\n      while (isseparator(c = nxtch()))\r\n         continue;\r\n      if (isterminator(c))\r\n         break;\r\n      ap = buf;\r\n      if (isspecial(c)) {\r\n         *ap++ = c;\r\n         if (c == '>' && look() == '>')\r\n            *ap++ = nxtch();\r\n      } \r\n      else { /* -- !isspecial(c) */\r\n         while (!isterminator(c) \r\n                && (quote || !isspecial(c) && !isseparator(c))) {\r\n\t    if (ap == &buf[MAXLEN])\r\n\t       error(\"argument too long\", 0);\r\n\t    if (c == quote)\t\t/* end of quoted string */\r\n\t       quote = 0;\r\n\t    else \r\n               if (!quote && (c == '\\'' || c == '\"'))\r\n\t          quote = c;\t/* start of quoted string */\r\n\t       else {\r\n\t          if (quote)\r\n\t             c |= QUOTE;\r\n\t          *ap++ = c;\r\n\t       }\r\n\t    if (!quote && isspecial(look()))\r\n\t       break;\r\n\t    c = nxtch();\r\n         } /* -- while (!isterminator(c) ... */\r\n      } /* -- else (!isspecial(c)) */\r\n      *ap = 0;\r\n      if (iswild(buf)) {\r\n         _flip(buf, buf, MAXLEN);\r\n\t cp = strrchr(buf,'\\\\');\r\n\t if (!cp) cp=strrchr(buf,':');\r\n\t if (!cp) cp=buf; else ++cp;\r\n\t fibbuf[0]='\\0';\r\n\t if ( ! _glob(buf, fibbuf) )\r\n            do {\r\n\t       argbuf[argc]=alloc(cp-buf+strlen(fibbuf));\r\n\t       if (cp-buf) strncpy(argbuf[argc],buf,cp-buf);\r\n\t       strcpy(argbuf[argc++]+(cp-buf), fibbuf+1);\r\n\t    } while ( ! _glob(buf, fibbuf) ) ;\r\n         else {\r\n\t    perror(buf);\r\n\t    fputc('\\n', stderr);\r\n\t    argbuf[argc++]=strcpy(alloc(strlen(buf)+1),buf);\r\n         }\r\n      } /* -- if (iswild(buf)) */\r\n      else { /* !iswild(buf) */\r\n         argbuf[argc++] = ap = alloc(ap-buf+1);\r\n         cp = buf;\r\n         do {\r\n\t    *ap++ = *cp & ~QUOTE;\r\n         } while (*cp++);\r\n      }\r\n   } /* -- while (look())\r\n\r\n   /* now do redirection */\r\n\r\n   for (i = j = 0 ; j < argc ; j++)\r\n      if (isspecial(c = argbuf[j][0])) {\r\n\t if (j == argc-1)\r\n\t    error(\"no name after \", argbuf[j], 0);\r\n\t if (c == '<')\r\n\t    redirect(\"input\", argbuf[j+1], \"r\", stdin);\r\n\t else {\r\n\t    ap = argbuf[j][1] == '>' ? \"a\" : \"w\";\r\n\t    redirect(\"output\", argbuf[j+1], ap, stdout);\r\n\t }\r\n\t j++;\r\n      } \r\n      else /* !isspecial() */\r\n\t argbuf[i++] = argbuf[j];\r\n   _argc_ = i;\r\n   argbuf[i++] = (char *)0;\r\n   argv = (char **)alloc(i * sizeof *argv);\r\n   bmove(argbuf, argv, i * sizeof *argv);\r\n\r\n   return argv;\r\n}\r\n\r\nstatic char\r\nnxtch()\r\n{\r\n   if (interactive && *str == '\\\\' && str[1] == 0) {\r\n      if (!bp)\r\n\t bp = alloc(256);\r\n      if (isatty(fileno(stdin)))\r\n\t fprintf(stderr, \"%s> \", name);\r\n      gets(bp);\r\n      str = bp;\r\n   }\r\n   if (*str)\r\n      return *str++;\r\n   return 0;\r\n}\r\n\r\nstatic void\r\nerror(s)\r\nchar *\ts;\r\n{\r\n   register char **\tsp;\r\n\r\n   sp = &s;\r\n   while (*sp)\r\n      sputs(*sp++);\r\n   sputs(\"\\n\");\r\n   exit(-1);\r\n}\r\n\r\nstatic void\r\nsputs(s)\r\nregister char *\ts;\r\n{\r\n   while(*s) {\r\n      if (*s == '\\n')\r\n         bdos(CPMWCON, '\\r');\r\n      bdos(CPMWCON, *s++);\r\n   }\r\n}\r\n\r\nstatic char *\r\nalloc(n)\r\nshort\tn;\r\n{\r\n   char *\tbp;\r\n\r\n   if ((bp = sbrk(n)) == (char *)-1)\r\n      error(\"no room for arguments\", 0);\r\n   return bp;\r\n}\r\n\r\nstatic void\r\nredirect(str_name, file_name, mode, stream)\r\nchar *\tstr_name, * file_name, * mode;\r\nFILE *\tstream;\r\n{\r\n   if (redone[stream-_iob]++)\r\n      error(\"Ambiguous \", str_name, \" redirection\", 0);\r\n   if (freopen(file_name, mode, stream) != stream)\r\n      error(\"Can't open \", file_name, \" for \", str_name, 0);\r\n}\r\n\r\nstatic char\r\niswild(buf)\r\nchar *\tbuf;\r\n{\r\n   return strchr(buf, '*') || strchr(buf, '?');\r\n}\r\n\r\nstatic char\r\nisspecial(c)\r\nchar\tc;\r\n{\r\n   return c == '<' || c == '>';\r\n}\r\n\r\nstatic char\r\nisseparator(c)\r\nchar\tc;\r\n{\r\n   return c == ' ' || c == '\\t' || c == '\\n';\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/GETCWD.AS",
    "content": "; file: getcwd.as\r\n; author: Arnold Metselaar\r\n;\r\n; implements \r\n; char * getcwd(int drive)\r\n; drive: \r\n;\t0 - current\r\n;\t1 - A:\r\n;\t2 - B: etc.\r\n;\r\nglobal _getcwd, bDos\r\n\r\npsect text\r\n_getcwd:\r\npop hl\r\npop de ; get arg\r\npush de\r\npush hl ; restore stack\r\nld a,e\r\nor a\r\njr nz, 1f\r\nld c,19h ; get default drive\r\ncall bDos\r\ninc a\r\n1:\r\nld b,a\r\nadd a,'A'-1\r\nld hl,cwdbuf\r\nld (hl),a\r\ninc hl\r\nld (hl),':'\r\ninc hl\r\nld (hl),'\\'\r\ninc hl\r\nex de,hl\r\nld c,59h ; _GETCD, get current directory\r\ncall bDos\r\nld hl,cwdbuf\r\nret\r\n\r\npsect bss\r\ncwdbuf: defs 67\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/GETENV.AS",
    "content": ";string.h: 4: typedef\tint\t\tptrdiff_t;\r\n;string.h: 5: typedef\tunsigned\tsize_t;\r\n;string.h: 18: extern char *\tstrcpy(char *, char *);\r\n;string.h: 34: extern size_t\tstrlen(char *);\r\n;stdlib.h: 27: extern void *\tmalloc(size_t);\r\n\r\n;B:GETENV.C: 9: char *\r\n;B:GETENV.C: 10: getenv(s)\r\n;B:GETENV.C: 11: char *\ts;\r\n;B:GETENV.C: 12: {\r\npsect\ttext\r\nglobal\t_getenv\r\n_getenv:\r\nglobal\tncsv, cret, indir, bDos\r\ncall\tncsv\r\ndefw\t-255\r\n;B:GETENV.C: 13:   register char *res;\r\n;B:GETENV.C: 14:   char val[255];\r\n\r\n  ld bc,0FF6Bh ; _GENV, buffersize=255\r\n  push ix\r\n  pop hl\r\n  ld de,-255 \r\n  add hl,de ; val\r\n  ld (hl),0 ; make sure val is empty if *s invalid\r\n  ex de,hl\r\n  ld l,(ix+6) ; s\r\n  ld h,(ix+7)\r\n  call bDos\r\n; out de==val\r\n;B:GETENV.C: 29:   res= (strlen(val)==0) ? ((void *)0) : malloc(strlen(val)+1);\r\nglobal\t_strlen\r\nglobal\t_malloc\r\npush\tde\r\ncall\t_strlen\r\npop bc\r\nld\ta,l\r\nor\th\r\njp\tz,10f\r\npush\tix\r\npop\tde\r\nld\thl,-255\r\nadd\thl,de\r\npush\thl\r\ncall\t_strlen\r\npop\tbc\r\ninc\thl\r\npush\thl\r\ncall\t_malloc\r\npop\tbc\r\njp\t12f\r\n10:\r\nld\thl,0\r\n12:\r\nld\tC,l\r\nld\tB,h\r\n;B:GETENV.C: 30:   return (res==((void *)0)) ? ((void *)0) : strcpy(res, val);\r\nglobal\t_strcpy\r\nld\ta,l\r\nor\th\r\njp\tz,10f\r\npush\tix\r\npop\tde\r\nld\thl,-255\r\nadd\thl,de\r\npush\thl\r\npush\tbc\r\ncall\t_strcpy\r\npop\tbc\r\njp\t12f\r\n10:\r\nld\thl,0\r\n12:\r\n;B:GETENV.C: 31: }\r\njp\tcret\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/GETS.C",
    "content": "/*\r\n *\tgets and fgets for Zios stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<string.h>\r\n\r\nchar *\r\nfgets(s, n, f)\r\nchar *\t\ts;\r\nregister FILE *\tf;\r\n{\r\n\tchar *\ts1 = s;\r\n\tint\tc;\r\n\r\n\twhile(n-- && (c = getc(f)) != EOF && (*s++ = c) != '\\n')\r\n\t\t/* VOID */;\r\n\t*s = 0;\r\n\tif(s == s1)\r\n\t\treturn((char *)NULL);\r\n\treturn(s1);\r\n}\r\n\r\nchar *\r\ngets(s)\r\nchar *\ts;\r\n{\r\n\tif((s = fgets(s, -1, stdin)) == (char *)NULL)\r\n\t\treturn((char *)NULL);\r\n\ts[strlen(s)-1] = 0;\r\n\treturn(s);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/GETW.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tStdio getw()\r\n */\r\n\r\ngetw(stream)\r\nregister FILE *\tstream;\r\n{\r\n\tshort\thi, lo;\r\n\r\n\tif((lo = getc(stream)) == EOF || (hi = getc(stream)) == EOF)\r\n\t\treturn EOF;\r\n\treturn (hi << 8) + (lo & 0xFF);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/ISATTY.C",
    "content": "isatty(f)\r\nunsigned char\tf;\r\n{\r\n#asm\r\nglobal bDos\r\n  ld c,04Bh ; _IOCTL\r\n  ld b,(ix+6) ; f\r\n  xor a ; 0 => get file handle status\r\n  call bDos\r\n  ld a,080h\r\n  and e\r\n  rlca\r\n  ld l,a\r\n  xor a\r\n  ld h,a\r\n#endasm\r\n  /* implicit return hl; */\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/LIBDOS2.TXT",
    "content": "LIBDOS2 - IO-library for MSX-DOS2 and HiTech-C\r\n----------------------------------------------\r\n\r\nHiTech-C comes with a standard library (libc.lib) that does not\r\nsupport subdirectories and environment items under MSX-DOS2.\r\n\r\nThis library (libdos2.lib) is specificly written  for  MSX-DOS2\r\nand fully supports subdirectories and environment items. \r\n\r\n\tObtaining LIBDOS2\r\n\r\nDownload libdos2.pma from http://banzai.msx.nu and unpack using\r\nlhext.com. The distribution contains the library (libdos2.lib),\r\nthe sources (*.as, *.c) and some documentation (this file).\r\n\r\n\tUsing LIBDOS2\r\n\r\nTo use libdos2  you  must  first  place  libdos2.lib  in  the\r\ndirectory as libc.lib and then invoke the C-compiler with the\r\n\"-ldos2\" option. If you want  to  link  in  the  support  for\r\nfloating point numbers as well you must make sure libf.lib is\r\nscanned before libdos2.lib (\"-lf -ldos2\"). \r\nNote that libdos2.lib is not a complete C-library,  you  will\r\nstill need some functions from libc.lib, this is not normally\r\na  concern  because  the  compiler   driver   (e.g.   cc.com)\r\nautomatically instructs the linker to scan libc.lib.\r\nPrograms linked with libdos2 will only  run  under  MSX-DOS2.\r\nMany functions could be rewritten to work under both DOS1 and\r\nDOS2, but the DOS2-only versions are more compact. Of  course\r\nyou can easily make two versions of your program.\r\n\r\n\tDocumentation\r\n\r\nMost functions are described in the documentation that  comes\r\nwith HiTech-C.  A  possibly  incomplete  list  of  differences\r\nbetween how libdos2 does and what the  documentation  says  it\r\ndoes is below.\r\n\r\nIn functions taking a filename as argument, you can use '/' as\r\na path-separator; libdos2 will perform a  substitution  before\r\npassing a filename to  MSX-DOS2.  This  substitution  is  also\r\navailable to applications directly as \r\n\r\n\tint _flip(char *d, char *s, unsigned int n);\r\n\r\n\tCopy at most n characters from s to d, \r\n\tany occurence of '/' will be replaced by '\\\\'.\r\n\r\nThe functions _getargs() and _glob() are intended for wildcard\r\nexpansion  in  the  command-line  (-R  option),  but  may   be\r\nused directly as well, see glob.as and getargs.c for details.\r\n\r\nThe function  open()  takes  the  same  values  for  the  mode\r\nargument as the original in  libc.lib.  Additionally  you  may\r\ntake a bitwise or with O_INHER to make the handle  inheritable\r\nfor child processes created with the DOS2 call  _FORK  (0x60).\r\nThe  macro  O_INHER  is  defined  in  unixio.h  together  with\r\nO_RDONLY, O_WRONLY and O_RDWR.\r\n\r\nThe  header  file  dirent.h  contains  declarations  for  some\r\nfuntions to read directories. These functions comply with  the\r\nPOSIX standard.\r\n\r\n\tDIR * opendir (char * name);\r\n\t\r\n\tOpen the directory with the given  name  for  reading,\r\n        returns NULL and sets errno if  the  operation  fails,\r\n        use malloc() to allocate memory.\r\n\r\n\tstruct dirent * readdir (DIR * dir);\r\n\r\n        Read one entry from directory dir,  struct  dirent  is\r\n        actually a  file  information  block  and  defined  in\r\n        dirent.h, but if you want to write a portable program,\r\n        you should only use char d_name[],  a  zero-terminated\r\n        string with at most  NAME_MAX  characters  before  the\r\n        zero.\r\n        The result of readdir() will  be  overwritten  by  the\r\n        next call to readdir() for the same directory.\r\n\r\n\tint closedir (DIR * dir);\r\n\r\n        Close directory dir and release the associated storage\r\n        with free().\r\n\r\n\tvoid rewinddir (DIR * dir);\r\n\r\n        Reset the pointer in directory dir, the next  call  to\r\n        readdir() for this directory  will  return  the  first\r\n        directory entry.\r\n\r\nOther functions  operating  on  directories  are  declared  in\r\nsys.h: \r\n\r\n\tint chdir (char * name);\r\n\tint mkdir (char * name);\r\n\tint getcwd (int drive);\r\n\tint rmdir (char * name);\r\n\r\n        These functions follow the HiTech-C documentation. The\r\n        functions  mkdir()  and  getcwd()  have  a   different\r\n        calling convention than their POSIX counterparts.\r\n\r\nThe  getenv()  function  returns  a  pointer  to   a   freshly\r\nmalloc()'ed string rather than a pointer to static storage. It\r\nis possible to free()  the  pointer,  but  this  will  not  be\r\nportable to other systems. \r\nLibdos2 does not provide a char ** environ.\r\n\r\nPlease send bug reports, comments, suggestions for improvement\r\netc. to Arnold Metselaar<arnold.metselaar@planet.nl>.\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/MAKEFILE",
    "content": "# standard IO for MSX-DOS2\r\n\r\n..all : libdos2.lib\r\nDIST = ldos2_04\r\nHFILES = dirent.h unixio.h stat.h\r\nXFILES = libdos2.txt libdos2.lib changes makefile\r\ndistribution : $(DIST).lzh\r\n\r\n# All object files. Ordering does matter\r\n\r\nALLOBJ = getargs.obj start1.obj start2.obj assert.obj printf.obj fprintf.obj\r\nALLOBJ += sprintf.obj doprnt.obj puts.obj gets.obj fwrite.obj getw.obj \r\nALLOBJ += putchar.obj perror.obj fputc.obj flsbuf.obj fopen.obj freopen.obj\r\nALLOBJ += rewind.obj fseek.obj fread.obj remove.obj setbuf.obj fscanf.obj\r\nALLOBJ += cgets.obj cputs.obj scanf.obj sscanf.obj doscan.obj ungetc.obj\r\nALLOBJ += fgetc.obj filbuf.obj stdclean.obj fclose.obj chdir.obj unlink.obj\r\nALLOBJ += rmdir.obj fflush.obj buf.obj open.obj chmod.obj creat.obj mkdir.obj\r\nALLOBJ += utime.obj read.obj write.obj seek.obj rename.obj isatty.obj close.obj\r\nALLOBJ += dup.obj opendir.obj readdir.obj stat.obj act_file.obj flip.obj\r\nALLOBJ += _utime.obj errno.obj getenv.obj setenv.obj exit.obj getcwd.obj\r\nALLOBJ += closedir.obj rewnddir.obj fakecpcl.obj glob.obj bdos.obj\r\n\r\n# sourcefiles in C that cannot, or need not, be optimised with OPTIM\r\n# mostly due #asm - constructions : \r\nCXSRC  = read.c write.c seek.c isatty.c close.c dup.c errno.c \r\n\r\nCXOBJ = $(CXSRC:.c=.obj)\r\n\r\n# assembly sourcefiles\r\nASSRC = getenv.as setenv.as exit.as start1.as start2.as getcwd.as\r\nASSRC += opendir.as readdir.as closedir.as rewnddir.as act_file.as\r\nASSRC += fakecpcl.as fgetc.as glob.as flip.as _utime.as bdos.as fputc.as\r\n\r\nASOBJ = $(ASSRC:.as=.obj)\r\n\r\n# The rest are optimizable C sources\r\nCOBJ = $(ALLOBJ)\r\nCOBJ -= $(ASOBJ) $(CXOBJ)\r\n\r\nCSRC = $(COBJ:.obj=.c)\r\n..obj : $(ASOBJ)\r\n\r\nlibdos2.lib : makefile $(ALLOBJ)\r\n\t:del libdos2.lib\r\n\tlibr <<EOF\r\n\tr libdos2.lib \\\\\r\n\t$(ALLOBJ:.obj=.obj \\\\\\n)\r\n\t \r\n\tEOF\r\n\r\n\r\n$(DIST).lzh : $(XFILES) $(ASSRC) $(CSRC) $(CXSRC)\r\n\techo del $(DIST).lzh > pack.bat\t\r\n\txargs -b >> pack.bat <<EOF  lhpack $(DIST)\r\n\t$(XFILES) $(HFILES)\r\n\t$(CSRC)\r\n\t$(CXSRC)\r\n\t$(ASSRC)\r\n\tEOF\r\n\techo lhpack can not be run from make, please run pack.bat from the prompt \r\n\r\n%.obj : ASOBJ : %.as\r\n\tzas -O%.obj %.as\r\n\r\n%.obj : COBJ : %.c\r\n\tcc -c -o -o%.obj %.c\r\n\r\n%.obj : CXOBJ : %.c\r\n\tcc -c -o%.obj %.c\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/MKDIR.C",
    "content": "/*\r\n * mkdir (char *)\r\n *\r\n * create a directory with the given name.\r\n */\r\n\r\nextern int _act_file(char*, int, int);\r\n\r\nmkdir(name)\r\nchar *\tname;\r\n{ \r\n  int res;  \r\n  res = _act_file(name, 8, 0x1044);\r\n  return (res < 0) ? -1 : 0;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/OPEN.C",
    "content": "/*\r\n * opens the file with the given name\r\n * slashes in the name are converted to backslashes\r\n *\r\n * mode: 0 - read\r\n *       1 - write\r\n *       2 - read/write\r\n */\r\n\r\n_act_file (char * name, int mode, int bc);\r\n\r\nopen(name, mode)\r\nchar *\tname;\r\n{\r\n  return _act_file(name, mode, 0x43);\r\n}\r\n\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/OPENDIR.AS",
    "content": "; opendir.as \r\n; #include <dirent.h>\r\n; #include <stdlib.h>\r\n\r\n; DIR * opendir(char * name)\r\nglobal _opendir\r\nglobal ncsv, cret, __flip, _malloc, _free, bDos, _errno\r\n\r\npsect text\r\n_opendir:\r\ncall ncsv\r\ndefw -69\r\nld hl, 0\r\nadd hl,sp\r\nld (ix-2),l\r\nld (ix-1),h ; address to store slash-flipped name\r\nld bc,67\r\npush bc\r\nld e,(ix+6)\r\nld d,(ix+7) ; name\r\npush de\r\npush hl\r\ncall __flip\r\npop hl ; address of slash-flipped name\r\npop bc\r\npop bc\r\n\r\n; \".\" -> getcwd (default drive)\r\n; \"x:.\" -> getcwd (drive x)\r\nld b,0\r\ninc hl\r\nld a,(hl)\r\ncp ':'\r\njr nz,1f\r\ndec hl\r\nld a,(hl)\r\nand 0ffh - ('a'-'A')\r\nsub 'A'-1\r\nld b,a\r\ninc hl\r\ninc hl\r\ninc hl\r\nld a,(hl)\r\n\r\n1:\r\nor a\r\njr nz,2f\r\ndec hl\r\nld a,(hl)\r\ncp '.'\r\njr nz,2f\r\n\r\nld (hl),'\\'\r\ninc hl\r\nex de,hl\r\nld c,059h ; _GETCD\r\ncall bDos\r\n\r\n2:\r\n\r\nld hl, 128 ; sizeof( DIR )\r\npush hl\r\ncall _malloc\r\npop bc\r\npush hl\r\nld a,l\r\nor h\r\njr z,noram\r\n\r\nld e,(ix-2)\r\nld d,(ix-1) ; name, flipped \r\npush de\r\n; we need to treat a root directory in a special way:\r\ncall isroot\r\npop de\r\nex (sp),ix\r\nld (ix+14),10h\r\nld bc, 1640h ; 40h : _FFIRST 16h: also hidden, system and directory\r\ncall nz,bDos ; call the bDos only for non-root directories\r\n\r\nld (ix+64),0 ; no entry read so far\r\nld b,(ix+14) ; attribute\r\nex (sp),ix\r\njr nz,error\r\nld a,b\r\nand 10h\r\njr z, notdir\r\n\r\npop hl\r\njp cret\r\n\r\nnoram:\r\nld bc, 0DEh ; .NORAM\r\nld (_errno),bc\r\njp cret ; return NULL\r\n\r\nnotdir:\r\nld a, 0CFh ; .IATTR\r\nerror:\r\nld (_errno),a\r\nxor a\r\nld (_errno+1),a\r\ncall _free ; address of allocated block is already on the stack\r\nld hl, 0\r\njp cret ; return NULL\r\n\r\nisroot:\r\n; in  - DE: pointer to (flipped) pathname\r\n;     - HL: pointer to res->dir_dir\t\r\n; out: * Z: pathname points to a root directory \r\n;      *NZ: pathname does not point to a root directory\r\n; if pathname points to a root then drive and path are copied to res->dir_dir\r\n; if the path starts with [d:].\\ and the cwd is the root dir,\r\n; then the '.' is removed from the string\r\n\r\nld b,0\r\ninc de\r\nld a,(de)\r\ncp ':'\r\njr nz, 1f\r\ndec de\r\nld a,(de)\r\nand 0ffh-('a'-'A')\r\nld b,a\r\ninc de\r\ninc de\r\ninc de\r\nld a,(de)\r\n1:\r\ncp '\\'\r\njr z,4f\r\nor a\r\nret nz\r\ndec de\r\nld a,(de)\r\ncp '\\'\r\nret nz\r\nld a,b\r\nor a\r\njr nz, 2f\r\npush hl\r\nld c,19h ; _CURDRV\r\ncall bDos\r\nadd a,'A'\r\npop hl\r\n2:\r\nld (hl),a\r\ninc hl\r\nld (hl),':'\r\ninc hl\r\nld (hl),'\\'\r\ninc hl\r\nxor a\r\nld (hl),a\r\nret\r\n\r\n4:\r\n; The first component is just one char, check for \".\\\" with\r\n; the root dir as cwd\r\ndec de\r\nld a,(de)\r\ncp '.'\r\nret nz\r\nld a,b\r\nor a\r\njr z,5f\r\nsub 'A'-1\r\nld b,a\r\n5:\r\npush de\r\npush hl\r\nex de,hl\r\nld c,59h ; _GETCD\r\ncall bDos\r\npop hl\r\npop de\r\nld a,(hl)\r\nor a\r\nret nz\r\n; DE points to a '.' that we do not want\r\nld l,e\r\nld h,d\r\n6:\r\ninc hl\r\nld a,(hl)\r\nld (de),a\r\ninc de\r\ncp 1\r\nret c ; look for '\\0', but do not set Z-flag\r\njr 6b\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/PERROR.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern\tint\terrno;\r\nextern\tchar *\tsys_err[];\r\nextern\tint\tsys_ner;\r\n\r\nstatic\r\nps(s)\r\nchar *\ts;\r\n{\r\n  while(*s)\r\n    putc(*s++, stderr);\r\n}\r\n\r\nvoid perror(char * s)\r\n{\r\n  char err_text[64];\r\n  int my_errno;\r\n  \r\n  my_errno=errno;\r\n  ps(s);\r\n  putc(':', stderr);\r\n  \r\n#asm\r\nglobal bDos\r\n  push ix\r\n  pop hl\r\n  ld de,-64\r\n  add hl,de\r\n  ex de,hl\r\n  ld c,066h ; _EXPLAIN\r\n  ld b,(ix+-66) ; my_errno\r\n  call bDos\r\n#endasm\r\n  ps(err_text);\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/PRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern int\t_doprnt();\r\n\r\nprintf(f, a)\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\treturn(_doprnt(stdout, f, &a));\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/PUTCHAR.C",
    "content": "/*\r\n *\tFake routines for getchar and putchar\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\n#undef\tgetchar\r\n#undef\tputchar\r\ngetchar()\r\n{\r\n\treturn(getc(stdin));\r\n}\r\n\r\nputchar(c)\r\n{\r\n\treturn(putc(c, stdout));\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/PUTS.C",
    "content": "/*\r\n *\tputs and fputs for Zios stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nfputs(s, f)\r\nchar *\t\ts;\r\nregister FILE *\tf;\r\n{\r\n\twhile(*s)\r\n\t\tputc(*s++, f);\r\n}\r\n\r\nputs(s)\r\nchar *\t\ts;\r\n{\r\n\tfputs(s, stdout);\r\n\tputchar('\\n');\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/READ.C",
    "content": "/* Read bytes from file */\r\n\r\nread(fd, buf, nbytes)\r\nunsigned char\tfd;\r\nchar *\tbuf;\r\nunsigned short\tnbytes;\r\n{\r\n#asm\r\nglobal _errno, cret, bDos\r\n  ld c,048h ; _READ\r\n  ld b,(ix+6) ; fd\r\n  ld e,(ix+8) ; buf\r\n  ld d,(ix+9)\r\n  ld l,(ix+10) ; nbytes\r\n  ld h,(ix+11)\r\n  call bDos\r\n  jp z,cret ; no error, return hl\r\n  ld (_errno),a\r\n  xor a\r\n  ld (_errno+1),a\r\n#endasm\r\n /* implicit return hl=number of bytes read */\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/READDIR.AS",
    "content": "; readdir.as\r\n\r\n; struct dirent * readdir (DIR * dir)\r\n\r\npsect text\r\nglobal _readdir\r\nglobal csv, cret, _errno, bDos\r\n_readdir:\r\ncall csv\r\nld e,(ix+6)\r\nld d,(ix+7)\r\nld hl,64\r\nadd hl,de\r\nld bc, 1640h ; 40h : _FFIRST 16h: also hidden, system and directory\r\nld a,(hl)\r\nor a\r\njr z, first\r\ninc c ; 41h : _FNEXT\r\n\r\nfirst:\r\npush hl\r\nex (sp),ix\r\nld hl,nulstr\r\n psect data\r\nnulstr:\r\n defb 0\r\n psect text\r\ncall bDos\r\nex (sp),ix\r\npop hl\r\njp z,cret\r\n\r\nld l,a\r\nld h,0\r\nld (_errno),hl\r\nld l,h\r\njp cret\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/REMOVE.C",
    "content": "extern int\tunlink();\r\n\r\nremove(s)\r\nchar *\ts;\r\n{\r\n\treturn unlink(s);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/RENAME.C",
    "content": "#define BUFLEN 67\r\nextern int _flip(char*, char*, int); \r\n\r\nint rename(char *n1, char *n2)\r\n{\r\n  char namebuf[BUFLEN]; /* needed for slash-flipping */\r\n\r\n  if (_flip(namebuf, n1, BUFLEN))\r\n  {\r\n#asm\r\nglobal _errno, cret, bDos\r\n  push ix\r\n  pop hl\r\n  ld de,-BUFLEN\r\n  add hl,de\r\n  ex de,hl\r\n  ld l,(ix+8) ; n2\r\n  ld h,(ix+9)\r\n  ld c,78 ; _RENAME\r\n  call bDos\r\n  ld hl,0\r\n  jp z,cret ; return 0\r\n  ld (_errno),a\r\n  ld a,l\r\n  ld (_errno+1),a\r\n1:\r\n#endasm\r\n  }\r\n  return -1;\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/REWIND.C",
    "content": "#include\t<stdio.h>\r\n\r\nrewind(stream)\r\nFILE *\tstream;\r\n{\r\n\tfseek(stream, 0L, 0);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/REWNDDIR.AS",
    "content": "; rewnddir.as\r\n\r\n; void rewinddir (DIR * dir)\r\n; {\r\n;    dir->dir_file.d_valid = 0;\r\n; }\r\n\r\nglobal _rewinddir\r\npsect text\r\n\r\n_rewinddir:\r\npop hl\r\npop de ; dir\r\npush de\r\npush hl\r\nld hl, 64\r\nadd hl,de\r\nld (hl),0\r\nret\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/RMDIR.C",
    "content": "/* remove directory of given  name */\r\nextern int _act_file(char * name, int mode, int bc);\r\nextern int errno;\r\n\r\nrmdir(name)\r\nchar *\tname;\r\n{\r\n  return _act_file(name, 8, 0x4D);\r\n}\r\n\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/SCANF.C",
    "content": "/*\r\n *\tStdio scanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\t_doscan();\r\n\r\nscanf(fmt, args)\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\treturn _doscan(stdin, fmt, &args);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/SEEK.C",
    "content": "/* changes position in file */\r\n\r\nlong lseek(int fd, long offs, int wh)\r\n{\r\n#asm\r\n  global bDos\r\n  ld c,04Ah ; _SEEK\r\n  ld b,(ix+6) ; fd\r\n  ld l,(ix+8) ; offs\r\n  ld h,(ix+9)\r\n  ld e,(ix+10)\r\n  ld d,(ix+11)\r\n  ld a,(ix+12) ; wh\r\n  call bDos ; new pointer in de:hl\r\n  ex de,hl ; Hitech's calling convention requires long in hl:de\r\n#endasm\r\n  /* implicit return hl:de; */\r\n} \r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/SETBUF.C",
    "content": "/*\r\n *\tSetbuf for Zios stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nsetbuf(f, c)\r\nregister FILE *\tf;\r\nchar *\t\tc;\r\n{\r\n\tif(!(f->_flag & _IOMYBUF) && f->_base)\r\n\t\t_buffree(f->_base);\r\n\tf->_cnt = 0;\r\n\tif(!(f->_base = f->_ptr = c)) {\r\n\t\tf->_flag &= ~_IOMYBUF;\r\n\t\treturn;\r\n\t}\r\n\tf->_flag |= _IOMYBUF;\r\n\tif(f->_flag & _IOWRT)\r\n\t\tf->_cnt = BUFSIZ;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/SETENV.AS",
    "content": "; void setenv(char *name, char * val)\r\nglobal  csv, cret, bDos\r\npsect text\r\nglobal _setenv\r\n_setenv:\r\npop\tbc ; return address\r\npop\thl ; name\r\npop\tde ; val\r\npush\tde\r\npush\thl\r\npush\tbc\r\nld\tc,6Ch ; _SENV\r\njp\tbDos\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/SPRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nstatic\tFILE\tspf;\r\n\r\nsprintf(wh, f, a)\r\nchar *\twh;\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\tspf._cnt = 32767;\r\n\tspf._ptr = wh;\r\n\tspf._flag = _IOWRT|_IOBINARY|_IOSTRG;\r\n\t_doprnt(&spf, f, &a);\r\n\t*spf._ptr = 0;\r\n\treturn spf._ptr - wh;\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/SSCANF.C",
    "content": "/*\r\n *\tStdio sscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<string.h>\r\n\r\nextern int\t_doscan();\r\n\r\nsscanf(str, fmt, args)\r\nchar *\tstr;\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\tFILE\tfile;\r\n\r\n\tfile._base = file._ptr = str;\r\n\tfile._cnt = strlen(str);\r\n\tfile._flag = _IOSTRG|_IOBINARY|_IOREAD;\r\n\treturn _doscan(&file, fmt, &args);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/START1.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t__getargs, startup, __argc_, bDos\r\n\r\nstartup:\r\n; ensure the program is running under msx-dos2\r\n\tld c, 06Fh ; _DOSVER (MSX-DOS2)\r\n\tcall bDos\r\n\tor a\r\n\tjr nz, nodos2\r\n\tld a,b\r\n\tcp 2\r\n\tjr c, nodos2\r\n\r\n;close AUX and PRN,which are not supposed to be open \r\n;    when the program starts, should be harmless under DOS1\r\n        ld bc, 0345h ; _CLOSE, handle 3:AUX\r\n        call bDos\r\n        ld bc, 0445h ; _CLOSE, handle 4:PRN\r\n        call bDos\r\n\tjp\t__getargs\r\n\r\nnodos2:\r\n\tld de, errmsg\r\n\tld c, 09h ; _STROUT\r\n\tcall bDos\r\n\tld c,00h ; _TERM0\r\n\tcall bDos\r\n\r\n\tpsect\tdata\r\nerrmsg:\r\n\tdefm\t'*** wrong version of msx-dos.'\r\n\tdefb\t13,10,'$'\r\n\r\n\tpsect\tbss\r\n__argc_:\r\n\tdefs\t2\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/START2.AS",
    "content": "\tglobal\t__getargs, __argc_\r\n\tpsect\ttext\r\n\r\n__getargs:\r\n\tpop\thl\t\t;return address\r\n\texx\r\n\tpop\thl\r\n\tpop\thl\t\t;unjunk stack\r\n\tld\ta,(80h)\t\t;get buffer length\r\n\tinc\ta\t\t;allow for null byte\r\n\tneg\r\n\tld\tl,a\r\n\tld\th,-1\r\n\tadd\thl,sp\r\n\tld\tsp,hl\t\t;allow space for args\r\n\tex\tde,hl\t\t;save sp\r\n\tld\tbc,0\t\t;flag end of args\r\n\tpush\tbc\r\n\tld\thl,80h\t\t;address of argument buffer\r\n\tld\tc,(hl)\r\n\tld\tb,0\r\n\tadd\thl,bc\t\t;end of arguments\r\n\tex\tde,hl\r\n\tadd\thl,bc\t\t;end of space for arguments\r\n\tld\tb,c\r\n\tld\tc,1\r\n\tdec\thl\r\n\tld\t(hl),0\r\n\tinc\tb\r\n\tjr\t3f\r\n\r\n2:\tld\ta,(de)\r\n\tcp\t' '\r\n\tdec\tde\r\n\tjr\tnz,1f\r\n\tpush\thl\t\t; store argument\r\n\tinc\tc               ; arg counter\r\n4:\tld\ta,(de)\t\t; remove extra spaces\r\n\tcp\t' '\r\n\tjr\tnz,5f\r\n\tdec\tde\r\n\tjr\t4b\r\n5:\r\n\txor\ta\r\n1:\tdec\thl\r\n\tld\t(hl),a\r\n3:\r\n\tdjnz\t2b\r\n\tld\t(__argc_),bc\t\t;store argcount\r\n\tld\thl,nularg\r\n\tpush\thl\r\n\tld\thl,0\r\n\tadd\thl,sp\r\n\texx\r\n\tpush\tde\t\t; junk the stack again\r\n\tpush\tde\r\n\tpush\thl\t\t; return address\r\n\texx\r\n\tret\r\n\r\n\tpsect\tdata\r\nnularg:\tdefb\t0\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/STAT.C",
    "content": "/*\r\n *\tint stat(char * s, struct stat * b);\r\n *\r\n *\tFills  in the supplied struct stat with modification and\r\n *\taccess time and file size.\r\n */\r\n\r\n#include\t<stat.h>\r\n#include\t<time.h>\r\nextern int errno;\r\nextern int _flip(char *, char *, unsigned int);\r\n\r\n\r\nstruct fib /* MSX-DOS2 file info block */\r\n{\r\n  char magic; /* 0xff */\r\n  char name[13];\r\n  unsigned char attr; \r\n  unsigned short mtime;\r\n  unsigned short mdate;\r\n  short cluster;\r\n  long size;\r\n  char drive;\r\n  char pad[64-26];\r\n};\r\n\r\n#define MAXLEN 67\r\n\r\nstatic time_t seconds(struct tm * tp);\r\n\r\nint\r\nstat(register char * s, register struct stat * b)\r\n{\r\n  /* changes in local variables must be reflected in asm-code */\r\n  struct tm td;\r\n  struct fib info;\r\n  char name[MAXLEN];  \r\n\r\n  if (! _flip(name,s,MAXLEN)) return -1;\r\n  else ;\r\n#asm\r\n  global _errno, bDos\r\n  push ix\r\n  pop de\r\n  push de\r\n  ld ix, -82 ; offset of info in frame\r\n  add ix,de ; ix= (&info) \r\n  ld hl,-149 ; offset of name[] in frame\r\n  add hl,de\r\n  ex de,hl ; de=name\r\n  ld bc, 01640h ; 40: _FFIRST, 16: hidden,system,directory\r\n  call bDos\r\n  pop ix\r\n  jr z,1f\r\n  ld (_errno),a\r\n  xor a\r\n  ld (_errno+1),a\r\n  ld hl,-1\r\n  jp cret\r\n1:\r\n#endasm\r\n\r\n  b->st_mode = (info.attr & 0x10)?S_IREAD|S_IEXEC|S_IFDIR:S_IREAD|S_IFREG;\r\n  if ((info.attr & 1)==0) b->st_mode |= S_IWRITE;\r\n  if (info.attr & 2) b->st_mode |= S_HIDDEN;\r\n  if (info.attr & 4) b->st_mode |= S_SYSTEM;\r\n  if (info.attr & 0x20) b->st_mode |= S_ARCHIVE;\r\n  \r\n  td.tm_sec = (info.mtime & 0x1f) *2;\r\n  td.tm_min = (info.mtime >> 5) & 0x3f;\r\n  td.tm_hour= (info.mtime >> 11) & 0x1f;\r\n  td.tm_mday=  info.mdate & 0x1f;\r\n  td.tm_mon = (info.mdate >> 5) & 0xf;\r\n  td.tm_year=((info.mdate >> 9) & 0x7f) + 1980;\r\n  \r\n  b->st_mtime=b->st_atime=seconds(& td);\r\n  b->st_size=info.size;\r\n  \r\n  return 0;\r\n}\r\n\r\n/* computes seconds past since 1/1/1970 (ignoring leap seconds) */\r\nstatic time_t seconds(struct tm * tp)\r\n{\r\n  int yr;\r\n  unsigned long res;\r\n  /* som[n] = number of days in first n months of non-leap year */\r\n  static int som[12]={   0, 31, 59, 90,120,151,181,212,243,273,304,334 };\r\n\r\n  res = (tp->tm_year-1970)*365 + (tp->tm_year-1969)/4; \r\n  res+= som[tp->tm_mon-1] + tp->tm_mday-1;\r\n  if ((yr%4==0) && (tp->tm_mon > 2)) res++; /* days past since 1/1/1970 */\r\n  /* leap year heuristic is wrong in 2100, > 2^{32} sec after 1/1/1970 */\r\n\r\n  return ((res*24l + tp->tm_hour)*60l + tp->tm_min)*60l + tp->tm_sec;\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/STAT.H",
    "content": "struct stat\r\n{\r\n\tshort\tst_mode;\t/* flags */\r\n\tlong\tst_atime;\t/* access time */\r\n\tlong\tst_mtime;\t/* modification time */\r\n\tlong\tst_size;\t/* file size in bytes */\r\n};\r\n\r\n/* Flag bits in st_mode */\r\n\r\n#define\tS_IFMT\t\t0x600\t/* type bits */\r\n#define\t\tS_IFDIR\t0x400\t/* is a directory */\r\n#define\t\tS_IFREG\t0x200\t/* is a regular file */\r\n#define\tS_IREAD\t\t0400\t/* file can be read */\r\n#define\tS_IWRITE\t0200\t/* file can be written */\r\n#define\tS_IEXEC\t\t0100\t/* file can be executed */\r\n#define\tS_HIDDEN\t0x1000\t/* file is hidden */\r\n#define\tS_SYSTEM\t0x2000\t/* file is marked system */\r\n#define\tS_ARCHIVE\t0x4000\t/* file has been written to */\r\n\r\nstruct utimbuf {\r\n\tlong ac_time;\r\n\tlong mod_time;\r\n};\r\n\r\nextern int\tstat(char *, struct stat *);\r\nextern int \tutime(char *, struct utimbuf *);\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/STDCLEAN.C",
    "content": "#include\t<stdio.h>\r\n\r\n_cleanup()\r\n{\r\n\tuchar\ti;\r\n\tregister struct _iobuf *\tip;\r\n\r\n\ti = _NFILE;\r\n\tip = _iob;\r\n\tdo {\r\n\t\tfclose(ip);\r\n\t\tip++;\r\n\t} while(--i);\r\n}\r\n/*\r\n *\tInitial setup for stdio\r\n */\r\n\r\nchar\t_sibuf[BUFSIZ];\r\nFILE\t_iob[_NFILE] =\r\n{\r\n\t{\r\n\t\t_sibuf,\r\n\t\t0,\r\n\t\t_sibuf,\r\n\t\t_IOREAD|_IOMYBUF,\r\n\t\t0\t\t\t/* stdin */\r\n\t},\r\n\t{\r\n\t\t(char *)0,\r\n\t\t0,\r\n\t\t(char *)0,\r\n\t\t_IOWRT|_IONBF,\r\n\t\t1\t\t\t/* stdout */\r\n\t},\r\n\t{\r\n\t\t(char *)0,\r\n\t\t0,\r\n\t\t(char *)0,\r\n\t\t_IOWRT|_IONBF,\r\n\t\t2\t\t\t/* stderr */\r\n\t},\r\n};\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/UNGETC.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tungetc for Zios\r\n */\r\n\r\nungetc(c, stream)\r\nint\t\tc;\r\nregister FILE *\tstream;\r\n{\r\n\tif(c == EOF || !(stream->_flag & _IOREAD) ||\r\n\t\tstream->_base == (char *)NULL || stream->_cnt == BUFSIZ)\r\n\t\treturn(EOF);\r\n\tif(stream->_ptr == stream->_base)\r\n\t\tstream->_ptr++;\r\n\telse\r\n\t\tstream->_cnt++;\r\n\t*--stream->_ptr = c;\r\n\treturn(c);\r\n}\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/UNIXIO.H",
    "content": "/*\r\n *\tDeclarations for Unix style low-level I/O functions.\r\n */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\n#ifndef SEEK_SET\r\n#define SEEK_SET 0\r\n#define SEEK_CUR 1\r\n#define SEEK_END 2\r\n#endif\r\n#ifndef O_RDONLY\r\n#define O_RDONLY 0\r\n#define O_WRONLY 1\r\n#define O_RDWR 2\r\n#define O_INHER 4\r\n#endif\r\n \r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\nextern int\topen(char *, int);\r\nextern int\tclose(int);\r\nextern int\tcreat(char *, int);\r\nextern int\tdup(int);\r\nextern long\tlseek(int, long, int);\r\nextern int\tread(int, void *, int);\r\nextern int\tunlink(char *);\r\nextern int\twrite(int, void *, int);\r\nextern int\tisatty(int);\r\nextern int\tchmod(char *, int);\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/UNLINK.C",
    "content": "/* remove file of given  name */\r\nextern int _act_file(char * name, int mode, int bc);\r\nextern int errno;\r\n\r\nunlink(name)\r\nchar *\tname;\r\n{\r\n  return _act_file(name, 0, 0x4D);\r\n}\r\n\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/UTIME.C",
    "content": "/* utime.c */\r\n\r\n#include <time.h>\r\n#include <stat.h>\r\n\r\nextern int _flip(char*, char*, int); \r\nextern int _utime(char*, int, int);\r\n\r\n#define BUFLEN 67\r\n\r\nint utime(char * name, struct utimbuf *tb)\r\n{\r\n  register struct tm *tp;\r\n  int fat_date, fat_time;\r\n  char buf[BUFLEN];\r\n\r\n  if (_flip(buf, name, BUFLEN)) { /* '/' to '\\\\' */ \r\n    tp=gmtime(tb->mod_time);\r\n    fat_date= (tp->tm_year-80)<<9 + tp->tm_mon<<5 + tp->tm_mday;\r\n    fat_time=  tp->tm_hour << 11 + tp->tm_min << 5 + tp->tm_sec >>1;\r\n    return _utime(buf, fat_date, fat_time);\r\n  }\r\n  return -1;\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/ldos2_04/WRITE.C",
    "content": "write(fd, buf, nbytes)\r\nunsigned char\tfd;\r\nchar *\tbuf;\r\nunsigned short\tnbytes;\r\n{\r\n#asm\r\nglobal _errno, cret, bDos\r\n ld c,049h ; _WRITE\r\n ld b,(ix+6) ; fd\r\n ld e,(ix+8) ; buf\r\n ld d,(ix+9)\r\n ld l,(ix+10) ; nbytes\r\n ld h,(ix+11)\r\n call bDos\r\n jp z,cret\r\n ld (_errno),a\r\n xor a\r\n ld (_errno+1),a\r\n#endasm\r\n /* implicit return hl=number of bytes written */\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/CONVTIME.C",
    "content": "/*\r\n * This routine converts the date and time in MS(X)DOS format to\r\n * Unix style date and time - seconds since 00:00:00 Jan 1 1970.\r\n * Pierre Gielen 10/93\r\n *\r\n * Public Domain for Hitech-C standard MSXDOS library\r\n */\r\n\r\n#include <time.h>\r\n\r\nlong convtime(dostime,dosdate)\r\nunsigned int dosdate,dostime;\r\n{\r\n\tunsigned int cday = 0;\r\n        unsigned int cnt,year,month;\r\n\ttime_t t;\r\n\tstatic unsigned char dpermo[12] =\r\n\t\t     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r\n\r\n        year = ((dosdate >> 9) & (int)0x7f)+10;     /* bits 15..9  */\r\n\tmonth = ((dosdate >> 5) & (int)0xf)-1;\t    /* bits  8..5  */\r\n\r\n        for (cnt=0;cnt<year;cnt++)\r\n\t{\r\n\t  cday += 365;\r\n\t  if (((1970+cnt) % 4)==0)\t/* leapyear */\r\n\t    ++cday;\r\n\t}\r\n        if(((1970+year)%4)==0)          /* if current leapyear */\r\n\t  if(month>1)\t\t\t/* if past february */\r\n\t    ++cday;\r\n        for (cnt=0;cnt<month;cnt++)\r\n\t  cday += dpermo[cnt];\t\t/* add days per month */\r\n\r\n        t = (long)(cday + (dosdate & (int)0x1f)-1); /* days bits  4..0  */\r\n        t *= 24;                                    /* date in past hours */\r\n        t += ((dostime >> 11) & (int)0x1f);         /* hours, bits 15..11 */\r\n\tt *= 60;\r\n        t += ((dostime >> 5) & (int)0x3f);          /* minutes, bits 10..5  */\r\n\tt *= 60;\r\n        t += ((dostime << 1) & (int)0x3e);          /* seconds, bits  4..0  */\r\n\r\n\treturn (long)t;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/DOPRNT.C",
    "content": "#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n#include\t<string.h>\r\n\r\n\r\n/*\r\n *\tdoprnt for Z80\r\n */\r\n\r\nextern int\tatoi(char *);\r\nextern int\t_pnum();\r\n\r\n/* Routines for formatted output must be able to cope with \r\n   strings longer than 255 bytes.  -  Arnold M */\r\nstatic unsigned int ival;\r\nstatic char *\tx;\r\nstatic FILE *\tffile;\r\n\r\nstatic\r\npputc(c)\r\nchar\tc;\r\n{\r\n\tputc(c, ffile);\r\n}\r\n\r\nstatic char *\r\nicvt(cp)\r\nregister char *\tcp;\r\n{\r\n\tival = atoi(cp);\r\n\twhile(isdigit((unsigned)*cp))\r\n\t\tcp++;\r\n\treturn cp;\r\n}\r\n\r\n_doprnt(file, f, a)\r\nFILE *\tfile;\r\nregister char *\t\tf;\r\nint *\t\ta;\r\n{\r\n\tchar\tc;\r\n\tuchar\tfill, left;\r\n\tunsigned int i, prec, width; /* Allow for long strings.  - Arnold M */ \r\n\tuchar\tbase, sign, len;\r\n\r\n\tffile = file;\r\n\twhile(c = *f++)\r\n\t\tif(c != '%')\r\n\t\t\tpputc(c);\r\n\t\telse {\r\n\t\t\tbase = 10;\r\n\t\t\twidth = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tleft = 0;\r\n\t\t\tlen = sizeof(int)/sizeof *a;\r\n\t\t\tif(*f == '-') {\r\n\t\t\t\tf++;\r\n\t\t\t\tleft++;\r\n\t\t\t}\r\n\t\t\tfill = *f == '0';\r\n\t\t\tif(isdigit((unsigned)*f)) {\r\n\t\t\t\tf = icvt(f);\r\n\t\t\t\twidth = ival;\r\n\t\t\t} else if(*f == '*') {\r\n\t\t\t\twidth = *a++;\r\n\t\t\t\tf++;\r\n\t\t\t}\r\n\t\t\tif(*f == '.')\r\n\t\t\t\tif(*++f == '*') {\r\n\t\t\t\t\tprec = *a++;\r\n\t\t\t\t\tf++;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tf = icvt(f);\r\n\t\t\t\t\tprec = ival;\r\n\t\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tprec = fill ? width : 0;\r\n\t\t\tif(*f == 'l') {\r\n\t\t\t\tf++;\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\t}\r\n\t\t\tswitch(c = *f++) {\r\n\r\n\t\t\tcase 0:\r\n\t\t\t\treturn;\r\n\t\t\tcase 'o':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'd':\r\n\t\t\t\tsign = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'x':\r\n\t\t\t\tsign = 1; /* a-f in lower case */ \r\n\t\t\tcase 'X':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\tx = *(char **)a;\r\n\t\t\t\ta += sizeof(char *)/sizeof *a;\r\n\t\t\t\tif(!x)\r\n\t\t\t\t\tx = \"(null)\";\r\n\t\t\t\ti = strlen(x);\r\ndostring:\r\n\t\t\t\tif(prec && prec < i)\r\n\t\t\t\t\ti = prec;\r\n\t\t\t\tif(width > i)\r\n\t\t\t\t\twidth -= i;\r\n\t\t\t\telse\r\n\t\t\t\t\twidth = 0;\r\n\t\t\t\tif(!left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\twhile(i--)\r\n\t\t\t\t\tpputc(*x++);\r\n\t\t\t\tif(left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\tcontinue;\r\n\t\t\tcase 'c':\r\n\t\t\t\tc = *a++;\r\n\t\t\tdefault:\r\n\t\t\t\tx = &c;\r\n\t\t\t\ti = 1;\r\n\t\t\t\tgoto dostring;\r\n\r\n\t\t\tcase 'u':\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tif(left) {\r\n\t\t\t\tleft = width;\r\n\t\t\t\twidth = 0;\r\n\t\t\t}\r\n\t\t\twidth = _pnum((len == sizeof(int)/sizeof *a ? (sign ? (long)*a : (unsigned long)*a) : *(long *)a), prec, width, sign, base, pputc);\r\n\t\t\ta += len;\r\n\t\t\twhile(left-- > width)\r\n\t\t\t\tpputc(' ');\r\n\t\t}\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/FDOPRNT.C",
    "content": "#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n\r\n\r\n/*\r\n *\tdoprnt for 8086\r\n */\r\n\r\n/* Routines for formatted output must be able to cope with \r\n   strings longer than 255 bytes.  -  Arnold M */\r\nstatic unsigned int ival;\r\nstatic char *\tx;\r\nstatic FILE *\tffile;\r\nextern int\tatoi(char *);\r\nextern int\tstrlen(char *);\r\n\r\nstatic\r\npputc(c)\r\nint\tc;\r\n{\r\n\tputc(c, ffile);\r\n}\r\n\r\nstatic char *\r\nicvt(cp)\r\nregister char *\tcp;\r\n{\r\n\tival = atoi(cp);\r\n\twhile(isdigit((unsigned)*cp))\r\n\t\tcp++;\r\n\treturn cp;\r\n}\r\n\r\n_doprnt(file, f, a)\r\nFILE *\tfile;\r\nregister char *\t\tf;\r\nint *\t\ta;\r\n{\r\n\tchar\tc;\r\n\tuchar\tfill, left;\r\n\tint\tprec;\r\n\tunsigned int i, width; /* Allow for long strings.  - Arnold M */ \r\n\tuchar\tbase, sign, len;\r\n\tuchar\tftype;\r\n\textern\tshort _pnum(), _fnum();\r\n\r\n\tffile = file;\r\n\twhile(c = *f++)\r\n\t\tif(c != '%')\r\n\t\t\tpputc(c);\r\n\t\telse {\r\n\t\t\tbase = 10;\r\n\t\t\twidth = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tleft = 0;\r\n\t\t\tftype = 0;\r\n\t\t\tlen = sizeof(int)/sizeof *a;\r\n\t\t\tif(*f == '-') {\r\n\t\t\t\tf++;\r\n\t\t\t\tleft++;\r\n\t\t\t}\r\n\t\t\tfill = *f == '0';\r\n\t\t\tif(isdigit((unsigned)*f)) {\r\n\t\t\t\tf = icvt(f);\r\n\t\t\t\twidth = ival;\r\n\t\t\t} else if(*f == '*') {\r\n\t\t\t\twidth = *a++;\r\n\t\t\t\tf++;\r\n\t\t\t}\r\n\t\t\tif(*f == '.')\r\n\t\t\t\tif(*++f == '*') {\r\n\t\t\t\t\tprec = *a++;\r\n\t\t\t\t\tf++;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tf = icvt(f);\r\n\t\t\t\t\tprec = ival;\r\n\t\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tprec = fill ? width : -1;\r\n\t\t\tif(*f == 'l') {\r\n\t\t\t\tf++;\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\t}\r\n\t\t\tswitch(c = *f++) {\r\n\r\n\t\t\tcase 0:\r\n\t\t\t\treturn;\r\n\t\t\tcase 'o':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'd':\r\n\t\t\t\tsign = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'x':\r\n\t\t\t\tsign = 1; /* a-f in lower case */\r\n\t\t\tcase 'X':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\tx = *(char **)a;\r\n\t\t\t\ta += sizeof(char *)/sizeof *a;\r\n\t\t\t\tif(!x)\r\n\t\t\t\t\tx = \"(null)\";\r\n\t\t\t\ti = strlen(x);\r\ndostring:\r\n\t\t\t\tif(prec < 0)\r\n\t\t\t\t\tprec = 0;\r\n\t\t\t\tif(prec && prec < i)\r\n\t\t\t\t\ti = prec;\r\n\t\t\t\tif(width > i)\r\n\t\t\t\t\twidth -= i;\r\n\t\t\t\telse\r\n\t\t\t\t\twidth = 0;\r\n\t\t\t\tif(!left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\twhile(i--)\r\n\t\t\t\t\tpputc(*x++);\r\n\t\t\t\tif(left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\tcontinue;\r\n\t\t\tcase 'c':\r\n\t\t\t\tc = *a++;\r\n\t\t\tdefault:\r\n\t\t\t\tx = &c;\r\n\t\t\t\ti = 1;\r\n\t\t\t\tgoto dostring;\r\n\r\n\t\t\tcase 'u':\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'e':\r\n\t\t\t\tsign++;\r\n\r\n\t\t\tcase 'g':\r\n\t\t\t\tsign++;\r\n\r\n\t\t\tcase 'f':\r\n\t\t\t\tif(prec < 0)\r\n\t\t\t\t\tprec = 6;\r\n\t\t\t\tftype = 1;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tif(left) {\r\n\t\t\t\tleft = width;\r\n\t\t\t\twidth = 0;\r\n\t\t\t}\r\n\t\t\tif(prec < 0)\r\n\t\t\t\tprec = 0;\r\n\t\t\tif(ftype) {\r\n\t\t\t\twidth = _fnum(*(double *)a, prec, width, sign, pputc);\r\n\t\t\t\ta += sizeof(double)/sizeof(*a);\r\n\t\t\t} else {\r\n\t\t\t\twidth = _pnum((len == sizeof(int)/sizeof *a ? (sign ? (long)*a : (unsigned long)*a) : *(long *)a), prec, width, sign, base, pputc);\r\n\t\t\t\ta += len;\r\n\t\t\t}\r\n\t\t\twhile(left-- > width)\r\n\t\t\t\tpputc(' ');\r\n\t\t}\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/FIXES.TXT",
    "content": "Fixes for the libraries provided with HiTech-C.\r\n\r\n  HiTech has given kind permission to  use  its  C-compiler  for\r\ncp/m without paying a fee. hiTech has also released as  freeware\r\nsome libraries for cp/m and the sources thereof.\r\n\r\n  Pierre Gielen has made adaptations and extensions for  msxdos2\r\nand has released as public domain in 1993. I have  bundled  some\r\nof these changes with some fixes, improvements and  additions  I\r\nhave written myself.\r\n\r\n  I have deliberately left out the things that work  only  under\r\nmsx-dos2 to keep it  easy  to  make  programs  that  work  under\r\nmsxdos1; there is libdos2 for those who want to  use  the  extra\r\npossibilities of msx-dos2.\r\n\r\n  To use these patches you can copy the header and library files\r\nin this package to the directory where you  keep  your  copy  of\r\nHiTech-C or type 'make install'. You are free to use, modify and\r\nredistribute this package. Please send bug-reports,  suggestions\r\netc. to me.\r\n\r\nArnold Metselaar <arnold.metselaar@planet.nl>\r\n\r\n\r\n  The following files are present in this package:\r\n\r\nfixes.txt \r\n\tthis file\r\n\r\nmakefile\r\n        Use with a recent version of make.com to create object  files\r\n        and update library files. Run make without  arguments  for  a\r\n        list of possibilities.\r\n\r\nlibc.lib\r\nlibf.lib\r\n\tReplacements for the equally named libraries that  come  with\r\n        HiTech-C. \r\n\r\nstring.h\r\n\tChanged header file that reflects which string  functions  are\r\n        actually available in libc.lib.\r\n\r\ntime.h\r\n\tChanged header file declaring some extra functions.\r\n\r\n\tSOURCEFILES:\r\n\r\nmemchr.as\tvoid * memchr (void * s, int c, size_t n)\r\nmemmove.as\tvoid * memmove (void * dest, void * src, size_t n) \r\n\tMissing in the original libc.lib.\r\n\r\nmemcmp.as\tint memcmp (void * s1, void * s2, size_t n)\r\nmemcpy.as\tvoid * memcpy (void * dest, void * src, size_t n) \r\n\tMore  efficient  implementations  of  these   functions,   the\r\n        original implementations are in C. \r\n\r\nmemset.as\tvoid * memset (void * s, int c, size_t n)\r\n        The original function written in C has the c and n arguments\r\n        interchanged, this one follows the standard ordering.\r\n\r\nstrchr.as\tchar * strchr(char * s, int c)\r\n\t\tchar * index (char * s, int c)\r\nstrrchr.as\tchar * strrchr(char * s, int c)\r\n\t\tchar * rindex (char * s, int c)\r\n        When c==0 the original functions would return NULL, and these\r\n        functions  will  return  the  address  of  the  closing   NUL\r\n        character.\r\n\r\nstricmp.as\tint strcasecmp(char *s1, char *s2)\r\nstrnicmp.as\tint strncasecmp(char *s1, char *s2, size_t n)\r\n        These extra functions  are  similar  to  strcmp  and  strncmp\r\n        respectively, but letters are converted to lower case  before\r\n        comparison, which leads to a case insensitive comparison.\r\n\r\nstrstr.c\tchar * strstr (char *t, char *s) \r\nstrnstr.c\tchar * strnstr (char *t, char *s, unsigned int n) \r\nstristr.c\tchar * strcasestr (char *t, char *s) \r\nstrnistr.c\tchar * strncasestr (char *t, char *s, unsigned int n) \r\n        These extra functions locate the first occurence of string  s\r\n        in string t. The functions strnstr  and  strcasestr  read  at\r\n        most n characters from string t. The functions strcasestr and\r\n        strncasestr use case insensitive comparisons.\r\n        All these functions return a pointer to the  first  character\r\n        of the first occurence of string s in string t if found,  and\r\n        NULL otherwise.\r\n\r\nstrdup.c\tchar * strdup (char * s)\r\n\tThis function allocates a  new  buffer  for  and  copies  the\r\n        string pointed to by s to it. It returns  a  pointer  to  the\r\n        copy of the string or NULL if memory allocation  failed.  The\r\n        memory block can be release with free().\r\n\r\nstrtok.c\tchar *strtok(char *s, char *tok, size_t toklen, char *brk)\r\n        This function copies  characters  from  s  to  tok  until  it\r\n        encounters one of the characters in  brk  or  until  toklen-1\r\n        characters have been copied, whichever comes first.  It  then\r\n        adds a terminating zero.\r\n\tThis function does not conform to the posix standard. \r\n\r\ntime.c\t\ttime_t time (time_t * tp)\r\n\t\ttime_t timerset (time_t t)\r\n\t\tint timeup (time_t t)\r\nmsxtime.as\ttime_t msxtime ()\r\n\tThe function time gives the time in seconds  since  00:00:00,\r\n        Jan  1st,  1970  (unix  style),  timerset  and   timeup   are\r\n        convenience functions that can be used  to  check  a  certain\r\n        time interval has passed. The actual conversion  is  done  in\r\n        msxtime.\r\n\r\ngetch.as\tchar getch(void);    /* get character */\r\n\t\tchar getche(void);   /* get/echo character */\r\n\t\tvoid putch(int);     /* output character to console*/\r\n\t\tvoid ungetch(int);   /* unget character */\r\n\t\tint kbhit(void);     /* true if keyboard hit */\r\n\t\tvoid cursor(char onoff)\r\n\tAccelerated versions of these functions declared in conio.h.\r\n\r\ninout.as\tbyte in(byte io-address)\r\n\t\tbyte out(byte io-address,byte value)\r\n\t\tvoid di();\r\n\t\tvoid ei();\r\n        The functions in() and out() can be used  to  access  the  IO\r\n        ports of the CPU directly. Interrupts  can  be  disabled  and\r\n        enabled with di()  and  ei()  respectively.  These  functions\r\n        disable and enable the generation of interrupts  by  the  VDP\r\n        rather than the servicing by the  CPU,  since  many  MSX-bios\r\n        routines enable interrupts even when  they  are  called  with\r\n        interrupts disabled.\r\n\r\npeekpoke.as\tvoid poke(word address, byte value)\r\n\t\tbyte peek(word address)\r\n        These  functions  are  equivalent  to  the   more   efficient\r\n        (*((byte*)address))   =   value    and    (*((byte*)address))\r\n        respectively. Programmers with experience in basic will  find\r\n        them more familiar.\r\n\r\nsleep.c\t\tvoid sleep (unsigned int seconds)\r\n\tThis function does nothing until the given number of  seconds\r\n        has passed.\r\n\r\nstrftime.c\tsize_t strftime(char *s, size_t maxs, char *f, struct tm *t)\r\n        This function takes a broken down time (*t) and  converts  it\r\n        to a string, in the way specified by the format string (f).\r\n\r\nconvtime.c\tlong convtime(unsigned int dostime, unsigned int dosdate)\r\n        This routine converts the date and time in MS(X)DOS format to\r\n        Unix style date and time - seconds since 00:00:00 Jan 1 1970.\r\n\r\nfdoprnt.c\tdoprnt(FILE* fp, char* format, ...)\r\ndoprnt.c\tdoprnt(FILE* fp, char* format, ...)\r\n        Routines used by printf and similar functions to format data,\r\n        fdoprnt contains the variant that can also handle floats. The\r\n        original versions use 8 bit variables to hold string lengths,\r\n        which fails on strings larger than 255 characters. If you  do\r\n        not use such very long strings, you may  prefer  to  use  the\r\n        original functions, that are somewhat smaller and faster.\r\n\r\nfbcd.obj\r\n\tInternal  routine,  used  to  print  floating  point  numbers,\r\n        strangely enough the source provided by HiTech is correct, but\r\n        the object file in libc.lib was not.\r\n\r\nfrelop.as\r\n\tInternal routine, correction for  a  bug  that  caused  wrong\r\n        results when comparing negative numbers that  have  the  same\r\n        exponent.\r\n\r\nrcsv.as\r\n\tInternal routine, marginal improvement in size\u0001@and speed. \r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/FRELOP.AS",
    "content": ";\tfloating relational operation - returns flags as though\r\n;\ta floating subtract was done.\r\n;\tbugfix (-1.5 used to be deemed larger than -1.25) by Arnold M \r\n\r\n\tpsect\ttext\r\n\tglobal\tfrelop\r\n\r\nfrelop:\r\n\texx\t\t\t;select\talternate reg set\r\n\tpop\thl\t\t;return\taddress\r\n\texx\t\t\t;get other set again\r\n\tpop\tbc\t\t;low word of 2nd arg\r\n\tex\tde,hl\t\t;put hi\tword of\t1st in de\r\n\tex\t(sp),hl\t\t;get hi\tword of\t2nd in hl\r\n\tex\tde,hl\t\t;hi word of 1st\tback in\thl\r\n\tld\ta,h\t\t;test for differing signs\r\n\txor\td\r\n\tjp\tp,2f\t\t;the same, so ok\r\n\tld\ta,h\t\t;get the sign of the LHS\r\n\tor\t1\t\t;ensure zero flag is reset, set sign flag\r\n\tpop\tbc\t\t;unjunk stack\r\n\tjp\t1f\t\t;return\twith sign of LHS\r\n2:\r\n\tld\ta,h\t\t;test for differing exponents\r\n\tsub\td\t\t;compare with the other\r\n\tjr\tz,2f\t\t;the same, go for mantissas\r\n\txor\th\t\t;complement sign flag if operands -ve\r\n\tor\t1\t\t;reset zero flag\r\n\tpop\tbc\t\t;unjunk stack\r\n\tjp\t1f\t\t;and return\r\n2:\r\n\tsbc\thl,de\t\t;set the flags (Cy=0 from sub d)\r\n\tpop\thl\t\t;low word of 1st into hl again\r\n\tjr\tnz,3f\t\t;go check sign if not zero\r\n\tsbc\thl,bc\t\t;now set flags on basis\tof low word\r\n\tjr\tz,1f\t\t;if zero, all ok\r\n3:\r\n\trra\t\t\t;carry into sign bit of a\r\n\txor\td\t\t;complement sign flag if operands -ve (AM)\r\n\tor\t1\t\t;reset zero flag\r\n\r\n1:\r\n\texx\t\t\t;get return address\r\n\tjp\t(hl)\t\t;and return with stack clean\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/GETCH.AS",
    "content": "; Hi-Tech C standard library\r\n;\r\n; Accelerated MSXDOS versions of the following console functions\r\n; (defined in conio.h):\r\n;\r\n; char\t   getch(void);    /* get character */\r\n; char\t   getche(void);   /* get/echo character */\r\n; void\t   putch(int);\t   /* output character to console;/\r\n; void\t   ungetch(int);   /* unget character;/\r\n; int\t   kbhit(void);    /* true if keyboard hit;/\r\n;\r\n; added new function:\r\n;\r\n; void\t   cursor(int); \t       [ 1 = on,  0 = off ]\r\n;\r\n; Use this file to update the Hitech-C standard library libc.lib.\r\n;\r\n; PGN 10/93\r\n; Last update 12/93\r\n\r\n\r\n;void cursor(char onoff)\r\n\r\n\tpsect\ttext\r\n\tglobal\t_cursor\r\n_cursor:\r\n\tld\ta,l\r\n\tld\t(0fca9h),a\t; 0=off else on\r\n\tld\t(0fcaah),a\t; line style cursor if on\r\n\tret\r\n\r\n;char getch(void)\r\n\r\n\tpsect\ttext\r\n\tglobal\t_getch\r\n_getch:\r\n\tld\thl,(pushbk)\r\n\tld\ta,h\r\n\tor\tl\t\t; if pushed back\r\n\tjr\tz,1f\t\t; none\r\n\tld\tde,0\r\n\tld\t(pushbk),de\t; else delete pushback\r\n\tret\t\t\t; return with hl\r\n1:\tpush\tix\r\n\tpush\tiy\r\n\tld\tix,09fh\r\n\tld\tiy,(0fcc0h)\r\n\tcall\t01ch\t\t; chget\r\n\tld\tl,a\r\n\tld\th,0\r\n\tpop\tiy\r\n\tpop\tix\r\n\tret\r\n\r\n\r\n;char getche(void)\r\n\r\n\tpsect\ttext\r\n\tglobal\t_getche\r\n_getche:\r\n\tld\thl,(pushbk)\r\n\tld\ta,h\r\n\tor\tl\t\t; if pushed back\r\n\tjr\tz,2f\t\t; none\r\n\tld\tde,0\r\n\tld\t(pushbk),de\t; else delete pushback\r\n\tret\t\t\t; return with hl\r\n2:\tcall\t1b\t\t; get character\r\n\tpush\thl\r\n\tcall\t_putch\r\n\tpop\thl\r\n\tret\r\n\r\n;void ungetch(char)\r\n\r\n\tpsect\ttext\r\n\tglobal\t_ungetch\r\n_ungetch:\r\n\tld\t(pushbk),hl\r\n\tret\r\n\tpsect\tdata\r\npushbk:\r\n\tdefw\t0\r\n\r\n;void putch(char)\r\n\r\n\tpsect\ttext\r\n\tglobal\t_putch\r\n_putch:\r\n\tld\ta,l\r\n\tcp\t10\t\t; if newline\r\n\tjr\tnz,3f\r\n\tld\thl,13\r\n\tcall\t3f\r\n\tld\thl,10\r\n3:\tpush\tix\r\n\tpush\tiy\r\n\tld\ta,l\r\n\tld\tix,0a2h\r\n\tld\tiy,(0fcc0h)\r\n\tcall\t01ch\r\n\tpop\tiy\r\n\tpop\tix\r\n\tret\r\n\r\n;int kbhit()\r\n\r\n\tpsect\ttext\r\n\tglobal\t_kbhit\r\n_kbhit:\r\n\tld\thl,(0f3fah)\t; getpnt\r\n\tld\ta,(0f3f8h)\t; putpnt\r\n\tcp\tl\r\n\tld\thl,1\r\n\tret\tnz\t\t; if NZ then keypressed\r\n\tld\thl,0\r\n\tret\r\n\r\n; end of file\r\n"
  },
  {
    "path": "msx2dist/libfix01/INOUT.AS",
    "content": "\tglobal _in, _out\r\n\tglobal _di, _ei\r\n\r\n\tpsect\ttext\r\n\r\n; byte in(byte io-address)\r\n\r\n_in:\r\n\tld\tc,l\t\t;port address\r\n\tin\tl,(c)\t\t;read port\r\n\tld\th,0\t\t;zero extend it\r\n\tret\r\n\r\n; byte out(byte io-address,byte value)\r\n\r\n_out:\r\n\tpop\thl\t\t;return address\r\n\tpop\tbc\t\t;port address\r\n\tpop\tde\t\t;data\r\n\tpush\tde\r\n\tpush\tbc\r\n\tpush\thl\r\n\tout\t(c),e\t\t;output the data\r\n\tld\tl,c\t\t;return value in hl also\r\n\tld\th,0\r\n\tret\r\n\r\n; void di();\r\n; void ei();\r\n\r\n_di:\tld\ta,(0f3e0h)\r\n        and     0dfh\r\n        jr      1f\r\n\r\n_ei:\tld\ta,(0f3e0h)\r\n        or      20h\r\n\r\n1:      ld      b,a\r\n        ld      c,1\r\n        push    ix\r\n        push    iy\r\n        ld      ix,047h ; routine WRTVDP\r\n        ld      iy,(0fcc0h) ; in main bios rom\r\n        call    01ch\r\n        pop     iy\r\n        pop     ix\r\n        xor     a\r\n        ld      (0fca9h),a\r\n\tret\r\n\r\n\r\n\tend\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MAKEFILE",
    "content": "# makefile for fixes in HiTech-C's libraries\r\n\t\r\n# Directory where the libraries are installed:\r\n# Backslashes must be doubled twice here because make will process them twice\r\nDIR = a:\\\\\\\\hitech\r\n# Command to move a library file,\r\n# change to copy if the library files are on a different drive or partition:\r\nMV = move\r\n\r\n# Name for distribution package:\r\nDIST = libfix01.lzh\r\n\r\n# Options to pass to the C compiler:\r\n# -o : optimise, *strongly recommended*,\r\n# -v : be verbose, lets you follow the progress.\r\n#\r\nCFLAGS = -o -v\r\n\r\n# if you want another tiomezone than central european time, \r\n# you can define TZNAME and recompile strftime.c. For example:\r\n#\r\n# CFLAGS += '-DTZNAME=\"GMT\"'\r\n\r\nhelp :\r\n\ttype $$m.t <<EOF\r\n\tThe following targets are available:\r\n\tupdate : build object files and replace them in .\\\\libc.libc, and .\\\\libf.lib.\r\n\treorder : put object files in libc.lib in the right order, \r\n\t          not needed for libf.lib. \r\n\tinstall : copy libraries and updated header files to $(DIR). \r\n\tdistribution : make a new distribution package in $(DIST).\r\n\tclean : delete the objectfiles extracted from libc.lib by 'make reorder'.\r\n\tveryclean : delete the extracted objectfiles and also those made from sources.\r\n\t\r\n\tChange DIR in the makefile if you do not have HiTech-C in $(DIR).\r\n\tEOF\r\n\r\n# source files\r\n#\r\nLC_C = sleep.c time.c convtime.c strftime.c doprnt.c\r\nLC_C += strdup.c strstr.c stristr.c strnstr.c strnistr.c strtok.c \r\nLF_C = fdoprnt.c\r\nLC_AS1 = msxtime.as memcmp.as memcpy.as memmove.as memset.as memchr.as getch.as\r\nLC_AS2 = frelop.as strnicmp.as stricmp.as strchr.as strrchr.as inout.as\r\nLC_AS2 += peekpoke.as signal.as rcsv.as\r\nSRC  = $(LC_C) $(LF_C) $(LC_AS1) $(LC_AS2)\r\n\r\n# all object files for libc.lib, order is important:\r\n#\r\nLIBC_ALL  = getargs.obj start1.obj start2.obj assert.obj printf.obj fprintf.obj\r\nLIBC_ALL += fcbname.obj sprintf.obj doprnt.obj getenv.obj gets.obj puts.obj\r\nLIBC_ALL += fwrite.obj getw.obj putw.obj srand1.obj putchar.obj perror.obj\r\nLIBC_ALL += fputc.obj flsbuf.obj fopen.obj freopen.obj rewind.obj fseek.obj\r\nLIBC_ALL += fread.obj remove.obj fscanf.obj sscanf.obj scanf.obj doscan.obj\r\nLIBC_ALL += fgetc.obj filbuf.obj stdclean.obj fclose.obj fflush.obj open.obj\r\nLIBC_ALL += read.obj write.obj seek.obj stat.obj chmod.obj rename.obj creat.obj\r\nLIBC_ALL += isatty.obj close.obj unlink.obj dup.obj execl.obj getfcb.obj\r\nLIBC_ALL += cleanup.obj setbuf.obj ctime.obj cgets.obj cputs.obj ungetc.obj\r\nLIBC_ALL += buf.obj abort.obj signal.obj exit.obj sleep.obj time.obj\r\nLIBC_ALL += convtime.obj timezone.obj getch.obj getuid.obj bdos.obj bdoshl.obj\r\nLIBC_ALL += bios.obj _exit.obj fakeclean.obj fakecpcln.obj sys_err.obj\r\nLIBC_ALL += memcpy.obj memcmp.obj memset.obj abs.obj asallsh.obj allsh.obj\r\nLIBC_ALL += asalrsh.obj asar.obj asdiv.obj asladd.obj asland.obj asll.obj\r\nLIBC_ALL += asllrsh.obj aslmul.obj aslor.obj aslsub.obj aslxor.obj strftime.obj\r\nLIBC_ALL += asmod.obj atoi.obj atol.obj blkclr.obj blkcpy.obj calloc.obj\r\nLIBC_ALL += asmul.obj bitfield.obj ctype_.obj getsp.obj strchr.obj inout.obj\r\nLIBC_ALL += peekpoke.obj iregset.obj isalpha.obj isdigit.obj\r\nLIBC_ALL += islower.obj isspace.obj isupper.obj ladd.obj land.obj linc.obj\r\nLIBC_ALL += llrsh.obj longjmp.obj lor.obj pnum.obj brelop.obj qsort.obj\r\nLIBC_ALL += strdup.obj malloc.obj strtok.obj wrelop.obj lrelop.obj frelop.obj\r\nLIBC_ALL += lsub.obj lxor.obj max.obj idiv.obj ldiv.obj swap.obj aslr.obj\r\nLIBC_ALL += bmove.obj imul.obj rand.obj alrsh.obj lmul.obj strrchr.obj sbrk.obj\r\nLIBC_ALL += shar.obj shll.obj shlr.obj strcat.obj strcmp.obj strcpy.obj\r\nLIBC_ALL += strlen.obj strncat.obj strncmp.obj strncpy.obj tolower.obj\r\nLIBC_ALL += toupper.obj xtoi.obj memmove.obj memchr.obj strstr.obj stristr.obj\r\nLIBC_ALL += strnstr.obj strnistr.obj msxtime.obj strnicmp.obj stricmp.obj\r\nLIBC_ALL += rcsv.obj csv.obj\r\n\r\n# object files that will be replaced\r\n#\r\nCOBJ = $(LC_C:.c=.obj) $(LF_C:.c=.obj) \r\nOBJC = $(LC_AS1:.as=.obj) $(LC_AS2:.as=.obj)\r\nLIBC_NEW = $(LC_C:.c=.obj) $(OBJC)\r\nLIBF_NEW = fbcd.obj $(LF_C:.c=.obj) \r\n\r\n# We keep the rest\r\n#\r\nTMP  = $(LIBC_ALL)\r\nTMP -= $(LIBC_NEW)\r\nLIBC_KEPT = $(TMP)\r\nTMP =\r\nTMP =\r\n\r\nupdate : libc.lib $(DIR)/libf.lib\r\n\r\nlibc.lib : $(LIBC_NEW)\r\n\tlibr <<EOF\r\n\tr libc.lib \\\\\r\n\t$(LC_C:.c=.obj) \\\\\r\n\t$(OBJC)\r\n\tEOF\r\n\r\nlibf.lib : $(LIBF_NEW)\r\n\tlibr r libf.lib $(LIBF_NEW)\r\n\r\nreorder : extract $(LIBC_NEW)\r\n\t:del $$tmp.lib\r\n\tlibr <<EOF\r\n\tr $$tmp.lib $(LIBC_ALL:.obj=.obj\\\\\\n)\r\n\tEOF\r\n\tcopy $$tmp.lib libc.lib\r\n\t:del $$tmp.lib\r\n\r\nextract :\r\n\tmake -v -f - <<EOF\r\n\tL = $(LIBC_KEPT:.obj=.obj\\\\\\nL += )\r\n\t..all : $$(L)\r\n\t% : L : LIBC.LIB\r\n\t\tlibr x libc.lib %\r\n\tEOF\r\n\t\r\n# Install the changes\r\n#\r\ninstall : $(DIR)/libc.lib $(DIR)/string.h $(DIR)/time.h $(DIR)/libf.lib\r\n\r\n$(DIR)/string.h : string.h\r\n\tcopy string.h $(DIR)\\\\*.*\r\n$(DIR)/time.h : time.h\r\n\tcopy time.h $(DIR)\\\\*.*\r\n$(DIR)/libc.lib : libc.lib\r\n\tcopy libc.lib $(DIR)\\\\*.*\r\n$(DIR)/libf.lib : libf.lib\r\n\tcopy libf.lib $(DIR)\\\\*.*\r\n\r\n# standard rules to make object files\r\n#\r\n%.obj  : OBJC : %.as\r\n\tzas -n -o%.obj %.as\r\n\r\n%.obj  : COBJ : %.c\r\n\tcc -c $(CFLAGS) -O%.obj %.c\r\n\r\n# clean up\r\n#\r\nclean :\r\n\tcopy $$m.t $$clean.bat <<EOF\r\n\tdel $(LIBC_KEPT:.obj=.obj\\ndel) >nul\r\n\tEOF\r\n\t:$$clean.bat\r\n\tdel $$clean.bat\r\n\r\ncleanmore :\r\n\tcopy $$m.t $$clean.bat <<EOF\r\n\tdel $(LIBC_NEW:.obj=.obj\\ndel) $(LF_C:.c=.obj)\r\n\tEOF\r\n\t:$$clean.bat\r\n\tdel $$clean.bat\r\n\r\nveryclean : clean cleanmore\r\n\r\n# make a package for distribution\r\n#\r\nEXTRA = fixes.txt makefile string.h time.h fbcd.obj libc.lib libf.lib\r\n\r\ndistribution : $(DIST)\r\n\r\n$(DIST) : $(EXTRA) $(SRC)\r\n\t:del pack.bat\r\n\tcopy $$m.t pack.bat <<EOF\r\n\tdel $(DIST)\r\n\tlhpack $(DIST) $(EXTRA) $(LF_C)\r\n\tlhpack $(DIST) $(LC_C)\r\n\tlhpack $(DIST) $(LC_AS1)\r\n\tlhpack $(DIST) $(LC_AS2)\r\n\tEOF\r\n\techo Lhpack cannot be run from make, please run pack.bat from the command line.\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MEMCHR.AS",
    "content": "; void * memchr (void * s, int c, size_t n)\r\n; added to HiTech's libc.lib by Arnold M\r\n\r\nglobal _memchr\r\n_memchr:\r\npop af\r\npop hl ; s\r\npop de ; c\r\npop bc ; n\r\npush bc\r\npush de\r\npush hl\r\npush af\r\n\r\nld a,c\r\nor b\r\njr z,none\r\nld a,e\r\ncpir\r\ndec hl\r\nret z\r\nnone:\r\nld hl,0\r\nret\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MEMCMP.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_memcmp, rcsv, cret\r\n; int memcmp(void * s1, void *s1, size_t n)\r\n; fast version using cpi by Arnold M\r\n\r\n_memcmp:\r\n\tcall\trcsv\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,3f\r\n1:\r\n\tld\ta,(de)\r\n\tcpi\t; cp (hl), inc hl, dec bc\r\n\tjr\tnz,2f\r\n\tinc\tde\r\n\tjp\tpe,1b\r\n3:\r\n\tld\thl,0\r\n\tjp\tcret\r\n2:\r\n\tdec\thl\t; undo cpi\r\n\tcp\t(hl)\t; get carry\r\n\tld\thl,1\r\n\tjp\tc,cret\r\n\tdec\thl\r\n\tdec\thl\r\n\tjp\tcret\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MEMCPY.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_memcpy, rcsv, cret\r\n; int memcpy(void * s1, void *s1, size_t n)\r\n; fast version using ldir by Arnold M\r\n\r\n_memcpy:\r\n\tcall\trcsv\r\n\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,1f\r\n\tpush\thl\r\n\tex\tde,hl\r\n\tldir\r\n\tpop\thl\r\n1:\r\n\tjp\tcret\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MEMMOVE.AS",
    "content": "\tpsect\ttext\r\n\tglobal\t_memmove, rcsv, cret\r\n\r\n; void * memmove ( void * dest, void * src, size_t n ) \r\n; memcpy variant that handles overlapping blocks properly\r\n; added to HiTech's libc.lib by Arnold M\r\n\r\n_memmove:\r\n\tcall\trcsv\r\n; dest in HL, src in DE, n in BC\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,1f\r\n\tsbc\thl,de\r\n\tadd\thl,de\r\n\tjr\tc,2f\r\n; dest >= src, copy backward \r\n\tdec\tbc\r\n\tadd\thl,bc\r\n\tex\tde,hl\r\n\tadd\thl,bc\r\n\tinc\tbc\r\n\tlddr\r\n\tinc\tde\r\n\tex\tde,hl\r\n1:\r\n\tjp\tcret\r\n2:\t\r\n; dest < src, copy forward\r\n\tpush\thl\r\n\tex\tde,hl\r\n\tldir\r\n\tpop\thl\r\n1:\r\n\tjp\tcret\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MEMSET.AS",
    "content": "; memset.as\r\n\r\nglobal _memset, csv, cret\r\n\r\n; void * memset (void *s, int c, size_t n)\r\n; fast version with standard argument order by Arnold M\r\n\r\npsect\ttext \r\n_memset:\r\n\tcall\tcsv\r\n\tld\tl,(ix+6)\r\n\tld\th,(ix+7)\r\n\tld\tc,(ix+10)\r\n\tld\tb,(ix+11)\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,1f\r\n\tld\te,(ix+8)\r\n\tld\t(hl),e\r\n\tdec\tbc\r\n\tld\ta,c\r\n\tor\tb\r\n\tjr\tz,1f\r\n\tpush\thl\r\n\tld\te,l\r\n\tld\td,h\r\n\tinc\tde\r\n\tldir\r\n\tpop\thl\r\n1:\r\n\tjp\tcret\r\n\t\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/MSXTIME.AS",
    "content": "; time_t msxtime();\r\n; used by time(), timerset() and timeup() functions\r\n; Public domain by Pierre Gielen.\r\n\r\n\tpsect text\r\n\tglobal _msxtime\r\n\r\n_msxtime:\r\n\tpush\tix\r\n\tpush\tiy\r\n\tld\tc,02ah\t\t; get date\r\n\tcall\t5\r\n\r\n\tld\tbc,-1970\t; unix offset\r\n\tadd\thl,bc\t\t; hl=jaren sinds 1970, d=maanden, e=dag\r\n\tpush\tde\t\t; bewaar e=dag, d=maand\r\n\tld\ta,l\r\n\tadd\ta,70\t\t; *** LEAPYEAR BUGFIX ***\r\n\tpush\taf\t\t; bewaar jaar\r\n\tld\tc,d\t\t; c=maand\r\n\tld\tb,l\t\t; b jaren sinds 1970\r\n\tld\thl,0\t\t; vanaf 0\r\n\tld\ta,1\t\t; modulo 4 teller\r\n\tld\tde,365\t\t; dagen per jaar\r\n1:\tadd\thl,de\t\t; tel 1 jaar in dagen er bij op\r\n\tinc\ta\t\t; verhoog modulo 4 teller\r\n\tand\t3\t\t; elke 4 jaar\r\n\tjr\tnz,2f\t\t; nee\r\n\tinc\thl\t\t; ja, 1 dag extra voor schrikkeljaar\r\n2:\tdjnz\t1b\t\t; en dat b keer achter elkaar\r\n\r\n; hl bevat nu het aantal dagen in de jaren sinds 1970\r\n\r\n\tpop\taf\t\t; het huidige jaar\r\n\tand\t3\t\t; is dit een schrikkeljaar?\r\n\tjr\tnz,3f\t\t; nee\r\n\tld\ta,c\t\t; ja, dan pak maand\r\n\tcp\t3\t\t; als februari voorbij is\r\n\tjr\tc,3f\t\t; nog niet\r\n\tinc\thl\t\t; wel, dan 1 extra voor 29 februari\r\n;\r\n3:\tld\tb,c\t\t; maand in b\r\n\tld\tde,17f\t\t; tabel met aantal dagen per maand\r\n\tjr\t5f\t\t; bereken dagen\r\n;\r\n4:\tcall\t7f\t\t; tel aantal dagen in deze maand bij totaal\r\n\tinc\tde\t\t; verhoog maandentabel-pointer\r\n5:\tdjnz\t4b\t\t; volgende (voor b maanden)\r\n\r\n\tpop\tde\t\t; de dag staat nog in e\r\n\tld\ta,e\r\n\tdec\ta\t\t; offset 0 (niet 1)\r\n\tcall\t6f\t\t; tel op bij totaal\r\n\tjr\t8f\t\t; klaar\r\n\r\n7:\tld\ta,(de)\t\t; add day of current month\r\n6:\tadd\ta,l\r\n\tld\tl,a\r\n\tret\tnc\r\n\tinc\th\r\n\tret\r\n\r\n8:\tcall\t9f\r\n\tld\t(95f),hl      ; zet totaal in long1 buffer\r\n\tld\thl,0\r\n\tld\t(95f+2),hl\r\n\tinc\thl\r\n\tld\t(96f+2),hl\r\n\tld\thl,05180h\r\n\tld\t(96f),hl      ; zet 15180h (=seconden per dag) in LONG2\r\n\tcall\t10f\t      ; long1 = long1 * long2\r\n\tcall\t11f\t      ; long3 = long1\r\n\r\n\tld\tc,02ch\t\t; get time\r\n\tcall\t5\r\n\r\n\tpush\tde\t\t; bewaar d=seconden\r\n\tpush\thl\t\t; bewaar h=uren, l=minuten\r\n\r\n\tcall\t9f\r\n\tld\tl,h\t\t; hl=uren\r\n\tld\th,0\r\n\tld\t(95f),hl\r\n\tld\thl,3600\r\n\tld\t(96f),hl\r\n\tcall\t10f\r\n\tld\thl,(95f)\r\n\tld\t(96f),hl\r\n\tld\thl,(95f+2)\r\n\tld\t(96f+2),hl    ; verplaats long 1 naar long2\r\n\tcall\t12f\t      ; haal jaren in seconden\r\n\tcall\t13f\t      ; long1=long1+long2\r\n\r\n\tld\thl,0\t\t; offset 0\r\n\tpop\tde\t\t; haal e=minuten (was l)\r\n\tld\ta,e\r\n\tor\ta\t\t; 0?\r\n\tjr\tz,15f\t\t; dan hebben we dit niet nodig\r\n\tld\td,0\r\n\tld\tb,60\t\t; seconden per minuut\r\n16:\r\n\tadd\thl,de\r\n\tdjnz\t16b\t\t; tel minuten in seconden op in hl\r\n\r\n15:\tld\t(96f),hl\t; in long2 (long1 nog ok)\r\n\tld\thl,0\r\n\tld\t(96f+2),hl\r\n\tcall\t13f\t\t; tel minuten op\r\n\r\n\tpop\thl\t\t; haal h=seconden (was d)\r\n\tld\tl,h\t\t; in l\r\n\tld\th,0\r\n\tld\t(96f),hl\r\n\tld\thl,0\r\n\tld\t(96f+2),hl\r\n\tcall\t13f\t\t; tel seconden op\r\n\r\n\tld\tde,(95f)\r\n\tld\thl,(95f+2)    ; resultaat nu in hlde, zoals Hitech wenst\r\n\tpop\tiy\r\n\tpop\tix\r\n\tret\r\n\r\n\r\n\tpsect data\r\n\r\n; tabel met aantal dagen per maand (geen schrikkeljaar)\r\n\r\n17:\tdefb\t31,28,31,30,31,30,31,31,30,31,30,31\r\n\r\n\tpsect text\r\n\r\n11:\tpush\thl\r\n\tld\thl,(95f)\r\n\tld\t(97f),hl\r\n\tld\thl,(95f+2)\r\n\tld\t(97f+2),hl\r\n\tpop\thl\r\n\tret\r\n\r\n12:\tpush\thl\r\n\tld\thl,(97f)\r\n\tld\t(95f),hl\r\n\tld\thl,(97f+2)\r\n\tld\t(95f+2),hl\r\n\tpop\thl\r\n\tret\r\n\r\n9:\tpush\thl\r\n\tld\thl,0\r\n\tld\t(95f),hl\r\n\tld\t(95f+2),hl\r\n\tld\t(96f),hl\r\n\tld\t(96f+2),hl\r\n\tpop\thl\r\n\tret\r\n\r\n10:\tld\thl,95f\r\n\tld\tde,96f\r\n\tld\ta,4\r\n\tld\tc,4\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tex\tde,hl\r\n\tld\t(93f),hl\r\n\tld\thl,94f\r\n\tadd\thl,bc\r\n\tld\t(92f),hl\r\n\tld\tl,c\r\n\tld\th,b\r\n\tadd\thl,hl\r\n\tadd\thl,hl\r\n\tadd\thl,hl\r\n\tinc\thl\r\n\tld\t(91f),hl\r\n\r\n\tld\tb,c\r\n\tld\thl,94f\r\n\r\n18:\tld\t(hl),0\r\n\tinc\thl\r\n\tdjnz\t18b\r\n\r\n\tand\ta\r\n19:\tld\tb,c\r\n\tld\thl,(92f)\r\n\r\n20:\tdec\thl\r\n\trr\t(hl)\r\n\tdjnz\t20b\r\n\r\n\tld\tl,e\r\n\tld\th,d\r\n\tld\tb,c\r\n\r\n21:\tdec\thl\r\n\trr\t(hl)\r\n\tdjnz\t21b\r\n\r\n\tjp\tnc,22f\r\n\r\n\tpush\tde\r\n\tld\tde,(93f)\r\n\tld\thl,94f\r\n\tld\tb,c\r\n\tand\ta\r\n\r\n23:\tld\ta,(de)\r\n\tadc\ta,(hl)\r\n\tld\t(hl),a\r\n\tinc\tde\r\n\tinc\thl\r\n\tdjnz\t23b\r\n\tpop\tde\r\n\r\n22:\tld\ta,(91f)\r\n\tdec\ta\r\n\tld\t(91f),a\r\n\tjp\tnz,19b\r\n\tpush\taf\r\n\tld\ta,(91f+1)\r\n\tand\ta\r\n\tjp\tz,24f\r\n\tdec\ta\r\n\tld\t(91f+1),a\r\n\tpop\taf\r\n\tjp\t19b\r\n\r\n24:\tpop\taf\r\n\tret\r\n\r\n13:\tld\thl,95f\r\n\tld\tde,96f\r\n\tld\tb,4\t\t; lengte\r\n14:\tld\ta,(de)\r\n\tadc\ta,(hl)\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\t14b\r\n\tret\r\n\r\n\tpsect data\r\n\r\n91:\tdefs\t2\t\t; teller\r\n92:\tdefs\t2\r\n93:\tdefs\t2\r\n94:\tdefs\t8\r\n95:\tdefs\t4\t\t; buffers voor longints\r\n96:\tdefs\t4\r\n97:\tdefs\t4\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/PEEKPOKE.AS",
    "content": "; These routines were previously in inout.as, I've put them in a \r\n; separate file because they can be easiliy rewritten, so they need not\r\n; take up space in a .com file - Arnold M\r\n \r\n\tglobal _peek, _poke\r\n\tpsect\ttext\r\n\r\n; void poke(word address, byte value)\r\n\r\n_poke:\r\n        pop     hl              ;return address\r\n        pop     de              ;address\r\n        pop     bc              ;value\r\n        push    bc\r\n        push    de\r\n\tld\ta,c\r\n        ld      (de),a\r\n\tjp\t(hl)\r\n\r\n; byte peek(word address)\r\n\r\n_peek:\r\n        pop     de              ;return address\r\n        pop     hl              ;peek address\r\n        push    hl\r\n        push    de\r\n        ld      l,(hl)\r\n        ld      h,0\r\n        ret\r\n\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/RCSV.AS",
    "content": "; rcsv, save old iy,ix and get three arguments in hl,de,bc\r\n; return with new framepointer in ix.\r\n; save 2 bytes and 34 T-states compared to HiTech's version - Arnold M.\r\n\r\n\tglobal\trcsv\r\n\t\r\nARG\tequ\t6\t\t;offset of 1st arg\r\n\tmacro\tldrd reg\r\n\tld\treg,(hl)\r\n\tdec\thl\r\n\tendm\r\n\tpsect\ttext\r\nrcsv:\r\n\tex\t(sp),iy\t\t;save iy, get return address\r\n\tpush\tix\r\n\tld\tix,0\r\n\tadd\tix,sp\t\t;new frame pointer\r\n\tld\thl,ARG+5\r\n\tadd\thl,sp\t\t;top of args \r\n\tldrd\tb\r\n\tldrd\tc\r\n\tldrd\td\r\n\tldrd\te\r\n\tld\th,(hl)\r\n\tld\tl,(ix+ARG+0)\r\n\tjp\t(iy)\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/SIGNAL.AS",
    "content": "; SIGNAL.C, manually modified for MSXDOS-2\r\n;\r\n;static void (*  where)();\r\n;\r\n;void (*signal(sig, action))()\r\n;int\t sig;\r\n;void (* action)(int);\r\n;{\r\n;\t void (* prev)();\r\n;\r\n;\t if(sig != SIGINT)\r\n;\t\t return (void (*)())-1;\r\n;\t prev = where;\r\n;\t where = action;\r\n;\t return prev;\r\n;}\r\n\r\nglobal\t_signal\r\nglobal\tcsv,cret\r\npsect\ttext\r\n_signal:\r\ncall csv\r\npush hl\r\nld\tde,1\r\nld\tl,(ix+6)\r\nld\th,(ix+7)\r\nor\ta\r\nsbc\thl,de\r\njr\tz,1f\r\nld\thl,-1\r\njp\tcret\r\n1:\r\nld\thl,(_where)\r\nex\tde,hl\t\t; de = previous\r\nld\tl,(ix+8)\r\nld\th,(ix+9)\t; new _where\r\nld\t(_where),hl\r\nex\tde,hl\t\t; return previous\r\njp\tcret\r\n\r\n\r\n;void _sigchk()\r\n;{\r\n;\t char\t c;\r\n;\r\n;\t if (where == SIG_IGN)\r\n;\t    return;\r\n;\t if (bdos(CONSTAT) != 0) {\r\n;\t    c = bdos(CONIN);\r\n;\t    if (c != CPMRBT)\r\n;\t       return;\r\n;\t    if (where == SIG_DFL)\r\n;\t       exit(0);\r\n;\t    (*where)();\r\n;\t }\r\n;}\r\n\r\nglobal\t__sigchk,_exit,indir\r\n\r\n__sigchk:\r\nld\ta,(0fc9bh)\t; INTFLG\r\ncp\t3\t\t; if ctrl-stop pressed\r\njp\tz,1f\t\t; then ignore all bypasses\r\n\r\nld\thl,(0f3fah)\t; getpnt\r\nld\ta,(0f3f8h)\t; putpnt\r\ncp\tl\t\t; if not keypressed\r\nret\tz\t\t; then return\r\n\r\nld\tde,1\t\t; SIG_IGN\r\nld\thl,(_where)\t; if where == SIG_IGN\r\nor\ta\r\nsbc\thl,de\r\nret\tz\t\t; then return\r\n\r\npush\tix\r\npush\tiy\r\nld\tix,09fh\r\nld\tiy,(0fcc0h)\r\ncall\t01ch\t\t; _CHGET\r\npop\tiy\r\npop\tix\r\ncp\t3\t\t; if not CTRL-C\r\nret\tnz\t\t; then return\r\n\r\nld\thl,(_where)\t; else look where to go\r\nld\ta,l\r\nor\th\r\njr\tnz,2f\t\t; not goto 0 ?\r\n\r\n1:\r\nld\thl,0\r\npush\thl\r\ncall\t_exit\t\t; default to exit(0)\r\n\r\n2:\r\nld\thl,(_where)\r\ncall\tindir\r\nret\r\n\r\npsect\tbss\r\n_where:\r\ndefs\t2\r\n\r\nend\r\n\r\n\r\n"
  },
  {
    "path": "msx2dist/libfix01/SLEEP.C",
    "content": "/*\r\n * Sleep function for Hi-Tech C\r\n * PGN 12/93\r\n */\r\n\r\n#include <time.h>\r\n\r\nvoid sleep(seconds)\r\nunsigned int seconds;\r\n{\r\n\tlong t0;\r\n\tt0 = (long)time((long *)0)+seconds;\r\n\twhile (time((long *)0)<=t0);\t\t/* wait seconds */\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRCHR.AS",
    "content": "; strchr(char *s, int c)\r\n; version that can find the closing \\0 by Arnold M\r\n\r\n\tpsect\ttext\r\n\tglobal\trcsv, cret, _strchr, _index\r\n\r\n_strchr:\r\n_index:\r\n\tpop\tbc\r\n\tpop\thl\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\thl\r\n\tpush\tbc\r\n\r\n\tjr\t3f\r\n1:\r\n\tinc\thl\r\n3:\r\n\tld\ta,(hl)\r\n\tcp\te ; check for a match first, e may be zero\r\n\tret\tz\r\n\r\n\tor\ta\r\n\tjr\tnz,1b\r\n\tld\thl,0\r\n\tret\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRDUP.C",
    "content": "#include <string.h>\r\nextern char *malloc();\r\n\r\nchar * strdup(char * str)\r\n{\r\n  char *dup;\r\n\r\n  if ( (dup = malloc(strlen(str)+1)) ) /* add one for the closing \\0 */\r\n    return strcpy(dup, str);\r\n  return (dup);\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRFTIME.C",
    "content": "/**\r\n *\r\n * strftime.c\r\n *\r\n * implements the ansi c function strftime()\r\n *\r\n * written 6 september 1989 by jim nutt\r\n * released into the public domain by jim nutt\r\n *\r\n * modified 21-Oct-89 by Rob Duff\r\n *\r\n**/\r\n\r\n#ifndef TZNAME\r\n#define TZNAME \"CET\"    /* my timezone (PGN) */\r\n#endif\r\n\r\n#include <stddef.h>     /* for size_t */\r\n#include <stdarg.h>     /* for va_arg */\r\n#include <time.h>       /* for struct tm */\r\n\r\n/*\r\n** The following line should be appended to TIME.H.\r\n** Also copy size_t define from STRING.H.\r\n*/\r\n/* \r\nextern size_t strftime(char *s, size_t maxs, char *f, struct tm *t);\r\n*/\r\n\r\nstatic char *aday[] = {\r\n    \"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"\r\n};\r\n\r\nstatic char *day[] = {\r\n    \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\",\r\n    \"Thursday\", \"Friday\", \"Saturday\"\r\n};\r\n\r\nstatic char *amonth[] = {\r\n    \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\r\n    \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"\r\n};\r\n\r\nstatic char *month[] = {\r\n    \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\r\n    \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"\r\n};\r\n\r\nstatic char buf[26];\r\n\r\nstatic void strfmt(char *str, char *fmt, ...);\r\n\r\n/**\r\n *\r\n * size_t strftime(char *str,\r\n *                 size_t maxs,\r\n *                 const char *fmt,\r\n *                 const struct tm *t)\r\n *\r\n *      this functions acts much like a sprintf for time/date output.\r\n *      given a pointer to an output buffer, a format string and a\r\n *      time, it copies the time to the output buffer formatted in\r\n *      accordance with the format string.  the parameters are used\r\n *      as follows:\r\n *\r\n *          str is a pointer to the output buffer, there should\r\n *          be at least maxs characters available at the address\r\n *          pointed to by str.\r\n *\r\n *          maxs is the maximum number of characters to be copied\r\n *          into the output buffer, included the '\\0' terminator\r\n *\r\n *          fmt is the format string.  a percent sign (%) is used\r\n *          to indicate that the following character is a special\r\n *          format character.  the following are valid format\r\n *          characters:\r\n *\r\n *              %A      full weekday name (Monday)\r\n *              %a      abbreviated weekday name (Mon)\r\n *              %B      full month name (January)\r\n *              %b      abbreviated month name (Jan)\r\n *              %c      standard date and time representation\r\n *              %d      day-of-month (01-31)\r\n *              %H      hour (24 hour clock) (00-23)\r\n *              %I      hour (12 hour clock) (01-12)\r\n *              %j      day-of-year (001-366)\r\n *              %M      minute (00-59)\r\n *              %m      month (01-12)\r\n *              %p      local equivalent of AM or PM\r\n *              %S      second (00-59)\r\n *              %U      week-of-year, first day sunday (00-53)\r\n *              %W      week-of-year, first day monday (00-53)\r\n *              %w      weekday (0-6, sunday is 0)\r\n *              %X      standard time representation\r\n *              %x      standard date representation\r\n *              %Y      year with century\r\n *              %y      year without century (00-99)\r\n *              %Z      timezone name\r\n *              %%      percent sign\r\n *\r\n *      the standard date string is equivalent to:\r\n *\r\n *          %a %b %d %Y\r\n *\r\n *      the standard time string is equivalent to:\r\n *\r\n *          %H:%M:%S\r\n *\r\n *      the standard date and time string is equivalent to:\r\n *\r\n *          %a %b %d %H:%M:%S %Y\r\n *\r\n *      strftime returns the number of characters placed in the\r\n *      buffer, not including the terminating \\0, or zero if more\r\n *      than maxs characters were produced.\r\n *\r\n**/\r\n\r\nsize_t strftime(char *s, size_t maxs, char *f, struct tm *t)\r\n{\r\n      int w;\r\n      char *p, *q, *r;\r\n\r\n      p = s;\r\n      q = s + maxs - 1;\r\n      while ((*f != '\\0'))\r\n      {\r\n            if (*f++ == '%')\r\n            {\r\n                  r = buf;\r\n                  switch (*f++)\r\n                  {\r\n                  case '%' :\r\n                        r = \"%\";\r\n                        break;\r\n\r\n                  case 'a' :\r\n                        r = aday[t->tm_wday];\r\n                        break;\r\n\r\n                  case 'A' :\r\n                        r = day[t->tm_wday];\r\n                        break;\r\n\r\n                  case 'b' :\r\n                        r = amonth[t->tm_mon];\r\n                        break;\r\n\r\n                  case 'B' :\r\n                        r = month[t->tm_mon];\r\n                        break;\r\n\r\n                  case 'c' :\r\n                        strfmt(r, \"%0 %0 %2 %2:%2:%2 %4\",\r\n                              aday[t->tm_wday], amonth[t->tm_mon],\r\n                              t->tm_mday,t->tm_hour, t->tm_min,\r\n                              t->tm_sec, t->tm_year+1900);\r\n                        break;\r\n\r\n                  case 'd' :\r\n                        strfmt(r,\"%2\",t->tm_mday);\r\n                        break;\r\n\r\n                  case 'H' :\r\n                        strfmt(r,\"%2\",t->tm_hour);\r\n                        break;\r\n\r\n                  case 'I' :\r\n                        strfmt(r,\"%2\",(t->tm_hour%12)?t->tm_hour%12:12);\r\n                        break;\r\n\r\n                  case 'j' :\r\n                        strfmt(r,\"%3\",t->tm_yday+1);\r\n                        break;\r\n\r\n                  case 'm' :\r\n                        strfmt(r,\"%2\",t->tm_mon+1);\r\n                        break;\r\n\r\n                  case 'M' :\r\n                        strfmt(r,\"%2\",t->tm_min);\r\n                        break;\r\n\r\n                  case 'p' :\r\n                        r = (t->tm_hour>11)?\"PM\":\"AM\";\r\n                        break;\r\n\r\n                  case 'S' :\r\n                        strfmt(r,\"%2\",t->tm_sec);\r\n                        break;\r\n\r\n                  case 'U' :\r\n                        w = t->tm_yday/7;\r\n                        if (t->tm_yday%7 > t->tm_wday)\r\n                              w++;\r\n                        strfmt(r, \"%2\", w);\r\n                        break;\r\n\r\n                  case 'W' :\r\n                        w = t->tm_yday/7;\r\n                        if (t->tm_yday%7 > (t->tm_wday+6)%7)\r\n                              w++;\r\n                        strfmt(r, \"%2\", w);\r\n                        break;\r\n\r\n                  case 'w' :\r\n                        strfmt(r,\"%1\",t->tm_wday);\r\n                        break;\r\n\r\n                  case 'x' :\r\n                        strfmt(r, \"%3s %3s %2 %4\", aday[t->tm_wday],\r\n                              amonth[t->tm_mon], t->tm_mday, t->tm_year+1900);\r\n                        break;\r\n\r\n                  case 'X' :\r\n                        strfmt(r, \"%2:%2:%2\", t->tm_hour,\r\n                              t->tm_min, t->tm_sec);\r\n                        break;\r\n\r\n                  case 'y' :\r\n                        strfmt(r,\"%2\",t->tm_year%100);\r\n                        break;\r\n\r\n                  case 'Y' :\r\n                        strfmt(r,\"%4\",t->tm_year+1900);\r\n                        break;\r\n\r\n                  case 'Z' :\r\n\t\t\tr = TZNAME;\r\n                        break;\r\n\r\n                  default:\r\n                        buf[0] = '%';     /* reconstruct the format */\r\n                        buf[1] = f[-1];\r\n                        buf[2] = '\\0';\r\n                        if (buf[1] == 0)\r\n                              f--;        /* back up if at end of string */\r\n                  }\r\n                  while (*r)\r\n                  {\r\n                        if (p == q)\r\n                        {\r\n                              *q = '\\0';\r\n                              return 0;\r\n                        }\r\n                        *p++ = *r++;\r\n                  }\r\n            }\r\n            else\r\n            {\r\n                  if (p == q)\r\n                  {\r\n                        *q = '\\0';\r\n                        return 0;\r\n                  }\r\n                  *p++ = f[-1];\r\n            }\r\n      }\r\n      *p = '\\0';\r\n      return p - s;\r\n}\r\n\r\n/*\r\n *  stdarg.h\r\n *\r\ntypedef void *va_list;\r\n#define va_start(vp,v) (vp=((char*)&v)+sizeof(v))\r\n#define va_arg(vp,t) (*((t*)(vp))++)\r\n#define va_end(vp)\r\n *\r\n */\r\n\r\nstatic int pow[5] = { 1, 10, 100, 1000, 10000 };\r\n\r\n/**\r\n * static void strfmt(char *str, char *fmt);\r\n *\r\n * simple sprintf for strftime\r\n *\r\n * each format descriptor is of the form %n\r\n * where n goes from zero to four\r\n *\r\n * 0    -- string %s\r\n * 1..4 -- int %?.?d\r\n *\r\n**/\r\n\r\nstatic void strfmt(char *str, char *fmt, ...)\r\n{\r\n      int ival, ilen;\r\n      char *sval;\r\n      va_list vp;\r\n\r\n      va_start(vp, fmt);\r\n      while (*fmt)\r\n      {\r\n            if (*fmt++ == '%')\r\n            {\r\n                  ilen = *fmt++ - '0';\r\n                  if (ilen == 0)                /* zero means string arg */\r\n                  {\r\n                        sval = va_arg(vp, char*);\r\n                        while (*sval)\r\n                              *str++ = *sval++;\r\n                  }\r\n                  else                          /* always leading zeros */\r\n                  {\r\n                        ival = va_arg(vp, int);\r\n                        while (ilen)\r\n                        {\r\n                              ival %= pow[ilen--];\r\n                              *str++ = '0' + ival / pow[ilen];\r\n                        }\r\n                  }\r\n            }\r\n            else  *str++ = fmt[-1];\r\n      }\r\n      *str = '\\0';\r\n      va_end(vp);\r\n}\r\n\r\n#ifdef TEST\r\n\r\n#include <stdio.h>      /* for printf */\r\n#include <time.h>       /* for strftime */\r\n\r\nchar test[80];\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n      int len;\r\n      char *fmt;\r\n      time_t now;\r\n\r\n      time(&now);\r\n\r\n      fmt = (argc == 1) ? \"%I:%M %p\\n%c\\n\" : argv[1];\r\n      len = strftime(test,sizeof test, fmt, localtime(&now));\r\n      printf(\"%d: %s\\n\", len, test);\r\n      return !len;\r\n}\r\n\r\n#endif /* TEST */\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRICMP.AS",
    "content": "; int strcasecmp(const char *s1, const char *s2)\r\n; return a value less than 0, 0 or greater than 0 if s1 is found, respectively, \r\n;   to be less than equal or greater than s2 ignoring case\r\n; by Arnold M\r\n\r\npsect text\r\n\r\nmacro tolower\r\n  cp 'A'\r\n  jr c, 10f\r\n  cp 'Z'+1\r\n  jr nc, 10f\r\n  add  a, 'a'-'A'\r\n10: \r\nendm\r\n\r\nglobal _strcasecmp\r\n_strcasecmp:\r\n\r\npop bc\r\npop hl ; s1\r\npop de ; s2\r\npush de\r\npush hl\r\npush bc\r\n\r\n1:\r\nld a,(de) ;*s2\r\ntolower\r\nld c,a\r\nld a,(hl) ;*s1 \r\ntolower\r\ncp c\r\njr nz,2f\r\ninc hl\r\ninc de\r\nor a\r\njp nz,1b\r\nld h,a\r\nld l,a\r\nret\r\n\r\n2:\r\nsbc hl,hl\r\nret c\r\ninc hl\r\nret\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRING.H",
    "content": "/*\tString functions */\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#ifndef\tNULL\r\n#define\tNULL\t((void *)0)\r\n#endif\tNULL\r\n\r\nextern int\terrno;\t\t\t/* system error number */\r\n\r\nextern void *\tmemcpy(void *, void *, size_t);\r\nextern void *\tmemmove(void *, void *, size_t);\r\nextern void *\tmemset(void *, int, size_t);\r\nextern char *\tstrcat(char *, char *);\r\nextern char *\tstrncat(char *, char *, size_t);\r\nextern char *\tstrcpy(char *, char *);\r\nextern char *\tstrncpy(char *, char *, size_t);\r\nextern char *\tstrdup(char *);\r\nextern int\tmemcmp(void *, void *, size_t);\r\nextern int\tstrcmp(char *, char *);\r\nextern int\tstrncmp(char *, char *, size_t);\r\nextern int\tstrcasecmp(char *, char *);\r\nextern int\tstrncasecmp(char *, char *, size_t);\r\nextern void *\tmemchr(void *, int, size_t);\r\nextern size_t\tstrlen(char *);\r\nextern char *\tstrchr(char *, int);\r\nextern char *\tindex(char *, int);\r\nextern char *\tstrrchr(char *, int);\r\nextern char *\trindex(char *, int);\r\nextern char *\tstrstr(char*, char*);\r\nextern char *\tstrcasestr(char*, char*);\r\nextern char *\tstrnstr(char*, char*, size_t);\r\nextern char *\tstrncasestr(char*, char*, size_t);\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRISTR.C",
    "content": "/*\r\n * char * strcasestr (char *t, char *s) \r\n * \r\n * Find string s in string t, disregarding the case of letters.\r\n *\r\n * Return \r\n *    -\tThe smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\n#include <ctype.h>\r\n\r\nchar * strcasestr (char *t, char *s) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n\r\n   do \r\n     {\r\n       t1 = t;\r\n       s1 = s;\r\n       while(*s1) {\r\n         if (toupper(*s1) != toupper(*(t1++))) \r\n\t    break;\r\n\t else\r\n\t    ++s1;\r\n       }\r\n       if (!*s1) return t;\r\n     } \r\n   while (*(t++));\r\n\r\n   return (char *) 0;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRNICMP.AS",
    "content": "; int strncasecmp(const char *s1, const char *s2, size_t n)\r\n; return a value less than 0, 0 or greater than 0 if s1 is found, respectively, \r\n;   to be less than equal or greater than s2 ignoring case\r\n; by Arnold M\r\n\r\npsect text\r\n\r\nmacro tolower\r\n  cp 'A'\r\n  jr c, 10f\r\n  cp 'Z'+1\r\n  jr nc, 10f\r\n  add  a, 'a'-'A'\r\n10: \r\nendm\r\n\r\nglobal _strncasecmp, rcsv, cret\r\n\r\n_strncasecmp:\r\n call rcsv ; hl=s1, de=s2, bc=n\r\n ld b,c ; keep low part of n in reg b,  reg c is used as scratch\r\n ld a,b\r\n or a\r\n jr z,bzero\r\nloop:\r\n ld a,(de) ;*s2\r\n tolower\r\n ld c,a\r\n ld a,(hl) ;*s1 \r\n tolower\r\n cp c\r\n jr nz,diff\r\n or a\r\n jr z, equal\r\n inc hl\r\n inc de\r\n djnz loop\r\nbzero:\r\n dec (ix+6+5) ; n / 0x100\r\n jp p,loop ; dec m does not affect the carry flag\r\n ld a,(ix+6+5)\r\n inc a\r\n jr nz,loop\r\n\r\nequal:\r\n ld h,a\r\n ld l,a\r\n jp cret\r\n\r\ndiff:\r\n sbc hl,hl\r\n jp c,cret\r\n inc hl\r\n jp cret\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRNISTR.C",
    "content": "/*\r\n * char * strncasestr (char *t, char *s, unsigned int n) \r\n * \r\n * Find string s in string t, disregarding the case of letters.\r\n * At most n characters from t are used. \r\n *\r\n * Returns \r\n *    -\tA smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p and strictly before t+n, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\n#include <ctype.h>\r\n\r\nchar * strncasestr (char *t, char *s, unsigned int n) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n   unsigned int n1;\r\n\r\n   if (!*s) return t;\r\n   while (*t && n) {\r\n       t1 = t;\r\n       n1 = n;\r\n       s1 = s;\r\n       while (*s1) {\r\n           if (toupper(*s1) != toupper(*(t1++))) break;\r\n           else {\r\n               ++s1;\r\n               if (!--n1) break;\r\n           }\r\n       }\r\n       if (!*s1) return t;\r\n       --n;\r\n       ++t;\r\n     }\r\n   return (char *) 0;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRNSTR.C",
    "content": "/*\r\n * char * strnstr (char *t, char *s, unsigned int n) \r\n * \r\n * Find string s in string t, using at most n characters from t. \r\n *\r\n * Returns \r\n *    -\tA smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p and strictly before t+n, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\nchar * strnstr (char *t, char *s, unsigned int n) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n   unsigned int n1;\r\n\r\n   if (!*s) return t;\r\n   while (*t && n) {\r\n       t1 = t;\r\n       n1 = n;\r\n       s1 = s;\r\n       while (*s1) {\r\n           if (*s1 != *(t1++)) break;\r\n           else {\r\n               ++s1;\r\n               if (!--n1) break;\r\n           }\r\n       }\r\n       if (!*s1) return t;\r\n       --n;\r\n       ++t;\r\n     }\r\n   return (char *) 0;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRRCHR.AS",
    "content": "; strrchr(char *s, int c)\r\n; version that can find the closing \\0 by Arnold M\r\n\r\n\tpsect\ttext\r\n\tglobal\trcsv, cret, _strrchr, _rindex\r\n\r\n_strrchr:\r\n_rindex:\r\n\tpop\tbc\r\n\tpop\thl\r\n\tpop\tde\r\n\tpush\tde\r\n\tpush\thl\r\n\tpush\tbc\r\n\r\n\tld\tbc,1 ; the closing nul is considered part of the string here\r\n\tjr\t5f\r\n6:\r\n\tinc\thl\r\n\tinc\tbc\r\n5:\r\n\tld\ta,(hl)\r\n\tor\ta\r\n\tjr\tnz,6b\r\n1:\r\n\tld \ta,e\r\n\tcpdr\r\n\tinc\thl\r\n\tret\tz\r\n\tld\tl,c\r\n\tld\th,b\r\n\tret\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRSTR.C",
    "content": "/*\r\n * char * strstr (char *t, char *s) \r\n * \r\n * Find string s in string t.\r\n *\r\n * Return \r\n *    -\tThe smallest pointer p between t and t+strlen(t) inclusive, such that\r\n *\tthe characters from s upto but not including the first NUL character \r\n *\tcan be found starting from p, or\r\n *    -\tNULL if there is no such pointer.\r\n */\r\nchar * strstr (char *t, char *s) \r\n{\r\n   char *t1;\r\n   char *s1;\r\n\r\n   do \r\n     {\r\n       t1 = t;\r\n       s1 = s;\r\n       while(*s1) {\r\n         if (*s1 != *(t1++)) \r\n\t    break;\r\n\t else\r\n\t    ++s1;\r\n       }\r\n       if (!*s1) return t;\r\n     } \r\n   while (*(t++));\r\n\r\n   return (char *) 0;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/STRTOK.C",
    "content": "/*\r\n**  strtok() -- public domain by Ray Gardner, modified by Bob Stout\r\n**              not modified for Hi-Tech C by Pierre Gielen :-)\r\n**              comment corrected by Arnold Metselaar\r\n**\r\n**   You pass this function a string to parse, a buffer to receive the\r\n**   \"token\" that gets scanned, the length of the buffer, and a string of\r\n**   \"break\" characters that stop the scan.  It will copy the string into\r\n**   the buffer up to any of the break characters, or until the buffer is\r\n**   full, and will always leave the buffer null-terminated.  It will\r\n**   return a pointer to the first character from s that was not copied to\r\n**   tok.\r\n*/\r\n\r\n#include <stddef.h>\r\n\r\nchar *strtok(char *s, char *tok, size_t toklen, char *brk)\r\n{\r\n      char *lim, *b;\r\n\r\n      if (!*s)\r\n            return NULL;\r\n\r\n      lim = tok + toklen - 1;\r\n      while (*s && (tok<lim))\r\n      {\r\n            for (b=brk;*b;b++)\r\n            {\r\n                  if (*s==*b)\r\n                  {\r\n                        *tok=0;\r\n                        return(s);\r\n                  }\r\n            }\r\n            *tok++ = *s++;\r\n      }\r\n      *tok = 0;\r\n      return(s);\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/TIME.C",
    "content": "/*\r\n * MSX system-dependant time(), timerset() and timeup() functions\r\n * for Hi-Tech C 3.10.\r\n * time() returns (long)time in UNIX format: seconds since 00:00:00,\r\n * 1/1/1970. Bug fixed for leap year test, 6/94.\r\n * timerset() returns a (long) timervalue.\r\n * timeup() checks if time for that value is up (only 1 second\r\n * resolution, use mtimerset() and mtimeup() macros in time.h for\r\n * 100ms resolution.\r\n * Public domain by Pierre Gielen.\r\n * The function msxtime() is moved to msxtime.as by Arnold Metselaar 1/06.\r\n */\r\n\r\n#include\t<time.h>\r\n\r\n/* moved to msxtime.as: */\r\nextern time_t msxtime();\r\n\r\ntime_t\r\ntime(tp)\r\ntime_t *\ttp;\r\n{\r\n\ttime_t t;\r\n\tt = msxtime();\r\n\tif(tp)\r\n\t   *tp = t;\r\n\treturn t;\r\n}\r\n\r\ntime_t timerset(value)\r\nlong value;\r\n{\r\n\treturn (msxtime()+value);\r\n}\r\n\r\nint timeup(timer)\r\nlong timer;\r\n{\r\n\tif(msxtime() < timer)\r\n\t  return(0);\r\n\treturn(1);\r\n}\r\n\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/libfix01/TIME.H",
    "content": "/* time.h voor hitech-c\r\n * aanpassing 01/06\r\n */\r\n\r\n\r\n#ifndef _TIME\r\n\r\ntypedef\tlong\ttime_t;\t\t/* for representing times in seconds */\r\nstruct tm {\r\n\tint\ttm_sec;\r\n\tint\ttm_min;\r\n\tint\ttm_hour;\r\n\tint\ttm_mday;\r\n\tint\ttm_mon;\r\n\tint\ttm_year;\r\n\tint\ttm_wday;\r\n\tint\ttm_yday;\r\n\tint\ttm_isdst;\r\n};\r\n#define\t_TIME\r\n#endif\t_TIME\r\n\r\n#ifndef\t_STDDEF\r\ntypedef\tint\t\tptrdiff_t;\t/* result type of pointer difference */\r\ntypedef\tunsigned\tsize_t;\t\t/* type yielded by sizeof */\r\n#define\t_STDDEF\r\n#define\toffsetof(ty, mem)\t((int)&(((ty *)0)->mem))\r\n#endif\t_STDDEF\r\n\r\n#define CLK_TCK 50\t\t\t  /* for 50Hz interrupt frequency */\r\n#define JIFFY (*(unsigned short *)0xfc9e) /* clock tick counter */\r\n#define jtimerset(s) (JIFFY=(0-(s * 5)))   /* set timer in 100ms slices */\r\n#define jtimeup() (JIFFY==0)\r\n\r\nextern int\ttime_zone;\t/* minutes WESTWARD of Greenwich */\r\n\t\t\t\t/* this value defaults to 0 since with\r\n\t\t\t\t   operating systems like MS-DOS there is\r\n\t\t\t\t   no time zone information available */\r\nextern time_t time(time_t *); /* seconds since 00:00:00 Jan 1 1970 */\r\nextern char * asctime(struct tm *);   /* converts struct tm to ascii time */\r\nextern char * ctime();\t      /* current local time in ascii form */\r\nextern struct tm * gmtime();\t   /* Universal time */\r\nextern struct tm * localtime();    /* local time */\r\n\r\nextern time_t timerset(time_t);    /* set a timer in seconds */\r\nextern int timeup(time_t);\t   /* check if timer expired */\r\nextern size_t strftime(char *s, size_t maxs, char *f, struct tm *t);\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/FILE.C",
    "content": "#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n/*\r\n * The header file string.h should declare\r\n * extern int strcasecmp(char * s1, char * s2);\r\n * a function that is provided as part of the 'fixes for Hitech libraries'.\r\n */\r\n\r\n#include \"make.h\"\r\nextern int debug;\r\n\r\n/*\r\n * Return file-node for 'fname'.\r\n * If it doesn't exist or fname starts with %, then create one.\r\n */\r\nFILENODE *filenode(char *fname)\r\n{\r\n  FILENODE *f, *afnode(), *gfile();\r\n\r\n  if ( (f = gfile(fname)) == NULL )\r\n    f = afnode(fname);\r\n\r\n  return f;\r\n}\r\n\r\n/*\r\n * Add a dependency to the node 'fnd'.\r\n * 'fnd' will depend on 'fname'.\r\n */\r\naddfile(FILENODE *fnd, char *fname)\r\n{\r\n  NODE *n;\r\n  FILENODE *f;\r\n\r\n  if (fnd == NULL) {\t\t\t/* punt if no root file */\r\n    fprintf(stderr, \"No current root, can't add dependency '%s'\\n\", fname);\r\n    return;\r\n  }\r\n  f = filenode(fname);\r\n  n = (NODE *)xalloc(sizeof(NODE)); /* xalloc checks for out of mem. */\r\n  n->nnext = fnd->fnode;\r\n  fnd->fnode = n;\r\n  n->nfile = f;\r\n}\r\n\r\n\r\n/*\r\n * Add a line of method-text to the node 'fnode'.\r\n */\r\naddmeth(FILENODE *fnode, char *methtext)\r\n{\r\n  int len;\r\n  char * p;\r\n\r\n  if (fnode == NULL || methtext == NULL) return;\r\n\r\n  len = strlen(methtext) + 2;\r\n  if (fnode->fmake == NULL) {\r\n    p = gmacro(BEFORE);\r\n    /* xalloc checks for out of mem.  */\r\n    if (!p) p=\"\";\r\n    fnode->fmake = (char *)xalloc((strlen(p)+1)); \r\n    strcpy(fnode->fmake, p);\r\n  }\r\n  len += strlen(fnode->fmake);\r\n  /* realloc doesn't.  */\r\n  if ( (fnode->fmake=realloc(fnode->fmake, len)) == NULL) allerr();\r\n\r\n  strcat(fnode->fmake, methtext);\r\n  len = strlen(fnode->fmake);\r\n  if (len && fnode->fmake[len - 1] != '\\n')\r\n    strcat(fnode->fmake, \"\\n\");\r\n}\r\n\r\n\r\n/*\r\n * Get a filenode for the file called 'fn'.\r\n * Returns NULL if the node doesn't exist.\r\n */\r\nFILENODE *gfile(char *fn)\r\n{\r\n  FILENODE *f;\r\n\r\n  for (f = froot ; f != NULL ; f = f->fnext)\r\n    if (!strcasecmp(fn, f->fname)) return f;\r\n  return NULL;\r\n}\r\n\r\n\r\n/*\r\n * Alloc space for a new file node.\r\n * To faciiltate %-rules, do not check for \r\n * an existing FILENODE with the same name. -AM\r\n */\r\nFILENODE *afnode(char *name)\r\n{\r\n  FILENODE *f;\r\n\r\n  /* we need not check for NULL here; xalloc does that for us */\r\n  f = (FILENODE *)xalloc(sizeof(FILENODE));\r\n  f->fname = (char *)xalloc(strlen(name)+1);\r\n  strcpy(f->fname, name);\r\n  f->fmake = NULL;\r\n  f->fnode = NULL;\r\n  f->fdate = 0L;\r\n  f->fflag = 0;\r\n\r\n  f->fnext = froot;\r\n  froot = f;\r\n  return f;\r\n}\r\n\r\n\r\n/*\r\n * Print dependency tree.\r\n */\r\nprtree()\r\n{\r\n  FILENODE *f;\r\n  NODE *n;\r\n\r\n  puts(\"\\ndependency tree\");\r\n  for (f = froot ; f != NULL ; f = f->fnext) {\r\n    if ( !(f->fflag&DUMMYP) ) {\r\n      printf(\"%s%s%s\", f->fname,\r\n\t     (f->fflag & ROOTP) ? \" (root)\" : \"\",\r\n\t     (f->fflag & REBUILT) ? \" (rebuilt)\" : \"\",\r\n\t     (f->fflag & FAILED) ? \" (failed)\" : \"\");\r\n      if (f->fdate != 0L)\r\n\tprintf(\"(%lu)\\n\", f->fdate);\r\n      else \r\n\tputchar('\\n');\t\r\n      if (f->fmake != NULL)\r\n        printf(\"%s\", f->fmake);\r\n      for (n = f->fnode ; n != NULL ; n = n->nnext)\r\n        printf(\"\\t%s\\n\", (n->nfile)->fname);\r\n      putchar('\\n');\r\n    }\r\n  }\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/MACRO.C",
    "content": "#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <ctype.h>\r\n#include \"make.h\"\r\nextern char * strcasestr(char *, char *);\r\n\r\nextern int debug;\r\n\r\n/*\r\n * Macro processing\r\n */\r\n\r\nstatic int emacro(char *name, char * dest);\r\n\r\n/*\r\n * Perform macro substitution from 'orig' to newly allocated string.\r\n * Return pointer to the string.\r\n * A macro reference is in one of two forms:\r\n *\t\t<MACCHAR>(macro-name)\r\n *  \tor\t<MACCHAR><single-character>\r\n *\r\n * \"<MACCHAR><MACCHAR>\" expands to a single '<MACCHAR>'\r\n */\r\nchar * mexpand(char *orig, char macchar)\r\n{\r\n  int ddi, destsiz;\r\n  char *s, *d, *dest, mname[STRSIZ];\r\n\r\n  destsiz=strlen(orig);\r\n  for (s=orig; *s;)\r\n    if (*s == macchar) {\r\n      if (*++s == macchar) {\r\n\tdestsiz--;\r\n\ts++;\r\n\tcontinue;\r\n      }\r\n      if (!*s) {\r\n\tdestsiz--;\r\n\tbreak;\r\n      }\r\n      d = mname;\r\n      if (*s != '(') {\r\n\t*d++ = *s++;\r\n\tdestsiz-=2;\r\n      }\r\n      else {\r\n\tfor (++s; *s && *s!=')';) *d++ = *s++;\r\n\tdestsiz-=d-mname+3;\r\n\tif (*s != ')') \r\n\t  destsiz++;\r\n\telse ++s;\r\n      }\r\n      *d = 0;\r\n      destsiz += emacro(mname, NULL);\r\n    } \r\n    else\r\n      s++;\r\n  dest=xalloc(destsiz+1);\r\n  ddi = 0;\r\n  for (s=orig; *s;)\r\n    if (*s == macchar) {\r\n      if (*++s == macchar) {\r\n\tdest[ddi++] = *s++;\r\n\tcontinue;\r\n      }\r\n      if (!*s) break;\r\n      d = mname;\r\n      if (*s != '(') *d++ = *s++;\r\n      else {\r\n\tfor (++s; *s && *s!=')';) *d++ = *s++;\r\n\tif (*s != ')') puts(\"Missed matching ')'\");\r\n\telse ++s;\r\n      }\r\n      *d = 0;\r\n      ddi += emacro(mname, dest+ddi);\r\n    } \r\n    else \r\n      dest[ddi++] = *s++;\r\n\r\n  dest[ddi]=0;\r\n  if (strlen(dest)!=destsiz) {\r\n    fprintf(stderr, \"strlen(dest)=%d, destsiz=%d.\\n\",strlen(dest),destsiz);\r\n    exit(2);\r\n  } \r\n  return dest;\r\n}\r\n\r\n\r\n/*\r\n * Lookup a macro, possible performing \r\n * a substitution.\r\n * Return number of chars in the expansion.\r\n */\r\nstatic int emacro(char *name, char * dest)\r\n{\r\n  char *end, *pat, *rep, *def;\r\n  int res, pl, rl;\r\n\r\n  end=strchr(name, ':');\r\n  if (end) {\r\n    *end = 0;\r\n    def=gmacro(name);\r\n    if (!def) {\r\n      if (dest) \r\n\tfprintf(stderr, \"Undefined macro: %s\\n\", name);\r\n      return 0;\r\n    }\r\n    *end = ':';\r\n    pat = end+1;\r\n    rep = strchr(pat, '=');\r\n    res = 0;\r\n    if (!rep) {\r\n      if (dest) fprintf(stderr, \r\n\t\t\t\"$(%s): missing '=' in macro substitution\\n\", name);\r\n    }\r\n    else {\r\n      pl = rep-pat;\r\n      ++rep;\r\n      rl = strlen(rep);\r\n      end = def+strlen(def)-pl;\r\n      while (def <= end) {\r\n\tif ((0 == def[pl] || isspace(def[pl])) \r\n\t    && 0 == strncmp(def, pat, pl)) {\r\n\t  res += rl;\r\n\t  def += pl;\r\n\t  if (dest) {\r\n\t    strcpy(dest, rep);\r\n\t    dest += rl;\r\n\t  }\r\n\t}\r\n\telse {\r\n\t  if (dest) *(dest++) = *def;\r\n\t  res++;\r\n\t  def++;\r\n\t}\r\n      }\r\n      res += strlen(def);\r\n      if (dest) strcpy(dest, def);\r\n    }\r\n  }\r\n  else {\r\n    def = gmacro(name);\r\n    if (!def) {\r\n      if (dest) \r\n\tfprintf(stderr, \"Undefined macro: %s\\n\", name);\r\n      return 0;\r\n    }\r\n    res = strlen(def);\r\n    if (dest) strcpy(dest, def);\r\n  }\r\n  return res;\r\n}\r\n\r\n\r\n/*\r\n * Define a macro.\r\n * Give the macro called 'name' the string expansion 'def'.\r\n * Old macro-names are superseded, NOT replaced.\r\n * exit with error-message if can't define the macro.\r\n */\r\nvoid defmac(char *name, char *def)\r\n{\r\n  MACRO *m;\r\n\r\n  /* we need not check for out of mem. here; xalloc does that for us */\r\n  m = (MACRO *)xalloc(sizeof(MACRO));\r\n  m->mname = (char *)xalloc(strlen(name)+1);\r\n  m->mvalue = (char *)xalloc(strlen(def)+1);\r\n\r\n  strcpy(m->mname, name);\r\n  strcpy(m->mvalue, def);\r\n  m->mnext = mroot;\r\n  mroot = m;\r\n}\r\n\r\n/*\r\n * Searches tok in lst, \r\n * tok must appear as a separate token,\r\n * comparison is case insensitive.\r\n */\r\nchar * tok_find(char * lst, char *tok)\r\n{\r\n   char * srch, c;\r\n   int toklen;\r\n\r\n   toklen=strlen(tok);\r\n   for (srch = lst ; ; ) {\r\n      srch = strcasestr(srch, tok);\r\n      if (!srch)\r\n\t break;\r\n      c=srch[toklen];\r\n      if (isspace(c)) c=0;\r\n      if ( !c && (srch == lst || isspace(srch[-1])) ) \r\n\t break;\r\n      else\r\n\t srch += toklen;\r\n   }\r\n   return srch;\r\n}\r\n\r\n/*\r\n * diffmac - remove tokens from macro.\r\n *\r\n * All tokens in the old value the macro that do not appear as token\r\n * in del are copied to the new value.\r\n * The old value is superseded, NOT replaced.\r\n */\r\nvoid diffmac(char *name, char *del)\r\n{\r\n   MACRO *m;\r\n   char *cp, * newval;\r\n   char *next, *last;\r\n\r\n   for ( m=mroot ; (m!=NULL) && (strcmp(name, m->mname)!=0) ; m=m->mnext )\r\n      ;\r\n\r\n   if ( m!=NULL ) {\r\n      cp = m->mvalue;\r\n      newval = xalloc(strlen(cp)+1);\r\n      for (next=newval ; *cp ; ) {\r\n\t while (isspace(*cp)) cp++;\r\n\t if (*cp) {\r\n\t    last = next;\r\n\t    while (*cp && !isspace(*cp)) *next++ = *cp++;\r\n\t    *next = 0;\r\n\t    if (tok_find(del, last))\r\n\t       next = last;\r\n\t    else\r\n\t       *next++ = ' ';\r\n\t }\r\n      }\r\n      *next = 0;\r\n      defmac(name, newval);\r\n      free(newval);\r\n   }\r\n   else\r\n      fprintf(stderr, \"%s -= ... ignored because the macro is undefined.\\n\", \r\n\t      name);\r\n}\r\n\r\n/*\r\n * Replaces the macro called name with \r\n * the concatenation of its value and suf.\r\n * If there is no macro called name, a new\r\n * macro called name with value suf is created\r\n */ \r\nvoid catmac(char * name, char * suf)\r\n{\r\n   MACRO *m;\r\n   char *cp;\r\n\r\n   for ( m=mroot ; (m!=NULL) && (strcmp(name, m->mname)!=0) ; m=m->mnext )\r\n      ;\r\n\r\n   if ( m!=NULL ) {\r\n      if ( (cp=realloc(m->mvalue, strlen(m->mvalue)+strlen(suf)+2)) == NULL ) \r\n\t allerr();\r\n      m->mvalue=strcat(strcat(cp,\" \"), suf);\r\n   }\r\n   else {\r\n      fprintf(stderr, \"Macro %s not yet defined.\\n\", name);\r\n      defmac(name, suf);\r\n   }\r\n} \r\n\r\n/*\r\n * undefmac - undefine a macro.\r\n * Return 0 if macro was succesfully undefined, -1 if not found.\r\n */\r\nint undefmac(char * name)\r\n{\r\n  MACRO *m = mroot;\r\n  MACRO *prev = NULL;\r\n\r\n  while (m != NULL && strcmp(name, m->mname)) {\r\n    prev = m;\r\n    m = m->mnext;\r\n  }\r\n\r\n  if (m == NULL) return -1;\r\n  if (prev == NULL) mroot = m->mnext;\r\n  else prev->mnext = m->mnext;\r\n\r\n  free(m->mname);\r\n  free(m->mvalue);\r\n  free(m);\r\n  return 0;\r\n}\r\n\r\n\r\n/*\r\n * Lookup a macro called 'name'.\r\n * Return a pointer to its definition,\r\n * or NULL if it does not exist.\r\n */\r\nchar *gmacro(char *name)\r\n{\r\n  MACRO *m;\r\n        \r\n  for (m=mroot; m != NULL; m=m->mnext)\r\n    if (!strcmp(name, m->mname)) return m->mvalue;\r\n  return NULL;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/MAKE.C",
    "content": "#include <stdio.h>\r\n#include <ctype.h>\r\n#define MAXMODS 50\r\n#define DATE unsigned long\r\n\r\nint fmake(char *);\r\n\r\n/*\r\n *  MAKE - Maintain seperate source files\r\n *\r\n *  SYNOPSIS\r\n *\tMAKE [-f file] [-a] [-n] [-d] [-k] [-v] [name] ...\r\n *\t   f: use 'file' instead of default makefile\r\n *\t   a: assume all modules are obsolete (recompile everything)\r\n *\t   n: don't recompile, just list steps to recompile\r\n *\t   d: debugging (print tree, file info)\r\n *\t   k: keep going after error\r\n *\t   v: verbose (display steps before executing)\r\n *\t   name: module name to recompile\r\n *\r\n *  AUTHORS\r\n *\tLandon M. Dyer, Atari Inc.\r\n *\tArnold Metselaar\r\n *\r\n */\r\n\r\nchar *mfiles[] = {\t\t\t/* default makefiles */\r\n  \"MAKEFILE\",\r\n  \"MAKEFILE.2\",                   /* e.g. DOS2 makefile */\r\n  \"MAKEFILE.1\",\r\n  \"\"\r\n};\r\n\r\n/* MACRO *mroot = NULL;\t\t*//* root of macro-list */\r\n/* FILENODE *froot = NULL;\t*//* root of filenode-list */\r\n/* FILENODE *firstf = NULL;\t*//* the very first filenode */\r\n/* FILE *mkfp = NULL;\t\t*//* script file */\r\nchar *modnames[MAXMODS];\t/* module-names mentioned in commandline */\r\nint modcount = 0;\t\t/* #of module-names */\r\n\r\nint obsolete = 0;\t\t/*nonzero: every file should be recompiled */\r\nint debug = 0;\t\t\t/*nonzero: turn on debugging */\r\nint noexec = 0; \t\t/*nonzero: no execution of commands */\r\nint keepgoing = 0; \t\t/*nonzero: don't give up after first error */\r\nint verbose = 0; \t\t/*nonzero: print commands before executing */\r\n\r\n#define clower(a) (isupper(a) ? tolower(a) : a)\r\n\r\n/*\r\n * process a simple option \r\n */\r\nstatic void opt_char(char c)\r\n{\r\n  switch (clower(c)) {\r\n    case 'a': obsolete=1; break;\r\n    case 'd': debug=1; break;\r\n    case 'n': noexec=1; break;\r\n    case 'k': keepgoing=1; break;\r\n    case 'v': verbose=1; break;\r\n    default:\r\n      fprintf(stderr, \"Unknown switch: %c\\n\", c);\r\n    break;\r\n  }\r\n} \r\n\r\nint main(int argc, char** argv)\r\n{\r\n  int arg, i;\r\n  char *mfile = NULL;\r\n\r\n  for (arg = 1; arg < argc; ++arg)\r\n  if (*argv[arg] == '-') {\r\n    if ('f'==clower(argv[arg][1])) {\r\n      if (++arg >= argc) {\r\n  \tfprintf(stderr, \"-f needs filename argument.\\n\");\r\n  \treturn 1;\r\n      }\r\n      mfile = argv[arg];\r\n    }\r\n    else \r\n      opt_char(argv[arg][1]);\r\n  }\r\n  else \r\n    if (modcount < MAXMODS) {\r\n      if (argv[arg][0]) /* ignore trailing whitespace */\r\n        modnames[modcount++] = argv[arg];\r\n    }\r\n    else {\r\n      fprintf(stderr, \"Too many module names.\\n\");\r\n      return 1;\r\n    }\r\n  if (mfile != NULL) {\r\n    arg = fmake(mfile);\r\n    if (arg == -1)\r\n      fprintf(stderr, \"\\nCannot open makefile\\n\");\r\n  } \r\n  else {\r\n    for (i = 0; *mfiles[i]; ++i)\r\n       if ((arg=fmake(mfiles[i])) != -1) break;\r\n    if (!*mfiles[i])\r\n      fprintf(stderr, \"\\nCannot open makefile\\n\");\r\n  }\r\n  if (debug) prtree();\r\n  return arg;\r\n}\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/MAKE.H",
    "content": "#define ESCCHAR '\\\\'            /* escape char (is one \\) */\r\n#define MACCHAR '$'             /* macro-definition char */\r\n#define COMCHAR '#'             /* comment char */\r\n#define\tDEFMAC\t\"=\"\t\t/* macro-definition token */\r\n#define\tCATMAC\t\"+=\"\t\t/* macro-concatenation token */\r\n#define DIFFMAC \"-=\"\t\t/* macro-filtering token */\r\n#define\tDEPEND\t\":\"\t\t/* dependency-definition token */\r\n#define\tINIT\t\"~INIT\"\t\t\t/* initialization macro */\r\n#define\tDEINIT\t\"~DEINIT\"\t\t/* de-init macro */\r\n#define\tBEFORE\t\"~BEFORE\"\t\t/* the per-root 'startup' method */\r\n#define\tAFTER\t\"~AFTER\"\t\t/* the per-root 'wrapup' method */\r\n\r\n#define DEBUG\tif(0)\r\n#define\tSTRSIZ\t512\r\n#define\tMAXMODS\t50\r\n\r\n/* file attributes */\r\n#define\tREBUILT\t0x01\t\t/* file has been reconstructed */\r\n#define\tROOTP\t0x02\t\t/* file was named on left side of DEPEND */\r\n#define FAILED\t0x04\t\t/* reconstructing the file failed */\r\n#define DUMMYP  0x08\t\t/* 'file' only exists within %-rule */ \r\n\r\n#define DATE unsigned long\r\n\r\n\r\nstruct node {\r\n\tstruct filenode *nfile;\t/* this node's file */\r\n\tstruct node *nnext;\t/* the next node */\r\n};\r\ntypedef struct node NODE;\r\n\r\n\r\nstruct filenode {\r\n\tchar *fname;\t\t/* the filename */\r\n\tchar *fmake;\t\t/* remake string for file */\r\n\tDATE fdate;\t\t/* 32 bit last-modification date */\r\n\tNODE *fnode;\t\t/* files this file depends on */\r\n\tchar fflag;\t\t/* magic flag bits */\r\n\tstruct filenode *fnext;\t/* the next file */\r\n};\r\ntypedef struct filenode FILENODE;\r\n\r\n\r\nstruct macro {\r\n\tchar *mname;\t\t/* the macro's name */\r\n\tchar *mvalue;\t\t/* the macro's definition */\r\n\tstruct macro *mnext;\t/* the next macro */\r\n};\r\ntypedef struct macro MACRO;\r\n\r\n\r\nextern MACRO *mroot;\r\nextern FILENODE *froot;\r\n\r\nchar *gmacro(char *name);\r\nFILENODE *filenode(char *fname);\r\nFILENODE *gfile(char *fn);\r\nchar *token(char **strpp);\r\nvoid *xalloc(unsigned len);\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/MAKE.MAN",
    "content": " MAKE(I)                         3/10/84                                 MAKE(I)\r\n\r\n\r\n\r\nNAME\r\n\tMAKE - maintain multiple source files\r\n\r\n\r\nSYNOPSIS\r\n\tMAKE [-N] [-A] [-V] [-D] [-K] [-F makefile] [name ...]\r\n\r\n\r\nDESCRIPTION\r\n\r\n        MAKE is a utility inspired by the Unix(tm) command of the same name.\r\n        MAKE helps maintain programs that are constructed from  many  files.\r\n        MAKE processes a \"makefile\", a file which describes how to  build  a\r\n        program from its  source  files,  and  executes  the  the  steps  in\r\n        sub-processes. MAKE uses 48 KiB video memory to store its own state.\r\n\r\n\tBe careful: this MAKE is NOT compatible with Unix(tm) MAKE!\r\n\r\n        The 'N' option causes MAKE to print out the steps it would follow in\r\n        order to rebuild the program. The 'A' option tells  MAKE  to  assume\r\n        that  all  files  are  obsolete,  and  that  everything  should   be\r\n        recompiled. The 'V' options causes MAKE to print  out  the  commands\r\n        before executing them. The  'D'  tells  make  print  out  even  more\r\n        information. MAKE normally stops after the first error (nonzero exit\r\n        status), the 'K' option instructs MAKE to keep going with other that\r\n        files that do not depend on a file that caused  an  error.  The  'F'\r\n        option, followed by a filename, can be used to  specify  a  makefile\r\n        other than the default one.\r\n\r\n        If no names are specified in the commandline, the  first  dependency\r\n        in the makefile is examined. Otherwise, the specified root names are\r\n        brought up to date. Filenames are not case sensitive. \r\n\r\n        It is possible to use wildcards in the command line to  rebuild  all\r\n        all files matching a pattern:\r\n\r\n\tMAKE *.o\r\n\r\n        Instructs Make to rebuild all _existing_ object files in the current\r\n        directory.\r\n\r\n\tThe default makefiles are:\r\n\r\n\t\t\t\tMAKEFILE\r\n\t\t\t\tMAKEFILE.2\r\n\t\t\t\tMAKEFILE.1\r\n\r\n        If the first makefile cannot be found, MAKE attempts to use the next\r\n        one. This way a  program  can  be  distributed  with  makefiles  for\r\n        different compilers or different MSXDOS versions. If no makefile  is\r\n        ever found, MAKE prints a diagnostic and aborts.\r\n\r\n\r\nTHE MAKEFILE\r\n\r\n        Comments begin with '#' and extend to the end of the line. A '#' (or\r\n        almost any other character) may be escaped with the escape character\r\n        slash backward (\\). An escape character may be typed by doubling  it\r\n        (\\\\). The standard Unix escape codes are recognized (\\n, \\r, \\t, \\b,\r\n        \\f).\r\n        Subdirectories are supported by MAKE through the use of LIBDOS2, but\r\n        may not be fully supported by the programs used  to  actually  build\r\n        your program. Use the slash forward (/) as a path separator, like in\r\n        Unix(tm).\r\n        A makefile is a list of dependencies. A  dependency  consists  of  a\r\n        root name, a colon, and zero or more names of dependent files.  (The\r\n        colon MUST be surrounded by whitespace.) For instance, in:\r\n\r\n\t\tmake.com : make.o utils.o parsedir.o file.o macro.o\r\n\r\n        the file 'make.com' depends on five other files. A root name with an\r\n        empty dependency, as in:\r\n\r\n\t\tprint :\r\n\r\n\tis assumed NEVER up to date, and will always be recompiled.\r\n\r\n\tThe dependency list may be continued on successive lines:\r\n\r\n\t\tbigfile.com : one.o two.o three.o four.o\r\n\t\tfive.o six.o gronk.o freeple.o scuzzy.lnk\r\n\t\tfrog.txt greeble.out\r\n\r\n        Any number of 'method' lines may follow a dependency.  Method  lines\r\n        begin with an ascii tab. When a  file  is  to  be  recompiled,  MAKE\r\n        interprets these lines (minus the tab) as commands.\r\n        Set commands, which change  the  environment  are  handled  by  MAKE\r\n        itself, and changes to the environment are reverted when MAKE  stops\r\n        processing a method.\r\n        It  searches  for  a  .com-file  in  the  directories  in  the  PATH\r\n        environment variable. if that fails,  MAKE  loads  the  the  program\r\n        pointed to by the SHELL environment variable to interpret the line.\r\n        If a method line starts with a colon (:) the colon then the colon is\r\n        not treated as a part of the command and  the  exit  status  of  the\r\n        command is ignored.\r\n\r\n\tFor example, in:\r\n\r\n\t\tmake.com : make.o parsedir.o file.o macro.o mk.h\r\n\t\t\tlink make, parsedir, file, macro\r\n\t\t\t:del scratch\r\n\t\t\techo \"Just another version of MAKE ...\"\r\n\r\n        the three lines following the dependency  make  up  the  method  for\r\n        recompiling (or in this case, re-linking) the  file  'make.com'.  If\r\n        there is no file named scratch the  error  code  from  del  will  be\r\n        ignored because of the colon.\r\n\t\r\n        If the macro \"~INIT\" is defined, its text will  be  executed  before\r\n        any other method. If the macro \"~DEINIT\" is defined, its  text  will\r\n        executed just before MAKE exits.\r\n\r\n\t\t~INIT = mode 80\\ntl msxcalc\\n\r\n\t\t~DEINIT = $(~DEINIT)tk \"JvdM MSXCALC\"\\ncls\r\n\r\n\twill expand to:\r\n\r\n\t\tmode 80\r\n\t\ttl msxcalc\r\n\t\t.\r\n\t\t.\r\n\t\ttk \"JvdM MSXCALC\"\r\n\t\tcls\r\n\r\n        When a root's method is defined, the value of the macro \"~BEFORE\" is\r\n        prefixed to the method, and the  value  of  the  macro  \"~AFTER\"  is\r\n        appended to it.\r\n\r\n        Frequently one wants to maintain more than one program with a single\r\n        makefile. In this case, a \"master dependency\" can  appear  first  in\r\n        the file:\r\n\r\n\t\tallOfMyToolsAndHorribleHacks : cat peek poke.com grunge\r\n\t\tcat : cat.com\r\n\t\tcat.com : ....\r\n\t\t\t(stuff for CAT.COM)\r\n\t\tpeek : peek.com\r\n\t\tpeek.com : (stuff for PEEK.COM)\r\n\t\tpoke.com : (stuff for POKE.COM)\r\n\t\tgrunge : grunge.com\r\n\t\tgrunge.com : (stuff for grunge)\r\n\r\n        In other words, make will  bring  everything  up  to  date  that  is\r\n        somehow connected to the first  dependency  (its  assumed  that  the\r\n        incredibly lengthy filename specified in this example won't actually\r\n        exist).\r\n\r\n\r\nMACROS\r\n        A macro is defined by a line of the form (the '=' MUST be surrounded\r\n        by whitespace):\r\n\r\n\t\t<macro-name> = <macro-body>\r\n\r\n        A macro may be deleted by assigning an empty value to it. Macros may\r\n        be redefined, but  old  definitions  stay  around.  If  a  macro  is\r\n        redefined,  and  the  redefinition  is  later  deleted,  the   first\r\n        definition will take effect:\r\n\r\n        A way to change a macro is to use the operator +=, which  must  also\r\n        be surrounded by whitespace:\r\n\r\n\t\t<macro-name> += <addendum>\r\n\r\n        In this case the old definition does not stay around. It  is  useful\r\n        for building long macro values.\r\n\r\n\tOne can also remove items from a list using the -=  operator,  which\r\n        must also be surrounded by whitespace:\r\n\r\n\t\t<macro-name> -= <delendum>\r\n\r\n\tIn this case both the macro value and the delendum is treated  as  a\r\n        list of tokens, so it is not possible to delete parts of words.  The\r\n        old macro value stay around like in  the  case  of  a  normal  macro\r\n        definition.\r\n\r\n\t\tMAC = first\t\t\t! MAC = \"first\"\r\n\t\tMAC = second\t\t\t! MAC = \"second\"\r\n\t\tMAC = $(MAC) third\t\t! MAC = \"second third\"\r\n\t\tMAC += fourth\t\t\t! MAC = \"second third fourth\"\r\n\t\tMAC -= third\t\t\t! MAC = \"second fourth\"\r\n\t\tMAC =\t\t\t\t! MAC = \"second third fourth\"\r\n\t\tMAC =\t\t\t\t! MAC = \"second\"\r\n\t\tMAC =\t\t\t\t! MAC = \"first\"\r\n\t\tMAC =\t\t\t\t! MAC has no definition\r\n\r\n\tA macro may be referenced in two ways:\r\n\r\n\t\t\t$<char>   or\t$(macro-name)\r\n\r\n        The first way only works if the macro's name is a single  character.\r\n        If the macro's name  is  longer  than  one  character,  it  must  be\r\n        enclosed in parenthesis. ['$' may be escaped by doubling it (\"$$\".)]\r\n\tFor example, in:\r\n\r\n\t\tG = mk.h mk1.h\r\n\t\tOBJS = make.o file.o parsedir.o macro.o\r\n\t\tBOTH = $(OBJS) $G\r\n\t\r\n\t\tmake.com : $(OBJS) $G\r\n\t\tmake.com : $(BOTH)\r\n\t\tmake.com : mk.h mk1.h make.o file.o parsedir.o macro.o\r\n\t\t\techo \"This is a dollar sign --> $$\"\r\n\r\n        after macro expansion, the three dependencies will appear  identical\r\n        and the two '$'s in the last line will turn into one '$'.\r\n\r\nSUBSITUTION REFERENCES\r\n\tMake can substitute suffices when it expands  a  macro.  Sustitution\r\n        references   have    the    same    form    as    in    GNU    make;\r\n        $(MACRONAME:pattern=relpacement). Note  that  there  are  no  spaces\r\n        around the ':' and the '=' here.  Each  occurence  of  pattern  that\r\n        immediately precedes whitespace or the end of the  macro  value,  is\r\n        replaced with the replacement.\r\n\tFor example in:\r\n\t\tOBJ = bar.o foo.o\r\n\t\tSRC = $(OBJ:o=c)\r\n\tthe value of SRC will be 'bar.c foo.c'\t\r\n\r\n\r\n%-RULES\r\n        Often many files are build in the same way. %-Rules can be  used  to\r\n        describe the build method of several files in one rule.\r\n        A %-rules consists of a pattern starting with '%', a colon (:),  the\r\n        name of macro, another colon optionally followed by dependencies and\r\n        methods.\r\n        For each  filename  in  the  value  of  the  macro  a  new  rule  is\r\n        constructed from the %-rule as follows.\r\n        The stem is what must be substituted  for  '%'  in  the  pattern  to\r\n        obtain the filename. The macro name and one colon are  removed  from\r\n        the %-rules and all occurences of '%' are replaced by the stem.\r\n\r\n\tFor example:\r\n\r\n\tH = PROG.H\r\n\tOBJS = PROG.O PART2.O\r\n\t%.O : OBJS : %.C $H\r\n\t\tCC -c -o -v %.C\r\n\tPART2.O : EXTRA.H\r\n\r\n\tis equivalent to\r\n\r\n\tPROG.O : PROG.C PROG.H\r\n\t\tCC -c -o -v PROG.C\r\n\tPART2.O : PART2.C PROG.H EXTRA.H\r\n\t\tCC -c -o -v PART2.C\r\n\r\nREDIRECTIONING\r\n\tMake supports redirectioning of the standard input stream with  \"<\",\r\n        of standard output with \">\" and \">>\" and of standard error with \"2>\"\r\n        and \"2>>\". This is done by replacing handles 0,1,2 with  the  \"close\r\n        file handle\" and the \"duplicate file handle\" msxdos2 bdos  calls  as\r\n        appropriate.\r\n\r\nHERE-DOCUMENTS\r\n        If a line contains \"<<\" directly followed by a word,  the  following\r\n        lines until a line starting with the word are copied to '$M.T'.  The\r\n        characters \"<<\" and the word are removed from the line and \"$M.T\" is\r\n        opened for input and provided as standard input. This is  useful  in\r\n        combination with HiTech-C when one wants to link more  object  files\r\n        than would fit on a command line.\r\n\tFor example:\r\n\tbigprog.com : $(COBJ) $(ASOBJ) $(LIBS)\r\n\t\tcc <<EOF\r\n\t\t-Obigprog.com -Mbigprog.map\u0001@-R\r\n\t\t $(COBJ:.o=.o \\\\\\n)\r\n\t\t $(ASOBJ)\r\n\t\t $(LIBS)\r\n\t\tEOF\r\n\r\n        Note the substitution trick to prevent overly long  lines,  this  is\r\n        needed for programs that use the 'buffered input' bdos  call  (0x0a)\r\n        to read standard input.\r\n        \r\n\r\nUNIX(tm) MAKE AND THIS ONE\r\n        They are NOT the same. Do not expect Unix  makefiles  to  work  with\r\n        this MAKE, even if you change the pathnames. There  are  some  major\r\n        differences between this version and the standard Unix(tm) MAKE:\r\n\r\n        1. Multiple root names are not allowed. Unix(tm) MAKE accepts  lines\r\n           of the form:\r\n\r\n\t\tname1 name2 : depend1 depend2\r\n\r\n\t   but this one doesn't.\r\n\r\n\t2. There is no equivalent of double-colon (\"::\".)\r\n\r\n\t3. Suffix rules must be rewritten as %-rules.\r\n\r\n\r\nSAMPLE MAKEFILE\r\n\t#\r\n\t# MSXDOS2 Make utility\r\n\t# (compile with HI-TECH C, link with libdos2 by Arnold Metselaar)\r\n\r\n\t# where HiTech-C and the special vsh3.o can be found:\r\n\r\n\tCDIR = A:/HITECH\r\n\r\n\tLIBS = $(CDIR)/libdos2.lib $(CDIR)/libc.lib\r\n\tCOBJ = make.o utils.o macro.o token.o parsedir.o file.o mspawn.o\r\n\tH = make.h\r\n\tFILES = $H $(COBJ:.o=.c)\r\n\tDIST = make_003.lzh\r\n\tDOCUMENTATION = readme make.man makefile\r\n\r\n\t#\r\n\t# update make.com\r\n\t#\r\n\r\n\tMAKE.COM : $(COBJ) $(CDIR)/VSH3.O $(LIBS)\r\n\t\tCC -V -OMAKE.COM -MMAKE.MAP -R -N VSH3.O $(COBJ) -lDOS2 \r\n\r\n\t#\r\n\t# update object files\r\n\t#\r\n\r\n\t%.O : COBJ : %.C $H\r\n\t\tCC -c -o -v %.C\r\n\r\n\t#\r\n\t# update distribution archive\r\n\t#\r\n\r\n\tdistribution : $(DIST)\r\n\r\n\t$(DIST) : MAKE.COM $(FILES) $(DOCUMENTATION)\r\n\t\t:del $(DIST)\r\n\t\techo lhpack $(DIST) MAKE.COM $(DOCUMENTATION) > pack.bat\r\n\t\techo lhpack $(DIST) $(FILES) >> pack.bat\r\n\t\techo lhpack can not be run from make, please run pack.bat from the command prompt \r\n\r\n\t#\r\n\t# end of makefile\r\n\r\n\r\nENVIRONMENT ITEMS\r\n    VSHTOP\r\n\r\n        If set, VSHTOP specifies the first page of video  memory  that  will\r\n        not be used or probed by MAKE. Pages 0..7 are ordinary video memory,\r\n        pages 8..11 are the extended video memory. Legal values  are  2..12,\r\n        default is 12. Other values are silently ignored. If VSHTOP is 2  or\r\n        3, MAKE will not work. You can use this to protect  data  in  higher\r\n        pages. Some emulators may need VSHTOP=8.\r\n\r\n    PATH\r\n\r\n        The PATH environment specifies a  search  path  for  .com-files,  it\r\n        should be a semicolon(;)-separated list  of  directories,  like  for\r\n        COMMAND2.COM\r\n\r\n\tIt is possible to set environment items with \"set\" as a  part  of  a\r\n        targets method. Environment items changed this way will be  restored\r\n        by make when it stops executing the methos of the target.\r\n\r\nKNOWN BUGS\r\n        MAKE uses video memory to store its internal state when executing  a\r\n        subprocess. MAKE allocates 48 KiB from the top  of  the  video  ram.\r\n        MAKE and CC recognise the video memory in use by  MAKE.  Some  other\r\n        programs, like lhpack, overwrite the video memory used by MAKE. Such\r\n        programs must be run directly from the  command  prompt  or  from  a\r\n        batch file.\r\n\r\n        MAKE probes for extended video memory and may not run properly on on\r\n        emulators that do not emulate extended memory correctly.  If  that's\r\n        the case try \"set VSHTOP=8\".\r\n\r\n        The screen flashes when MAKE reads/writes its  state  from/to  video\r\n        memory. This is to improve reliability of video memory access.\r\n\r\n\t\r\nAUTHORS\r\n\tLandon Dyer\t\t\tG.DYER@SU-SCORE.ARPA\r\n\t175 Calvert Dr. #F-211\t\tBASHFL::DYER (Atari Coinop)\r\n\tCupertino, CA 95014             - original version\r\n\r\n\tPierre Gielen - adaptations for MSX-DOS2\r\n\r\n\tArnold Metselaar\t<arnold.metselaar@planet.nl>\r\n\t\t- code for executing subprocesses and continuing\r\n\t\t- %-rules\r\n\t\t- here-documents\r\n\t\t- additional macro functionality\r\n\t\t- redirectioning\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/MAKEFILE",
    "content": "#\r\n# MSXDOS2 Make utility\r\n# Compile with HI-TECH C. \r\n# Needs: \r\n#\t- vsh3.o, which belongs to cc.com\r\n# \t- libdos2.lib \r\n# \t- strcasecmp(), addition to libc.lib (get the fixes for HiTech libs)\r\n# \t- strcasestr(), idem\r\n\r\n# Directory where the libraries and vsh3.o are stored\r\nCDIR = A:/HITECH\r\n \r\nLIBS = $(CDIR)/libdos2.lib $(CDIR)/libc.lib\r\nCOBJ = make.o utils.o macro.o token.o parsedir.o file.o mspawn.o path.o\r\nXOBJ = xargs.o token.o path.o\r\n\r\nH = make.h\r\nFILES = $H $(COBJ:.o=.c)\r\nFILES -= $(XOBJ:.o=.c)\r\nFILES += $(XOBJ:.o=.c)\r\nDIST = make_004.lzh\r\nDOCUMENTATION = readme make.man makefile\r\n\r\n#\r\n# update make.com\r\n#\r\n\r\nmake.com : $(COBJ) $(CDIR)/VSH3.O $(LIBS)\r\n\tCC -V -OMAKE.COM -MMAKE.MAP -R -N VSH3.O $(COBJ) -lDOS2 \r\n\r\n#\r\n# update xargs.com\r\n#\r\n\r\nxargs.com : $(XOBJ) $(CDIR)/VSH2.O $(LIBS)\r\n\tCC -V -OXARGS.COM -MXARGS.MAP -R -N VSH2.O $(XOBJ) -lDOS2\r\n\r\n#\r\n# update object files\r\n#\r\n\r\n%.O : COBJ : %.C $H\r\n\tCC -c -o -v %.C\r\n\r\nxargs.o : xargs.c\r\n\tCC -c -o -v xargs.c\r\n\r\n#\r\n# update distribution archive\r\n#\r\n\t\r\ndistribution : $(DIST)\r\n\r\n$(DIST) : MAKE.COM xargs.com $(FILES) $(DOCUMENTATION)\r\n\techo del $(DIST) > pack.bat\r\n\txargs -b <<EOF lhpack $(DIST) >> pack.bat \r\n\tmake.com xargs.com $(DOCUMENTATION)\r\n\t$(FILES)\r\n\tEOF\r\n\techo lhpack can not be run from make, please run pack.bat from the command prompt \r\n\r\n#\r\n# end of makefile\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/MSPAWN.C",
    "content": "#include <stdio.h>\r\n#include <unixio.h>\r\n#include <string.h>\r\n#include <stdlib.h>\r\n#include <ctype.h>\r\n#include <stat.h>\r\n\r\n#ifndef O_TRUNC\r\n#define O_TRUNC 0\r\n#endif\r\n#ifndef O_WRONLY\r\n#define O_WRONLY 0\r\n#endif\r\n\r\nextern int _spawn(char*, char*, char *);\r\nextern char *token(char **);\r\n\r\nint spawnblock(char *);\r\nchar * pathfind(char *);\r\nint spawnline(char *, char *);\r\nextern int verbose;\r\nextern int noexec;\r\n\r\nstatic char * tmpnam = \"$M.T\";\r\n\r\nint mkfile(char *s, char *fds, char **q)\r\n{\r\n  int klen, val;\r\n  FILE * fp; \r\n  register char * res;\r\n  \r\n  for (klen=0, s+=2 ; isalnum(*s) ; ++s) ++klen;\r\n  s-=klen;\r\n  if (noexec) printf(\"<<%.*s\\n\", klen, s);\r\n  for (res=*q ; *res && strncmp(res,s,klen) ; ++res) {\r\n    if ( !(res=strchr(res,'\\n')) ) \r\n      break;\r\n  } \r\n  if (!res)\r\n    fputs(\"make: runaway << text\\n\", stderr);\r\n  else {\r\n    fp=noexec ? stdout : fopen(tmpnam,\"w\");\r\n    if (!fp) {\r\n      val=errno;\r\n      perror(tmpnam);\r\n      fputs(\" while creating temp. file in make:mkfile()\\n\",stderr);\r\n      return val;\r\n    }\r\n    *res=0;\r\n    if ((fputs(*q,fp)==EOF)||(fputs(\"\\32\\n\",fp)==EOF)) {\r\n      val=errno;\r\n      perror(tmpnam);\r\n      fputs(\" while writing temp. file in make:mkfile()\\n\",stderr);\r\n      if (!noexec) \r\n\tfclose (fp); \r\n      return val;\r\n    }\r\n    *res=*s;\r\n    if (!noexec && fclose(fp)) {\r\n      val=errno;\r\n      perror(tmpnam);\r\n      fputs(\" while closing temp. file in make:mkfile()\\n\",stderr);\r\n      return val;\r\n    }\r\n    if (noexec) \r\n      printf(\"%.*s\\n\", klen, s);\r\n    while ( *res && ('\\n'!=*res++) ) /* nix */ ;\r\n    memmove(s-2, s+klen, strlen(s+klen)+1);\r\n  }\r\n  if (noexec)\r\n    val=0;\r\n  else {\r\n    val=open(tmpnam, O_RDONLY|O_INHER);\r\n    if (val<0) {\r\n      val=errno;\r\n      perror(tmpnam);\r\n      fputs(\" while opening for redirectioning.\\n\", stderr); \r\n    }\r\n    else {\r\n      fds[0]=val;\r\n      val=0;\r\n    }\r\n  }\r\n  *q=res;\r\n  return val;\r\n}\r\n\r\n\r\nstruct env_sav {\r\n  char * name;\r\n  char * val;\r\n  struct env_sav * next;\r\n} ;\r\nstruct env_sav * env_stack;\r\n\r\n/*\r\n * undo changes made by do_set\r\n */\r\nvoid pop_env()\r\n{\r\n  struct env_sav *cur, *nxt;\r\n\r\n  for ( cur=env_stack ; cur ; cur=nxt) {\r\n    setenv(cur->name, cur->val);\r\n    free(cur->val);\r\n    nxt = cur->next;\r\n    free(cur);\r\n  }\r\n} \r\n\r\n/* process redirectioning */\r\nint redir(char *p, char *fds)\r\n{\r\n  int mode, append, n, fd;\r\n  char *s, *t;\r\n\r\n  n=append=0;\r\n  s=p;\r\n  switch (*s) {\r\n  case '2':\r\n    ++n;\r\n    ++s;\r\n  case '>':\r\n    ++n;\r\n    ++s;\r\n    mode=O_WRONLY|O_INHER;\r\n    if ('>'==*s) {\r\n      append=1;\r\n      ++s;\r\n    }\r\n    break;\r\n  case '<':\r\n    ++s;\r\n    mode=O_RDONLY|O_INHER;\r\n  }\r\n  while (*s && isspace(*s)) \r\n    ++s;\r\n  for (t=s ; *t && !isspace(*t) ; ++t)  \r\n    ;\r\n  if (noexec||verbose) putchar(*p);\r\n  *p=*t;\r\n  *t=0;\r\n  if (noexec||verbose) {\r\n    printf(\"%s \",p+1);\r\n    fd=0;\r\n  }\r\n  if (!noexec) {\r\n    if (n && !append) {\r\n      fd=creat(s,0666); /* Ensure the file exists.  */\r\n      close(fd);\r\n    }\r\n    fd=open(s,mode);\r\n    if (fd<0) {\r\n      perror(s);\r\n      fputs(\" while opening for redirectioning.\\n\", stderr);\r\n    }\r\n    else {\r\n      fds[n]=fd;\r\n      if (append) lseek(fd, 0, SEEK_END);\r\n    }\r\n  }\r\n  if (*p) memmove(p+1, t+1, strlen(t+1)+1);\r\n  return (fd<0)?errno:0;\r\n}\r\n\r\n\r\n/* \r\n * Executes a subprocess for each line in blok.\r\n * Stops when a subprocess returns a nonzero exit-status\r\n * If a line starts with ':', the ':' is skipped and the exitstatus is ignored.\r\n * return value is exit-status of last subprocess executed, \r\n * or zero if the last line processed starts with ':'\r\n *\r\n * if a line contains \"<<\" followed by a word, the following lines\r\n * until a line starting with the word are copied to '$M.T'.\r\n * \"<<\" and the word are removed from the line and '$M.T' is open for input.\r\n */\r\n\r\nint spawnblock(char *blok)\r\n{\r\n  int res, i;\r\n  char *linbuf, *p, *q, *s;\r\n  char quote, heredoc, fds[3];\r\n\r\n  env_stack = NULL;\r\n  linbuf=malloc(strlen(blok)+1); \r\n  if (!linbuf) {\r\n    fputs(\"*** Out of memory\\n\",stderr);\r\n    return 0xDE;\r\n  }\r\n  heredoc=0;\r\n  for (p=strcpy(linbuf,blok),res=0 ; (res==0) && (*p) ; p=q) {\r\n    fds[0]=0; fds[1]=1; fds[2]=2;\r\n    for (q=p ; (*q)&&(*q!='\\n') ; ++q) /* nix */;\r\n    if (*q=='\\n') *q++='\\0';\r\n    /* messy; obey \"\" and '' */\r\n    for (s=p ; *s && (res==0); ) {\r\n      switch (*s) {\r\n      case '\"':\r\n      case '\\'':\r\n\tquote=*s++;\r\n\twhile (*s && (*s++ != quote)) \r\n\t  ;\r\n\tbreak;\r\n      case '>':\r\n\tres=redir(((s>p) && ('2'==s[-1])) ? s-1 : s, fds);\r\n\tbreak;\r\n      case '<':\r\n\tif ('<'==s[1]) {\r\n\t  res=mkfile(s, fds, &q);\r\n\t  heredoc=!noexec;\r\n        }\r\n        else\r\n\t  res=redir(s, fds);\r\n\tbreak;\r\n      default:\r\n\ts++;\r\n      } \r\n    }\r\n    if (res) break;  \r\n    res = spawnline(p,fds);\r\n    for ( i=0 ; i<3 ; ++i) \r\n      if (fds[i]>2) \r\n\tclose(fds[i]);\r\n    if (heredoc) {\r\n      unlink(tmpnam);\r\n      heredoc=0;\r\n    }\r\n  }\r\n  pop_env();\r\n  free(linbuf);\r\n  return res;  \r\n}\r\n\r\n/*\r\n * change the environment like set would do, but store the old value\r\n */\r\nint do_set(char * line)                                             \t\r\n{\r\n  char * q;\r\n  struct env_sav * penv;\r\n\r\n  q=token(&line);\r\n  penv=malloc(sizeof(struct env_sav));\r\n  if (penv) {\r\n    penv->val=getenv(q);\r\n    penv->next=env_stack;\r\n    setenv(q,line);\r\n    return 0;\r\n  }\r\n  else {\r\n    fputs(\"*** Out of memory\\n\",stderr);\r\n    return 0xDE;\r\n  }\r\n}\r\n\r\n\r\nchar *shell = NULL;\r\n\r\n/*\r\n * executes one subprocess.\r\n * if the first token in line can be found in the command search path,\r\n * the file is loaded and executed directly, \r\n * otherwise line is interpreted by the program pointed to by the \r\n * environment variable SHELL.\r\n */ \r\nint spawnline(char *line, char *fds)\r\n{\r\n  char *command, *progfile, ignore;\r\n  static char set[]=\"set\";\r\n  int res;\r\n\r\n  if (':' == *line) {\r\n    ignore=1;\r\n    ++line;\r\n  }\r\n  else\r\n    ignore=0;\r\n\r\n  command=token(&line);\r\n  if (0 == strcasecmp(&set, command))\r\n    progfile=&set;\r\n  else \r\n    progfile=pathfind(command);\r\n\r\n  if (progfile==NULL) {\r\n    if (!shell) shell=getenv(\"SHELL\");\r\n    if (!shell) {\r\n      fprintf(stderr,\r\n              \"make: '%s' not found in path, and 'SHELL' not in environment\\n\",\r\n\t      command);\r\n      return 0x8E; /* unrecognised command */\r\n    }\r\n    else {\r\n      progfile=shell;\r\n      if (*line) *strchr(command, '\\0')=' ';\r\n      line=command;\r\n    }\r\n  }\r\n\r\n  if (progfile!=&set && strlen(line)>126) {\r\n     fprintf(stderr,\"%s %.20s... : Linebuffer overflow\\n\", progfile, line);\r\n     res=0x8D; /* BUFUL */\r\n  }  \r\n  else {    \r\n    if (verbose||noexec) {\r\n      printf(noexec ? \"%s %s\\n\": \"[MAKE] %s %s\\n\", progfile, line);\r\n    }\r\n    if (progfile==&set)\r\n      res=do_set(line);\r\n    else\r\n      res=noexec ? 0 : _spawn(progfile, line, fds);\r\n    if (progfile == shell) {\r\n      if (res==0x8C) \r\n\tres=0; /* internal 'error' code meaning no error */\r\n      else\r\n\tcommand=token(&line);\r\n    }\r\n  }\r\n  if (res && (!ignore || verbose))\r\n     fprintf(stderr, \"'%s' failed with error code %d%s.\\n\", \r\n\t\t     command, res, ignore ? \" (ignored)\" : \"\");\r\n  return (ignore ? 0 : res);\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/PARSEDIR.C",
    "content": "#include <stdio.h>\r\n#include <limits.h>\r\n#include <stat.h>\r\n#include \"make.h\"\r\n\r\nstatic struct stat statbuf;\r\n\r\n#define endoftime ULONG_MAX\t\t/* when i'm old and wise */\r\n\r\n/*\r\n * Get a file's creation date.\r\n */\r\nint getdate(FILENODE *f)\r\n{\r\n  char fnm[65];\r\n  strncpy(fnm,f->fname,65);\r\n\r\n  if (!stat(fnm,&statbuf))\r\n    f->fdate = statbuf.st_mtime;\r\n  else {\r\n    fprintf(stderr, \"Can't get date for file '%s'\\n\", f->fname);\r\n    f->fdate = endoftime;\r\n  }\r\n  return 0;\r\n}\r\n\r\n\r\n/*\r\n * laterdt - compare two dates.\r\n * Return -1, 0 or 1 if date1 < date2, date1 == date2, or date1 > date2\r\n */\r\nint laterdt(DATE date1, DATE date2)\r\n{\r\n  if(date1 > date2)\r\n    return 1;\r\n  if (date1 < date2)\r\n    return -1;\r\n  return 0;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/PATH.C",
    "content": "#include <stdio.h>\r\n#include <string.h>\r\n#include <stdlib.h>\r\n#include <ctype.h>\r\n#include <stat.h>\r\n\r\nextern _flip(char *, char *, int); /* substitute '\\\\' for '/' */ \r\n\r\n#define MAXLEN 66\r\nstatic char **path_elt;\r\nstatic char padbuf[MAXLEN+1];\r\nstatic char *nopath[]={\"\", NULL};\r\n\r\n/*\r\n * Tries to find command s in the search path.\r\n * Returns the filename if it is found and\r\n * NULL otherwise.\r\n */\r\nchar * pathfind(char* s)\r\n{\r\n  char *pad,*p;\r\n  int n,i;\r\n  struct stat dummy;\r\n\r\n  if (path_elt==NULL) {\r\n    pad=getenv(\"PATH\");\r\n    if ((!pad)||strlen(pad)==0) path_elt=nopath;\r\n    else {\r\n      for (p=pad, n=1 ; *p ; ) if (*p++ == ';') ++n;\r\n      path_elt=malloc((n+1)*sizeof(char*)); \r\n      if (path_elt) {\r\n\tpath_elt[0]=pad;\r\n\tfor (i=0,p=pad ; (*p) ; )\r\n\t  switch (*p) {\r\n\t    case ';':\r\n\t      *p='\\0';\r\n              path_elt[++i]=++p;\r\n              break;\r\n            case ' ':\r\n              ++path_elt[i];\r\n              /* fall through */\r\n            default:\r\n              ++p;\r\n          }\r\n        path_elt[++i]=NULL;\r\n      }\r\n      else {\r\n\tfputs(\"Not enough memory, ignoring $PATH\\n\",stderr);\r\n\tpath_elt=nopath;\r\n      }\r\n    }\r\n  }\r\n  \r\n  for (i=0,pad=NULL ; path_elt[i] && !pad ; ++i)\r\n    if (strlen(path_elt[i])+strlen(s)+5<=MAXLEN) {\r\n      strcpy(padbuf,path_elt[i]);\r\n      if (*padbuf)\r\n        switch (padbuf[strlen(padbuf)-1]) {\r\n        case ':': \r\n        case '/': \r\n        case '\\\\':\r\n          break;\r\n        default: \r\n          strcat(padbuf,\"\\\\\");\r\n        }\r\n      strcat(strcat(padbuf,s),\".COM\");\r\n      if (stat(padbuf, &dummy)==0) { \r\n\t_flip(padbuf, padbuf, MAXLEN+1);\r\n\tpad=padbuf;\r\n      } \r\n    }\r\n  return pad;\r\n}\r\n\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/README",
    "content": "The original version of this make program was written by Landon Dryer.\r\nPierre Gielen has adapted it to msx-dos, and later Arnold Metselaar \r\nadapted it further for msx-dos2 and made some important improvements\r\n\r\nThe contents of Readme file that came with the old msx-dos version is below.\r\n\r\n\r\nLast month I wrote a version of the Unix(tm) utility MAKE.  It runs under\r\nVAX/VMS and MSDOS 2.0.  I am placing it in the public domain, and it is yours\r\nfor the asking.  You may copy it, or give it away.  You can make any changes\r\nyou like to it.  All I ask is that you DO NOT TRY TO SELL IT.\r\n\r\nAnyway, there is now a MAKE for MSXDOS.  It is free, and it works pretty well.\r\nI'm giving it away because it might do the world some good.  Who knows?\r\n\r\nCaveat: this version of MAKE is NOT compatible with the Unix(tm) version.\r\nSome differences are explained in the documentation.  Most of the problem stems\r\nfrom the fact that I've never had a chance to use the original version of MAKE,\r\nand the documentation I've seen on it has been poor.  My idea of what a make\r\nprogram should do is almost certainly different from what you Unix(tm) hackers\r\nare used to.  Well, hell -- the software is worth what you paid for it.  Have\r\nfun.\r\n\r\nIn order to get MAKE running on your system, you need to:\r\n\r\n\t1.  Read the documentation file MAKE.MAN.  (Yes, read the\r\n\t    directions.)\r\n\r\n\t2.  Edit the file MAKE.H to represent your system\r\n\r\n\t3.  Recompile the source code\r\n\r\n\t4.  Test out MAKE by running it on itself.  (Make a backup\r\n\t    first!)\r\n\r\n\r\n\r\n\t\t\tGood luck,\r\n\r\n\t\t\tLandon Dyer (G.DYER @ SU-SCORE)\r\n\r\n\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/TOKEN.C",
    "content": "#include <stdio.h>\r\n#include <ctype.h>\r\n#include \"make.h\"\r\n\r\nvoid stripwh(char **strpp);\r\n\r\n/*\r\n * Get next token from the string.  Return a pointer to it, or NULL.\r\n * Adjust pointer to point to next part of string.\r\n * The string is modified.\r\n * A token consists of any number of non-white characters.\r\n */\r\nchar *token(char **strpp)\r\n{\r\n  char *s, *beg;\r\n\r\n  stripwh(strpp);\r\n  if (!**strpp) return NULL;\r\n\r\n  beg = s = *strpp;\r\n  while (*s && !isspace(*s)) ++s;\r\n  if (*s) *s++ = '\\0';\r\n  *strpp = s;\r\n  return beg;\r\n}\r\n\r\n\r\n/*\r\n * Parse character escape-sequences in a line of text.\r\n *\t<EscChar><EscChar> = <EscChar>\r\n *\t<EscChar>n = newline, and so on\r\n *\t<EscChar><char> = <char>\r\n * The string is truncated at the first non-escaped occurance of 'comchar'.\r\n */\r\nescape(char *str, char comchar)\r\n{\r\n  char *d, c;\r\n\r\n  for (d = str; *str && *str != comchar; ++str)\r\n    if (*str == ESCCHAR && *(str + 1)) \r\n      switch((c = *++str)) {\r\n\tcase ESCCHAR:\r\n\t  *d++ = ESCCHAR;\r\n\t  break;\r\n\tcase 'n':\r\n\t  *d++ = '\\n';\r\n\t  break;\r\n        case 'r':\r\n\t  *d++ = '\\r';\r\n\t  break;\r\n\tcase 't':\r\n\t  *d++ = '\\t';\r\n\t  break;\r\n\tcase 'b':\r\n\t  *d++ = '\\b';\r\n\t  break;\r\n        case 'f':\r\n\t  *d++ = '\\f';\r\n\t  break;\r\n\r\n\tdefault:\r\n\t  *d++ = c;\r\n\t  break;\r\n    } \r\n    else *d++ = *str;\r\n\r\n  *d++ = 0;\r\n}\r\n\r\n\r\nvoid stripwh(char **strpp)\r\n{\r\n  char *s;\r\n\r\n  s = *strpp;\r\n  while(isspace(*s)) ++s;\r\n  *strpp = s;\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/UTILS.C",
    "content": "#include <stdio.h>\r\n#include <limits.h>\r\n#include <stdlib.h>\r\n#include <ctype.h>\r\n#include <string.h>\r\n#include <conio.h>\r\n#include \"make.h\"\r\nint fmake(char *);\r\nint examine(FILENODE *, DATE);\r\nint recomp(FILENODE *);\r\nint determ();\r\n\r\nextern int laterdt(DATE,DATE);\r\nextern void defmac(char *, char *);\r\nextern void catmac(char *, char *);\r\nextern void diffmac(char *, char *);\r\nextern int undefmac(char *);\r\nextern int spawnblock(char*);\r\nextern int strcasecmp(char*, char*);\r\nvoid finish(FILENODE *f);\r\n\r\n#define PADLEN\t64\t\t\t/* maximum length of filename */ \r\n\r\nMACRO *mroot = NULL;\t\t/* root of macro-list */\r\nFILENODE *froot = NULL; \t/* root of filenode-list */\r\nFILENODE *firstf = NULL;\t/* the very first filenode */\r\nFILE *mkfp = NULL;\t\t/* script file */\r\nextern int modcount;\r\nextern int debug;\r\nextern int obsolete;\r\nextern int keepgoing;\r\nextern int verbose;\r\nextern int noexec;\r\nextern char *modnames[MAXMODS]; /* module-names mentioned in commandline */\r\n\r\n#define endoftime ULONG_MAX\t/* a date, the very last possible */\r\n\r\nvoid fparse(FILE *fp);\r\n\r\n/*\r\n * Construct dependency tree from the makefile 'fn'.\r\n * Figure out what has to be recompiled, and write a script file to do that.\r\n */\r\n\r\nint fmake(char * fn)\r\n{\r\n  int res;\r\n  FILE *fp;\r\n\r\n  if (0 == strcmp(\"-\",fn))\r\n    fp = stdin;\r\n  else  \r\n    if ((fp = fopen(fn, \"r\")) == NULL) return -1;\r\n  fparse(fp);\r\n  res=determ();\r\n  \r\n  fclose(fp);\r\n  return res;\r\n}\r\n\r\nchar * mexpand(char *orig, char macchar);\r\n\r\n/*\r\n * Parse the input file, defining macros and building the dependency tree.\r\n */\r\nvoid fparse(FILE *fp)\r\n{\r\n  char *strp, *tok1, *tok2, *s;\r\n  FILENODE *lastf = NULL;\r\n  char *ebuf, ibuf[STRSIZ];\r\n\r\n  for (;; free(ebuf)) {\r\n    if (fgets(ibuf, STRSIZ, fp) == NULL) break;\r\n    /* changed prototype of mexpand() to handle long expansions - AM */\r\n    ebuf = mexpand(ibuf, MACCHAR);\r\n    escape(ebuf, COMCHAR);\r\n\r\n    /* clobber last newline in string */\r\n    s = ebuf + strlen(ebuf) - 1;\r\n    if (s >= ebuf && *s == '\\n') *s = '\\0';\r\n\r\n    if (*ebuf == '\\t') {\r\n      addmeth(lastf, ebuf+1);\r\n      continue;\r\n    }\r\n\r\n    strp = ebuf;\r\n    if ((tok1 = token(&strp)) == NULL) continue;\r\n    if ((tok2 = token(&strp)) != NULL) {\r\n      if (!strcmp(tok2, DEFMAC)) {\r\n         if (*strp) defmac(tok1, strp);\r\n\t else \r\n\t   if (undefmac(tok1) < 0)\r\n\t     fprintf(stderr,\"Can't undefine macro '%s'\\n\", tok1);\r\n\t continue;\r\n      }\r\n      else if (!strcmp(tok2, CATMAC)) {\r\n         if (*strp) catmac(tok1, strp);\r\n         else fprintf(stderr,\"'%s %s' ignored.\\n\", tok1, CATMAC);\r\n\t continue;\r\n      } \r\n      else if (!strcmp(tok2, DIFFMAC)) {\r\n         if (*strp) diffmac(tok1, strp);\r\n         else fprintf(stderr,\"'%s %s' ignored.\\n\", tok1, DIFFMAC);\r\n\t continue;\r\n      } \r\n      else if (!strcmp(tok2, DEPEND)) {\r\n\t finish(lastf);\r\n\r\n\t lastf = filenode(tok1);\r\n\t if (firstf == NULL) firstf = lastf;\r\n\t lastf->fmake = NULL;\r\n\r\n\t /* ${~BEFORE} is prepended by addmeth(), \r\n          * if the file contains a method line for this root. */\r\n\r\n\t lastf->fflag |= ROOTP;\r\n\t while ((tok1 = token(&strp)) != NULL)\r\n            addfile(lastf, tok1);\r\n\t continue;\r\n      }\r\n      else addfile(lastf, tok2);\r\n    }\r\n    do {\r\n      addfile(lastf, tok1);\r\n    } while((tok1 = token(&strp)) != NULL);\r\n  }\r\n  finish(lastf);\r\n}\r\n\r\nint match(char *buf, char *pat, char *name);\r\nchar *subs(char *x, char *s); \r\n\r\n/*\r\n * Called to finish the parsing of a dependency rule.\r\n * The value of AFTER is added to the method.\r\n * If the rule is a %-rule then a new rule is generated for each\r\n * target in the expansion\r\n */\r\nvoid finish(FILENODE * fnd)\r\n{\r\n   NODE *dep, *rp, *dp;\r\n   FILENODE *rfp; \r\n   char *cp, *xp, *fn, *rest;\t\r\n   char stem[PADLEN];\r\n\r\n   if (fnd->fmake)\r\n     addmeth(fnd, gmacro(AFTER));\r\n   if (fnd->fname[0]=='%') {\r\n     fnd->fflag |= DUMMYP ;\r\n     for ( rp=fnd->fnode ; rp&&strcmp(rp->nfile->fname,DEPEND) ; rp=rp->nnext)\r\n\tif (strchr(rp->nfile->fname, '%')) rp->nfile->fflag |= DUMMYP ;\r\n     if ( (dep=rp) )\r\n\tdep->nfile->fflag |= DUMMYP ;\r\n     else {\r\n\tfprintf(stderr, \"Can't find second '%s' in %%-rule.\\n\", DEPEND);\r\n\texit(2);\r\n     } \r\n     /* the 'dependencies' in the linked list are in reverse order */\r\n     if (dep->nnext == NULL) {\r\n\tfprintf(stderr, \"In %%-rule: No macro name given.\\n\");\r\n\texit(2);\r\n     }\r\n     fn = dep->nnext->nfile->fname;\r\n     if ( (cp=gmacro(fn)) == NULL ) {\r\n\tfprintf(stderr, \"In %%-rule: macro '%s' not defined.\\n\", fn);\r\n\texit(2);\r\n     }\r\n     if (debug) {\r\n       puts(\"%-rule:\");\r\n       printf(\"pattern ='%s'\\n\",fnd->fname);\r\n       printf(\"$(%s)='%s'\\n\", fn, cp);\r\n     }\r\n     dep->nnext->nfile->fflag |= DUMMYP ; \r\n     xp=xalloc(strlen(cp)+1); /* xalloc checks for out of mem. */\r\n     rest=strcpy(xp,cp);\r\n     while ( (fn=token(&rest)) ) {\r\n\tif (! match(stem, fnd->fname, fn))\r\n\t   fprintf(stderr, \"'%s' does not match '%s'.\\n\", \r\n\t\t   fn, fnd->fname);\r\n\telse {\r\n\t   if (debug) printf(\"\\t%s\\n\",fn);\r\n\t   rfp=filenode(fn);\r\n\t   rfp->fflag |= ROOTP;\r\n\t   for ( dp=fnd->fnode ; dp!=dep ; dp=dp->nnext ) {\r\n\t      cp=subs(dp->nfile->fname, stem);\r\n\t      addfile(rfp, cp);\r\n\t      free(cp);\r\n\t   }\r\n\t   if (fnd->fmake) \r\n\t     rfp->fmake = subs(fnd->fmake, stem);\r\n\t}\r\n     }\r\n     free(xp);\r\n     for ( rp=fnd->fnode ; rp ; rp=dp) {\r\n\tdp=rp->nnext;\r\n\t/* if (rp->nfile->fflag & DUMMYP) frnode(rp->nfile); */\r\n\tfree(rp);\r\n     }\r\n     fnd->fnode=NULL;\r\n     if (fnd->fmake) {\r\n\tfree(fnd->fmake);\r\n\tfnd->fmake=NULL;\r\n     }\r\n   } /* endif (fnd-->fname[0]=='%') */\r\n}\r\n\r\n/*\r\n * 'matches' name against the pattern;\r\n * pat must begin with a '%', and the end of name must\r\n * be equal to the second to last characters in pat.\r\n * if this is the case then the beginning of name is stored in buf and\r\n * returns 1 on success, 0 otherwise\r\n */\r\nint match(char *buf, char *pat, char *name)\r\n{\r\n   int len;\r\n\r\n   len=strlen(name)-strlen(pat+1);\r\n   if (len>=PADLEN) {\r\n\tfprintf(stderr, \"'%s' : too long!\\n\");\r\n\treturn 0;\r\n   } \r\n   if (strcasecmp(name+len,pat+1)!=0)\r\n      return 0;\r\n   strncpy(buf, name, len);\r\n   buf[len]='\\0';\r\n   return 1;\r\n}\r\n\r\n/*\r\n * returns a newly malloc()ed string, formed from x by \r\n * replacing each occurence of '%' with s.\r\n */\r\nchar *subs(char *x, char *s)\r\n{\r\n   char *p, *res;\r\n   int len, slen;\r\n\r\n   slen=strlen(s);\r\n   for (p=x,len=0 ; (*p) ; ++p)\r\n      len+=(*p=='%') ? slen : 1; \r\n   res=xalloc(len+1); /* xalloc() checks for out of mem. */\r\n   for (p=res ; (*x) ; ++x) {\r\n      if (*x=='%') {\r\n\tstrcpy(p,s);\r\n\tp+=slen;\r\n      }\r\n      else\r\n\t*p++ = *x;\r\n   }\r\n   *p='\\0';\r\n   return res;\r\n}\r\n/*\r\n * Determine sequence of recompiles from the creation dates.\r\n * If there is anything to recompile, \r\n * then do it by calling recomp().\r\n */\r\nint determ()\r\n{\r\n  FILENODE *f;\r\n  int i,res;\r\n  char *m;\r\n\r\n  if (firstf == NULL) {\t\t\t/* empty tree */\r\n    printf(\"No changes\\n\");\r\n    return 0;\r\n  }\r\n  res=0;\r\n  if (modcount == 0) \r\n    res=(examine(firstf, endoftime)==FAILED)?1:0;\r\n  else \r\n    for (i = 0; (i < modcount) && (!res || keepgoing) ; ++i) {\r\n      if ((f = gfile(modnames[i])) == NULL) {\r\n\tfprintf(stderr, \"Can't find root '%s'.\\n\", modnames[i]);\r\n\tcontinue;\r\n      }\r\n      if ((f->fflag & ROOTP)== 0) {\r\n        fprintf(stderr, \"'%s' is not a root!\\n\", f->fname);\r\n        continue;\r\n      }\r\n      res=(examine(f,endoftime)==FAILED)||res?1:0;\r\n    }\r\n\r\n  if (mkfp != NULL) {\r\n    m=gmacro(DEINIT);\r\n    if (m)\r\n      res=(spawnblock(m) || res)?1:0;\r\n  }\r\n  else\r\n    printf(\"No changes\\n\");\r\n\r\n  return res;\r\n}\r\n\r\n\r\n/*\r\n * Examine filenode 'fnd' and see if it has to be recompiled.\r\n * 'date' is the last-touched date of the node's father\r\n * (or 'endoftime' if its a root file.)\r\n * Returns REBUILT if recompilation was successful,\r\n *         FAILED if recompilation failed and \r\n *         0 otherwise\r\n *\r\n * Root files with NO dependencies are assumed not to be up to date.\r\n */\r\nint examine(FILENODE *fnd, DATE date)\r\n{\r\n  int rebuildp = 0;\r\n  NODE *n;\r\n\r\n  if (debug) {\r\n    printf(\"\\n examine(%s, \", fnd->fname);\r\n    if (endoftime == date) \r\n      printf(\"endoftime) {\");\r\n    else\r\n      printf(\"%lu) {\", date);\r\n  }\r\n\r\n  getdate(fnd);\r\n\r\n  if ((fnd->fnode == NULL) && (fnd->fflag & ROOTP)) {\r\n    if (debug) puts(\"root w/o dependencies\");\r\n    rebuildp = REBUILT;\r\n  }\r\n  else \r\n    for ( n=fnd->fnode ;\r\n          (n!=NULL) && (keepgoing || ((rebuildp&FAILED)==0)) ;\r\n          n=n->nnext) {\r\n      if (n->nfile->fflag & FAILED) {\r\n        rebuildp = FAILED;\r\n        fnd->fflag |= FAILED;\r\n      }\r\n      else \r\n        rebuildp |= examine(n->nfile, fnd->fdate);\r\n  }\r\n  if (rebuildp & FAILED)\r\n    fprintf(stderr, \"'%s' not remade because of errors\\n\", fnd->fname);\r\n    \r\n  if ( REBUILT==(rebuildp&(REBUILT|FAILED)) ) {\r\n    if (debug) putchar('\\n');\r\n    if (recomp(fnd)) rebuildp=FAILED;\r\n  }\r\n  if (laterdt(fnd->fdate, date) > 0) {\r\n     if (debug) printf (\"newer; %lu \", fnd->fdate);\r\n     rebuildp |= REBUILT;\r\n  }\r\n  if (obsolete || (date==endoftime) )\r\n    rebuildp |= REBUILT;\r\n\r\n  if (debug) printf(\" %s }\", rebuildp \r\n\t\t\t   ? ( (rebuildp&FAILED) ? \"failed\" : \"rebuilt\" )\r\n\t\t\t   : \"uptodate\" );\r\n  return (rebuildp&FAILED)?FAILED:rebuildp;\r\n}\r\n\r\n\r\n/*\r\n * Make sure a filenode gets recompiled.\r\n * returns non-zero on faillure\r\n */\r\nint recomp(FILENODE *f)\r\n{\r\n/* FILENODE *sf; */\r\n  char *m;\r\n  int res;\r\n\r\n  res = 0;\r\n  if (mkfp == NULL) {\r\n    mkfp = stdout;\r\n    if ((m = gmacro(INIT)) != NULL)\r\n      res=spawnblock(m);\r\n  }\r\n  if (f->fflag & REBUILT) return res;\r\n  if (verbose||debug) printf(\"** (re)compiling %s:\\n\",f->fname);\r\n  if (f->fmake != NULL)\r\n    res=spawnblock(f->fmake);\r\n  f->fflag |= (res ? FAILED : REBUILT);\r\n\r\n  return res;\r\n}\r\n\r\n/*\r\n * Try to allocate memory, and check for NULL\t\r\n */\r\nvoid *xalloc(unsigned len)\r\n{\r\n  void * res;\r\n  res=malloc(len);\r\n  if (!res) allerr(); /* does not return */\r\n  return res;\r\n}\r\n\r\n/*\r\n * Complain about being out of memory, and then die.\r\n */\r\nallerr() {\r\n  fprintf(stderr, \"Can't alloc -- no space left (I give up!)\\n\");\r\n  noexec=1;\r\n  exit(1);\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "msx2dist/make_004/XARGS.C",
    "content": "/* xargs.c - simple xargs program */\r\n\r\n/* xargs [-a file] [-t|--no-exec|-b] <command> [initial-args ...]\r\n * read token from stdin and construct/execute subcommands;\r\n * each subcommand is of the form \r\n * <command> [initial-args ...] <tokens from stdin>\r\n * each token read from stdin is passed to one subcommand\r\n */\r\n\r\n#include <unixio.h>\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n\r\nchar * pathfind(char* s);\r\nint _spawn(char*,char*,char*);\r\nchar *token(char**);\r\n\r\n/* max. total length of arguments (for cp/m and msxdos(2)): */\r\n#define ARGLEN 126\r\n/* require some margin for the extra arguments */\r\n#define MARGIN 12\r\n\r\n#define BUFLEN 512\r\nint verbose, do_exec;\r\n\r\nvoid print_help(FILE* fp)\r\n{\r\n  static char *help[]={\r\n  \"Usage: xargs [options] [command [initial args...]]\",\r\n  \"\",\r\n  \"Execute command repeatedly with arguments read from standard input.\", \r\n  \"Options can be\",\r\n  \"--help\\t: print this help and exit\",\r\n  \"--no-exec\\t: do not execute the commands, implies -t\",\r\n  \"--\\t: marks end of options to xargs, the next item is used as the command\",\r\n  \"-a file\\t: read arguments from file ratherthan stdin\",\r\n  \"-b\\t: generate batch file; do not search command in PATH and\",\r\n  \"\\t  do not execute the commands, implies -t\",\r\n  \"-t\\t: type out commands\",\r\n  NULL\r\n  };\r\n  int i;\r\n  for (i=0 ; help[i] ; ++i) {\r\n    fputs(help[i],fp);\r\n    fputc('\\n', fp);\r\n  }\r\n}\r\n\r\nstatic char *shell;\r\nint parse(int argc, char *argv[], char **name, char **prog, char **iniargs)\r\n{\r\n  int i,batch, rest, res, len;\r\n  char *p;\r\n  FILE * help;\r\n\r\n  *name=NULL;\r\n  help=NULL;\r\n  batch=verbose=0; \r\n  do_exec=1;\r\n  for (i=1, rest=argc ; i<rest ; ++i) {\r\n    if ('-' != argv[i][0]) {\r\n      rest=i;\r\n      break;\r\n    }\r\n    switch (argv[i][1]) {\r\n    case 'a': \r\n      if (argv[i][2])\r\n\t*name=argv[i]+2;\r\n      else {\r\n\tif (++i < argc)\r\n\t  *name=argv[i];\r\n\telse {\r\n\t  fprintf(stderr, \"-a option needs filename\");\r\n\t  help=stderr;\r\n\t  res=1;\r\n\t}\r\n      }\r\n      break;\r\n    case 'b':\r\n      batch=1;\r\n      break;\r\n    case 't':\r\n      verbose=1;\r\n      break;\r\n    case '-':\r\n      if (argv[i][2]) {\r\n\tif (0==strcmp(argv[i]+2,\"help\")) {\r\n\t  help=stdout;\r\n\t  res=0x8C;\r\n\t}\r\n\telse if (0==strcmp(argv[i]+2,\"no-exec\")) {\r\n\t  do_exec=0;\r\n\t  verbose=1;\r\n\t}\r\n\telse {\r\n\t  fprintf(stderr, \"unknown option: %s\", argv[i]);\r\n\t  help=stderr;\r\n\t  res=1;\r\n\t}\r\n      }\r\n      else\r\n\trest=i+1;\r\n      break;\r\n    default:\r\n      fprintf(stderr, \"unknown option: %s\", argv[i]);\r\n      help=stderr;\r\n      res=1;\r\n    }\r\n  }\r\n  if (help) {\r\n    print_help(help);\r\n    return res;\r\n  }\r\n  if (batch || rest==argc) {\r\n    verbose=1;\r\n    do_exec=0;\r\n    *prog=\"\";\r\n  }\r\n  else {\r\n    *prog=pathfind(argv[rest]);\r\n    if  (NULL==*prog) {\r\n      if (!shell) shell=getenv(\"SHELL\");\r\n      if (!shell) {\r\n        fprintf(stderr,\r\n                \"xargs: '%s' not found in path, and 'SHELL' not in environment\\n\",\r\n\t        argv[rest]);\r\n        return 0x8E; /* unrecognised command */\r\n      }\r\n      else \r\n        *prog=shell;\r\n    }\r\n    else\r\n      ++rest;\r\n  }\r\n  if (rest==argc)\r\n    *iniargs=\" \";\r\n  else {\r\n    for (i=rest, len=argc-rest ; i<argc ; ++i)\r\n      len+=strlen(argv[i]);\r\n    if (**prog) ++len;\r\n    if (len>ARGLEN-MARGIN) {\r\n      fprintf(stderr,\"xargs: the initial arguments take up too much space.\\n\");\r\n      return 0x8D; /* .BUFUL */\r\n    } \r\n    *iniargs=p=malloc(len+1);\r\n    if (**prog)\r\n      *p++=' ';\r\n    for (i=rest ; i<argc ; ++i) {\r\n      strcpy(p,argv[i]);\r\n      p+=strlen(argv[i]);\r\n      *p++=' ';\r\n    }\r\n    *p=0;\r\n  }\r\n  return 0;\r\n}\r\n\r\nint do_read(char * name, int fd, char* buf, unsigned blen)\r\n{\r\n  int len,res;\r\n  char *p;\r\n\r\n  res=0;\r\n  len=read(fd, buf, blen);\r\n  if (len<0) {\r\n    res=errno;\r\n    perror(name);\r\n    fputs(\" while reading.\\n\", stderr);\r\n    buf[0]=0;\r\n    res=1;\r\n  }\r\n  else {\r\n    buf[len]=0;\r\n    p=strchr(buf, 26); /* check for cp/m eof */\r\n    if (p) {\r\n      *p=0;\r\n      res=1;\r\n    }\r\n  }\r\n  return res;\r\n}\r\n\r\nint do_once(char * prog, char * argbuf, char * fds)\r\n{\r\n  int res;\r\n  if (verbose) {\r\n    if (do_exec) printf(\"[XARGS] \");\r\n    printf(\"%s%s\\n\", prog, argbuf);\r\n  }\r\n  if (do_exec)\r\n    res=_spawn(prog, argbuf, fds);\r\n  else\r\n    res=0;\r\n  return res;\r\n}\r\n\r\nint do_xargs(char * input, int in, char * prog, char * iniargs)\r\n{\r\n  int res, len;\r\n  unsigned char inilen;\r\n  char ateof, *p, *q, *tok, fds[3];\r\n  static char inbuf[BUFLEN+1];\r\n  static char argbuf[BUFLEN+1];\r\n  \r\n  if (0==in) {\r\n    res=open(\"NUL\", O_RDONLY|O_INHER);\r\n    if (res<0) {\r\n      res=errno;\r\n      perror(\"xargs: NUL\");\r\n      fputs(\" while opening for input.\\n\",stderr);\r\n      return res;\r\n    }\r\n    else\r\n      fds[0]=res;\r\n  }\r\n  else\r\n    fds[0]=0;\r\n  fds[1]=1; fds[2]=2;\t\r\n\r\n  res=0;\r\n  inilen=strlen(iniargs);\r\n  strcpy(argbuf, iniargs);\r\n  q=argbuf+inilen;\r\n  p=inbuf;\r\n  ateof=do_read(input, in, inbuf, BUFLEN);\r\n  while (*p||!ateof) {\r\n    tok=token(&p);\r\n    if (tok) {\r\n      len=strlen(tok);\r\n      if (len+inilen>ARGLEN) {\r\n        fprintf(stderr, \"%.20s... too long, ignored\\n\", tok);\r\n      }\r\n      else {\r\n        if (q+len>argbuf+ARGLEN) {\r\n\t  *q--=0;\r\n\t  if (' '==*q) *q=0;\r\n\t  res=do_once(prog, argbuf, fds);\r\n\t  q=argbuf+inilen;\r\n        }\r\n        strcpy(q,tok);\r\n        q+=len;\r\n        if (q<argbuf+ARGLEN)\r\n\t  *q++=' ';\r\n      }\r\n    }\r\n    if (!ateof && (p>inbuf+BUFLEN/2)) {\r\n      len=inbuf+BUFLEN-p;\r\n      memcpy(inbuf, p, len);\r\n      ateof=do_read(input,in,inbuf+len,BUFLEN-len);\r\n      p=inbuf;\r\n    }\r\n  }\r\n  *q--=0;\r\n  if (' '==*q) *q=0;\r\n  res=do_once(prog, argbuf, fds);\r\n\r\n  if (fds[0]) \r\n    close(fds[0]);\r\n  return res;\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n  char * argfile, * prog, *iniargs;\r\n  int fd, res;\r\n\r\n  res=parse(argc, argv, &argfile, &prog, &iniargs);\r\n  if (res) \r\n    return (0x8C==res) ? 0 : res;\r\n\r\n  if (argfile) {\r\n    fd=open(argfile, O_RDONLY);\r\n    if (fd<0) {\r\n      res=errno;\r\n      perror(argfile);\r\n      fprintf(stderr, \" while opening to read arguments. \\n\");\r\n      return res;\r\n    }\r\n  }\r\n  else\r\n    fd=0;\r\n\r\n  res=do_xargs(fd?argfile:\"(stdin)\", fd, prog, iniargs);\r\n\r\n  if (fd)\r\n    close(fd);\r\n}\r\n\r\n\u001a"
  },
  {
    "path": "overlays/B280OVR.SUB",
    "content": "c280\r\n<-c -of2 ovrload.c ovrbgn.as\r\n"
  },
  {
    "path": "overlays/BUILDOVR.SUB",
    "content": "c\r\n<-c -o ovrload.c ovrbgn.as\r\n"
  },
  {
    "path": "overlays/LIBOVR.SUB",
    "content": "era libovr.lib\r\nlibr \r\n<r libovr.lib \\\r\n<ovrload.obj ovrbgn.obj\r\n"
  },
  {
    "path": "overlays/M280LIBV.SUB",
    "content": "era lib280ov.lib\r\nlibr \r\n<r lib280ov.lib \\\r\n<ovrload.obj ovrbgn.obj\r\n"
  },
  {
    "path": "overlays/OVERLAY.H",
    "content": "#ifndef _HTC_OVERLAY_H\r\n#define _HTC_OVERLAY_H\r\n\r\n#include <stdint.h>\r\nintptr_t ovrload(char *ovr_name,intptr_t args);\r\n#endif\r\n"
  },
  {
    "path": "overlays/OVRBGN.AS",
    "content": "; Fake overlay\r\n\r\n\r\nsize\tequ\t05000h\t\t; max overlay size\r\n\r\n\tglobal\t__ovrbgn, __ovrsize, __ovrstart\r\n\r\n\tpsect\ttext\r\n\r\n__ovrsize:\r\n\tdefw\tsize\t\t; this should never be overlaid\r\n__ovrstart:\r\n\tdefw\t__ovrbgn\r\n\r\n\tpsect\tbss\t\t; this goes in the uninit bit\r\n__ovrbgn:\r\n\tdefs\tsize\t\t; reserve room for overlay\r\n\r\n\tend\r\n"
  },
  {
    "path": "overlays/OVREADME.TXT",
    "content": "\t\t\t** Overlays with Hi-Tech C **\r\n\r\n\tThe following procedure may be used to create overlays for use\r\nwith Hi-Tech C. Although messy to compile and link, it results in a smaller\r\nTPA being used by a given program. Thus larger programs can be created: the\r\nonly penalty is the time taken to load the overlay from disk.\r\n\r\n1. Creating the source files.\r\n\tAn overlay can be called from the main program using\r\n\r\n\t[value = ]ovloader(filename,argument);\r\n\r\nwhere <filename> is a string containing the overlay's filename (without the\r\n.ovr extension) and <argument> is a single argument to the function. The\r\nresult of the overlay may optionally be assigned to a value, as in any C\r\nfunction.\r\n\r\n\tThe overlay may reference functions, global symbols etc. in the main\r\nprogram, but otherwise appears as a normal C program, except that the main\r\nfunction must be called ovmain() instead of main().\r\n\r\n2. Linking and producing the overlays.\r\n\r\n\tThe main function must be linked first. Ensure that the modules\r\novloader.c and ovbgn.as (in that order) are linked as well, and request the\r\ncompiler to produce a symbol table (-F option).\r\n\tOnce this has been completed, run the SYM2AS program on the .SYM\r\nfile (e.g. SYM2AS TEST.SYM), and this will produce a file named MAIN.AS,\r\ncontaining the addresses from the main portion in assembler-source form.\r\nThen run ZAS on this (ZAS MAIN.AS), and this will produce a file named\r\nMAIN.OBJ. You will need this to link the overlays.\r\n\tYou will need to examine the MAIN.AS file, as you need the address\r\nof _ovbgn for the following step. Assume this is 01234h for the purposes\r\nof this explanation.\r\n\tCompile the overlay(s) with the -C option to result in .OBJ files.\r\nDo not invoke the linker as this will result in many errors! When you have\r\ndone this, make up a small ascii file (with wordstar etc.) to direct the\r\nlinker. The format of this file should be as follows (NOTE: MUST be in lower\r\ncase!):\r\n\r\n-c01234h -ptext=01234h,data -otest1.ovr test1.obj <other modules as reqd> \\\r\nmain.obj 0:a:libc.lib\r\n\r\n(assuming the overlay is to be test1.ovr, the source was test1.c). Other\r\nmodules may be linked in as well. Note the use of the \\ character to\r\ncontinue input onto the next line. Naturally, you should replace the '01234h'\r\nwith the actual value of _ovbgn as obtained from the MAIN.AS file.\r\n\r\n\tAssume this file is named TEST.LNK. You are now ready to link the\r\noverlay. Use the command\r\n\r\nLINK <TEST.LNK\r\n\r\n\tand it should rumble away to itself and complete. Note that you do\r\nnot have to repeat the linking and loading of the main segment if you only\r\nchange the overlay source: the same main.obj file may be used each time the\r\noverlay is re-linked. The TEST.LNK file should remain the same as well, but\r\nremember to alter it as necessary if you change the main program file.\r\n\r\n\tThe OVBGN.AS file contains an equate to set the maximum overlay\r\nsize: it is currently set to 5000h (20k). This should be sufficient for\r\nmost purposes, but it may be lowered if your overlays are small. If you link\r\nthe overlays with the -Mxxxx.MAP option in the .LNK file, a map of the\r\noverlay will be produced. Examination of this will show whether the max\r\noverlay size needs to be changed.\r\n\r\n\tAlthough messy, this process produces working overlays with Hi-Tech\r\nC. This compiler does seem to produce small, fast code for Z80 machines,\r\nand is probably worth persevering with.\r\n\r\n\t\t\t-- Ron Murray, 25/8/88\r\n\r\n\r\n"
  },
  {
    "path": "overlays/OVRLOAD.C",
    "content": "#include <overlay.h>\r\n#include <string.h>\r\n#include <unixio.h>\r\n\r\nextern unsigned _ovrsize;\r\nextern char *_ovrstart;\r\nextern intptr_t _ovrbgn(intptr_t args);\r\nextern char ovrfilename[15]={0};\r\n\r\n/* Overlay loader for Hi-Tech C */\r\nintptr_t ovrload(char *name,intptr_t args)\r\n{\r\n\tint fd, size;\r\n    char ovrname[9];\r\n\tchar filename[15], *p, *index();\r\n\r\n    strncpy(ovrname,name,8);\r\n    ovrname[8]=0;\r\n\tstrcpy(filename,ovrname);\t/* Copy the filename */\r\n\tstrcat(filename,\".ovr\");\t/* add the extent */\r\n\tif ((fd = open(filename, 0)) < 0)\r\n\t{\r\n\t\tstrcpy(filename,\"a0:\");\t/* not there -- see if it's on A0: */\r\n\t\tstrcat(filename, (p = index(ovrname,':')) ? p+1 : ovrname);\r\n\t\tstrcat(filename,\".ovr\");\r\n\t\tif ((fd = open(filename,0)) < 0) {\r\n\t\t\tgoto error;\t\t/* Not there either */\r\n        }\r\n\t}\r\n    if(!strcmp(filename,ovrfilename) && _ovrbgn) {\r\n        return _ovrbgn(args);\r\n    }\r\n\tsize = read(fd,_ovrstart,_ovrsize);\r\n\tclose(fd);\r\n\tif (size < 0 || !_ovrbgn) {\r\n\t\tgoto error;\t\t\t/* read error */\r\n    }\r\n    strcpy(ovrfilename,filename);\r\n\treturn _ovrbgn(args);\t\t/* ok, execute the overlay */\r\n\r\nerror:\r\n\treturn -1;\r\n}\r\n"
  },
  {
    "path": "overlays/SYMTOAS.C",
    "content": "/*\r\n *\tCopyright (C) 1984-1897 HI-TECH SOFTWARE\r\n *\r\n *\tThis software remains the property of HI-TECH SOFTWARE and is\r\n *\tsupplied under licence only. The use of this software is\r\n *\tpermitted under the terms of that licence only. Copying of\r\n *\tthis software except for the purpose of making backup or\r\n *\tworking copies for the use of the licensee on a single\r\n *\tprocessor is prohibited.\r\n */\r\n#include\t<stdio.h>\r\n#include\t<ctype.h>\r\n#include\t<string.h>\r\n#include\t<cpm.h>\r\n#include\t<exec.h>\r\n#include\t<stat.h>\r\n#include    <sys.h>\r\n#include    <stdlib.h>\r\n#include    <unixio.h>\r\n\r\n#define MAXLINE (200)\r\n#define START (\"__ovrbgn\")\r\nint sym2as(char * fname, char * tmpas);\r\n\r\nint main(int argc, char ** argv) {\r\n    int rc=0;\r\n    if(argc<2) {\r\n        fprintf(stderr,\"SYMTOAS V1.00\\n\");\r\n        fprintf(stderr,\"Missing sym file\\n\");\r\n        return -1;\r\n    }\r\n    if(argc==2) {\r\n        rc=sym2as(argv[1],0);\r\n    } else {\r\n        rc=sym2as(argv[1],argv[2]);\r\n    }\r\n    if(rc==-1) {\r\n        return -1;\r\n    }\r\n    return 0;\r\n}\r\n\r\nint sym2as(char * fname, char * tmpas) {\r\n    static char line[MAXLINE+1];\r\n    char *addr=line;\r\n    char *sym=line+5;\r\n    register int i=0;\r\n    register int j=0;\r\n    int c=0;\r\n    char* r=0;\r\n    int base=0x100;\r\n    FILE * in;\r\n    FILE * out;\r\n\r\n    in=fopen(fname,\"rt\");\r\n    if(!in) {\r\n        fprintf(stderr,\"Cannot open %s\\n\",fname);\r\n        return -1;\r\n    }\r\n    if(0==tmpas) {\r\n        out=stdout;\r\n    } else {\r\n        out=fopen(tmpas,\"wt\");\r\n        if(!out) {\r\n            fclose(in);\r\n            return -1;\r\n        }\r\n    }\r\n    fprintf(out,\"%31s\\n\",\"psect data\");\r\n    while(!feof(in)&& !ferror(in)) {\r\n        i=0; \r\n        while(i<MAXLINE) {\r\n            c=fgetc(in);\r\n            if(isspace(c)&&(i==0)) {\r\n                continue;\r\n            }\r\n            if(c==EOF ||c=='\\n'||c=='\\r') {\r\n                break;\r\n            }\r\n            line[i++]=c;\r\n        }\r\n        line[i]=0;\r\n        r=index(line,' ');\r\n        if(!r) {\r\n            continue;\r\n        }\r\n        *r=0;\r\n        addr=line;\r\n        sym=r+1;\r\n        while(*sym && isspace(*sym)) {\r\n            sym++;\r\n        }\r\n        fprintf(out,\"%27s %s\\n\",\"global\",sym);\r\n        if(strlen(addr)>4) {\r\n            addr+=strlen(addr);\r\n            addr-=4;\r\n        }\r\n        for(j=strlen(sym)-1;j>=0;j--) {\r\n            if(isspace(sym[j])) {\r\n                sym[j]=0;\r\n            }\r\n        }\r\n        fprintf(out,\"%-20s %s 0%sh\\n\",sym,\"defl\",addr);\r\n    }\r\n    fprintf(out,\"%24s\\n\",\"end\\n\");\r\n    if(ferror(in)) {\r\n        fclose(in);\r\n        if(0!=tmpas) {\r\n            fclose(out);\r\n        }\r\n        return -1;\r\n    }\r\n    fclose(in);\r\n    if(0!=tmpas) {\r\n        fclose(out);\r\n    }\r\n    return base;\r\n}\r\n"
  },
  {
    "path": "pipemgr/MKRSX.SUB",
    "content": "z80asm pipemgr/m\r\n:link pipemgr[op nr]\r\n:erase pipemgr.rel\r\n:erase pipemgr.rsx\r\nrename pipemgr.rsx=pipemgr.prl\r\n"
  },
  {
    "path": "pipemgr/PIPEMGR.C",
    "content": "/*********************************************************************\r\n* PIPEMGR helper subroutines. One tests if stdin is coming from a    *\r\n* pipe, and the other shuffles the arguments so that blank arguments *\r\n* are dropped.                                                       *\r\n**********************************************************************/\r\n\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <ctype.h>\r\n#include <sys.h>\r\n#include <cpm.h>\r\n#include \"pipemgr.h\"\r\n\r\nextern int _piped;\r\n\r\nstruct\r\n{\r\n      char func;\r\n      char npars;\r\n      char *txt;\r\n} pcb = {0x76, 1, \"PIPEMGR \"};\r\n\r\n\r\nint stdin_piped(void)\r\n{\r\n      if (!_piped) return 0;\r\n\r\n      return (bdoshl(0x3C, &pcb) & 0x100);\r\n}\r\n\r\n\r\nvoid init_args(int *argc, char ***argv)\r\n{\r\n    int i,j;\r\n\r\n    for (i = 1; i < (*argc); i++)\r\n    {\r\n        if ((*argv)[i][0]) continue;\r\n        for (j = i; j < ((*argc) - 1); j++) (*argv)[j] = (*argv)[j+1];\r\n        --i; \r\n        --(*argc);\r\n    }\r\n}\r\n\r\n\r\nchar safe_toupper(char c)\r\n{\r\n      if (!islower(c)) return c;\r\n      return toupper(c);\r\n}\r\n\r\n"
  },
  {
    "path": "pipemgr/PIPEMGR.DOC",
    "content": "===============================================================================\nPIPEMGR v1.02    Pipe manager for CP/M Plus       John Elliott, 3 January 2000.\n===============================================================================\n\nRecent changes: PIPEMGR 1.00 contained bugs when the output of one program\n               was piped to another. This could result in a \"can't open input\"\n               error. It also overwrote a file when asked to append to it.\n               These bugs have been fixed in v1.02.\n\n  This documentation is for programmers who want to use PIPEMGR in their\nown programs. Hardly any of the information here need be handed on to the\nusers of the programs - just the details of the command line syntax (for \nexample, see EGDOC.TXT).\n\n  PIPEMGR.RSX (only) is distributed under the GNU Library General Public\nLicense, version 2 (see COPYING.LIB). The accompanying utilities may be \ndistributed freely, but no source is provided.\n\n  Those of us who have used DOS or UNIX computers will be familiar with\nthe idea of the \"pipe\" - a system by which the output of a program may be\nsent directly into the input of another. This functionality is not present in\nCP/M, although there have been some program suites (such as the Van Nuys \nTools) which could simulate it.\n\n  PIPEMGR is another program of this type. It is an RSX module, which should\nbe attached to suitable programs with GENCOM. When it is attached, it adds \nvarious system calls designed to make implementation of pipes easier to \nprogram. It supports three devices: \n\n - Standard input (stdin) - input to the program, either from the keyboard or\n  from a file.\n - Standard output (stdout) - conventional data output from the program, \n  perhaps to a screen or to a file.\n - Standard error (stderr) - error messages output by the program.\n\n  PIPEMGR requires CP/M-80 version 3 (CP/M Plus) and a Z80 processor.\n\nPIPEMGR API\n=========== \n\n  All calls are made to the BDOS (CALL 5) with C=3Ch and DE pointing to an\narea of memory (the RSXPB) whose format is described in each function. Note \nthat these functions behave like genuine BDOS functions; they return data in\nHL = BA and corrupt C, D, E and the flags. What happens to the Z80 registers \nIX etc. is left to the discretion of the BIOS.\n\n - Initialise PIPEMGR. This call should always be made before attempting to\n  use the features of PIPEMGR.\n\n      RSXPB:    DEFB 79h,1      ;Function code\n                DEFW addr       ;Address of authentication string\n\n      addr:     DEFB 'PIPEMGR ' ;authentication string\n\n    This function scans the standard command tail at 80h for any of the \n  following redirection operations:\n\n    <file    - Standard input comes from \"file\".\n    >file    - Standard output is sent to \"file\". If \"file\" exists, it is \n              deleted.\n   >>file    - Standard output is appended to \"file\".\n   >&file    - Standard output and standard error are sent to \"file\".\n   >>&file   - Standard output and standard error are appended to \"file\".\n   |command  - Standard output is sent into the standard input of \"command\"\n              (which is a standard CP/M command) via a file on the temporary\n              file drive (set using SETDEF). \n   |&command - Standard output and standard error are sent into the standard\n              input of the next program.\n\n    The filenames can be right up against the redirection symbols, or have\n  a space between them (ie,  \">file\"  or  \" > file\"  ).\n    Any filename passed to PIPEMGR can include user numbers, for example:\n\n      10A:FILE.TXT\n       B5:README.1ST\n        0:PROFILE.SUB\n\n    It can also handle four special device names:\n\n    CON: - The current screen/keyboard device(s) as set by DEVICE CON:=xxx\n    AUX: - The current auxiliary device(s) as set by DEVICE AUX:=xxx\n    LST: - The current printer as set by DEVICE LST:=xxx\n    NUL: - Nothing. Inputting from it returns End-Of-File; output to it is \n          lost. \n\n    Note that unlike DOS, the : at the end of the device name is mandatory,\n  and you can't prepend \\DEV\\ to the device name.\n\n    If any PIPEMGR operator is found, then it will be replaced in the command\n  by spaces - so, when your program is called with:\n\n   MYPROG <file1 /G |GREP Fish\n\n  after this call, it will look as if the user had typed:\n\n   MYPROG        /G\n        \n    Take care of this if you're programming in a language like Hi-Tech C. In \n  the above example, argv[1] to argv[8] will be strings of zero length, and \n  argv[9] will hold the \"/G\" option.\n\n  This function returns HL=00FFh if PIPEMGR is not present, or 0 if it is.\n\n - Read a byte from standard input.\n\n      RSXPB:    DEFB 7Ch,0\n\n   Returns H=0 if end-of-file - otherwise H is nonzero and L=the byte read. \n  There are some special considerations to deal with when considering what \n  constitutes an end-of-file; see \"File sizes\" below.\n\n - Write a byte to standard output.\n\n      RSXPB:    DEFB 7Dh,1\n                DEFB byte,0\n\n    Returns with HL undefined.\n\n - Write a byte to standard error.\n\n      RSXPB:   DEFB 7Ah,1\n               DEFB byte,0\n\n    Returns with HL undefined.\n\n - Emergency terminate PIPEMGR (pending data not written to disc).\n\n      RSXPB:  DEFB 7Fh,1          ; or 7Eh,1\n              DEFW addr           ;address of authentication string\n\n      addr:   DEFB 'PIPEMGR '                                \n\n    Returns with HL undefined. This can be called at any time to force PIPEMGR\n   to quit.\n\n - Return PIPEMGR version.\n\n      RSXPB:  DEFB 7Bh,1\n              DEFW addr           ;address of authentication string.\n\n      addr:   DEFB 'PIPEMGR '\n\n    Returns H = major version number (BCD), L = minor version (BCD). Currently\n    returns 0100h (1.00). If PIPEMGR is not loaded, returns HL=00FFh.\n\n - Return PIPEMGR status\n\n      RSXPB:  DEFB 76h,1\n              DEFW addr           ;address of authentication string.\n\n      addr:   DEFB 'PIPEMGR '\n\n  Returns B=H=bitmapped flags:\n\n     Bit 0 set if stdin  is redirected\n     Bit 1 set if stdout is redirected\n     Bit 2 set if stderr is redirected\n     Bit 3 set if redirected input is coming from a pipe\n     Bit 4 set if redirected input is going to a pipe\n\n  This call can be used (for example) to check whether your program should\n pause after every screen of information. If output is redirected, it will;\n but if not, then the paged screen can be used.\n\n - There is no need to call any function when your program quits. \n\nIn Use\n======\n\n  Having created your program, and used GENCOM to combine it with PIPEMGR:\n\nGENCOM myprog PIPEMGR\n\nthen the program will be capable of performing the redirections and pipings\nlisted above. If you are creating a pipe (ie, a series of commands separated\nby | symbols) then all the programs in the pipe except possibly the last\nmust have been written to use the PIPEMGR functions; so:\n\nFOO |BAR |BAZ |TEE PANCAKE |PIP LST:=CON:[N]\n\nis a valid pipe provided that FOO.COM, BAR.COM, BAZ.COM and TEE.COM were all\nwritten to use the PIPEMGR functions. The last program (in this case, \nPIP.COM) does not need to be a PIPEMGR program. For more details on piping\ninto a non-PIPEMGR program, see below.\n\nFile sizes\n==========\n\n  Under CP/M versions 1 and 2, file sizes could not be stored exactly, but only\nto the nearest 128 bytes. Because of this, text files which were not an exact\nmultiple of 128 bytes in length would have an End-Of-File marker added (^Z,\nASCII 26). \n  CP/M 3 and its 80x86 successors (DOSPLUS, REAL/32 etc.) can store file sizes\nexactly. This feature is used by very few programs, though; most still rely on\nthe ^Z character.\n\n  PIPEMGR always uses the exact file size, and treats ^Z as just another \ncharacter. This is consistent with the behaviour of UNIX, and allows binary\nfiles to be sent through pipes without being damaged. Thus a program which\nwants to read a text file from standard input will have to check two \nconditions:\n  1. That on return, H is nonzero.\n  2. That if H is nonzero, L is not 26 (1Ah, ^Z). \n\n  Files created by PIPEMGR always have the exact size set. For compatibility\nwith programs which do not use exact sizes, any unused bytes in the last \nrecord are set to ^Z (1Ah). \n  When a pipe is in operation, the number of bytes received by the second \nprogram is the same as the number sent by the first; no ^Z characters are\nappended.\n  If you want to be able to preserve exact lengths when copying files, \nuse PPIP v1.9 or later.\n\nPiping into a non-PIPEMGR program\n=================================\n\n  PIPEMGR can be used to simulate keyboard input into a program even if that\nprogram does not use the PIPEMGR calls. As long as the program uses BDOS calls\nto read the keyboard, PIPEMGR can simulate input into it. The following \nBDOS functions are modified only when:\ni)   A pipe is in use.\nii)  The currently running program has not used the \"Initialise PIPEMGR\" call.\niii) Bits 8 and 9 of the console mode word are not both set. Setting both these\n    bits is a signal to disable all console redirection.\n\nC=01h: Input character.\n    The next character from the pipe is read in. Both carriage returns and \n  line feeds are passed to the program (for compatibility with PIP). When\n  no more characters are available, ^Z is returned. The character is not\n  echoed to the screen.\n\nC=06h: Direct console I/O (input functions).\n  E=0FFh: As C=01h.\n  E=0FEh: As C=0Bh.\n  E=0FDh: As C=01h.\n\n0Ah: Input line.\n  Reads in characters until the buffer is full, or a CR or LF character is\n encountered, or no more characters are available. The characters are not\n echoed. When no more characters are available, it returns a blank line.\n\n0Bh: Console status.\n  The exact effect of this command depends on the setting of bits 8 and 9 of\n  the console mode word:\n\nbits 9 8\n     0 0  - \"Compatibility\" mode. All calls to this function return 0, unless\n           they immediately follow another call to this function. This is the\n           same behaviour that SUBMIT and GET exhibit. The second call will \n           return 0FFh.\n     0 1  - Always returns 0FFh.\n     1 0  - Always returns 0.\n     1 1  - Input from PIPEMGR is disabled; the keyboard will be used.\n\nPIPEMGR and other piping systems\n================================\n\n  Since PIPEMGR can simulate keyboard input, it can be used with programs\nthat use other piping systems (such as the DIO library). Here's an example:\n\nPMPROG1 | PMPROG2 | DIOPROG1 | DIOPROG2\n\nThe first two '|' symbols are controlled by PIPEMGR; the third one is \ncontrolled by DIO, and its behaviour has no connection with PIPEMGR. \n  Unfortunately, it is not possible to do this the other way round. DIO\nprograms cannot cope with CP/M Plus RSX headers, so a pipeline like:\n\nDIOPROG1 | DIOPROG2 | PMPROG1 |PMPROG2 \n\nwill not work (PMPROG1 will not execute). You will have to simulate it with:\n\nDIOPROG1 | DIOPROG2 >tmp.$$$ ! PMPROG1 <tmp.$$$ | PMPROG2 ! era tmp.$$$\n\n(commands separated by ! marks and PIPEMGR pipes can apparently be mixed\nfreely.)\n\n  PIPEMGR versions of the Van Nuys Tools (the major DIO suite) have been \nwritten by me and should be available wherever you got PIPEMGR. Note that\nthey include their own versions of LS, CAT and TEE.\n\nHi-Tech C library\n=================\n\n  A modified version of the Hi-Tech C library (LIBC.LIB) is provided. \nSee LIBCNEW.DOC for details.\n\n\n"
  },
  {
    "path": "pipemgr/PIPEMGR.H",
    "content": "\r\n#define MAXLINE 150\r\n#define TRUE 1\r\n#define FALSE 0\r\n\r\nextern int _piped;\r\n\r\nextern int stdin_piped(void);\r\nextern void init_args(int *argc, char ***argv);\r\nextern char safe_toupper(char c);\r\n\r\n"
  },
  {
    "path": "pipemgr/PIPEMGR.TXT",
    "content": "This is a somewhat modified version of PIPEMGR.RSX by John Elliott.\r\n\r\nPIPEMGR is an RSX which when attached to suitable programs provides input and\r\noutput redirection capability.  One possible use is to capture the output of\r\na program to a text file.  The DISKINFO tool supplied on Tesseract volume 89\r\nis such a program.  So are pograms compiled with the updated Hi-Tech C from\r\nTesseract tvolume 91.\r\n\r\nThe archive contains TEE.COM which has the pipe manager RSX attached and so\r\nbehaves like its namesake in the UNIX world.\r\n\r\nJon Saxton\r\nJune 2014\r\n\r\nVersion 1.03 of PIPEMGR reverts the last sector byte count to the\r\nDOS Plus interpretation as the number of USED bytes.  To revert to\r\nthe Jon Saxton ISIS interpretation (number of UNUSED bytes) change\r\nthe conditional 'exact' to -1 and rebuild using MKRSX.SUB\r\n\r\nTony Nicholson\r\n17-Mar-2022\r\n"
  },
  {
    "path": "pipemgr/PIPEMGR.Z80",
    "content": ";------------------------------------------------------------------------------\r\n;\tPIPEMGR - piping and redirection for CP/M Plus and Z80 CPU.\r\n;\r\n; Copying policy: GNU Library GPL, version 2.\r\n;------------------------------------------------------------------------------\r\n; Original code by John Elliott\r\n;\thttp://www.seasip.demon.co.uk/Cpm/software/Pipemgr/index.html\r\n;\r\n; Source comments, BDOS call names, RSX call names and FCB field names added\r\n; by Jon Saxton, May 2014.  In general, comments with a space after the semi-\r\n; colon are mine while those without a space are John Elliott's originals.\r\n;------------------------------------------------------------------------------\r\n; 2022-03-18\tagn\tTony Nicholson\r\n;\r\n; Reverted to use the DOS Plus convention for actual file size (added\r\n; an 'exact' conditional so that PIPEMGR can be rebuilt to use the\r\n; ISIS convention if required), and bumped version to 1.03.\r\n;\r\n;------------------------------------------------------------------------------\r\n; 2014-04-03\tjrs\r\n;\r\n; Added one instruction and deleted four to change the sense of the \"last\r\n; sector byte count\" to mean the number of UNUSED bytes in the last sector.\r\n;------------------------------------------------------------------------------\r\n; 2014-05-20\tjrs\r\n;\r\n; Found a long-standing bug in the > redirection operator.  If the target file\r\n; does not have a drive specifier then the temporary file is created on the\r\n; currently logged-in drive.  If the host program logs onto a different drive\r\n; then the RSX loses connection to the temporary and target files.\r\n;\r\n; The solution was simple.  A drive number was added to the FCB.\r\n;------------------------------------------------------------------------------\r\n; 2014-05-21\tjrs\r\n;\r\n; Altered > and >> redirection operators to write directly to the output file\r\n; rather than writing to a temporary file and subsequently renaming it.  This\r\n; fixed a bug in the >> operator which would never append to a file.\r\n;------------------------------------------------------------------------------\r\n\t.z80\r\n\r\nCR\t  equ\t13\r\nLF\t  equ\t10\r\n\r\nrename\tequ\t 0\t\t; -1 to have > operator write to a temporary\r\n\t\t\t\t;    file and then rename that file on exit;\r\n\t\t\t\t;  0 to have > operator write to the named\r\n\t\t\t\t;    file directly\r\n\r\nexact\tequ\t0\t\t;agn - revert to DOS Plus mode\r\n\t\t\t\t;  0 Selects the DOS Plus exact file size\r\n\t\t\t\t;    where the last sector byte count\r\n\t\t\t\t;    contains the number of USED bytes\r\n\t\t\t\t;    but 0 means 128\r\n\t\t\t\t; -1 Selects the ISX/ISIS convention for\r\n\t\t\t\t;    exact file size where the last sector\r\n\t\t\t\t;    byte count contains the number of\r\n\t\t\t\t;    UNUSED bytes\r\n\r\n; BDOS calls\r\n; ==========\r\nCONIN\t  equ\t  1\t\t; 01 - Input from console (keyboard)\r\nCONOUT\t  equ\t  2\t\t; 02 - Output to console\r\nAUXIN\t  equ\t  3\t\t; 03 - Input from auxiliary device\r\nAUXOUT\t  equ\t  4\t\t; 04 - Output to auxiliary device\r\nLSTOUT\t  equ\t  5\t\t; 05 - Output to list device (printer)\r\nDCONIO\t  equ\t  6\t\t; 06 - Direct console I/O\r\nCOSTR\t  equ\t  9\t\t; 09 - Console output of string\r\nRDCONBUF  equ\t 10\t\t; 0A - Read console buffer\r\nCONSTAT\t  equ\t 11\t\t; 0B - Get console status\r\nSELDRV\t  equ\t 14\t\t; 0E - Select drive\r\nOPENF\t  equ\t 15\t\t; 0F - Open file\r\nCLOSEF    equ\t 16\t\t; 10 - Close file\r\nDELETEF\t  equ\t 19\t\t; 13 - Delete file\r\nCURDRV\t  equ\t 25\t\t; 19 - Get current drive\r\nSETDMA\t  equ\t 26\t\t; 1A - Set DMA address\r\nREADSEQ\t  equ\t 20\t\t; 14 - Sequential read\r\nWRITESEQ  equ\t 21\t\t; 15 - Sequential write\r\nCREATEF\t  equ\t 22\t\t; 16 - Create file\r\nRENAMEF\t  equ\t 23\t\t; 17 - Rename file\r\nSETATTR\t  equ\t 30\t\t; 1E - Set file attributes (& length)\r\nGSUSER\t  equ\t 32\t\t; 20 - Get/set user number\r\nREADRAN\t  equ\t 33\t\t; 21 - Random read\r\nWRITERAN  equ\t 34\t\t; 22 - Random write\r\nSIZEF\t  equ\t 35\t\t; 23 - Compute file size\r\nERRMODE\t  equ\t 45\t\t; 2D - Set error mode\r\nCHAIN\t  equ\t 47\t\t; 2F - Chain to program\r\nACCSCB\t  equ\t 49\t\t; 31 - Access SCB (System Control Block)\r\nCALLRSX\t  equ\t 60\t\t; 3C - Call RSX\r\nCONMODE\t  equ\t109\t\t; 6D - Get/set console mode\r\nPARSEFN\t  equ\t152\t\t; 98 - Parse file name\r\n\r\n; PIPEMGR functions\r\n; =================\r\nPMSTAT\t  equ\t118\t\t; 76 - Get PIPEMGR status\r\nPMINIT\t  equ\t121\t\t; 79 - Initialise\r\nPMSTERR\t  equ\t122\t\t; 7A - Write byte to stderr\r\nPMVER\t  equ\t123\t\t; 7B - Get PIPEMGR version\r\nPMSTINP   equ\t124\t\t; 7C - Read byte from stdin\r\nPMSTOUT\t  equ\t125\t\t; 7D - Write byte to stdout\r\nPMTERM1\t  equ\t126\t\t; 7E - Emergency termination\r\nPMTERM2\t  equ\t127\t\t; 7F - Emergency termination\r\n\r\n;------------------------------------------------------------------------------\r\n;\t\t\t\tFCB layout\r\n;\r\n; Note that fields beyond .rr are not part of the standard CP/M file control\r\n; block.  Furthermore, the treatment of those fields in this RSX is different\r\n; from that defined in cpm.h and used by Hi-Tech C programs.\r\n;------------------------------------------------------------------------------\r\n;\t      offset    length\tdescription\r\n;\t\t--\t  --\t----------------------------------------\r\n.dr\tequ\t 0\t;  1\tDrive code\r\n.fn\tequ\t 1\t;  8\tFile name\r\n.ft\tequ\t 9\t;  3\tFile type\r\n.ex\tequ\t12\t;  1\tExtent\r\n.s1\tequ\t13\t;  1\tSystem use.  May hold user number (ZPM3)\r\n.s2\tequ\t14\t;  1\tSystem use.  May hold drive number (ZPM3)\r\n.rc\tequ\t15\t;  1\tNumber of records in current extent (.ex)\r\n.dm\tequ\t16\t; 16\tDisk map (filled in by CP/M)\r\n.cr\tequ\t32\t;  1\tCurrent record for sequential read or write\r\n.rr\tequ\t33\t;  3\tRandom record number (24 bit no.)\r\n.r0\tequ\t33\t;  1\tIndividual offsets for random record\r\n.r1\tequ\t34\t;  1\t /\r\n.r2\tequ\t35\t;  1\t/\r\n; RSX usage\r\n.??\tequ\t36\t;  1\tNot used in the original code\r\n.ud\tequ\t37\t;  1\tUser number or device code\r\n;------------------------------------------------------------------------------\r\n\tcseg\r\n;------------------------------------------------------------------------------\r\n;\t\t\t      RSX prefix\r\n;------------------------------------------------------------------------------\r\n\tdefs\t6\t\t;CP/M version\r\njump:\tjp\tinit\t\t;First call is a special case\r\nfdos:\tjp\t6\t\t;FDOS (overwritten by loader)w\r\nPrev:\tdefw\t7\t\t;Previous RSX\r\ndelete:\tdefb\t0ffh\t\t;Delete this RSX?\r\nbanked:\tdefb\t0\t\t;Banked system flag\r\nrname:\tdefb\t'PIPEMGR '\r\n\tdefb\t0,0,0\r\n\r\n;------------------------------------------------------------------------------\r\n;\t\tInitial entry.  This code is only executed once.\r\n;------------------------------------------------------------------------------\r\ninit:\tpush\tbc\r\n\tpush\tde\r\n\tsub\ta\r\n\tjp\tpe,bypass\t;Can't run on an 8080.\r\n\tld\tc,CALLRSX\r\n\tld\tde,verchk\r\n\tcall\tfdos\r\n\tinc\ta\r\n\tjr\tz,nomgr\t\t;No duplicate PIPEMGR loaded\t\r\nbypass:\tld\thl,fdos\r\n\tld\t(jump+1),hl\t;Bypass PIPEMGR\t\r\n\tpop\tde\r\n\tpop\tbc\r\n\tjr\tfdos\r\n\r\nnomgr:\tld\thl,catch\r\n\tld\t(jump+1),hl\r\n\tpop\tde\r\n\tpop\tbc\r\n;------------------------------------------------------------------------------\r\n;\t\tSubsequent entry to this RSX is redirected here\r\n;------------------------------------------------------------------------------\r\n\r\ncatch:\r\n\tld\ta,c\r\n\tcp\tCONMODE\t\t;Set console mode\r\n\tjr\tnz,catch0\r\n\tld\ta,h\r\n\tand\t3\r\n\tld\t(cpol),a\r\n\tld\ta,c\r\ncatch0:\r\n\tcp\tSETDMA\r\n\tjr\tnz,catch1\r\n\tld\t(dma),de\r\ncatch1:\r\n\tld\ta,(PipedI)\r\n\tor\ta\r\n\tjr\tz,catch2\r\n\tld\ta,(awake)\r\n\tor\ta\r\n\tjr\tnz,catch2\r\n\r\n;RSX asleep, but input is piped.\r\n\r\n\tld\ta,(cpol)\r\n\tcp\t3\r\n\tjr\tz,catch2\t;Is keyboard redirection disabled?\r\n\tld\ta,c\r\n\tcp\tCONSTAT\r\n\tjp\tz,con11\t\r\n\txor\ta\r\n\tld\t(ckey),a\t;Last call was not for console status\r\n\tld\ta,c\r\n\tcp\tCONIN\r\n\tjp\tz,con1\r\n\tcp\tDCONIO\r\n\tjp\tz,con6\r\n\tcp\tRDCONBUF\r\n\tjp\tz,con10\r\ncatch2:\tld\ta,c\r\n\tcp\tCALLRSX\r\n\tjp\tnz,fdos\r\n\tld\ta,(de)\t\t;Sub-function number\r\n\tcp\tPMVER\r\n\tjp\tz,chkver\r\n\tcp\tPMINIT\r\n\tjr\tz,initrsx\r\n\tld\ta,(awake)\r\n\tor\ta\t\t;0 if RSX asleep\r\n\tjp\tz,fdos\r\n\tld\ta,(de)\r\n\tcp\tPMSTERR\r\n\tjp\tz,PipeErr\r\n\tcp\tPMSTOUT\r\n\tjp\tz,PipeOut\r\n\tcp\tPMSTINP\r\n\tjp\tz,PipeIn\r\n\tcall\tidrsx\r\n\tjr\tnz,jfdos\r\n\tld\ta,(de)\r\n\tcp\tPMTERM2\t\t;Kill RSX\r\n\tjp\tz,killrsx\r\n\tcp\tPMTERM1\t\t;Kill RSX\r\n\tjp\tz,killrsx\r\n\tcp\tPMSTAT\r\n\tjr\tz,rxstat\r\njfdos:\tjp\tfdos\r\n\r\nrxstat:\tld\ta,(inflg)\t;Return bitmapped flags\r\n\tand\t1\r\n\tld\th,a\r\n\tld\ta,(outflg)\t;Output via PIPEMGR?\r\n\tand\t2\r\n\tor\th\r\n\tld\th,a\r\n\tld\ta,(errflg)\r\n\tand\t4\r\n\tor\th\r\n\tld\th,a\r\n\tld\ta,(PipedI)\r\n\tand\t8\r\n\tor\th\r\n\tld\th,a\r\n\tld\ta,(PipedO)\r\n\tand\t16\r\n\tor\th\r\n\tld\th,a\r\n\tld\tb,a\r\n\txor\ta\r\n\tld\tl,a\r\n\tret\r\n\r\ninitrsx:\r\n\tcall\tidrsx\r\n\tjr\tnz,jfdos\r\n\r\n;Initialise PIPEMGR. \r\n\r\n\tld\ta,0ffh\t\t;RSX has been awakened\r\n\tld\t(awake),a\r\n\txor\ta\r\n\tld\t(pclosed),a\t;Pipe file does not need opening\r\n\tld\ta,(PipedI)\r\n\tor\ta\r\n\tjr\tz,initr0\r\n\tld\ta,-1\r\n\tld\t(inflg),a\r\ninitr0:\r\n\tld\tde,80h\r\n\tld\ta,(de)\r\n\tinc\tde\r\n\tld\tl,a\r\n\tld\th,0\r\n\tadd\thl,de\r\n\tld\t(hl),0\r\nckpipe1:\r\n\tld\ta,(de)\r\n\tld\t(pstrt),de\r\n\tcp\t'<'\r\n\tjr\tz,parsein\r\n\tcp\t'>'\r\n\tjr\tz,parseout\r\n\tcp\t'|'\r\n\tjr\tz,parsepi\r\n\tcp\t'\\'\r\n\tjr\tz,parsebk\r\n\tor\ta\r\n\tjr\tz,endcall\r\n\tinc\tde\r\n\tjr\tckpipe1\t\r\n\r\nparsebk:\r\n\tinc\tde\r\n\tld\ta,(de)\r\n\tor\ta\r\n\tjr\tz,endcall\r\n\tjr\tckpipe1\t\r\n\r\nparsein:\t\r\n\tld\thl,infcb\r\n\tcall\tfparse\r\n\tjr\tckpipe1\r\n\r\nparseout:\r\n\tinc\tde\r\n\tld\ta,(de)\r\n\tcp\t'&'\r\n\tjr\tz,parso1\r\n\tcp\t'>'\r\n\tjr\tz,parsa1\r\n\tdec\tde\r\n\tjr\tparso2\r\n\r\nparsa1:\r\n\tinc\tde\r\n\tld\ta,1\r\n\tld\t(oapp),a\r\n\tld\ta,(de)\r\n\tcp\t'&'\r\n\tjr\tz,parso1\r\n\tdec\tde\r\n\tjr\tparso2\r\n\r\nparso1:\r\n\tld\ta,-1\r\n\tld\t(errflg),a\r\nparso2:\r\n\tld\thl,outfcb\t; [2014-05-21 jrs]\r\n\tcall\tfparse\r\n\tjr\tckpipe1\r\n\r\nparsepi:\r\n\tinc\tde\r\n\tld\ta,(de)\r\n\tcp\t'&'\r\n\tjr\tz,parsp1\r\n\tdec\tde\r\n\tpush\tde\r\n\tjr\tparsp2\r\n\r\nparsp1:\r\n\tld\ta,-1\r\n\tld\t(errflg),a\r\n\tpush\tde\r\nparsp2:\r\n\t; +++ Note to myself ...\r\n\t;\r\n\t; This may need to have a drive plugged in to prevent issues when\r\n\t; the host program logs onto a different drive.  However, check\r\n\t; the usage of the CP/M temporary drive setting a few instructions\r\n\t; further on.\r\n\t;\r\n\t; On the next instruction, why the -1 ???\r\n\r\n\tld\tde,pipeo$-1\r\n\tld\thl,outfcb\r\n\tcall\tfparse\r\n\tcall\ttempdrv\r\n\tld\t(outfcb+.dr),a\r\n\tpop\thl\t\t;Command after the '|'\r\n\tld\t(hl),0\t\t;End it\r\n\tinc\thl\r\n\tld\tde,pipenxt\r\n\tld\tbc,80h\r\n\tldir\r\n\tld\ta,-1\r\n\tld\t(PipedO),a\r\nendcall:\r\n\r\n;[20-11-1998] File names parsed.\r\n;\r\n; [jrs 2014-05-18]\r\n;\r\n; The original code wrote redirected output to a temporary file $PIPEMGR.$$$\r\n; and, on exit, renamed that file to the one specified on the command line as\r\n; the redirection target.\r\n;\r\n; That presented a problem with the append operator (>>) because the output\r\n; really needed to be written to the target file and not to a temporary one.\r\n;\r\n; For the simple redirect operator (>) there seems little point in writing to\r\n; a temporary file and then renaming it.  It has the advantage of preserving\r\n; the original output file in the event that something gets screwed up but the\r\n; use of the > operator suggests that the user is prepared to have the file\r\n; overwritten anyway.\r\n\r\n;------------------------------------------------------------------------------\r\n; [2014-04-20 jrs] Ensure that a drive number is included in the FCB in case\r\n; the host program switches to a different drive.\r\n\r\n\tld\ta,(outfcb)\r\n\tor\ta\t\t; Is a drive specified on the command line?\r\n\tjr\tnz,ec0\t\t; Skip if so\r\n\tld\tc,CURDRV\t; Get current drive\r\n\tcall\tfdos\r\n\tinc\ta\t\t; 0-15 -> 1-16\r\n\tld\t(outfcb+.dr),a\r\nec0:\r\n;------------------------------------------------------------------------------\r\n\tld\ta,(inflg)\r\n\tor\ta\r\n\tcall\tnz,openin\r\n\tcall\tobuf1A\r\n\tld\tde,outfcb\r\ncreat:\r\n\tpush\tiy\r\n\tpush\tde\r\n\tpop\tiy\r\n\tld\ta,(iy-1)\r\n\tor\ta\r\n\tjp\tz,fcreat\t;No creation required\r\n\tld\ta,(iy+.ud)\r\n\tcp\t20h\r\n\tjr\tnc,dcreat\t;Character device\r\n\tcall\tclrflds\r\n\tld\ta,(oapp)\r\n\tor\ta\r\n\tjp\tnz,append\r\nrcreat:\r\n\tld\tc,DELETEF\r\n\tcall\tfcbdos\r\n\tcall\tclrflds\r\n\txor\ta\r\n\tld\t(outptr),a\r\n\tld\t(iy+.??),a\r\n\tld\tc,CREATEF\r\n\tcall\tfcbdos\r\n\tinc\ta\r\n\tjp\tz,ecreat\r\ndcreat:\r\n\tcall\thookwb\r\n\txor\ta\r\n\tld\t(delete),a\r\n\tjp\tfcreat\r\nclrflds:\r\n\txor\ta\r\n\tld\t(iy+.ex),a\r\n\tld\t(iy+.s1),a\r\n\tld\t(iy+.s2),a\r\n\tld\t(iy+.cr),a\r\n\tld\t(iy+.rc),a\r\n\tret\r\nappend:\r\n\t; The original code for appending to an existing output file read the\r\n\t; entire file from the beginning and scanned for a text file EOF marker\r\n\t; (1Ah).  The PIPEMGR documentation says that the redirector should\r\n\t; work for binary files and so it is not clear that looking for a text\r\n\t; EOF marker is a valid exercise.\r\n\t;\r\n\t; Assuming that scanning is valid (despite the documentation) then it\r\n\t; should only be done if the length of the file is a multiple of 128\r\n\t; bytes.  For such a file the scan only needs to be done in the last\r\n\t; sector of the file.\r\n\t;\r\n\t; I am not sure that scanning is ever necessary.  Files created by the\r\n\t; redirector have their exact lengths set and that information can be\r\n\t; used to position the file for writing.\r\n\t;\r\n\t; Scanning might be useful if it should be desirable to append re-\r\n\t; directed output to a file created by some other program.\r\n\t;\r\n\t; [jrs 2014-05-22]\r\n\r\n\tld\t(iy+.cr),255\t; Prepare to fetch last sector byte count\r\n\tld\tc,OPENF\t\t; Try to open the file\r\n\tcall\tfcbdos\r\n\tinc\ta\r\n\tjp\tz,rcreat\t; If the file doesn't exist then create it\r\n\r\n\t; Repurpose the unused byte in John Elliott's FCB extension to hold\r\n\t; the last sector byte count.\r\n\tld\ta,(iy+.cr)\t; Get LSBC\r\n\tld\t(iy+.??),a\t; Store it for later use\r\n\tld\t(iy+.cr),0\t; Clear CR field for sequential I/O\r\n\tld\tde,outbuf\t; Establish data address for read\r\n\tcall\tset_dma\r\n\r\n\t; The FCB address is in IY\r\n\r\n\tld\tc,SIZEF\t\t; Compute file size\r\n\tcall\tfcbdos\r\n\r\n\tld\ta,(iy+.r0)\t; Check for zero-length file\r\n\tor\ta,(iy+.r1)\r\n\tor\ta,(iy+.r2)\r\n\tjp\tz,fcreat\r\n\r\n\tdec\t(iy+.r0)\t; Step back to previous record\r\n\tjr\tnc,at_prev\r\n\tdec\t(iy+.r1)\r\n\tjr\tnc,at_prev\r\n\tdec\t(iy+.r2)\r\nat_prev:\r\n\tld\tc,READRAN\t; Read last record of file\r\n\tcall\tfcbdos\r\n\tor\ta\t\t; Success?\r\n\tjp\tnz,rcreat\t; Delete and recreate on any error\r\n\r\n\tld\ta,(iy+.??)\t; Get last record byte count\r\n\tand\ta\t\t; Done if not zero\r\n\tjr\tnz,hooky\r\n\tld\thl,outbuf\t; Scan for EOF marker\r\n\tld\ta,1Ah\r\n\tld\tbc,128\r\n\tcpir\r\n\tinc\tc\r\n\tld\ta,c\r\nhooky:\r\n  if exact\t\t\t;agn UNUSED case (ISIS)\r\n\tneg\t\t\t; Convert unused bytes to used bytes\r\n  endif\r\n\tand\t7Fh\r\n\tld\t(outptr),a\t; Ready for the next byte.\r\n\tcall\thookwb\r\n\txor\ta\r\n\tld\t(delete),a\r\n\tjp\tfcreat\r\n\r\nfcbdos:\r\n\tld\ta,(iy+.ud)\t; fcb[37] holds user+1 if user number specified\r\n\tor\ta\r\n\tjr\tnz,fcbd1\t; Skip if user specified\r\n\tpush\tbc\t\t; Save BDOS function number\r\n\tld\te,0FFh\r\n\tld\tc,GSUSER\r\n\tcall\tyfdos\t\t;Get user\r\n\tld\t(ousr),a\t; Save original user number\r\n\tinc\ta\t\t; Store user+1 at fcb[37]\r\n\tld\t(iy+.ud),a\r\n\tjr\tfcbd2\r\n\r\nfcbd1:\r\n\tcp\t32\t\t; If user < 32 then we have a file, otherwise\r\n\tjr\tc,fcbd1a\t; we have a device in which case we simply\r\n\txor\ta\t\t; return 0 (success) and don't do BDOS call!\r\n\tret\r\n\r\nfcbd1a:\r\n\tpush\tbc\t\t; Save BDOS function\r\n\tld\te,0FFh\t\t;Get user\r\n\tld\tc,GSUSER\r\n\tcall\tyfdos\r\n\tld\t(ousr),a\t; Save original user\r\nfcbd2:\r\n\tld\te,(iy+.ud)\t; Get user+1 from fcb[37]\r\n\tdec\te\t\t; Normalise\r\n\tld\tc,GSUSER\r\n\tcall\tyfdos\t\t;Set user\r\n\tpop\tbc\t\t; Recover BDOS function\r\n\tpush\tiy\t\t; Copy FCB address to DE\r\n\tpop\tde\r\n\tcall\tyfdos\r\n\tpush\taf\t\t; Save BDOS results\r\n\tpush\thl\r\n\tld\ta,(ousr)\t; Get original user number\r\n\tld\te,a\r\n\tld\tc,GSUSER\t;Restore old user\r\n\tcall\tyfdos\r\n\tpop\thl\t\t; Recover BDOS results\r\n\tpop\taf\r\n\tret\r\n\r\nyfdos:\r\n\tpush\tiy\r\n\tcall\tfdos\r\n\tpop\tiy\r\n\tret\r\n\r\necreat:\r\n\tld\tde,warn1\t;\"Error creating output\"\r\n\tcall\tprint\r\n\tld\tde,warn2a\r\n\tcall\tprint\r\n\tpop\tiy\r\n\tld\t(iy-1),0\r\n\tdefb\t21h\t\t;Swallow the POP IY\r\n\t\t\t\t; (Converts it to LD HL,xxxx)\r\nfcreat:\r\n\tpop\tiy\r\n\tld\tde,(dma)\r\n\tcall\tset_dma\t\t;Restore user DMA\r\n\txor\ta\r\n\tld\tb,a\r\n\tld\th,a\r\n\tld\tl,a\r\n\tret\r\n\r\nudconv:\r\n\tld\tb,4\t\t;Generate uppercase version of DEV: spec.\r\n\tpush\tix\r\n\tld\tde,infcb+32\t;Workspace\r\nudc0:\r\n\tld\ta,(ix+0)\t; Translate to upper case (is this necessary?)\r\n\tcp\t'a'\r\n\tjr\tc,udc1\r\n\tcp\t'z'\r\n\tjr\tnc,udc1\r\n\tsub\t20h\r\nudc1:\r\n\tld\t(de),a\r\n\tinc\tde\r\n\tinc\tix\r\n\tdjnz\tudc0\r\n\tpop\tix\r\n\tld\tc,4\t\t; Look through the device names for a match\r\n\tld\thl,cpcon\r\nudc2:\r\n\tld\tde,infcb+32\r\n\tld\tb,4\r\n\tcall\tcp$\r\n\tjr\tz,udc3\r\n\tdec\tc\r\n\tjr\tnz,udc2\t\r\n\tjr\tuconv\t\t;No match.\t\r\n\r\nudc3:\t\t\t\t; +++ Here is where device gets into FCB\r\n\tld\ta,24h\r\n\tsub\tc\t\t;A = DEV: id\r\n\tld\thl,(pfcb+2)\r\n\tdec\thl\r\n\tld\t(hl),-1\t\t;FCB active, piping.\r\n\tld\tde,38\r\n\tadd\thl,de\r\n\tld\t(hl),a\t\t;Set DEV: in FCB.\r\n\tld\thl,(pfcb)\r\n\tld\tde,4\r\n\tadd\thl,de\t\t;HL = return value\r\n\tld\ta,(hl)\r\n\tor\ta\r\n\tjr\tnz,dozap0\r\n\tld\thl,0\t\t;EOL\r\ndozap0:\r\n\tpop\tix\r\n\tjp\tdozap1\t\t;Cover up the redirector.\r\n\r\nuconv:\t\t\t\t; IX points at input string.  On completion ...\r\n\tld\thl,0\t\t;L=User number, H=drive letter\r\n\tld\tb,2\t\t;B=1 if user number supplied\r\nuconv1:\r\n\tld\ta,(ix+0)\r\n\tcp\t'0'\t\t; Check for a decimal digit\r\n\tjp\tc,fpendi\r\n\tcp\t':'\t\t; '9'+1 = ':' (How convenient!)\r\n\tjr\tc,numeri\r\n\tjr\tz,ucend\r\n\tld\th,a\t\t; Not a digit.  Perhaps a letter?\r\n\tinc\tix\r\n\tjr\tuconv1\r\n\r\nnumeri:\r\n\tand\t0Fh\t\t;A=digit, 0-9\r\n\tld\tc,a\r\n\tld\ta,l\t\t;L=running total\r\n\tadd\ta,a\t\t;*2\r\n\tadd\ta,a\t\t;*4\r\n\tadd\ta,l\t\t;*5\r\n\tadd\ta,a\t\t;*10\r\n\tadd\ta,c\t\t;*10+c\r\n\tld\tl,a\r\n\tinc\tix\r\n\tld\tb,1\t\t;user number supplied\r\n\tjr\tuconv1\r\n\r\nucend:\r\n\tdjnz\tucend0\t\t;If B=1, no user number supplied.\r\n\tld\ta,l\r\n\tinc\ta\t\t; Store user+1 (to disambiguate 0)\r\n\tpush\tiy\r\n\tld\tiy,(pfcb+2)\t; Get FCB pointer\r\n\tld\t(iy+.ud),a\t; Store user number in FCB\r\n\tpop\tiy\t\r\nucend0:\r\n\tld\ta,h\r\n\tor\ta\r\n\tjr\tz,nodrv\t\t;u:filename\r\n\tld\t(ix-1),H\r\n\tld\tix,(pfcb)\r\nucend1:\r\n\tld\ta,(ix+1)\r\n\tcp\t':'\r\n\tjr\tz,restq\r\n\tld\t(ix+0),' '\r\n\tinc\tix\r\n\tjr\tucend1\t\t\r\n\r\nnodrv:\r\n\tinc\tix\t\t;IX -> filename proper\r\n\tld\thl,(pfcb)\r\nnodrv1:\r\n\tld\ta,(hl)\r\n\tld\t(hl),' '\r\n\tinc\thl\r\n\tcp\t':'\r\n\tjr\tnz,nodrv1\r\nrestq:\r\n\tld\t(pfcb),ix\t\r\n\tjr\trestt\r\n\r\nfparse:\r\n\tinc\tde\r\n\tld\ta,(de)\t\t;[19-11-1998] skip spaces betweeen operator & \r\n\tcp\t' '\t\t;argument.\r\n\tjr\tz,fparse\r\n\r\n\tld\t(pfcb),de\t; Input string\r\n\tld\t(pfcb+2),hl\t; FCB\r\n\tpush\tix\r\n\tpush\thl\t\t; Copy FCB address to IX\r\n\tpop\tix\r\n\tld\t(ix+.ud),0\t;No user number\r\n\tld\tix,(pfcb)\t; IX := pointer to input string\r\n\tld\ta,(ix+1)\t; Get 2nd character\r\n\tcp\t':'\t\t; If 2nd or 3rd character is a colon then\r\n\tjp\tz,uconv\t\t;  look for a user number\r\n\tld\ta,(ix+2)\r\n\tcp\t':'\r\n\tjp\tz,uconv\r\n\tld\ta,(ix+3)\t; If 4th character is a colon then scan\r\n\tcp\t':'\t\t;  for user and/or drive device name\r\n\tjp\tz,udconv\r\nrestt:\t\t\t\t; All parsed, or not specified\r\n\tpop\tix\r\n\tld\tde,pfcb\r\n\tld\tc,PARSEFN\r\n\tcall\tfdos\r\ndozap1:\r\n\tld\ta,h\r\n\tand\tl\r\n\tinc\ta\r\n\tjr\tz,fpend\r\n\tld\ta,h\r\n\tor\tl\r\n\tjr\tz,eoln\r\n\tpush\thl\t\t;HL->next character in line.\r\n\tld\tde,(pstrt)\r\n\tand\ta\r\n\tsbc\thl,de\t\t;L=length of redirector\r\n\tex\tde,hl\t\t;E=length of redirector\t\r\nzaprd:\r\n\tld\t(hl),' '\r\n\tinc\thl\r\n\tdec\te\r\n\tjr\tnz,zaprd\r\n\tpop\tde\t\t;DE=next character in line\r\n\tld\thl,(pfcb+2)\r\n\tdec\thl\r\n\tld\t(hl),-1\t\t;Flag, must be 0 or -1\r\n\tinc\thl\r\n\tret\r\n\r\neoln:\r\n\tld\thl,(pstrt)\r\n\tld\t(hl),0\t\t;Chop redirection off\r\n\tld\ta,l\r\n\tand\t7Fh\r\n\tdec\ta\r\n\tld\t(80h),a\t\t;Command line ends here.\r\n\tld\tde,pfcb\r\n\tld\thl,0\r\n\tld\t(pfcb),hl\r\n\tld\thl,(pfcb+2)\r\n\tdec\thl\r\n\tld\t(hl),-1\t\t;Pipe active\r\n\tinc\thl\r\n\tret\r\n\r\nfpendi:\r\n\tpop\tix\r\nfpend:\r\n\tld\tde,(pfcb)\r\n\tld\thl,(pfcb+2)\r\n\tret\r\n\r\n\tdseg\r\npfcb:\t\t\t\t; Parse Filename Control Block\r\n\tdefw\t0\t\t; Address of input string\r\n\tdefw\t0\t\t; Address of FCB (output)\r\n\tcseg\r\n\r\nchkver:\r\n\tcall\tidrsx\r\n\tjp\tnz,fdos\r\n\tld\thl,0103h\t;agn bump version to PIPEMGR 1.03\r\n\tret\r\n\r\ncon1:\r\n\tcall\tpbytin\r\n\tld\ta,h\r\n\tor\ta\r\n\tjr\tnz,bahl\r\n\tld\tl,1Ah\r\nbahl:\r\n\tld\tb,h\r\n\tld\ta,l\r\n\tret\r\n\r\ncon6:\tld\ta,e\r\n\tcp\t0fdh\r\n\tjp\tc,fdos\r\n\tjr\tz,con1\r\n\tcp\t0feh\r\n\tjr\tz,con11\r\n\tcall\tpbytin\r\n\tjr\tcon1\r\n\r\n\tdseg\r\n\tdefs\t20\r\ngsp:\tdefw\t0\r\n\tcseg\r\n\r\ncon11:\r\n\tld\ta,(cpol)\r\n\t\t\t;Get console mode, including policy for function 0Bh\r\n\tcp\t1\t;True\r\n\tjr\tz,RetTrue\r\n\tcp\t2\r\n\tjr\tz,RetFalse\r\n\r\n;Return conditional value. Two consecutive calls are necessary to signal a\r\n;keypress - the first always returns 0.\r\n\r\n\tld\ta,(ckey)\t;Was last FDOS call 0Bh?\r\n\tor\ta\r\n\tjr\tnz,RetTrue\t;No. Return False.\r\n\tdec\ta\r\n\tld\t(ckey),a\t;Signal that the last BDOS call was 0Bh.\r\nRetFalse:\r\n\txor\ta\r\n\tret\r\n\r\nRetTrue:\r\n\txor\ta\r\n\tld\t(ckey),a\r\n\tdec\ta\r\n\tret\r\n\r\ncon10:\r\n\tex\tde,hl\t\t;HL->buffer\r\n\tld\ta,h\r\n\tor\tl\r\n\tld\tc,0\r\n\tjr\tnz,con10a\r\n\tld\thl,(dma)\r\n\tinc\thl\r\n\tld\tc,(hl)\r\n\tdec\thl\r\ncon10a:\r\n\tld\ta,(hl)\t\t;HL->buf[0]\r\n\tsub\tc\r\n\tld\tb,a\t\t;B=maximum length\r\n\tret\tc\r\n\tinc\thl\t\t;HL->buf[1]\r\n\tpush\thl\r\n\tinc\thl\r\n\tpush\tbc\t\t;HL->space for input\r\n\tld\tb,0\r\n\tadd\thl,bc\r\n\tpop\tbc\r\ncon10b:\r\n\tpush\thl\r\n\tpush\tbc\r\n\tcall\tqbytin\r\n\tpop\tbc\r\n\tld\ta,h\t\r\n\tor\ta\r\n\tjr\tz,con10c\r\n\tld\ta,l\r\n\tcp\tCR\r\n\tjr\tz,con10c\r\n\tcp\tLF\r\n\tjr\tz,con10c\r\n\tpop\thl\r\n\tld\t(hl),a\r\n\tinc\thl\r\n\tinc\tc\r\n\tdjnz\tcon10b\r\n\tdefb\t3Eh\t\t;Swallow the POP HL  ;;; jr\tcon10d\r\n\t\t\t\t; Converts POP HL to LD A,xx\r\ncon10c:\r\n\tpop\thl\r\ncon10d:\r\n\tpop\thl\r\n\tld\t(hl),c\r\n\tret\r\n\r\nPipeIn:\r\n\tld\ta,(inflg)\r\n\tor\ta\r\n\tjr\tnz,pipei1\r\n\tld\ta,(crbuf)\r\n\tor\ta\r\n\tjr\tz,nolf\r\n\tcp\tLF\r\n\tjr\tz,donelf\r\n\tld\tc,CONOUT\r\n\tld\te,LF\r\n\tcall\tfdos\r\ndonelf:\r\n\txor\ta\r\n\tld\t(crbuf),a\r\n\tld\thl,010ah\r\n\tjp\tbahl\r\n\r\n\tdseg\r\ncrbuf:\tdefb\t0\r\n\tcseg\r\n\r\ncrlf:\r\n\tld\t(crbuf),a\r\n\tld\tc,CONOUT\r\n\tld\te,CR\r\n\tcall\tfdos\r\n\tld\thl,010dh\r\n\tjp\tbahl\r\n\r\nnolf:\r\n\tld\tc,CONIN\r\n\tcall\tfdos\r\n\tcp\tCR\r\n\tjr\tz,crlf\r\n\tcp\tLF\r\n\tjr\tz,crlf\r\n\tld\tl,a\r\n\tcp\t1Ah\r\n\tld\th,0\r\n\tjp\tz,bahl\r\n\tinc\th\r\n\tjp\tbahl\r\n\r\npipei1:\r\n\tcall\tbytin\r\n\tjp\tbahl\r\n\r\nPipeOut:\r\n\tinc\tde\t\t; Step to the output character\r\n\tinc\tde\r\n\tld\ta,(de)\r\n\tld\te,a\r\n\tld\ta,(outflg)\t;Output via PIPEMGR?\r\n\tld\tc,2\r\n\tor\ta\r\n\tjp\tz,fdos\r\nbytout:\r\n\tld\ta,(outfcb+.ud)\t;E=character\r\n\tcp\t20h\t\t;CON:\r\n\tjr\tc,bytoz1\r\n\tld\tc,2\r\n\tjp\tz,fdos\r\n\tcp\t21h\t\t;AUX:\r\n\tld\tc,4\r\n\tjp\tz,fdos\r\n\tcp\t22h\t\t;LST:\r\n\tld\tc,5\r\n\tjp\tz,fdos\t\t;NUL:\r\n\tret\r\n\r\nbytoz1:\r\n\tld\ta,(outptr)\r\n\tpush\tde\r\n\tcp\t80h\r\n\tcall\tnc,wrobuf\r\n\tpop\tde\r\n\tld\tl,a\r\n\tld\th,0\r\n\tld\tbc,outbuf\r\n\tadd\thl,bc\r\n\tld\t(hl),e\r\n\tinc\ta\r\n\tld\t(outptr),a\r\n\tret\r\n\r\nPipeErr:\r\n\tinc\tde\r\n\tinc\tde\r\n\tld\ta,(de)\r\n\tld\te,a\r\n\tld\ta,(errflg)\r\n\tld\tc,2\r\n\tor\ta\r\n\tjp\tz,fdos\r\n\tjr\tbytout\r\n\r\nret1a:\r\n\tld\thl,1Ah\r\n\tret\r\n\r\nqbytin:\r\n\tcall\tpbytin\r\n\tld\ta,(lastin)\r\n\tld\tc,a\r\n\tld\ta,l\r\n\tld\t(lastin),a\r\n\tcp\tLF\r\n\tret\tnz\r\n\tld\ta,c\r\n\tcp\tCR\t\t;CR,LF -> CR\r\n\tret\tnz\r\n\r\n;Fall through to...\r\n\r\npbytin:\r\n\tld\ta,(pclosed)\r\n\tor\ta\r\n\tjr\tz,bytin\r\n\tcall\topenin\r\n\txor\ta\r\n\tld\t(pclosed),a\r\n\tld\t(awake),a\t;openin wakes up the RSX.\r\nbytin:\r\n\tld\ta,(ineof)\r\n\tor\ta\r\n\tjr\tnz,ret1a\r\n\tld\ta,(infcb+.ud)\t;Input from a device?\r\n\tcp\t20h\r\n\tjr\tc,bytiz1\t;CON:\r\n\tld\tc,CONIN\r\n\tjr\tz,hlba\r\n\tcp\t21h\t\t;AUX:\r\n\tld\tc,AUXIN\r\n\tjr\tz,hlba\r\n\tld\thl,001Ah\t;LST: / NUL:\r\n\tret\r\n\t\r\nhlba:\r\n\tcall\tfdos\r\n\tld\tl,a\r\n\txor\t1Ah\t\t;H=0 if EOF\r\n\tld\th,a\r\n\tret\r\n\r\nbytiz1:\r\n\tld\thl,(inlen)\t\r\n\tld\tde,(inlen+2)\t; DEHL has input length\r\n\tld\ta,h\r\n\tor\tl\r\n\tor\td\r\n\tor\te\r\n\tjr\tz,ret1a\t\t; DEHL = 0; send a CP/M text EOF\r\n\tdec\thl\t\t; Decrement DEHL\r\n\tld\t(inlen),hl\r\n\tld\ta,h\r\n\tand\tl\r\n\tinc\ta\r\n\tjr\tnz,byti01\r\n\tdec\tde\r\n\tld\t(inlen+2),de\r\nbyti01:\r\n\tld\ta,(inptr)\r\n\tcp\t80h\r\n\tcall\tnc,rdibuf\r\n\tld\tl,a\r\n\tinc\ta\r\n\tld\t(inptr),a\r\n\tld\th,0\r\n\tld\tde,inbuf\r\n\tadd\thl,de\r\n\tld\tl,(hl)\r\n\tld\th,1\r\n\tret\r\n\r\nrdibuf:\r\n\tld\tde,inbuf\r\n\tcall\tset_dma\r\n\tpush\tiy\r\n\tld\tiy,infcb\r\n\tld\tc,READSEQ\r\n\tcall\tfcbdos\r\n\tpop\tiy\r\n\tld\tde,(dma)\r\n\tcall\tset_dma\r\n\tor\ta\r\n\tjr\tz,rdib1\r\n\tld\t(ineof),a\r\n\tcall\tibuf1A\r\nrdib1:\r\n\txor\ta\r\n\tld\t(inptr),a\r\n\tret\r\n\r\nwrobuf:\r\n\tld\tde,outbuf\r\n\tcall\tset_dma\r\n\tpush\tiy\r\n\tld\tiy,outfcb\r\n\tld\tc,WRITESEQ\r\n\tcall\tfcbdos\r\n\r\n\tld\tde,(dma)\r\n\tcall\tset_dma\r\n\tpop\tiy\r\n\tcall\tobuf1A\r\n\tld\tde,(dma)\r\n\tcall\tset_dma\r\n\txor\ta\r\n\tld\t(outptr),a\r\n\tret\r\n\r\nCloseIn:\r\n\tld\ta,80h\r\n\tld\t(inptr),a\r\n\tld\ta,(inflg)\r\n\tor\ta\r\n\tret\tz\r\n\txor\ta\r\n\tld\t(inflg),a\r\n\tld\tiy,infcb\r\n\tld\tc,CLOSEF\r\n\tcall\tfcbdos\r\n\tld\ta,(PipedI)\t;Was input piped?\r\n\tor\ta\r\n\tret\tz\r\n\tld\tiy,infcb\r\n\tld\thl,0\r\n\tld\t(infcb+14),hl\r\n\tld\t(infcb+12),hl\r\n\tld\tc,DELETEF\r\n\tcall\tfcbdos\t\t;Delete the input pipe\r\n\tret\r\n\r\nCloseOut:\r\n\tld\ta,(outflg)\t;Output via PIPEMGR?\r\n\tor\ta\r\n\tret\tz\r\n\tld\ta,(outptr)\r\n\tor\ta\r\n\tpush\taf\r\n\tcall\tnz,wrobuf\r\n\tld\tiy,outfcb\r\n\tld\tc,CLOSEF\r\n\tcall\tfcbdos\r\n\tpop\taf\r\n\r\n  if exact\t\t;agn UNUSED last sector byte count\r\n\r\n; Next instruction added to change meaning of last sector byte count from\r\n; USED bytes to UNUSED bytes.  [jrs 03-04-2014]\r\n\tneg\r\n\r\n  endif\r\n\r\n\tand\t7fh\r\n\r\n;;\tld\t(outfcb+.cr),a\r\n;;\tld\ta,(outfcb+6)\r\n;;\tset\t7,a\r\n;;\tld\t(outfcb+6),a\r\n\r\n\tld\t(iy+.cr),a\t; Taking advantage of the fact that IY\r\n\tset\t7,(iy+6)\t; holds address of outfcb!\r\n\t\r\n\tld\tc,SETATTR\r\n;;\tld\tiy,outfcb\r\n\tcall\tfcbdos\r\n\r\n;[20-11-1998] Generate a temp file and rename it when closing.\r\n\r\n;\tld\tiy,Xoutfcb\r\n;\tld\tc,DELETEF\r\n;\tcall\tfcbdos\r\n;\tld\thl,Xoutfcb\r\n;\tld\tde,outfcb+16\r\n;\tld\tbc,16\r\n;\tldir\r\n;\r\n;\tld\tc,RENAMEF\t;Rename temp file.\r\n;\tld\tiy,outfcb\r\n;\tcall\tfcbdos\r\n;\r\n;\txor\ta\r\n;\tld\t(outflg),a\r\n;\tld\t(Xoutflg),a\t;JCE 1-1-2000 keep these flags in sync\r\n\r\n\tret\r\n\r\nmyboot:\r\n\r\n;Called when program terminates\r\n\r\n\tld\tsp,inbuf+7fh\r\n\tcall\tuhookwb\r\n\txor\ta\t\t;RSX is asleep\r\n\tld\t(awake),a\r\n\tld\tc,ERRMODE\t;Can't afford recursive RST 0's\r\n\tld\te,0FFh\r\n\tcall\tfdos\r\n\tcall\tCloseIn\t\t;Close STDIN, STDOUT & STDERR.\r\n\tcall\tCloseOut\r\n\txor\ta\r\n\tld\t(PipedI),a\r\n\tld\ta,(PipedO)\t;Was there a pipe?\r\n\tor\ta\r\n\tjr\tnz,xferpipe\r\n\tdec\ta\r\n\tld\t(delete),a\t;Set to delete RSX\r\n\trst\t0\t\t;RSX vanishes...\r\n\r\nxferpipe:\r\n\txor\ta\r\n\tld\t(PipedO),a\r\n\tdec\ta\r\n\tld\t(PipedI),a\r\n\tld\t(inflg),a\r\n;\tld\thl,Xoutfcb\t;JCE 1-1-2000 1.01: Use Xoutfcb not outfcb\r\n\t\t\t\t; JRS 2014-06-17: No.  outfcb is correct.\r\n\tld\thl,outfcb\r\n\r\n\tld\tde,renfcb\t;so the right rename is done\r\n\tld\tbc,38\r\n\tpush\thl\r\n\tldir\r\n\tpop\thl\t\r\n\tld\tde,renfcb+10h\r\n\tld\tbc,10h\r\n\tldir\r\n\tld\thl,0\r\n\tld\t(renfcb+12),hl\r\n\tld\t(renfcb+14),hl\r\n\tld\t(renfcb+28),hl\r\n\tld\t(renfcb+30),hl\r\n\tld\t(renfcb+32),hl\t;Zap the rename fcb\r\n\tld\thl,'NI'\t\t;\"PIPEIN\"\r\n\tld\t(renfcb+21),hl\r\n\tld\thl,'  '\r\n\tld\t(renfcb+23),hl\r\n\tld\tiy,renfcb\r\n\tld\tc,RENAMEF\r\n\tcall\tfcbdos\t\t;Rename \"PIPEOUT\" to \"PIPEIN\"\r\n\r\n\tld\thl,renfcb+16\r\n\tld\tde,infcb\t;Make input file FCB.\r\n\tld\tbc,12\r\n\tldir\r\n\tld\ta,(renfcb+.ud)\r\n\tld\t(infcb+.ud),a\t;Transfer uid as well.\r\n\r\n\txor\ta\r\n\tld\t(delete),a\t;Return control to CP/M. RSX stays loaded\r\n\t\t\t\t;but asleep.\r\n\tld\t(awake),a\r\n\tld\thl,pipenxt\r\n\tld\tde,80h\r\n\tld\tb,d\r\n\tld\tc,e\r\n\tldir\r\n\tcall\thookwb\t\t;We will need this because the pipe is running\r\n\tld\thl,(1)\r\n\tinc\thl\r\n\tld\tde,splboot\r\n\tld\t(hl),e\r\n\tinc\thl\r\n\tld\t(hl),d\r\n\txor\ta\r\n\tld\t(cpol),a\t;Console input policy\r\n\tinc\ta\r\n\tld\t(pclosed),a\r\n\tld\tc,CHAIN\r\n\tld\te,0\r\n\tcall\tfdos\t\t;Chain to command given in pipe\r\n\tjp\toboot\r\n\r\nsplboot:\r\n\tld\thl,(1)\r\n\tinc\thl\r\n\tld\tde,myboot\r\n\tld\t(hl),e\r\n\tinc\thl\r\n\tld\t(hl),d\r\n\tjp\toboot\r\n\r\nhookwb:\tld\ta,(wbflag)\t\t; Is warm boot hooked already?\r\n\tor\ta\r\n\tret\tnz\t\t\t; If so then nothing to do\r\n\tld\thl,(1)\t\t\t; Get target of JP at address 0\r\n\tld\ta,(hl)\t\t\t; Get instruction that is there\r\n\tld\t(hl),0C3h\t\t; Store a JP\r\n\tinc\thl\t\t\t; Step to address\r\n\tld\tbc,myboot\t\t; Load address of local routine\r\n\tld\te,(hl)\t\t\t; Save current warm boot vector and\r\n\tld\t(hl),c\t\t\t; plug in the address of the local\r\n\tinc\thl\t\t\t; routine.\r\n\tld\td,(hl)\r\n\tld\t(hl),b\r\n\tld\t(oboot),a\t\t; Store the original vector\r\n\tld\t(oboot+1),de\r\n\tld\ta,1\t\t\t; Flag that the warm boot hook is\r\n\tld\t(wbflag),a\t\t; in place.\r\n\tret\r\n\r\nuhookwb:\r\n\tld\ta,(wbflag)\r\n\tor\ta\r\n\tret\tz\r\n\tld\tde,(1)\r\n\tld\thl,oboot\r\n\tld\tbc,3\r\n\tldir\r\n\txor\ta\r\n\tld\t(wbflag),a\r\n\tret\r\n\r\nidrsx:\r\n\tpush\tde\r\n\tex\tde,hl\r\n\tinc\thl\r\n\tinc\thl\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n\tld\thl,rname\r\n\tld\tb,8\r\n\tcall\tcp$\r\n\tpop\tde\r\n\tret\r\n\r\ncp$:\r\n\tld\ta,(de)\t\t; Compares strings at HL and DE for length B.\r\n\tcp\t(hl)\t\t; Leaves HL=HL+B and DE = DE+B regardless of\r\n\tjr\tnz,cp$1\t\t; the result.  Z flag is set and A=0 if the\r\n\tinc\tde\t\t; strings are identical, otherwise Z flag is\r\n\tinc\thl\t\t; reset and A<>0\r\n\tdjnz\tcp$\r\n\txor\ta\r\n\tret\r\n\r\ncp$1:\r\n\tinc\thl\r\n\tinc\tde\r\n\tdjnz\tcp$1\r\n\txor\ta\r\n\tdec\ta\r\n\tret\t\r\n\r\ntempdrv:\r\n\tld\t(gsp),sp\r\n\tld\tsp,gsp\r\n\tpush\tbc\r\n\tpush\tde\r\n\tpush\thl\r\n\tld\tde,scb1\r\n\tld\tc,ACCSCB\r\n\tcall\tfdos\r\n\tpop\thl\r\n\tpop\tde\r\n\tpop\tbc\r\n\tld\tsp,(gsp)\r\n\tret\r\n\r\nkillrsx:\r\n\txor\ta\r\n\tdec\ta\r\n\tld\t(delete),a\r\n\tld\thl,fdos\r\n\tld\t(fdos-2),hl\r\n\tpush\tbc\r\n\tpush\tde\r\n\tcall\tuhookwb\r\n\tpop\tde\r\n\tpop\tbc\r\n\tjp\tfdos\r\n\r\nopenin:\r\n\tpush\tiy\r\n\tld\thl,0\r\n\tld\t(inlen),hl\r\n\tld\t(inlen+2),hl\r\n\r\n\tld\tc,SIZEF\t\t;Compute size of input file\r\n\tld\tiy,infcb\r\n\tcall\tfcbdos\r\n\tinc\ta\r\n\tjp\tz,noinp\r\n\tld\tde,(infcb+.r1)\t; Load file size (sectors) from .rr field\r\n\tld\ta,(infcb+21h)\r\n\tld\th,a\r\n\tld\tl,0\t\t; Convert sectors to bytes\r\n\tsrl\td\r\n\trr\te\r\n\trr\th\r\n\trr\tl\t\t;DEHL = size of file, bytes\r\n\tld\t(inlen),hl\r\n\tld\t(inlen+2),de\r\n\tld\thl,0\r\n\tld\t(infcb+12),hl\r\n\tld\t(infcb+14),hl\r\n\tld\ta,l\r\n\tdec\ta\r\n\tld\t(infcb+.cr),a\r\n\tld\tc,OPENF\r\n\tld\tiy,infcb\r\n\tcall\tfcbdos\r\n\tinc\ta\r\n\tjp\tz,noinp\r\n\tld\ta,(infcb+.cr)\r\n\tand\t7fh\r\n;------------------------------------------------------------------------\r\n; This original code assumed byte count at FCB[32] represents the number\r\n; of USED bytes in the last sector.  However this program now interprets\r\n; FCB[32] as the number of UNUSED bytes in the last sector.  We don't\r\n; need to test for zero.  Instead, we unconditionally subtract the last\r\n; sector byte count from the calculated file length.\r\n\r\n  if not exact\t\t;agn DOS Plus has USED last byte count\r\n\r\n\tjr\tz,nomsb\t\t;No adjustment necessary\r\n\tld\tb,a\r\n\tld\ta,80h\r\n\tsub\tb\t\t;A=no. unused bytes\r\n\r\n  endif\r\n\r\n;------------------------------------------------------------------------\r\n\tld\tc,a\r\n\tld\tb,0\r\n\tld\thl,(inlen)\r\n\tand\ta\r\n\tsbc\thl,bc\r\n\tld\t(inlen),hl\r\n\tjr\tnc,nomsb\r\n\tld\thl,(inlen+2)\r\n\tld\ta,h\r\n\tor\tl\r\n\tjr\tz,nomsb\r\n\tdec\thl\r\n\tld\t(inlen+2),hl\r\nnomsb:\r\n\tcall\thookwb\r\n\txor\ta\r\n\tld\t(infcb+.cr),a\r\n\tld\t(delete),a\t;Pipemgr is running\r\n\tld\t(pclosed),a\r\n\tld\t(ineof),a\r\n\tld\t(lastin),a\r\n\tld\t(ckey),a\r\n\tdec\ta\r\n\tld\t(inflg),a\t;Input is redirected.\r\n\tld\t(awake),a\t;RSX is awake\r\n\tpop\tiy\r\n\tret\r\n\r\n\tdseg\r\nwarn1:\tdefb\t13,10,\"PIPEMGR: Can't open $\"\r\nwarn1a:\tdefb\t'input.',13,10,'$'\r\nwarn2a:\tdefb\t'output.',13,10,'$'\r\n\tcseg\r\n\r\nset_dma:\r\n\tld\t(gsp),sp\r\n\tld\tsp,gsp\r\n\tpush\thl\r\n\tpush\tde\r\n\tpush\tbc\r\n\tpush\taf\r\n\tpush\tiy\r\n\tld\tc,SETDMA\r\n\tcall\tfdos\r\n\tpop\tiy\r\n\tpop\taf\r\n\tpop\tbc\r\n\tpop\tde\r\n\tpop\thl\r\n\tld\tsp,(gsp)\r\n\tret\r\n\r\nnoinp:\r\n\txor\ta\t\t;Failed to open input\r\n\tld\t(inflg),a\r\n\tinc\ta\r\n\tld\t(ineof),a\r\n\tld\tde,warn1\r\n\tcall\tprint\r\n\tld\tde,warn1a\r\n\tcall\tprint\r\n\tpop\tiy\r\n\tret\r\n\r\nprint:\r\n\tld\tc,COSTR\r\n\tjp\tfdos\r\n\r\nibuf1A:\r\n\tld\thl,inbuf\r\n\tjr\tfill1A\r\nobuf1A:\r\n\tld\thl,outbuf\r\nfill1A:\r\n\tld\td,h\r\n\tld\te,l\r\n\tinc\tde\r\n\tld\tbc,127\r\n\tld\t(hl),1Ah\r\n\tldir\r\n\tret\r\n\r\n\tdseg\r\ncpcon:\tdefb\t'CON:AUX:LST:NUL:'\r\nPipedI:\tdefb\t0\t\t;MUST be either 0 or -1\r\nPipedO:\tdefb\t0\t\t;MUST be either 0 or -1\r\ninflg:\tdefb\t0\t\t;MUST be either 0 or -1\r\ninfcb:\tdefs\t38\r\noutflg:\tdefb\t0\t\t;MUST be either 0 or -1\r\noutfcb:\tdefb\t0,'$PIPEMGR$$$'\r\n\tdefs\t26\r\n\r\n;Xoutflg:defb\t0\r\n;Xoutfcb:defs\t38\r\nerrflg:\tdefb\t0\t\t;MUST be either 0 or -1\r\n\r\npipenxt:\r\n\tdefs\t80h\r\n\r\ninbuf:\tdefs\t80h\r\ninptr:\tdefb\t80h\r\noutbuf:\tdefs\t80h\r\noutptr:\tdefb\t0\r\n\r\nrenfcb:\tdefs\t38\r\n\r\ninlen:\tdefw\t0,0\t\t;Bytes in input file.\r\npclosed:\r\n\tdefb\t0\t\t;Pipe needs opening?\r\nawake:\tdefb\t0\r\noapp:\tdefb\t0\r\nineof:\tdefb\t0\t\t;EOF latch\r\nwbflag:\tdefb\t0\t\t;WBOOT vector hooked?\r\noboot:\tdefs\t3\t\t;Original boot routine\r\nverchk:\tdefb\tPMVER,1\r\n\tdefw\trname\r\npipeo$:\tdefb\t'0:PIPEOUT.$$$',0\t\r\ndma:\tdefw\t80h\r\nscb1:\tdefw\t50h\r\npstrt:\tdefw\t0\r\nlastin:\tdefb\t0\r\nckey:\tdefb\t0\r\ncpol:\tdefb\t0\r\nousr:\tdefb\t0\r\n\tcseg\r\n\r\n\tend\r\n"
  },
  {
    "path": "pipemgr/TEE.C",
    "content": "/*\r\n%CC1 $1.C -X -E5000\r\n%CLINK $1 DIO  -S\r\n%DELETE $1.CRL \r\n*/\r\n/*********************************************************************\r\n*                               TEE                                  *\r\n**********************************************************************\r\n*                  COPYRIGHT 1983 EUGENE H. MALLORY                  *\r\n* Converted to Hi-Tech C by John Elliott, 17 November 1998           *\r\n*                                                                    *\r\n* Build using   C -O -C PIPEMGR.C                                    *\r\n*               C -O TEE.C PIPEMGR.OBJ -LC ! GENCOM TEE PIPEMGR      *\r\n*               ERA TEE.OBJ                                          *\r\n*               ERA PIPEMGR.OBJ                                      *\r\n*                                                                    *\r\n*********************************************************************/\r\n\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <ctype.h>\r\n#include \"pipemgr.h\"\r\n    \r\nchar *version;\r\n    \r\nint main(int argc, char **argv)\r\n{\r\n    FILE *fp;\r\n    int c;\r\n    char teeflag;\r\n    char fname[MAXLINE];\r\n\r\n    version = \"Version 3.0\";\r\n    \r\n    init_args(&argc, &argv);\r\n\r\n    if (argc >= 2)\r\n    {\r\n        strcpy(fname, *++argv);\r\n        teeflag = TRUE;\r\n        fp = fopen(fname, \"w\");\r\n        if (!fp)\r\n        {\r\n            fprintf(stderr,\"TEE: Unable to create file \\'%s\\'.\",fname);\r\n            exit(1);\r\n        }\r\n    }\r\n    else\r\n        teeflag = FALSE;\r\n\r\n    while ((c=getchar()) != EOF) \r\n    {\r\n        putchar(c);\r\n        if (teeflag)\r\n            putc(c,fp);\r\n    }\r\n    fflush(fp);\r\n    fclose(fp);\r\n    exit(0);\r\n}\r\n"
  },
  {
    "path": "stdio/ASSERT.C",
    "content": "#include\t<assert.h>\r\n#include\t<stdio.h>\r\n#include\t<stdlib.h>\r\n\r\nvoid\r\n_fassert(line, file, exp)\r\nchar *\tfile, * exp;\r\nint\tline;\r\n{\r\n\tfprintf(stderr, \"Assertion failed: %s line %d: \\\"%s\\\"\\n\", file, line, exp);\r\n\tabort();\r\n}\r\n"
  },
  {
    "path": "stdio/BUF.C",
    "content": "#include\t<stdio.h>\r\n#include\t<sys.h>\r\n\r\nstatic union stdbuf\r\n{\r\n\tchar\t\tbufarea[BUFSIZ];\r\n\tunion stdbuf   *link;\r\n} *freep;\r\n\r\nchar *_bufallo()\r\n{\r\n    register union stdbuf *pp;\r\n\r\n    if (pp = freep)\r\n\tfreep = pp->link;\r\n    else\r\n\tpp = (union stdbuf *)sbrk(BUFSIZ);\r\n    return pp->bufarea;\r\n}\r\n\r\nvoid _buffree(char *pp)\r\n{\r\n    register union stdbuf *up;\r\n\r\n    up = (union stdbuf *)pp;\r\n    up->link = freep;\r\n    freep = up;\r\n}\r\n"
  },
  {
    "path": "stdio/BUILDSTD.SUB",
    "content": "c \r\n<-o -c getargs.c getenv.c assert.c printf.c fprintf.c sprintf.c \\\r\n<doprnt.c gets.c puts.c fwrite.c getw.c putw.c \\\r\n<putchar.c perror.c fputc.as flsbuf.c \\\r\n<fopen.c freopen.c fseek.c fread.c rewind.c remove.c \\\r\n<setbuf.c fscanf.c ctime.c cgets.c cputs.c \\\r\n<sscanf.c scanf.c doscan.c ungetc.c \\\r\n<fgetc.as filbuf.c stdclean.c fclose.c fflush.c \\\r\n<buf.c exit.c fakeclean.c"
  },
  {
    "path": "stdio/C280LIBC.LOG",
    "content": "\r\n10E>date\r\nA:DATE     COM  (User 0)\r\n\rFri 05/09/2025 12:33:27\r\n10E>; Compile all LIB280C.LIB modules from sources for Z280\r\n10E>;\r\n10E>; Sources are on drive E:\r\n10E>; Z280 object files are created on drive M:\r\n10E>;\r\n10E>m:\r\n10M>pip m:=e:stdio.i\r\nA:PIP      COM  (User 0)\r\n\r\n10M>c280\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -v -o2 -c e:abort.c \\\r\nc> e:abs.as \\\r\nc> e:allsh.as \\\r\nc> e:alrsh.as \\\r\nc> e:asallsh.as \\\r\nc> e:asalrsh.as \\\r\nc> e:asar.as \\\r\nc> e:asdiv.as \\\r\nc> e:asladd.as \\\r\nc> e:asland.as \\\r\nc> e:asll.as \\\r\nc> e:asllrsh.as \\\r\nc> e:aslmul.as \\\r\nc> e:aslor.as \\\r\nc> e:aslr.as \\\r\nc> e:aslsub.as \\\r\nc> e:aslxor.as \\\r\nc> e:asmod.as \\\r\nc> e:asmul.as \\\r\nc> e:assert.c \\\r\nc> e:atoi.as \\\r\nc> e:atol.c \\\r\nc> e:bdos.as \\\r\nc> e:bios.as \\\r\nc> e:bitfield.as \\\r\nc> e:blkclr.as \\\r\nc> e:blkcpy.c \\\r\nc> e:bmove.as \\\r\nc> e:brelop.as \\\r\nc> e:buf.c \\\r\nc> e:calloc.c \\\r\nc> e:cgets.c \\\r\nc> e:chmod.c \\\r\nc> e:cleanup.c \\\r\nc> e:close.c \\\r\nc> e:convtime.c \\\r\nc> e:cputs.c \\\r\nc> e:creat.c \\\r\nc> e:csv.as \\\r\nc> e:ctime.c \\\r\nc> e:ctype_.c \\\r\nc> e:ctype.c \\\r\nc> e:doprnt.c \\\r\nc> e:doscan.c \\\r\nc> e:dup.c \\\r\nc> e:exec.as \\\r\nc> e:execl.as \\\r\nc> e:_exit.as \\\r\nc> e:exit.c \\\r\nc> e:fakeclea.c \\\r\nc> e:fakecpcl.as \\\r\nc> e:fcbname.c \\\r\nc> e:fclose.c \\\r\nc> e:fflush.c \\\r\nc> e:fgetc.c \\\r\nc> e:filbuf.c \\\r\nc> e:flsbuf.c \\\r\nc> e:fopen.c \\\r\nc> e:fprintf.c \\\r\nc> e:fputc.c \\\r\nc> e:fread.c \\\r\nc> e:frelop.as \\\r\nc> e:freopen.c \\\r\nc> e:fscanf.c \\\r\nc> e:fseek.c \\\r\nc> e:fwrite.c \\\r\nc> e:getargs.c \\\r\nc> e:getch.c \\\r\nc> e:getenv.c \\\r\nc> e:getfcb.c \\\r\nc> e:gets.c \\\r\nc> e:getsp.as \\\r\nc> e:getuid.as \\\r\nc> e:getw.c \\\r\nc> e:idiv.as \\\r\nc> e:imul.as \\\r\nc> e:index.as \\\r\nc> e:inout.as \\\r\nc> e:iregset.as \\\r\nc> e:isalpha.as \\\r\nc> e:isatty.c \\\r\nc> e:isdigit.as\r\nE:ABORT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:ABORT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OABORT.OBJ $CTMP5.$$$\r\nE:ABS.AS\r\n0:A:OPTIMH E:ABS.AS $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OABS.OBJ $CTMP5.$$$\r\nE:ALLSH.AS\r\n0:A:OPTIMH E:ALLSH.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OALLSH.OBJ $CTMP5.$$$\r\nE:ALRSH.AS\r\n0:A:OPTIMH E:ALRSH.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OALRSH.OBJ $CTMP5.$$$\r\nE:ASALLSH.AS\r\n0:A:OPTIMH E:ASALLSH.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OASALLSH.OBJ $CTMP5.$$$\r\nE:ASALRSH.AS\r\n0:A:OPTIMH E:ASALRSH.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OASALRSH.OBJ $CTMP5.$$$\r\nE:ASAR.AS\r\n0:A:OPTIMH E:ASAR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OASAR.OBJ $CTMP5.$$$\r\nE:ASDIV.AS\r\n0:A:OPTIMH E:ASDIV.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OASDIV.OBJ $CTMP5.$$$\r\nE:ASLADD.AS\r\n0:A:OPTIMH E:ASLADD.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASLADD.OBJ $CTMP5.$$$\r\nE:ASLAND.AS\r\n0:A:OPTIMH E:ASLAND.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASLAND.OBJ $CTMP5.$$$\r\nE:ASLL.AS\r\n0:A:OPTIMH E:ASLL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OASLL.OBJ $CTMP5.$$$\r\nE:ASLLRSH.AS\r\n0:A:OPTIMH E:ASLLRSH.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OASLLRSH.OBJ $CTMP5.$$$\r\nE:ASLMUL.AS\r\n0:A:OPTIMH E:ASLMUL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASLMUL.OBJ $CTMP5.$$$\r\nE:ASLOR.AS\r\n0:A:OPTIMH E:ASLOR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASLOR.OBJ $CTMP5.$$$\r\nE:ASLR.AS\r\n0:A:OPTIMH E:ASLR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OASLR.OBJ $CTMP5.$$$\r\nE:ASLSUB.AS\r\n0:A:OPTIMH E:ASLSUB.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASLSUB.OBJ $CTMP5.$$$\r\nE:ASLXOR.AS\r\n0:A:OPTIMH E:ASLXOR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OASLXOR.OBJ $CTMP5.$$$\r\nE:ASMOD.AS\r\n0:A:OPTIMH E:ASMOD.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OASMOD.OBJ $CTMP5.$$$\r\nE:ASMUL.AS\r\n0:A:OPTIMH E:ASMUL.AS $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 5 bytes replaced\r\n0:A:ZAS -J -OASMUL.OBJ $CTMP5.$$$\r\nE:ASSERT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:ASSERT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 6 bytes size optimised away\r\n 12 bytes replaced\r\n0:A:ZAS -J -N -OASSERT.OBJ $CTMP5.$$$\r\nE:ATOI.AS\r\n0:A:OPTIMH E:ATOI.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OATOI.OBJ $CTMP5.$$$\r\nE:ATOL.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:ATOL.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 15 bytes size optimised away\r\n 30 bytes replaced\r\n0:A:ZAS -J -N -OATOL.OBJ $CTMP5.$$$\r\nE:BDOS.AS\r\n0:A:OPTIMH E:BDOS.AS $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OBDOS.OBJ $CTMP5.$$$\r\nE:BIOS.AS\r\n0:A:OPTIMH E:BIOS.AS $CTMP5.$$$\r\n 5 bytes size optimised away\r\n 22 bytes replaced\r\n0:A:ZAS -J -OBIOS.OBJ $CTMP5.$$$\r\nE:BITFIELD.AS\r\n0:A:OPTIMH E:BITFIELD.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OBITFIELD.OBJ $CTMP5.$$$\r\nE:BLKCLR.AS\r\n0:A:OPTIMH E:BLKCLR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OBLKCLR.OBJ $CTMP5.$$$\r\nE:BLKCPY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:BLKCPY.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OBLKCPY.OBJ $CTMP5.$$$\r\nE:BMOVE.AS\r\n0:A:OPTIMH E:BMOVE.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OBMOVE.OBJ $CTMP5.$$$\r\nE:BRELOP.AS\r\n0:A:OPTIMH E:BRELOP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OBRELOP.OBJ $CTMP5.$$$\r\nE:BUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:BUF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 4 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OBUF.OBJ $CTMP5.$$$\r\nE:CALLOC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CALLOC.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 9 bytes size optimised away\r\n 26 bytes replaced\r\n0:A:ZAS -J -N -OCALLOC.OBJ $CTMP5.$$$\r\nE:CGETS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CGETS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 21 bytes size optimised away\r\n 42 bytes replaced\r\n0:A:ZAS -J -N -OCGETS.OBJ $CTMP5.$$$\r\nE:CHMOD.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CHMOD.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 16 bytes size optimised away\r\n 24 bytes replaced\r\n0:A:ZAS -J -N -OCHMOD.OBJ $CTMP5.$$$\r\nE:CLEANUP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CLEANUP.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 12 bytes size optimised away\r\n 24 bytes replaced\r\n0:A:ZAS -J -N -OCLEANUP.OBJ $CTMP5.$$$\r\nE:CLOSE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CLOSE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 6 bytes size optimised away\r\n 13 bytes replaced\r\n0:A:ZAS -J -N -OCLOSE.OBJ $CTMP5.$$$\r\nE:CONVTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CONVTIME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 11 bytes size optimised away\r\n 61 bytes replaced\r\n0:A:ZAS -J -N -OCONVTIME.OBJ $CTMP5.$$$\r\nE:CPUTS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CPUTS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -N -OCPUTS.OBJ $CTMP5.$$$\r\nE:CREAT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CREAT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 6 bytes size optimised away\r\n 18 bytes replaced\r\n0:A:ZAS -J -N -OCREAT.OBJ $CTMP5.$$$\r\nE:CSV.AS\r\n0:A:OPTIMH E:CSV.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OCSV.OBJ $CTMP5.$$$\r\nE:CTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CTIME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 160 bytes size optimised away\r\n 320 bytes replaced\r\n0:A:ZAS -J -N -OCTIME.OBJ $CTMP5.$$$\r\nE:CTYPE_.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CTYPE_.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OCTYPE_.OBJ $CTMP5.$$$\r\nE:CTYPE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:CTYPE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 4 bytes size optimised away\r\n 8 bytes replaced\r\n0:A:ZAS -J -N -OCTYPE.OBJ $CTMP5.$$$\r\nE:DOPRNT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:DOPRNT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 45 bytes size optimised away\r\n 108 bytes replaced\r\n0:A:ZAS -J -N -ODOPRNT.OBJ $CTMP5.$$$\r\nE:DOSCAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:DOSCAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 125 bytes size optimised away\r\n 270 bytes replaced\r\n0:A:ZAS -J -N -ODOSCAN.OBJ $CTMP5.$$$\r\nE:DUP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:DUP.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -ODUP.OBJ $CTMP5.$$$\r\nE:EXEC.AS\r\n0:A:OPTIMH E:EXEC.AS $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OEXEC.OBJ $CTMP5.$$$\r\nE:EXECL.AS\r\n0:A:OPTIMH E:EXECL.AS $CTMP5.$$$\r\n 71 bytes size optimised away\r\n 122 bytes replaced\r\n0:A:ZAS -J -OEXECL.OBJ $CTMP5.$$$\r\nE:_EXIT.AS\r\n0:A:OPTIMH E:_EXIT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -O_EXIT.OBJ $CTMP5.$$$\r\nE:EXIT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:EXIT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -N -OEXIT.OBJ $CTMP5.$$$\r\nE:FAKECLEA.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FAKECLEA.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OFAKECLEA.OBJ $CTMP5.$$$\r\nE:FAKECPCL.AS\r\n0:A:OPTIMH E:FAKECPCL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OFAKECPCL.OBJ $CTMP5.$$$\r\nE:FCBNAME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FCBNAME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 57 bytes size optimised away\r\n 109 bytes replaced\r\n0:A:ZAS -J -N -OFCBNAME.OBJ $CTMP5.$$$\r\nE:FCLOSE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FCLOSE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 9 bytes size optimised away\r\n 18 bytes replaced\r\n0:A:ZAS -J -N -OFCLOSE.OBJ $CTMP5.$$$\r\nE:FFLUSH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FFLUSH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 19 bytes size optimised away\r\n 38 bytes replaced\r\n0:A:ZAS -J -N -OFFLUSH.OBJ $CTMP5.$$$\r\nE:FGETC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FGETC.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 32 bytes size optimised away\r\n 64 bytes replaced\r\n0:A:ZAS -J -N -OFGETC.OBJ $CTMP5.$$$\r\nE:FILBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FILBUF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 38 bytes size optimised away\r\n 84 bytes replaced\r\n0:A:ZAS -J -N -OFILBUF.OBJ $CTMP5.$$$\r\nE:FLSBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FLSBUF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 22 bytes size optimised away\r\n 40 bytes replaced\r\n0:A:ZAS -J -N -OFLSBUF.OBJ $CTMP5.$$$\r\nE:FOPEN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FOPEN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 4 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OFOPEN.OBJ $CTMP5.$$$\r\nE:FPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FPRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 7 bytes size optimised away\r\n 10 bytes replaced\r\n0:A:ZAS -J -N -OFPRINTF.OBJ $CTMP5.$$$\r\nE:FPUTC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FPUTC.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 26 bytes size optimised away\r\n 52 bytes replaced\r\n0:A:ZAS -J -N -OFPUTC.OBJ $CTMP5.$$$\r\nE:FREAD.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FREAD.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 71 bytes size optimised away\r\n 143 bytes replaced\r\n0:A:ZAS -J -N -OFREAD.OBJ $CTMP5.$$$\r\nE:FRELOP.AS\r\n0:A:OPTIMH E:FRELOP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OFRELOP.OBJ $CTMP5.$$$\r\nE:FREOPEN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FREOPEN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 30 bytes size optimised away\r\n 66 bytes replaced\r\n0:A:ZAS -J -N -OFREOPEN.OBJ $CTMP5.$$$\r\nE:FSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FSCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 7 bytes size optimised away\r\n 10 bytes replaced\r\n0:A:ZAS -J -N -OFSCANF.OBJ $CTMP5.$$$\r\nE:FSEEK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FSEEK.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 91 bytes size optimised away\r\n 173 bytes replaced\r\n0:A:ZAS -J -N -OFSEEK.OBJ $CTMP5.$$$\r\nE:FWRITE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:FWRITE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 76 bytes size optimised away\r\n 153 bytes replaced\r\n0:A:ZAS -J -N -OFWRITE.OBJ $CTMP5.$$$\r\nE:GETARGS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:GETARGS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 192 bytes size optimised away\r\n 432 bytes replaced\r\n0:A:ZAS -J -N -OGETARGS.OBJ $CTMP5.$$$\r\nE:GETCH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:GETCH.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OGETCH.OBJ $CTMP5.$$$\r\nE:GETENV.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:GETENV.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 115 bytes size optimised away\r\n 242 bytes replaced\r\n0:A:ZAS -J -N -OGETENV.OBJ $CTMP5.$$$\r\nE:GETFCB.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:GETFCB.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 139 bytes size optimised away\r\n 282 bytes replaced\r\n0:A:ZAS -J -N -OGETFCB.OBJ $CTMP5.$$$\r\nE:GETS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:GETS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 32 bytes size optimised away\r\n 64 bytes replaced\r\n0:A:ZAS -J -N -OGETS.OBJ $CTMP5.$$$\r\nE:GETSP.AS\r\n0:A:OPTIMH E:GETSP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OGETSP.OBJ $CTMP5.$$$\r\nE:GETUID.AS\r\n0:A:OPTIMH E:GETUID.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OGETUID.OBJ $CTMP5.$$$\r\nE:GETW.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:GETW.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OGETW.OBJ $CTMP5.$$$\r\nE:IDIV.AS\r\n0:A:OPTIMH E:IDIV.AS $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OIDIV.OBJ $CTMP5.$$$\r\nE:IMUL.AS\r\n0:A:OPTIMH E:IMUL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OIMUL.OBJ $CTMP5.$$$\r\nE:INDEX.AS\r\n0:A:OPTIMH E:INDEX.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OINDEX.OBJ $CTMP5.$$$\r\nE:INOUT.AS\r\n0:A:OPTIMH E:INOUT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OINOUT.OBJ $CTMP5.$$$\r\nE:IREGSET.AS\r\n0:A:OPTIMH E:IREGSET.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OIREGSET.OBJ $CTMP5.$$$\r\nE:ISALPHA.AS\r\n0:A:OPTIMH E:ISALPHA.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OISALPHA.OBJ $CTMP5.$$$\r\nE:ISATTY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:ISATTY.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 3 bytes replaced\r\n0:A:ZAS -J -N -OISATTY.OBJ $CTMP5.$$$\r\nE:ISDIGIT.AS\r\n0:A:OPTIMH E:ISDIGIT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OISDIGIT.OBJ $CTMP5.$$$\r\nERA $CTMP1.$$$\r\nERA $CTMP2.$$$\r\nERA $CTMP3.$$$\r\nERA $CTMP5.$$$\r\nERA $$EXEC.$$$\r\n\r\n10M>c280\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -v -o2 -c e:islower.as \\\r\nc> e:isspace.as \\\r\nc> e:isupper.as \\\r\nc> e:ladd.as \\\r\nc> e:land.as \\\r\nc> e:ldiv.as \\\r\nc> e:linc.as \\\r\nc> e:llrsh.as \\\r\nc> e:lmul.as \\\r\nc> e:longjmp.as \\\r\nc> e:lor.as \\\r\nc> e:lrelop.as \\\r\nc> e:lsub.as \\\r\nc> e:lxor.as \\\r\nc> e:malloc.c \\\r\nc> e:max.as \\\r\nc> e:memcmp.c \\\r\nc> e:memcpy.c \\\r\nc> e:memset.c \\\r\nc> e:mktime.c \\\r\nc> e:open.c \\\r\nc> e:perror.c \\\r\nc> e:pnum.c \\\r\nc> e:printf.c \\\r\nc> e:putchar.c\r\nE:ISLOWER.AS\r\n0:A:OPTIMH E:ISLOWER.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OISLOWER.OBJ $CTMP5.$$$\r\nE:ISSPACE.AS\r\n0:A:OPTIMH E:ISSPACE.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OISSPACE.OBJ $CTMP5.$$$\r\nE:ISUPPER.AS\r\n0:A:OPTIMH E:ISUPPER.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OISUPPER.OBJ $CTMP5.$$$\r\nE:LADD.AS\r\n0:A:OPTIMH E:LADD.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OLADD.OBJ $CTMP5.$$$\r\nE:LAND.AS\r\n0:A:OPTIMH E:LAND.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OLAND.OBJ $CTMP5.$$$\r\nE:LDIV.AS\r\n0:A:OPTIMH E:LDIV.AS $CTMP5.$$$\r\n 8 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -OLDIV.OBJ $CTMP5.$$$\r\nE:LINC.AS\r\n0:A:OPTIMH E:LINC.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -OLINC.OBJ $CTMP5.$$$\r\nE:LLRSH.AS\r\n0:A:OPTIMH E:LLRSH.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OLLRSH.OBJ $CTMP5.$$$\r\nE:LMUL.AS\r\n0:A:OPTIMH E:LMUL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OLMUL.OBJ $CTMP5.$$$\r\nE:LONGJMP.AS\r\n0:A:OPTIMH E:LONGJMP.AS $CTMP5.$$$\r\n 15 bytes size optimised away\r\n 36 bytes replaced\r\n0:A:ZAS -J -OLONGJMP.OBJ $CTMP5.$$$\r\nE:LOR.AS\r\n0:A:OPTIMH E:LOR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OLOR.OBJ $CTMP5.$$$\r\nE:LRELOP.AS\r\n0:A:OPTIMH E:LRELOP.AS $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OLRELOP.OBJ $CTMP5.$$$\r\nE:LSUB.AS\r\n0:A:OPTIMH E:LSUB.AS $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OLSUB.OBJ $CTMP5.$$$\r\nE:LXOR.AS\r\n0:A:OPTIMH E:LXOR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OLXOR.OBJ $CTMP5.$$$\r\nE:MALLOC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:MALLOC.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 99 bytes size optimised away\r\n 268 bytes replaced\r\n0:A:ZAS -J -N -OMALLOC.OBJ $CTMP5.$$$\r\nE:MAX.AS\r\n0:A:OPTIMH E:MAX.AS $CTMP5.$$$\r\n 1 bytes size optimised away\r\n 2 bytes replaced\r\n0:A:ZAS -J -OMAX.OBJ $CTMP5.$$$\r\nE:MEMCMP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:MEMCMP.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 13 bytes size optimised away\r\n 26 bytes replaced\r\n0:A:ZAS -J -N -OMEMCMP.OBJ $CTMP5.$$$\r\nE:MEMCPY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:MEMCPY.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OMEMCPY.OBJ $CTMP5.$$$\r\nE:MEMSET.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:MEMSET.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 14 bytes size optimised away\r\n 28 bytes replaced\r\n0:A:ZAS -J -N -OMEMSET.OBJ $CTMP5.$$$\r\nE:MKTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:MKTIME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 75 bytes size optimised away\r\n 140 bytes replaced\r\n0:A:ZAS -J -N -OMKTIME.OBJ $CTMP5.$$$\r\nE:OPEN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:OPEN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 30 bytes size optimised away\r\n 81 bytes replaced\r\n0:A:ZAS -J -N -OOPEN.OBJ $CTMP5.$$$\r\nE:PERROR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:PERROR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 8 bytes size optimised away\r\n 18 bytes replaced\r\n0:A:ZAS -J -N -OPERROR.OBJ $CTMP5.$$$\r\nE:PNUM.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:PNUM.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 28 bytes size optimised away\r\n 50 bytes replaced\r\n0:A:ZAS -J -N -OPNUM.OBJ $CTMP5.$$$\r\nE:PRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:PRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 5 bytes size optimised away\r\n 6 bytes replaced\r\n0:A:ZAS -J -N -OPRINTF.OBJ $CTMP5.$$$\r\nE:PUTCHAR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:PUTCHAR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -N -OPUTCHAR.OBJ $CTMP5.$$$\r\nERA $CTMP1.$$$\r\nERA $CTMP2.$$$\r\nERA $CTMP3.$$$\r\nERA $CTMP5.$$$\r\nERA $$EXEC.$$$\r\n\r\n10M>c280\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -v -o2 -c e:puts.c \\\r\nc> e:putw.c \\\r\nc> e:qsort.c \\\r\nc> e:rand.c \\\r\nc> e:rcsv.as \\\r\nc> e:read.c \\\r\nc> e:remove.c \\\r\nc> e:rename.c \\\r\nc> e:rewind.c \\\r\nc> e:rindex.as \\\r\nc> e:sbrk.as \\\r\nc> e:scanf.c \\\r\nc> e:seek.c \\\r\nc> e:setbuf.c \\\r\nc> e:shar.as \\\r\nc> e:shll.as \\\r\nc> e:shlr.as \\\r\nc> e:signal.c \\\r\nc> e:sprintf.c \\\r\nc> e:srand1.c \\\r\nc> e:srand.as \\\r\nc> e:sscanf.c \\\r\nc> e:start1.as \\\r\nc> e:start2.as \\\r\nc> e:stat.c \\\r\nc> e:stdclean.c \\\r\nc> e:strcat.as \\\r\nc> e:strchr.as \\\r\nc> e:strcmp.as \\\r\nc> e:strcpy.as \\\r\nc> e:strdup.c \\\r\nc> e:strftime.c \\\r\nc> e:stricmp.as \\\r\nc> e:stristr.c \\\r\nc> e:strlen.as \\\r\nc> e:strncat.as \\\r\nc> e:strncmp.as \\\r\nc> e:strncpy.as \\\r\nc> e:strnicmp.as \\\r\nc> e:strnistr.c \\\r\nc> e:strnstr.c \\\r\nc> e:strrchr.as \\\r\nc> e:strstr.c \\\r\nc> e:strtok.c \\\r\nc> e:swap.as \\\r\nc> e:sys_err.c \\\r\nc> e:time.c \\\r\nc> e:timezone.c \\\r\nc> e:tolower.as \\\r\nc> e:toupper.as \\\r\nc> e:ungetc.c \\\r\nc> e:unlink.c \\\r\nc> e:wrelop.as \\\r\nc> e:write.c \\\r\nc> e:xtoi.as \\\r\nc> e:zc280cpm.as \\\r\nc> e:zd280cpm.as \\\r\nc> e:zn280cpm.as \\\r\nc> e:zr280cpm.as \\\r\nc> e:libcver.c\r\nE:PUTS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:PUTS.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 15 bytes size optimised away\r\n 30 bytes replaced\r\n0:A:ZAS -J -N -OPUTS.OBJ $CTMP5.$$$\r\nE:PUTW.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:PUTW.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 8 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -OPUTW.OBJ $CTMP5.$$$\r\nE:QSORT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:QSORT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 142 bytes size optimised away\r\n 351 bytes replaced\r\n0:A:ZAS -J -N -OQSORT.OBJ $CTMP5.$$$\r\nE:RAND.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:RAND.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -N -ORAND.OBJ $CTMP5.$$$\r\nE:RCSV.AS\r\n0:A:OPTIMH E:RCSV.AS $CTMP5.$$$\r\n 6 bytes size optimised away\r\n 12 bytes replaced\r\n0:A:ZAS -J -ORCSV.OBJ $CTMP5.$$$\r\nE:READ.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:READ.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 120 bytes size optimised away\r\n 221 bytes replaced\r\n0:A:ZAS -J -N -OREAD.OBJ $CTMP5.$$$\r\nE:REMOVE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:REMOVE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -N -OREMOVE.OBJ $CTMP5.$$$\r\nE:RENAME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:RENAME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 15 bytes size optimised away\r\n 18 bytes replaced\r\n0:A:ZAS -J -N -ORENAME.OBJ $CTMP5.$$$\r\nE:REWIND.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:REWIND.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 2 bytes size optimised away\r\n 4 bytes replaced\r\n0:A:ZAS -J -N -OREWIND.OBJ $CTMP5.$$$\r\nE:RINDEX.AS\r\n0:A:OPTIMH E:RINDEX.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -ORINDEX.OBJ $CTMP5.$$$\r\nE:SBRK.AS\r\n0:A:OPTIMH E:SBRK.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSBRK.OBJ $CTMP5.$$$\r\nE:SCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 5 bytes size optimised away\r\n 6 bytes replaced\r\n0:A:ZAS -J -N -OSCANF.OBJ $CTMP5.$$$\r\nE:SEEK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SEEK.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 49 bytes size optimised away\r\n 99 bytes replaced\r\n0:A:ZAS -J -N -OSEEK.OBJ $CTMP5.$$$\r\nE:SETBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SETBUF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 40 bytes size optimised away\r\n 80 bytes replaced\r\n0:A:ZAS -J -N -OSETBUF.OBJ $CTMP5.$$$\r\nE:SHAR.AS\r\n0:A:OPTIMH E:SHAR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSHAR.OBJ $CTMP5.$$$\r\nE:SHLL.AS\r\n0:A:OPTIMH E:SHLL.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSHLL.OBJ $CTMP5.$$$\r\nE:SHLR.AS\r\n0:A:OPTIMH E:SHLR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSHLR.OBJ $CTMP5.$$$\r\nE:SIGNAL.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SIGNAL.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OSIGNAL.OBJ $CTMP5.$$$\r\nE:SPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SPRINTF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -OSPRINTF.OBJ $CTMP5.$$$\r\nE:SRAND1.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SRAND1.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OSRAND1.OBJ $CTMP5.$$$\r\nE:SRAND.AS\r\n0:A:OPTIMH E:SRAND.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSRAND.OBJ $CTMP5.$$$\r\nE:SSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SSCANF.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 18 bytes size optimised away\r\n 28 bytes replaced\r\n0:A:ZAS -J -N -OSSCANF.OBJ $CTMP5.$$$\r\nE:START1.AS\r\n0:A:OPTIMH E:START1.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTART1.OBJ $CTMP5.$$$\r\nE:START2.AS\r\n0:A:OPTIMH E:START2.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTART2.OBJ $CTMP5.$$$\r\nE:STAT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STAT.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 73 bytes size optimised away\r\n 154 bytes replaced\r\n0:A:ZAS -J -N -OSTAT.OBJ $CTMP5.$$$\r\nE:STDCLEAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STDCLEAN.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OSTDCLEAN.OBJ $CTMP5.$$$\r\nE:STRCAT.AS\r\n0:A:OPTIMH E:STRCAT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRCAT.OBJ $CTMP5.$$$\r\nE:STRCHR.AS\r\n0:A:OPTIMH E:STRCHR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRCHR.OBJ $CTMP5.$$$\r\nE:STRCMP.AS\r\n0:A:OPTIMH E:STRCMP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRCMP.OBJ $CTMP5.$$$\r\nE:STRCPY.AS\r\n0:A:OPTIMH E:STRCPY.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRCPY.OBJ $CTMP5.$$$\r\nE:STRDUP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRDUP.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 10 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OSTRDUP.OBJ $CTMP5.$$$\r\nE:STRFTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRFTIME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 185 bytes size optimised away\r\n 428 bytes replaced\r\n0:A:ZAS -J -N -OSTRFTIME.OBJ $CTMP5.$$$\r\nE:STRICMP.AS\r\n0:A:OPTIMH E:STRICMP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRICMP.OBJ $CTMP5.$$$\r\nE:STRISTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRISTR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 25 bytes size optimised away\r\n 50 bytes replaced\r\n0:A:ZAS -J -N -OSTRISTR.OBJ $CTMP5.$$$\r\nE:STRLEN.AS\r\n0:A:OPTIMH E:STRLEN.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRLEN.OBJ $CTMP5.$$$\r\nE:STRNCAT.AS\r\n0:A:OPTIMH E:STRNCAT.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRNCAT.OBJ $CTMP5.$$$\r\nE:STRNCMP.AS\r\n0:A:OPTIMH E:STRNCMP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRNCMP.OBJ $CTMP5.$$$\r\nE:STRNCPY.AS\r\n0:A:OPTIMH E:STRNCPY.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRNCPY.OBJ $CTMP5.$$$\r\nE:STRNICMP.AS\r\n0:A:OPTIMH E:STRNICMP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRNICMP.OBJ $CTMP5.$$$\r\nE:STRNISTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRNISTR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 45 bytes size optimised away\r\n 90 bytes replaced\r\n0:A:ZAS -J -N -OSTRNISTR.OBJ $CTMP5.$$$\r\nE:STRNSTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRNSTR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 44 bytes size optimised away\r\n 88 bytes replaced\r\n0:A:ZAS -J -N -OSTRNSTR.OBJ $CTMP5.$$$\r\nE:STRRCHR.AS\r\n0:A:OPTIMH E:STRRCHR.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSTRRCHR.OBJ $CTMP5.$$$\r\nE:STRSTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRSTR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 22 bytes size optimised away\r\n 44 bytes replaced\r\n0:A:ZAS -J -N -OSTRSTR.OBJ $CTMP5.$$$\r\nE:STRTOK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:STRTOK.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 38 bytes size optimised away\r\n 76 bytes replaced\r\n0:A:ZAS -J -N -OSTRTOK.OBJ $CTMP5.$$$\r\nE:SWAP.AS\r\n0:A:OPTIMH E:SWAP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OSWAP.OBJ $CTMP5.$$$\r\nE:SYS_ERR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:SYS_ERR.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OSYS_ERR.OBJ $CTMP5.$$$\r\nE:TIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:TIME.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 18 bytes size optimised away\r\n 32 bytes replaced\r\n0:A:ZAS -J -N -OTIME.OBJ $CTMP5.$$$\r\nE:TIMEZONE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:TIMEZONE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTIMEZONE.OBJ $CTMP5.$$$\r\nE:TOLOWER.AS\r\n0:A:OPTIMH E:TOLOWER.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OTOLOWER.OBJ $CTMP5.$$$\r\nE:TOUPPER.AS\r\n0:A:OPTIMH E:TOUPPER.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OTOUPPER.OBJ $CTMP5.$$$\r\nE:UNGETC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:UNGETC.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 27 bytes size optimised away\r\n 54 bytes replaced\r\n0:A:ZAS -J -N -OUNGETC.OBJ $CTMP5.$$$\r\nE:UNLINK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:UNLINK.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 14 bytes size optimised away\r\n 20 bytes replaced\r\n0:A:ZAS -J -N -OUNLINK.OBJ $CTMP5.$$$\r\nE:WRELOP.AS\r\n0:A:OPTIMH E:WRELOP.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OWRELOP.OBJ $CTMP5.$$$\r\nE:WRITE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:WRITE.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 94 bytes size optimised away\r\n 167 bytes replaced\r\n0:A:ZAS -J -N -OWRITE.OBJ $CTMP5.$$$\r\nE:XTOI.AS\r\n0:A:OPTIMH E:XTOI.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OXTOI.OBJ $CTMP5.$$$\r\nE:ZC280CPM.AS\r\n0:A:OPTIMH E:ZC280CPM.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OZC280CPM.OBJ $CTMP5.$$$\r\nE:ZD280CPM.AS\r\n0:A:OPTIMH E:ZD280CPM.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OZD280CPM.OBJ $CTMP5.$$$\r\nE:ZN280CPM.AS\r\n0:A:OPTIMH E:ZN280CPM.AS $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -OZN280CPM.OBJ $CTMP5.$$$\r\nE:ZR280CPM.AS\r\n0:A:OPTIMH E:ZR280CPM.AS $CTMP5.$$$\r\n 3 bytes size optimised away\r\n 10 bytes replaced\r\n0:A:ZAS -J -OZR280CPM.OBJ $CTMP5.$$$\r\nE:LIBCVER.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: E:LIBCVER.C $CTMP1.$$$\r\n0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$\r\n0:A:CGEN $CTMP2.$$$ $CTMP1.$$$\r\n0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$\r\n0:A:OPTIMH $CTMP2.$$$ $CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OLIBCVER.OBJ $CTMP5.$$$\r\nERA $CTMP1.$$$\r\nERA $CTMP2.$$$\r\nERA $CTMP3.$$$\r\nERA $CTMP5.$$$\r\nERA $$EXEC.$$$\r\n\r\n10M>; All modules compiled.\r\n10M>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "stdio/C280LIBC.SUB",
    "content": "era c280libc.log\r\nput console output to file c280libc.log [system]\r\ndate\r\n; Compile all LIB280C.LIB modules from sources for Z280\r\n;\r\n; Sources are on drive E:\r\n; Z280 object files are created on drive M:\r\n;\r\nm:\r\npip m:=e:stdio.i\r\nc280\r\n<-v -o2 -c e:abort.c \\\r\n<e:abs.as \\\r\n<e:allsh.as \\\r\n<e:alrsh.as \\\r\n<e:asallsh.as \\\r\n<e:asalrsh.as \\\r\n<e:asar.as \\\r\n<e:asdiv.as \\\r\n<e:asladd.as \\\r\n<e:asland.as \\\r\n<e:asll.as \\\r\n<e:asllrsh.as \\\r\n<e:aslmul.as \\\r\n<e:aslor.as \\\r\n<e:aslr.as \\\r\n<e:aslsub.as \\\r\n<e:aslxor.as \\\r\n<e:asmod.as \\\r\n<e:asmul.as \\\r\n<e:assert.c \\\r\n<e:atoi.as \\\r\n<e:atol.c \\\r\n<e:bdos.as \\\r\n<e:bios.as \\\r\n<e:bitfield.as \\\r\n<e:blkclr.as \\\r\n<e:blkcpy.c \\\r\n<e:bmove.as \\\r\n<e:brelop.as \\\r\n<e:buf.c \\\r\n<e:calloc.c \\\r\n<e:cgets.c \\\r\n<e:chmod.c \\\r\n<e:cleanup.c \\\r\n<e:close.c \\\r\n<e:convtime.c \\\r\n<e:cputs.c \\\r\n<e:creat.c \\\r\n<e:csv.as \\\r\n<e:ctime.c \\\r\n<e:ctype_.c \\\r\n<e:ctype.c \\\r\n<e:doprnt.c \\\r\n<e:doscan.c \\\r\n<e:dup.c \\\r\n<e:exec.as \\\r\n<e:execl.as \\\r\n<e:_exit.as \\\r\n<e:exit.c \\\r\n<e:fakeclea.c \\\r\n<e:fakecpcl.as \\\r\n<e:fcbname.c \\\r\n<e:fclose.c \\\r\n<e:fflush.c \\\r\n<e:fgetc.c \\\r\n<e:filbuf.c \\\r\n<e:flsbuf.c \\\r\n<e:fopen.c \\\r\n<e:fprintf.c \\\r\n<e:fputc.c \\\r\n<e:fread.c \\\r\n<e:frelop.as \\\r\n<e:freopen.c \\\r\n<e:fscanf.c \\\r\n<e:fseek.c \\\r\n<e:fwrite.c \\\r\n<e:getargs.c \\\r\n<e:getch.c \\\r\n<e:getenv.c \\\r\n<e:getfcb.c \\\r\n<e:gets.c \\\r\n<e:getsp.as \\\r\n<e:getuid.as \\\r\n<e:getw.c \\\r\n<e:idiv.as \\\r\n<e:imul.as \\\r\n<e:index.as \\\r\n<e:inout.as \\\r\n<e:iregset.as \\\r\n<e:isalpha.as \\\r\n<e:isatty.c \\\r\n<e:isdigit.as\r\nc280\r\n<-v -o2 -c e:islower.as \\\r\n<e:isspace.as \\\r\n<e:isupper.as \\\r\n<e:ladd.as \\\r\n<e:land.as \\\r\n<e:ldiv.as \\\r\n<e:linc.as \\\r\n<e:llrsh.as \\\r\n<e:lmul.as \\\r\n<e:longjmp.as \\\r\n<e:lor.as \\\r\n<e:lrelop.as \\\r\n<e:lsub.as \\\r\n<e:lxor.as \\\r\n<e:malloc.c \\\r\n<e:max.as \\\r\n<e:memcmp.c \\\r\n<e:memcpy.c \\\r\n<e:memset.c \\\r\n<e:mktime.c \\\r\n<e:open.c \\\r\n<e:perror.c \\\r\n<e:pnum.c \\\r\n<e:printf.c \\\r\n<e:putchar.c\r\nc280\r\n<-v -o2 -c e:puts.c \\\r\n<e:putw.c \\\r\n<e:qsort.c \\\r\n<e:rand.c \\\r\n<e:rcsv.as \\\r\n<e:read.c \\\r\n<e:remove.c \\\r\n<e:rename.c \\\r\n<e:rewind.c \\\r\n<e:rindex.as \\\r\n<e:sbrk.as \\\r\n<e:scanf.c \\\r\n<e:seek.c \\\r\n<e:setbuf.c \\\r\n<e:shar.as \\\r\n<e:shll.as \\\r\n<e:shlr.as \\\r\n<e:signal.c \\\r\n<e:sprintf.c \\\r\n<e:srand1.c \\\r\n<e:srand.as \\\r\n<e:sscanf.c \\\r\n<e:start1.as \\\r\n<e:start2.as \\\r\n<e:stat.c \\\r\n<e:stdclean.c \\\r\n<e:strcat.as \\\r\n<e:strchr.as \\\r\n<e:strcmp.as \\\r\n<e:strcpy.as \\\r\n<e:strdup.c \\\r\n<e:strftime.c \\\r\n<e:stricmp.as \\\r\n<e:stristr.c \\\r\n<e:strlen.as \\\r\n<e:strncat.as \\\r\n<e:strncmp.as \\\r\n<e:strncpy.as \\\r\n<e:strnicmp.as \\\r\n<e:strnistr.c \\\r\n<e:strnstr.c \\\r\n<e:strrchr.as \\\r\n<e:strstr.c \\\r\n<e:strtok.c \\\r\n<e:swap.as \\\r\n<e:sys_err.c \\\r\n<e:time.c \\\r\n<e:timezone.c \\\r\n<e:tolower.as \\\r\n<e:toupper.as \\\r\n<e:ungetc.c \\\r\n<e:unlink.c \\\r\n<e:wrelop.as \\\r\n<e:write.c \\\r\n<e:xtoi.as \\\r\n<e:zc280cpm.as \\\r\n<e:zd280cpm.as \\\r\n<e:zn280cpm.as \\\r\n<e:zr280cpm.as \\\r\n<e:libcver.c\r\n; All modules compiled.\r\nput console to console\r\ne:\r\n"
  },
  {
    "path": "stdio/CGETS.C",
    "content": "#include\t<conio.h>\r\n\r\nchar *\r\ncgets(s)\r\nchar *\ts;\r\n{\r\n\tchar *\ts1 = s;\r\n\tint\tc;\r\n\r\n\twhile((c = getche()) != '\\r' &&  c != '\\n')\r\n\t\t*s++ = c;\r\n\t*s = 0;\r\n\tif(s == s1)\r\n\t\treturn((char *)0);\r\n\treturn(s1);\r\n}\r\n"
  },
  {
    "path": "stdio/COMPLIBC.LOG",
    "content": "\r\n10E>date\r\nA:DATE     COM  (User 0)\r\n\rFri 05/09/2025 09:37:50\r\n10E>; Compile all LIBC19.LIB modules from sources\r\n10E>c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -o -v -c abort.c \\\r\nc> abs.as \\\r\nc> allsh.as \\\r\nc> alrsh.as \\\r\nc> asallsh.as \\\r\nc> asalrsh.as \\\r\nc> asar.as \\\r\nc> asdiv.as \\\r\nc> asladd.as \\\r\nc> asland.as \\\r\nc> asll.as \\\r\nc> asllrsh.as \\\r\nc> aslmul.as \\\r\nc> aslor.as \\\r\nc> aslr.as \\\r\nc> aslsub.as \\\r\nc> aslxor.as \\\r\nc> asmod.as \\\r\nc> asmul.as \\\r\nc> assert.c \\\r\nc> atoi.as \\\r\nc> atol.c \\\r\nc> bdos.as \\\r\nc> bios.as \\\r\nc> bitfield.as \\\r\nc> blkclr.as \\\r\nc> blkcpy.c \\\r\nc> bmove.as \\\r\nc> brelop.as \\\r\nc> buf.c \\\r\nc> calloc.c \\\r\nc> cgets.c \\\r\nc> chmod.c \\\r\nc> cleanup.c \\\r\nc> close.c \\\r\nc> convtime.c \\\r\nc> cputs.c \\\r\nc> creat.c \\\r\nc> csv.as \\\r\nc> ctime.c \\\r\nc> ctype_.c \\\r\nc> ctype.c \\\r\nc> doprnt.c \\\r\nc> doscan.c \\\r\nc> dup.c \\\r\nc> exec.as \\\r\nc> execl.as \\\r\nc> _exit.as \\\r\nc> exit.c \\\r\nc> fakeclea.c \\\r\nc> fakecpcl.as \\\r\nc> fcbname.c \\\r\nc> fclose.c \\\r\nc> fflush.c \\\r\nc> fgetc.c \\\r\nc> filbuf.c \\\r\nc> flsbuf.c \\\r\nc> fopen.c \\\r\nc> fprintf.c \\\r\nc> fputc.c \\\r\nc> fread.c \\\r\nc> frelop.as \\\r\nc> freopen.c \\\r\nc> fscanf.c \\\r\nc> fseek.c \\\r\nc> fwrite.c \\\r\nc> getargs.c \\\r\nc> getch.c \\\r\nc> getenv.c \\\r\nc> getfcb.c \\\r\nc> gets.c \\\r\nc> getsp.as \\\r\nc> getuid.as \\\r\nc> getw.c \\\r\nc> idiv.as \\\r\nc> imul.as \\\r\nc> index.as \\\r\nc> inout.as \\\r\nc> iregset.as \\\r\nc> isalpha.as \\\r\nc> isatty.c \\\r\nc> isdigit.as\r\nABORT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: ABORT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OABORT.OBJ M:$CTMP2.$$$\r\nABS.AS\r\n0:A:ZAS -J -OABS.OBJ ABS.AS\r\nALLSH.AS\r\n0:A:ZAS -J -OALLSH.OBJ ALLSH.AS\r\nALRSH.AS\r\n0:A:ZAS -J -OALRSH.OBJ ALRSH.AS\r\nASALLSH.AS\r\n0:A:ZAS -J -OASALLSH.OBJ ASALLSH.AS\r\nASALRSH.AS\r\n0:A:ZAS -J -OASALRSH.OBJ ASALRSH.AS\r\nASAR.AS\r\n0:A:ZAS -J -OASAR.OBJ ASAR.AS\r\nASDIV.AS\r\n0:A:ZAS -J -OASDIV.OBJ ASDIV.AS\r\nASLADD.AS\r\n0:A:ZAS -J -OASLADD.OBJ ASLADD.AS\r\nASLAND.AS\r\n0:A:ZAS -J -OASLAND.OBJ ASLAND.AS\r\nASLL.AS\r\n0:A:ZAS -J -OASLL.OBJ ASLL.AS\r\nASLLRSH.AS\r\n0:A:ZAS -J -OASLLRSH.OBJ ASLLRSH.AS\r\nASLMUL.AS\r\n0:A:ZAS -J -OASLMUL.OBJ ASLMUL.AS\r\nASLOR.AS\r\n0:A:ZAS -J -OASLOR.OBJ ASLOR.AS\r\nASLR.AS\r\n0:A:ZAS -J -OASLR.OBJ ASLR.AS\r\nASLSUB.AS\r\n0:A:ZAS -J -OASLSUB.OBJ ASLSUB.AS\r\nASLXOR.AS\r\n0:A:ZAS -J -OASLXOR.OBJ ASLXOR.AS\r\nASMOD.AS\r\n0:A:ZAS -J -OASMOD.OBJ ASMOD.AS\r\nASMUL.AS\r\n0:A:ZAS -J -OASMUL.OBJ ASMUL.AS\r\nASSERT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: ASSERT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OASSERT.OBJ M:$CTMP2.$$$\r\nATOI.AS\r\n0:A:ZAS -J -OATOI.OBJ ATOI.AS\r\nATOL.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: ATOL.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OATOL.OBJ M:$CTMP2.$$$\r\nBDOS.AS\r\n0:A:ZAS -J -OBDOS.OBJ BDOS.AS\r\nBIOS.AS\r\n0:A:ZAS -J -OBIOS.OBJ BIOS.AS\r\nBITFIELD.AS\r\n0:A:ZAS -J -OBITFIELD.OBJ BITFIELD.AS\r\nBLKCLR.AS\r\n0:A:ZAS -J -OBLKCLR.OBJ BLKCLR.AS\r\nBLKCPY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: BLKCPY.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OBLKCPY.OBJ M:$CTMP2.$$$\r\nBMOVE.AS\r\n0:A:ZAS -J -OBMOVE.OBJ BMOVE.AS\r\nBRELOP.AS\r\n0:A:ZAS -J -OBRELOP.OBJ BRELOP.AS\r\nBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: BUF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OBUF.OBJ M:$CTMP2.$$$\r\nCALLOC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CALLOC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCALLOC.OBJ M:$CTMP2.$$$\r\nCGETS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CGETS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCGETS.OBJ M:$CTMP2.$$$\r\nCHMOD.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CHMOD.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCHMOD.OBJ M:$CTMP2.$$$\r\nCLEANUP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CLEANUP.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCLEANUP.OBJ M:$CTMP2.$$$\r\nCLOSE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CLOSE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCLOSE.OBJ M:$CTMP2.$$$\r\nCONVTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CONVTIME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCONVTIME.OBJ M:$CTMP2.$$$\r\nCPUTS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CPUTS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCPUTS.OBJ M:$CTMP2.$$$\r\nCREAT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CREAT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCREAT.OBJ M:$CTMP2.$$$\r\nCSV.AS\r\n0:A:ZAS -J -OCSV.OBJ CSV.AS\r\nCTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CTIME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCTIME.OBJ M:$CTMP2.$$$\r\nCTYPE_.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CTYPE_.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCTYPE_.OBJ M:$CTMP2.$$$\r\nCTYPE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: CTYPE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OCTYPE.OBJ M:$CTMP2.$$$\r\nDOPRNT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: DOPRNT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -ODOPRNT.OBJ M:$CTMP2.$$$\r\nDOSCAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: DOSCAN.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -ODOSCAN.OBJ M:$CTMP2.$$$\r\nDUP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: DUP.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -ODUP.OBJ M:$CTMP2.$$$\r\nEXEC.AS\r\n0:A:ZAS -J -OEXEC.OBJ EXEC.AS\r\nEXECL.AS\r\n0:A:ZAS -J -OEXECL.OBJ EXECL.AS\r\n_EXIT.AS\r\n0:A:ZAS -J -O_EXIT.OBJ _EXIT.AS\r\nEXIT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: EXIT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OEXIT.OBJ M:$CTMP2.$$$\r\nFAKECLEA.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FAKECLEA.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFAKECLEA.OBJ M:$CTMP2.$$$\r\nFAKECPCL.AS\r\n0:A:ZAS -J -OFAKECPCL.OBJ FAKECPCL.AS\r\nFCBNAME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FCBNAME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFCBNAME.OBJ M:$CTMP2.$$$\r\nFCLOSE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FCLOSE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFCLOSE.OBJ M:$CTMP2.$$$\r\nFFLUSH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FFLUSH.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFFLUSH.OBJ M:$CTMP2.$$$\r\nFGETC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FGETC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFGETC.OBJ M:$CTMP2.$$$\r\nFILBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FILBUF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFILBUF.OBJ M:$CTMP2.$$$\r\nFLSBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FLSBUF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFLSBUF.OBJ M:$CTMP2.$$$\r\nFOPEN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FOPEN.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFOPEN.OBJ M:$CTMP2.$$$\r\nFPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FPRINTF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFPRINTF.OBJ M:$CTMP2.$$$\r\nFPUTC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FPUTC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFPUTC.OBJ M:$CTMP2.$$$\r\nFREAD.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FREAD.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFREAD.OBJ M:$CTMP2.$$$\r\nFRELOP.AS\r\n0:A:ZAS -J -OFRELOP.OBJ FRELOP.AS\r\nFREOPEN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FREOPEN.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFREOPEN.OBJ M:$CTMP2.$$$\r\nFSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FSCANF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFSCANF.OBJ M:$CTMP2.$$$\r\nFSEEK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FSEEK.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFSEEK.OBJ M:$CTMP2.$$$\r\nFWRITE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FWRITE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFWRITE.OBJ M:$CTMP2.$$$\r\nGETARGS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: GETARGS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OGETARGS.OBJ M:$CTMP2.$$$\r\nGETCH.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: GETCH.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OGETCH.OBJ M:$CTMP2.$$$\r\nGETENV.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: GETENV.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OGETENV.OBJ M:$CTMP2.$$$\r\nGETFCB.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: GETFCB.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OGETFCB.OBJ M:$CTMP2.$$$\r\nGETS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: GETS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OGETS.OBJ M:$CTMP2.$$$\r\nGETSP.AS\r\n0:A:ZAS -J -OGETSP.OBJ GETSP.AS\r\nGETUID.AS\r\n0:A:ZAS -J -OGETUID.OBJ GETUID.AS\r\nGETW.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: GETW.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OGETW.OBJ M:$CTMP2.$$$\r\nIDIV.AS\r\n0:A:ZAS -J -OIDIV.OBJ IDIV.AS\r\nIMUL.AS\r\n0:A:ZAS -J -OIMUL.OBJ IMUL.AS\r\nINDEX.AS\r\n0:A:ZAS -J -OINDEX.OBJ INDEX.AS\r\nINOUT.AS\r\n0:A:ZAS -J -OINOUT.OBJ INOUT.AS\r\nIREGSET.AS\r\n0:A:ZAS -J -OIREGSET.OBJ IREGSET.AS\r\nISALPHA.AS\r\n0:A:ZAS -J -OISALPHA.OBJ ISALPHA.AS\r\nISATTY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: ISATTY.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OISATTY.OBJ M:$CTMP2.$$$\r\nISDIGIT.AS\r\n0:A:ZAS -J -OISDIGIT.OBJ ISDIGIT.AS\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -o -v -c islower.as \\\r\nc> isspace.as \\\r\nc> isupper.as \\\r\nc> ladd.as \\\r\nc> land.as \\\r\nc> ldiv.as \\\r\nc> linc.as \\\r\nc> llrsh.as \\\r\nc> lmul.as \\\r\nc> longjmp.as \\\r\nc> lor.as \\\r\nc> lrelop.as \\\r\nc> lsub.as \\\r\nc> lxor.as \\\r\nc> malloc.c \\\r\nc> max.as \\\r\nc> memcmp.c \\\r\nc> memcpy.c \\\r\nc> memset.c \\\r\nc> mktime.c \\\r\nc> open.c \\\r\nc> perror.c \\\r\nc> pnum.c \\\r\nc> printf.c \\\r\nc> putchar.c\r\nISLOWER.AS\r\n0:A:ZAS -J -OISLOWER.OBJ ISLOWER.AS\r\nISSPACE.AS\r\n0:A:ZAS -J -OISSPACE.OBJ ISSPACE.AS\r\nISUPPER.AS\r\n0:A:ZAS -J -OISUPPER.OBJ ISUPPER.AS\r\nLADD.AS\r\n0:A:ZAS -J -OLADD.OBJ LADD.AS\r\nLAND.AS\r\n0:A:ZAS -J -OLAND.OBJ LAND.AS\r\nLDIV.AS\r\n0:A:ZAS -J -OLDIV.OBJ LDIV.AS\r\nLINC.AS\r\n0:A:ZAS -J -OLINC.OBJ LINC.AS\r\nLLRSH.AS\r\n0:A:ZAS -J -OLLRSH.OBJ LLRSH.AS\r\nLMUL.AS\r\n0:A:ZAS -J -OLMUL.OBJ LMUL.AS\r\nLONGJMP.AS\r\n0:A:ZAS -J -OLONGJMP.OBJ LONGJMP.AS\r\nLOR.AS\r\n0:A:ZAS -J -OLOR.OBJ LOR.AS\r\nLRELOP.AS\r\n0:A:ZAS -J -OLRELOP.OBJ LRELOP.AS\r\nLSUB.AS\r\n0:A:ZAS -J -OLSUB.OBJ LSUB.AS\r\nLXOR.AS\r\n0:A:ZAS -J -OLXOR.OBJ LXOR.AS\r\nMALLOC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: MALLOC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OMALLOC.OBJ M:$CTMP2.$$$\r\nMAX.AS\r\n0:A:ZAS -J -OMAX.OBJ MAX.AS\r\nMEMCMP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: MEMCMP.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OMEMCMP.OBJ M:$CTMP2.$$$\r\nMEMCPY.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: MEMCPY.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OMEMCPY.OBJ M:$CTMP2.$$$\r\nMEMSET.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: MEMSET.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OMEMSET.OBJ M:$CTMP2.$$$\r\nMKTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: MKTIME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OMKTIME.OBJ M:$CTMP2.$$$\r\nOPEN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: OPEN.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OOPEN.OBJ M:$CTMP2.$$$\r\nPERROR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: PERROR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OPERROR.OBJ M:$CTMP2.$$$\r\nPNUM.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: PNUM.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OPNUM.OBJ M:$CTMP2.$$$\r\nPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: PRINTF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OPRINTF.OBJ M:$CTMP2.$$$\r\nPUTCHAR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: PUTCHAR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OPUTCHAR.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nc> -o -v -c puts.c \\\r\nc> putw.c \\\r\nc> qsort.c \\\r\nc> rand.c \\\r\nc> rcsv.as \\\r\nc> read.c \\\r\nc> remove.c \\\r\nc> rename.c \\\r\nc> rewind.c \\\r\nc> rindex.as \\\r\nc> sbrk.as \\\r\nc> scanf.c \\\r\nc> seek.c \\\r\nc> setbuf.c \\\r\nc> shar.as \\\r\nc> shll.as \\\r\nc> shlr.as \\\r\nc> signal.c \\\r\nc> sprintf.c \\\r\nc> srand1.c \\\r\nc> srand.as \\\r\nc> sscanf.c \\\r\nc> start1.as \\\r\nc> start2.as \\\r\nc> stat.c \\\r\nc> stdclean.c \\\r\nc> strcat.as \\\r\nc> strchr.as \\\r\nc> strcmp.as \\\r\nc> strcpy.as \\\r\nc> strdup.c \\\r\nc> strftime.c \\\r\nc> stricmp.as \\\r\nc> stristr.c \\\r\nc> strlen.as \\\r\nc> strncat.as \\\r\nc> strncmp.as \\\r\nc> strncpy.as \\\r\nc> strnicmp.as \\\r\nc> strnistr.c \\\r\nc> strnstr.c \\\r\nc> strrchr.as \\\r\nc> strstr.c \\\r\nc> strtok.c \\\r\nc> swap.as \\\r\nc> sys_err.c \\\r\nc> time.c \\\r\nc> timezone.c \\\r\nc> tolower.as \\\r\nc> toupper.as \\\r\nc> ungetc.c \\\r\nc> unlink.c \\\r\nc> wrelop.as \\\r\nc> write.c \\\r\nc> xtoi.as \\\r\nc> zcrtcpm.as \\\r\nc> zdrtcpm.as \\\r\nc> znrtcpm.as \\\r\nc> zrrtcpm.as \\\r\nc> libcver.c\r\nPUTS.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: PUTS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OPUTS.OBJ M:$CTMP2.$$$\r\nPUTW.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: PUTW.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OPUTW.OBJ M:$CTMP2.$$$\r\nQSORT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: QSORT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OQSORT.OBJ M:$CTMP2.$$$\r\nRAND.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: RAND.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -ORAND.OBJ M:$CTMP2.$$$\r\nRCSV.AS\r\n0:A:ZAS -J -ORCSV.OBJ RCSV.AS\r\nREAD.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: READ.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OREAD.OBJ M:$CTMP2.$$$\r\nREMOVE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: REMOVE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OREMOVE.OBJ M:$CTMP2.$$$\r\nRENAME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: RENAME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -ORENAME.OBJ M:$CTMP2.$$$\r\nREWIND.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: REWIND.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OREWIND.OBJ M:$CTMP2.$$$\r\nRINDEX.AS\r\n0:A:ZAS -J -ORINDEX.OBJ RINDEX.AS\r\nSBRK.AS\r\n0:A:ZAS -J -OSBRK.OBJ SBRK.AS\r\nSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SCANF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSCANF.OBJ M:$CTMP2.$$$\r\nSEEK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SEEK.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSEEK.OBJ M:$CTMP2.$$$\r\nSETBUF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SETBUF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSETBUF.OBJ M:$CTMP2.$$$\r\nSHAR.AS\r\n0:A:ZAS -J -OSHAR.OBJ SHAR.AS\r\nSHLL.AS\r\n0:A:ZAS -J -OSHLL.OBJ SHLL.AS\r\nSHLR.AS\r\n0:A:ZAS -J -OSHLR.OBJ SHLR.AS\r\nSIGNAL.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SIGNAL.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSIGNAL.OBJ M:$CTMP2.$$$\r\nSPRINTF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SPRINTF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSPRINTF.OBJ M:$CTMP2.$$$\r\nSRAND1.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SRAND1.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSRAND1.OBJ M:$CTMP2.$$$\r\nSRAND.AS\r\n0:A:ZAS -J -OSRAND.OBJ SRAND.AS\r\nSSCANF.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SSCANF.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSSCANF.OBJ M:$CTMP2.$$$\r\nSTART1.AS\r\n0:A:ZAS -J -OSTART1.OBJ START1.AS\r\nSTART2.AS\r\n0:A:ZAS -J -OSTART2.OBJ START2.AS\r\nSTAT.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STAT.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTAT.OBJ M:$CTMP2.$$$\r\nSTDCLEAN.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STDCLEAN.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTDCLEAN.OBJ M:$CTMP2.$$$\r\nSTRCAT.AS\r\n0:A:ZAS -J -OSTRCAT.OBJ STRCAT.AS\r\nSTRCHR.AS\r\n0:A:ZAS -J -OSTRCHR.OBJ STRCHR.AS\r\nSTRCMP.AS\r\n0:A:ZAS -J -OSTRCMP.OBJ STRCMP.AS\r\nSTRCPY.AS\r\n0:A:ZAS -J -OSTRCPY.OBJ STRCPY.AS\r\nSTRDUP.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRDUP.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRDUP.OBJ M:$CTMP2.$$$\r\nSTRFTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRFTIME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRFTIME.OBJ M:$CTMP2.$$$\r\nSTRICMP.AS\r\n0:A:ZAS -J -OSTRICMP.OBJ STRICMP.AS\r\nSTRISTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRISTR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRISTR.OBJ M:$CTMP2.$$$\r\nSTRLEN.AS\r\n0:A:ZAS -J -OSTRLEN.OBJ STRLEN.AS\r\nSTRNCAT.AS\r\n0:A:ZAS -J -OSTRNCAT.OBJ STRNCAT.AS\r\nSTRNCMP.AS\r\n0:A:ZAS -J -OSTRNCMP.OBJ STRNCMP.AS\r\nSTRNCPY.AS\r\n0:A:ZAS -J -OSTRNCPY.OBJ STRNCPY.AS\r\nSTRNICMP.AS\r\n0:A:ZAS -J -OSTRNICMP.OBJ STRNICMP.AS\r\nSTRNISTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRNISTR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRNISTR.OBJ M:$CTMP2.$$$\r\nSTRNSTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRNSTR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRNSTR.OBJ M:$CTMP2.$$$\r\nSTRRCHR.AS\r\n0:A:ZAS -J -OSTRRCHR.OBJ STRRCHR.AS\r\nSTRSTR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRSTR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRSTR.OBJ M:$CTMP2.$$$\r\nSTRTOK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: STRTOK.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSTRTOK.OBJ M:$CTMP2.$$$\r\nSWAP.AS\r\n0:A:ZAS -J -OSWAP.OBJ SWAP.AS\r\nSYS_ERR.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: SYS_ERR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OSYS_ERR.OBJ M:$CTMP2.$$$\r\nTIME.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TIME.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTIME.OBJ M:$CTMP2.$$$\r\nTIMEZONE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TIMEZONE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTIMEZONE.OBJ M:$CTMP2.$$$\r\nTOLOWER.AS\r\n0:A:ZAS -J -OTOLOWER.OBJ TOLOWER.AS\r\nTOUPPER.AS\r\n0:A:ZAS -J -OTOUPPER.OBJ TOUPPER.AS\r\nUNGETC.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: UNGETC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OUNGETC.OBJ M:$CTMP2.$$$\r\nUNLINK.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: UNLINK.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OUNLINK.OBJ M:$CTMP2.$$$\r\nWRELOP.AS\r\n0:A:ZAS -J -OWRELOP.OBJ WRELOP.AS\r\nWRITE.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: WRITE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OWRITE.OBJ M:$CTMP2.$$$\r\nXTOI.AS\r\n0:A:ZAS -J -OXTOI.OBJ XTOI.AS\r\nZCRTCPM.AS\r\n0:A:ZAS -J -OZCRTCPM.OBJ ZCRTCPM.AS\r\nZDRTCPM.AS\r\n0:A:ZAS -J -OZDRTCPM.OBJ ZDRTCPM.AS\r\nZNRTCPM.AS\r\n0:A:ZAS -J -OZNRTCPM.OBJ ZNRTCPM.AS\r\nZRRTCPM.AS\r\n0:A:ZAS -J -OZRRTCPM.OBJ ZRRTCPM.AS\r\nLIBCVER.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: LIBCVER.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OLIBCVER.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\nERA M:$$EXEC.$$$\r\n\r\n10E>; All modules compiled.\r\n10E>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "stdio/COMPLIBC.SUB",
    "content": "era complibc.log\r\nput console output to file complibc.log [system]\r\ndate\r\n; Compile all LIBC19.LIB modules from sources\r\nc\r\n<-o -v -c abort.c \\\r\n<abs.as \\\r\n<allsh.as \\\r\n<alrsh.as \\\r\n<asallsh.as \\\r\n<asalrsh.as \\\r\n<asar.as \\\r\n<asdiv.as \\\r\n<asladd.as \\\r\n<asland.as \\\r\n<asll.as \\\r\n<asllrsh.as \\\r\n<aslmul.as \\\r\n<aslor.as \\\r\n<aslr.as \\\r\n<aslsub.as \\\r\n<aslxor.as \\\r\n<asmod.as \\\r\n<asmul.as \\\r\n<assert.c \\\r\n<atoi.as \\\r\n<atol.c \\\r\n<bdos.as \\\r\n<bios.as \\\r\n<bitfield.as \\\r\n<blkclr.as \\\r\n<blkcpy.c \\\r\n<bmove.as \\\r\n<brelop.as \\\r\n<buf.c \\\r\n<calloc.c \\\r\n<cgets.c \\\r\n<chmod.c \\\r\n<cleanup.c \\\r\n<close.c \\\r\n<convtime.c \\\r\n<cputs.c \\\r\n<creat.c \\\r\n<csv.as \\\r\n<ctime.c \\\r\n<ctype_.c \\\r\n<ctype.c \\\r\n<doprnt.c \\\r\n<doscan.c \\\r\n<dup.c \\\r\n<exec.as \\\r\n<execl.as \\\r\n<_exit.as \\\r\n<exit.c \\\r\n<fakeclea.c \\\r\n<fakecpcl.as \\\r\n<fcbname.c \\\r\n<fclose.c \\\r\n<fflush.c \\\r\n<fgetc.c \\\r\n<filbuf.c \\\r\n<flsbuf.c \\\r\n<fopen.c \\\r\n<fprintf.c \\\r\n<fputc.c \\\r\n<fread.c \\\r\n<frelop.as \\\r\n<freopen.c \\\r\n<fscanf.c \\\r\n<fseek.c \\\r\n<fwrite.c \\\r\n<getargs.c \\\r\n<getch.c \\\r\n<getenv.c \\\r\n<getfcb.c \\\r\n<gets.c \\\r\n<getsp.as \\\r\n<getuid.as \\\r\n<getw.c \\\r\n<idiv.as \\\r\n<imul.as \\\r\n<index.as \\\r\n<inout.as \\\r\n<iregset.as \\\r\n<isalpha.as \\\r\n<isatty.c \\\r\n<isdigit.as\r\nc\r\n<-o -v -c islower.as \\\r\n<isspace.as \\\r\n<isupper.as \\\r\n<ladd.as \\\r\n<land.as \\\r\n<ldiv.as \\\r\n<linc.as \\\r\n<llrsh.as \\\r\n<lmul.as \\\r\n<longjmp.as \\\r\n<lor.as \\\r\n<lrelop.as \\\r\n<lsub.as \\\r\n<lxor.as \\\r\n<malloc.c \\\r\n<max.as \\\r\n<memcmp.c \\\r\n<memcpy.c \\\r\n<memset.c \\\r\n<mktime.c \\\r\n<open.c \\\r\n<perror.c \\\r\n<pnum.c \\\r\n<printf.c \\\r\n<putchar.c\r\nc\r\n<-o -v -c puts.c \\\r\n<putw.c \\\r\n<qsort.c \\\r\n<rand.c \\\r\n<rcsv.as \\\r\n<read.c \\\r\n<remove.c \\\r\n<rename.c \\\r\n<rewind.c \\\r\n<rindex.as \\\r\n<sbrk.as \\\r\n<scanf.c \\\r\n<seek.c \\\r\n<setbuf.c \\\r\n<shar.as \\\r\n<shll.as \\\r\n<shlr.as \\\r\n<signal.c \\\r\n<sprintf.c \\\r\n<srand1.c \\\r\n<srand.as \\\r\n<sscanf.c \\\r\n<start1.as \\\r\n<start2.as \\\r\n<stat.c \\\r\n<stdclean.c \\\r\n<strcat.as \\\r\n<strchr.as \\\r\n<strcmp.as \\\r\n<strcpy.as \\\r\n<strdup.c \\\r\n<strftime.c \\\r\n<stricmp.as \\\r\n<stristr.c \\\r\n<strlen.as \\\r\n<strncat.as \\\r\n<strncmp.as \\\r\n<strncpy.as \\\r\n<strnicmp.as \\\r\n<strnistr.c \\\r\n<strnstr.c \\\r\n<strrchr.as \\\r\n<strstr.c \\\r\n<strtok.c \\\r\n<swap.as \\\r\n<sys_err.c \\\r\n<time.c \\\r\n<timezone.c \\\r\n<tolower.as \\\r\n<toupper.as \\\r\n<ungetc.c \\\r\n<unlink.c \\\r\n<wrelop.as \\\r\n<write.c \\\r\n<xtoi.as \\\r\n<zcrtcpm.as \\\r\n<zdrtcpm.as \\\r\n<znrtcpm.as \\\r\n<zrrtcpm.as \\\r\n<libcver.c\r\n; All modules compiled.\r\nput console to console\r\n"
  },
  {
    "path": "stdio/CPUTS.C",
    "content": "#include\t<conio.h>\r\n\r\nvoid cputs(s)\r\nregister char *\ts;\r\n{\r\n\twhile(*s)\r\n\t\tputch(*s++);\r\n}\r\n"
  },
  {
    "path": "stdio/CTIME.C",
    "content": "/*\r\n *\tCtime for HI-TECH C - no daylight saving\r\n */\r\n\r\n#include\t<time.h>\r\n\r\nunsigned char\tmonlen[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r\n\r\nstatic\r\nput2d(cp, i, cl, ct)\r\nchar *\t\tcp, cl, ct;\r\nunsigned\ti;\r\n{\r\n\t*cp = ct;\r\n\t*--cp = i%10 + '0';\r\n\tif(i /= 10)\r\n\t\t*--cp = i + '0';\r\n\telse\r\n\t\t*--cp = cl;\r\n}\r\n\r\nstatic\r\ndylen(yr)\r\nunsigned\tyr;\r\n{\r\n\tif(yr%4)\r\n\t\treturn(365);\r\n\treturn(366);\r\n}\r\n\r\nstruct tm *\r\nlocaltime(tp)\r\ntime_t *\ttp;\r\n{\r\n\ttime_t\tt;\r\n\r\n\tt = *tp - time_zone*60L;\r\n\treturn gmtime(&t);\r\n}\r\n\r\nstruct tm *\r\ngmtime(tp)\r\ntime_t *\ttp;\r\n{\r\n\tunsigned\tday, mon, yr, cumday;\r\n\ttime_t\t\tt;\r\n\tstatic struct tm\ttim;\r\n\r\n\tt = *tp;\r\n\ttim.tm_sec = t % 60L;\r\n\tt /= 60L;\r\n\ttim.tm_min = t % 60L;\r\n\tt /= 60L;\r\n\ttim.tm_hour = t % 24L;\r\n\tday = t / 24L;\r\n\ttim.tm_wday = (day + 4) % 7;\r\n\tyr = 70;\r\n\tcumday = 0;\r\n\twhile((cumday += dylen(yr)) <= day)\r\n\t\tyr++;\r\n\ttim.tm_year = yr;\r\n\tcumday -= dylen(yr);\r\n\tday -= cumday;\r\n\ttim.tm_yday = day;\r\n\tcumday = 0;\r\n\tmon = 0;\r\n\tif((yr % 4) == 0)\r\n\t\tmonlen[1] = 29;\r\n\telse\r\n\t\tmonlen[1] = 28;\r\n\twhile((cumday += monlen[mon]) <= day)\r\n\t\tmon++;\r\n\tcumday -= monlen[mon];\r\n\tday -= cumday;\r\n\ttim.tm_mday = day + 1;\r\n\ttim.tm_mon = mon;\r\n\treturn &tim;\r\n}\r\n\r\nchar *\r\nasctime(tim)\r\nregister struct tm *\ttim;\r\n{\r\n\tregister char *\ts, * cp;\r\n\tshort\t\ti;\r\n\tstatic char\tbuf[27];\r\n\r\n\ts = &\"SunMonTueWedThuFriSat\"[tim->tm_wday*3];\r\n\ti = 3;\r\n\tcp = buf;\r\n\tdo\r\n\t\t*cp++ = *s++;\r\n\twhile(--i);\r\n\t*cp++ = ' ';\r\n\ts = &\"JanFebMarAprMayJunJulAugSepOctNovDec\"[tim->tm_mon*3];\r\n\ti = 3;\r\n\tdo\r\n\t\t*cp++ = *s++;\r\n\twhile(--i);\r\n\tbuf[7] = ' ';\r\n\tput2d(buf+10, tim->tm_mday, ' ', ' ');\r\n\tput2d(buf+13, tim->tm_hour, '0', ':');\r\n\tput2d(buf+16, tim->tm_min, '0', ':');\r\n\tput2d(buf+19, tim->tm_sec, '0', ' ');\r\n\tput2d(buf+22, tim->tm_year/100 + 19, ' ', 0);\r\n\tput2d(buf+24, tim->tm_year%100, '0', '\\n');\r\n\treturn(buf);\r\n}\r\n\r\nchar *\r\nctime(tp)\r\ntime_t *\ttp;\r\n{\r\n\treturn asctime(localtime(tp));\r\n}\r\n"
  },
  {
    "path": "stdio/DOPRNT.C",
    "content": "#include\t<stdio.h>\r\n#include\t<stdlib.h>\r\n#include\t<ctype.h>\r\n#include\t<string.h>\r\n\r\n\r\n/*\r\n *\tdoprnt for Z80\r\n */\r\n\r\nextern int\t_pnum();\r\n\r\nstatic uchar\tival;\r\nstatic char *\tx;\r\nstatic FILE *\tffile;\r\n\r\nstatic\r\npputc(c)\r\nchar\tc;\r\n{\r\n\tputc(c, ffile);\r\n}\r\n\r\nstatic char *\r\nicvt(cp)\r\nregister char *\tcp;\r\n{\r\n\tival = atoi(cp);\r\n\twhile(isdigit((unsigned)*cp))\r\n\t\tcp++;\r\n\treturn cp;\r\n}\r\n\r\n_doprnt(file, f, a)\r\nFILE *\tfile;\r\nregister char *\t\tf;\r\nint *\t\ta;\r\n{\r\n\tchar\tc;\r\n\tuchar\tfill, left;\r\n\tunsigned int\ti;\r\n\tuchar\tbase, width, prec, sign;\r\n\tunsigned int\tlen;\r\n\r\n\tffile = file;\r\n\twhile(c = *f++)\r\n\t\tif(c != '%')\r\n\t\t\tpputc(c);\r\n\t\telse {\r\n\t\t\tbase = 10;\r\n\t\t\twidth = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tleft = 0;\r\n\t\t\tlen = sizeof(int)/sizeof *a;\r\n\t\t\tif(*f == '-') {\r\n\t\t\t\tf++;\r\n\t\t\t\tleft++;\r\n\t\t\t}\r\n\t\t\tfill = *f == '0';\r\n\t\t\tif(isdigit((unsigned)*f)) {\r\n\t\t\t\tf = icvt(f);\r\n\t\t\t\twidth = ival;\r\n\t\t\t} else if(*f == '*') {\r\n\t\t\t\twidth = *a++;\r\n\t\t\t\tf++;\r\n\t\t\t}\r\n\t\t\tif(*f == '.')\r\n\t\t\t\tif(*++f == '*') {\r\n\t\t\t\t\tprec = *a++;\r\n\t\t\t\t\tf++;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tf = icvt(f);\r\n\t\t\t\t\tprec = ival;\r\n\t\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tprec = fill ? width : 0;\r\n\t\t\tif(*f == 'l') {\r\n\t\t\t\tf++;\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\t}\r\n\t\t\tswitch(c = *f++) {\r\n\r\n\t\t\tcase 0:\r\n\t\t\t\treturn;\r\n\t\t\tcase 'o':\r\n\t\t\tcase 'O':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'd':\r\n\t\t\tcase 'D':\r\n\t\t\t\tsign = 1;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'x':\r\n\t\t\tcase 'X':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\tx = *(char **)a;\r\n\t\t\t\ta += sizeof(char *)/sizeof *a;\r\n\t\t\t\tif(!x)\r\n\t\t\t\t\tx = \"(null)\";\r\n\t\t\t\ti = strlen(x);\r\ndostring:\r\n\t\t\t\tif(prec && prec < i)\r\n\t\t\t\t\ti = prec;\r\n\t\t\t\tif(width > i)\r\n\t\t\t\t\twidth -= i;\r\n\t\t\t\telse\r\n\t\t\t\t\twidth = 0;\r\n\t\t\t\tif(!left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\twhile(i--)\r\n\t\t\t\t\tpputc(*x++);\r\n\t\t\t\tif(left)\r\n\t\t\t\t\twhile(width--)\r\n\t\t\t\t\t\tpputc(' ');\r\n\t\t\t\tcontinue;\r\n\t\t\tcase 'c':\r\n\t\t\t\tc = *a++;\r\n\t\t\tdefault:\r\n\t\t\t\tx = &c;\r\n\t\t\t\ti = 1;\r\n\t\t\t\tgoto dostring;\r\n\r\n\t\t\tcase 'u':\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tif(left) {\r\n\t\t\t\tleft = width;\r\n\t\t\t\twidth = 0;\r\n\t\t\t}\r\n\t\t\tif(isupper(c))\r\n\t\t\t\tlen = sizeof(long)/sizeof *a;\r\n\t\t\twidth = _pnum((len == sizeof(int)/sizeof *a ? (sign ? (long)*a : (unsigned long)*a) : *(long *)a), prec, width, sign, base, pputc);\r\n\t\t\ta += len;\r\n\t\t\twhile(left-- > width)\r\n\t\t\t\tpputc(' ');\r\n\t\t}\r\n}\r\n"
  },
  {
    "path": "stdio/DOSCAN.C",
    "content": "/*\r\n *\t_doscan - implement scanf, fscanf, sscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<stdlib.h>\r\n#include \t<ctype.h>\r\n\r\nstatic FILE *\tfp;\r\n\r\nstatic\r\nrange(c, base)\r\nint\tc;\r\nuchar\tbase;\r\n{\r\n\tif(isdigit(c))\r\n\t\tc -= '0';\r\n\telse\r\n\t\t{\r\n\t\tc = tolower(c) ;\r\n\t\tif (isalpha(c))\r\n\t\t\tc = c - 'a' + 10 ;\r\n\t\telse\r\n\t\t\treturn -1 ;\r\n\t\t}\r\n\tif (c >= base)\r\n\t\treturn -1 ;\r\n\treturn c ;\r\n}\r\n\r\nstatic\r\nwspace()\r\n{\r\n\tint\tc;\r\n\r\n\twhile(isspace(c = getc(fp)))\r\n\t\tcontinue;\r\n\tif(c != EOF)\r\n\t\tungetc(c, fp);\r\n}\r\n\r\n_doscan(file, fmt, args)\r\nFILE *\t\tfile;\r\nregister char *\tfmt;\r\nint **\t\targs;\r\n{\r\n\tuchar\tc, sign, base, n, noass,len;\r\n\tchar\twidth ;\r\n\tchar *\tsptr;\r\n\tint\tch;\r\n\tlong\tval;\r\n\r\n\tfp = file;\r\n\tn = 0;\r\n\twhile(c = *fmt++) {\r\n\r\n\t\tlen = 0 ;\r\n\t\tif(isspace(c)) {\r\n\t\t\twspace();\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif(c == '%') {\r\n\t\t\tnoass = 0;\r\n\t\t\twidth = 0;\r\nloop:\r\n\t\t\tswitch(c = *fmt++) {\r\n\r\n\t\t\tcase '\\0':\r\n\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\r\n\t\t\tcase '*':\r\n\t\t\t\tnoass++;\r\n\t\t\t\tgoto loop;\r\n\r\n\t\t\tcase 'l':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'h':\r\n\t\t\t\tgoto loop;\r\n\r\n\t\t\tcase 'D':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'd':\r\n\t\t\t\tbase = 10;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'O':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'o':\r\n\t\t\t\tbase = 8;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'X':\r\n\t\t\t\tlen++;\r\n\t\t\tcase 'x':\r\n\t\t\t\tbase = 16;\r\n\t\t\t\tbreak ;\r\n\r\n\t\t\tcase 's':\r\n\t\t\t\twspace();\r\n\t\t\t\tif ( !noass )\r\n\t\t\t\t\tsptr = (char *)*args++;\r\n\t\t\t\tif ((ch = getc(fp)) == EOF )\r\n\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\twhile(ch && ch != EOF && !isspace(ch)) {\r\n\t\t\t\t\tif(ch == *fmt) {\r\n\t\t\t\t\t\tfmt++;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif ( !noass ) \r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t\tif(--width == 0)\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tch = getc(fp);\r\n\t\t\t\t}\r\n\t\t\t\tn++;\r\n\t\t\t\tif ( !noass ) \r\n\t\t\t\t\t*sptr = 0;\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tcase 'c':\r\n\t\t\t\tif ( !noass )\r\n\t\t\t\t\tsptr = (char *)*args++;\r\n\t\t\t\tdo {\r\n\t\t\t\t\tif ((ch = getc(fp)) == EOF) \r\n\t\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\t\tif ( !noass )\r\n\t\t\t\t\t\t*sptr++ = ch;\r\n\t\t\t\t} while(--width > 0);\r\n\t\t\t\tn++;\r\n\t\t\t\tcontinue;\r\n\t\t\tdefault:\r\n\t\t\t\tif(isdigit(c)) {\r\n\t\t\t\t\twidth = atoi(fmt-1);\r\n\t\t\t\t\twhile(isdigit(*fmt))\r\n\t\t\t\t\t\tfmt++;\r\n\t\t\t\t\tgoto loop;\r\n\t\t\t\t}\r\n\t\t\t\tif(c != (ch = getc(fp)))\r\n\t\t\t\t\tif(ch == EOF)\r\n\t\t\t\t\t\treturn n ? n : EOF;\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tungetc(ch, fp);\r\n\t\t\t\t\t\treturn n;\r\n\t\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\twspace();\r\n\t\t\tval = 0;\r\n\t\t\tsign = 0;\r\n\t\t\tch = getc(fp);\r\n\t\t\tif(ch == '-') {\r\n\t\t\t\tsign++;\r\n\t\t\t\tch = getc(fp);\r\n\t\t\t}\r\n\t\t\tif(range(ch, base) == -1)\r\n\t\t\t\treturn n ? n : feof(fp) ? EOF : 0;\r\n\t\t\tdo {\r\n\t\t\t\tval = val * base + range(ch, base);\r\n\t\t\t} while (( --width != 0 ) && ( range(ch = getc(fp),base) != -1 )) ;\r\n\t\t\tn++;\r\n\t\t\tif (range(ch,base) == -1)\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\tif(sign)\r\n\t\t\t\tval = -val;\r\n\t\t\tif ( !noass )\r\n\t\t\t\tif(len)\r\n\t\t\t\t\t*(long *)*args++ = val;\r\n\t\t\t\telse\r\n\t\t\t\t\t**args++ = val;\r\n\t\t\tcontinue;\r\n\t\t} else if(c != (ch = getc(fp))) {\r\n\t\t\tif(ch != EOF) {\r\n\t\t\t\tungetc(ch, fp);\r\n\t\t\t\treturn n;\r\n\t\t\t} else\r\n\t\t\t\treturn n ? n : EOF;\r\n\t\t}\r\n\t}\r\n\treturn n;\r\n}\r\n"
  },
  {
    "path": "stdio/EXIT.C",
    "content": "extern void _cleanup(void);\r\nextern void _exit(int);\r\n\r\nexit(v)\r\n{\r\n\t_cleanup();\r\n\t_exit(v);\r\n}\r\n"
  },
  {
    "path": "stdio/FAKECLEA.C",
    "content": "_cleanup()\r\n{\r\n}\r\n"
  },
  {
    "path": "stdio/FCLOSE.C",
    "content": "/*\r\n *\tfclose - for HI-TECH C Z80 CP/M stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<unixio.h>\r\n\r\nfclose(f)\r\nregister FILE *\tf;\r\n{\r\n\tif(!(f->_flag & (_IOREAD|_IOWRT)))\r\n\t\treturn(EOF);\r\n\tfflush(f);\r\n\tf->_flag &= ~(_IOREAD|_IOWRT|_IONBF|_IOLBF);\r\n\tif(f->_base && !(f->_flag & _IOMYBUF)) {\r\n\t\t_buffree(f->_base);\r\n\t\tf->_base = (char *)NULL;\r\n\t}\r\n\tif(close(fileno(f)) == -1 || f->_flag & _IOERR)\r\n\t\treturn EOF;\r\n\telse\r\n\t\treturn 0;\r\n}\r\n"
  },
  {
    "path": "stdio/FFLUSH.C",
    "content": "/*\r\n *  fflush for HI-TECH C Z80 CP/M stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<unixio.h>\r\n\r\nint fflush(register FILE *f)\r\n{\r\n\tif (f->_flag & _IOREAD && !(f->_flag & _IODIRN)) {\r\n\t\t/* File in read mode and not modified */\r\n\t\tf->_cnt = 0;\r\n\t\tf->_ptr = f->_base;\r\n\t\tif(f->_flag & _IOERR)\r\n\t\t\treturn EOF;\r\n\t\telse\r\n\t\t\treturn 0;\r\n\t\t}\r\n\tif(!(f->_flag & _IOWRT) || !(f->_flag & _IODIRN) ||\r\n\t\tf->_base == NULL || f->_cnt == 0)\r\n\t\t\treturn 0;\r\n\tif(write(fileno(f), f->_base, f->_cnt) != f->_cnt)\r\n\t\tf->_flag |= _IOERR|_IOEOF;\r\n\tf->_cnt = 0;\r\n\tf->_ptr = f->_base;\r\n\tif(f->_flag & _IOERR)\r\n\t\treturn EOF;\r\n\telse\r\n\t\treturn 0;\r\n}\r\n"
  },
  {
    "path": "stdio/FGETC.C",
    "content": "/*\r\n *\tfgetc\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\t_filbuf(FILE *);\r\n\r\nfgetc(f)\r\nregister FILE *\tf;\r\n{\r\n\tint\tc;\r\n\r\n\tif(f->_flag & _IOEOF || !(f->_flag & _IOREAD) || f->_flag & _IODIRN && f->_cnt) {\r\nreteof:\r\n\t\tf->_flag |= _IOEOF;\r\n\t\treturn EOF;\r\n\t}\r\n\tf->_flag &= ~_IODIRN;\r\n\tfor(;;) {\r\n\t\tif(f->_cnt > 0) {\r\n\t\t\tf->_cnt--;\r\n\t\t\tc = (unsigned)*f->_ptr++;\r\n\t\t} else if(f->_flag & _IOSTRG)\r\n\t\t\tgoto reteof;\r\n\t\telse\r\n\t\t\tc = _filbuf(f);\r\n\t\tif(!(f->_flag & _IOBINARY)) {\r\n\t\t\tif(c == 032) {\r\n\t\t\t\tif(f->_base) {\r\n\t\t\t\t\tf->_cnt++;\r\n\t\t\t\t\tf->_ptr--;\r\n\t\t\t\t}\r\n\t\t\t\tgoto reteof;\r\n\t\t\t} else if(c == '\\r')\r\n\t\t\t\tcontinue;\r\n\t\t}\r\n\t\treturn c;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "stdio/FILBUF.C",
    "content": "/*\r\n *\t_filbuf for HI-TECH C stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<unixio.h>\r\n\r\n_filbuf(f)\r\nregister FILE *\tf;\r\n{\r\n\tregister FILE *\top;\r\n\r\n\tf->_cnt = 0;\r\n\tif(!(f->_flag & _IOREAD))\r\n\t\treturn(EOF);\r\n\tfor(op = _iob ; op != _iob + _NFILE ; op++)\r\n\t\tif((op->_flag & (_IOWRT|_IOLBF)) == (_IOWRT|_IOLBF))\r\n\t\t\tfflush(op);\r\n\tif(f->_size == 0) {\r\n\t\tuchar\tc;\r\n\t\tf->_cnt = 0;\r\n\t\tif(read(fileno(f), &c, 1) == 1)\r\n\t\t\treturn(c);\r\n\t\tf->_flag |= _IOEOF;\r\n\t\treturn(EOF);\r\n\t}\r\n\tif((f->_cnt = read(fileno(f), f->_base, f->_size)) <= 0) {\r\n\t\tif(f->_cnt == 0)\r\n\t\t\tf->_flag |= _IOEOF;\r\n\t\telse\r\n\t\t\tf->_flag |= _IOERR|_IOEOF;\r\n\t\tf->_ptr = f->_base;\r\n\t\tf->_cnt = 0;\r\n\t\treturn(EOF);\r\n\t}\r\n\tf->_ptr = f->_base;\r\n\tf->_cnt--;\r\n\treturn((unsigned)*f->_ptr++);\r\n}\r\n"
  },
  {
    "path": "stdio/FLSBUF.C",
    "content": "/*\r\n *\t_flsbuf for HI-TECH C stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<unixio.h>\r\n\r\n_flsbuf(char c, register FILE * f)\r\n{\r\n\tif(!(f->_flag & _IOWRT)) {\r\n\t\tf->_flag |= _IOERR|_IOEOF;\r\n\t\tf->_cnt = 0;\r\n\t\treturn EOF;\r\n\t}\r\n\tif(f->_size == 0) {\r\n\t\tif(f->_flag & (_IONBF|_IOMYBUF) || isatty(fileno(f)) ||\r\n\t\t\t(f->_base = _bufallo()) == (char *)-1) {\r\n\t\t\tf->_base = (char *)0;\r\n\t\t\tf->_size = 0;\r\n\t\t\tf->_flag |= _IONBF;\r\n\t\t\tf->_cnt = 0;\r\n\t\t\tif(write(fileno(f), &c, 1) == 1)\r\n\t\t\t\treturn c & 0xFF;\r\n\t\t\tf->_flag |= _IOERR|_IOEOF;\r\n\t\t\treturn EOF;\r\n\t\t} else\r\n\t\t\tf->_size = BUFSIZ;\r\n\t} else if(write(fileno(f), f->_base, f->_cnt) != f->_cnt)\r\n\t\tf->_flag |= _IOERR|_IOEOF;\r\n\tf->_cnt = 1;\r\n\t*f->_base = c;\r\n\tf->_ptr = f->_base+1;\r\n\tif(f->_flag & _IOERR)\r\n\t\treturn(EOF);\r\n\treturn c & 0xFF;\r\n}\r\n"
  },
  {
    "path": "stdio/FOPEN.C",
    "content": "/*\r\n *\tfopen.c - stdio fopen \r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\n\r\nFILE *\r\nfopen(name, mode)\r\nchar *\tname, * mode;\r\n{\r\n\tregister FILE *\tf;\r\n\r\n\tfor(f = _iob ; f != &_iob[_NFILE] ; f++)\r\n\t\tif(!(f->_flag & (_IOREAD|_IOWRT)))\r\n\t\t\tbreak;\r\n\tif(f == &_iob[_NFILE])\r\n\t\treturn((FILE *)NULL);\r\n\treturn freopen(name, mode, f);\r\n}\r\n"
  },
  {
    "path": "stdio/FPRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern int\t_doprnt();\r\n\r\nfprintf(file, f, a)\r\nFILE *\tfile;\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\treturn(_doprnt(file, f, &a));\r\n}\r\n"
  },
  {
    "path": "stdio/FPUTC.C",
    "content": "/*\r\n *\tfputc for HI-TECH C stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int _flsbuf(char, FILE *);\r\n\r\nfputc(c, f)\r\nregister FILE *\tf;\r\nint\tc;\r\n{\r\n\tif(!(f->_flag & _IOWRT) || !(f->_flag & _IODIRN) && f->_cnt)\r\n\t\treturn EOF;\r\n\tf->_flag |= _IODIRN;\r\n\tc &= 0xFF;\r\n\tif(f->_cnt == 0)\r\n\t\tf->_ptr = f->_base;\r\n\tif(f->_flag & _IOSEEKED && f->_flag & _IOAPPEND)\r\n\t\tfseek(f, 0L, SEEK_END);\t\t/* force write at EOF */\r\n\tf->_flag &= ~_IOSEEKED;\r\n\tif(c == '\\n' && !(f->_flag & _IOBINARY))\r\n\t\tfputc('\\r', f);\r\n\tif(f->_cnt != f->_size) {\r\n\t\tf->_cnt++;\r\n\t\t*f->_ptr++ = c;\r\n\t} else\r\n\t\treturn _flsbuf(c, f);\r\n\tif(c == '\\n' && f->_flag & _IOLBF && fflush(f) == EOF)\r\n\t\tc = EOF;\r\n\treturn c;\r\n}\r\n"
  },
  {
    "path": "stdio/FREAD.C",
    "content": "#include\t<stdio.h>\r\n#include\t<string.h>\r\n\r\n/*\r\n *\tfread for HI-TECH C stdio\r\n */\r\n\r\nfread(buf, size, nitems, stream)\r\nvoid *\tbuf;\r\nregister FILE *\tstream;\r\nunsigned\tsize, nitems;\r\n{\r\n\tregister char *\t\tptr;\r\n\tregister unsigned\tcount, n;\r\n\tshort\t\t\tc;\r\n\r\n\tif(stream->_flag & _IOEOF || !(stream->_flag & _IOREAD) || stream->_flag & _IODIRN && stream->_cnt) {\r\n\t\tstream->_flag |= _IOEOF;\r\n\t\treturn 0;\r\n\t}\r\n\tstream->_flag &= ~_IODIRN;\r\n\tcount = size * nitems;\r\n\tptr = buf;\r\n\twhile(count && !feof(stream)) {\r\n\t\tif(stream->_cnt && stream->_size && stream->_flag & _IOBINARY) {\r\n\t\t\tn = stream->_cnt;\r\n\t\t\tif(n > count)\r\n\t\t\t\tn = count;\r\n\t\t\tif(n) {\r\n\t\t\t\tmemcpy(ptr, stream->_ptr, n);\r\n\t\t\t\tptr += n;\r\n\t\t\t\tcount -= n;\r\n\t\t\t\tstream->_ptr += n;\r\n\t\t\t\tstream->_cnt -= n;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif((c = getc(stream)) == EOF)\r\n\t\t\tbreak;\r\n\t\telse {\r\n\t\t\t--count;\r\n\t\t\t*ptr++ = c;\r\n\t\t}\r\n\t}\r\n\treturn(nitems - (count+size-1)/size);\r\n}\r\n"
  },
  {
    "path": "stdio/FREOPEN.C",
    "content": "/*\r\n *\tfreopen.c - HI-TECH C stdio freopen \r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<unixio.h>\r\n\r\n\r\nFILE *\r\nfreopen(name, mode, iob)\r\nchar *\tname, * mode;\r\nregister FILE *\tiob;\r\n{\r\n\tuchar\t\tc, rw;\r\n\r\n\tfclose(iob);\r\n\tc = rw = 0;\r\n\tiob->_flag &= _IOMYBUF;\r\n\tswitch(*mode) {\r\n\r\n\tcase 'w':\r\n\t\tc++;\r\n\tcase 'a':\r\n\t\tc++;\r\n\tcase 'r':\r\n\t\tbreak;\r\n\tdefault:\r\n\t\treturn NULL;\r\n\t}\r\n\trw = 0;\r\n\twhile(*++mode)\r\n\t\tif(*mode == 'b')\r\n\t\t\tiob->_flag |= _IOBINARY;\r\n\t\telse if(*mode == '+') {\r\n\t\t\tiob->_flag |= _IORW;\r\n\t\t\trw = 2;\r\n\t\t} else \r\n\t\t\tbreak;\r\n\t\r\n\tswitch(c) {\r\n\r\n\tcase 0:\r\n\t\tiob->_file = open(name, rw);\r\n\t\tbreak;\r\n\r\n\tcase 1:\r\n\t\tif((iob->_file = open(name, rw ? 2 : 1)) >= 0)\r\n\t\t\tbreak;\r\n\t\t/* else fall through */\r\n\tcase 2:\r\n\t\tiob->_file = creat(name, 0666);\r\n\t\tif(iob->_file >= 0 && rw) {\r\n\t\t\tclose(iob->_file);\r\n\t\t\tiob->_file = open(name, rw);\r\n\t\t}\r\n\t\tbreak;\r\n\t}\r\n\tif(iob->_file < 0)\r\n\t\treturn (FILE *)NULL;\r\n\tif(!(iob->_flag & (_IONBF|_IOMYBUF))) {\r\n\t\tiob->_base = _bufallo();\r\n\t\tiob->_size = BUFSIZ;\r\n\t}\r\n\tif(iob->_base == (char *)-1) {\r\n\t\tiob->_base = (char *)0;\r\n\t\tclose(iob->_file);\r\n\t\tiob->_flag = 0;\r\n\t\treturn (FILE *)NULL;\r\n\t}\r\n\tiob->_ptr = iob->_base;\r\n\tiob->_cnt = 0;\r\n\tif(c)\r\n\t\tiob->_flag |= _IOWRT;\r\n\telse\r\n\t\tiob->_flag |= _IOREAD;\r\n\tif(c == 1)\r\n\t\tfseek(iob, 0L, 2);\r\n\treturn iob;\r\n}\r\n"
  },
  {
    "path": "stdio/FSCANF.C",
    "content": "/*\r\n *\tStdio fscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\nextern int\t_doscan();\r\n\r\nfscanf(file, fmt, args)\r\nFILE *\tfile;\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\treturn _doscan(file, fmt, &args);\r\n}\r\n"
  },
  {
    "path": "stdio/FSEEK.C",
    "content": "#include\t<stdio.h>\r\n#include\t<cpm.h>\r\n\r\nextern long\tlseek(), _fsize(), ftell();\r\n\r\nstatic long\r\n_ssize(f)\r\nregister FILE *\tf;\r\n{\r\n\tuchar\tutmp, ftmp;\r\n\tlong\tx;\r\n\tregister struct fcb *\tfc;\r\n\tchar\tbuf[SECSIZE];\r\n\r\n\tfc = &_fcb[fileno(f)];\r\n\tif(f->_flag & _IOBINARY)\r\n#if 0\r\n\t\treturn _fsize(fileno(f));\r\n#else\r\n\t\treturn fc->fsize;\t/* Supports exact file sizes */\r\n#endif\r\n\tif((ftmp = f->_flag) & _IOWRT)\r\n\t\tfflush(f);\r\n\tutmp = fc->use;\r\n\tfc->use = U_READ;\r\n\tf->_flag |= _IOREAD;\r\n\tf->_flag &= ~_IOWRT;\r\n\tlseek(fileno(f), -(long)SECSIZE, SEEK_END);/* seek 1 sector before end */\r\n\tf->_cnt = 0;\r\n\tfread(buf, sizeof(buf[0]), SECSIZE, f);\r\n\tx = ftell(f);\r\n\tfc->use = utmp;\r\n\tf->_flag = ftmp;\r\n\tif(f->_flag & _IOWRT) {\r\n\t\tf->_cnt = BUFSIZ;\r\n\t\tf->_ptr = f->_base;\r\n\t}\r\n\treturn x;\r\n}\r\n\r\nfseek(f, offs, ptr)\r\nregister FILE *\tf;\r\nlong\t\toffs;\r\nint\t\tptr;\r\n{\r\n\tlong\troffs;\r\n\r\n\tclreof(f);\r\n\tif(!f->_base)\r\n\t\tif(lseek(fileno(f), offs, ptr) == -1L)\r\n\t\t\treturn -1;\r\n\t\telse\r\n\t\t\treturn 0;\r\n\tswitch(ptr) {\r\n\r\n\tcase 0:\t/* relative to beginning of file */\r\n\t\tbreak;\r\n\r\n\tcase 1:\t/* relative to current postion */\r\n\t\toffs += ftell(f);\r\n\t\tbreak;\r\n\r\n\tcase 2:\t/* relative toend of file- CP/M makes us work hard */\r\n\t\toffs += _ssize(f);\r\n\t\tbreak;\r\n\r\n\tdefault:\r\n\t\treturn -1;\r\n\t}\r\n\troffs = offs - ftell(f);\r\n\tif(f->_flag & _IOREAD && !(f->_flag & _IOWRT) && roffs >= 0 && roffs <= f->_cnt) {\r\n\t\tf->_cnt -= roffs;\r\n\t\tf->_ptr += roffs;\r\n\t\treturn 0;\r\n\t}\r\n\tif(f->_flag & _IODIRN && f->_cnt)\r\n\t\tfflush(f);\r\n\tf->_cnt = 0;\r\n\tf->_ptr = f->_base;\r\n\tif(lseek(f->_file, offs, 0) < 0)\r\n\t\treturn -1;\r\n\treturn 0;\r\n}\r\n\r\nlong\r\nftell(f)\r\nregister FILE *\tf;\r\n{\r\n\tlong\tpos;\r\n\r\n\tpos = lseek(f->_file, 0L, SEEK_CUR);\r\n\tif(f->_cnt < 0)\r\n\t\tf->_cnt = 0;\r\n\tif(f->_base && f->_flag & _IODIRN)\r\n\t\treturn pos + f->_cnt;\r\n\treturn pos - f->_cnt;\r\n}\r\n"
  },
  {
    "path": "stdio/FWRITE.C",
    "content": "#include\t<stdio.h>\r\n#include\t<string.h>\r\n\r\n/*\r\n *\tfwrite\r\n */\r\n\r\nfwrite(buf, size, nitems, stream)\r\nvoid *\tbuf;\r\nregister FILE *\tstream;\r\nunsigned\tsize, nitems;\r\n{\r\n\tregister unsigned\tcount, n;\r\n\tregister char *\t\tptr;\r\n\r\n\tif(!(stream->_flag & _IOWRT) || !(stream->_flag & _IODIRN) && stream->_cnt)\r\n\t\treturn 0;\r\n\tstream->_flag |= _IODIRN;\r\n\tif(stream->_cnt == 0)\r\n\t\tstream->_ptr = stream->_base;\r\n\tif(stream->_flag & _IOSEEKED && stream->_flag & _IOAPPEND)\r\n\t\tfseek(stream, 0L, SEEK_END);\t/* force write at EOF */\r\n\tstream->_flag &= ~_IOSEEKED;\r\n\tcount = size * nitems;\r\n\tptr = buf;\r\n\twhile(count) {\r\n\t\tif(stream->_base && stream->_flag & _IOBINARY) {\r\n\t\t\tn = stream->_size - stream->_cnt;\r\n\t\t\tif(n > count)\r\n\t\t\t\tn = count;\r\n\t\t\tif(n) {\r\n\t\t\t\tmemcpy(stream->_ptr, ptr, n);\r\n\t\t\t\tptr += n;\r\n\t\t\t\tcount -= n;\r\n\t\t\t\tstream->_ptr += n;\r\n\t\t\t\tstream->_cnt += n;\r\n\t\t\t\tif(stream->_cnt == stream->_size)\r\n\t\t\t\t\tfflush(stream);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif(putc(*ptr++, stream) == EOF)\r\n\t\t\tbreak;\r\n\t\telse\r\n\t\t\t--count;\r\n\t}\r\n\treturn(nitems - (count+size-1)/size);\r\n}\r\n"
  },
  {
    "path": "stdio/GETARGS.C",
    "content": "/*---------------------------------------------------------------------------\r\n *\r\n * GETARGS.C\tModified version from Tesseract vol 91\r\n *\r\n *  _getargs(str, name) - process string into argument buffer.\r\n *\r\n *  If str is null, read lines from standard input instead, using name as a\r\n *  prompt.\r\n *\r\n *  Continuation lines are recognized by a \\ as the last character on the\r\n *  line.\r\n *\r\n *  The redirections recognized are:\r\n *\r\n *      >   >>  <\r\n *\r\n *  Redirections of the form >& and >>& are not yet supported.\r\n *  Note that the >> redirections depend on fseek working correctly\r\n *  on text files, when seeking relative to the end of the file.\r\n *\r\n *  Wildcards (? and *) are expanded in the usual way.\r\n *\r\n *  The quotes \" and ' may be used to enclose arguments which contain\r\n *  white space the wild characters and > or <.\r\n *\r\n *  The argument buffer is sbrk-ed and a pointer to it is returned.\r\n *  The count of arguments is left in the global _argc_. The count\r\n *  may also be found by counting the arguments; the last one is a null\r\n *  pointer.\r\n *\r\n *  The zero'th argument is set to the name parameter.\r\n *----------------------------------------------------------------------------\r\n *  Jon Saxton, 2014-04-22\r\n *\r\n *  1.\tThe original implementation terminated the program if a wildcard\r\n *\tname did not match any file on disk.  That no longer happens.  The\r\n *\tprogram continues processing and expanding arguments.\r\n *  2.\tUser numbers are now included in the expanded arguments if and when\r\n *\tappropriate.\r\n *----------------------------------------------------------------------------\r\n *  Usage:\r\n *\t#include <stdio.h>\t/ * for _getargs() declaration * /\r\n *\textern int _argc_;\r\n *\tchar **args;\r\n *\t/ * Expand arguments and set program name.* /\r\n *\targs = _getargs((char *)0x81, \"myprog\"); \r\n *\t/ * Now use _argc_ and args[] in lieu of argc and argv[] * /\r\n *--------------------------------------------------------------------------*/\r\n\r\n#include    <cpm.h>\r\n#include    <stdio.h>\r\n#include    <ctype.h>\r\n#include    <string.h>\r\n#include    <sys.h>\r\n#include    <signal.h>\r\n\r\n#define MAXARGS 200         /* max number of arguments */\r\n#define MAXLEN  100         /* max length of an argument */\r\n#define QUOTE   0x80        /* quoted bit in args */\r\n\r\n#define isterminator(c) ((c) == 0)\r\n#define look()      (*str)\r\n\r\nextern int   _argc_;\r\nextern int   isatty(int);\r\nstatic char *name, *str, *bp;\r\nstatic char  interactive;\r\nstatic char  redone[3];\r\nstatic void  sputs(char *), error(char *, ...);\r\nstatic void redirect(char *, char *, char *, FILE *);\r\nstatic char *alloc(short);\r\nstatic char  nxtch();\r\nstatic char  iswild(char *), isspecial(char), isseparator(char);\r\n\r\nchar **_getargs(char *_str, char *_name)\r\n{\r\n    char          **argv;\r\n    struct fcb      fc, *fx;\r\n    register char  *ap;\r\n    char           *cp;\r\n    short           argc;\r\n    char            c, user, quote;\r\n    unsigned short  i, j;\r\n    char           *argbuf[MAXARGS];\r\n    char            dmabuf[4][32];\r\n    char            buf[MAXLEN];\r\n\r\n    bp = (char *)0;\r\n    quote = redone[0] = redone[1] = redone[2] = 0;\r\n    name = _name;\r\n    str = _str;\r\n    if (interactive = str == (char *)0)\r\n        str = \"\\\\\";\r\n    argbuf[0] = name;\r\n    argc = 1;\r\n\r\n    /* first step - process arguments and do globbing */\r\n\r\n    while (look())\r\n    {\r\n        if (argc == MAXARGS)\r\n            error(\"too many arguments\", 0);\r\n        while (isseparator(c = nxtch()))\r\n            continue;\r\n        if (isterminator(c))\r\n            break;\r\n        ap = buf;\r\n        if (isspecial(c))\r\n        {\r\n            *ap++ = c;\r\n            if (c == '>' && look() == '>')\r\n                *ap++ = nxtch();\r\n        }\r\n        else\r\n        {\r\n            while (!isterminator(c)\r\n                    && (quote || !isspecial(c) && !isseparator(c)))\r\n            {\r\n                if (ap == &buf[MAXLEN])\r\n                    error(\"argument too long\", 0);\r\n                if (c == quote)      /* end of quoted string */\r\n                    quote = 0;\r\n                else if (!quote && (c == '\\'' || c == '\"'))\r\n                    quote = c;  /* start of quoted string */\r\n                else\r\n                {\r\n                    if (quote)\r\n                        c |= QUOTE;\r\n                    *ap++ = c;\r\n                }\r\n                if (!quote && isspecial(look()))\r\n                    break;\r\n                c = nxtch();\r\n            }\r\n        }\r\n        *ap = 0;\r\n        if (iswild(buf))\r\n        {\r\n            ap = buf;\r\n            setfcb(&fc, buf);\r\n            bdos(CPMSDMA, dmabuf);\r\n            user = (c = getuid()) != fc.uid;\r\n            setuid(fc.uid);\r\n            if ((j = bdos(CPMFFST, &fc) & 0xFF) != 255)\r\n                do\r\n                {\r\n                    ap = buf;\r\n                    if (c != fc.uid)\r\n                    {\r\n                        sprintf(ap, \"%u\", fc.uid);\r\n                        ap += strlen(ap);\r\n                    }\r\n                    if (fc.dr)\r\n                        *ap++ = fc.dr + 'A' - 1;\r\n                    if (fc.dr || user)\r\n                        *ap++ = ':';\r\n                    fx = (struct fcb *)dmabuf[j];\r\n                    cp = fx->name;\r\n                    while (*cp != ' ' && cp < &fx->name[8])\r\n                        *ap++ = *cp++ & ~0x80;\r\n                    *ap++ = '.';\r\n                    cp = fx->ft;\r\n                    while (*cp != ' ' && cp < &fx->ft[3])\r\n                        *ap++ = *cp++ & ~0x80;\r\n                    *ap++ = 0;\r\n                    strcpy(argbuf[argc++] = alloc(ap-buf+1), buf);\r\n                }\r\n                while ((j = bdos(CPMFNXT) & 0xFF) != 255);\r\n            setuid(c);\r\n        }\r\n        else\r\n        {\r\n            argbuf[argc++] = ap = alloc(ap-buf+1);\r\n            cp = buf;\r\n            do\r\n                *ap++ = *cp & ~QUOTE;\r\n            while(*cp++);\r\n        }\r\n    }\r\n\r\n    /* now do redirection */\r\n\r\n    for (i = j = 0 ; j < argc ; j++)\r\n        if (isspecial(c = argbuf[j][0]))\r\n        {\r\n            if (j == argc-1)\r\n                error(\"no name after \", argbuf[j], 0);\r\n            if (c == '<')\r\n                redirect(\"input\", argbuf[j+1], \"r\", stdin);\r\n            else\r\n            {\r\n                ap = argbuf[j][1] == '>' ? \"a\" : \"w\";\r\n                redirect(\"output\", argbuf[j+1], ap, stdout);\r\n            }\r\n            ++j;\r\n        }\r\n        else\r\n            argbuf[i++] = argbuf[j];\r\n    _argc_ = i;\r\n    argbuf[i++] = (char *)0;\r\n    argv = (char **)alloc(i * sizeof *argv);\r\n    bmove(argbuf, argv, i * sizeof *argv);\r\n    return argv;\r\n}\r\n\r\nstatic char nxtch()\r\n{\r\n    if (interactive && *str == '\\\\' && str[1] == 0)\r\n    {\r\n        if (!bp)\r\n            bp = alloc(256);\r\n        if (isatty(fileno(stdin))) {\r\n            signal_t prev=signal(SIGINT,SIG_IGN);\r\n            fprintf(stderr, \"%s> \", name);\r\n            signal(SIGINT,prev);\r\n        }\r\n        gets(bp);\r\n        str = bp;\r\n    }\r\n    if (*str)\r\n        return *str++;\r\n    return 0;\r\n}\r\n\r\nstatic void error(char *s, ...)\r\n{\r\n    register char **sp;\r\n\r\n    sp = &s;\r\n    while(*sp)\r\n        sputs(*sp++);\r\n    sputs(\"\\n\");\r\n    exit(-1);\r\n}\r\n\r\nstatic void sputs(char *s)\r\n{\r\n    while (*s)\r\n    {\r\n        if (*s == '\\n')\r\n            bdos(CPMWCON, '\\r');\r\n        bdos(CPMWCON, *s++);\r\n    }\r\n}\r\n\r\nstatic char *alloc(short n)\r\n{\r\n    char *bp;\r\n\r\n    if ((bp = sbrk(n)) == (char *)-1)\r\n        error(\"no room for arguments\", 0);\r\n    return bp;\r\n}\r\n\r\nstatic void redirect(char *str_name, char *file_name, char *mode, FILE *stream)\r\n{\r\n    if (redone[stream-_iob]++)\r\n        error(\"Ambiguous \", str_name, \" redirection\", 0);\r\n    if (freopen(file_name, mode, stream) != stream)\r\n        error(\"Can't open \", file_name, \" for \", str_name, 0);\r\n}\r\n\r\nstatic char iswild(char *buf)\r\n{\r\n    return strchr(buf, '*') || strchr(buf, '?');\r\n}\r\n\r\nstatic char isspecial(char c)\r\n{\r\n    return c == '<' || c == '>';\r\n}\r\n\r\nstatic char isseparator(char c)\r\n{\r\n    return c == ' ' || c == '\\t' || c == '\\n';\r\n}\r\n"
  },
  {
    "path": "stdio/GETENV.C",
    "content": "#include    <stdio.h>\r\n#include    <string.h>\r\n#if CPM\r\n#include    <cpm.h>\r\n#endif\r\n\r\n#define ENVFILE \"0:A:ENVIRON\"   /* Must be of the form 0:X: */\r\n\r\n       char **    environ;\r\nextern char *    sbrk();\r\n\r\nstatic char envname[]=ENVFILE;\r\n\r\nstatic char loadenv(char *name, char **avec, char *abuf, short *i,\r\n                    short avsize, short absize)\r\n{\r\n    FILE *fp;\r\n    register char *cp;\r\n\r\n    if((fp = fopen(name, \"r\")) == NULL) return(0);\r\n\r\n    while((*i) < avsize && fgets(abuf, absize, fp)) {\r\n        cp = sbrk(strlen(abuf)+1);\r\n        strcpy(cp, abuf);\r\n        cp[strlen(cp)-1] = 0;\r\n        avec[(*i)++] = cp;\r\n    }\r\n    fclose(fp);\r\n\r\n    return(1);\r\n}\r\n\r\nchar * getenv(char * s)\r\n{\r\n    register char **    xp;\r\n    short            i;\r\n    static char        setup;\r\n\r\n    if(!setup) {\r\n        short           av,ab;\r\n        unsigned short  scbpb;\r\n        char        drive;\r\n        char *        avec[40];\r\n        char        abuf[128];\r\n\r\n        i = 0;\r\n\r\n#if CPM   /*  CP/M environment simulation? */\r\n        av=sizeof avec / sizeof avec[0];\r\n        ab=sizeof abuf;\r\n        if((bdoshl(CPMVERS) & 0x0FF0)==0x0030)    /* CP/M 3 */\r\n        {\r\n            for (scbpb=0x4C; scbpb<0x50; scbpb++)\r\n            {\r\n                drive=bdos(CPMSCB,&scbpb);\r\n                if (drive & 0x20) \r\n                    break; /* End of chain */ \r\n                else \r\n                {\r\n                    /* if default, get current drive 0..15 */\r\n                    if (!drive) \r\n                        drive=bdos(CPMIDRV)+1; /**AGN fix*/\r\n                    envname[2]=drive+'@';\r\n                    if (loadenv(envname+2,avec,abuf,&i,av,ab)) \r\n                        break;\r\n                    if (loadenv(envname,avec,abuf,&i,av,ab)) \r\n                        break;\r\n                 }\r\n            }\r\n            if (i==0) \r\n                loadenv(envname+4,avec,abuf,&i,av,ab);\r\n        }\r\n        else    /* Not CP/M 3. Search current drive & user 0 */\r\n        {\r\n            envname[2]='0';\r\n            if (!loadenv(envname+2,avec,abuf,&i,av,ab))\r\n                   loadenv(envname+4,avec,abuf,&i,av,ab);\r\n        }\r\n#else\r\n        loadenv(envname+4,avec,abuf,&i,av,ab);\r\n#endif\r\n        avec[i] = 0;\r\n        xp = (char **)sbrk(i * sizeof avec[0]);\r\n        memcpy(xp, avec, i * sizeof avec[0]);\r\n        environ = xp;\r\n        setup = 1;\r\n    }\r\n    i = strlen(s);\r\n    for(xp = environ ; *xp ; xp++)\r\n        if(strncmp(*xp, s, i) == 0 && (*xp)[i] == '=')\r\n            return *xp + i+1;\r\n    return (char *)0;\r\n}\r\n"
  },
  {
    "path": "stdio/GETS.C",
    "content": "/*\r\n *  gets and fgets for HI-TECH C stdio\r\n */\r\n\r\n#include    <stdio.h>\r\n#include    <string.h>\r\n\r\nchar *fgets(char *s, int n, register FILE *f)\r\n{\r\n    char *s1 = s;\r\n    int c;\r\n\r\n    while (--n && (c = fgetc(f)) != EOF && (*s++ = c) != '\\n')\r\n        /* VOID */;\r\n    *s = 0;\r\n    if (s == s1)\r\n        return (char *)NULL;\r\n    return s1;\r\n}\r\n\r\nchar *gets(char *s)\r\n{\r\n    if ((s = fgets(s, -1, stdin)) == (char *)NULL)\r\n        return (char *)NULL;\r\n    s[strlen(s)-1] = 0;\r\n    return s;\r\n}\r\n"
  },
  {
    "path": "stdio/GETW.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tStdio getw()\r\n */\r\n\r\ngetw(stream)\r\nregister FILE *\tstream;\r\n{\r\n\tshort\thi, lo;\r\n\r\n\tif((lo = getc(stream)) == EOF || (hi = getc(stream)) == EOF)\r\n\t\treturn EOF;\r\n\treturn (hi << 8) | (lo & 0xFF);\r\n}\r\n"
  },
  {
    "path": "stdio/LISTMODC.SUB",
    "content": "libr s libc12.lib > modules.prn\r\n\r\n"
  },
  {
    "path": "stdio/M280LIBC.LOG",
    "content": "\r\n10E>; Use librarian to place all modules in m:lib280c.lib\r\n10E>; NB: the ordering is important for resolving dependencies at link time\r\n10E>m:\r\n10M>era m:lib280c.lib\r\nNo File\r\n10M>libr\r\nA:LIBR     COM  (User 0)\r\nlibr> r m:lib280c.lib\t\\\r\nlibr> libcver.obj\t\\\r\nlibr> start1.obj\t\\\r\nlibr> getargs.obj\t\\\r\nlibr> assert.obj\t\\\r\nlibr> printf.obj\t\\\r\nlibr> fprintf.obj\t\\\r\nlibr> sprintf.obj\t\\\r\nlibr> doprnt.obj\t\\\r\nlibr> getenv.obj\t\\\r\nlibr> gets.obj\t\\\r\nlibr> puts.obj\t\\\r\nlibr> fwrite.obj\t\\\r\nlibr> getw.obj\t\\\r\nlibr> putw.obj\t\\\r\nlibr> close.obj\t\\\r\nlibr> putchar.obj\t\\\r\nlibr> perror.obj\t\\\r\nlibr> fputc.obj\t\\\r\nlibr> flsbuf.obj\t\\\r\nlibr> fopen.obj\t\\\r\nlibr> freopen.obj\t\\\r\nlibr> fseek.obj\t\\\r\nlibr> fread.obj\t\\\r\nlibr> rewind.obj\t\\\r\nlibr> remove.obj\t\\\r\nlibr> setbuf.obj\t\\\r\nlibr> fscanf.obj\t\\\r\nlibr> ctime.obj\t\\\r\nlibr> cgets.obj\t\\\r\nlibr> cputs.obj\t\\\r\nlibr> sscanf.obj\t\\\r\nlibr> scanf.obj\t\\\r\nlibr> doscan.obj\t\\\r\nlibr> ungetc.obj\t\\\r\nlibr> fgetc.obj\t\\\r\nlibr> filbuf.obj\t\\\r\nlibr> stdclean.obj\t\\\r\nlibr> fclose.obj\t\\\r\nlibr> fflush.obj\t\\\r\nlibr> buf.obj\t\\\r\nlibr> exit.obj\t\\\r\nlibr> open.obj\t\\\r\nlibr> read.obj\t\\\r\nlibr> write.obj\t\\\r\nlibr> seek.obj\t\\\r\nlibr> stat.obj\t\\\r\nlibr> chmod.obj\t\\\r\nlibr> fcbname.obj\t\\\r\nlibr> rename.obj\t\\\r\nlibr> creat.obj\t\\\r\nlibr> time.obj\t\\\r\nlibr> convtime.obj\t\\\r\nlibr> timezone.obj\t\\\r\nlibr> mktime.obj\t\\\r\nlibr> isatty.obj\t\\\r\nlibr> cleanup.obj\t\\\r\nlibr> close.obj\t\\\r\nlibr> unlink.obj\t\\\r\nlibr> dup.obj\t\\\r\nlibr> execl.obj\t\\\r\nlibr> getfcb.obj\t\\\r\nlibr> srand1.obj\t\\\r\nlibr> abort.obj\t\\\r\nlibr> getch.obj\t\\\r\nlibr> signal.obj\t\\\r\nlibr> getuid.obj\t\\\r\nlibr> bdos.obj\t\\\r\nlibr> bios.obj\t\\\r\nlibr> _exit.obj\t\\\r\nlibr> fakeclean.obj\t\\\r\nlibr> fakecpcln.obj\t\\\r\nlibr> sys_err.obj\t\\\r\nlibr> memcpy.obj\t\\\r\nlibr> memcmp.obj\t\\\r\nlibr> memset.obj\t\\\r\nlibr> strftime.obj\t\\\r\nlibr> asmod.obj\t\\\r\nlibr> abs.obj\t\\\r\nlibr> asallsh.obj\t\\\r\nlibr> allsh.obj\t\\\r\nlibr> asalrsh.obj\t\\\r\nlibr> asar.obj\t\\\r\nlibr> asdiv.obj\t\\\r\nlibr> asladd.obj\t\\\r\nlibr> asland.obj\t\\\r\nlibr> asll.obj\t\\\r\nlibr> asllrsh.obj\t\\\r\nlibr> aslmul.obj\t\\\r\nlibr> aslor.obj\t\\\r\nlibr> aslsub.obj\t\\\r\nlibr> aslxor.obj\t\\\r\nlibr> atoi.obj\t\\\r\nlibr> atol.obj\t\\\r\nlibr> blkclr.obj\t\\\r\nlibr> blkcpy.obj\t\\\r\nlibr> calloc.obj\t\\\r\nlibr> asmul.obj\t\\\r\nlibr> bitfield.obj\t\\\r\nlibr> ctype_.obj\t\\\r\nlibr> getsp.obj\t\\\r\nlibr> index.obj\t\\\r\nlibr> strchr.obj\t\\\r\nlibr> qsort.obj\t\\\r\nlibr> malloc.obj\t\\\r\nlibr> max.obj\t\\\r\nlibr> idiv.obj\t\\\r\nlibr> pnum.obj\t\\\r\nlibr> ldiv.obj\t\\\r\nlibr> swap.obj\t\\\r\nlibr> aslr.obj\t\\\r\nlibr> bmove.obj\t\\\r\nlibr> imul.obj\t\\\r\nlibr> rand.obj\t\\\r\nlibr> alrsh.obj\t\\\r\nlibr> lmul.obj\t\\\r\nlibr> rindex.obj\t\\\r\nlibr> strrchr.obj\t\\\r\nlibr> sbrk.obj\t\\\r\nlibr> shar.obj\t\\\r\nlibr> shll.obj\t\\\r\nlibr> shlr.obj\t\\\r\nlibr> strcat.obj\t\\\r\nlibr> strcmp.obj\t\\\r\nlibr> strcpy.obj\t\\\r\nlibr> strlen.obj\t\\\r\nlibr> strncat.obj\t\\\r\nlibr> strncmp.obj\t\\\r\nlibr> strncpy.obj\t\\\r\nlibr> strstr.obj\t\\\r\nlibr> strnstr.obj\t\\\r\nlibr> strdup.obj\t\\\r\nlibr> stricmp.obj\t\\\r\nlibr> stristr.obj\t\\\r\nlibr> strnicmp.obj\t\\\r\nlibr> strnistr.obj\t\\\r\nlibr> strtok.obj\t\\\r\nlibr> inout.obj\t\\\r\nlibr> iregset.obj\t\\\r\nlibr> isalpha.obj\t\\\r\nlibr> isdigit.obj\t\\\r\nlibr> islower.obj\t\\\r\nlibr> isspace.obj\t\\\r\nlibr> isupper.obj\t\\\r\nlibr> ladd.obj\t\\\r\nlibr> land.obj\t\\\r\nlibr> linc.obj\t\\\r\nlibr> llrsh.obj\t\\\r\nlibr> longjmp.obj\t\\\r\nlibr> lor.obj\t\\\r\nlibr> brelop.obj\t\\\r\nlibr> wrelop.obj\t\\\r\nlibr> lrelop.obj\t\\\r\nlibr> frelop.obj\t\\\r\nlibr> lsub.obj\t\\\r\nlibr> lxor.obj\t\\\r\nlibr> csv.obj\t\\\r\nlibr> rcsv.obj\t\\\r\nlibr> tolower.obj\t\\\r\nlibr> toupper.obj\t\\\r\nlibr> xtoi.obj\r\n\r\n10M>libr s m:lib280c.lib\r\nA:LIBR     COM  (User 0)\r\nlibcver.obj     D __libcver     \r\nstart1.obj      D __argc_       U __getargs     D startup       \r\ngetargs.obj     U __argc_       D __getargs     U __iob         U _bdos       \r\n\t\tU _bmove        U _exit         U _fprintf      U _freopen    \r\n\t\tU _gets         U _getuid       U _isatty       U _sbrk       \r\n\t\tU _setfcb       U _setuid       U _signal       U _sprintf    \r\n\t\tU _strchr       U _strcpy       U _strlen       U adiv        \r\n\t\tU cret          U csv           U indir         U ncsv        \r\n\t\tU shal          U wrelop        \r\nassert.obj      D __fassert     U __iob         U _abort        U _fprintf    \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nprintf.obj      U __doprnt      U __iob         D _printf       U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfprintf.obj     U __doprnt      D _fprintf      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsprintf.obj     U __doprnt      D _sprintf      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\ndoprnt.obj      U __ctype_      D __doprnt      U __pnum        U _atoi       \r\n\t\tU _fputc        U _strlen       U brelop        U cret        \r\n\t\tU csv           U indir         U ncsv          U wrelop      \r\ngetenv.obj      U _bdos         D _environ      U _fclose       U _fgets      \r\n\t\tU _fopen        D _getenv       U _memcpy       U _sbrk       \r\n\t\tU _strcpy       U _strlen       U _strncmp      U cret        \r\n\t\tU csv           U indir         U ncsv          U wrelop      \r\ngets.obj        U __iob         U _fgetc        D _fgets        D _gets       \r\n\t\tU _strlen       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nputs.obj        U __iob         U _fputc        D _fputs        D _puts       \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfwrite.obj      U _fflush       U _fputc        U _fseek        D _fwrite     \r\n\t\tU _memcpy       U cret          U indir         U ldiv        \r\n\t\tU lmul          U ncsv          U wrelop        \r\ngetw.obj        U _fgetc        D _getw         U cret          U csv         \r\n\t\tU indir         U ncsv          U shal          \r\nputw.obj        U _fputc        D _putw         U cret          U csv         \r\n\t\tU indir         U ncsv          U shar          \r\nclose.obj       U __exact       U __fcb         U _bdos         D _close      \r\n\t\tU _getuid       U _setuid       U amul          U brelop      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nputchar.obj     U __iob         U _fgetc        U _fputc        D _getchar    \r\n\t\tD _putchar      U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nperror.obj      U __iob         U _errno        U _fputc        D _perror     \r\n\t\tU _sys_err      U _sys_ner      U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\nfputc.obj       U __flsbuf      U _fflush       D _fputc        U _fseek      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nflsbuf.obj      U __bufallo     D __flsbuf      U _isatty       U _write      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfopen.obj       U __iob         D _fopen        U _freopen      U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfreopen.obj     U __bufallo     U _close        U _creat        U _fclose     \r\n\t\tD _freopen      U _fseek        U _open         U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfseek.obj       U __fcb         U _fflush       U _fread        D _fseek      \r\n\t\tD _ftell        U _lseek        U aladd         U alsub       \r\n\t\tU amul          U arelop        U asaladd       U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfread.obj       U _fgetc        D _fread        U _memcpy       U cret        \r\n\t\tU indir         U ldiv          U lmul          U ncsv        \r\n\t\tU wrelop        \r\nrewind.obj      U _fseek        D _rewind       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nremove.obj      D _remove       U _unlink       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsetbuf.obj      U __bufallo     U __buffree     D _setbuf       D _setvbuf    \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfscanf.obj      U __doscan      D _fscanf       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nctime.obj       D _asctime      D _ctime        D _gmtime       D _localtime  \r\n\t\tD _monlen       U _time_zone    U adiv          U aldiv       \r\n\t\tU almod         U almul         U alsub         U amod        \r\n\t\tU amul          U asaldiv       U asldiv        U cret        \r\n\t\tU csv           U indir         U lmod          U ncsv        \r\n\t\tU wrelop        \r\ncgets.obj       D _cgets        U _getche       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\ncputs.obj       D _cputs        U _putch        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsscanf.obj      U __doscan      D _sscanf       U _strlen       U cret        \r\n\t\tU indir         U ncsv          \r\nscanf.obj       U __doscan      U __iob         D _scanf        U cret        \r\n\t\tU csv           U indir         U ncsv          \r\ndoscan.obj      U __ctype_      D __doscan      U _atoi         U _fgetc      \r\n\t\tU _tolower      U _ungetc       U cret          U csv         \r\n\t\tU indir         U lladd         U llmul         U ncsv        \r\n\t\tU wrelop        \r\nungetc.obj      D _ungetc       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nfgetc.obj       U __filbuf      D _fgetc        U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\nfilbuf.obj      D __filbuf      U __iob         U _fflush       U _read       \r\n\t\tU cret          U csv           U indir         U ncsv        \r\n\t\tU wrelop        \r\nstdclean.obj    D __cleanup     D __iob         D __sibuf       U _fclose     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfclose.obj      U __buffree     U _close        D _fclose       U _fflush     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfflush.obj      D _fflush       U _write        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nbuf.obj         D __bufallo     D __buffree     U _sbrk         U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nexit.obj        U __cleanup     U __exit        D _exit         U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nopen.obj        U __exact       U __fcb         D __fsize       U _bdos       \r\n\t\tU _errno        U _getfcb       U _getuid       D _open       \r\n\t\tU _putfcb       U _setfcb       U _setuid       U adiv        \r\n\t\tU aland         U aldiv         U amul          U asalsub     \r\n\t\tU brelop        U cret          U csv           U indir       \r\n\t\tU ncsv          U shll          U wrelop        \r\nread.obj        U __fcb         U __piped       U __putrno      U __sigchk    \r\n\t\tU _bdos         U _bmove        U _getuid       D _read       \r\n\t\tU _setuid       U aldiv         U alsub         U amul        \r\n\t\tU asaladd       U brelop        U cret          U indir       \r\n\t\tU lladd         U lrelop        U ncsv          U wrelop      \r\nwrite.obj       U __fcb         U __piped       U __putrno      U __sigchk    \r\n\t\tU _bdos         U _bmove        U _getuid       U _setuid     \r\n\t\tD _write        U aldiv         U amul          U arelop      \r\n\t\tU asaladd       U brelop        U cret          U indir       \r\n\t\tU ncsv          U wrelop        \r\nseek.obj        U __fcb         D _lseek        U aladd         U amul        \r\n\t\tU arelop        U brelop        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nstat.obj        U __exact       U _bdos         U _convtime     U _getuid     \r\n\t\tU _setfcb       U _setuid       D _stat         U asallsh     \r\n\t\tU asalsub       U cret          U indir         U lladd       \r\n\t\tU lllsh         U ncsv          U shal          U wrelop      \r\nchmod.obj       U _bdos         D _chmod        U _getuid       U _setfcb     \r\n\t\tU _setuid       U cret          U indir         U ncsv        \r\nfcbname.obj     U __fcb         U _bdos         D _fcbname      U _sprintf    \r\n\t\tU _strlen       U amul          U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\nrename.obj      U _bdos         D _rename       U _setfcb       U _unlink     \r\n\t\tU cret          U indir         U ncsv          \r\ncreat.obj       U __fcb         U _bdos         D _creat        U _errno      \r\n\t\tU _getfcb       U _getuid       U _setfcb       U _setuid     \r\n\t\tU _unlink       U adiv          U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\ntime.obj        U _bdos         U _convtime     D _time         U cret        \r\n\t\tU indir         U ncsv          \r\nconvtime.obj    D _convtime     D _frmbcd       U asaladd       U asalmul     \r\n\t\tU cret          U csv           U indir         U lmul        \r\n\t\tU ncsv          \r\ntimezone.obj    D _time_zone    \r\nmktime.obj      D _mktime       U _time_zone    U almul         U amod        \r\n\t\tU asaladd       U cret          U indir         U ncsv        \r\n\t\tU wrelop        \r\nisatty.obj      U __fcb         D _isatty       U amul          U cret        \r\n\t\tU csv           U indir         U ncsv          \r\ncleanup.obj     D __cpm_clean   D __fcb         D __initrsx     D __putrno    \r\n\t\tU _close        U alrsh         U brelop        U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nclose.obj       U __exact       U __fcb         U _bdos         D _close      \r\n\t\tU _getuid       U _setuid       U amul          U brelop      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nunlink.obj      U _bdos         U _errno        U _getuid       U _setfcb     \r\n\t\tU _setuid       D _unlink       U cret          U indir       \r\n\t\tU ncsv          \r\ndup.obj         U __fcb         D _dup          U _getfcb       U adiv        \r\n\t\tU amul          U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nexecl.obj       U _bmove        D _execl        D _execv        U _setfcb     \r\n\t\tU _strcat       U _strlen       U _strncpy      U indir       \r\ngetfcb.obj      U __ctype_      U __fcb         U _atoi         D _getfcb     \r\n\t\tU _getuid       D _putfcb       D _setfcb       U _toupper    \r\n\t\tU brelop        U cret          U csv           U indir       \r\n\t\tU ncsv          U wrelop        \r\nsrand1.obj      U _kbhit        U _putchar      U _srand        D _srand1     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nabort.obj       D _abort        U _bdos         U _exit         U cret        \r\n\t\tU indir         U ncsv          \r\ngetch.obj       U _bdos         D _getch        D _getche       D _kbhit      \r\n\t\tD _putch        D _ungetch      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsignal.obj      D __sigchk      U _bdos         U _exit         D _signal     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\ngetuid.obj      D _getuid       D _setuid       U cret          U csv         \r\nbdos.obj        D _bdos         U _errno        U cret          U csv         \r\nbios.obj        D _bios         U cret          U csv           D exit22      \r\n_exit.obj       U __cpm_clean   D __exit        \r\nfakeclean.obj   D __cleanup     U cret          U indir         U ncsv        \r\nfakecpcln.obj   D __cpm_clean   \r\nsys_err.obj     D _errno        D _sys_err      D _sys_ner      \r\nmemcpy.obj      D _memcpy       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nmemcmp.obj      D _memcmp       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nmemset.obj      D _memset       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nstrftime.obj    D _strftime     U adiv          U amod          U asamod      \r\n\t\tU cret          U indir         U ncsv          U wrelop      \r\nasmod.obj       U amod          D asamod        D aslmod        U lmod        \r\nabs.obj         D _abs          \r\nasallsh.obj     U allsh         D asallsh       D aslllsh       U iregstore   \r\nallsh.obj       D allsh         D lllsh         \r\nasalrsh.obj     U alrsh         D asalrsh       U iregstore     \r\nasar.obj        D asar          U shar          \r\nasdiv.obj       U adiv          D asadiv        D asldiv        U ldiv        \r\nasladd.obj      U aladd         D asaladd       D aslladd       U iregset     \r\n\t\tU iregstore     \r\nasland.obj      U aland         D asaland       D aslland       U iregset     \r\n\t\tU iregstore     \r\nasll.obj        D asal          D asll          U shal          \r\nasllrsh.obj     D asllrsh       U iregstore     U llrsh         \r\naslmul.obj      U almul         D asalmul       D asllmul       U iregset     \r\n\t\tU iregstore     \r\naslor.obj       U alor          D asalor        D asllor        U iregset     \r\n\t\tU iregstore     \r\naslsub.obj      U alsub         D asalsub       D asllsub       U iregset     \r\n\t\tU iregstore     \r\naslxor.obj      U alxor         D asalxor       D asllxor       U iregset     \r\n\t\tU iregstore     \r\natoi.obj        D _atoi         \r\natol.obj        U __ctype_      D _atol         U aladd         U almul       \r\n\t\tU cret          U indir         U ncsv          \r\nblkclr.obj      D _blkclr       \r\nblkcpy.obj      D _blkcpy       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\ncalloc.obj      U _bmove        D _calloc       D _cfree        U _free       \r\n\t\tU _malloc       U asamul        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nasmul.obj       U amul          D asamul        D aslmul        \r\nbitfield.obj    D bfext         D bfins         \r\nctype_.obj      D __ctype_      \r\ngetsp.obj       D __getsp       \r\nindex.obj       D _index        U cret          U rcsv          \r\nstrchr.obj      D _strchr       U cret          U rcsv          \r\nqsort.obj       U __swap        U _bmove        U _free         U _malloc     \r\n\t\tD _qsort        U adiv          U cret          U indir       \r\n\t\tU lmul          U ncsv          U wrelop        \r\nmalloc.obj      U _bmove        D _free         D _malloc       D _realloc    \r\n\t\tU _sbrk         U adiv          U amul          U cret        \r\n\t\tU csv           U indir         U ldiv          U lmul        \r\n\t\tU ncsv          U wrelop        \r\nmax.obj         D _max          \r\nidiv.obj        D adiv          D amod          D ldiv          D lmod        \r\npnum.obj        D __pnum        U aslldiv       U brelop        U cret        \r\n\t\tU indir         U llmod         U ncsv          U wrelop      \r\nldiv.obj        D aldiv         D almod         D asaldiv       D asalmod     \r\n\t\tD aslldiv       D asllmod       D lldiv         D llmod       \r\nswap.obj        D __swap        U cret          U rcsv          \r\naslr.obj        D aslr          U shlr          \r\nbmove.obj       D _bmove        D _movmem       \r\nimul.obj        D amul          D lmul          \r\nrand.obj        D _rand         D _srand        U almul         U alrsh       \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nalrsh.obj       D alrsh         \r\nlmul.obj        D almul         D llmul         \r\nrindex.obj      D _rindex       U cret          U rcsv          \r\nstrrchr.obj     D _strrchr      U cret          U rcsv          \r\nsbrk.obj        U __Hbss        D _brk          D _checksp      D _sbrk       \r\nshar.obj        D shar          \r\nshll.obj        D shal          D shll          \r\nshlr.obj        D shlr          \r\nstrcat.obj      D _strcat       \r\nstrcmp.obj      D _strcmp       \r\nstrcpy.obj      D _strcpy       \r\nstrlen.obj      D _strlen       \r\nstrncat.obj     D _strncat      U cret          U rcsv          \r\nstrncmp.obj     D _strncmp      U cret          U rcsv          \r\nstrncpy.obj     D _strncpy      U cret          U rcsv          \r\nstrstr.obj      D _strstr       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nstrnstr.obj     D _strnstr      U cret          U indir         U ncsv        \r\nstrdup.obj      U _malloc       U _strcpy       D _strdup       U _strlen     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nstricmp.obj     D _strcasecmp   \r\nstristr.obj     D _strcasestr   U _toupper      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nstrnicmp.obj    D _strncasecmp  U cret          U rcsv          \r\nstrnistr.obj    D _strncasestr  U _toupper      U cret          U indir       \r\n\t\tU ncsv          \r\nstrtok.obj      D _strtok       U cret          U csv           U indir       \r\n\t\tU ncsv          U wrelop        \r\ninout.obj       D _in           D _inp          D _out          D _outp       \r\niregset.obj     D iregset       D iregstore     \r\nisalpha.obj     D _isalpha      \r\nisdigit.obj     D _isdig        D _isdigit      \r\nislower.obj     D _islower      \r\nisspace.obj     D _isspace      \r\nisupper.obj     D _isupper      \r\nladd.obj        D aladd         D lladd         \r\nland.obj        D aland         D lland         \r\nlinc.obj        D ladec         D lainc         D lldec         D llinc       \r\nllrsh.obj       D llrsh         \r\nlongjmp.obj     D _longjmp      D _setjmp       \r\nlor.obj         D alor          D llor          \r\nbrelop.obj      D brelop        \r\nwrelop.obj      D wrelop        \r\nlrelop.obj      D arelop        D lrelop        \r\nfrelop.obj      D frelop        \r\nlsub.obj        D alsub         D llsub         \r\nlxor.obj        D alxor         D llxor         \r\ncsv.obj         D cret          D csv           D indir         D ncsv        \r\nrcsv.obj        D rcsv          \r\ntolower.obj     D _tolower      \r\ntoupper.obj     D _toupper      \r\nxtoi.obj        D _ishex        D _xtoi         \r\n\r\n10M>e:\r\n10E>pip e:=m:lib280c.lib\r\nA:PIP      COM  (User 0)\r\n\r\n10E>; Library m:lib280c.lib created\r\n10E>; Remember to copy it to current directory and A0:\r\n10E>;\r\n10E>; Now save the Z280 object files in E:LIB280C.LBR\r\n10E>dir m:*.obj[fu,length=65535]\r\nA:DIR      COM  (User 0)\r\n\r\nScanning Directory...\r\n\r\nSorting  Directory...\r\n\r\nDirectory For Drive M:  User 10\r\n\r\n    Name     Bytes   Recs   Attributes   Prot      Update          Create    \r\n------------ ------ ------ ------------ ------ --------------  --------------\r\n\r\nABORT    OBJ     4k      2 Dir RW       None   05/09/25 12:33  05/09/25 12:33\r\nABS      OBJ     4k      1 Dir RW       None   05/09/25 12:33  05/09/25 12:33\r\nALLSH    OBJ     4k      1 Dir RW       None   05/09/25 12:33  05/09/25 12:33\r\nALRSH    OBJ     4k      1 Dir RW       None   05/09/25 12:33  05/09/25 12:33\r\nASALLSH  OBJ     4k      2 Dir RW       None   05/09/25 12:33  05/09/25 12:33\r\nASALRSH  OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASAR     OBJ     4k      1 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASDIV    OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLADD   OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLAND   OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLL     OBJ     4k      1 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLLRSH  OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLMUL   OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLOR    OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLR     OBJ     4k      1 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLSUB   OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASLXOR   OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASMOD    OBJ     4k      2 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASMUL    OBJ     4k      1 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nASSERT   OBJ     4k      3 Dir RW       None   05/09/25 12:34  05/09/25 12:34\r\nATOI     OBJ     4k      2 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nATOL     OBJ     4k      4 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBDOS     OBJ     4k      4 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBIOS     OBJ     4k      5 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBITFIELD OBJ     4k      2 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBLKCLR   OBJ     4k      1 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBLKCPY   OBJ     4k      2 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBMOVE    OBJ     4k      1 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBRELOP   OBJ     4k      1 Dir RW       None   05/09/25 12:35  05/09/25 12:35\r\nBUF      OBJ     4k      3 Dir RW       None   05/09/25 12:36  05/09/25 12:36\r\nCALLOC   OBJ     4k      4 Dir RW       None   05/09/25 12:36  05/09/25 12:36\r\nCGETS    OBJ     4k      3 Dir RW       None   05/09/25 12:36  05/09/25 12:36\r\nCHMOD    OBJ     4k      4 Dir RW       None   05/09/25 12:36  05/09/25 12:36\r\nCLEANUP  OBJ     4k      7 Dir RW       None   05/09/25 12:36  05/09/25 12:36\r\nCLOSE    OBJ     4k      5 Dir RW       None   05/09/25 12:37  05/09/25 12:37\r\nCONVTIME OBJ     4k      5 Dir RW       None   05/09/25 12:37  05/09/25 12:37\r\nCPUTS    OBJ     4k      2 Dir RW       None   05/09/25 12:37  05/09/25 12:37\r\nCREAT    OBJ     4k      6 Dir RW       None   05/09/25 12:37  05/09/25 12:37\r\nCSV      OBJ     4k      2 Dir RW       None   05/09/25 12:37  05/09/25 12:37\r\nCTIME    OBJ     4k     17 Dir RW       None   05/09/25 12:38  05/09/25 12:38\r\nCTYPE    OBJ     4k      2 Dir RW       None   05/09/25 12:38  05/09/25 12:38\r\nCTYPE_   OBJ     4k      2 Dir RW       None   05/09/25 12:38  05/09/25 12:38\r\nDOPRNT   OBJ     4k     17 Dir RW       None   05/09/25 12:39  05/09/25 12:39\r\nDOSCAN   OBJ     4k     23 Dir RW       None   05/09/25 12:39  05/09/25 12:39\r\nDUP      OBJ     4k      3 Dir RW       None   05/09/25 12:39  05/09/25 12:39\r\nEXEC     OBJ     4k     22 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\nEXECL    OBJ     4k      9 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\nEXIT     OBJ     4k      2 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\nFAKECLEA OBJ     4k      1 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\nFAKECPCL OBJ     4k      1 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\nFCBNAME  OBJ     4k     12 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\nFCLOSE   OBJ     4k      3 Dir RW       None   05/09/25 12:41  05/09/25 12:41\r\nFFLUSH   OBJ     4k      4 Dir RW       None   05/09/25 12:41  05/09/25 12:41\r\nFGETC    OBJ     4k      4 Dir RW       None   05/09/25 12:41  05/09/25 12:41\r\nFILBUF   OBJ     4k      6 Dir RW       None   05/09/25 12:41  05/09/25 12:41\r\nFLSBUF   OBJ     4k      5 Dir RW       None   05/09/25 12:42  05/09/25 12:42\r\nFOPEN    OBJ     4k      3 Dir RW       None   05/09/25 12:42  05/09/25 12:42\r\nFPRINTF  OBJ     4k      2 Dir RW       None   05/09/25 12:42  05/09/25 12:42\r\nFPUTC    OBJ     4k      5 Dir RW       None   05/09/25 12:42  05/09/25 12:42\r\nFREAD    OBJ     4k      6 Dir RW       None   05/09/25 12:42  05/09/25 12:42\r\nFRELOP   OBJ     4k      2 Dir RW       None   05/09/25 12:43  05/09/25 12:43\r\nFREOPEN  OBJ     4k      9 Dir RW       None   05/09/25 12:43  05/09/25 12:43\r\nFSCANF   OBJ     4k      2 Dir RW       None   05/09/25 12:43  05/09/25 12:43\r\nFSEEK    OBJ     4k     11 Dir RW       None   05/09/25 12:43  05/09/25 12:43\r\nFWRITE   OBJ     4k      7 Dir RW       None   05/09/25 12:44  05/09/25 12:44\r\nGETARGS  OBJ     8k     37 Dir RW       None   05/09/25 12:45  05/09/25 12:45\r\nGETCH    OBJ     4k      5 Dir RW       None   05/09/25 12:45  05/09/25 12:45\r\nGETENV   OBJ     4k     14 Dir RW       None   05/09/25 12:46  05/09/25 12:46\r\nGETFCB   OBJ     4k     16 Dir RW       None   05/09/25 12:46  05/09/25 12:46\r\nGETS     OBJ     4k      4 Dir RW       None   05/09/25 12:46  05/09/25 12:46\r\nGETSP    OBJ     4k      1 Dir RW       None   05/09/25 12:46  05/09/25 12:46\r\nGETUID   OBJ     4k      2 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nGETW     OBJ     4k      3 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nIDIV     OBJ     4k      4 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nIMUL     OBJ     4k      2 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nINDEX    OBJ     4k      2 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nINOUT    OBJ     4k      2 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nIREGSET  OBJ     4k      1 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nISALPHA  OBJ     4k      2 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nISATTY   OBJ     4k      3 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nISDIGIT  OBJ     4k      1 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nISLOWER  OBJ     4k      1 Dir RW       None   05/09/25 12:47  05/09/25 12:47\r\nISSPACE  OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nISUPPER  OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLADD     OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLAND     OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLDIV     OBJ     4k      7 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLIBCVER  OBJ     4k      1 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\nLINC     OBJ     4k      2 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLLRSH    OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLMUL     OBJ     4k      2 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLONGJMP  OBJ     4k      2 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLOR      OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLRELOP   OBJ     4k      2 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLSUB     OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nLXOR     OBJ     4k      1 Dir RW       None   05/09/25 12:48  05/09/25 12:48\r\nMALLOC   OBJ     4k     14 Dir RW       None   05/09/25 12:49  05/09/25 12:49\r\nMAX      OBJ     4k      1 Dir RW       None   05/09/25 12:49  05/09/25 12:49\r\nMEMCMP   OBJ     4k      2 Dir RW       None   05/09/25 12:49  05/09/25 12:49\r\nMEMCPY   OBJ     4k      2 Dir RW       None   05/09/25 12:49  05/09/25 12:49\r\nMEMSET   OBJ     4k      2 Dir RW       None   05/09/25 12:49  05/09/25 12:49\r\nMKTIME   OBJ     4k     10 Dir RW       None   05/09/25 12:50  05/09/25 12:50\r\nOPEN     OBJ     4k     11 Dir RW       None   05/09/25 12:50  05/09/25 12:50\r\nPERROR   OBJ     4k      5 Dir RW       None   05/09/25 12:50  05/09/25 12:50\r\nPNUM     OBJ     4k      7 Dir RW       None   05/09/25 12:50  05/09/25 12:50\r\nPRINTF   OBJ     4k      2 Dir RW       None   05/09/25 12:51  05/09/25 12:51\r\nPUTCHAR  OBJ     4k      3 Dir RW       None   05/09/25 12:51  05/09/25 12:51\r\nPUTS     OBJ     4k      3 Dir RW       None   05/09/25 12:51  05/09/25 12:51\r\nPUTW     OBJ     4k      3 Dir RW       None   05/09/25 12:51  05/09/25 12:51\r\nQSORT    OBJ     4k     10 Dir RW       None   05/09/25 12:52  05/09/25 12:52\r\nRAND     OBJ     4k      3 Dir RW       None   05/09/25 12:52  05/09/25 12:52\r\nRCSV     OBJ     4k      1 Dir RW       None   05/09/25 12:52  05/09/25 12:52\r\nREAD     OBJ     4k     15 Dir RW       None   05/09/25 12:52  05/09/25 12:52\r\nREMOVE   OBJ     4k      2 Dir RW       None   05/09/25 12:52  05/09/25 12:52\r\nRENAME   OBJ     4k      3 Dir RW       None   05/09/25 12:53  05/09/25 12:53\r\nREWIND   OBJ     4k      2 Dir RW       None   05/09/25 12:53  05/09/25 12:53\r\nRINDEX   OBJ     4k      2 Dir RW       None   05/09/25 12:53  05/09/25 12:53\r\nSBRK     OBJ     4k      3 Dir RW       None   05/09/25 12:53  05/09/25 12:53\r\nSCANF    OBJ     4k      2 Dir RW       None   05/09/25 12:53  05/09/25 12:53\r\nSEEK     OBJ     4k      5 Dir RW       None   05/09/25 12:53  05/09/25 12:53\r\nSETBUF   OBJ     4k      6 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSHAR     OBJ     4k      1 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSHLL     OBJ     4k      1 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSHLR     OBJ     4k      1 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSIGNAL   OBJ     4k      4 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSPRINTF  OBJ     4k      3 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSRAND    OBJ     4k      1 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSRAND1   OBJ     4k      3 Dir RW       None   05/09/25 12:54  05/09/25 12:54\r\nSSCANF   OBJ     4k      2 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTART1   OBJ     4k      2 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTART2   OBJ     4k      2 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTAT     OBJ     4k     10 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTDCLEAN OBJ     4k      4 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTRCAT   OBJ     4k      1 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTRCHR   OBJ     4k      1 Dir RW       None   05/09/25 12:55  05/09/25 12:55\r\nSTRCMP   OBJ     4k      1 Dir RW       None   05/09/25 12:56  05/09/25 12:56\r\nSTRCPY   OBJ     4k      1 Dir RW       None   05/09/25 12:56  05/09/25 12:56\r\nSTRDUP   OBJ     4k      3 Dir RW       None   05/09/25 12:56  05/09/25 12:56\r\nSTRFTIME OBJ     4k     31 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRICMP  OBJ     4k      1 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRISTR  OBJ     4k      3 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRLEN   OBJ     4k      1 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRNCAT  OBJ     4k      2 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRNCMP  OBJ     4k      2 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRNCPY  OBJ     4k      2 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRNICMP OBJ     4k      3 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRNISTR OBJ     4k      4 Dir RW       None   05/09/25 12:57  05/09/25 12:57\r\nSTRNSTR  OBJ     4k      4 Dir RW       None   05/09/25 12:58  05/09/25 12:58\r\nSTRRCHR  OBJ     4k      1 Dir RW       None   05/09/25 12:58  05/09/25 12:58\r\nSTRSTR   OBJ     4k      3 Dir RW       None   05/09/25 12:58  05/09/25 12:58\r\nSTRTOK   OBJ     4k      4 Dir RW       None   05/09/25 12:58  05/09/25 12:58\r\nSWAP     OBJ     4k      2 Dir RW       None   05/09/25 12:58  05/09/25 12:58\r\nSYS_ERR  OBJ     4k      6 Dir RW       None   05/09/25 12:58  05/09/25 12:58\r\nTIME     OBJ     4k      3 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nTIMEZONE OBJ     4k      1 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nTOLOWER  OBJ     4k      1 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nTOUPPER  OBJ     4k      1 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nUNGETC   OBJ     4k      3 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nUNLINK   OBJ     4k      4 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nWRELOP   OBJ     4k      1 Dir RW       None   05/09/25 12:59  05/09/25 12:59\r\nWRITE    OBJ     4k     14 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\nXTOI     OBJ     4k      2 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\nZC280CPM OBJ     4k      9 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\nZD280CPM OBJ     4k      3 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\nZN280CPM OBJ     4k     10 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\nZR280CPM OBJ     4k     11 Dir RW       None   05/09/25 13:00  05/09/25 13:00\r\n_EXIT    OBJ     4k      2 Dir RW       None   05/09/25 12:40  05/09/25 12:40\r\n\r\nTotal Bytes     =    672k  Total Records =     695  Files Found =  167\r\nTotal 1k Blocks =    198   Used/Max Dir Entries For Drive M:  233/ 512\r\n\r\n10E>era e:lib280c.lbr\r\n10E>; Enter the number of files from above DIR command when prompted\r\n10E>nulu e:lib280c.lbr -a m:*.obj -x\r\nA:NULU     COM  (User 0)\r\n^Z\rNULU 1.52  (07/12/87)\r\nCopyright (C) 1984, 1985 & 1987 by Martin Murray\r\nBug fixes in version 1.52 by Mick Waters\r\n\r\nTYPE -H FOR HELP\r\n\r\n\r\nCOMPLIBC.LOG | ABORT   .C   | ABS     .AS  | ALLSH   .AS  | ALRSH   .AS \r\nASALLSH .AS  | ASALRSH .AS  | ASAR    .AS  | ASDIV   .AS  | ASLADD  .AS \r\nASLAND  .AS  | ASLL    .AS  | ASLLRSH .AS  | ASLMUL  .AS  | ASLOR   .AS \r\nASLR    .AS  | ASLSUB  .AS  | ASLXOR  .AS  | ASMOD   .AS  | ASMUL   .AS \r\nASSERT  .C   | ATOI    .AS  | ATOL    .C   | B280OVR .SUB | BUILDALL.SUB\r\nABORT   .OBJ | BITFIELD.AS  | BLKCLR  .AS  | BLKCPY  .C   | BMOVE   .AS \r\nBRELOP  .AS  | BUF     .C   | TESTBDOS.C   | ABS     .OBJ | BUILD-C2.SUB\r\nBUILDCPM.SUB | BUILDCRT.SUB | BUILDGEN.SUB | BUILDOVR.SUB | BUILDSTD.SUB\r\nC       .C   | C-JS    .C   | C-ORIG  .C   | TESTARGS.COM | OPTIMH  .C  \r\nTESTBDOS.COM | C280LIBC.SUB | C280OPTS.    | _EXIT   .AS  | BDOS    .AS \r\nOPTIMH  .COM | CALLOC  .C   | CGETS   .C   | CHMOD   .C   | CLEANUP .C  \r\nCLOSE   .C   | BIOS    .AS  | EXIT    .AS  | BUILD-C .LOG | ZCRTCPM .AS \r\nCONVTIME.C   | CPUTS   .C   | CREAT   .C   | CSV     .AS  | CSV-CPM .AS \r\nCTIME   .C   | CTYPE   .C   | CTYPE_  .C   | DECODE  .C   | DEHUFF  .C  \r\nDEHUFF  .COM | DOPRNT  .C   | DOSCAN  .C   | DUP     .C   | ENCODE  .C  \r\nENHUFF  .C   | ENHUFF  .COM | ENVIRON .    | EXEC    .AS  | EXECL   .AS \r\nALLSH   .OBJ | EXIT    .C   | FAKECLEA.AS  | FAKECLEA.C   | FAKECPCL.AS \r\nFCBNAME .C   | FCLOSE  .C   | C280Z80 .COM | ALRSH   .OBJ | FILBUF  .C  \r\nFILESIZE.C   | ASALLSH .OBJ | FLSBUF  .C   | FOPEN   .C   | FPRINTF .C  \r\nFPUTC   .AS  | FREAD   .C   | FRELOP  .AS  | FREOPEN .C   | FSCANF  .C  \r\nASALRSH .OBJ | ZAS-SRC .LBR | GETARGS .C   | GETCH   .C   | GETENV  .C  \r\nGETFCB  .C   | GETS    .C   | GETSP   .AS  | GETUID  .AS  | GETW    .C  \r\nHELLO   .C   | HELLOS  .C   | HUFF    .H   | IDIV    .AS  | IMUL    .AS \r\nINDEX   .AS  | INOUT   .AS  | IREGSET .AS  | ISALPHA .AS  | ISATTY  .C  \r\nISDIGIT .AS  | ISLOWER .AS  | ISSPACE .AS  | ISUPPER .AS  | LADD    .AS \r\nLAND    .AS  | LDIV    .AS  | LIBCVER .C   | LIBOVR  .SUB | LIBSYM  .PAS\r\nLINC    .AS  | LISTLIBS.SUB | LISTMODC.SUB | LLRSH   .AS  | LMUL    .AS \r\nLONGJMP .AS  | LOR     .AS  | LRELOP  .AS  | LSUB    .AS  | LXOR    .AS \r\nM280LIBC.LOG | M280LIBV.SUB | MAKEFILE.COD | MAKEFILE.CPM | ASAR    .OBJ\r\nMAKEFILE.GEN | MAKEFILE.STD | ZNRTCPM .AS  | ASDIV   .OBJ | MALLOC  .C  \r\nMAX     .AS  | MEMCMP  .C   | MEMCPY  .C   | MEMSET  .C   | MISC    .C  \r\nMKTIME  .C   | NOMAIN  .C   | OBJDUMP .COM | OPEN    .C   | ASLADD  .OBJ\r\nASLAND  .OBJ | OPTIONS .    | OVRBGN  .AS  | OVREADME.TXT | OVRLOAD .C  \r\nPERROR  .C   | PNUM    .C   | PRINTF  .C   | PUTCHAR .C   | PUTS    .C  \r\nPUTW    .C   | QSORT   .C   | RAND    .C   | RCSV    .AS  | READ    .C  \r\nRELIBCPM.SUB | RELIBGEN.SUB | RELIBSTD.SUB | REMOVE  .C   | RENAME  .C  \r\nREWIND  .C   | RINDEX  .AS  | SBRK    .AS  | SCANF   .C   | SEEK    .C  \r\nSETBUF  .C   | SHAR    .AS  | SHLL    .AS  | SHLR    .AS  | SIGNAL-O.C  \r\nSPRINTF .C   | SRAND   .AS  | SRAND1  .C   | SSCANF  .C   | START1  .AS \r\nSTART2  .AS  | STAT    .C   | ASLL    .OBJ | STDCLEAN.C   | STDIO   .I  \r\nSTRCAT  .AS  | STRCHR  .AS  | STRCMP  .AS  | STRCPY  .AS  | STRDUP  .C  \r\nSTRFTIME.C   | STRICMP .AS  | STRISTR .C   | STRLEN  .AS  | STRNCAT .AS \r\nSTRNCMP .AS  | STRNCPY .AS  | STRNICMP.AS  | STRNISTR.C   | STRNSTR .C  \r\nSTRRCHR .AS  | STRSTR  .C   | STRTOK  .C   | SWAP    .AS  | SYMTOAS .C  \r\nSYMTOAS .COM | SYS_ERR .C   | TEST    .LOG | TEST-OPT.AS  | TESTAES .C  \r\nTESTAES .COM | TESTARGS.C   | ASLLRSH .OBJ | ASLMUL  .OBJ | TESTBIOS.C  \r\nZRRTCPM .AS  | TESTBUG .AS  | TESTBUG .C   | TESTENV .C   | TESTFILE.C  \r\nASLOR   .OBJ | TESTFTIM.C   | ASLR    .OBJ | TESTHELL.C   | ASLSUB  .OBJ\r\nTESTIO  .C   | ASLXOR  .OBJ | TESTIO  .ERR | TESTIO  .STA | TESTL   .C  \r\nZC280CPM.AS  | TESTLTOF.AS  | TESTLTOF.C   | TESTOPTH.AS  | TESTOVR .C  \r\nASMOD   .OBJ | TESTOVR1.C   | ZN280CPM.AS  | TESTOVR2.C   | ZR280CPM.AS \r\nASMUL   .OBJ | TESTPR  .C   | ASSERT  .OBJ | TESTPWD .C   | TESTQSRT.C  \r\nTESTRC  .C   | ATOI    .OBJ | TESTREL .C   | TESTSTR .C   | ATOL    .OBJ\r\nTESTSUB .C   | TESTTRIG.C   | BDOS    .OBJ | TESTUID .C   | TESTVER .C  \r\nTESTVER .SUB | TESTVIEW.C   | TESTWILD.C   | BIOS    .OBJ | TIME    .C  \r\nTIMEZONE.C   | TOLOWER .AS  | TOUPPER .AS  | FGETC   .AS  | BITFIELD.OBJ\r\nBLKCLR  .OBJ | BLKCPY  .OBJ | UNGETC  .C   | UNLINK  .C   | WRELOP  .AS \r\nWRITE   .C   | XTOI    .AS  | BMOVE   .OBJ | BRELOP  .OBJ | ZD280CPM.AS \r\nZDRTCPM .AS  | BUF     .OBJ | CALLOC  .OBJ | CGETS   .OBJ | CHMOD   .OBJ\r\nZXCCCPM .AS  | CLEANUP .OBJ | CLOSE   .OBJ | CONVTIME.OBJ | CPUTS   .OBJ\r\nCREAT   .OBJ | CSV     .OBJ | CTIME   .OBJ | CTYPE_  .OBJ | CTYPE   .OBJ\r\nCOMPLIBC.SUB | DOPRNT  .OBJ | DOSCAN  .OBJ | DUP     .OBJ | EXEC    .OBJ\r\nEXECL   .OBJ | _EXIT   .OBJ | EXIT    .OBJ | FAKECLEA.OBJ | FAKECPCL.OBJ\r\nFCBNAME .OBJ | FCLOSE  .OBJ | FFLUSH  .OBJ | FGETC   .OBJ | FILBUF  .OBJ\r\nFLSBUF  .OBJ | FOPEN   .OBJ | FPRINTF .OBJ | FPUTC   .OBJ | FREAD   .OBJ\r\nFRELOP  .OBJ | FREOPEN .OBJ | FSCANF  .OBJ | FSEEK   .OBJ | FWRITE  .OBJ\r\nGETARGS .OBJ | GETCH   .OBJ | GETENV  .OBJ | GETFCB  .OBJ | GETS    .OBJ\r\nGETSP   .OBJ | GETUID  .OBJ | GETW    .OBJ | IDIV    .OBJ | IMUL    .OBJ\r\nINDEX   .OBJ | INOUT   .OBJ | IREGSET .OBJ | ISALPHA .OBJ | ISATTY  .OBJ\r\nISDIGIT .OBJ | ISLOWER .OBJ | ISSPACE .OBJ | ISUPPER .OBJ | LADD    .OBJ\r\nLAND    .OBJ | LDIV    .OBJ | LINC    .OBJ | LLRSH   .OBJ | FFLUSH  .C  \r\nLMUL    .OBJ | LONGJMP .OBJ | LOR     .OBJ | LRELOP  .OBJ | LSUB    .OBJ\r\nLXOR    .OBJ | MALLOC  .OBJ | MAX     .OBJ | MEMCMP  .OBJ | MEMCPY  .OBJ\r\nMEMSET  .OBJ | MKTIME  .OBJ | OPEN    .OBJ | PERROR  .OBJ | PNUM    .OBJ\r\nPRINTF  .OBJ | PUTCHAR .OBJ | PUTS    .OBJ | PUTW    .OBJ | QSORT   .OBJ\r\nRAND    .OBJ | RCSV    .OBJ | READ    .OBJ | REMOVE  .OBJ | RENAME  .OBJ\r\nREWIND  .OBJ | RINDEX  .OBJ | SBRK    .OBJ | SCANF   .OBJ | SEEK    .OBJ\r\nSETBUF  .OBJ | SHAR    .OBJ | SHLL    .OBJ | SHLR    .OBJ | SIGNAL  .OBJ\r\nSPRINTF .OBJ | SRAND1  .OBJ | SRAND   .OBJ | SSCANF  .OBJ | START1  .OBJ\r\nSTART2  .OBJ | STAT    .OBJ | STDCLEAN.OBJ | STRCAT  .OBJ | STRCHR  .OBJ\r\nSTRCMP  .OBJ | STRCPY  .OBJ | STRDUP  .OBJ | STRFTIME.OBJ | STRICMP .OBJ\r\nSTRISTR .OBJ | STRLEN  .OBJ | STRNCAT .OBJ | STRNCMP .OBJ | STRNCPY .OBJ\r\nSTRNICMP.OBJ | STRNISTR.OBJ | STRNSTR .OBJ | STRRCHR .OBJ | STRSTR  .OBJ\r\nSTRTOK  .OBJ | SWAP    .OBJ | SYS_ERR .OBJ | TIME    .OBJ | TIMEZONE.OBJ\r\nTOLOWER .OBJ | TOUPPER .OBJ | UNGETC  .OBJ | UNLINK  .OBJ | WRELOP  .OBJ\r\nWRITE   .OBJ | FILESIZE.COM | @LIBC309.-20 | XTOI    .OBJ | ZCRTCPM .OBJ\r\nLIBOVR  .LIB | C280LIBC.LOG | ZDRTCPM .OBJ | EXEC-BLD.SUB | FGETC   .C  \r\nFGETC-O .AS  | TESTVER .COM | FPUTC   .C   | FPUTC-O .AS  | FSHOW   .C  \r\nZNRTCPM .OBJ | ZRRTCPM .OBJ | LIBCVER .OBJ | MAKELIBC.LOG | TEST    .DAT\r\nTESTBIOS.COM | TESTFILE.COM | TESTFTIM.COM | TESTHELL.COM | TESTIO  .COM\r\nTESTOVR .COM | TESTOVR1.OVR | TESTOVR2.OVR | TESTOVRX.SYM | TESTPR  .COM\r\nTESTRC  .COM | TESTSTR .COM | TESTTRIG.COM | TESTUID .COM | TESTVIEW.COM\r\nTESTWILD.COM | LIBC20  .LIB | LIB280C .LIB | BUILD-C .SUB | ZC280CPM.OBJ\r\nZD280CPM.OBJ | ZN280CPM.OBJ | ZR280CPM.OBJ | SIGNAL  .C   | C309-20 .COM\r\nC280-20 .COM | M280LIBC.SUB | TEST280 .LOG | TEST-OPT.AS2 | TEST    .SUB\r\nTEST280 .SUB | TEST-OPT.AS3 | OPTIMH80.COM | FSEEK   .C   | FWRITE  .C  \r\nMKLIBC  .SUB | C309-20 .C   | MAKELIBC.SUB | \r\nDrive E: Total 8000k, Used 7456k, Free 544k\r\n\r\nLibrary E10:LIB280C.LBR^G not found.\r\n  To make it, enter the number of entries to allow.\r\n  Press RETURN now to abort making the library.\r\nAllow how many entries: 167\r\nLibrary E10:LIB280C.LBR open.\r\n(Buffer size: 216 sectors)\r\nActive entries: 1, Deleted: 0, Free: 167, Total: 168.\r\nAdding:    M10:ISLOWER .OBJ\r\nAdding:    M10:ISSPACE .OBJ\r\nAdding:    M10:ISUPPER .OBJ\r\nAdding:    M10:ABORT   .OBJ\r\nAdding:    M10:ABS     .OBJ\r\nAdding:    M10:ALLSH   .OBJ\r\nAdding:    M10:ALRSH   .OBJ\r\nAdding:    M10:ASALLSH .OBJ\r\nAdding:    M10:ASALRSH .OBJ\r\nAdding:    M10:ASAR    .OBJ\r\nAdding:    M10:ASDIV   .OBJ\r\nAdding:    M10:ASLADD  .OBJ\r\nAdding:    M10:ASLAND  .OBJ\r\nAdding:    M10:ASLL    .OBJ\r\nAdding:    M10:ASLLRSH .OBJ\r\nAdding:    M10:ASLMUL  .OBJ\r\nAdding:    M10:ASLOR   .OBJ\r\nAdding:    M10:ASLR    .OBJ\r\nAdding:    M10:ASLSUB  .OBJ\r\nAdding:    M10:ASLXOR  .OBJ\r\nAdding:    M10:ASMOD   .OBJ\r\nAdding:    M10:ASMUL   .OBJ\r\nAdding:    M10:ASSERT  .OBJ\r\nAdding:    M10:ATOI    .OBJ\r\nAdding:    M10:ATOL    .OBJ\r\nAdding:    M10:BDOS    .OBJ\r\nAdding:    M10:BIOS    .OBJ\r\nAdding:    M10:BITFIELD.OBJ\r\nAdding:    M10:BLKCLR  .OBJ\r\nAdding:    M10:BLKCPY  .OBJ\r\nAdding:    M10:BMOVE   .OBJ\r\nAdding:    M10:BRELOP  .OBJ\r\nAdding:    M10:BUF     .OBJ\r\nAdding:    M10:CALLOC  .OBJ\r\nAdding:    M10:CGETS   .OBJ\r\nAdding:    M10:CHMOD   .OBJ\r\nAdding:    M10:CLEANUP .OBJ\r\nAdding:    M10:CLOSE   .OBJ\r\nAdding:    M10:CONVTIME.OBJ\r\nAdding:    M10:CPUTS   .OBJ\r\nAdding:    M10:CREAT   .OBJ\r\nAdding:    M10:CSV     .OBJ\r\nAdding:    M10:CTIME   .OBJ\r\nAdding:    M10:CTYPE_  .OBJ\r\nAdding:    M10:CTYPE   .OBJ\r\nAdding:    M10:DOPRNT  .OBJ\r\nAdding:    M10:DOSCAN  .OBJ\r\nAdding:    M10:DUP     .OBJ\r\nAdding:    M10:EXEC    .OBJ\r\nAdding:    M10:EXECL   .OBJ\r\nAdding:    M10:_EXIT   .OBJ\r\nAdding:    M10:EXIT    .OBJ\r\nAdding:    M10:FAKECLEA.OBJ\r\nAdding:    M10:FAKECPCL.OBJ\r\nAdding:    M10:FCBNAME .OBJ\r\nAdding:    M10:FCLOSE  .OBJ\r\nAdding:    M10:FFLUSH  .OBJ\r\nAdding:    M10:FGETC   .OBJ\r\nAdding:    M10:FILBUF  .OBJ\r\nAdding:    M10:FLSBUF  .OBJ\r\nAdding:    M10:FOPEN   .OBJ\r\nAdding:    M10:FPRINTF .OBJ\r\nAdding:    M10:FPUTC   .OBJ\r\nAdding:    M10:FREAD   .OBJ\r\nAdding:    M10:FRELOP  .OBJ\r\nAdding:    M10:FREOPEN .OBJ\r\nAdding:    M10:FSCANF  .OBJ\r\nAdding:    M10:FSEEK   .OBJ\r\nAdding:    M10:FWRITE  .OBJ\r\nAdding:    M10:GETARGS .OBJ\r\nAdding:    M10:GETCH   .OBJ\r\nAdding:    M10:GETENV  .OBJ\r\nAdding:    M10:GETFCB  .OBJ\r\nAdding:    M10:GETS    .OBJ\r\nAdding:    M10:GETSP   .OBJ\r\nAdding:    M10:GETUID  .OBJ\r\nAdding:    M10:GETW    .OBJ\r\nAdding:    M10:IDIV    .OBJ\r\nAdding:    M10:IMUL    .OBJ\r\nAdding:    M10:INDEX   .OBJ\r\nAdding:    M10:INOUT   .OBJ\r\nAdding:    M10:IREGSET .OBJ\r\nAdding:    M10:ISALPHA .OBJ\r\nAdding:    M10:ISATTY  .OBJ\r\nAdding:    M10:ISDIGIT .OBJ\r\nAdding:    M10:LADD    .OBJ\r\nAdding:    M10:LAND    .OBJ\r\nAdding:    M10:LDIV    .OBJ\r\nAdding:    M10:LINC    .OBJ\r\nAdding:    M10:LLRSH   .OBJ\r\nAdding:    M10:LMUL    .OBJ\r\nAdding:    M10:LONGJMP .OBJ\r\nAdding:    M10:LOR     .OBJ\r\nAdding:    M10:LRELOP  .OBJ\r\nAdding:    M10:LSUB    .OBJ\r\nAdding:    M10:LXOR    .OBJ\r\nAdding:    M10:MALLOC  .OBJ\r\nAdding:    M10:MAX     .OBJ\r\nAdding:    M10:MEMCMP  .OBJ\r\nAdding:    M10:MEMCPY  .OBJ\r\nAdding:    M10:MEMSET  .OBJ\r\nAdding:    M10:MKTIME  .OBJ\r\nAdding:    M10:OPEN    .OBJ\r\nAdding:    M10:PERROR  .OBJ\r\nAdding:    M10:PNUM    .OBJ\r\nAdding:    M10:PRINTF  .OBJ\r\nAdding:    M10:PUTCHAR .OBJ\r\nAdding:    M10:PUTS    .OBJ\r\nAdding:    M10:PUTW    .OBJ\r\nAdding:    M10:QSORT   .OBJ\r\nAdding:    M10:RAND    .OBJ\r\nAdding:    M10:RCSV    .OBJ\r\nAdding:    M10:READ    .OBJ\r\nAdding:    M10:REMOVE  .OBJ\r\nAdding:    M10:RENAME  .OBJ\r\nAdding:    M10:REWIND  .OBJ\r\nAdding:    M10:RINDEX  .OBJ\r\nAdding:    M10:SBRK    .OBJ\r\nAdding:    M10:SCANF   .OBJ\r\nAdding:    M10:SEEK    .OBJ\r\nAdding:    M10:SETBUF  .OBJ\r\nAdding:    M10:SHAR    .OBJ\r\nAdding:    M10:SHLL    .OBJ\r\nAdding:    M10:SHLR    .OBJ\r\nAdding:    M10:SIGNAL  .OBJ\r\nAdding:    M10:SPRINTF .OBJ\r\nAdding:    M10:SRAND1  .OBJ\r\nAdding:    M10:SRAND   .OBJ\r\nAdding:    M10:SSCANF  .OBJ\r\nAdding:    M10:START1  .OBJ\r\nAdding:    M10:START2  .OBJ\r\nAdding:    M10:STAT    .OBJ\r\nAdding:    M10:STDCLEAN.OBJ\r\nAdding:    M10:STRCAT  .OBJ\r\nAdding:    M10:STRCHR  .OBJ\r\nAdding:    M10:STRCMP  .OBJ\r\nAdding:    M10:STRCPY  .OBJ\r\nAdding:    M10:STRDUP  .OBJ\r\nAdding:    M10:STRFTIME.OBJ\r\nAdding:    M10:STRICMP .OBJ\r\nAdding:    M10:STRISTR .OBJ\r\nAdding:    M10:STRLEN  .OBJ\r\nAdding:    M10:STRNCAT .OBJ\r\nAdding:    M10:STRNCMP .OBJ\r\nAdding:    M10:STRNCPY .OBJ\r\nAdding:    M10:STRNICMP.OBJ\r\nAdding:    M10:STRNISTR.OBJ\r\nAdding:    M10:STRNSTR .OBJ\r\nAdding:    M10:STRRCHR .OBJ\r\nAdding:    M10:STRSTR  .OBJ\r\nAdding:    M10:STRTOK  .OBJ\r\nAdding:    M10:SWAP    .OBJ\r\nAdding:    M10:SYS_ERR .OBJ\r\nAdding:    M10:TIME    .OBJ\r\nAdding:    M10:TIMEZONE.OBJ\r\nAdding:    M10:TOLOWER .OBJ\r\nAdding:    M10:TOUPPER .OBJ\r\nAdding:    M10:UNGETC  .OBJ\r\nAdding:    M10:UNLINK  .OBJ\r\nAdding:    M10:WRELOP  .OBJ\r\nAdding:    M10:WRITE   .OBJ\r\nAdding:    M10:XTOI    .OBJ\r\nAdding:    M10:ZC280CPM.OBJ\r\nAdding:    M10:ZD280CPM.OBJ\r\nAdding:    M10:ZN280CPM.OBJ\r\nAdding:    M10:ZR280CPM.OBJ\r\nAdding:    M10:LIBCVER .OBJ\r\nActive entries: 168, Deleted: 0, Free: 0, Total: 168.\r\n\r\nClosing E10:LIB280C.LBR...\r\n\r\n\r\n10E>; Finally copy over the start-up modules\r\n10E>pip e:=m:z?280cpm.obj\r\nA:PIP      COM  (User 0)\r\n\r\nCOPYING -\r\nZC280CPM.OBJ\r\nZD280CPM.OBJ\r\nZN280CPM.OBJ\r\nZR280CPM.OBJ\r\n\r\n10E>;\r\n10E>put console to console\r\nA:PUT      COM  (User 0)\r\n\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a\u001a"
  },
  {
    "path": "stdio/M280LIBC.SUB",
    "content": "era m280libc.log\r\nput console output to file m280libc.log [system]\r\n; Use librarian to place all modules in m:lib280c.lib\r\n; NB: the ordering is important for resolving dependencies at link time\r\nm:\r\nera m:lib280c.lib\r\nlibr\r\n<r m:lib280c.lib\t\\\r\n<libcver.obj\t\\\r\n<start1.obj\t\\\r\n<getargs.obj\t\\\r\n<assert.obj\t\\\r\n<printf.obj\t\\\r\n<fprintf.obj\t\\\r\n<sprintf.obj\t\\\r\n<doprnt.obj\t\\\r\n<getenv.obj\t\\\r\n<gets.obj\t\\\r\n<puts.obj\t\\\r\n<fwrite.obj\t\\\r\n<getw.obj\t\\\r\n<putw.obj\t\\\r\n<close.obj\t\\\r\n<putchar.obj\t\\\r\n<perror.obj\t\\\r\n<fputc.obj\t\\\r\n<flsbuf.obj\t\\\r\n<fopen.obj\t\\\r\n<freopen.obj\t\\\r\n<fseek.obj\t\\\r\n<fread.obj\t\\\r\n<rewind.obj\t\\\r\n<remove.obj\t\\\r\n<setbuf.obj\t\\\r\n<fscanf.obj\t\\\r\n<ctime.obj\t\\\r\n<cgets.obj\t\\\r\n<cputs.obj\t\\\r\n<sscanf.obj\t\\\r\n<scanf.obj\t\\\r\n<doscan.obj\t\\\r\n<ungetc.obj\t\\\r\n<fgetc.obj\t\\\r\n<filbuf.obj\t\\\r\n<stdclean.obj\t\\\r\n<fclose.obj\t\\\r\n<fflush.obj\t\\\r\n<buf.obj\t\\\r\n<exit.obj\t\\\r\n<open.obj\t\\\r\n<read.obj\t\\\r\n<write.obj\t\\\r\n<seek.obj\t\\\r\n<stat.obj\t\\\r\n<chmod.obj\t\\\r\n<fcbname.obj\t\\\r\n<rename.obj\t\\\r\n<creat.obj\t\\\r\n<time.obj\t\\\r\n<convtime.obj\t\\\r\n<timezone.obj\t\\\r\n<mktime.obj\t\\\r\n<isatty.obj\t\\\r\n<cleanup.obj\t\\\r\n<close.obj\t\\\r\n<unlink.obj\t\\\r\n<dup.obj\t\\\r\n<execl.obj\t\\\r\n<getfcb.obj\t\\\r\n<srand1.obj\t\\\r\n<abort.obj\t\\\r\n<getch.obj\t\\\r\n<signal.obj\t\\\r\n<getuid.obj\t\\\r\n<bdos.obj\t\\\r\n<bios.obj\t\\\r\n<_exit.obj\t\\\r\n<fakeclean.obj\t\\\r\n<fakecpcln.obj\t\\\r\n<sys_err.obj\t\\\r\n<memcpy.obj\t\\\r\n<memcmp.obj\t\\\r\n<memset.obj\t\\\r\n<strftime.obj\t\\\r\n<asmod.obj\t\\\r\n<abs.obj\t\\\r\n<asallsh.obj\t\\\r\n<allsh.obj\t\\\r\n<asalrsh.obj\t\\\r\n<asar.obj\t\\\r\n<asdiv.obj\t\\\r\n<asladd.obj\t\\\r\n<asland.obj\t\\\r\n<asll.obj\t\\\r\n<asllrsh.obj\t\\\r\n<aslmul.obj\t\\\r\n<aslor.obj\t\\\r\n<aslsub.obj\t\\\r\n<aslxor.obj\t\\\r\n<atoi.obj\t\\\r\n<atol.obj\t\\\r\n<blkclr.obj\t\\\r\n<blkcpy.obj\t\\\r\n<calloc.obj\t\\\r\n<asmul.obj\t\\\r\n<bitfield.obj\t\\\r\n<ctype_.obj\t\\\r\n<getsp.obj\t\\\r\n<index.obj\t\\\r\n<strchr.obj\t\\\r\n<qsort.obj\t\\\r\n<malloc.obj\t\\\r\n<max.obj\t\\\r\n<idiv.obj\t\\\r\n<pnum.obj\t\\\r\n<ldiv.obj\t\\\r\n<swap.obj\t\\\r\n<aslr.obj\t\\\r\n<bmove.obj\t\\\r\n<imul.obj\t\\\r\n<rand.obj\t\\\r\n<alrsh.obj\t\\\r\n<lmul.obj\t\\\r\n<rindex.obj\t\\\r\n<strrchr.obj\t\\\r\n<sbrk.obj\t\\\r\n<shar.obj\t\\\r\n<shll.obj\t\\\r\n<shlr.obj\t\\\r\n<strcat.obj\t\\\r\n<strcmp.obj\t\\\r\n<strcpy.obj\t\\\r\n<strlen.obj\t\\\r\n<strncat.obj\t\\\r\n<strncmp.obj\t\\\r\n<strncpy.obj\t\\\r\n<strstr.obj\t\\\r\n<strnstr.obj\t\\\r\n<strdup.obj\t\\\r\n<stricmp.obj\t\\\r\n<stristr.obj\t\\\r\n<strnicmp.obj\t\\\r\n<strnistr.obj\t\\\r\n<strtok.obj\t\\\r\n<inout.obj\t\\\r\n<iregset.obj\t\\\r\n<isalpha.obj\t\\\r\n<isdigit.obj\t\\\r\n<islower.obj\t\\\r\n<isspace.obj\t\\\r\n<isupper.obj\t\\\r\n<ladd.obj\t\\\r\n<land.obj\t\\\r\n<linc.obj\t\\\r\n<llrsh.obj\t\\\r\n<longjmp.obj\t\\\r\n<lor.obj\t\\\r\n<brelop.obj\t\\\r\n<wrelop.obj\t\\\r\n<lrelop.obj\t\\\r\n<frelop.obj\t\\\r\n<lsub.obj\t\\\r\n<lxor.obj\t\\\r\n<csv.obj\t\\\r\n<rcsv.obj\t\\\r\n<tolower.obj\t\\\r\n<toupper.obj\t\\\r\n<xtoi.obj\r\nlibr s m:lib280c.lib\r\ne:\r\npip e:=m:lib280c.lib\r\n; Library m:lib280c.lib created\r\n; Remember to copy it to current directory and A0:\r\n;\r\n; Now save the Z280 object files in E:LIB280C.LBR\r\ndir m:*.obj[fu,length=65535]\r\nera e:lib280c.lbr\r\n; Enter the number of files from above DIR command when prompted\r\nnulu e:lib280c.lbr -a m:*.obj -x\r\n; Finally copy over the start-up modules\r\npip e:=m:z?280cpm.obj\r\n;\r\nput console to console\r\n"
  },
  {
    "path": "stdio/M280LIBV.SUB",
    "content": "era lib280ov.lib\r\nlibr \r\n<r lib280ov.lib \\\r\n<ovrload.obj ovrbgn.obj\r\n"
  },
  {
    "path": "stdio/MAKEFILE",
    "content": ".SUFFIXES:\t.c .obj .as\r\nBIN\t= /usr/hitech/bin\r\nLIB\t= ../../lib\r\nAR\t= $(BIN)/libr r\r\nC\t= $(BIN)/zc\r\nCFLAGS\t= -O -x\r\nLD\t= $(BIN)/link\r\nAS\t= $(BIN)/zas\r\nASFLAGS\t= -x\r\nENHUFF\t= $(BIN)/enhuff\r\n\r\n.c.obj:\r\n\t$(C) $(CFLAGS) -c $<\r\n.as.obj:\r\n\t$(AS) $(ASFLAGS) $<\r\n\r\nOBJS\t= getargs.obj assert.obj printf.obj fprintf.obj sprintf.obj doprnt.obj \\\r\n\t  gets.obj puts.obj fwrite.obj getw.obj putw.obj getenv.obj \\\r\n\t  putchar.obj perror.obj fputc.obj flsbuf.obj \\\r\n\t  fopen.obj freopen.obj fseek.obj fread.obj rewind.obj remove.obj \\\r\n\t  setbuf.obj fscanf.obj ctime.obj cgets.obj cputs.obj \\\r\n\t  sscanf.obj scanf.obj doscan.obj ungetc.obj \\\r\n\t  fgetc.obj filbuf.obj stdclean.obj fclose.obj fflush.obj \\\r\n\t  buf.obj exit.obj fakeclean.obj\r\n\r\nSRCS\t= fgetc.as fputc.as assert.c buf.c cgets.c stdclean.c \\\r\n\t  cputs.c ctime.c doprnt.c doscan.c exit.c fakeclean.c \\\r\n\t  fclose.c fflush.c filbuf.c flsbuf.c fopen.c fprintf.c \\\r\n\t  fread.c freopen.c fscanf.c fseek.c fwrite.c getargs.c \\\r\n\t  getenv.c gets.c getw.c perror.c printf.c putchar.c \\\r\n\t  puts.c putw.c remove.c rewind.c scanf.c setbuf.c \\\r\n\t  setup.c sprintf.c sscanf.c stdio.h stdio.i ungetc.c\r\n\r\nzlibstdio.lib:\t$(OBJS)\r\n\t$(AR) zlibstdio.lib $(OBJS)\r\n\r\ninstall:\t$(LIB)/zlibstdio.lib\r\n\r\n$(LIB)/zlibstdio.lib:\tzlibstdio.lib\r\n\tcp zlibstdio.lib $(LIB)/zlibstdio.lib\r\n\tchmod og+r $(LIB)/zlibstdio.lib\r\n\r\nfgetc.obj:\tfgetc.as\r\nclean:\r\n\t-rm -f zlibstdio.lib *.obj\r\n\r\nhuff:\r\n\t-rm -f stdio.huf\r\n\t$(ENHUFF) -a stdio.huf Makefile $(SRCS)\r\n\r\nprint:\r\n\tprint Makefile *.h *.c *.i *.as\r\n"
  },
  {
    "path": "stdio/MAKELIBC.LOG",
    "content": "\r\n10E>; Use librarian to place all modules in LIBC20.LIB\r\n10E>; NB: the ordering is important for resolving dependencies at link time\r\n10E>era LIBC20.lib\r\n10E>libr\r\nA:LIBR     COM  (User 0)\r\nlibr> r LIBC20.lib\t\\\r\nlibr> libcver.obj\t\\\r\nlibr> start1.obj\t\\\r\nlibr> getargs.obj\t\\\r\nlibr> assert.obj\t\\\r\nlibr> printf.obj\t\\\r\nlibr> fprintf.obj\t\\\r\nlibr> sprintf.obj\t\\\r\nlibr> doprnt.obj\t\\\r\nlibr> getenv.obj\t\\\r\nlibr> gets.obj\t\\\r\nlibr> puts.obj\t\\\r\nlibr> fwrite.obj\t\\\r\nlibr> getw.obj\t\\\r\nlibr> putw.obj\t\\\r\nlibr> putchar.obj\t\\\r\nlibr> perror.obj\t\\\r\nlibr> fputc.obj\t\\\r\nlibr> flsbuf.obj\t\\\r\nlibr> fopen.obj\t\\\r\nlibr> freopen.obj\t\\\r\nlibr> fseek.obj\t\\\r\nlibr> fread.obj\t\\\r\nlibr> rewind.obj\t\\\r\nlibr> remove.obj\t\\\r\nlibr> setbuf.obj\t\\\r\nlibr> fscanf.obj\t\\\r\nlibr> ctime.obj\t\\\r\nlibr> cgets.obj\t\\\r\nlibr> cputs.obj\t\\\r\nlibr> sscanf.obj\t\\\r\nlibr> scanf.obj\t\\\r\nlibr> doscan.obj\t\\\r\nlibr> ungetc.obj\t\\\r\nlibr> fgetc.obj\t\\\r\nlibr> filbuf.obj\t\\\r\nlibr> stdclean.obj\t\\\r\nlibr> fclose.obj\t\\\r\nlibr> fflush.obj\t\\\r\nlibr> buf.obj \t\\\r\nlibr> exit.obj\t\\\r\nlibr> open.obj \t\\\r\nlibr> read.obj \t\\\r\nlibr> write.obj\t\\\r\nlibr> seek.obj \t\\\r\nlibr> stat.obj \t\\\r\nlibr> chmod.obj\t\\\r\nlibr> fcbname.obj\t\\\r\nlibr> rename.obj\t\\\r\nlibr> creat.obj\t\\\r\nlibr> time.obj \t\\\r\nlibr> convtime.obj\t\\\r\nlibr> timezone.obj\t\\\r\nlibr> mktime.obj\t\\\r\nlibr> isatty.obj\t\\\r\nlibr> cleanup.obj\t\\\r\nlibr> close.obj\t\\\r\nlibr> unlink.obj\t\\\r\nlibr> dup.obj  \t\\\r\nlibr> execl.obj\t\\\r\nlibr> getfcb.obj\t\\\r\nlibr> srand1.obj\t\\\r\nlibr> abort.obj\t\\\r\nlibr> getch.obj\t\\\r\nlibr> signal.obj\t\\\r\nlibr> getuid.obj\t\\\r\nlibr> bdos.obj \t\\\r\nlibr> bios.obj \t\\\r\nlibr> _exit.obj\t\\\r\nlibr> fakeclean.obj\t\\\r\nlibr> fakecpcln.obj\t\\\r\nlibr> sys_err.obj\t\\\r\nlibr> memcpy.obj\t\\\r\nlibr> memcmp.obj\t\\\r\nlibr> memset.obj\t\\\r\nlibr> strftime.obj\t\\\r\nlibr> asmod.obj\t\\\r\nlibr> abs.obj  \t\\\r\nlibr> asallsh.obj\t\\\r\nlibr> allsh.obj\t\\\r\nlibr> asalrsh.obj\t\\\r\nlibr> asar.obj \t\\\r\nlibr> asdiv.obj\t\\\r\nlibr> asladd.obj\t\\\r\nlibr> asland.obj\t\\\r\nlibr> asll.obj \t\\\r\nlibr> asllrsh.obj\t\\\r\nlibr> aslmul.obj\t\\\r\nlibr> aslor.obj\t\\\r\nlibr> aslsub.obj\t\\\r\nlibr> aslxor.obj\t\\\r\nlibr> atoi.obj \t\\\r\nlibr> atol.obj \t\\\r\nlibr> blkclr.obj\t\\\r\nlibr> blkcpy.obj\t\\\r\nlibr> calloc.obj\t\\\r\nlibr> asmul.obj\t\\\r\nlibr> bitfield.obj\t\\\r\nlibr> ctype_.obj\t\\\r\nlibr> getsp.obj\t\\\r\nlibr> index.obj\t\\\r\nlibr> strchr.obj\t\\\r\nlibr> qsort.obj\t\\\r\nlibr> malloc.obj\t\\\r\nlibr> max.obj  \t\\\r\nlibr> idiv.obj \t\\\r\nlibr> pnum.obj \t\\\r\nlibr> ldiv.obj \t\\\r\nlibr> swap.obj \t\\\r\nlibr> aslr.obj \t\\\r\nlibr> bmove.obj\t\\\r\nlibr> imul.obj \t\\\r\nlibr> rand.obj \t\\\r\nlibr> alrsh.obj\t\\\r\nlibr> lmul.obj \t\\\r\nlibr> rindex.obj\t\\\r\nlibr> strrchr.obj\t\\\r\nlibr> sbrk.obj \t\\\r\nlibr> shar.obj \t\\\r\nlibr> shll.obj \t\\\r\nlibr> shlr.obj \t\\\r\nlibr> strcat.obj\t\\\r\nlibr> strcmp.obj\t\\\r\nlibr> strcpy.obj\t\\\r\nlibr> strlen.obj\t\\\r\nlibr> strncat.obj\t\\\r\nlibr> strncmp.obj\t\\\r\nlibr> strncpy.obj\t\\\r\nlibr> strstr.obj\t\\\r\nlibr> strnstr.obj\t\\\r\nlibr> strdup.obj\t\\\r\nlibr> stricmp.obj\t\\\r\nlibr> stristr.obj\t\\\r\nlibr> strnicmp.obj\t\\\r\nlibr> strnistr.obj\t\\\r\nlibr> strtok.obj\t\\\r\nlibr> inout.obj\t\\\r\nlibr> iregset.obj\t\\\r\nlibr> isalpha.obj\t\\\r\nlibr> isdigit.obj\t\\\r\nlibr> islower.obj\t\\\r\nlibr> isspace.obj\t\\\r\nlibr> isupper.obj\t\\\r\nlibr> ladd.obj \t\\\r\nlibr> land.obj \t\\\r\nlibr> linc.obj \t\\\r\nlibr> llrsh.obj\t\\\r\nlibr> longjmp.obj\t\\\r\nlibr> lor.obj  \t\\\r\nlibr> brelop.obj\t\\\r\nlibr> wrelop.obj\t\\\r\nlibr> lrelop.obj\t\\\r\nlibr> frelop.obj\t\\\r\nlibr> lsub.obj \t\\\r\nlibr> lxor.obj \t\\\r\nlibr> csv.obj  \t\\\r\nlibr> rcsv.obj \t\\\r\nlibr> tolower.obj\t\\\r\nlibr> toupper.obj\t\\\r\nlibr> xtoi.obj\r\n\r\n10E>; Library LIBC20.LIB created\r\n10E>libr s LIBC20.lib\r\nA:LIBR     COM  (User 0)\r\nlibcver.obj     D __libcver     \r\nstart1.obj      D __argc_       U __getargs     D startup       \r\ngetargs.obj     U __argc_       D __getargs     U __iob         U _bdos       \r\n\t\tU _bmove        U _exit         U _fprintf      U _freopen    \r\n\t\tU _gets         U _getuid       U _isatty       U _sbrk       \r\n\t\tU _setfcb       U _setuid       U _signal       U _sprintf    \r\n\t\tU _strchr       U _strcpy       U _strlen       U adiv        \r\n\t\tU cret          U csv           U indir         U ncsv        \r\n\t\tU shal          U wrelop        \r\nassert.obj      D __fassert     U __iob         U _abort        U _fprintf    \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nprintf.obj      U __doprnt      U __iob         D _printf       U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfprintf.obj     U __doprnt      D _fprintf      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsprintf.obj     U __doprnt      D _sprintf      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\ndoprnt.obj      U __ctype_      D __doprnt      U __pnum        U _atoi       \r\n\t\tU _fputc        U _strlen       U brelop        U cret        \r\n\t\tU csv           U indir         U ncsv          U wrelop      \r\ngetenv.obj      U _bdos         D _environ      U _fclose       U _fgets      \r\n\t\tU _fopen        D _getenv       U _memcpy       U _sbrk       \r\n\t\tU _strcpy       U _strlen       U _strncmp      U cret        \r\n\t\tU csv           U indir         U ncsv          U wrelop      \r\ngets.obj        U __iob         U _fgetc        D _fgets        D _gets       \r\n\t\tU _strlen       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nputs.obj        U __iob         U _fputc        D _fputs        D _puts       \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfwrite.obj      U _fflush       U _fputc        U _fseek        D _fwrite     \r\n\t\tU _memcpy       U cret          U indir         U ldiv        \r\n\t\tU lmul          U ncsv          U wrelop        \r\ngetw.obj        U _fgetc        D _getw         U cret          U csv         \r\n\t\tU indir         U ncsv          U shal          \r\nputw.obj        U _fputc        D _putw         U cret          U csv         \r\n\t\tU indir         U ncsv          U shar          \r\nputchar.obj     U __iob         U _fgetc        U _fputc        D _getchar    \r\n\t\tD _putchar      U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nperror.obj      U __iob         U _errno        U _fputc        D _perror     \r\n\t\tU _sys_err      U _sys_ner      U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\nfputc.obj       U __flsbuf      U _fflush       D _fputc        U _fseek      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nflsbuf.obj      U __bufallo     D __flsbuf      U _isatty       U _write      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfopen.obj       U __iob         D _fopen        U _freopen      U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfreopen.obj     U __bufallo     U _close        U _creat        U _fclose     \r\n\t\tD _freopen      U _fseek        U _open         U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfseek.obj       U __fcb         U _fflush       U _fread        D _fseek      \r\n\t\tD _ftell        U _lseek        U aladd         U alsub       \r\n\t\tU amul          U arelop        U asaladd       U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nfread.obj       U _fgetc        D _fread        U _memcpy       U cret        \r\n\t\tU indir         U ldiv          U lmul          U ncsv        \r\n\t\tU wrelop        \r\nrewind.obj      U _fseek        D _rewind       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nremove.obj      D _remove       U _unlink       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsetbuf.obj      U __bufallo     U __buffree     D _setbuf       D _setvbuf    \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfscanf.obj      U __doscan      D _fscanf       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nctime.obj       D _asctime      D _ctime        D _gmtime       D _localtime  \r\n\t\tD _monlen       U _time_zone    U adiv          U aldiv       \r\n\t\tU almod         U almul         U alsub         U amod        \r\n\t\tU amul          U asaldiv       U asldiv        U cret        \r\n\t\tU csv           U indir         U lmod          U ncsv        \r\n\t\tU wrelop        \r\ncgets.obj       D _cgets        U _getche       U cret          U csv         \r\n\t\tU indir         U ncsv          \r\ncputs.obj       D _cputs        U _putch        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsscanf.obj      U __doscan      D _sscanf       U _strlen       U cret        \r\n\t\tU indir         U ncsv          \r\nscanf.obj       U __doscan      U __iob         D _scanf        U cret        \r\n\t\tU csv           U indir         U ncsv          \r\ndoscan.obj      U __ctype_      D __doscan      U _atoi         U _fgetc      \r\n\t\tU _tolower      U _ungetc       U cret          U csv         \r\n\t\tU indir         U lladd         U llmul         U ncsv        \r\n\t\tU wrelop        \r\nungetc.obj      D _ungetc       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nfgetc.obj       U __filbuf      D _fgetc        U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\nfilbuf.obj      D __filbuf      U __iob         U _fflush       U _read       \r\n\t\tU cret          U csv           U indir         U ncsv        \r\n\t\tU wrelop        \r\nstdclean.obj    D __cleanup     D __iob         D __sibuf       U _fclose     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfclose.obj      U __buffree     U _close        D _fclose       U _fflush     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nfflush.obj      D _fflush       U _write        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nbuf.obj         D __bufallo     D __buffree     U _sbrk         U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nexit.obj        U __cleanup     U __exit        D _exit         U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nopen.obj        U __exact       U __fcb         D __fsize       U _bdos       \r\n\t\tU _errno        U _getfcb       U _getuid       D _open       \r\n\t\tU _putfcb       U _setfcb       U _setuid       U adiv        \r\n\t\tU aland         U aldiv         U amul          U asalsub     \r\n\t\tU brelop        U cret          U csv           U indir       \r\n\t\tU ncsv          U shll          U wrelop        \r\nread.obj        U __fcb         U __piped       U __putrno      U __sigchk    \r\n\t\tU _bdos         U _bmove        U _getuid       D _read       \r\n\t\tU _setuid       U aldiv         U alsub         U amul        \r\n\t\tU asaladd       U brelop        U cret          U indir       \r\n\t\tU lladd         U lrelop        U ncsv          U wrelop      \r\nwrite.obj       U __fcb         U __piped       U __putrno      U __sigchk    \r\n\t\tU _bdos         U _bmove        U _getuid       U _setuid     \r\n\t\tD _write        U aldiv         U amul          U arelop      \r\n\t\tU asaladd       U brelop        U cret          U indir       \r\n\t\tU ncsv          U wrelop        \r\nseek.obj        U __fcb         D _lseek        U aladd         U amul        \r\n\t\tU arelop        U brelop        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nstat.obj        U __exact       U _bdos         U _convtime     U _getuid     \r\n\t\tU _setfcb       U _setuid       D _stat         U asallsh     \r\n\t\tU asalsub       U cret          U indir         U lladd       \r\n\t\tU lllsh         U ncsv          U shal          U wrelop      \r\nchmod.obj       U _bdos         D _chmod        U _getuid       U _setfcb     \r\n\t\tU _setuid       U cret          U indir         U ncsv        \r\nfcbname.obj     U __fcb         U _bdos         D _fcbname      U _sprintf    \r\n\t\tU _strlen       U amul          U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\nrename.obj      U _bdos         D _rename       U _setfcb       U _unlink     \r\n\t\tU cret          U indir         U ncsv          \r\ncreat.obj       U __fcb         U _bdos         D _creat        U _errno      \r\n\t\tU _getfcb       U _getuid       U _setfcb       U _setuid     \r\n\t\tU _unlink       U adiv          U cret          U csv         \r\n\t\tU indir         U ncsv          U wrelop        \r\ntime.obj        U _bdos         U _convtime     D _time         U cret        \r\n\t\tU indir         U ncsv          \r\nconvtime.obj    D _convtime     D _frmbcd       U asaladd       U asalmul     \r\n\t\tU cret          U csv           U indir         U lmul        \r\n\t\tU ncsv          \r\ntimezone.obj    D _time_zone    \r\nmktime.obj      D _mktime       U _time_zone    U almul         U amod        \r\n\t\tU asaladd       U cret          U indir         U ncsv        \r\n\t\tU wrelop        \r\nisatty.obj      U __fcb         D _isatty       U amul          U cret        \r\n\t\tU csv           U indir         U ncsv          \r\ncleanup.obj     D __cpm_clean   D __fcb         D __initrsx     D __putrno    \r\n\t\tU _close        U alrsh         U brelop        U cret        \r\n\t\tU csv           U indir         U ncsv          \r\nclose.obj       U __exact       U __fcb         U _bdos         D _close      \r\n\t\tU _getuid       U _setuid       U amul          U brelop      \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nunlink.obj      U _bdos         U _errno        U _getuid       U _setfcb     \r\n\t\tU _setuid       D _unlink       U cret          U indir       \r\n\t\tU ncsv          \r\ndup.obj         U __fcb         D _dup          U _getfcb       U adiv        \r\n\t\tU amul          U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nexecl.obj       U _bmove        D _execl        D _execv        U _setfcb     \r\n\t\tU _strcat       U _strlen       U _strncpy      U indir       \r\ngetfcb.obj      U __ctype_      U __fcb         U _atoi         D _getfcb     \r\n\t\tU _getuid       D _putfcb       D _setfcb       U _toupper    \r\n\t\tU brelop        U cret          U csv           U indir       \r\n\t\tU ncsv          U wrelop        \r\nsrand1.obj      U _kbhit        U _putchar      U _srand        D _srand1     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nabort.obj       D _abort        U _bdos         U _exit         U cret        \r\n\t\tU indir         U ncsv          \r\ngetch.obj       U _bdos         D _getch        D _getche       D _kbhit      \r\n\t\tD _putch        D _ungetch      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nsignal.obj      D __sigchk      U _bdos         U _exit         D _signal     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\ngetuid.obj      D _getuid       D _setuid       U cret          U csv         \r\nbdos.obj        D _bdos         U _errno        U cret          U csv         \r\nbios.obj        D _bios         U cret          U csv           D exit22      \r\n_exit.obj       U __cpm_clean   D __exit        \r\nfakeclean.obj   D __cleanup     U cret          U indir         U ncsv        \r\nfakecpcln.obj   D __cpm_clean   \r\nsys_err.obj     D _errno        D _sys_err      D _sys_ner      \r\nmemcpy.obj      D _memcpy       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nmemcmp.obj      D _memcmp       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nmemset.obj      D _memset       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nstrftime.obj    D _strftime     U adiv          U amod          U asamod      \r\n\t\tU cret          U indir         U ncsv          U wrelop      \r\nasmod.obj       U amod          D asamod        D aslmod        U lmod        \r\nabs.obj         D _abs          \r\nasallsh.obj     U allsh         D asallsh       D aslllsh       U iregstore   \r\nallsh.obj       D allsh         D lllsh         \r\nasalrsh.obj     U alrsh         D asalrsh       U iregstore     \r\nasar.obj        D asar          U shar          \r\nasdiv.obj       U adiv          D asadiv        D asldiv        U ldiv        \r\nasladd.obj      U aladd         D asaladd       D aslladd       U iregset     \r\n\t\tU iregstore     \r\nasland.obj      U aland         D asaland       D aslland       U iregset     \r\n\t\tU iregstore     \r\nasll.obj        D asal          D asll          U shal          \r\nasllrsh.obj     D asllrsh       U iregstore     U llrsh         \r\naslmul.obj      U almul         D asalmul       D asllmul       U iregset     \r\n\t\tU iregstore     \r\naslor.obj       U alor          D asalor        D asllor        U iregset     \r\n\t\tU iregstore     \r\naslsub.obj      U alsub         D asalsub       D asllsub       U iregset     \r\n\t\tU iregstore     \r\naslxor.obj      U alxor         D asalxor       D asllxor       U iregset     \r\n\t\tU iregstore     \r\natoi.obj        D _atoi         \r\natol.obj        U __ctype_      D _atol         U aladd         U almul       \r\n\t\tU cret          U indir         U ncsv          \r\nblkclr.obj      D _blkclr       \r\nblkcpy.obj      D _blkcpy       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\ncalloc.obj      U _bmove        D _calloc       D _cfree        U _free       \r\n\t\tU _malloc       U asamul        U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nasmul.obj       U amul          D asamul        D aslmul        \r\nbitfield.obj    D bfext         D bfins         \r\nctype_.obj      D __ctype_      \r\ngetsp.obj       D __getsp       \r\nindex.obj       D _index        U cret          U rcsv          \r\nstrchr.obj      D _strchr       U cret          U rcsv          \r\nqsort.obj       U __swap        U _bmove        U _free         U _malloc     \r\n\t\tD _qsort        U adiv          U cret          U indir       \r\n\t\tU lmul          U ncsv          U wrelop        \r\nmalloc.obj      U _bmove        D _free         D _malloc       D _realloc    \r\n\t\tU _sbrk         U adiv          U amul          U cret        \r\n\t\tU csv           U indir         U ldiv          U lmul        \r\n\t\tU ncsv          U wrelop        \r\nmax.obj         D _max          \r\nidiv.obj        D adiv          D amod          D ldiv          D lmod        \r\npnum.obj        D __pnum        U aslldiv       U brelop        U cret        \r\n\t\tU indir         U llmod         U ncsv          U wrelop      \r\nldiv.obj        D aldiv         D almod         D asaldiv       D asalmod     \r\n\t\tD aslldiv       D asllmod       D lldiv         D llmod       \r\nswap.obj        D __swap        U cret          U rcsv          \r\naslr.obj        D aslr          U shlr          \r\nbmove.obj       D _bmove        D _movmem       \r\nimul.obj        D amul          D lmul          \r\nrand.obj        D _rand         D _srand        U almul         U alrsh       \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nalrsh.obj       D alrsh         \r\nlmul.obj        D almul         D llmul         \r\nrindex.obj      D _rindex       U cret          U rcsv          \r\nstrrchr.obj     D _strrchr      U cret          U rcsv          \r\nsbrk.obj        U __Hbss        D _brk          D _checksp      D _sbrk       \r\nshar.obj        D shar          \r\nshll.obj        D shal          D shll          \r\nshlr.obj        D shlr          \r\nstrcat.obj      D _strcat       \r\nstrcmp.obj      D _strcmp       \r\nstrcpy.obj      D _strcpy       \r\nstrlen.obj      D _strlen       \r\nstrncat.obj     D _strncat      U cret          U rcsv          \r\nstrncmp.obj     D _strncmp      U cret          U rcsv          \r\nstrncpy.obj     D _strncpy      U cret          U rcsv          \r\nstrstr.obj      D _strstr       U cret          U csv           U indir       \r\n\t\tU ncsv          \r\nstrnstr.obj     D _strnstr      U cret          U indir         U ncsv        \r\nstrdup.obj      U _malloc       U _strcpy       D _strdup       U _strlen     \r\n\t\tU cret          U csv           U indir         U ncsv        \r\nstricmp.obj     D _strcasecmp   \r\nstristr.obj     D _strcasestr   U _toupper      U cret          U csv         \r\n\t\tU indir         U ncsv          \r\nstrnicmp.obj    D _strncasecmp  U cret          U rcsv          \r\nstrnistr.obj    D _strncasestr  U _toupper      U cret          U indir       \r\n\t\tU ncsv          \r\nstrtok.obj      D _strtok       U cret          U csv           U indir       \r\n\t\tU ncsv          U wrelop        \r\ninout.obj       D _in           D _inp          D _out          D _outp       \r\niregset.obj     D iregset       D iregstore     \r\nisalpha.obj     D _isalpha      \r\nisdigit.obj     D _isdig        D _isdigit      \r\nislower.obj     D _islower      \r\nisspace.obj     D _isspace      \r\nisupper.obj     D _isupper      \r\nladd.obj        D aladd         D lladd         \r\nland.obj        D aland         D lland         \r\nlinc.obj        D ladec         D lainc         D lldec         D llinc       \r\nllrsh.obj       D llrsh         \r\nlongjmp.obj     D _longjmp      D _setjmp       \r\nlor.obj         D alor          D llor          \r\nbrelop.obj      D brelop        \r\nwrelop.obj      D wrelop        \r\nlrelop.obj      D arelop        D lrelop        \r\nfrelop.obj      D frelop        \r\nlsub.obj        D alsub         D llsub         \r\nlxor.obj        D alxor         D llxor         \r\ncsv.obj         D cret          D csv           D indir         D ncsv        \r\nrcsv.obj        D rcsv          \r\ntolower.obj     D _tolower      \r\ntoupper.obj     D _toupper      \r\nxtoi.obj        D _ishex        D _xtoi         \r\n\r\n10E>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "stdio/MAKELIBC.SUB",
    "content": "era makelibc.log\r\nput console output to file makelibc.log [system]\r\n; Use librarian to place all modules in LIBC20.LIB\r\n; NB: the ordering is important for resolving dependencies at link time\r\nera LIBC20.lib\r\nlibr\r\n<r LIBC20.lib\t\\\r\n<libcver.obj\t\\\r\n<start1.obj\t\\\r\n<getargs.obj\t\\\r\n<assert.obj\t\\\r\n<printf.obj\t\\\r\n<fprintf.obj\t\\\r\n<sprintf.obj\t\\\r\n<doprnt.obj\t\\\r\n<getenv.obj\t\\\r\n<gets.obj\t\\\r\n<puts.obj\t\\\r\n<fwrite.obj\t\\\r\n<getw.obj\t\\\r\n<putw.obj\t\\\r\n<putchar.obj\t\\\r\n<perror.obj\t\\\r\n<fputc.obj\t\\\r\n<flsbuf.obj\t\\\r\n<fopen.obj\t\\\r\n<freopen.obj\t\\\r\n<fseek.obj\t\\\r\n<fread.obj\t\\\r\n<rewind.obj\t\\\r\n<remove.obj\t\\\r\n<setbuf.obj\t\\\r\n<fscanf.obj\t\\\r\n<ctime.obj\t\\\r\n<cgets.obj\t\\\r\n<cputs.obj\t\\\r\n<sscanf.obj\t\\\r\n<scanf.obj\t\\\r\n<doscan.obj\t\\\r\n<ungetc.obj\t\\\r\n<fgetc.obj\t\\\r\n<filbuf.obj\t\\\r\n<stdclean.obj\t\\\r\n<fclose.obj\t\\\r\n<fflush.obj\t\\\r\n<buf.obj \t\\\r\n<exit.obj\t\\\r\n<open.obj \t\\\r\n<read.obj \t\\\r\n<write.obj\t\\\r\n<seek.obj \t\\\r\n<stat.obj \t\\\r\n<chmod.obj\t\\\r\n<fcbname.obj\t\\\r\n<rename.obj\t\\\r\n<creat.obj\t\\\r\n<time.obj \t\\\r\n<convtime.obj\t\\\r\n<timezone.obj\t\\\r\n<mktime.obj\t\\\r\n<isatty.obj\t\\\r\n<cleanup.obj\t\\\r\n<close.obj\t\\\r\n<unlink.obj\t\\\r\n<dup.obj  \t\\\r\n<execl.obj\t\\\r\n<getfcb.obj\t\\\r\n<srand1.obj\t\\\r\n<abort.obj\t\\\r\n<getch.obj\t\\\r\n<signal.obj\t\\\r\n<getuid.obj\t\\\r\n<bdos.obj \t\\\r\n<bios.obj \t\\\r\n<_exit.obj\t\\\r\n<fakeclean.obj\t\\\r\n<fakecpcln.obj\t\\\r\n<sys_err.obj\t\\\r\n<memcpy.obj\t\\\r\n<memcmp.obj\t\\\r\n<memset.obj\t\\\r\n<strftime.obj\t\\\r\n<asmod.obj\t\\\r\n<abs.obj  \t\\\r\n<asallsh.obj\t\\\r\n<allsh.obj\t\\\r\n<asalrsh.obj\t\\\r\n<asar.obj \t\\\r\n<asdiv.obj\t\\\r\n<asladd.obj\t\\\r\n<asland.obj\t\\\r\n<asll.obj \t\\\r\n<asllrsh.obj\t\\\r\n<aslmul.obj\t\\\r\n<aslor.obj\t\\\r\n<aslsub.obj\t\\\r\n<aslxor.obj\t\\\r\n<atoi.obj \t\\\r\n<atol.obj \t\\\r\n<blkclr.obj\t\\\r\n<blkcpy.obj\t\\\r\n<calloc.obj\t\\\r\n<asmul.obj\t\\\r\n<bitfield.obj\t\\\r\n<ctype_.obj\t\\\r\n<getsp.obj\t\\\r\n<index.obj\t\\\r\n<strchr.obj\t\\\r\n<qsort.obj\t\\\r\n<malloc.obj\t\\\r\n<max.obj  \t\\\r\n<idiv.obj \t\\\r\n<pnum.obj \t\\\r\n<ldiv.obj \t\\\r\n<swap.obj \t\\\r\n<aslr.obj \t\\\r\n<bmove.obj\t\\\r\n<imul.obj \t\\\r\n<rand.obj \t\\\r\n<alrsh.obj\t\\\r\n<lmul.obj \t\\\r\n<rindex.obj\t\\\r\n<strrchr.obj\t\\\r\n<sbrk.obj \t\\\r\n<shar.obj \t\\\r\n<shll.obj \t\\\r\n<shlr.obj \t\\\r\n<strcat.obj\t\\\r\n<strcmp.obj\t\\\r\n<strcpy.obj\t\\\r\n<strlen.obj\t\\\r\n<strncat.obj\t\\\r\n<strncmp.obj\t\\\r\n<strncpy.obj\t\\\r\n<strstr.obj\t\\\r\n<strnstr.obj\t\\\r\n<strdup.obj\t\\\r\n<stricmp.obj\t\\\r\n<stristr.obj\t\\\r\n<strnicmp.obj\t\\\r\n<strnistr.obj\t\\\r\n<strtok.obj\t\\\r\n<inout.obj\t\\\r\n<iregset.obj\t\\\r\n<isalpha.obj\t\\\r\n<isdigit.obj\t\\\r\n<islower.obj\t\\\r\n<isspace.obj\t\\\r\n<isupper.obj\t\\\r\n<ladd.obj \t\\\r\n<land.obj \t\\\r\n<linc.obj \t\\\r\n<llrsh.obj\t\\\r\n<longjmp.obj\t\\\r\n<lor.obj  \t\\\r\n<brelop.obj\t\\\r\n<wrelop.obj\t\\\r\n<lrelop.obj\t\\\r\n<frelop.obj\t\\\r\n<lsub.obj \t\\\r\n<lxor.obj \t\\\r\n<csv.obj  \t\\\r\n<rcsv.obj \t\\\r\n<tolower.obj\t\\\r\n<toupper.obj\t\\\r\n<xtoi.obj\r\n; Library LIBC20.LIB created\r\nlibr s LIBC20.lib\r\nput console to console\r\n"
  },
  {
    "path": "stdio/PERROR.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern\tint\terrno;\r\nextern\tchar *\tsys_err[];\r\nextern\tint\tsys_ner;\r\n\r\nstatic void ps(char *s)\r\n{\r\n    while(*s)\r\n        putc(*s++, stderr);\r\n}\r\n\r\nvoid perror(char *s)\r\n{\r\n    ps(s);\r\n    putc(':', stderr);\r\n    if (errno < sys_ner)\r\n        ps(sys_err[errno]);\r\n    else\r\n        ps(\"Unknown error\");\r\n    putc('\\n', stderr);\r\n}\r\n"
  },
  {
    "path": "stdio/PRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nextern int\t_doprnt();\r\n\r\nprintf(f, a)\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\treturn(_doprnt(stdout, f, &a));\r\n}\r\n"
  },
  {
    "path": "stdio/PUTCHAR.C",
    "content": "/*\r\n *\tFake routines for getchar and putchar\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\n#undef\tgetchar\r\n#undef\tputchar\r\ngetchar()\r\n{\r\n\treturn(getc(stdin));\r\n}\r\n\r\nputchar(c)\r\n{\r\n\treturn(putc(c, stdout));\r\n}\r\n"
  },
  {
    "path": "stdio/PUTS.C",
    "content": "/*\r\n *\tputs and fputs for HI-TECH C stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nfputs(s, f)\r\nchar *\t\ts;\r\nregister FILE *\tf;\r\n{\r\n\twhile(*s)\r\n\t\tif(putc(*s++, f) == EOF)\r\n\t\t\treturn EOF;\r\n\treturn 0;\r\n}\r\n\r\nputs(s)\r\nchar *\t\ts;\r\n{\r\n\tregister int\ti;\r\n\r\n\ti = fputs(s, stdout);\r\n\tputchar('\\n');\r\n\treturn i;\r\n}\r\n"
  },
  {
    "path": "stdio/PUTW.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tputw for Zios\r\n */\r\n\r\nputw(w, stream)\r\nregister FILE *\tstream;\r\n{\r\n\tif(putc(w&0xFF, stream) == EOF || putc((w >> 8)&0xFF, stream) == EOF)\r\n\t\treturn(EOF);\r\n\treturn(w);\r\n}\r\n"
  },
  {
    "path": "stdio/RELIBCPM.SUB",
    "content": "libr \r\n<r libc3.lib \\\r\n<start1.obj open.obj read.obj write.obj chmod.obj seek.obj \\\r\n<fcbname.obj rename.obj creat.obj time.obj convtime.obj timezone.obj \\\r\n<stat.obj isatty.obj cleanup.obj close.obj unlink.obj dup.obj getfcb.obj \\\r\n<srand1.obj getch.obj signal.obj getuid.obj <abort.obj execl.obj bdos.obj \\\r\n<bios.obj _exit.obj exit.obj fakeclean.obj fakecpcln.obj sys_err.obj\r\n"
  },
  {
    "path": "stdio/RELIBGEN.SUB",
    "content": "libr\r\n<r libc3.lib \\\r\n<abs.obj allsh.obj alrsh.obj asallsh.obj asalrsh.obj asar.obj \\\r\n<asdiv.obj asladd.obj asland.obj asll.obj asllrsh.obj \\\r\n<aslmul.obj aslor.obj aslr.obj aslsub.obj aslxor.obj \\\r\n<asmod.obj asmul.obj atoi.obj atol.obj bitfield.obj \\\r\n<blkclr.obj blkcpy.obj bmove.obj brelop.obj calloc.obj csv.obj \\\r\n<ctype.obj ctype_.obj frelop.obj getsp.obj idiv.obj imul.obj \\\r\n<index.obj inout.obj iregset.obj isalpha.obj isdigit.obj \\\r\n<islower.obj isspace.obj isupper.obj ladd.obj land.obj ldiv.obj \\\r\n<linc.obj llrsh.obj lmul.obj longjmp.obj lor.obj lrelop.obj \\\r\n<lsub.obj lxor.obj malloc.obj max.obj memcmp.obj <memcpy.obj \\\r\n<memset.obj pnum.obj qsort.obj rand.obj rcsv.obj \\\r\n<rindex.obj sbrk.obj shar.obj shll.obj shlr.obj strcat.obj \\\r\n<strchr.obj strcmp.obj strcpy.obj strlen.obj strncat.obj \\\r\n<strncmp.obj strncpy.obj strrchr.obj swap.obj tolower.obj \\\r\n<toupper.obj wrelop.obj xtoi.obj"
  },
  {
    "path": "stdio/RELIBSTD.SUB",
    "content": "libr \r\n<r libc3.lib \\\r\n<getargs.obj getenv.obj assert.obj printf.obj fprintf.obj sprintf.obj \\\r\n<doprnt.obj gets.obj puts.obj fwrite.obj getw.obj putw.obj \\\r\n<putchar.obj perror.obj fputc.obj flsbuf.obj \\\r\n<fopen.obj freopen.obj fseek.obj fread.obj rewind.obj remove.obj \\\r\n<setbuf.obj fscanf.obj ctime.obj cgets.obj cputs.obj \\\r\n<sscanf.obj scanf.obj doscan.obj ungetc.obj \\\r\n<fgetc.obj filbuf.obj stdclean.obj fclose.obj fflush.obj \\\r\n<buf.obj exit.obj fakeclean.obj"
  },
  {
    "path": "stdio/REMOVE.C",
    "content": "#include\t<unixio.h>\r\n\r\nremove(s)\r\nchar *\ts;\r\n{\r\n\treturn unlink(s);\r\n}\r\n"
  },
  {
    "path": "stdio/REWIND.C",
    "content": "#include\t<stdio.h>\r\n\r\nrewind(stream)\r\nFILE *\tstream;\r\n{\r\n\tfseek(stream, 0L, SEEK_SET);\r\n}\r\n"
  },
  {
    "path": "stdio/SCANF.C",
    "content": "/*\r\n *\tStdio scanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nextern int\t_doscan();\r\n\r\nscanf(fmt, args)\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\treturn _doscan(stdin, fmt, &args);\r\n}\r\n"
  },
  {
    "path": "stdio/SETBUF.C",
    "content": "/*\r\n *\tSetbuf for HI-TECH C stdio\r\n */\r\n\r\n#include\t<stdio.h>\r\n\r\nvoid setbuf(f, c)\r\nregister FILE *\tf;\r\nchar *\t\tc;\r\n{\r\n\tif(c)\r\n\t\tsetvbuf(f, c, _IOFBF, BUFSIZ);\r\n\telse\r\n\t\tsetvbuf(f, c, _IONBF, 0);\r\n}\r\n\r\nsetvbuf(register FILE * stream, register char * buf, int mode, size_t size)\r\n{\r\n\tswitch(mode) {\r\n\tcase _IONBF:\t/* Not buffered */\r\n\t\tif(!(stream->_flag & _IOMYBUF) && stream->_base)\r\n\t\t\t_buffree(stream->_base);\r\n\t\tstream->_base = stream->_ptr = 0;\r\n\t\tstream->_flag &= ~(_IOMYBUF|_IOLBF);\r\n\t\tstream->_flag |= _IONBF;\r\n\t\tbreak;\r\n\r\n\tcase _IOLBF:\t/* Line buffered or */\r\n\tcase _IOFBF:\t/* Fully buffered */\r\n\t\tif(buf)\r\n\t\t\tstream->_flag |= _IOMYBUF;\r\n\t\tif(!buf && !(buf = stream->_base)) {\r\n\t\t\tif(!(buf = _bufallo()))\r\n\t\t\t\treturn -1;\r\n\t\t\tsize = BUFSIZ;\r\n\t\t}\r\n\t\tstream->_base = buf;\r\n\t\tstream->_size = size;\r\n\t\tstream->_flag &= ~(_IONBF|_IOLBF);\r\n\t\tstream->_flag |= mode;\r\n\t\tbreak;\r\n\r\n\tdefault:\r\n\t\treturn -1;\r\n\t}\r\n\tstream->_cnt = 0;\r\n\treturn 0;\r\n}\r\n"
  },
  {
    "path": "stdio/SPRINTF.C",
    "content": "#include\t<stdio.h>\r\n\r\nstatic\tFILE\tspf;\r\n\r\nsprintf(wh, f, a)\r\nchar *\twh;\r\nchar *\tf;\r\nint\ta;\r\n{\r\n\tspf._size = 32767;\r\n\tspf._cnt = 0;\r\n\tspf._base = spf._ptr = wh;\r\n\tspf._flag = _IOWRT|_IOBINARY|_IOSTRG;\r\n\t_doprnt(&spf, f, &a);\r\n\t*spf._ptr = 0;\r\n\treturn spf._ptr - wh;\r\n}\r\n"
  },
  {
    "path": "stdio/SSCANF.C",
    "content": "/*\r\n *\tStdio sscanf\r\n */\r\n\r\n#include\t<stdio.h>\r\n#include\t<string.h>\r\n\r\nextern int\t_doscan();\r\n\r\nsscanf(str, fmt, args)\r\nchar *\tstr;\r\nchar *\tfmt;\r\nint\targs;\r\n{\r\n\tFILE\tfile;\r\n\r\n\tfile._base = file._ptr = str;\r\n\tfile._size = file._cnt = strlen(str);\r\n\tfile._flag = _IOSTRG|_IOBINARY|_IOREAD;\r\n\treturn _doscan(&file, fmt, &args);\r\n}\r\n"
  },
  {
    "path": "stdio/STDCLEAN.C",
    "content": "#include\t<stdio.h>\r\n\r\n_cleanup()\r\n{\r\n\tuchar\ti;\r\n\tregister struct _iobuf *\tip;\r\n\r\n\ti = _NFILE;\r\n\tip = _iob;\r\n\tdo {\r\n\t\tfclose(ip);\r\n\t\tip++;\r\n\t} while(--i);\r\n}\r\n/*\r\n *\tInitial setup for stdio\r\n */\r\n\r\nchar\t_sibuf[BUFSIZ];\r\nFILE\t_iob[_NFILE] =\r\n{\r\n\t{\r\n\t\t_sibuf,\r\n\t\t0,\r\n\t\t_sibuf,\r\n\t\t_IOREAD|_IOMYBUF,\r\n\t\t0,\t\t\t/* stdin */\r\n\t\tBUFSIZ\r\n\t},\r\n\t{\r\n\t\t(char *)0,\r\n\t\t0,\r\n\t\t(char *)0,\r\n\t\t_IOWRT|_IONBF,\r\n\t\t1,\t\t\t/* stdout */\r\n\t\t0\r\n\t},\r\n\t{\r\n\t\t(char *)0,\r\n\t\t0,\r\n\t\t(char *)0,\r\n\t\t_IOWRT|_IONBF,\r\n\t\t2,\t\t\t/* stderr */\r\n\t\t0\r\n\t},\r\n};\r\n"
  },
  {
    "path": "stdio/STDIO.I",
    "content": ";\tOffsets of things in the _iob structure\r\n\r\n\tptr\tequ\t0\t\t;pointer to next byte\r\n\tcnt\tequ\t2\t\t;number of bytes left\r\n\tbase\tequ\t4\t\t;beginning of buffer\r\n\tflag\tequ\t6\t\t;flag bits\r\n\tfile\tequ\t8\t\t;file number\r\n\r\n;\tThe bit numbers of the flags in flag\r\n\t\r\n\t_IOREAD_BIT\tequ\t0\r\n\t_IOWRT_BIT\tequ\t1\r\n\t_IONBF_BIT\tequ\t2\r\n\t_IOMYBUF_BIT\tequ\t3\r\n\t_IOEOF_BIT\tequ\t4\r\n\t_IOERR_BIT\tequ\t5\r\n\t_IOSTRG_BIT\tequ\t6\r\n\t_IOBINARY_BIT\tequ\t7\r\n\r\n;\tVarious characters\r\n\r\n\tCPMEOF\tequ\t032q\t\t; EOF byte \r\n\tNEWLINE\tequ\t012q\t\t; newline character \r\n\tRETURN\tequ\t015q\t\t; carriage return \r\n\r\n\tEOF\tequ\t-1\t\t; stdio EOF value\r\n\r\n"
  },
  {
    "path": "stdio/UNGETC.C",
    "content": "#include\t<stdio.h>\r\n\r\n/*\r\n *\tungetc for HI-TECH C\r\n */\r\n\r\nungetc(c, stream)\r\nint\t\tc;\r\nregister FILE *\tstream;\r\n{\r\n\tif(c == EOF || !(stream->_flag & _IOREAD) || stream->_flag & _IODIRN ||\r\n\t\tstream->_base == (char *)NULL || stream->_cnt == stream->_size)\r\n\t\treturn(EOF);\r\n\tif(stream->_ptr == stream->_base)\r\n\t\tstream->_ptr++;\r\n\telse\r\n\t\tstream->_cnt++;\r\n\t*--stream->_ptr = c;\r\n\treturn(c);\r\n}\r\n"
  },
  {
    "path": "test/TEST-OPT.AS",
    "content": "; Test input for OPTIMH (Z280 code optimiser)\r\n;\r\nglobal _instr\r\nn\tequ\t25\r\nnn\tequ\t1abch\r\npsect text\r\n_instr:\r\n;\r\n\tglobal csv,cret\r\n\tcall csv\r\n\tjp\tcret\r\n;\r\n\tglobal amul,lmul\r\n\tcall\tamul\r\n\tcall\tlmul\r\n;\r\nlabel:\tld\t(hl),c\r\n\tinc\thl\r\n\tld\t(hl),b\r\n\tinc\thl\r\n;\r\n\tld\t(hl),c\r\n\tinc\thl\r\n\tld\t(hl),b\r\n;\r\n\tld\t(hl),e\r\n\tinc\thl\r\n\tld\t(hl),d\r\n;\r\n\tld\tc,(hl)\r\n\tinc\thl\r\n\tld\tb,(hl)\r\n;\r\n\tld\te,(hl)\r\n\tinc\thl\r\n\tld\td,(hl)\r\n;\r\n\tld\tc,(ix+n)\r\n\tld\tb,(ix+n+1)\r\n\tld\tc,(iy+n)\r\n\tld\tb,(iy+n+1)\r\n;\r\n\tld\te,(ix+n)\r\n\tld\td,(ix+n+1)\r\n;\r\n\tld\tl,(ix+n)\r\n\tld\th,(ix+n+1)\r\n;\r\n\tld\t(ix+n),c\r\n\tld\t(ix+n+1),b\r\n;\r\n\tld\t(ix+n),e\r\n\tld\t(ix+n+1),d\r\n;\r\n\tld\t(ix+n),l\r\n\tld\t(ix+n+1),h\r\n;\r\n\tor\ta\r\n\tsbc\thl,bc\r\n;\r\n\tor\ta\r\n\tsbc\thl,de\r\n;\r\n\tpush\tix\r\n\tpop\tde\r\n\tld\thl,nn\r\n\tadd\thl,de\r\n;\r\n\tpush\tix\r\n\tpop\tde\r\n;\r\n\tpush\tix\r\n\tpop\thl\r\n;\r\n; Addressing with large offset\r\n;\r\n\tpush\tix\r\n\tpop\tde\r\n\tld\thl,nn\r\n\tadd\thl,de\r\n;\r\n\tpush\tiy\r\n\tpop\tde\r\n\tld\thl,nn\r\n\tadd\thl,de\r\n;\r\n"
  },
  {
    "path": "test/TEST-OPT.AS2",
    "content": "; Test input for OPTIMH (Z280 code optimiser)\r\n;\r\nglobal _instr\r\nn\tequ\t25\r\nnn\tequ\t1abch\r\npsect text\r\n_instr:\r\n;\r\n\tglobal csv,cret\r\n;->call csv\r\npush\tiy\r\npush\tix\r\n;-> lda ix,(sp+0)\r\ndefb\t0ddh,0edh,02h,0,0\r\n;->jp cret\r\nld\tsp,ix\r\npop\tix\r\npop\tiy\r\nret\r\n;\r\n\tglobal amul,lmul\r\n;->multw  hl,de\r\ndefb\t0edh,0d2h\r\n;->multuw  hl,de\r\ndefb\t0edh,0d3h\r\n;\r\nlabel:\r\n;->ldw (hl),bc\r\ndefb\t0edh,0eh\r\ninc\thl\r\n\tinc\thl\r\n;\r\n;->ldw (hl),bc\r\ndefb\t0edh,0eh\r\ninc\thl\r\n;\r\n;->ldw (hl),de\r\ndefb\t0edh,1eh\r\ninc\thl\r\n;\r\n;->ldw bc,(hl)\r\ndefb\t0edh,06h\r\ninc\thl\r\n;\r\n;->ldw de,(hl)\r\ndefb\t0edh,16h\r\ninc\thl\r\n;\r\n;->ldw  bc,(ix+n)\r\ndefb\t0ddh,0edh,06h,+n\r\n;->ldw  bc,(iy+n)\r\ndefb\t0fdh,0edh,06h,+n\r\n;\r\n;->ldw  de,(ix+n)\r\ndefb\t0ddh,0edh,16h,+n\r\n;\r\n;->ldw  hl,(ix+n)\r\ndefb\t0ddh,0edh,26h,+n\r\n;\r\n;->ldw  (ix+n),bc\r\ndefb\t0ddh,0edh,0eh,+n\r\n;\r\n;->ldw  (ix+n),de\r\ndefb\t0ddh,0edh,1eh,+n\r\n;\r\n;->ldw  (ix+n),hl\r\ndefb\t0ddh,0edh,2eh,+n\r\n;\r\n;->subw  hl,bc\r\ndefb\t0edh,0ceh\r\n;\r\n;->subw  hl,de\r\ndefb\t0edh,0deh\r\n;\r\n;->lda  hl,(ix+nn)\r\ndefb\t0edh,2ah\r\ndefw\tnn\r\n;\r\n;->ld  d,ixh\r\ndefb\t0ddh,54h\r\n;->ld  e,ixl\r\ndefb\t0ddh,5dh\r\n;\r\n;->lda  hl,(ix+0)\r\ndefb\t0edh,2ah,0,0\r\n;\r\n; Addressing with large offset\r\n;\r\n;->lda  hl,(ix+nn)\r\ndefb\t0edh,2ah\r\ndefw\tnn\r\n;\r\n;->lda  hl,(iy+nn)\r\ndefb\t0edh,32h\r\ndefw\tnn\r\n;\r\n\r\n; optimiser statistics:\r\n; 15 bytes speed optimised away\r\n; 68 bytes replaced\r\n\r\n"
  },
  {
    "path": "test/TEST-OPT.AS3",
    "content": "; Test input for OPTIMH (Z280 code optimiser)\r\n;\r\nglobal _instr\r\nn\tequ\t25\r\nnn\tequ\t1abch\r\npsect text\r\n_instr:\r\n;\r\n\tglobal csv,cret\r\n\tcall csv\r\n\tjp\tcret\r\n;\r\n\tglobal amul,lmul\r\n;->multw  hl,de\r\ndefb\t0edh,0d2h\r\n;->multuw  hl,de\r\ndefb\t0edh,0d3h\r\n;\r\nlabel:\r\n;->ldw (hl),bc\r\ndefb\t0edh,0eh\r\ninc\thl\r\n\tinc\thl\r\n;\r\n;->ldw (hl),bc\r\ndefb\t0edh,0eh\r\ninc\thl\r\n;\r\n;->ldw (hl),de\r\ndefb\t0edh,1eh\r\ninc\thl\r\n;\r\n;->ldw bc,(hl)\r\ndefb\t0edh,06h\r\ninc\thl\r\n;\r\n;->ldw de,(hl)\r\ndefb\t0edh,16h\r\ninc\thl\r\n;\r\n;->ldw  bc,(ix+n)\r\ndefb\t0ddh,0edh,06h,+n\r\n;->ldw  bc,(iy+n)\r\ndefb\t0fdh,0edh,06h,+n\r\n;\r\n;->ldw  de,(ix+n)\r\ndefb\t0ddh,0edh,16h,+n\r\n;\r\n;->ldw  hl,(ix+n)\r\ndefb\t0ddh,0edh,26h,+n\r\n;\r\n;->ldw  (ix+n),bc\r\ndefb\t0ddh,0edh,0eh,+n\r\n;\r\n;->ldw  (ix+n),de\r\ndefb\t0ddh,0edh,1eh,+n\r\n;\r\n;->ldw  (ix+n),hl\r\ndefb\t0ddh,0edh,2eh,+n\r\n;\r\n;->subw  hl,bc\r\ndefb\t0edh,0ceh\r\n;\r\n;->subw  hl,de\r\ndefb\t0edh,0deh\r\n;\r\n;->lda  hl,(ix+nn)\r\ndefb\t0edh,2ah\r\ndefw\tnn\r\n;\r\n;->ld  d,ixh\r\ndefb\t0ddh,54h\r\n;->ld  e,ixl\r\ndefb\t0ddh,5dh\r\n;\r\n;->lda  hl,(ix+0)\r\ndefb\t0edh,2ah,0,0\r\n;\r\n; Addressing with large offset\r\n;\r\n;->lda  hl,(ix+nn)\r\ndefb\t0edh,2ah\r\ndefw\tnn\r\n;\r\n;->lda  hl,(iy+nn)\r\ndefb\t0edh,32h\r\ndefw\tnn\r\n;\r\n\r\n; optimiser statistics:\r\n; 25 bytes size optimised away\r\n; 62 bytes replaced\r\n\r\n"
  },
  {
    "path": "test/TEST.LOG",
    "content": "\r\n10E>date\r\nA:DATE     COM  (User 0)\r\n\rTue 02/09/2025 13:37:29\r\n10E>; Compile all tests\r\n10E>c -v -o filesize.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: FILESIZE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OFILESIZE.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OFILESIZE.COM 0:A:CRTCPM.OBJ FILESIZE.OBJ 0:A:LIBC.LIB\r\nERA FILESIZE.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testver.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTVER.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTVER.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTVER.COM 0:A:CRTCPM.OBJ TESTVER.OBJ 0:A:LIBC.LIB\r\nERA TESTVER.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testio.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTIO.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTIO.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTIO.COM 0:A:CRTCPM.OBJ TESTIO.OBJ 0:A:LIBC.LIB\r\nERA TESTIO.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testuid.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTUID.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTUID.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTUID.COM 0:A:CRTCPM.OBJ TESTUID.OBJ 0:A:LIBC.LIB\r\nERA TESTUID.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o teststr.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTSTR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTSTR.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTSTR.COM 0:A:CRTCPM.OBJ TESTSTR.OBJ 0:A:LIBC.LIB\r\nERA TESTSTR.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testbios.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTBIOS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTBIOS.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTBIOS.COM 0:A:CRTCPM.OBJ TESTBIOS.OBJ 0:A:LIBC.LIB\r\nERA TESTBIOS.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testbdos.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTBDOS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTBDOS.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTBDOS.COM 0:A:CRTCPM.OBJ TESTBDOS.OBJ 0:A:LIBC.LIB\r\nERA TESTBDOS.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testtrig.c -lf\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTTRIG.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTTRIG.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTTRIG.COM 0:A:CRTCPM.OBJ TESTTRIG.OBJ 0:A:LIBF.LIB 0:A:LIBC.LIB\r\nERA TESTTRIG.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testftim.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTFTIM.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTFTIM.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTFTIM.COM 0:A:CRTCPM.OBJ TESTFTIM.OBJ 0:A:LIBC.LIB\r\nERA TESTFTIM.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testfile.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTFILE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTFILE.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTFILE.COM 0:A:CRTCPM.OBJ TESTFILE.OBJ 0:A:LIBC.LIB\r\nERA TESTFILE.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testaes.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTAES.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTAES.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTAES.COM 0:A:CRTCPM.OBJ TESTAES.OBJ 0:A:LIBC.LIB\r\nERA TESTAES.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testrc.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTRC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTRC.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTRC.COM 0:A:CRTCPM.OBJ TESTRC.OBJ 0:A:LIBC.LIB\r\nERA TESTRC.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testview.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTVIEW.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTVIEW.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTVIEW.COM 0:A:CRTCPM.OBJ TESTVIEW.OBJ 0:A:LIBC.LIB\r\nERA TESTVIEW.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testwild.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTWILD.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTWILD.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTWILD.COM 0:A:CRTCPM.OBJ TESTWILD.OBJ 0:A:LIBC.LIB\r\nERA TESTWILD.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -ftestovrx.sym -v -o testovr.c -lovr\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTOVR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTOVR.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -DTESTOVRX.SYM -Ptext=0,data,bss -C100H -OTESTOVR.COM 0:A:CRTCPM.OBJ TESTOVR.OBJ 0:A:LIBOVR.LIB 0:A:LIBC.LIB\r\nERA TESTOVR.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -y -o -v testovr2.c testovrx.sym\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nTESTOVR2.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTOVR2.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTOVR2.OBJ M:$CTMP2.$$$\r\n0:A:SYMTOAS TESTOVRX.SYM M:$CTMP5.$$$\r\nTESTOVRX.SYM\r\n0:A:ZAS -OTESTOVRX.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=03689h,data -C3689H -OTESTOVR2.OVR TESTOVR2.OBJ TESTOVRX.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -y -o -v testovr1.c testovrx.sym\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nTESTOVR1.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTOVR1.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTOVR1.OBJ M:$CTMP2.$$$\r\n0:A:SYMTOAS TESTOVRX.SYM M:$CTMP5.$$$\r\nTESTOVRX.SYM\r\n0:A:ZAS -OTESTOVRX.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=03689h,data -C3689H -OTESTOVR1.OVR TESTOVR1.OBJ TESTOVRX.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -a -v -o testhell.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTHELL.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTHELL.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -L -Pcpm=0,text,data,bss,stack -OM:$L.OBJ 0:A:RRTCPM.OBJ TESTHELL.OBJ 0:A:LIBC.LIB\r\n0:A:OBJTOHEX -R -B100H M:$L.OBJ TESTHELL.COM\r\nERA M:$L.OBJ\r\nERA TESTHELL.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c -v -o testpr.c\r\nA:C        COM  (User 0)\r\nHi-Tech Z80 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TESTPR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:ZAS -J -N -OTESTPR.OBJ M:$CTMP2.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTPR.COM 0:A:CRTCPM.OBJ TESTPR.OBJ 0:A:LIBC.LIB\r\nERA TESTPR.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>testver\r\nE:TESTVER  COM\r\nCP/M BDOS Version (3.1)\r\nMachine (MCS80/Z80)\r\nBDOS Address (0xE500)\r\nBIOS Address (0xF800)\r\nTPA Size (57.0K)\r\nC library version LIBC 3.09-20\r\nUsing DOS Plus exact file size mode\r\n\r\n10E>era testio.sta\r\n10E>era testio.out\r\nNo File\r\n10E>era testio.err\r\n10E>testovr\r\nE:TESTOVR  COM\r\noverlay test\r\nhello from overlay 01\r\noverlay return is 0\r\nhello from overlay 01\r\noverlay return is 0\r\nhello from overlay 02\r\noverlay return is 0\r\nhello from overlay 01\r\noverlay return is 0\r\n\r\n10E>testio\r\nE:TESTIO   COM\r\nhexa,22\r\nCP/M BDOS 3.1\r\n\r\n10E>testuid\r\nE:TESTUID  COM\r\ngetuid=10\r\nsetuid=0\r\ngetuid=3\r\ngetuid=3\r\n\r\n10E>teststr\r\nE:TESTSTR  COM\r\nstrcmp test:\r\n- test<>Test=1\r\n- test<>test=0\r\n- test1<>test=1\r\n- test<>test1=-1\r\n- rest<>test=-1\r\nstricmp test:\r\n- test<>Test=0\r\n- test<>test=0\r\n- test1<>test=1\r\n- test<>test1=-1\r\n- rest<>test=-1\r\nstrnicmp test:\r\n- test<>test1=0\r\n- test1<>test=0\r\n- Test1<>test=0\r\n\r\n10E>testbios\r\nE:TESTBIOS COM\r\nZ3ENV is not established.  (This is not an error.)\r\nPress a key: rc = 005A, character = Z\r\nThe next message should say \"Did this work?\"\r\nDid this work?\r\n\r\n10E>testbdos\r\nE:TESTBDOS COM\r\nFirst some perror() tests ...\r\n\r\n 0:Unknown error\r\n 1:Reading empty space\r\n 2:Disc is full\r\n 3:Can't close extent\r\n 4:Unwritten extent\r\n 5:Directory full\r\n 6:File pointer out of range\r\n 7:File not found\r\n 8:Unknown error\r\n 9:Invalid FCB\r\n10:Disc has been changed\r\n11:Unknown error\r\n12:Unknown error\r\n13:Unknown error\r\n14:Unknown error\r\n15:Unknown error\r\n16:Unknown error\r\n17:Disc I/O error\r\n18:Disc is read-only\r\n19:File is read-only\r\n20:Invalid drive\r\n21:File already open\r\n22:Unknown error\r\n23:Password error\r\n24:File exists\r\n25:Ambiguous filename\r\n26:File is wheel protected\r\n27:Unknown error\r\n\r\n\r\n10E>testtrig\r\nE:TESTTRIG COM\r\n\r\n  n  LN             EXP            SIN            COS            ATAN\r\n 01  0.000000e+00   2.718282e+00   8.414710e-01   5.403027e-01   7.853984e-01 \r\n 02  6.931472e-01   7.389057e+00   9.092979e-01  -4.161470e-01   1.107149e+00 \r\n 03  1.098612e+00   2.008553e+01   1.411210e-01  -9.899925e-01   1.249046e+00 \r\n 04  1.386294e+00   5.459816e+01  -7.568022e-01  -6.536458e-01   1.325818e+00 \r\n 05  1.609438e+00   1.484131e+02  -9.589247e-01   2.836612e-01   1.373401e+00 \r\n 06  1.791759e+00   4.034287e+02  -2.794167e-01   9.601700e-01   1.405648e+00 \r\n 07  1.945910e+00   1.096633e+03   6.569862e-01   7.539034e-01   1.428900e+00 \r\n 08  2.079441e+00   2.980960e+03   9.893584e-01  -1.454998e-01   1.446442e+00 \r\n 09  2.197225e+00   8.103081e+03   4.121198e-01  -9.111303e-01   1.460140e+00 \r\n 10  2.302585e+00   2.202647e+04  -5.440199e-01  -8.390721e-01   1.471128e+00 \r\n 11  2.397895e+00   5.987416e+04  -9.999902e-01   4.425162e-03   1.480137e+00 \r\n 12  2.484906e+00   1.627547e+05  -5.365752e-01   8.438536e-01   1.487656e+00 \r\n 13  2.564949e+00   4.424134e+05   4.201660e-01   9.074473e-01   1.494025e+00 \r\n 14  2.639057e+00   1.202605e+06   9.906074e-01   1.367387e-01   1.499489e+00 \r\n 15  2.708050e+00   3.269020e+06   6.502893e-01  -7.596868e-01   1.504229e+00 \r\n 16  2.772589e+00   8.886121e+06  -2.879014e-01  -9.576599e-01   1.508378e+00 \r\n 17  2.833213e+00   2.415499e+07  -9.613971e-01  -2.751643e-01   1.512041e+00 \r\n 18  2.890371e+00   6.565992e+07  -7.509893e-01   6.603170e-01   1.515298e+00 \r\n 19  2.944439e+00   1.784822e+08   1.498742e-01   9.887048e-01   1.518214e+00 \r\n\r\n10E>testftim\r\nE:TESTFTIM COM\r\n34: 01:50 PM\r\nTue Sep 02 13:50:07 2025\r\n\r\n\r\n10E>testfile\r\nE:TESTFILE COM\r\ncreate file...\r\nrename file (0)\r\ndelete file (0)\r\ndelete file (255)\r\ncreate file...\r\n\r\n10E>testaes\r\nE:TESTAES  COM\r\ntxt: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \r\nkey: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F \r\n---\r\nenc: 8E A2 B7 CA 51 67 45 BF EA FC 49 90 4B 49 60 89 \r\ntst: 8e a2 b7 ca 51 67 45 bf ea fc 49 90 4b 49 60 89\r\ndec: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \r\n\r\n10E>testrc\r\nE:TESTRC   COM\r\n\r\n10E>testview testh*.c testver.c\r\nE:TESTVIEW COM\r\n 1: TESTHELL.C\r\n#include <stdio.h>\r\n\r\nint main() {\r\n    printf(\"Hello\\n\");\r\n}\r\n 2: TESTVER.C\r\n#include \"stdio.h\"\r\n#include \"cpm.h\"\r\n#include <stdio.h>\r\n\r\nextern char _exact;\t/* exact file size mode */\r\nextern char *_libcver;\t/* LIBC version string */\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    int i;\r\n    int minor=0;\r\n    int major=0;\r\n    int machine;\r\n    int system;\r\n    int* bdosaddr=(int*)6;\r\n    int* biosaddr=(int*)1;\r\n    unsigned int tpa;\r\n\r\n    i=bdos(CPMVERS,0);\r\n    switch(i) {\r\n    case 0x00:\r\n        major=1;\r\n        minor=0;\r\n        break;\r\n    default:\r\n        major=((i>>4)&0x0F);\r\n        minor=(i&0x0F);\r\n        break;\r\n    }\r\n    machine=(i>>12)&0x0F;\r\n    system=(i>>8)&0x0F;\r\n    printf(\"CP/M BDOS Version (%d.%d)\\n\",major,minor);\r\n    if(system!=0) {\r\n        printf(\"Network (%s%s%s)\\n\",system&0x01?\"[MP/M]\":\"\",system&0x02?\"[CP/Net]\":\"\",\r\n            system&0x04?\"[Multi User]\":\"\");\r\n    }\r\n    switch(machine) {\r\n    case 0:\r\n        printf(\"Machine (MCS80/Z80)\\n\",machine);\r\n        break;\r\n    case 1:\r\n        printf(\"Machine (MCS86)\\n\");\r\n        break;\r\n    case 2:\r\n        printf(\"Machine (68000/Z8000)\\n\");\r\n        break;\r\n    default:\r\n        printf(\"Machine (?)\\n\");\r\n        break;\r\n    }\r\n    printf(\"BDOS Address (0x%04x)\\n\",*bdosaddr-6);\r\n    printf(\"BIOS Address (0x%04x)\\n\",*biosaddr-3);\r\n    tpa=((*bdosaddr-6)-0x100);\r\n    fprintf(stdout,\"TPA Size (%u.%uK)\\n\",tpa/1024,(tpa % 1024)/100);\r\n\r\n    fprintf(stdout,\"C library version %s\\n\",_libcver);\r\n    switch(_exact) {\r\n    case 'C':\r\n        printf(\"Exact file size not used (CP/M 2 mode)\\n\");\r\n        break;\r\n    case 'D':\r\n        printf(\"Using DOS Plus exact file size mode\\n\");\r\n        break;\r\n    case 'I':\r\n        printf(\"Using ISIS exact file size mode\\n\");\r\n    default:\r\n        printf(\"Unknown exact file size mode 0%xH\\n\",_exact);\r\n        break;\r\n    }\r\n\r\n    return 0;\r\n}\r\n\r\n\r\n10E>testwild test*.c test*.com\r\nE:TESTWILD COM\r\nProgram name: TESTWILD\r\n 1: TESTBDOS.C\r\n 2: TESTAES.C\r\n 3: TESTARGS.C\r\n 4: TESTBIOS.C\r\n 5: TESTBUG.C\r\n 6: TESTENV.C\r\n 7: TESTFILE.C\r\n 8: TESTFTIM.C\r\n 9: TESTHELL.C\r\n10: TESTIO.C\r\n11: TESTL.C\r\n12: TESTLTOF.C\r\n13: TESTOVR.C\r\n14: TESTOVR1.C\r\n15: TESTOVR2.C\r\n16: TESTPR.C\r\n17: TESTPWD.C\r\n18: TESTQSRT.C\r\n19: TESTRC.C\r\n20: TESTREL.C\r\n21: TESTSTR.C\r\n22: TESTSUB.C\r\n23: TESTTRIG.C\r\n24: TESTUID.C\r\n25: TESTVER.C\r\n26: TESTVIEW.C\r\n27: TESTWILD.C\r\n28: TESTARGS.COM\r\n29: TESTBDOS.COM\r\n30: TESTAES.COM\r\n31: TESTVER.COM\r\n32: TESTBIOS.COM\r\n33: TESTFILE.COM\r\n34: TESTFTIM.COM\r\n35: TESTHELL.COM\r\n36: TESTIO.COM\r\n37: TESTOVR.COM\r\n38: TESTPR.COM\r\n39: TESTRC.COM\r\n40: TESTSTR.COM\r\n41: TESTTRIG.COM\r\n42: TESTUID.COM\r\n43: TESTVIEW.COM\r\n44: TESTWILD.COM\r\n\r\n10E>testhell\r\nE:TESTHELL COM\r\nHello\r\n\r\n10E>testpr\r\nE:TESTPR   COM\r\nlen: 320\r\nstring: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n\r\n10E>filesize test*.*\r\nE:FILESIZE COM\r\nargc = 65\r\n                         Bytes\r\n             File   ftell()   fopen() Sectors    kB\r\n----------------- --------- --------- ------- -----\r\n       TESTBDOS.C      1280      1280      10     2\r\n     TESTARGS.COM     12544     12544      98    13\r\n     TESTBDOS.COM     13568     13568     106    14\r\n         TEST.LOG     19072     19072     149    19\r\n      TEST-OPT.AS       896       896       7     1\r\n        TESTAES.C     13952     13952     109    14\r\n      TESTAES.COM     17152     17152     134    17\r\n       TESTARGS.C       256       256       2     1\r\n       TESTBIOS.C      1280      1280      10     2\r\n       TESTBUG.AS      4480      4480      35     5\r\n        TESTBUG.C       512       512       4     1\r\n        TESTENV.C       256       256       2     1\r\n       TESTFILE.C       896       896       7     1\r\n       TESTFTIM.C       512       512       4     1\r\n       TESTHELL.C       128       128       1     1\r\n         TESTIO.C       768       768       6     1\r\n       TESTIO.ERR        15        15       1     1\r\n       TESTIO.STA         8         8       1     1\r\n          TESTL.C       128       128       1     1\r\n      TESTLTOF.AS      8576      8576      67     9\r\n       TESTLTOF.C      1408      1408      11     2\r\n      TESTOPTH.AS       384       384       3     1\r\n        TESTOVR.C       512       512       4     1\r\n       TESTOVR1.C       128       128       1     1\r\n       TESTOVR2.C       128       128       1     1\r\n         TESTPR.C       640       640       5     1\r\n        TESTPWD.C      1152      1152       9     2\r\n       TESTQSRT.C       768       768       6     1\r\n         TESTRC.C       256       256       2     1\r\n     TESTOVR2.OBJ       256       256       2     1\r\n        TESTREL.C       128       128       1     1\r\n        TESTSTR.C       896       896       7     1\r\n        TESTSUB.C      1280      1280      10     2\r\n       TESTTRIG.C      4480      4480      35     5\r\n        TESTUID.C       384       384       3     1\r\n        TESTVER.C      1920      1920      15     2\r\n      TESTVER.SUB       128       128       1     1\r\n       TESTVIEW.C      1024      1024       8     1\r\n       TESTWILD.C       896       896       7     1\r\n      TESTVER.COM     13952     13952     109    14\r\n         TEST.DAT         7         7       1     1\r\n     TESTBIOS.COM     13824     13824     108    14\r\n     TESTFILE.COM     13696     13696     107    14\r\n     TESTFTIM.COM     16640     16640     130    17\r\n     TESTHELL.COM      9472      9472      74    10\r\n       TESTIO.COM     13568     13568     106    14\r\n      TESTOVR.COM     13824     13824     108    14\r\n     TESTOVR1.OVR       128       128       1     1\r\n     TESTOVR2.OVR       128       128       1     1\r\n     TESTOVRX.SYM      2688      2688      21     3\r\n       TESTPR.COM     13568     13568     106    14\r\n       TESTRC.COM     13056     13056     102    13\r\n      TESTSTR.COM     13824     13824     108    14\r\n     TESTTRIG.COM     18688     18688     146    19\r\n      TESTUID.COM     13184     13184     103    13\r\n     TESTVIEW.COM     13312     13312     104    13\r\n     TESTWILD.COM     13184     13184     103    13\r\n      TEST280.LOG     24064     24064     188    24\r\n     TEST-OPT.AS2      1311      1311      11     2\r\n         TEST.SUB       896       896       7     1\r\n      TEST280.SUB      1024      1024       8     1\r\n     TEST-OPT.AS3      1214      1214      10     2\r\n     TESTOVRX.OBJ      2944      2944      23     3\r\n     TESTOVR1.OBJ       256       256       2     1\r\n\r\n10E>; All tests completed\r\n10E>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "test/TEST.SUB",
    "content": "era test.log\r\nput console output to file test.log [system]\r\ndate\r\n; Compile all tests\r\nc -v -o filesize.c\r\nc -v -o testver.c\r\nc -v -o testio.c\r\nc -v -o testuid.c\r\nc -v -o teststr.c\r\nc -v -o testbios.c\r\nc -v -o testbdos.c\r\nc -v -o testtrig.c -lf\r\nc -v -o testftim.c\r\nc -v -o testfile.c\r\nc -v -o testaes.c\r\nc -v -o testrc.c\r\nc -v -o testview.c\r\nc -v -o testwild.c\r\nc -ftestovrx.sym -v -o testovr.c -lovr\r\nc -y -o -v testovr2.c testovrx.sym\r\nc -y -o -v testovr1.c testovrx.sym\r\nc -a -v -o testhell.c\r\nc -v -o testpr.c\r\ntestver\r\nera testio.sta\r\nera testio.out\r\nera testio.err\r\ntestovr\r\ntestio\r\ntestuid\r\nteststr\r\ntestbios\r\ntestbdos\r\ntesttrig\r\ntestftim\r\ntestfile\r\ntestaes\r\ntestrc\r\ntestview testh*.c testver.c\r\ntestwild test*.c test*.com\r\ntesthell\r\ntestpr\r\nfilesize test*.*\r\n; All tests completed\r\nput console to console\r\n"
  },
  {
    "path": "test/TEST280.LOG",
    "content": "\r\n10E>date\r\nA:DATE     COM  (User 0)\r\n\rTue 02/09/2025 13:51:35\r\n10E>; Compile all test280\r\n10E>c280 -v -o2 filesize.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: FILESIZE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 57 bytes size optimised away\r\n 123 bytes replaced\r\n0:A:ZAS -J -N -OFILESIZE.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OFILESIZE.COM 0:A:C280CPM.OBJ FILESIZE.OBJ 0:A:LIB280C.LIB\r\nERA FILESIZE.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testver.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTVER.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 34 bytes size optimised away\r\n 74 bytes replaced\r\n0:A:ZAS -J -N -OTESTVER.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTVER.COM 0:A:C280CPM.OBJ TESTVER.OBJ 0:A:LIB280C.LIB\r\nERA TESTVER.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testio.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTIO.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 32 bytes size optimised away\r\n 66 bytes replaced\r\n0:A:ZAS -J -N -OTESTIO.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTIO.COM 0:A:C280CPM.OBJ TESTIO.OBJ 0:A:LIB280C.LIB\r\nERA TESTIO.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testuid.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTUID.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTUID.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTUID.COM 0:A:C280CPM.OBJ TESTUID.OBJ 0:A:LIB280C.LIB\r\nERA TESTUID.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 teststr.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTSTR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 28 bytes size optimised away\r\n 72 bytes replaced\r\n0:A:ZAS -J -N -OTESTSTR.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTSTR.COM 0:A:C280CPM.OBJ TESTSTR.OBJ 0:A:LIB280C.LIB\r\nERA TESTSTR.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testbios.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTBIOS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 20 bytes size optimised away\r\n 42 bytes replaced\r\n0:A:ZAS -J -N -OTESTBIOS.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTBIOS.COM 0:A:C280CPM.OBJ TESTBIOS.OBJ 0:A:LIB280C.LIB\r\nERA TESTBIOS.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testbdos.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTBDOS.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 43 bytes size optimised away\r\n 66 bytes replaced\r\n0:A:ZAS -J -N -OTESTBDOS.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTBDOS.COM 0:A:C280CPM.OBJ TESTBDOS.OBJ 0:A:LIB280C.LIB\r\nERA TESTBDOS.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testtrig.c -lf\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTTRIG.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTTRIG.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTTRIG.COM 0:A:C280CPM.OBJ TESTTRIG.OBJ 0:A:LIB280F.LIB 0:A:LIB280C.LIB\r\nERA TESTTRIG.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testftim.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTFTIM.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 19 bytes size optimised away\r\n 30 bytes replaced\r\n0:A:ZAS -J -N -OTESTFTIM.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTFTIM.COM 0:A:C280CPM.OBJ TESTFTIM.OBJ 0:A:LIB280C.LIB\r\nERA TESTFTIM.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testfile.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTFILE.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 18 bytes size optimised away\r\n 36 bytes replaced\r\n0:A:ZAS -J -N -OTESTFILE.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTFILE.COM 0:A:C280CPM.OBJ TESTFILE.OBJ 0:A:LIB280C.LIB\r\nERA TESTFILE.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testaes.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTAES.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 264 bytes size optimised away\r\n 553 bytes replaced\r\n0:A:ZAS -J -N -OTESTAES.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTAES.COM 0:A:C280CPM.OBJ TESTAES.OBJ 0:A:LIB280C.LIB\r\nERA TESTAES.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testrc.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTRC.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTRC.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTRC.COM 0:A:C280CPM.OBJ TESTRC.OBJ 0:A:LIB280C.LIB\r\nERA TESTRC.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testview.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTVIEW.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 33 bytes size optimised away\r\n 66 bytes replaced\r\n0:A:ZAS -J -N -OTESTVIEW.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTVIEW.COM 0:A:C280CPM.OBJ TESTVIEW.OBJ 0:A:LIB280C.LIB\r\nERA TESTVIEW.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testwild.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTWILD.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 14 bytes size optimised away\r\n 32 bytes replaced\r\n0:A:ZAS -J -N -OTESTWILD.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTWILD.COM 0:A:C280CPM.OBJ TESTWILD.OBJ 0:A:LIB280C.LIB\r\nERA TESTWILD.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -ftestovrx.sym -v -o2 testovr.c -lovr\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTOVR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 8 bytes size optimised away\r\n 16 bytes replaced\r\n0:A:ZAS -J -N -OTESTOVR.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -DTESTOVRX.SYM -Ptext=0,data,bss -C100H -OTESTOVR.COM 0:A:C280CPM.OBJ TESTOVR.OBJ 0:A:LIB280OVR.LIB 0:A:LIB280C.LIB\r\nERA TESTOVR.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -y -o2 -v testovr2.c testovrx.sym\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nTESTOVR2.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTOVR2.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTOVR2.OBJ M:$CTMP5.$$$\r\n0:A:SYMTOAS TESTOVRX.SYM M:$CTMP5.$$$\r\nTESTOVRX.SYM\r\n0:A:ZAS -OTESTOVRX.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=031C2h,data -C31C2H -OTESTOVR2.OVR TESTOVR2.OBJ TESTOVRX.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -y -o2 -v testovr1.c testovrx.sym\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\nTESTOVR1.C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTOVR1.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTOVR1.OBJ M:$CTMP5.$$$\r\n0:A:SYMTOAS TESTOVRX.SYM M:$CTMP5.$$$\r\nTESTOVRX.SYM\r\n0:A:ZAS -OTESTOVRX.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=031C2h,data -C31C2H -OTESTOVR1.OVR TESTOVR1.OBJ TESTOVRX.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -a -v -o2 testhell.c -lc\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTHELL.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTHELL.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -L -Pcpm=0,text,data,bss,stack -OM:$L.OBJ 0:A:R280CPM.OBJ TESTHELL.OBJ 0:A:LIB280C.LIB 0:A:LIB280C.LIB\r\n0:A:OBJTOHEX -R -B100H M:$L.OBJ TESTHELL.COM\r\nERA M:$L.OBJ\r\nERA TESTHELL.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>c280 -v -o2 testpr.c\r\nA:C280     COM  (User 0)\r\nHi-Tech Z280 C Compiler (CP/M-80) V3.09-20\r\nCopyright (C) 1984-87 HI-TECH SOFTWARE\r\nUpdated from https://github.com/agn453/HI-TECH-Z80-C\r\n0:A:CPP -DCPM -DHI_TECH_C -Dz80 -DZ280 -I0:A: TESTPR.C M:$CTMP1.$$$\r\n0:A:P1 M:$CTMP1.$$$ M:$CTMP2.$$$ M:$CTMP3.$$$\r\n0:A:CGEN M:$CTMP2.$$$ M:$CTMP1.$$$\r\n0:A:OPTIM M:$CTMP1.$$$ M:$CTMP2.$$$\r\n0:A:OPTIMH M:$CTMP2.$$$ M:$CTMP5.$$$\r\n 0 bytes size optimised away\r\n 0 bytes replaced\r\n0:A:ZAS -J -N -OTESTPR.OBJ M:$CTMP5.$$$\r\nERA M:$CTMP1.$$$\r\nERA M:$CTMP2.$$$\r\nERA M:$CTMP3.$$$\r\nERA M:$CTMP5.$$$\r\n0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTESTPR.COM 0:A:C280CPM.OBJ TESTPR.OBJ 0:A:LIB280C.LIB\r\nERA TESTPR.OBJ\r\nERA M:$$EXEC.$$$\r\n\r\n10E>testver\r\nE:TESTVER  COM\r\nCP/M BDOS Version (3.1)\r\nMachine (MCS80/Z80)\r\nBDOS Address (0xE500)\r\nBIOS Address (0xF800)\r\nTPA Size (57.0K)\r\nC library version LIB280C 3.09-20\r\nUsing DOS Plus exact file size mode\r\n\r\n10E>era testio.sta\r\n10E>era testio.out\r\nNo File\r\n10E>era testio.err\r\n10E>testovr\r\nE:TESTOVR  COM\r\noverlay test\r\nhello from overlay 01\r\noverlay return is 0\r\nhello from overlay 01\r\noverlay return is 0\r\nhello from overlay 02\r\noverlay return is 0\r\nhello from overlay 01\r\noverlay return is 0\r\n\r\n10E>testio\r\nE:TESTIO   COM\r\nhexa,22\r\nCP/M BDOS 3.1\r\n\r\n10E>testuid\r\nE:TESTUID  COM\r\ngetuid=10\r\nsetuid=0\r\ngetuid=3\r\ngetuid=3\r\n\r\n10E>teststr\r\nE:TESTSTR  COM\r\nstrcmp test:\r\n- test<>Test=1\r\n- test<>test=0\r\n- test1<>test=1\r\n- test<>test1=-1\r\n- rest<>test=-1\r\nstricmp test:\r\n- test<>Test=0\r\n- test<>test=0\r\n- test1<>test=1\r\n- test<>test1=-1\r\n- rest<>test=-1\r\nstrnicmp test:\r\n- test<>test1=0\r\n- test1<>test=0\r\n- Test1<>test=0\r\n\r\n10E>testbios\r\nE:TESTBIOS COM\r\nZ3ENV is not established.  (This is not an error.)\r\nPress a key: rc = 005A, character = Z\r\nThe next message should say \"Did this work?\"\r\nDid this work?\r\n\r\n10E>testbdos\r\nE:TESTBDOS COM\r\nFirst some perror() tests ...\r\n\r\n 0:Unknown error\r\n 1:Reading empty space\r\n 2:Disc is full\r\n 3:Can't close extent\r\n 4:Unwritten extent\r\n 5:Directory full\r\n 6:File pointer out of range\r\n 7:File not found\r\n 8:Unknown error\r\n 9:Invalid FCB\r\n10:Disc has been changed\r\n11:Unknown error\r\n12:Unknown error\r\n13:Unknown error\r\n14:Unknown error\r\n15:Unknown error\r\n16:Unknown error\r\n17:Disc I/O error\r\n18:Disc is read-only\r\n19:File is read-only\r\n20:Invalid drive\r\n21:File already open\r\n22:Unknown error\r\n23:Password error\r\n24:File exists\r\n25:Ambiguous filename\r\n26:File is wheel protected\r\n27:Unknown error\r\n\r\n\r\n10E>testtrig\r\nE:TESTTRIG COM\r\n\r\n  n  LN             EXP            SIN            COS            ATAN\r\n 01  0.000000e+00   2.718281e+00   8.414713e-01   5.403028e-01   7.853984e-01 \r\n 02  6.931472e-01   7.389053e+00   9.092976e-01  -4.161476e-01   1.107149e+00 \r\n 03  1.098612e+00   2.008552e+01   1.411195e-01  -9.899930e-01   1.249045e+00 \r\n 04  1.386294e+00   5.459809e+01  -7.568034e-01  -6.536440e-01   1.325817e+00 \r\n 05  1.609438e+00   1.484130e+02  -9.589241e-01   2.836642e-01   1.373401e+00 \r\n 06  1.791759e+00   4.034281e+02  -2.794138e-01   9.601711e-01   1.405647e+00 \r\n 07  1.945910e+00   1.096632e+03   6.569884e-01   7.539010e-01   1.428899e+00 \r\n 08  2.079441e+00   2.980951e+03   9.893582e-01  -1.455027e-01   1.446441e+00 \r\n 09  2.197225e+00   8.103070e+03   4.121158e-01  -9.111318e-01   1.460139e+00 \r\n 10  2.302585e+00   2.202641e+04  -5.440236e-01  -8.390698e-01   1.471127e+00 \r\n 11  2.397895e+00   5.987400e+04  -9.999905e-01   4.429656e-03   1.480136e+00 \r\n 12  2.484906e+00   1.627543e+05  -5.365700e-01   8.438562e-01   1.487655e+00 \r\n 13  2.564949e+00   4.424122e+05   4.201716e-01   9.074452e-01   1.494024e+00 \r\n 14  2.639058e+00   1.202601e+06   9.906083e-01   1.367328e-01   1.499489e+00 \r\n 15  2.708050e+00   3.269011e+06   6.502848e-01  -7.596909e-01   1.504228e+00 \r\n 16  2.772589e+00   8.886073e+06  -2.879071e-01  -9.576581e-01   1.508378e+00 \r\n 17  2.833213e+00   2.415486e+07  -9.613985e-01  -2.751586e-01   1.512040e+00 \r\n 18  2.890371e+00   6.565974e+07  -7.509834e-01   6.603216e-01   1.515297e+00 \r\n 19  2.944439e+00   1.784818e+08   1.498831e-01   9.887040e-01   1.518213e+00 \r\n\r\n10E>testftim\r\nE:TESTFTIM COM\r\n34: 02:05 PM\r\nTue Sep 02 14:05:05 2025\r\n\r\n\r\n10E>testfile\r\nE:TESTFILE COM\r\ncreate file...\r\nrename file (0)\r\ndelete file (0)\r\ndelete file (255)\r\ncreate file...\r\n\r\n10E>testaes\r\nE:TESTAES  COM\r\ntxt: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \r\nkey: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F \r\n---\r\nenc: 8E A2 B7 CA 51 67 45 BF EA FC 49 90 4B 49 60 89 \r\ntst: 8e a2 b7 ca 51 67 45 bf ea fc 49 90 4b 49 60 89\r\ndec: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \r\n\r\n10E>testrc\r\nE:TESTRC   COM\r\n\r\n10E>testview testh*.c testver.c\r\nE:TESTVIEW COM\r\n 1: TESTHELL.C\r\n#include <stdio.h>\r\n\r\nint main() {\r\n    printf(\"Hello\\n\");\r\n}\r\n 2: TESTVER.C\r\n#include \"stdio.h\"\r\n#include \"cpm.h\"\r\n#include <stdio.h>\r\n\r\nextern char _exact;\t/* exact file size mode */\r\nextern char *_libcver;\t/* LIBC version string */\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    int i;\r\n    int minor=0;\r\n    int major=0;\r\n    int machine;\r\n    int system;\r\n    int* bdosaddr=(int*)6;\r\n    int* biosaddr=(int*)1;\r\n    unsigned int tpa;\r\n\r\n    i=bdos(CPMVERS,0);\r\n    switch(i) {\r\n    case 0x00:\r\n        major=1;\r\n        minor=0;\r\n        break;\r\n    default:\r\n        major=((i>>4)&0x0F);\r\n        minor=(i&0x0F);\r\n        break;\r\n    }\r\n    machine=(i>>12)&0x0F;\r\n    system=(i>>8)&0x0F;\r\n    printf(\"CP/M BDOS Version (%d.%d)\\n\",major,minor);\r\n    if(system!=0) {\r\n        printf(\"Network (%s%s%s)\\n\",system&0x01?\"[MP/M]\":\"\",system&0x02?\"[CP/Net]\":\"\",\r\n            system&0x04?\"[Multi User]\":\"\");\r\n    }\r\n    switch(machine) {\r\n    case 0:\r\n        printf(\"Machine (MCS80/Z80)\\n\",machine);\r\n        break;\r\n    case 1:\r\n        printf(\"Machine (MCS86)\\n\");\r\n        break;\r\n    case 2:\r\n        printf(\"Machine (68000/Z8000)\\n\");\r\n        break;\r\n    default:\r\n        printf(\"Machine (?)\\n\");\r\n        break;\r\n    }\r\n    printf(\"BDOS Address (0x%04x)\\n\",*bdosaddr-6);\r\n    printf(\"BIOS Address (0x%04x)\\n\",*biosaddr-3);\r\n    tpa=((*bdosaddr-6)-0x100);\r\n    fprintf(stdout,\"TPA Size (%u.%uK)\\n\",tpa/1024,(tpa % 1024)/100);\r\n\r\n    fprintf(stdout,\"C library version %s\\n\",_libcver);\r\n    switch(_exact) {\r\n    case 'C':\r\n        printf(\"Exact file size not used (CP/M 2 mode)\\n\");\r\n        break;\r\n    case 'D':\r\n        printf(\"Using DOS Plus exact file size mode\\n\");\r\n        break;\r\n    case 'I':\r\n        printf(\"Using ISIS exact file size mode\\n\");\r\n    default:\r\n        printf(\"Unknown exact file size mode 0%xH\\n\",_exact);\r\n        break;\r\n    }\r\n\r\n    return 0;\r\n}\r\n\r\n\r\n10E>testwild test*.c test*.com\r\nE:TESTWILD COM\r\nProgram name: TESTWILD\r\n 1: TESTBDOS.C\r\n 2: TESTAES.C\r\n 3: TESTARGS.C\r\n 4: TESTBIOS.C\r\n 5: TESTBUG.C\r\n 6: TESTENV.C\r\n 7: TESTFILE.C\r\n 8: TESTFTIM.C\r\n 9: TESTHELL.C\r\n10: TESTIO.C\r\n11: TESTL.C\r\n12: TESTLTOF.C\r\n13: TESTOVR.C\r\n14: TESTOVR1.C\r\n15: TESTOVR2.C\r\n16: TESTPR.C\r\n17: TESTPWD.C\r\n18: TESTQSRT.C\r\n19: TESTRC.C\r\n20: TESTREL.C\r\n21: TESTSTR.C\r\n22: TESTSUB.C\r\n23: TESTTRIG.C\r\n24: TESTUID.C\r\n25: TESTVER.C\r\n26: TESTVIEW.C\r\n27: TESTWILD.C\r\n28: TESTARGS.COM\r\n29: TESTBDOS.COM\r\n30: TESTAES.COM\r\n31: TESTVER.COM\r\n32: TESTBIOS.COM\r\n33: TESTFILE.COM\r\n34: TESTFTIM.COM\r\n35: TESTHELL.COM\r\n36: TESTIO.COM\r\n37: TESTOVR.COM\r\n38: TESTPR.COM\r\n39: TESTRC.COM\r\n40: TESTSTR.COM\r\n41: TESTTRIG.COM\r\n42: TESTUID.COM\r\n43: TESTVIEW.COM\r\n44: TESTWILD.COM\r\n\r\n10E>testhell\r\nE:TESTHELL COM\r\nHello\r\n\r\n10E>testpr\r\nE:TESTPR   COM\r\nlen: 320\r\nstring: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n\r\n10E>filesize test*.*\r\nE:FILESIZE COM\r\nargc = 65\r\n                         Bytes\r\n             File   ftell()   fopen() Sectors    kB\r\n----------------- --------- --------- ------- -----\r\n       TESTBDOS.C      1280      1280      10     2\r\n     TESTARGS.COM     12544     12544      98    13\r\n     TESTBDOS.COM     12288     12288      96    12\r\n         TEST.LOG     22912     22912     179    23\r\n      TEST-OPT.AS       896       896       7     1\r\n        TESTAES.C     13952     13952     109    14\r\n      TESTAES.COM     15616     15616     122    16\r\n       TESTARGS.C       256       256       2     1\r\n       TESTBIOS.C      1280      1280      10     2\r\n       TESTBUG.AS      4480      4480      35     5\r\n        TESTBUG.C       512       512       4     1\r\n        TESTENV.C       256       256       2     1\r\n       TESTFILE.C       896       896       7     1\r\n       TESTFTIM.C       512       512       4     1\r\n       TESTHELL.C       128       128       1     1\r\n         TESTIO.C       768       768       6     1\r\n       TESTIO.ERR        15        15       1     1\r\n       TESTIO.STA         8         8       1     1\r\n          TESTL.C       128       128       1     1\r\n      TESTLTOF.AS      8576      8576      67     9\r\n       TESTLTOF.C      1408      1408      11     2\r\n      TESTOPTH.AS       384       384       3     1\r\n        TESTOVR.C       512       512       4     1\r\n       TESTOVR1.C       128       128       1     1\r\n       TESTOVR2.C       128       128       1     1\r\n         TESTPR.C       640       640       5     1\r\n        TESTPWD.C      1152      1152       9     2\r\n       TESTQSRT.C       768       768       6     1\r\n         TESTRC.C       256       256       2     1\r\n     TESTOVR2.OBJ       256       256       2     1\r\n        TESTREL.C       128       128       1     1\r\n        TESTSTR.C       896       896       7     1\r\n        TESTSUB.C      1280      1280      10     2\r\n       TESTTRIG.C      4480      4480      35     5\r\n        TESTUID.C       384       384       3     1\r\n        TESTVER.C      1920      1920      15     2\r\n      TESTVER.SUB       128       128       1     1\r\n       TESTVIEW.C      1024      1024       8     1\r\n       TESTWILD.C       896       896       7     1\r\n      TESTVER.COM     12800     12800     100    13\r\n         TEST.DAT         7         7       1     1\r\n     TESTBIOS.COM     12544     12544      98    13\r\n     TESTFILE.COM     12416     12416      97    13\r\n     TESTFTIM.COM     15104     15104     118    15\r\n     TESTHELL.COM      8704      8704      68     9\r\n       TESTIO.COM     12288     12288      96    12\r\n      TESTOVR.COM     12544     12544      98    13\r\n     TESTOVR1.OVR       128       128       1     1\r\n     TESTOVR2.OVR       128       128       1     1\r\n     TESTOVRX.SYM      2688      2688      21     3\r\n       TESTPR.COM     12416     12416      97    13\r\n       TESTRC.COM     11904     11904      93    12\r\n      TESTSTR.COM     12672     12672      99    13\r\n     TESTTRIG.COM     17024     17024     133    17\r\n      TESTUID.COM     12032     12032      94    12\r\n     TESTVIEW.COM     12160     12160      95    12\r\n     TESTWILD.COM     12032     12032      94    12\r\n      TEST280.LOG     21120     21120     165    21\r\n     TEST-OPT.AS2      1311      1311      11     2\r\n         TEST.SUB       896       896       7     1\r\n      TEST280.SUB      1024      1024       8     1\r\n     TEST-OPT.AS3      1214      1214      10     2\r\n     TESTOVRX.OBJ      2944      2944      23     3\r\n     TESTOVR1.OBJ       256       256       2     1\r\n\r\n10E>; Z280 optimiser\r\n10E>optimh -f test-opt.as test-opt.as2\r\nE:OPTIMH   COM\r\n 15 bytes speed optimised away\r\n 68 bytes replaced\r\n\r\n10E>optimh test-opt.as test-opt.as3\r\nE:OPTIMH   COM\r\n 25 bytes size optimised away\r\n 62 bytes replaced\r\n\r\n10E>; All tests completed\r\n10E>put console to console\r\nA:PUT      COM  (User 0)\r\n"
  },
  {
    "path": "test/TEST280.SUB",
    "content": "era test280.log\r\nput console output to file test280.log [system]\r\ndate\r\n; Compile all test280\r\nc280 -v -o2 filesize.c\r\nc280 -v -o2 testver.c\r\nc280 -v -o2 testio.c\r\nc280 -v -o2 testuid.c\r\nc280 -v -o2 teststr.c\r\nc280 -v -o2 testbios.c\r\nc280 -v -o2 testbdos.c\r\nc280 -v -o2 testtrig.c -lf\r\nc280 -v -o2 testftim.c\r\nc280 -v -o2 testfile.c\r\nc280 -v -o2 testaes.c\r\nc280 -v -o2 testrc.c\r\nc280 -v -o2 testview.c\r\nc280 -v -o2 testwild.c\r\nc280 -ftestovrx.sym -v -o2 testovr.c -lovr\r\nc280 -y -o2 -v testovr2.c testovrx.sym\r\nc280 -y -o2 -v testovr1.c testovrx.sym\r\nc280 -a -v -o2 testhell.c -lc\r\nc280 -v -o2 testpr.c\r\ntestver\r\nera testio.sta\r\nera testio.out\r\nera testio.err\r\ntestovr\r\ntestio\r\ntestuid\r\nteststr\r\ntestbios\r\ntestbdos\r\ntesttrig\r\ntestftim\r\ntestfile\r\ntestaes\r\ntestrc\r\ntestview testh*.c testver.c\r\ntestwild test*.c test*.com\r\ntesthell\r\ntestpr\r\nfilesize test*.*\r\n; Z280 optimiser\r\noptimh -f test-opt.as test-opt.as2\r\noptimh test-opt.as test-opt.as3\r\n; All tests completed\r\nput console to console\r\n"
  },
  {
    "path": "test/TESTAES.C",
    "content": "/*  \r\n*   Byte-oriented AES-256 implementation.\r\n*   All lookup tables replaced with 'on the fly' calculations. \r\n*\r\n*   Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com\r\n*   Other contributors: Hal Finney\r\n*\r\n*   Permission to use, copy, modify, and distribute this software for any\r\n*   purpose with or without fee is hereby granted, provided that the above\r\n*   copyright notice and this permission notice appear in all copies.\r\n*\r\n*   THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\r\n*   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\r\n*   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\r\n*   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r\n*   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\r\n*   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\r\n*   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r\n*\r\n*   Some minor changes made for CP/M-80 C compiler compatibility\r\n*   from Peter Dassow, see http://www.z80.eu/c-compiler.html\r\n*/\r\n\r\ntypedef unsigned char uint8_t;\r\n\r\ntypedef struct {\r\n        uint8_t key[32]; \r\n        uint8_t enckey[32]; \r\n        uint8_t deckey[32];\r\n} aes256_context;\r\n\r\ntypedef uint8_t * u8ptr;\r\ntypedef aes256_context * aes256_ptr;\r\n\r\n#define F(x)   (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b))\r\n#define FD(x)  (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))\r\n\r\n/* #define BACK_TO_TABLES */\r\n#ifdef BACK_TO_TABLES\r\n\r\nconst uint8_t sbox[256] = {\r\n    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,\r\n    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\r\n    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,\r\n    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,\r\n    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,\r\n    0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,\r\n    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,\r\n    0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,\r\n    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,\r\n    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,\r\n    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,\r\n    0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,\r\n    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,\r\n    0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,\r\n    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,\r\n    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,\r\n    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,\r\n    0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,\r\n    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,\r\n    0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,\r\n    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,\r\n    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,\r\n    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,\r\n    0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,\r\n    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,\r\n    0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,\r\n    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,\r\n    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,\r\n    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,\r\n    0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,\r\n    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,\r\n    0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16\r\n};\r\nconst uint8_t sboxinv[256] = {\r\n    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,\r\n    0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,\r\n    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,\r\n    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,\r\n    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,\r\n    0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,\r\n    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,\r\n    0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,\r\n    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,\r\n    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,\r\n    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,\r\n    0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,\r\n    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,\r\n    0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,\r\n    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,\r\n    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,\r\n    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,\r\n    0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,\r\n    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,\r\n    0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,\r\n    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,\r\n    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,\r\n    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,\r\n    0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,\r\n    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,\r\n    0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,\r\n    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,\r\n    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,\r\n    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,\r\n    0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,\r\n    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,\r\n    0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d\r\n};\r\n\r\n#define rj_sbox(x)     sbox[(x)]\r\n#define rj_sb_inv(x) sboxinv[(x)]\r\n\r\n#else /* tableless subroutines */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nuint8_t gf_alog(x) /* calculate anti-logarithm gen 3 */\r\nuint8_t x;\r\n{\r\n    uint8_t atb = 1, z;\r\n\r\n    while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;}\r\n\r\n    return atb;\r\n} /* gf_alog */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nuint8_t gf_log(x) /* calculate logarithm gen 3 */\r\nuint8_t x;\r\n{\r\n    uint8_t atb = 1, i = 0, z;\r\n\r\n    do {\r\n        if (atb == x) break;\r\n        z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;\r\n    } while (++i > 0);\r\n\r\n    return i;\r\n} /* gf_log */\r\n\r\n\r\n/* -------------------------------------------------------------------------- */\r\nuint8_t gf_mulinv(x) /* calculate multiplicative inverse */\r\nuint8_t x;\r\n{\r\n    return (x) ? gf_alog(255 - gf_log(x)) : 0;\r\n} /* gf_mulinv */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nuint8_t rj_sbox(x)\r\nuint8_t x;\r\n{\r\n    uint8_t y, sb;\r\n\r\n    sb = y = gf_mulinv(x);\r\n    y = (y<<1)|(y>>7); sb ^= y;  y = (y<<1)|(y>>7); sb ^= y; \r\n    y = (y<<1)|(y>>7); sb ^= y;  y = (y<<1)|(y>>7); sb ^= y;\r\n\r\n    return (sb ^ 0x63);\r\n} /* rj_sbox */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nuint8_t rj_sb_inv(x)\r\nuint8_t x;\r\n{\r\n    uint8_t y, sb;\r\n\r\n    y = x ^ 0x63;\r\n    sb = y = (y<<1)|(y>>7);\r\n    y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y;\r\n\r\n    return gf_mulinv(sb);\r\n} /* rj_sb_inv */\r\n\r\n#endif\r\n\r\n/* -------------------------------------------------------------------------- */\r\nuint8_t rj_xtime(x)\r\nuint8_t x; \r\n{\r\n    return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);\r\n} /* rj_xtime */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_subBytes(buf)\r\nuint8_t *buf;\r\n{\r\n    register uint8_t i = 16;\r\n\r\n    while (i--) buf[i] = rj_sbox(buf[i]);\r\n} /* aes_subBytes */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_sb_inv(buf)\r\nu8ptr buf;\r\n{\r\n    register uint8_t i = 16;\r\n\r\n    while (i--) buf[i] = rj_sb_inv(buf[i]);\r\n} /* aes_sb_inv */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_addRoundKey(buf,key)\r\nu8ptr buf,key;\r\n{\r\n    register uint8_t i = 16;\r\n\r\n    while (i--) buf[i] ^= key[i];\r\n} /* aes_addRoundKey */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_ar_cpy(buf,key,cpk)\r\nu8ptr buf,key,cpk;\r\n{\r\n    register uint8_t i = 16;\r\n\r\n    while (i--)  buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i];\r\n} /* aes_ar_cpy */\r\n\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_shiftRows(buf)\r\nu8ptr buf;\r\n{\r\n    register uint8_t i, j; /* to make it potentially parallelable :) */\r\n\r\n    i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i;\r\n    i = buf[10]; buf[10] = buf[2]; buf[2] = i;\r\n    j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j;\r\n    j = buf[14]; buf[14] = buf[6]; buf[6]  = j;\r\n\r\n} /* aes_shiftRows */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_sr_inv(buf)\r\nu8ptr buf;\r\n{\r\n    register uint8_t i, j; /* same as above :) */\r\n\r\n    i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i;\r\n    i = buf[2]; buf[2] = buf[10]; buf[10] = i;\r\n    j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j;\r\n    j = buf[6]; buf[6] = buf[14]; buf[14] = j;\r\n\r\n} /* aes_sr_inv */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_mixColumns(buf)\r\nu8ptr buf;\r\n{\r\n    register uint8_t i, a, b, c, d, e;\r\n\r\n    for (i = 0; i < 16; i += 4)\r\n    {\r\n        a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];\r\n        e = a ^ b ^ c ^ d;\r\n        buf[i] ^= e ^ rj_xtime(a^b);   buf[i+1] ^= e ^ rj_xtime(b^c);\r\n        buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a);\r\n    }\r\n} /* aes_mixColumns */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_mc_inv(buf)\r\nu8ptr buf;\r\n{\r\n    register uint8_t i, a, b, c, d, e, x, y, z;\r\n\r\n    for (i = 0; i < 16; i += 4)\r\n    {\r\n        a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];\r\n        e = a ^ b ^ c ^ d;\r\n        z = rj_xtime(e);\r\n        x = e ^ rj_xtime(rj_xtime(z^a^c));  y = e ^ rj_xtime(rj_xtime(z^b^d));\r\n        buf[i] ^= x ^ rj_xtime(a^b);   buf[i+1] ^= y ^ rj_xtime(b^c);\r\n        buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a);\r\n    }\r\n} /* aes_mc_inv */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_expandEncKey(k,rc)\r\nu8ptr k, rc; \r\n{\r\n    register uint8_t i;\r\n\r\n    k[0] ^= rj_sbox(k[29]) ^ (*rc);\r\n    k[1] ^= rj_sbox(k[30]);\r\n    k[2] ^= rj_sbox(k[31]);\r\n    k[3] ^= rj_sbox(k[28]);\r\n    *rc = F( *rc);\r\n\r\n    for(i = 4; i < 16; i += 4)  { k[i] ^= k[i-4];   k[i+1] ^= k[i-3];\r\n      k[i+2] ^= k[i-2]; k[i+3] ^= k[i-1]; }\r\n    k[16] ^= rj_sbox(k[12]);\r\n    k[17] ^= rj_sbox(k[13]);\r\n    k[18] ^= rj_sbox(k[14]);\r\n    k[19] ^= rj_sbox(k[15]);\r\n\r\n    for(i = 20; i < 32; i += 4) { k[i] ^= k[i-4];   k[i+1] ^= k[i-3];\r\n      k[i+2] ^= k[i-2]; k[i+3] ^= k[i-1]; }\r\n\r\n} /* aes_expandEncKey */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_expDecKey(k, rc)\r\nu8ptr k, rc; \r\n{\r\n    uint8_t i;\r\n\r\n    for(i = 28; i > 16; i -= 4) { k[i+0] ^= k[i-4]; k[i+1] ^= k[i-3]; \r\n      k[i+2] ^= k[i-2]; k[i+3] ^= k[i-1]; }\r\n\r\n    k[16] ^= rj_sbox(k[12]);\r\n    k[17] ^= rj_sbox(k[13]);\r\n    k[18] ^= rj_sbox(k[14]);\r\n    k[19] ^= rj_sbox(k[15]);\r\n\r\n    for(i = 12; i > 0; i -= 4)  { k[i+0] ^= k[i-4]; k[i+1] ^= k[i-3];\r\n      k[i+2] ^= k[i-2]; k[i+3] ^= k[i-1]; }\r\n\r\n    *rc = FD(*rc);\r\n    k[0] ^= rj_sbox(k[29]) ^ (*rc);\r\n    k[1] ^= rj_sbox(k[30]);\r\n    k[2] ^= rj_sbox(k[31]);\r\n    k[3] ^= rj_sbox(k[28]);\r\n} /* aes_expDecKey */\r\n\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes256_init(ctx, k)\r\naes256_ptr ctx;\r\nu8ptr k;\r\n{\r\n    uint8_t rcon = 1;\r\n    register uint8_t i;\r\n\r\n    for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];\r\n    for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon);\r\n} /* aes256_init */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes_done(ctx)\r\naes256_ptr ctx;\r\n{\r\n    register uint8_t i;\r\n\r\n    for (i = 0; i < sizeof(ctx->key); i++) \r\n        ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;\r\n} /* aes_done */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes256_encrypt_ecb(ctx, buf)\r\naes256_ptr ctx;\r\nu8ptr buf;\r\n{\r\n    uint8_t i, rcon;\r\n\r\n    aes_ar_cpy(buf, ctx->enckey, ctx->key);\r\n    for(i = 1, rcon = 1; i < 14; ++i)\r\n    {\r\n        aes_subBytes(buf);\r\n        aes_shiftRows(buf);\r\n        aes_mixColumns(buf);\r\n        if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);\r\n        else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);\r\n    }\r\n    aes_subBytes(buf);\r\n    aes_shiftRows(buf);\r\n    aes_expandEncKey(ctx->key, &rcon); \r\n    aes_addRoundKey(buf, ctx->key);\r\n} /* aes256_encrypt */\r\n\r\n/* -------------------------------------------------------------------------- */\r\nvoid aes256_decrypt_ecb(ctx, buf)\r\naes256_ptr ctx;\r\nu8ptr buf;\r\n{\r\n    uint8_t i, rcon;\r\n\r\n    aes_ar_cpy(buf, ctx->deckey, ctx->key);\r\n    aes_sr_inv(buf);\r\n    aes_sb_inv(buf);\r\n\r\n    for (i = 14, rcon = 0x80; --i;)\r\n    {\r\n        if( ( i & 1 ) )           \r\n        {\r\n            aes_expDecKey(ctx->key, &rcon);\r\n            aes_addRoundKey(buf, &ctx->key[16]);\r\n        }\r\n        else aes_addRoundKey(buf, ctx->key);\r\n        aes_mc_inv(buf);\r\n        aes_sr_inv(buf);\r\n        aes_sb_inv(buf);\r\n    }\r\n    aes_addRoundKey( buf, ctx->key); \r\n} /* aes256_decrypt */\r\n\r\n#define DUMP(s, i, buf, sz)  {printf(s);                   \\\r\n                              for (i = 0; i < (sz);i++)    \\\r\n                                  printf(\"%02x \", buf[i]); \\\r\n                              printf(\"\\n\");}\r\n\r\naes256_context ctx; \r\nuint8_t key[32];\r\nuint8_t buf[16];\r\n\r\nint main (int argc, char *argv[])\r\n{\r\n    int i;\r\n\r\n    /* put a test vector */\r\n    for (i = 0; i < sizeof(buf);i++) buf[i] = i * 16 + i;\r\n    for (i = 0; i < sizeof(key);i++) key[i] = i;\r\n\r\n    DUMP(\"txt: \", i, buf, sizeof(buf));\r\n    DUMP(\"key: \", i, key, sizeof(key));\r\n    printf(\"---\\n\");\r\n\r\n    aes256_init(&ctx, key);\r\n    aes256_encrypt_ecb(&ctx, buf);\r\n\r\n    DUMP(\"enc: \", i, buf, sizeof(buf));\r\n    printf(\"tst: 8e a2 b7 ca 51 67 45 bf ea fc 49 90 4b 49 60 89\\n\");\r\n\r\n    aes256_init(&ctx, key);\r\n    aes256_decrypt_ecb(&ctx, buf);\r\n    DUMP(\"dec: \", i, buf, sizeof(buf));\r\n\r\n    aes_done(&ctx);\r\n\r\n    return 0;\r\n} /* main */\r\n"
  },
  {
    "path": "test/TESTARGS.C",
    "content": "#include <stdio.h>\r\n#include <float.h>\r\n\r\nint main(int argc, char ** argv) {\r\n    int i;\r\n    for(i=0;i<argc;i++) {\r\n        printf(\"%d: %s\\n\",i,argv[i]);\r\n    }\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTBDOS.C",
    "content": "/*----------------------------------------------------------------------*\\\r\n | testbdos\t\t\t\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | A small program to test the updated bdos() function of Hi-Tech C\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Jon Saxton\tApril 2014\t\t\t\t\t\t|\r\n\\*----------------------------------------------------------------------*/\r\n\r\n#include <cpm.h>\r\n#include <stdio.h>\r\n\r\nvoid test(short func, void *data)\r\n{\r\n    int e;\r\n    short rc = bdose(func, data);\r\n    e = errno;\r\n    printf(\"rc = %04x, errno = %d\\n\", rc, errno);\r\n    errno = e;\r\n    if (errno)\r\n\tperror(\"test\");\r\n}\r\n\r\nvoid vogon(char *fn)\t/* Just for the debugger */\r\n{\r\n    char fcb[50];\r\n    struct _pfcb\r\n    {\r\n        char *str;\r\n        char *fcb;\r\n    } pfcb;\r\n    pfcb.fcb = fcb;\r\n    pfcb.str = fn;\r\n    test(152, &pfcb);\r\n    test(15, fcb);\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int e;\r\n    char s[6];\r\n    printf(\"First some perror() tests ...\\n\\n\");\r\n    for (e=0; e<28; ++e)\r\n    {\r\n        sprintf(s,\"%2d\",e);\r\n        errno = e;\r\n        perror(s);\r\n    }\r\n    putchar('\\n');\r\n    bdose(0x2D, 0xFF);\r\n/*\r\n    test(14,(void *)3);\r\n    test(14,(void *)6);\r\n*/\r\n/*\r\n    vogon(\"b:zpm3ldr.rel;asdf\");\r\n    if (argc > 1)\r\n       vogon(argv[1]);\r\n*/\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTBIOS.C",
    "content": "/*----------------------------------------------------------------------*\\\r\n | TESTBIOS\t\t\t\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | A small program to test BIOS calls with a variety of parameters.\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Written for CP/M 3.  May not work on CP/M 2.2.\t\t\t|\r\n\\*----------------------------------------------------------------------*/\r\n\r\n#include <cpm.h>\r\n#include <stdio.h>\r\n\r\nchar\r\n    src[] = \"Did this work?\",\r\n    dst[sizeof src];\r\n\r\nint main(int argc, char *argv[], char *z3env)\r\n{\r\n    short\r\n\trc;\r\n\r\n    if (z3env)\r\n\tprintf(\"Z3ENV at %04x\\n\");\r\n    else\r\n\tputs(\"Z3ENV is not established.  (This is not an error.)\");\r\n\r\n    for (rc = 1; rc < argc; ++rc)\r\n\tprintf(\"%2d: %s\\n\", argv[rc]);\r\n\r\n    /* BIOS call with no parameters */\r\n    printf(\"Press a key: \");\r\n    rc = bios(3,0xBCBC,0xDEDE);\r\n    printf(\"rc = %04x, character = \", rc);\r\n\r\n    /* BIOS call with one parameter (in BC) */\r\n    rc = bios(4, rc, 0xDEDE);\r\n\r\n    /* BIOS call with one parameter (in A) */\r\n    rc = bios(27,1,0xBCBC,0xDEDE,0x1414);\r\n\r\n    puts(\"\\nThe next message should say \\\"Did this work?\\\"\");\r\n\r\n    /* BIOS call with three parameters (BC, DE & HL) */\r\n    bios(29,0x0101);\r\n    bios(25,sizeof src, src, dst);\r\n    puts(dst);\r\n}\r\n"
  },
  {
    "path": "test/TESTFILE.C",
    "content": "#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <unixio.h>\r\n\r\nint main() {\r\n    FILE * f;\r\n    int i;\r\n    fprintf(stderr,\"create file...\\n\");\r\n    f=fopen(\"test.dat\",\"w\");\r\n    if(!f) {\r\n        fprintf(stderr,\"cannot create file (%d)\\n\",errno);\r\n        return -1;\r\n    }\r\n    fprintf(f,\"Hello\\n\");\r\n    fclose(f);\r\n    i=rename(\"test.dat\",\"testx.dat\");\r\n    fprintf(stderr,\"rename file (%d)\\n\",i);\r\n    i=unlink(\"testx.dat\");\r\n    fprintf(stderr,\"delete file (%d)\\n\",i);\r\n    i=unlink(\"testx.dat\");\r\n    fprintf(stderr,\"delete file (%d)\\n\",i);\r\n    fprintf(stderr,\"create file...\\n\");\r\n    f=fopen(\"test.dat\",\"w\");\r\n    if(!f) {\r\n        fprintf(stderr,\"cannot create file (%d)\\n\",errno);\r\n        return -1;\r\n    }\r\n    fprintf(f,\"Hello\\n\");\r\n    fclose(f);\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTFTIM.C",
    "content": "\r\n#include <stdio.h>      /* for printf */\r\n#include <time.h>       /* for strftime */\r\n\r\nchar test[80];\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n      int len;\r\n      char *fmt;\r\n      time_t now;\r\n\r\n      time(&now);\r\n\r\n      fmt = (argc == 1) ? \"%I:%M %p\\n%c\\n\" : argv[1];\r\n      len = strftime(test,sizeof test, fmt, localtime(&now));\r\n      printf(\"%d: %s\\n\", len, test);\r\n      return !len;\r\n}\r\n"
  },
  {
    "path": "test/TESTHELL.C",
    "content": "#include <stdio.h>\r\n\r\nint main() {\r\n    printf(\"Hello\\n\");\r\n}\r\n"
  },
  {
    "path": "test/TESTIO.C",
    "content": "#include \"stdio.h\"\r\n#include \"cpm.h\"\r\n#include <stdio.h>\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    int i;\r\n    int minor=0;\r\n    int major=0;\r\n    FILE *f;\r\n    char c=34;\r\n\r\n    fprintf(stderr,\"%s,%02x\\n\",\"hexa\",c);\r\n    freopen(\"testio.err\",\"w\",stderr);\r\n    fprintf(stderr,\"argc=%d\\n\",argc);\r\n    for(i=0;i<argc;i++) {\r\n        fprintf(stderr,\"argv=%s\\n\",argv[i]);\r\n    }\r\n    f=fopen(\"testio.sta\",\"w\");\r\n    fprintf(f,\"stamp\\r\\n\");\r\n    fclose(f);\r\n    i=bdos(CPMVERS,0);\r\n    switch(i) {\r\n    case 0x00:\r\n        major=1;\r\n        minor=0;\r\n        break;\r\n    default:\r\n        major=((i>>4)&0x0F);\r\n        minor=(i&0x0F);\r\n        break;\r\n    }\r\n    printf(\"CP/M BDOS %d.%d\\n\",major,minor);\r\n    return 0;\r\n}\r\n\r\n"
  },
  {
    "path": "test/TESTOVR.C",
    "content": "#include <cpm.h>\r\n#include <stdio.h>\r\n#include <overlay.h>\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    intptr_t i;\r\n    printf(\"overlay test\\n\");\r\n    i=ovrload(\"testovr1\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    i=ovrload(\"testovr1\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    i=ovrload(\"testovr2\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    i=ovrload(\"testovr1\",0);\r\n    printf(\"overlay return is %d\\n\",i);\r\n    return 0;\r\n}\r\n\r\n"
  },
  {
    "path": "test/TESTOVR1.C",
    "content": "void * yop(void *a) {\r\n    printf(\"hello from overlay 01\\n\");\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTOVR2.C",
    "content": "void * yop(void *a) {\r\n    printf(\"hello from overlay 02\\n\");\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTPR.C",
    "content": "/* Test printf()'s ability to print long strings */\r\n\r\n#include <stdio.h>\r\n\r\nchar test[500] = { \"\\\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\" };\r\n\r\nint main() {\r\n  printf(\"len: %d\\n\", strlen(test));\r\n  printf(\"string: %s\\n\", test);\r\n  return 0;\r\n}\r\n\r\n"
  },
  {
    "path": "test/TESTPWD.C",
    "content": "#include <cpm.h>\r\n#include <stdio.h>\r\n#include <string.h>\r\n#include <ctype.h>\r\n\r\nstruct fcb ffcb;\r\n\r\nchar password[20];\r\n\r\nchar *getpass(struct fcb *pfcb)\r\n{\r\n    char\r\n       *cp,\r\n        lyne[100];\r\n    printf(\"Enter password: \");\r\n    fflush(stdout);\r\n    gets(lyne);\r\n    if (strlen(lyne))\r\n    {\r\n        for (cp = lyne; *cp; ++cp)\r\n            if (islower(*cp))\r\n                *cp = toupper(*cp);\r\n        strncpy(password,lyne,8);\r\n        strcat(password, \"        \");\r\n        return password;\r\n    }\r\n    return NULL;\r\n}\r\n\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    FILE\r\n        *f;\r\n    int\r\n        c;\r\n\r\n    if (argc < 2)\r\n        return 0;\r\n\r\n    bdos(CPMERRM, 0xFF);\r\n    setfcb(&ffcb, argv[2]);\r\n/*  _passwd = getpass;  */\r\n\r\n    f = fopen(argv[1],\"r\");\r\n\r\n    if (f)\r\n    {\r\n        printf(\"Processing %s:\\n\", argv[1]);\r\n        while (!feof(f))\r\n        {\r\n             c = fgetc(f);\r\n             if (!feof(f))\r\n                 putchar(c);\r\n        }\r\n        fclose(f);\r\n        return 0;\r\n    }\r\n    else\r\n    {\r\n        printf(\"Failed to open %s\", argv[1]);\r\n        perror(\" - \");\r\n    }\r\n    return 1;\r\n}\r\n"
  },
  {
    "path": "test/TESTRC.C",
    "content": "#include \"stdio.h\"\r\n#include \"cpm.h\"\r\n#include <stdio.h>\r\n\r\n#include <stdio.h>\r\n#include <sys.h>\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    return 33;\r\n}\r\n\r\n"
  },
  {
    "path": "test/TESTREL.C",
    "content": "#include <stdio.h>\r\n\r\nint main() {\r\n    printf(\"Hello Reloc\\n\");\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTSTR.C",
    "content": "#include <stdio.h>\r\n#include <string.h>\r\n#include <ctype.h>\r\n\r\nchar *v[]={\r\n    \"test\",\"Test\",\r\n    \"test\",\"test\",\r\n    \"test1\",\"test\",\r\n    \"test\",\"test1\",\r\n    \"rest\",\"test\",\r\n    0\r\n};\r\n\r\nint main() {\r\n    int i=0;\r\n    printf(\"strcmp test:\\n\");\r\n    while(v[i]) {\r\n        printf(\"- %s<>%s=%d\\n\",v[i],v[i+1],strcmp(v[i],v[i+1]));\r\n        i=i+2;\r\n    }\r\n    i=0;\r\n    printf(\"stricmp test:\\n\");\r\n    while(v[i]) {\r\n        printf(\"- %s<>%s=%d\\n\",v[i],v[i+1],stricmp(v[i],v[i+1]));\r\n        i=i+2;\r\n    }\r\n    printf(\"strnicmp test:\\n\");\r\n    printf(\"- %s<>%s=%d\\n\",\"test\",\"test1\",strnicmp(\"test\",\"test1\",strlen(\"test\")));\r\n    printf(\"- %s<>%s=%d\\n\",\"test1\",\"test\",strnicmp(\"test1\",\"test\",strlen(\"test\")));\r\n    printf(\"- %s<>%s=%d\\n\",\"Test1\",\"test\",strnicmp(\"Test1\",\"test\",strlen(\"test\")));\r\n    return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTTRIG.C",
    "content": "/*\r\n * TESTTRIG.C\r\n *\r\n * Test to verify release v3.09-1 has fixed floating point\r\n * Trigonometry routines.\r\n *\r\n * Compile using\r\n *\r\n * \tc -o -lf testtrig.c\r\n *\r\n * From a USENET newsgroup post to comp.os.cpm on 2013-09-02 by \"Ed\"\r\n *\r\n * \"LIBF.LIB supplied with the freeware Hitech-C 3.09 release\r\n *  produces inaccurate trig results.  I found that by simply\r\n *  recompiling the library with the existing source files from\r\n *  FLOAT.HUF, it fixed the problem.  Absolutely no changes\r\n *  to the sources were required.\r\n *\r\n *  Below is a comparison of results between the original and\r\n *  rebuilt library.\r\n *\r\n * ---\r\n *\r\n * (using original LIBF.LIB)\r\n *\r\n *   n  LN             EXP            SIN            COS            ATAN\r\n *  01  0.000000e+00   2.703595e+00   8.502954e-01   5.339794e-01   7.800306e-01\r\n *  02  6.931469e-01   7.309311e+00   9.107645e-01  -4.232263e-01   1.116727e+00\r\n *  03  1.098605e+00   1.976185e+01   1.411983e-01  -9.956650e-01   1.257505e+00\r\n *  04  1.386294e+00   5.342758e+01  -7.673132e-01  -6.481950e-01   1.333912e+00\r\n *  05  1.609434e+00   1.444486e+02  -9.609912e-01   2.909977e-01   1.381350e+00\r\n *  06  1.791752e+00   3.905289e+02  -2.795844e-01   9.680709e-01   1.413529e+00\r\n *  07  1.945900e+00   1.055842e+03   6.572353e-01   7.495101e-01   1.436745e+00\r\n *  08  2.079441e+00   2.854568e+03   9.921404e-01  -1.529755e-01   1.454266e+00\r\n *  09  2.197222e+00   7.717445e+03   4.124018e-01  -9.213704e-01   1.467951e+00\r\n *  10  2.302581e+00   2.086538e+04  -5.440205e-01  -8.359161e-01   1.478932e+00\r\n *  11  2.397890e+00   5.641094e+04  -1.003614e+00   1.190640e-02   1.487935e+00\r\n *  12  2.484899e+00   1.525148e+05  -5.370088e-01   8.565310e-01   1.495450e+00\r\n *  13  2.564940e+00   4.123360e+05   4.199748e-01   9.057026e-01   1.501817e+00\r\n *  14  2.639047e+00   1.114781e+06   9.952080e-01   1.294013e-01   1.507279e+00\r\n *  15  2.708037e+00   3.013969e+06   6.509256e-01  -7.748882e-01   1.512017e+00\r\n *  16  2.772588e+00   8.148225e+06  -2.875695e-01  -9.574937e-01   1.516165e+00\r\n *  17  2.833212e+00   2.202966e+07  -9.671226e-01  -2.681288e-01   1.519827e+00\r\n *  18  2.890369e+00   5.955735e+07  -7.518865e-01   6.661855e-01   1.523084e+00\r\n *  19  2.944436e+00   1.610253e+08   1.494345e-01   9.902740e-01   1.525998e+00\r\n * \r\n * \r\n * (using rebuilt LIBF.LIB)\r\n * \r\n *   n  LN             EXP            SIN            COS            ATAN\r\n *  01  0.000000e+00   2.718280e+00   8.414706e-01   5.403037e-01   7.853970e-01\r\n *  02  6.931469e-01   7.389050e+00   9.092973e-01  -4.161461e-01   1.107148e+00\r\n *  03  1.098612e+00   2.008552e+01   1.411217e-01  -9.899922e-01   1.249045e+00\r\n *  04  1.386294e+00   5.459808e+01  -7.568023e-01  -6.536445e-01   1.325817e+00\r\n *  05  1.609438e+00   1.484130e+02  -9.589242e-01   2.836605e-01   1.373400e+00\r\n *  06  1.791759e+00   4.034281e+02  -2.794159e-01   9.601696e-01   1.405647e+00\r\n *  07  1.945910e+00   1.096632e+03   6.569859e-01   7.539025e-01   1.428899e+00\r\n *  08  2.079441e+00   2.980951e+03   9.893581e-01  -1.454975e-01   1.446441e+00\r\n *  09  2.197224e+00   8.103068e+03   4.121197e-01  -9.111288e-01   1.460139e+00\r\n *  10  2.302584e+00   2.202640e+04  -5.440195e-01  -8.390731e-01   1.471127e+00\r\n *  11  2.397894e+00   5.987400e+04  -9.999901e-01   4.422163e-03   1.480136e+00\r\n *  12  2.484906e+00   1.627543e+05  -5.365736e-01   8.438515e-01   1.487654e+00\r\n *  13  2.564949e+00   4.424121e+05   4.201658e-01   9.074482e-01   1.494024e+00\r\n *  14  2.639056e+00   1.202602e+06   9.906070e-01   1.367416e-01   1.499488e+00\r\n *  15  2.708049e+00   3.269002e+06   6.502892e-01  -7.596840e-01   1.504228e+00\r\n *  16  2.772588e+00   8.886073e+06  -2.879012e-01  -9.576598e-01   1.508377e+00\r\n *  17  2.833213e+00   2.415486e+07  -9.613965e-01  -2.751657e-01   1.512040e+00\r\n *  18  2.890371e+00   6.565973e+07  -7.509890e-01   6.603144e-01   1.515297e+00\r\n *  19  2.944438e+00   1.784813e+08   1.498741e-01   9.887048e-01   1.518213e+00\r\n *  \"\r\n */\r\n\r\n#include <math.h>\r\n\r\nfloat a,b,c,d,e,f,g;\r\nint i;\r\n\r\nint main() {\r\n  a = 1.0;\r\n  printf(\"\\n  n  LN             EXP            SIN            COS            ATAN\");\r\n  for(i=1;i<20;i++)\r\n {\r\n  b = log(a);\r\n  c = exp(a);\r\n  d = sin(a);\r\n  e = cos(a);\r\n  f = atan(a);\r\n\r\n  printf(\"\\n%3.2d\",i);\r\n  printf(\"%14.6e \",b);\r\n  printf(\"%14.6e \",c);\r\n  printf(\"%14.6e \",d);\r\n  printf(\"%14.6e \",e);\r\n  printf(\"%14.6e \",f);\r\n\r\n  a=a+1.0;\r\n  }\r\n  printf(\"\\n\");\r\n  return 0;\r\n}\r\n"
  },
  {
    "path": "test/TESTUID.C",
    "content": "#include \"stdio.h\"\r\n#include \"cpm.h\"\r\n#include <stdio.h>\r\n\r\n#include <stdio.h>\r\n#include <sys.h>\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    printf(\"getuid=%d\\n\",getuid());\r\n    printf(\"setuid=%d\\n\",setuid(3));\r\n    printf(\"getuid=%d\\n\",getuid());\r\n    printf(\"getuid=%d\\n\",getuid());\r\n    return 0;\r\n}\r\n\r\n"
  },
  {
    "path": "test/TESTVER.C",
    "content": "#include \"stdio.h\"\r\n#include \"cpm.h\"\r\n#include <stdio.h>\r\n\r\nextern char _exact;\t/* exact file size mode */\r\nextern char *_libcver;\t/* LIBC version string */\r\n\r\nint main(int argc, char ** argv)\r\n{\r\n    int i;\r\n    int minor=0;\r\n    int major=0;\r\n    int machine;\r\n    int system;\r\n    int* bdosaddr=(int*)6;\r\n    int* biosaddr=(int*)1;\r\n    unsigned int tpa;\r\n\r\n    i=bdos(CPMVERS,0);\r\n    switch(i) {\r\n    case 0x00:\r\n        major=1;\r\n        minor=0;\r\n        break;\r\n    default:\r\n        major=((i>>4)&0x0F);\r\n        minor=(i&0x0F);\r\n        break;\r\n    }\r\n    machine=(i>>12)&0x0F;\r\n    system=(i>>8)&0x0F;\r\n    printf(\"CP/M BDOS Version (%d.%d)\\n\",major,minor);\r\n    if(system!=0) {\r\n        printf(\"Network (%s%s%s)\\n\",system&0x01?\"[MP/M]\":\"\",system&0x02?\"[CP/Net]\":\"\",\r\n            system&0x04?\"[Multi User]\":\"\");\r\n    }\r\n    switch(machine) {\r\n    case 0:\r\n        printf(\"Machine (MCS80/Z80)\\n\",machine);\r\n        break;\r\n    case 1:\r\n        printf(\"Machine (MCS86)\\n\");\r\n        break;\r\n    case 2:\r\n        printf(\"Machine (68000/Z8000)\\n\");\r\n        break;\r\n    default:\r\n        printf(\"Machine (?)\\n\");\r\n        break;\r\n    }\r\n    printf(\"BDOS Address (0x%04x)\\n\",*bdosaddr-6);\r\n    printf(\"BIOS Address (0x%04x)\\n\",*biosaddr-3);\r\n    tpa=((*bdosaddr-6)-0x100);\r\n    fprintf(stdout,\"TPA Size (%u.%uK)\\n\",tpa/1024,(tpa % 1024)/100);\r\n\r\n    fprintf(stdout,\"C library version %s\\n\",_libcver);\r\n    switch(_exact) {\r\n    case 'C':\r\n        printf(\"Exact file size not used (CP/M 2 mode)\\n\");\r\n        break;\r\n    case 'D':\r\n        printf(\"Using DOS Plus exact file size mode\\n\");\r\n        break;\r\n    case 'I':\r\n        printf(\"Using ISIS exact file size mode\\n\");\r\n    default:\r\n        printf(\"Unknown exact file size mode 0%xH\\n\",_exact);\r\n        break;\r\n    }\r\n\r\n    return 0;\r\n}\r\n\r\n"
  },
  {
    "path": "test/TESTVER.SUB",
    "content": "testver\r\n:dir testver.*[fu\r\n"
  },
  {
    "path": "test/TESTVIEW.C",
    "content": "/*----------------------------------------------------------------------*\\\r\n | testargs.c\t\t\t\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | This program is designed to test wildcard expansion without calling\t|\r\n | routine _getargs().\t\t\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Invoke with one or more file names (which may contain wildcards).\t|\r\n | The program will display the names of any files which match.\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Note that there is no easy way to set the program name (argv[0]).\t|\r\n\\*----------------------------------------------------------------------*/\r\n\r\n#include <stdio.h>\r\n#include <cpm.h>\r\n#include <sys.h>\r\n\r\nvoid view(char *);\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int a;\r\n    bdos(45,255);\r\n\r\n    for (a = 1; a < argc; ++a)\r\n    {\r\n        printf(\"%2d: %s\\n\", a, argv[a]);\r\n        view(argv[a]);\r\n    }\r\n}\r\n\r\nvoid view(char *fn)\r\n{\r\n    FILE  *f;\r\n    char  *bp, buf[200];\r\n\r\n    f = fopen(fn, \"r\");\r\n    while (bp=fgets(buf, 200, f))\r\n        printf(\"%s\", bp);\r\n    fclose(f);\r\n}\r\n"
  },
  {
    "path": "test/TESTWILD.C",
    "content": "/*----------------------------------------------------------------------*\\\r\n | testwild.c\t\t\t\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | This program is designed to test wildcard expansion using the stdio\t|\r\n | routine _getargs().\t\t\t\t\t\t\t|\r\n |\t\t\t\t\t\t\t\t\t|\r\n | Invoke with one or more file names (which may contain wildcards).\t|\r\n | The program will display the names of any files which match.\t\t|\r\n\\*----------------------------------------------------------------------*/\r\n\r\n#include <stdio.h>\r\n#include <cpm.h>\r\n#include <sys.h>\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int a;\r\n    extern int _argc_;\r\n    char **args;\r\n\r\n    args = _getargs((char *)0x81, \"TESTWILD\");\r\n\r\n    printf(\"Program name: %s\\n\", args[0]);\r\n\r\n    for (a = 1; a < _argc_; ++a)\r\n    {\r\n        printf(\"%2d: %s\\n\", a, args[a]);\r\n    }\r\n}\r\n"
  },
  {
    "path": "z280dist/C280OPTS",
    "content": "HI-TECH Z280 CP/M C compiler options:\r\n\r\n-A\tGenerate a self-relocating .COM program.\r\n-C\tGenerate object code only; don't link.\r\n-CR     Produce a cross-reference listing e.g. -CRfile.crf\r\n-D\tDefine a symbol, e.g. -DDEBUG=1\r\n-E\tSpecify executable output filename, e.g. -Efile.com\r\n-Ffile\tGenerate a symbol file for debug.com or overlay build (default L.SYM)\r\n-H      Output help (the OPTIONS file) and exit.\r\n-I\tSpecify an include directory, e.g. -I1:B:\r\n-L\tScan a library, e.g. -LF scans the floating point library.\r\n-M\tGenerate a map file, e.g. -Mfile.map\r\n-N\tUse the N280CPM.OBJ start-up with minimal _getargs().\r\n-O\tInvoke the peephole optimizer (reduced code-size)\r\n-O2\tInvoke the Z280 optimizer for reduced code size.\r\n-OF2\tInvoke the Z280 optimizer for faster Speed (slightly larger code-size).\r\n-S\tGenerate assembler code in a .AS file; don't assemble or link.\r\n-U\tUndefine a predefined symbol, e.g. -UDEBUG\r\n-V\tBe verbose during compilation.\r\n-W\tSet warning level, e.g. -w5 or -w-2\r\n-X\tSuppress local symbols in symbol tables.\r\n"
  },
  {
    "path": "z280dist/OPTIMH.C",
    "content": "\r\n/*-\r\n * All OPTIMH.C source code is \r\n * (c) Copyright (1993-96) by Stefan Nitschke and Alexander Schmid\r\n *\r\n * Redistribution and use in source and binary forms are permitted\r\n * provided that: (1) source distributions retain this entire copyright\r\n * notice and comment, (2) it is not used for military purpose in\r\n * any form, and (3) distributions including binaries display\r\n * the following acknowledgement:  ``This product includes software\r\n * developed by Stefan Nitschke and his contributors''\r\n * in the documentation or other materials provided with the distribution\r\n * and in all advertising materials mentioning features or use of this\r\n * software. Neither the name of the author nor the names of its\r\n * contributors may be used to endorse or promote products derived\r\n * from this software without specific prior written permission.\r\n * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR\r\n * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r\n */\r\n\r\n/*\r\n   Z280 optimiser for the HITECH 3.09 c-compiler\r\n   St.Nitschke 11.05.93\r\n   Erweitert und Umgesetzt von Turbo-Pascal auf Hi-Tech-C\r\n   (Converted and enhanced from Turbo-Pascal to Hi-Tech-C)\r\n   Alexander Schmid 30.10.93\r\n\r\n   This version is included in the GitHub repository for Hi Tech Z80 C\r\n   at https://github.com/agn453/HI-TECH-Z80-C\r\n\r\n   Modification History\r\n\r\n   04-Jun-2025\tTony Nicholson\r\n\t\tStatement labels without a space after the colon were\r\n\t\t causing the character after the colon to be replaced\r\n\t\t by a space (overwriting the first character of the\r\n\t\t opcode/assembler directive).\r\n   31-Oct-2023\tTony Nicholson\r\n\t\tTranslated German to English comments added in brackets;\r\n\t\tCorrect additional byte and replaced counter updates;\r\n\t\tSummary output includes \"speed\" or \"size\";\r\n\t\tChange default filetype for output from .ASO to .AS2;\r\n\t\tSome \"call csv\" and \"jp cret\" speed optimisations were\r\n\t\t not being detected (add space and tab tests); and\r\n\t\tStatement labels on optimised statements were being\r\n\t\t omitted from optimised output.\r\n\r\n   18-Mar-1996\tStefan Nitschke\r\n\r\n   The following instructions are optimised:\r\n\r\n      call amul        -> multw hl,de\r\n\r\n      call lmul        -> multuw hl,de\r\n\r\n      call csv\t\t-> push\tiy, push ix, lda ix,(sp+0)  (+6 bytes)\r\n\r\n      jp cret\t\t-> ld sp,ix pop ix pop iy ret (+4 bytes)\r\n\r\n      ld  (hl),c\r\n      inc hl           -> ldw (hl),bc\r\n      ld  (hl),b       -> inc hl\r\n\r\n      ld  (hl),e\r\n      inc hl           -> ldw (hl),de\r\n      ld  (hl),d       -> inc hl\r\n\r\n      ld  c,(hl)\r\n      inc hl           -> ldw bc,(hl)\r\n      ld  b,(hl)       -> inc hl\r\n\r\n      ld  e,(hl)\r\n      inc hl           -> ldw de,(hl)\r\n      ld  d,(hl)       -> inc hl\r\n\r\n      ld  c,(ix+n)     or iy\r\n      ld  b,(ix+n+1)   -> ldw bc,(ix+n)    (2 byte)\r\n\r\n      ld  e,(ix+n)     or iy\r\n      ld  d,(ix+n+1)   -> ldw de,(ix+n)    (2 byte)\r\n\r\n      ld  l,(ix+n)     or iy\r\n      ld  h,(ix+n+1)   -> ldw hl,(ix+n)    (2 byte)\r\n\r\n      ld  (ix+n),c     or iy\r\n      ld  (ix+n+1),b   -> ldw (ix+n),bc    (2 byte)\r\n\r\n      ld  (ix+n),e     or iy\r\n      ld  (ix+n+1),d   -> ldw (ix+n),de    (2 byte)\r\n\r\n      ld  (ix+n),l     or iy\r\n      ld  (ix+n+1),h   -> ldw (ix+n),hl    (2 byte)\r\n\r\n      or  a\r\n      sbc hl,bc        -> subw hl,bc       (1 byte)\r\n\r\n      or  a\r\n      sbc hl,de        -> subw hl,de       (1 byte)\r\n\r\n      push  ix\r\n      pop   de\r\n      ld    hl,nn\r\n      add   hl,de      -> lda hl,(ix+nn)   (3 byte)\r\n\r\n      push  ix         -> ld  e,ixl\r\n      pop   de         -> ld  d,ixh\r\n\r\n      push  ix\r\n      pop   hl         -> lda hl,(ix+0)\r\n\r\n   Addressing with large offset\r\n\r\n      push  ix\r\n      pop   de\r\n      ld    hl,nn\r\n      add   hl,de      -> lda hl,(ix+nn)   (3 byte)\r\n\r\n      push\tiy\r\n      pop\tde\r\n      ld\thl,nn\r\n      add\thl,de\t-> lda\thl,(iy+nn)  (3 byte)\r\n\r\n\r\n   The following didn't work:\r\n      ld    hl,nn\r\n      push  hl         -> push nn\r\n\r\n      ld    hl,(nn)\r\n      push  hl         -> push (nn)\r\n\r\n      ld    de,(nn)\r\n      ld    hl,mm      -> ld   hl,(nn)\r\n      add   hl,de      -> lda  hl,(hl+mm)  (1 byte)\r\n\r\n */\r\n\r\n#include <stdio.h>\r\n#include <string.h>\r\n#include <ctype.h>\r\n\r\n#define TRUE 1\r\n#define FALSE 0\r\n\r\nextern char *rindex();\r\n\r\nFILE\t*infile,*outfile;\r\nchar\t*inptr,inname[20],*outptr,outname[20];\r\nint\ti,count,repl,lines,posit;\r\nchar\tfound;\r\nchar\tspeed;\r\nchar\ttext[101];\r\nchar\tline[6][101];\r\n\r\n/* sucht dden String s im String t */\r\n/* (search for the string s in the string t) */\r\nint instr(char *t, char *s) {\r\n    register int i,j,k;\r\n    for (i=0; s[i] != '\\0'; ++i) {\r\n        for (j=i, k=0; t[k]!='\\0' && s[j]==t[k]; ++j, ++k);\r\n        if (t[k] == '\\0') return(i+1);\r\n    }\r\n    return 0;\r\n}\r\n\r\n/* kopiert ab Position p maximal i Zeichen von String a in String b */\r\n/* (from position p, copy up to i characters from string a to string b) */\r\nvoid copyn(char *a, char *b, int p, int i) {\r\n    register int x;\r\n    char ch;\r\n    for(x=0; x<100; ++x) b[x]='\\0';\r\n    for(x=p; x<p+i; ++x){\r\n\tch = a[x];\r\n\tb[x-p] = (ch!=0x0D) && (ch!=0x0A) && (ch!=0x00) ? ch : '\\0';\r\n    }\r\n}\r\n\r\nvoid csv(char *str1,char *bytes) {\r\n    if(instr(str1,line[0])) {\r\n        fprintf(outfile,\";->call csv\\n\");\r\n        fprintf(outfile,\"push\\tiy\\npush\\tix\\n;-> lda ix,(sp+0)\\ndefb\\t%s\\n\",bytes);\r\n        lines = 0;\r\n        count -= 6;\t/* 6 bytes mehr aber schneller */\r\n        repl += 3;\t/*\t   more (but faster) */\r\n        found = TRUE;\r\n    }\r\n}\r\n\r\nvoid cret(char *str1) {\r\n    if(instr(str1,line[0])) {\r\n        fprintf(outfile,\";->jp cret\\n\");\r\n        fprintf(outfile,\"ld\\tsp,ix\\npop\\tix\\npop\\tiy\\nret\\n\");\r\n        lines = 0;\r\n        count -= 4;\t/* 4 bytes mehr aber schneller */\r\n        repl += 3;\t/*\t   more (but faster) */\r\n        found = TRUE;\r\n    }\r\n}\r\n\r\nvoid mult(char *str1, char *str2,char *bytes) {\r\n    if(instr(str1,line[0])) {\r\n        fprintf(outfile,\";->%s  hl,de\\n\",str2);\r\n        fprintf(outfile,\"defb\\t%s\\n\",bytes);\r\n        lines = 0;\r\n        ++count;\t/* 1 byte less */\r\n        repl += 3;\t/* replaces call amul/lmul */\r\n        found = TRUE;\r\n    }\r\n}\r\n\r\nvoid ldw1(char *str1, char *byte1) {  /* ldw  (hl),xx */\r\n    char *strr1=\"ld\\t(hl),b\";\r\n    strr1[8]=str1[1];\r\n    if(instr(strr1,line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);\r\n        lines = 1;\r\n        if(instr(\"inc\\thl\",line[1])) {\r\n            if(lines<2) fgets(line[2],100,infile);\r\n            lines = 2;\r\n            strr1[8]=str1[0];\r\n            if(instr(strr1,line[2])) {\r\n                fprintf(outfile,\";->ldw (hl),%s\\n\",str1);\r\n                fprintf(outfile,\"defb\\t%s\\n\",byte1);\r\n                fputs(\"inc\\thl\\n\",outfile);\r\n                lines = 0;\r\n                found = TRUE;\r\n                repl += 2;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nvoid ldw2(char *str1, char *byte1) {  /* ldw  xx,(hl) */\r\n    char *strr1=\"ld\\tb,(hl)\";\r\n    strr1[3]=str1[1];\r\n    if(instr(strr1,line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);\r\n        lines = 1;\r\n        if(instr(\"inc\\thl\",line[1])) {\r\n            if(lines<2) fgets(line[2],100,infile);\r\n            lines = 2;\r\n            strr1[3]=str1[0];\r\n            if(instr(strr1,line[2])) {\r\n                fprintf(outfile,\";->ldw %s,(hl)\\n\",str1);\r\n                fprintf(outfile,\"defb\\t%s\\n\",byte1);\r\n                fputs(\"inc\\thl\\n\",outfile);\r\n                lines = 0;\r\n                found = TRUE;\r\n                repl += 2;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nvoid ldw3(char *str1, char *str2, char *byte1) {  /* ldw xx,(yy+ofs) */\r\n    char strr1[20];\r\n    strcpy(strr1,\"ld\\tc,(\"); strcat(strr1,str2);\r\n    strr1[3]=str1[1];\r\n    if(instr(strr1,line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);\r\n        lines = 1;\r\n        strr1[3]=str1[0];\r\n        if(instr(strr1,line[1])) {\r\n            lines = 0;\r\n            found = TRUE;\r\n            count += 2;\r\n            repl += 4;\r\n            posit = instr(str2,line[0])+1;\r\n            copyn(line[0],text,posit,instr(\")\",line[0])-posit-1);\r\n            fprintf(outfile,\";->ldw  %s,(%s%s)\\n\",str1,str2,text);\r\n            fprintf(outfile,\"defb\\t%s,%s\\n\",byte1,text);\r\n        }\r\n    }\r\n}\r\n\r\nvoid ldw4(char *str1, char *str2, char *byte1) {  /* ldw  (xx+ofs),yy */\r\n    char strr1[20],strr2[20];\r\n    strcpy(strr1,\"ld\\t(\"); strcat(strr1,str2); \r\n    strcpy(strr2,\"),c\"); strr2[2]=str1[1];\r\n    if(instr(strr1,line[0]) && instr(strr2,line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);\r\n        lines = 1;\r\n        strr2[2]=str1[0];\r\n        if(instr(strr1,line[1]) && instr(strr2,line[1])) {\r\n            lines = 0;\r\n            found = TRUE;\r\n            count += 2;\r\n            repl += 4;\r\n            posit = instr(str2,line[0])+1;\r\n            copyn(line[0],text,posit,instr(\")\",line[0])-posit-1);\r\n            fprintf(outfile,\";->ldw  (%s%s),%s\\n\",str2,text,str1);\r\n            fprintf(outfile,\"defb\\t%s,%s\\n\",byte1,text);\r\n        }\r\n    }\r\n }\r\n \r\nvoid pushix(void) {\r\n    fprintf(outfile,\";->ld  d,ixh\\n\");\r\n    fprintf(outfile,\"defb\\t0ddh,54h\\n\");\r\n    fprintf(outfile,\";->ld  e,ixl\\n\");\r\n    fprintf(outfile,\"defb\\t0ddh,5dh\\n\");\r\n    found = TRUE;\r\n    --count;  /* eine Byte MEHR, aber schneller ! */\r\n    repl += 4; /* one more byte (but faster) */\r\n}\r\n \r\nvoid pushiy(void) {\r\n    fprintf(outfile,\";->ld  d,iyh\\n\");\r\n    fprintf(outfile,\"defb\\t0fdh,54h\\n\");\r\n    fprintf(outfile,\";->ld  e,iyl\\n\");\r\n    fprintf(outfile,\"defb\\t0fdh,5dh\\n\");\r\n    found = TRUE;\r\n    --count;  /* eine Byte MEHR, aber schneller ! */\r\n    repl += 4; /* one more byte (but faster) */\r\n}\r\n\r\nvoid subwhl(char *str1, char *byte1) {\r\n    if(instr(\"or\\ta\",line[0])) {\r\n        char strr1[20];\r\n        strcpy(strr1,\"sbc\\thl,\"); strcat(strr1,str1); \r\n        if(lines<1) fgets(line[1],100,infile);   /* subw  hl,xx */\r\n        lines = 1;\r\n        if(instr(strr1,line[1])) {\r\n            lines = 0;\r\n            found = TRUE;\r\n            ++count;\r\n            repl += 2;\r\n            fprintf(outfile,\";->subw  hl,%s\\n\",str1);\r\n            fprintf(outfile,\"defb\\t%s\\n\",byte1);\r\n        }\r\n    }\r\n}\r\n\r\nvoid label(void) {\r\n/* check for statement label in line[0].  if detected, output the label\r\n   on a line by itself and strip the label from line[0] */\r\n\r\n    register int p, x;\r\n    char lab[101], islabel, c;\r\n\r\n    if(p = instr(\":\",line[0])) {\r\n\tcopyn(line[0],lab,0,p); /* copy label */\r\n\tislabel = TRUE;\r\n\tfor (x=0; x<(p-1); x++) {\r\n\t    c = lab[x]; /* valid chars are 0..9, a..z, $ and _ */\r\n\t    if( (!isalnum(c)) && (c!='$') && (c!='_') ) {\r\n\t\tislabel = FALSE;\r\n\t    }\r\n\t}\r\n\tif (islabel && (line[0][p+1]!='\\0')) { /* check if bare label too */\r\n            fprintf(outfile,\"%s\\n\",lab);\r\n\t    for (x=0; x<p; x++) line[0][x] = ' '; /* blank out label */\r\n\t}\r\n    }\r\n}\r\n\r\nvoid check(void) {\r\n/******************************************************************************/\r\n    if(instr(\"mul\",line[0])) {\r\n       if(!found) mult(\"call\\tamul\",\"multw\",\"0edh,0d2h\");  /* multw  hl,de    */\r\n       if(!found) mult(\"call\\tlmul\",\"multuw\",\"0edh,0d3h\"); /* multuw  hl,de   */\r\n    }\r\n/******************************************************************************/\r\n    if(speed) {\r\n        /* both these increase speed at the expense of 6 extra bytes */\r\n        if(instr(\"csv\",line[0])) {\r\n            if(!found) csv(\"call csv\",\"0ddh,0edh,02h,0,0\");  /* call csv   */\r\n            if(!found) csv(\"call\\tcsv\",\"0ddh,0edh,02h,0,0\");  /* call csv   */\r\n        }\r\n        if(instr(\"cret\",line[0])) {\r\n            if(!found) cret(\"jp cret\");  /* jp cret   */\r\n            if(!found) cret(\"jp\\tcret\");  /* jp cret   */\r\n        }\r\n    }\r\n/******************************************************************************/\r\n    if(instr(\"(hl),\",line[0])) {\r\n        if(!found) ldw1(\"bc\",\"0edh,0eh\");                  /* ldw  (hl),bc    */\r\n        if(!found) ldw1(\"de\",\"0edh,1eh\");                  /* ldw  (hl),de    */\r\n    }\r\n/******************************************************************************/\r\n    if(instr(\",(hl)\",line[0])) {\r\n        if(!found) ldw2(\"bc\",\"0edh,06h\");                  /* ldw  bc,(hl)    */\r\n        if(!found) ldw2(\"de\",\"0edh,16h\");                  /* ldw  de,(hl)    */\r\n    }\r\n/******************************************************************************/\r\n    if(instr(\"(ix\",line[0])) {\r\n        if(!found) ldw3(\"bc\",\"ix\",\"0ddh,0edh,06h\");        /* ldw bc,(ix+ofs) */\r\n        if(!found) ldw3(\"de\",\"ix\",\"0ddh,0edh,16h\");        /* ldw de,(ix+ofs) */\r\n        if(!found) ldw3(\"hl\",\"ix\",\"0ddh,0edh,26h\");        /* ldw hl,(ix+ofs) */\r\n\r\n        if(!found) ldw4(\"bc\",\"ix\",\"0ddh,0edh,0eh\");        /* ldw (ix+ofs),bc */\r\n        if(!found) ldw4(\"de\",\"ix\",\"0ddh,0edh,1eh\");        /* ldw (ix+ofs),de */\r\n        if(!found) ldw4(\"hl\",\"ix\",\"0ddh,0edh,2eh\");        /* ldw (ix+ofs),hl */\r\n    }\r\n/******************************************************************************/\r\n    if(instr(\"(iy\",line[0])) {\r\n        if(!found) ldw3(\"bc\",\"iy\",\"0fdh,0edh,06h\");        /* ldw bc,(iy+ofs) */\r\n        if(!found) ldw3(\"de\",\"iy\",\"0fdh,0edh,16h\");        /* ldw de,(iy+ofs) */\r\n        if(!found) ldw3(\"hl\",\"iy\",\"0fdh,0edh,26h\");        /* ldw hl,(iy+ofs) */\r\n\r\n        if(!found) ldw4(\"bc\",\"iy\",\"0fdh,0edh,0eh\");        /* ldw (iy+ofs),bc */\r\n        if(!found) ldw4(\"de\",\"iy\",\"0fdh,0edh,1eh\");        /* ldw (iy+ofs),de */\r\n        if(!found) ldw4(\"hl\",\"iy\",\"0fdh,0edh,2eh\");        /* ldw (iy+ofs),hl */\r\n    }\r\n/******************************************************************************/\r\n    if(instr(\"or\\ta\",line[0])) {\r\n        if(!found) subwhl(\"bc\",\"0edh,0ceh\");               /* subw  hl,bc     */\r\n        if(!found) subwhl(\"de\",\"0edh,0deh\");               /* subw  hl,de     */\r\n    }\r\n/******************************************************************************/\r\n   if(!found) if(instr(\"push\\tix\",line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);             /* lda hl,(ix+ofs) */\r\n        lines = 1;\r\n        if(instr(\"pop\\tde\",line[1])) {\r\n            if(lines<2) fgets(line[2],100,infile);\r\n            lines = 2;\r\n            if(instr(\"ld\\thl,\",line[2])) {\r\n                if(lines<3) fgets(line[3],100,infile);\r\n                lines = 3;\r\n                if(instr(\"add\\thl,de\",line[3])) {\r\n                    copyn(line[2],text,instr(\"hl,\",line[2])+2,6);\r\n                    if(instr(\")\",text))\r\n                        copyn(text,text,instr(\")\",text)-1,strlen(text));\r\n                    fprintf(outfile,\";->lda  hl,(ix+%s)\\n\",text);\r\n                    fputs(\"defb\\t0edh,2ah\\n\",outfile);\r\n                    fprintf(outfile,\"defw\\t%s\\n\",text);\r\n                    lines = 0;\r\n                    found = TRUE;\r\n                    count += 3;\r\n                    repl += 2;\r\n                }\r\n            }\r\n            else {\r\n                pushix();\r\n                strcpy(line[0],line[1]);\r\n                strcpy(line[1],line[2]);\r\n                lines = 1;\r\n            }\r\n        }\r\n        else if(instr(\"pop\\thl\",line[1])) {\r\n            fprintf(outfile,\";->lda  hl,(ix+0)\\n\");\r\n            fprintf(outfile,\"defb\\t0edh,2ah,0,0\\n\");\r\n            found = TRUE;\r\n            repl += 4;\r\n            --count;\r\n            lines = 0;\r\n        }\r\n    }\r\n/******************************************************************************/\r\n   if(!found) if(instr(\"push\\tiy\",line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);             /* lda hl,(iy+ofs) */\r\n        lines = 1;\r\n        if(instr(\"pop\\tde\",line[1])) {\r\n            if(lines<2) fgets(line[2],100,infile);\r\n            lines = 2;\r\n            if(instr(\"ld\\thl,\",line[2])) {\r\n                if(lines<3) fgets(line[3],100,infile);\r\n                lines = 3;\r\n                if(instr(\"add\\thl,de\",line[3])) {\r\n                    copyn(line[2],text,instr(\"hl,\",line[2])+2,6);\r\n                    if(instr(\")\",text))\r\n                        copyn(text,text,instr(\")\",text)-1,strlen(text));\r\n                    fprintf(outfile,\";->lda  hl,(iy+%s)\\n\",text);\r\n                    fputs(\"defb\\t0edh,32h\\n\",outfile);\r\n                    fprintf(outfile,\"defw\\t%s\\n\",text);\r\n                    lines = 0;\r\n                    found = TRUE;\r\n                    count += 3;\r\n                    repl += 2;\r\n                }\r\n            }\r\n            else {\r\n                pushiy();\r\n                strcpy(line[0],line[1]);\r\n                strcpy(line[1],line[2]);\r\n                lines = 1;\r\n            }\r\n        }\r\n        else if(instr(\"pop\\thl\",line[1])) {\r\n            fprintf(outfile,\";->lda  hl,(iy+0)\\n\");\r\n            fprintf(outfile,\"defb\\t0edh,32h,0,0\\n\");\r\n            found = TRUE;\r\n            repl += 4;\r\n            --count;\r\n            lines = 0;\r\n        }\r\n    }\r\n\r\n/******************************************************************************/\r\n/* verursacht Fehler */\r\n/* (causes errors) */\r\n#ifdef xxx\r\n    if(!found) if(instr(\"ld\\thl,\",line[0]) && instr(\"(\",line[0])==0) {\r\n        if(lines<1)  fgets(line[1],100,infile);            /* push arg        */\r\n        lines = 1;\r\n        if(instr(\"push\\thl\",line[1])) {\r\n            lines = 0;\r\n            found = TRUE;\r\n            repl += 2;\r\n            posit = instr(\"hl,\",line[0])+2;\r\n            copyn(line[0],text,posit,50);\r\n            fprintf(outfile,\";->push  %s\\n\",text);\r\n            fputs(\"defb\\t0fdh,0f5h\\n\",outfile);\r\n            fprintf(outfile,\"defw\\t%s\\n\",text);\r\n        }\r\n    }\r\n#endif\r\n/******************************************************************************/\r\n/* verursacht Fehler */\r\n/* (causes errors) */\r\n#ifdef xxx\r\n    if(!found) if(instr(\"ld\\thl,(\",line[0])) {\r\n        if(lines<1)  fgets(line[1],100,infile);            /* push (arg)      */\r\n        lines = 1;\r\n        if(instr(\"push\\thl\",line[1])) {\r\n            lines = 0;\r\n            found = TRUE;\r\n            repl += 2;\r\n            posit = instr(\"hl,\",line[0])+2;\r\n            copyn(line[0],text,posit,50);\r\n            fprintf(outfile,\";->push  %s\\n\",text);\r\n            fputs(\"defb\\t0ddh,0d5h\\n\",outfile);\r\n            ++posit;\r\n            copyn(line[0],text,posit,instr(\")\",line[0])-posit-1);\r\n            fprintf(outfile,\"defw\\t%s\\n\",text);\r\n        }\r\n    }\r\n#endif\r\n/******************************************************************************/\r\n/* verursacht Fehler */\r\n/* (causes errors) */\r\n#ifdef xxx\r\n   if(!found) if(instr(\"ld\\tde,(\",line[0])) {\r\n        if(lines<1) fgets(line[1],100,infile);             /* lda hl,(hl+ofs) */\r\n        lines = 1;\r\n        if(instr(\"ld\\thl,\",line[1]) && !instr(\"(\",line[1])) {\r\n            if(lines<2) fgets(line[2],100,infile);\r\n            lines = 2;\r\n            if(instr(\"add\\thl,de\",line[2])) {\r\n                posit = instr(\"de\",line[0]+1);\r\n                line[0][posit] = 'h'; line[0][posit+1] = 'l';\r\n                copyn(line[1],text,instr(\"hl,\",line[1])+2,50);\r\n                fputs(line[0],outfile);\r\n                fprintf(outfile,\";->lda  hl,(hl+%s)\\n\",text);\r\n                fputs(\"defb\\t0edh,3ah\\n\",outfile);\r\n                fprintf(outfile,\"defw\\t%s\\n\",text);\r\n                lines = 0;\r\n                found = TRUE;\r\n                ++count;\r\n                repl += 5;\r\n            }\r\n        }\r\n    }\r\n#endif \r\n/******************************************************************************/\r\n}\r\n\r\nmain(int argc,*argv[]) {\r\n    if(argc==1) {\r\n        puts(\"Z280 optimiser for the HITECH C-Compiler\");\r\n        printf(\"Name of input file :\"); scanf(\"%s\",inname);\r\n        printf(\"Name of output file :\"); scanf(\"%s\",outname);\r\n    }\r\n    else if(argc==2) {\r\n        strcpy(inname,(char*)argv[1]);\r\n        if(rindex(inname,'.')==NULL)\r\n        strcat(inname,\".AS\");\r\n        inptr=inname; outptr=outname;\r\n        while(*inptr != '.') *outptr++ = *inptr++;\r\n        strcat(outname,\".AS2\");\r\n    }\r\n    else if(argc==3) {\r\n        strcpy(inname,(char*)argv[1]);\r\n        strcpy(outname,(char*)argv[2]);\r\n    }\r\n    else if(argc==4) {\r\n        if(stricmp((char *)argv[1],\"-F\")==0)\r\n            speed = 1;\r\n\telse {\r\n\t    printf(\"First arg can only be -F for speed (Fast) optimization\\n\");\r\n\t    exit(1);\r\n\t}\r\n        strcpy(inname,(char*)argv[2]);\r\n        strcpy(outname,(char*)argv[3]);\r\n    }\r\n    if((infile = fopen(inname,\"r\"))==NULL) {\r\n        printf(\"Can't open %s\\n\",inname);\r\n        exit(1);\r\n    }\r\n    if((outfile = fopen(outname,\"w\"))==NULL) {\r\n        printf(\"Can't open %s\\n\",outname);\r\n        exit(1);\r\n    }\r\n    count = 0;\r\n    repl = 0;\r\n    while(fgets(line[0],100,infile) != NULL) {\r\n\tlabel();\r\n        lines = 0;\r\n        found = FALSE;\r\n        check();\r\n        if(!found) fputs(line[0],outfile);\r\n        while(lines>0) {\r\n            found = FALSE;\r\n            strcpy(line[0],line[1]);\r\n            strcpy(line[1],line[2]);\r\n            strcpy(line[2],line[3]);\r\n            --lines;\r\n            check();\r\n            if(!found) fputs(line[0],outfile);\r\n        }\r\n    }\r\n    printf(\" %d bytes %s optimised away\\n\",count,speed?\"speed\":\"size\");\r\n    printf(\" %d bytes replaced\\n\",repl);\r\n    fputs(\"\\n; optimiser statistics:\\n\",outfile);\r\n    fprintf(outfile,\"; %d bytes %s optimised away\\n\",count,speed?\"speed\":\"size\");\r\n    fprintf(outfile,\"; %d bytes replaced\\n\\n\",repl);\r\n    fputc(0x1a,outfile); /* explizites (explicit) EOF */\r\n    fclose(infile);\r\n    fclose(outfile);\r\n    exit(0);\r\n}  \r\n\r\n"
  }
]