Agon Light y otras revisiones de la plataforma Agon se basan en el procesador Zilog eZ80. El eZ80 tiene un espacio de direcciones de 24 bits que admite 16 megabytes de memoria, en comparación con los 64 kilobytes del Z80 original. El eZ80 tiene dos modos de funcionamiento: el modo estándar Z80, que tiene registros de 16 bits que facilitan el acceso a 64 k de memoria, pero requiere el uso de "banca" para acceder a más de 64 k de memoria; y el modo de operación ADL (datos de dirección largos), que extiende los registros a 24 bits, haciendo que todo el espacio de direcciones sea fácilmente accesible.
Cuando consideramos lenguajes de programación de alto nivel, hay varios disponibles para el Z80, pero están limitados a 64k de memoria o tienen métodos incómodos de cambio de banco para acceder a mayor memoria.
Teniendo en cuenta los lenguajes de programación C, hay varios compiladores C Z80 disponibles. Hasta la fecha, la comunidad Agon se ha centrado en dos:
Entorno de desarrollo Zilog ZDS II que puede producir código ADL eZ80. Este fue el conjunto original de herramientas utilizado por los desarrolladores de Agon, pero es de código cerrado, se ejecuta solo en Windows y solo admite el estándar de datos C89.
SDCC (compilador C de dispositivos pequeños) , una opción popular para computadoras de 8 bits, y adaptarlo para Agon ha sido el foco de varias personas en la computadora Agon. Este es un buen compilador para Z80, pero solo admite Z80 y no el modo ADL.
Como alternativa, la cadena de herramientas CEdev C/C++ es un compilador de código abierto que puede producir código ADL. Está dirigido a la calculadora TI-84 Plus CE (basada en el procesador eZ80) y tiene una red de tamaño razonable. CEdev se basa en las versiones eZ80 del compilador LLVM y del ensamblador fasmg. Produce código ADL con punteros de 24 bits, enteros de 24 bits, largos de 32 bits, cortos de 16 bits y flotantes de 32 bits. También hay una biblioteca bastante extensa para programas C y C++ (aunque no es compatible con ISO... todavía).
AgDev es el resultado de un esfuerzo por modificar CEdev para adaptarlo al conjunto de funciones y al diseño de hardware de la plataforma Agon. El resultado es una cadena de herramientas más potente y compatible con C++, en comparación con otras opciones de Agon.
Descargue usted mismo una versión de lanzamiento o una versión desde el código fuente. Coloque la compilación en un directorio de su elección.
Luego, asegúrese de que la carpeta /bin
se pueda encontrar en PATH
; Si estás en Windows, sigue esta guía o puedes ejecutar cedev.bat y ejecutar comandos desde allí. En Linux, ejecute export PATH=/<insert path here>/bin:$PATH
en una ventana de terminal.
Esto sigue el mismo enfoque que la cadena de herramientas CE original (consulte la parte inferior de la página de inicio de CEdev). El proceso de compilación se modificó para detenerse en la generación del archivo .bin
. Este es el ejecutable de Agon Light.
Recomiendo usar:
hacer limpio hacer V=1
El comando make clean
se puede utilizar para eliminar los resultados de compilaciones anteriores y así forzar una recompilación.
El proceso de construcción pasa por los siguientes pasos:
Compilación de archivos fuente .c en código de bits LLVM (.bc) usando ez80-clang
Vinculación de código de bits LLVM mediante ez80-link
. Esto incluye optimización del tiempo de enlace.
Generación de código ensamblador eZ80 (.src) para los programas fuente usando ez80-clang
Ensamblaje y vinculación del código ensamblador generado (del paso 3) con las bibliotecas y el tiempo de ejecución del compilador mediante fasmg
; esto incluye la creación del ejecutable destinado a una ubicación de memoria específica. Esta es la parte principal del proceso de construcción que debe ajustarse.
Consulte la nota de aplicación de Zilog "Llamar a C desde asm.pdf".
Las funciones llamadas solo deben conservar el registro y la pila IX.
Los argumentos se desplazan del último al primero correspondiente al prototipo C. En eZ80, siempre se envían 3 bytes a la pila, independientemente del tamaño real. Sin embargo, la función ensambladora debe tener cuidado de utilizar solo los bytes válidos que se envían. Por ejemplo, si se utiliza un tipo corto , el byte superior del valor insertado en la pila contendrá datos arbitrarios. Esta tabla enumera las ubicaciones relativas a sp desde dentro de la función llamada. Tenga en cuenta que sp + [0,2]
contiene la dirección del remitente.
Tipo C/C++ | Tamaño | Ubicación de la pila |
---|---|---|
carbonizarse | 1 byte | sp + [3] |
corto | 2 bytes | sp + [3,4] |
entero | 3 bytes | sp + [3,5] |
largo | 4 bytes | sp + [3,6] |
largo, largo | 8 bytes | sp + [3,10] |
flotar | 4 bytes | sp + [3,6] |
doble | 4 bytes | sp + [3,6] |
puntero | 3 bytes | sp + [3,5] |
Tenga en cuenta que eZ80 es little endian, es decir, el byte menos significativo se almacena primero.
Esta tabla enumera qué registros se utilizan para los valores de retorno de una función. El signo del tipo no afecta los registros utilizados, pero puede afectar el valor devuelto. El LSB está ubicado en el registro en el extremo derecho de la expresión; por ejemplo, E:UHL
indica que el registro L
almacena el LSB.
Tipo C/C++ | Volver Registrarse |
---|---|
carbonizarse | A |
corto | HL |
entero | UHL |
largo | E:UHL |
largo, largo | BC:UDE:UHL |
flotar | E:UHL |
doble | E:UHL |
puntero | UHL |
¡No cumple con ISO!
Consta de lo siguiente:
Archivo E/S:
fopen()
, freopen(),
fclose()
fputc()
, fputs()
fgetc()
, ungetc()
, fgets()
feof()
, ferror()
, fflush()
fread()
, fwrite()
fseek()
, rewind()
, ftell()
clearerr()
remove()
Entrada estándar/salida estándar:
putchar()
, puts()
getchar()
, gets_s()
Salida formateada
printf()
(y vprintf()
)
sprintf()
(y vsprintf()
)
snprintf()
(y vsnprintf()
)
Entrada formateada
scanf()
sscanf()
Hay algunas otras cosas aquí, como stdint
y demás, pero en su mayoría deberían coincidir con las expectativas de la biblioteca estándar normal. Principalmente.
stdio
Puede redirigir la salida usando freopen()
en stdout
o stderr
:
putchar()
- sale a outchar()
a menos que la salida sea redirigida, en cuyo caso sale a fputc()
puts()
- llama putchar()
printf()
(y vprintf()
): llama npf_putc_std()
, que llama putchar()
en nanoprintf.c
fputc()
- llama mos_fputc()
a menos que se llame en stdout
cuando llama outchar()
- evita llamar putchar()
para que no haya riesgo de bucles de llamadas a funciones
Puede redirigir la entrada usando freopen()
en stdin
:
getchar()
- llama inchar()
para obtener el carácter y outchar()
para repetir el carácter (incluso si la salida ha sido redirigida). Si la salida no ha sido redirigida, llama fgetc()
y no repite el carácter.
gets_s()
- llama getchar()
si la entrada no ha sido redirigida (las líneas terminan con CR). Las llamadas fgets()
de entrada han sido redirigidas (las líneas terminan con el par CR/LF).
scanf()
- llama getchar()
en uscan.c
(no necesita actualización)
fgetc()
- llama mos_fgetc()
a menos que se llame en stdin cuando llama inchar()
y hace eco con outchar()
- evita llamar getchar()
para que no haya riesgo de bucles de llamadas a funciones
Requiere FILE *
, que es un puntero a un identificador de archivo devuelto por fopen
y pasado a las rutinas IO del archivo para indicar el archivo sobre el que se realizará la acción.
Otros archivos relacionados:
stdio.h
: archivos de encabezado normales, que definen las diversas funciones y la definición de tipo para FILE
files.c
: crea una instancia del almacenamiento para identificadores de archivos, incluidos: stdout, stderr, stdin.
Se definen los siguientes identificadores de archivos estándar:
salida stdout
: salida predeterminada
stderr
: salida predeterminada para mensaje de error
stdin
- entrada predeterminada
MOS no implementa la redirección de entrada/salida, por lo que de forma predeterminada todos usan la consola.
Hay dos opciones disponibles para el procesamiento de la línea de comandos.
Esto se incluye automáticamente si la función principal se define como
int principal(int argc, char* argv[])
Divide la línea de comandos usando el espacio como delimitador. Las opciones de la línea de comando están disponibles en la matriz argv[]
como de costumbre.
Esto se incluye opcionalmente si el archivo MAKE de la aplicación incluye:
LDHAS_ARG_PROCESSING = 1
Esto apoya
Citando con comillas dobles
Redirección de entrada/salida
>out_file.txt
: redirige la salida estándar a out_file.txt
, creando un nuevo archivo
>>out_file.txt
: redirige la salida estándar a out_file.txt
, agregándolo al final del archivo
<in_file.txt
: redirige la entrada estándar para que sea desde in_file.txt
Para obtener documentación actual sobre los comandos MOS, consulte la documentación de Agon Console8.
El MOS (sistema operativo de la máquina) proporciona una interfaz para el sistema de archivos Agon y algunos periféricos de hardware, como el mouse. Mantiene información sobre las variables del sistema en una estructura SYSVAR
grande a la que se puede acceder desde el lado Z80. Generalmente su código C declarará un puntero a esta estructura, inicializado así:
estático volátil SYSVAR* sv; sv=vdp_vdu_init();
Para obtener más información, consulte <mos_api.h>
.
Para obtener documentación actual sobre los comandos de VDU, consulte la documentación de Agon Console8.
El VDP (procesador de visualización de vídeo) acepta un flujo de texto de MOS, actuando como un terminal de texto/gráficos. La secuencia de texto puede contener:
Texto normal
Secuencias de escape/comandos para controlar la pantalla y enviar comandos de gráficos/sonido/etc.
Cuando MOS devuelve resultados como resultado del envío de un comando, estos se almacenan en SYSVAR
y no se devuelven directamente en respuesta al comando. La respuesta es asincrónica: para comprobar que se ha devuelto un resultado:
Establezca vdp_pflags
en SYSVAR
en cero
Emitir el comando VDU
Espere a que se establezca el bit correspondiente en vdp_pflags
; consulte <mos_api.h>
para ver las máscaras de bits
Los comandos pueden ser enviados por:
putch()
- carácter único (esto no forma parte de la biblioteca estándar de C)
mos_puts()
- cadena de varios caracteres
Ambos salen directamente a MOS/VDP; tenga en cuenta que no forman parte de la biblioteca STDIO y no están sujetos a traducción o redirección CR/LF.
AgDev proporciona funciones prácticas para muchos comandos de la VDU. Por ejemplo, para cambiar el MODO de la pantalla a 3, C llama a vdp_mode(3);
enviará 22,3
como bytes individuales a la salida, equivalente a putch(22); putch(3);
Para obtener una lista de estas funciones, consulte <vdp_vdu.h>
. Las funciones adicionales relacionadas con el manejo del teclado se encuentran en <vdp_key.h>
.