diff --git a/xa-2.4.0+relmode.diff b/xa-2.4.0+relmode.diff deleted file mode 100644 index ef10c8e..0000000 --- a/xa-2.4.0+relmode.diff +++ /dev/null @@ -1,302 +0,0 @@ -diff --git a/xa/misc/file65.c b/xa/misc/file65.c -index cec2d98..f9fe753 100644 ---- a/xa/misc/file65.c -+++ b/xa/misc/file65.c -@@ -48,6 +48,8 @@ int rompar = 0; - int romoff = 0; - int labels = 0; - -+int verbose = 0; -+ - void usage(FILE *fp) - { - fprintf(fp, -@@ -62,13 +64,14 @@ void usage(FILE *fp) - " in the same ROM. Add offset to start address.\n" - " -A offset same as `-a', but only print the start address of the next\n" - " file in the ROM\n" -- " -V print undefined and global labels\n" -+ " -v print undefined and global labels\n" -+ " -vv print undefined and global labels, and relocation tables\n" - " --version output version information and exit\n" - " --help display this help and exit\n"); - } - - int main(int argc, char *argv[]) { -- int i = 1, n, mode, hlen; -+ int i, j, n, mode, hlen; - FILE *fp; - char *aligntxt[4]= {"[align 1]","[align 2]","[align 4]","[align 256]"}; - if(argc<=1) { -@@ -76,12 +79,14 @@ int main(int argc, char *argv[]) { - exit(1); - } - -- if (strstr(argv[1], "--help")) { -+ i = 1; -+ -+ if (strstr(argv[i], "--help")) { - usage(stdout); - exit(0); - } - -- if (strstr(argv[1], "--version")) { -+ if (strstr(argv[i], "--version")) { - version(programname, progversion, author, copyright); - exit(0); - } -@@ -90,11 +95,12 @@ int main(int argc, char *argv[]) { - if(argv[i][0]=='-') { - /* process options */ - switch(argv[i][1]) { -- case 'V': -- labels = 1; -- break; - case 'v': -- printf("file65: Version 0.2\n"); -+ j = 1; -+ while (argv[i][j] == 'v') { -+ verbose ++; -+ j++; -+ } - break; - case 'a': - case 'A': -@@ -142,7 +148,7 @@ int main(int argc, char *argv[]) { - printf(" zero segment @ $%04x - $%04x [$%04x bytes]\n", hdr[21]*256+hdr[20], hdr[21]*256+hdr[20]+hdr[23]*256+hdr[22], hdr[23]*256+hdr[22]); - printf(" stack size $%04x bytes %s\n", hdr[25]*256+hdr[24], - (hdr[25]*256+hdr[24])==0?"(i.e. unknown)":""); -- if(labels) { -+ if(verbose) { - read_options(fp); - print_labels(fp, hdr[11]*256+hdr[10] + hdr[15]*256+hdr[14]); - } -@@ -231,13 +237,13 @@ void print_option(unsigned char *buf, int len) { - } - - int read_options(FILE *fp) { -- int c, l=0; -+ int c, d, l=0; - unsigned char tb[256]; - - c=fgetc(fp); l++; - while(c && c!=EOF) { - c&=255; -- fread(tb, 1, c-1, fp); -+ d = fread(tb, 1, c-1, fp); - if(labels) print_option(tb, c); - l+=c; - c=fgetc(fp); -@@ -247,11 +253,17 @@ int read_options(FILE *fp) { - - int print_labels(FILE *fp, int offset) { - int i, nud, c, seg, off; -+ const char *segments[] = { "undef", "abs", "text", "data", "bss", "zero" }; -+ const char *reltype[] = { "-", "LOW", "HIGH", "-", "WORD", "SEG", "SEGADDR" }; -+ - /* - printf("print_labels:offset=%d\n",offset); - */ - fseek(fp, offset, SEEK_CUR); - -+ // ----------------------------------------------------------- -+ // print undefined labels -+ - nud = (fgetc(fp) & 0xff); - nud += ((fgetc(fp) << 8) & 0xff00); - -@@ -269,25 +281,59 @@ printf("print_labels:offset=%d\n",offset); - printf("\n"); - } - -+ // --------------------------------------------------------- -+ // skip relocation tables -+ -+ // two tables, one for text one for data - for(i=0;i<2;i++) { -+ unsigned char lowbyte; -+ unsigned short index; -+ unsigned short offset = 0; -+ -+ if (verbose > 1) { -+ printf("Relocation table for %s:\n", i ? "text":"data"); -+ } -+ - c=fgetc(fp); - while(c && c!=EOF) { - c&= 0xff; - while(c == 255 && c!= EOF) { -+ offset += 254; - c=fgetc(fp); - if(c==EOF) break; - c&= 0xff; - } - if(c==EOF) break; -+ offset += c; - - c=fgetc(fp); -- if( (c & 0xe0) == 0x40 ) fgetc(fp); -- if( (c & 0x07) == 0 ) { fgetc(fp); fgetc(fp); } -- -+ if( (c & 0xe0) == 0x40 ) { -+ lowbyte = fgetc(fp); -+ } -+ if( (c & 0x07) == 0 ) { -+ index = fgetc(fp) & 0xff; -+ index += (fgetc(fp) & 0xff) << 8; -+ } -+ if (verbose > 1) { -+ printf("\t%d:%s(%s (%d)", offset, reltype[ (c>>5) & 0xf], segments[c & 0x07], (c&0x07)); -+ if ( (c & 0xe0) == 0x40) { -+ printf(", %02x", lowbyte); -+ } -+ if ( (c & 0x07) == 0) { -+ printf(", %04x", index); -+ } -+ printf(")"); -+ } - c=fgetc(fp); - } -+ if (verbose > 1) { -+ printf("\n"); -+ } - } - -+ -+ // --------------------------------------------------------- -+ // print global labels - nud = (fgetc(fp) & 0xff); - nud += ((fgetc(fp) << 8) & 0xff00); - printf("Global Labels: %d\n", nud); -diff --git a/xa/src/xat.c b/xa/src/xat.c -index 52671ea..c44809d 100644 ---- a/xa/src/xat.c -+++ b/xa/src/xat.c -@@ -632,45 +632,45 @@ printf("reloc: er=%d, l=%d, segment=%d, pc[%d]=%04x, pc[abs(%d)]=%04x, pc[text(% - dsb_len = 0; - } else - if(n==Ktext) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = relmode ? SEG_TEXT : SEG_ABS; - t[0]=Ksegment; - t[1]=segment; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else - if(n==Kdata) { - if(relmode) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_DATA; - t[0]=Ksegment; - t[1]=SEG_DATA; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kbss) { - if(relmode) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_BSS; - t[0]=Ksegment; - t[1]=SEG_BSS; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kzero) { - if(relmode) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_ZERO; - t[0]=Ksegment; - t[1]=SEG_ZERO; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } -diff --git a/xa/tests/csapiec/testseg.ok b/xa/tests/csapiec/testseg.ok -index 254ccb1..6a377b3 100644 -Binary files a/xa/tests/csapiec/testseg.ok and b/xa/tests/csapiec/testseg.ok differ -diff --git a/xa/tests/relmode/Makefile b/xa/tests/relmode/Makefile -index 350a7a7..68d64ba 100644 ---- a/xa/tests/relmode/Makefile -+++ b/xa/tests/relmode/Makefile -@@ -4,7 +4,7 @@ - - XA=../../xa - --tests: mixabs1 mixabs2 -+tests: mixabs1 mixabs2 mix1 mix2 clean - - - mixabs1: mixabsolute.a65 -@@ -17,6 +17,18 @@ mixabs2: mixabsolute.a65 - ../../reloc65 -bt 40960 -o $@ $@.tmp - ../hextool -cmp=b.ok < $@ - -+mix1: mix1.a65 -+ ${XA} -R -o $@.o65 $< -+ file65 -V $@.o65 -+ reloc65 -X -o $@ $@.o65 -+ ../hextool -cmp=$@.ok < $@.o65 -+ -+mix2: mix2.a65 -+ ${XA} -R -o $@.o65 $< -+ file65 -V $@.o65 -+ reloc65 -X -o $@ $@.o65 -+ ../hextool -cmp=$@.ok < $@.o65 -+ - clean: -- rm -f a.err a.o65 a.hex b.o65 mixabs2* -+ rm -f a.err *.o65 a.hex mixabs2* mix1 mix2 - -diff --git a/xa/tests/relmode/mix1.a65 b/xa/tests/relmode/mix1.a65 -new file mode 100644 -index 0000000..10b0762 ---- /dev/null -+++ b/xa/tests/relmode/mix1.a65 -@@ -0,0 +1,11 @@ -+ -+ .text -+ -+ .word $0401 -+ *=$0401 -+ *= -+ -+ .data -+NextPacketPtr: .byte 0,0 ; word -+ -+ -diff --git a/xa/tests/relmode/mix1.ok b/xa/tests/relmode/mix1.ok -new file mode 100644 -index 0000000..f86cb21 -Binary files /dev/null and b/xa/tests/relmode/mix1.ok differ -diff --git a/xa/tests/relmode/mix2.a65 b/xa/tests/relmode/mix2.a65 -new file mode 100644 -index 0000000..4cfc3e2 ---- /dev/null -+++ b/xa/tests/relmode/mix2.a65 -@@ -0,0 +1,11 @@ -+ -+ .text -+ -+ .word $0401 -+ *=$0401 -+ -+ -+ .data -+NextPacketPtr: .byte 0,0 ; word -+ -+ -diff --git a/xa/tests/relmode/mix2.ok b/xa/tests/relmode/mix2.ok -new file mode 100644 -index 0000000..f86cb21 -Binary files /dev/null and b/xa/tests/relmode/mix2.ok differ diff --git a/xa/src/xat.c.orig b/xa/src/xat.c.orig deleted file mode 100644 index 52671ea..0000000 --- a/xa/src/xat.c.orig +++ /dev/null @@ -1,2831 +0,0 @@ -/* xa65 - 65xx/65816 cross-assembler and utility suite - * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) - * maintained by Cameron Kaiser - * - * Core tokenizing module/pass 1 and pass 2 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* enable this to turn on (copious) optimization output */ - -#undef LISTING_DEBUG -#undef DEBUG_CONV -#undef DEBUG_CAST -#undef DEBUG_RELOC -#undef DEBUG_AM - -#include -#include -#include - -#include "xad.h" -#include "xah.h" -#include "xah2.h" - -#include "xar.h" -#include "xa.h" -#include "xaa.h" -#include "xal.h" -#include "xat.h" -#include "xao.h" -#include "xap.h" -#include "xacharset.h" -#include "xalisting.h" - -int dsb_len = 0; - -static int t_conv(signed char*,signed char*,int*,int,int*,int*,int*,int,int*); -static int t_keyword(signed char*,int*,int*); -static int tg_asc(signed char*,signed char*,int*,int*,int*,int*,int); -static void tg_dez(signed char*,int*,int*); -static void tg_hex(signed char*,int*,int*); -static void tg_oct(signed char*,int*,int*); -static void tg_bin(signed char*,int*,int*); -static int t_p2(signed char *t, int *ll, int fl, int *al); -//static void do_listing(signed char *listing, int listing_len, signed char *bincode, int bincode_len); - -void list_setbytes(int number_of_bytes_per_line); - -/* assembly mnemonics and pseudo-op tokens */ -/* ina and dea don't work yet */ -/* Note AF 20110624: added some ca65 compatibility pseudo opcodes, - * many are still missing (and will most likely never by supported in this - * code base). Potential candidates are .hibytes, .lobytes, .asciiz, - * .addr, .charmap, .dbyt, .faraddr, .bankbytes, .segment (at least for the known ones) - * .incbin is similar to our .bin, but with parameters reversed (argh...) - * I like the .popseg/.pushseg pair; - * .global/.globalzp is equivalent to forward-defining a label in the global block - * .export/.exportzp could be implemented with a commandline switch to NOT export - * global labels, where .exported labels would still be exported in an o65 file. - */ -char *kt[] ={ -/* 1 2 3 4 5 6 7 8 9 10 */ - "adc","and","asl","bbr","bbs","bcc","bcs","beq","bit","bmi", - "bne","bpl","bra","brk","bvc","bvs","brl","clc","cld","cli", -/* - "clv","cmp","cpx","cpy","cop","dea","dec","dex","dey","eor", -*/ - "clv","cmp","cpx","cpy","cop",/*"dea",*/"dec","dex","dey","eor", - -/* - "ina","inc","inx","iny","jmp","jsr","lda","ldx","ldy","lsr", -*/ - /*"ina",*/"inc","inx","iny","jmp","jsr","lda","ldx","ldy","lsr", - "mvp","mvn","nop","ora","pha","php","phx","phy","pla","plp", - "plx","ply","phb","phd","phk","plb","pld","pea","pei","per", - - "rmb","rol","ror","rti","rts","rep","rtl","sbc","sec","sed", - "sei","smb","sta","stx","sty","stz","sep","stp","tax","tay", - "trb","tsb","tsx","txa","txs","tya","txy","tyx","tcd","tdc", - - "tcs","tsc","wai","wdb","xba","xce", - - ".byt",".word",".asc",".dsb", ".(", ".)", "*=", ".text",".data",".bss", - ".zero",".fopt", ".byte", ".end", ".list", ".xlist", ".dupb", ".blkb", ".db", ".dw", - ".align",".block", ".bend",".al",".as",".xl",".xs", ".bin", ".aasc", ".code", - ".include", ".import", ".importzp", ".proc", ".endproc", - ".zeropage", ".org", ".reloc", ".listbytes", - ".scope", ".endscope", ".assert" - -}; - -/* arithmetic operators (purely for listing, parsing is done programmatically */ -char *arith_ops[] = { - "", "+", "-", - "*", "/", - ">>", "<<", - "<", ">", "=" - "<=", ">=", "<>", - "&", "^", "|", - "&&", "||", "==", "!=", "!" -}; - -/* length of arithmetic operators indexed by operator number */ -static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2,2,2,1 }; - -/* mvn and mvp are handled specially, they have a weird syntax */ -#define Kmvp 38 -#define Kmvn Kmvp+1 - -/* index into token array for pseudo-ops */ -/* last valid mnemonic */ -#define Lastbef 93 - -#define Kbyt Lastbef+1 -#define Kword Lastbef+2 -#define Kasc Lastbef+3 -#define Kdsb Lastbef+4 -#define Kopen Lastbef+5 /* .( */ -#define Kclose Lastbef+6 /* .) */ -#define Kpcdef Lastbef+7 /* *=value */ -#define Ktext Lastbef+8 -#define Kdata Lastbef+9 -#define Kbss Lastbef+10 -#define Kzero Lastbef+11 -#define Kfopt Lastbef+12 -#define Kbyte Lastbef+13 /* gets remapped to Kbyt */ -#define Kend Lastbef+14 /* ignored (MASM compat.) */ -#define Klist Lastbef+15 /* ignored (MASM compat.) */ -#define Kxlist Lastbef+16 /* ignored (MASM compat.) */ -#define Kdupb Lastbef+17 /* gets remapped to Kdsb */ -#define Kblkb Lastbef+18 /* gets remapped to Kdsb */ -#define Kdb Lastbef+19 /* gets remapped to Kbyt */ -#define Kdw Lastbef+20 /* gets remapped to Kword */ -#define Kalign Lastbef+21 -#define Kblock Lastbef+22 /* gets remapped to .( */ -#define Kbend Lastbef+23 /* gets remapped to .) */ - -#define Kalong Lastbef+24 -#define Kashort Lastbef+25 -#define Kxlong Lastbef+26 -#define Kxshort Lastbef+27 - -#define Kbin Lastbef+28 -#define Kaasc Lastbef+29 - -#define Kcode Lastbef+30 /* gets remapped to Ktext */ - -/* 93 + 30 -> 123 */ - -#define Kinclude Lastbef+31 -#define Kimport Lastbef+32 -#define Kimportzp Lastbef+33 -#define Kproc Lastbef+34 /* mapped to Kopen */ -/* 93 + 35 -> 128 */ -#define Kendproc Lastbef+35 /* mapped to Kclose */ -#define Kzeropage Lastbef+36 /* mapped to Kzero */ -#define Korg Lastbef+37 /* mapped to Kpcdef - with parameter equivalent to "*=$abcd" */ -#define Krelocx Lastbef+38 /* mapped to Kpcdef - without parameter equivalent to "*=" */ -#define Klistbytes (Lastbef+39-256) -#define Kscope (Lastbef+40) /* mapped to Kopen */ -#define Kendscope (Lastbef+41) /* mapped to Kclose */ - -#define Kassert (Lastbef+42-256) - -/* last valid token+1 */ -#define Anzkey Lastbef+43 /* define last valid token number; last define above plus one */ - - -#define Kreloc (Anzkey-256) /* *= (relocation mode) */ -#define Ksegment (Anzkey+1-256) /* this actually now is above 127, which might be a problem as char is signed ... */ - -int number_of_valid_tokens = Anzkey; - -/* array used for hashing tokens (26 entries, a-z) */ - -static int ktp[]={ 0,3,17,25,28,29,29,29,29,32,34,34,38,40,41,42,58, - 58,65,76,90,90,90,92,94,94,94,Anzkey }; - -#define Admodes 24 - -/* - * opcodes for each addressing mode - * high byte: supported architecture (no bits = original NMOS 6502) - * bit 1: R65C02 - * bit 2: 65816 and allows 16-bit quantity (accum only) - * bit 3: 65816 and allows 16-bit quantity (index only) - * low byte: opcode itself - * - * each opcode is indexed in this order: *=65816, ^=R65C02 - * 00 = implied - * 01 = zero page - * 02 = zero page,x - * 03 = direct page,y* - * 04 = direct page (indirect)* - * 05 = (indirect,x) - * 06 = (indirect),y - * 07 = immediate (8-bit) - * 08 = absolute - * 09 = absolute,x - * 10 = absolute,y - * 11 = relative - * 12 = (indirect-16) i.e., jmp (some_vector) - * 13 = (absolute,x)* - * 14 = zero page+relative test'n'branch ^ - * 15 = zero page clear'n'set'bit ^ - * 16 = relative long* - * 17 = absolute long* - * 18 = absolute long,x* - * 19 = stack relative* - * 20 = stack relative (indirect),y* - * 21 = direct page (indirect long)* - * 22 = direct page (indirect long),y* - * 23 = (indirect long) - */ - -static int ct[Lastbef+1][Admodes] ={ -/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 imm */ -{ -1, 0x65,0x75,-1,0x172,0x61,0x71,0x469,0x6d,0x7d,0x79,-1, -1, -1, -1, -1, -1,0x26f,0x27f,0x263,0x273,0x267,0x277,-1 }, /*adc*/ -{ -1, 0x25,0x35,-1,0x132,0x21,0x31,0x429,0x2d,0x3d,0x39,-1, -1, -1, -1, -1, -1,0x22f,0x23f,0x223,0x233,0x227,0x237,-1 }, /*and*/ -{ 0x0a,0x06,0x16,-1, -1, -1, -1, -1, 0x0e,0x1e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*asl*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x10f,-1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bbr*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x18f,-1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bbs*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x90,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bcc*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xb0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bcs*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xf0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*beq*/ -{ -1, 0x24,0x134,-1, -1, -1, -1, 0x589,0x2c,0x13c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bit*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x30,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bmi*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xd0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bne*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x10,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bpl*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x180,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bra*/ -{ 0x00,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*brk*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x50,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bvc*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x70,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bvs*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x282, -1, -1, -1, -1, -1, -1, -1 }, /*brl*/ -{ 0x18,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*clc*/ -{ 0xd8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cld*/ -{ 0x58,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cli*/ -{ 0xb8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*clv*/ -{ -1, 0xc5,0xd5,-1, 0x1d2,0xc1,0xd1,0x4c9,0xcd,0xdd,0xd9,-1, -1, -1, -1, -1,-1,0x2cf,0x2df,0x2c3,0x2d3,0x2c7,0x2d7,-1 }, /*cmp*/ -{ -1, 0xe4,-1, -1, -1, -1, -1, 0x8e0,0xec,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cpx*/ -{ -1, 0xc4,-1, -1, -1, -1, -1, 0x8c0,0xcc,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cpy*/ -{ -1, -1, -1, -1, -1, -1, -1, 0x202,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cop*/ -/* -{ 0x13a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },*/ /*dea*/ -{ 0x13a,0xc6,0xd6,-1, -1, -1, -1, -1, 0xce,0xde,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*dec*/ -{ 0xca,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*dex*/ -{ 0x88,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*dey*/ -{ -1, 0x45,0x55,-1, 0x152,0x41,0x51,0x449,0x4d,0x5d,0x59,-1, -1, -1, -1, -1,-1,0x24f,0x25f,0x243,0x253,0x247,0x257,-1 }, /*eor*/ -/* -{ 0x11a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },*/ /*ina*/ -{ 0x11a,0xe6,0xf6,-1, -1, -1, -1, -1, 0xee,0xfe,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*inc*/ -{ 0xe8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*inx*/ -{ 0xc8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*iny*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, 0x4c,-1, -1, -1, 0x6c,0x17c,-1, -1, -1,0x25c, -1, -1, -1, -1, -1,0x2dc}, /*jmp*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, 0x20,-1, -1, -1, -1, 0x2fc,-1, -1, -1,0x222, -1, -1, -1, -1, -1, -1 }, /*jsr*/ -{ -1, 0xa5,0xb5,-1, 0x1b2,0xa1,0xb1,0x4a9,0xad,0xbd,0xb9,-1, -1, -1, -1, -1,-1,0x2af,0x2bf,0x2a3,0x2b3,0x2a7,0x2b7,-1 }, /*lda*/ -{ -1, 0xa6,-1, 0xb6,-1, -1, -1, 0x8a2,0xae,-1, 0xbe,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ldx*/ -{ -1, 0xa4,0xb4,-1, -1, -1, -1, 0x8a0,0xac,0xbc,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ldy*/ -{ 0x4a,0x46,0x56,-1, -1, -1, -1, -1, 0x4e,0x5e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*lsr*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, 0x244,-1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*mvp*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, 0x254,-1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*mvn*/ -{ 0xea,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*nop*/ -{ -1, 0x05,0x15,-1, 0x112,0x01,0x11,0x409,0x0d,0x1d,0x19,-1, -1, -1, -1, -1,-1,0x20f,0x21f,0x203,0x213,0x207,0x217,-1 }, /*ora*/ -{ 0x48,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pha*/ -{ 0x08,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*php*/ -{ 0x1da,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phx*/ -{ 0x15a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phy*/ -{ 0x68,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pla*/ -{ 0x28,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*plp*/ -{ 0x1fa,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*plx*/ -{ 0x17a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ply*/ -{ 0x28b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phb*/ -{ 0x20b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phd*/ -{ 0x24b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phk*/ -{ 0x2ab,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*plb*/ -{ 0x22b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pld*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, 0x2f4,-1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pea*/ -{ -1, -1, -1, -1,0x2d4, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pei*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, 0x262,-1, -1, -1, -1, -1, -1, -1 }, /*per*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x107, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rmb*/ -{ 0x2a,0x26,0x36,-1, -1, -1, -1, -1, 0x2e,0x3e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rol*/ -{ 0x6a,0x66,0x76,-1, -1, -1, -1, -1, 0x6e,0x7e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ror*/ -{ 0x40,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rti*/ -{ 0x60,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rts*/ -{ -1, -1, -1, -1, -1, -1, -1, 0x2c2,-1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rep*/ -{ 0x26b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rtl*/ -{ -1, 0xe5,0xf5,-1, 0x1f2,0xe1,0xf1,0x4e9,0xed,0xfd,0xf9,-1, -1, -1, -1, -1,-1,0x2ef,0x2ff,0x2e3,0x2f3,0x2e7,0x2f7,-1 }, /*sbc*/ -{ 0x38,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sec*/ -{ 0xf8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sed*/ -{ 0x78,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sei*/ -{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x187, -1, -1, -1, -1, -1, -1, -1, -1 }, /*smb*/ -{ -1, 0x85,0x95,-1, 0x192,0x81,0x91,-1, 0x8d,0x9d,0x99,-1, -1, -1, -1, -1,-1,0x28f,0x29f,0x283,0x293,0x287,0x297,-1 }, /*sta*/ -{ -1, 0x86,-1, 0x96,-1, -1, -1, -1, 0x8e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*stx*/ -{ -1, 0x84,0x94,-1, -1, -1, -1, -1, 0x8c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sty*/ -{ -1, 0x164,0x174,-1, -1, -1, -1, -1, 0x19c,0x19e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*stz*/ -{ -1, -1, -1, -1, -1, -1, -1, 0x2e2,-1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sep*/ -{ 0x2db,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*stp*/ -{ 0xaa,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tax*/ -{ 0xa8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tay*/ -{ -1, 0x114,-1, -1, -1, -1, -1, -1, 0x11c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*trb*/ -{ -1, 0x104,-1, -1, -1, -1, -1, -1, 0x10c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tsb*/ -{ 0xba,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tsx*/ -{ 0x8a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*txa*/ -{ 0x9a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*txs*/ -{ 0x98,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tya*/ -{ 0x29b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*txy*/ -{ 0x2bb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tyx*/ -{ 0x25b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tcd*/ -{ 0x27b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tdc*/ -{ 0x21b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tcs*/ -{ 0x23b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tsc*/ -{ 0x2cb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*wai*/ -{ 0x242,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*wdb*/ -{ 0x2eb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*xba*/ -{ 0x2fb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /*xce*/ - - -} ; - -#define Syntax 14 -#define Maxbyt 4 - -/* grouped syntaxes. each row = operand type, column = bytes allowed */ -static int at[Syntax][Maxbyt] ={ -{ 0, -1, -1 ,-1 }, /* implied: no operand */ -{ -1, 7, -1 ,-1 }, /* immediate: single byte operand only */ -{ -1, 15, -1 ,-1 }, /* relative: single byte operand only */ -{ -1, -1, 14 ,-1 }, /* test'n'branch: two bytes only */ -{ -1, 1, 8 ,17 }, /* addressing: 1 byte for zp, - 2 for absolute, - 3 for absolute long */ -{ -1, 2, 9 ,18 }, /* ,x: same */ -{ -1, 3, 10 ,-1 }, /* ,y: 1 byte for dp,y, - 2 for absolute,y */ -{ -1, 4, 12 ,-1 }, /* (indirect): 1 byte for (dp), - 2 for (absolute) */ -{ -1, 5, 13 ,-1 }, /* (i,x): 1 byte for (zp,x), - 2 for (a,x) */ -{ -1, 6, -1 ,-1 }, /* (i),y: 1 byte only */ -{ -1, 21, 23 ,-1 }, /* (indirect long): 1 byte for (dp), - 2 for (a) */ -{ -1, 22, -1 ,-1 }, /* (indirect long),y: 1 byte only */ -{ -1, 19, -1 ,-1 }, /* stack relative: 1 byte only */ -{ -1, 20, -1 ,-1 } /* SR (in),y: 1 byte only */ -}; - -#define AnzAlt 5 - -/* disambiguation table. for example, arbitrary instruction xxx $0000 could - be either interpreted as an absolute operand, or possibly relative. - note: does not look at comma or after, if present. */ -static int xt[AnzAlt][2] ={ /* Alternativ Adr-Modes */ -{ 8, 11 }, /* abs -> rel */ -{ 2, 3 }, /* z,x -> z,y */ -{ 5, 6 }, /* ,x) -> ),y */ -{ 9, 10 }, /* a,x -> a,y */ - -{ 8, 16 } /* abs -> relong */ -}; - -/* cross check: instruction should be this many bytes long in total */ -/* indexed by addressing mode */ -static int le[] ={ 1,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2, - /* new modes */ 3,4,4,2,2,2,2,3 }; - -/* indicates absolute->zp optimizable addressing modes (abs->zp) */ -/* indexed by addressing mode */ -static int opt[] ={ -1,-1,-1,-1,-1,-1,-1,-1,1,2,3,-1,4,5,-1,-1, - /*new*/ -1,8,9,-1,-1,-1,-1,-1 }; /* abs -> zp */ - -/*********************************************************************************************/ -/* pass 1 */ -int t_p1(signed char *s, signed char *t, int *ll, int *al) -{ - static int er,l,n,v,nk,na1,na2,bl,am,sy,i,label,byte; /*,j,v2 ;*/ - int afl = 0; - int tlen; /* token listing length, to adjust length that is returned */ - int inp; /* input pointer in t[] */ - unsigned char cast; - -/* notes and typical conventions ... er = error code - am = addressing mode in use -*/ - - cast='\0'; - bl=0; - *al = 0; - -/* printf("\n"); */ - - /* convert the next token from string s */ -#ifdef DEBUG_AM -fprintf(stderr, "- p1 %d starting -\n", pc[segment]); -#endif - - /* As the t_p1 code below always works through the tokens - * from t_conv in such a way that it always produces a shorter - * result, the conversion below takes place "in place". - * This, however, means that the original token sequence, which - * would be useful for some assembler listing, is overwritten. - * While the original assumption was ok for a constrained - * environment like the Atari ST, this is no longer true. - * Converting the code below to have separate input and output - * areas would be error-prone, so we do some copy-magic here - * instead...*/ - /* we keep three bytes buffer for "T_LISTING" and the length of the - * token list - */ - t[0]=T_LISTING; - er=t_conv(s,t+6,&l,pc[segment],&nk,&na1,&na2,0,&byte); - tlen = l+6; - t[1]=tlen&255; - t[2]=(tlen>>8)&255; - t[3]=segment; - t[4]=pc[segment]&255; - t[5]=(pc[segment]>>8)&255; - /* now we have to duplicate the token sequence from the T_LISTING buffer - * to the end of "t", so we can then in-place convert it - * below. Non-overlapping, size is known in advance, so - * using memcpy is fine here - */ - inp = 0; - /* discard label definitions before copying the buffer, so we don't get - * label defined errors */ - while (inp1) && (t[inp]base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length(); - romable=1; - } - if(!er) - { - -/* - * - * pseudo-op dispatch (except .byt, .asc) - * - */ - // fix sign - n=t[0]; // & 0xff; - - /* TODO: make that a big switch statement... */ - /* maybe later. Cameron */ - - if(n==Kend || n==Klist || n==Kxlist) { - *ll = 0; /* ignore */ - } else - if(n==Kinclude) { - *ll = 0; /* no output length */ - i=1; - if(t[i]=='\"') { - int k,j=0; - char binfname[255]; - i++; - k=t[i]+i+1; - i++; - while(i 255) - er = E_NOMEM; /* buffer overflow */ - } - binfname[j] = '\0'; - er=icl_open(binfname); - } else { - er=E_SYNTAX; - } - } else - if(n==Kfopt) { - if(romable==1) er=E_ROMOPT; - t[0] = Kbyt; - set_fopt(l,t,nk+1-na1+na2); - *ll = 0; - } else - if(n==Klistbytes) { - int p = 0; - if(!(er=a_term(t+1,&p,&l,pc[segment],&afl,&label,0))) { - er=E_OKDEF; - } - *ll = 3; - t[0] = Klistbytes; - t[1] = p & 0xff; - t[2] = (p >> 8) & 0xff; - //printf("Klistbytes p1: er=%d, l=%d\n", er, l); - } else - if(n==Kpcdef) - { - int tmp; - // get parameter for *= - er=a_term(t+1,&tmp,&l,pc[segment],&afl,&label,0); - // found? - if(!er) - { - i=1; - wval(i,tmp, 0); /* writes T_VALUE, 3 bytes value, plus one byte */ - t[i++]=T_END; - *ll=7; - er=E_OKDEF; -#ifdef DEBUG_RELOC -printf("set pc=%04x, oldsegment=%d, pc[segm]=%04x, ", - pc[SEG_ABS], segment, pc[segment]); -printf(" wrote %02x %02x %02x %02x %02x %02x, %02x, %02x\n", - t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7]); -#endif - if(segment==SEG_TEXT) { - pc[SEG_ABS] = tmp; - r_mode(RMODE_ABS); - } else { - if(!relmode) { - pc[segment] = tmp; - } else { - er = E_ILLSEGMENT; - } - } -/*printf("newsegment=%d, pc[ABS]=%04x\n", segment, pc[SEG_ABS]);*/ - } else { - // no param found, only "*=". - // if we ABS, we switch back to reloc -#ifdef DEBUG_RELOC -printf("reloc: er=%d, l=%d, segment=%d, pc[%d]=%04x, pc[abs(%d)]=%04x, pc[text(%d)]=%04x\n", - er, l, segment, segment, pc[segment], SEG_ABS, pc[SEG_ABS],SEG_TEXT, pc[SEG_TEXT]); -#endif - if((segment==SEG_ABS) && (er==E_SYNTAX && l==0)) { - t[0]=Kreloc; - i=1; - wval(i,pc[SEG_TEXT], 0); - t[i++]=T_END; - *ll=7; - er=E_OKDEF; - r_mode(RMODE_RELOC); -/*printf(" : newseg=%d, pc[newseg]=%04x, pc[abs]=%04x, pc[text]=%04x\n", - segment, pc[segment], pc[SEG_ABS], pc[SEG_TEXT]);*/ - } - } - } else - if(n==Kopen) - { - if(showblk) fprintf(stderr, "%s line %d: .(\n", pp_getidat()->fname, pp_getidat()->fline); - b_open(); - er=E_NOLINE; - } else - if(n==Kclose) - { - if(showblk) fprintf(stderr, "%s line %d: .)\n", pp_getidat()->fname, pp_getidat()->fline); - er=b_close(); - if(!er) er=E_NOLINE; - } else - if(n==Kalong) - { - if (!w65816) { - er=E_65816; - } else { - memode=1; - t[0]=Kalong; - *ll=1; - er=E_OKDEF; - } - } else - if(n==Kashort) - { - memode=0; - t[0]=Kashort; - *ll=1; - er=E_OKDEF; - } else - if(n==Kxlong) - { - if (!w65816) { - er=E_65816; - } else { - xmode=1; - t[0]=Kxlong; - *ll=1; - er=E_OKDEF; - } - } else - if(n==Kxshort) - { - xmode=0; - t[0]=Kxshort; - *ll=1; - er=E_OKDEF; - } else - if(n==Kdsb) - { - dsb_len = 1; - if(!(er=a_term(t+1,&bl,&l,pc[segment],&afl,&label,0))) { - er=E_OKDEF; - } - dsb_len = 0; - } else - if(n==Ktext) { - segment = relmode ? SEG_TEXT : SEG_ABS; - t[0]=Ksegment; - t[1]=segment; - *ll=2; - er=E_OKDEF; - r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else - if(n==Kdata) { - if(relmode) { - segment = SEG_DATA; - t[0]=Ksegment; - t[1]=SEG_DATA; - *ll=2; - er=E_OKDEF; - r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kbss) { - if(relmode) { - segment = SEG_BSS; - t[0]=Ksegment; - t[1]=SEG_BSS; - *ll=2; - er=E_OKDEF; - r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kzero) { - if(relmode) { - segment = SEG_ZERO; - t[0]=Ksegment; - t[1]=SEG_ZERO; - *ll=2; - er=E_OKDEF; - r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if (n==Kassert) { /* ignore this in first pass, just check syntax */ - int x; - i = 1; - - /* XXX: sadly, can't implement unary logical not yet */ - if(!(er=a_term(t+i,&x,&l,pc[segment],&afl,&label,1))) { - i += l; - } - if(t[i] == ',') { /* skip comma */ - i++; - } else { - er = E_SYNTAX; - } - /* get filename. - the tokenizer can either see it as a multichar string ... */ - if (!er) { - int k; - - if(t[i]=='\"') { - i++; - k=t[i]+i+1; - i++; - while(i 255) - er = E_NOMEM; /* buffer overflow */ - } - binfnam[j] = '\0'; - /* or as a 'char' if it's a single character ("word" would - have been caught by the above) */ - } else - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { - binfnam[0] = v; - binfnam[1] = '\0'; - i += l; - } - } - - /* three arguments only please */ - if (!er && t[i] != T_END && t[i] != T_COMMENT) { - er = E_SYNTAX; - } - - if (!er) { - FILE *foo; - -#ifdef DEBUG_AM - fprintf(stderr, -"binclude1 offset = %i len = %i filename = %s endchar = %i\n", - offset, length, binfnam, i); -#endif - if (!(foo = fopen(binfnam, "rb"))) { - er = E_FNF; - } else { - fseek(foo, 0, SEEK_END); - if ((length+offset) > ftell(foo)) { - er = E_OUTOFDATA; - } else { - length = (length) ? length : - (ftell(foo)-offset); - } - fclose(foo); - } - if (!er) { - if (length > 65535 && !w65816) { - errout(W_OVER64K); - } else if (length > 16777215) { - errout(W_OVER16M); - } - /* pass parameters back to xa.c */ - *ll=i+1; -/* - bl=length+2; -*/ - bl=length; - er = E_OKDEF; /* defer to pass 2 */ - } - } - } else - if(n==Kalign) { - int tmp; - if(segment!=SEG_ABS) { - if(!(er=a_term(t+1,&tmp,&l,pc[segment],&afl,&label,0))) { - if(tmp == 1 || tmp == 2 || tmp == 4 || tmp == 256) { - set_align(tmp); - if(pc[segment] & (tmp-1)) { /* not aligned */ - int tmp2; - t[0]=Kdsb; - i=1; - bl=tmp=(tmp - (pc[segment] & (tmp-1))) & (tmp-1); - wval(i,tmp, 0); - t[i++]=','; - tmp2= 0xea; - wval(i,tmp2, 0); /* nop opcode */ - t[i++]=T_END; - *ll=9; - er=E_OKDEF; - } else { - *ll=0; /* ignore if aligned right */ - } - } else { - er=E_ILLALIGN; - } - } - } else { - er=E_ILLSEGMENT; - } - } else - /* optimization okay on pass 1: use 0 for fl */ - { -#ifdef DEBUG_AM -fprintf(stderr, "E_OK ... t_p2 xat.c %i %i\n", t[0], *ll); -#endif - /* this actually calls pass2 on the current tokenization stream, - * but without including the Klisting token listing */ - er=t_p2(t,ll,(0 | byte), al); -#ifdef DEBUG_AM -fprintf(stderr, "... --> er=%d\n", er); -#endif - } - - } else - if(er==E_NODEF) - { - - /* - * no label was found from t_conv! - * try to figure out most likely length - * - */ - -#ifdef DEBUG_AM -fprintf(stderr, "E_NODEF pass1 xat.c\n"); -#endif - er = E_OK; /* stuff error */ - n=t[0]; /* look at first token */ - - /* mnemonic dispatch -- abbreviated form in t_p2, but changed here - to not do anything other than 24-bit optimization since we - don't know the value of the label */ - - /* choose addressing mode; add commas found */ - - if(n>=0 && n<=Lastbef && n != Kmvn && n != Kmvp) /* not for mvn/p */ - { - int inp = 1; /* input pointer */ - - if(t[inp]==T_END || t[inp]==T_COMMENT) - { - sy=0; /* implied */ - inp++; - } else - if(t[inp]=='#') - { - sy=1+nk; /* immediate */ - inp++; - } else - if(t[inp]=='(') - { - sy=7+nk; /* computed */ - inp++; - } else { - sy=4+nk; /* absolute or zero page */ - } - - /* this actually finds the cast for all addressing modes, - but t_conv() only puts it there for immediate (#) or absolute/ - absolute indexed addressing modes */ - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; -#ifdef DEBUG_CAST - printf("Found cast to: %c\n", cast); -#endif - } - - /* length counter set to maximum length + 1 */ - if (w65816 || (t[l-1]=='@' || t[l-1] == '!')) { - /* for 65816 allow addressing modes up to 4 byte overall length */ - bl=Maxbyt+1; - } else { - /* for other modes only check for addressing modes up to 3 byte overall length */ - bl=Maxbyt; - } - - /* find best fit for length of this operand */ - while(--bl) - { - - /* look at syntax table (at) using syntax (sy) as index. - is there an addressing mode for an operand - of this length? am = addressing mode */ - - if((am=at[sy][bl-1])>=0) - { - if(am>Admodes-1) /* no, it's -1, syntax error */ - { - er=E_SYNTAX; - break; - } - if(ct[n][am]>=0) /* yes, valid token *and* mode, - so we're done */ - break; - - /* no valid mode for this token, see if it's something - ambiguous; if so, try to interpret in that - context. */ - for(v=0;v=0) - break; - if(v=0 && am>16) /* <<< NOTE! */ - if(ct[n][opt[am]]>=0) - am=opt[am]; - } - /* if ` is declared, force further optimization */ - if (cast=='`') { - if (opt[am]<0 || ct[n][opt[am]]<0) - errout(E_ADRESS); - am=opt[am]; - } - /* if ! is declared, force to 16-bit quantity */ - if (cast=='!' && am>16 && opt[am]>=0 && bl) { - am=opt[am]; - } - - /* couldn't match anything for this opcode */ - if(!bl) - er=E_SYNTAX; - else { - /* ok, get length of instruction */ - bl=le[am]; - /* and add one for 65816 special instruction modes */ - if( ((ct[n][am]&0x400) && memode) || - ((ct[n][am]&0x800) && xmode)) { - bl++; - } - } - - - if (er == E_NODEF) - er = E_OK; - - /* .byt, .asc, .word, .dsb, .fopt pseudo-op dispatch */ - - } else - if(n==Kimportzp) { - int i; - *ll=0; /* no output */ - bl = 0; /* no output length */ - /* import labels; next follow a comma-separated list of labels that are - imported. Tokenizer has already created label entries, we only need to - set the flags appropriately */ - i=1; -/*printf("Kimport: t[i]=%d\n",t[i]);*/ - while(t[i]==T_LABEL) { - int n = (t[i+1] & 255) | (t[i+2] << 8); /* label number */ -/*printf("lg_import: %d\n",n);*/ - lg_importzp(n); - i+=3; - while (t[i]==' ') i++; - if (t[i]!=',') break; - i++; - while (t[i]==' ') i++; - } - er=E_NOLINE; - } else - if(n==Kimport) { - int i; - *ll=0; /* no output */ - bl = 0; /* no output length */ - /* import labels; next follow a comma-separated list of labels that are - imported. Tokenizer has already created label entries, we only need to - set the flags appropriately */ - i=1; -/*printf("Kimport: t[i]=%d\n",t[i]);*/ - while(t[i]==T_LABEL) { - int n = (t[i+1] & 255) | (t[i+2] << 8); /* label number */ -/*printf("lg_import: %d\n",n);*/ - lg_import(n); - i+=3; - while (t[i]==' ') i++; - if (t[i]!=',') break; - i++; - while (t[i]==' ') i++; - } - er=E_NOLINE; - } else - if(n==Kmvn || n==Kmvp) - { - bl=3; - if (!w65816) er = E_65816; - } else - if(n==Kbyt || n==Kasc || n==Kaasc) - { -#ifdef DEBUG_AM -fprintf(stderr, "byt pass 1 %i\n", nk+1-na1+na2); -#endif - bl=nk+1-na1+na2; - } else - if(n==Kword) - { - bl=2*nk+2; - } else - if(n==Kdsb) - { - er=a_term(t+1,&bl,&l,pc[segment],&afl,&label,0); - } else - if(n==Kfopt) - { - set_fopt(l-1,t+1, nk+1-na1+na2); - *ll = 0; - } else - if(n==T_OP) - { - er=E_OKDEF; - } else - er=E_NODEF; - - if(!er) - er=E_OKDEF; -#ifdef DEBUG_AM -fprintf(stderr, "guessing instruction length is %d\n", bl); -#endif - } - if(er==E_NOLINE) - { - er=E_OK; - *ll=0; - } - - *al += bl; - pc[segment]+=bl; - if(segment==SEG_TEXT) pc[SEG_ABS]+=bl; - if(segment==SEG_ABS) pc[SEG_TEXT]+=bl; - - /* adjust length by token listing buffer length */ -#ifdef DEBUG_CONV - printf("converted: (er=%d, t=%p, ll=%d, tlen=%d):",er, t, *ll, tlen); - for(i=0;i<*ll;i++) - printf("%02x,",t[i] & 0xff); - printf("\n"); - printf("adjusted len=%d\n", *ll+tlen); -#endif - - *ll = *ll + tlen; - return(er); -} - -/*********************************************************************************************/ -/* t_pass 2 - * - * *t is the token list as given from pass1 - * *ll is the returned length of bytes (doubles as - * input for whether OK or OKDEF status from pass1) - * fl defines if we allow zeropage optimization - * - * Conversion takes place "in place" in the *t array. - */ - -/** - * function called from the main loop, where "only" the - * undefined labels have to be resolved and the affected - * opcodes are assembled, the rest is passed through from - * pass1 (pass-through is done in t_p2, when *ll<0) - * As this is not called from p1, assume that we do not - * do length optimization - * - * *t is the input token list - * *ll is the input length of the token list, - * and the output of how many bytes of the buffer are to be taken - * into the file; note that for .dsb and .bin, this does NOT match - * the length in the internal data structures! - */ -int t_p2_l(signed char *t, int *ll, int *al) -{ - int er = E_OK; - int l = *ll; - - if (l < 0) l = -l; - -#if 0 - { - printf("t_p2_l (ll=%d, t=%p):", *ll, t); - for(int i=0;i l) - { - int i; - - // that is corrupt data and should not happen - list_flush(); - printf("corrupt: t_p2_l (l=%d, tlen=%d, ll=%d, t=%p):", l, tlen, *ll, t); - for(i=0;i0 when E_OKDEF */ - { - *ll=-*ll; - bl=*ll; - er=E_OK; - - } else - { - n=t[0]; - if(n==T_OP) - { - n=cval(t+1); - er=a_term(t+4,&v,&l,pc[segment],&nafl,&label,0); - - if(!er) - { - if(t[3]=='=') - { - v2=v; - } else { - if( (!(er=l_get(n,&v2, &afl))) - && ((afl & A_FMASK)!=(SEG_UNDEF<<8)) - && ((afl & A_FMASK)!=(SEG_UNDEFZP<<8)) ) - { - if(t[3]=='+') - { - if(afl && nafl) { errout(E_WPOINTER); nafl=0; } - nafl = afl; - v2+=v; - } else - if(t[3]=='-') - { - if( (((nafl & A_FMASK)>>8) != afl) - || ((nafl & A_MASK)==A_HIGH) ) { - errout(E_WPOINTER); - nafl=0; - } else { - nafl = afl; - } - v2-=v; - } else - if(t[3]=='*') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - v2*=v; - } else - if(t[3]=='/') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - if(v) - v2/=v; - else - er=E_DIV; - } else - if(t[3]=='|') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - v2=v|v2; - } else - if(t[3]=='&') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - v2=v2&v; - } - } - } - l_set(n,v2,nafl>>8); - - *ll=0; - if(!er) - er=E_NOLINE; - } - } else - if(n==Kword) - { - i=1; - j=0; - while(!er && t[i]!=T_END && t[i] != T_COMMENT) - { - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) - { -/*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", - afl,pc[segment],v); */ - if(afl) u_set(pc[segment]+j, afl, label, 2); - t[j++]=v&255; - t[j++]=(v>>8)&255; - - i+=l; - if(t[i]!=T_END && t[i] != T_COMMENT && t[i]!=',') - er=E_SYNTAX; - else - if(t[i]==',') - i++; - - } - } - *ll=j; - bl=j; - } else - if (n == Kassert) - { - int result = 0; - int c; - i = 1; - - /* this time, actually check something */ - if(!(er=a_term(t+i,&result,&l,pc[segment],&afl,&label,1))) { - i += l; - } - if(t[i] == ',') { /* skip comma */ - i++; - } else { - er = E_SYNTAX; - } - /* get filename. - the tokenizer can either see it as a multichar string ... */ - if (!er) { - int k; - - if (!result) - fprintf(stderr, "Assertion failed: "); - if(t[i]=='\"') { - i++; - k=t[i]+i+1; - i++; - while(i 255) - er = E_NOMEM; /* buffer overflow */ - } - binfnam[j] = '\0'; - flen = j; - /* or as a 'char' if it's a single character ("word" would - have been caught by the above) */ - } else - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { - binfnam[0] = v; - binfnam[1] = '\0'; - i += l; - flen = 1; - } - } - - /* three arguments only please */ - if (!er && t[i] != T_END && t[i] != T_COMMENT) { - er = E_SYNTAX; - } - - if (!er) { - FILE *foo; - -#ifdef DEBUG_AM - fprintf(stderr, -"binclude2 offset = %i len = %i filename = %s endchar = %i\n", - offset, length, binfnam, i); -#endif - if (!(foo = fopen(binfnam, "rb"))) { - er = E_FNF; - } else { - fseek(foo, 0, SEEK_END); - if ((length+offset) > ftell(foo)) { - er = E_OUTOFDATA; - } else { - length = (length) ? length : - (ftell(foo)-offset); - } - fclose(foo); - } - if (!er) { - if (length > 65535 && !w65816) { - errout(W_OVER64K); - } else if (length > 16777215) { - errout(W_OVER16M); - } - /* pass parameters back to xa.c */ - *ll=length; -/* - bl=length+2; -*/ - bl=length; - t[0] = offset & 255; - t[1] = (offset >> 8) & 255; - t[2] = (offset >> 16) & 255; - /* God help us if the index is > 65535 */ - t[3] = fstart & 255; - t[4] = (fstart >> 8) & 255; - t[5] = flen; /* to massage 'char' types */ - er = E_BIN; - } - } - } else - if (n==Kmvn || n==Kmvp) - { - /* special case these instructions' syntax */ - int wide=0; - i=1; - j=1; - /* write opcode */ - t[0] = ((n == Kmvp) ? 0x44 : 0x54); - while(!er && t[i]!=T_END && t[i]!=T_COMMENT) - { - if (wide) /* oops */ - er = E_SYNTAX; -#ifdef DEBUG_AM -fprintf(stderr, "mvn mvp: %i %i %i %i %i\n", t[0], t[i], wide, i, j); -#endif - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) - { -/*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", - afl,pc[segment],v); */ - if(afl) u_set(pc[segment]+j, afl, label, 2); - i+=l; - if (v & 0xff00) - er=E_ILLQUANT; - else - t[j++]=v; - } - if (j > 3) - er=E_SYNTAX; - if(t[i]!=T_END && t[i]!=T_COMMENT && t[i]!=',') - er=E_SYNTAX; - else - if(t[i]==',') - i++; - } - if (j != 3) er = E_SYNTAX; /* oops */ - - /* before we leave, swap the bytes. although disassembled as - mv? src,dest it's actually represented as - mv? $ddss -- see - http://6502org.wikidot.com/software-65816-memorymove */ - i = t[2]; - t[2] = t[1]; - t[1] = i; - - *ll = j; - bl = j; - if (!w65816) er = E_65816; - } else if(n==Kasc || n==Kbyt || n==Kaasc) { - i=1; - j=0; - while(!er && t[i]!=T_END && t[i] != T_COMMENT) - { - if(t[i]=='\"') - { - i++; - k=t[i]+i+1; - i++; - while(i er=%d, nbytes=%d\n", er, nbytes); - list_setbytes(nbytes); - l = 2; - *ll=0; - bl =0; - } else - if(n==Ksegment) { - segment = t[1]; - *ll=0; - bl =0; - } else - if(n==Kdsb) - { - dsb_len = 1; - if(!(er=a_term(t+1,&j,&i,pc[segment],&afl,&label,0))) - { - if (j<0) - er=E_NEGDSBLEN; - else -/* - if(t[i+1]!=',') - er=E_SYNTAX; - else -*/ -/* - if((segment!=SEG_ABS) && afl) - er=E_ILLPOINTER; - else -*/ - { - dsb_len = 0; - - if(t[i+1]==',') { - er=a_term(t+2+i,&v,&l,pc[segment],&afl,&label,0); - } else { - v=0; - } - if(!er && v>>8) - er=E_OVERFLOW; - t[0]=v&255; - if(!er) - { - *ll=j; - bl=j; -#ifdef DEBUG_AM -fprintf(stderr, "Kdsb E_DSB %i\n", j); -#endif - er=E_DSB; - } - } - if(!er) - bl=j; - } - dsb_len = 0; - } else - if(n>=0 && n<=Lastbef) - { - int inp = 1; /* input pointer */ - signed char cast = '\0'; /* cast value */ - - c = t[inp]; - - if(c=='#') - { - inp++; - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; -#ifdef DEBUG_CAST - printf("Found cast to (2): %c\n", cast); -#endif - } - sy=1; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { -/* if(1) printf("a_term returns afl=%04x\n",afl); */ - - rlt[0] = afl; - lab[0] = label; - inp+=l; - if(t[inp]!=T_END && t[inp] != T_COMMENT) - { - if(t[inp]!=',') - er=E_SYNTAX; - else - { - inp++; - sy++; - if(!(er=a_term(t+inp,vv+1,&l,pc[segment],&afl,&label,1))) - { - rlt[1] = afl; - lab[1] = label; - inp+=l; - if(t[inp]!=T_END && t[inp] != T_COMMENT) - { - if(t[inp]!=',') - er=E_SYNTAX; - else - { - inp++; - sy++; - if(!(er=a_term(t+inp,vv+2,&l,pc[segment],&afl,&label,1))) - { - rlt[2] = afl; - lab[2] = label; - inp+=l; - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - er=E_SYNTAX; - } - } - } - } - } - } - } - } else - if(c==T_END || c==T_COMMENT) - { - sy=0; - } else - if(c=='(') - { - inp++; - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; -#ifdef DEBUG_CAST - printf("Found cast to (3): %c\n", cast); -#endif - } - sy=7; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { - inp += l; - rlt[0] = afl; - lab[0] = label; - - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - { - if(t[inp]==',') - { - inp++; - if (tolower(t[inp])=='x') - sy=8; - else - sy=13; - - } else - if(t[inp]==')') - { - inp++; - if(t[inp]==',') - { - inp++; - if(tolower(t[inp])=='y') - sy=9; - else - er=E_SYNTAX; - } else - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - er=E_SYNTAX; - } - } else - er=E_SYNTAX; - } - } else - if(c=='[') - { - inp++; - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; -#ifdef DEBUG_CAST - printf("Found cast to (4): %c\n", cast); -#endif - } - sy=10; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { - inp += l; - rlt[0] = afl; - lab[0] = label; - - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - { - if(t[inp]==']') - { - inp++; - if(t[inp]==',') - { - inp++; - if(tolower(t[inp])=='y') - sy=11; - else - er=E_SYNTAX; - } else - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - er=E_SYNTAX; - } - } else - er=E_SYNTAX; - } - } else - { - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; -#ifdef DEBUG_CAST - printf("Found cast to (5): %c\n", cast); -#endif - } - sy=4; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { - inp += l; - rlt[0] = afl; - lab[0] = label; - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - { - if(t[inp]==',') - { - inp++; - if(tolower(t[inp])=='y') - sy=6; - else - if(tolower(t[inp])=='s') - sy=12; - else - sy=5; - } else - er=E_SYNTAX; - } - } - } - - /* set bl to maximum overall length +1 as while() below starts with decrementing it */ - if (w65816 || cast=='@' || cast== '!') { - /* for 65816 allow addressing modes up to 4 byte overall length */ - bl=Maxbyt+1; - } else { - /* for other modes only check for addressing modes up to 3 byte overall length */ - bl=Maxbyt; - } - -#ifdef DEBUG_AM - printf("--- trying to find am using: (max+1) bl=%d, sy=%d\n", bl, sy); -#endif - while(--bl) - { - if((am=at[sy][bl-1])>=0) - { - if(am>Admodes) - { - er=E_SYNTAX; - break; - } - if(ct[n][am]>=0) - break; - - for(v=0;v=0) - break; - if(v16 - && !er - && (((vv[0]&0xff8000)==0xff8000) || !(vv[0]&0xff0000)) - && opt[am]>=0) - if(ct[n][opt[am]]>=0) - am=opt[am]; -#ifdef DEBUG_AM -fprintf(stderr, -"aftaa1: pc= %d, am = %d and vv[0] = %d, optimize = %d, bitmask = %d, bl = %d\n", - pc[segment], am, vv[0], fl, (vv[0]&0xffff00), bl); -#endif - if(cast!='!') { - if(bl && !er && !(vv[0]&0xffff00) && opt[am]>=0) { - if(ct[n][opt[am]]>=0) { - if (!fl || cast=='`') { - am=opt[am]; - } else { - errout(W_FORLAB); - } - } - } - } -#ifdef DEBUG_AM -fprintf(stderr, -"aftaa2: pc=%d, am=%d and vv[0]=%d, optimize=%d, bitmask=%d, op=%d, bl=%d\n", - pc[segment], am, vv[0], fl, (vv[0]&0xffff00), ct[n][opt[am]], bl); -#endif - } - - if(!bl) - er=E_SYNTAX; - else - { - bl=le[am]; - if( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode)) { - bl++; - } - if ((am != 11 && am != 16) && (vv[0] > 255 || vv[0] < -256) && bl == 2) { - er = E_OVERFLOW; - } else - if ((am != 11 && am != 16) && (vv[0] > 65535 || vv[0] < -65536) && (bl == 2 || bl == 3)) { - er = E_OVERFLOW; - } - *ll=bl; - } - -#ifdef DEBUG_AM -fprintf(stderr, "byte length is now %d, am=%d, er=%d\n", bl, am, er); -#endif - - if(!er) - { - t[0]=ct[n][am]&0x00ff; - if(ct[n][am]&0x0300) - { - if(ct[n][am]&0x100) { - ncmos++; - if(!cmosfl) - er=E_CMOS; - } else { - n65816++; - if(!w65816) { -fprintf(stderr,"n=%d, am=%d\n", n, am); - er=E_65816; - } - } - } - if(am!=0) - { - if((am<8 && !( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode) )) || (am>=19 && am!=23)) - { - if(vv[0]&0xff00) { -#ifdef DEBUG_AM -fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]); -#endif - er=E_OVERFLOW; - } - else - t[1]=vv[0]; -/*if(rlt[0]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ - if(rlt[0]) u_set(pc[segment]+1, rlt[0], lab[0], 1); - } else - if(((am<14 || am==23) && am!=11) || am==7) - { - if (vv[0]>0xffff) { -#ifdef DEBUG_AM -fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]); -#endif - er=E_OVERFLOW; - } - else { - t[1]=vv[0]&255; - t[2]=(vv[0]>>8)&255; -/*if(rlt[0]) printf("relocation 2 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ - if(rlt[0]) u_set(pc[segment]+1, rlt[0], lab[0], 2); - } - } else - if(am==11 || am==16) { - /* relative, relative long */ - if((segment!=SEG_ABS) && (!rlt[0])) { - er=E_ILLPOINTER; - } else { -/*printf("am=11, pc=%04x, vv[0]=%04x, segment=%d\n",pc[segment],vv[0], segment);*/ - v=vv[0]-pc[segment]-le[am]; - if(((v&0xff80)!=0xff80) && (v&0xff80) && (am==11)) - er=E_RANGE; - else { - t[1]=v&255; - t[2]=(v>>8)&255; - } - } - } else - if(am==14) { - if(vv[0]&0xfff8 || vv[1]&0xff00) - er=E_RANGE; - else - if((segment!=SEG_ABS) && (rlt[0] || !rlt[2])) { - er=E_ILLPOINTER; - } else { -/*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ - if(rlt[1]) u_set(pc[segment]+1, rlt[1], lab[1], 1); - t[0]=t[0]|(vv[0]<<4); - t[1]=vv[1]; - v=vv[2]-pc[segment]-3; - if((v&0xff80) && ((v&0xff80)!=0xff80)) - er=E_OVERFLOW; - else - t[2]=v; - } - } else - if(am==15) - { -/*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ - if(rlt[1]) u_set(pc[segment]+1, rlt[1], lab[1], 1); - if(vv[0]&0xfff8 || vv[1]&0xff00) - er=E_OVERFLOW; - else - { - t[0]=t[0]|(vv[0]<<4); - t[1]=vv[1]; - } - } else - if(am==17 || am==18) - { - t[1]=vv[0]&255; - t[2]=(vv[0]>>8)&255; - t[3]=(vv[0]>>16)&255; - if(rlt[0]) { - rlt[0]|=A_LONG; - u_set(pc[segment]+1, rlt[0], lab[0], 3); - } - - } else - er=E_SYNTAX; - } - } - - } else - er=E_SYNTAX; - } - -#ifdef DEBUG_AM -fprintf(stderr, "-- endof P2\n"); -#endif - pc[segment]+=bl; - if(segment==SEG_TEXT) pc[SEG_ABS]+=bl; - if(segment==SEG_ABS) pc[SEG_TEXT]+=bl; - *al = bl; - return(er); -} - -/*********************************************************************************************/ -/* helper function for the preprocessor, to compute an arithmetic value - * (e.g. for #if or #print). - * First tokenizes it, then calculates the value - */ -int b_term(char *s, int *v, int *l, int pc) -{ - static signed char t[MAXLINE]; - int er,i,afl, label; - - if(!(er=t_conv((signed char*)s,t,l,pc,&i,&i,&i,1,NULL))) - { - er=a_term(t,v,&i,pc,&afl,&label,0); - - } - return(er); -} - -/*********************************************************************************************/ -/* translate a string into a first-pass sequence of tokens; - * Take the text from *s (stopping at \0 or ';'), tokenize it - * and write the result to *t, returning the length of the - * token sequence in *l - * - * Input params: - * s source input line - * t output token sequence buffer - * l return length of output token sequence here - * pc the current PC to set address labels to that value - * nk return number of comma in the parameters - * na1 asc text count returned - * na2 total byte count in asc texts returned - * af arithmetic flag: 0=do label definitions, parse opcodes and params; - * 1=only tokenize parameters, for b_term() call from the preprocessor - * for arithmetic conditions - * bytep ??? - */ -static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk, - int *na1, int *na2, int af, int *bytep) -{ - static int v,f; - static int operand,o; - int fl,afl; - int p,q,ll,mk,er; - int ud; /* counts undefined labels */ - int n; /* label number to be passed between l_def (definition) and l_set (set the value) */ - int byte; - int uz; /* unused at the moment */ - /*static unsigned char cast;*/ - -/* ich verstehe deutsch, aber verstehen andere leute nicht; so, werde ich - diese bemerkungen uebersetzen ... cameron */ -/* I understand German, but other folks don't, so I'll translate these - comments ... Cameron */ -/* note that I don't write so good tho' ;) */ - - *nk=0; /* comma count */ - *na1=0; /* asc text count */ - *na2=0; /* total bytecount in asc texts */ - ll=0; - er=E_OK; /* error state */ - p=0; - q=0; - ud = uz = byte =0; - mk=0; /* 0 = add'l commas ok */ - fl=0; /* 1 = pass text thru */ - afl=0; /* pointer flag for label */ - - // skip leading whitespace - while(isspace(s[p])) p++; - - n=T_END; - /*cast='\0';*/ - - if(!af) - { - while(s[p]!='\0' && s[p]!=';') - { - //printf("CONV: %s\n", s); - - if (s[p] == ':') { - // this is a ca65 unnamed label - if ((er = l_def((char*)s+p, &ll, &n, &f))) - break; - l_set(n,pc,segment); /* set as address value */ - t[q++]=T_DEFINE; - t[q++]=n&255; - t[q++]=(n>>8)&255; - n=0; - - p+=ll; - - while(isspace(s[p])) p++; - - // end of line - if (s[p] == 0 || s[p] == ';') { - break; - } - } - - /* is keyword? */ - if(!(er=t_keyword(s+p,&ll,&n))) - break; - - /* valid syntax, but just not a real token? */ - if(er && er!=E_NOKEY) - break; - - // if so, try to understand as label - // it returns the label number in n - if((er=l_def((char*)s+p,&ll,&n,&f))) - break; - - p+=ll; - - while(isspace(s[p])) p++; - - if(s[p]=='=') - { - /*printf("Found = @%s\n",s+p);*/ - t[q++]=T_OP; - t[q++]=n&255; - t[q++]=(n>>8)&255; - t[q++]='='; - p++; - ll=n=0; - break; - } else - if(s[p]==':' && s[p+1]=='=') /* support := label assignments (ca65 compatibility) */ - { - /*printf("Found := @%s\n", s+p);*/ - t[q++]=T_OP; - t[q++]=n&255; - t[q++]=(n>>8)&255; - t[q++]='='; - p+=2; - ll=n=0; - break; - } else - if(f && s[p]!='\0' && s[p+1]=='=') - { - t[q++]=T_OP; - t[q++]=n&255; - t[q++]=(n>>8)&255; - t[q++]=s[p]; - p+=2; - ll=n=0; - break; - } else - if(s[p]==':') /* to support label: ... syntax */ - { - p++; - while(s[p]==' ') p++; - l_set(n,pc,segment); /* set as address value */ - t[q++]=T_DEFINE; - t[q++]=n&255; - t[q++]=(n>>8)&255; - n=0; - - } else { /* label ... syntax */ - l_set(n,pc,segment); /* set as address value */ - t[q++]=T_DEFINE; - t[q++]=n&255; - t[q++]=(n>>8)&255; - n=0; - } - - } - - if(n != Kmvn && n != Kmvp && ((n & 0xff) <=Lastbef)) { - mk=1; /* = only 1 comma ok for normal opcodes */ - } - } - - if(s[p]=='\0' || s[p]==';') - { - er=E_NOLINE; - ll=0; - } else - if(!er) - { - - p+=ll; - if(ll) { - t[q++]= n & 0xff; -/* - if( (n&0xff) == Kmacro) { - t[q++]= (n >> 8) & 0xff; - } -*/ - } - - operand=1; - - // skip whitespace - while(isspace(s[p])) { - p++; - } - - if(s[p]=='#') - { - mk=0; - t[q++]=s[p++]; - - // skip following whitespace - while(isspace(s[p])) { - p++; - } - } - -/* - * - * operand processing - * byte = length of operand in bytes to be assembled - * - * - */ - - /* this addresses forced high/low/two byte addressing, but only - for the first operand. Further processing is done in a_term() - */ - -/* FIXIT2 */ - - while(s[p]!='\0' && s[p]!=';' && !er) - { - if(fl) - { - // pass through text (e.g. for ",y") - t[q++]=s[p++]; - - } else - { - if(operand) - { - /* are we forcing the operand into a particular - addressing mode? !, @, ` operators - Note these are not available in ca65, but we only - switch off "@" which are used for cheap local labels*/ - if(s[p]=='!' || (s[p]=='@' && !ca65) || s[p]=='`') - { -#ifdef DEBUG_CAST - printf("Setting cast to: %c\n", s[p]); -#endif - t[q++]=T_CAST; - t[q++]=s[p]; - operand= -operand+1; - p++; - } else - if(s[p]=='(' || s[p]=='-' || s[p]=='>' || - s[p]=='<' || s[p]=='[') - { - t[q++]=s[p++]; - operand= -operand+1; /* invert to become reinverted */ - } else - if(s[p]=='*') - { - t[q++]=s[p++]; - } else - /* maybe it's a label - Note that for ca65 cheap local labels, we check for "@" */ - if(isalpha(s[p]) || s[p]=='_' || ((s[p]==':' || s[p]=='@') && ca65)) - { - - int p2 = 0; - if (n == (Klistbytes & 0xff)) { - // check for "unlimited" - // Note: this could be done by a more general "constants" handling, - // where in appropriate places (like the one here), constants are - // replaced by a pointer to a predefined constants info, e.g. using - // a T_CONSTANT. Which would also fix the listing of this constant - // (which is currently listed as "0") - static char *unlimited = "unlimited"; - while (s[p+p2] != 0 && unlimited[p2] != 0 && s[p+p2] == unlimited[p2]) p2++; - } - if (p2 == 9) { // length of "unlimited" - er = E_OK; - // found constant - wval(q, 0, 'd'); - p += p2; - } else { - //m=n; - er=l_search((char*)s+p,&ll,&n,&v,&afl); - - if (er == E_NODEF && undefok) { - lg_toglobal(s+p); - } - - if(!er) - { - if(afl) { - t[q++]=T_POINTER; - t[q++]=afl & 255; - t[q++]=v & 255; - t[q++]=(v>>8) & 255; - t[q++]=n & 255; /* cheap fix for listing */ - t[q++]=(n>>8) & 255; /* why is the label already resolved in t_conv? */ - } else { - t[q++]=T_LABEL; - t[q++]=n & 255; - t[q++]=(n>>8) & 255; - /*wval(q,v, 0);*/ - } - } else - if(er==E_NODEF) - { -#ifdef DEBUG_AM -fprintf(stderr, "could not find %s\n", (char *)s+p); -#endif - t[q++]=T_LABEL; - t[q++]=n & 255; - t[q++]=(n>>8) & 255; -/* - if(afl==SEG_ZEROUNDEF) uz++; -*/ - ud++; // number of undefined labels - er=E_OK; - } - p+=ll; - } - } - else - if(s[p]<='9' && (s[p]>'0' || (s[p] == '0' && !ctypes))) - { - tg_dez(s+p,&ll,&v); - p+=ll; - wval(q,v, 'd'); - } - else - /* handle encodings: hex, binary, octal, quoted strings */ - switch(s[p]) { - case '0': - // only gets here when "ctypes" is set, and starts with 0 - // we here check for the C stype "0xHEX" and "0OCTAL" encodings - if ('x' == tolower(s[p+1])) { - // c-style hex - tg_hex(s+p+2, &ll, &v); - p+=2+ll; - wval(q, v, '$'); - } else - if (isdigit(s[p+1])) { - // c-style octal if digit follows - tg_oct(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '&'); - } else { - // else use decimal (0) - tg_dez(s+p,&ll,&v); - p+=ll; - wval(q,v, 'd'); - } - break; - case '$': - tg_hex(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '$'); - break; - case '%': - tg_bin(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '%'); - break; - case '&': - tg_oct(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '&'); - break; - case '\'': - case '\"': - er=tg_asc(s+p,t+q,&q,&p,na1,na2,n); - break; - case ',': - if(mk) - while(s[p]!='\0' && s[p]!=';') - { - while(s[p]==' ') p++; - *nk+=(s[p]==','); - t[q++]=s[p++]; - } - else - { - *nk+=1; - t[q++]=s[p++]; - } - break; - default : - er=E_SYNTAX; - break; - } - operand= -operand+1; - - } else /* operator */ - { - o=0; - if(s[p]==')' || s[p]==']') - { - t[q++]=s[p++]; - operand =-operand+1; - } else - if(s[p]==',') - { - t[q++]=s[p++]; - if(mk) { - // if only one comma, pass through all following text - esp. ",y" or ",x" etc - fl++; - } - *nk+=1; - } else - switch(s[p]) { - case '+': - o=1; - break; - case '-': - o=2; - break; - case '*': - o=3; - break; - case '/': - o=4; - break; - case '!': - if (s[p+1] == '=') o=12; - break; - case '<': - switch (s[p+1]) { - case '<': - o=6; - break; - case '>': - o=12; - break; - case '=': - o=10; - break; - default : - o=7; - break; - } - break; - case '>': - switch (s[p+1]) { - case '>': - o=5; - break; - case '<': - o=12; - break; - case '=': - o=11; - break; - default: - o=8; - break; - } - break; - case '=': - switch (s[p+1]) { - case '<': - o=10; - break; - case '>': - o=11; - break; - case '=': - o=9; p++; /* hack */ - break; - default: - o=9; - break; - } - break; - case '&': - if (s[p+1]=='&') - o=16; - else - o=13; - break; - case '|': - if (s[p+1]=='|') - o=17; - else - o=15; - break; - case '^': - o=14; - break; - default: - er=E_SYNTAX; - break; - } - if(o) - { - t[q++]=o; - p+=lp[o]; - } - operand= -operand+1; - } - - while(s[p]==' ') p++; - } - } - } -//printf("er=%d, ud=%d\n", er, ud); - if(!er) - { -/* - if(uz==1 && ud==1 && byte!=2) { - byte=1; - } - if(byte == 1) { - t[q++] = T_FBYTE; - } else if(byte == 2) { - t[q++] = T_FADDR; - } -*/ - byte = 0; - if(ud > 0) { - er=E_NODEF; - byte = 1; - } - } - - if (s[p] == ';') { - /* handle comments */ - /* first find out how long */ - int i; - for (i = p+1; s[i] != '\0'; i++); - i = i - p; /* actual length of the comment, including zero-byte terminator */ - /*if (i >= 1) {*/ - /* there actually is a comment */ - t[q++] = T_COMMENT; - t[q++] = i&255; - t[q++] = (i>>8)&255; - memcpy(t+q, s+p+1, i); /* also copy zero terminator, used in listing */ - q += i; - /*}*/ - } - t[q++]=T_END; - /* FIXME: this is an unholy union of two "!" implementations :-( */ - /* FIXME FIXME FIXME ... - if (operand==1) { - t[q++]='\0'; - t[q++]=cast; - } - */ - *l=q; - if(bytep) *bytep=byte; - return(er); -} - -/********************************************************************************************* - * identifies a keyword in s, if it is found, starting with s[0] - * A keyword is either a mnemonic, or a pseudo-opcode - */ -static int t_keyword(signed char *s, int *l, int *n) -{ - int i = 0; // index into keywords - int j = 0; - int hash; - - // keywords either start with a character, a "." or "*" - if(!isalpha(s[0]) && s[0]!='.' && s[0]!='*' ) - return(E_NOKEY); - - // if first char is a character, use it as hash... - if(isalpha(s[0])) - hash=tolower(s[0])-'a'; - else - hash=26; - - - // check for "*=" - if(s[0]=='*') { - j=1; - while(s[j] && isspace(s[j])) j++; - if(s[j]=='=') { - i=Kpcdef; - j++; - } - } - - // no keyword yet found? - if(!i) { - // get sub-table from hash code, and compare with table content - // (temporarily) redefine i as start index in opcode table, and hash as end index - i=ktp[hash]; - hash=ktp[hash+1]; - // check all entries in opcode table from start to end for that hash code - while(i='0') - val=val*8+(s[i++]-'0'); - - *l=i; - *v=val; -} - -static void tg_hex(signed char *s, int *l, int *v) -{ - int i=0,val=0; - - while((s[i]>='0' && s[i]<='9') || (tolower(s[i])<='f' && tolower(s[i])>='a')) - { - val=val*16+(s[i]<='9' ? s[i]-'0' : tolower(s[i])-'a'+10); - i++; - } - *l=i; - *v=val; -} - -/* - * tokenize a string - handle two delimiter types, ' and " - */ -static int tg_asc(signed char *s, signed char *t, int *q, int *p, int *na1, int *na2,int n) -{ - - int er=E_OK,i=0,j=0,bs=0; - - signed char delimiter = s[i++]; - -#ifdef DEBUG_AM -fprintf(stderr, "tg_asc token = %i\n", n); -#endif - - t[j++]='"'; /* pass2 token for string */ - j++; /* skip place for length */ - - while(s[i]!='\0' && (bs || s[i]!=delimiter)) - { - - /* implement backslashed quotes for 2.4 */ - if(n != Kbin && s[i] == '\\' && !bs && !xa23) { - bs=1; i++; continue; - } else bs=0; - /* do NOT convert for Kbin or Kaasc, or for initial parse */ - if (!n || n == Kbin || n == Kaasc) { - t[j++]=s[i]; -/* XXX 2.4 implement option for ^ for backwards compatibility */ - } else if(ca65 || !xa23 || s[i]!='^') { /* no escape code "^" - TODO: does ca65 has an escape code */ - t[j++]=convert_char(s[i]); - } else { /* escape code */ - signed char payload = s[i+1]; - switch(payload) { - case '\0': - er=E_SYNTAX; - break; - case '\"': - if (payload == delimiter) { - t[j++]=convert_char(payload); - i++; - } else { - er=E_SYNTAX; - } - break; - case '\'': - if (payload == delimiter) { - t[j++]=convert_char(payload); - i++; - } else { - er=E_SYNTAX; - } - break; - case '^': - t[j++]=convert_char('^'); - i++; - break; - default: - t[j++]=convert_char(payload&0x1f); - i++; - break; - } - } - i++; - } - if(j==3) /* optimize single byte string to value */ - { - t[0]=T_VALUE; - t[1]=t[2]; - t[2]=0; - t[3]=0; - t[4]=delimiter; - j+=2; - } else - { /* handle as string */ - t[1]=j-2; - *na1 +=1; - *na2 +=j-2; - } - if(s[i]==delimiter) { /* in case of no error */ - i++; /* skip ending delimiter */ - } - *q +=j; - *p +=i; - return(er); -} - - diff --git a/xa/src/xat.c.rej b/xa/src/xat.c.rej deleted file mode 100644 index 160d731..0000000 --- a/xa/src/xat.c.rej +++ /dev/null @@ -1,52 +0,0 @@ ---- src/xat.c -+++ src/xat.c -@@ -632,45 +632,45 @@ - dsb_len = 0; - } else - if(n==Ktext) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = relmode ? SEG_TEXT : SEG_ABS; - t[0]=Ksegment; - t[1]=segment; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else - if(n==Kdata) { - if(relmode) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_DATA; - t[0]=Ksegment; - t[1]=SEG_DATA; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kbss) { - if(relmode) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_BSS; - t[0]=Ksegment; - t[1]=SEG_BSS; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kzero) { - if(relmode) { -+ r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_ZERO; - t[0]=Ksegment; - t[1]=SEG_ZERO; - *ll=2; - er=E_OKDEF; -- r_mode(RMODE_RELOC); // use of segments always switches of ABS reloc mode - } else { - er=E_ILLSEGMENT; - }