Rutinas de error de YS A continuacion mi traduccion al castellano del texto original en ingles, de material publicado en Your Spectrum y Your sinclair. I - Your Spectrum 11 FEB. 1985 P.34 " RUTINA DE ERRORES Los mensajes de error en el Speccy nunca parecen contar plenamente en su repentina aparicion. John Durst nos trae una interesante pieza de codigo que hace uso de la rutina de manejo de errores que existe en la ROM para tener el control del programa del usuario en los casos de desaborde, errores al tipear y similares. Aqui tenemos dos formas de hacer que la rutina de 'error' del Spectrum haga algo mas util que solo volver al modo de comando, con su informe apropiado. Antes de usar cualquiera de ellos, es bueno asegurarse que el programa no esta generando ningun error real; es decir, debe estar apropiadamente depurado, para que los 'errores' sean esos con los que tratara el programa mismo. Eso limita los posibles errores principalmente a efectos de BREAK o quizas, desbordamientos, errores de tipeo, variables no definidas y asi. La razon de esto es mas que obvia. Si su programa genera un error realmente serio, el mensaje mas apropiado sera el mejor posible como respuesta; de esa forma usted tiene la chance de hacer algo para evitar que suceda otra vez. Cualquier respuesta 'automatica' es muy probable que lo lleve a un atolladero mucho mayor. CAMBIO DE DIRECCIONES El modo mas facil de cambiar la respuesta a un error es simplemente alterando la direccion ERRSP y hacer que apunte — por decir — al inicio de una rutina (un menu, o algo similar). Esto funciona muy bien con programas totalmente en codigo maquina. Yo solia enviar cualquier clase de BREAK a un menu principal - usualmente esos BREAKs durante LOAD, o SAVE, o alguno provocado mediante alguna tecla pre programada. Desafortunadamente, eso no funciona del todo bien desde un programa Basic, terminando con no hacer nada o ejecutar un NEW. Algo mas elaborado, que si funcionaria desde un programa Basic, implica la vieja idea del modo de Interrupciones. Al ir de un modo de Interrupciones al otro, osea del IM1 al IM2, usted puede hacer que ERRNR sea escaneado durante cada interrupcion. Si la rutina encuentra algo diferente a FF (lo cual significa 'todo claro'), entonces saltara a una rutina que tenga los datos de algun comando - tal como 'GOTO 10' en ELINE - y enseguida ejecutarlo. Todo eso parece virtualmente a prueba de fuego, excepto que - ocasionalmente - es posible congestionar el espacio de edicion. El Spectrum da entonces un poderoso 'eructo' (por indigestion?) y aparece el mensaje 'GOTO 10' (o lo que sea) en la parte baja de la pantalla. Pero, si pulsa ENTER, obedecera esa orden justo como se deseaba. La respuesta es muy simple - 'GOTO 10' consiste de 9 bytes, del modo sigte.: EC 31 30 0E 00 00 OA 00 00 EC es el token de 'GO TO'; 31 y 30 son 10 en ASCII; OE nos indica que un numero le sigue; y los ultimos 5 bytes son el numero 10, como valor entero (OA). OPERACIONES DE ERROR El resto de la rutina lleva a cabo cuatro operaciones: restaura ERR_SP to la condicion 'OK', volviendola FF; eso limpia el area de edicion usando la rutina de la ROM SET_MIN, en 16B0; crea un espacio de 9 bytes en dicha area usando otra rutina en la ROM, MAKEROOM, en 1655; y final mente, carga los 9 bytes preparados para el comando, en la misma area para luego saltar de vuelta a la ROM en 12E2, para su ejecucion. Tambien es necesario introducir dos rutinas cortas - para alterar el modo de Interrupcion y volverla a cambiar. Solo por broma (y conveniencia) las he puesto en dos UDGs, para que las pueda llamar mediante USR USR "M" y USR USR "N". La rutina 'Retorno a IM1' es necesaria si desea poder volver a listar su programa Basic. Pero, claro esta, si es muy conciente de la seguridad, no le contara a nadie lo que hace RANDOMIZE USR USR "N"! Y.S. NOTES HEX ASSEMBLER -------------------------------------------------------- Interrupt vector FEFF 82 address FF00 FF -------------------------------------------------------- Interrupt routine FF82 F5 PUSH AF FFB3 3A 3A 5C LD A,(5C3A) FF86 3C INC A FF87 20 04 JR NZ,FFBD FF89 F1 POP AF FF8A C3 38 00 JP 0038 FF8D F1 POP AF FF8E 3E FF LD A,FF FF90 32 3A 5C LD (5C3A),A FF93 CD B0 16 CALL 16B0 FF96 2A 59 5C LD HL,(5C59) FF99 01 09 00 LD BC,0009 FF9C CD 55 16 CALL 1655 FF9F 2A 59 5C LD HL,(5C59) FFA2 11 AF FF LD DE,FFAF FFA5 01 09 00 LD BC,0009 FFA8 EB EX DE,HL FFA9 ED B0 LDIR FFAB FB EI FFAC C3 E2 12 JP 12E2 -------------------------------------------------------- DEFB:("GOTO10") FFAF EC 31 30 0E 00 00 0A 00 00 -------------------------------------------------------- Set FFB8 3E FE LD A,FE Interrupt FFBA ED 47 LD I,A USR USR FFBC ED 5E IM2 "M" FFBE C9 RET -------------------------------------------------------- Restore FFC0 3E 3F LD A,3F Interrupts FFC2 ED 47 LD I,A USR USR FFC4 ED 56 IM1 "N" FFC6 C9 RET " II - Your Sinclair 3 MAR 1986 P.41 " TASK FORCE Joseph Otten de Manchester tiene la forma perfecta de confundir a todos esos tipos que les gusta interrumpir para ver tus programas. Usa esto cuando quieras salvar un programa tuyo pero antes salva una version desprotegida: POKE 23613,0: SAVE "name" CODE 23613,PEEK 23627+256•PEEK 23628-23613: GOTO La variable del sistema ERRSP esta en 23613/4 asi que al alterarla pasaran toda clase de cosas graciosas si se da un error en el programa. Esta rutina por Andrew Cope de Exeter provee de una funcion ON ERROR GOTO. No es relocalizable pero puede ser ensamblada en cualquier direccion conveniente. Andrew usa 64400 para poder hacer espacio a algunos caracteres redefinidos. 0000 ORG 64400 0010 LD DE, ERR_M 0020 LD HL, (23613) 0030 LD (HL),E 0040 INC HL 0030 LD (HL),D 0060 RET 0070 ERR_M LD A,(23610) 0080 INC A 0090 LD BC,(23728) 0100 LD (23662),BC 0110 XOR A 0120 DEC A 0130 LD (23610),A 0140 INC A 0130 LD (23664),A 0160 LD HL,(23641) 0170 LD BC,2 0180 CALL 1652H 0190 EX DE,HL 0200 LD (HL),232 0210 INC HL 0220 LD (HL),13 0230 BTEST CALL 1F54H 0240 JP C,12CEH 0230 JR BTEST 0260 END Para poder usarla todo lo que necesitas hacer es elegir la linea a la cual quieres que ON ERROR salte. Esta puede ser una subrutina de modo que puedas alterarla como te plazca. Para activarla, solo tienes que llamar al codigo una vez. Despues de eso, todos los errores seran capturados auto maticamente. Andrew sugiere lo sigte.: 5 DEF FN h(x)=INT(x/236): DEF FN l(x)=x-256*FN h(x) 10 RANDOMIZE USR 64400 20 LET erl= nro. de linea al cual saltar: GOSUB 9000 Resto del programa 9000 REM subrutina 9010 POKE 23728,FN l(erl) 9020 POKE 23729,FN h(erl) 9030 RETURN Andrew tambien nos hace una sugerencia interesante. Puedes ahorrar espacio y tiempo en leer (READ) todas las DATAs en una matriz antes que el programa empiece. El dice que reduce el 'tiempo de acceso' a la mitad. A mi me parece que toma menos tiempo leer una sentencia DATA antes que accesar a una variable DIMensionada. Bueno, me pregunto quien tiene la razon. Por que no desarrollas un programa que actue como benchmark y nos lo envias con tus resultados? " (c)2022 zx_if1@hotmail.com