Bancos de memoria desde basic sin HIMEM

Programando el Amstrad en BASIC, C, etc.
Avatar de Usuario
NotFound
Me voy lanzando
Me voy lanzando
Mensajes: 36
Registrado: Mié 17 Ene , 2007 4:31 pm

Bancos de memoria desde basic sin HIMEM

Mensajepor NotFound » Mié 14 Jul , 2021 12:45 pm

Hola.

He estado pensando sobre el acceso a bancos de memoria desde Basic, sin recurrir a RSX externas ni a rutinas en código máquina.

Para ello hay que asegurarse de que la zona de paginación no interfiere con usos internos del Basic ni el propio programa y sus variables, y eso nornalmente se hace poniendo el HIMEM por debajo de &4000.

Pensando en ello, lo único que realmente hace falta es asegurarse de que los 16KB de memoria empezando en &4000 quedan libres de interferencias. Podemos hacer eso definiendo un array entero de dimensión 8191 (2 bytes por entero, y teniendo en cuenta que los índices van de 0 a n), si encontramos la forma de ubicar el array en la posición que queramos.

Tras algunas pruebas llegué a esto:

Código: Seleccionar todo

10 REM First define all non array variables
20 i% = 0
30 addr! = 0
40 d! = 0
50 REM Define the filler and page arrays
60 DIM filler%(0)
70 DIM a%(0)
80 REM Ensure the array content will start at even address
90 addr! = @a%(0)
100 IF a > &4000 THEN ERROR 7
110 IF (addr! AND 1) = 0 THEN GOTO 190
120 IF wasodd% THEN PRINT "Oddity!": END
130 ERASE a%
140 ERASE filler%
150 wasodd% = 1
160 DIM filler%(0)
170 DIM a%(0)
180 GOTO 90
190 REM Dimension the filler to position a% content at &4000
200 ERASE a%
210 ERASE filler%
220 DIM filler%((&4000 - addr!) / 2)
230 REM Dimension a% to use 16KB
240 DIM a%(16 * 512 - 1)
250 REM Verify a%
260 addr! = @a%(0)
270 IF UNT(addr!) <> &4000 THEN PRINT "Unexpected fail!" : END
Hay dos partes en el proceso: asegurarse de que partimos de una dirección par, y a partir de eso crear un array que rellene el espacio disponible para que el array usado para paginación empiece en &4000
También hay que asegurarse de que las direcciones no vayan a cambiar, definiendo previamente todas las variables no array que vayamos a usar. Y naturalmente el programa y todas sus variables no deben llegar a ocupar espacio por encima de &4000

Comprobemos que funciona: añadimos al bloque anterior esta parte, que dibuja algo en pantalla y lo copia al banco 4:

Código: Seleccionar todo

1000 REM Example: copy screen content to bank 1
1010 MODE 2
1020 MOVE 0, 0 : DRAW 640, 400
1030 MOVE 0, 0 : DRAW 640, 0
1040 MOVE 0, 0 : DRAW 0, 400
1050 MOVE 640, 0 : DRAW 0, 400
1060 MOVE 639, 400 : DRAW 639, 0
1070 MOVE 639, 399 : DRAW 0, 399
1080 REM Copy it
1090 OUT &7FC4, &C4
1100 FOR i% = 0 TO 16383
1110 POKE &4000 + i%, PEEK(&C000 + i%)
1120 POKE &C000 + i%, 0
1130 NEXT
1140 OUT &7FC0, &C0
1150 MODE 1
1160 REM Verify by reding it from other progran
1170 PRINT "Verifying..."
1180 RUN"memg
Y con este otro lo verificamos, añadiéndole también el bloque inicial y guardándolo como "memg":

Código: Seleccionar todo

1000 REM Copy the saved screen back to screen
1010 MODE 2
1020 LOCATE 1, 21 : PRINT "Verifying..."
1030 OUT &7FC4, &C4
1040 FOR i% = 0 TO &3FFF
1050 POKE &C000 + i%, PEEK(&4000 + i%)
1060 NEXT
1070 OUT &7FC0, &C0
Bueno, funciona. Pero la verdad es que no tengo claro si tiene alguna utilidad real o no pasa de curioso truco.
Salu2

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro


La Comunidad Española
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic