diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b76f117 --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +# --------------------------- +# MESCC & TOOL CHAIN BINARIES +# --------------------------- +cpm.exe +cpm2.exe +cpm_player.exe +cc.com +cc.COM +CC.COM +ccopt.com +ccopt.COM +CCOPT.COM +#zsm.com +#ZSM.COM +#hextocom.com +#hextocom.COM +#HEXTOCOM.COM +#link.com +#LINK.COM +#prntosym.com +#prntosym.COM +#PRNTOSYM.COM +#zmac.exe + +# --------------- +# MESCC LIBRARIES +# --------------- +alloc.h +atexit.h +bsearch.h +clock.h +conio.h +cpm.h +ctype.h +fileio.h +fprintf.h +mem.h +mescc.h +printf.h +qsort.h +rand.h +redir.h +setjmp.h +sprintf.h +stdbool.h +string.h +xprintf.h +z80.h + +# ------------------ +# INTERMEDIATE FILES +# ------------------ +*.HEX +*.ZSM +*.PRN + +# ----------------------- +# PROJECT FILES & FOLDERS +# ----------------------- +backup/ diff --git a/BINTOASM.COM b/BINTOASM.COM new file mode 100644 index 0000000..37923b4 Binary files /dev/null and b/BINTOASM.COM differ diff --git a/DUMP.COM b/DUMP.COM new file mode 100644 index 0000000..53728ce Binary files /dev/null and b/DUMP.COM differ diff --git a/HEXTOCOM.COM b/HEXTOCOM.COM new file mode 100644 index 0000000..202be89 Binary files /dev/null and b/HEXTOCOM.COM differ diff --git a/PRL.COM b/PRL.COM new file mode 100644 index 0000000..1ed192c Binary files /dev/null and b/PRL.COM differ diff --git a/PRNTOSYM.COM b/PRNTOSYM.COM new file mode 100644 index 0000000..2cdf067 Binary files /dev/null and b/PRNTOSYM.COM differ diff --git a/RSX.COM b/RSX.COM new file mode 100644 index 0000000..a1af0d9 Binary files /dev/null and b/RSX.COM differ diff --git a/ZSM.COM b/ZSM.COM new file mode 100644 index 0000000..5ce1976 Binary files /dev/null and b/ZSM.COM differ diff --git a/ZSMPP.COM b/ZSMPP.COM new file mode 100644 index 0000000..12d737b Binary files /dev/null and b/ZSMPP.COM differ diff --git a/bintoasm.c b/bintoasm.c new file mode 100644 index 0000000..fbecfbd --- /dev/null +++ b/bintoasm.c @@ -0,0 +1,103 @@ +/* BinToAsm.c + + Converts a binary file into an assembler file for Z80. + + Copyright (C) 2004-2015 Miguel I. Garcia Lopez, FloppySoftware + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + To compile with MESCC: + + cc bintoasm + ccopt bintoasm.zsm + zsm bintoasm + hextocom bintoasm + + Revisions: + + 22 Feb 2004 : v1.00 + 03 Apr 2007 : v1.01 / Minor changes. + 10 Apr 2007 : Output 8 bytes in a line instead of 16. + 15 May 2007 : v1.02 / Added title & usage help. + 04 Sep 2015 : v1.03 / Amended some messages and comments. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define VERSION "1.03 / 04 Sep 2015\n\n(c) 2004-2015 FloppySoftware" + +FILE *fpi, *fpo; + +int data, chpos; +unsigned counter; + +main(argc, argv) +int argc, argv[]; +{ + printf("BinToAsm v%s\n\n", VERSION); + + if(argc!=3) + { + printf("Usage: bintoasm binfile asmfile\n"); + exit(1); + } + + if((fpi=fopen(argv[1],"rb"))==NULL) + error("Opening input file"); + + if((fpo=fopen(argv[2],"w"))==NULL) + error("Opening output file"); + + counter=chpos=0; + + while((data=fgetc(fpi))!=EOF) + { + if(!chpos) + fprintf(fpo, " DEFB"); + + fprintf(fpo, " %03d", data); + + if(++chpos!=8) + fprintf(fpo, ","); + else + { + fprintf(fpo, "\n"); + chpos=0; + } + + ++counter; + } + + printf("%d bytes\n", counter); + + if(fclose(fpi)) + error("Closing input file"); + + if(fclose(fpo)) + error("Closing output file"); +} + +error(txt) +char *txt; +{ + printf("ERROR: %s\n", txt); + exit(1); +} diff --git a/dump.c b/dump.c new file mode 100644 index 0000000..9175514 --- /dev/null +++ b/dump.c @@ -0,0 +1,157 @@ +/* dump.c + + Print contents of a file in byte and ascii format. + + (c) 2000-2015 Miguel I. Garcia Lopez, FloppySoftware. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Usage: + + dump filename + + To compile with MESCC: + + cc dump + ccopt dump.zsm + zsm dump + hextocom dump + + Revisions: + + ?? ?? 2000 : v1.00 + 10 Nov 2013 : v1.20 + 04 Sep 2015 : v1.21 : Amended some messages and comments. +*/ + +/* LIBRARIES +*/ + +#define CC_FREAD + +#include +#include +#include + +/* DEFs +*/ + +#define VERSION "Dump v1.21 / 04 Sep 2015\n\n(c) 2000-2015 FloppySoftware" + +/* PROGRAM +*/ + +main(argc,argv) +int argc; +int argv[]; +{ + int i, /* Counter */ + offset; /* Offset in file */ + + FILE *fp; /* Channel for file */ + + char buffer[16]; /* Buffer for input file */ + + /* Check right number of parameters */ + + if(argc != 2) + { + puts(VERSION); + puts("\nUsage: dump fname"); + return 1; + } + + /* Open file in binary mode */ + + if((fp = fopen((argv[1]),"rb")) == NULL) + error("Can't open file"); + + /* Initialize variables */ + + offset=0; + + /* Start */ + + while(fread(buffer, 16, 1, fp) == 1) + { + /* Print offset */ + + puthex4(offset); putchar(' '); putchar(':'); putchar(' '); + + /* Print data in hexadecimal format */ + + for(i = 0; i < 16; ++i) + { + puthex2(buffer[i]); putchar(' '); + } + + /* Separator */ + + putchar(':'); putchar(' '); + + /* Print data in ascii format */ + + for(i = 0; i < 16; ++i) + { + if(buffer[i] > 31 && buffer[i] < 128) + putchar(buffer[i]); + else + putchar('.'); + } + + /* End of line */ + + putchar('\n'); + + /* Update offset */ + + offset += 16; + } + + fclose(fp); + + return 0; +} + +error(txt) +char *txt; +{ + puts(txt); + + exit(1); +} + +puthex4(word) +int word; +{ + puthex2(word >> 8); + puthex2(word); +} + +puthex2(byte) +char byte; +{ + puthex1(byte >> 4); + puthex1(byte); +} + +puthex1(nibble) +char nibble; +{ + nibble &= 0x0F; + + putchar(nibble < 10 ? '0' + nibble : 'A' + nibble - 10); +} + diff --git a/hextobin.c b/hextobin.c new file mode 100644 index 0000000..a06d607 --- /dev/null +++ b/hextobin.c @@ -0,0 +1,225 @@ +/* hextobin.c + + Converts a HEX file into a binary file. + Can be used to generate a COM file for CP/M if it is ORGed to 0x0100. + + (C) 2007-2015 Miguel I. Garcia Lopez, FloppySoftware. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Compile with MESCC: + + cc hextobin + ccopt hextobin.zsm + zsm hextobin + hextocom hextobin + + Revisions: + + 18 Apr 2007 : v1.00 + 21 Apr 2007 : Shows first and last addresses, code size. + 29 Apr 2007 : v1.01 + Bug showing code size upper than 0x8000 (shows + negative number). Changed %d to %u to solve this bug. + 15 Apr 2007 : v1.02 / Change usage text. + 04 Sep 2015 : v1.03 / Modified some messages and comments. +*/ + +#include + +#include +#include + +#define VERSION "1.03 / 04 Sep 2015\n\n(c) 2007-2015 FloppySoftware" + +#ifndef BYTE +#define BYTE unsigned char +#endif + +#ifndef WORD +#define WORD unsigned int +#endif + +FILE *fpi, /* HEX - Input file */ + *fpo; /* COM - Output file */ + +BYTE chksum; /* Checksum of current line */ + +WORD adr, /* Load address */ + ladr, /* Load address of current line */ + first_adr; /* First address */ + +int lbytes, /* Number of data bytes of current line */ + line, /* Number of current line */ + run, /* Zero to exit program */ + flag_adr; /* Zero if load address undefined */ + +/* Show error and exit +*/ + +error(txt) +char *txt; +{ + printf("ERROR: %s.\n", txt); + exit(1); +} + +/* Show error with line number and exit +*/ + +errorln(txt) +char *txt; +{ + printf("ERROR in line %d: %s.\n", line, txt); + exit(1); +} + +/* Read hex nibble +*/ + +BYTE getnib() +{ + int c; + + c=fgetc(fpi); + + if(c>='0' && c<='9') + return c-'0'; + else if(c>='A' && c<='F') + return c-'A'+10; + else if(c==EOF) + error("Unexpected EOF"); + else + error("Bad hex digit"); +} + +/* Read two hex nibbles +*/ + +BYTE gethex() +{ + BYTE nib, hex; + + nib=getnib(); + + chksum+=(hex=(nib << 4) + getnib()); + + return hex; +} + +/* Write byte +*/ + +putbyte(byte) +BYTE byte; +{ + if(fputc(byte, fpo)==EOF) + error("Writing binfile"); +} + +/* Main + */ + +main(argc, argv) +int argc, argv[]; +{ + int c; + + printf("HexToBin v%s\n\n", VERSION); + + if(argc!=3) + { + printf("Usage: hextobin hexfile binfile\n"); + exit(1); + } + + if((fpi=fopen(argv[1], "r"))==NULL) + error("Opening hexfile"); + + if((fpo=fopen(argv[2], "wb"))==NULL) + error("Opening binfile"); + + first_adr=adr=0; /* Load address */ + line=run=1; /* Line number and loop variable */ + flag_adr=0; /* Load address undefined */ + + while((c=fgetc(fpi))!=EOF && run) + { + if(c!=':') + errorln("Missing colon"); + + chksum=0; + + lbytes=gethex(); /* Bytes per line */ + + ladr=gethex(); + ladr=(ladr<<8)+gethex(); /* Load adress */ + + switch(gethex()) /* Line type */ + { + case 0 : /* Data */ + if(!lbytes) + break; + + if(!flag_adr) + { + first_adr=adr=ladr; + ++flag_adr; + } + else if(adrladr) + errorln("Bad address"); + + adr+=lbytes; + + while(lbytes--) + putbyte(gethex()); + break; + case 1 : /* End */ + run=0; + break; + default : + errorln("Unknown record type"); + } + + gethex(); /* Checksum */ + + if(chksum) + errorln("Bad checksum"); + + if((c=fgetc(fpi))!='\n') + errorln("Missing newline"); + + ++line; + } + + if(fclose(fpi)) + error("Closing hexfile"); + + if(fclose(fpo)) + error("Closing binfile"); + + printf("First address: %04x\n", first_adr); + printf("Last address: %04x\n", adr-1); + printf("Size of code: %04x (%u dec) bytes\n", adr-first_adr, adr-first_adr); + +} diff --git a/hextobin.com b/hextobin.com new file mode 100644 index 0000000..bd9e3bc Binary files /dev/null and b/hextobin.com differ diff --git a/hextocom.c b/hextocom.c new file mode 100644 index 0000000..59bbd02 --- /dev/null +++ b/hextocom.c @@ -0,0 +1,276 @@ +/* hextocom.c + + Converts an HEX file into a COM file for CP/M. + + (C) 2007-2016 FloppySoftware (Miguel I. Garcia Lopez, Spain). + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + To compile with MESCC: + + cc hextocom + ccopt hextocom.zsm + zsm hextocom + hextocom hextocom + + Revisions: + + (hextobin.c) + + 18 Apr 2007 : v1.00 : + 21 Apr 2007 : : Shows first and last addresses, code size. + 29 Apr 2007 : v1.01 : Bug showing code size upper than 0x8000 (shows + negative number). Changed %d to %u to solve this bug. + 15 May 2007 : v1.02 : Change usage text. + + (hextocom.c) + + 13 Nov 2014 : v1.03 : Modified to generate COM files for CP/M. + 04 Sep 2015 : v1.04 : Modified some comments and messages. + 10 Jan 2016 : v1.05 : Cleaned. +*/ + +/* Defines for MESCC libraries + --------------------------- +*/ +#define CC_FILEIO_SMALL // Exclude fread(), fwrite() and fgets(). + +/* Standard MESCC library + ---------------------- +*/ +#include + +/* Standard MESCC libraries + ------------------------ +*/ +#include +#include +#include + +/* Project defs. + ------------- +*/ +#define APP_NAME "HexToCom" +#define APP_VERSION "v1.05 / 10 Jan 2016" +#define APP_COPYRGT "(c) 2007-2016 FloppySoftware" +#define APP_USAGE "HexToCom filename" + +/* Globals + ------- +*/ +FILE *fpi, /* HEX - Input file */ + *fpo; /* COM - Output file */ + +BYTE chksum; /* Checksum of current line */ + +WORD adr, /* Load address */ + ladr, /* Load address of current line */ + first_adr; /* First address */ + +int lbytes, /* Number of data bytes of current line */ + line, /* Number of current line */ + run, /* Zero to exit program */ + flag_adr; /* Zero if load address undefined */ + +char fn_hex[FILENAME_MAX], /* HEX - filename */ + fn_com[FILENAME_MAX]; /* COM - filename */ + +/* Print error and exit + -------------------- +*/ +error(txt) +char *txt; +{ + printf("%s: %s.\n", APP_NAME, txt); + exit(-1); +} + +/* Print error with line number and exit + ------------------------------------- +*/ +errorln(txt) +char *txt; +{ + printf("%s: Error in line %d - %s.\n", APP_NAME, line, txt); + exit(-1); +} + +/* Read hex nibble + --------------- +*/ +BYTE getnib() +{ + int c; + + c=fgetc(fpi); + + if(c>='0' && c<='9') + return c-'0'; + + if(c>='A' && c<='F') + return c-'A'+10; + + if(c==EOF) + error("Unexpected EOF"); + + error("Bad hexadecimal digit"); +} + +/* Read two hex nibbles + -------------------- +*/ +BYTE gethex() +{ + BYTE nib, hex; + + nib=getnib(); + + chksum+=(hex=(nib << 4) + getnib()); + + return hex; +} + +/* Write byte + ---------- +*/ +putbyte(byte) +BYTE byte; +{ + if(fputc(byte, fpo)==EOF) + error("Writing COM file"); +} + +/* Main + ---- +*/ +main(argc, argv) +int argc, argv[]; +{ + /* Program name, copyright, etc. */ + + printf("%s %s\n\n", APP_NAME, APP_VERSION); + printf("%s\n\n", APP_COPYRGT); + + /* Show usage? */ + + if(argc != 2) + { + printf("Usage: %s\n", APP_USAGE); + exit(0); + } + + /* Filenames */ + + if(strchr(argv[1], '.') != NULL) + error("Bad filename (no type, please)"); + + if(strlen(argv[1]) > 10) /* D:FILENAME */ + error("Bad filename (too long)"); + + strcat(strcpy(fn_hex, argv[1]), ".HEX"); + strcat(strcpy(fn_com, argv[1]), ".COM"); + + /* Open files */ + + if((fpi=fopen(fn_hex, "r"))==NULL) + error("Opening HEX file"); + + if((fpo=fopen(fn_com, "wb"))==NULL) + error("Opening COM file"); + + /* Start process */ + + first_adr=adr=0; /* Load address */ + line=run=1; /* Line number and loop variable */ + flag_adr=0; /* Load address undefined */ + + while(run) + { + if(fgetc(fpi) != ':') + errorln("Missing colon"); + + chksum=0; + + lbytes=gethex(); /* Bytes per line */ + + ladr=gethex(); + ladr=(ladr<<8)+gethex(); /* Load adress */ + + switch(gethex()) /* Line type */ + { + case 0 : /* Data */ + if(!lbytes) + { + run = 0; + break; + } + + if(!flag_adr) + { + if((first_adr=adr=ladr) != 0x0100) + error("Start address must be 0100H"); + + ++flag_adr; + } + else if(adrladr) + errorln("Bad address"); + + adr+=lbytes; + + while(lbytes--) + putbyte(gethex()); + break; + case 1 : /* End */ + run=0; + break; + default : + errorln("Unknown record type"); + break; + } + + gethex(); /* Checksum */ + + if(chksum) + errorln("Bad checksum"); + + if(fgetc(fpi)!='\n') + errorln("Missing newline"); + + ++line; + } + + /* Close files */ + + if(fclose(fpi)) + error("Closing HEX file"); + + if(fclose(fpo)) + error("Closing COM file"); + + /* Print facts */ + + printf("First address: %04x\n", first_adr); + printf("Last address: %04x\n", adr-1); + printf("Size of code: %04x (%u dec) bytes\n", adr-first_adr, adr-first_adr); + +} diff --git a/make_prl.bat b/make_prl.bat new file mode 100644 index 0000000..2c83778 --- /dev/null +++ b/make_prl.bat @@ -0,0 +1,4 @@ +cpm cc prl +cpm ccopt prl +cpm zsm prl +cpm hextocom prl \ No newline at end of file diff --git a/make_rsx.bat b/make_rsx.bat new file mode 100644 index 0000000..cc1fc89 --- /dev/null +++ b/make_rsx.bat @@ -0,0 +1,4 @@ +cpm cc rsx +cpm ccopt rsx +cpm zsm rsx +cpm hextocom rsx \ No newline at end of file diff --git a/prl.c b/prl.c new file mode 100644 index 0000000..0dbbb4f --- /dev/null +++ b/prl.c @@ -0,0 +1,416 @@ +/* prl.c + + Make PRL file. + + Copyright (c) 2016 Miguel Garcia / FloppySoftware + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + Author's contact: + + www.floppysoftware.es + cpm-connections.blogspot.com + floppysoftware@gmail.com + + To compile with MESCC: + + cc prl + ccopt prl + zsm prl + hextocom prl + + Usage: + + prl filename[.com] filename[.com] filename[.prl] + + Revisions: + + 23 Nov 2016 : Start. +*/ + +/* Defines for MESCC libraries + --------------------------- +*/ +#define CC_FREAD // Include fread() +#define CC_FWRITE // Include fwrite() + +/* Standard MESCC library + ---------------------- +*/ +#include + +/* Standard MESCC libraries + ------------------------ +*/ +#include +//#include +//#include +//#include +//#include +#include // For get_rsize() +//#include +#include +//#include +#include +#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + +/* Project defs. + ------------- +*/ +#define APP_NAME "PRL" +#define APP_VERSION "v1.00 / 18 Nov 2016" +#define APP_COPYRGT "(c) 2016 FloppySoftware" +#define APP_USAGE "prl filename[.com] filename[.com] filename[.prl]" + +#define TMP_FNAME "prl.$$$" + +#define PRL_HEADER_SIZE 256 + +#define PRL_H_BYTES 1 // WORD: Bytes in program image (code + initialised data) +#define PRL_H_BSS 4 // WORD: Bytes reserved for unitialised data +#define PRL_H_LADR 7 // WORD: Load address +#define PRL_H_CBASE 10 // WORD: BIOS link + +/* Globals + ------- +*/ +int task = -1; + +char cm1_fname[FILENAME_MAX]; +char cm2_fname[FILENAME_MAX]; +char prl_fname[FILENAME_MAX]; +char tmp_fname[FILENAME_MAX]; + +FILE *cm1_fp; +FILE *cm2_fp; +FILE *tmp_fp; + +BYTE prl_header[PRL_HEADER_SIZE]; + +/* Program entry + ------------- +*/ +main(argc, argv) +int argc; +unsigned int argv[]; // char *argv[] - unsupported by MESCC (yet?) +{ + // Show usage if there are no arguments + if(argc == 1) + { + usage(); + } + + // Check arguments + if(argc != 4) + { + error_bad_cmdline(); + } + + // Take COM filename #1 + get_fname(cm1_fname, argv[1], "COM"); + + // Take COM filename #2 + get_fname(cm2_fname, argv[2], "COM"); + + // Take PRL filename + get_fname(prl_fname, argv[3], "PRL"); + + // Take TMP filename + get_temp_fname(prl_fname); + + // Process + process(); + + // Success + exit(0); +} + +/* Process files + ------------- +*/ +process() +{ + WORD recs, *pw; + int i, k, b, h, bitmap_size; + BYTE rec_bf1[128], rec_bf2[128], *pb_bitmap, byte, mask; + + // Open COM filename #1 + if(!(cm1_fp = fopen(cm1_fname, "rb"))) + { + error_open(); + } + + // Open COM filename #2 + if(!(cm2_fp = fopen(cm2_fname, "rb"))) + { + error_open(); + } + + // Open TMP filename + if(!(tmp_fp = fopen(tmp_fname, "wb"))) + { + error_open(); + } + + // Get COM file size in CP/M records + if(!(recs = get_rsize(cm1_fname))) + { + error("File is empty"); + } + + // Check valid file size + if(recs > 512) + { + error("File is too big"); + } + + // Check size coincidence between both COM files + if(recs != get_rsize(cm2_fname)) + { + error("Files differ in size"); + } + + // Alloc memory for relocation bitmap + bitmap_size = recs * 16; + + if(!(pb_bitmap = malloc(bitmap_size))) + { + error("No memory for relocation bitmap"); + } + + // Initialize PRL header + *(pw = prl_header + PRL_H_BYTES) = recs * 128; + + // Write PRL header + if(fwrite(prl_header, PRL_HEADER_SIZE, 1, tmp_fp) != 1) + { + error_write(); + } + + // Write COM file #1 contents to TMP -- FIXME -- try to speed up this! + for(i = b = 0; i < recs; ++i) + { + if(fread(rec_bf1, 128, 1, cm1_fp) != 1) + { + error_read(); + } + + if(fwrite(rec_bf1, 128, 1, tmp_fp) != 1) + { + error_write(); + } + + if(fread(rec_bf2, 128, 1, cm2_fp) != 1) + { + error_read(); + } + + for(k = 0; k < 128; k += 8) + { + mask = 128; + + for(h = byte = 0; h < 8; ++h) + { + if(rec_bf1[k + h] != rec_bf2[k + h]) + { + byte |= mask; + } + + mask = mask >> 1; + } + + pb_bitmap[b++] = byte; + } + } + + // Write PRL relocation bitmap to TMP + if(fwrite(pb_bitmap, bitmap_size, 1, tmp_fp) != 1) + { + error_write(); + } + + // Close COM filename #1 + fclose(cm1_fp); + + // Close COM filename #2 + fclose(cm2_fp); + + // Close TMP filename + if(fclose(tmp_fp)) + { + error_close(); + } + + // Delete old PRL file if exists + remove(prl_fname); + + // Rename TMP file to PRL filename + if(rename(tmp_fname, prl_fname)) + { + error("Can't rename file"); + } +} + +/* Copy a filename and add a file type if needed + --------------------------------------------- +*/ +get_fname(dest, fname, ftype) +char *dest, *fname, *ftype; +{ + int len_type; + + len_type = (strchr(fname, '.') ? 0 : strlen(ftype) + 1); + + if(strlen(fname) + len_type >= FILENAME_MAX) + { + error_fname(); + } + + strcpy(dest, fname); + + if(len_type) + { + strcat(dest, "."); strcat(dest, ftype); + } +} + +/* Generate temporary filename + --------------------------- +*/ +get_temp_fname(fname) +char *fname; +{ + char *pc; + int k; + + pc = strchr(fname, ':'); + + k = (pc ? pc - fname + 1 : 0); + + pc = TMP_FNAME; + + if(k + strlen(pc) >= FILENAME_MAX) + { + error_fname(); + } + + if(k) + { + memcpy(tmp_fname, fname, k); + } + + strcpy(tmp_fname + k, pc); +} + +/* Get file size in records of 128 bytes each + ------------------------------------------ +*/ +get_rsize(fname) +char *fname; +{ + BYTE fcb[36]; + WORD *pw; + + if(!setfcb(fname, fcb)) + { + if(!bdos_a(BF_FSIZE, fcb)) + { + return *(pw = fcb + 33); + } + } + + error("Can't get file size"); +} + +/* Show usage and exit + ------------------- +*/ +usage() +{ + printf("%s %s - %s\n\n", APP_NAME, APP_VERSION, APP_COPYRGT); + printf("Make PRLs - Page ReLocatable files.\n\n"); + printf("Usage: %s\n\n", APP_USAGE); + + exit(0); +} + +/* Print error and exit + -------------------- +*/ +error(msg) +char *msg; +{ + printf("%s: %s\n", APP_NAME, msg); + + exit(-1); +} + +/* Error: bad command line + ----------------------- +*/ +error_bad_cmdline() +{ + error("Bad command line"); +} + +/* Error: filename too long + ------------------------ +*/ +error_fname() +{ + error("Filename is too long"); +} + +/* Error: can't open file + ---------------------- +*/ +error_open() +{ + error("Can't open file"); +} + +/* Error: can't close file + ----------------------- +*/ +error_close() +{ + error("Can't close file"); +} + +/* Error: reading file + ------------------- +*/ +error_read() +{ + error("Reading file"); +} + +/* Error: writing file + ------------------- +*/ +error_write() +{ + error("Writing file"); +} + + \ No newline at end of file diff --git a/prntosym.c b/prntosym.c new file mode 100644 index 0000000..600d153 --- /dev/null +++ b/prntosym.c @@ -0,0 +1,268 @@ +/* prntosym.c + + Extract symbols from a PRN file (from ZSM v2.8). + + (C) 2015 FloppySoftware (Miguel I. Garcia Lopez, Spain). + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + CONTACT: + + www.floppysoftware.vacau.com + cpm-connections.blogspot.com + floppysoftware@gmail.com + + USAGE: + + prntosym source [> destination] + + TO COMPILE WITH MESCC: + + cc prntosym + ccopt prntosym.zsm + zsm prntosym + hextocom prntosym + + REVISIONS: + + 20 Aug 2015 : v1.00 : Initial version. + 21 Aug 2015 : v1.01 : Added SKIP_INTERNAL and SKIP_SAMARUX defines. + Added EXIT to skipped symbol names in SamaruX. + 24 Aug 2015 : v1.02 : Minor changes in file output. + 04 Sep 2015 : v1.03 : Modified some comments and messages. + + NOTES: + + It was developed to support SamaruX external commands, but it can be useful on other matters too. + + It skips some symbol names, if you define: + + SKIP_INTERNAL : To skip symbols finishing with a decimal digit, like 'a32' (MESCC internal ones). + + SKIP_SAMARUX : To skip following symbols: + + CCFREEMEM + EXIT + MAIN +*/ + +/* MESCC DEFs +*/ + +#define CC_STDIO /* Support for stdin, stdout, stderr */ +#define CC_REDIR /* Support for command line redirection */ + +#define CC_NO_SWITCH /* No switch */ + +/* MESCC libraries +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* DEFs and globals +*/ + +#define SKIP_INTERNAL +#define SKIP_SAMARUX + +#define VERSION "1.03 / 04 Sep 2015\n\n(c) 2015 FloppySoftware" + +#define BUF_LEN 127 /* Max. lenght for input buffer */ +#define BUF_SIZ 128 /* Size for input buffer */ + +FILE *fp; /* Input file FP */ +char buf[BUF_SIZ]; /* Input buffer */ + +/* Main + */ + +main(argc, argv) +int argc, argv[]; +{ + /* Show banner */ + + fprintf(stderr, "PrnToSym v%s\n\n", VERSION); + + /* Check arguments */ + + if(argc != 2) + { + fprintf(stderr, "Usage: prntosym inputfile [> outputfile]\n"); + exit(1); + } + + /* Process input file */ + + procfile(argv[1]); + + /* End */ + + fprintf(stderr, "Done.\n"); +} + +/* Process input file +*/ + +procfile(fn) +char *fn; +{ + int k, flag; + + /* Open file */ + + if((fp = fopen(fn, "r")) == NULL) + error("Opening input file"); + + /* Process file */ + + flag = 0; + + while(1) + { + /* Read line */ + + if(fgets(buf, BUF_SIZ, fp) == NULL) + break; + + /* Check EOL */ + + k = strlen(buf); + + if(buf[--k] != '\n') + error("Line too long or missing newline"); + + /* Clear LF and put a ZERO instead */ + + buf[k] = 0; + + /* Process line */ + + if(flag) + procline(); + else if(!memcmp(buf, "Next", 4)) /* ie: Next address: CE05H */ + ++flag; + } + + /* Close file */ + + fclose(fp); +} + +/* Process input line +*/ + +procline() +{ + char *p, name[12], adr[5]; + int k, x; + + /* Link to line */ + + p = buf; + + /* Can be an empty or title line */ + + if(*p == 12 || !(*p)) + return; + + /* Each line can hold up to 4 symbols: */ + + /* NUMBER 52C5 NXTLAB BC5D OPFNAME BC7C ORFN 6144 */ + + while(isalpha(*p) || *p == '_') + { + /* Symbol name */ + + k = 0; + + do { + name[k++] = *p++; + + if(k == 12) + error("Symbol name too long"); + + } while(isalpha(*p) || *p == '_' || isdigit(*p)); + + name[k] = 0; + + /* Skip blanks */ + + while(*p == ' ' || *p == '\t') + ++p; + + /* Address */ + + x = 0; + + while(isxdigit(*p)) { + adr[x++] = *p++; + + if(x == 5) + error("Bad symbol address"); + } + + adr[x] = 0; + + /* Skip blanks */ + + while(*p == ' ' || *p == '\t') + ++p; + +#ifdef SKIP_INTERNAL + /* Skip symbols finishing with a decimal digit (MESCC internal ones) */ + + if(isdigit(name[k - 1])) + continue; +#endif + +#ifdef SKIP_SAMARUX + /* Skip some symbols for SamaruX external commands */ + + if(!strcmp(name, "CCFREEMEM")) + continue; + + if(!strcmp(name, "EXIT")) + continue; + + if(!strcmp(name, "MAIN")) + continue; +#endif + + /* Print symbol and address */ + + fprintf(stdout, "%-12s equ 0%sH\n", name, adr); + } + + /* Check EOL */ + + if(*p) + error("Bad line format"); +} + +/* Print error and exit +*/ + +error(txt) +char *txt; +{ + fprintf(stderr, "ERROR: %s.\n", txt); exit(1); +} diff --git a/releases/zsm20/TEST1A.ASM b/releases/zsm20/TEST1A.ASM new file mode 100644 index 0000000..cc45c04 --- /dev/null +++ b/releases/zsm20/TEST1A.ASM @@ -0,0 +1,191 @@ +; +; Z80 ASSEMBLER TEST INSTRUCTION FILE +; + ORG 100H ;TEST ORG PSEUDO OP +LABEL1 EQU $ ;TEST EQU PSEUDO OP + DEFW LABEL1 ;TEST DEFW PSEUDO OP + DEFB 03FH ;TEST DEFB PSEUDO OP FORM 1 + DEFB 'THIS IS A TEST' ;TEST DEFB PSEUDO OP FORM 2 + DEFS 55 ;TEST DEFS PSEUDO OP +; +; THE NEXT THREE LINES USE THE IBM PSEUDO WHICH WAS ADDED TO +; FACILITATE SCREEN FORMATTING. +; +; THE FORMAT IS: IBM HEX,ASCII,HEX,ASCII,... WITH NO QUOTES +; AROUND THE ASCII +; +; IF THE USER WHISHES TO USE ASCII FIRST THEN THE FIRST BYTE MUST +; BEGIN WITH A QUOTE. +; +; THE HEX NUMBERS MUST BE IN PAIRS AND MUST NOT HAVE 'H' AFTER THEM +; THE ASCII STRINGS CAN INCLUDE ANY CHARACTERS (INCLUDING QUOTES AND +; SEMI-COLONS EXCEPT NO COMMAS +; +; +; + IBM 1A0000,TOP OF SCREEN ON LEAR SEIGLER ADM3,0D0A0D0A,DOWN 3 LINES + IBM 0FAD,ASCII CODING,0FE4,SCREEN FORMATTING + IBM 'ASCII FIRST,0DFF,THEN HEX +; + LD A,B ;TEST LOAD + LD A,0FFH + LD A,(HL) + LD A,(IX+5) + LD A,(IY+6) + LD (HL),B + LD (IX+5),B + LD (IY+5),B + LD (HL),23 + LD (IX+1),24 + LD (IY+1),25 + LD (BC),A + LD (DE),A + LD (LABEL1),A + LD A,(BC) + LD A,(DE) + LD A,(LABEL1) + LD A,I + LD A,R + LD I,A + LD R,A + LD BC,LABEL1 + LD DE,LABEL1 + LD HL,LABEL1 + LD SP,LABEL1 + LD IX,LABEL1 + LD IY,LABEL1 + LD HL,(LABEL1) + LD IX,(LABEL1) + LD IY,(LABEL1) + LD (LABEL1),HL + LD (LABEL1),BC + LD (LABEL1),DE + LD (LABEL1),IX + LD (LABEL1),IY + LD SP,HL + LD SP,IX + LD SP,IY + PUSH BC + PUSH DE + PUSH HL + PUSH AF + PUSH IX + PUSH IY + POP BC + POP DE + POP HL + POP IX + POP IY + POP AF + EX DE,HL + EX AF,AF' + EXX + EX (SP),HL + EX (SP),IX + EX (SP),IY + LDI + LDIR + LDD + LDDR + CPI + CPIR + CPD + CPDR + ADD A + ADD 0FFH + ADD (HL) + ADD (IX+5) + ADD (IY+6) + ADC A + SUB A + SBC A + AND A + OR A + XOR A + CP A + INC A + INC (HL) + INC (IX+3) + INC (IY+5) + DEC (HL) + DAA + CPL + NEG + CCF + SCF + NOP + HALT + DI + EI + IM0 + IM1 + IM2 + ADD HL,BC + ADC HL,DE + SBC HL,DE + ADD IX,BC + ADD IY,DE + INC IX + INC IY + DEC IX + DEC IY + RLCA + RLA + RRCA + RRA + RLC B + + RLC (HL) + RLC (IX+5) + RLC (IY+4) + RL B + RRC B + RR B + SLA B + SRA B + SRL B + RLD + RRD + BIT 5,E + BIT 5,(HL) + BIT 5,(IX+5) + BIT 5,(IY+4) + SET 4,B + SET 4,(HL) + SET 4,(IX+5) + SET 4,(IY+4) + RES 4,E + RES 4,(HL) + JP LABEL1 + JP NZ,LABEL1 + JP C,LABEL1 + JR +6 + JR C,5 + JR NC,5 + JR Z,5 + JR NZ,5 + JP (HL) + JP (IX) + JP (IY) + DJNZ 5 + CALL LABEL1 + CALL NZ,LABEL1 + RET + RET NZ + RETI + RETN + RST 38H + IN A,(03H) + IN B,(C) + INI + INIR + IND + INDR + OUT (034H),A + OUT (C),E + OUTI + OTIR + OUTD + OTDR + END $ + \ No newline at end of file diff --git a/releases/zsm20/TEST2.ASM b/releases/zsm20/TEST2.ASM new file mode 100644 index 0000000..c85a450 --- /dev/null +++ b/releases/zsm20/TEST2.ASM @@ -0,0 +1,37 @@ +MULT:; UNSIGNED SIXTEEN BIT INTEGER MULTIPLY. +; ON ENTRANCE: MULTIPLIER IN DE. +; MULTIPLICAND IN HL. +; +; ON EXIT: RESULT IN HL. +; +; REGISTER USES: +; +; +; H HIGH ORDER PARTIAL RESULT +; L LOW ORDER PARTIAL RESULT +; D HIGH ORDER MULTIPLICAND +; E LOW ORDER MULTIPLICAND +; B COUNTER FOR NUMBER OF SHIFTS +; C HIGH ORDER BITS OF MULTIPLIER +; A LOW ORDER BITS OF MULTIPLIER +; + LD B,16; NUMBER OF BITS- INITIALIZE + LD C,D; MOVE MULTIPLIER + LD A,E; + LD X,Y ;SHOULD GET 'U' ERROR + LOAD A,B ;SHOULD GET 'O' ERROR + CP 'A' ;TEST 'X' FORMAT + EX DE,HL; MOVE MULTIPLICAND + LD HL,0; CLEAR PARTIAL RESULT + EJECT ;TEST EJECT PROCESSING +MLOOP: SRL C; SHIFT MULTIPLIER RIGHT + RRA; LEAST SIGNIFICANT BIT IS IN CARRY + JR NC,NOADD-$; IF NO CARRY SKIP THE ADD + ADD HL,DE; ELSE ADD MULTIPLICAND TO PARTIAL RESULT +NOADD: EX DE,HL; SHIFT MULTIPLICAND LEFT + ADD HL,HL; BY MULTIPLYING IT BY TWO + EX DE,HL; + DJNZ MLOOP-$; REPEAT UNTIL NO MORE BITS + RET; + END; + \ No newline at end of file diff --git a/releases/zsm20/Z80.DOC b/releases/zsm20/Z80.DOC new file mode 100644 index 0000000..984aa78 --- /dev/null +++ b/releases/zsm20/Z80.DOC @@ -0,0 +1,402 @@ + Z-80 Macro Library Documentation + -------------------------------- + +I. + The purpose of this library is to enable the assembly of the Z-80 + instruction set on a CP/M sytem using the CP/M MAC macro assembler. + + This library is invoked with the pseudo-op: + + " MACLIB Z80 " + +II. + The following symbols and notations are used in the individual macro + descriptions; + + r - Any of the 8 bit registers: A, B, C, D, E, H, L, or M + rr - Any of the 16 bit register pairs: BC, DE, HL, or SP + nn - 8 bit immediate data (0 through 255) + d - 8 bit signed displacment (-128 through +127) + nnnn - 16 bit address or immediate data (0 through 65535) + b - bit number (0-7, 7 is most significant, 0 is least) + addr - 16 bit address within PC+127 through PC-128 + m(zzz) - Memory at address "zzz" + +III. + + MACLIB ver. Zilog ver TDL ver +-------------- ------------- ------------- + +LDX r,d LD r,(IX+d) MOV r,d(IX) + Load register from indexed memory (with IX) + +LDY r,d LD r,(IY+d) MOV r,d(IY) + Load register from indexed memory (with IY) + +STX r,d LD (IX+d),r MOV d(IX),r + Store register to indexed memory (with IX) + +STY r,d LD (IY+d),r MOV d(IY),r + Store register to indexed memory (with IY) + +MVIX nn,d LD (IX+d),nn MVI d(IX) + Move immediate to indexed memory (with IX) + +MVIY nn,d LD (IY+d),nn MVI d(IY) + Move immediate to indexed memory (with IY) + +LDAI LD A,I LDAI + Move I to A + +LDAR LD A,R LDAR + Move R to A + +STAI LD I,A STAI + Move A to I + +STAR LD R,A STAR + Move A to R + +LXIX nnnn LD IX,nnnn LXI IX,nnnn + Load IX immediate (16 bits) + +LXIY nnnn LD IY,nnnn LXI IY,nnnn + Load IY immediate (16 bits) + +LBCD nnnn LD BC,(nnnn) LBCD nnnn + Load BC direct (from memory at nnnn) + +LDED nnnn LD DE,(nnnn) LDED nnnn + Load DE direct + +LSPD nnnn LD SP,(nnnn) LSPD nnnn + Load SP direct + +LIXD nnnn LD IX,(nnnn) LIXD nnnn + Load IX direct + +LIYD nnnn LD IY,(nnnn) LIYD nnnn + Load IY direct + +SBCD nnnn LD (nnnn),BC SBCD nnnn + Store BC direct (to memory at nnnn) + +SDED nnnn LD (nnnn),DE SDED nnnn + Store DE direct + +SSPD nnnn LD (nnnn),SP SSPD nnnn + Store SP direct + +SIXD nnnn LD (nnnn),IX SIXD nnnn + Store IX direct + +SIYD nnnn LD (nnnn),IY SIYD nnnn + Store IY direct + +SPIX LD SP,IX SPIX + Copy IX to the SP + +SPIY LD SP,IY SPIY + Copy IY to the SP + +PUSHIX PUSH IX PUSH IX + Push IX into the stack + +PUSHIY PUSH IY PUSH IY + Push IY into the stack + +POPIX POP IX POP IX + Pop IX from the stack + +POPIY POP IY POP IY + Pop IY from the stack + +EXAF EX AF,AF' EXAF + Exchange AF and the alternate, AF' + +EXX EXX EXX + Exchange BC DE HL with BC' DE' HL' + +XTIX EX (SP),IX XTIX + Exchange IX with the top of the stack + +XTIY EX (SP),IY XTIY + Exchange IY with the top of the stack + +LDI LDI LDI + Move m(HL) to m(DE), increment DE and HL, decrement BC + +LDIR LDIR LDIR + Repeat LDI until BC = 0 + +LDD LDD LDD + Move m(HL) to m(DE), decrement HL, DE, and BC + +LDDR LDDR LDDR + Repeat LDD until BC = 0 + +CCI CPI CCI + Compare A with m(HL), increment HL, decrement BC + +CCIR CPIR CCIR + Repeat CCI until BC = 0 or A = m(HL) + +CCD CPD CCD + Compare A with m(HL), decrement HL and BC + +CCDR CPDR CCDR + Repeat CCD until BC = 0 or A = m(HL) + +ADDX d ADD (IX+d) ADD d(IX) + Indexed add to A + +ADDY d ADD (IY+d) ADD d(IY) + Indexed add to A + +ADCX d ADC (IX+d) ADC d(IX) + Indexed add with carry + +ADCY d ADC (IY+d) ADC d(IY) + Indexed add with carry + +SUBX d SUB (IX+d) SUB d(IX) + Indexed subtract + +SUBY d SUB (IY+d) SUB d(IY) + Indexed Subtract + +SBCX d SBC (IX+d) SBB d(IX) + Indexed subtract with "borrow" + +SBCY d SBC (IY+d) SBB d(IY) + Indexed subtract with borrow + +ANDX d AND (IX+d) ANA d(IX) + Indexed logical and + +ANDY d AND (IY+d) ANA d(IY) + Indexed logical and + +XORX d XOR (IX+d) XRA d(IX) + Indexed logical exclusive or + +XORY d XOR (IY+d) XRA d(IY) + Indexed logical exclusive or + +ORX d OR (IX+d) ORA d(IX) + Indexed logical or + +ORY d OR (IY+d) ORA d(IY) + Indexed logical exclusive or + +CMPX d CP (IX+d) CMP d(IX) + Indexed compare + +CMPY d CP (IY+d) CMP d(IY) + Index compare + +INRX d INC (IX+d) INR d(IX) + Increment memory at m(IX+d) + +INRY d INC (IY+d) INR d(IY) + Increment memory at m(IY+d) + +DCRX d INC (IX+d) INR d(IX) + Decrement memory at m(IX+d) + +DCRY d DEC (IY+d) DCR d(IY) + Decrement memory at m(IX+d) + +NEG NEG NEG + Negate A (two's complement) + +IM0 IM0 IM0 + Set interrupt mode 0 + +IM1 IM1 IM1 + Set interrupt mode 1 + +IM2 IM2 IM2 + Set interrupt mode 2 + +DADC rr ADC HL,rr DADC rr + Add with carry rr to HL + +DSBC rr SBC HL,rr DSBC rr + Subtract with "borrow" rr from HL + +DADX rr ADD IX,rr DADX rr + Add rr to IX (rr may be BC, DE, SP, IX) + +DADY rr ADD IY,rr DADY rr + Add rr to IY (rr may be BC, DE, SP, IY) + +INXIX INC IX INX IX + Increment IX + +INXIY INC IY INX IY + Increment IY + +DCXIX DEC IX DCX IX + Decrement IX + +DCXIY DEC IY DCX IY + Decrement IY + +BIT b,r BIT b,r BIT b,r + Test bit b in register r + +SETB b,r SET b,r SET b,r + Set bit b in register r + +RES b,r RES b,r RES b,r + Reset bit b in register r + +BITX b,d BIT b,(IX+d) BIT b,d(IX) + Test bit b in memory at m(IX+d) + +BITY b,d BIT b,(IY+d) BIT b,d(IY) + Test bit b in memory at m(IY+d) + +SETX b,d SET b,(IX+d) SET b,d(IX) + Set bit b in memory at m(IX+d) + +SETY b,d SET b,(IY+d) SET b,d(IY) + Set bit b in memory at m(IY+d) + +RESX b,d RES b,(IX+d) RES b,d(IX) + Reset bit b in memory at m(IX+d) + +RESY b,d RES b,(IY+d) RES b,d(IY) + Reset bit b in memory at m(IY+d) + +JR addr JR addr-$ JMPR addr + Jump relative unconditional + +JRC addr JR C,addr-$ JRC addr + Jump relative if Carry indicator true + +JRNC addr JR NC,addr-$ JRNC addr + Jump relative if carry indicator false + +JRZ addr JR Z,addr-$ JRC addr + Jump relative if Zero indicator true + +JRNZ addr JR NZ,addr-$ JRNZ addr + Jump relative if Zero indicator false + +DJNZ addr DJNZ addr-$ DJNZ addr + Decrement B, jump relative if non-zero + +PCIX JMP (IX) PCIX + Jump to address in IX ie, Load PC from IX + +PCIY JMP (IY) PCIY + Jump to address in IY + +RETI RETI RETI + Return from interrupt + +RETN RETN RETN + Return from non-maskable interrupt + +INP r IN r,(C) INP r + Input from port C to register r + +OUTP r OUT (C),r OUTP r + Output from register r to port (C) + +INI INI INI + Input from port (C) to m(HL), increment HL, decrement b + +INIR INIR INIR + Input from port (C) to m(HL), increment HL, decrement B, repeat if B <> 0 + +OUTI OTI OUTI + Output from m(HL) to port (C), increment HL, decrement B + +OUTIR OTIR OUTIR + Repeat OUTI until B = 0 + +IND IND IND + Input from port (C) to m(HL), decrement HL & B + +INDR INDR INDR + Repeat IND until B = 0 + +OUTD OTD OUTD + Output from m(HL) to port (C), decrement HL & B + +OUTDR OTDR OUTDR + Repeat OUTD until B = 0 + +RLCR r RLC r RLCR r + Rotate left circular register + +RLCX d RLC (IX+d) RLCR d(IX) + Rotate left circular indexed memory + +RLCY d RLC (IY+d) RLCR d(IY) + Rotate left circular indexed memory + +RALR r RL r RALR r + Rotate left arithmetic register + +RALX d RL (IX+d) RALR d(IX) + Rotate left arithmetic indexed memory + +RALY d RL (IY+d) RALR d(IY) + Rotate left arithmetic indexed memory + +RRCR r RRC r RRCR r + Rotate right circular register + +RRCX d RRC (IX+d) RRCR d(IX) + Rotate right circular indexed + +RRCY d RRC (IY+d) RRCR d(IY) + Rotate right circular indexed + +RARR r RR r RARR r + Rotate right arithmetic register + +RARX d RR (IX+d) RARR d(IX) + Rotate right arithmetic indexed memory + +RARY d RR (IY+d) RARR d(IY) + Rotate right arithmetic indexed memory + +SLAR r SLA r SLAR r + Shift left register + +SLAX d SLA (IX+d) SLAR d(IX) + Shift left indexed memory + +SLAY d SLA (IY+d) SLAR d(IY) + Shift left indexed memory + +SRAR r SRA r SRAR r + Shift right arithmetic register + +SRAX d SRA (IX+d) SRAR d(IX) + Shift right arithmetic indexed memory + +SRAY d SRA (IY+d) SRAR d(IY) + Shift right arithmetic indexed memory + +SRLR r SRL r SRLR r + Shift right logical register + +SRLX d SRL (IX+d) SRLR d(IX) + Shift right logical indexed memory + +SRLY d SRL (IY+d) SRLR d(IY) + Shift right logical indexed memory + +RLD RLD RLD + Rotate left digit + +RRD RRD RRD + Rotate right digit + + \ No newline at end of file diff --git a/releases/zsm20/Z80.LIB b/releases/zsm20/Z80.LIB new file mode 100644 index 0000000..f786589 --- /dev/null +++ b/releases/zsm20/Z80.LIB @@ -0,0 +1,457 @@ +; @CHK MACRO USED FOR CHECKING 8 BIT DISPLACMENTS +; +@CHK MACRO ?DD ;; USED FOR CHECKING RANGE OF 8-BIT DISP.S + IF (?DD GT 7FH) AND (?DD LT 0FF80H) + 'DISPLACEMENT RANGE ERROR - Z80 LIB' + ENDIF + ENDM +LDX MACRO ?R,?D + @CHK ?D + DB 0DDH,?R*8+46H,?D + ENDM +LDY MACRO ?R,?D + @CHK ?D + DB 0FDH,?R*8+46H,?D + ENDM +STX MACRO ?R,?D + @CHK ?D + DB 0DDH,70H+?R,?D + ENDM +STY MACRO ?R,?D + @CHK ?D + DB 0FDH,70H+?R,?D + ENDM +MVIX MACRO ?N,?D + @CHK ?D + DB 0DDH,36H,?D,?N + ENDM +MVIY MACRO ?N,?D + @CHK ?D + DB 0FDH,36H,?D,?N + ENDM +LDAI MACRO + DB 0EDH,57H + ENDM +LDAR MACRO + DB 0EDH,5FH + ENDM +STAI MACRO + DB 0EDH,47H + ENDM +STAR MACRO + DB 0EDH,4FH + ENDM + +LXIX MACRO ?NNNN + DB 0DDH,21H + DW ?NNNN + ENDM +LXIY MACRO ?NNNN + DB 0FDH,21H + DW ?NNNN + ENDM +LDED MACRO ?NNNN + DB 0EDH,5BH + DW ?NNNN + ENDM +LBCD MACRO ?NNNN + DB 0EDH,4BH + DW ?NNNN + ENDM +LSPD MACRO ?NNNN + DB 0EDH,07BH + DW ?NNNN + ENDM +LIXD MACRO ?NNNN + DB 0DDH,2AH + DW ?NNNN + ENDM +LIYD MACRO ?NNNN + DB 0FDH,2AH + DW ?NNNN + ENDM +SBCD MACRO ?NNNN + DB 0EDH,43H + DW ?NNNN + ENDM +SDED MACRO ?NNNN + DB 0EDH,53H + DW ?NNNN + ENDM +SSPD MACRO ?NNNN + DB 0EDH,73H + DW ?NNNN + ENDM +SIXD MACRO ?NNNN + DB 0DDH,22H + DW ?NNNN + ENDM +SIYD MACRO ?NNNN + DB 0FDH,22H + DW ?NNNN + ENDM +SPIX MACRO + DB 0DDH,0F9H + ENDM +SPIY MACRO + DB 0FDH,0F9H + ENDM +PUSHIX MACRO + DB 0DDH,0E5H + ENDM +PUSHIY MACRO + DB 0FDH,0E5H + ENDM +POPIX MACRO + DB 0DDH,0E1H + ENDM +POPIY MACRO + DB 0FDH,0E1H + ENDM +EXAF MACRO + DB 08H + ENDM +EXX MACRO + DB 0D9H + ENDM +XTIX MACRO + DB 0DDH,0E3H + ENDM +XTIY MACRO + DB 0FDH,0E3H + ENDM + +LDI MACRO + DB 0EDH,0A0H + ENDM +LDIR MACRO + DB 0EDH,0B0H + ENDM +LDD MACRO + DB 0EDH,0A8H + ENDM +LDDR MACRO + DB 0EDH,0B8H + ENDM +CCI MACRO + DB 0EDH,0A1H + ENDM +CCIR MACRO + DB 0EDH,0B1H + ENDM +CCD MACRO + DB 0EDH,0A9H + ENDM +CCDR MACRO + DB 0EDH,0B9H + ENDM + +ADDX MACRO ?D + @CHK ?D + DB 0DDH,86H,?D + ENDM +ADDY MACRO ?D + @CHK ?D + DB 0FDH,86H,?D + ENDM +ADCX MACRO ?D + @CHK ?D + DB 0DDH,8EH,?D + ENDM +ADCY MACRO ?D + @CHK ?D + DB 0FDH,8EH,?D + ENDM +SUBX MACRO ?D + @CHK ?D + DB 0DDH,96H,?D + ENDM +SUBY MACRO ?D + @CHK ?D + DB 0FDH,96H,?D + ENDM +SBCX MACRO ?D + @CHK ?D + DB 0DDH,9EH,?D + ENDM +SBCY MACRO ?D + @CHK ?D + DB 0FDH,9EH,?D + ENDM +ANDX MACRO ?D + @CHK ?D + DB 0DDH,0A6H,?D + ENDM +ANDY MACRO ?D + @CHK ?D + DB 0FDH,0A6H,?D + ENDM +XORX MACRO ?D + @CHK ?D + DB 0DDH,0AEH,?D + ENDM +XORY MACRO ?D + @CHK ?D + DB 0FDH,0AEH,?D + ENDM +ORX MACRO ?D + @CHK ?D + DB 0DDH,0B6H,?D + ENDM +ORY MACRO ?D + @CHK ?D + DB 0FDH,0B6H,?D + ENDM +CMPX MACRO ?D + @CHK ?D + DB 0DDH,0BEH,?D + ENDM +CMPY MACRO ?D + @CHK ?D + DB 0FDH,0BEH,?D + ENDM +INRX MACRO ?D + @CHK ?D + DB 0DDH,34H,?D + ENDM +INRY MACRO ?D + @CHK ?D + DB 0FDH,34H,?D + ENDM +DCRX MACRO ?D + @CHK ?D + DB 0DDH,035H,?D + ENDM +DCRY MACRO ?D + @CHK ?D + DB 0FDH,35H,?D + ENDM + +NEG MACRO + DB 0EDH,44H + ENDM +IM0 MACRO + DB 0EDH,46H + ENDM +IM1 MACRO + DB 0EDH,56H + ENDM +IM2 MACRO + DB 0EDH,5EH + ENDM + + +BC EQU 0 +DE EQU 2 +HL EQU 4 +IX EQU 4 +IY EQU 4 +DADC MACRO ?R + DB 0EDH,?R*8+4AH + ENDM +DSBC MACRO ?R + DB 0EDH,?R*8+42H + ENDM +DADX MACRO ?R + DB 0DDH,?R*8+09H + ENDM +DADY MACRO ?R + DB 0FDH,?R*8+09H + ENDM +INXIX MACRO + DB 0DDH,23H + ENDM +INXIY MACRO + DB 0FDH,23H + ENDM +DCXIX MACRO + DB 0DDH,2BH + ENDM +DCXIY MACRO + DB 0FDH,2BH + ENDM + +BIT MACRO ?N,?R + DB 0CBH,?N*8+?R+40H + ENDM +SETB MACRO ?N,?R + DB 0CBH,?N*8+?R+0C0H + ENDM +RES MACRO ?N,?R + DB 0CBH,?N*8+?R+80H + ENDM + +BITX MACRO ?N,?D + @CHK ?D + DB 0DDH,0CBH,?D,?N*8+46H + ENDM +BITY MACRO ?N,?D + @CHK ?D + DB 0FDH,0CBH,?D,?N*8+46H + ENDM +SETX MACRO ?N,?D + @CHK ?D + DB 0DDH,0CBH,?D,?N*8+0C6H + ENDM +SETY MACRO ?N,?D + @CHK ?D + DB 0FDH,0CBH,?D,?N*8+0C6H + ENDM +RESX MACRO ?N,?D + @CHK ?D + DB 0DDH,0CBH,?D,?N*8+86H + ENDM +RESY MACRO ?N,?D + @CHK ?D + DB 0FDH,0CBH,?D,?N*8+86H + ENDM + +JR MACRO ?N + DB 18H,?N-$-1 + ENDM +JRC MACRO ?N + DB 38H,?N-$-1 + ENDM +JRNC MACRO ?N + DB 30H,?N-$-1 + ENDM +JRZ MACRO ?N + DB 28H,?N-$-1 + ENDM +JRNZ MACRO ?N + DB 20H,?N-$-1 + ENDM +DJNZ MACRO ?N + DB 10H,?N-$-1 + ENDM + +PCIX MACRO + DB 0DDH,0E9H + ENDM +PCIY MACRO + DB 0FDH,0E9H + ENDM + +RETI MACRO + DB 0EDH,4DH + ENDM +RETN MACRO + DB 0EDH,45H + ENDM + +INP MACRO ?R + DB 0EDH,?R*8+40H + ENDM +OUTP MACRO ?R + DB 0EDH,?R*8+41H + ENDM +INI MACRO + DB 0EDH,0A2H + ENDM +INIR MACRO + DB 0EDH,0B2H + ENDM +IND MACRO + DB 0EDH,0AAH + ENDM +INDR MACRO + DB 0EDH,0BAH + ENDM +OUTI MACRO + DB 0EDH,0A3H + ENDM +OUTIR MACRO + DB 0EDH,0B3H + ENDM +OUTD MACRO + DB 0EDH,0ABH + ENDM +OUTDR MACRO + DB 0EDH,0BBH + ENDM + + +RLCR MACRO ?R + DB 0CBH, 00H + ?R + ENDM +RLCX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 06H + ENDM +RLCY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 06H + ENDM +RALR MACRO ?R + DB 0CBH, 10H+?R + ENDM +RALX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 16H + ENDM +RALY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 16H + ENDM +RRCR MACRO ?R + DB 0CBH, 08H + ?R + ENDM +RRCX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 0EH + ENDM +RRCY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 0EH + ENDM +RARR MACRO ?R + DB 0CBH, 18H + ?R + ENDM +RARX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 1EH + ENDM +RARY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 1EH + ENDM +SLAR MACRO ?R + DB 0CBH, 20H + ?R + ENDM +SLAX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 26H + ENDM +SLAY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 26H + ENDM +SRAR MACRO ?R + DB 0CBH, 28H+?R + ENDM +SRAX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 2EH + ENDM +SRAY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 2EH + ENDM +SRLR MACRO ?R + DB 0CBH, 38H + ?R + ENDM +SRLX MACRO ?D + @CHK ?D + DB 0DDH, 0CBH, ?D, 3EH + ENDM +SRLY MACRO ?D + @CHK ?D + DB 0FDH, 0CBH, ?D, 3EH + ENDM +RLD MACRO + DB 0EDH, 6FH + ENDM +RRD MACRO + DB 0EDH, 67H + ENDM + \ No newline at end of file diff --git a/releases/zsm20/Z80ASM.COM b/releases/zsm20/Z80ASM.COM new file mode 100644 index 0000000..8b0c3d9 Binary files /dev/null and b/releases/zsm20/Z80ASM.COM differ diff --git a/releases/zsm20/Z80DOC.DOC b/releases/zsm20/Z80DOC.DOC new file mode 100644 index 0000000..61debe7 --- /dev/null +++ b/releases/zsm20/Z80DOC.DOC @@ -0,0 +1,132 @@ + + + Z + 8 + 0 + A + S + M + + + ZILOG/MOSTEK + + Z80-CPU + + + ASSEMBLY + LANGUAGE + PROCESSOR + + + (C) COPYRIGHT 1977 LCS + ALL RIGHTS RESERVED + + + LATEST REVISION: 21-JULY-1977 + + + Z 8 0 A S M + + Z80ASM IS AN ASSEMBLER FOR THE ZILOG/MOSTEK Z80-CPU MICROPROCESSOR. + +IT IS DESIGNED TO RUN UNDER THE CP/M OPERATING SYSTEM FROM DIGITAL RESEARCH. + +CP/M WILL RUN ON EITHER AN 8080A SYSTEM OR A Z80 SYSTEM. Z80ASM WILL RUN + +IN THE CP/M MINIMUM (16K) SYSTEM BUT WILL UTILIZE MORE MEMORY FOR SYMBOL + +TABLE STORAGE IN LARGER (UP TO 64K) CP/M SYSTEMS. + + Z80ASM READS A SOURCE (ASM) FILE PRODUCED BY THE CP/M 'ED' TEXT EDITOR + +PROGRAM AND PRODUCES AN OPTIONAL LISTING (ON THE LST: DEVICE) AND AN OPTIONAL + +OBJECT CODE (HEX) FILE IN INTEL FORMAT HEX. THE 'HEX' FILE CAN BE LOADED + +FOR EXECUTION USING 'DDT' OR 'LOAD' COMMANDS OF CP/M OR IT CAN BE PUNCHED + +ON PAPER TAPE USING THE 'PIP' PROGRAM. + + INPUT STATEMENTS ARE FREE FORMAT (I.E. NOT COLUMN ORIENTED). BETWEEN + +FIELDS ANY NUMBER OF BLANK OR TAB CHARACTERS MAY BE PRESENT BUT WITHIN A FIELD + +THERE MAY BE NO BLANK OR TAB CHARACTERS. HOWEVER, STATEMENTS LABELS MUST BE + +IN THE FIRST POSITION OF THE LINE. STATEMENT LABELS MAY HAVE A COLON FOLLOWING + +THEM BUT THE COLON IS NOT REQUIRED. COMMENTS ARE PRECEEDED BY A SEMICOLON + +AND MAY APPEAR BY THEMSELVES OR FOLLOWING ALL OF THE FIELDS ON A SOURCE LINE. + + + ALL THE ZILOG/MOSTEK MNEMONICS ARE SUPPORTED WITH THE FOLLOWING + +EXCEPTIONS: + + 1. THE Z80CPU TECHNICAL MANUAL HAS CONFLICTING INFORMATION REGARDING + THE SYNTAX OF THE RLC,RL,RRC AND RR INSTRUCTIONS WHEN THE A + REGISTER IS USED AS THE OPERAND. ON PAGE 50 THE FORMS + 'RLCA','RLA','RRCA','RRA' ARE USED WHILE ON PAGE 68 THE FORM + 'RR A' IS SHOWN. Z80ASM WILL SUPPORT ONLY THE 'RRA', ETC. FORM. + + 2. THE Z80CPU MANUAL DOES NOT DESCRIBE THE PSEUDO OPERATORS AVAILABLE + EXCEPT THAT 'EQU' AND 'DEFS' ARE USED ON PAGE 67 IN THE SAMPLE + PROGRAM. THE LIST BELOW DESCRIBES THE PSEUDO OPERATORS AVAILABLE + IN Z80ASM AND THEIR ARGUMENT FORMATS: + +