El archivo m6502.asm liberado por Microsoft en Github contiene el código ensamblador del intérprete BASIC de 8K. El código está diseñado para ser ensamblado condicionalmente para diferentes máquinas de la época (finales de los 70s).
1. Configuración y Portabilidad (Los "Switches")
Al principio del archivo (líneas 10-50), verás una serie de definiciones o "switches". Bill Gates y su equipo diseñaron esto para que el mismo código pudiera funcionar en múltiples ordenadores simplemente cambiando una variable.
- REALIO: Define la máquina destino.
- REALIO=4: Apple II (Apple BASIC).
- REALIO=3: Commodore (PET/CBM).
- REALIO=2: OSI (Ohio Scientific).
- REALIO=1: KIM-1 (MOS Technology).
- ROMSW: Define si el BASIC correrá desde una ROM (como en el Apple II o C64) o si se cargará en RAM.
- INTPRC / ADDPRC: Controlan la precisión matemática y el soporte para arrays de enteros.
2. Página Cero (Zero Page) - El "Corazón"
El procesador 6502 es más rápido accediendo a los primeros 256 bytes de memoria (Página 0). Microsoft BASIC utiliza intensivamente esta área para sus "registros" virtuales y punteros.
Ubicaciones críticas definidas en el código:
- TXTPTR: El puntero al texto. Indica qué carácter del código BASIC se está leyendo actualmente.
- FAC (Floating Accumulator): El "Acumulador Flotante". Como el 6502 solo tiene registros de 8 bits, el BASIC simula un registro de 32-40 bits aquí para hacer matemáticas (sumas, restas, senos, cosenos).
- VARTAB: Puntero al inicio de las variables simples en memoria.
- ARYTAB: Puntero al inicio de los arrays.
- STREND: Final del almacenamiento en uso.
3. Rutinas Clave y Conceptos
A. CHRGET (La rutina automodificable)
Ubicada cerca de la etiqueta RAM CODE o CHRGET.
Esta es quizás la rutina más famosa. Se copia desde la ROM a la RAM (Página Cero) al iniciar.
- Función: Lee el siguiente carácter del código BASIC, incrementa el puntero de texto (TXTPTR) y verifica si es un número o un comando.
- Truco: Usa código automodificable para velocidad. Modifica la dirección de memoria de la instrucción LDA directamente en lugar de usar punteros indirectos lentos.
B. CRUNCH (El Tokenizador)
Cuando escribes una línea como 10 PRINT "HOLA", el BASIC no guarda la palabra "PRINT".
- La rutina CRUNCH escanea la entrada.
- Compara las palabras con la lista RESLST (Reserved Word List).
- Si encuentra "PRINT", lo convierte en un solo byte (un token, con el bit alto encendido, ej. valor 153). Esto ahorra mucha memoria RAM.
C. NEWSTT (New Statement)
Es el despachador principal.
- Verifica si hay un ctrl-c (interrupción).
- Lee el siguiente token.
- Usa una tabla de saltos (STMDSP - Statement Dispatch) para ir a la subrutina correcta (ej: GOTO, LET, FOR, IF).
D. FRMEVL (Evaluador de Fórmulas)
Es el motor lógico. Implementa un algoritmo recursivo (tipo Shunting-yard) para evaluar expresiones matemáticas como A = B * (C + 1).
- Usa la pila (Stack) del 6502 para guardar precedencia de operadores.
- Llama a las rutinas matemáticas para operar sobre el FAC.
4. El Paquete Matemático (Math Pack)
El archivo contiene una sección enorme dedicada a matemáticas de punto flotante. El 6502 no tiene instrucciones de multiplicar o dividir, así que todo es software.
- Formato de Números (40-bit):
- 1 byte para el Exponente.
- 4 bytes para la Mantisa (la parte significativa).
- El bit de signo se guarda aparte o empaquetado.
- Rutinas:
- FADD: Suma flotante.
- FMULT: Multiplicación (realizada mediante sumas y desplazamientos de bits repetidos).
- LOG, SIN, COS: Usan polinomios de aproximación (series de Taylor/Chebyshev) definidos en tablas de constantes como SINCON o ATNCON.
5. Manejo de Memoria y "Garbage Collection"
El código maneja dinámicamente la memoria.
- Las variables se guardan después del código del programa.
- Los Strings (cadenas de texto) se guardan al final de la memoria (arriba) y crecen hacia abajo.
- GARBAGE COLLECTION (GARBA2): Cuando te quedas sin memoria para textos, esta rutina se activa. Es famosa por "congelar" los ordenadores antiguos durante segundos. Reorganiza todos los strings activos y borra los que ya no se usan para liberar espacio.
6. Curiosidades en el Código
Si buscas en el archivo, encontrarás créditos y mensajes de error clásicos:
- Error Messages (ERRTAB): "SYNTAX ERROR", "DIVISION BY ZERO".
- Huevo de Pascua (KIMROM): En la etiqueta AUTTXT, verás:
DT "WRITTEN BY WEILAND & GATES"
(Referencia a Ric Weiland y Bill Gates).
Resumen del Flujo de Ejecución
- Inicio (INIT): Determina cuánta RAM hay y configura los punteros.
- Bucle Principal (MAIN): Imprime "READY" (o "Ok").
- Input (INLIN): Espera que el usuario escriba algo.
- Tokenización (CRUNCH): Convierte texto a tokens.
- Ejecución (GONE / NEWSTT):
- Si tiene número de línea -> Lo guarda en memoria (LIST).
- Si no tiene número -> Lo ejecuta inmediatamente (RUN).