Microhobby 12. Año II, del 22 al 28 de enero de 1985

Utilidades: Carga y almacenamiento de programas con velocidad variable (II)

Paco Martín y José María Diaz

Esperamos que el artículo anterior haya cumplido la misión de aclarar al lector el método empleado para analizar la sintaxis de los nuevos comandos que se nos ocurra incluir en el Basic del Spectrum.

Partiendo de esta premisa, presentamos en este número la rutina de sintaxis completa, es decir, con unas modificaciones necesarias para mayor comodidad de uso, pero que de incluirlas en la anterior exposición, pensamos que hubieran dificultado en extremo la comprensión de la lógica del programa.

Asimismo, hemos incluido también parte de la rutina de velocidad variable para que se pueda ir examinando con el detalle y la tranquilidad que requiere, dada la cierta complejidad de este proceso, en el que se mezclan, siguiendo una lógica precisa, partes de la rutina ROM del ordenador modificadas de acuerdo a nuestros propósitos, con trozos de código que ha sido necesario «fabricar», bastante repletos de trucos y artimañas de programación, que esperamos sean útiles a los programadores ávidos de lenguaje máquina.

Hemos tratado de explicar, con la mayor precisión y brevedad posibles, lo que está sucediendo en el microprocesador mientras ejecuta, paso a paso la rutina, esperando, no obstante, que el lector consiga una visión de conjunto, a vista de pájaro, del procedimiento como un todo.

Antes de terminar, dos aclaraciones:

  • para mayor comodidad de uso, después del “REM” deben colocarse dos puntos; así obtendremos fácilmente los “TOKENS” de SAVE, LOAD, VERIFY o MERGE.
  • La rutina está pensada para que a velocidad normal (1.500 baudios) sea plenamente compatible con el sistema operativo del ordenador; sin embargo, quisiéramos matizar de nuevo que a altas velocidades de transferencia de información, la precisión con la que este proceso ocurre, depende de las características físicas del aparato de cassette utilizado.

Listado ensamblador

	ORG	60000
	LD	HL,(23645)	TOMA LA DIRECCION CH-ADD PARA SINTAXIS INICIAL.
	INC	HL
	LD	A,(HL)
	CP	234 ;'REM'	COMPRUEBA LA PRESENCIA DE "REM"
	JR	NZ,ERRORA	Y ":"
	INC	HL
	LD	A,(HL)		SI NO EXISTEN. SALTA A ERROR
	CP	":"
	JR	NZ,ERRORA
	INC	HL
	LD	A,(HL)		EXAMINA LOS SIGUIENTES
	CP	248 ;'SAVE'	CARACTERES DE LA LINEA DE
	JR	Z,TSAVE		COMANDO PARA BIFURCARA
	CP	239 ;'LOAD'	LA SUBRUTINA CORRESPONDIENTE.
	JP	Z,TLOAD
	CP	214 ;'VERIFY'
	JP	Z,TVERIF
	CP	213 ;'MERGE'
	JR	Z,TMERGE
	JR	ERRORA		SI NINGUNO EXISTE SALTA A ERROR.
ERROR6	RST	8		LLAMADAS A LA SUBRUTINA ROM DE MENSAJES DE ERROR
	DEFB	5; 'NUMBER'TOO BIG'
ERRORA	RST	8
	DEFB	9; 'INVALID ARGUMENT
ERRORB	RST	8
	DEFB	10; 'INTEGER OUT OF RANGE'
ERRORC	RST	8
	DEFB	11; NONSENSE IN BASIC'
ERRORF	RST	8
	DEFB	14; INVALID ARGUMENT'
ERRORR	RST	8
	DEFB	26; 'TAPE LOADING ERROR'
TSAVE	CALL	BAUDIO		TOMA EL NUMERO INDICADOR DELA VELOCIDAD DE GRABA-
	CALL	NAME		CION. NOMBRE Y SI SU LONGITUD ES
	JR	C,ERRORF	CERO O MAYOR QUE 10. SALTA A ERROR.
	CALL	SINTAX		COGE EL RESTO DE LOS DATOS.
	PUSH	AF		PRESERVA EL INDICADOR DE "TIPO".
	LD	A,#FD		ABRE CANAL 0
	CALL	#1601
	XOR	A
	LD	DE,#9A1		MENSAJE "START TAPE..."
	CALL	#C0A
	SET	5,(IY+2)	FLAG PARA BORRAR MENSAJE.
	CALL	#15D4		ESPERAR PULSACION TECLA.
	LD	IX,CABEC	PUNTERO PARA EL BUFFER DE CABECERA.
	LD	DE,17		LONGITUD DEL BUFFER.
	XOR	A		INDICA "ES UNA CABECERA",
	CALL	SAVE		SALVA LA CABECERA.
	LD	B,#32
PSAV	HALT			SE PRODUCE UN RETARDO ANTES DE SALVAR EL SEGUNDO
	DJNZ	PSAV		BLOQUE.
	POP	AF		RECUPERA "TIPO"
	LD	DE,(LONT)	LONGITUD DEL BLOQUE A SALVAR.
	LD	A,#FF		SEÑAL "BLOQUE DE DATOS".
	LD	IX,(23635)	SI ES UN PROGRAMA. TOMA DIR. DE COMIENZO.
	JR	C FSAV
	LD	IX,(DIRT)	SI NO. LA DIRECCION ESPECIFICADA EN EL COMANDO.
FSAV	CALL SAVE
	RET
TMERGE	CALL	BAUDIO
	CALL	NAME
	CALL	C,CPNAME	COMPRUEBA QUE EL FINAL ES'"'
	INC	HL
	LD	A,(HL)		AL FINAL DEBE HABER UN "ENTER".
	CP	13
	JR	NZ,ERRORC
	CALL	RELOAD		CARGA LA CABECERA.
	LD	BC,(LONBUF)	LONGITUD TOTAL DEL PROGRAMA
	PUSH	BC
	INC	BC
	RST	48		CREA EN EL AREA DE TRABAJO "BC+1" ESPACIOS.
	LD	(HL),#80	PONE UN INDICADOR DE FIN EN LA LOCALIZACION EXTRA.
	EX	DE,HL
	POP	DE
	PUSH	HL
	PUSH	HL
	POP	IX
	LD	A,#FF
	CALL	LMBYT		CARGA EL BLOQUE DEL PROGRAMA.
	JP	2253		EFECTUA LA OPERACION DE "MERGE".
TVERIF	CALL	LDPREV		INICIALIZA VALORES.
	RES	0,(IY+37)	SEÑAL "VERIFICANDO".
	JR	NC,LDBYTE	SALTA SI NO ES UN PROGRAMA BASIC.
	JR	CPROG		VERIFICA EL PROGRAMA BASIC.
LDPREV	CALL	BAUDIO		TOMA LOS VALORES DEL COMANDO.
	CALL	NAME		COMPRUEBA SINTAXIS Y CARGA LA CABECERA.
	CALL	C,CPNAME
	CALL	NSINT
	PUSH	AF		PRESERVA EL INDICADOR DE TIPO.
	CALL	RELOAD
	POP	AF		LO RECUPERA.
	RET
TLOAD	CALL	LDPREV
	SET	0,(IY+37)	SEÑAL "CARGA EL BLOQUE".
	JR	NC,LDBYTE	SALTA SI NO ES UN PROGRAMA BASIC.
	LD	DE,(LONBUF)	TOMA LONGITUD TOTAL DEL BLOQUE A CARGAR.
	LD	HL,(23635)
	ADD	HL,DE		MIRA SI EL PROGRAMA A CARGAR ES MENOR QUE EL PRO-
	EX	DE,HL		GRAMA RESIDENTE.
	LD	HL,(23641)
	SCF
	SBC	HL,DE
	JR	C,ADDS		SI ES MAYOR O IGUAL. SALTA
	JR	Z,ADDS		PARA CREAR ESPACIO.
	LD	B,H		RECLAMA LOS BYTES SOBRANTES.
	LD	C,L
	EX	DE,HL
	CALL	#19E8
	JR	PPL
ADDS	ADD	HL,DE		CREA ESPACIO SUFICIENTE EN MEMORIA PARA EL NUEVO
	EX	DE,HL		PROGRAMA.
	AND	A
	SBC	HL,DE
	LD 	B,H
	LD	C,L
	EX	DE,HL
	CALL	#1655
PPL	LD	HL,(23635)	ASIGNA LA DIRECCION CORRECTA DE LAS VARIABLES DE
	LD	BC,(INFBUF)	PROGRAMA.
	ADD	HL,BC
	LD	(23627),HL
	LD	HL,(DIBUF)	MIRA SI EL PROGRAMA BASIC SE AUTOEJECUTA Y EN QUE LI-
	LD	A,H		NEA.
	AND	#C0
	JR	NZ,CPROG
	LD	(23618),HL	SI ES ASI. HACE UNA COPIA.
	LD	(IY+10),0	SEÑALA PRIMERA INSTRUCCION DE LA LINEA.
CPROG	LD	DE,(LONBUF)
	LD	IX,(23635)
CARGA	LD	A,#FF
	BIT	0 ,(IY+37)	EXAMINA "LOAD O VERIFY"
	JR	Z,VBYT
LMBYT	SCF
VBYT	CALL	LOAD
	RET	C
	JP	ERRORR
LDBYTE	AND	A		SE EFECTUA UN CHEQUEO DEL REGISTRO "A" PARA DETER-
	JR	NZ,INDEF	MINAR EL TIPO DE CARGA
	LD	IX,16384	A=0 INDICA "LOAD SCREENS".
	LD	DE,(LONT)	A=1 INDICA "LOAD CODE".
	LD	HL,(LONBUF)	A=2 INDICA "LOAD CODE XXXX".
	AND	A		A=3 INDICA "LOAD CODE XXXX. XXXX".
	SBC	HL,DE
	JP	NZ,ERRORR
	JR	CARGA
INDEF	CP	2
	JR	NC(DIDEF)
	LD	IX,(DIBUF)
DEFLO	LD	DE,(LONBUF)
	JR	CARGA
DIDEF	LD	IX,(DIRT)
	JR	NZ,TODEF
	JR	DEFLO
TODEF	LD	DE,(LONT)
	JR	CARGA
RELOAD	LD	IX,BUFCAB	DIRECCION DE CARGA DE LA CABECERA.
	LD	DE,17
	XOR	A
	SCF
	CALL	LOAD
	JR	NC,RELOAD	SI ERROR. INSISTE.
	RES	0,(IY+2)	ABRE CANAL SUPERIOR DE PANTALLA.
	LD	(IY+82),3	PREVEE SCROLL DE TRES LINEAS.
	LD	HL,CABEC	DIRECCION PUNTERO CABECERA ESPECIFICADA.
	LD	C,128		SEÑAL "DIFERENTE TIPO".
	LD	A,(BUFCAB)
	CP	(HL)		COMPARA AMBAS CABECERAS.
	JR	NZ,LDTIP	SALTA SI NO SON IGUALES.
	LD	C,246		SEÑAL "10 CARACTERES IGUALES".
LDTIP	CP	4		SI EL TIPO DE BLOQUE ES MAYOR
	JR	NC,RELOAD	QUE 3,CARGA NUEVA CABECERA
	LD	DE,#9C0
	PUSH	BC		IMPRIME EL MENSAJE ASOCIADO A CADA TIPO DE BLOQUE
	CALL	#C0A		Y EL NOMBRE DEL BLOQUE ENTRANTE.
	POP	BC
	LD	DE,BUFNAM
	LD	HL,NOMBRE
	LD	B,10
	LD	A,(HL)
	INC	A
	JR	NZ,LDNAME
	LD	A,C
	ADD	A,B
	LD	C,A
LDNAME	LD	A,(DE)
	CP	(HL)
	INC	HL
	INC	DE
	JR	NZ,LDPR
	INC	C
LDPR	RST	16
	DJNZ	LDNAME
	BIT	7,C		EXAMINA SI EL TIPO Y EL NOMBRE
	JR	NZ,RELOAD	ENTRANTES COINCIDEN.
	LD	A,13
	RST	16
	RET
 
012/utilidades.txt · Última modificación: d/m/Y H:i por miguel
Recent changes RSS feed Creative Commons License Driven by DokuWiki Made on Mac