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