Wiki » History » Version 2

Txinto Vaz, 09/08/2013 03:35 PM

1 1 Txinto Vaz
h1. Framework Retro para programación C con SDCC
2 1 Txinto Vaz
3 1 Txinto Vaz
{{>toc}}
4 1 Txinto Vaz
5 1 Txinto Vaz
+Objetivo:+ desarrollar un entorno de programación de proyectos retro en C/Ensamblador para todo tipo de ordenadores de 8 o 16 bits que carecen de él.  En una primera etapa quiere cubrirse la plataforma MSX (con todas sus variantes) para ir más tarde incorporando otras (Spectrum, Amstrad CPC, Amiga, C-64).  Si un software para un microprocesador de 8 bits es desarrollado en 2013, entonces la única razón para no usar herramientas de 2013 es que quiera desarrollarse en la propia plataforma como un ejercicio arqueológico.
6 1 Txinto Vaz
7 1 Txinto Vaz
Hemos decidido que nuestro entorno debe disponer de las siguientes herramientas:
8 1 Txinto Vaz
* Compilador C orientado a sistemas con poca memoria.
9 1 Txinto Vaz
* Sistema operativo Linux, para poder distribuir el sistema completo como una máquina virtual sin violar licencias o como paquete para ser instalado en cualquier máquina.  También para tener un acceso mejor a las herramientas de programación open-source más actuales sin hacerle “injertos” al sistema operativo (léase Min-GW o CygWin).
10 1 Txinto Vaz
* Sistema de control de versiones, para poder publicar los cambios de nuestro software, marcar versiones, distribuirla a beta-testers, codificar en comunidad, etc.
11 1 Txinto Vaz
* Sistema de gestión de incidencias: para poder concentrar y asignar las tareas a realizar, los bugs a resolver, guardar información sobre su resolución, etc.  Es deseable que el sistema de control de incidencias tenga wiki, foros, capacidad de subir ficheros, pueda mantener varios proyectos a la vez, etc.  Y también que permita conectarse en caliente con los repositorios y pueda vincularse la información del wiki y de las incidencias con el propio código, especialmente con los comentarios del código.
12 1 Txinto Vaz
* Sistema de generación automática de documentación a partir del código.  Similar a JavaDoc o Doxygen.
13 1 Txinto Vaz
* Sistema de test unitario, similar a JUnit, UnitTest, etc.
14 1 Txinto Vaz
* Entorno de desarrollo integrado que intente conjugar todas éstas herramientas (Eclipse, Netbeans...).
15 1 Txinto Vaz
* Sistemas de automatización de compilación/test inteligentes tipo Makefile, o más evolucionado.
16 1 Txinto Vaz
(seguir ampliando)
17 1 Txinto Vaz
* Y, por supuesto, emuladores configurados (o quasi-configurados si hay algún tema legal por ahí) para probar los desarrollos sin demasiada complicación.
18 1 Txinto Vaz
19 2 Txinto Vaz
h2. Compilador SDCC
20 1 Txinto Vaz
21 1 Txinto Vaz
SDCC es un compilador C especialmente indicado para pequeños dispositivos (de ahí su nombre Small Devices C Compiler).  Es un avanzado compilador de hoy en día que se mantiene gracias a su uso para robótica y pequeños microcontroladores como los PIC o los 8051.
22 1 Txinto Vaz
La lista de microcontroladores que maneja es la siguiente:
23 1 Txinto Vaz
SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08
24 1 Txinto Vaz
Al estar preparado para Z80 permite ser usado para desarrollar programas para MSX, Spectrum, Amstrad CPC, etc.
25 1 Txinto Vaz
Genera código en ensamblador que es fácilmente consultable y modificable, lo que nos ayuda, además, a aprender cómo funciona el ensamblador.  También nos permite encapsular sentencias en ensamblador para realizar partes de rutinas que sean más fáciles o más óptimas en ese lenguaje.
26 1 Txinto Vaz
27 1 Txinto Vaz
h3. SDCC vs GNU C
28 1 Txinto Vaz
29 1 Txinto Vaz
La versión actual es la 3.2.0. que data de 2012, por lo que se trata de un proyecto vivo que incorpora (sin dejar de vista su orientación a pequeños dispositivos) los últimos avances o tendencias.
30 1 Txinto Vaz
Cabe remarcar que al disponer de un preprocesador actual nos permite introducir directivas y alternativas de compilación en el código fuente de la misma manera que se realiza en GNU.  También al ser un proyecto que crece en la sombra de GNU C, busca tener las máximas similitudes en el tema de sintaxis o de argumentos de compilación (por ejemplo introducir un #define desde la línea de compilación se hace con el argumento -D), lo que minimiza las veces que debamos recurrir a documentación específica para aprender algo que luego no nos vaya a servir para programar ordenadores o microcontroladores más potentes.
31 1 Txinto Vaz
32 1 Txinto Vaz
En el caso del MC68000, corazón de los Atari ST y de los Amiga, el surtido de compiladores C de su época era 
33 1 Txinto Vaz
extenso y muy optimizado, por lo que  la franja que queda entre el crosscompiling con GNU C y el “retro-compiling” con un C de la época es demasiado pequeño, y no existe una alternativa como la del SDCC.  En ese caso, si un programador busca alto rendimiento, tiene que lidiar con compiladores muy eficientes pero obsoletos, y muchas veces tiene que invertir mucho tiempo en saber si una opción es posible realizarla con ese compilador y saber cómo se ejecuta.
34 1 Txinto Vaz
35 1 Txinto Vaz
Nuestro propósito es no perder de vista la sinergia con GNU C, que está dotado de unas herramientas de test y debug muy interesante para depurar gran parte de nuestro código, si conseguimos mantener una alta compatibilidad con Linux.  Si el 80% de un programa es ANSI C y manejo de datos y memoria, podemos intentar mantener esos módulos compatibles entre SDCC y GNU para así poder, por ejemplo, ejecutar tests automáticos, reutilizar código en ambos sentidos, o debugar paso a paso buscando un puntero que se pierde o una conversión mal resuelta.
36 1 Txinto Vaz
También podemos (como se hace en la programación de microcontroladores de control de sistemas con altas exigencias de seguridad) utilizar definiciones de tipos propias, como UI_8 (unsigned int de 8 bits), en vez de los tipos de C (unsigned int).  De esa manera al tratar de debugar en Linux una rutina C  no veremos diferencias entre un número que se desborda en un MSX (los enteros de un MSX son de 8 bits por defecto) y que no se desborda en un Linux (con enteros seguramente de 32 bits si no se especifica lo contrario).
37 1 Txinto Vaz
38 1 Txinto Vaz
Otra de las razones por las que nos interesa mantener nuestro código lo más parecido al GCC es la de los entornos de programación.  Tanto Eclipse como Netbeans proporcionan facilidades tremendas para refactorizar, debugar, documentar y organizar proyectos software.  También para disparar baterías de test automáticos.  Éstas herramientas realizan el “syntax highlight” sobre el código, alertando de conversiones erróneas o de funciones no declaradas.  Merece la pena invertir en desarrollar funciones simuladas o “stub” protegidas por una directiva de compilación para que el entorno nos ayude todo lo posible a  
39 1 Txinto Vaz
40 1 Txinto Vaz
h2. Retrolib: Árbol de directorios con librerías de los ordenadores retro
41 1 Txinto Vaz
42 1 Txinto Vaz
Queremos ir juntando las diferentes librerías C/Ensamblador de cada ordenador en nuestro entorno de programación.  Habrá rutinas de carácter general, otras dependientes del procesador central, otras dependientes del sistema operativo del ordenador, de la familia, del modelo concreto.  También habrá librerías dependientes del chip de sonido, del de vídeo, etc.
43 1 Txinto Vaz
44 1 Txinto Vaz
Si creamos un árbol de directorios determinado, podemos realizar una compilación de proyectos utilizando un Makefile configurable.  En una primera versión podríamos tener unos ejemplos de proyecto funcionando que podrían copiarse para crear nuevos proyectos.  En el nuevo proyecto en un fichero el usuario indicaría la ubicación de sus fuentes y mediante variables escogería el ordenador al que va orientado (p.e. MSX), la versión de dicho ordenador (p.e. MSX1), el “target” de la compilación (p.e. cartucho ROM o comando para sistema MSX-DOS), y la variante.
45 1 Txinto Vaz
46 1 Txinto Vaz
Un ejemplo de variante es la siguiente: en MSX utilizando las librerías publicadas y documentadas por Avelino (poner bien ésta cita) tendríamos “startup básico” que es compatible con todos los sistemas MSX-DOS o “startup avanzado”, que permite invocar comandos con argumentos al estilo usual (argc, argv), pero que es menos compatible.  En el caso de los cartuchos ROM, podríamos tener la configuración básica de cartuchos hasta 32Kb o hablar de los MegaROM.
47 1 Txinto Vaz
48 1 Txinto Vaz
Deberíamos también tener un sistema de “módulos” que podamos activar o desactivar con flags en nuestros Makefiles.  Con éstos módulos podríamos introducir características propias de periféricos tipo Yamaha Music Module, Philips FM-Pac, MIDI, etc 
49 1 Txinto Vaz
50 1 Txinto Vaz
h3. Primera propuesta para la estructura
51 1 Txinto Vaz
52 1 Txinto Vaz
La forma más práctica y realista de desarrollar una arbol de directorios ideal es partir de una idea y madurarla contra ejemplos de proyectos reales y que deban compilar.  La propuesta actual tiene la siguiente forma:
53 1 Txinto Vaz
* proyecto1
54 1 Txinto Vaz
** src (fuentes del usuario)
55 1 Txinto Vaz
*** main.c
56 1 Txinto Vaz
*** func1.c
57 1 Txinto Vaz
*** func2.c
58 1 Txinto Vaz
** lib (librería del usuario)
59 1 Txinto Vaz
*** modulo1
60 1 Txinto Vaz
**** include
61 1 Txinto Vaz
**** src
62 1 Txinto Vaz
**** lib
63 1 Txinto Vaz
*** modulo2
64 1 Txinto Vaz
**** ...
65 1 Txinto Vaz
** build (directorio para la compilación)
66 1 Txinto Vaz
*** Makefile
67 1 Txinto Vaz
*** dist (directorio para el/los ejecutables) y sus ficheros de configuración/despliegue
68 1 Txinto Vaz
* retrolib (librería retro unificada)
69 1 Txinto Vaz
** cpus
70 1 Txinto Vaz
*** cpu1 (p.e. z80)
71 1 Txinto Vaz
**** include
72 1 Txinto Vaz
**** src
73 1 Txinto Vaz
**** lib
74 1 Txinto Vaz
*** cpu2
75 1 Txinto Vaz
***** include
76 1 Txinto Vaz
***** src
77 1 Txinto Vaz
***** lib
78 1 Txinto Vaz
*** ...
79 1 Txinto Vaz
** computers (podrían estar cada uno dentro de su CPU, pero de momento está bien ahí)
80 1 Txinto Vaz
*** msx (en el primer nivel está la “familia”)
81 1 Txinto Vaz
**** system (librerías de MSX globales)
82 1 Txinto Vaz
***** include
83 1 Txinto Vaz
***** src
84 1 Txinto Vaz
***** lib
85 1 Txinto Vaz
***** msx.mk
86 1 Txinto Vaz
**** versions
87 1 Txinto Vaz
***** msx1
88 1 Txinto Vaz
****** include
89 1 Txinto Vaz
****** src
90 1 Txinto Vaz
****** lib
91 1 Txinto Vaz
****** msx1.mk
92 1 Txinto Vaz
***** msx2
93 1 Txinto Vaz
****** include
94 1 Txinto Vaz
****** src
95 1 Txinto Vaz
****** lib
96 1 Txinto Vaz
****** msx2.mk
97 1 Txinto Vaz
**** targets
98 1 Txinto Vaz
***** com
99 1 Txinto Vaz
****** include
100 1 Txinto Vaz
****** src
101 1 Txinto Vaz
****** lib
102 1 Txinto Vaz
****** com.mk
103 1 Txinto Vaz
****** variants
104 1 Txinto Vaz
******* standard_startup
105 1 Txinto Vaz
******** include
106 1 Txinto Vaz
******** src
107 1 Txinto Vaz
******** lib
108 1 Txinto Vaz
******** standard_startup.mk
109 1 Txinto Vaz
******* advanced_startup
110 1 Txinto Vaz
******** include
111 1 Txinto Vaz
******** src
112 1 Txinto Vaz
******** lib
113 1 Txinto Vaz
******** advanced_startup.mk
114 1 Txinto Vaz
***** rom
115 1 Txinto Vaz
****** include
116 1 Txinto Vaz
****** src
117 1 Txinto Vaz
****** lib
118 1 Txinto Vaz
****** rom.mk
119 1 Txinto Vaz
****** variants
120 1 Txinto Vaz
******* rom32k
121 1 Txinto Vaz
******** include
122 1 Txinto Vaz
******** src
123 1 Txinto Vaz
******** lib
124 1 Txinto Vaz
******** rom32k.mk
125 1 Txinto Vaz
******* megarom
126 1 Txinto Vaz
******** include
127 1 Txinto Vaz
******** src
128 1 Txinto Vaz
******** lib
129 1 Txinto Vaz
******** megarom.mk
130 1 Txinto Vaz
*** spectrum
131 1 Txinto Vaz
**** system
132 1 Txinto Vaz
***** include
133 1 Txinto Vaz
***** src
134 1 Txinto Vaz
***** ...
135 1 Txinto Vaz
136 1 Txinto Vaz
En cada fichero mk están partes del makefile que se incluyen en función de lo que los usuarios vayan especificando en el Makefile del proyecto.  La idea de hacerlo así es intentar que cada proyecto se compile siempre desde sus fuentes, para intentar que el linkador no incorpore funciones que no vayamos a necesitar, como ocurriría si linkáramos librerías precompiladas.
137 1 Txinto Vaz
138 1 Txinto Vaz
h3. Estructura de Makefiles
139 1 Txinto Vaz
140 1 Txinto Vaz
Acompañando a la estructura de directorios, existirá una estructura de ficheros *.mk que serán incluídos por el Makefile de proyecto según las opciones que el usuario escoja en dicho makefile.  Así, en prácticamente cada directorio de cada nodo del árbol encontramos una estructura que se repite una y otra vez: los directorios include, src y lib y el correspondiente *.mk con un nombre igual que el nodo.
141 1 Txinto Vaz
142 1 Txinto Vaz
Por ejemplo, si un usuario está desarrollando una aplicación MSX, compatible con toda la gama (sin decantarse por ninguna versión msx1 o msx2, con un target de fichero com (ejecutable de MSX-DOS) y con el startup avanzado, al seleccionar esas opciones en el Makefile se le incluirán los *.mk correspondientes:
143 1 Txinto Vaz
144 1 Txinto Vaz
<pre>
145 1 Txinto Vaz
../../retrolib/cpus/z80/z80.mk
146 1 Txinto Vaz
../../retrolib/computers/msx/msx.mk
147 1 Txinto Vaz
../../retrolib/computers/msx/targets/com/com.mk
148 1 Txinto Vaz
../../retrolib/computers/msx/targets/com/variants/advanced/advanced.mk
149 1 Txinto Vaz
</pre>
150 1 Txinto Vaz
151 1 Txinto Vaz
Dentro de éste último nos podemos encontrar que se añaden más argumentos a los flags de compilación, por ejemplo:
152 1 Txinto Vaz
153 1 Txinto Vaz
<pre>
154 1 Txinto Vaz
STARTUPFLAGS += --no-std-crt0 $(COMPPATH)/targets/$(TARGET)/startups/$(STARTUP)/lib/crt0msx_msxdos_advanced.rel --code-loc 0x0178
155 1 Txinto Vaz
</pre>
156 1 Txinto Vaz
157 1 Txinto Vaz
mientras que si hubiésemos tomado la opción “standard” se habría incluído el fichero
158 1 Txinto Vaz
159 1 Txinto Vaz
<pre>
160 1 Txinto Vaz
../../retrolib/computers/msx/targets/com/variants/standard/standard.mk
161 1 Txinto Vaz
</pre>
162 1 Txinto Vaz
de contenido:
163 1 Txinto Vaz
164 1 Txinto Vaz
<pre>
165 1 Txinto Vaz
STARTUPFLAGS += --no-std-crt0 $(COMPPATH)/targets/$(TARGET)/startups/$(STARTUP)/lib/crt0msx_msxdos.rel --code-loc 0x0107
166 1 Txinto Vaz
</pre>
167 1 Txinto Vaz
168 1 Txinto Vaz
Aquí también pueden encontrarse tareas de compilación, etc.
169 1 Txinto Vaz
170 1 Txinto Vaz
h3. Makefile de proyecto
171 1 Txinto Vaz
172 1 Txinto Vaz
h2. Programación en comunidad
173 1 Txinto Vaz
174 1 Txinto Vaz
h3. Sistemas de control de versiones
175 1 Txinto Vaz
176 1 Txinto Vaz
h4. Uso local
177 1 Txinto Vaz
178 1 Txinto Vaz
h4. Uso básico
179 1 Txinto Vaz
180 1 Txinto Vaz
h4. Uso concurrente
181 1 Txinto Vaz
182 1 Txinto Vaz
h4. Opciones disponibles
183 1 Txinto Vaz
184 1 Txinto Vaz
h5. SVN
185 1 Txinto Vaz
186 1 Txinto Vaz
h5. Mercurial
187 1 Txinto Vaz
188 1 Txinto Vaz
h5. Git
189 1 Txinto Vaz
190 1 Txinto Vaz
h3. Sistemas de control de incidencias
191 1 Txinto Vaz
192 1 Txinto Vaz
h3. Forjas de proyectos
193 1 Txinto Vaz
194 1 Txinto Vaz
...