forked from amberisvibin/chibi-pc09
copy all local files to repo
cp/m files, sprites, circuit design
This commit is contained in:
41
emu/z80pack-1.9/z80asm/Makefile
Normal file
41
emu/z80pack-1.9/z80asm/Makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
CFLAGS = -c -O
|
||||
LFLAGS = -s
|
||||
|
||||
OBJ = z80amain.o \
|
||||
z80atab.o \
|
||||
z80anum.o \
|
||||
z80aout.o \
|
||||
z80arfun.o \
|
||||
z80apfun.o \
|
||||
z80aopc.o \
|
||||
z80aglb.o
|
||||
|
||||
z80asm : $(OBJ)
|
||||
cc $(OBJ) $(LFLAGS) -o z80asm
|
||||
|
||||
z80amain.o : z80amain.c z80a.h z80aglb.h
|
||||
cc $(CFLAGS) z80amain.c
|
||||
|
||||
z80atab.o : z80atab.c z80a.h z80aglb.h
|
||||
cc $(CFLAGS) z80atab.c
|
||||
|
||||
z80anum.o : z80anum.c z80a.h z80aglb.h
|
||||
cc $(CFLAGS) z80anum.c
|
||||
|
||||
z80aout.o : z80aout.c z80a.h z80aglb.h
|
||||
cc $(CFLAGS) z80aout.c
|
||||
|
||||
z80arfun.o : z80arfun.c z80a.h z80aglb.h
|
||||
cc $(CFLAGS) z80arfun.c
|
||||
|
||||
z80apfun.o : z80apfun.c z80a.h z80aglb.h
|
||||
cc $(CFLAGS) z80apfun.c
|
||||
|
||||
z80aopc.o : z80aopc.c z80a.h
|
||||
cc $(CFLAGS) z80aopc.c
|
||||
|
||||
z80aglb.o : z80aglb.c z80a.h
|
||||
cc $(CFLAGS) z80aglb.c
|
||||
|
||||
clean:
|
||||
rm -f core *.o z80asm
|
144
emu/z80pack-1.9/z80asm/z80a.h
Normal file
144
emu/z80pack-1.9/z80asm/z80a.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* OS dependant definitions
|
||||
*/
|
||||
#define LENFN 2048 /* max. filename length */
|
||||
#define READA "r" /* file open mode read ascii */
|
||||
#define WRITEA "w" /* file open mode write ascii */
|
||||
#define WRITEB "w" /* file open mode write binary */
|
||||
|
||||
/*
|
||||
* various constants
|
||||
*/
|
||||
#define REL "1.3"
|
||||
#define COPYR "Copyright (C) 1987-2006 by Udo Munk"
|
||||
#define SRCEXT ".asm" /* filenamen extension source */
|
||||
#define OBJEXT ".bin" /* filenamen extension object */
|
||||
#define LSTEXT ".lis" /* filenamen extension listing */
|
||||
#define OUTBIN 1 /* format of object: binary */
|
||||
#define OUTMOS 2 /* Mostek binaer */
|
||||
#define OUTHEX 3 /* Intel hex */
|
||||
#define OUTDEF OUTMOS /* default object format */
|
||||
#define COMMENT ';' /* inline comment character */
|
||||
#define LINCOM '*' /* comment line if in columne 1 */
|
||||
#define LABSEP ':' /* label separator */
|
||||
#define STRSEP '\'' /* string separator */
|
||||
#define ENDFILE "END" /* end of source */
|
||||
#define MAXFN 512 /* max. no. source files */
|
||||
#define MAXLINE 128 /* max. line length source */
|
||||
#define PLENGTH 65 /* default lines/page in listing */
|
||||
#define SYMSIZE 8 /* max. symbol length */
|
||||
#define INCNEST 5 /* max. INCLUDE nesting depth */
|
||||
#define IFNEST 5 /* max IF.. nesting depth */
|
||||
#define HASHSIZE 500 /* max. entries in symbol hash array */
|
||||
#define OPCARRAY 256 /* size of object buffer */
|
||||
#define SYMINC 100 /* start size of sorted symbol array */
|
||||
|
||||
/*
|
||||
* structure opcode table
|
||||
*/
|
||||
struct opc {
|
||||
char *op_name; /* opcode name */
|
||||
int (*op_fun) (); /* function pointer code generation */
|
||||
int op_c1; /* first base opcode*/
|
||||
int op_c2; /* second base opcode */
|
||||
};
|
||||
|
||||
/*
|
||||
* structure operand table
|
||||
*/
|
||||
struct ope {
|
||||
char *ope_name; /* operand name */
|
||||
int ope_sym; /* symbol value operand */
|
||||
};
|
||||
|
||||
/*
|
||||
* structure symbol table entries
|
||||
*/
|
||||
struct sym {
|
||||
char *sym_name; /* symbol name */
|
||||
int sym_wert; /* symbol value */
|
||||
struct sym *sym_next; /* next entry */
|
||||
};
|
||||
|
||||
/*
|
||||
* structure nested INCLUDE's
|
||||
*/
|
||||
struct inc {
|
||||
unsigned inc_line; /* line counter for listing */
|
||||
char *inc_fn; /* filename */
|
||||
FILE *inc_fp; /* file pointer */
|
||||
};
|
||||
|
||||
/*
|
||||
* definition of operand symbols
|
||||
* definitions for registers A, B, C, D, H, L and (HL)
|
||||
* are defined as the bits used in operands and may not
|
||||
* be changed!
|
||||
*/
|
||||
#define REGB 0 /* register B */
|
||||
#define REGC 1 /* register C */
|
||||
#define REGD 2 /* register D */
|
||||
#define REGE 3 /* register E */
|
||||
#define REGH 4 /* register H */
|
||||
#define REGL 5 /* register L */
|
||||
#define REGIHL 6 /* register indirect HL */
|
||||
#define REGA 7 /* register A */
|
||||
#define REGI 8 /* register I */
|
||||
#define REGR 9 /* register R */
|
||||
#define REGAF 10 /* register pair AF */
|
||||
#define REGBC 11 /* register pair BC */
|
||||
#define REGDE 12 /* register pair DE */
|
||||
#define REGHL 13 /* register pair HL */
|
||||
#define REGIX 14 /* register IX */
|
||||
#define REGIY 15 /* register IY */
|
||||
#define REGSP 16 /* register SP */
|
||||
#define REGIBC 17 /* register indirect BC */
|
||||
#define REGIDE 18 /* register indirect DE */
|
||||
#define REGIIX 19 /* register indirect IX */
|
||||
#define REGIIY 20 /* register indirect IY */
|
||||
#define REGISP 21 /* register indirect SP */
|
||||
#define FLGNC 30 /* flag no carry */
|
||||
#define FLGNZ 31 /* flag not zerro */
|
||||
#define FLGZ 32 /* flag zerro */
|
||||
#define FLGM 33 /* flag minus */
|
||||
#define FLGP 34 /* flag plus */
|
||||
#define FLGPE 35 /* flag parrity even */
|
||||
#define FLGPO 36 /* flag parrity odd */
|
||||
#define NOOPERA 98 /* no operand */
|
||||
#define NOREG 99 /* operand isn't register */
|
||||
|
||||
/*
|
||||
* definitions of error numbers for error messages in listfile
|
||||
*/
|
||||
#define E_ILLOPC 0 /* illegal opcode */
|
||||
#define E_ILLOPE 1 /* illegal operand */
|
||||
#define E_MISOPE 2 /* missing operand */
|
||||
#define E_MULSYM 3 /* multiple defined symbol */
|
||||
#define E_UNDSYM 4 /* undefined symbol */
|
||||
#define E_VALOUT 5 /* value out of bounds */
|
||||
#define E_MISPAR 6 /* missing parren */
|
||||
#define E_MISHYP 7 /* missing string separator */
|
||||
#define E_MEMOVR 8 /* memory override (ORG) */
|
||||
#define E_MISIFF 9 /* missing IF at ELSE or ENDIF */
|
||||
#define E_IFNEST 10 /* to many IF's nested */
|
||||
#define E_MISEIF 11 /* missing ENDIF */
|
||||
#define E_INCNEST 12 /* to many INCLUDE's nested */
|
||||
|
||||
/*
|
||||
* definition fatal errors
|
||||
*/
|
||||
#define F_OUTMEM 0 /* out of memory */
|
||||
#define F_USAGE 1 /* usage: .... */
|
||||
#define F_HALT 2 /* assembly halted */
|
||||
#define F_FOPEN 3 /* can't open file */
|
||||
#define F_INTERN 4 /* internal error */
|
67
emu/z80pack-1.9/z80asm/z80aglb.c
Normal file
67
emu/z80pack-1.9/z80asm/z80aglb.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* this module contains all global variables other
|
||||
* than CPU specific tables
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "z80a.h"
|
||||
|
||||
char *infiles[MAXFN], /* source filenames */
|
||||
objfn[LENFN + 1], /* object filename */
|
||||
lstfn[LENFN + 1], /* listing filename */
|
||||
*srcfn, /* filename of current processed source file */
|
||||
line[MAXLINE], /* buffer for one line souce */
|
||||
tmp[MAXLINE], /* temporary buffer */
|
||||
label[SYMSIZE+1], /* buffer for label */
|
||||
opcode[MAXLINE], /* buffer for opcode */
|
||||
operand[MAXLINE], /* buffer for operand */
|
||||
ops[OPCARRAY], /* buffer for generated object code */
|
||||
title[MAXLINE]; /* buffer for titel of souce */
|
||||
|
||||
int list_flag, /* flag for option -l */
|
||||
sym_flag, /* flag for option -s */
|
||||
ver_flag, /* flag for option -v */
|
||||
dump_flag, /* flag for option -x */
|
||||
pc, /* programm counter */
|
||||
pass, /* processed pass */
|
||||
iflevel, /* IF nesting level */
|
||||
gencode = 1, /* flag for conditional object code */
|
||||
errors, /* error counter */
|
||||
errnum, /* error number in pass 2 */
|
||||
sd_flag, /* list flag for PSEUDO opcodes */
|
||||
/* = 0: address from <val>, data from <ops> */
|
||||
/* = 1: address from <sd_val>, data from <ops>*/
|
||||
/* = 2: no address, data from <ops> */
|
||||
/* = 3: address from <sd_val>, no data */
|
||||
/* = 4: suppress whole line */
|
||||
sd_val, /* output value for PSEUDO opcodes */
|
||||
prg_adr, /* start address of programm */
|
||||
prg_flag, /* flag for prg_adr valid */
|
||||
out_form = OUTDEF, /* format of object file */
|
||||
symsize; /* size of symarray */
|
||||
|
||||
FILE *srcfp, /* file pointer for current source */
|
||||
*objfp, /* file pointer for object code */
|
||||
*lstfp, /* file pointer for listing */
|
||||
*errfp; /* file pointer for error output */
|
||||
|
||||
unsigned
|
||||
c_line, /* current line no. in current source */
|
||||
s_line, /* line no. counter for listing */
|
||||
p_line, /* no. printed lines on page */
|
||||
ppl = PLENGTH, /* page length */
|
||||
page; /* no. of pages for listing */
|
||||
|
||||
struct sym
|
||||
*symtab[HASHSIZE], /* symbol table */
|
||||
**symarray; /* sorted symbol table */
|
62
emu/z80pack-1.9/z80asm/z80aglb.h
Normal file
62
emu/z80pack-1.9/z80asm/z80aglb.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* global variable declarations
|
||||
*/
|
||||
|
||||
extern char *infiles[],
|
||||
objfn[],
|
||||
lstfn[],
|
||||
*srcfn,
|
||||
line[],
|
||||
tmp[],
|
||||
label[],
|
||||
opcode[],
|
||||
operand[],
|
||||
ops[],
|
||||
title[];
|
||||
|
||||
extern int list_flag,
|
||||
sym_flag,
|
||||
ver_flag,
|
||||
dump_flag,
|
||||
pc,
|
||||
pass,
|
||||
iflevel,
|
||||
gencode,
|
||||
errors,
|
||||
errnum,
|
||||
sd_flag,
|
||||
sd_val,
|
||||
prg_adr,
|
||||
prg_flag,
|
||||
out_form,
|
||||
symsize,
|
||||
no_opcodes,
|
||||
no_operands;
|
||||
|
||||
extern FILE *srcfp,
|
||||
*objfp,
|
||||
*lstfp,
|
||||
*errfp;
|
||||
|
||||
extern unsigned c_line,
|
||||
s_line,
|
||||
p_line,
|
||||
ppl,
|
||||
page;
|
||||
|
||||
extern struct sym *symtab[],
|
||||
**symarray;
|
||||
|
||||
extern struct opc opctab[];
|
||||
|
||||
extern struct ope opetab[];
|
503
emu/z80pack-1.9/z80asm/z80amain.c
Normal file
503
emu/z80pack-1.9/z80asm/z80amain.c
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* main module, handles the options and runs 2 passes over the sources
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "z80a.h"
|
||||
#include "z80aglb.h"
|
||||
|
||||
void init(void), options(int, char *[]);
|
||||
void usage(void), fatal(int, char *);
|
||||
void pass1(void), p1_file(char *);
|
||||
void pass2(void), p2_file(char *);
|
||||
void open_o_files(char *), get_fn(char *, char *, char *);
|
||||
char *get_label(char *, char *);
|
||||
char *get_opcode(char *, char *);
|
||||
char *get_arg(char *, char *);
|
||||
|
||||
extern void asmerr(int);
|
||||
extern void lst_line(int, int);
|
||||
extern void lst_sym(void);
|
||||
extern void lst_sort_sym(int);
|
||||
extern void obj_header(void);
|
||||
extern void obj_end(void);
|
||||
extern void obj_writeb(int);
|
||||
extern struct opc *search_op(char *);
|
||||
extern int put_sym(char *, int);
|
||||
extern void put_label(void);
|
||||
extern int copy_sym(void);
|
||||
extern void n_sort_sym(int);
|
||||
extern void a_sort_sym(int);
|
||||
|
||||
static char *errmsg[] = { /* error messages for fatal() */
|
||||
"out of memory: %s", /* 0 */
|
||||
"usage: z80asm -ofile -f[b|m|h] -l[file] -s[n|a] {-x} -v -dsymbol ... file ...",
|
||||
"Assembly halted", /* 2 */
|
||||
"can't open file %s", /* 3 */
|
||||
"internal error: %s" /* 4 */
|
||||
};
|
||||
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int len;
|
||||
|
||||
init();
|
||||
options(argc, argv);
|
||||
printf("Z80 - Assembler Release %s, %s\n", REL, COPYR);
|
||||
pass1();
|
||||
pass2();
|
||||
if (list_flag) {
|
||||
switch (sym_flag) {
|
||||
case 0: /* no symbol table */
|
||||
break;
|
||||
case 1: /* unsorted symbol table */
|
||||
lst_sym();
|
||||
break;
|
||||
case 2: /* symbol table sorted by name */
|
||||
len = copy_sym();
|
||||
n_sort_sym(len);
|
||||
lst_sort_sym(len);
|
||||
break;
|
||||
case 3: /* symbol table sorted by address */
|
||||
len = copy_sym();
|
||||
a_sort_sym(len);
|
||||
lst_sort_sym(len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fclose(lstfp);
|
||||
}
|
||||
return(errors);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
void init(void)
|
||||
{
|
||||
errfp = stdout;
|
||||
}
|
||||
|
||||
/*
|
||||
* process options
|
||||
*/
|
||||
void options(int argc, char *argv[])
|
||||
{
|
||||
register char *s, *t;
|
||||
register int i;
|
||||
|
||||
while (--argc > 0 && (*++argv)[0] == '-')
|
||||
for (s = argv[0]+1; *s != '\0'; s++)
|
||||
switch (*s) {
|
||||
case 'o':
|
||||
case 'O':
|
||||
if (*++s == '\0') {
|
||||
puts("name missing in option -o");
|
||||
usage();
|
||||
}
|
||||
get_fn(objfn, s, OBJEXT);
|
||||
s += (strlen(s) - 1);
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
if (*(s + 1) != '\0') {
|
||||
get_fn(lstfn, ++s, LSTEXT);
|
||||
s += (strlen(s) - 1);
|
||||
}
|
||||
list_flag = 1;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
if (*(s + 1) == '\0')
|
||||
sym_flag = 1;
|
||||
else if ((*(s + 1) == 'n') || (*(s + 1) == 'N'))
|
||||
sym_flag = 2;
|
||||
else if ((*(s + 1) == 'a') || (*(s + 1) == 'A'))
|
||||
sym_flag = 3;
|
||||
else {
|
||||
printf("unknown option -%s\n", s);
|
||||
usage();
|
||||
}
|
||||
s += (strlen(s) - 1);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
dump_flag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
if ((*(s + 1) == 'b') || (*(s + 1) == 'B'))
|
||||
out_form = OUTBIN;
|
||||
else if ((*(s + 1) == 'm') || (*(s + 1) == 'M'))
|
||||
out_form = OUTMOS;
|
||||
else if ((*(s + 1) == 'h') || (*(s + 1) == 'H'))
|
||||
out_form = OUTHEX;
|
||||
else {
|
||||
printf("unknown option -%s\n", s);
|
||||
usage();
|
||||
}
|
||||
s += (strlen(s) - 1);
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
if (*++s == '\0') {
|
||||
puts("name missing in option -d");
|
||||
usage();
|
||||
}
|
||||
t = tmp;
|
||||
while (*s)
|
||||
*t++ = islower(*s) ? toupper(*s++)
|
||||
: *s++;
|
||||
s--;
|
||||
*t = '\0';
|
||||
if (put_sym(tmp, 0))
|
||||
fatal(F_OUTMEM, "symbols");
|
||||
break;
|
||||
case 'v':
|
||||
case 'V':
|
||||
ver_flag = 1;
|
||||
break;
|
||||
default :
|
||||
printf("unknown option %c\n", *s);
|
||||
usage();
|
||||
}
|
||||
i = 0;
|
||||
while ((argc--) && (i < MAXFN)) {
|
||||
if ((infiles[i] = malloc(LENFN + 1)) == NULL)
|
||||
fatal(F_OUTMEM, "filenames");
|
||||
get_fn(infiles[i], *argv++, SRCEXT);
|
||||
i++;
|
||||
}
|
||||
if (i == 0) {
|
||||
printf("no input file given\n");
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* error in options, print usage
|
||||
*/
|
||||
void usage(void)
|
||||
{
|
||||
fatal(F_USAGE, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* print error messages and abort
|
||||
*/
|
||||
void fatal(int i, char *arg)
|
||||
{
|
||||
printf(errmsg[i], arg);
|
||||
putchar('\n');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass 1:
|
||||
* - process all source files
|
||||
*/
|
||||
void pass1(void)
|
||||
{
|
||||
register int fi;
|
||||
|
||||
pass = 1;
|
||||
pc = 0;
|
||||
fi = 0;
|
||||
if (!ver_flag)
|
||||
puts("Pass 1");
|
||||
open_o_files(infiles[fi]);
|
||||
while (infiles[fi] != NULL) {
|
||||
if (!ver_flag)
|
||||
printf(" Read %s\n", infiles[fi]);
|
||||
p1_file(infiles[fi]);
|
||||
fi++;
|
||||
}
|
||||
if (errors) {
|
||||
fclose(objfp);
|
||||
unlink(objfn);
|
||||
printf("%d error(s)\n", errors);
|
||||
fatal(F_HALT, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass 1:
|
||||
* - process one source file
|
||||
*
|
||||
* Input: name of source file
|
||||
*/
|
||||
void p1_file(char *fn)
|
||||
{
|
||||
c_line = 0;
|
||||
srcfn = fn;
|
||||
if ((srcfp = fopen(fn, READA)) == NULL)
|
||||
fatal(F_FOPEN, fn);
|
||||
while (p1_line())
|
||||
;
|
||||
fclose(srcfp);
|
||||
if (iflevel)
|
||||
asmerr(E_MISEIF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass 1:
|
||||
* - process one line of source
|
||||
*
|
||||
* Output: 1 line processed
|
||||
* 0 EOF
|
||||
*/
|
||||
int p1_line(void)
|
||||
{
|
||||
register char *p;
|
||||
register int i;
|
||||
register struct opc *op;
|
||||
|
||||
if ((p = fgets(line, MAXLINE, srcfp)) == NULL)
|
||||
return(0);
|
||||
c_line++;
|
||||
p = get_label(label, p);
|
||||
p = get_opcode(opcode, p);
|
||||
p = get_arg(operand, p);
|
||||
if (strcmp(opcode, ENDFILE) == 0)
|
||||
return(0);
|
||||
if (*opcode) {
|
||||
if ((op = search_op(opcode)) != NULL) {
|
||||
i = (*op->op_fun)(op->op_c1, op->op_c2);
|
||||
if (gencode)
|
||||
pc += i;
|
||||
} else
|
||||
asmerr(E_ILLOPC);
|
||||
} else
|
||||
if (*label)
|
||||
put_label();
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass 2:
|
||||
* - process all source files
|
||||
*/
|
||||
void pass2(void)
|
||||
{
|
||||
register int fi;
|
||||
|
||||
pass = 2;
|
||||
pc = 0;
|
||||
fi = 0;
|
||||
if (!ver_flag)
|
||||
puts("Pass 2");
|
||||
obj_header();
|
||||
while (infiles[fi] != NULL) {
|
||||
if (!ver_flag)
|
||||
printf(" Read %s\n", infiles[fi]);
|
||||
p2_file(infiles[fi]);
|
||||
fi++;
|
||||
}
|
||||
obj_end();
|
||||
fclose(objfp);
|
||||
printf("%d error(s)\n", errors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass 2:
|
||||
* - process one source file
|
||||
*
|
||||
* Input: name of source file
|
||||
*/
|
||||
void p2_file(char *fn)
|
||||
{
|
||||
c_line = 0;
|
||||
srcfn = fn;
|
||||
if ((srcfp = fopen(fn, READA)) == NULL)
|
||||
fatal(F_FOPEN, fn);
|
||||
while (p2_line())
|
||||
;
|
||||
fclose(srcfp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass 2:
|
||||
* - process one line of source
|
||||
*
|
||||
* Output: 1 line processed
|
||||
* 0 EOF
|
||||
*/
|
||||
int p2_line(void)
|
||||
{
|
||||
register char *p;
|
||||
register int op_count;
|
||||
register struct opc *op;
|
||||
|
||||
if ((p = fgets(line, MAXLINE, srcfp)) == NULL)
|
||||
return(0);
|
||||
c_line++;
|
||||
s_line++;
|
||||
p = get_label(label, p);
|
||||
p = get_opcode(opcode, p);
|
||||
p = get_arg(operand, p);
|
||||
if (strcmp(opcode, ENDFILE) == 0) {
|
||||
lst_line(pc, 0);
|
||||
return(0);
|
||||
}
|
||||
if (*opcode) {
|
||||
op = search_op(opcode);
|
||||
op_count = (*op->op_fun)(op->op_c1, op->op_c2);
|
||||
if (gencode) {
|
||||
lst_line(pc, op_count);
|
||||
obj_writeb(op_count);
|
||||
pc += op_count;
|
||||
} else {
|
||||
sd_flag = 2;
|
||||
lst_line(0, 0);
|
||||
}
|
||||
} else {
|
||||
sd_flag = 2;
|
||||
lst_line(0, 0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* open output files:
|
||||
* input is filename of source file
|
||||
* list and object filenames are build from source filename if
|
||||
* not given by options
|
||||
*/
|
||||
void open_o_files(char *source)
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if (*objfn == '\0')
|
||||
strcpy(objfn, source);
|
||||
if ((p = strrchr(objfn, '.')) != NULL)
|
||||
strcpy(p, OBJEXT);
|
||||
else
|
||||
strcat(objfn, OBJEXT);
|
||||
|
||||
if (out_form == OUTHEX)
|
||||
objfp = fopen(objfn, WRITEA);
|
||||
else
|
||||
objfp = fopen(objfn, WRITEB);
|
||||
if (objfp == NULL)
|
||||
fatal(F_FOPEN, objfn);
|
||||
if (list_flag) {
|
||||
if (*lstfn == '\0')
|
||||
strcpy(lstfn, source);
|
||||
if ((p = strrchr(lstfn, '.')) != NULL)
|
||||
strcpy(p, LSTEXT);
|
||||
else
|
||||
strcat(lstfn, LSTEXT);
|
||||
if ((lstfp = fopen(lstfn, WRITEA)) == NULL)
|
||||
fatal(F_FOPEN, lstfn);
|
||||
errfp = lstfp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create a filename in "dest" from "src" and "ext"
|
||||
*/
|
||||
void get_fn(char *dest, char *src, char *ext)
|
||||
{
|
||||
register int i;
|
||||
register char *sp, *dp;
|
||||
|
||||
i = 0;
|
||||
sp = src;
|
||||
dp = dest;
|
||||
while ((i++ < LENFN) && (*sp != '\0'))
|
||||
*dp++ = *sp++;
|
||||
*dp = '\0';
|
||||
if ((strrchr(dest,'.') == NULL) &&
|
||||
(strlen(dest) <= (LENFN - strlen(ext))))
|
||||
strcat(dest, ext);
|
||||
}
|
||||
|
||||
/*
|
||||
* get labels, constants and variables from source line
|
||||
* convert names to upper case and truncate length of name
|
||||
*/
|
||||
char *get_label(char *s, char *l)
|
||||
{
|
||||
register int i;
|
||||
|
||||
i = 0;
|
||||
if (*l == LINCOM)
|
||||
goto comment;
|
||||
while (!isspace(*l) && *l != COMMENT && *l != LABSEP && i < SYMSIZE) {
|
||||
*s++ = islower(*l) ? toupper(*l++) : *l++;
|
||||
i++;
|
||||
}
|
||||
comment:
|
||||
*s = '\0';
|
||||
return(l);
|
||||
}
|
||||
|
||||
/*
|
||||
* get opcode into s from source line l
|
||||
* converts to uper case
|
||||
*/
|
||||
char *get_opcode(char *s, char *l)
|
||||
{
|
||||
if (*l == LINCOM)
|
||||
goto comment;
|
||||
while (!isspace(*l) && *l != COMMENT && *l != LABSEP)
|
||||
l++;
|
||||
if (*l == LABSEP)
|
||||
l++;
|
||||
while (*l == ' ' || *l == '\t')
|
||||
l++;
|
||||
while (!isspace(*l) && *l != COMMENT)
|
||||
*s++ = islower(*l) ? toupper(*l++) : *l++;
|
||||
comment:
|
||||
*s = '\0';
|
||||
return(l);
|
||||
}
|
||||
|
||||
/*
|
||||
* get operand into s from source line l
|
||||
* converts to upper case
|
||||
* strings inside of 's are copied without changes
|
||||
*/
|
||||
char *get_arg(char *s, char *l)
|
||||
{
|
||||
if (*l == LINCOM)
|
||||
goto comment;
|
||||
while (*l == ' ' || *l == '\t')
|
||||
l++;
|
||||
while (*l != '\n' && *l != COMMENT) {
|
||||
if (isspace(*l)) {
|
||||
l++;
|
||||
continue;
|
||||
}
|
||||
if (*l != STRSEP) {
|
||||
*s++ = islower(*l) ? toupper(*l) : *l;
|
||||
l++;
|
||||
continue;
|
||||
}
|
||||
*s++ = *l++;
|
||||
if (*(s - 2) == 'F') /* EX AF,AF' !!!!! */
|
||||
continue;
|
||||
while (*l != STRSEP) {
|
||||
if (*l == '\n' || *l == '\0' || *l == COMMENT)
|
||||
goto comment;
|
||||
*s++ = *l++;
|
||||
}
|
||||
*s++ = *l++;
|
||||
}
|
||||
comment:
|
||||
*s = '\0';
|
||||
return(l);
|
||||
}
|
309
emu/z80pack-1.9/z80asm/z80anum.c
Normal file
309
emu/z80pack-1.9/z80asm/z80anum.c
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* modul with numercial computation and conversion
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "z80a.h"
|
||||
#include "z80aglb.h"
|
||||
|
||||
#ifndef isxdigit
|
||||
#define isxdigit(c) (isdigit(c) || (c>='a' && c<='f') || (c>='A' && c<='F'))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* definitions of operator symbols for expression parser
|
||||
*/
|
||||
#define OPEDEC 1 /* decimal number */
|
||||
#define OPEHEX 2 /* hexadecimal number */
|
||||
#define OPEOCT 3 /* octal number */
|
||||
#define OPEBIN 4 /* binary number */
|
||||
#define OPESUB 5 /* arithmetical - */
|
||||
#define OPEADD 6 /* arithmetical + */
|
||||
#define OPEMUL 7 /* arithmetical * */
|
||||
#define OPEDIV 8 /* arithmetical / */
|
||||
#define OPEMOD 9 /* arithmetical modulo */
|
||||
#define OPESHL 10 /* logical shift left */
|
||||
#define OPESHR 11 /* logical shift right */
|
||||
#define OPELOR 12 /* logical OR */
|
||||
#define OPELAN 13 /* logical AND */
|
||||
#define OPEXOR 14 /* logical XOR */
|
||||
#define OPECOM 15 /* logical complement */
|
||||
#define OPESYM 99 /* symbol */
|
||||
|
||||
extern struct sym *get_sym(char *);
|
||||
extern void asmerr(int);
|
||||
|
||||
/*
|
||||
* recursive expression parser
|
||||
*
|
||||
* Input: pointer to argument rest string
|
||||
*
|
||||
* Output: computed value
|
||||
*/
|
||||
int eval(char *s)
|
||||
{
|
||||
register char *p;
|
||||
register int val;
|
||||
char word[MAXLINE];
|
||||
struct sym *sp;
|
||||
|
||||
val = 0;
|
||||
while (*s) {
|
||||
p = word;
|
||||
if (*s == '(') {
|
||||
s++;
|
||||
while (*s != ')') {
|
||||
if (*s == '\0') {
|
||||
asmerr(E_MISPAR);
|
||||
goto eval_break;
|
||||
}
|
||||
*p++ = *s++;
|
||||
}
|
||||
*p = '\0';
|
||||
s++;
|
||||
val = eval(word);
|
||||
continue;
|
||||
}
|
||||
if (*s == STRSEP) {
|
||||
s++;
|
||||
while (*s != STRSEP) {
|
||||
if (*s == '\n' || *s == '\0') {
|
||||
asmerr(E_MISHYP);
|
||||
goto hyp_error;
|
||||
}
|
||||
*p++ = *s++;
|
||||
}
|
||||
s++;
|
||||
hyp_error:
|
||||
*p = '\0';
|
||||
val = strval(word);
|
||||
continue;
|
||||
}
|
||||
if (isari(*s))
|
||||
*p++ = *s++;
|
||||
else
|
||||
while (!isspace(*s) && !isari(*s) && (*s != '\0'))
|
||||
*p++ = *s++;
|
||||
*p = '\0';
|
||||
switch (get_type(word)) {
|
||||
case OPESYM: /* symbol */
|
||||
if (strcmp(word, "$") == 0) {
|
||||
val = pc;
|
||||
break;
|
||||
}
|
||||
if (strlen(word) > SYMSIZE)
|
||||
word[SYMSIZE] = '\0';
|
||||
if ((sp = get_sym(word)) != NULL)
|
||||
val = sp->sym_wert;
|
||||
else
|
||||
asmerr(E_UNDSYM);
|
||||
break;
|
||||
case OPEDEC: /* decimal number */
|
||||
val = atoi(word);
|
||||
break;
|
||||
case OPEHEX: /* hexadecimal number */
|
||||
val = axtoi(word);
|
||||
break;
|
||||
case OPEBIN: /* binary number */
|
||||
val = abtoi(word);
|
||||
break;
|
||||
case OPEOCT: /* octal number */
|
||||
val = aotoi(word);
|
||||
break;
|
||||
case OPESUB: /* arithmetical - */
|
||||
val -= eval(s);
|
||||
goto eval_break;
|
||||
case OPEADD: /* arithmetical + */
|
||||
val += eval(s);
|
||||
goto eval_break;
|
||||
case OPEMUL: /* arithmetical * */
|
||||
val *= eval(s);
|
||||
goto eval_break;
|
||||
case OPEDIV: /* arithmetical / */
|
||||
val /= eval(s);
|
||||
goto eval_break;
|
||||
case OPEMOD: /* arithmetical modulo */
|
||||
val %= eval(s);
|
||||
goto eval_break;
|
||||
case OPESHL: /* logical shift left */
|
||||
val <<= eval(s);
|
||||
goto eval_break;
|
||||
case OPESHR: /* logical shift right */
|
||||
val >>= eval(s);
|
||||
goto eval_break;
|
||||
case OPELOR: /* logical OR */
|
||||
val |= eval(s);
|
||||
goto eval_break;
|
||||
case OPELAN: /* logical AND */
|
||||
val &= eval(s);
|
||||
goto eval_break;
|
||||
case OPEXOR: /* logical XOR */
|
||||
val ^= eval(s);
|
||||
goto eval_break;
|
||||
case OPECOM: /* logical complement */
|
||||
val = ~(eval(s));
|
||||
goto eval_break;
|
||||
}
|
||||
}
|
||||
eval_break:
|
||||
return(val);
|
||||
}
|
||||
|
||||
/*
|
||||
* get typ of operand
|
||||
*
|
||||
* Input: pointer to string with operand
|
||||
*
|
||||
* Output: operand typ
|
||||
*/
|
||||
int get_type(char *s)
|
||||
{
|
||||
if (isdigit(*s)) { /* numerical operand */
|
||||
if (isdigit(*(s + strlen(s) - 1))) /* decimal number */
|
||||
return(OPEDEC);
|
||||
else if (*(s + strlen(s) - 1) == 'H') /* hexadecimal number */
|
||||
return(OPEHEX);
|
||||
else if (*(s + strlen(s) - 1) == 'B') /* binary number */
|
||||
return(OPEBIN);
|
||||
else if (*(s + strlen(s) - 1) == 'O') /* octal number */
|
||||
return(OPEOCT);
|
||||
} else if (*s == '-') /* arithmetical operand - */
|
||||
return(OPESUB);
|
||||
else if (*s == '+') /* arithmetical operand + */
|
||||
return(OPEADD);
|
||||
else if (*s == '*') /* arithmetical operand * */
|
||||
return(OPEMUL);
|
||||
else if (*s == '/') /* arithmetical operand / */
|
||||
return(OPEDIV);
|
||||
else if (*s == '%') /* arithmetical modulo */
|
||||
return(OPEMOD);
|
||||
else if (*s == '<') /* logical shift left */
|
||||
return(OPESHL);
|
||||
else if (*s == '>') /* logical shift rigth */
|
||||
return(OPESHR);
|
||||
else if (*s == '|') /* logical OR */
|
||||
return(OPELOR);
|
||||
else if (*s == '&') /* logical AND */
|
||||
return(OPELAN);
|
||||
else if (*s == '^') /* logical XOR */
|
||||
return(OPEXOR);
|
||||
else if (*s == '~') /* logical complement */
|
||||
return(OPECOM);
|
||||
return(OPESYM); /* operand is symbol */
|
||||
}
|
||||
|
||||
/*
|
||||
* check a character for arithmetical operators
|
||||
* +, -, *, /, %, <, >, |, &, ~ and ^
|
||||
*/
|
||||
int isari(int c)
|
||||
{
|
||||
return((c) == '+' || (c) == '-' || (c) == '*' ||
|
||||
(c) == '/' || (c) == '%' || (c) == '<' ||
|
||||
(c) == '>' || (c) == '|' || (c) == '&' ||
|
||||
(c) == '~' || (c) == '^');
|
||||
}
|
||||
|
||||
/*
|
||||
* conversion of string with hexadecimal number to integer
|
||||
* format: nnnnH or 0nnnnH if 1st digit > 9
|
||||
*/
|
||||
int axtoi(char *str)
|
||||
{
|
||||
register int num;
|
||||
|
||||
num = 0;
|
||||
while (isxdigit(*str)) {
|
||||
num *= 16;
|
||||
num += *str - ((*str <= '9') ? '0' : '7');
|
||||
str++;
|
||||
}
|
||||
return(num);
|
||||
}
|
||||
|
||||
/*
|
||||
* conversion of string with octal number to integer
|
||||
* format: nnnnO
|
||||
*/
|
||||
int aotoi(char *str)
|
||||
{
|
||||
register int num;
|
||||
|
||||
num = 0;
|
||||
while ('0' <= *str && *str <= '7') {
|
||||
num *= 8;
|
||||
num += (*str++) - '0';
|
||||
}
|
||||
return(num);
|
||||
}
|
||||
|
||||
/*
|
||||
* conversion of string with binary number to integer
|
||||
* format: nnnnnnnnnnnnnnnnB
|
||||
*/
|
||||
int abtoi(char *str)
|
||||
{
|
||||
register int num;
|
||||
|
||||
num = 0;
|
||||
while ('0' <= *str && *str <= '1') {
|
||||
num *= 2;
|
||||
num += (*str++) - '0';
|
||||
}
|
||||
return(num);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert ASCII string to integer
|
||||
*/
|
||||
int strval(char *str)
|
||||
{
|
||||
register int num;
|
||||
|
||||
num = 0;
|
||||
while (*str) {
|
||||
num <<= 8;
|
||||
num += (int) *str++;
|
||||
}
|
||||
return(num);
|
||||
}
|
||||
|
||||
/*
|
||||
* check value for range -256 < value < 256
|
||||
* Output: value if in range, otherwise 0 and error message
|
||||
*/
|
||||
int chk_v1(int i)
|
||||
{
|
||||
if (i >= -255 && i <= 255)
|
||||
return(i);
|
||||
else {
|
||||
asmerr(E_VALOUT);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check value for range -128 < value < 128
|
||||
* Output: value if in range, otherwise 0 and error message
|
||||
*/
|
||||
int chk_v2(int i)
|
||||
{
|
||||
if (i >= -127 && i <= 127)
|
||||
return(i);
|
||||
else {
|
||||
asmerr(E_VALOUT);
|
||||
return(0);
|
||||
}
|
||||
}
|
172
emu/z80pack-1.9/z80asm/z80aopc.c
Normal file
172
emu/z80pack-1.9/z80asm/z80aopc.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* opcode tables
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "z80a.h"
|
||||
|
||||
extern int op_1b(), op_2b(), op_pupo(), op_ex(), op_ld();
|
||||
extern int op_call(), op_ret(), op_jp(), op_jr(), op_djnz(), op_rst();
|
||||
extern int op_add(), op_adc(), op_sub(), op_sbc(), op_cp();
|
||||
extern int op_inc(), op_dec(), op_or(), op_xor(), op_and();
|
||||
extern int op_rl(), op_rr(), op_sla(), op_sra(), op_srl(), op_rlc(), op_rrc();
|
||||
extern int op_out(), op_in(), op_im();
|
||||
extern int op_set(), op_res(), op_bit();
|
||||
extern int op_org(), op_dl(), op_equ();
|
||||
extern int op_ds(), op_db(), op_dw(), op_dm();
|
||||
extern int op_misc();
|
||||
extern int op_cond();
|
||||
extern int op_glob();
|
||||
|
||||
/*
|
||||
* opcode table:
|
||||
* includes entries for all opcodes and pseudo ops other than END
|
||||
* must be sorted in ascending order!
|
||||
*/
|
||||
struct opc opctab[] = {
|
||||
{ "ADC", op_adc, 0, 0 },
|
||||
{ "ADD", op_add, 0, 0 },
|
||||
{ "AND", op_and, 0, 0 },
|
||||
{ "BIT", op_bit, 0, 0 },
|
||||
{ "CALL", op_call, 0, 0 },
|
||||
{ "CCF", op_1b, 0x3f, 0 },
|
||||
{ "CP", op_cp, 0, 0 },
|
||||
{ "CPD", op_2b, 0xed, 0xa9 },
|
||||
{ "CPDR", op_2b, 0xed, 0xb9 },
|
||||
{ "CPI", op_2b, 0xed, 0xa1 },
|
||||
{ "CPIR", op_2b, 0xed, 0xb1 },
|
||||
{ "CPL", op_1b, 0x2f, 0 },
|
||||
{ "DAA", op_1b, 0x27, 0 },
|
||||
{ "DEC", op_dec, 0, 0 },
|
||||
{ "DEFB", op_db, 0, 0 },
|
||||
{ "DEFL", op_dl, 0, 0 },
|
||||
{ "DEFM", op_dm, 0, 0 },
|
||||
{ "DEFS", op_ds, 0, 0 },
|
||||
{ "DEFW", op_dw, 0, 0 },
|
||||
{ "DI", op_1b, 0xf3, 0 },
|
||||
{ "DJNZ", op_djnz, 0, 0 },
|
||||
{ "EI", op_1b, 0xfb, 0 },
|
||||
{ "EJECT", op_misc, 1, 0 },
|
||||
{ "ELSE", op_cond, 98, 0 },
|
||||
{ "ENDIF", op_cond, 99, 0 },
|
||||
{ "EQU", op_equ, 0, 0 },
|
||||
{ "EX", op_ex, 0, 0 },
|
||||
{ "EXTRN", op_glob, 1, 0 },
|
||||
{ "EXX", op_1b, 0xd9, 0 },
|
||||
{ "HALT", op_1b, 0x76, 0 },
|
||||
{ "IFDEF", op_cond, 1, 0 },
|
||||
{ "IFEQ", op_cond, 3, 0 },
|
||||
{ "IFNDEF", op_cond, 2, 0 },
|
||||
{ "IFNEQ", op_cond, 4, 0 },
|
||||
{ "IM", op_im, 0, 0 },
|
||||
{ "IN", op_in, 0, 0 },
|
||||
{ "INC", op_inc, 0, 0 },
|
||||
{ "INCLUDE", op_misc, 6, 0 },
|
||||
{ "IND", op_2b, 0xed, 0xaa },
|
||||
{ "INDR", op_2b, 0xed, 0xba },
|
||||
{ "INI", op_2b, 0xed, 0xa2 },
|
||||
{ "INIR", op_2b, 0xed, 0xb2 },
|
||||
{ "JP", op_jp, 0, 0 },
|
||||
{ "JR", op_jr, 0, 0 },
|
||||
{ "LD", op_ld, 0, 0 },
|
||||
{ "LDD", op_2b, 0xed, 0xa8 },
|
||||
{ "LDDR", op_2b, 0xed, 0xb8 },
|
||||
{ "LDI", op_2b, 0xed, 0xa0 },
|
||||
{ "LDIR", op_2b, 0xed, 0xb0 },
|
||||
{ "LIST", op_misc, 2, 0 },
|
||||
{ "NEG", op_2b, 0xed, 0x44 },
|
||||
{ "NOLIST", op_misc, 3, 0 },
|
||||
{ "NOP", op_1b, 0, 0 },
|
||||
{ "OR", op_or, 0, 0 },
|
||||
{ "ORG", op_org, 0, 0 },
|
||||
{ "OTDR", op_2b, 0xed, 0xbb },
|
||||
{ "OTIR", op_2b, 0xed, 0xb3 },
|
||||
{ "OUT", op_out, 0, 0 },
|
||||
{ "OUTD", op_2b, 0xed, 0xab },
|
||||
{ "OUTI", op_2b, 0xed, 0xa3 },
|
||||
{ "PAGE", op_misc, 4, 0 },
|
||||
{ "POP", op_pupo, 1, 0 },
|
||||
{ "PRINT", op_misc, 5, 0 },
|
||||
{ "PUBLIC", op_glob, 2, 0 },
|
||||
{ "PUSH", op_pupo, 2, 0 },
|
||||
{ "RES", op_res, 0, 0 },
|
||||
{ "RET", op_ret, 0, 0 },
|
||||
{ "RETI", op_2b, 0xed, 0x4d },
|
||||
{ "RETN", op_2b, 0xed, 0x45 },
|
||||
{ "RL", op_rl, 0, 0 },
|
||||
{ "RLA", op_1b, 0x17, 0 },
|
||||
{ "RLC", op_rlc, 0, 0 },
|
||||
{ "RLCA", op_1b, 0x07, 0 },
|
||||
{ "RLD", op_2b, 0xed, 0x6f },
|
||||
{ "RR", op_rr, 0, 0 },
|
||||
{ "RRA", op_1b, 0x1f, 0 },
|
||||
{ "RRC", op_rrc, 0, 0 },
|
||||
{ "RRCA", op_1b, 0x0f, 0 },
|
||||
{ "RRD", op_2b, 0xed, 0x67 },
|
||||
{ "RST", op_rst, 0, 0 },
|
||||
{ "SBC", op_sbc, 0, 0 },
|
||||
{ "SCF", op_1b, 0x37, 0 },
|
||||
{ "SET", op_set, 0, 0 },
|
||||
{ "SLA", op_sla, 0, 0 },
|
||||
{ "SRA", op_sra, 0, 0 },
|
||||
{ "SRL", op_srl, 0, 0 },
|
||||
{ "SUB", op_sub, 0, 0 },
|
||||
{ "TITLE", op_misc, 7, 0 },
|
||||
{ "XOR", op_xor, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* compute no. of table entries for search_op()
|
||||
*/
|
||||
int no_opcodes = sizeof(opctab) / sizeof(struct opc);
|
||||
|
||||
/*
|
||||
* table with reserverd operand words: registers and flags
|
||||
* must be sorted in ascending order!
|
||||
*/
|
||||
struct ope opetab[] = {
|
||||
{ "(BC)", REGIBC },
|
||||
{ "(DE)", REGIDE },
|
||||
{ "(HL)", REGIHL },
|
||||
{ "(IX)", REGIIX },
|
||||
{ "(IY)", REGIIY },
|
||||
{ "(SP)", REGISP },
|
||||
{ "A", REGA },
|
||||
{ "AF", REGAF },
|
||||
{ "B", REGB },
|
||||
{ "BC", REGBC },
|
||||
{ "C", REGC },
|
||||
{ "D", REGD },
|
||||
{ "DE", REGDE },
|
||||
{ "E", REGE },
|
||||
{ "H", REGH },
|
||||
{ "HL", REGHL },
|
||||
{ "I", REGI },
|
||||
{ "IX", REGIX },
|
||||
{ "IY", REGIY },
|
||||
{ "L", REGL },
|
||||
{ "M", FLGM },
|
||||
{ "NC", FLGNC },
|
||||
{ "NZ", FLGNZ },
|
||||
{ "P", FLGP },
|
||||
{ "PE", FLGPE },
|
||||
{ "PO", FLGPO },
|
||||
{ "R", REGR },
|
||||
{ "SP", REGSP },
|
||||
{ "Z", FLGZ }
|
||||
};
|
||||
|
||||
/*
|
||||
* compute no. of table entries
|
||||
*/
|
||||
int no_operands = sizeof(opetab) / sizeof(struct ope);
|
360
emu/z80pack-1.9/z80asm/z80aout.c
Normal file
360
emu/z80pack-1.9/z80asm/z80aout.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 21-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* module for output functions to list, object and error files
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "z80a.h"
|
||||
#include "z80aglb.h"
|
||||
|
||||
void flush_hex(void);
|
||||
int chksum(void);
|
||||
void btoh(unsigned char, char **);
|
||||
|
||||
extern void fatal(int, char *);
|
||||
|
||||
static char *errmsg[] = { /* error messages for asmerr() */
|
||||
"illegal opcode", /* 0 */
|
||||
"illegal operand", /* 1 */
|
||||
"missing operand", /* 2 */
|
||||
"multiply defined symbol", /* 3 */
|
||||
"undefined symbol", /* 4 */
|
||||
"value out of range", /* 5 */
|
||||
"missing )", /* 6 */
|
||||
"missing string separator", /* 7 */
|
||||
"memory override", /* 8 */
|
||||
"missing IF", /* 9 */
|
||||
"IF nesting to deep", /* 10 */
|
||||
"missing ENDIF", /* 11 */
|
||||
"INCLUDE nesting to deep" /* 12 */
|
||||
};
|
||||
|
||||
#define MAXHEX 32 /* max no bytes/hex record */
|
||||
|
||||
static unsigned short hex_adr; /* current address in hex record */
|
||||
static int hex_cnt; /* current no bytes in hex buffer */
|
||||
|
||||
static unsigned char hex_buf[MAXHEX]; /* buffer for one hex record */
|
||||
static char hex_out[MAXHEX*2+11]; /* ASCII buffer for one hex record */
|
||||
|
||||
/*
|
||||
* print error message to listfile and increase error counter
|
||||
*/
|
||||
void asmerr(int i)
|
||||
{
|
||||
if (pass == 1) {
|
||||
fprintf(errfp, "Error in file: %s Line: %d\n", srcfn, c_line);
|
||||
fprintf(errfp, errmsg[i]);
|
||||
fprintf(errfp, "\n\n");
|
||||
} else
|
||||
errnum = i;
|
||||
errors++;
|
||||
}
|
||||
|
||||
/*
|
||||
* begin new page in listfile
|
||||
*/
|
||||
void lst_header(void)
|
||||
{
|
||||
fprintf(lstfp, "\fZ80-Assembler\t\tRelease %s\t\t\t\tPage %d\n", REL,
|
||||
++page);
|
||||
fprintf(lstfp, "Source file: %s\n", srcfn);
|
||||
fprintf(lstfp, "Title: %s\n", title);
|
||||
p_line = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* print header for source lines
|
||||
*/
|
||||
void lst_attl(void)
|
||||
{
|
||||
fprintf(lstfp, "\nLOC OBJECT CODE LINE STMT SOURCE CODE\n");
|
||||
p_line += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* print one line into listfile, if -l option set
|
||||
*/
|
||||
void lst_line(int val, int opanz)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (!list_flag || sd_flag == 4) {
|
||||
sd_flag = 0;
|
||||
return;
|
||||
}
|
||||
if ((p_line >= ppl) || (c_line == 1)) {
|
||||
lst_header();
|
||||
lst_attl();
|
||||
}
|
||||
switch (sd_flag) {
|
||||
case 0:
|
||||
fprintf(lstfp, "%04x ", val & 0xffff);
|
||||
break;
|
||||
case 1:
|
||||
fprintf(lstfp, "%04x ", sd_val & 0xffff);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(lstfp, " ");
|
||||
break;
|
||||
case 3:
|
||||
fprintf(lstfp, "%04x ", sd_val & 0xffff);
|
||||
goto no_data;
|
||||
default:
|
||||
fatal(F_INTERN, "illegal listflag for function lst_line");
|
||||
break;
|
||||
}
|
||||
if (opanz >= 1) fprintf(lstfp, "%02x ", ops[0] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
if (opanz >= 2) fprintf(lstfp, "%02x ", ops[1] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
if (opanz >= 3) fprintf(lstfp, "%02x ", ops[2] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
if (opanz >= 4) fprintf(lstfp, "%02x ", ops[3] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
no_data:
|
||||
fprintf(lstfp, "%6d %6d %s", c_line, s_line, line);
|
||||
if (errnum) {
|
||||
fprintf(errfp, "=> %s", errmsg[errnum]);
|
||||
putc('\n', errfp);
|
||||
errnum = 0;
|
||||
p_line++;
|
||||
}
|
||||
sd_flag = 0;
|
||||
p_line++;
|
||||
if (opanz > 4 && sd_flag == 0) {
|
||||
opanz -= 4;
|
||||
i = 4;
|
||||
sd_val = val;
|
||||
while (opanz > 0) {
|
||||
if (p_line >= ppl) {
|
||||
lst_header();
|
||||
lst_attl();
|
||||
}
|
||||
s_line++;
|
||||
sd_val += 4;
|
||||
fprintf(lstfp, "%04x ", sd_val & 0xffff);
|
||||
if (opanz-- > 0) fprintf(lstfp, "%02x ",
|
||||
ops[i++] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
if (opanz-- > 0) fprintf(lstfp, "%02x ",
|
||||
ops[i++] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
if (opanz-- > 0) fprintf(lstfp, "%02x ",
|
||||
ops[i++] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
if (opanz-- > 0) fprintf(lstfp, "%02x ",
|
||||
ops[i++] & 0xff);
|
||||
else fprintf(lstfp, " ");
|
||||
fprintf(lstfp, "%6d %6d\n", c_line, s_line);
|
||||
p_line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print symbol table into listfile unsorted
|
||||
*/
|
||||
void lst_sym(void)
|
||||
{
|
||||
register int i, j;
|
||||
register struct sym *np;
|
||||
|
||||
p_line = j = 0;
|
||||
strcpy(title,"Symboltable");
|
||||
for (i = 0; i < HASHSIZE; i++) {
|
||||
if (symtab[i] != NULL) {
|
||||
for (np = symtab[i]; np != NULL; np = np->sym_next) {
|
||||
if (p_line == 0) {
|
||||
lst_header();
|
||||
fputs("\n", lstfp);
|
||||
p_line += 1;
|
||||
}
|
||||
fprintf(lstfp, "%-8s %04x\t", np->sym_name,
|
||||
np->sym_wert & 0xffff);
|
||||
if (++j == 4) {
|
||||
fprintf(lstfp, "\n");
|
||||
if (p_line++ >= ppl)
|
||||
p_line = 0;
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print sorted symbol table into listfile
|
||||
*/
|
||||
void lst_sort_sym(int len)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
p_line = i = j = 0;
|
||||
strcpy(title, "Symboltable");
|
||||
while (i < len) {
|
||||
if (p_line == 0) {
|
||||
lst_header();
|
||||
fputs("\n", lstfp);
|
||||
p_line += 1;
|
||||
}
|
||||
fprintf(lstfp, "%-8s %04x\t", symarray[i]->sym_name,
|
||||
symarray[i]->sym_wert & 0xffff);
|
||||
if (++j == 4) {
|
||||
fprintf(lstfp, "\n");
|
||||
if (p_line++ >= ppl)
|
||||
p_line = 0;
|
||||
j = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* write header record into object file
|
||||
*/
|
||||
void obj_header(void)
|
||||
{
|
||||
switch (out_form) {
|
||||
case OUTBIN:
|
||||
break;
|
||||
case OUTMOS:
|
||||
putc(0xff, objfp);
|
||||
putc(prg_adr & 0xff, objfp);
|
||||
putc(prg_adr >> 8, objfp);
|
||||
break;
|
||||
case OUTHEX:
|
||||
hex_adr = prg_adr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* write end record into object file
|
||||
*/
|
||||
void obj_end(void)
|
||||
{
|
||||
switch (out_form) {
|
||||
case OUTBIN:
|
||||
break;
|
||||
case OUTMOS:
|
||||
break;
|
||||
case OUTHEX:
|
||||
flush_hex();
|
||||
fprintf(objfp, ":0000000000\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* write opcodes in ops[] into object file
|
||||
*/
|
||||
void obj_writeb(int opanz)
|
||||
{
|
||||
register int i;
|
||||
|
||||
switch (out_form) {
|
||||
case OUTBIN:
|
||||
fwrite(ops, 1, opanz, objfp);
|
||||
break;
|
||||
case OUTMOS:
|
||||
fwrite(ops, 1, opanz, objfp);
|
||||
break;
|
||||
case OUTHEX:
|
||||
for (i = 0; opanz; opanz--) {
|
||||
if (hex_cnt >= MAXHEX)
|
||||
flush_hex();
|
||||
hex_buf[hex_cnt++] = ops[i++];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* write <count> bytes 0xff into object file
|
||||
*/
|
||||
void obj_fill(int count)
|
||||
{
|
||||
switch (out_form) {
|
||||
case OUTBIN:
|
||||
while (count--)
|
||||
putc(0xff, objfp);
|
||||
break;
|
||||
case OUTMOS:
|
||||
while (count--)
|
||||
putc(0xff, objfp);
|
||||
break;
|
||||
case OUTHEX:
|
||||
flush_hex();
|
||||
hex_adr += count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create a hex record in ASCII and write into object file
|
||||
*/
|
||||
void flush_hex(void)
|
||||
{
|
||||
char *p;
|
||||
register int i;
|
||||
|
||||
if (!hex_cnt)
|
||||
return;
|
||||
p = hex_out;
|
||||
*p++ = ':';
|
||||
btoh((unsigned char) hex_cnt, &p);
|
||||
btoh((unsigned char) (hex_adr >> 8), &p);
|
||||
btoh((unsigned char) (hex_adr & 0xff), &p);
|
||||
*p++ = '0';
|
||||
*p++ = '0';
|
||||
for (i = 0; i < hex_cnt; i++)
|
||||
btoh(hex_buf[i], &p);
|
||||
btoh((unsigned char) chksum(), &p);
|
||||
*p++ = '\n';
|
||||
*p = '\0';
|
||||
fwrite(hex_out, 1, strlen(hex_out), objfp);
|
||||
hex_adr += hex_cnt;
|
||||
hex_cnt = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert unsigned char into ASCII hex and copy to string at p
|
||||
* increase p by 2
|
||||
*/
|
||||
void btoh(unsigned char byte, char **p)
|
||||
{
|
||||
register unsigned char c;
|
||||
|
||||
c = byte >> 4;
|
||||
*(*p)++ = (c < 10) ? (c + '0') : (c - 10 + 'A');
|
||||
c = byte & 0xf;
|
||||
*(*p)++ = (c < 10) ? (c + '0') : (c - 10 + 'A');
|
||||
}
|
||||
|
||||
/*
|
||||
* computer checksum for Intel hex record
|
||||
*/
|
||||
int chksum(void)
|
||||
{
|
||||
register int i, j, sum;
|
||||
|
||||
sum = hex_cnt;
|
||||
sum += hex_adr >> 8;
|
||||
sum += hex_adr & 0xff;
|
||||
for (i = 0; i < hex_cnt; i++) {
|
||||
j = hex_buf[i];
|
||||
sum += j & 0xff;
|
||||
}
|
||||
return (0x100 - (sum & 0xff));
|
||||
}
|
446
emu/z80pack-1.9/z80asm/z80apfun.c
Normal file
446
emu/z80pack-1.9/z80asm/z80apfun.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 22-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* processing of all PSEUDO ops
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "z80a.h"
|
||||
#include "z80aglb.h"
|
||||
|
||||
extern void fatal(int, char *);
|
||||
extern void p1_file(char *);
|
||||
extern void p2_file(char *);
|
||||
extern int eval(char *);
|
||||
extern void asmerr(int);
|
||||
extern void lst_header(void);
|
||||
extern void lst_attl(void);
|
||||
extern void lst_line(int, int);
|
||||
extern void obj_fill(int);
|
||||
extern struct sym *get_sym(char *);
|
||||
extern int put_sym(char *, int);
|
||||
extern void put_label(void);
|
||||
|
||||
/*
|
||||
* ORG
|
||||
*/
|
||||
int op_org(void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
i = eval(operand);
|
||||
if (i < pc) {
|
||||
asmerr(E_MEMOVR);
|
||||
return(0);
|
||||
}
|
||||
if (pass == 1) { /* PASS 1 */
|
||||
if (!prg_flag) {
|
||||
prg_adr = i;
|
||||
prg_flag++;
|
||||
}
|
||||
} else { /* PASS 2 */
|
||||
if (++prg_flag > 2)
|
||||
obj_fill(i - pc);
|
||||
sd_flag = 2;
|
||||
}
|
||||
pc = i;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* EQU
|
||||
*/
|
||||
int op_equ(void)
|
||||
{
|
||||
if (!gencode)
|
||||
return(0);
|
||||
if (pass == 1) { /* Pass 1 */
|
||||
if (get_sym(label) == NULL) {
|
||||
sd_val = eval(operand);
|
||||
if (put_sym(label, sd_val))
|
||||
fatal(F_OUTMEM, "symbols");
|
||||
} else
|
||||
asmerr(E_MULSYM);
|
||||
} else { /* Pass 2 */
|
||||
sd_flag = 1;
|
||||
sd_val = eval(operand);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* DEFL
|
||||
*/
|
||||
int op_dl(void)
|
||||
{
|
||||
if (!gencode)
|
||||
return(0);
|
||||
sd_flag = 1;
|
||||
sd_val = eval(operand);
|
||||
if (put_sym(label, sd_val))
|
||||
fatal(F_OUTMEM, "symbols");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* DEFS
|
||||
*/
|
||||
int op_ds(void)
|
||||
{
|
||||
register int val;
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
if (pass == 1)
|
||||
if (*label)
|
||||
put_label();
|
||||
sd_val = pc;
|
||||
sd_flag = 3;
|
||||
val = eval(operand);
|
||||
if ((pass == 2) && !dump_flag)
|
||||
obj_fill(val);
|
||||
pc += val;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* DEFB
|
||||
*/
|
||||
int op_db(void)
|
||||
{
|
||||
register int i;
|
||||
register char *p;
|
||||
register char *s;
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
i = 0;
|
||||
p = operand;
|
||||
if (pass == 1)
|
||||
if (*label)
|
||||
put_label();
|
||||
while (*p) {
|
||||
if (*p == STRSEP) {
|
||||
p++;
|
||||
while (*p != STRSEP) {
|
||||
if (*p == '\n' || *p == '\0') {
|
||||
asmerr(E_MISHYP);
|
||||
goto hyp_error;
|
||||
}
|
||||
ops[i++] = *p++;
|
||||
if (i >= OPCARRAY)
|
||||
fatal(F_INTERN, "Op-Code buffer overflow");
|
||||
}
|
||||
p++;
|
||||
} else {
|
||||
s = tmp;
|
||||
while (*p != ',' && *p != '\0')
|
||||
*s++ = *p++;
|
||||
*s = '\0';
|
||||
ops[i++] = eval(tmp);
|
||||
if (i >= OPCARRAY)
|
||||
fatal(F_INTERN, "Op-Code buffer overflow");
|
||||
}
|
||||
if (*p == ',')
|
||||
p++;
|
||||
}
|
||||
hyp_error:
|
||||
return(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* DEFM
|
||||
*/
|
||||
int op_dm(void)
|
||||
{
|
||||
register int i;
|
||||
register char *p;
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
i = 0;
|
||||
p = operand;
|
||||
if (pass == 1)
|
||||
if (*label)
|
||||
put_label();
|
||||
if (*p != STRSEP) {
|
||||
asmerr(E_MISHYP);
|
||||
return(0);
|
||||
}
|
||||
p++;
|
||||
while (*p != STRSEP) {
|
||||
if (*p == '\n' || *p == '\0') {
|
||||
asmerr(E_MISHYP);
|
||||
break;
|
||||
}
|
||||
ops[i++] = *p++;
|
||||
if (i >= OPCARRAY)
|
||||
fatal(F_INTERN, "Op-Code buffer overflow");
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* DEFW
|
||||
*/
|
||||
int op_dw(void)
|
||||
{
|
||||
register int i, len, temp;
|
||||
register char *p;
|
||||
register char *s;
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
p = operand;
|
||||
i = len = 0;
|
||||
if (pass == 1)
|
||||
if (*label)
|
||||
put_label();
|
||||
while (*p) {
|
||||
s = tmp;
|
||||
while (*p != ',' && *p != '\0')
|
||||
*s++ = *p++;
|
||||
*s = '\0';
|
||||
if (pass == 2) {
|
||||
temp = eval(tmp);
|
||||
ops[i++] = temp & 0xff;
|
||||
ops[i++] = temp >> 8;
|
||||
if (i >= OPCARRAY)
|
||||
fatal(F_INTERN, "Op-Code buffer overflow");
|
||||
}
|
||||
len += 2;
|
||||
if (*p == ',')
|
||||
p++;
|
||||
}
|
||||
return(len);
|
||||
}
|
||||
|
||||
/*
|
||||
* EJECT, LIST, NOLIST, PAGE, PRINT, TITLE, INCLUDE
|
||||
*/
|
||||
int op_misc(int op_code, int dummy)
|
||||
{
|
||||
register char *p, *d;
|
||||
static char fn[LENFN];
|
||||
static int incnest;
|
||||
static struct inc incl[INCNEST];
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
sd_flag = 2;
|
||||
switch(op_code) {
|
||||
case 1: /* EJECT */
|
||||
if (pass == 2)
|
||||
p_line = ppl;
|
||||
break;
|
||||
case 2: /* LIST */
|
||||
if (pass == 2)
|
||||
list_flag = 1;
|
||||
break;
|
||||
case 3: /* NOLIST */
|
||||
if (pass == 2)
|
||||
list_flag = 0;
|
||||
break;
|
||||
case 4: /* PAGE */
|
||||
if (pass == 2)
|
||||
ppl = eval(operand);
|
||||
break;
|
||||
case 5: /* PRINT */
|
||||
if (pass == 1) {
|
||||
p = operand;
|
||||
while (*p) {
|
||||
if (*p != STRSEP)
|
||||
putchar(*p++);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
break;
|
||||
case 6: /* INCLUDE */
|
||||
if (incnest >= INCNEST) {
|
||||
asmerr(E_INCNEST);
|
||||
break;
|
||||
}
|
||||
incl[incnest].inc_line = c_line;
|
||||
incl[incnest].inc_fn = srcfn;
|
||||
incl[incnest].inc_fp = srcfp;
|
||||
incnest++;
|
||||
p = line;
|
||||
d = fn;
|
||||
while(isspace(*p)) /* ignore white space until INCLUDE */
|
||||
p++;
|
||||
while(!isspace(*p)) /* ignore INCLUDE */
|
||||
p++;
|
||||
while(isspace(*p)) /* ignore white space until filename */
|
||||
p++;
|
||||
while(!isspace(*p) && *p != COMMENT) /* get filename */
|
||||
*d++ = *p++;
|
||||
*d = '\0';
|
||||
if (pass == 1) { /* PASS 1 */
|
||||
if (!ver_flag)
|
||||
printf(" Include %s\n", fn);
|
||||
p1_file(fn);
|
||||
} else { /* PASS 2 */
|
||||
sd_flag = 2;
|
||||
lst_line(0, 0);
|
||||
if (!ver_flag)
|
||||
printf(" Include %s\n", fn);
|
||||
p2_file(fn);
|
||||
}
|
||||
incnest--;
|
||||
c_line = incl[incnest].inc_line;
|
||||
srcfn = incl[incnest].inc_fn;
|
||||
srcfp = incl[incnest].inc_fp;
|
||||
printf(" Resume %s\n", srcfn);
|
||||
if (list_flag && (pass == 2)) {
|
||||
lst_header();
|
||||
lst_attl();
|
||||
}
|
||||
sd_flag = 4;
|
||||
break;
|
||||
case 7: /* TITLE */
|
||||
if (pass == 2) {
|
||||
p = line;
|
||||
d = title;
|
||||
while (isspace(*p)) /* ignore white space until TITLE */
|
||||
p++;
|
||||
while (!isspace(*p)) /* ignore TITLE */
|
||||
p++;
|
||||
while (isspace(*p)) /* ignore white space until text */
|
||||
p++;
|
||||
if (*p == STRSEP)
|
||||
p++;
|
||||
while (*p != '\n' && *p != STRSEP && *p != COMMENT)
|
||||
*d++ = *p++;
|
||||
*d = '\0';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal(F_INTERN, "illegal opcode for function op_misc");
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* IFDEF, IFNDEF, IFEQ, IFNEQ, ELSE, ENDIF
|
||||
*/
|
||||
int op_cond(int op_code, int dummy)
|
||||
{
|
||||
register char *p, *p1, *p2;
|
||||
static int condnest[IFNEST];
|
||||
|
||||
switch(op_code) {
|
||||
case 1: /* IFDEF */
|
||||
if (iflevel >= IFNEST) {
|
||||
asmerr(E_IFNEST);
|
||||
break;
|
||||
}
|
||||
condnest[iflevel++] = gencode;
|
||||
if (gencode)
|
||||
if (get_sym(operand) == NULL)
|
||||
gencode = 0;
|
||||
break;
|
||||
case 2: /* IFNDEF */
|
||||
if (iflevel >= IFNEST) {
|
||||
asmerr(E_IFNEST);
|
||||
break;
|
||||
}
|
||||
condnest[iflevel++] = gencode;
|
||||
if (gencode)
|
||||
if (get_sym(operand) != NULL)
|
||||
gencode = 0;
|
||||
break;
|
||||
case 3: /* IFEQ */
|
||||
if (iflevel >= IFNEST) {
|
||||
asmerr(E_IFNEST);
|
||||
break;
|
||||
}
|
||||
condnest[iflevel++] = gencode;
|
||||
p = operand;
|
||||
if (!*p || !(p1 = strchr(operand, ','))) {
|
||||
asmerr(E_MISOPE);
|
||||
break;
|
||||
}
|
||||
if (gencode) {
|
||||
p2 = tmp;
|
||||
while (*p != ',')
|
||||
*p2++ = *p++;
|
||||
*p2 = '\0';
|
||||
if (eval(tmp) != eval(++p1))
|
||||
gencode = 0;
|
||||
}
|
||||
break;
|
||||
case 4: /* IFNEQ */
|
||||
if (iflevel >= IFNEST) {
|
||||
asmerr(E_IFNEST);
|
||||
break;
|
||||
}
|
||||
condnest[iflevel++] = gencode;
|
||||
p = operand;
|
||||
if (!*p || !(p1 = strchr(operand, ','))) {
|
||||
asmerr(E_MISOPE);
|
||||
break;
|
||||
}
|
||||
if (gencode) {
|
||||
p2 = tmp;
|
||||
while (*p != ',')
|
||||
*p2++ = *p++;
|
||||
*p2 = '\0';
|
||||
if (eval(tmp) == eval(++p1))
|
||||
gencode = 0;
|
||||
}
|
||||
break;
|
||||
case 98: /* ELSE */
|
||||
if (!iflevel)
|
||||
asmerr(E_MISIFF);
|
||||
else
|
||||
if ((iflevel == 0) || (condnest[iflevel - 1] == 1))
|
||||
gencode = !gencode;
|
||||
break;
|
||||
case 99: /* ENDIF */
|
||||
if (!iflevel)
|
||||
asmerr(E_MISIFF);
|
||||
else
|
||||
gencode = condnest[--iflevel];
|
||||
break;
|
||||
default:
|
||||
fatal(F_INTERN, "illegal opcode for function op_cond");
|
||||
break;
|
||||
}
|
||||
sd_flag = 2;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* EXTRN and PUBLIC
|
||||
*/
|
||||
int op_glob(int op_code, int dummy)
|
||||
{
|
||||
if (!gencode)
|
||||
return(0);
|
||||
sd_flag = 2;
|
||||
switch(op_code) {
|
||||
case 1: /* EXTRN */
|
||||
break;
|
||||
case 2: /* PUBLIC */
|
||||
break;
|
||||
default:
|
||||
fatal(F_INTERN, "illegal opcode for function op_glob");
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
3274
emu/z80pack-1.9/z80asm/z80arfun.c
Normal file
3274
emu/z80pack-1.9/z80asm/z80arfun.c
Normal file
File diff suppressed because it is too large
Load Diff
255
emu/z80pack-1.9/z80asm/z80atab.c
Normal file
255
emu/z80pack-1.9/z80asm/z80atab.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 22-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* module with table oprations on opcode and symbol tables
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "z80a.h"
|
||||
#include "z80aglb.h"
|
||||
|
||||
extern void fatal(int, char *);
|
||||
extern void asmerr(int);
|
||||
|
||||
/*
|
||||
* binary search in sorted table opctab
|
||||
*
|
||||
* Input: pointer to string with opcode
|
||||
*
|
||||
* Output: pointer to table element, or NULL if not found
|
||||
*/
|
||||
struct opc *search_op(char *op_name)
|
||||
{
|
||||
register int cond;
|
||||
register struct opc *low, *high, *mid;
|
||||
|
||||
low = &opctab[0];
|
||||
high = &opctab[no_opcodes - 1];
|
||||
while (low <= high) {
|
||||
mid = low + (high - low) / 2;
|
||||
if ((cond = strcmp(op_name, mid->op_name)) < 0)
|
||||
high = mid - 1;
|
||||
else if (cond > 0)
|
||||
low = mid + 1;
|
||||
else
|
||||
return(mid);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* binary search on sorted table opetab
|
||||
*
|
||||
* Input: pointer to string with operand
|
||||
*
|
||||
* Output: symbol for operand, NOOPERA if empty operand,
|
||||
* NOREG if operand not found
|
||||
*/
|
||||
int get_reg(char *s)
|
||||
{
|
||||
register int cond;
|
||||
register struct ope *low, *high, *mid;
|
||||
|
||||
if (s == NULL || *s == '\0')
|
||||
return(NOOPERA);
|
||||
low = &opetab[0];
|
||||
high = &opetab[no_operands - 1];
|
||||
while (low <= high) {
|
||||
mid = low + (high - low) / 2;
|
||||
if ((cond = strcmp(s, mid->ope_name)) < 0)
|
||||
high = mid - 1;
|
||||
else if (cond > 0)
|
||||
low = mid + 1;
|
||||
else
|
||||
return(mid->ope_sym);
|
||||
}
|
||||
return(NOREG);
|
||||
}
|
||||
|
||||
/*
|
||||
* hash search on symbol table symtab
|
||||
*
|
||||
* Input: pointer to string with symbol
|
||||
*
|
||||
* Output: pointer to table element, or NULL if not found
|
||||
*/
|
||||
struct sym *get_sym(char *sym_name)
|
||||
{
|
||||
register struct sym *np;
|
||||
|
||||
for (np = symtab[hash(sym_name)]; np != NULL; np = np->sym_next)
|
||||
if (strcmp(sym_name, np->sym_name) == 0)
|
||||
return(np);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* add symbol to symbol table symtab, or modify existing symbol
|
||||
*
|
||||
* Input: sym_name pointer to string with symbol name
|
||||
* sym_wert value of symbol
|
||||
*
|
||||
* Output: 0 symbol added/modified
|
||||
* 1 out of memory
|
||||
*/
|
||||
int put_sym(char *sym_name, int sym_wert)
|
||||
{
|
||||
struct sym *get_sym();
|
||||
register int hashval;
|
||||
register struct sym *np;
|
||||
|
||||
char *strsave(char *);
|
||||
|
||||
if (!gencode)
|
||||
return(0);
|
||||
if ((np = get_sym(sym_name)) == NULL) {
|
||||
np = (struct sym *) malloc(sizeof (struct sym));
|
||||
if (np == NULL)
|
||||
return(1);
|
||||
if ((np->sym_name = strsave(sym_name)) == NULL)
|
||||
return(1);
|
||||
hashval = hash(sym_name);
|
||||
np->sym_next = symtab[hashval];
|
||||
symtab[hashval] = np;
|
||||
}
|
||||
np->sym_wert = sym_wert;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* add label to symbol table, error if symbol already exists
|
||||
*/
|
||||
void put_label(void)
|
||||
{
|
||||
struct sym *get_sym(char *);
|
||||
|
||||
if (get_sym(label) == NULL) {
|
||||
if (put_sym(label, pc))
|
||||
fatal(F_OUTMEM, "symbols");
|
||||
} else
|
||||
asmerr(E_MULSYM);
|
||||
}
|
||||
|
||||
/*
|
||||
* hash algorithm
|
||||
*
|
||||
* Input: pointer to string with name
|
||||
*
|
||||
* Output: hash value
|
||||
*/
|
||||
int hash(char *name)
|
||||
{
|
||||
register int hashval;
|
||||
|
||||
for (hashval = 0; *name;)
|
||||
hashval += *name++;
|
||||
return(hashval % HASHSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* save string into allocated memory
|
||||
*
|
||||
* Input: pointer to string
|
||||
*
|
||||
* Output: pointer to allocated memory with string
|
||||
*/
|
||||
char *strsave(char *s)
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if ((p = malloc((unsigned) strlen(s)+1)) != NULL)
|
||||
strcpy(p, s);
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy whole symbol hast table into allocated pointer array
|
||||
* used for sorting the symbol table later
|
||||
*/
|
||||
int copy_sym(void)
|
||||
{
|
||||
register int i, j;
|
||||
register struct sym *np;
|
||||
|
||||
symarray = (struct sym **) malloc(SYMINC * sizeof(struct sym *));
|
||||
if (symarray == NULL)
|
||||
fatal(F_OUTMEM, "sorting symbol table");
|
||||
symsize = SYMINC;
|
||||
for (i = 0, j = 0; i < HASHSIZE; i++) {
|
||||
if (symtab[i] != NULL) {
|
||||
for (np = symtab[i]; np != NULL; np = np->sym_next) {
|
||||
symarray[j++] = np;
|
||||
if (j == symsize) {
|
||||
symarray = (struct sym **) realloc((char *) symarray, symsize * sizeof(struct sym *) + SYMINC * sizeof(struct sym *));
|
||||
if (symarray == NULL)
|
||||
fatal(F_OUTMEM, "sorting symbol table");
|
||||
symsize += SYMINC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(j);
|
||||
}
|
||||
|
||||
/*
|
||||
* sort symbol table by name
|
||||
*/
|
||||
void n_sort_sym(int len)
|
||||
{
|
||||
register int gap, i, j;
|
||||
register struct sym *temp;
|
||||
|
||||
for (gap = len/2; gap > 0; gap /= 2)
|
||||
for (i = gap; i < len; i++)
|
||||
for (j = i-gap; j >= 0; j -= gap) {
|
||||
if (strcmp(symarray[j]->sym_name,
|
||||
symarray[j+gap]->sym_name) <= 0)
|
||||
break;
|
||||
temp = symarray[j];
|
||||
symarray[j] = symarray[j+gap];
|
||||
symarray[j+gap] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sort symbol table by address
|
||||
*/
|
||||
void a_sort_sym(int len)
|
||||
{
|
||||
register int gap, i, j;
|
||||
register struct sym *temp;
|
||||
|
||||
for (gap = len/2; gap > 0; gap /= 2)
|
||||
for (i = gap; i < len; i++)
|
||||
for (j = i-gap; j >= 0; j -= gap) {
|
||||
if (numcmp(symarray[j]->sym_wert,
|
||||
symarray[j+gap]->sym_wert) <= 0)
|
||||
break;
|
||||
temp = symarray[j];
|
||||
symarray[j] = symarray[j+gap];
|
||||
symarray[j+gap] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compares two 16bit values, result like strcmp()
|
||||
*/
|
||||
int numcmp(int n1, int n2)
|
||||
{
|
||||
if ((unsigned) (n1 & 0xffff) < (unsigned) (n2 & 0xffff))
|
||||
return(-1);
|
||||
else if ((unsigned) (n1 & 0xffff) > (unsigned) (n2 & 0xffff))
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
}
|
Reference in New Issue
Block a user