;                 UNIVERSIDAD IBEROAMERICANA
; PROYECTO DE ARQUITECTURA Y PROGRAMACION DE MICROPROCESADORES
; JUAN CARLOS CASTRO ARENAL                 OTOQO 1994
				; VICTOR INIESTRA
	TITLE	INTERPRETE	; MAURICIO ORDOQEZ
 
	ORG	1000	; VARIABLES DEFINIDAS A PARTIR DE 1000
 
ABRE	EQU	FF0D
ESCR	EQU	FF1D
LEE	EQU	FF4B	; DIRECCIONES USADAS POR EL DRIVER INTERACTIVO
CIERRA	EQU	FF15
BUZON	EQU	6000
 
 
; RESULTADO DE LA VALIDACION: 0=NUMERO 1=LET 2=ADD 3=SUBS 4=PRINT
;                             5=TRANSFER 6=ALL 7=VARIABLE DESCONOCIDA
;                             8=VAR-1 9=VAR-2 A=VAR-3 B=VAR-4 C=VAR-5 D=VAR-6
 
VALIDA1	DEFB	0
PALA1	DEFM	"      " ; ESPACIO QUE GUARDA LA PALABRA 1
	DEFB	0FF	 ; CON ESTO PUEDO ESCRIBIR LA PALABRA CON LA REF. PALA1
			 ; Y TAMBIEN SIRVE PARA INDICAR EL FINAL DE LA PALABRA
HEX1	DEFS	2	 ; HEX(PALABRA 1) SI LO TIENE :+)
 
VALIDA2	DEFB	0
PALA2	DEFM	"      " ; PALABRA 2
	DEFB	0FF
HEX2	DEFS	2	 ; HEX(PALABRA 2)
 
VALIDA3	DEFB	0
PALA3	DEFM	"      " ; PALABRA 3
	DEFB	0FF
HEX3	DEFS	2	 ; HEX(PALABRA 3)
 
VARIA1	DEFM	"VAR-1 " ; VARIABLE 1. EL NOMBRE PODRA SER CAMBIADO
	DEFB	0FF	 ; INDICA EL FINAL DE LA VARIABLE
HEXVA1	DEFS	2	 ; HEX(VARIABLE 1) SEGMENTO PARA GUARDAR EL VALOR HEX
			 ; DE LA VARIABLE
 
VARIA2	DEFM	"VAR-2 " ; VARIABLE 2
	DEFB	0FF
HEXVA2	DEFS	2	 ; HEX(VARIABLE 2)
 
VARIA3	DEFM	"VAR-3 " ; VARIABLE 3
	DEFB	0FF
HEXVA3	DEFS	2	 ; HEX(VARIABLE 3)
 
VARIA4	DEFM	"VAR-4 " ; VARIABLE 4
	DEFB	0FF
HEXVA4	DEFS	2	 ; HEX(VARIABLE 4)
 
VARIA5	DEFM	"VAR-5 " ; VARIABLE 5
	DEFB	0FF
HEXVA5	DEFS	2	 ; HEX(VARIABLE 5)
 
VARIA6	DEFM	"VAR-6 " ; VARIABLE 6
	DEFB	0FF
HEXVA6	DEFS	2	 ; HEX(VARIABLE 6)
 
VERB1	DEFM	"LET   " ; VERBO 1
VERB2	DEFM	"ADD   " ; VERBO 2
VERB3	DEFM	"SUBS  " ; VERBO 3
VERB4	DEFM	"PRINT " ; VERBO 4
VERB5	DEFM	"TRANSF" ; VERBO 5
VERB6	DEFM	"ALL   " ; OPCION DEL VERBO PRINT
			 ; POR LO QUE NO PUEDE SER VARIABLE
 
SIG_LIN	DEFB	0A,0D,0FF ; CUANDO QUIERO AVANZAR UNA LINEA, ESCRIBO SIG_LIN
 
MENSAJE	DEFM	"Proy. de Arq. y Prog. de Proc."		
	DEFB	0FF
MENS0	DEFM	"Sintaxis- Verbo o Comando Ilegal"
	DEFB	0FF
MENS1	DEFM	"Leteando"
	DEFB	0FF
MENS2	DEFM	"Addeando"
	DEFB	0FF
MENS3	DEFM	"Subeando"
	DEFB	0FF
MENS4	DEFM	"Printeando"
	DEFB	0FF
MENS5	DEFM	"Transfereando"		
	DEFB	0FF
MENSVA	DEFM	"OPERACION REALIZADA"
	DEFB	0FF
MENSI	DEFM	"Num. max. de var. alcanzado"
	DEFB	0FF
MENSO	DEFM	"Error de parametros"
	DEFB	0FF
OVFLOW	DEFM	"Overflow"
	DEFB	0FF
PROMPT	DEFM	">"
	DEFB	0FF
 
NUM	DEFB	0FF	; NUMERO RECIBIDO EN HEXADECIMAL A SER CONVERTIDO
	DEFB	0FF	; EN DECIMAL Y POSTERIORMENTE EN ASCII PARA PODERLO
			; DESPLEGAR EN LA PANTALLA
PAR1	DEFB	0
PAR2	DEFB	0	; LOS SIGUIENTES ESPACIOS QUE SE DEFINEN SON PARA
PAR3	DEFB 	0	; IR GUARDANDO LOS SUMANDOS (4096,256,16,1)
PAR4	DEFB	0
PAR5	DEFB	0
 
SAL5	DEFB	0	; VARIABLES QUE SE UTILIZAN PARA IR GUARDANDO LOS
SAL4	DEFB	0	; VALORES PARCIALES DE LAS SUMAS ASI COMO EL RESULTADO
SAL3	DEFB	0	; FINAL QUE SERA DESPLEGADO EN LA PANTALLA
SAL2	DEFB	0
SAL1	DEFB	0	
	DEFB	0FF	; SIRVE PARA INDICAR EL FINAL DE LA CADENA A SER IMPRESA
 
CUENTA	DEFB	0 ; CONTADOR MILUSOS
NUMVER	DEFB	0 ; INDICA QUE VERBO ESTOY VALIDANDO
NUMVAR	DEFB	0 ; INDICA QUE VARIABLE ESTOY VALIDANDO
VALVER	DEFB	0 ; RESULTADO DE LA VALIDACION DEL VERBO (INDICA SI ES O NO 
		  ; VERBO ADEMAS DE INDICAR CUAL ES)
VALVAR	DEFB	0 ; RESULTADO DE LA VALIDACION DE LA VARIABLE (INDICA SI ES O NO
		  ; VARIABLE ADEMAS DE INDICAR CUAL ES)	
VARIAS	DEFB	6 ; NUMERO DE VARIABLES ASIGNABLES (EVITA QUE SE DEFINAN MAS
		  ; DE SEIS VARIABLES)
 
ORACIO	DEFS	1 ; FRASE A ANALIZAR
 
 
	ORG	0	; PROGRAMA
	LDSP	#5000
	JZ	BEGIN	;VE AL PROGRAMA PRINCIPAL
	JNZ	BEGIN
 
REGRE:	LD	X	; 
	SUB	#20
	INX
	JNZ	REGRE
	RET		; REGRESA EL CONTROL AL MACRO SEPARA
LEE1:	LD	#7	; ES 7 PORQUE SE INCLUYE EL ESPACIO
	STO	CUENTA	; ES EL CONTADOR
 
	; ESTAS LINEAS VAN A HACER CASI LO MISMO QUE SE HIZO PARA PASAR LO
	; DEL BUZON A ORACIO; AHORA SE VAN A PASAR CADA UNA DE LAS PALABRAS
	; DE LA ORACIO A PALA1, PALA2 Y PALA3 RESPECTIVAMENTE, MEDIANTE VARIAS
	; LLAMADAS DEL ESTE PROCEDIMIENTO. DETECTA EL FINAL DE UNA PALABRA 
	; MEDIANTE EL ESPACIO QUE DEBE DE TENER AL FINAL DE LA MISMA O CUANDO
	; YA HAYA COPIADO LAS 6 PRIMERAS LETRAS DE LA PALABRA.
 
LEE2:	LD	CUENTA	
	SUB	#1
	JZ	REGRE
	STO	CUENTA
	LD	X	; A=LETRA(FRASE)
	SUB	#20	; A=LETRA(FRASE)-" "
	JZ	REGRE 	; LETRA(FRASE)=" "? SI: YA ACABE.
	ADD	#20 	; VUELVE A AGREGAR LO QUE LE QUITE ANTES
	STO	Y	; ALMACENA ESTA LETRA EN LA LOCALIDAD CORRESPONDIENTE
	INY		; AVANZA UNA LETRA EN LA FRASE
	INX		; AVANZA UNA LETRA EN LA PALABRA
	JZ	LEE2	; CONTINUALE HASTA QUE ACABES CON ESTA
	JNZ	LEE2	; PALABRA DE LA FRASE
 
VALID:
	LD	#1	; CHECA SI LA PALABRA QUE QUIERO VALIDAR
	STO	NUMVER	; ES IGUAL AL PRIMER VERBO
	LDY	VERB1
	CALL	VAL
	
	LD	#2	; ES EL SEGUNDO VERBO?
	STO	NUMVER
	LDY	VERB2
	CALL	VAL
	
	LD	#3	; EL TERCERO?
	STO	NUMVER
	LDY	VERB3
	CALL	VAL
	
	LD	#4	; EL CUARTO?
	STO	NUMVER
	LDY	VERB4
	CALL	VAL
 
	LD	#5	; EL QUINTO?
	STO	NUMVER
	LDY	VERB5
	CALL	VAL
 
	LD	#6	; EL SEXTO?
	STO	NUMVER
	LDY	VERB6
	CALL	VAL
	
	RET		; YA ACABE DE VALIDAR, REGRESA AL PRINCIPAL
 
VAL:	PUSH	X	; SALVAGUARDA LA DIRECCION DE LA PALABRA QUE
	LD	#1	; ESTOY VALIDANDO
	STO	CUENTA  ; ASEGURATE DE COMPARAR SOLO 6 LETRAS
VALI:	LD	#1
	ADD	#0FF	; ACARREO=1 (PARA LA RESTA)
	LD	X
	SBC	Y
	JNZ	RETOR	; @X=@Y? SI NO ES ASI, NO ES EL MISMO VERBO
	LD	CUENTA
	SUB	#6	; YA COMPARE SEIS LETRAS?
	JZ	SI_ES	; SI YA LO HICE, SI ES EL VERBO
	INX
	INY		; MUEVETE A LA SIGUIENTE LETRA
	LD	CUENTA
	ADD	#1	; YA LLEVO OTRA
	STO	CUENTA
	JZ	VALI	; COMPARA OTRA VEZ
	JNZ	VALI
SI_ES:	LD	NUMVER	; CARGA EL NUMERO DE VERBO QUE ESTOY COMPARANDO
	STO	VALVER	; ALMACENALO EN VALIDA
RETOR:	POP	X	; RECUPERA LA DIRECCION DE LA PALABRA VALIDABLE
	RET		; REGRESA A VALID
 
 
VALIDV:
	LD	#8	; CHECA SI LA PALABRA QUE QUIERO VALIDAR
	STO	NUMVAR	; ES IGUAL A LA PRIMERA VARIABLE
	LDY	VARIA1
	CALL	VALV
	
	LD	#9	; ES EL SEGUNDO VERBO?
	STO	NUMVAR
	LDY	VARIA2
	CALL	VALV
	
	LD	#0A	; EL TERCERO?
	STO	NUMVAR
	LDY	VARIA3
	CALL	VALV
	
	LD	#0B	; EL CUARTO?
	STO	NUMVAR
	LDY	VARIA4
	CALL	VALV
 
	LD	#0C	; EL QUINTO?
	STO	NUMVAR
	LDY	VARIA5
	CALL	VALV
 
	LD	#0D	; EL SEXTO?
	STO	NUMVAR
	LDY	VARIA6
	CALL	VALV
	
	RET		; YA ACABE DE VALIDAR, REGRESA AL PRINCIPAL
 
VALV:	PUSH	X	; SALVAGUARDA LA DIRECCION DE LA PALABRA QUE
	LD	#1	; ESTOY VALIDANDO
	STO	CUENTA  ; ASEGURATE DE COMPARAR SOLO 6 LETRAS
VALIV:	LD	#1
	ADD	#0FF	; ACARREO=1 (PARA LA RESTA)
	LD	X
	SBC	Y
	JNZ	RETORV	; @X=@Y? SI NO ES ASI, NO ES EL MISMO VERBO
	LD	CUENTA
	SUB	#6	; YA COMPARE SEIS LETRAS?
	JZ	SI_ESV	; SI YA LO HICE, SI ES EL VERBO
	INX
	INY		; MUEVETE A LA SIGUIENTE LETRA
	LD	CUENTA
	ADD	#1	; YA LLEVO OTRA
	STO	CUENTA
	JZ	VALIV	; COMPARA OTRA VEZ
	JNZ	VALIV
SI_ESV:	LD	NUMVAR	; CARGA EL NUMERO DE VERBO QUE ESTOY COMPARANDO
	STO	VALVAR	; ALMACENALO EN VALIDA
RETORV:	POP	X	; RECUPERA LA DIRECCION DE LA PALABRA VALIDABLE
	RET		; REGRESA A VALID
 
HEXV:	LD	HEX3	; COMO ESTA EN DOS BYTES SE TIENE QUE CARGAR UNO POR
	STO	X	; UNO E IR ALMACENANDOLO DONDE LE CORRESPONDE
	INX
	LD	HEX3+1
	STO	X
	RET
NOMV:	
	LD	PALA2	; ES LOS MISMO QUE EN HEXV PERO CON LA DIFERENCIA DE
	STO	X	; DE QUE EN ESTE CASO SON SEIS BYTES (CADA LETRA OCUPA 
	INX		; 1 BYTE ), UNO POR LETRA
	LD	PALA2+1
	STO	X
	INX
	LD	PALA2+2
	STO	X
	INX
	LD	PALA2+3
	STO	X
	INX
	LD	PALA2+4
	STO	X
	INX
	LD	PALA2+5
	STO	X
	RET
LETEA:
	LD	VARIAS	; ESTE PROCEDIMIENTO ES COMO UN CASE
	SUB	#1	; IDENTIFICA EN QUE VARIABLE TENGO QUE GUARDAR EL
	JZ	VR6	; EL VALOR QUE EL USUARIO QUIERE ASIGNARLE A ALGUNA
	SUB	#1	; VARIABLE. SABE EN QUE VARIABLE LO VA A GUARDAR
	JZ	VR5	; (VARIA1, VARIA2, ETC.) GRACIAS AL VALOR QUE TIENE
	SUB	#1	; VARIAS
	JZ	VR4
	SUB	#1
	JZ	VR3
	SUB	#1
	JZ	VR2
	JNZ	VR1
VR1:	LDX	HEXVA1	; CARGO EN X LA DIRECCION DEL LUGAR DONDE SE GUARDARA
	CALL	HEXV	; EL VALOR HEXADECIMAL DE LA VARIABLE. HEXV ES LA QUE
			; ALMACENA EL VALOR HEXADECIMAL DE LA VARIABLE DADA POR
			; EL USUARIO (GUARDA HEX3 (VALOR HEXADECIMAL DE LA 3A
			; PALABRA) EN HEXVA1, HEXVA2, ETC. SEGUN SEA EL CASO)
	LDX	VARIA1	; GUARDA EL VALOR ASCCI DE LA PALA2 EN VARIA1, VARIA2, 
	CALL	NOMV	; ETC. SEGUN SEA EL CASO
	JZ	PNI
	JNZ	PNI
VR2:	LDX	HEXVA2
	CALL	HEXV
[5~	LDX	VARIA2
	CALL	NOMV
	JZ	PNI
	JNZ	PNI
VR3:	LDX	HEXVA3
	CALL	HEXV
	LDX	VARIA3
	CALL	NOMV
	JZ	PNI
	JNZ	PNI
VR4:	LDX	HEXVA4
	CALL	HEXV
	LDX	VARIA4
	CALL	NOMV
	JZ	PNI
	JNZ	PNI
VR5:	LDX	HEXVA5
	CALL	HEXV
	LDX	VARIA5
	CALL	NOMV
	JZ	PNI
	JNZ	PNI
VR6:	LDX	HEXVA6
	CALL	HEXV
	LDX	VARIA6
	CALL	NOMV	
PNI:	LDX	MENSVA	; ESTE MENSAJE ES DE OPERACION REALIZADA
	CALL	ESCR
	RET
 
ILEGAL:	LD	#7
	STO	CUENTA
	JZ	SALIDA
	JNZ	SALIDA
 
DEC09:	LD	X	; A=@X
	AND	#0F	; A=BAJO(@X)
 
	PUSH	A
	SUB	#0A
	LD	#0
	ADC	#0
	POP	A
	JZ	ILEGAL
 
	SL		; A=BAJO(@X)*10
	SL
	SL
	SL
	STO	Y	; Y=BAJO(@X)*10
	JZ	UNIDAD
	JNZ	UNIDAD	; VE A LEER LA UNIDAD
 
DECAF:	LD	X
	AND	#0F
	
	PUSH	A
	SUB	#7
	LD	#0
	ADC	#0
	POP	A
	JZ	ILEGAL
 
	ADD	#9	; A=BAJO(@X)+9
	SL
	SL
	SL
	SL
	STO	Y
	JZ	UNIDAD
	JNZ	UNIDAD
 
UNI09:	LD	X	; A=@X
	AND	#0F	; A=BAJO(@X)
	PUSH	A
	SUB	#0A
	LD	#0
	ADC	#0
	JZ	ILEGAL
	LD	#0	; CARRY=0
	ADD	#0
	POP	A
	ADC	Y	; A=Y+BAJO(@X)
	STO	Y	; Y=Y+BAJO(@X)
	JZ	SALIDA
	JNZ	SALIDA
 
UNIAF:	LD	X	; A=@X
	AND	#0F	; A=BAJO(@X)
	PUSH	A
	SUB	#7
	LD	#0
	ADC	#0
	JZ	ILEGAL
	POP	A
	ADD	#9
	ADC	Y	; A=Y+BAJO(@X)
	STO	Y	; Y=Y+BAJO(@X)
	JZ	SALIDA
	JNZ	SALIDA
 
ASCHEX:	
	LD	X	; A=@X
	AND	#0F0	; A=ALTO(@X)
	SUB	#30	; ALTO(@X)=30? (30,31,32,...,39)
	JZ	DEC09	; X ESTA ENTRE 0 Y 9
	SUB	#10	; ALTO(@X)=40? (41,42,..46)
	JZ	DECAF	; X ESTA ENTRE A Y F
	JNZ	ILEGAL
 
UNIDAD:	INX		; AHORA LEE LA UNIDAD
	LD	X	
	AND	#0F0
	SUB	#30
	JZ	UNI09
	SUB	#10
	JZ	UNIAF
	JNZ	ILEGAL
 
SALIDA:	INX		; PREPARA LA SIGUIENTE CIFRA
	INY
	RET		; REGRESA A RECNUM
 
RECNUM:
	CALL	ASCHEX	; PRIMERA CIFRA
	CALL	ASCHEX	; SEGUNDA CIFRA
	RET		; REGRESA AL PRINCIPAL
 
ASIGNA:	LDY	ORACIO	; CARGO EN EL REGISTRO Y LA DIRECCION DEL ESPACIO EN
			; EL QUE VOY A GUARDAR LA FRASE DADA POR EL USUARIO
NO:	LD	X	; EN EL REGISTRO X SE ENCUENTRA APUNTADA LA FRASE DADA
			; POR EL USUARIO (BUZON)
	SUB	#0FF
	JZ	SALTE
	ADD	#0FF
	STO	Y
	INX
	INY
	JZ	NO
	JNZ	NO
SALTE:	LD	#6	; CARGA UN 6 PARA QUE ME SIRVA COMO CONTADOR PARA 
	PUSH	Y	; PONER 6 ESPACIOS EN LA PARTE FINAL DE ORACIO PARA
	POP	X	; QUE EL  PROCEDIMIENTO DE SEPARACION FUNCIONE BIEN
	CALL	KLEAN	; CON EL PUSH Y EL POP INTERCAMBIO EL VALOR DE Y 
	RET		; ASIGNANDOLO A X PARA ASI LLAMAR A KLEAN
 
MACRO	SEPARA	NUM_PAL
	LDY	NUM_PAL	; Y=NUMERO PALABRA (PAL1, PAL2, PAL3)
	CALL	LEE1	; LLAMA A LEE1 QUE ES EL QUE REALMENTE VA A SEPARAR
			; LAS PALABRAS
ENDM
 
MACRO	VAL_NUM	NUM_PAL, NUM_HEX, NUM_VALIDA
	LD	#0	; ESTE PROCEDIMIENTO ES PARA VER SI ES O NO NUMERO
	STO	CUENTA
	LDX	NUM_PAL	; X=NUMERO PALABRA
	LDY	NUM_HEX	; Y=NUMERO HEX
	CALL	RECNUM	; RECONOCE EL NUMERO QUE ES LA PALABRA NUMERO
	LD	CUENTA	; SI CUENTA REGRESA UN CERO LA PALABRA ES NUMERO
			; SI REGRESA UN 7 NO ES (VARIABLE NO VALIDA)
	STO	NUM_VALIDA	; NUM_VALIDA ES PARA REGRESAR EL VALOR DE
			; CUENTA (ES O NO NUMERO)
 
ENDM
 
MACRO VAL_VER	NUM_PAL, NUM_VALIDA
	LD	NUM_VALIDA
	STO	VALVER	
	LDX	NUM_PAL	; X=LA PALABRA QUE QUIERO VALIDAR
	CALL	VALID	; VE A VALIDAR VERBOS
	LD	VALVER
	STO	NUM_VALIDA
ENDM
 
MACRO VAL_VAR	NUM_PL, NUM_VALID
	LD	NUM_VALID
	STO	VALVAR	
	LDX	NUM_PL	; X=LA PALABRA QUE QUIERO VALIDAR
	CALL	VALIDV	; VE A VALIDAR VARIABLES
	LD	VALVAR
	STO	NUM_VALID
ENDM
 
ARGERR:	LDX	MENSO	; DESPLIEGA EL ERROR DE ARGUMENTO
	CALL	ESCR
	RET
 
IDVAR1:	LDX	SIG_LIN	
	CALL	ESCR
 
	LD	VALIDA2	; CARGA VALIDA2 PARA SABER QUE ES LA SEGUNDA PALABRA
			; DE LA FRASE (NUMERO, VERBO, ETC.)
 
	SUB	#8	; COMIENZA EN 8 PORQUE ESE ES EL CODIGO DE LA BANDERA
	JZ	OPC218	; PARA LA PRIMERA VARIABLE
	SUB	#1	
	JZ	OPC219
	SUB	#1
	JZ	OPC21A
	SUB	#1
	JZ	OPC21B
	SUB	#1
	JZ	OPC21C
	SUB	#1
	JZ	OPC21D	
	CALL	ARGERR	; LLAMA ERROR DE ARGUMENTO
	LD	#1	; EN CASO DE QUE SEA UN ERROR DE ARGUMENTO 
	RET		; REGRESA UN 1 POR MEDIO DEL ACUMULADOR QUE INDICA
			; QUE ES UNA VARIABLE DESCONOCIDA
 
OPC218:	LDX	HEXVA1	; HAGO QUE X APUNTE A LA DIRECCION DONDE ESTA EL 
			; VALOR HEXADECIMAL DE LA VARIABLE EN CUESTION
	JZ	PL
	JNZ	PL
OPC219:	LDX	HEXVA2
	JZ	PL
	JNZ	PL
OPC21A:	LDX	HEXVA3
	JZ	PL
	JNZ	PL
OPC21B:	LDX	HEXVA4
	JZ	PL
	JNZ	PL
OPC21C:	LDX	HEXVA5
	JZ	PL
	JNZ	PL
OPC21D:	LDX	HEXVA6
 
PL:	LD	#0	; CARGO UN CERO PARA REGRESARLO POR MEDIO DEL ACUMULADOR
	RET		; PARA INDICAR QUE NO HUBO ERROR
 
IDVAR2:	LD	VALIDA3	
 
	SUB	#8
	JZ	OPC228
	SUB	#1
	JZ	OPC229
	SUB	#1
	JZ	OPC22A
	SUB	#1
	JZ	OPC22B
	SUB	#1
	JZ	OPC22C
	SUB	#1
	JZ	OPC22D	
	CALL	ARGERR
	LD	#1
	RET
 
OPC228:	LDY	HEXVA1
	JZ	PO
	JNZ	PO
OPC229:	LDY	HEXVA2
	JZ	PO
	JNZ	PO
OPC22A:	LDY	HEXVA3
	JZ	PO
	JNZ	PO
OPC22B:	LDY	HEXVA4
	JZ	PO
	JNZ	PO
OPC22C:	LDY	HEXVA5
	JZ	PO
	JNZ	PO
OPC22D:	LDY	HEXVA6
 
PO:	LD	#0
	RET
 
KLEAN:	PUSH	A	; GUARDA EL VALOR DEL ACUMULADOR (CONTADOR)
	LD	#20	; CARGA UN 20 (ESPACIO)
	STO	X	; GUARDA EL 20 EN EL ESPACIO CORRESPONDIENTE A LA
        INX		; DIRECCION APUNTADA POR X 
	POP	A	; RECUPERA EL VALOR DEL CONTADOR PARA DECREMENTARLO EN 
	SUB	#1	; UNO, CUANDO SEA CERO REGRESA A DONDE FUE LLAMADO
	JNZ	KLEAN
	RET
 
LIMPIA:	LD	#6	; CARGA UN 6 EN EL ACUMULADOR PARA SER USADO EN KLEAN
	LDX	PALA1	; CARGA EN EL REGISTRO X LA PALA1 PARA SER USADA EN KLEA
	CALL	KLEAN	
	LD	#6
	LDX	PALA2
	CALL	KLEAN
	LD	#6
	LDX	PALA3
	CALL	KLEAN
	RET
 
ID:	LD	VALIDA1	; VALOR QUE TIENE LA BANDERA DE LA PRIMERA PALABRA
			; DE LA FRASE DADA POR EL USUARIO
	SUB	#1
	JZ	OPC1	; 1A PALABRA = LET
	SUB	#1
	JZ	OPC2	; 1A PALABRA = ADD
	SUB	#1
	JZ	OPC3	; 1A PALABRA = SUBS
	SUB	#1
	JZ	OPC4	; 1A PALABRA = PRINT
	SUB	#1
	JZ	OPC5	; 1A PALABRA = TRANSFER
	JNZ	OPC6	; 1A PALABRA = NO VERB (NO VALIDO)
	
OPC1:	LDX	MENS1	; PRIMERA PALABRA=LET
	CALL	ESCR
 
	LD	VALIDA2	; ESTO ES PARA CHECAR QUE LA 2A PALABRA SEA UNA
	SUB	#7	; VARIABLE DESCONOCIDA
	JZ	OPC11
	CALL	ARGERR	; LLAMA A ERROR DE ARGUMENTO YA QUE LA SEGUNDA PALABRA
			; NO FUE UNA VARIABLE ANTERIORMENTE DESCONOCIDA (VALIDA2
			; DIFERENTE DE 7).
	JZ	NPI
	JNZ	NPI
 
OPC11:	LD	VALIDA3	; ES PARA CHECAR QUE LA TERCERA PALABRA SEA UN NUMERO
	ADD	#0	
	JZ	OPC12	 
	CALL	ARGERR	; EN CASO DE QUE NO LO SEA, LLAMA AL ERROR DE ARGUMENTO
	JZ	NPI
	JNZ	NPI
 
OPC12:	LD	VARIAS	; ESTE PROCEDIMIENTO ES PARA CHECAR QUE NO SE HAYA
	ADD	#0	; EXCEDIDO EL NUMERO DE VARIABLES QUE SE PUEDEN DECLARAR
	JZ	INSMEM	; SI = 0, LLAMA AL MENSAJE DE MEMORIA INSUFICIENTE
	CALL	LETEA	; LLEVA A CABO EL PROCEDIMIENTO DE LET
	LD	VARIAS	; DECREMENTA VARIAS (BANDERA QUE SE INICIALIZA CON 6
	SUB	#1	; Y QUE SIRVE COMO UN CONTADOR  PARA INDICARME
	STO	VARIAS	; CUANDO SE ME TERMINA EL ESPACIO DISPONIBLE PARA
	JZ	NPI	; LA DECLARACION DE VARIABLES (LET))
	JNZ	NPI
 
INSMEM:	LDX	MENSI	; DESPLIEGA EL MENSAJE DE YA SE ME ACABO EL ESPACIO
	CALL	ESCR	; EN MEMORIA DISPONIBLE PARA LA DECLARACION DE VARIABLES
	JZ	NPI
	JNZ	NPI
 
OPC2:	LDX	MENS2	; PRIMERA PALABRA=ADD
	CALL	ESCR
 
	CALL	IDVAR1	; LLAMA A IDVAR1, QUE IDENTIFICA QUE VARIABLE ES MI
			; SEGUNDA PALABRA (VER QUE EXISTA LA VARIABLE QUE SE 
			; QUIERE SUMAR (QUE YA HAYA SIDO DECLARADA))
	SUB	#1	; SI IDVAR1 ME REGRESA UN 1 QUIERE DECIR QUE LA 
			; VARIABLE ESPECIFICADA EN PALA2, ES DESCONOCIDA
			; QUE EL USUARIO NO LA HA DECLARADO ANTERIORMENTE	
	JZ	NPI	; Y SI ES DESCONOCIDA SE SALE DEL PROCEDIMIENTO
			; ADEMAS, IDVAR1 REGRESA EN X LA DIRECCION DONDE 
			; COMIENZA EL VALOR HEXADECIMAL DE LA VARIABLE QUE
			; REPRESENTO A LA SEGUNDA PALABRA DE LA FRASE
	CALL	IDVAR2	; HACE LO MISMO PERO CON LA TERCERA PALABRA DE LA FRASE
	SUB	#1	; IDVAR2 REGRESA LA DIRECCION DEL VALOR HEXADECIMAL EN Y
			; DE LA VARIABLE(QUE REPRESENTO LA 3A PALABRA DE LA
			; FRASE) 
	JZ	NPI
 
	LD	#0	; PARA LIMPIAR LA BANDERA DEL ACARREO
	ADD	#0
	INX		; INCREMENTO X y Y PARA APUNTAR A LA PARTE BAJA
	INY
	LD	X	; CARGO A LO QUE ESTA APUNTANDO X Y SE LO SUMO
	ADC	Y	; A LO QUE ESTA APUNTANDO Y
	STO	Y	; EL RESULTADO LO GUARDO EN Y
	DEX		; DECREMENTO X y Y PARA APUNTAR A LA PARTE ALTA
	DEY
	LD	X	; SUMO X y Y Y LO GUARDO EN Y
	ADC	Y
	STO	Y
 
	LD	#0	; ESTA OPERACION ES PARA REVISAR QUE NO SE HAYA 
	ADC	#0	; GENERADO UN ACARREO DESPUES DE HABER SUMADO LA PARTE
	JZ	NPI	; ALTA, DE SER ASI SE LLAMARA AL MENSAJE DE OVERFLOW
 
	LDX	OVFLOW
	CALL	ESCR
 
	JZ	NPI
	JNZ	NPI
 
OPC3:	LDX	MENS3	; PRIMERA PALABRA=SUBS
	CALL	ESCR
 
	CALL	IDVAR1	; REALIZA LAS MISMAS OPERACIONES QUE EN LA SUMA (ARRIBA)
	SUB	#1	; PERO PARA LA RESTA
	JZ	NPI
	CALL	IDVAR2
	SUB	#1
	JZ	NPI
 
; AQUI COMIENZA LA RESTA
	LD	#1	; PRENDO LA BANDERA DEL ACARREO PARA QUE NO HAYA 
	ADD	#0FF	; PROBLEMA AL RESTAR
	INX		; INCREMENTO X y Y PARA APUNTAR A LA PARTE BAJA
	INY
	LD	X	; LE RESTO Y A X
	SBC	Y
	STO	Y	; y LO GUARDO EN Y
 
	LD	#0
	ADC	#0
	JZ	CNT1
 
	DEY
	LD	Y
	ADD	#1
	STO	Y
	INY
 
CNT1:	LD	#1
	ADD	#0FF
	DEX
	DEY
	LD	X
	SBC	Y
	STO	Y
 
	LD	#0
	ADC	#0
	JZ	NPI
 
	LDX	OVFLOW
	CALL	ESCR
 
	JZ	NPI
	JNZ	NPI
 
OPC4:	LDX	MENS4	; PRIMERA PALABRA=PRINT
	CALL	ESCR
 
	LD	VALIDA2	; CHECA SI EL PARAMETRO ES ALL SI LA RESTA DA CERO
	SUB	#6	; QUIERE DECIR QUE SI ES PRINT ALL 
	JNZ	OPC41
 
	LDX	SIG_LIN
	CALL	ESCR
	LDX	VARIA1	; ESCRIBE EL NOMBRE DE LA VARIABLE EN TURNO A SER 
	CALL	ESCR	; IMPRESA
	LD	HEXVA1	; CARGA EL VALOR HEXADECIMAL DE LA VARIABLE EN TURNO
	STO	NUM	; Y LO GUARDA EN NUM, PRIMERO LA ALTA Y LUEGO LA BAJA
	LD	HEXVA1+1
	STO	NUM+1
	CALL	IMPRI	; IMPRIME EL VALOR ALMACENADO EN NUM
 
	LDX	SIG_LIN	; HACE LO MISMO QUE ARRIBA PERO CON LA VARIABLE 2
	CALL	ESCR	; Y ASI SUCESIVAMENTE EN TODAS LAS VARIABLES
	LDX	VARIA2
	CALL	ESCR
	LD	HEXVA2
	STO	NUM
	LD	HEXVA2+1
	STO	NUM+1
	CALL	IMPRI
 
	LDX	SIG_LIN
	CALL	ESCR
	LDX	VARIA3
	CALL	ESCR
	LD	HEXVA3
	STO	NUM
	LD	HEXVA3+1
	STO	NUM+1
	CALL	IMPRI
 
	LDX	SIG_LIN
	CALL	ESCR
	LDX	VARIA4
	CALL	ESCR
	LD	HEXVA4
	STO	NUM
	LD	HEXVA4+1
	STO	NUM+1
	CALL	IMPRI
 
	LDX	SIG_LIN
	CALL	ESCR
	LDX	VARIA5
	CALL	ESCR
	LD	HEXVA5
	STO	NUM
	LD	HEXVA5+1
	STO	NUM+1
	CALL	IMPRI
 
	LDX	SIG_LIN
	CALL	ESCR
	LDX	VARIA6
	CALL	ESCR
	LD	HEXVA6
	STO	NUM
	LD	HEXVA6+1
	STO	NUM+1
	CALL	IMPRI
 
	JZ	NPI
	JNZ	NPI
 
OPC41	CALL	IDVAR1	; ES PARA VER SI EXISTE LA 2A PALABRA DE LA FRASE
	SUB	#1	; DENTRO DE LAS VARIABLES DEFINIDAS
	JZ	NPI
 
	LD	X
	STO	NUM
	INX
	LD	X
	STO	NUM+1
	CALL	IMPRI
 
	JZ	NPI
	JNZ	NPI
 
 
SUMDEC:	PUSH	A	; GUARDO EL VALOR DEL ACUMULADOR (UN 0 AL PRINCIPIO)
	LD	#0	; ESTO ES PARA APAGAR LA BANDERA DEL ACARREO
	ADD	#0
	POP	A	; RECUPERO EL VALOR DEL ACUMULADOR
	ADC	X	; SE LO SUMO A X y LUEGO ESE RESULTADO SE LO SUMO
	ADC	Y	; A Y (ESTAS TRES SUMAS SON PARA AGREGA EL ACARREO
			; EN CASO DE QUE SE HAYA GENERADO)
	STO	Y	; LO GUARDO EN Y
	LD	#1	; PRENDO LA BANDERA DEL ACARREO PARA PODER EFECTUAR UN
	ADD	#0FF	; SBC SIN QUE ME AFECTE
	LD	#9	; CARGO UN 9 Y SE LO RESTO PARA CHECAR SI EL NUMERO
	SBC	Y	; ES IGUAL O MAYOR A 9
	LD	#0	; CARGO UN CERO Y  LE SUMO UN CERO CON ACARREO PARA
			; CHECAR SI SE GENERO ACARREO AL REALIZAR LA RESTA
	ADC	#0
	JZ	REGRET	; SI ES CERO QUIERE DECIR QUE ES IGUAL O MENOR A NUEVE
			; Y YA NO ES NECESARIO REALIZAR LA SIGUIENTE OPERACION
	LD	Y	; SI  ES MAYOR QUE NUEVE LE SUMO 6 Y LE RESTO DIEZ PARA
	ADD	#6	; CONVERTIRLO EN UN NUMERO DECIMAL
	SUB	#10
	STO	Y
	LD	#1	; CARGO UN 1 PARA UTILIZARLO COMO EL ACARREO QUE SE 
			; GENERA SI RESULTA UN NUMERO MAYOR QUE NUEVE.
REGRET:	RET	
 
A_1:	SUB	#0	; RESTO CERO PARA VER SI YA TERMINE EL NUMERO 
	JZ	REGRET	; DETERMINADO DE SUMAS QUE ME LO INDICO LA PARTE
			; ALTA O BAJA DE NUM 
	PUSH	A	; GUARDO EL VALOR DEL ACUMULADOR (QUE SIRVE DE CONTADOR)
	LD	#0	
	LDX	PAR1	; LE PASO POR PARAMETROS DE REGISTRO PAR1 Y SAL1 A 
	LDY	SAL1	; SUMDEC
	CALL	SUMDEC
	LDX	PAR2
	LDY	SAL2
	CALL	SUMDEC
	LDX	PAR3
	LDY	SAL3
	CALL	SUMDEC
	LDX	PAR4
	LDY	SAL4
	CALL	SUMDEC
	LDX	PAR5
	LDY	SAL5
	CALL	SUMDEC
	POP	A	; RECUPERO EL VALOR DEL ACUMULADOR (CONTADOR) PARA
	SUB	#1	; DECREMENTARLO
	JZ	A_1
	JNZ	A_1
 
IMPRI:	LD	#0	; SE GUARDA UN CERO EN TODA LA CADENA QUE CONTENDRA EL
	STO	SAL1	; RESULTADO DE LA CONVERSION DE HEX-DEC
	STO	SAL2
	STO	SAL3
	STO	SAL4
	STO	SAL5
	STO	PAR5
	LD	#4	; CARGO EL 4096 EN PAR4, PAR... ETC.
	STO	PAR4	; PARA SUMARLO TANTAS VECES COMO EL NUM ME LO
	LD	#0	; INDIQUE
	STO	PAR3
	LD	#9
	STO	PAR2
	LD	#6
	STO	PAR1
 
 
	LD	NUM	; CARGO NUM PARA QUITARLE LA PARTE BAJA
	AND	#0F0
	SR
	SR
	SR
	SR
	CALL	A_1
	
 
SIG2:	LD	#0	; ES PARA REALIZAR LAS SUMAS CON 256
	STO	PAR4
	LD	#2
	STO	PAR3
	LD	#5
	STO	PAR2
	LD	#6
	STO	PAR1
 
 
	LD	NUM
	AND	#0F
	CALL	A_1
 
SIG3:	LD	#0	; ES PARA REALIZAR LAS SUMAS CON 16
	STO	PAR3
	LD	#1
	STO	PAR2
	LD	#6
	STO	PAR1
 
 
	LD	NUM+1
	AND	#0F0
	SR
	SR
	SR
	SR
 
	CALL	A_1
	
 
SIG4:	LD	#0	; ES PARA REALIZAR LAS SUMAS CON UNOS ( LA CANTIDAD
	STO	PAR2	; ME LA INDICA LA PARTE BAJA DE NUM+1)
	LD	#1
	STO	PAR1
 
 
	LD	NUM+1
	AND	#0F
 
	CALL	A_1
 
SIG5:	
	LD	SAL1	; SE LE SUMA 30 A CADA UNA DE LAS SALIDAS PARA 
	ADD	#30	; CONVERTIRLAS EN UN VALOR ASCII Y DE ESTA MANERA
	STO	SAL1	; PUEDAN SER DESPLEGADAS EN LA PANTALLA
			; EL CONJUNTO DSE LAS SAL1, SAL2, ETC, FORMAN LA CADENA
			; QUE SE DESPLEGARA EN LA PANTALLA
 
	LD	SAL2
	ADD	#30
	STO	SAL2
 
	LD	SAL3
	ADD	#30
	STO	SAL3
 
	LD	SAL4
	ADD	#30
	STO	SAL4
 
	LD	SAL5
	ADD	#30
	STO	SAL5
	LDX	SAL5	; HAGO QUE APUNTE X A LA PARTE ALTA DE LA CADENA A SER
	CALL	ESCR	; IMPRESA
	RET
 
OPC5:	LDX	MENS5	; PRIMERA PALABRA=TRANSFER
	CALL	ESCR
	
	CALL	IDVAR1
	SUB	#1
	JZ	NPI
	CALL	IDVAR2
	SUB	#1
	JZ	NPI
 
 
	LD	X
	STO	Y
	INX
	INY
	LD	X
	STO	Y
 
	JZ	NPI
	JNZ	NPI
OPC6:	LDX	MENS0	; PRIMERA PALABRA = NO VERBO
	CALL	ESCR
 
NPI:	RET
 
BEGIN:
	CALL	LIMPIA	; LLENA DE ESPACIOS LOS LUGARES OCUPADOS POR PALA1..
			; PARA EVITAR BASURA
	CALL	ABRE	; ABRE LA VENTANA DE COMUNICACION CON EL USUARIO
 
	LDX	MENSAJE
	CALL	ESCR
	LDX	SIG_LIN
	CALL	ESCR
 
	LDX	PROMPT
	CALL	ESCR
 
	CALL	LEE	; RECIBE LA FRASE DEL USUARIO GUARDANDOLA EN BUZON
			; Y SIENDO APUNTADA POR X
	CALL	ASIGNA	; LO QUE HAY EN BUZON LO GUARDA EN ORACIO (ESPACIO 
			; RESERVADO PARA PODER GUARDAR Y MANEJAR LA FRASE
 
	LDX	ORACIO	; X=ORACION A SEPARAR
 
	SEPARA	PALA1
	SEPARA	PALA2
	SEPARA	PALA3	; SEPARA LA ORACION EN SUS CINCO PRIMERAS PALABRAS
			; ASIGNANDOLAS A LAS LOCALIDADES PALA1, PALA2,..
			; CADA PALABRA PODRA TENER A LO MAS 6 LETRAS.
 
	VAL_NUM PALA1, HEX1, VALIDA1	; VALIDA CADA UNA DE LAS PALABRAS
	VAL_NUM PALA2, HEX2, VALIDA2	; PARA VER SI SON NUMEROS VALIDOS.
	VAL_NUM PALA3, HEX3, VALIDA3	; SI LO SON LOS ASIGNA A HEX1, HEX2
					; Y PONE UN VALOR DE 0 A VALIDA1,2.
					; SI NO LO SON PONE UN 5 A VALIDA1,2
					; Y ALGO DE BASURA A HEX1, HEX2.
	; SOLO RECONOCERA LAS PRIMERAS 4 LETRAS DE LA PALABRA.
 
	VAL_VER	PALA1, VALIDA1 ; VALIDA CADA UNA DE LAS PALABRAS PARA VER SI SON
	VAL_VER	PALA2, VALIDA2 ; VERBOS VALIDOS. SI LO SON LES ASIGNA EL NUMERO
	VAL_VER	PALA3, VALIDA3 ; DE VERBO (1,6) A VALIDA1 O A VALIDA2 O A...
 
	VAL_VAR PALA1, VALIDA1	; LOS MISMOS COMENTARIOS QUE ARRIBA PERO CON 
	VAL_VAR PALA2, VALIDA2  ; RESPECTO A LAS VARIABLES Y ASIGNANDO VALORES
	VAL_VAR PALA3, VALIDA3	; DE (8,D)
 
	CALL	ID
 
	CALL	LEE
	CALL	CIERRA
		
	JNZ	BEGIN
	JZ	BEGIN
END

    Source: geocities.com/v.iniestra/apuntes/arq_proc

               ( geocities.com/v.iniestra/apuntes)                   ( geocities.com/v.iniestra)