UNIVERSIDAD AUTONOMA METROPOLITANA UNIDAD IZTAPALAPA DOCUMENTACION DEL PROYECTO TERMINALI1 "ENSAMBLADOR Y SIMULADOR DE UN MICROPROCESADOR" ALUMNO: SERGUEI MENDOZA SOYLOVICH ASESOR: FRANCISCO OLVERA SEPTIEMBRE 1992 INDICE: INTRODUCCION APENDICE A: LISTA DE ARCHIVOS QUE CONSTITUYEN EL PROYECTO APENDICE B: PASOS A SEGUIR PARA GENERAR EL ENSAMBLADOR Y EL SIMULADOR APENDICE C: GRAMATICA DEL ENSAMBLADOR APENDICE D: LISTA DE INSTRUCCIONES DEL ENSAMBLADOR LISTADO esp1ex.c LISTADO cod1ex.x LISTADO espyacc.c LISTADO myasm.c LISTADO mi0simf.c LISTADO p0pup.h LISTADO m0use.h LISTADO miosimf.prj Este proyecto fue realizado durante el trimestre 91-1 en la Universidad Autónoma Metropolitana, Unidad Iztapalapa. El proyecto fue dirigido por el Ing. Francisco Olvera y surgió como una oportunidad de conocer mejor la mecánica del funcionamiento de un procesador, a la vez que permitióobtener un mejor manejo de los generadores de analizadores sintácticos y léxicos, como lo son YACC y LEX. Asimismo, el manejo de programas con muchas líneas de código es un buen fogueo para un estudiante de computación, ya que permite la generación de una disciplina y una consciencia de la importancia de una buena documentación para el éxito final de un proyecto. El proyecto consiste de dos partes : la primera, es un programa ensamblador que genera un seudocódigo objeto para un microprocesador hipotlético, utilizo el término de "seudocódigo", porque en el archivo que genera el ensamblaclor , cada línea consiste del código fuente original, conlbinado con el código objeto que éste genera, esta técnica se empleó para poder tener disponibles al emulador los nombres simbólicos ;asignados a las variables y a las etiquetas: la segunda parte es un programa emulador que permite ejecutar paso a paso el código objeto generado por el ensamblador, desplegando el contenido de los registros y de la memoria del microprocesador y permitiendo modificar los mismos ( debido a esta última característica, este programa también se podría denominar como depurador ). El resto de este documento está dividido en tres partes principales: la referente al ensamblador, la referente al emulador y los apéndices. En la parte referente al ensamblador se mencionan, entre otras cosas, los pasos que se siguieron para llegar a la escritura del programa en sí y las dificultades con las que se tuvo que lidiar . En la parte referente al emulador se describen la técnica que se utilizó para el manejo de la interfslz gráfica y los parametros por simular. En la parte de los apéndices, se incluyeron instrucciones para la generación de los programas a partir de sus códigos fuente y los listados de los archivos involucrados. APENDICE A LISTA DE ARCHIVOS QUE CONSTITUYEN EL PROYECTO: 1) El programa ensamblador consiste delos siguientes archivos: esp1ex.c - especificaciones para LEX 1.l. 1.2. cod1ex.c - lista de cedigos para LEX 1.3. espyac.c - especificaciones para YACC 1.4. myasm.c - programa principal del ensamblador 1.5. y0ut.c salida generada por YACC 1.6.lout.c salida generada por LEX - 2) El programa simulador del micoprocesador consiste de los siguientes archivos: - 2.1. mysim.c programa principal del simulador 2.2. p0pup.h - rutinas de manejo de ventanas 2.3. m0use.h - rutinas de manejo del mouse 2.4. mysim.prj - project para la compilacien delsimulador 2.5. popup.obj librerias compiladas paramanejo de ventanas 2.6. mouse.obj - librerjas compiladas paramanejo de mlouse - APENDICE B 1)PASOS A SEGUIR PARA GENERAR EL ENSAMBLADOR Para podergenerar el ensamblador a partirde los archivos fuentes se siguieron los pasos que a continuacion sedescriben: 1 .l. CAex esp1ex.c ( se genera como salida1exyy.c ) 1.2.C>copy 1exyy.c 1out.c ( para evitar la sobreescritura de 1exyy.c ) 1.3.C>yacc espyacc.c ( se genera como salida ytab.c ) 1.4.C>copy ytab.c y0ut.c ( para evitar la sobreescriturade ytab.c ) 1 S . C>edit y0ut.c ( borrar "#" em la linea1370 aproximadamente ) 1.6.C>tc myasm.c ( se compila myasm.c y se generamyasm.exe ) 2) PASOS A SEGUIR PARA GENERAR EL SlMULADOFl 2.1.Entrar a Turbo C 2.2. Cargar el project mysim.prj 2.3.Ejecutar la opcien de compilacitn 2.4.Como salida se genera el ejecutable mysim.exe APENDICE C GRAMATICA DELENSAMBLADOR PROG : I DECLS PROG-DECL PROG-DECL DECLS : DECL I DECLS DECL DECL : I I I I I ID EQU HEX ID EQU DHEX ID HEX DB DB HEX ID DEFS HEX HEXDEFS PROG-DECL: CUERPOSEND CUERPOS: CUERPO I CUERPOS CUERPO I CUERPO : ORG HEX INSTS Y INSTS : I , INST I I I I I : INST INSTS INST ET1 OPERACION OPERACION ET1 OPERACIONU OPERANDO OPERACIONU OPERANDO ET1 OPERACIONB OPERANDO, OPERACIONB OPERANDO, OPERANDO OPIERANDO APENDICE D LISTA DE INSTRUCCIONES DEL ENSAMBLADOR: NOTACION: RR= AL, AH, BL, BH DD= A X , BX, IX, SP QQ= A X , BX, IX, IF PP1= A X , BX, IY, SP PP2= AX, BX, IX, SP WW= A X , BX, IX, IY l.GRUPO DE INSTRUCCIONES DE CARGA DE 8BITS; 1. LD R,R 2. LD R,N 3. LD R,(IX+D) 4. LD R,(IY+D) 5. LD (IX+D),R 6. LD (IY+D),R 7. LD (IX+D),N 8. LD(IY+D),N 9. LD AL,(NN) 10. LD (NN),AL 11. LD AL,INTV 12. LD INTV,AL 2. GRUPO DE INSTRUCCIONES DE CARGA DE 16 BITS 1. LD DD,NN 2. LD IY,IX 3. LD DD,(NN) 4. LD (NN),DD 5. LD SP,IX 6. PUSH QQ 7. POP QQ 3. GRUPO DE INSTRUCCIONES ARITMETICASY LOGICAS 1. ADD RR 2.ADDN 3. ADD (IX+D) 4. ADD (IY+D) 5. ADC RR 6. SUB RR 7. SBC RR 8.AND RR 9.OR RR 10. XOR RR 11. INC RR 12. INC (IX+D) 13. INC (IY+D) 14. DEC RR 15. DEC (IX+D) 16. DEC (IY+D) 4. GRUPO DE INSTRUCCIONES GENERALES 1. DAA 2. CPL 3. NEG 4. CCF 5. SCF 6. NOP 7. HALT 8. DI 9. El 5. GRUPO DE INSTRUCCIONES ARITMETICAS DE 16 IBITS l.ADW AX,BX 2. ACW AX,BX 3. SCW AX,BX 4. ADW IX,PPl 5. ADW IY,PP2 6 . INC WW 7. DEC WW 6. GRUPO DE ROTACION Y SHIR1. RLC RR 2. RLC (IX+D) 3. RLC (IY+D) 4. RL RR 5 . R R RR 6. RRC RR 7. SL RR 8.SR RR 7. GRUPO DE SET, RESET Y TEST BIT 1. BIT B,R 2. BIT B,(IX+D) 3. BIT B,(IY+D) 4. BIT B,R 5. BIT B,(IX+D) 6. BIT B,(IY+D) 7. RES B,R 8. RES B,(IX+D) 9. RES B,(IY+D) 8. GRUPO DE JUMP, CALL Y RETURN 1. JP NN 2. JPC CC,NN 3. JR EE 4. JRC CC,EE 5. JP (IX) 6. JP (IY) 7. DJNZ EE 8. CALL NN 9. RET 10. RETI /* Especificaciones para LEX ( esp1ex.c ) */ extern int nolines=O; I d h [A-Z] /* letra */ [O-91 I* digit0 *I [O-9a-fl /* digito hexadecimal */ %o% return(tok-no=c-AL); "AL" return(tok-no=c-AH); "AH" return(tok-no=c-BL); "BL" return(tok-no=c-BH); "BH" "IY" return(tok-no=c-lY); "AX return(tok-no=c-AX); "BX' return(tok-no=c-BX); "IX return(tok-no=c-IX); return(tok-no=c-SP); "SP" "FLAGS" return(tok-no=c-FLAGS); "INTV return(tok-no=c-lNTV); return(tok-no=c-LD); "LD" "PUSH"return(tok"no=c-PUSH); "POP" return(tok-no=c-POP); "ADD" return(tok-no=c-ADD); "ADC" return(tok-no=c-ADC); "SUB" return(tok-no=c-SUB); "SBC" return(tok-no=c-SBC); " A N D return(tok-no=c-AND); "OR" return(tok-no=c-OR); "XOR" return(tok-no=c-XOR); "INC" return(tok-no=c-INC); "DEC" return(tok-no=c-DEC); "DAA" return(tok-no=c-DAA); "CPL" return(tok-no=c-CPL); "NEG" return(tok-no=c-NEG); "CCF" return(tok-no=c-CCF); "SCF" return(tok-no=c-SCF); "HALT" return(tok-no=c-HALT); return(tok-no=c-DI); "DI" "El" return(tok-no=c-El); "RLC" return(tok-no=c-RLC); return(tok-no=c-RL); "RL" "RR" return(tok-no=c-RR); "RRC" return(tok-no=c-RRC); "SL" return(tok-no=c-SL); "SR" return(tok-no=c-SR); "Blf" return(tok-no=c-BIT); "SET" return(tok-no=c-SET); "RES" return(tok-no=c-RES); return(tok-no=c-JP); "JP" "JR return(tok-no=c-JR); "DJNZ" return(tok-no=c-DJNZ); "CALL" return(tok-no=c-CALL); "RET" return(tok-no=c-RET); "RETI"return(tok-no=c-RETI); "JPC" return(tok-no=c-JPC); "JRC "ADW' "ACW "SCW return(tok-no=c-JRC); return(tok-no=c-ADW); return(tok-no=c-ACW); return(tok-no=c-SCW); "NZ" "Z" "NC" "C" "S" "NS" "P" "N P" return(tok-no=c-NZ); return(tok-no=c-Z); return(tok-no=c-NC); return(tok-no=c-C); return(tok-no=c-S); return(tok-no=c-NS); return(tok-no=c-P); return(tok-no=c-NP); "ORG" return(tok-no=c-ORG); "END" return(tok-no=c-END); "EQU" return(tok-no=c-EQU); "DB" return(tok-no=c-DB); "DEFS" return(tok-no=c-DEFS); {N{lIl{d))* { strcpy(tokstr,yytext); return(tok-no=c-id); 1 {h){h) { tokvall=tokval2=0; strcpy(tokstr,yytext); tokvall =conv-hex(tokstr); /* hex de 2 digitos */ return(tok-no=-hex); 1 v"o{h){h) { tokvall =O; strcpy(tokstr,yytext); tokvall =conv-hex(tokstr)*256; tokvall +=conv_hex(tokstr+2); return(tok-no=c-dhex); /* hexde 4 digitos */ return(c-mas); return(c-menos); return(c-coma); "+" I, I S I t 11 VI. I t ,I. return(c-pyc); return(c-2p); return(c-p-a); return(c-p-c); ,u "(" '7" " "+ \n ; { 1 nolines++; /* return(c-CR);*/ int chextoint(char *cp) /* convierte un digito hex a entero */ { int aux=O; if(*cp>='O' && *cp<='9') aux=*cp-'0'; else aux=*cp-87; return(aux); 1 int conv-hex(char *cp) /* convierte un numero hex a entero */ { int aux=O; aux=chextoint(cp)*l6; aux+=chextoint(cp+l); return(aux); } YYwraPO { return(1); 1 I* archivo cod1ex.x : codigos de salida para lex *I #define c-AL 257 #define c-AH 258 #define c-BL 259 #define c-BH 260 #define c-lY 261 #define c-AX 262 #define c-BX 263 #define c-lX 264 #define c-SP 265 #define c-FLAGS 266 #define c-INTV 267 /* definiciones de condiciones de salto *I #define c-NZ #define c-Z #define c-NC #define c-C #define c-S #define c-NS #define c-P #define c-NP 268 269 270 271 272 273 274 275 I* definiciones de codigos de operaciones*I #define c-LD 276 #define c-PUSH 277 #define278 c-POP #define c-ADD 279 #define c-ADC 280 #define c-SUB 281 #define c-SBC 282 #define c-AND 283 #define c-OR 284 #define c-XOR 285 #define c-INC 286 #define c-DEC 287 #define c-DAA 288 #define c-CPL 289 #define c-NEG 290 #define c-CCF 291 #define c-SCF 292 #define c-HALT 293 #define c-DI 294 #define c-El 295 #define c-RLC 296 #define c-RL 297 #define c-RR 298 #define c-RRC 299 #define c-SL 300 #define c-SR 301 #define c-BIT 302 #define c-SET 303 #define c-RES 304 #define c-JP 305 #define c-JR 306 #define c-DJNZ 307 #define c-CALL308 #define c-RET 309 #define c-RETI 310 #define c-JPC 31 1 #define c-JRC312 #define c-mas #define c-menos #define c-coma #define c-pyc #define c-p-a #define c-p-c #define c-id #define c-dec #define c-hex #define c-dhex #define c-2p #define c-ORG #define c-END #define c-DB #define c-DEFS #define c-EQU #define c-CR #define c-ADW #define c-ACW #define c-SCW 313 314 315 316 317 31 8 319 320 32 1 322 323 324 325 326 327 328 329 330 331 332 /* archivo espyacc.c : especificaciones de entrada para yacc *I %{ /* DEFINICIONES */ #include <stdio.h> #define c-IXD 400 #define c-IYD 401 #define c-IXP 402 Mefine c-IYP 403 #define c-APNN 404 #define c-OPNR 405 /* Operando No Resuelto */ ##define c-OPR 406 /* Operando Resuelto */ #define c-APID 407 #define c-IXID 408 #define c-IYID 409 struct line-node{ int c-tok; /* codigo de token */ char nombre[lO]; /* si esetiqueta,leyenda */ int valor; /* si es numero, valor */ 1; struct code-line{ /* codigo generado por una linea de ensamblador */ int byte?; int byte2; int byte3; int status?; int status2; int status3; int num; int pcounter; struct code-line *next; 1: struct etistr{ /* cadena con la leyenda de un etiqueta */ char name[l O]; int value; >; struct lab-node{ /* nodode la lista deetiquetas */ char name[l O]; int value; struct lab-node *next; struct lab-node *prev; struct 1; ref-node{ /* nodo de la lista dereferencias */ int ref; struct ref-node *next; 1; struct op-node{ /* nodode la lista deoperandos char name[l O]; struct ref-node *next-ref; struct op-node *next-op; struct op-node *prev-op; */ 1; ............................................................................ I /* VARIABLES GLOBALES *I struct lab-node*lab-head=NULL; I* lista de labels *I struct op-node*op-head=NULL; /* lista de operandos "I struct line-node linea[4]; I* una linea consistea lo masde4 elem */ struct etistr eti; int tok-no; I* codigo del token *I int tokvall ,tokval2; int nolines=O; char tokstr[50]; struct code-line*first-line=NULL; I* lista decodigo *I int seguir; int va1,stat; int pc=O; I* programcounter *I int bytes=O; /* cuantos bytes incrementar el PC */ ............................................................................. I %) %Start PROG %token c-AL c-AH c-BL c-BH c-lY c-AX c-BX c-lX c-SP c-.FLAGS c-INTV c-NZc-Zc-NCc-Cc-Sc-NSc-Pc-NPc-LDc-PUSHc-POPc-ADD c-ADC c-SUB c-SBC c-AND c-OR c-XOR c-INC c-DEC c-DAA c-CPL c-NEG c-CCFc-SCFc-HALTc-DIc-Elc-RLCc-RLc-RRc-RRCc-SLc-SR c-BIT c-SET c-RES c-JP c-JR c-DJNZ c-CALL c-RET c-RET1 c-JPC c-JRC c-mas c-menos c-coma c-pyc c-p-a c-p-c c-id c-dec c-hex c-dhex c-2p c-ORG c-END c-DB c-DEFS c-EQU c-CR c-ADWI c-ACW c-SCW %% PROG : EQUS PROG-DECL I PROG-DECL EQU EQUS EQU EQUS : I EQU ID c-EQU c-hex { eti.value=tokvall; lab-mngr(eti.name,eti.value,&seguir); if(seguir==O) myerror(nolines,l); : 1 I ID c-EQU c-d hex { eti.value=tokvall ; lab-mngr(eti.name,eti.value,&seguir); if(seguir==O) myerror(nolines,l); : c-id { ID strcpy(eti.name,tokstr); PROG-DECL: CUERPOS CUERPOS I C-END CUERPO CUERPOS CUERPO CUERPO c-ORG c-hex { pc=tokvall ; 1 DEFSINS DEFSINS : DEFS INSTS INSTS DEFS : DEF DEFS DEF I I DEF : ETlQ c-DB c-hex { eti.value=pc; lab-mngr(eti.name,eti.value,&seguir); if(seguir==O) myerror(nolines,l); I I I INSTS : I INST 1 c-DB c-hex ETlQ c-DEFS c-hex c-DEFS c-hex INST INSTS INST : OPERACION { ini(linea); linea[l].c-tok=tok-no; gen-cod(linea,&bytes); pc+=bytes; I ETlQ 1 C2P OPERACION { ini(linea); eti.value=pc; lab-mngr(eti.name,eti.value,&seguir); if(seguir==O) myerror(nolines,l); else { linea[l].c-tok=tok-no; gen-cod(linea,&bytes); pc+=bytes; 1 I OPERACIONU OPERANDO 1 { ini(linea); linea[l].c-tok=tok-no; } { if(tok-no==c-id) /* si es identificador */ { strcpy(eti.name,tokstr); op-mngr(eti.name,nolines,&val,&stat); if(stat) /* si esta en la lista *I { linea[2].c-tok=c-OPR; linea[2].valor=val; gen-cod(linea,&bytes); pc+=bytes; 1 else I* no esta */ { linea[2].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes; 1 1 else /* no es un identificador */ { linea[2].c-tok=tok-no; linea[2].valor=tokvall; strcpy(linea[2].nombre,tokstr); gen-cod(linea,&bytes); pc+=bytes; I ETlQ L2P OPERACIONU { ini(1inea); eti.value=pc; lab-mngr(eti.name,eti.value,&segulir); if(seguir==O) myerror(nolines,l); linea[l].c-tok=tok-no; OPERANDO 1 { if(tok-no==c-id) { I* si es identificador *I strcpy(eti.name,tokstr); op-mngr(eti.name,nolines,&val,&stat); if(stat) I* si esta en la lista *I { linea[2].c-tok=c-OPR; linea[2].valor=val; gen-cod(linea,&bytes); pc+=bytes; 1 else I* no esta *I { linea[2].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes; 1 1 else I* no es un identificador *I { linea[2].c-tok=tok-no; linea[2].valor=tokvall; strcpy(linea[2].nombre,tokstr); gen-cod(linea,&bytes); pc+=bytes; IOPERACIONB OPERANDO 1 1 1 { ini(linea); linea[l].c-tok=tok-no; { if(tok-no==c-id) I* si es identificadolr *I { strcpy(eti.name,tokstr); op-mngr(eti.name,nolines,&val,&stat); if(stat) I* si esta en la lista *I { linea[2].c-tok=c-OPR; linea[2].valor=val; 1 else I* no esta *I { linea[2].c-tok=c-OPNR; 1 1 else I* no es un identificador *I { linea[2].c-tok=tok-no; I linea[2].valor=tokvall; strcpy(linea[2].nombre,tokstr); 1 c-coma OPERANDO { 1 if(tok-no==c-id) I* si es identificador *I { strcpy(eti.name,tokstr); op-mngr(eti.name,nolines,&val,&stat); if(stat) I* si esta en la lista *I { linea[3].c-tok=c-OPR; linea[3].valor=val; gen-cod(linea,&bytes); pc+=bytes; 1 else I* no esta *I { linea[3].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes; 1 1 else I* no es un identificador *I { linea[3].c_tok=tok-n0; linea[3].valor=tokvail; strcpy(linea[3].nombre,tokstr); gen-cod(linea,&bytes); pc+=bytes; 1 IETIQ C2P OPERACIONB C ini(linea); eti.value=pc; lab-mngr(eti.name,eti.value,&seguir); if(seguir==O) myerror(nolines,l); linea[l].c-tok=tok-no; OPERANDO 1 { if(tok-no==c-id) I* si es identificador *I { strcpy(eti.name,tokstr); op-mngr(eti.name,nolines,&val,&stat); if(stat) I* si esta en la lista *I { Iinea[2].c_tok=c_OPR; linea[2].valor=val; 1 else I* no esta *I { linea[2].c-tok=c-OPNR; 1 1 else /* no es un identificador *I { linea[2].c-tok=tok-no; linea[2].valor=tokvall; strcpy(linea[2].nombre,tokstr); c-coma OPERANDO 1 1 { if(tok-no==c-id) I* si es identificador *I { strcpy(eti.name,tokstr); op-mngr(eti.name,nolines,&val,&stat); if(stat) I* si esta en la lista *I { Iinea[3].c_tok=c_OPR; linea[3].valor=val; gen-cod(linea,&bytes); pc+=bytes; 1 else I* no esta *I { linea[3].c-tok=c-OPNR; gen-cod(linea,&bytes); pc+=bytes; 1 1 else I* no es un identificador *I { linea[3].c-tok=tok-no; linea[3].valor=tokvall; strcpy(linea[3].nombre,tokstr); gen-cod(linea,&bytes); pc+=bytes; 1 ETlQ 1 : c-id { strcpy(eti.name,tokstr); 1 OPERACION : I c-CPL I c-NEG c-RET I c-RETI I c-CCF 1 c-SCF 1 c-DI 1 c-IEI I c-HALT OPERACIONU : c-PUSH I c-POP I c-ADD I c-ADC I cS , UB I c-SBC I c-OR I c-XOR I c-INC 1 c-DEC 1 c-RLC 1 c-RL I c-RR I c-RRC 1 c-SL I c-SR I c-JP I c-JR 1 c-DJNZ 1 c-CALL 1 c-AND OPERACIONB : I c-JPC c-LD I c-ADW I c-ACW I c-SCW I c--BIT I c-SET I I c-JRC c-p-a c-lX c-p-c { tok-no=c-lXP; } c-p-a c-lY c-p-c { tok-no=c-lYP; } c-p-a c-dhex c-p-c { tok-no=c-APNN; } c-p-a c-id c-p-c { tok-no=c-id; } c-p-a c-lX SIGNO c-hex c-p-c { tok-no=c-lXD; } c-p-a c-lY SIGNO c-hex c-p-c { tok-no=c-lYD; } c-p-a c-lX SIGNO c-id c-p-c { tok-no=c-lXID; } c-p-a c-lY SIGNO c-id c-p-c { tok-no=c-lYID; } SIGNO : c-mas I c-menos ................................................................... /* manejo de listas */ ................................................................... / / /* generacion de url nodo para la lista de codigo */ struct code-line *new-code-lineO { struct code-line *aux; aux=(struct code-line *)malloc(sizeof(struct code-line)); aux->bytel =O; aux->byte2=0; aux->byte3=0; aux->status1 =O; aux->status2=0; aux->status3=0; aux->num=O; aux->pcounter=O; aux->next=NULL; 1 /* agregar codigo generado a la lista de codigo */ add-code(int b l ,int b2,int b3,int s l ,int s2,int s3,int num,int cp) { struct code-line *auxl ,*aux2,*aux3; if (first-line==NULL) /* primera linea de codigo */ { first-line=new-code-lineO; first-line->bytel=bl; first-line->byte2=b2; first-line->byte3=b3; first-line->status1 =SI; c-RES I first-line->status2=s2; first-line->status3=s3; first-line->num=num; first-line->pcounter=cp; I* ya hay lineas de codigo *I else { I I auxl =first-line; while ( aux2=aux1 ->next ) auxl=aux2 ; I* auxl is the last node*/ aux2=new_code_lineo; aux2->bytel = b l ; aux2->byte2=b2; aux2->byte3=b3; aux2->statusl = s l ; aux2->status2=s2; aux2->status3=s3; aux2->num=num; aux2->pcounter=cp; auxl->next=aux2; I* imprimir la lista de codigo *I print-codeo { struct code-line *aux; aux=first-line; while(aux) { printf("1ine %d , PC %x :",aux->num,aux->pcounter); if(aux-xtatusl) printf("%x ",aux->bytel); if(aux->status2) printf("%x ",aux->byte2); if(aux->status3) printf("%x ",aux->byte3); printf("\n"); aux=aux->next; I 1 I* manejo de errores *I myerror(int lineajnt error-no) { switch(error-no){ case 1: printf("Error: operandos incorrectos en linea %d\n",linea); break; case 2: printf("Error: referencia incorrecta en linea %d\n",linlea); break; I I exit(1); I* inicializar la estructura para una linea *I ini(struct line-node linaux[4]) { int i; for(i=O;i<4;i++) { linaux[i].c-tok=O; 1 /* funcion auxiliar para generar el codigo de una operacion */ add-op(int *code,int cod-op) { switch(cod-op){ case c-AX: *code=*codelOxO; break; case c-BX: *code=*codelOxl; break; case c-IX: *code=*codelOx2; break; case c-FLAGS: *code=*codelOx3; break; default: myerror(nolines,l); break; 1 1 ................................................................... I /* generacion de codigo para instrucciones sin operandos*l ................................................................... I codigo-op(struct line-node 1[4],int*codl) { switch(l[l].c-tok){ case c-CPL: *codl=Ox99; break; case c-NEG: *cod1 =Ox9a;break; case c-CCF: *codl=Ox9b; break; case c-SCF: *codl=Ox9c; break; case c-DI: *codl=Ox9e; break; case c-El. *codl=Ox9f; break; case c-HALT: *cod1 =Ox9d;break; case c-RET: *cod1=0xe9; break; case c-RETI: *codl=Oxea; break; 1 1 /* funcion auxiliar para generar el codigo de una operacion *I add-rr(int *code,int cod-op) { switch(cod-op){ case c-AL: *code=*codelOxO; break; case c-AH: *code=*codelOxl; break; case c-BL: *code=*codelOx2; break; case c-BH: *code=*codelOx3; break; default: myerror(nolines,l); break; 1 /* funcion auxiliar para generar el codigo de una operacion */ add_rr2(int *code,int cod-op) { switch(cod-op){ case c-AL: *code=*codelOxO; break; case c-AH: *code=*codelOxl ; break; case c-BL: *code=*code)Ox2; break; case c-BH: *code=*codelOx3; break; 1 1 /* funcion auxiliar para generar el codigo de una operacion *I addwrr3(int *code,int cod-op) { switch(cod-op){ case c-AL: *code=*codelOxO; break; case c-AH: *code=*codelOx4; break; case c-BL: *code=*codelOx8; break; case c-BH: *code=*codelOxc; break; 1 ................................................................... I I* generacion de codigo para instrucciones de dos operandos*I ................................................................... I codigo-opb(struct line-node 1[4],int *cod1 ,int *cod2,int *cod3, int *SI, int *s2, int *s3) { int auxint=O; int s=O; int c=O; *S1 =1; switch(l[l].c-tok){ case c-LD: /* main switch *I if((l[2].c-tok==c-AL 11 I[2].c_tok==c_AH 11 l[2].c_tok==c_BL 11 l[2].c_tok==c_BH) && (l[3].c_tok==c_AL 11 I[3].c-tok==c-AH / I 1[3].c_tok==c_BL 11 1[3].c_tok==c_BH 11 l[3].c_tok==c_lXD 11 I[3].c-tok==c-lYD 11 I[3].c-tok==c_lXIDII I[3].c-tok==c-lYID 11 1[3].c-tok==c_hex)) { *cod1=O; *codl=add-rr3(codl,1[2].c-tok); if(I[3].c_tok==c_AL 11 I[3].c-tok==c-AH 1[3].c-tok==c-BL 1) I[3].c_tok==c_BH) { I( *codl=add-rr2(codl,1[3].c-tok); 1 else { switch(l[3].c-tok){ case c-hex: *cod1 =Ox1O; *codl=add-rr2(codl,1[2].c-tok); *cod2=1[3].valor; *s2= 1; break; case c-IXD: *cod1=Ox14; *cod1=add-rr2(codl,1[2].c-tok); *cod2=1[3].valor; *s2=1; I break; case c-IYD: *cod1 =Ox18; *codl=add-rr2(codl,1[2].c-tok); *cod2=1[3].valor; *s2= 1; break; case c-IXID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod1=Ox14; *codl=add-rr2(codl,1[2].c-tok); *cod2=auxint; *s2= 1; 1 else myerror(nolines,2); break; case c-IYID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod1=Ox1 8; *codl=add~rr2(codl,1[2].c~tok); *cod2=auxint; *s2= 1; 1 else myerror(nolines,2); break; } I* switch local */ } /* else */ } I* if3 *I if(l[2].c-tok==c-AL && (I[3].c-tok==c-APNN 1) I[3].c_tok==c_lNTV 11 I[3].c-tok==c-OPR)) { switch(l[3].c-tok){ case c-OPR: case c-APNN: *codl=Ox26; *cod2=1[3].valor & Oxff; *cod3=(1[3].valor >>8) & Oxff; *s2=1; *s3=1; break; case c-INTV: *codl=Ox28; break; 1 if(I[3].c_tok==c_AL && (I[2].c-tok==c-APNN 1[2].c-tok==c-lNTV 11 1[2].c-tok==c-OPR)) { switch(l[2].c-tok){ case c-OPR: case c-APNN: *codl=Ox27; *cod2=1[2].valor & Oxff; 11 *cod3=(1[2].valor >>8) & Oxff; *s2= 1; *s3= 1; break; case c-INTV: *cod1 =Ox29; break; I I if((1[2].c-tok==c-lXD 11 1[2].c_tok== c-IXID) && (1[3].c-tok==c-hex 11 I[3].c_tok==c_OPR)) { *cod1 =Ox24; *cod2=1[2].valor; if(l[2].c-tok==c-lXID) { if(busca-lab(l[2].nombre,&auxint)) /* si esta en la lista */ { *cod2=auxint; 1 I else myerror(nolines,2); *cod3=1[3].valor; *s2=*s3=1; 1 if((1[2].c-tok==c-lYD 11 1[2].c_tok== c-IYID) && (1[3].c-tok==c-hex 11 I[3].c_tok==c_OPR)) { *cod1 =Ox25; *cod2=1[2].valor; if(l[2].c-tok==c-lYlD) { if(busca-lab(l[2].nombre,&auxint)) /* si esta en la lista */ I I *cod2=auxint; else myerror(nolines,2); *cod3=1[3].valor; *s2=*s3=1; 1 if(1[2].c-tok==c-lY && 1[3].c-tok==c_lX) { *cod1=Ox2a; I if(l[2].c_tok==c_SP && I[3].c_tok==c_lX) { *cod1 =Ox2b; 1 if((l[2].c_tok==c_AX 11 1[2].c_tok==c_BX 11 1[2].c_tok==c_lX 11 I[2].c_tok==c_SP) && (1[3].c_tok==c_dhex 11 I[3].c_tok==c_OPR)) { switch(l[2].c-tok){ case c_AX:*codl=Ox2c;break; case c_BX:*codl=Ox2d;break; case c_lX:*codl =Ox2e;break; case c_SP:*codl=Ox2f;break; 1 *cod2=1[3].valor & Oxff; *cod3=(1[3].valor >>8) & Oxff; *s2=1; *s3= 1; 1 if((1[2].c;_tok==c_AX 11 1[2].c_tok==c_BX 11 1[2].c_tok==c_lX 11 I[2].c_tok==c_SP) && (I[3].c_tok==c_APNN 11 I[3].c_tok==c_OPR)) { switch(l[2].c-tok){ case c_AX:*codl=Ox30;break; case c_BX:*codl=Ox3l;break; case c-lX:*codl =Ox32;break; case c_SP:*codl=Ox33;break; 1 *cod2=1[3].valor & Oxff; *cod3=(1[3].valor >>8) & Oxff; *s2= 1; *s3= 1; 1 if((l[3].c_tok==c_AX I/ I[3].c_tok==c_BX 11 1[3].c-tok==c-lX 11 I[3].c_tok==c_SP) && (I[2].c_tok==c_APNN (1 1[2].c_tok==c_OPR)) { switch(l[3].c-tok){ case c_AX:*codl=Ox34;break; case c-BX:*codl =Ox35;break; case c_IX:*codl=Ox36;break; case c_SP:*codl=Ox37;break; 1 *cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1; *s3=1; 1 if((1[2].c_tok==c_lXD 11 I[2].c_tok==c_lYD 11 I[2].c_tok==c_IXIDII I[2].c-tok==c-lYID) && (I[3].c_tok==c_AL 11 I(3].c-tok==c-AH 11 1[3].c_tok==c_BL (1 I[3].c_tok==c_BH)) { switch(l[2].c_tok){ case c-IXD: *cod1 =Ox1 c; *codl=add-rr(cod1,1[3].c-tok); *cod2=1[2].valor; *s2=1; break; case c-lXID:if(busca-lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1=Ox1 c; *codl=add-rr2(codl,1[3].c-tok); *cod2=auxint; *s2=1 ; 1 else myerror(nolines,2); break; case c-IYD: *codl=Ox20; *cod1=add-rr(codl,1[3].c-tok); *cod2=1[2].valor; *s2=1 ; break; case c-lYID:if(busca-lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1=Ox20; *codl=add-rr2(codl,1[3].c-tok); *cod2=auxint; *s2=1 ; 1 else myerror(nolines,2); break; } /* switch de ultimas opciones*/ }break; case c-ADW: switch(l[2].c-tok){ case c-AX: if(l[3].c-tok==c-BX) *cod1 =OxbO; else myerror(nolines,l); break; case c-IX: switch(l[3].c-tok){ case c-AX: *codl=OxaO;break; case c-BX: *codl=Oxal ;break; case c-IY: *codl=Oxa2;break; case c-SP: *codl=Oxa3;break; default: myerror(nolines,l);break; 1 break; case c-IY: switch(l[3].c-tok){ case c-AX: *codl=Oxa4;break; case c-BX: *codl=Oxa5;break; case c-IX: *codl=Oxa6;break; case c-SP: *cod1=0xa7;break; default: myerror(nolines,l);break; 1 break; 1 break; case c-ACW: if((1[2].c-tok==c-AX) &&(1[3].c_tok==c_BX)) *cod1=Oxbl ; else myerror(nolines,l); break: case c-SCW: if((I[2].c_tok==c_AX) &&(l[3].c-tok==c-BX)) *cod1=0xb2; else myerror(nolines,l); break; case c-BIT:if( (1[2].c-tok==c-hex 11 1[2].c-tok==c-OPR)&& (1[2].valor>=O) && (1[2].valor<=7)) { *cod2=1[2].valor; *s2= 1; switch(l[3].c-tok){ case c-AL: *codl=OxcO;break; case c-AH: *codl=Oxcl ;break; case c-BL: *codl=Oxc2;break; case c-BH: *codl=Oxc3;break; case c-IXD: *cod1 =Oxc4; *cod3=1[3].valor; *s3=1; break; case c-IYD: *cod1 =Oxc5; *cod3=1[3].valor; *s3=1; break; case c-IXID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod1 =Oxc4; *cod3=auxint; *s3=1; 1 else myerror(nolines,2); break; case c-IYID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod1 =Oxc5; *cod3=auxint; *s3= 1; 1 else myerror(nolines,2); break; 1 else myerror(nolines,2); break; case c-SET:if( (1[2].c-tok==c-hex 11 1[2].c-tok==c-OPR)&& (1[2].valor>=O) && (1[2].valor<=7)) { *cod2=1[2].valor; *s2= 1; switch(l[3].c-tok){ case c-AL: *codl=Oxc8;break; case c-AH: *codl=Oxc9;break; case c-BL: *codl=Oxca;break; case c-BH: *codl=Oxcb;break; case c-IXD: *cod1 =Oxc6; *cod3=1[3].valor; *s3=1; break; case c-IYD: *cod1 =Oxc7; *cod3=1[3].valor; *s3= 1; break; case c-IXID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod1 =Oxc6; *cod3=auxint; *s3=1; 1 else myerror(nolines,2); break; case c-IYID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod 1=Oxc7; *cod3=auxint; *s3= 1; 1 else myerror(nolines,2); break; 1 1 else myerror(nolines,2); break; case c-RES:if( (1[2].c-tok==c-hex 11 1[2].c-tok==c-OPR)&& (1[2].valor>=O) && (1[2].valor<=7)) c *cod2=1[2].valor; *s2= 1; switch(l[3].c-tok){ case c-AL: *cod1 =Oxcc;break; case c-AH: *codl=Oxcd;break; case c-BL: *codl=Oxce;break; case c-BH: *codl=Oxcf;break; case c-IXD: *cod1 =Oxel ; *cod3=1(3).valor; *s3=1 ; break; case c-IYD: *codl=Oxe2; *cod3=1[3].valor; *s3=1 ; break; case c-IXID: if(busca-lab(l[3].nornbre,&auxint)) /* si esta en la lista */ { *cod1=Oxel ; *cod3=auxint; *s3=1; 1 else myerror(nolines,2); break; case c-IYID: if(busca-lab(l[3].nombre,&auxint)) /* si esta en la lista */ { *cod1=0xe2; *cod3=auxint; "s3=1; 1 else myerror(nolines,2); break; 1 1 else myerror(nolines,2); break; case c-JPC:switch(l[2].c-tok){ case c-NZ: *codl=OxdO;break; case c-2: *cod1 =Oxd1 ;break; case c-NC: *codl=Oxd2; break; casec-C: *codl=Oxd3;break; case c-S:*codl=Oxd4;break; case c-NS: *codl=Oxd5;break; case c-P: *codl=Oxd6;break; case c-NP: *codl=Oxd7;break; default: myerror(nolines,2);break; 1 switch(l[3].c-tok){ case c-dhex: case c-OPR: *cod2=1[3].valor& Oxff; *cod3=(1[3].valor >>8) & Oxff; *s2=1 ; *s3=1 ; break: I* status =2 -> no resuelto *I case c-OPNR: *cod2=0; *s2=2; *cod3=0; *s3=2; break; default: myerror(nolines,2);break; }break; case c-JRC:break; ................................................................... I /* codigo para instrucciones de un operando *I ................................................................... I codigo-opu(struct line-node 1[4],int *cod1 ,int *cod2,int *cod3,int *sl ,int *s2,int *s3) { int sigue=l ; int auxint=O; *S1=1; I* default:byte 1 valido, los demasno */ *s2=0; *s3=0; switch(l[l].c-tok){ case c-PUSH : *cod1=Ox38; add-op(codl,1[2].c-tok); break; case c-POP : *codl=Ox3c; add_op(codl,I[2].c_tok); break; case c-ADD : *codl=Ox40; switch(l[2].c-tok){ case c-OPR: case c-hex:*codl =Ox44; *cod2=1[2].valor; *s2= 1; sigue=O; break; case c-lXD:*codl =Ox45; *cod2=1[2].valor; *s2= 1; sigue=O; break; case c_lYD:*codl=Ox46; *cod2=1[2].valor; *s2= 1; sigue=O; break; case c-lXID:if(busca-lab(1[2].nombre,&auxint)) /* si esta en la lista *I { *cod1 =Ox45; *cod2=auxint; *s2= 1; sigue=O; 1 else myerror(nolines,2); break: case c~lYID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1 =Ox46; *cod2=auxint; *s2= 1; sigue=O; 1 else myerror(nolines,2): break; 1 if(sigue) add-rr(cod1,1[2].c-tok); break; case c-ADC : *codl=0x48;add~rr(cod1,1[2].c~tok); break; case c-SUB : *cod1=0x4c;add~rr(cod1,1[2].c~tok);break; case c-SBC : *cod1=0x50;add~rr(codl,1[2].c~tok); break; case c-AND : *codl=Ox54;add_rr(codl ,1[2].c_tok); break; break; case c-OR : *codl=0x58;add~rr(codl,1[2].c~tok); case c-XOR : *codl=Ox5c;add-rr(codl ,I[2].c-tok); break; case c-INC : *codl=Ox60; switch(l[2].c-tok){ case c-AX: *cod?=Oxa8;sigue=O;break; case c-BX: *cod1 =Oxa9;sigue=O;break; case c-IX: *codl=Oxaa:sigue=O;break; case c-IY: *codl=Oxab;sigue=O;break; case c-lXD:*codl =Ox47; *cod2=1[2].valor; *s2=1; sigue=O; break; case c_lYD:*codl=Ox68; *cod2=1[2].valor; *s2=1; sigue=O; break; case c-lXID:if(busca-lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1 =Ox47; *cod2=auxint; *s2=1; sigue=O; 1 else myerror(nolines,2); break: case c~lYID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1 =Ox68; *cod2=auxint; *s2=1; sigue=O; 1 case c-lYID:if(busca-lab(1[2].nombre,&auxint)) *cod1 =Ox46; *cod2=auxint; *s2=1 ; sigue=O; 1 else myerror(nolines,2); if(sigue) add-rr(cod1,1[2].c-tok); break; case c-ADC : *codl=0x48;add~rr(codl,1[2].c~tok); break; case c-SUB : *codl=0x4c;add~rr(codl,1[2].c~tok); break; case c-SBC : *codl=0x50;add~rr(codl,1[2].c~tok); break; case c-AND : *codl=0x54;add~rr(codl,1[2].c~tok); break; case c-OR : *cod1=Ox58;add_rr(codl,1[2].c_tok);break; case c-XOR : *codl=Ox5c;~dd-rr(codl,I[2].c-tok); break; case c-INC : *cod1=Ox60; switch(l[2].c-tok){ case c-AX: *cod1=Oxa8;sigue=O;break; case c-BX: *cod1=Oxa9;sigue=O;break; case c-IX: *codl=Oxaa;sigue=O;break; case c-IY: *codl=Oxab;sigue=O;break; case c-lXD:*codl =Ox47; *cod2=1[2].valor; *s2=1 ; sigue=O; break; case c-lYD:*codl =Ox68; *cod2=1[2].valor; *s2=1 ; sigue=O; break; case c~lXID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */ c 1 *cod1=Ox47; *cod2=auxint; *s2=1; sigue=O; else myerror(nolines,2); break; case c~lYID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1 ~ 0 x 6 8 ; *cod2=auxint; *s2=1 ; sigue=O; I else myerror(nolines,2); break; 1 if(sigue) add-rr(cod1,1[2].c-tok); break: case c-DEC : *cod1 ~ 0 x 6 4 ; switch(l[2].c-tok){ case c-AX: *cod1=Oxac;sigue=O;break; case c-BX: *cod1=Oxad;sigue=O;break; case c-IX: *cod1 =Oxae;sigue=O;break; case c-IY: *cod1 =Oxaf;sigue=O;break; case c-lXD:*codl =Ox69; *cod2=1[2].valor; *s2=1 ; sigue=O; break; case c-lYD:*codl =Ox6a; *cod2=1[2].valor; *s2=1 ; sigue=O; break; case c-lXID:if(busca-lab(l[2].nombre,&auxint)) /* si esta en la lista */ { *cod1=Ox69; *cod2=auxint; *s2=1 ; sigue=O; 1 else myerror(nolines,2); break; case c~lYID:if(busca~lab(1[2].nombre,&auxint)) /* si esta en la lista */ { *cod1=Ox6a; *cod2=auxint; *s2=1 ; sigue=O; 1 else myerror(nolines,2); break; 1 if(sigue) add-rr(cod1,1[2].c-tok); break: case c-RLC : *cod1 =0x80;add~rr(codl,1[2].c~tok); break; case c-RL : *cod1=Ox84;add-rr(codl,1[2].c-tok); break; case c-RR : *codl=0x88;add~rr(codl,1[2].c~tok); break; break; case c-RRC : *codl=0x8c;add~rr(codl,l[2].c~tok); case c-SL : *codI=Ox90;add-rr(codl,1[2].c-tok); break; case c-SR : *codl=0x94;add~rr(codl,1[2].c~tok); break; case c-JP : *codl=Oxe3; switch(l[2].c-tok){ case c-dhex: case c-OPR: *cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1; *s3= 1; break; /* status =2 -> no resuelto */ case c-OPNR: *cod2=0; *s2=2; *cod3=0; *s3=2; break; case c-IXP: *codl=Oxe5;break; case c-IYP: *codl=Oxe6;break; 1 break; case c-JR : case c-DJNZ: *cod1 =0xe7; switch(l[2].c-tok){ case c-OPR: *cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1; *s3=1; break; /* status =2 -> no resuelto *I case c-OPNR: *cod2=0; *s2=2; *cod3=0; *s3=2; break; 1 break; case c-CALL: *cod1 =0xe8; switch(l[2].c-tok){ case c-dhex: case c-OPR: *cod2=1[2].valor & Oxff; *cod3=(1[2].valor >>8) & Oxff; *s2= 1; *s3=1; break; /* status =2 -> no resuelto */ case c-OPNR: *cod2=0; *s2=2; *cod3=0; *s3=2; break; default: myerror(nolines,l); break; }break; 1 1................................................................... /* genera codigo a partir de linea *I / gen-cod(struct line-node 1[4],int 'bytes) { int i; int bcl=O,bc2=O,bc3=0; /* bytes de codigo */ int s l =O,s2=O,s3=0; /* status de los bytes de codigo */ int valid=O; *bytes = 1; /* default: un byte de codigo */ if(l[l].c-tok && 1[2].c_tok && I[3].c_tok) { codigo-opb(l,&bcl ,&bc2,&bc3,&sl ,&s2,&s3); add-code(bc1 ,bc2,bc3,sl ,s2,s3,nolines,pc); if(s1 && S2 && s3) *bytes=3; else if(s1 && s2) *bytes=2; 1 else { if(l[l].c-tok && I[2].c-tok ) { codigo-opu(l,&bcl ,&bc2,&bc3,&sl ,&s2,&s3); add-code(bc1 ,bc2,bc3,sl ,s2,~3,nolines,pc); if(s1 && S2 && s3) *bytes=3; else if(s1 && s2) *bytes=2; 1 else { if(l[l].c-tok ) { codigo-op(l,&bcl); add-code(bcl,O,O,l ,O,O,nolines,pc); 1 1 1 1 ....................................................................... / /* genera un nuevo nodo para la lista de etiquetas */ struct lab-node *new-lab-nodeO { struct lab-node *aux; aux=(struct lab-node *)rnalloc(sizeof(struct lab-node)); aux->next=NULL; aux->prev=NULL; return(aux); 1 /* genera un nuevo nodo para la lista de operandos */ struct op-node *new-op-nodeO { struct op-node *aux; aux=(struct op-node *)malloc(sizeof(struct op-node)); aux->next-op=NULL; aux->prev-op=NULL; aux->next-ref=NULL; 1 I* genera un nuevo nodo para la lista de referencias *I struct ref-node *new-ref-nodeO { struct ref-node *aux; aux=(struct ref-ptr *)malloc(sizeof(struct ref-node)); aux->next=NULL; 1 ....................................................................... I I* agrega un nuevo nodo a la lista de etiquetas *I agrega-lab(char name[lO],int valor) { struct lab-node *aux-lab1 ,*aux_lab2; if(1ab-head==NULL) I* si la lista esta vacia *I { lab-head=new-lab-nodeO; strcpy(lab-head->name,name); lab-head->value=valor; 1 else { I* hay ya algo *I aux-labl=lab-head; while ( aux-lab2=aux-labl->next ) aux-labl=aux-lab2 ; I* aux-lab1 is the last node*/ aux-lab2=new-lab-nodeO; strcpy(au~-lab2->name,name); aux-lab2->value=valor; aux-lab2->prev=aux-labl; aux-labl->next=aux-lab2; 1 1 I* realiza una busqueda sobre la lista de etiquetas *I int busca-lab(char name[l O],int *valor) { struct lab-node *auxl ; auxl =lab-head; while( (strcmp(aux1->name,name)!=O)&&auxl ) auxl =auxl ->next; if(strcmp(aux1->name,name)==O) { *valor=auxl->value; return(1); 1 else return(0); /* realiza una busqueda sobre la lista de operandos *I struct op-node *busca-op(char name[l O]) { struct op-node *auxl ; auxl =op-head; while( (strcmp(aux1->name,name)!=O)&& auxl ) auxl =auxl ->next-op; if(strcmp(aux1->name,name)==O) { return(aux1); 1 else { 1 auxl =NULL; return(aux1); 1 /* agrega un nuevo nodo a la lista de referencias *I agrega-ref(struct op-node *op,int re9 struct ref-node 'auxl ,*aux2; auxl =op->next-ref; while ( aux2=auxl->next ) auxl=aux2 ; I* auxl is the last node*/ aux2=new-ref-nodeO; aux2->ref=ref; auxl->next=aux2: /* agrega un nuevo nodo a la lista de operandos *I agrega-op(char name[lO],int re9 { int sigue=l ; struct op-node *auxl ,*aux2; if(op-head==NULL) /* si la lista esta vacia */ op-head=new-op-nodeO; strcpy(op-head->name,name); op-head->next-ref=new-ref-nodeO; op-head->next-ref->ref=ref; /* ya hay algo */ auxl =busca-op(name); if(aux1) /* si ya esta en la lista op*/ agrega-ref(aux1 ,ref); /* lista no vacia, pero no esta op */ else { auxl =op-head; while ( aux2=auxl-~next~op ) auxI=aux2 ; /* auxl is the last node*/ aux2=new-op-nodeO; strcpy(aux2->name,name); aux2->next-ref=new-ref_nodeO; /* busca una linea de codigo a partir del numero de linea */ struct code-line *busca-cl(int numero) { struct code-line *aux; aux=first-line; while(aux) { if(aux->num==numero) return(aux); aux=aux->next; 1 return(aux); 1 /* modifica una linea de codigo ya generada *I mod-codigo(int code-line,int new-value) { struct code-line *aux; aux=busca-cl(code-line); if(aux) /* si existe ese numero de linea */ { if(aux->status2==2 ) { aux->byte2=new-value 8, Oxff; aux->byte3=(new-value>>8) 8, Oxff; aux->st~4us2=1; aux->status3=1; else myerror(nolines,2); 1 /* resuelve el valor deuna referencia */ resolve-ref(char name[lO],int valor) { struct op-node *auxop; struct ref-node *auxref; auxop=busca-op(name); if (auxop==NULL) return(1); /*myerror(nolines,2);*/ auxref=auxop->next-ref; while(auxref) { mod-codigo(auxref->ref,valor); auxref=auxref->next: 1....................................................................... I I* manejo de la lista de operandos *I op-mngr(char name-op[l O],int ref,int *valor,int *status) { if(busca-lab(name-op,valor)) /* si esta op, regresa valor *I *status=l ; else I* si no, agregalo laa lista op de *I { agrega-op(name-op,ref); *status=O; 1 1 I* manejo de lalista de etiquetas *I lab-mngr(char name-lab[lO],int { 1 valor,int *status) if(busca-lab(name-lab,valor)) I* si esta, genera error *I *status=O; else { agrega-lab(name-lab,valor); resolve-ref(name-lab,valor); *status=l ; 1 /* imprime etiquetas y sus valores en arch *I void print-lab(FILE *arch) { struct lab-node *aux; aux=lab-head; fprintf(arch," NOMBRE\t\tVALOR\n"); while(aux) { fprintf(arch," %s\t\to/~04x\n",aux-~name,aux-~value); aux=aux->next; 1 } I* manejo de errores de yacc *I yyerror(char *cad ) { printf("ERR0R . %S on line %d\n",cad,noiines); return(1); 1 o /* archivo myasm.c : ensamblador, espera recibir los nombres de los archivos de entrada (ensamblador) y de salida(codigo objeto), genera un tercer archivo.sym con la lista de simbolos resueltos. Llama a yyparseo y yylexo */ #include <stdio.h> #include <dos.h> #include "yout.c" #include "cod1ex.c" #include "1out.c" ......................................................................... /* lista de funciones */ YyparseO; /* llamadaal analizadorsintactico */ print-lab(fsym); /* se imprime la lista de simbolos */ gen-lst(namei,nameo); /* se imprime la lista de codigo *I ......................................................................... gen-lst(char filename[40],char oname[40]) { FILE *filei,*fileo; char cadena[80]; int ¡=O; struct code-line *aux; aux=first-line; if((filei=fopen(filename,"r"))==NULL) /* se abre el archivo de entrada*/ .. { printf("Error al abrir el archivo %s\n",filename); 1 else { /* se abre el archivo de salida */ if((fileo=fopen(oname,"w"))==NULL) { printf("Error al abrir el archivo %s\n",oname); 1 else { while(*fgets(cadena,80,filei)!=NULL) { fprintf(fileo,"%03d. /* imprime num de linea */ if(aux-mum==¡ && aux) { /* imprime el contador del programa */ fprintf(fileo,"%04x: ",aux->pcounter); /* imprime los bytes de codigo */ if(aux-xtatusl) fprintf(fileo,"%02x ",aux->bytel); if(aux->status2) fprintf(fiIeo,"%02x ",aux->byte2); if(aux->status3) fprintf(fiIeo,"%02x ",aux->byte3); aux=aux->next; 'I,¡); 1 fprintf(fileo,": %s",cadena); i++; 1 fclose(fi1ei); fclose(fi1eo); 1 1 1 void main(int argc,char *argv[]) { FILE *fi,*fo,*fsym; int i; char *charp,*charp2; char namei[l4]; char nameo[l4]; char namesym[l4]; if(argc==l) /* error, no se dio argumento */ { printf("MYASM : Error, no se ha dado nombre de archivo."); exit(1); 1 if(argc==2) /*solo se dio el nombre del archivo de entrada*/ { strcpy(namei,argv[l]); strcpy(nameo,namei); /* se genera el nombre del archivo de codigo */ charp=strchr(nameo,'.'); charp++; *charp='\O'; strcat(nameo,"lst"); /* se genera el nombre del archivo de simbolos resueltos */ strcpy(nan;esym,namei); charp=strchr(namesym,'.'); charp++; *charp='\O'; strcat(namesym,"sym"); 1 if(argc>=3) /* se dieron nombres de archivos de entrada y salida */ { strcpy(namei,argv[l]); strcpy(nameo,argv[2]); strcpy(namesym,namei); /* se genera el nombre del archivo de simbolos resueltos */ charp=strchr(namesym,'.'); charp++; *charp='\O'; strcat(namesym,"sym"); 1 if((fi=fopen(namei,"r"))!=NULL) { if((fo=fopen(nameo,"w"))!=NULL) { if((fsym=fopen(namesym,"w"))!=NULL) { printf("Archivos abiertos exitosamente.\n"); fclose(f0); yyin=fi; yyparse0; /* llamada al analizadorsintactico */ fclose(yyin); print-lab(fsym); /* se imprime la lista de simbolos */ fclose(fsym); gen-lst(namei,nameo); /* se imprime la lista de codigo */ 1 else printf("Error al abrir %s.",namesym); fclose(fo); 1 else printf("Error al abrir %s.",nameo); fclose(fi); 1 else printf("Error al abrir %s.",namei); /* archivo miosimf.c : simulador del microprocesador *I .................................................................. lista de funciones: asigna(int codigo,int to,int d-to,int v-to, int from,int d-fromjnt v-from,struct op *salida) I* obtiene el siguientebyte del codigo *I int next0 int next-w0 I* obtiene el siguienteword del codigo *I decodif(int instr, struct op *outp) dec-carga(int instr,struct op *Sal) dec-arit(int instr,struct op *Sal) dec-rot(int instr,struct op *sal) dec-call(int instr,struct op *sal) gen-flags(int *banderas) regen-flags(int banderas) zflag(int valor) ejec(struct op oper) int cap-num(n,x,y) struct image-node *new-image-nodeO agrega-image(char text[80],int valori,int valorpc) struct image-node *busca-image(int newpc) int firstpco I* busca en la lista-imagen del archivo . k t el primer PC *I revisa2p(char *auxp) fimage(char filename[40]) I* genera la lista-imagen del archivo filename */ /* muestra 64 bytes de la memoria a partir de la direccion *orig en la ventana que este activa *I print-mem(int *orig) show-reg0 I* muestra el status de los registros en la ventana activada */ show-reg20 altera-reg0 /* altera los valores de los registros *I int chextoint(char *cp) int conv-hex(char *cp) int conv-dec(char *charp,int tamano) separa(char cadena[80],int *newline, int *newpc, int *bytel, int *byte2, int *byte3,int *status) altera-memo I* altera los valores de la memoria *I menu-memo mem2(int *dir) menu") /* perrrde generar una interrupcion si estan habilitadas *I I* le pide al usuario el nombre de un archivo . k t y revisa qque exista *I print-arch(char filename[30],int *filestat) I* menu inicial delsimulador, mientras error y no-ESC => sigue */ print-ini(char name[40],int *fileerr) print-image0 I* imprime un renglon de la lista-imagen del archivo en la ventana activada *I print-reng(struct image-node *aux) print-opt0 /* opciones del simulador *I void gen-symbols(char namei[l4]) Fin de la lista de funciones. ........................................................................ I ......................................................................... I #include <conio.h> #include "p0pup.h" #include "mouse.h" #include <alloc.h> #include <stdio.h> #include <ctype.h> I* definiciones de entidades direccionables *I #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define AL O AH 1 BL 2 BH 3 IY 5 AX 20 BX 21 IX 22 SP 23 FLAGS 24 IXD 10 IYD 11 AP1-NN 12 AP2-NN 15 N 13 W 14 I* word *I INTV 8 M9 I* definiciones de codigos de operaciones *I #define1LD #define PUSH #define POP #define ADD #define ADC #define SUB #define SBC #define AND #define OR #define XOR1 #define INC 11 #define DEC #define DAA 13 #define CPL #define NEG #define CCF #define SCF #define HALT #define DI #define El #define RLC #define 22 RL #define 23 RR #define RRC 24 #define SL #define 26 SR 2 3 4 5 6 7 8 9 O 12 14 15 16 17 18 19 20 21 25 #define BIT #define SET #define RES #define JP #define JR #define DJNZ #define CALL #define RET #define RETI #define JPC #define JRC #define ADW #define ACW #define SCW 27 28 29 3c 31 32 33 34 35 36 37 38 39 40 /* definiciones de condiciones de salto */ #define N 2 #define 2 #define NC #define C #define S #define NS #define P #define 7NP O 1 2 3 4 5 6 #define MAXMEM Ox100 ......................................................................... / typedef struct op{ int union acc{ int axbx[2]; char ab11[4]; }accs; /* operacion por realizar */ codigo; int int int destino; destino */ desp-destino; /* desp v-destino; /* valor destino */ int int int fuente; desp-fuente; v-fuente; /* desplazamiento origen*/ /* valor origen */ 1; /* O) AX , 1) BX */ /* O AL, 1AH, 2 BL, 3 BH */ /* informacion sobre un renglon de un archivo .Ist */ struct ¡magemnode{ int lineno; /* # derenglondentro del archivo */ int linepc; /* PC de la instruccion por ejecutar */ char info[80]; /* cadena con [etiqueta] instruccion */ struct image-node *next; 1; ......................................................................... /* variables globales / *I int CF=O,SF=O,ZF=O,IFF=O,PF=O; /* FLAGS *I int reg[4]={0,0,0,0}; /*registros:IX, IY, SP, IP */ char reg-intv; /*registros: FLAGS, INTV */ intreg-flags=O; int intflag=O; /* bandera de interrupciones */ int no-halt=l; /* bandera de halt */ int mem[MAXMEM]; /* arreglomemoria de *I int pcglob=O; /* PC simulador del *I struct image-node *image-head=NULL; ........................................................................ * * * modulo de decodificacion de instrucciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . asigna(int codigo,int to,int d-to,int v-to, int from,int d-from,int v-from,struct op *salida) { salida-xodigo = codigo; salida->fuente = from; salida->desp-fuente = d-from; salida->v-fuente = v-from; salida->destino = to; salida->desp-destino = d-to; salida->v-destino = v-to; } ......................................................................... / int next0 /* obtieneelsiguientebyte delcodigo */ { return(mem[pcglob++]); 1 intnext-w0 /* obtiene el siguienteword delcodigo */ int intaux,intaux2; int auxl ,aux2; auxl =next(); aux2=nextO; intaux=aux2; /* high */ intaux=intauxcc$; auxl= auxl & OxOOff; /* low */ intaux=intauxlauxl; return(intaux); ......................................................................... decodif(int instr, struct op *outp) { char rotado; rotado=instr; rotado=rotado>>6; switch (rotado){ ,I case O: dec-carga(instr,outp); break; case 1: dec-arit(instr,outp); break; case Oxfffe: dec-rot(instr,outp); break; case Oxffff: dec-call(instr,outp); break; 1 1 .......................................................................... dec-carga(int instr,struct op *sal) { int maskl=0x0006,mask2=0x0003; int auxl ,aux2,auxint; if (instr>=OxO && instrc=OxF) /* LD r,r' */ { auxl = (instr&maskl)>>2 ; aux2 = instr&mask2; asigna(LD,auxl ,O,O,aux2,0,0,sal); 1 if (instr>=Oxl O && instr<=Ox13) /* LD r,n *I { auxl = next(); aux2 = instr&mask2; asigna(LD,aux2,0,0,N,O,auxl ,sal); 1 if (instr>=Oxl4 && instrc=Oxl7) /* LD r,(lX+d) */ { auxl = next(); aux2 = insrr&mask2; asigna(LD,aux2,0,0,IXD,auxl ,O,sal); 1 if (instr>=Oxl8 && instrc=Oxl b) /* LD r,(lY+d) */ { auxl = next(); aux2 = instr&mask2; asigna(LD,aux2,0,0,IYD,auxl ,O,sal); 1 if (instr>=Oxlc && instrc=Oxlf) { /* LD (IX+d),r */ auxl = next(); aux2 = instr&mask2; asigna(LD,IXD,auxl ,O,aux2,0,0,sal); 1 if (instr>=Ox20 && instrc=Ox23) /* LD (IY+d),r */ { auxl = next(); aux2 = instr&mask2; asigna(LD,IYD,auxl ,O,aux2,0,0,sal); 1 switch(instr){ case 0x24: auxl = nexto; /* LD (IX+d),n */ aux2 = next(); asigna(LD,IXD,auxl ,O,N,O,aux2,sal); break; case 0x25: auxl = nexto; /* LD (IY+d),n */ aux2 = next(); asigna(LD,IYD,auxl ,O,N,O,aux2,sal); break; / case 0x26: aux2 = next-w0; /* LD AL,(nn) */ asigna(LD,AL,O,O,AP1~NN,aux2,0,sal); break; case 0x27: auxl = next-w0; /* LD (nn),AL */ asigna(LD,APl-NN,auxl ,O,AL,O,O,sal); break; case 0x28: asigna(LD,AL,O,O,INTV,O,O,sal); /* LD AL,INTV */ break; case 0x29: asigna(LD,INTV,O,O,AL,O,O,sal); /* LD INT'V,AL */ 1 if (instr>=Ox2c && instr<=Ox2f) /* LD dd,nn */ { aux2 = next-w0; /* dd= AX,BX,IX,SP */ auxl = instr&mask2; auxl =auxl+20; asigna(LD,auxl ,O,O,W,O,aux2,sal); 1 if (instr>=Ox30 && instr<=Ox33) { aux2 = next-w0; auxl = instr&mask2; auxl =auxl+20; I* LD dd,(nn) */ asigna(LD,auxl ,O,O,AP2-NN,aux2,0,sal); 1 if (instr>=Ox34 && instr<=Ox37) { /* LD (nn),dd */ auxl = next-w0; aux2 = instr&mask2 + 20; asigna(LD,AP2-NN,auxl ,O,aux2,0,0,sal); 1 switch(instr){ case Ox2a: asigna(LD,IY,O,O,IX,O,O,sal); break; case Ox2b: asigna(LD,SP,O,O,IX,O,O,sal); break; /* LD IY,IX /* LD SP,IX */ 1 if (instr>=Ox38 && instrc=Ox3b) /* PUSH qq */ { /* qq=AX,BX,IX,FLAGS *I auxl = (instr&mask2) + 20; if (auxl==23) auxl++; /* as¡ auxl es FLAGS */ asigna(PUSH,O,O,O,auxl,O,O,sal); 1 if (instr>=Ox3c && instr<=Ox3f) I* POP qq *I { auxl = (instr&mask2) + 20; if (auxl==23) auxl++; /* asi auxl.es FLAGS */ asigna(POP,auxl ,O,O,O,O,O,sal); 1 1 ......................................................................... dec-arit(int instr,struct op *sal) { int mask2=0x0003; I' int auxl ,aux2; if (instr>=Ox40 && instr<=Ox43) /*ADD r */ { aux2 = instr&mask2; asigna(ADD,AL,O,O,aux2,O,O,sal); 1 if (instr>=Ox48 && instr<=Ox4b) { aux2 = instr&mask2; /* ADC r */ asigna(ADC,AL,O,O,aux2,O,O,sal); 1 if (instr>=Ox4c && instr<=Ox4f) /*SUB r */ { aux2 = insfr&mask2; asigna(SUB,AL,O,O,auxZ,O,O,sal); 1 if (instr>=Ox50 && instr<=Ox53) { /* SBC r */ aux2 = instr&mask2; asigna(SBC,AL,O,O,aux2,O,O,sal); 1 if (instr>=Ox54 && instr<=Ox57) /*AND r */ { aux2 = instr&mask2; asigna(AND,AL,O,O,auxZ,O,O,sal); 1 if (instr>=Ox58 && instr<=Ox5b) { /* OR r */ aux2 = instr&mask2; asigna(OR,AL,O,O,aux2,O,O,sal); 1 if (instr>=Ox5c&& instr<=Ox5f) { /* XOR r */ aux2 = instr&mask2; asigna(XOR,AL,O,O,aux2,O,O,sal); 1 if (instr>=Ox60 && instr<=Ox63) /* INC r */ { aux2 = instr&mask2; asigna(lNC,aux2,0,0,aux2,O,O,sal); 1 if (instr>=Ox64 && instr<=Ox67) /* DEC r */ { aux2 = instr&mask2; asigna(DEC,aux2,0,0,aux2,O,O,sal); 1 switch(instr){ case 0x44: auxl = next(); /*ADD n */ asigna(ADD,AL,O,O,N,O,auxl ,sal); break; case0x45: aux2 = next(); I* ADD (IX+d)*/ dsigna(ADD,AL,O,O,IXD,aux2,0,sal); break; case0x46: aux2 = next(); /* ADD (IY+d)*/ asigna(ADD,AL,O,O,IYD,aux2,0,sal); break; I* INC (IX+d) *I aux2 = next(); asigna(lNC,IXD,aux2,0,IXD,aux2,0,sal); break; case0x68: aux2 = next(); I* INC (IY+d) */ case0x47: asigna(lNC,IYD,aux2,O,lYD,aux2,0,sal); break; case0x69:aux2 = next(); I* D E C (IX+d) *I asigna(DEC,IXD,aux2,O,lXD,aux2,0,sal); break; case Ox6a: aux2 = next(); I* DEC (IY+d)*I asigna(DEC,IYD,aux2,0,IYD,aux2,0,sal); break; } 1.......................................................................... dec-rot(int instr,struct op *sal) { int mask=Ox0003; int auxl ,aux2; if (instr>=Ox80 && instr<=Ox83) I* R L C r *I { auxl = instr&mask; asigna(RLC,auxl ,O,O,O,O,O,sal); I 1 if (instr>=Ox84 && instr<=Ox87) I* R L r *I { auxl = instr&mask; asigna(RL,auxl ,O,O,O,O,O,sal); 1 if (instr>=Ox88 && instr<=Ox8b) I* RR r *I { auxl = instr&mask; asigna(RR,auxl ,O,O,O,O,O,sal); 1 if (instr>=Ox8c && instr<=Ox8f) /* R R C r */ { auxl = instr&mask; asigna(RRC,auxl ,O,O,O,O,O,sal); 1 if (instr>=Ox90&& instr<=Ox93) I* SL r *I { auxl = instr&mask; asigna(SL,auxl ,O,O,O,O,O,sal); } if (instr>=Ox94 && instr<=Ox97) I* SR r *I { auxl = instr&mask; asigna(SR,auxl ,O,O,O,O,O,sal); 1 switch(instr){ case 0x98: asigna(DAA,AL,O,O,O,O,O,sal); I* DAA *I break; case 0x99: asigna(CPL,AL,O,O,O,O,O,sal); I* CPL *I break; case Ox9a: asigna(NEG,AL,O,O,O,O,O,sal); I* NEG */ I break; case Ox9b: asigna(CCF,FLAGS,O,O,O,O,O,sal); /* CCF */ break; case Ox9c: asigna(SCF,FLAGS,O,O,O,O,O,sal); I* SCF *I break; case Ox9d: asigna(HALT,O,O,O,O,O,O,sal); I* HALT *I break; case Ox9e: asigna(DI,FLAGS,O,O,O,O,O,sal); I* DI *I break; case Ox9f: asigna(EI,FLAGS,O,O,O,O,O,sal); I* El *I break; case OxbO: asigna(ADD,AX,O,O,BX,O,O,sal); /* A D DA X , B X */ break; caseOxbl : asigna(ADC,AX,O,O,BX,O,O,sal); /* A D C A X , B X *I break; case Oxb2: asigna(SBC,AX,O,O,BX,O,O,sal); I* SBC AX,BX *I break; if (instr>=OxaO && instr<=Oxa3) { auxl = instr&mask; switch(auxl){ case O: aux2 = A X ; break; case 1 : aux2 = BX; break; case 2: aux2 = IY; break; case 3: aux2 = SP; break; /* ADD IX ppl */ I* ppl=AX,BX,IY,SP*I 1 I asigna(ADD,IX,O,O,aux2,O,O,sal); if (instr>=Oxa4 && instr<=Oxa7) { auxl = instr&mask; switch(auxl){ case O: aux2 = A X ; break; case 1 : aux2 = BX; break; case 2: aux2 = IX; break; case 3: aux2 = SP; break; I* ADD IY,pp2 *I I* pp2=AX,BX,IX,SP*I I I asigna(ADD,IY,O,O,aux2,O,O,sal); if (instr>=Oxa8&& instr<=Oxab) I* INC ww *I I* ww=AX,BX,IX,IY*I auxl = instr&mask; switch(auxl){ case O: aux2 = A X ; break; case 1 : aux2 = BX; break; case 2: aux2 = IX; break; case 3: aux2 = IY; break; { 1 asigna(lNC,aux2,0,0,aux2,O,O,sal); 1 if (instr>=Oxac && instr<=Oxaf) { auxl = instr&mask; switch(auxl){ case O: dux2 = A X ; break; I* D E C ww *I dec-call(int instr,struct op *sal) { int mask=0x0003,mask3=0xOOO7; int auxl ,aux2; if (instr>=OxcO && instr<=Oxc3) { aux2 = next(); auxl = instr&mask; I* BIT b.r */ asigna(BIT,auxl,0,0,aux2,0,0,sal); 1 if (instr>=Oxc8 && instr<=Oxcb) { aux2 = next(); auxl = instr&mask; asigna(SET,auxl ,O,O,aux2,0,0,sal); I* SET b,r *I 1 I* RES b,r *I if (instr>=Oxcc && instrc=Oxcf) { aux2 = next(); auxl = instr&mask; asigna(RES,auxl,0,0,aux2,0,0,sal); 1 if (instr>=OxdO && instr<=Oxd7) { auxl = instr&mask3; aux2 = next-w0; asigna(JPC,O,O,aux2,O,O,auxl,sal); I* JPC ccc,nn */ 1 if (instr>=Oxd8 && instr<=Oxdf) { auxl = instr&mask3; aux2 = next-w0; asigna(JRC,O,O,aux2,O,O,auxl,sal); I* JRC ccc,nn *I 1 switch(instr){ case Oxc4: aux2 = next(); I* BIT b,(lX+d:)*I auxl = next(); asigna(BIT,IXD,auxl ,O,aux2,0,0,sal); break; I* BIT b,(lY+d:) */ case Oxc5: aux2 = next(); auxl = next(); asigna(BIT,IYD,auxl ,O,aux2,0,0,sal); break; case Oxc6: aux2 = next(); I* SET b,(lX+cl) */ auxl = next(); asigna(SET,IXD,auxl ,O,aux2,0,0,sal); break; I* SET b,(lY+d) *I case Oxc7: aux2 = next(); auxl = next(); asigna(SET,IYD,auxl ,O,aux2,0,0,saI); break; case Oxel: aux2 = next(); I* RES b,(lX+d) *I auxl = next(); asigna(RES,IXD,auxl ,O,aux2,0,0,sal); break; case Oxe2: aux2 = next(); I* RES b,(lY+d) */ auxl = next(); asigna(RES,IYD,auxl ,O,aux2,0,0,sal); break; case Oxe3: auxl = next-w0; I* JP nn *I asigna(JP,W,O,auxl ,O,O,O,sal); break; case Oxe4: auxl = next-w0; I* JR e *I asigna(JR,W,O,auxl ,O,O,O,sal); break; case Oxe5: asigna(JP,IX,O,O,O,O,O,sal); I* JP (IX) *I break; case Oxe6. asigna(JP,IY,O,O,O,O,O,sal); I* JP (IY) *I break; case Oxe7: auxl = next-w0; asigna(DJNZ,BL,O,O,O,O,auxl,sal); I* DJNZe *I break; case Oxe8: auxl = next-w0; I* CALL nn *I asigna(CALL,O,O,auxl ,O,O,O,sal); break; case Oxe9: asigna(RET,O,O,O,O,O,O,sal); I* RET *I break; case Oxea: asigna(RETI,O,O,O,O,O,O,sal); I* RETI *I break; 1 1 ......................................................................... * * modulo de ejecucion de las instrucciones * .......................................................................... I gen-flags(int *banderas) *banderas=O; if(CF) *banderasI=Ox80; if(SF) *banderasl=Ox40; if(ZF) *banderasl=Ox20; if(lFF) *banderasl=Oxl O; if(PF) *banderasI=Ox8; regen-flags(int banderas) { CF=SF=ZF=IFF=PF=O; if(banderas & 0x80) CF=I ; if(banderas & 0x40) SF=I ; if(banderas & 0x20) ZF=l ; if(banderas & 0x1 O) IFF4 ; if(banderas & 0x8) P F = l ; 1 zflag(int valor) { if(valor==O) ZF=l ; else ZF=O; 1 ejec(struct op oper) { char *fuente1 ,*destino1; int *fuente2; int *fuente3; int *destino2; int *destino3; int auxhl; int intaux,intaux2; int carry; char mask=O; int saltar=O; fuentel =O; switch(oper.fuente){ I* modos de direccionamiento, *I case O: fuentel=&accs.abll[O]; break; I* A L */ case 1 : fuentel=&accs.abll[l]; break; I* AH *I case 2: fuentel=&accs.abll[2]; break; I* B L *I case 3:fuentel=&accs.abll[3]; break; I* B H *I case 5: fuente2=&reg[l]; break;I* IY *I case 8: fuentel =&reg-intv; break; I* INTV *I case 1 O: fuentel =&mem[reg[O]+oper.desp-fuente]; break; I* IX+desp *I case 1 1 : fuentel =&mem[reg[l]+oper.desp-fuente]; break; /* IY+desp *I case12:fuentel =&mem[oper.desp-fuente]; break; I* (NN) *I case 13: fuentel=malloc(sizeof(fuentel)); *fuente1 =oper.v-fuente; break; case 14: fuente2=malloc(sizeof(fuente2)); *fuente2=oper.v-fuente; break; case 15: fuente2=&mem[oper.desp-fuente]; fuente3=&mem[oper.desp-fuente+l]; break; case 20: fuente2=&acc~.axbx[O]; break; I* A X *I case 21: fuente2=&accs.axbx[l]; break;I* B X *I case 22: fuente2=&reg[O]; break; I* IX *I case 23: fuente2=&reg[2]; break; I* SP *I case 24: gen-flags(&reg-flags); fuente2=&reg_flags; break; I* F L A G S *I 1 switch(oper.destino){ I* modos de direccionamiento *I case O: destinol=&accs.abll[O]; break;I* A L *I case 1 : destinol=&accs.abll[l]; break; I* AH *I case 2: destinol=&accs.abll[2]; break; I* B L *I case 3: destinol=&accs.abll[3]; break;I* BH *I case 5: destino2=&reg[l]; break;I* IY *I case 8: destinol=&reg-intv; break; I* INTV *I case 10: destinol =&mem[reg[O]+oper.desp_destino]; break; I* IX+desp *I case 11: destinol=&mem[reg[l ]+oper.desp-destino]; break; I* IY+desp *I case 12: destinol=&mem[oper.desp-destino]; break;/" (NN) ap-1 byte *I case 13: destinol =&(oper.desp-destino); break; case 14: destinol=&(oper.desp-destino); break; case 15: destino2=&mem[oper.desp_destino]; destino3=&mem[oper.desp_destino+l]; break; I* (NN) ap-2bytes *I case 20: destino2=&accs.axbx[O]; break; case 21 : destin02=&accs.axbx[l]; break; case 22: destin02=&reg[O]; break; destino2=&reg[2]; case 23: break; case 24: destin02=&reg_flags; break; /* AX */ I* BX *I I* IX "'I I* SP *I I* FLAGS *I 1 switch (oper.codigo){ case LD: if (fuentel==O) { if(oper,fuente==l5) /* (nnnn) */ auxhl=(*fuente2)<<8; I* parte alta *I auxhll=*fuente3; I* parte baja */ *destino2=auxhl; if(oper.destino==15) I* (nnnn) *I { *destino3=*fuente2&0xff; /* parte baja *I *destino2=(*fuente2)>>8; I* parte alta *I *destino2=*destino2&0xff; } else *destino2=*fuente2; /* se mueven 2 bytes */ } I* if (oper.fuente==l5) *I zflag(*destino2); /* genera el ZF *I } I* if (fuentel==O) *I else { *destino1 =*fuente1; I* se mueve 1 byte *I zflag(*destinol); I* genera el ZF *I 1 break; case PUSH: mem[reg[2]+1]=*fuente2&Oxff; I* mem[SP-2]=qql *I mem[reg[2]+2]=(*fuente2&0xffOO)>>8; I* mem[SP-l]=qqh *I reg[2]=reg[2]+2; /* SP=SP+2 *I break: case POP: reg[2]=reg[2]-2; intaux=mem[reg[2]+2]; intaux=intaux<<8; intaux2=mem[reg[2]+1]; intaux2=intaux2&0x00ff: I* high *I I* low *I intaux=intauxlintaux2; *destino2=intaux; if(oper.destino==FLAGS) regen-flags(reg-flags); break; I* POP FLAGS *I case ADD: if (fuentel==O) { *destino2=*destino2 + *fuente2; I* se mueven 2 bytes *I zflag(*destino2); 1 else { *destino1 =*destino1 + *fuente1 ; I* se mueve 1 byte *I zflag(*destinol); 1 break; case ADC: if (fuentel==O) { *destino2=*destino2 + *fuente2 + CF; zflag(*destino2); 1 else { *destinol=*destinol + *fuente1 + CF; zflag(*destinol); 1 break; case SUB: case SBC: *destinol= *destino1 - *fuentel; zflag(*destinol); break; if (fuentel==O) { *destino2=*destino2 - *fuente2 - CF; zflag(*destino2); 1 else { *destino1 =*destino1 - *fuente1 - CF; zflag(*destinol); 1 break; case AND: *destino1 = *destino1 & ‘fuentel; zflag(*destinol); break; case case OR: *destino1 = *destino1 I *fuentel; zflag(*destinol); bl (;a k; XOR: *destino1 = *destino1 *fuentel; case case case case case case case case case case zflag(*destinol); break; INC: if (fuentel==O) *destino2 = *fuente2 + 1; I* se mueven 2 bytes */ else *destino1 = *fuente1 + 1; /* se mueve 1 byte *I break; DEC: if (fuentel ==O) *destino2 = *fuente2 - 1; I* se mueven 2 bytes *I else *destino1 = *fuente1 - 1; I* se mueve 1 byte */ break; CPL: *destino1 = -*destino1 ; break; NEG: *destino1 = O - *destinol; break; CCF: if (CF) CF=O; else CF=l; break; SCF: CF=1; break; HALT: no_halt=O; break; DI: IFF=O; intflag=O; break; El: IFF=l; intflag=l ; break; RLC: I* 9-bit rotate *I if (*destino1 & 0x80) /* r.7=1 */ { if (CF==O) { CF=I ; *destino1 = *destino1 << 1; I* r.0 = O *I 1 else { *destino1 = *destino1 <c 1; *destino1 = *destino1 I 0x01; I* r.0 = 1 *I 1 1 else I* r.7=0*/ { if (CF) { CF=O; *destino1 = *destino1 << 1; *destino1 = *destino1 I 0x01; I* r.0 = 1 *I 1 else *destino1 = *destino1 << 1; 1 caseRL: zflag(*destinol); break; /* 8-bit rotate *I if (*destino1 & 0x80) /* r.7=1 *I { if (CF==O) CF=l; *destino1 = *destino1 << 1; *destino1 = *destino1 I 0x01; I* r.0 = CF *I 1 else I* r.7=0*/ { if (CF) CF=O; *destino1 = *destino1 << 1; 1 caseRR: zflag(*destinol); break; /*8-bit rotate *I if (*destino1 & 0x01) I* r.7=1 */ { if (CF==O) CF= 1; *destino1 = *destino1 >> 1; *destino1 = *destino1 I 0x80; I* r.0 = CF */ else I* r.7=0*/ { if (CF) CF=O; *destino1 = *destino1 >> 1; 1 case zflag(*destinol); break; RRC: /*9-bit rotate *I if (*destino1 & 0x01) I* r.0=1 *I { if (CF==O) { CF=l; *destino1 = *destino1 >> 1; I* r.7 = O *I 1 else { 1 *destino1 = *destino1 >> 1; *destino1 = *destino1 I 0x80; I* r.7 = 1 *I 1 else I* r.O=O *I { if (CF) { CF=O; *destino1 = 'destino1 >> 1: I *destino1 = *destino1 I 0x80; /* r.7 = 1 */ else I case *destino1 = *destino1 >> 1; zflag(*destinol); break; SL: if (*destino1 & 0x80) /* r.7=1 */ { if (CF==O) CF=1; *destino1 = *destino1 << 1; I I* r.7=0*/ else { if (CF) CF=O; *destino1 = *destino1 << 1; I case zflag(*destinol); break; SR: if (*destino1 & 0x01) /* r.0=1 */ { if (CF==O) CF=1; *destino? = *destino1 >> 1; I else /* r.O=O*/ { if (CF) CF=O; *destino1 = *destino1 >> 1; I case zflag(*destinol); break; BIT: switch (oper.fuente){ /* oper.fuente = # de bit "/ case O: mask = 0x1; break; case 1: mask = 0x2; break; case 2: mask = 0x4; break; case 3: mask = 0x8; break; case 4: mask = 0x10; break; case 5: mask = 0x20; break; case 6: mask = 0x40; break; case 7: mask = 0x80; break; I if (*destino1 8, mask) ZF=O; /* si bit == 1 , ZF = O */ else ZF=l; /* si bit == O , ZF = 1 */ break; case SET: switch (oper.fuente){ /* oper.fuente = # de bit *,I case O: mask = 0x1; break; case 1: mask = 0x2; break; case 2: mask = 0x4; break; case 3: mask = 0x8; break; case 4: mask = 0x10; break; case 5: mask = 0x20; break; case 6: mask = 0x40; break; case 7: mask = 0x80; break; 1 if (( *destino1 & mask)==O) *destino1 = *destino1 I mask; break; case RES: switch (oper.fuente){ I* oper.fuente = # de bit */ case O: mask = 0x1; break; case 1: mask = 0x2; break; case 2: mask = 0x4; break; case 3: mask = 0x8; break; case 4: mask = 0x10; break; case 5: mask = 0x20; break; case 6: mask = 0x40; break; ;ase 7: mask = 0x80; break; 1 case case case case case case case if (*destino1 & mask) { mask = -mask; *destino1 = *destino1 & mask; } break; JP: pcglob = 0per.v-destino; break; = pcglob + 0per.v-destino;break; JR:pcglob DJNZ: accs.abll[2] = accs.abll[2]-1; /* BL --; */ if (accs.abll[2] != O) pcglob = 0per.v-fuente; break; CALL: mem[reg[2]+1]=pcglob; /* mem[SP-2]=ipl *I mem[reg[2]+2]=pcglob>>8; I* mem[SP-l]=iph *I reg[2]=reg[2]+2; /* SP=SP+2 */ pcglob = 0per.v-destino; break: RET: RETI: reg[2]=reg[2]-2; /* POP PC */ intaux=mem[reg[2]+2]; /* high */ intaux=intaux<<8; intaux2=mem[reg[2]+1]; /* low *I intaux2=intaux2&0x00ff; intaux=intauxlintaux2; pcglob=intaux; break; JPC: saltar=O; switch(oper.v-fuente){ case NZ: if ((reg-flags & Ox20)==0) saItar=l; case Z: if (reg-flags & 0x20) saltar=l; case NC: if ((reg-flags & Ox80)==0) saItar=l ; case C: if (reg-flags & 0x80) saltar=l; case S: if (reg-flags & 0x40) saltar=l; case NS: if ((reg-flags & Ox40)==0) saltar=l ; case P: if (reg-flags & 0x8) saltar=l; case NP: if ((reg-flags & Ox8)==0) saltar=l ; 1 case JRC: if (saltar) pcglob = 0per.v-destino; else pcglob = pcglob + 1; break; saltar=O; switch(oper.v-fuente){ case NZ: if ((reg-flags & Ox20)==0) saltar=l ; case Z: if (reg-flags & 0x20) saltar=l; case NC: if ((reg-flags & Ox80)==0) saltar=l ; case C: if (reg-flags & 0x80) saltar=l; case S: if (reg-flags & 0x40) saItar=l; case NS: if ((reg-flags & Ox40)==0) saltar=l; case P: if (reg-flags & 0x8) saltar=l; case NP: if ((reg-flags & Ox8)==0) saltar-1; 1 if (saltar) pcglob = pcglob + 0per.v-destino; else pcglob = pcglob + 1; break; default : printf("error\n");break; /* captura numero decimal de n digitos en la posicion x,y */ int cap-num(n,x,yj int n,x,y; { int ap=O,xO,aux; int suma=O,factor,i; int valor-car; char cad[l O]; char c: xo=x; do { gotoxy(x,y); c=toupper(getchO); if (((c>='O') && (c<='9'))11((c>='A1)&& (cc='F'))) { cad[ap]=c; printf("%c",c); cad[ap+l]=O; ap++; x++; 1 else switch(c){ case '\b': if (x>xO) {ap--; x--; gotoxy(x,y); printf(" "); } break; case '\x1B':/*escaparO*/;break; 1 1 while ((c!=I3) & (apcn) & (c!='\xlB')); facto-1 ; for (¡=I ;ic=n;i++j { if(cad[n-i]c='9') valor-car=cad[n-i]-48; else valor-car=cad[n-i]-55; suma=suma+valor-car*factor; factor=factor*l6; 1 return(suma); 1 ....................................................................... * * modulo de generacion de la imagen del archivo . k t * ....................................................................... I struct image-node *new-image-nodeO { struct image-node *aux; aux=(struct image-node *)malloc(sizeof(structimage-node)); aux->lineno=O; aux->linepc=O; aux->next=NULL; 1 agrega-image(char text[80],int valori,int valorpc) { struct image-node *auxl ,*aux2; I* si la lista esta vacia *I if(image-head==NULL) { image-head=new-image-nodeO; strcpy(image-head->info,text); image-head->lineno=valori; image-head->linepc=valorpc; 1 else { 1 1 I* ya hay algo *I auxl =image-head; while (aux2=auxl->next) auxl=aux2 ; /* aux-lab1 is the last node*/ aux2=new-image-nodeO; strcpy(aux2->info,text); aux2->lineno=valori; aux2->linepc=valorpc; auxl ->next=aux2; struct image-node *busca-image(int newpc) { struct image-node *auxl ; auxl =image-head; while( auxl->linepc!=newpc && auxl ) auxl =auxl ->next; if(aux1->linepc==newpc) { return(aux1); 1 else return(NULL); 1 I* busca en la lista-imagen del archivo .kt el primer PC *I int firstpco { struct image-node *auxl ; int dummy; int auxpc; int auxstat; auxl=image-head; while(aux1) { separa(auxl-~info,&dummy,&auxpc,&dummy,&dummy,&dummy,&auxstat); if(auxstat==O) auxl =auxl ->next; else return(auxpc); 1 return(0); 1 ....................................................................... revisa2p(char *auxp) { while(*auxp) { if( *auxp==':') return(1); auxp++; 1 return(0); 1 int chextoint(char *cp) { int aux=O; if(*cp>='O' && *cpc='9') aux=*cp-'O'; else aux=*cp-87; return(aux); 1 int conv-hex(char *cp) { int aux=O; I aux=chextoint(cp)*16; aux+=chextoint(cp+l); return(aux); 1 int conv-dec(char *charp,int tamano) { int ¡=O; int potencia=l ; int auxint=O; int res=0; char *auxcar; auxcar=charp; for(i=l;i<tamano;i++) potencia*=l O; for(i=tamano;i>O;i--) { auxint=*auxcar-'0'; auxint*=potencia; res+=auxint; potencia/=l O; auxcar++; 1 return(res); 1 separa(char cadena[80],int *newline, int *newpc, int *bytel, int *byte2, int *byte3,int *status) char bl[4]="00"; char b2[4]="00"; char b3[4]="00"; char auxcad[20]=""; char *charp,*charp2; int auxint=O,i=O; charp=cadena; strncpy(auxcad,cadena,3); *newline=conv~dec(auxcad,3); while rcharp != charp++; strncpy(auxcad,charp+2,4); if (revisa2p(auxcad)) l.') { *status=O; /*'linea sin codigo */ } else { auxint=conv~hex(auxcad)*256; auxint+=conv~hex(auxcad+2); *newpc=auxint; while rcharp != charp++; charp2=charp+2; charp++; I:') while @harp != I:') { charp++; i++; 1 switch(¡){ case 4: strcpy(b1 ,charp2,2); *byte1=conv_hex(bl); *status=l ; break; case 7: strcpy(b1 ,charp2,2); strcpy(b2,charp2+3,2); *bytel=conv-hex(b1); *byte2=conv_hex(b2); *status=2; break; case 10: strcpy(b1 ,charp2,2); strcpy(b2,charp2+3,2); ~trcpy(b3,charp2+6,2); *byte1=conv-hex(b1); *byte2=conv_hex(b2); *byte3=conv_hex(b3); *status=3; break; fimage(char filename[40]) /* genera la lista-imagen del archivo filename */ { FILE *file; char cadena[80]; int ¡=O; int cl=O,c2=0,c3=0; int num,temppc,delta; if((file=fopen(filename,"r"))==NULL) { printf("Error al abrir el archivo %s\n",filename); 1 else { while(*fgets(cadena,80,file)!=NULL) { separa(cadena,&num,&temppc,&cl,&c2,&c3,&delta); agrega-image(cadena,num,temppc); switch(delta){ case 1 : mem[temppc]=cl ; break; case 2: mem[temppc]=cl ; mem[temppc+l]=c2; break; case 3: mem[temppc]=cl; mem[temppc+l]=c2; mem[temppc+2]=c3; break; default: break; 1 1 fclose(fi1ename); 1 1........................................................................ * * procedimientos despliegue de del simulador * ........................................................................ I /* muestra 64 bytes dela memoria a partir de la direccion *orig en la ventana que este activa *I print-mem(int *orig) { int i; int j; if(*orig >= MAXMEM) *orig=O; ifrorig c O) *orig=MAXMEM -64; for(i=O;ic=64;) { mprintf("%04x ",*orig+i); for(j=O;jc8;j++) { mprintf("%02x ",mem[*orig+i]); i++; 1 mprintf("\r\n"); 1 1 show-reg0 I* muestra el status de los registros en la ventana activada *I { clrscro; mprintf("ins: %02x\r\n",mem[pcglob]); mprintf("AX %04x\r\n",accs.axbx[O]); mprintf("BX %04x\r\n",accs.axbx[l]); mprintf("1X %04x\r\n",reg[O]); mprintf("lY %04x\r\n",reg[l]); mprintf("SP %04x\r\n",reg[2]); mprintf("1P %Olix\r\n",pcglob); mprintf("F%04x\r\n",reg_flags); mprintf("1V %04x\r\n",reg_intv); 1 show-reg20 { clrscro; mprintf("AX %04x\r\n",accs.axbx[O]); mprintf("BX %04x\r\n",accs.axbx[l]); mprintf("lX %04x\r\n",reg[O]); mprintf("1Y %04x\r\n",reg[l]); mprintf("SP %04x\r\n",reg[2]); mprintf("lP %04x\r\n",pcglob); mprintf("lV %04x\r\n",reg-¡ntv); mprintf("CF % I d SF % I d ",CF,SF); mprintf("ZF % I d IFF % I d ",ZF,IFF); mprintf("PF %ld",PF); 1 altera-reg0 /* altera los valores de los registros */ { char opcion='x'; int valor=O; int dir=O; clrscro; mprintf(" O AX \r\n"); mprintf(" 1 BX \r\n"); mprintf(" 2 IX \r\n"); mprintf(" 3 IY \r\n"); mprintf(" 4 SP \r\n"); mprintf(" 5 F \r\n"); mprintf(" 6 IV \r\n"); mprintf("reg: "); while(opcion 'O' 11 opcion > '6') opcion=getchO; mprintf("%c \r\n",opcion); mprintf("va1:"); valor=cap~num(4,wherexO,whereyO); switch (option){ case 'O':accs.axbx[O]=valor; break; I* AX *I case 'l':accs.axbx[l]=valor; break; I* BX *I case '2':reg[O]=valor; break; I* IX *I case '3':reg[l]=valor; break; /* IY */ case '4':reg[2]=valor; break; I* SP *I case '5':reg-flags=valor; break; case '6':reg_intv=valor; break; 1 mprintf("\r\nPress space:"); getcho; clrscro; 1 altera-memo /* altera los valores de la memoria */ { char opcion='x'; int valor=O; int dir=O; clrscro; mprintf("\r\nDireccion"); I mprintf("\r\n(hhhh):"); dir=cap-num(4,wherexO,whereyO); mprintf("\r\nValor "); mprintf("\r\nnuevo "); mprintf("\r\n(hh):"); valor=cap~num(2,wherex~,wherey0); mem[dir]=valor; mprintf("\r\nPress space:"); getcho; 1 menu-memo { clrscro; mprintf("\r\nESC Salir"); mprintf("\r\nEnter modif'); mprintf("\r\nCursor select"); 1 mem2(int *dir) { char opcion='x'; int valor-0; int reng-uno,tecla; int xloc,yloc; int act-dir; int *aux-dir; *aux-dir=*dir; act-dir=*dir; xIoc=6; yloc=l ; gotoxy(xloc,yloc); while((tecla=bioskey(O))!=ESCKEY) { if(tecla==UPKEY) { if (yloc>l) yloc-=l ; act_dir-=8; 1 gotoxy(6,l O); mprintf("%x",act-dir); gotoxy(xloc,yloc); 1 if(tecla==DOWNKEY) { if (yloc<9) { yloc+=l ; act_dir+=8; 1 gotoxy(6,I O); mprintf("%x",act-dir); gotoxy(xloc,yloc); 1 if(tecla==LEFTKEY) { if (xl006) { xloc-=3; act-dir-=l; 1 gotoxy(6,lO); mprintf("%x",act-dir); gotoxy(xloc,yloc); 1 if(tecla==RIGHTKEY) { if (xloc<27) { xloc+=3; act-dir+=l ; 1 gotoxy(6,lO); mprintf("%x",act_dir); gotoxy(xloc,yloc); 1 if (tecla==CRKEY) { valor=cap~num(2,wherexO,wherey0); mem[act-dir]=valor; clrscro; print-mem(aux-dir); gotoxy(xloc,yloc); 1 menu-into I* permite generar una interrupcion si estan habilitadas *I { char opcion='x'; intvalor=O; int dir=O; clrscro; if(intflag) { mprintf("\r\nVectorde"); mprintf("\r\ninterrupcion"); mprintf("\r\n(hhhh):"); dir=cap-num(4,wherexo,whereyO); I* PUSH PC *I mem[reg[2]+1]=pcglob&Oxff; I* mem[SP-2]=pcglobl *I mem[reg[2]+2]=(pcglob&Oxff00)>>8; I* mem[SP-l]=pcglobh *I reg[2]=reg[2]+2; I* SP=SP+2 *I pcglob=dir; 1 else { mprintf("lnt\r\n"); mprintf("not\r\n"); mprintf("enabled\r\n"); 1 mprintf("\r\nPress space:"); getcho; 1 /* le pide al usuario el nombre de un archivo .Ist y revisa qque exista */ print-arch(char filename[30],int *filestat) { FILE *inpf; mprintff'Nombre de archivo(.lst):\r\n"); scanf("%s",filename); if((inpf=fopen(filename,"r"))==NULL) mprintf("\r\nError al abrir archivo."); getcho; *filestat=l ; mprintf("\r\nArchivo cargado \r\nsin problemas."); *filestat=O; fclose(inpf); getcho; /* menu inicial del simulador, mientras error y no-ESC => sigue */ print-ini(char name[40],int *fileerr) { windesc *wa,*wi; int key; wi=draw-win(CTRWIN,CTRWlN,30,1O,"Main menu",tile,&defcolors); clrscro; mprintf(" C) Cargar un archivo .Ist\r\n"); mprintff' ESC) Salir"); do { key=bioskey(O); } while( (key!=Ox2e43) && (key!=ESCKEY)); /* Cargar archivo */ if (key==Ox2e43) { wa=draw-win(CTRWIN,20,30,5,"File window",tile,&defcolors); print-arch(name,fileerr); rmv-win(wa); rmv-win(wi); } else /* Escapar *I { rmv-win(wi); mouse-reset(); clrscro; exit(1); print-image0 { struct image-node *aux; aux=image-head; while(aux) { mprintf("%s \r",aux->info); aux=aux->next; 1 1 /* imprime un renglon de la lista-imagen del archivo en la verltana activada *I print-reng(struct image-node *aux) { if(aux) mprintf("%s \r",aux->info); 1 print-opt0 /* opciones del simulador */ { clrsct-0; mprintf("C: continua\r\n"); mprintf("R: alt reg\r\n"); mprintf("M: alt mem\r\n"); mprintf("1: int \r\n"); mprintf("PgUp: mem\r\n"); mprintf("PgDn: mem\r\n"); mprintf("SPACE: ejec\r\n"); mprintf("ESC: saIir\r\n"); 1 void gen-symbols(char namei[l4]) { FILE *fi,*fo,*fsym; int i; char *charp,*charp2; char nameo[l4]; char namesym[l4]; char cadena1[50]; char cadena2[50]; strcpy(namesyrr1,namei); charp=strchr(namesym,'.'); charp++; *charp='\O'; strcat(namesym,"sym"); if((fsym=fopen(namesym,"r"))!=NULL) { while ( fscanf(fsym,"%s %s",&cadenal ,&cadena2)!=EOF) mprintf("%s %s\r\n",cadenal ,cadena2); I fclose(fsyrn); else mprintf("Error al abrir %s.\r\n",namesym); 1 char archivo(40]; windesc *wl ,*w2,*w3,*w4,*w5; int goflag=l ; struct op *test; int cont=l ,i,codigo; charcharaux='7'; int tecla; int ejec-continua=O; int error=l ; int lastdir=O; I* direccion de despliegue de memoria *I int intactiva=O; I* bandera que ayuda a ejecutar la primera instruccion de la interrupcion */ struct image-node *reng; while(1) I* Forever, ya que esc se sale con exit(); *I { clrscro; init-wino; init~mouse(MOUSE~OPTlONAL,MOUSE_TEXT_MODE,MOUSE~TEXT~MODE); error=l ; while( error) { slct-win(base-win); clrscro; print-ini(archivo,&error); I I* clrscro; if(gof1ag) { fimage(archiv0); w l = draw-win(l,1,65,12,"Disassembler",tile,&defcolors); w2 = draw~win(66,1,14,12,"Registers",tile,&defcolor~); w3 = draw-win(l,13,35,12,"Memory",tile,&defcolors); print-mem(&lastdir); w4 = draw~win(66,13,14,12,"0ptions",tile,&defcolors); print-opto; w5 = draw_win(36,13,30,12,"Symbols",tile,&defcolors); getchO;*/ accs.axbx[0]=0x0; accs.axbx(1 ]=OXO; slct-win(w2); show-reg20; slct-win(w5); gen-symbols(archivo); pcglob=firstpcO; no-halt=l ; ejec-continua=O; while(no-halt) { codigo=nextO; slct-win(w1); reng=busca-image(pcglob-I); print-reng(reng); slct-win(w4); pri:it-optO; if(!ejec-continua) while(no-halt && (tecla=bioskey(O))!=SPACEBAR) { if(tecla==Ox2e43 11 tecla==Ox2e63) /* C c *,I { ejec-continua=l ; 1 if(tecla==Oxl372 I( tecla==Oxl352) /* R r */ slct-win(w4); altera-rego; slct-win(w2); show-reg20; slct-win(w4); print-opto; 1 if(tecIa==Ox326d 11 tecIa==Ox324d) /* M m ”/ { slct-win(w4); menu-memo; slct-win(w3); mem2(&lastdir); slct-win(w4); print-opto; 1 if(tecla==PGUPKEY) { slct-win(w3); lastdir-=64; print-mem(&lastdir); slct-win(w4); print-opto; 1 if(tecla==PGDNKEY) { slct-win(w3); lastdir+=64; print-mem(&lastdir); slct-win(w4); print-opto; 1 if(tecla==Oxl769 (1 tecla==Oxl749) /* i I */ { slct-win(w4); pcglob-; /* ya que next lo incremento */ menu-into; intactiva=l ; slct-win(w4); print-opto; 1 if(tecla==ESCKEY) no-halt=O; 1 if(intactiva) { codigo=nextO; slct-win(w1); reng=busca-image(pcg1ob-1); print-reng(reng); intactiva=O; 1 if(no-halt) { decodif(codigo,test); ejecrtest); slct-win(w2); show-reg20; slct-win(w3); print-mem(&lastdir); 1 } /*while (nohalt) */ slct-win(w1); mprintf("\r\n Fin de ejecucion."); r"intf("\r\n Presione barra espaciadora..."); getcho; image-head=NULL; rmv-win(w2); rmv-win(w1); rmv-win(w3); rmv-win(w4); rmv-win(w5); mouse-reset(); clrscro; } /* if (goflag) */ } /*while (1) */ } /* main0 */ I /* Text mode popup window package (p0pup.h) */ #define CTRWIN 999 typedef struct texel-struct{ unsigned char ch; unsigned char attr; } texel; typedef struct wincolors-struct{ char border-type; unsigned char border-color, text-color, title-color, hilite-color; } wincolors; enum windowtype {popup,tile}; typedef struct winstruct{ char *name; void *image; struct winstruct *under, *over; wincolors wc; char xul,yul,xlr,ylr,wd,ht; char xsave,ysave; enum windowtype wtype; } windesc; extern windesc *base-win; extern windesc *curr-win; extern wincolors defcolors; extern wincolors invcolors; extern wincolors monocolors; extern wincolors errcolors; extern wincolors msgcolors; #define rmv-win(w) view-win(w,O) #define slct-win(w) view-win(w,l) extern void init-win(void); extern windesc *draw-win(int x, int y, int wd, int ht, char *title, enum windowtype wt, wincolors *wc); extern void view-win(windesc *this, int select); extern void clr-win(void); extern void draw-box(int xul, int yul, int xlr, int ylr,int btype,int attr); extern void centerstr(int xu1,int yul,int xlr,int ylr, char *S,unsigned char a); extern void mprintf(char *fmt,...); extern void prtfstr(int x,int y,char *fmt,unsigned char attrjnt wd, ...); extern void swap-image(windesc *w); #defineSWRNF 0 , l ,-LINE #define SERRF 0,2,-LINE #define SMSGF O,O,-LINE #defineFWRNF 1 , l ,-LINE #defineFERRF 1,2,-LINE #define FMSGF l,O,-LINE #define SWRN 0 , l ,O,"" #define SERR 0,2,0,"" #define SMSG O,O,O,"" #define FWRN 1,l ,O,"" #define FERR 1,2,il,"" #define FMSG 1,O,O,"" , FILE, FILE, FILE, FILE- , , FILEFILE- extern int erm; extern int erry; extern windesc *errw; extern int msgx; extern int msgy; extern windesc *msgw; extern void numnewlines(char*S,int *n, int *w); extern void popmsg(int x, int y, char *msg, char *title, char soundout, wincolors *wc); extern void reperr(int level, char *msg); extern void repmsg(char *msg); extern void sayerr(int ferr, int errflag, int Ino, char *pname, char *fmt,...); extern void beep(void); extern unsigned int getkey(void); U I* Mouse toolkit header file (m0use.h) *I #define lo(9 ((9 8, Oxff) #define hi(9 (lo(f >> 8)) I* common scan-asci codes *I #define CTRLC Ox2e03 #define CTRLH 0x2308 #defineCTRLl0x1709 #define CTRLL 0 x 2 6 0 ~ #define CTRLK Ox250b #define CTRLJ Ox240a #define CTRLU 0x1615 #define CTRLR 0x1312 #define CRKEY 0x1 cod #define CTRLRKEY 0x1 coa #define UPKEY 0x4800 #define DOWNKEY 0x5000 #define LEFTKEY Ox4b00 #define RIGHTKEY Ox4d00 #define SHFTLEFT Ox4b34 #define SHFTRIGHT Ox4d36 #define DELKEY 0x5300 #define INSKEY 0x5200 #define BSKEY 0xOe08 #define SPACEBAR 0x3920 #define PGUPKEY 0x4900 #define PGDNKEY Ox5100 #define SHFTUPKEY 0x4838 #define SHFTDNKEY 0x5032 #define SHFTPGUPKEY 0x4939 #define SHFTPGDNKEY 0x5133 #define HOMEKEY 0x4700 #define ENDKEY Ox4fOO #define ESCKEY Ox011b #define ALT-D 0x2000 #define ALT-E 0x1 200 #define ALT-I0x1 700 #define ALT-R 0x1 300 #define ALT-S 0x1fOO #define ALT-T 0x1400 #define ALT-X Ox2d00 #define FlOKEY 0x4400 I* mouse pseudokeys *I #define LEFT-MOUSE-PRESS Oxffol #define RIGHT-MOUSE-PRESS OxffO2 #define LEFT-MOUSE-REL Oxff 11 #define RIGHT-MOUSE-REL Oxff 12 ' /* mouse driver function codes */ #define "RESET #define M-SHOW-CURS #define M-HIDE-CURS2 #define M-GET-STATUS #define M-SET-CURS 4 #define M-GET-PRESS 0 1 3 5 #define #define #define #define #define M-GET-REL 6 M-SET-X-BOUNDS M-SET-Y-BOUNDS M-SET-G-CURS M-SET-T-CURS 7 8 9 10 #define MOUSE-NEEDED 1 #define MOUSE-OPTIONAL O #define MOUSE-TEXT-MODE O extern int mouse-text-x; extern int mouse-text-y; extern int mouse-grph-x; extern int mouse-grph-y; extern int mouse-initialized; extern void mouse(int *m1 ,int *m2,int *m3,int *m4); extern int check-mouse-driver(int need-mouse); extern int init-mouse(int need-mousejnt gd,int gm); extern int mouse-reset(void); extern void move-mouse(int x,int y); extern void mouse-on(int code); extern void mouse-off(int code); extern void mouse-grph-posn(int *x,int *y); extern void mouse-txt-posn(int *x,int *y); extern int mouse-in-box(int graphflag,int leftjnt right,int top,int bottom); extern int button-releasegnt b); extern int button-press(int b); extern int button-state(void); extern int mouse-trigger(int button-dir); I* Archivo miosimf.prj : project para la compilacióndelsimulador popup.obj mouse.obj miosimf.c o */