Manual de programación del ZX Spectrum para (muy) torpes

(http://moebiuspuck.wordpress.com)




CAPÍTULO 3: MAX2: Fabricándonos un escritorio desde BASIC (parte I).

Esta es la tercera parte del "Manual de programación del ZX Spectrum para (muy) torpes", creado por +3Code, y en ella, como ya hiciéramos en la primera, llenaremos un vacío existente en el mercado de software para +3: un interface gráfico de usuario (o GUI) tipo escritorio en toda regla, pero sin complicarnos mucho la vida, por favor.

Lo cierto es que no se trata de un proyecto nuevo, y ya veía trabajando en algo desde hace un tiempo, como se puede ver en las dos imágenes de la derecha, pero aprovecharé este capítulo para "pasarlo a limpio", mostrando su desarrollo desde cero. Vaya por delante que, obviamente, tenemos que conectar un ratón al Spectrum. Manejar un cursor gráfico con O-P-Q-A y similares, como poder se puede, pero vamos, que no...

Así, vamos a listar por una parte lo requerido a nivel de hardware:
- ZX Spectrum +3
+ ROMs +3e* (ver nota al final del capítulo)
+ Interface Kempston Mouse
+ Kempston Mouse

Por otra parte, a nivel de software, vamos a necesitar:
+ un "driver" para trabajar con el Kempston Mouse desde BASIC
+ un "fondo de escritorio", que será una imagen SCREEN$
+ los iconos
+ un poco de código BASIC, que iremos viendo en qué consiste

Con respecto al "driver", la cosa es rápida y podemos encontrar uno estupendo (Chris Cowley, 2003) en las páginas de Velesoft, con lo que ya tenemos algo de código, que vamos a distribuir por lo que será la extensión final del programa:

  10 CLEAR 59999
  20 REM

  30 REM
  40 LOAD "mouse.drv" CODE 60000
  50
REM
 100 REM

 150 REM
 200 REM
 250 REM
 280 GOSUB 9900
 300 REM
 350 REM
 400 REM
 450 REM
 500 REM
 550 REM
 560 STOP
9900 LET btn=USR 60000
9910 LET x=PEEK 60827
9920 LET y=PEEK 60828
9930 RETURN


Como podemos ver al testear el programa-demo que viene, cada vez que hacemos un GOSUB 9900 se ejecuta el binario "mouse.drv" y pasa el control al mismo, permitiendo manejar el ratón en pantalla. Al pulsar un botón del ratón, devuelve el control al programa BASIC, retornando también tres variables: btn (botón 1 o 2) y coordenadas X e Y del puntero del ratón.

Para los iconos inicialmente pensé emplear GDU y, opcionalmente, el Paint Plus. Sin embargo existe una mejor propuesta, y es el IZX de Andrew Owen y Einar Saukas (2013), un conjunto de iconos ya predefinidos y con una rutina CM que facilita su uso desde BASIC. Al fusionar ambas cosas (ojo, que hay que cambiar el CLEAR), el programa se nos va quedando así:

  10 CLEAR 54999
  20 REM
  30 REM
  40 LOAD "mouse.drv" CODE 60000
 
50 LOAD "izx.drv" CODE 55000
  60 REM                           | r= linea
 
70 DEF FN z(r,c,i)=USR 55000
     | c= columna
  80 REM                           | i= icono
  90 REM                           |
 100 FLASH FN z(0,0,9)             | Icono para el disco A
 110 FLASH FN z(0,28,10)           | Icono para "System"
 120 FLASH FN z(5,0,9)             | Icono para el disco B
 
130 FLASH FN z(19,28,24)          | Icono para la papelera
 
140 FLASH FN z(19,0,22)           | Icono para "Exit"
 150 REM
 200 REM
 250 REM
 
280 GOSUB 9900
 300 REM
 350 REM
 400 REM
 450 REM
 500 REM
 550 REM
 560 STOP
9900 LET btn=USR 60000
9910 LET x=PEEK 60827
9920 LET y=PEEK 60828
9930 RETURN


Sobre la manera en la que he usado el IZX, hay un par de detalles a comentar. En el programa-demo que hay en la cara A de la cinta IZX.tap.zip encontramos un programa BASIC, el binario del IZX (archivo "IZXdriver", se carga en la dirección 55000, mide 119 bytes) y un fichero con los iconos (archivo "IZX icons", se carga en la dirección 55200, mide 1025 bytes). Dado que el sistema de disco emplea 1K como mínimo para cada fichero, resulta mejor empaquetar ambos y copiar ese bloque de memoria, desde 55000 hasta 56225, en un solo fichero de 1225 bytes, que es lo que yo he hecho, produciendo el archivo "izx.drv" que carga en la dirección 55000.

Con respecto a la impresión de texto en pantalla, después de examinar muchas rutinas, vamos usar el Micro-PRINT 85, una rutina creada en 1984 por la casa británica Myrmidon Software, que nos va a permitir trabajar con 6 modos de texto (32, 36, 42, 51, 64 y 80 caracteres por linea). Al añadir esta rutina, el programa se nos queda así:

  10 CLEAR 54999
  20 REM
  30 REM
  40 LOAD "mouse.drv" CODE 60000
 
50 LOAD "izx.drv" CODE 55000
  60 LOAD "mprint85.bin" CODE 64268
  70 DEF FN z(r,c,i)=USR 55000
  80 REM
 
90 REM
 100 FLASH FN z(0,0,9)
 110 FLASH FN z(0,28,10)
 120 FLASH FN z(5,0,9)
 130 FLASH FN z(19,28,24)
 140 FLASH FN z(19,0,22)
 15
0 LET li=4: LET bt=56    | li= linea
 
160 LET no=51: LET co=0
    | bt= atributos
 170 LET p$="Disk A"        | no= número de caracteres por linea (36,42,51,64,80)
 180 RANDOMIZE USR 64564    | co= columna
 190 LET li=4: LET co=45    | p$= texto a imprimir
 200 LET p$="System"        | RANDOMIZE USR 64564 = llama a la rutina de impresión
 210 RANDOMIZE USR 64564
 220 LET li=9: LET co=0
 230 LET p$="Disk B"
 240 RANDOMIZE USR 64564
 250 LET li=23: LET co=0
 260 LET p$=" Exit "
 270 RANDOMIZE USR 64564
 280 GOSUB 9900
 300 REM

 350 REM
 400 REM
 450 REM
 500 REM
 550 REM
 560 STOP
9900 LET btn=USR 60000
9910 LET x=PEEK 60827
9920 LET y=PEEK 60828
9930 RETURN


A todo esto ya solo falta añadirle un par de cosas. Hay también una observación sobre el uso que hago de la rutina Micro-PRINT 85: aunque funciona perfectamente en el +3, el código fue creado en el 48K, en el que se podía escribir LET at=x, siendo "at" una de las variables que tenemos que emplear para controlar el programa desde BASIC. El editor de +3BASIC no permite usar "at" como nombre de variable, al ser una palabra reservada. Así, he tenido que retocar el código, renombrando a la variable como "bt", tras lo que podemos emplear la rutina cómodamente en nuestros programas del +3.

Cosas que añadimos: el "fondo de escritorio", que lo sacamos de http://zxart.ee, en concreto usaré esta pantalla, obra de Evgenij Kolesnikov (aka "Buddy") de 2015. Es en blanco y negro, y de hecho vamos a mantener casi todo el GUI en blanco y negro, en tanto nos facilita algunas cosas. También, antes de dar por terminada esta primera versión "demo" (en la parte II propongo ampliaciones de este sistema básico), añadiré dos ejemplos de posible presentación de "ventanas" estáticas, siendo ésta la versión final y definitiva del programa en esta primera parte:

Listado
  10 CLEAR 54999
  20 INK 7: PRINT PAPER 0;"MAX2"+CHR$(13)+
  CHR$(13); BRIGHT 1; FLASH 1;" @"; INVERSE 1
  ;" @"

  30 COPY "system.bin" TO "m:system.bin"
  40 LOAD "mouse.drv" CODE 60000
 
50 LOAD "izx.drv" CODE 55000
  60 LOAD "mprint85.bin" CODE 64268
  70 DEF FN z(r,c,i)=USR 55000
  80 BORDER 7: PAPER 7: BRIGHT 0: INK 0: CLS
 
90 LOAD "img.scr" SCREEN$
 100 FLASH FN z(0,0,9)
 110 FLASH FN z(0,28,10)
 120 FLASH FN z(5,0,9)
 130 FLASH FN z(19,28,24)
 140 FLASH FN z(19,0,22)
 15
0 LET li=4: LET bt=56
 160 LET no=51: LET co=0
 170 LET p$="Disk A"
 180 RANDOMIZE USR 64564
 190 LET li=4: LET co=45
 200 LET p$="System"
 210 RANDOMIZE USR 64564
 220 LET li=9: LET co=0
 230 LET p$="Disk B"
 240 RANDOMIZE USR 64564
 250 LET li=23: LET co=0
 260 LET p$=" Exit "
 270 RANDOMIZE USR 64564
 280 GOSUB 9900
 290 IF x>230 AND x<250 AND y>5 AND y<35 THEN
  GO TO 490

 300 IF x>230 AND x<250 AND y>150 AND y<180
  THEN GO TO 330
 310 IF x>5 AND x<25 AND y>150 AND y<180 THEN
  STOP
 320 GOTO 280
 330 SAVE "m:max.dsk" CODE 18432,2048
 340 FOR x=8 TO 15
 350 PRINT AT x,1; BRIGHT 0; PAPER 7;,,: NEXT
  x

 360 PRINT AT 9,1; BRIGHT 1; PAPER 4; INK 2;
  " "; PAPER 5; INK 6;" "; PAPER 0; INK 7;" Sy
  s tem "

 370 PLOT BRIGHT 0; INK 7;87,103
 380 FOR x=10 TO 14
 390 PRINT AT x,3; BRIGHT 1; PAPER
  7;,"               "

 400 NEXT x
 410 PLOT 24,95: DRAW -17,0: DRAW 0,9: DRAW 17,0
 420 PLOT 88,96: DRAW 158,0: DRAW 2,-2: DRAW 0,
  -37: DRAW -2,-2: DRAW -221,0: DRAW -2,2: DRAW 0,37

 430 PRINT AT 11,7; BRIGHT 1; PAPER 1; INK 6;"MAX2"
  ; AT 13,7;"Demo Version 1"

 440 GO SUB 9900
 450 FOR x=8 TO 15
 460 PRINT AT x,0; BRIGHT 0; PAPER 7;,,: NEXT x
 470 LOAD "m:max.dsk" CODE 18432
 480 GO TO 280
 490 SAVE "m:max.dsk" SCREEN$
 500 LOAD "m:system.bin" CODE 57064
 510 LET a=57064
 520 PRINT AT 11,3;"Copyrights"; AT 12,4; INK 2;"- K.
  Mouse Driver: (2003)"; AT 13,5;"Chris Cowley"; AT 14,
  4;"- IZX. (2013)"; AT 15,5;"Andrew Owen, Einar Saukas"
  ; AT 16,4;"- Micro-PRINT 85: (1984)"; AT 17,5;"Myrmidon
  Software"; AT 18,4;"- Screen: (2015)"; AT 19,5;"Evgenij
  Kolesnikov"

 530 GOSUB 9900
 540 LOAD "m:max.dsk" SCREEN$
 550 GO TO 280
 560 STOP

9900 LET btn=USR 60000
9910 LET x=PEEK 60827
9920 LET y=PEEK 60828
9930 RETURN


Comentando un poco el código añadido, las líneas 290, 300 y 310 marcan los tres iconos que de momento activaremos ("System", "Exit" y la papelera, los iconos de acceso a los discos de momento no son funcionales). Las líneas 340 y 350 pueden ser eliminadas sin  problemas (de hecho queda mejor), solo se han incluido para ilustrar el sistema de grabación/carga de tercios de pantalla (líneas 330 y 470); como se recordará, la imagen que se ve en la pantalla está en la memoria RAM a partir de la dirección 16384. Cada tercio de pantalla ocupa 2048 bytes (en total 6144) y después de los tres, a partir de 22528, hay 768 bytes más con los atributos (color, brillo, etc) de la pantalla. En total 6912 bytes. Cada una de estas franjas puede ser salvada y cargada como imagen SCREEN$ de manera independiente (sin los atributos), al estar situadas una detrás de otra en memoria. Esto lo podemos hacer sencillamente con:

- Parte superior. SAVE "nombre" CODE 16384, 2048
- Parte central. SAVE "nombre" CODE 18432, 2048
- Parte inferior. SAVE "nombre" CODE 20480, 2048

Cada una de estas sub-pantallas de 2K puede ser cargada empleando LOAD "nombre" CODE o LOAD "nombre" SCREEN$, para sus posiciones originales. También podemos forzarlas a otra posición en la pantalla a través de LOAD "" CODE posición. Lo que se carga en la línea 500 (el fichero "system.bin") es un programa compilado con Hisoft BASIC para +3, que en su versión no compilada (el fichero "system.bas"), es lo siguiente:

-------------------------------------------------------
  10 REM : OPEN 
#
  20 BRIGHT 1
  30 FOR x=3 TO 20
  40 PRINT AT x,2;"                             "
  50 NEXT x
  60 PLOT BRIGHT 0;24,160: DRAW BRIGHT 0;-17,0:
DRAW BRIGHT 0;0,-8: PLOT BRIGHT 0;7,151: DRAW
BRIGHT 0;9,0: DRAW BRIGHT 1;8,0
  70 PRINT AT 2,1; INK 2; PAPER 4;" "; INK 6;
PAPER 5;" "; AT 2,3; INK 7; PAPER 0; " System"
  80 PLOT OVER 1; BRIGHT 0; PAPER 0; INK 7;87,159
  90 PLOT BRIGHT 0;88,152: DRAW BRIGHT 0;158,0
 100 PLOT BRIGHT 1;247,151
 110 PLOT BRIGHT 0;248,150: DRAW BRIGHT 0;0,-141
 120 PLOT BRIGHT 1;247,8
 130 PLOT BRIGHT 0;246,7: DRAW BRIGHT 0;-229,0
 140 PLOT BRIGHT 1;16,8
 150 PLOT BRIGHT 0;15,9: DRAW BRIGHT 0;0,141
 160 PRINT AT 4,4;"System Vars.:"
 170 LET n=23635
 180 LET m= PEEK n+256* PEEK (n+1)
 190 PRINT AT 6,3;"-PROG:";m
 200 LET n=23627
 210 LET m= PEEK n+256* PEEK (n+1)
 220 PRINT AT 7,3;"-VARS:";m
 230 LET n=23653
 240 LET m= PEEK n+256* PEEK (n+1)
 250 PRINT AT 8,3;"-STKEND:";m
 260 LET n=23730
 270 LET m= PEEK n+256* PEEK (n+1)
 280 PRINT AT 6,3;"-RAMTOP:";m
 290 PRINT AT 4,22; PAPER 6; INK 5;"  MAX2  ";
AT 5,22; BRIGHT 0; INVERSE 1; INK 1;"Demo v.1"
 300 PRINT AT 7,17;"Free Mem.:"; INT ((65535-
USR 7962)/1024);"K"
 310 LET n=23642
 320 PRINT AT 8,17;"P. Mem.:";( PEEK n*256+ PEEK
(n-1))-( PEEK (n-6)*256+ PEEK (n-7));"B"
 330 PLOT 176,144: DRAW 63,0: DRAW 1,-1: DRAW 0,-15:
DRAW -1,-1: DRAW -63,0: DRAW -1,1: DRAW 0,15: DRAW 1,1
 340 PLOT 104,82: DRAW 139,0: DRAW 2,-2: DRAW 0,-68:
DRAW -2,-2: DRAW -223,0: DRAW -2,2: DRAW 0,68: DRAW 2,2:
DRAW 2,0
 350 PLOT 131,126: DRAW 0,-30
 360 REM : CLOSE #
-------------------------------------------------------

Este segundo programa, muy mejorable, crea una ventana con información básica del sistema. Podemos comparar la velocidad de presentación de esta "ventana" con una realizada en BASIC interpretado (líneas 330 a 480). Más adelante (en la parte II), veremos cómo aprovechar más el compilador Hisoft BASIC.

A continuación, podemos contemplar algunas pantallas de esta primera demo del escritorio MAX2:

Carga del MAX2    Escritorio MAX2

Información    Ventana desde BASIC

El archivo que contiene el programa y todos los ficheros necesarios es el siguiente:

FILE_INFO:
 Name: Size:
Description:


 
CAT
  1. DISK


  2. IMG.SCR


  3. IZX.DRV


  4. LEEME.TXT


  5. MAX2.BAS


  6. MOUSE.DRV


  7. MPRINT85.BIN


  8. SYSTEM.BAS


  9. SYSTEM.BIN


  •  1K
    (16Bytes)

  •  7K
    (6912Bytes)

  •  2K
    (1225Bytes)

  •  1K
    (256Bytes)

  •  3K
    (2491Bytes)

  •  1K
    (833Bytes)

  •  2K
    (1100Bytes)

  •  3K
    (1898Bytes)

  •  3K
    (2743Bytes)
  • Fichero BASIC. Auto- arranque (LINE 1)

  • Pantalla SCREEN$


  • Fichero binario. Dri-
    ver e iconos IZX

  • Fichero ASCII


  • Fichero BASIC. Auto- arranque (LINE 10)

  • Fichero binario. Con-
    trol del ratón Kemps-
    ton
  • Fichero binario. Ruti-
    na Micro-PRINT

  • Fichero BASIC. Para compilar con Hisoft BASIC
  • Fichero binario. Ver-
    sión compilada de "system.bas"

 MAX2.dsk


 leeme.txt

 
  191K


 4K

 Imagen de disco para
 emulador

 Fichero ASCII

 MAX2v1.dsk.zip

 
 14K


 Fichero comprimido

La memoria de la máquina por encima de la RAMTOP (en 54999) queda tras la carga del MAX2 como se puede ver en el gráfico a continuación:

Los programas considerados actualmente básicos del MAX2 son los marcados en rojo, mientras programas accesorios son los marcados en verde (en este caso, el fichero "system.bin").

El disco y el programa han sido probados en varios emuladores y en varias configuraciones (+3 y +3e, inglés y español) sin que aparentemente presenten problemas de carga o ejecución. Requiere que el emulador tenga soporte para ratón Kempston y que esta opción esté activada en la configuración.

Para visualizar el fichero "leeme.txt" del disco, lo más funcional es teclear desde el editor +3BASIC:

COPY "leeme.txt" TO SCREEN$

También puede ser leído en un editor de texto convencional o cargado en una variable, por ejemplo con:

LOAD "leeme.txt" DATA a$: PRINT a$

Todo el código fuente desarrollado y distribuido por +3Code puede ser utilizado libremente por otros usuarios para sus propios programas.



* Opcional. La versión inicial corre tanto en el +3 como en el +3e, en la versión que veremos en la parte II de este texto, tenía previsto requerir de algunas de las funcionalidades del +3e, aunque luego veremos que de momento no va a ser así.


ċ
MAX2v1.dsk.zip
(13k)
Rambo Petazeta,
10 sept. 2017 11:58
Comments