Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Avatar de Usuario
luiscoco
Mensajes: 2328
Registrado: 15 May 2011 04:23
Ubicación: Caracas, Venezuela
Agradecido : 30 veces
Agradecimiento recibido: 44 veces
Contactar:

Re: Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Mensajepor luiscoco » 19 Ago 2017 23:15

Último mensaje de la página anterior:

Eso es correcto, yo tengo un plan, más o menos, si me ayudan a discutirlo tal vez salga algo bueno
Hasta ahora probé un simple for y estoy decepcionado, tarda casi medio segundo cada print, jajaja
obviamente es el print analizado por el BASIC y luego usado, jaja solo era una prueba
no veo el print de "C"

Código: Seleccionar todo

#pragma options -machine=coco2b

#include <basic.h>
//#include <conio.h>

int main(void)
{
    int a;
    clrscr();
    for(a=1;a<10;a++){
        PRINT(0,"%i",a);PRINT(0,"%c",13);
    }
    a=INKEY();
    return 0;
}

Avatar de Usuario
luiscoco
Mensajes: 2328
Registrado: 15 May 2011 04:23
Ubicación: Caracas, Venezuela
Agradecido : 30 veces
Agradecimiento recibido: 44 veces
Contactar:

Re: Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Mensajepor luiscoco » 19 Ago 2017 23:27

pser1 escribió:Buenos días,
he encontrado un 'comodín' que permite llamar al intérprete de Basic y dejar que el resuelva las funciones. Patéticos resultados!
Tratad de compilar este programilla:

Código: Seleccionar todo

#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <graph.h>
#include <basic.h>

int main(void)
{
    PMODE(3,1);
    PCLS(1);
    SCREEN(1,0);
    COLOR(2,0);
    system("R=80");
    for (int i=0;i<10;i++) {
       system("R=R-5");
       system("CIRCLE(128,96),R");
    }
    return 0;
}

Ya me diréis si no es más rápido el Basic directamente -507
saludos
pere


Con respecto a tus círculos, en este ejemplo usamos trozos de líneas de basic, e incluso variables, como si estuviera activo (y lo está).
Lo mejor sería llamar directamente a la función, aunque no mejoraría mucho, ya que esa función es lenta en realizar su trabajo, no se que tan eficiente sea, creo haber visto, en los fuentes del extbasic que usa tablas de seno, aca hay que hablar con SIMON a ver que puede ir mejorando

En las funciones gráficas, lo que me gustaría es unificar los comandos para que ellos sirvan para todas las resoluciones, pero me tope con un problema, al parecer usan memorias independientes, eso quiere decir que puedes ha un círculos en una resolución y a la vez otro independiente en otra resolución.

Por cierto si usas #include <basic.h> ya no necesitas los demás.

Hasta ahora hemos podido usar el Basic desde "C", Usar los comandos y funciones del BASIC en ROM casi directo

Avatar de Usuario
Chema
Mensajes: 1514
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 407 veces
Agradecimiento recibido: 180 veces
Contactar:

Re: Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Mensajepor Chema » 19 Ago 2017 23:35

Los compiladores de C para estas máquinas suelen ser cómodos, no eficientes en el código que generan.

Los que hay para 6502 son horribles en general generando código como 5 veces más largo y lento. Y a veces peor que eso.

Son útiles para prototipos o pruebas de concepto, pero las rutinas interesantes tienen que ser escritas en asm.

Por cierto, para imprimir en C se usa printf (definida en stdio.h) que suele ser un monstruo. Si es para imprimir cadenas mejor puts y para caracteres putchar.

Avatar de Usuario
luiscoco
Mensajes: 2328
Registrado: 15 May 2011 04:23
Ubicación: Caracas, Venezuela
Agradecido : 30 veces
Agradecimiento recibido: 44 veces
Contactar:

Re: Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Mensajepor luiscoco » 19 Ago 2017 23:47

Use tu ejemplo para probar MCIRCLE y parece más rápido, dibujan diferente, MCIRCLE tambien empieza abajo y las zonas planas están en sitios diferentes, la manera mas rapida de pintar un círculo completo es dibujando los 4 cuadrantes a la vez pero solo si es completo

Código: Seleccionar todo

#pragma options -machine=coco2b

#include <basic.h>
int main(void)
{
    PMODE(3,1);
    PCLS(1);
    SCREEN(1,0);
    COLOR(2,0);
    system("R=100");
    for (int i=1;i<10;i++) {
       system("R=R-10");
       system("CIRCLE(128,96),R");
    }
    for (int i=1;i<10;i++) {
       MCIRCLE(128, 96, i*10, 3);
    }
    return 0;
}


No estoy seguro pero creo que no maneja polimorfismo tan útil para hacer cosas como: int ABS(int) y float ABS(float)

Avatar de Usuario
luiscoco
Mensajes: 2328
Registrado: 15 May 2011 04:23
Ubicación: Caracas, Venezuela
Agradecido : 30 veces
Agradecimiento recibido: 44 veces
Contactar:

Re: Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Mensajepor luiscoco » 19 Ago 2017 23:59

Chema escribió:Los compiladores de C para estas máquinas suelen ser cómodos, no eficientes en el código que generan.

Los que hay para 6502 son horribles en general generando código como 5 veces más largo y lento. Y a veces peor que eso.

Son útiles para prototipos o pruebas de concepto, pero las rutinas interesantes tienen que ser escritas en asm.

Por cierto, para imprimir en C se usa printf (definida en stdio.h) que suele ser un monstruo. Si es para imprimir cadenas mejor puts y para caracteres putchar.


Gracias chema, yo veo esto más bien como práctica para hacer el BASIC nuevo, hecho en ASSEMBLER.
Acá es rápido implementar funciones nuevas, pero no estoy del todo cómodo, ya que el editor no me ayuda a buscar comandos y parámetros, hay que compilar todo a cada rato, y no entender bien aun nada de la librería, pero iremos diseñando a ver que queda para el BASIC

Yo en base a las pruebas mentales que he hecho, creo que sería un BASIC muy rápido, y transportable a otras máquinas, al menos el diseño, muchos votarosn por el "C" pero creo que carga a la máquina un poco, perdiendo algo con respecto al ASS, pero mejora al BASIC actual

Avatar de Usuario
luiscoco
Mensajes: 2328
Registrado: 15 May 2011 04:23
Ubicación: Caracas, Venezuela
Agradecido : 30 veces
Agradecimiento recibido: 44 veces
Contactar:

Re: Nuevo proyecto CoCo "C" CoCo/Dragon/CP400

Mensajepor luiscoco » 20 Ago 2017 00:51

COMANDOS DEL BASIC para este "C"
Todos saltan al BASIC en ROM para que analice los parámetros (BAS), A veces Directo a las funciones(ROM), excepto los marcados con (C), que realizan la función en "C"

Comenzaré, indicando algunas posibles mejoras, y siempre actualizare este mensaje, o lo llevare al primero.

Código: Seleccionar todo

int  ABS     (int numeric) Retorna el numero absoluto (siempre positivos) de un integer, no utiliza numeros de punto flotante (float, single, double)
int  BACKUP  (int d)                Sirve para Backup desde 0 a 0 o desde la unidad normal a la misma unidad
int  BACKUP2 (int d1, int d2)       No entiendo porque no uso el mismo nombre y ya el C averigua cual usar
int  CLOADM  (char* fn, unsigned offset)
void CLOSE   (int fd)               (C)
void CLS     (int c)
void COLOR   (int c1, int c2)
int  COPY    (char* f1, char* f2)   No copia en 1 drive a otro disco?
int  CSAVEM  (char* fn, void* start, void* finish, void* exec)
int  DIR     (int d)
int  DRIVE   (int d)
int  DSKINI  (int d)
void HCIRCLE (int x, int y, int r)
void HCLS    (int c)
void HCOLOR  (int c1, int c2)
void __HLINE (int x1, int y1, int x2, int y2, char* mode, char* type)
void HLINE   (int x1, int y1, int x2, int y2, int onoff)
void HLINE_B (int x1, int y1, int x2, int y2, int onoff)
void HLINE_BF(int x1, int y1, int x2, int y2, int onoff)
void HPAINT  (int x, int y, int c, int b)
void HSCREEN (int mode)
int  INKEY   (void)
size_t INPUT (int fd, char* s) No soporta casette
byte JOYSTK  (int j)
int  KILL    (char* fn)
void LARC    (int x, int y, int w, int h, int s, int e, int c)
void LELLIPSE(int x, int y, int w, int h, int c)
void LINE    (int x1, int y1, int x2, int y2, int onoff)
void LINE_B  (int x1, int y1, int x2, int y2, int onoff)
void LINE_BF (int x1, int y1, int x2, int y2, int onoff)
void LLINE   (int x1, int y1, int x2, int y2, int c)
void LLINE_B (int x1, int y1, int x2, int y2, int c)
void LLINE_BF(int x1, int y1, int x2, int y2, int c)
void __LINE  (int x1, int y1, int x2, int y2, char* mode, char* type)
int LOADM    (char* fn, word offset)
void LRESET  (int x, int y)
void LSET    (int x, int y, int c)
int  LPOINT  (int x, int y)
void MARC    (int x, int y, int w, int h, int s, int e, byte c)
void MCIRCLE (int x, int y, int r, byte c)
void MCLIP   (int x1, int y1, int x2, int y2)
void MELLIPSE(int x, int y, int w, int h, byte c)
void MLINE   (int x1, int y1, int x2, int y2, byte c)
void MRESET  (int x, int y)
void MSET    (int x, int y, byte c)
byte MPOINT  (int x, int y)
int  OPEN    (char mode, int fd, char* fn, size_t len)
int  OPEN_D  (int f, char* fn, size_t len)
int  OPEN_I  (int f, char* fn)
int  OPEN_O  (int f, char* fn)
void PAINT   (int x, int y, int c, int b)
void PCLS    (int pen)
void PCOPY   (int p1, int p2)
byte PEEK    (word addr)
void PMODE   (int mode, int page)
void POKE    (word addr, word value)
int  PRINT   (int fd, char* fmt, ...)
int  RENAME  (char* f1, char* f2)
void RESET   (int x, int y)
int  SAVEM   (char* fn, void* start, void* finish, void* exec)
void SCREEN  (int mode, int css)
void SET     (int x, int y, int c)
void SOUND   (int tone, int duration)
word TIMER   (void)
int  UNLOAD  (int d)
void* VARPTR (char* s)
int  VERIFY  (int onoff)
int  VERIFY_OFF(void)
int  VERIFY_ON (void)


int ABS(int valor)
Está hecho en "C" solo le falta poder trabajar con otros tipos de datos, como int|byte|word|long|single o float|double y retorna el tipo de dato adecuado.


int BACKUP (int d[, int d])
Debe poder trabajar con uno o dos parámetros, por ser un comando peligroso la unidad default no debería tomarse en cuenta, hay que ser específico
Las unidades DRAGON comienzan en 1 (hay que ver qué hacer en este caso).
Este comando hay que mejorarlo,
* Dragon al copiar puede formatear y decirle caras y pistas BACKUP 1 to 3,2,80 hace un backup desde la unidad 1 a la 3 con 2 caras y 80 pistas.
* Usar eficientemente 64K o toda la memoria que posea, para memorizar los datos cuando hay una sola unidad
* Tal vez no copiar sectores sin datos, (cuando hay una sola unidad hay que hacer menos pases si el disco no está lleno), tal vez un parámetro adicional.
* No borrar el programa, el basic se borra.
* Formatear a la vez, falla si no esta formateado el disco destino, (si formatea necesitará los parámetros del DSKINI)
Ejem:
BACKUP(0)
BACKUP(0,1)
BACKUP(1) (podría copiar de la unidad 1 a la unidad 0 si es la predeterminada pero es peligroso)

int CLOADM (char* fn, unsigned offset)
Carga un programa de lenguaje de máquina desde el cassette
* El parámetro offset puede ser opcional ya que hay un predeterminado.
* No se si es posible, pero este lenguaje no podría usar CLOAD ya que no se que va ha hacer con un programa en BASIC? Pararlo a "C", jeje seria bueno.

void CLOSE (int fd)
Rutina hecha en "C" con los controles nativos.

void CLS (int color)
Esta rutina borra la pantalla de texto con un color o si se omite el parámetro, con el dolor predeterminado, pero siempre me gusto el que pudiera usar cualquier carácter.
* Mejora: Si se usa un char como dato podría usar ese char para rellenar la pantalla.
* Mejora 2: Podría tener parámetros desde/hasta (como posición en bytes) o desde/hasta como líneas, o ventana, con 4 coordenadas, que opinan?

void COLOR (int c1, int c2)
Selecciona el color de pintar y de fondo predeterminado
* debería haber una función que permita saber cuales son esto predeterminados, por ejemplo; COLORBG, y COLORFG

int COPY (char* f1, char* f2)
Copia un archivo a otro disco, puede ser en la misma unidad, si se usan 2 nombres diferentes tambien cambiara el nombre
* Debe ser opcional el 2do parametro, asi si no se coloca, sería una copia con una sola unidad a otro disco.

int CSAVEM (char* fn, void* start, void* finish, void* exec)
Graba un programa o zona de memoria en cassette
* podría tener unos predeterminados del último programa cargado

int DIR(int d)
Muestra el directorio de un disco, sin parámetros muestra el disco predeterminado
* Dragon tiene un directorio mejorado, que se detiene al completar una pantalla, utiliza bytes y no granulos, que tantos problemas da, tiene protección de archivos y muestra la cantidad de archivos listados y el espacio libre.
* Se debería poder usar cualquier formato de disco en cualquier equipo, yo la verdad prefiero el de DRAGON.
* Resumen de DIR, o 2 columnas
* Opciones para solo nombre
* Opción para seleccionar y wildcard
* Debería poder capturarse los que muestra para usarlo en interfaces con los usuarios y no tener que aprender la estructura interna
* Retorna la cantidad de archivos o espacio libre o el error?
* Seria bueno poder rellenar una estructura por el lado izquierdo, tal vez?, con los archivos leídos. o DIR y DIRNEXT o FINDNEXT, el problema es saber cuántos hay primero, por eso otros sistemas usan DIR("wildcard") y luego DIR sin parámetros o FINDNEXT o DIRNEXT, NEXTFILE?
* Seria bueno que tuvieran Directorios para el Disco duro principalmente.
Propongo
* int DIR(int d[, char* fn][, int Flags][, dirArray Array]) Opcionalmente puede tener busqueda de wildcard, Flags y un array para rellenar
* Si se usa la versión de wild card se puede omitir la unidad ya que iría él los wildcard? "?TR*:0" o no?
FLAGS:
R = Resumido, Solo Nombre y extensión.
2 = 2 columnas.
P = No Pausar por cada pantalla, ya que el predeterminado es pausar por cada pantalla, diria tambien presione una tecla, incluido en el último resto de dir, el problema seria el idioma.

void DRIVE(int d)
Selecciona la unidad predeterminada

int DSKINI (int d)
Formatea discos.
* Borra el basic, no se si se podrá usar. acá no hay basic , jeje
* El DRAGON posee int DSKINIT(int d, int lados, int pistas) que tiene mas parametros, lados y pistas ademas de la unidad, predeterminado 1 lado, 40 pistas

int FREE(int fd)
Obtiene el espacio libre en el disco, en gránulos en coco y en bytes en DRAGON

FRE$ obtiene la cantidad d espacio en bytes que queda para variables de basic, no se puede usar

COMANDOS GRÁFICOS SOLO PARA COCO3
void HCIRCLE (int x, int y, int r)
void HCLS (int c)
void HCOLOR (int c1, int c2)
void __HLINE (int x1, int y1, int x2, int y2, char* mode, char* type)
void HLINE (int x1, int y1, int x2, int y2, int onoff)
void HLINE_B (int x1, int y1, int x2, int y2, int onoff)
void HLINE_BF(int x1, int y1, int x2, int y2, int onoff)
void HPAINT (int x, int y, int c, int b)
void HSCREEN (int mode)


int INKEY(void)
Devuelve el código del carácter o el carácter mismo (ya que en C esto es lo mismo) que recién se presionó
* Debería tener un buffer para varias teclas, tal vez capturarlas por interrupción y tener velocidad de repetición y tiempo de comienzo ademas de algún sonido al escribir.
* La coco escribe más rápido las teclas que la DRAGON

size_t INPUT(int fd, char* s) No soporta cassette

byte JOYSTK(int j)
Toma el valor de un joystick
* El comando debería escribirse como en el BASIC, ¿o como la palabra joystick?
* La lectura del joystick 0 lee todas los Joysticks, esto debería cambiar porque si lees el joystick(1) que es la coordenada y del joystick derecho, no se modifica si no ha leído la del 0 primero. La funcionalidad ideal es que cualquier lectura de los joystick tome el valor para todos pero para no repetir lectura se puede hacer que al pasar el valor este se borre así al pedir el valor de nuevo, y ser cero se procederá a releer de nuevo y luego dar el valor.
* Mejora de resolución: solo tiene 64 valores desde 0 a 63 para cada eje de 2 joystick, ya que solo tiene 6 bits de DAC (conversor digtal analogico) que se usa para comparar con los potenciómetros de los joysticks y así saber su valor, hay varios accesorios que permiten más resolución tambien Nick Marenter y otros inventaron un método por promedios que obtienen mas resolucion sobre todo para la coco3.
* Ojala tubiera un conversor Analogico a digital verdadero, aunque comparado con las demás que solo tienen der, izq, arriba y abajo más el disparo, pues no está mal.

int KILL(char* fn)
Borra un archivo
* Podría escribir basura en los sectores, si se le pide?
* Debería haber un comando UNDELETE, El dos debería usar sectores nuevos y solo reusar los borrados cuando estos se acaben, asi se podria desborrar los archivos mejor, ciertamente solo se marcan, se marca el nombre del directorio, en dragon no se estropea el nombre, en ambos equipos se liberan los sectores del archivo borrado, pero se podría dejar rastro para desborrar.

CIRCLE(X,Y),radio[,color][,hw][,start][,end]
Coloca un círculo con centro en X,Y y un del radio especificado con un color dado, el parámetro hw da una relación entre el ancho y el alto, este puede ser un número desde 0 al 255, siendo 0 una línea Horizontal del tamaño del diámetro, 2 veces el radio, Si el parámetro hw es 1 se obtendrá un círculo y si es mayor el circulo se hara mas alto sin cambiar el diámetro hasta tener un alargamiento máximo a los 255, prácticamente un rectángulo. El parámetro start y end son números desde el 0 al 1, siendo 0 la posición de las 3 en punto, bajando a las 6 en punto para un valor de 0,25, y así hasta el 1. El círculo se pintara como la sección elegida, start=0 y end=0 es para un círculo completo.

void LARC(int x, int y, int w, int h, int s, int e, int c)
Nuevo comando para hacer arcos (círculos).
Es algo diferente al anterior.
Parámetros: X,Y, ancho[,alto][,start], end, color

POR TERMINAR
void LELLIPSE(int x, int y, int w, int h, int c)
void LINE (int x1, int y1, int x2, int y2, int onoff)
void LINE_B (int x1, int y1, int x2, int y2, int onoff)
void LINE_BF (int x1, int y1, int x2, int y2, int onoff)
void LLINE (int x1, int y1, int x2, int y2, int c)
void LLINE_B (int x1, int y1, int x2, int y2, int c)
void LLINE_BF(int x1, int y1, int x2, int y2, int c)
void __LINE (int x1, int y1, int x2, int y2, char* mode, char* type)


int KILL(char* fn)
Borra archivos

int LOADM (char* fn, word offset)
Carga un programa en lenguaje de maquina

void LRESET (int x, int y)
void LSET (int x, int y, int c)
int LPOINT (int x, int y)


Comandos gráficos de resolución media
void MARC (int x, int y, int w, int h, int s, int e, byte c)
void MCIRCLE (int x, int y, int r, byte c)
void MCLIP (int x1, int y1, int x2, int y2)
void MELLIPSE(int x, int y, int w, int h, byte c)
void MLINE (int x1, int y1, int x2, int y2, byte c)
void MRESET (int x, int y)
void MSET (int x, int y, byte c)
byte MPOINT (int x, int y)


int OPEN(char mode, int fd, char* fn, size_t len)
int OPEN_D(int f, char* fn, size_t len)
int OPEN_I(int f, char* fn)
int OPEN_O(int f, char* fn)

Abre un archivo en el modo indicado
void PAINT (int x, int y, int c, int b)
Pinta una zona de gráficos, empezando en el punto X,Y con el color C y hasta encontrar el color b

void PCLS(int pen)
Borra la pantalla con un color especificado

void PCOPY (int p1, int p2)
Copia una página gráfica a otra, simplemente copia memoria.
* inicialmente la COCO/DRAGON reserva 4 páginas y máximo puede tener 8, ese límite ya no es válido, cada página es de 1569 bytes, y en PMODE 4 Se usan 4 páginas, sea 6144 bytes, pienso que se pueden tener más de esa cantidad de páginas

byte PEEK (word addr)
Lee un byte desde una dirección
* Lo tratare en POKE

void PMODE (int mode, int page)
Selecciona el modo gráfico y la pagina a ver
* Debería integrarse con los modos HI

void POKE (word addr, word value)
Debido a que la coco 3 y otros equipos pueden tener más de 64k hay que prevenir que se usen funciones más amplias
Si tomamos por ejemplo POKE, hay sistemas que usan DPOKE, WPOKE, LPOKE o POKEL para direccionar word o long, creo que en "C" debido al polimorfismo se debería solo usar POKE y el derivaría la acción a una rutina porque que contemple un LONG o WORD de entrada de dirección
Otro modo es usando paginación visible al usuario, colocan POKE(int Address, int Banco, int Data)
Este comando tambien puede poner no solo un byte sino 2, 4 o 8 bytes, Si hay polimorfismo sería fácil
El POKE Idealmente sería: POKE byte|int|word|long|single o float|Double Dirección, bit|int|byte|word|long|single o float|Double Valor
El PEEK Idealmente sería: ubyte o uchar|uint|uword|ulong Valor=PEEK(byte|int|word|long Dirección[, Options int bytecount])
Detalle: Si no se usa el opcional parámetro bytecount, leerá un solo byte y mantendrá la compatibilidad con basic y dependiendo de esa cantidad de bytes retorna un tipo de datos adecuado.

int PRINT (int fd, char* fmt, ...)
int RENAME (char* f1, char* f2)
void RESET (int x, int y)
int SAVEM (char* fn, void* start, void* finish, void* exec)
void SCREEN (int mode, int css)
void SET (int x, int y, int c)
void SOUND (int tone, int duration)
word TIMER (void)
int UNLOAD (int d)
void* VARPTR (char* s)
int VERIFY (int onoff)
int VERIFY_OFF(void)
int VERIFY_ON (void)[/code]









VERIFY

NUEVOS COMANDOS
lo tiene la Dragon, la coco no
void BEEP(int cant) uno o varios beeps
void BOOT(int d)Bootea un sistema operativo, lo carga en 9728 y lo ejecuta con EXEC 9730.
void CREATE(char * fn, int cant) Crea un archivo de datos de cant de bytes de data
ERROR GOTO
FLREAD”FILE”, FROM 100, FOR 60; string Lee un archivo a un string comenzando en 100 hasta 160
FREAD”FILE”, FROM 30, FOR 60; variable list
FWRITE”FILE”, FROM 10, FOR 30; variable list
HIMEM no lo tiene coco
WAIT


Volver a “Tandy CoCo”

¿Quién está conectado?

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