Bueno, pues esta es mi primera tontería con SCANNING

Código: Seleccionar todo
PRINT_FP equ 2de3h
SCANNING equ 24fbh
CHAN_OPEN equ 1601h
org 32768
Main proc
ld hl,(5c5dh) ;guardo CD_ADD
push hl ;en pila, para restaurarlo después
ld hl,Expresion
ld (5c5dh),hl ;apunto CH_ADD a mi expresión a evaluar
set 7,(iy+1) ;FLAGS en modo ejecución (evaluación)
call SCANNING
ld a,2
call CHAN_OPEN ;abrir canal S para imprimir
call PRINT_FP ;imprimimos el resultado
pop hl
ld (5c5dh),hl ;restauramos CH_ADD
ret
endp
Expresion db "16",14,0,0,16,0,0,"+16",14,0,0,16,0,0,13,128
end Main
La expresión tiene ya añadidos los números en notación de "coma flotante escondida" que usa el Spectrum, es decir, justo después de cada literal numérico se almacena el 14 (indicativo de "número") seguidos de los 5 bytes que codifican un número en el Spectrum, sea real o entero. En este caso, los números son enteros, lo que simplifica la codificación

Esto de añadir la versión "escondida" del número dentro de la expresión lo realiza automáticamente la rutina SCANNING cuando se ejecuta en modo "chequeo de sintaxis". Esto lo hace la ROM del Spectrum cuando tecleamos una línea de programa y pulsamos ENTER. Así, cuando esa línea se ejecuta, no hay que volver a generar el número en notación de coma flotante cada vez, sino que se coge la versión que dejó allí "preparada" el chequeador de sintaxis. De esto se encarga una parte de SCANNING, la rutina S-DECIMAL:
Código: Seleccionar todo
; This important routine is called during runtime and from LINE-SCAN
; when a BASIC line is checked for syntax. It is this routine that
; inserts, during syntax checking, the invisible floating point numbers
; after the numeric expression. During runtime it just picks these
; numbers up. It also handles BIN format numbers.
; ->
;; S-BIN
;; S-DECIMAL
Por tanto, para poder saltarnos la fase de chequeo de sintaxis, y dado que SCANNING necesita esa representación interna, la he añadido "a pelo" en la expresión, que pasa de ser 16+16 a ser 16(version interna de 16)+16(version interna de 16), es decir:
Código: Seleccionar todo
Expresion db "16",14,0,0,16,0,0,"+16",14,0,0,16,0,0,13,128
Y por último, uso el 13 y el 128 para indicar fin de expresión (creo que bastaría con uno de los dos).
SCANNING, como usa el calculador de la ROM, deja su resultado en lo alto del stack. Aquí estoy asumiendo que dicho resultado va a ser numérico (esto se comprueba con el bit 6 de FLAGS, que si es 1 significa que el resultado es numérico, y si es 0, es alfanumérico). Entonces, sólo me falta hacer algo con ese resultado, por ejemplo, imprimirlo con PRINT-FP.
Me queda cambiar el programa para que chequee sintaxis y evalue la expresión, así puedo codificar la expresión de la forma habitual: "16+16" por ejemplo. Miraré a ver cómo se ejecuta la función VAL, que tiene toda la pinta de ser lo que necesito

He intentado hacerlo tal cual, chequeando la sintaxis de la expresión, pero parece que la rutinilla que inserta el número "escondido" no funciona bien si la expresión está más allá de STKEND, ya que hace uso de MAKE-ROOM y otras, que sólo funcionan bien (eso parece) en zonas de memoria por debajo de STKEND.
Es por esto de la necesidad de chequear la sintaxis, que no convendría usar lo de "RAND USR 64000: REM sentencia nueva", ya que esa sentencia nueva tendría que ser chequeada en sintaxis y evaluada cada vez que se ejecutara, en lugar de sólo evaluarse.
NOTA: ¿será posible? ¿¿Pues no acabo de descubrir que las variables en BASIC pueden contener espacios??
Código: Seleccionar todo
; -----------------
; THE 'LET' COMMAND
; -----------------
; Sinclair BASIC adheres to the ANSI-78 standard and a LET is required in
; assignments e.g. LET a = 1 : LET h$ = "hat".
;
; Long names may contain spaces but not colour controls (when assigned).
; a substring can appear to the left of the equals sign.
Vamos, que un
LET esto es una variable = 4 funciona!! y el correspondiente
PRINT esto es una variable también funciona. Ahora acabo de comprobar que realmente esto se dice en el apéndice C del manual de BASIC, si bien lo que dice expresamente es que los espacios en blanco se ignoran cuando se crea la variable, o cuando se usa. O sea, que realmente
PRINT estoesunavariable también funciona. Curioso
