* Initial support for the z80 CPU
authorpancake@pair
Sat, 04 Feb 2012 03:51:22 +0100
changeset 2007ef840cc3d292
parent 2006 93a31fe3d930
child 2008 8fc36b5c23db
* Initial support for the z80 CPU
- assembler, disassembler and basic code analysis
- code analysis is very primitive atm
libr/anal/p/anal_arm.c
libr/anal/p/anal_z80.c
libr/anal/p/z80.mk
libr/asm/arch/z80/Makefile
libr/asm/arch/z80/disasm.c
libr/asm/arch/z80/test.c
libr/asm/arch/z80/z80.c
libr/asm/arch/z80/z80.h
libr/asm/arch/z80/z80asm.c
libr/asm/arch/z80/z80asm.h
libr/asm/p/asm_z80.c
libr/include/r_anal.h
libr/include/r_types.h
libr/util/str.c
mk/hg-utils.mk
plugins.def.cfg
     1.1 --- a/libr/anal/p/anal_arm.c	Fri Feb 03 20:52:20 2012 +0100
     1.2 +++ b/libr/anal/p/anal_arm.c	Sat Feb 04 03:51:22 2012 +0100
     1.3 @@ -120,8 +120,10 @@
     1.4  	memset (op, '\0', sizeof (RAnalOp));
     1.5  	op->addr = addr;
     1.6  	op->type = R_ANAL_OP_TYPE_UNK;
     1.7 +#if 0
     1.8  	op->jump = op->fail = -1;
     1.9  	op->ref = op->value = -1;
    1.10 +#endif
    1.11  	if (anal->bits==16)
    1.12  		return op_thumb(anal, op, addr, data, len);
    1.13  	op->length = 4;
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/libr/anal/p/anal_z80.c	Sat Feb 04 03:51:22 2012 +0100
     2.3 @@ -0,0 +1,167 @@
     2.4 +/* radare - LGPL - Copyright 2012 - pancake<nopcode.org> */
     2.5 +
     2.6 +#include <string.h>
     2.7 +#include <r_types.h>
     2.8 +#include <r_lib.h>
     2.9 +#include <r_asm.h>
    2.10 +#include <r_anal.h>
    2.11 +// hack
    2.12 +#include "../../asm/arch/z80/z80.c"
    2.13 +
    2.14 +static int z80_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
    2.15 +	char out[32];
    2.16 +	int ilen = z80dis (0, data, out, len);
    2.17 +	memset (op, '\0', sizeof (RAnalOp));
    2.18 +	op->addr = addr;
    2.19 +	op->type = R_ANAL_OP_TYPE_UNK;
    2.20 +	switch (data[0]) {
    2.21 +		case 0x00:
    2.22 +			op->type = R_ANAL_OP_TYPE_NOP;
    2.23 +			break;
    2.24 +		case 0x03:
    2.25 +		case 0x04:
    2.26 +		case 0x0c:
    2.27 +		case 0x13:
    2.28 +		case 0x14:
    2.29 +		case 0x1c:
    2.30 +		case 0x23:
    2.31 +		case 0x24:
    2.32 +		case 0x2c:
    2.33 +		case 0x33:
    2.34 +		case 0x34:
    2.35 +		case 0x3c:
    2.36 +			op->type = R_ANAL_OP_TYPE_ADD; // INC
    2.37 +			break;
    2.38 +		case 0x09:
    2.39 +		case 0x19:
    2.40 +		case 0x29:
    2.41 +		case 0x39:
    2.42 +		case 0x80:
    2.43 +		case 0x81:
    2.44 +		case 0x82:
    2.45 +		case 0x83:
    2.46 +		case 0x84:
    2.47 +		case 0x85:
    2.48 +		case 0x86:
    2.49 +		case 0x87:
    2.50 +		case 0xc6:
    2.51 +			op->type = R_ANAL_OP_TYPE_ADD;
    2.52 +			break;
    2.53 +		case 0x90:
    2.54 +		case 0x91:
    2.55 +		case 0x92:
    2.56 +		case 0x93:
    2.57 +		case 0x94:
    2.58 +		case 0x95:
    2.59 +		case 0x96:
    2.60 +		case 0x97:
    2.61 +		case 0xd6:
    2.62 +			op->type = R_ANAL_OP_TYPE_SUB;
    2.63 +			break;
    2.64 +		case 0xc0:
    2.65 +		case 0xc8:
    2.66 +		case 0xc9:
    2.67 +		case 0xd0:
    2.68 +		case 0xd8:
    2.69 +		case 0xe0:
    2.70 +		case 0xe8:
    2.71 +		case 0xf0:
    2.72 +		case 0xf8:
    2.73 +			op->type = R_ANAL_OP_TYPE_RET;
    2.74 +			break;
    2.75 +		case 0x05:
    2.76 +		case 0x0b:
    2.77 +		case 0x0d:
    2.78 +		case 0x15:
    2.79 +		case 0x1b:
    2.80 +		case 0x1d:
    2.81 +		case 0x25:
    2.82 +		case 0x2b:
    2.83 +		case 0x2d:
    2.84 +		case 0x35:
    2.85 +		case 0x3b:
    2.86 +		case 0x3d:
    2.87 +			// XXXX: DEC
    2.88 +			op->type = R_ANAL_OP_TYPE_SUB;
    2.89 +			break;
    2.90 +		case 0xc5:
    2.91 +		case 0xd5:
    2.92 +		case 0xe5:
    2.93 +		case 0xf5:
    2.94 +			op->type = R_ANAL_OP_TYPE_PUSH;
    2.95 +			break;
    2.96 +		case 0xc1:
    2.97 +		case 0xd1:
    2.98 +		case 0xe1:
    2.99 +		case 0xf1:
   2.100 +			op->type = R_ANAL_OP_TYPE_POP;
   2.101 +			break;
   2.102 +		case 0x40:
   2.103 +		case 0x49:
   2.104 +		case 0x52:
   2.105 +		case 0x5b:
   2.106 +		case 0x64:
   2.107 +		case 0x6d:
   2.108 +		case 0x76:
   2.109 +		case 0x7f:
   2.110 +			op->type = R_ANAL_OP_TYPE_TRAP; // HALT
   2.111 +			break;
   2.112 +		case 0x10:
   2.113 +		case 0x18:
   2.114 +		case 0x20:
   2.115 +		case 0x28:
   2.116 +		case 0x30:
   2.117 +		case 0x38:
   2.118 +		case 0xc2:
   2.119 +		case 0xc3:
   2.120 +		case 0xca:
   2.121 +		case 0xd2:
   2.122 +		case 0xda:
   2.123 +		case 0xe2:
   2.124 +		case 0xe9:
   2.125 +		case 0xea:
   2.126 +		case 0xf2:
   2.127 +		case 0xfa:
   2.128 +			op->type = R_ANAL_OP_TYPE_JMP; // jmpz
   2.129 +			break;
   2.130 +
   2.131 +		case 0xc4:
   2.132 +		case 0xcc:
   2.133 +		case 0xcd:
   2.134 +		case 0xd4:
   2.135 +		case 0xdc:
   2.136 +		case 0xdd:
   2.137 +		case 0xe4:
   2.138 +		case 0xec:
   2.139 +		case 0xed:
   2.140 +		case 0xf4:
   2.141 +		case 0xfc:
   2.142 +		case 0xfd:
   2.143 +			op->type = R_ANAL_OP_TYPE_CALL;
   2.144 +			break;
   2.145 +	}
   2.146 +	return op->length = ilen;
   2.147 +}
   2.148 +
   2.149 +struct r_anal_plugin_t r_anal_plugin_z80 = {
   2.150 +	.name = "z80",
   2.151 +	.arch = R_SYS_ARCH_Z80,
   2.152 +	.bits = 16,
   2.153 +	.desc = "Z80 CPU code analysis plugin",
   2.154 +	.init = NULL,
   2.155 +	.fini = NULL,
   2.156 +	.op = &z80_op,
   2.157 +	.set_reg_profile = NULL,
   2.158 +	.fingerprint_bb = NULL,
   2.159 +	.fingerprint_fcn = NULL,
   2.160 +	.diff_bb = NULL,
   2.161 +	.diff_fcn = NULL,
   2.162 +	.diff_eval = NULL
   2.163 +};
   2.164 +
   2.165 +#ifndef CORELIB
   2.166 +struct r_lib_struct_t radare_plugin = {
   2.167 +	.type = R_LIB_TYPE_ANAL,
   2.168 +	.data = &r_anal_plugin_z80
   2.169 +};
   2.170 +#endif
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/libr/anal/p/z80.mk	Sat Feb 04 03:51:22 2012 +0100
     3.3 @@ -0,0 +1,12 @@
     3.4 +OBJ_Z80=anal_z80.o
     3.5 +
     3.6 +STATIC_OBJ+=${OBJ_Z80}
     3.7 +TARGET_Z80=anal_z80.${EXT_SO}
     3.8 +
     3.9 +ALL_TARGETS+=${TARGET_Z80}
    3.10 +LDFLAGS+=-L../../lib -lr_lib
    3.11 +LDFLAGS+=-L../../syscall -lr_syscall
    3.12 +LDFLAGS+=-L../../diff -lr_diff
    3.13 +
    3.14 +${TARGET_Z80}: ${OBJ_Z80}
    3.15 +	${CC} $(call libname,anal_z80) ${LDFLAGS} ${CFLAGS} -o anal_z80.${EXT_SO} ${OBJ_Z80}
     4.1 --- a/libr/asm/arch/z80/Makefile	Fri Feb 03 20:52:20 2012 +0100
     4.2 +++ b/libr/asm/arch/z80/Makefile	Sat Feb 04 03:51:22 2012 +0100
     4.3 @@ -1,4 +1,4 @@
     4.4  all:
     4.5 -	${CC} -o a -DVERSION=\"0.1\" *.c
     4.6 -	#${CC} -o a -DMAIN_ASM -DVERSION=\"0.1\" *.c
     4.7 +	${CC} -o d -DVERSION=\"0.1\" disasm.c test.c
     4.8 +	${CC} -Wall -g -ggdb -o a -DMAIN_ASM -DVERSION=\"0.1\" z80asm.c
     4.9  	#${CC} -o d -DMAIN_DIS -DVERSION=\"0.1\" *.c
     5.1 --- a/libr/asm/arch/z80/disasm.c	Fri Feb 03 20:52:20 2012 +0100
     5.2 +++ b/libr/asm/arch/z80/disasm.c	Sat Feb 04 03:51:22 2012 +0100
     5.3 @@ -76,6 +76,7 @@
     5.4  #define WORD short
     5.5  #define UWORD unsigned short
     5.6  #define UBYTE unsigned char
     5.7 +#define ut8 unsigned char
     5.8  #define STR char*
     5.9  #define BYTE char
    5.10  #define ULONG unsigned int
    5.11 @@ -85,11 +86,10 @@
    5.12   
    5.13  #define CODESIZE        8192L           // 8K Programmcode
    5.14  #define FUTURA_189      1               // Sprungtabellen-Sprünge für Futura Aquariencomputer ROM V1.89
    5.15 -#define DEBUGGER        0               // wenn 1, dann landet man bei berechneten
    5.16                                          // Sprüngen im Debugger. Siehe auch oben.
    5.17   
    5.18  // Speicher für den Programmcode
    5.19 -static UBYTE       *Opcodes; //[CODESIZE];
    5.20 +//static UBYTE       *Opcodes; //[CODESIZE];
    5.21   
    5.22  // Flag pro Speicherstelle, ob Opcode, Operand, Daten
    5.23  // Bit 4 = 1, d.h. hier wird per JR o.ä. hingesprungen.
    5.24 @@ -99,12 +99,10 @@
    5.25      Data
    5.26  } DataType;
    5.27   
    5.28 -UBYTE       OpcodesFlags[CODESIZE];
    5.29   
    5.30  // Länge eines Opcodes in Bytes ermitteln
    5.31 -UBYTE       OpcodeLen(ULONG p)
    5.32 -{
    5.33 -UBYTE   len = 1;
    5.34 +UBYTE OpcodeLen(ULONG p, const ut8 *Opcodes) {
    5.35 +	UBYTE   len = 1;
    5.36   
    5.37      switch(Opcodes[p]) {// Opcode
    5.38      case 0x06:          // LD B,n
    5.39 @@ -253,30 +251,18 @@
    5.40      return(len);
    5.41  }
    5.42   
    5.43 -void ParseOpcodes(ULONG adr) {
    5.44 -	WORD    i,len;
    5.45 +ULONG ParseOpcodes(ULONG adr, ut8 *Opcodes, int len) {
    5.46 +	int i;
    5.47  	ULONG   next;
    5.48  	Boolean label = R_TRUE;
    5.49   
    5.50 -    do {
    5.51 -        if(label)                       // ein Label setzen?
    5.52 -            OpcodesFlags[adr] |= 0x10;  // Label setzen
    5.53 -        if((OpcodesFlags[adr] & 0x0F) == Opcode) break; // Schleife erkannt!
    5.54 -        if((OpcodesFlags[adr] & 0x0F) == Operand) {
    5.55 -            fprintf (stderr, "Illegaler Sprung?!?");
    5.56 -            return;
    5.57 -        }
    5.58 -        len = OpcodeLen(adr);           // Länge vom Opcode ermitteln
    5.59 -        for(i=0;i<len;i++)
    5.60 -            OpcodesFlags[adr+i] = Operand;  // Opcode eintragen
    5.61 -        OpcodesFlags[adr] = Opcode;     // Start des Opcodes markieren
    5.62 -        if(label) {                     // ein Label setzen?
    5.63 -            OpcodesFlags[adr] |= 0x10;  // Label setzen
    5.64 -            label = R_FALSE;              // Label-Flag zurücksetzen
    5.65 -        }
    5.66 +        i = OpcodeLen (adr, Opcodes);           // Länge vom Opcode ermitteln
    5.67 +	if (len<i)
    5.68 +		return 0; // not enought bytes
    5.69 +	len = i;
    5.70 +        next = adr + len;               // Ptr auf den Folgeopcode
    5.71   
    5.72 -        next = adr + len;               // Ptr auf den Folgeopcode
    5.73 -        switch(Opcodes[adr]) {          // Opcode holen
    5.74 +        switch (Opcodes[adr]) {
    5.75          case 0xCA:      // JP c,????
    5.76          case 0xC2:
    5.77          case 0xDA:
    5.78 @@ -285,13 +271,13 @@
    5.79          case 0xE2:
    5.80          case 0xFA:
    5.81          case 0xF2:
    5.82 -                ParseOpcodes((Opcodes[adr+2]<<8) + Opcodes[adr+1]);
    5.83 +                ParseOpcodes((Opcodes[adr+2]<<8) + Opcodes[adr+1], Opcodes, len);
    5.84                  break;
    5.85          case 0x28:      // JR c,??
    5.86          case 0x20:
    5.87          case 0x38:
    5.88          case 0x30:
    5.89 -                ParseOpcodes(adr + 2 + (BYTE)Opcodes[adr+1]);
    5.90 +                ParseOpcodes(adr + 2 + (BYTE)Opcodes[adr+1], Opcodes, len);
    5.91                  break;
    5.92          case 0xCC:      // CALL c,????
    5.93          case 0xC4:
    5.94 @@ -301,7 +287,7 @@
    5.95          case 0xE4:
    5.96          case 0xFC:
    5.97          case 0xF4:
    5.98 -                ParseOpcodes((Opcodes[adr+2]<<8) + Opcodes[adr+1]);
    5.99 +                ParseOpcodes ((Opcodes[adr+2]<<8) + Opcodes[adr+1], Opcodes, len);
   5.100                  break;
   5.101          case 0xC8:      // RET c
   5.102          case 0xC0:
   5.103 @@ -320,10 +306,10 @@
   5.104          case 0xEF:      // RST 28
   5.105          case 0xF7:      // RST 30
   5.106          case 0xFF:      // RST 38
   5.107 -                ParseOpcodes(Opcodes[adr] & 0x38);
   5.108 +                ParseOpcodes (Opcodes[adr] & 0x38, Opcodes, len);
   5.109                  break;
   5.110          case 0x10:      // DJNZ ??
   5.111 -                ParseOpcodes(adr + 2 + (BYTE)Opcodes[adr+1]);
   5.112 +                ParseOpcodes(adr + 2 + (BYTE)Opcodes[adr+1], Opcodes, len);
   5.113                  break;
   5.114          case 0xC3:      // JP ????
   5.115                  next = (Opcodes[adr+2]<<8) + Opcodes[adr+1];
   5.116 @@ -334,605 +320,602 @@
   5.117                  label = R_TRUE;
   5.118                  break;
   5.119          case 0xCD:      // CALL ????
   5.120 -                ParseOpcodes((Opcodes[adr+2]<<8) + Opcodes[adr+1]);
   5.121 +                ParseOpcodes ((Opcodes[adr+2]<<8) + Opcodes[adr+1], Opcodes, len);
   5.122                  break;
   5.123          case 0xC9:      // RET
   5.124 -                return;
   5.125 +                return 1;
   5.126          case 0xE9:
   5.127 -#if DEBUGGER
   5.128 -                DebugStr("\pJP (HL) gefunden"); // JP (HL)
   5.129 -#endif
   5.130                  break;
   5.131          case 0xDD:
   5.132 -#if DEBUGGER
   5.133                  if(Opcodes[adr+1] == 0xE9) {    // JP (IX)
   5.134 -                    DebugStr("\pJP (IX) gefunden");
   5.135 +                    printf ("\tJP (IX) gefunden");
   5.136                  }
   5.137 -#endif
   5.138                  break;
   5.139          case 0xFD:
   5.140 -#if DEBUGGER
   5.141 -                if(Opcodes[adr+1] == 0xE9) {    // JP (IY)
   5.142 -                    DebugStr("\pJP (IY) gefunden");
   5.143 +                if (Opcodes[adr+1] == 0xE9) {    // JP (IY)
   5.144 +                    printf ("\tJP (IY) gefunden");
   5.145                  }
   5.146 -#endif
   5.147                  break;
   5.148          case 0xED:
   5.149 -                if(Opcodes[adr+1] == 0x4D) {    // RTI
   5.150 -                    return;
   5.151 -                } else if(Opcodes[adr+1] == 0x45) { // RETN
   5.152 -                    return;
   5.153 -                }
   5.154 +		if (Opcodes[adr+1] == 0x4D) {    // RTI
   5.155 +			return 2;
   5.156 +		} else if (Opcodes[adr+1] == 0x45) { // RETN
   5.157 +			return 2;
   5.158 +		}
   5.159                  break;
   5.160          }
   5.161 -        adr = next;
   5.162 -    } while(1);
   5.163 +	return next;
   5.164  }
   5.165   
   5.166  // Disassemblieren
   5.167 -void Disassemble(const UBYTE *code, STR s)
   5.168 -{
   5.169 -Opcodes = code;
   5.170 -UWORD adr = 0;
   5.171 -UBYTE           a = Opcodes[adr];
   5.172 -UBYTE           d = (a >> 3) & 7;
   5.173 -UBYTE           e = a & 7;
   5.174 -static STR      reg[8] = {"B","C","D","E","H","L","(HL)","A"};
   5.175 -static STR      dreg[4] = {"BC","DE","HL","SP"};
   5.176 -static STR      cond[8] = {"NZ","Z","NC","C","PO","PE","P","M"};
   5.177 -static STR      arith[8] = {"ADD\t\tA,","ADC\t\tA,","SUB\t\t","SBC\t\tA,","AND\t\t","XOR\t\t","OR\t\t","CP\t\t"};
   5.178 -CHAR            stemp[80];      // temp.String für sprintf()
   5.179 -CHAR            ireg[3];        // temp.Indexregister
   5.180 +int Disassemble(UWORD adr, const unsigned char *Opcodes, STR s, int olen) {
   5.181 +	UBYTE           a = Opcodes[0];
   5.182 +	UBYTE           d = (a >> 3) & 7;
   5.183 +	UBYTE           e = a & 7;
   5.184 +	static STR reg[8] = {"b","c","d","e","h","l","(hl)","a"};
   5.185 +	static STR dreg[4] = {"bc","de","hl","sp"};
   5.186 +	static STR cond[8] = {"nz","z","nc","c","po","pe","p","m"};
   5.187 +	static STR arith[8] = {"add a,","adc a,","sub ","sbc a,","and ","xor ","or ","cp "};
   5.188 +	char stemp[80];      // temp.String für sprintf()
   5.189 +	char ireg[3];        // temp.Indexregister
   5.190 +	int len = OpcodeLen (0, Opcodes);
   5.191   
   5.192 -    switch(a & 0xC0) {
   5.193 -    case 0x00:
   5.194 -        switch(e) {
   5.195 -        case 0x00:
   5.196 -            switch(d) {
   5.197 -            case 0x00:
   5.198 -                strcpy(s,"NOP");
   5.199 -                break;
   5.200 -            case 0x01:
   5.201 -                strcpy(s,"EX\t\tAF,AF'");
   5.202 -                break;
   5.203 -            case 0x02:
   5.204 -                strcpy(s,"DJNZ\t");
   5.205 -                sprintf(stemp,"%4.4Xh",adr+2+(BYTE)Opcodes[adr+1]);strcat(s,stemp);
   5.206 -                break;
   5.207 -            case 0x03:
   5.208 -                strcpy(s,"JR\t\t");
   5.209 -                sprintf(stemp,"%4.4Xh",adr+2+(BYTE)Opcodes[adr+1]);strcat(s,stemp);
   5.210 -                break;
   5.211 -            default:
   5.212 -                strcpy(s,"JR\t\t");
   5.213 -                strcat(s,cond[d & 3]);
   5.214 -                strcat(s,",");
   5.215 -                sprintf(stemp,"%4.4Xh",adr+2+(BYTE)Opcodes[adr+1]);strcat(s,stemp);
   5.216 -                break;
   5.217 -            }
   5.218 -            break;
   5.219 -        case 0x01:
   5.220 -            if(a & 0x08) {
   5.221 -                strcpy(s,"ADD\t\tHL,");
   5.222 -                strcat(s,dreg[d >> 1]);
   5.223 -            } else {
   5.224 -                strcpy(s,"LD\t\t");
   5.225 -                strcat(s,dreg[d >> 1]);
   5.226 -                strcat(s,",");
   5.227 -                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.228 -            }
   5.229 -            break;
   5.230 -        case 0x02:
   5.231 -            switch(d) {
   5.232 -            case 0x00:
   5.233 -                strcpy(s,"LD\t\t(BC),A");
   5.234 -                break;
   5.235 -            case 0x01:
   5.236 -                strcpy(s,"LD\tA,(BC)");
   5.237 -                break;
   5.238 -            case 0x02:
   5.239 -                strcpy(s,"LD\t\t(DE),A");
   5.240 -                break;
   5.241 -            case 0x03:
   5.242 -                strcpy(s,"LD\t\tA,(DE)");
   5.243 -                break;
   5.244 -            case 0x04:
   5.245 -                strcpy(s,"LD\t\t(");
   5.246 -                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.247 -                strcat(s,"),HL");
   5.248 -                break;
   5.249 -            case 0x05:
   5.250 -                strcpy(s,"LD\t\tHL,(");
   5.251 -                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.252 -                strcat(s,")");
   5.253 -                break;
   5.254 -            case 0x06:
   5.255 -                strcpy(s,"LD\t\t(");
   5.256 -                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.257 -                strcat(s,"),A");
   5.258 -                break;
   5.259 -            case 0x07:
   5.260 -                strcpy(s,"LD\t\tA,(");
   5.261 -                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.262 -                strcat(s,")");
   5.263 -                break;
   5.264 -            }
   5.265 -            break;
   5.266 -        case 0x03:
   5.267 -            if(a & 0x08)
   5.268 -                strcpy(s,"DEC\t\t");
   5.269 -            else
   5.270 -                strcpy(s,"INC\t\t");
   5.271 -            strcat(s,dreg[d >> 1]);
   5.272 -            break;
   5.273 -        case 0x04:
   5.274 -            strcpy(s,"INC\t\t");
   5.275 -            strcat(s,reg[d]);
   5.276 -            break;
   5.277 -        case 0x05:
   5.278 -            strcpy(s,"DEC\t\t");
   5.279 -            strcat(s,reg[d]);
   5.280 -            break;
   5.281 -        case 0x06:              // LD   d,n
   5.282 -            strcpy(s,"LD\t\t");
   5.283 -            strcat(s,reg[d]);
   5.284 -            strcat(s,",");
   5.285 -            sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.286 -            break;
   5.287 -        case 0x07:
   5.288 -            {
   5.289 -            static STR str[8] = {"RLCA","RRCA","RLA","RRA","DAA","CPL","SCF","CCF"};
   5.290 -            strcpy(s,str[d]);
   5.291 -            }
   5.292 -            break;
   5.293 -        }
   5.294 -        break;
   5.295 -    case 0x40:                          // LD   d,s
   5.296 -        if(d == e) {
   5.297 -            strcpy(s,"HALT");
   5.298 -        } else {
   5.299 -            strcpy(s,"LD\t\t");
   5.300 -            strcat(s,reg[d]);
   5.301 -            strcat(s,",");
   5.302 -            strcat(s,reg[e]);
   5.303 -        }
   5.304 -        break;
   5.305 -    case 0x80:
   5.306 -        strcpy(s,arith[d]);
   5.307 -        strcat(s,reg[e]);
   5.308 -        break;
   5.309 -    case 0xC0:
   5.310 -        switch(e) {
   5.311 -        case 0x00:
   5.312 -            strcpy(s,"RET\t\t");
   5.313 -            strcat(s,cond[d]);
   5.314 -            break;
   5.315 -        case 0x01:
   5.316 -            if(d & 1) {
   5.317 -                switch(d >> 1) {
   5.318 -                case 0x00:
   5.319 -                    strcpy(s,"RET");
   5.320 -                    break;
   5.321 -                case 0x01:
   5.322 -                    strcpy(s,"EXX");
   5.323 -                    break;
   5.324 -                case 0x02:
   5.325 -                    strcpy(s,"JP\t\t(HL)");
   5.326 -                    break;
   5.327 -                case 0x03:
   5.328 -                    strcpy(s,"LD\t\tSP,HL");
   5.329 -                    break;
   5.330 -                }
   5.331 -            } else {
   5.332 -                strcpy(s,"POP\t\t");
   5.333 -                if((d >> 1)==3)
   5.334 -                    strcat(s,"AF");
   5.335 -                else
   5.336 -                    strcat(s,dreg[d >> 1]);
   5.337 -            }
   5.338 -            break;
   5.339 -        case 0x02:
   5.340 -            strcpy(s,"JP\t\t");
   5.341 -            strcat(s,cond[d]);
   5.342 -            strcat(s,",");
   5.343 -            sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.344 -            break;
   5.345 -        case 0x03:
   5.346 -            switch(d) {
   5.347 -            case 0x00:
   5.348 -                strcpy(s,"JP\t\t");
   5.349 -                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.350 -                break;
   5.351 -            case 0x01:                  // 0xCB
   5.352 -                a = Opcodes[++adr];     // Erweiterungsopcode holen
   5.353 -                d = (a >> 3) & 7;
   5.354 -                e = a & 7;
   5.355 -                stemp[1] = 0;           // temp.String = 1 Zeichen
   5.356 -                switch(a & 0xC0) {
   5.357 -                case 0x00:
   5.358 -                    {
   5.359 -                    static STR str[8] = {"RLC","RRC","RL","RR","SLA","SRA","???","SRL"};
   5.360 -                    strcpy(s,str[d]);
   5.361 -                    }
   5.362 -                    strcat(s,"\t\t");
   5.363 -                    strcat(s,reg[e]);
   5.364 -                    break;
   5.365 -                case 0x40:
   5.366 -                    strcpy(s,"BIT\t\t");
   5.367 -                    stemp[0] = d+'0';strcat(s,stemp);
   5.368 -                    strcat(s,",");
   5.369 -                    strcat(s,reg[e]);
   5.370 -                    break;
   5.371 -                case 0x80:
   5.372 -                    strcpy(s,"RES\t\t");
   5.373 -                    stemp[0] = d+'0';strcat(s,stemp);
   5.374 -                    strcat(s,",");
   5.375 -                    strcat(s,reg[e]);
   5.376 -                    break;
   5.377 -                case 0xC0:
   5.378 -                    strcpy(s,"SET\t\t");
   5.379 -                    stemp[0] = d+'0';strcat(s,stemp);
   5.380 -                    strcat(s,",");
   5.381 -                    strcat(s,reg[e]);
   5.382 -                    break;
   5.383 -                }
   5.384 -                break;
   5.385 -            case 0x02:
   5.386 -                strcpy(s,"OUT\t\t(");
   5.387 -                sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.388 -                strcat(s,"),A");
   5.389 -                break;
   5.390 -            case 0x03:
   5.391 -                strcpy(s,"IN\t\tA,(");
   5.392 -                sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.393 -                strcat(s,")");
   5.394 -                break;
   5.395 -            case 0x04:
   5.396 -                strcpy(s,"EX\t\t(SP),HL");
   5.397 -                break;
   5.398 -            case 0x05:
   5.399 -                strcpy(s,"EX\t\tDE,HL");
   5.400 -                break;
   5.401 -            case 0x06:
   5.402 -                strcpy(s,"DI");
   5.403 -                break;
   5.404 -            case 0x07:
   5.405 -                strcpy(s,"EI");
   5.406 -                break;
   5.407 -            }
   5.408 -            break;
   5.409 -        case 0x04:
   5.410 -            strcpy(s,"CALL\t");
   5.411 -            strcat(s,cond[d]);
   5.412 -            strcat(s,",");
   5.413 -            sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.414 -            break;
   5.415 -        case 0x05:
   5.416 -            if(d & 1) {
   5.417 -                switch(d >> 1) {
   5.418 -                case 0x00:
   5.419 -                    strcpy(s,"CALL\t");
   5.420 -                    sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.421 -                    break;
   5.422 -                case 0x02:              // 0xED
   5.423 -                    a = Opcodes[++adr]; // Erweiterungsopcode holen
   5.424 -                    d = (a >> 3) & 7;
   5.425 -                    e = a & 7;
   5.426 -                    switch(a & 0xC0) {
   5.427 -                    case 0x40:
   5.428 -                        switch(e) {
   5.429 -                        case 0x00:
   5.430 -                            strcpy(s,"IN\t\t");
   5.431 -                            strcat(s,reg[d]);
   5.432 -                            strcat(s,",(C)");
   5.433 -                            break;
   5.434 -                        case 0x01:
   5.435 -                            strcpy(s,"OUT\t\t(C),");
   5.436 -                            strcat(s,reg[d]);
   5.437 -                            break;
   5.438 -                        case 0x02:
   5.439 -                            if(d & 1)
   5.440 -                                strcpy(s,"ADC");
   5.441 -                            else
   5.442 -                                strcpy(s,"SBC");
   5.443 -                            strcat(s,"\t\tHL,");
   5.444 -                            strcat(s,dreg[d >> 1]);
   5.445 -                            break;
   5.446 -                        case 0x03:
   5.447 -                            if(d & 1) {
   5.448 -                                strcpy(s,"LD\t\t");
   5.449 -                                strcat(s,dreg[d >> 1]);
   5.450 -                                strcat(s,",(");
   5.451 -                                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.452 -                                strcat(s,")");
   5.453 -                            } else {
   5.454 -                                strcpy(s,"LD\t\t(");
   5.455 -                                sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.456 -                                strcat(s,"),");
   5.457 -                                strcat(s,dreg[d >> 1]);
   5.458 -                            }
   5.459 -                            break;
   5.460 -                        case 0x04:
   5.461 -                            {
   5.462 -                            static STR str[8] = {"NEG","???","???","???","???","???","???","???"};
   5.463 -                            strcpy(s,str[d]);
   5.464 -                            }
   5.465 -                            break;
   5.466 -                        case 0x05:
   5.467 -                            {
   5.468 -                            static STR str[8] = {"RETN","RETI","???","???","???","???","???","???"};
   5.469 -                            strcpy(s,str[d]);
   5.470 -                            }
   5.471 -                            break;
   5.472 -                        case 0x06:
   5.473 -                            strcpy(s,"IM\t\t");
   5.474 -                            stemp[0] = d + '0' - 1; stemp[1] = 0;
   5.475 -                            strcat(s,stemp);
   5.476 -                            break;
   5.477 -                        case 0x07:
   5.478 -                            {
   5.479 -                            static STR str[8] = {"LD\t\tI,A","???","LD\t\tA,I","???","RRD","RLD","???","???"};
   5.480 -                            strcpy(s,str[d]);
   5.481 -                            }
   5.482 -                            break;
   5.483 -                        }
   5.484 -                        break;
   5.485 -                    case 0x80:
   5.486 -                        {
   5.487 -                        static STR str[32] = {"LDI","CPI","INI","OUTI","???","???","???","???",
   5.488 -                                              "LDD","CPD","IND","OUTD","???","???","???","???",
   5.489 -                                              "LDIR","CPIR","INIR","OTIR","???","???","???","???",
   5.490 -                                              "LDDR","CPDR","INDR","OTDR","???","???","???","???"};
   5.491 -                        strcpy(s,str[a & 0x1F]);
   5.492 -                        }
   5.493 -                        break;
   5.494 -                    }
   5.495 -                    break;
   5.496 -                default:                // 0x01 (0xDD) = IX, 0x03 (0xFD) = IY
   5.497 -                    strcpy(ireg,(a & 0x20)?"IY":"IX");
   5.498 -                    a = Opcodes[++adr]; // Erweiterungsopcode holen
   5.499 -                    switch(a) {
   5.500 -                    case 0x09:
   5.501 -                        strcpy(s,"ADD\t\t");
   5.502 -                        strcat(s,ireg);
   5.503 -                        strcat(s,",BC");
   5.504 -                        break;
   5.505 -                    case 0x19:
   5.506 -                        strcpy(s,"ADD\t\t");
   5.507 -                        strcat(s,ireg);
   5.508 -                        strcat(s,",DE");
   5.509 -                        break;
   5.510 -                    case 0x21:
   5.511 -                        strcpy(s,"LD\t\t");
   5.512 -                        strcat(s,ireg);
   5.513 -                        strcat(s,",");
   5.514 -                        sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.515 -                        break;
   5.516 -                    case 0x22:
   5.517 -                        strcpy(s,"LD\t\t(");
   5.518 -                        sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.519 -                        strcat(s,"),");
   5.520 -                        strcat(s,ireg);
   5.521 -                        break;
   5.522 -                    case 0x23:
   5.523 -                        strcpy(s,"INC\t\t");
   5.524 -                        strcat(s,ireg);
   5.525 -                        break;
   5.526 -                    case 0x29:
   5.527 -                        strcpy(s,"ADD\t\t");
   5.528 -                        strcat(s,ireg);
   5.529 -                        strcat(s,",");
   5.530 -                        strcat(s,ireg);
   5.531 -                        break;
   5.532 -                    case 0x2A:
   5.533 -                        strcpy(s,"LD\t\t");
   5.534 -                        strcat(s,ireg);
   5.535 -                        strcat(s,",(");
   5.536 -                        sprintf(stemp,"%4.4Xh",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.537 -                        strcat(s,")");
   5.538 -                        break;
   5.539 -                    case 0x2B:
   5.540 -                        strcpy(s,"DEC\t\t");
   5.541 -                        strcat(s,ireg);
   5.542 -                        break;
   5.543 -                    case 0x34:
   5.544 -                        strcpy(s,"INC\t\t(");
   5.545 -                        strcat(s,ireg);
   5.546 -                        strcat(s,"+");
   5.547 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.548 -                        strcat(s,")");
   5.549 -                        break;
   5.550 -                    case 0x35:
   5.551 -                        strcpy(s,"DEC\t\t(");
   5.552 -                        strcat(s,ireg);
   5.553 -                        strcat(s,"+");
   5.554 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.555 -                        strcat(s,")");
   5.556 -                        break;
   5.557 -                    case 0x36:
   5.558 -                        strcpy(s,"LD\t\t(");
   5.559 -                        strcat(s,ireg);
   5.560 -                        strcat(s,"+");
   5.561 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.562 -                        strcat(s,"),");
   5.563 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+2]);strcat(s,stemp);
   5.564 -                        break;
   5.565 -                    case 0x39:
   5.566 -                        strcpy(s,"ADD\t\t");
   5.567 -                        strcat(s,ireg);
   5.568 -                        strcat(s,",SP");
   5.569 -                        break;
   5.570 -                    case 0x46:
   5.571 -                    case 0x4E:
   5.572 -                    case 0x56:
   5.573 -                    case 0x5E:
   5.574 -                    case 0x66:
   5.575 -                    case 0x6E:
   5.576 -                        strcpy(s,"LD\t\t");
   5.577 -                        strcat(s,reg[(a>>3)&7]);
   5.578 -                        strcat(s,",(");
   5.579 -                        strcat(s,ireg);
   5.580 -                        strcat(s,"+");
   5.581 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.582 -                        strcat(s,")");
   5.583 -                        break;
   5.584 -                    case 0x70:
   5.585 -                    case 0x71:
   5.586 -                    case 0x72:
   5.587 -                    case 0x73:
   5.588 -                    case 0x74:
   5.589 -                    case 0x75:
   5.590 -                    case 0x77:
   5.591 -                        strcpy(s,"LD\t\t(");
   5.592 -                        strcat(s,ireg);
   5.593 -                        strcat(s,"+");
   5.594 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.595 -                        strcat(s,"),");
   5.596 -                        strcat(s,reg[a & 7]);
   5.597 -                        break;
   5.598 -                    case 0x7E:
   5.599 -                        strcpy(s,"LD\t\tA,(");
   5.600 -                        strcat(s,ireg);
   5.601 -                        strcat(s,"+");
   5.602 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.603 -                        strcat(s,")");
   5.604 -                        break;
   5.605 -                    case 0x86:
   5.606 -                        strcpy(s,"ADD\t\tA,(");
   5.607 -                        strcat(s,ireg);
   5.608 -                        strcat(s,"+");
   5.609 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.610 -                        strcat(s,")");
   5.611 -                        break;
   5.612 -                    case 0x8E:
   5.613 -                        strcpy(s,"ADC\t\tA,(");
   5.614 -                        strcat(s,ireg);
   5.615 -                        strcat(s,"+");
   5.616 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.617 -                        strcat(s,")");
   5.618 -                        break;
   5.619 -                    case 0x96:
   5.620 -                        strcpy(s,"SUB\t\t(");
   5.621 -                        strcat(s,ireg);
   5.622 -                        strcat(s,"+");
   5.623 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.624 -                        strcat(s,")");
   5.625 -                        break;
   5.626 -                    case 0x9E:
   5.627 -                        strcpy(s,"SBC\t\tA,(");
   5.628 -                        strcat(s,ireg);
   5.629 -                        strcat(s,"+");
   5.630 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.631 -                        strcat(s,")");
   5.632 -                        break;
   5.633 -                    case 0xA6:
   5.634 -                        strcpy(s,"AND\t\tA,(");
   5.635 -                        strcat(s,ireg);
   5.636 -                        strcat(s,"+");
   5.637 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.638 -                        strcat(s,")");
   5.639 -                        break;
   5.640 -                    case 0xAE:
   5.641 -                        strcpy(s,"XOR\t\tA,(");
   5.642 -                        strcat(s,ireg);
   5.643 -                        strcat(s,"+");
   5.644 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.645 -                        strcat(s,")");
   5.646 -                        break;
   5.647 -                    case 0xB6:
   5.648 -                        strcpy(s,"OR\t\tA,(");
   5.649 -                        strcat(s,ireg);
   5.650 -                        strcat(s,"+");
   5.651 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.652 -                        strcat(s,")");
   5.653 -                        break;
   5.654 -                    case 0xBE:
   5.655 -                        strcpy(s,"CP\t\tA,(");
   5.656 -                        strcat(s,ireg);
   5.657 -                        strcat(s,"+");
   5.658 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.659 -                        strcat(s,")");
   5.660 -                        break;
   5.661 -                    case 0xE1:
   5.662 -                        strcpy(s,"POP\t\t");
   5.663 -                        strcat(s,ireg);
   5.664 -                        break;
   5.665 -                    case 0xE3:
   5.666 -                        strcpy(s,"EX\t\t(SP),");
   5.667 -                        strcat(s,ireg);
   5.668 -                        break;
   5.669 -                    case 0xE5:
   5.670 -                        strcpy(s,"PUSH\t");
   5.671 -                        strcat(s,ireg);
   5.672 -                        break;
   5.673 -                    case 0xE9:
   5.674 -                        strcpy(s,"JP\t\t(");
   5.675 -                        strcat(s,ireg);
   5.676 -                        strcat(s,")");
   5.677 -                        break;
   5.678 -                    case 0xF9:
   5.679 -                        strcpy(s,"LD\t\tSP,");
   5.680 -                        strcat(s,ireg);
   5.681 -                        break;
   5.682 -                    case 0xCB:
   5.683 -                        a = Opcodes[adr+2]; // weiteren Unteropcode
   5.684 -                        d = (a >> 3) & 7;
   5.685 -                        stemp[1] = 0;
   5.686 -                        switch(a & 0xC0) {
   5.687 -                        case 0x00:
   5.688 -                            {
   5.689 -                            static STR str[8] = {"RLC","RRC","RL","RR","SLA","SRA","???","SRL"};
   5.690 -                            strcpy(s,str[d]);
   5.691 -                            }
   5.692 -                            strcat(s,"\t\t");
   5.693 -                            break;
   5.694 -                        case 0x40:
   5.695 -                            strcpy(s,"BIT\t\t");
   5.696 -                            stemp[0] = d + '0';
   5.697 -                            strcat(s,stemp);
   5.698 -                            strcat(s,",");
   5.699 -                            break;
   5.700 -                        case 0x80:
   5.701 -                            strcpy(s,"RES\t\t");
   5.702 -                            stemp[0] = d + '0';
   5.703 -                            strcat(s,stemp);
   5.704 -                            strcat(s,",");
   5.705 -                            break;
   5.706 -                        case 0xC0:
   5.707 -                            strcpy(s,"SET\t\t");
   5.708 -                            stemp[0] = d + '0';
   5.709 -                            strcat(s,stemp);
   5.710 -                            strcat(s,",");
   5.711 -                            break;
   5.712 -                        }
   5.713 -                        strcat(s,"(");
   5.714 -                        strcat(s,ireg);
   5.715 -                        strcat(s,"+");
   5.716 -                        sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.717 -                        strcat(s,")");
   5.718 -                        break;
   5.719 -                    }
   5.720 -                    break;
   5.721 -                }
   5.722 -            } else {
   5.723 -                strcpy(s,"PUSH\t");
   5.724 -                if((d >> 1)==3)
   5.725 -                    strcat(s,"AF");
   5.726 -                else
   5.727 -                    strcat(s,dreg[d >> 1]);
   5.728 -            }
   5.729 -            break;
   5.730 -        case 0x06:
   5.731 -            strcpy(s,arith[d]);
   5.732 -            sprintf(stemp,"%2.2Xh",Opcodes[adr+1]);strcat(s,stemp);
   5.733 -            break;
   5.734 -        case 0x07:
   5.735 -            strcpy(s,"RST\t\t");
   5.736 -            sprintf(stemp,"%2.2Xh",a & 0x38);strcat(s,stemp);
   5.737 -            break;
   5.738 -        }
   5.739 -        break;
   5.740 -    }
   5.741 +	switch(a & 0xC0) {
   5.742 +	case 0x00:
   5.743 +		switch(e) {
   5.744 +		case 0x00:
   5.745 +			switch(d) {
   5.746 +			case 0x00:
   5.747 +				strcpy (s,"nop");
   5.748 +				break;
   5.749 +			case 0x01:
   5.750 +				strcpy (s,"ex af, af'");
   5.751 +				break;
   5.752 +			case 0x02:
   5.753 +				strcpy (s,"djnz ");
   5.754 +				sprintf (stemp,"0x%4.4X",adr+2+(BYTE)Opcodes[adr+1]);strcat(s,stemp);
   5.755 +				break;
   5.756 +			case 0x03:
   5.757 +				strcpy(s,"jr ");
   5.758 +				sprintf(stemp,"0x%4.4X",adr+2+(BYTE)Opcodes[adr+1]);strcat(s,stemp);
   5.759 +				break;
   5.760 +			default:
   5.761 +				strcpy(s,"jr ");
   5.762 +				strcat(s,cond[d & 3]);
   5.763 +				strcat(s,", ");
   5.764 +				sprintf(stemp,"0x%4.4X",adr+2+(BYTE)Opcodes[adr+1]);strcat(s,stemp);
   5.765 +				break;
   5.766 +			}
   5.767 +			break;
   5.768 +		case 0x01:
   5.769 +			if (a & 0x08) {
   5.770 +				strcpy(s,"add hl, ");
   5.771 +				strcat(s,dreg[d >> 1]);
   5.772 +			} else {
   5.773 +				strcpy (s,"ld ");
   5.774 +				strcat (s,dreg[d >> 1]);
   5.775 +				strcat (s,", ");
   5.776 +				sprintf (stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.777 +			}
   5.778 +			break;
   5.779 +		case 0x02:
   5.780 +			switch(d) {
   5.781 +				case 0x00:
   5.782 +					strcpy(s,"ld (bc), a");
   5.783 +					break;
   5.784 +				case 0x01:
   5.785 +					strcpy(s,"ld a, (bc)");
   5.786 +					break;
   5.787 +				case 0x02:
   5.788 +					strcpy(s,"ld (de), a");
   5.789 +					break;
   5.790 +				case 0x03:
   5.791 +					strcpy(s,"ld a, (de)");
   5.792 +					break;
   5.793 +				case 0x04:
   5.794 +					strcpy(s,"ld (");
   5.795 +					sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.796 +					strcat(s,"), hl");
   5.797 +					break;
   5.798 +				case 0x05:
   5.799 +					strcpy(s,"ld hl, (");
   5.800 +					sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.801 +					strcat(s,")");
   5.802 +					break;
   5.803 +				case 0x06:
   5.804 +					strcpy(s,"ld (");
   5.805 +					sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.806 +					strcat(s,"), a");
   5.807 +					break;
   5.808 +				case 0x07:
   5.809 +					strcpy(s,"ld a,(");
   5.810 +					sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.811 +					strcat(s,")");
   5.812 +					break;
   5.813 +			}
   5.814 +			break;
   5.815 +		case 0x03:
   5.816 +			if (a & 0x08)
   5.817 +				strcpy (s,"dec ");
   5.818 +			else
   5.819 +				strcpy (s,"inc ");
   5.820 +			strcat (s,dreg[d >> 1]);
   5.821 +			break;
   5.822 +		case 0x04:
   5.823 +			strcpy (s,"inc ");
   5.824 +			strcat (s,reg[d]);
   5.825 +			break;
   5.826 +		case 0x05:
   5.827 +			strcpy (s, "dec ");
   5.828 +			strcat (s, reg[d]);
   5.829 +			break;
   5.830 +		case 0x06:              // LD   d,n
   5.831 +			strcpy(s,"ld ");
   5.832 +			strcat(s,reg[d]);
   5.833 +			strcat(s,", ");
   5.834 +			sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
   5.835 +			break;
   5.836 +		case 0x07:
   5.837 +			{
   5.838 +				static const STR str[8] = {"rlcs", "rrca", "rla", "rra", "daa", "cpl", "scf", "ccf"};
   5.839 +				strcpy (s,str[d]);
   5.840 +			}
   5.841 +			break;
   5.842 +		}
   5.843 +		break;
   5.844 +	case 0x40:                          // LD   d,s
   5.845 +		if(d == e) {
   5.846 +			strcpy(s,"halt");
   5.847 +		} else {
   5.848 +			strcpy(s,"ld ");
   5.849 +			strcat(s,reg[d]);
   5.850 +			strcat(s,", ");
   5.851 +			strcat(s,reg[e]);
   5.852 +		}
   5.853 +		break;
   5.854 +	case 0x80:
   5.855 +		strcpy(s,arith[d]);
   5.856 +		strcat(s,reg[e]);
   5.857 +		break;
   5.858 +	case 0xC0:
   5.859 +		switch (e) {
   5.860 +		case 0x00:
   5.861 +			strcpy(s,"ret ");
   5.862 +			strcat(s,cond[d]);
   5.863 +			break;
   5.864 +		case 0x01:
   5.865 +			if(d & 1) {
   5.866 +				switch(d >> 1) {
   5.867 +					case 0x00:
   5.868 +						strcpy(s,"ret");
   5.869 +						break;
   5.870 +					case 0x01:
   5.871 +						strcpy(s,"exx");
   5.872 +						break;
   5.873 +					case 0x02:
   5.874 +						strcpy(s,"jp (hl)");
   5.875 +						break;
   5.876 +					case 0x03:
   5.877 +						strcpy(s,"ld sp,hl");
   5.878 +						break;
   5.879 +				}
   5.880 +			} else {
   5.881 +				strcpy(s,"pop ");
   5.882 +				if((d >> 1)==3)
   5.883 +					strcat(s,"af");
   5.884 +				else
   5.885 +					strcat(s,dreg[d >> 1]);
   5.886 +			}
   5.887 +			break;
   5.888 +		case 0x02:
   5.889 +			strcpy(s,"jp ");
   5.890 +			strcat(s,cond[d]);
   5.891 +			strcat(s,", ");
   5.892 +			sprintf(stemp, "0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));
   5.893 +			strcat(s,stemp);
   5.894 +			break;
   5.895 +		case 0x03:
   5.896 +			switch(d) {
   5.897 +				case 0x00:
   5.898 +					strcpy (s, "jp ");
   5.899 +					sprintf (stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.900 +					break;
   5.901 +				case 0x01:                  // 0xCB
   5.902 +					a = Opcodes[++adr];     // Erweiterungsopcode holen
   5.903 +					d = (a >> 3) & 7;
   5.904 +					e = a & 7;
   5.905 +					stemp[1] = 0;           // temp.String = 1 Zeichen
   5.906 +					switch(a & 0xC0) {
   5.907 +						case 0x00:
   5.908 +							{
   5.909 +								static STR str[8] = {"rlc","rrc","rl","rr","sla","sra","???","srl"};
   5.910 +								strcpy(s,str[d]);
   5.911 +							}
   5.912 +							strcat(s," ");
   5.913 +							strcat(s,reg[e]);
   5.914 +							break;
   5.915 +						case 0x40:
   5.916 +							strcpy(s,"bit ");
   5.917 +							stemp[0] = d+'0';strcat(s,stemp);
   5.918 +							strcat(s,",");
   5.919 +							strcat(s,reg[e]);
   5.920 +							break;
   5.921 +						case 0x80:
   5.922 +							strcpy(s,"res ");
   5.923 +							stemp[0] = d+'0';strcat(s,stemp);
   5.924 +							strcat(s,",");
   5.925 +							strcat(s,reg[e]);
   5.926 +							break;
   5.927 +						case 0xC0:
   5.928 +							strcpy(s, "set ");
   5.929 +							stemp[0] = d+'0';strcat(s,stemp);
   5.930 +							strcat(s,",");
   5.931 +							strcat(s,reg[e]);
   5.932 +							break;
   5.933 +					}
   5.934 +					break;
   5.935 +				case 0x02:
   5.936 +					strcpy (s,"out (");
   5.937 +					sprintf (stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
   5.938 +					strcat (s,"),A");
   5.939 +					break;
   5.940 +				case 0x03:
   5.941 +					strcpy(s,"in a, (");
   5.942 +					sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
   5.943 +					strcat(s,")");
   5.944 +					break;
   5.945 +				case 0x04:
   5.946 +					strcpy(s,"ex (sp), hl");
   5.947 +					break;
   5.948 +				case 0x05:
   5.949 +					strcpy(s,"ex de, hl");
   5.950 +					break;
   5.951 +				case 0x06:
   5.952 +					strcpy(s,"di");
   5.953 +					break;
   5.954 +				case 0x07:
   5.955 +					strcpy(s,"ei");
   5.956 +					break;
   5.957 +			}
   5.958 +			break;
   5.959 +		case 0x04:
   5.960 +			strcpy(s,"call ");
   5.961 +			strcat(s,cond[d]);
   5.962 +			strcat(s,", ");
   5.963 +			sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.964 +			break;
   5.965 +		case 0x05:
   5.966 +			if(d & 1) {
   5.967 +				switch(d >> 1) {
   5.968 +					case 0x00:
   5.969 +						strcpy(s,"call ");
   5.970 +						sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
   5.971 +						break;
   5.972 +					case 0x02:              // 0xED
   5.973 +						a = Opcodes[++adr]; // Erweiterungsopcode holen
   5.974 +						d = (a >> 3) & 7;
   5.975 +						e = a & 7;
   5.976 +						switch(a & 0xC0) {
   5.977 +							case 0x40:
   5.978 +							switch(e) {
   5.979 +								case 0x00:
   5.980 +									strcpy(s,"in ");
   5.981 +									strcat(s,reg[d]);
   5.982 +									strcat(s,", (c)");
   5.983 +									break;
   5.984 +								case 0x01:
   5.985 +									strcpy(s,"out (c), ");
   5.986 +									strcat(s,reg[d]);
   5.987 +									break;
   5.988 +								case 0x02:
   5.989 +									if(d & 1)
   5.990 +										strcpy(s,"adc");
   5.991 +									else
   5.992 +										strcpy(s,"sbc");
   5.993 +									strcat(s," HL, ");
   5.994 +									strcat(s,dreg[d >> 1]);
   5.995 +									break;
   5.996 +								case 0x03:
   5.997 +									if(d & 1) {
   5.998 +										strcpy(s,"ld ");
   5.999 +										strcat(s,dreg[d >> 1]);
  5.1000 +										strcat(s,",(");
  5.1001 +										sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
  5.1002 +										strcat(s,")");
  5.1003 +									} else {
  5.1004 +										strcpy(s,"ld (");
  5.1005 +										sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
  5.1006 +										strcat(s,"),");
  5.1007 +										strcat(s,dreg[d >> 1]);
  5.1008 +									}
  5.1009 +									break;
  5.1010 +								case 0x04:
  5.1011 +									{
  5.1012 +										static STR str[8] = {"neg","???","???","???","???","???","???","???"};
  5.1013 +										strcpy(s,str[d]);
  5.1014 +									}
  5.1015 +									break;
  5.1016 +								case 0x05:
  5.1017 +									{
  5.1018 +										static STR str[8] = {"retn","reti","???","???","???","???","???","???"};
  5.1019 +										strcpy(s,str[d]);
  5.1020 +									}
  5.1021 +									break;
  5.1022 +								case 0x06:
  5.1023 +									strcpy(s,"IM ");
  5.1024 +									stemp[0] = d + '0' - 1; stemp[1] = 0;
  5.1025 +									strcat(s,stemp);
  5.1026 +									break;
  5.1027 +								case 0x07:
  5.1028 +									{
  5.1029 +										static STR str[8] = {"ld i, a","???","ld a, i","???","rrd","rld","???","???"};
  5.1030 +										strcpy(s,str[d]);
  5.1031 +									}
  5.1032 +									break;
  5.1033 +							}
  5.1034 +							break;
  5.1035 +						case 0x80:
  5.1036 +							{
  5.1037 +								static STR str[32] = {"LDI","CPI","INI","OUTI","???","???","???","???",
  5.1038 +									"ldd","CPD","IND","OUTD","???","???","???","???",
  5.1039 +									"ldir","cpir","INIR","OTIR","???","???","???","???",
  5.1040 +									"lddr","cpdr","INDR","OTDR","???","???","???","???"};
  5.1041 +								strcpy(s,str[a & 0x1F]);
  5.1042 +							}
  5.1043 +							break;
  5.1044 +						}
  5.1045 +						break;
  5.1046 +					default:                // 0x01 (0xDD) = IX, 0x03 (0xFD) = IY
  5.1047 +						strcpy (ireg,(a & 0x20)?"iy":"ix");
  5.1048 +						a = Opcodes[++adr]; // Erweiterungsopcode holen
  5.1049 +						switch(a) {
  5.1050 +							case 0x09:
  5.1051 +								strcpy(s,"add ");
  5.1052 +								strcat(s,ireg);
  5.1053 +								strcat(s,", bc");
  5.1054 +								break;
  5.1055 +							case 0x19:
  5.1056 +								strcpy(s,"add ");
  5.1057 +								strcat(s,ireg);
  5.1058 +								strcat(s,", de");
  5.1059 +								break;
  5.1060 +							case 0x21:
  5.1061 +								strcpy(s,"ld ");
  5.1062 +								strcat(s,ireg);
  5.1063 +								strcat(s,",");
  5.1064 +								sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
  5.1065 +								break;
  5.1066 +							case 0x22:
  5.1067 +								strcpy(s,"ld (");
  5.1068 +								sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
  5.1069 +								strcat(s,"), ");
  5.1070 +								strcat(s,ireg);
  5.1071 +								break;
  5.1072 +							case 0x23:
  5.1073 +								strcpy (s,"inc ");
  5.1074 +								strcat (s, ireg);
  5.1075 +								break;
  5.1076 +							case 0x29:
  5.1077 +								strcpy(s,"add ");
  5.1078 +								strcat(s,ireg);
  5.1079 +								strcat(s,",");
  5.1080 +								strcat(s,ireg);
  5.1081 +								break;
  5.1082 +							case 0x2A:
  5.1083 +								strcpy(s,"ld ");
  5.1084 +								strcat(s,ireg);
  5.1085 +								strcat(s,", (");
  5.1086 +								sprintf(stemp,"0x%4.4X",Opcodes[adr+1]+(Opcodes[adr+2]<<8));strcat(s,stemp);
  5.1087 +								strcat(s,")");
  5.1088 +								break;
  5.1089 +							case 0x2B:
  5.1090 +								strcpy(s,"dec ");
  5.1091 +								strcat(s,ireg);
  5.1092 +								break;
  5.1093 +							case 0x34:
  5.1094 +								strcpy(s,"inc (");
  5.1095 +								strcat(s,ireg);
  5.1096 +								strcat(s,"+");
  5.1097 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1098 +								strcat(s,")");
  5.1099 +								break;
  5.1100 +							case 0x35:
  5.1101 +								strcpy(s,"dec (");
  5.1102 +								strcat(s,ireg);
  5.1103 +								strcat(s,"+");
  5.1104 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1105 +								strcat(s,")");
  5.1106 +								break;
  5.1107 +							case 0x36:
  5.1108 +								strcpy(s,"ld (");
  5.1109 +								strcat(s,ireg);
  5.1110 +								strcat(s,"+");
  5.1111 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1112 +								strcat(s,"),");
  5.1113 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+2]);strcat(s,stemp);
  5.1114 +								break;
  5.1115 +							case 0x39:
  5.1116 +								strcpy(s,"add ");
  5.1117 +								strcat(s,ireg);
  5.1118 +								strcat(s,", sp");
  5.1119 +								break;
  5.1120 +							case 0x46:
  5.1121 +							case 0x4E:
  5.1122 +							case 0x56:
  5.1123 +							case 0x5E:
  5.1124 +							case 0x66:
  5.1125 +							case 0x6E:
  5.1126 +								strcpy(s,"ld ");
  5.1127 +								strcat(s,reg[(a>>3)&7]);
  5.1128 +								strcat(s,",(");
  5.1129 +								strcat(s,ireg);
  5.1130 +								strcat(s,"+");
  5.1131 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1132 +								strcat(s,")");
  5.1133 +								break;
  5.1134 +							case 0x70:
  5.1135 +							case 0x71:
  5.1136 +							case 0x72:
  5.1137 +							case 0x73:
  5.1138 +							case 0x74:
  5.1139 +							case 0x75:
  5.1140 +							case 0x77:
  5.1141 +								strcpy(s,"ld (");
  5.1142 +								strcat(s,ireg);
  5.1143 +								strcat(s,"+");
  5.1144 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1145 +								strcat(s,"),");
  5.1146 +								strcat(s,reg[a & 7]);
  5.1147 +								break;
  5.1148 +							case 0x7E:
  5.1149 +								strcpy(s,"ld A,(");
  5.1150 +								strcat(s,ireg);
  5.1151 +								strcat(s,"+");
  5.1152 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1153 +								strcat(s,")");
  5.1154 +								break;
  5.1155 +							case 0x86:
  5.1156 +								strcpy(s,"add A, (");
  5.1157 +								strcat(s,ireg);
  5.1158 +								strcat(s,"+");
  5.1159 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1160 +								strcat(s,")");
  5.1161 +								break;
  5.1162 +							case 0x8E:
  5.1163 +								strcpy(s,"adc a,(");
  5.1164 +								strcat(s,ireg);
  5.1165 +								strcat(s,"+");
  5.1166 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1167 +								strcat(s,")");
  5.1168 +								break;
  5.1169 +							case 0x96:
  5.1170 +								strcpy(s,"sub (");
  5.1171 +								strcat(s,ireg);
  5.1172 +								strcat(s,"+");
  5.1173 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1174 +								strcat(s,")");
  5.1175 +								break;
  5.1176 +							case 0x9E:
  5.1177 +								strcpy(s,"sbc a, (");
  5.1178 +								strcat(s,ireg);
  5.1179 +								strcat(s,"+");
  5.1180 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1181 +								strcat(s,")");
  5.1182 +								break;
  5.1183 +							case 0xA6:
  5.1184 +								strcpy(s,"and a,(");
  5.1185 +								strcat(s,ireg);
  5.1186 +								strcat(s,"+");
  5.1187 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1188 +								strcat(s,")");
  5.1189 +								break;
  5.1190 +							case 0xAE:
  5.1191 +								strcpy(s,"xor a, (");
  5.1192 +								strcat(s,ireg);
  5.1193 +								strcat(s,"+");
  5.1194 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1195 +								strcat(s,")");
  5.1196 +								break;
  5.1197 +							case 0xB6:
  5.1198 +								strcpy(s,"or a,(");
  5.1199 +								strcat(s,ireg);
  5.1200 +								strcat(s,"+");
  5.1201 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1202 +								strcat(s,")");
  5.1203 +								break;
  5.1204 +							case 0xBE:
  5.1205 +								strcpy(s,"cp a,(");
  5.1206 +								strcat(s,ireg);
  5.1207 +								strcat(s,"+");
  5.1208 +								sprintf(stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1209 +								strcat(s,")");
  5.1210 +								break;
  5.1211 +							case 0xE1:
  5.1212 +								strcpy(s,"pop ");
  5.1213 +								strcat(s,ireg);
  5.1214 +								break;
  5.1215 +							case 0xE3:
  5.1216 +								strcpy(s,"ex (sp), ");
  5.1217 +								strcat(s,ireg);
  5.1218 +								break;
  5.1219 +							case 0xE5:
  5.1220 +								strcpy(s,"push ");
  5.1221 +								strcat(s,ireg);
  5.1222 +								break;
  5.1223 +							case 0xE9:
  5.1224 +								strcpy(s,"jp (");
  5.1225 +								strcat(s,ireg);
  5.1226 +								strcat(s,")");
  5.1227 +								break;
  5.1228 +							case 0xF9:
  5.1229 +								strcpy(s,"ld sp, ");
  5.1230 +								strcat(s,ireg);
  5.1231 +								break;
  5.1232 +							case 0xCB:
  5.1233 +								a = Opcodes[adr+2]; // weiteren Unteropcode
  5.1234 +								d = (a >> 3) & 7;
  5.1235 +								stemp[1] = 0;
  5.1236 +								switch(a & 0xC0) {
  5.1237 +									case 0x00:
  5.1238 +										{
  5.1239 +											static STR str[8] = {"rlc", "rrc", "rl", "rr", "sla", "sra", "???", "srl" };
  5.1240 +											strcpy(s,str[d]);
  5.1241 +										}
  5.1242 +										strcat(s," ");
  5.1243 +										break;
  5.1244 +									case 0x40:
  5.1245 +										strcpy(s,"bit ");
  5.1246 +										stemp[0] = d + '0';
  5.1247 +										strcat(s,stemp);
  5.1248 +										strcat(s,",");
  5.1249 +										break;
  5.1250 +									case 0x80:
  5.1251 +										strcpy(s,"res ");
  5.1252 +										stemp[0] = d + '0';
  5.1253 +										strcat(s,stemp);
  5.1254 +										strcat(s,",");
  5.1255 +										break;
  5.1256 +									case 0xC0:
  5.1257 +										strcpy(s,"set ");
  5.1258 +										stemp[0] = d + '0';
  5.1259 +										strcat(s,stemp);
  5.1260 +										strcat(s,",");
  5.1261 +										break;
  5.1262 +								}
  5.1263 +								strcat(s,"(");
  5.1264 +								strcat(s,ireg);
  5.1265 +								strcat(s,"+");
  5.1266 +								sprintf(stemp, "0x%2.2X",Opcodes[adr+1]);
  5.1267 +								strcat(s,stemp);
  5.1268 +								strcat(s,")");
  5.1269 +								break;
  5.1270 +						}
  5.1271 +						break;
  5.1272 +				}
  5.1273 +			} else {
  5.1274 +				strcpy (s,"push ");
  5.1275 +				if((d >> 1)==3)
  5.1276 +					strcat (s,"af");
  5.1277 +				else
  5.1278 +					strcat (s,dreg[d >> 1]);
  5.1279 +			}
  5.1280 +			break;
  5.1281 +		case 0x06:
  5.1282 +			strcpy (s,arith[d]);
  5.1283 +			sprintf (stemp,"0x%2.2X",Opcodes[adr+1]);strcat(s,stemp);
  5.1284 +			break;
  5.1285 +		case 0x07:
  5.1286 +			strcpy (s, "rst ");
  5.1287 +			sprintf (stemp,"0x%2.2X",a & 0x38);strcat(s,stemp);
  5.1288 +			break;
  5.1289 +		}
  5.1290 +		break;
  5.1291 +	}
  5.1292 +	return len;
  5.1293 +}
  5.1294 +
  5.1295 +int z80dis (int addr, const unsigned char *buf, char *out, int len) {
  5.1296 +	return Disassemble (addr, buf, out, len);
  5.1297  }
  5.1298   
  5.1299  #if MAIN_DIS
  5.1300 @@ -998,7 +981,7 @@
  5.1301          WORD    len,i;
  5.1302   
  5.1303          if((OpcodesFlags[adr] & 0x0F) == Data) {
  5.1304 -            fprintf(f,"L%4.4X:\tDEFB",(UWORD)adr);
  5.1305 +            fprintf(f,"L%4.4X: DEFB",(UWORD)adr);
  5.1306              for(i=0;i<16;i++) {
  5.1307                  if((OpcodesFlags[adr+i] & 0x0F) != Data) break;
  5.1308                  fprintf(f,"%c%2.2Xh",(i)?',':' ',Opcodes[adr+i]);
  5.1309 @@ -1006,12 +989,12 @@
  5.1310              fprintf(f,"\n");
  5.1311              adr += i;
  5.1312          } else {
  5.1313 -            len = OpcodeLen(adr);           // Länge vom Opcode ermitteln
  5.1314 +            len = OpcodeLen(adr, Opcodes);           // Länge vom Opcode ermitteln
  5.1315  #if 1
  5.1316              if(OpcodesFlags[adr] & 0x10)
  5.1317 -                fprintf(f,"L%4.4X:\t",adr);
  5.1318 +                fprintf(f,"L%4.4X: ",adr);
  5.1319              else
  5.1320 -                fprintf(f,"\t\t");
  5.1321 +                fprintf(f," ");
  5.1322  #else
  5.1323              fprintf(f,"%4.4X: ",(UWORD)adr);
  5.1324              for(i=0;i<len;i++)
     6.1 --- a/libr/asm/arch/z80/test.c	Fri Feb 03 20:52:20 2012 +0100
     6.2 +++ b/libr/asm/arch/z80/test.c	Sat Feb 04 03:51:22 2012 +0100
     6.3 @@ -1,10 +1,13 @@
     6.4 +#include <stdio.h>
     6.5  
     6.6 -main() {
     6.7 -	int i;
     6.8 -	char buf[32], str[1024];
     6.9 +int main() {
    6.10 +	int i, len;
    6.11 +	unsigned char buf[32];
    6.12 +	char str[1024];
    6.13  	for (i=0; i<255; i++) {
    6.14  		buf[0] = i;
    6.15 -		Disassemble (buf, str);
    6.16 -		printf ("%s\n", str);
    6.17 +		len = Disassemble (0, buf, str);
    6.18 +		printf ("%d  %02x%02x%02x --> %s\n", len, buf[0], buf[1], buf[2], str);
    6.19  	}
    6.20 +	return 0;
    6.21  }
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/libr/asm/arch/z80/z80.c	Sat Feb 04 03:51:22 2012 +0100
     7.3 @@ -0,0 +1,2 @@
     7.4 +#include "z80asm.c"
     7.5 +#include "disasm.c"
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/libr/asm/arch/z80/z80.h	Sat Feb 04 03:51:22 2012 +0100
     8.3 @@ -0,0 +1,9 @@
     8.4 +#ifndef _INCLUDE_Z80_H_
     8.5 +#define _INCLUDE_Z80_H_
     8.6 +
     8.7 +#include <r_util.h>
     8.8 +
     8.9 +int z80asm (unsigned char *outbuf, const char *str);
    8.10 +int z80dis (int addr, const unsigned char *buf, int len, char *out);
    8.11 +
    8.12 +#endif
     9.1 --- a/libr/asm/arch/z80/z80asm.c	Fri Feb 03 20:52:20 2012 +0100
     9.2 +++ b/libr/asm/arch/z80/z80asm.c	Sat Feb 04 03:51:22 2012 +0100
     9.3 @@ -1,3 +1,4 @@
     9.4 +/* 2012 - pancake@nopcode.org - radare2 integration */
     9.5  /* Z80 assembler by shevek
     9.6  
     9.7     Copyright (C) 2002-2009 Bas Wijnen <wijnen@debian.org>
     9.8 @@ -21,20 +22,28 @@
     9.9  
    9.10  #include "z80asm.h"
    9.11  
    9.12 +/* hack */
    9.13 +// must remove: equ, include, incbin, macro
    9.14 +static void wrt_ref (int val, int type, int count);
    9.15 +static unsigned char *obuf;
    9.16 +static int obuflen = 0;
    9.17 +#define write_one_byte(x,y) obuf[obuflen++] = x
    9.18 +#define wrtb(x) obuf[obuflen++] = x
    9.19 +
    9.20  /* global variables */
    9.21  /* mnemonics, used as argument to indx() in assemble */
    9.22  const char *mnemonics[] = {
    9.23 -  "call", "cpdr", "cpir", "djnz", "halt", "indr", "inir", "lddr", "ldir",
    9.24 -  "otdr", "otir", "outd", "outi", "push", "reti", "retn", "rlca", "rrca",
    9.25 -  "defb", "defw", "defs", "defm",
    9.26 -  "adc", "add", "and", "bit", "ccf", "cpd", "cpi", "cpl", "daa", "dec", "equ",
    9.27 -  "exx", "inc", "ind", "ini", "ldd", "ldi", "neg", "nop", "out", "pop",
    9.28 -  "res", "ret", "rla", "rlc", "rld", "rra", "rrc", "rrd", "rst", "sbc",
    9.29 -  "scf", "set", "sla", "sll", "sli", "sra", "srl", "sub", "xor", "org",
    9.30 -  "cp", "di", "ei", "ex", "im", "in", "jp", "jr", "ld", "or", "rl", "rr",
    9.31 -  "db", "dw", "ds", "dm",
    9.32 -  "include", "incbin", "if", "else", "endif", "end", "macro", "endm",
    9.33 -  "seek", NULL
    9.34 +	"call", "cpdr", "cpir", "djnz", "halt", "indr", "inir", "lddr", "ldir",
    9.35 +	"otdr", "otir", "outd", "outi", "push", "reti", "retn", "rlca", "rrca",
    9.36 +	"defb", "defw", "defs", "defm",
    9.37 +	"adc", "add", "and", "bit", "ccf", "cpd", "cpi", "cpl", "daa", "dec", "equ",
    9.38 +	"exx", "inc", "ind", "ini", "ldd", "ldi", "neg", "nop", "out", "pop",
    9.39 +	"res", "ret", "rla", "rlc", "rld", "rra", "rrc", "rrd", "rst", "sbc",
    9.40 +	"scf", "set", "sla", "sll", "sli", "sra", "srl", "sub", "xor", "org",
    9.41 +	"cp", "di", "ei", "ex", "im", "in", "jp", "jr", "ld", "or", "rl", "rr",
    9.42 +	"db", "dw", "ds", "dm",
    9.43 +	"include", "incbin", "if", "else", "endif", "end", "macro", "endm",
    9.44 +	"seek", NULL
    9.45  };
    9.46  
    9.47  /* linked lists */
    9.48 @@ -49,887 +58,404 @@
    9.49  const char *realoutputfilename;
    9.50  const char *labelfilename;
    9.51  struct infile *infile;
    9.52 -/* prefix for labels in labelfile */
    9.53 -const char *labelprefix = "";
    9.54  /* bools to see if files are opened */
    9.55 -int havelist = 0, label = 0;
    9.56 -/* number of infiles in array */
    9.57 -int infilecount;
    9.58 +static int havelist = 0;
    9.59  
    9.60  /* number of errors seen so far */
    9.61 -int errors = 0;
    9.62 +static int errors = 0;
    9.63  
    9.64  /* current line, address and file */
    9.65 -int addr = 0, file;
    9.66 +static int addr = 0, file;
    9.67  /* current number of characters in list file, for indentation */
    9.68 -int listdepth;
    9.69 +static int listdepth;
    9.70  
    9.71  /* use readbyte instead of (hl) if writebyte is true */
    9.72 -int writebyte;
    9.73 -const char *readbyte;
    9.74 +static int writebyte;
    9.75 +static const char *readbyte;
    9.76  /* variables which are filled by rd_* functions and used later,
    9.77   * like readbyte */
    9.78 -const char *readword, *indexjmp, *bitsetres;
    9.79 +static const char *readword, *indexjmp, *bitsetres;
    9.80  
    9.81  /* 0, 0xdd or 0xfd depening on which index prefix should be given */
    9.82 -int indexed;
    9.83 +static int indexed;
    9.84  
    9.85  /* increased for every -v option on the command line */
    9.86 -int verbose = 0;
    9.87 +static int verbose = 0;
    9.88  
    9.89  /* read commas after indx() if comma > 1. increase for every call */
    9.90 -int comma;
    9.91 +static int comma;
    9.92  
    9.93  /* address at start of line (for references) */
    9.94 -int baseaddr;
    9.95 +static int baseaddr;
    9.96  
    9.97  /* set by readword and readbyte, used for new_reference */
    9.98 -char mem_delimiter;
    9.99 +static char mem_delimiter;
   9.100  
   9.101  /* line currently being parsed */
   9.102 -char *buffer = NULL;
   9.103 +static char *buffer = NULL;
   9.104  
   9.105  /* if a macro is currently being defined */
   9.106 -int define_macro = 0;
   9.107 +static int define_macro = 0;
   9.108  
   9.109  /* file (and macro) stack */
   9.110 -int sp;
   9.111 -struct stack stack[MAX_INCLUDE];	/* maximum level of includes */
   9.112 +static int sp;
   9.113 +static struct stack stack[MAX_INCLUDE];	/* maximum level of includes */
   9.114  
   9.115 -/* Produce output even with errors.  */
   9.116 -int use_force = 0;
   9.117 +/* hack */
   9.118 +#include "expressions.c"
   9.119  
   9.120  /* print an error message, including current line and file */
   9.121 -void
   9.122 -printerr (int error, const char *fmt, ...)
   9.123 -{
   9.124 -  va_list l;
   9.125 -  va_start (l, fmt);
   9.126 -  if ((sp < 0) || (stack[sp].name == 0))
   9.127 -    {
   9.128 -      fprintf (stderr, "internal assembler error, sp == %i\n", sp);
   9.129 -      vfprintf (stderr, fmt, l);
   9.130 -      exit (2);
   9.131 -    }
   9.132 -  fprintf (stderr, "%s%s:%d: %s: ", stack[sp].dir ? stack[sp].dir->name : "",
   9.133 -	   stack[sp].name, stack[sp].line, error ? "error" : "warning");
   9.134 -  vfprintf (stderr, fmt, l);
   9.135 -  va_end (l);
   9.136 -  if (error)
   9.137 -    errors++;
   9.138 +void printerr (int error, const char *fmt, ...) {
   9.139 +	va_list l;
   9.140 +	va_start (l, fmt);
   9.141 +	if ((sp < 0) || (stack[sp].name == 0)) {
   9.142 +		fprintf (stderr, "internal assembler error, sp == %i\n", sp);
   9.143 +		vfprintf (stderr, fmt, l);
   9.144 +		exit (2);
   9.145 +	}
   9.146 +	fprintf (stderr, "%s%s:%d: %s: ", stack[sp].dir ? stack[sp].dir->name : "",
   9.147 +			stack[sp].name, stack[sp].line, error ? "error" : "warning");
   9.148 +	vfprintf (stderr, fmt, l);
   9.149 +	va_end (l);
   9.150 +	if (error)
   9.151 +		errors++;
   9.152  }
   9.153  
   9.154  /* skip over spaces in string */
   9.155 -const char *
   9.156 -delspc (const char *ptr)
   9.157 -{
   9.158 -  while (*ptr && isspace (*ptr))
   9.159 -    ptr++;
   9.160 -  if (*ptr == ';')
   9.161 -    ptr = "";
   9.162 -  return ptr;
   9.163 +const char * delspc (const char *ptr) {
   9.164 +	while (*ptr && isspace (*ptr))
   9.165 +		ptr++;
   9.166 +	if (*ptr == ';')
   9.167 +		ptr = "";
   9.168 +	return ptr;
   9.169  }
   9.170  
   9.171  /* read away a comma, error if there is none */
   9.172 -static void
   9.173 -rd_comma (const char **p)
   9.174 -{
   9.175 -  *p = delspc (*p);
   9.176 -  if (**p != ',')
   9.177 -    {
   9.178 -      printerr (1, "`,' expected. Remainder of line: %s\n", *p);
   9.179 -      return;
   9.180 -    }
   9.181 -  *p = delspc ((*p) + 1);
   9.182 +static void rd_comma (const char **p) {
   9.183 +	*p = delspc (*p);
   9.184 +	if (**p != ',') {
   9.185 +		printerr (1, "`,' expected. Remainder of line: %s\n", *p);
   9.186 +		return;
   9.187 +	}
   9.188 +	*p = delspc ((*p) + 1);
   9.189  }
   9.190  
   9.191  /* look ahead for a comma, no error if not found */
   9.192 -static int
   9.193 -has_argument (const char **p)
   9.194 -{
   9.195 -  const char *q = delspc (*p);
   9.196 -  return (*q == ',');
   9.197 +static int has_argument (const char **p) {
   9.198 +	const char *q = delspc (*p);
   9.199 +	return (*q == ',');
   9.200  }
   9.201  
   9.202  /* During assembly, many literals are not parsed.  Instead, they are saved
   9.203   * until all labels are read.  After that, they are parsed.  This function
   9.204   * is used during assembly, to find the place where the command continues. */
   9.205 -static void
   9.206 -skipword (const char **pos, char delimiter)
   9.207 -{
   9.208 -  /* rd_expr will happily read the expression, and possibly return
   9.209 -   * an invalid result.  It will update pos, which is what we need.  */
   9.210 -  /* Pass valid to allow using undefined labels without errors.  */
   9.211 -  int valid;
   9.212 -  rd_expr (pos, delimiter, &valid, sp, 0);
   9.213 -}
   9.214 -
   9.215 -/* callback function for argument parser, used to open output files. */
   9.216 -static FILE *
   9.217 -openfile (int *done,		/* flag to check that a file is opened only once. */
   9.218 -	  const char *type,	/* name of filetype for error message */
   9.219 -	  FILE * def,		/* default value, in case "-" is specified */
   9.220 -	  const char *name,	/* filename to open */
   9.221 -	  const char *flags)	/* open flags */
   9.222 -{
   9.223 -  FILE *retval;
   9.224 -  if (*done)
   9.225 -    {
   9.226 -      fprintf (stderr, "Error: more than one %s specified\n", type);
   9.227 -      exit (1);
   9.228 -    }
   9.229 -  *done = 1;
   9.230 -  if (def && (!name || (name[0] == '-' && name[1] == 0)))
   9.231 -    {
   9.232 -      return def;
   9.233 -    }
   9.234 -  if (!name || !name[0])
   9.235 -    {
   9.236 -      fprintf (stderr, "Error: no %s specified\n", type);
   9.237 -      exit (1);
   9.238 -    }
   9.239 -  if (!(retval = fopen (name, flags)))
   9.240 -    {
   9.241 -      fprintf (stderr, "Unable to open %s %s: %s\n",
   9.242 -	       type, name, strerror (errno));
   9.243 -      exit (1);
   9.244 -    }
   9.245 -  return retval;
   9.246 -}
   9.247 -
   9.248 -/* open an included file, searching the path */
   9.249 -static FILE *
   9.250 -open_include_file (const char *name, struct includedir **dir,
   9.251 -		   const char *flags)
   9.252 -{
   9.253 -  FILE *result;
   9.254 -  struct includedir *i;
   9.255 -  /* always try the current directory first */
   9.256 -  result = fopen (name, flags);
   9.257 -  if (result)
   9.258 -    {
   9.259 -      if (dir)
   9.260 -	*dir = NULL;
   9.261 -      return result;
   9.262 -    }
   9.263 -  for (i = firstincludedir; i != NULL; i = i->next)
   9.264 -    {
   9.265 -      char *tmp = malloc (strlen (i->name) + strlen (name) + 1);
   9.266 -      if (!tmp)
   9.267 -	{
   9.268 -	  printerr (1, "not enough memory trying to open include file\n");
   9.269 -	  return NULL;
   9.270 -	}
   9.271 -      strcpy (tmp, i->name);
   9.272 -      strcat (tmp, name);
   9.273 -      result = fopen (tmp, flags);
   9.274 -      free (tmp);
   9.275 -      if (result)
   9.276 -	{
   9.277 -	  if (dir)
   9.278 -	    *dir = i;
   9.279 -	  return result;
   9.280 -	}
   9.281 -    }
   9.282 -  return NULL;
   9.283 -}
   9.284 -
   9.285 -/* queue a file to be opened for reading */
   9.286 -static void
   9.287 -open_infile (const char *name)
   9.288 -{
   9.289 -  infile = realloc (infile, sizeof (struct infile) * (infilecount + 1));
   9.290 -  if (!infile)
   9.291 -    {
   9.292 -      fprintf (stderr, "Error: insufficient memory\n");
   9.293 -      exit (1);
   9.294 -    }
   9.295 -  /* only asm is currently supported */
   9.296 -  infile[infilecount].type = FILETYPE_ASM;
   9.297 -  infile[infilecount].name = name;
   9.298 -  if (verbose >= 5)
   9.299 -    fprintf (stderr, "queued inputfile %s\n", infile[infilecount].name);
   9.300 -  infilecount++;
   9.301 -}
   9.302 -
   9.303 -/* add a directory to the include search path */
   9.304 -static void
   9.305 -add_include (const char *name)
   9.306 -{
   9.307 -  struct includedir *i;
   9.308 -  i = malloc (sizeof (struct includedir) + strlen (name) + 1);
   9.309 -  if (!i)
   9.310 -    {
   9.311 -      fprintf (stderr, "Error: insufficient memory\n");
   9.312 -      exit (1);
   9.313 -    }
   9.314 -  strcpy (i->name, name);
   9.315 -  if (name[strlen (name) - 1] != '/')
   9.316 -    strcat (i->name, "/");
   9.317 -  i->next = firstincludedir;
   9.318 -  firstincludedir = i;
   9.319 -}
   9.320 -
   9.321 -static void
   9.322 -try_use_real_file (FILE * real, FILE ** backup)
   9.323 -{
   9.324 -  fpos_t pos;
   9.325 -  if (fgetpos (real, &pos) == 0)
   9.326 -    {
   9.327 -      *backup = real;
   9.328 -      return;
   9.329 -    }
   9.330 -  if (!(*backup = tmpfile ()))
   9.331 -    {
   9.332 -      fprintf (stderr, "Error: Unable to open temporary file: %s\n",
   9.333 -	       strerror (errno));
   9.334 -      exit (1);
   9.335 -    }
   9.336 -}
   9.337 -
   9.338 -static void
   9.339 -flush_to_real_file (FILE * real, FILE * tmp)
   9.340 -{
   9.341 -  int l, size, len = 0;
   9.342 -  char buf[BUFLEN];
   9.343 -  if (tmp == real)
   9.344 -    {
   9.345 -      return;
   9.346 -    }
   9.347 -  rewind (tmp);
   9.348 -  while (1)
   9.349 -    {
   9.350 -      clearerr (tmp);
   9.351 -      errno = 0;
   9.352 -      len = fread (buf, 1, BUFLEN, tmp);
   9.353 -      if (len == 0 && feof (tmp))
   9.354 -	break;
   9.355 -      if (len <= 0)
   9.356 -	{
   9.357 -	  fprintf (stderr, "error reading temp file: %s\n", strerror (errno));
   9.358 -	  exit (1);
   9.359 -	}
   9.360 -      l = 0;
   9.361 -      while (l < len)
   9.362 -	{
   9.363 -	  clearerr (real);
   9.364 -	  size = fwrite (&buf[l], 1, len - l, real);
   9.365 -	  if (size <= 0)
   9.366 -	    {
   9.367 -	      fprintf (stderr, "error writing final file: %s\n",
   9.368 -		       strerror (errno));
   9.369 -	      exit (1);
   9.370 -	    }
   9.371 -	  l += size;
   9.372 -	}
   9.373 -    }
   9.374 -}
   9.375 -
   9.376 -/* parse commandline arguments */
   9.377 -static void
   9.378 -parse_commandline (int argc, char **argv)
   9.379 -{
   9.380 -  const struct option opts[] = {
   9.381 -    {"help", no_argument, NULL, 'h'},
   9.382 -    {"version", no_argument, NULL, 'V'},
   9.383 -    {"verbose", no_argument, NULL, 'v'},
   9.384 -    {"list", optional_argument, NULL, 'l'},
   9.385 -    {"label", optional_argument, NULL, 'L'},
   9.386 -    {"input", required_argument, NULL, 'i'},
   9.387 -    {"output", required_argument, NULL, 'o'},
   9.388 -    {"label-prefix", required_argument, NULL, 'p'},
   9.389 -    {"includepath", required_argument, NULL, 'I'},
   9.390 -    {"force", no_argument, NULL, 'f'},
   9.391 -    {NULL, 0, NULL, 0}
   9.392 -  };
   9.393 -  const char *short_opts = "hVvl::L::i:o:p:I:f";
   9.394 -  int done = 0, i, out = 0;
   9.395 -  infile = NULL;
   9.396 -  while (!done)
   9.397 -    {
   9.398 -      switch (getopt_long (argc, argv, short_opts, opts, NULL))
   9.399 -	{
   9.400 -	case 'h':
   9.401 -	  /* split in two, to avoid too long string constant */
   9.402 -	  printf ("Usage: %s [options] [input files]\n"
   9.403 -		  "\n"
   9.404 -		  "Possible options are:\n"
   9.405 -		  "-h\t--help\t\tDisplay this help text and exit.\n"
   9.406 -		  "-V\t--version\tDisplay version information and exit.\n"
   9.407 -		  "-v\t--verbose\tBe verbose.  "
   9.408 -		  "Specify again to be more verbose.\n"
   9.409 -		  "-l\t--list\t\tWrite a list file.\n"
   9.410 -		  "-L\t--label\t\tWrite a label file.\n", argv[0]);
   9.411 -	  printf ("-p\t--label-prefix\tprefix all labels with this prefix.\n"
   9.412 -		  "-i\t--input\t\tSpecify an input file (-i may be omitted).\n"
   9.413 -		  "-o\t--output\tSpecify the output file.\n"
   9.414 -		  "-I\t--includepath\tAdd a directory to the include path.\n"
   9.415 -		  "Please send bug reports and feature requests to "
   9.416 -		  "<shevek@fmf.nl>\n");
   9.417 -	  exit (0);
   9.418 -	case 'V':
   9.419 -	  printf ("Z80 assembler version " VERSION "\n"
   9.420 -		  "Copyright (C) 2002-2007 Bas Wijnen "
   9.421 -		  "<shevek@fmf.nl>.\n"
   9.422 -		  "Copyright (C) 2005 Jan Wilmans "
   9.423 -		  "<jw@dds.nl>.\n"
   9.424 -		  "This program comes with ABSOLUTELY NO WARRANTY.\n"
   9.425 -		  "You may distribute copies of the program under the terms\n"
   9.426 -		  "of the GNU General Public License as published by\n"
   9.427 -		  "the Free Software Foundation; either version 2 of the\n"
   9.428 -		  "License, or (at your option) any later version.\n\n"
   9.429 -		  "The complete text of the GPL can be found in\n"
   9.430 -		  "/usr/share/common-licenses/GPL.\n");
   9.431 -	  exit (0);
   9.432 -	case 'v':
   9.433 -	  verbose++;
   9.434 -	  if (verbose >= 5)
   9.435 -	    fprintf (stderr, "Verbosity increased to level %d\n", verbose);
   9.436 -	  break;
   9.437 -	case 'o':
   9.438 -	  realoutputfile
   9.439 -	    = openfile (&out, "output file", stdout, optarg, "wb");
   9.440 -	  realoutputfilename = optarg;
   9.441 -	  if (verbose >= 5)
   9.442 -	    fprintf (stderr, "Opened outputfile\n");
   9.443 -	  break;
   9.444 -	case 'i':
   9.445 -	  open_infile (optarg);
   9.446 -	  break;
   9.447 -	case 'l':
   9.448 -	  reallistfile
   9.449 -	    = openfile (&havelist, "list file", stderr, optarg, "w");
   9.450 -	  if (verbose >= 5)
   9.451 -	    fprintf (stderr, "Opened list file\n");
   9.452 -	  break;
   9.453 -	case 'L':
   9.454 -	  labelfile = openfile (&label, "label file", stderr, optarg, "w");
   9.455 -	  labelfilename = optarg;
   9.456 -	  if (verbose >= 5)
   9.457 -	    fprintf (stderr, "Opened label file\n");
   9.458 -	  break;
   9.459 -	case 'p':
   9.460 -	  labelprefix = optarg;
   9.461 -	  break;
   9.462 -	case 'I':
   9.463 -	  add_include (optarg);
   9.464 -	  break;
   9.465 -	case 'f':
   9.466 -	  use_force = 1;
   9.467 -	  break;
   9.468 -	case -1:
   9.469 -	  done = 1;
   9.470 -	  break;
   9.471 -	default:
   9.472 -	  /* errors are handled by getopt_long */
   9.473 -	  break;
   9.474 -	}
   9.475 -    }
   9.476 -  for (i = optind; i < argc; ++i)
   9.477 -    open_infile (argv[i]);
   9.478 -  if (!infilecount)
   9.479 -    open_infile ("-");
   9.480 -  if (!out)
   9.481 -    realoutputfile = openfile (&out, "output file", stdout, "a.bin", "wb");
   9.482 -  try_use_real_file (realoutputfile, &outfile);
   9.483 -  if (havelist)
   9.484 -    try_use_real_file (reallistfile, &listfile);
   9.485 +static void skipword (const char **pos, char delimiter) {
   9.486 +	/* rd_expr will happily read the expression, and possibly return
   9.487 +	 * an invalid result.  It will update pos, which is what we need.  */
   9.488 +	/* Pass valid to allow using undefined labels without errors.  */
   9.489 +	int valid;
   9.490 +	rd_expr (pos, delimiter, &valid, sp, 0);
   9.491  }
   9.492  
   9.493  /* find any of the list[] entries as the start of ptr and return index */
   9.494 -static int
   9.495 -indx (const char **ptr, const char **list, int error, const char **expr)
   9.496 -{
   9.497 -  int i, l;
   9.498 -  *ptr = delspc (*ptr);
   9.499 -  if (!**ptr)
   9.500 -    {
   9.501 -      if (error)
   9.502 -	{
   9.503 -	  printerr (1, "unexpected end of line\n");
   9.504 -	  return 0;
   9.505 +static int indx (const char **ptr, const char **list, int error, const char **expr) {
   9.506 +	int i, l;
   9.507 +	*ptr = delspc (*ptr);
   9.508 +	if (!**ptr) {
   9.509 +		if (error) {
   9.510 +			printerr (1, "unexpected end of line\n");
   9.511 +			return 0;
   9.512 +		} else return 0;
   9.513  	}
   9.514 -      else
   9.515 +	if (comma > 1)
   9.516 +		rd_comma (ptr);
   9.517 +	for (i = 0; list[i]; i++) {
   9.518 +		const char *input = *ptr;
   9.519 +		const char *check = list[i];
   9.520 +		int had_expr = 0;
   9.521 +		if (!list[i][0])
   9.522 +			continue;
   9.523 +		l = strlen (list[i]);
   9.524 +		while (*check) {
   9.525 +			if (*check == ' ') {
   9.526 +				input = delspc (input);
   9.527 +			} else if (*check == '*') {
   9.528 +				*expr = input;
   9.529 +				mem_delimiter = check[1];
   9.530 +				rd_expr (&input, mem_delimiter, NULL, sp, 0);
   9.531 +				had_expr = 1;
   9.532 +			} else if (*check == '+') {
   9.533 +				if (*input == '+' || *input == '-') {
   9.534 +					*expr = input;
   9.535 +					mem_delimiter = check[1];
   9.536 +					rd_expr (&input, mem_delimiter, NULL, sp, 0);
   9.537 +				}
   9.538 +			} else if (*check == *input || (*check >= 'a' && *check <= 'z'
   9.539 +						&& *check - 'a' + 'A' == *input))
   9.540 +				++input;
   9.541 +			else break;
   9.542 +
   9.543 +			++check;
   9.544 +		}
   9.545 +		if (*check || (isalnum (check[-1]) && isalnum (input[0])))
   9.546 +			continue;
   9.547 +		if (had_expr) {
   9.548 +			input = delspc (input);
   9.549 +			if (*input && *input != ',')
   9.550 +				continue;
   9.551 +		}
   9.552 +		*ptr = input;
   9.553 +		comma++;
   9.554 +		return i + 1;
   9.555 +	}
   9.556 +	if (error)
   9.557 +		printerr (1, "parse error. Remainder of line=%s\n", *ptr);
   9.558  	return 0;
   9.559 -    }
   9.560 -  if (comma > 1)
   9.561 -    rd_comma (ptr);
   9.562 -  for (i = 0; list[i]; i++)
   9.563 -    {
   9.564 -      const char *input = *ptr;
   9.565 -      const char *check = list[i];
   9.566 -      int had_expr = 0;
   9.567 -      if (!list[i][0])
   9.568 -	continue;
   9.569 -      l = strlen (list[i]);
   9.570 -      while (*check)
   9.571 -	{
   9.572 -	  if (*check == ' ')
   9.573 -	    {
   9.574 -	      input = delspc (input);
   9.575 -	    }
   9.576 -	  else if (*check == '*')
   9.577 -	    {
   9.578 -	      *expr = input;
   9.579 -	      mem_delimiter = check[1];
   9.580 -	      rd_expr (&input, mem_delimiter, NULL, sp, 0);
   9.581 -	      had_expr = 1;
   9.582 -	    }
   9.583 -	  else if (*check == '+')
   9.584 -	    {
   9.585 -	      if (*input == '+' || *input == '-')
   9.586 -		{
   9.587 -		  *expr = input;
   9.588 -		  mem_delimiter = check[1];
   9.589 -		  rd_expr (&input, mem_delimiter, NULL, sp, 0);
   9.590 -		}
   9.591 -	    }
   9.592 -	  else if (*check == *input || (*check >= 'a' && *check <= 'z'
   9.593 -					&& *check - 'a' + 'A' == *input))
   9.594 -	    ++input;
   9.595 -	  else
   9.596 -	    break;
   9.597 -
   9.598 -	  ++check;
   9.599 -	}
   9.600 -      if (*check || (isalnum (check[-1]) && isalnum (input[0])))
   9.601 -	continue;
   9.602 -      if (had_expr)
   9.603 -	{
   9.604 -	  input = delspc (input);
   9.605 -	  if (*input && *input != ',')
   9.606 -	    continue;
   9.607 -	}
   9.608 -      *ptr = input;
   9.609 -      if (verbose >= 4)
   9.610 -	fprintf (stderr, "%5d (0x%04x): Piece of code found:%s\n",
   9.611 -		 stack[sp].line, addr, list[i]);
   9.612 -      if (verbose >= 6)
   9.613 -	fprintf (stderr, "%5d (0x%04x): Remainder of line=%s.\n",
   9.614 -		 stack[sp].line, addr, *ptr);
   9.615 -      comma++;
   9.616 -      return i + 1;
   9.617 -    }
   9.618 -  if (error)
   9.619 -    {
   9.620 -      printerr (1, "parse error. Remainder of line=%s\n", *ptr);
   9.621 -      if (verbose >= 3)
   9.622 -	{
   9.623 -	  fprintf (stderr, "When looking for any of:\n");
   9.624 -	  for (i = 0; list[i]; i++)
   9.625 -	    fprintf (stderr, "%s\t", list[i]);
   9.626 -	  fprintf (stderr, "\n");
   9.627 -	}
   9.628 -    }
   9.629 -  return 0;
   9.630  }
   9.631  
   9.632  /* read a mnemonic */
   9.633 -static int
   9.634 -readcommand (const char **p)
   9.635 -{
   9.636 -  return indx (p, mnemonics, 0, NULL);
   9.637 +static int readcommand (const char **p) {
   9.638 +	return indx (p, mnemonics, 0, NULL);
   9.639  }
   9.640  
   9.641  /* try to read a label and optionally store it in the list */
   9.642 -static void
   9.643 -readlabel (const char **p, int store)
   9.644 -{
   9.645 -  const char *c, *d, *pos, *dummy;
   9.646 -  int i, j;
   9.647 -  struct label *buf, *previous, **thefirstlabel;
   9.648 -  for (d = *p; *d && *d != ';'; ++d)
   9.649 -    {
   9.650 -    }
   9.651 -  for (c = *p; !strchr (" \r\n\t", *c) && c < d; ++c)
   9.652 -    {
   9.653 -    }
   9.654 -  pos = strchr (*p, ':');
   9.655 -  if (!pos || pos >= c)
   9.656 -    return;
   9.657 -  if (pos == *p)
   9.658 -    {
   9.659 -      printerr (1, "`:' found without a label");
   9.660 -      return;
   9.661 -    }
   9.662 -  if (!store)
   9.663 -    {
   9.664 -      *p = pos + 1;
   9.665 -      return;
   9.666 -    }
   9.667 -  c = pos + 1;
   9.668 -  dummy = *p;
   9.669 -  j = rd_label (&dummy, &i, &previous, sp, 0);
   9.670 -  if (i || j)
   9.671 -    {
   9.672 -      printerr (1, "duplicate definition of label %s\n", *p);
   9.673 -      *p = c;
   9.674 -      return;
   9.675 -    }
   9.676 -  if (NULL == (buf = malloc (sizeof (struct label) + c - *p)))
   9.677 -    {
   9.678 -      printerr (1, "not enough memory to store label %s\n", *p);
   9.679 -      *p = c;
   9.680 -      return;
   9.681 -    }
   9.682 -  strncpy (buf->name, *p, c - *p - 1);
   9.683 -  buf->name[c - *p - 1] = 0;
   9.684 -  if (verbose >= 3)
   9.685 -    fprintf (stderr, "%5d (0x%04x): Label found: %s\n", stack[sp].line,
   9.686 -	     addr, buf->name);
   9.687 -  *p = c;
   9.688 -  buf->value = addr;
   9.689 -  lastlabel = buf;
   9.690 -  if (buf->name[0] == '.')
   9.691 -    thefirstlabel = &stack[sp].labels;
   9.692 -  else
   9.693 -    thefirstlabel = &firstlabel;
   9.694 -  if (previous)
   9.695 -    buf->next = previous->next;
   9.696 -  else
   9.697 -    buf->next = *thefirstlabel;
   9.698 -  buf->prev = previous;
   9.699 -  buf->valid = 1;
   9.700 -  buf->busy = 0;
   9.701 -  buf->ref = NULL;
   9.702 -  if (buf->prev)
   9.703 -    buf->prev->next = buf;
   9.704 -  else
   9.705 -    *thefirstlabel = buf;
   9.706 -  if (buf->next)
   9.707 -    buf->next->prev = buf;
   9.708 +static void readlabel (const char **p, int store) {
   9.709 +	const char *c, *d, *pos, *dummy;
   9.710 +	int i, j;
   9.711 +	struct label *buf, *previous, **thefirstlabel;
   9.712 +	for (d = *p; *d && *d != ';'; ++d);
   9.713 +	for (c = *p; !strchr (" \r\n\t", *c) && c < d; ++c);
   9.714 +	pos = strchr (*p, ':');
   9.715 +	if (!pos || pos >= c)
   9.716 +		return;
   9.717 +	if (pos == *p) {
   9.718 +		printerr (1, "`:' found without a label");
   9.719 +		return;
   9.720 +	}
   9.721 +	if (!store) {
   9.722 +		*p = pos + 1;
   9.723 +		return;
   9.724 +	}
   9.725 +	c = pos + 1;
   9.726 +	dummy = *p;
   9.727 +	j = rd_label (&dummy, &i, &previous, sp, 0);
   9.728 +	if (i || j) {
   9.729 +		printerr (1, "duplicate definition of label %s\n", *p);
   9.730 +		*p = c;
   9.731 +		return;
   9.732 +	}
   9.733 +	if (NULL == (buf = malloc (sizeof (struct label) + c - *p))) {
   9.734 +		printerr (1, "not enough memory to store label %s\n", *p);
   9.735 +		*p = c;
   9.736 +		return;
   9.737 +	}
   9.738 +	strncpy (buf->name, *p, c - *p - 1);
   9.739 +	buf->name[c - *p - 1] = 0;
   9.740 +	*p = c;
   9.741 +	buf->value = addr;
   9.742 +	lastlabel = buf;
   9.743 +	if (buf->name[0] == '.')
   9.744 +		thefirstlabel = &stack[sp].labels;
   9.745 +	else thefirstlabel = &firstlabel;
   9.746 +	if (previous)
   9.747 +		buf->next = previous->next;
   9.748 +	else buf->next = *thefirstlabel;
   9.749 +	buf->prev = previous;
   9.750 +	buf->valid = 1;
   9.751 +	buf->busy = 0;
   9.752 +	buf->ref = NULL;
   9.753 +	if (buf->prev)
   9.754 +		buf->prev->next = buf;
   9.755 +	else *thefirstlabel = buf;
   9.756 +	if (buf->next)
   9.757 +		buf->next->prev = buf;
   9.758  }
   9.759  
   9.760 -static void new_reference (const char *data, int type, char delimiter,
   9.761 +static int new_reference (const char *data, int type, char delimiter,
   9.762  			   int ds_count);
   9.763  
   9.764 +#if 0
   9.765  /* write one byte to the outfile, and add it to the list file as well */
   9.766 -static void
   9.767 -write_one_byte (int b, int list)
   9.768 -{
   9.769 -  if (verbose >= 4)
   9.770 -    fprintf (stderr,
   9.771 -	     "%5d (0x%04x): write_one_byte called with argument 0x%02x\n",
   9.772 -	     stack[sp].line, addr, b);
   9.773 -  b &= 0xff;
   9.774 -  putc (b, outfile);
   9.775 -  if (list && havelist)
   9.776 -    {
   9.777 -      fprintf (listfile, " %02x", b);
   9.778 -      listdepth += 3;
   9.779 -    }
   9.780 -  addr++;
   9.781 -  addr &= 0xffff;
   9.782 +static void write_one_byte (int b, int list) {
   9.783 +	b &= 0xff;
   9.784 +	putc (b, outfile);
   9.785 +	if (list && havelist) {
   9.786 +		fprintf (listfile, " %02x", b);
   9.787 +		listdepth += 3;
   9.788 +	}
   9.789 +	addr++;
   9.790 +	addr &= 0xffff;
   9.791  }
   9.792  
   9.793  /* write byte to outfile and possibly some index things as well */
   9.794 -static void
   9.795 -wrtb (int b)
   9.796 -{
   9.797 -  if (verbose >= 4)
   9.798 -    fprintf (stderr, "%5d (0x%04x): wrtb called with argument 0x%02x\n",
   9.799 -	     stack[sp].line, addr, b);
   9.800 -  if (indexed)
   9.801 -    {
   9.802 -      if (verbose >= 5)
   9.803 -	fprintf (stderr, "%5d (0x%04x): writing indexed byte 0x%02x\n",
   9.804 -		 stack[sp].line, addr, indexed);
   9.805 -      write_one_byte (indexed, 1);
   9.806 -      indexed = 0;
   9.807 -    }
   9.808 -  if (writebyte)
   9.809 -    {
   9.810 -      if (verbose >= 5)
   9.811 -	fprintf (stderr, "%5d (0x%04x): using a xor on byte because there is "
   9.812 -		 "a writebyte.\n", stack[sp].line, addr);
   9.813 -      b ^= 0x40;
   9.814 -    }
   9.815 -  if (verbose >= 5)
   9.816 -    fprintf (stderr, "%5d (0x%04x): writing byte 0x%02x\n", stack[sp].line,
   9.817 -	     addr, b);
   9.818 -  if (bitsetres && b != 0xCB)
   9.819 -    {
   9.820 -      new_reference (bitsetres, TYPE_BSR, ',', b);
   9.821 -      bitsetres = NULL;
   9.822 -    }
   9.823 -  else
   9.824 -    {
   9.825 -      write_one_byte (b, 1);
   9.826 -    }
   9.827 -  if (indexjmp)
   9.828 -    {
   9.829 -      if (verbose >= 5)
   9.830 -	fprintf (stderr, "%5d (0x%04x): Making reference for index/jump %s\n",
   9.831 -		 stack[sp].line, addr, indexjmp);
   9.832 -      new_reference (indexjmp, TYPE_ABSB, ')', 1);
   9.833 -      indexjmp = NULL;
   9.834 -    }
   9.835 -  if (writebyte)
   9.836 -    {
   9.837 -      if (verbose >= 5)
   9.838 -	fprintf (stderr, "%5d (0x%04x): writing argument byte for padding\n",
   9.839 -		 stack[sp].line, addr);
   9.840 -      writebyte = 0;
   9.841 -      new_reference (readbyte, TYPE_ABSB, mem_delimiter, 1);
   9.842 -    }
   9.843 +static void wrtb (int b) {
   9.844 +	if (indexed) {
   9.845 +		write_one_byte (indexed, 1);
   9.846 +		indexed = 0;
   9.847 +	}
   9.848 +	if (writebyte)
   9.849 +		b ^= 0x40;
   9.850 +	if (bitsetres && b != 0xCB) {
   9.851 +		new_reference (bitsetres, TYPE_BSR, ',', b);
   9.852 +		bitsetres = NULL;
   9.853 +	} else write_one_byte (b, 1);
   9.854 +	if (indexjmp) {
   9.855 +		new_reference (indexjmp, TYPE_ABSB, ')', 1);
   9.856 +		indexjmp = NULL;
   9.857 +	}
   9.858 +	if (writebyte) {
   9.859 +		writebyte = 0;
   9.860 +		new_reference (readbyte, TYPE_ABSB, mem_delimiter, 1);
   9.861 +	}
   9.862  }
   9.863 +#endif
   9.864  
   9.865 -int
   9.866 -compute_ref (struct reference *ref, int allow_invalid)
   9.867 -{
   9.868 -  const char *ptr;
   9.869 -  int valid = 0;
   9.870 -  int backup_addr = addr;
   9.871 -  int backup_baseaddr = baseaddr;
   9.872 -  int backup_comma = comma;
   9.873 -  int backup_file = file;
   9.874 -  int backup_sp = sp;
   9.875 -  sp = ref->level;
   9.876 -  addr = ref->addr;
   9.877 -  baseaddr = ref->baseaddr;
   9.878 -  comma = ref->comma;
   9.879 -  file = ref->infile;
   9.880 -  if (verbose >= 3)
   9.881 -    fprintf (stderr, "%5d (0x%04x): Making reference to %s (done=%d, "
   9.882 -	     "computed=%d)\n",
   9.883 -	     stack[sp].line, addr, ref->input, ref->done,
   9.884 -	     ref->computed_value);
   9.885 -  ptr = ref->input;
   9.886 -  if (!ref->done)
   9.887 -    {
   9.888 -      ref->computed_value = rd_expr (&ptr, ref->delimiter,
   9.889 -				     allow_invalid ? &valid : NULL,
   9.890 -				     ref->level, 1);
   9.891 -      if (valid)
   9.892 -	ref->done = 1;
   9.893 -    }
   9.894 -  if (verbose >= 4)
   9.895 -    fprintf (stderr, "%5d (0x%04x): Reference is %d (0x%04x).\n",
   9.896 -	     stack[sp].line, addr, ref->computed_value, ref->computed_value);
   9.897 -  sp = backup_sp;
   9.898 -  addr = backup_addr;
   9.899 -  baseaddr = backup_baseaddr;
   9.900 -  comma = backup_comma;
   9.901 -  file = backup_file;
   9.902 -  return ref->computed_value;
   9.903 +int compute_ref (struct reference *ref, int allow_invalid) {
   9.904 +	const char *ptr;
   9.905 +	int valid = 0;
   9.906 +	int backup_addr = addr;
   9.907 +	int backup_baseaddr = baseaddr;
   9.908 +	int backup_comma = comma;
   9.909 +	int backup_file = file;
   9.910 +	int backup_sp = sp;
   9.911 +	sp = ref->level;
   9.912 +	addr = ref->addr;
   9.913 +	baseaddr = ref->baseaddr;
   9.914 +	comma = ref->comma;
   9.915 +	file = ref->infile;
   9.916 +	ptr = ref->input;
   9.917 +	if (!ref->done) {
   9.918 +		ref->computed_value = rd_expr (&ptr, ref->delimiter,
   9.919 +				allow_invalid ? &valid : NULL,
   9.920 +				ref->level, 1);
   9.921 +		if (valid)
   9.922 +			ref->done = 1;
   9.923 +	}
   9.924 +	sp = backup_sp;
   9.925 +	addr = backup_addr;
   9.926 +	baseaddr = backup_baseaddr;
   9.927 +	comma = backup_comma;
   9.928 +	file = backup_file;
   9.929 +	return ref->computed_value;
   9.930  }
   9.931  
   9.932 -static void wrt_ref (int val, int type, int count);
   9.933 -
   9.934  /* Create a new reference, to be resolved after assembling (so all labels are
   9.935   * known.) */
   9.936 -static void
   9.937 -new_reference (const char *p, int type, char delimiter, int ds_count)
   9.938 -{
   9.939 -  struct reference *tmp = NULL;
   9.940 -  long opos, lpos;
   9.941 -  int valid, value;
   9.942 -  const char *c;
   9.943 -  c = p;
   9.944 -  value = rd_expr (&c, delimiter, &valid, sp, 1);
   9.945 -  if (valid)
   9.946 -    {
   9.947 -      if (verbose >= 5)
   9.948 -	{
   9.949 -	  fprintf (stderr, "%5d (0x%04x): Using calculated value %d (%x) "
   9.950 -		   "immediately.\n", stack[sp].line, addr, value, value);
   9.951 +static int new_reference (const char *p, int type, char delimiter, int ds_count) {
   9.952 +	struct reference *tmp = NULL;
   9.953 +	int valid, value;
   9.954 +	const char *c;
   9.955 +	c = p;
   9.956 +	value = rd_expr (&c, delimiter, &valid, sp, 1);
   9.957 +	if (!valid) {
   9.958 +		fprintf (stderr, "invalid reference\n");
   9.959 +		return 0;
   9.960  	}
   9.961 -    }
   9.962 -  else
   9.963 -    {
   9.964 -      /* the expression is not valid (yet), we need to make a real reference.  */
   9.965 -      tmp = malloc (sizeof (struct reference) + strlen (p));
   9.966 -      if (!tmp)
   9.967 -	{
   9.968 -	  printerr (1, "unable to allocate memory for reference %s\n", p);
   9.969 -	  return;
   9.970 -	}
   9.971 -      tmp->file = malloc (strlen (stack[sp].name) + 1);
   9.972 -      if (!tmp->file)
   9.973 -	{
   9.974 -	  printerr (1, "unable to allocate memory for reference filename\n");
   9.975 -	  free (tmp);
   9.976 -	  return;
   9.977 -	}
   9.978 -      strcpy (tmp->file, stack[sp].name);
   9.979 -      if (stack[sp].dir)
   9.980 -	{
   9.981 -	  tmp->dir = malloc (strlen (stack[sp].dir->name)
   9.982 -			  + sizeof (struct includedir));
   9.983 -	  if (!tmp->dir)
   9.984 -	    {
   9.985 -	      printerr (1, "unable to allocate memory for reference dir\n");
   9.986 -	      free (tmp->file);
   9.987 -	      free (tmp);
   9.988 -	      return;
   9.989 -	    }
   9.990 -	  strcpy (tmp->dir->name, stack[sp].dir->name);
   9.991 -	}
   9.992 -      else
   9.993 -	tmp->dir = NULL;
   9.994 -      opos = ftell (outfile);
   9.995 -      lpos = havelist ? ftell (listfile) : 0;
   9.996 -      if (verbose >= 3)
   9.997 -	fprintf (stderr, "%5d (0x%04x): reference set to %s (delimiter=%c, "
   9.998 -		 "sp=%d)\n", stack[sp].line, addr, p, delimiter, sp);
   9.999 -      strcpy (tmp->input, p);
  9.1000 -      tmp->line = stack[sp].line;
  9.1001 -      tmp->addr = addr;
  9.1002 -      tmp->baseaddr = baseaddr;
  9.1003 -      tmp->count = ds_count;
  9.1004 -      tmp->infile = file;
  9.1005 -      tmp->comma = comma;
  9.1006 -      tmp->oseekpos = opos;
  9.1007 -      tmp->lseekpos = lpos;
  9.1008 -      tmp->delimiter = delimiter;
  9.1009 -      tmp->type = type;
  9.1010 -      tmp->next = firstreference;
  9.1011 -      tmp->done = 0;
  9.1012 -      tmp->level = sp;
  9.1013 -      if (type != TYPE_LABEL)
  9.1014 -	{
  9.1015 -	  if (firstreference)
  9.1016 -	    firstreference->prev = tmp;
  9.1017 -	  tmp->prev = NULL;
  9.1018 -	  firstreference = tmp;
  9.1019 -	}
  9.1020 -      /* Dummy value which should not give warnings */
  9.1021 -      value = (type == TYPE_RELB) ? ds_count : 0;
  9.1022 -    }
  9.1023 -  if (type != TYPE_LABEL)
  9.1024 -    {
  9.1025 -      wrt_ref (value, type, ds_count);
  9.1026 -    }
  9.1027 -  else
  9.1028 -    {
  9.1029 -      lastlabel->ref = tmp;
  9.1030 -      lastlabel->valid = valid;
  9.1031 -      lastlabel->value = value;
  9.1032 -    }
  9.1033 +	if (type == TYPE_LABEL) {
  9.1034 +		lastlabel->ref = tmp;
  9.1035 +		lastlabel->valid = valid;
  9.1036 +		lastlabel->value = value;
  9.1037 +	} else wrt_ref (value, type, ds_count);
  9.1038 +	return 1;
  9.1039  }
  9.1040  
  9.1041  /* write the last read word to file */
  9.1042 -static void
  9.1043 -write_word (void)
  9.1044 -{
  9.1045 -  new_reference (readword, TYPE_ABSW, mem_delimiter, 1);
  9.1046 +static int write_word (void) {
  9.1047 +	return new_reference (readword, TYPE_ABSW, mem_delimiter, 1);
  9.1048  }
  9.1049  
  9.1050  /* write the last read byte to file (relative) */
  9.1051 -static void
  9.1052 -write_rel (void)
  9.1053 -{
  9.1054 -  new_reference (readbyte, TYPE_RELB, mem_delimiter, (addr + 1) & 0xffff);
  9.1055 -  writebyte = 0;
  9.1056 +static int write_rel (void) {
  9.1057 +	int ret = new_reference (readbyte, TYPE_RELB, mem_delimiter, (addr + 1) & 0xffff);
  9.1058 +	writebyte = 0;
  9.1059 +	return ret;
  9.1060  }
  9.1061  
  9.1062  /* read a word from input and store it in readword. return 1 on success */
  9.1063 -static int
  9.1064 -rd_word (const char **p, char delimiter)
  9.1065 -{
  9.1066 -  *p = delspc (*p);
  9.1067 -  if (**p == 0)
  9.1068 -    return 0;
  9.1069 -  readword = *p;
  9.1070 -  mem_delimiter = delimiter;
  9.1071 -  skipword (p, delimiter);
  9.1072 -  return 1;
  9.1073 +static int rd_word (const char **p, char delimiter) {
  9.1074 +	*p = delspc (*p);
  9.1075 +	if (**p == 0)
  9.1076 +		return 0;
  9.1077 +	readword = *p;
  9.1078 +	mem_delimiter = delimiter;
  9.1079 +	skipword (p, delimiter);
  9.1080 +	return 1;
  9.1081  }
  9.1082  
  9.1083  /* read a byte from input and store it in readbyte. return 1 on success */
  9.1084 -static int
  9.1085 -rd_byte (const char **p, char delimiter)
  9.1086 -{
  9.1087 -  *p = delspc (*p);
  9.1088 -  if (**p == 0)
  9.1089 -    return 0;
  9.1090 -  readbyte = *p;
  9.1091 -  writebyte = 1;
  9.1092 -  mem_delimiter = delimiter;
  9.1093 -  skipword (p, delimiter);
  9.1094 -  return 1;
  9.1095 +static int rd_byte (const char **p, char delimiter) {
  9.1096 +	*p = delspc (*p);
  9.1097 +	if (**p == 0)
  9.1098 +		return 0;
  9.1099 +	readbyte = *p;
  9.1100 +	writebyte = 1;
  9.1101 +	mem_delimiter = delimiter;
  9.1102 +	skipword (p, delimiter);
  9.1103 +	return 1;
  9.1104  }
  9.1105  
  9.1106  /* read an address from infile and put it in reference table.
  9.1107   * so that it will be written here afterwards */
  9.1108 -static void
  9.1109 -rd_wrt_addr (const char **p, char delimiter)
  9.1110 -{
  9.1111 -  if (!rd_word (p, delimiter))
  9.1112 -    return;
  9.1113 -  write_word ();
  9.1114 +static int rd_wrt_addr (const char **p, char delimiter) {
  9.1115 +	if (!rd_word (p, delimiter))
  9.1116 +		return 0;
  9.1117 +	return write_word ();
  9.1118  }
  9.1119  
  9.1120  /* like rd_wrt_addr, but for a relative jump */
  9.1121 -static void
  9.1122 -rd_wrt_jr (const char **p, char delimiter)
  9.1123 -{
  9.1124 -  if (!rd_byte (p, delimiter))
  9.1125 -    return;
  9.1126 -  write_rel ();
  9.1127 +static int rd_wrt_jr (const char **p, char delimiter) {
  9.1128 +	if (!rd_byte (p, delimiter))
  9.1129 +		return 0;
  9.1130 +	return write_rel ();
  9.1131  }
  9.1132  
  9.1133  /* read (SP), DE, or AF */
  9.1134 -static int
  9.1135 -rd_ex1 (const char **p)
  9.1136 -{
  9.1137 +static int rd_ex1 (const char **p) {
  9.1138  #define DE 2
  9.1139  #define AF 3
  9.1140 -  const char *list[] = { "( sp )", "de", "af", NULL };
  9.1141 -  return indx (p, list, 1, NULL);
  9.1142 +	const char *list[] = { "( sp )", "de", "af", NULL };
  9.1143 +	return indx (p, list, 1, NULL);
  9.1144  }
  9.1145  
  9.1146  /* read first argument of IN */
  9.1147 -static int
  9.1148 -rd_in (const char **p)
  9.1149 -{
  9.1150 +static int rd_in (const char **p) {
  9.1151  #define A 8
  9.1152 -  const char *list[] = { "b", "c", "d", "e", "h", "l", "f", "a", NULL };
  9.1153 -  return indx (p, list, 1, NULL);
  9.1154 +	const char *list[] = { "b", "c", "d", "e", "h", "l", "f", "a", NULL };
  9.1155 +	return indx (p, list, 1, NULL);
  9.1156  }
  9.1157  
  9.1158  /* read second argument of out (c),x */
  9.1159 -static int
  9.1160 -rd_out (const char **p)
  9.1161 -{
  9.1162 -  const char *list[] = { "b", "c", "d", "e", "h", "l", "0", "a", NULL };
  9.1163 -  return indx (p, list, 1, NULL);
  9.1164 +static int rd_out (const char **p) {
  9.1165 +	const char *list[] = { "b", "c", "d", "e", "h", "l", "0", "a", NULL };
  9.1166 +	return indx (p, list, 1, NULL);
  9.1167  }
  9.1168  
  9.1169  /* read (c) or (nn) */
  9.1170 -static int
  9.1171 -rd_nnc (const char **p)
  9.1172 -{
  9.1173 +static int rd_nnc (const char **p) {
  9.1174  #define C 1
  9.1175 -  int i;
  9.1176 -  const char *list[] = { "( c )", "(*)", "a , (*)", NULL };
  9.1177 -  i = indx (p, list, 1, &readbyte);
  9.1178 -  if (i < 2)
  9.1179 -    return i;
  9.1180 -  return 2;
  9.1181 +	int i;
  9.1182 +	const char *list[] = { "( c )", "(*)", "a , (*)", NULL };
  9.1183 +	i = indx (p, list, 1, &readbyte);
  9.1184 +	if (i < 2)
  9.1185 +		return i;
  9.1186 +	return 2;
  9.1187  }
  9.1188  
  9.1189  /* read (C) */
  9.1190 -static int
  9.1191 -rd_c (const char **p)
  9.1192 -{
  9.1193 -  const char *list[] = { "( c )", "( bc )", NULL };
  9.1194 -  return indx (p, list, 1, NULL);
  9.1195 +static int rd_c (const char **p) {
  9.1196 +	const char *list[] = { "( c )", "( bc )", NULL };
  9.1197 +	return indx (p, list, 1, NULL);
  9.1198  }
  9.1199  
  9.1200  /* read a or hl */
  9.1201 -static int
  9.1202 -rd_a_hl (const char **p)
  9.1203 -{
  9.1204 +static int rd_a_hl (const char **p) {
  9.1205  #define HL 2
  9.1206 -  const char *list[] = { "a", "hl", NULL };
  9.1207 -  return indx (p, list, 1, NULL);
  9.1208 +	const char *list[] = { "a", "hl", NULL };
  9.1209 +	return indx (p, list, 1, NULL);
  9.1210  }
  9.1211  
  9.1212  /* read first argument of ld */
  9.1213 -static int
  9.1214 -rd_ld (const char **p)
  9.1215 -{
  9.1216 +static int rd_ld (const char **p) {
  9.1217  #define ldBC	1
  9.1218  #define ldDE	2
  9.1219  #define ldHL	3
  9.1220 @@ -951,88 +477,76 @@
  9.1221  #define ld_IX	19
  9.1222  #define ld_IY	20
  9.1223  #define ld_NN	21
  9.1224 -  int i;
  9.1225 -  const char *list[] = {
  9.1226 -    "ixh", "ixl", "iyh", "iyl", "bc", "de", "hl", "sp", "ix",
  9.1227 -    "iy", "b", "c", "d", "e", "h", "l", "( hl )", "a", "i",
  9.1228 -    "r", "( bc )", "( de )", "( ix +)", "(iy +)", "(*)", NULL
  9.1229 -  };
  9.1230 -  const char *nn;
  9.1231 -  i = indx (p, list, 1, &nn);
  9.1232 -  if (!i)
  9.1233 -    return 0;
  9.1234 -  if (i <= 2)
  9.1235 -    {
  9.1236 -      indexed = 0xdd;
  9.1237 -      return ldH + (i == 2);
  9.1238 -    }
  9.1239 -  if (i <= 4)
  9.1240 -    {
  9.1241 -      indexed = 0xfd;
  9.1242 -      return ldH + (i == 4);
  9.1243 -    }
  9.1244 -  i -= 4;
  9.1245 -  if (i == ldIX || i == ldIY)
  9.1246 -    {
  9.1247 -      indexed = i == ldIX ? 0xDD : 0xFD;
  9.1248 -      return ldHL;
  9.1249 -    }
  9.1250 -  if (i == ld_IX || i == ld_IY)
  9.1251 -    {
  9.1252 -      indexjmp = nn;
  9.1253 -      indexed = i == ld_IX ? 0xDD : 0xFD;
  9.1254 -      return ld_HL;
  9.1255 -    }
  9.1256 -  if (i == ld_NN)
  9.1257 -    readword = nn;
  9.1258 -  return i;
  9.1259 +	int i;
  9.1260 +	const char *list[] = {
  9.1261 +		"ixh", "ixl", "iyh", "iyl", "bc", "de", "hl", "sp", "ix",
  9.1262 +		"iy", "b", "c", "d", "e", "h", "l", "( hl )", "a", "i",
  9.1263 +		"r", "( bc )", "( de )", "( ix +)", "(iy +)", "(*)", NULL
  9.1264 +	};
  9.1265 +	const char *nn;
  9.1266 +	i = indx (p, list, 1, &nn);
  9.1267 +	if (!i)
  9.1268 +		return 0;
  9.1269 +	if (i <= 2) {
  9.1270 +		indexed = 0xdd;
  9.1271 +		return ldH + (i == 2);
  9.1272 +	}
  9.1273 +	if (i <= 4) {
  9.1274 +		indexed = 0xfd;
  9.1275 +		return ldH + (i == 4);
  9.1276 +	}
  9.1277 +	i -= 4;
  9.1278 +	if (i == ldIX || i == ldIY) {
  9.1279 +		indexed = i == ldIX ? 0xDD : 0xFD;
  9.1280 +		return ldHL;
  9.1281 +	}
  9.1282 +	if (i == ld_IX || i == ld_IY) {
  9.1283 +		indexjmp = nn;
  9.1284 +		indexed = i == ld_IX ? 0xDD : 0xFD;
  9.1285 +		return ld_HL;
  9.1286 +	}
  9.1287 +	if (i == ld_NN)
  9.1288 +		readword = nn;
  9.1289 +	return i;
  9.1290  }
  9.1291  
  9.1292  /* read first argument of JP */
  9.1293 -static int
  9.1294 -rd_jp (const char **p)
  9.1295 -{
  9.1296 -  int i;
  9.1297 -  const char *list[] = {
  9.1298 -    "nz", "z", "nc", "c", "po", "pe", "p", "m", "( ix )", "( iy )",
  9.1299 -    "(hl)", NULL
  9.1300 -  };
  9.1301 -  i = indx (p, list, 0, NULL);
  9.1302 -  if (i < 9)
  9.1303 -    return i;
  9.1304 -  if (i == 11)
  9.1305 -    return -1;
  9.1306 -  indexed = 0xDD + 0x20 * (i - 9);
  9.1307 -  return -1;
  9.1308 +static int rd_jp (const char **p) {
  9.1309 +	int i;
  9.1310 +	const char *list[] = {
  9.1311 +		"nz", "z", "nc", "c", "po", "pe", "p", "m", "( ix )", "( iy )",
  9.1312 +		"(hl)", NULL
  9.1313 +	};
  9.1314 +	i = indx (p, list, 0, NULL);
  9.1315 +	if (i < 9)
  9.1316 +		return i;
  9.1317 +	if (i == 11)
  9.1318 +		return -1;
  9.1319 +	indexed = 0xDD + 0x20 * (i - 9);
  9.1320 +	return -1;
  9.1321  }
  9.1322  
  9.1323  /* read first argument of JR */
  9.1324 -static int
  9.1325 -rd_jr (const char **p)
  9.1326 -{
  9.1327 -  const char *list[] = { "nz", "z", "nc", "c", NULL };
  9.1328 -  return indx (p, list, 0, NULL);
  9.1329 +static int rd_jr (const char **p) {
  9.1330 +	const char *list[] = { "nz", "z", "nc", "c", NULL };
  9.1331 +	return indx (p, list, 0, NULL);
  9.1332  }
  9.1333  
  9.1334  /* read A */
  9.1335 -static int
  9.1336 -rd_a (const char **p)
  9.1337 -{
  9.1338 -  const char *list[] = { "a", NULL };
  9.1339 -  return indx (p, list, 1, NULL);
  9.1340 +static int rd_a (const char **p) {
  9.1341 +	const char *list[] = { "a", NULL };
  9.1342 +	return indx (p, list, 1, NULL);
  9.1343  }
  9.1344  
  9.1345  /* read bc,de,hl,af */
  9.1346 -static int
  9.1347 -rd_stack (const char **p)
  9.1348 -{
  9.1349 -  int i;
  9.1350 -  const char *list[] = { "bc", "de", "hl", "af", "ix", "iy", NULL };
  9.1351 -  i = indx (p, list, 1, NULL);
  9.1352 -  if (i < 5)
  9.1353 -    return i;
  9.1354 -  indexed = 0xDD + 0x20 * (i - 5);
  9.1355 -  return 3;
  9.1356 +static int rd_stack (const char **p) {
  9.1357 +	int i;
  9.1358 +	const char *list[] = { "bc", "de", "hl", "af", "ix", "iy", NULL };
  9.1359 +	i = indx (p, list, 1, NULL);
  9.1360 +	if (i < 5)
  9.1361 +		return i;
  9.1362 +	indexed = 0xDD + 0x20 * (i - 5);
  9.1363 +	return 3;
  9.1364  }
  9.1365  
  9.1366  #if 0
  9.1367 @@ -1055,672 +569,359 @@
  9.1368  /* read b,c,d,e,h,l,(hl),a,(ix+nn),(iy+nn),nn 
  9.1369   * but now with extra hl or i[xy](15) for add-instruction
  9.1370   * and set variables accordingly */
  9.1371 -static int
  9.1372 -rd_r_add (const char **p)
  9.1373 -{
  9.1374 +static int rd_r_add (const char **p) {
  9.1375  #define addHL 	15
  9.1376 -  int i;
  9.1377 -  const char *list[] = {
  9.1378 -    "ixl", "ixh", "iyl", "iyh", "b", "c", "d", "e", "h", "l",
  9.1379 -    "( hl )", "a", "( ix +)", "( iy +)", "hl", "ix", "iy", "*", NULL
  9.1380 -  };
  9.1381 -  const char *nn;
  9.1382 -  i = indx (p, list, 0, &nn);
  9.1383 -  if (i == 18)	/* expression */
  9.1384 -    {
  9.1385 -      readbyte = nn;
  9.1386 -      writebyte = 1;
  9.1387 -      return 7;
  9.1388 -    }
  9.1389 -  if (i > 14)	/* hl, ix, iy */
  9.1390 -    {
  9.1391 -      if (i > 15)
  9.1392 -	indexed = 0xDD + 0x20 * (i - 16);
  9.1393 -      return addHL;
  9.1394 -    }
  9.1395 -  if (i <= 4)	/* i[xy][hl]  */
  9.1396 -    {
  9.1397 -      indexed = 0xdd + 0x20 * (i > 2);
  9.1398 -      return 6 - (i & 1);
  9.1399 -    }
  9.1400 -  i -= 4;
  9.1401 -  if (i < 9)
  9.1402 -    return i;
  9.1403 -  indexed = 0xDD + 0x20 * (i - 9);	/* (i[xy] +) */
  9.1404 -  indexjmp = nn;
  9.1405 -  return 7;
  9.1406 +	int i;
  9.1407 +	const char *list[] = {
  9.1408 +		"ixl", "ixh", "iyl", "iyh", "b", "c", "d", "e", "h", "l",
  9.1409 +		"( hl )", "a", "( ix +)", "( iy +)", "hl", "ix", "iy", "*", NULL
  9.1410 +	};
  9.1411 +	const char *nn;
  9.1412 +	i = indx (p, list, 0, &nn);
  9.1413 +	if (i == 18) { /* expression */
  9.1414 +		readbyte = nn;
  9.1415 +		writebyte = 1;
  9.1416 +		return 7;
  9.1417 +	}
  9.1418 +	if (i > 14) { /* hl, ix, iy */
  9.1419 +		if (i > 15)
  9.1420 +			indexed = 0xDD + 0x20 * (i - 16);
  9.1421 +		return addHL;
  9.1422 +	}
  9.1423 +	if (i <= 4) {/* i[xy][hl]  */
  9.1424 +		indexed = 0xdd + 0x20 * (i > 2);
  9.1425 +		return 6 - (i & 1);
  9.1426 +	}
  9.1427 +	i -= 4;
  9.1428 +	if (i < 9)
  9.1429 +		return i;
  9.1430 +	indexed = 0xDD + 0x20 * (i - 9);	/* (i[xy] +) */
  9.1431 +	indexjmp = nn;
  9.1432 +	return 7;
  9.1433  }
  9.1434  
  9.1435  /* read bc,de,hl, or sp */
  9.1436 -static int
  9.1437 -rd_rr_ (const char **p)
  9.1438 -{
  9.1439 -  const char *list[] = { "bc", "de", "hl", "sp", NULL };
  9.1440 -  return indx (p, list, 1, NULL);
  9.1441 +static int rd_rr_ (const char **p) {
  9.1442 +	const char *list[] = { "bc", "de", "hl", "sp", NULL };
  9.1443 +	return indx (p, list, 1, NULL);
  9.1444  }
  9.1445  
  9.1446  /* read bc,de,hl|ix|iy,sp. hl|ix|iy only if it is already indexed the same. */
  9.1447 -static int
  9.1448 -rd_rrxx (const char **p)
  9.1449 -{
  9.1450 -  const char *listx[] = { "bc", "de", "ix", "sp", NULL };
  9.1451 -  const char *listy[] = { "bc", "de", "iy", "sp", NULL };
  9.1452 -  const char *list[] = { "bc", "de", "hl", "sp", NULL };
  9.1453 -  switch (indexed)
  9.1454 -    {
  9.1455 -    case 0xDD:
  9.1456 -      return indx (p, listx, 1, NULL);
  9.1457 -    case 0xFD:
  9.1458 -      return indx (p, listy, 1, NULL);
  9.1459 -    default:
  9.1460 -      return indx (p, list, 1, NULL);
  9.1461 -    }
  9.1462 +static int rd_rrxx (const char **p) {
  9.1463 +	const char *listx[] = { "bc", "de", "ix", "sp", NULL };
  9.1464 +	const char *listy[] = { "bc", "de", "iy", "sp", NULL };
  9.1465 +	const char *list[] = { "bc", "de", "hl", "sp", NULL };
  9.1466 +	switch (indexed) {
  9.1467 +	case 0xDD:
  9.1468 +		return indx (p, listx, 1, NULL);
  9.1469 +	case 0xFD:
  9.1470 +		return indx (p, listy, 1, NULL);
  9.1471 +	default:
  9.1472 +		return indx (p, list, 1, NULL);
  9.1473 +	}
  9.1474  }
  9.1475  
  9.1476  /* read b,c,d,e,h,l,(hl),a,(ix+nn),(iy+nn),nn
  9.1477   * and set variables accordingly */
  9.1478 -static int
  9.1479 -rd_r (const char **p)
  9.1480 -{
  9.1481 -  int i;
  9.1482 -  const char *list[] = {
  9.1483 -    "ixl", "ixh", "iyl", "iyh", "b", "c", "d", "e", "h", "l", "( hl )",
  9.1484 -    "a", "( ix +)", "( iy +)", "*", NULL
  9.1485 -  };
  9.1486 -  const char *nn;
  9.1487 -  i = indx (p, list, 0, &nn);
  9.1488 -  if (i == 15)	/* expression */
  9.1489 -    {
  9.1490 -      readbyte = nn;
  9.1491 -      writebyte = 1;
  9.1492 -      return 7;
  9.1493 -    }
  9.1494 -  if (i <= 4)
  9.1495 -    {
  9.1496 -      indexed = 0xdd + 0x20 * (i > 2);
  9.1497 -      return 6 - (i & 1);
  9.1498 -    }
  9.1499 -  i -= 4;
  9.1500 -  if (i < 9)
  9.1501 -    return i;
  9.1502 -  indexed = 0xDD + 0x20 * (i - 9);
  9.1503 -  indexjmp = nn;
  9.1504 -  return 7;
  9.1505 +static int rd_r (const char **p) {
  9.1506 +	int i;
  9.1507 +	const char *nn;
  9.1508 +	const char *list[] = {
  9.1509 +		"ixl", "ixh", "iyl", "iyh", "b", "c", "d", "e", "h", "l", "( hl )",
  9.1510 +		"a", "( ix +)", "( iy +)", "*", NULL
  9.1511 +	};
  9.1512 +	i = indx (p, list, 0, &nn);
  9.1513 +	if (i == 15) { /* expression */
  9.1514 +		readbyte = nn;
  9.1515 +		writebyte = 1;
  9.1516 +		return 7;
  9.1517 +	}
  9.1518 +	if (i <= 4) {
  9.1519 +		indexed = 0xdd + 0x20 * (i > 2);
  9.1520 +		return 6 - (i & 1);
  9.1521 +	}
  9.1522 +	i -= 4;
  9.1523 +	if (i < 9)
  9.1524 +		return i;
  9.1525 +	indexed = 0xDD + 0x20 * (i - 9);
  9.1526 +	indexjmp = nn;
  9.1527 +	return 7;
  9.1528  }
  9.1529  
  9.1530  /* like rd_r(), but without nn */
  9.1531 -static int
  9.1532 -rd_r_ (const char **p)
  9.1533 -{
  9.1534 -  int i;
  9.1535 -  const char *list[] = {
  9.1536 -    "b", "c", "d", "e", "h", "l", "( hl )", "a", "( ix +)", "( iy +)", NULL
  9.1537 -  };
  9.1538 -  i = indx (p, list, 1, &indexjmp);
  9.1539 -  if (i < 9)
  9.1540 -    return i;
  9.1541 -  indexed = 0xDD + 0x20 * (i - 9);
  9.1542 -  return 7;
  9.1543 +static int rd_r_ (const char **p) {
  9.1544 +	int i;
  9.1545 +	const char *list[] = {
  9.1546 +		"b", "c", "d", "e", "h", "l", "( hl )", "a", "( ix +)", "( iy +)", NULL
  9.1547 +	};
  9.1548 +	i = indx (p, list, 1, &indexjmp);
  9.1549 +	if (i < 9)
  9.1550 +		return i;
  9.1551 +	indexed = 0xDD + 0x20 * (i - 9);
  9.1552 +	return 7;
  9.1553  }
  9.1554  
  9.1555  /* read a number from 0 to 7, for bit, set or res */
  9.1556 -static int
  9.1557 -rd_0_7 (const char **p)
  9.1558 -{
  9.1559 -  *p = delspc (*p);
  9.1560 -  if (**p == 0)
  9.1561 -    return 0;
  9.1562 -  bitsetres = *p;
  9.1563 -  skipword (p, ',');
  9.1564 -  return 1;
  9.1565 +static int rd_0_7 (const char **p) {
  9.1566 +	*p = delspc (*p);
  9.1567 +	if (**p == 0)
  9.1568 +		return 0;
  9.1569 +	bitsetres = *p;
  9.1570 +	skipword (p, ',');
  9.1571 +	return 1;
  9.1572  }
  9.1573  
  9.1574  /* read long condition. do not error if not found. */
  9.1575 -static int
  9.1576 -rd_cc (const char **p)
  9.1577 -{
  9.1578 -  const char *list[] = { "nz", "z", "nc", "c", "po", "pe", "p", "m", NULL };
  9.1579 -  return indx (p, list, 0, NULL);
  9.1580 +static int rd_cc (const char **p) {
  9.1581 +	const char *list[] = { "nz", "z", "nc", "c", "po", "pe", "p", "m", NULL };
  9.1582 +	return indx (p, list, 0, NULL);
  9.1583  }
  9.1584  
  9.1585  /* read long or short register,  */
  9.1586 -static int
  9.1587 -rd_r_rr (const char **p)
  9.1588 -{
  9.1589 -  int i;
  9.1590 -  const char *list[] = {
  9.1591 -    "iy", "ix", "sp", "hl", "de", "bc", "", "b", "c", "d", "e", "h",
  9.1592 -    "l", "( hl )", "a", "( ix +)", "( iy +)", NULL
  9.1593 -  };
  9.1594 -  i = indx (p, list, 1, &indexjmp);
  9.1595 -  if (!i)
  9.1596 -    return 0;
  9.1597 -  if (i < 16 && i > 2)
  9.1598 -    return 7 - i;
  9.1599 -  if (i > 15)
  9.1600 -    {
  9.1601 -      indexed = 0xDD + (i - 16) * 0x20;
  9.1602 -      return -7;
  9.1603 -    }
  9.1604 -  indexed = 0xDD + (2 - i) * 0x20;
  9.1605 -  return 3;
  9.1606 +static int rd_r_rr (const char **p) {
  9.1607 +	int i;
  9.1608 +	const char *list[] = {
  9.1609 +		"iy", "ix", "sp", "hl", "de", "bc", "", "b", "c", "d", "e", "h",
  9.1610 +		"l", "( hl )", "a", "( ix +)", "( iy +)", NULL
  9.1611 +	};
  9.1612 +	i = indx (p, list, 1, &indexjmp);
  9.1613 +	if (!i)
  9.1614 +		return 0;
  9.1615 +	if (i < 16 && i > 2)
  9.1616 +		return 7 - i;
  9.1617 +	if (i > 15) {
  9.1618 +		indexed = 0xDD + (i - 16) * 0x20;
  9.1619 +		return -7;
  9.1620 +	}
  9.1621 +	indexed = 0xDD + (2 - i) * 0x20;
  9.1622 +	return 3;
  9.1623  }
  9.1624  
  9.1625  /* read hl */
  9.1626 -static int
  9.1627 -rd_hl (const char **p)
  9.1628 -{
  9.1629 -  const char *list[] = { "hl", NULL };
  9.1630 -  return indx (p, list, 1, NULL);
  9.1631 +static int rd_hl (const char **p) {
  9.1632 +	const char *list[] = { "hl", NULL };
  9.1633 +	return indx (p, list, 1, NULL);
  9.1634  }
  9.1635  
  9.1636  /* read hl, ix, or iy */
  9.1637 -static int
  9.1638 -rd_hlx (const char **p)
  9.1639 -{
  9.1640 -  int i;
  9.1641 -  const char *list[] = { "hl", "ix", "iy", NULL };
  9.1642 -  i = indx (p, list, 1, NULL);
  9.1643 -  if (i < 2)
  9.1644 -    return i;
  9.1645 -  indexed = 0xDD + 0x20 * (i - 2);
  9.1646 -  return 1;
  9.1647 +static int rd_hlx (const char **p) {
  9.1648 +	int i;
  9.1649 +	const char *list[] = { "hl", "ix", "iy", NULL };
  9.1650 +	i = indx (p, list, 1, NULL);
  9.1651 +	if (i < 2)
  9.1652 +		return i;
  9.1653 +	indexed = 0xDD + 0x20 * (i - 2);
  9.1654 +	return 1;
  9.1655  }
  9.1656  
  9.1657  /* read af' */
  9.1658 -static int
  9.1659 -rd_af_ (const char **p)
  9.1660 -{
  9.1661 -  const char *list[] = { "af'", NULL };
  9.1662 -  return indx (p, list, 1, NULL);
  9.1663 +static int rd_af_ (const char **p) {
  9.1664 +	const char *list[] = { "af'", NULL };
  9.1665 +	return indx (p, list, 1, NULL);
  9.1666  }
  9.1667  
  9.1668  /* read 0(1), 1(3), or 2(4) */
  9.1669 -static int
  9.1670 -rd_0_2 (const char **p)
  9.1671 -{
  9.1672 -  const char *list[] = { "0", "", "1", "2", NULL };
  9.1673 -  return indx (p, list, 1, NULL);
  9.1674 +static int rd_0_2 (const char **p) {
  9.1675 +	const char *list[] = { "0", "", "1", "2", NULL };
  9.1676 +	return indx (p, list, 1, NULL);
  9.1677  }
  9.1678  
  9.1679  /* read argument of ld (hl), */
  9.1680 -static int
  9.1681 -rd_ld_hl (const char **p)
  9.1682 -{
  9.1683 -  int i;
  9.1684 -  const char *list[] = { "b", "c", "d", "e", "h", "l", "", "a", "*", NULL };
  9.1685 -  i = indx (p, list, 0, &readbyte);
  9.1686 -  if (i < 9)
  9.1687 -    return i;
  9.1688 -  writebyte = 1;
  9.1689 -  return 7;
  9.1690 +static int rd_ld_hl (const char **p) {
  9.1691 +	int i;
  9.1692 +	const char *list[] = { "b", "c", "d", "e", "h", "l", "", "a", "*", NULL };
  9.1693 +	i = indx (p, list, 0, &readbyte);
  9.1694 +	if (i < 9)
  9.1695 +		return i;
  9.1696 +	writebyte = 1;
  9.1697 +	return 7;
  9.1698  }
  9.1699  
  9.1700  /* read argument of ld (nnnn), */
  9.1701 -static int
  9.1702 -rd_ld_nn (const char **p)
  9.1703 -{
  9.1704 +static int rd_ld_nn (const char **p) {
  9.1705  #define ld_nnHL 5
  9.1706  #define ld_nnA 6
  9.1707 -  int i;
  9.1708 -  const char *list[] = { "bc", "de", "", "sp", "hl", "a", "ix", "iy", NULL };
  9.1709 -  i = indx (p, list, 1, NULL);
  9.1710 -  if (i < 7)
  9.1711 -    return i;
  9.1712 -  indexed = 0xdd + 0x20 * (i == 8);
  9.1713 -  return ld_nnHL;
  9.1714 +	int i;
  9.1715 +	const char *list[] = { "bc", "de", "", "sp", "hl", "a", "ix", "iy", NULL };
  9.1716 +	i = indx (p, list, 1, NULL);
  9.1717 +	if (i < 7)
  9.1718 +		return i;
  9.1719 +	indexed = 0xdd + 0x20 * (i == 8);
  9.1720 +	return ld_nnHL;
  9.1721  }
  9.1722  
  9.1723  /* read argument of ld a, */
  9.1724 -static int
  9.1725 -rd_lda (const char **p)
  9.1726 -{
  9.1727 +static int rd_lda (const char **p) {
  9.1728  #define A_I 9
  9.1729  #define A_R 10
  9.1730  #define A_NN 11
  9.1731 -  int i;
  9.1732 -  const char *list[] = {
  9.1733 -    "( sp )", "( iy +)", "( de )", "( bc )", "( ix +)", "b", "c", "d", "e", "h",
  9.1734 -    "l", "( hl )", "a", "i", "r", "(*)", "*", NULL
  9.1735 -  };
  9.1736 -  const char *nn;
  9.1737 -  i = indx (p, list, 0, &nn);
  9.1738 -  if (i == 2 || i == 5)
  9.1739 -    {
  9.1740 -      indexed = (i == 2) ? 0xFD : 0xDD;
  9.1741 -      indexjmp = nn;
  9.1742 -      return 7;
  9.1743 -    }
  9.1744 -  if (i == 17)
  9.1745 -    {
  9.1746 -      readbyte = nn;
  9.1747 -      writebyte = 1;
  9.1748 -      return 7;
  9.1749 -    }
  9.1750 -  if (i == 16)
  9.1751 -    {
  9.1752 -      readword = nn;
  9.1753 -    }
  9.1754 -  return i - 5;
  9.1755 +	int i;
  9.1756 +	const char *list[] = {
  9.1757 +		"( sp )", "( iy +)", "( de )", "( bc )", "( ix +)", "b", "c", "d", "e", "h",
  9.1758 +		"l", "( hl )", "a", "i", "r", "(*)", "*", NULL
  9.1759 +	};
  9.1760 +	const char *nn;
  9.1761 +	i = indx (p, list, 0, &nn);
  9.1762 +	if (i == 2 || i == 5) {
  9.1763 +		indexed = (i == 2) ? 0xFD : 0xDD;
  9.1764 +		indexjmp = nn;
  9.1765 +		return 7;
  9.1766 +	}
  9.1767 +	if (i == 17) {
  9.1768 +		readbyte = nn;
  9.1769 +		writebyte = 1;
  9.1770 +		return 7;
  9.1771 +	}
  9.1772 +	if (i == 16)
  9.1773 +		readword = nn;
  9.1774 +	return i - 5;
  9.1775  }
  9.1776  
  9.1777  /* read argument of ld b|c|d|e|h|l */
  9.1778 -static int
  9.1779 -rd_ldbcdehla (const char **p)
  9.1780 -{
  9.1781 -  int i;
  9.1782 -  const char *list[] = {
  9.1783 -    "b", "c", "d", "e", "h", "l", "( hl )", "a", "( ix +)", "( iy +)", "ixh",
  9.1784 -    "ixl", "iyh", "iyl", "*", NULL
  9.1785 -  };
  9.1786 -  const char *nn;
  9.1787 -  i = indx (p, list, 0, &nn);
  9.1788 -  if (i == 15)
  9.1789 -    {
  9.1790 -      readbyte = nn;
  9.1791 -      writebyte = 1;
  9.1792 -      return 7;
  9.1793 -    }
  9.1794 -  if (i > 10)
  9.1795 -    {
  9.1796 -      int x;
  9.1797 -      x = 0xdd + 0x20 * (i > 12);
  9.1798 -      if (indexed && indexed != x)
  9.1799 -	{
  9.1800 -	  printerr (1, "illegal use of index registers\n");
  9.1801 -	  return 0;
  9.1802 +static int rd_ldbcdehla (const char **p) {
  9.1803 +	int i;
  9.1804 +	const char *list[] = {
  9.1805 +		"b", "c", "d", "e", "h", "l", "( hl )", "a", "( ix +)", "( iy +)", "ixh",
  9.1806 +		"ixl", "iyh", "iyl", "*", NULL
  9.1807 +	};
  9.1808 +	const char *nn;
  9.1809 +	i = indx (p, list, 0, &nn);
  9.1810 +	if (i == 15) {
  9.1811 +		readbyte = nn;
  9.1812 +		writebyte = 1;
  9.1813 +		return 7;
  9.1814  	}
  9.1815 -      indexed = x;
  9.1816 -      return 6 - (i & 1);
  9.1817 -    }
  9.1818 -  if (i > 8)
  9.1819 -    {
  9.1820 -      if (indexed)
  9.1821 -	{
  9.1822 -	  printerr (1, "illegal use of index registers\n");
  9.1823 -	  return 0;
  9.1824 +	if (i > 10) {
  9.1825 +		int x;
  9.1826 +		x = 0xdd + 0x20 * (i > 12);
  9.1827 +		if (indexed && indexed != x) {
  9.1828 +			printerr (1, "illegal use of index registers\n");
  9.1829 +			return 0;
  9.1830 +		}
  9.1831 +		indexed = x;
  9.1832 +		return 6 - (i & 1);
  9.1833  	}
  9.1834 -      indexed = 0xDD + 0x20 * (i == 10);
  9.1835 -      indexjmp = nn;
  9.1836 -      return 7;
  9.1837 -    }
  9.1838 -  return i;
  9.1839 +	if (i > 8) {
  9.1840 +		if (indexed) {
  9.1841 +			printerr (1, "illegal use of index registers\n");
  9.1842 +			return 0;
  9.1843 +		}
  9.1844 +		indexed = 0xDD + 0x20 * (i == 10);
  9.1845 +		indexjmp = nn;
  9.1846 +		return 7;
  9.1847 +	}
  9.1848 +	return i;
  9.1849  }
  9.1850  
  9.1851  /* read nnnn, or (nnnn) */
  9.1852 -static int
  9.1853 -rd_nn_nn (const char **p)
  9.1854 -{
  9.1855 +static int rd_nn_nn (const char **p) {
  9.1856  #define _NN 1
  9.1857 -  const char *list[] = { "(*)", "*", NULL };
  9.1858 -  return 2 - indx (p, list, 0, &readword);
  9.1859 +	const char *list[] = { "(*)", "*", NULL };
  9.1860 +	return 2 - indx (p, list, 0, &readword);
  9.1861  }
  9.1862  
  9.1863  /* read {HL|IX|IY},nnnn, or (nnnn) */
  9.1864 -static int
  9.1865 -rd_sp (const char **p)
  9.1866 -{
  9.1867 +static int rd_sp (const char **p) {
  9.1868  #define SPNN 0
  9.1869  #define SPHL 1
  9.1870 -  int i;
  9.1871 -  const char *list[] = { "hl", "ix", "iy", "(*)", "*", NULL };
  9.1872 -  const char *nn;
  9.1873 -  i = indx (p, list, 0, &nn);
  9.1874 -  if (i > 3)
  9.1875 -    {
  9.1876 -      readword = nn;
  9.1877 -      return i == 4 ? 2 : 0;
  9.1878 -    }
  9.1879 -  if (i != 1)
  9.1880 -    indexed = 0xDD + 0x20 * (i - 2);
  9.1881 -  return 1;
  9.1882 +	int i;
  9.1883 +	const char *list[] = { "hl", "ix", "iy", "(*)", "*", NULL };
  9.1884 +	const char *nn;
  9.1885 +	i = indx (p, list, 0, &nn);
  9.1886 +	if (i > 3) {
  9.1887 +		readword = nn;
  9.1888 +		return i == 4 ? 2 : 0;
  9.1889 +	}
  9.1890 +	if (i != 1)
  9.1891 +		indexed = 0xDD + 0x20 * (i - 2);
  9.1892 +	return 1;
  9.1893  }
  9.1894  
  9.1895  /* write a reference after it has been computed */
  9.1896 -static void
  9.1897 -wrt_ref (int val, int type, int count)
  9.1898 -{
  9.1899 -  switch (type)
  9.1900 -    {
  9.1901 -    case TYPE_RST:
  9.1902 -      if ((val & 0x38) != val)
  9.1903 -	{
  9.1904 -	  printerr (1, "incorrect RST value %d (0x%02x)\n", val, val);
  9.1905 -	  return;
  9.1906 +static void wrt_ref (int val, int type, int count) {
  9.1907 +	switch (type) {
  9.1908 +	case TYPE_RST:
  9.1909 +		if ((val & 0x38) != val) {
  9.1910 +			printerr (1, "incorrect RST value %d (0x%02x)\n", val, val);
  9.1911 +			return;
  9.1912 +		}
  9.1913 +		write_one_byte (val + 0xC7, 1);
  9.1914 +		return;
  9.1915 +	case TYPE_ABSW:
  9.1916 +		if (val < -0x8000 || val >= 0x10000)
  9.1917 +			printerr (0, "word value %d (0x%x) truncated\n", val, val);
  9.1918 +		write_one_byte (val & 0xff, 1);
  9.1919 +		write_one_byte ((val >> 8) & 0xff, 1);
  9.1920 +		return;
  9.1921 +	case TYPE_ABSB:
  9.1922 +		if (val < -0x80 || val >= 0x100)
  9.1923 +			printerr (0, "byte value %d (0x%x) truncated\n", val, val);
  9.1924 +		write_one_byte (val & 0xff, 1);
  9.1925 +		return;
  9.1926 +	case TYPE_DS:
  9.1927 +		if (val < -0x80 || val >= 0x100)
  9.1928 +			printerr (0, "byte value %d (0x%x) truncated\n", val, val);
  9.1929 +		if (havelist) {
  9.1930 +			fprintf (listfile, " 0x%02x...", val & 0xff);
  9.1931 +			listdepth += 6;
  9.1932 +		}
  9.1933 +		while (count--)
  9.1934 +			write_one_byte (val & 0xff, 0);
  9.1935 +		return;
  9.1936 +	case TYPE_BSR:
  9.1937 +		if (val & ~7) {
  9.1938 +			printerr (1, "incorrect BIT/SET/RES value %d\n", val);
  9.1939 +			return;
  9.1940 +		}
  9.1941 +		write_one_byte (0x08 * val + count, 1);
  9.1942 +		return;
  9.1943 +	case TYPE_RELB:
  9.1944 +		val -= count;
  9.1945 +		if (val & 0xff80 && ~val & 0xff80) {
  9.1946 +			printerr (1, "relative jump out of range (%d)\n", val);
  9.1947 +		}
  9.1948 +		write_one_byte (val & 0xff, 1);
  9.1949 +		return;
  9.1950 +	case TYPE_LABEL:
  9.1951 +		printerr (1, "bug in the assembler: trying to write label reference.  "
  9.1952 +				"Please report.\n");
  9.1953 +		return;
  9.1954  	}
  9.1955 -      write_one_byte (val + 0xC7, 1);
  9.1956 -      return;
  9.1957 -    case TYPE_ABSW:
  9.1958 -      if (val < -0x8000 || val >= 0x10000)
  9.1959 -	printerr (0, "word value %d (0x%x) truncated\n", val, val);
  9.1960 -      write_one_byte (val & 0xff, 1);
  9.1961 -      write_one_byte ((val >> 8) & 0xff, 1);
  9.1962 -      return;
  9.1963 -    case TYPE_ABSB:
  9.1964 -      if (val < -0x80 || val >= 0x100)
  9.1965 -	printerr (0, "byte value %d (0x%x) truncated\n", val, val);
  9.1966 -      write_one_byte (val & 0xff, 1);
  9.1967 -      return;
  9.1968 -    case TYPE_DS:
  9.1969 -      if (val < -0x80 || val >= 0x100)
  9.1970 -	printerr (0, "byte value %d (0x%x) truncated\n", val, val);
  9.1971 -      if (havelist)
  9.1972 -	{
  9.1973 -	  fprintf (listfile, " 0x%02x...", val & 0xff);
  9.1974 -	  listdepth += 6;
  9.1975 -	}
  9.1976 -      while (count--)
  9.1977 -	{
  9.1978 -	  write_one_byte (val & 0xff, 0);
  9.1979 -	}
  9.1980 -      return;
  9.1981 -    case TYPE_BSR:
  9.1982 -      if (val & ~7)
  9.1983 -	{
  9.1984 -	  printerr (1, "incorrect BIT/SET/RES value %d\n", val);
  9.1985 -	  return;
  9.1986 -	}
  9.1987 -      write_one_byte (0x08 * val + count, 1);
  9.1988 -      return;
  9.1989 -    case TYPE_RELB:
  9.1990 -      val -= count;
  9.1991 -      if (val & 0xff80 && ~val & 0xff80) 
  9.1992 -	{
  9.1993 -	  printerr (1, "relative jump out of range (%d)\n", val);
  9.1994 -	}
  9.1995 -      write_one_byte (val & 0xff, 1);
  9.1996 -      return;
  9.1997 -    case TYPE_LABEL:
  9.1998 -      printerr (1, "bug in the assembler: trying to write label reference.  "
  9.1999 -		"Please report.\n");
  9.2000 -      return;
  9.2001 -    }
  9.2002 -}
  9.2003 -
  9.2004 -static char *
  9.2005 -get_include_name (const char **ptr)
  9.2006 -{
  9.2007 -  int pos = 0;
  9.2008 -  char quote;
  9.2009 -  char *name;
  9.2010 -  *ptr = delspc (*ptr);
  9.2011 -  name = malloc (strlen (*ptr));
  9.2012 -  if (!name)
  9.2013 -    {
  9.2014 -      printerr (1, "unable to allocate memory for filename %.*s\n",
  9.2015 -		strlen (*ptr) - 1, *ptr);
  9.2016 -      return NULL;
  9.2017 -    }
  9.2018 -  if (!**ptr)
  9.2019 -    {
  9.2020 -      printerr (1, "include without filename\n");
  9.2021 -      free (name);
  9.2022 -      return NULL;
  9.2023 -    }
  9.2024 -  quote = *(*ptr)++;
  9.2025 -  while (**ptr != quote)
  9.2026 -    {
  9.2027 -      if (!**ptr)
  9.2028 -	{
  9.2029 -	  printerr (1, "filename without closing quote (%c)\n", quote);
  9.2030 -	  free (name);
  9.2031 -	  return NULL;
  9.2032 -	}
  9.2033 -      name[pos++] = *(*ptr)++;
  9.2034 -    }
  9.2035 -  name[pos] = 0;
  9.2036 -  ++*ptr;
  9.2037 -  return name;
  9.2038 -}
  9.2039 -
  9.2040 -static int
  9.2041 -read_line (void)
  9.2042 -{
  9.2043 -  unsigned pos, newpos, size;
  9.2044 -  struct macro_arg *arg;
  9.2045 -  if (stack[sp].file)
  9.2046 -    {
  9.2047 -      FILE *f = stack[sp].file;
  9.2048 -      static char short_buffer[BUFLEN + 1];
  9.2049 -      if (buffer && buffer != short_buffer)
  9.2050 -	free (buffer);
  9.2051 -      buffer = NULL;
  9.2052 -      if (!fgets (short_buffer, BUFLEN + 1, f))
  9.2053 -	return 0;
  9.2054 -      if (strlen (short_buffer) < BUFLEN)
  9.2055 -	{
  9.2056 -	  buffer = short_buffer;
  9.2057 -	  return 1;
  9.2058 -	}
  9.2059 -      size = 2 * BUFLEN;
  9.2060 -      buffer = malloc (size + 1);
  9.2061 -      if (!buffer)
  9.2062 -	{
  9.2063 -	  printerr (1, "out of memory reading line\n");
  9.2064 -	  return 0;
  9.2065 -	}
  9.2066 -      memcpy (buffer, short_buffer, BUFLEN + 1);
  9.2067 -      while (1)
  9.2068 -	{
  9.2069 -	  char *b;
  9.2070 -	  if (!fgets (&buffer[size - BUFLEN], BUFLEN + 1, f)
  9.2071 -	      || (buffer[strlen (buffer) - 1] == '\n'))
  9.2072 -	    {
  9.2073 -	      return 1;
  9.2074 -	    }
  9.2075 -	  size += BUFLEN;
  9.2076 -	  b = realloc (buffer, size + 1);
  9.2077 -	  if (!b)
  9.2078 -	    {
  9.2079 -	      printerr (1, "out of memory reading line\n");
  9.2080 -	      return 0;
  9.2081 -	    }
  9.2082 -	  buffer = b;
  9.2083 -	}
  9.2084 -    }
  9.2085 -  /* macro line */
  9.2086 -  if (!stack[sp].macro_line)
  9.2087 -    {
  9.2088 -      unsigned i;
  9.2089 -      for (i = 0; i < stack[sp].macro->numargs; ++i)
  9.2090 -	free (stack[sp].macro_args[i]);
  9.2091 -      free (stack[sp].macro_args);
  9.2092 -      return 0;
  9.2093 -    }
  9.2094 -  size = strlen (stack[sp].macro_line->line) + 1;
  9.2095 -  for (arg = stack[sp].macro_line->args; arg; arg = arg->next)
  9.2096 -    size += strlen (stack[sp].macro_args[arg->which]);
  9.2097 -  buffer = malloc (size);
  9.2098 -  if (!buffer)
  9.2099 -    {
  9.2100 -      printerr (1, "out of memory\n");
  9.2101 -      return 0;
  9.2102 -    }
  9.2103 -  pos = 0;
  9.2104 -  newpos = 0;
  9.2105 -  for (arg = stack[sp].macro_line->args; arg; arg = arg->next)
  9.2106 -    {
  9.2107 -      memcpy (&buffer[newpos], &stack[sp].macro_line->line[pos],
  9.2108 -	      arg->pos - pos);
  9.2109 -      newpos += arg->pos - pos;
  9.2110 -      strcpy (&buffer[newpos], stack[sp].macro_args[arg->which]);
  9.2111 -      newpos += strlen (stack[sp].macro_args[arg->which]);
  9.2112 -      pos = arg->pos + 1;
  9.2113 -    }
  9.2114 -  strcpy (&buffer[newpos], &stack[sp].macro_line->line[pos]);
  9.2115 -  stack[sp].macro_line = stack[sp].macro_line->next;
  9.2116 -  return 1;
  9.2117 -}
  9.2118 -
  9.2119 -static unsigned
  9.2120 -get_macro_args (const char **ptr, char ***ret_args, int allow_empty)
  9.2121 -{
  9.2122 -  unsigned numargs = 0;
  9.2123 -  *ret_args = NULL;
  9.2124 -  while (1)
  9.2125 -    {
  9.2126 -      char **args;
  9.2127 -      const char *c;
  9.2128 -      *ptr = delspc (*ptr);
  9.2129 -      if (!**ptr)
  9.2130 -	break;
  9.2131 -      c = *ptr;
  9.2132 -      for (; **ptr && !strchr (" \r\n\t,;", **ptr); ++*ptr)
  9.2133 -	{
  9.2134 -	}
  9.2135 -      if (*ptr == c && !allow_empty)
  9.2136 -	{
  9.2137 -	  printerr (1, "empty macro argument\n");
  9.2138 -	  break;
  9.2139 -	}
  9.2140 -      ++numargs;
  9.2141 -      args = realloc (*ret_args, sizeof (char *) * numargs);
  9.2142 -      if (!args)
  9.2143 -	{
  9.2144 -	  printerr (1, "out of memory\n");
  9.2145 -	  --numargs;
  9.2146 -	  break;
  9.2147 -	}
  9.2148 -      *ret_args = args;
  9.2149 -      args[numargs - 1] = malloc (*ptr - c + 1);
  9.2150 -      if (!args[numargs - 1])
  9.2151 -	{
  9.2152 -	  printerr (1, "out of memory\n");
  9.2153 -	  --numargs;
  9.2154 -	  break;
  9.2155 -	}
  9.2156 -      memcpy (args[numargs - 1], c, *ptr - c);
  9.2157 -      args[numargs - 1][*ptr - c] = 0;
  9.2158 -    }
  9.2159 -  return numargs;
  9.2160  }
  9.2161  
  9.2162  /* do the actual work */
  9.2163 -static void
  9.2164 -assemble (void)
  9.2165 -{
  9.2166 -  int ifcount = 0, noifcount = 0;
  9.2167 -  const char *ptr;
  9.2168 -  struct label *l;
  9.2169 -  char *bufptr;
  9.2170 -  int r, s;			/* registers */
  9.2171 -  /* continue assembling until the last input file is done */
  9.2172 -  for (file = 0; file < infilecount; ++file)
  9.2173 -    {
  9.2174 -      int file_ended = 0;
  9.2175 -      sp = 0;			/* clear stack */
  9.2176 -      stack[sp].line = 0;
  9.2177 -      stack[sp].shouldclose = 0;
  9.2178 -      stack[sp].name = infile[file].name;
  9.2179 -      stack[sp].dir = NULL;
  9.2180 -      if (infile[file].name[0] == '-' && infile[file].name[1] == 0)
  9.2181 -	{
  9.2182 -	  stack[sp].file = stdin;
  9.2183 -	}
  9.2184 -      else
  9.2185 -	{
  9.2186 -	  stack[sp].file = fopen (infile[file].name, "r");
  9.2187 -	  if (!stack[sp].file)
  9.2188 -	    {
  9.2189 -	      printerr (1, "unable to open %s. skipping\n", infile[file].name);
  9.2190 -	      continue;
  9.2191 -	    }
  9.2192 -	  stack[sp].shouldclose = 1;
  9.2193 -	}
  9.2194 -      if (havelist)
  9.2195 -	fprintf (listfile, "# File %s\n", stack[sp].name);
  9.2196 -      if (buffer)
  9.2197 -	buffer[0] = 0;
  9.2198 -      /* loop until this source file is done */
  9.2199 -      while (1)
  9.2200 -	{
  9.2201 -	  int cmd, cont = 1;
  9.2202 -	  if (havelist)
  9.2203 -	    {
  9.2204 -	      if (buffer && buffer[0] != 0)
  9.2205 -		{
  9.2206 -		  int i, tabs;
  9.2207 -		  ptr = delspc (ptr);
  9.2208 -		  if (*ptr != 0)
  9.2209 -		    {
  9.2210 -		      printerr (1, "junk at end of line: %s\n", ptr);
  9.2211 -		    }
  9.2212 -		  if (listdepth < 8)
  9.2213 -		    tabs = 3;
  9.2214 -		  else if (listdepth < 16)
  9.2215 -		    tabs = 2;
  9.2216 -		  else
  9.2217 -		    tabs = 1;
  9.2218 -		  for (i = 0; i < tabs; ++i)
  9.2219 -		    fputc ('\t', listfile);
  9.2220 -		  fprintf (listfile, "%s\n", buffer);
  9.2221 +static int assemble (const char *str, unsigned char *_obuf) {
  9.2222 +	int ifcount = 0, noifcount = 0;
  9.2223 +	const char *ptr;
  9.2224 +	char *bufptr;
  9.2225 +	int r, s;			/* registers */
  9.2226 +
  9.2227 +	obuflen = 0;
  9.2228 +	obuf = _obuf;
  9.2229 +	/* continue assembling until the last input file is done */
  9.2230 +	//for (file = 0; file < infilecount; ++file)
  9.2231 +	do {
  9.2232 +		int file_ended = 0;
  9.2233 +		int cmd, cont = 1;
  9.2234 +		if (havelist) {
  9.2235 +			if (buffer && buffer[0] != 0) {
  9.2236 +				int i, tabs;
  9.2237 +				ptr = delspc (ptr);
  9.2238 +				if (*ptr != 0)
  9.2239 +					printerr (1, "junk at end of line: %s\n", ptr);
  9.2240 +				if (listdepth < 8)
  9.2241 +					tabs = 3;
  9.2242 +				else if (listdepth < 16)
  9.2243 +					tabs = 2;
  9.2244 +				else tabs = 1;
  9.2245 +				for (i = 0; i < tabs; ++i)
  9.2246 +					fputc ('\t', listfile);
  9.2247 +				fprintf (listfile, "%s\n", buffer);
  9.2248 +			}
  9.2249 +			listdepth = 4;
  9.2250  		}
  9.2251 -	      listdepth = 4;
  9.2252 -	    }
  9.2253 -	  /* throw away the rest of the file after end */
  9.2254 -	  if (file_ended)
  9.2255 -	    {
  9.2256 -	      while (read_line ())
  9.2257 -		{
  9.2258 -		  if (havelist)
  9.2259 -		    fprintf (listfile, "\t\t\t%s\n", buffer);
  9.2260 -		}
  9.2261 -	      file_ended = 0;
  9.2262 -	    }
  9.2263 -	  while (!read_line ())
  9.2264 -	    {
  9.2265 -	      struct reference *ref, *nextref;
  9.2266 -	      struct label *next;
  9.2267 -	      if (verbose >= 6)
  9.2268 -		fprintf (stderr, "finished reading file %s\n",
  9.2269 -			 stack[sp].name);
  9.2270 -	      if (havelist)
  9.2271 -		{
  9.2272 -		  if (stack[sp].file)
  9.2273 -		    fprintf (listfile, "# End of file %s\n", stack[sp].name);
  9.2274 -		  else
  9.2275 -		    fprintf (listfile, "# End of macro %s\n", stack[sp].name);
  9.2276 -		}
  9.2277 -	      if (stack[sp].shouldclose)
  9.2278 -		fclose (stack[sp].file);
  9.2279 -	      /* the top of stack is about to be popped off, throwing all
  9.2280 -	       * local labels out of scope.  All references at this level
  9.2281 -	       * which aren't computable are errors.  */
  9.2282 -	      for (ref = firstreference; ref; ref = nextref)
  9.2283 -		{
  9.2284 -		  nextref = ref->next;
  9.2285 -		  compute_ref (ref, 1);
  9.2286 -		  if (ref->done)
  9.2287 -		    continue;
  9.2288 -		  if (ref->level == sp)
  9.2289 -		    if (!ref->level--)
  9.2290 -		      {
  9.2291 -			printerr (1, "unable to resolve reference: %s\n",
  9.2292 -				  ref->input);
  9.2293 -			if (ref->prev)
  9.2294 -			  ref->prev->next = ref->next;
  9.2295 -			else
  9.2296 -			  firstreference = ref->next;
  9.2297 -			if (ref->next)
  9.2298 -			  ref->next->prev = ref->prev;
  9.2299 -			free (ref);
  9.2300 -		      }
  9.2301 -		}
  9.2302 -	      /* Ok, now junk all local labels of the top stack level */
  9.2303 -	      for (l = stack[sp].labels; l; l = next)
  9.2304 -		{
  9.2305 -		  next = l->next;
  9.2306 -		  if (l->ref)
  9.2307 -		    free (l->ref);
  9.2308 -		  free (l);
  9.2309 -		}
  9.2310 -	      stack[sp].labels = NULL;
  9.2311 -	      if (!sp--)
  9.2312 -		{
  9.2313 -		  cont = 0;
  9.2314 -		  break;
  9.2315 -		}
  9.2316 -	    }
  9.2317 +// XXX: must free
  9.2318 +		  buffer = strdup (str);
  9.2319  	  if (!cont)
  9.2320  	    break;		/* break to next source file */
  9.2321  	  if (havelist)
  9.2322 @@ -1750,89 +951,6 @@
  9.2323  	  readbyte = 0;
  9.2324  	  readword = 0;
  9.2325  	  cmd = readcommand (&ptr) - 1;
  9.2326 -	  if (noifcount)
  9.2327 -	    {
  9.2328 -	      switch (cmd)
  9.2329 -		{
  9.2330 -		case IF:
  9.2331 -		  noifcount++;
  9.2332 -		  break;
  9.2333 -		case ELSE:
  9.2334 -		  if (noifcount == 1)
  9.2335 -		    {
  9.2336 -		      noifcount = 0;
  9.2337 -		      ifcount++;
  9.2338 -		    }
  9.2339 -		  break;
  9.2340 -		case ENDIF:
  9.2341 -		  noifcount--;
  9.2342 -		}
  9.2343 -	      ptr = "";
  9.2344 -	      continue;
  9.2345 -	    }
  9.2346 -	  if (define_macro)
  9.2347 -	    {
  9.2348 -	      char *newptr;
  9.2349 -	      struct macro_line **current_line;
  9.2350 -	      for (current_line = &firstmacro->lines; *current_line;
  9.2351 -		   current_line = &(*current_line)->next)
  9.2352 -		{
  9.2353 -		}
  9.2354 -	      *current_line = malloc (sizeof (struct macro_line));
  9.2355 -	      if (!*current_line)
  9.2356 -		{
  9.2357 -		  printerr (1, "out of memory\n");
  9.2358 -		  continue;
  9.2359 -		}
  9.2360 -	      (*current_line)->next = NULL;
  9.2361 -	      (*current_line)->args = NULL;
  9.2362 -	      (*current_line)->line = malloc (strlen (buffer) + 1);
  9.2363 -	      if (!(*current_line)->line)
  9.2364 -		{
  9.2365 -		  printerr (1, "out of memory\n");
  9.2366 -		  free (*current_line);
  9.2367 -		  *current_line = NULL;
  9.2368 -		  continue;
  9.2369 -		}
  9.2370 -	      ptr = buffer;
  9.2371 -	      newptr = (*current_line)->line;
  9.2372 -	      while (*ptr)
  9.2373 -		{
  9.2374 -		  unsigned p;
  9.2375 -		  struct macro_arg **last_arg = &(*current_line)->args;
  9.2376 -		  for (p = 0; p < firstmacro->numargs; ++p)
  9.2377 -		    {
  9.2378 -		      if (strncmp (ptr, firstmacro->args[p],
  9.2379 -				   strlen (firstmacro->args[p])) == 0)
  9.2380 -			{
  9.2381 -			  struct macro_arg *newarg;
  9.2382 -			  newarg = malloc (sizeof (struct macro_arg));
  9.2383 -			  if (!newarg)
  9.2384 -			    {
  9.2385 -			      printerr (1, "out of memory\n");
  9.2386 -			      break;
  9.2387 -			    }
  9.2388 -			  newarg->next = NULL;
  9.2389 -			  *last_arg = newarg;
  9.2390 -			  last_arg = &newarg->next;
  9.2391 -			  newarg->pos = newptr - (*current_line)->line;
  9.2392 -			  newarg->which = p;
  9.2393 -			  /* leave one character so two macros following each
  9.2394 -			   * other keep their order. */
  9.2395 -			  ptr += strlen (firstmacro->args[p]) - 1;
  9.2396 -			  break;
  9.2397 -			}
  9.2398 -		    }
  9.2399 -		  *newptr++ = *ptr++;
  9.2400 -		}
  9.2401 -	      *newptr = 0;
  9.2402 -	      if (verbose >= 7)
  9.2403 -		fprintf (stderr, "added line to macro (cmd = %d): %s\n", cmd,
  9.2404 -			 (*current_line)->line);
  9.2405 -	      if (cmd == ENDM)
  9.2406 -		define_macro = 0;
  9.2407 -	      continue;
  9.2408 -	    }
  9.2409  	  switch (cmd)
  9.2410  	    {
  9.2411  	      int i, have_quote;
  9.2412 @@ -1890,16 +1008,12 @@
  9.2413  	      wrtb (0x40 + (r - 1));
  9.2414  	      break;
  9.2415  	    case CALL:
  9.2416 -	      if (!(r = rd_cc (&ptr)))
  9.2417 -		{
  9.2418 -		  wrtb (0xCD);
  9.2419 -		}
  9.2420 -	      else
  9.2421 -		{
  9.2422 +	      if ((r = rd_cc (&ptr))) {
  9.2423  		  wrtb (0xC4 + 8 * --r);
  9.2424  		  rd_comma (&ptr);
  9.2425 -		}
  9.2426 -	      rd_wrt_addr (&ptr, '\0');
  9.2427 +		} else wrtb (0xCD);
  9.2428 +	      if (!rd_wrt_addr (&ptr, '\0'))
  9.2429 +			return 0;
  9.2430  	      break;
  9.2431  	    case CCF:
  9.2432  	      wrtb (0x3F);
  9.2433 @@ -1934,8 +1048,7 @@
  9.2434  	    case DEC:
  9.2435  	      if (!(r = rd_r_rr (&ptr)))
  9.2436  		break;
  9.2437 -	      if (r < 0)
  9.2438 -		{
  9.2439 +	      if (r < 0) {
  9.2440  		  wrtb (0x05 - 8 * ++r);
  9.2441  		  break;
  9.2442  		}
  9.2443 @@ -1951,25 +1064,6 @@
  9.2444  	    case EI:
  9.2445  	      wrtb (0xFB);
  9.2446  	      break;
  9.2447 -	    case EQU:
  9.2448 -	      if (!lastlabel)
  9.2449 -		{
  9.2450 -		  printerr (1, "EQU without label\n");
  9.2451 -		  break;
  9.2452 -		}
  9.2453 -	      new_reference (ptr, TYPE_LABEL, 0, 0);
  9.2454 -	      if (verbose >= 4)
  9.2455 -		{
  9.2456 -		  if (lastlabel->valid)
  9.2457 -		    fprintf (stderr, "Assigned value %d to label %s.\n",
  9.2458 -			     lastlabel->value, lastlabel->name);
  9.2459 -		  else
  9.2460 -		    fprintf (stderr,
  9.2461 -			     "Scheduled label %s for later computation.\n",
  9.2462 -			     lastlabel->name);
  9.2463 -		}
  9.2464 -	      ptr = "";
  9.2465 -	      break;
  9.2466  	    case EX:
  9.2467  	      if (!(r = rd_ex1 (&ptr)))
  9.2468  		break;
  9.2469 @@ -2019,7 +1113,8 @@
  9.2470  		    }
  9.2471  		  tmp = readbyte;
  9.2472  		  wrtb (0xDB);
  9.2473 -		  new_reference (tmp, TYPE_ABSB, ')', 1);
  9.2474 +		  if (!new_reference (tmp, TYPE_ABSB, ')', 1))
  9.2475 +			return 0;
  9.2476  		  break;
  9.2477  		}
  9.2478  	      if (!rd_c (&ptr))
  9.2479 @@ -2060,23 +1155,20 @@
  9.2480  		  wrtb (0xE9);
  9.2481  		  break;
  9.2482  		}
  9.2483 -	      if (r == 0)
  9.2484 -		{
  9.2485 -		  wrtb (0xC3);
  9.2486 -		}
  9.2487 -	      else
  9.2488 -		{
  9.2489 +	      if (r) {
  9.2490  		  wrtb (0xC2 + 8 * --r);
  9.2491  		  rd_comma (&ptr);
  9.2492 -		}
  9.2493 -	      rd_wrt_addr (&ptr, '\0');
  9.2494 +		} else wrtb (0xC3);
  9.2495 +	      if (!rd_wrt_addr (&ptr, '\0'))
  9.2496 +			return 0;
  9.2497  	      break;
  9.2498  	    case JR:
  9.2499  	      r = rd_jr (&ptr);
  9.2500  	      if (r)
  9.2501  		rd_comma (&ptr);
  9.2502  	      wrtb (0x18 + 8 * r);
  9.2503 -	      rd_wrt_jr (&ptr, '\0');
  9.2504 +	      if (!rd_wrt_jr (&ptr, '\0'))
  9.2505 +			return 0;
  9.2506  	      break;
  9.2507  	    case LD:
  9.2508  	      if (!(r = rd_ld (&ptr)))
  9.2509 @@ -2234,7 +1326,8 @@
  9.2510  	      {
  9.2511  		const char *tmp = readbyte;
  9.2512  		wrtb (0xD3);
  9.2513 -		new_reference (tmp, TYPE_ABSB, ')', 1);
  9.2514 +		if (!new_reference (tmp, TYPE_ABSB, ')', 1))
  9.2515 +			return 0;
  9.2516  	      }
  9.2517  	      break;
  9.2518  	    case OUTD:
  9.2519 @@ -2325,7 +1418,8 @@
  9.2520  	      wrtb (0x67);
  9.2521  	      break;
  9.2522  	    case RST:
  9.2523 -	      new_reference (ptr, TYPE_RST, '\0', 1);
  9.2524 +	      if (!new_reference (ptr, TYPE_RST, '\0', 1))
  9.2525 +			return 0;
  9.2526  	      ptr = "";
  9.2527  	      break;
  9.2528  	    case SBC:
  9.2529 @@ -2431,7 +1525,8 @@
  9.2530  		  else
  9.2531  		    {
  9.2532  		      /* Read expression.  */
  9.2533 -		      new_reference (ptr, TYPE_ABSB, ',', 1);
  9.2534 +		      if (!new_reference (ptr, TYPE_ABSB, ',', 1))
  9.2535 +			return 0;
  9.2536  		      skipword (&ptr, ',');
  9.2537  		    }
  9.2538  		  ptr = delspc (ptr);
  9.2539 @@ -2454,7 +1549,8 @@
  9.2540  		}
  9.2541  	      while (1)
  9.2542  		{
  9.2543 -		  new_reference (readword, TYPE_ABSW, ',', 1);
  9.2544 +		  if (!new_reference (readword, TYPE_ABSW, ',', 1))
  9.2545 +			return 0;
  9.2546  		  ptr = delspc (ptr);
  9.2547  		  if (*ptr != ',')
  9.2548  		    break;
  9.2549 @@ -2473,22 +1569,20 @@
  9.2550  		  break;
  9.2551  		}
  9.2552  	      ptr = delspc (ptr);
  9.2553 -	      if (*ptr)
  9.2554 -		{
  9.2555 +	      if (*ptr) {
  9.2556  		  rd_comma (&ptr);
  9.2557  		  readbyte = 0;
  9.2558  		  rd_byte (&ptr, '\0');
  9.2559  		  writebyte = 0;
  9.2560 -		  new_reference (readbyte, TYPE_DS, '\0', r);
  9.2561 +		  if (!new_reference (readbyte, TYPE_DS, '\0', r))
  9.2562 +			return 0;
  9.2563  		  break;
  9.2564  		}
  9.2565 -	      if (havelist)
  9.2566 -		{
  9.2567 +	      if (havelist) {
  9.2568  		  fprintf (listfile, " 00...");
  9.2569  		  listdepth += 6;
  9.2570  		}
  9.2571 -	      for (i = 0; i < r; i++)
  9.2572 -		{
  9.2573 +	      for (i = 0; i < r; i++) {
  9.2574  		  write_one_byte (0, 0);
  9.2575  		}
  9.2576  	      break;
  9.2577 @@ -2498,88 +1592,6 @@
  9.2578  	    case ORG:
  9.2579  	      addr = rd_expr (&ptr, '\0', NULL, sp, 1) & 0xffff;
  9.2580  	      break;
  9.2581 -	    case INCLUDE:
  9.2582 -	      if (sp + 1 >= MAX_INCLUDE)
  9.2583 -		{
  9.2584 -		  printerr (1, "stack overflow (circular include?)");
  9.2585 -		  if (verbose >= 5)
  9.2586 -		    {
  9.2587 -		      int x;
  9.2588 -		      fprintf (stderr, "Stack dump:\nframe  line file\n");
  9.2589 -		      for (x = 0; x < MAX_INCLUDE; ++x)
  9.2590 -			fprintf (stderr, "%5d %5d %s\n", x, stack[x].line,
  9.2591 -				 stack[x].name);
  9.2592 -		    }
  9.2593 -		  break;
  9.2594 -		}
  9.2595 -	      {
  9.2596 -		struct name *name;
  9.2597 -		char *nm = get_include_name (&ptr);
  9.2598 -		if (!nm)
  9.2599 -		  break;
  9.2600 -		name = malloc (sizeof (struct name) + strlen (nm));
  9.2601 -		if (!name)
  9.2602 -		  {
  9.2603 -		    printerr (1, "out of memory while allocating name\n");
  9.2604 -		    free (nm);
  9.2605 -		    break;
  9.2606 -		  }
  9.2607 -		strcpy (name->name, nm);
  9.2608 -		free (nm);
  9.2609 -		++sp;
  9.2610 -		stack[sp].name = name->name;
  9.2611 -		stack[sp].shouldclose = 1;
  9.2612 -		stack[sp].line = 0;
  9.2613 -		stack[sp].file = open_include_file (name->name,
  9.2614 -						    &stack[sp].dir, "r");
  9.2615 -		if (!stack[sp].file)
  9.2616 -		  {
  9.2617 -		    printerr (1, "unable to open file %s\n", name->name);
  9.2618 -		    free (name);
  9.2619 -		    --sp;
  9.2620 -		    break;
  9.2621 -		  }
  9.2622 -		name->next = firstname;
  9.2623 -		name->prev = NULL;
  9.2624 -		if (name->next)
  9.2625 -		  name->next->prev = name;
  9.2626 -		firstname = name;
  9.2627 -		if (verbose >= 4)
  9.2628 -		  fprintf (stderr, "Reading file %s\n", name->name);
  9.2629 -	      }
  9.2630 -	      break;
  9.2631 -	    case INCBIN:
  9.2632 -	      {
  9.2633 -		FILE *incfile;
  9.2634 -		char *name = get_include_name (&ptr);
  9.2635 -		if (!name)
  9.2636 -		  break;
  9.2637 -		incfile = open_include_file (name, NULL, "rb");
  9.2638 -		if (!incfile)
  9.2639 -		  {
  9.2640 -		    printerr (1, "unable to open binary file %s\n", name);
  9.2641 -		    free (name);
  9.2642 -		    break;
  9.2643 -		  }
  9.2644 -		while (1)
  9.2645 -		  {
  9.2646 -		    char filebuffer[4096];
  9.2647 -		    size_t num = fread (filebuffer, 1, 4096, incfile);
  9.2648 -		    if (num == 0)
  9.2649 -		      break;
  9.2650 -		    if (num != fwrite (filebuffer, 1, num, outfile))
  9.2651 -		      {
  9.2652 -			printerr (1, "error including binary file %s: %s\n",
  9.2653 -				  name, strerror (errno));
  9.2654 -			break;
  9.2655 -		      }
  9.2656 -		    addr += num;
  9.2657 -		    addr &= 0xffff;
  9.2658 -		  }
  9.2659 -		fclose (incfile);
  9.2660 -		free (name);
  9.2661 -		break;
  9.2662 -	      }
  9.2663  	    case IF:
  9.2664  	      if (rd_expr (&ptr, '\0', NULL, sp, 1))
  9.2665  		ifcount++;
  9.2666 @@ -2606,55 +1618,6 @@
  9.2667  	      else
  9.2668  		ifcount--;
  9.2669  	      break;
  9.2670 -	    case MACRO:
  9.2671 -	      if (!lastlabel)
  9.2672 -		{
  9.2673 -		  printerr (1, "macro without label\n");
  9.2674 -		  break;
  9.2675 -		}
  9.2676 -	      if (define_macro)
  9.2677 -		{
  9.2678 -		  printerr (1, "nested macro definition\n");
  9.2679 -		  break;
  9.2680 -		}
  9.2681 -	      {
  9.2682 -		struct macro *m;
  9.2683 -		for (m = firstmacro; m; m = m->next)
  9.2684 -		  {
  9.2685 -		    if (strcmp (m->name, lastlabel->name) == 0)
  9.2686 -		      {
  9.2687 -			printerr (1, "duplicate macro definition\n");
  9.2688 -			break;
  9.2689 -		      }
  9.2690 -		  }
  9.2691 -		m = malloc (sizeof (struct macro));
  9.2692 -		if (!m)
  9.2693 -		  {
  9.2694 -		    printerr (1, "out of memory\n");
  9.2695 -		    break;
  9.2696 -		  }
  9.2697 -		m->name = malloc (strlen (lastlabel->name) + 1);
  9.2698 -		if (!m->name)
  9.2699 -		  {
  9.2700 -		    printerr (1, "out of memory\n");
  9.2701 -		    free (m);
  9.2702 -		    break;
  9.2703 -		  }
  9.2704 -		strcpy (m->name, lastlabel->name);
  9.2705 -		if (lastlabel->prev)
  9.2706 -		  lastlabel->prev->next = lastlabel->next;
  9.2707 -		else
  9.2708 -		  firstlabel = lastlabel->next;
  9.2709 -		if (lastlabel->next)
  9.2710 -		  lastlabel->next->prev = lastlabel->prev;
  9.2711 -		free (lastlabel);
  9.2712 -		m->next = firstmacro;
  9.2713 -		firstmacro = m;
  9.2714 -		m->lines = NULL;
  9.2715 -		m->numargs = get_macro_args (&ptr, &m->args, 0);
  9.2716 -		define_macro = 1;
  9.2717 -	      }
  9.2718 -	      break;
  9.2719  	    case ENDM:
  9.2720  	      if (stack[sp].file)
  9.2721  		printerr (1, "endm outside macro definition\n");
  9.2722 @@ -2674,159 +1637,37 @@
  9.2723  		break;
  9.2724  	      }
  9.2725  	    default:
  9.2726 -	      {
  9.2727 -		struct macro *m;
  9.2728 -		for (m = firstmacro; m; m = m->next)
  9.2729 -		  {
  9.2730 -		    if (strncmp (m->name, ptr, strlen (m->name)) == 0)
  9.2731 -		      {
  9.2732 -			unsigned numargs;
  9.2733 -			if (sp + 1 >= MAX_INCLUDE)
  9.2734 -			  {
  9.2735 -			    printerr (1, "stack overflow (circular include?)\n");
  9.2736 -			    if (verbose >= 5)
  9.2737 -			      {
  9.2738 -				int x;
  9.2739 -				fprintf (stderr,
  9.2740 -					 "Stack dump:\nframe  line file\n");
  9.2741 -				for (x = 0; x < MAX_INCLUDE; ++x)
  9.2742 -				  fprintf (stderr, "%5d %5d %s\n", x,
  9.2743 -					   stack[x].line, stack[x].name);
  9.2744 -			      }
  9.2745 -			    break;
  9.2746 -			  }
  9.2747 -			++sp;
  9.2748 -			ptr += strlen (m->name);
  9.2749 -			numargs = get_macro_args (&ptr, &stack[sp].macro_args,
  9.2750 -						  1);
  9.2751 -			if (numargs != m->numargs)
  9.2752 -			  {
  9.2753 -			    unsigned a;
  9.2754 -			    printerr (1, "invalid number of arguments for macro "
  9.2755 -				      "(is %d, must be %d)\n", numargs,
  9.2756 -				      m->numargs);
  9.2757 -			    for (a = 0; a < numargs; ++a)
  9.2758 -			      free (stack[sp].macro_args[a]);
  9.2759 -			    free (stack[sp].macro_args);
  9.2760 -			    break;
  9.2761 -			  }
  9.2762 -			stack[sp].name = m->name;
  9.2763 -			stack[sp].file = NULL;
  9.2764 -			stack[sp].line = 0;
  9.2765 -			stack[sp].macro = m;
  9.2766 -			stack[sp].macro_line = m->lines;
  9.2767 -			stack[sp].shouldclose = 0;
  9.2768 -			stack[sp].dir = NULL;
  9.2769 -			break;
  9.2770 -		      }
  9.2771 -		  }
  9.2772 -		if (m)
  9.2773 -		  break;
  9.2774 -	      }
  9.2775  	      printerr (1, "command or comment expected (was %s)\n", ptr);
  9.2776 +	      return 0;
  9.2777  	    }
  9.2778 -	}
  9.2779 -    }
  9.2780 -  if (ifcount || noifcount)
  9.2781 -    {
  9.2782 -      printerr (1, "reached EOF at IF level %d\n", ifcount + noifcount);
  9.2783 -    }
  9.2784 -  if (havelist)
  9.2785 -    {
  9.2786 -      fprintf (listfile, "%04x\n", addr);
  9.2787 -    }
  9.2788 -  {
  9.2789 -    struct reference *next;
  9.2790 -    struct reference *tmp;
  9.2791 -    /* Add a stack frame for error reporting.  */
  9.2792 -    ++sp;
  9.2793 -    for (tmp = firstreference; tmp; tmp = next)
  9.2794 -      {
  9.2795 -	int ref;
  9.2796 -	next = tmp->next;
  9.2797 -	fseek (outfile, tmp->oseekpos, SEEK_SET);
  9.2798 -	if (havelist)
  9.2799 -	  fseek (listfile, tmp->lseekpos, SEEK_SET);
  9.2800 -	stack[sp].name = tmp->file;
  9.2801 -	stack[sp].dir = tmp->dir;
  9.2802 -	stack[sp].line = tmp->line;
  9.2803 -	ref = compute_ref (tmp, 0);
  9.2804 -	wrt_ref (ref, tmp->type, tmp->count);
  9.2805 -	if (tmp->dir)
  9.2806 -	  free (tmp->dir);
  9.2807 -	free (tmp->file);
  9.2808 -	free (tmp);
  9.2809 -      }
  9.2810 -  }
  9.2811 -  if (!errors || use_force)
  9.2812 -    {
  9.2813 -      flush_to_real_file (realoutputfile, outfile);
  9.2814 -      if (havelist)
  9.2815 -	flush_to_real_file (reallistfile, listfile);
  9.2816 -    }
  9.2817 -  /* write all labels */
  9.2818 -  if (label)
  9.2819 -    fseek (labelfile, 0, SEEK_END);
  9.2820 -  for (l = firstlabel; l; l = l->next)
  9.2821 -    {
  9.2822 -      if (l->ref)
  9.2823 -	{
  9.2824 -	  compute_ref (l->ref, 0);
  9.2825 -	}
  9.2826 -      if (label)
  9.2827 -	{
  9.2828 -	  fprintf (labelfile, "%s%s:\tequ $%04x\n", labelprefix, l->name,
  9.2829 -		   l->value);
  9.2830 -	}
  9.2831 -    }
  9.2832 -  if (label)
  9.2833 -    fclose (labelfile);
  9.2834 -  while (firstlabel)
  9.2835 -    {
  9.2836 -      l = firstlabel->next;
  9.2837 -      free (firstlabel);
  9.2838 -      firstlabel = l;
  9.2839 -    }
  9.2840 -  fclose (outfile);
  9.2841 -  if (outfile != realoutputfile)
  9.2842 -    fclose (realoutputfile);
  9.2843 -  if (havelist)
  9.2844 -    {
  9.2845 -      fclose (listfile);
  9.2846 -      if (listfile != reallistfile && reallistfile != stderr)
  9.2847 -	fclose (reallistfile);
  9.2848 -    }
  9.2849 +    } while (0);
  9.2850    free (infile);
  9.2851 +return obuflen;
  9.2852 +}
  9.2853 +
  9.2854 +// XXX
  9.2855 +int z80asm (unsigned char *outbuf, const char *s) {
  9.2856 +	return assemble (s, outbuf);
  9.2857  }
  9.2858  
  9.2859  #ifdef MAIN_ASM
  9.2860 -int
  9.2861 -main (int argc, char **argv)
  9.2862 -{
  9.2863 -  /* default include file location */
  9.2864 -  add_include ("/usr/share/z80asm/headers/");
  9.2865 -  parse_commandline (argc, argv);
  9.2866 -  if (verbose >= 1)
  9.2867 -    fprintf (stderr, "Assembling....\n");
  9.2868 -  assemble ();
  9.2869 -  if (errors)
  9.2870 -    {
  9.2871 -      if (errors == 1)
  9.2872 -	fprintf (stderr, "*** 1 error found ***\n");
  9.2873 -      else
  9.2874 -	fprintf (stderr, "*** %d errors found ***\n", errors);
  9.2875 -      if (realoutputfile == outfile && !use_force)
  9.2876 -	{
  9.2877 -	  unlink (realoutputfilename);
  9.2878 -	  unlink (labelfilename);
  9.2879 -	}
  9.2880 -      return 1;
  9.2881 -    }
  9.2882 -  else
  9.2883 -    {
  9.2884 -      if (verbose >= 1)
  9.2885 -	fprintf (stderr, "Assembly succesful.\n");
  9.2886 -      return 0;
  9.2887 -    }
  9.2888 +int main (int argc, char **argv) {
  9.2889 +	int len;
  9.2890 +	unsigned char buf[4];
  9.2891 +
  9.2892 +	buf[0] = buf[1] = buf[2] = 0;
  9.2893 +	len = z80asm (buf, "nop");
  9.2894 +	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
  9.2895 +
  9.2896 +	len = z80asm (buf, "cp b");
  9.2897 +	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
  9.2898 +
  9.2899 +	len = z80asm (buf, "call 0x123");
  9.2900 +	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
  9.2901 +
  9.2902 +	len = z80asm (buf, "call bla");
  9.2903 +	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
  9.2904 +
  9.2905 +	return 0;
  9.2906  }
  9.2907  #endif
    10.1 --- a/libr/asm/arch/z80/z80asm.h	Fri Feb 03 20:52:20 2012 +0100
    10.2 +++ b/libr/asm/arch/z80/z80asm.h	Sat Feb 04 03:51:22 2012 +0100
    10.3 @@ -164,6 +164,7 @@
    10.4    char input[1];		/* variable size buffer containing formula */
    10.5  };
    10.6  
    10.7 +#if 0
    10.8  /* global variables */
    10.9  /* mnemonics, used as argument to indx() in assemble */
   10.10  extern const char *mnemonics[];
   10.11 @@ -229,6 +230,7 @@
   10.12  
   10.13  /* Produce output even with errors.  */
   10.14  extern int use_force;
   10.15 +#endif
   10.16  
   10.17  /* print an error message, including current line and file */
   10.18  void printerr (int error, const char *fmt, ...);
    11.1 --- a/libr/asm/p/asm_z80.c	Fri Feb 03 20:52:20 2012 +0100
    11.2 +++ b/libr/asm/p/asm_z80.c	Sat Feb 04 03:51:22 2012 +0100
    11.3 @@ -5,11 +5,19 @@
    11.4  #include <r_lib.h>
    11.5  #include <r_asm.h>
    11.6  
    11.7 -static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
    11.8 -	int len = 0;
    11.9 -	eprintf ("TODO\n");
   11.10 -	op->inst_len = len;
   11.11 -	return len;
   11.12 +#include "../arch/z80/z80.c"
   11.13 +
   11.14 +static int do_assemble(RAsm *a, RAsmOp *op, const char *buf) {
   11.15 +	return op->inst_len = z80asm (obuf, op->buf);
   11.16 +}
   11.17 +
   11.18 +static int do_disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf, ut64 len) {
   11.19 +	int dlen = z80dis (0, buf, op->buf_asm, len);
   11.20 +	if (dlen>0) {
   11.21 +		// printf ("LEN IS OK\n");
   11.22 +	} else dlen = 0;
   11.23 +	op->inst_len = dlen;
   11.24 +	return op->inst_len;
   11.25  }
   11.26  
   11.27  RAsmPlugin r_asm_plugin_z80 = {
   11.28 @@ -19,8 +27,8 @@
   11.29  	.bits = (int[]){ 8, 0 },
   11.30  	.init = NULL,
   11.31  	.fini = NULL,
   11.32 -	.disassemble = NULL,
   11.33 -	.assemble = &assemble, 
   11.34 +	.disassemble = do_disassemble,
   11.35 +	.assemble = &do_assemble, 
   11.36  };
   11.37  
   11.38  #ifndef CORELIB
    12.1 --- a/libr/include/r_anal.h	Fri Feb 03 20:52:20 2012 +0100
    12.2 +++ b/libr/include/r_anal.h	Sat Feb 04 03:51:22 2012 +0100
    12.3 @@ -580,6 +580,7 @@
    12.4  extern RAnalPlugin r_anal_plugin_sparc;
    12.5  extern RAnalPlugin r_anal_plugin_bf;
    12.6  extern RAnalPlugin r_anal_plugin_m68k;
    12.7 +extern RAnalPlugin r_anal_plugin_z80;
    12.8  
    12.9  #endif
   12.10  #endif
    13.1 --- a/libr/include/r_types.h	Fri Feb 03 20:52:20 2012 +0100
    13.2 +++ b/libr/include/r_types.h	Sat Feb 04 03:51:22 2012 +0100
    13.3 @@ -204,7 +204,8 @@
    13.4  	R_SYS_ARCH_BF = 0x400,
    13.5  	R_SYS_ARCH_SH = 0x800,
    13.6  	R_SYS_ARCH_AVR = 0x1000,
    13.7 -	R_SYS_ARCH_DALVIK = 0x2000
    13.8 +	R_SYS_ARCH_DALVIK = 0x2000,
    13.9 +	R_SYS_ARCH_Z80 = 0x4000
   13.10  };
   13.11  
   13.12  /* os */
    14.1 --- a/libr/util/str.c	Fri Feb 03 20:52:20 2012 +0100
    14.2 +++ b/libr/util/str.c	Sat Feb 04 03:51:22 2012 +0100
    14.3 @@ -831,7 +831,7 @@
    14.4  
    14.5  R_API const char *r_str_lastbut (const char *s, char ch, const char *but) {
    14.6  	int _b = 0;
    14.7 -	ut8 *b = &_b;
    14.8 +	ut8 *b = (ut8*)&_b;
    14.9  	const char *p, *lp = NULL;
   14.10  	const int bsz = sizeof (_b);
   14.11  	if (strlen (but) >= bsz) {
    15.1 --- a/mk/hg-utils.mk	Fri Feb 03 20:52:20 2012 +0100
    15.2 +++ b/mk/hg-utils.mk	Sat Feb 04 03:51:22 2012 +0100
    15.3 @@ -2,6 +2,9 @@
    15.4  # Makefile helpers for mercurial
    15.5  
    15.6  hg-miss:
    15.7 +	${MAKE} hg-miss2 | grep -v sys| grep -v git| grep -v maemo
    15.8 +
    15.9 +hg-miss2:
   15.10  	@-hg st . | grep -e vala$$ -e mk$$ | grep ^? | grep -v config-user | cut -c 2- || true
   15.11  	@-hg st . | grep -e \\.c$$ -e \\.h$$ | grep -v vapi | grep ^? | grep -v r_userconf | cut -c 2- || true
   15.12  	@-hg st . | grep -e \\.vapi$$ -e \\.acr$$ -e README$$ -e TODO$$ | grep ^? | cut -c 2- || true
    16.1 --- a/plugins.def.cfg	Fri Feb 03 20:52:20 2012 +0100
    16.2 +++ b/plugins.def.cfg	Sat Feb 04 03:51:22 2012 +0100
    16.3 @@ -24,6 +24,7 @@
    16.4  asm.msil
    16.5  asm.z80
    16.6  anal.sh
    16.7 +anal.z80
    16.8  anal.x86
    16.9  anal.x86_simple
   16.10  anal.arm