Hola,
Aviso que esto es una
paja mental, de caracter grave y por supuesto muy friki en variante retro. Encima es un tocho-mensaje, la mitad del mismo pensado según lo escribía...
Resulta que andaba yo mirando unpaws por cosas de la vida, y me encontré con que PAW solo tiene 107 condactos, pero usa 1 byte para codificar el opcode.
Eso significa que una aventura de PAW está desperdiciando nada menos que 149 posibilidades de distintos condactos, o mirándolo de otro modo, que desperdicia 21, y nos sobra un bit entero para otra cosa.
¿Para que otra cosa? ... Indirección. Esto es algo que ya tenía el DAAD, y por supuesto tiene Superglús, pero meterselo al PAW es un reto.
Digamos que si el opcode de LET es el 12 (es un ejemplo)
[12 100 5] ==> LET 100 5
[130 100 5] ==> LET @100 5 (140 = 12+128, es decir, el mismo opcode pero con el bit que sobra a 1)
Pero esto solo nos da para hacer indirección en el primer parámetro, así que quizá sea mejor algo así:
[130 1 100 5] ==> LET @100 5
[130 2 100 5] ==> LET 100 @5
[130 3 100 5] ==> LET @100 @5
Sí, gastamos un byte entero para decir que parámetros de los que siguen llevan indirección. Es un desperdicio ciertamente, porque sobran 6 bits, pero aunque la indirección es muy útil donde se usa, tampoco aparece continuamente, así que puede ser aceptable.
Bueno, sea uno u otro modelo, el caso es que como poco podría llevar indirección en un parámetro (ya veríamos si es más util en general el primero o el segundo, o si hay alguna manera de hacerlo variable segun condacto).
Y que hay que hacer para dar soporte a esto:
1) Debug paso a paso de PAW hasta encontrar donde se ejecuta el interprete que lee los opcodes. Supongo que en PAW habrá algún sitio que haga esto:
- Leer el opcode del condacto
- Mirar cuantos parámetros tiene (de una tabla lookup, supongo) , leerlos y meterlos en la pila.
- Mirar donde está la rutina que ejecuta ese condacto (en otra tabla lookup, supongo), y hacer un CALL.
- Al retornar del CALL, incrementar el puntero que apunte al siguiente condacto en el número de parámetros del condacto, para apuntar al siguiente opcode.
Y habría que cambiarlo a esto:
- Leer el opcode del condacto, y detectar si tiene indirección, quedándonos con el opcode real.
- Si no había indirección mirar cuantos parámetros tiene , leerlos y meterlos en la pila.
- Si había indirección, mirar cuantos parámetros tiene y los que tengan indirección, leer el valor del código, hacer la indirección, y meter los valores resultantes en la pila.
- Mirar donde está la rutina que ejecuta ese condacto y hacer un CALL.
- Al retornar del CALL, incrementar el puntero que apunte al siguiente condacto (si hay indirección y al final se mete el byte de más, numero de parámetros +1).
Para hacer la rutina que implementa la indirección hace falta hueco, y dudo que quepa en el mismo sitio que esté la actual sin indirección, así que probablemente tras leer el opcode habría que hacer un JMP a algun sitio donde hayamos implementado esta lógica y que a su vez, tras hacer el cambio de valores, vuelva a saltar a donde llegaríamos normalmente tras leer los parámetros.
¡Pero si no hay sitio para meter esa rutina! Pues no, probablemente esa rutina no cabe, o quizás sí, pero da igual. ¿Por qué?
Por
que con indirección nos sobran condactos.. Ver equivalencias:
Código:
copyfo place ojno @flagno
prompt let 42 value
score print 30
add plus flagno2 @flagno1
clear let flagno 0
copyff let flagno2 @flagno1
set let flagno 255
sub minus flagno2 @flagno1
create place objno 255
destroy place objno 252
ability let 37 v1;let 52 v2
carried isat objno 254
notcarr isnotat objno 254
notworn isnotat objno 253
worn isat objno 253
notzero noteq flagno 0
same eq flagno1 @flagno2
notsame noteq flagno1 @flagno2
zero eq flagno 0
No estoy 100% seguro de todos, especialmente de los de objetos, ya se afinaría.
Estoy seguro de que si podemos quitar el código que ejecuta todos esos condactos, queda hueco para meter la indirección, aunque haya que desplazar algunos otros para que el hueco esté todo junto. En cualquier caso, si se encuentra hueco sin quitarlos, pues no hace falta quitarlos.
En definitiva, deberíamos conseguir una versión
hackeada del interprete PAW que contenga estos parches.
Ya, ¿pero como hacemos que el editor de PAW soporte esa sintaxis y genere aventuras para ese intérprete?No lo hacemos, usamos inPAWS. Creo que sería fácil meter el soporte de esa sintaxis en inPAWs, y hacer que genere una base de datos PAW que el interprete
hackeado pueda ejecutar. Incluso puede que con inPAWs pudieramos darle soporte a esos condactos que hemos quitado, mediante el preprocesador (vamos, que el preprocesador nos cambia automaticamente cada ability X Y por let 37 X;let 52 Y).
Lo que sería importante es que este inPAWs modificado no permitiera meter los opcodes de los condactos borrados.
¿Y qué más podemos hacer?Pues no se, si al final se quitan los condactos, quizá quede hueco para otros condactos.
Superglús tiene un montón de condactos más que PAW, algunos de los cuales son razonables para una maquina de 8bits (los de reproducir ficheros OGG no). Se podría mirar si cabe implementar alguno intersante (y darle soporte en inPAWs).
Incluso...
paja mental #2... si conseguimos que todo el "hueco" que dejan los condactos esté junto, sería posible cargar condactos plugin con inPAWs. Algo como tener un ficherito con el binario de un condacto, y decir a que opcode lo aplicas. Por ejemplo, podríamos poner en inPAWs un
Código:
loadPlugin mul.plu 97
Lo cual haría que inPAWs, que debe de alguna manera poder saber donde tiene un .TAP del interprete hackeado, pudiera colocar el binario mul.plu en el primer hueco de la zona vaciada, y en la "tabla lookup" de condactos de PAW apuntar a el 97 a esa direccion. Para ello el mul.plu debería contener el nombre del condacto (para la sintaxis de inPaws), el numero de parámetros (para rellenar también la tabla lookup de parámetros y la propia sintaxis de inPaws) y el codigo binario propiamente dicho (Z80).
Si ponemos dos plugin:
Código:
loadPlugin mul.plu 97
loadPlugin div.plu 98
Pues inPAWS coloca el binario de uno detrás del otro y actualiza las tablas lookup. Como inPAWs sabe cuanto hueco hay, podrá dar una alarma si usas demasiados condactos plugin. Como el autor elige qué plugins usa, puede meter los que le hagan falta para esa aventura en concreto, y en otra aventura meter otros. Incluso hace más fácil el asunto de los EXTERN, si quieres hacer algo concreto en lugar de un EXTERN te haces un condacto plugin. Eso podría liberar el hueco del propio condacto EXTERN de hecho.
¿Se puede hacer para Amstrad CPC o PAW PC?Pues supongo que sí, habría que hackear su interprete y mirar el output que hace inPAWs para CPC.
¿Y para Superglús?Claro, pero es una tontería, Superglús ya soporta todo eso y más. Ahora bien, se podría generar una aventura con inPAWs que generara output de Spectrum, CPC, PAW-PC y Superglús.
¿Posibles problemas?Pues todo esto es una conjetura, así que lo mismo PAW no funciona así, no hay las tablas lookup que creo que debe haber, y no hay manera humana de hacer esto (lo de los plugins, lo de la indirección creo que sí).
¿Y para qué vale?Probablemente para nada. Es difícil que nadie use este hack para hacer una aventura, de hecho creo que salvo Mastodon nadie ha usado inPAWs para hacer una aventura (y eso que está genial). ¿Pero a que mola?
En fin, yo solo no creo que lo vaya a hacer, mas que nada porque no me da tiempo o quizá no le doy la prioridad que tendria que tener, pero no se, lo mismo si alguien se une y vamos viendo posibilidad, me animo.
¿Dije que era una
paja mental o no lo dije?
