Desarrollando cartuchos ROM con X-BASIC

Par DarkSchneider

Paladin (942)

Portrait de DarkSchneider

14-03-2014, 15:11

La idea es simplificar el desarrollo de ROM usando X-BASIC (AKA Turbo-BASIC, BASICKUN). Ya que para programar la lógica es mucho más sencillo de hacer y depurar, en ASM es fácil que se te escape algo y para cualquier cosita necesitas escribir mucho código.

El requisito es que el programa se ejecute con CALL RUN, ya que en este caso el programa entero se compila por lo que se podría prescindir el intérprete BASIC (creo). Luego se almacenaría el programa compilado con BSAVE y el binario se usaría para crear el programa de la ROM (en 4000h tras la cabecera).

Para ello hacen falta algunas cosas, de las cuales pregunto a continuación lo que por el momento me viene a la mente que haga falta:

1) ¿Dónde se almacena el compilado por X-BASIC?. Necesario para el BSAVE. He hecho un BSAVE 8000h-FFFFh y luego lo abro con un editor Hex pero no estoy acostumbrado a lo que un MSX tiene en RAM y no lo localizo. Y dónde mete las variables usadas en el fuente, para no pisar esa zona de memoria con POKEs.

2) Para desarrollar cartuchos, ¿qué es lo mejor?, se me había ocurrido pinchar un cartucho RAM en el slot 1 por ejemplo e ir volcando ahí los códigos máquina (llamados con USR) y datos que vaya generando. De esta forma es como si se tratara más o menos de un cartucho real. Bastaría con no pisar la página destinada al fuente (4000h-7FFFh) salvo por los CM, que se pondrían al final de dicha página, siempre que el fuente compilado no apure mucho los 16KB (que no creo). Los datos en 8000h-BFFFh ya que al compilar no hace falta ir leyendo el fuente BASIC por lo que esa página podemos cambiarla al slot de la RAM.
También he leído que los cartuchos de 64KB solían llevar un mapper, imagino que para dejar disponible la página de la BIOS para usarse desde el código del cartucho. En el emulador una de las opciones de RAM es memoria mapeada, pero no tengo ni idea de como funciona. He visto la documentación de los mappers y se trata de escribir en direcciones (6000h, etc.), pero ¿escribir qué?, y además, supuestamente la ROM no se puede escribir, ¿entonces cómo funciona eso?. Si es por poner un ejemplo, pues con un ASCII 16K estaría bien, que me parece una forma muy lógica de mapear, en páginas completas.

3) He hecho el método de pasar un BASIC a ROM (BSAVE y luego editar con Hex), y funciona. Sin embargo lo que no funcionan son los CM que tengo en el código BASIC en DATAs y que luego escribo en C000h mediante POKEs. Imagino que es porque al arrancar desde el cartucho, la página del C000h se mapea en ese mismo slot, ¿es eso?. En principio para estas pruebas sólo es una ROM de 16KB que contiene 8000h-BFFFh, por eso me ha extrañado que no funcione poner esos CM en C000h. Además falla justo ahí, ya que me salta el error en esa línea. Esta es parte del fuente:

...
110 FOR I%=0 TO 767:POKE &HD000+I%,0:NEXT I%
120 DATA &h01,0,3
130 DATA &h11,0,&h18
140 DATA &h2a,&hf8,&hf7
150 DATA &hcd,&h5c,0
160 DATA &hc9
170 FOR I%=0 TO 12:READ A:POKE &HC000+I%,A:NEXT I%
180 DEFUSR=&HC000:A=USR(&HD000)
...

Que vemos que ponemos "1 pantalla en RAM en D000h" todo a 0, luego el CM, luego ponemos ese CM en C000h, y luego lo ejecutamos para copiar la RAM en D000h a la VRAM. Si lo ejecuto en entorno BASIC OK pero en cartucho se cuelga y no hace nada.

Por el momento sería esto. Gracias.

!login ou Inscrivez-vous pour poster

Par Josb

Master (205)

Portrait de Josb

14-03-2014, 17:55

Para hacer ROM de 32 Kb que funcionen con kunbasic solo tienes que hacer estos dos pasos:

1. convertir el programa fuente basic a una rom de 16k (hay varios programas que te permiten hacerlo)
2. en el prompt DOS hacer: copy xbasic.rom+basic.rom ficherofinal.rom

y ya esta, una ROM de 32k en basic usando xbasic, con todas las posibilidades y velocidad de kun-basic.

¿ te sirve de ayuda ?

Par DarkSchneider

Paladin (942)

Portrait de DarkSchneider

14-03-2014, 23:04

Ese sería un 1er paso y permite usar comandos BASIC en el programa (como manejo de disco). Aunque ahora mismo me interesa más el siguiente paso, prescindir de BASIC. Cuando en XBASIC se ejecuta con CALL RUN, se compila todo el programa, por eso falla si detecta 1 línea que no compila. Pues bastaría saber donde va a parar ese compilado para capturarlo en una ROM, de forma que lo que nos queda es un ejecutable binario en toda regla, pero con la versatilidad en su desarrollo del XBASIC.

Voy a probar a rellenar de 0 el rango 8000h-(HIMEM-1) y luego cargar un programa y CALL RUN, y capturar ese rango en un fichero para ver si localizo donde se mete el programa.

Par DarkSchneider

Paladin (942)

Portrait de DarkSchneider

15-03-2014, 10:55

Vale traigo novedades:

1) El compilado se aloja JUSTO detrás del fuente en BASIC, esté donde esté. Incluso he probado a poner el inicio en C000h y se coloca detrás. Para quien quiera probarlo, que cargue un programa, ejecute CALL RUN, luego un BSAVE"",&h8000,&hffff y que lo abra con un editor hexadecimal. Una forma sencilla de buscar es:
- Añadiendo al final del programa BASIC un REM finaldeprograma y buscar por eso en el editor Hex.
- Buscando por la cadena hexadecimal 00 00 00 3E, por lo que he visto así es como SIEMPRE empieza el compilado XBASIC.

Una cosa que no había pensado es que no podemos ahora pillar ese código y ponerlo en 4000h + cabecera, porque entonces a la 1ª operación de salto puf. Entonces, el método puede ser algo como:
- CALL RUN. BSAVE.
- Localizar en un editor Hex donde queda el compilado. Hay que acordarse de quitar lo que añade el BSAVE al principio. Y si no lo hacemos de todo el rango (0h-ffffh) pues añadir lo oportuno.
- En la cabecera de la ROM, poner el INIT a la dirección donde empieza el compilado.
- Rellenar la parte del código BASIC con datos por ejemplo. Si hacemos esto recordar antes a modificar de donde leemos esos datos en el fuente y volver a ejecutar CALL RUN, antes de pisar el código BASIC con datos.
- La página 4000h-7FFFh rellenarla con datos.

Por lo tanto lo único que pasa es que nuestro código empezará en una dirección "rara", pero vamos nada grave.

@Josb, he estado pensando en eso de pegar las ROMs, y mira es útil para programas que usen el disco al tener disponibles los comandos, y podemos quitarnos el intérprete para usar esa página simplemente:
...
CALL TURBO ON
SET PAGE 1 SLOT CARTUCHO
...
SET PAGE 1 SLOT 0
CALL TURBO OFF
...
Es decir cuando entramos en un bloque compilado cambiamos la página 1 (4000h-7FFFh) al cartucho y antes de volver al BASIC lo retornamos al intérprete.

Hay una duda que sigo teniendo, para poner la ROM en el rango 4000h-BFFFh, ¿se puede con un editor Hex o hay que hacerlo por narices con un BSAVE desde el propio MSX?.

Par Guillian

Prophet (3476)

Portrait de Guillian

15-03-2014, 14:47

Me temo que no vas a poder hacer lo que quieres. No creo que el Basic Kun genere código en ensamblador autosuficiente. Casi con total seguridad hará uso de la BIOS y de la propia ROM del Basic Kun.
Además, si las variables las guarda en la zona #8000-#BFFF no funcionará a no ser que copies el programa de ROM a RAM.
Y el programa ensablado en una determinada dirección no es reubicable. Es decir, si el Basic Kun genera el código detrás del programa Basic, no puedes cargarlo en otra dirección que no sea esa.

Par DarkSchneider

Paladin (942)

Portrait de DarkSchneider

15-03-2014, 15:20

Pues empieza a tener toda la pinta la verdad. Incluso el programa más simple no se ejecuta directamente. De la BIOS no es problema porque la página 0 no la toco, en principio si pongo una ROM de 16-32KB no habría que cambiar de slot la página 0 si no me equivoco, ¿es así?.

Así que el problema, de darse lo anterior, seguramente sea por eso que mencionas @Guillian. Entonces probaré a hacer lo que dice @Josb, sería pegar el Basic Kun + programa BASIC en una sola ROM. Ya sería cuestión de ir probando porque si el compilado se quiere generar sí o sí detrás del código BASIC por narices, pues habría que hacer conicidir el último carácter de código en BFFFh, y así el compilado se generaría en C000h que ya es RAM y si puede. Igual se compila en la 1ª posición de RAM libre, quien sabe, así aunque tengas el fuente BASIC en 8000h + cabecera se compila bien.

Entonces, resumiendo, pegar ambas ROM, usar el sistema de pasar BASIC a ROM, y poner un CALL TURBO ON en la 1ª línea.

Lo que no tengo tan claro es qué hacer con la paginación, en trozos de BASIC se necesita la página 1 (4000h-7FFFh) en el slot 0 (de sistema), e imagino que cuando se pasa a sección TURBO se cambia por el Basic Kun automáticamente. Entonces parece que la página 1 no puede usarse en ningún momento salvo en subrutinas CM, siempre y cuando se cambie de slot dentro de la misma rutina y luego se vuelva a cambiar antes del RET.
Aunque de ser así tampoco hay mucho problema, porque precisamente por ejemplo para actualizar con los datos de una pantalla se hace con una subrutina CM para copiar dicha pantalla en VRAM, para lo cual la página 1 ya no se necesita ni BASIC ni XBASIC.

Par DarkSchneider

Paladin (942)

Portrait de DarkSchneider

15-03-2014, 16:54

Se me olvidó mencionar, esto usando un mapper claro, si no la página 1 de la ROM ya estaría ocupada por el Basic Kun, pero con el mapeador al ejecutar CM pues cambias el banco de la 4000h a una que tenga datos, y al terminar vuelves a restaurar el banco con el Basic Kun.

Par DarkSchneider

Paladin (942)

Portrait de DarkSchneider

15-03-2014, 20:13

Resuelta la duda, el compilador Basic Kun busca por la 1ª dirección de RAM escribible. Vamos que dejando el código BASIC a partir de la dirección 8021h (siguiendo el tutorial de BASIC a ROM), el compilado se ha generado en C000h.

Y además va perfecto el método de @Josb, poniendo una 1ª línea CALL TURBO ON y pegando las ROMS va de lujo, se ejecuta a velocidad de compilado.

Entonces este método la única pega que tiene es la de "desperdiciar" memoria de la ROM, 16KB del Basic Kun + fuente en BASIC, y parte de RAM, donde se alojará el compilado. Pero cuando se quieren hacer cosas en alto nivel pues es lo que hay. Total el precio de las ROM creo que ya no va tan alto Wink

Ahora tendré que liarme a ver como va el tema donde alojar los datos, ya sea en una ROM de 64KB o de 128KB.