Wiki » History » Version 4

Txinto Vaz, 09/08/2013 04:27 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 3 Txinto Vaz
h2. Compilador C
20 1 Txinto Vaz
21 3 Txinto Vaz
Buscaremos siempre los compiladores más adecuados a nuestra máquina.  En el caso inicial (MSX) hemos considerado el más adecuado el SDCC, que probablemente será el escogido para cualquier micro que contenga el Z80 como procesador principal.
22 3 Txinto Vaz
23 3 Txinto Vaz
h3. SDCC
24 3 Txinto Vaz
25 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.
26 1 Txinto Vaz
La lista de microcontroladores que maneja es la siguiente:
27 1 Txinto Vaz
SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08
28 1 Txinto Vaz
Al estar preparado para Z80 permite ser usado para desarrollar programas para MSX, Spectrum, Amstrad CPC, etc.
29 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.
30 1 Txinto Vaz
31 3 Txinto Vaz
h4. SDCC vs GNU C
32 1 Txinto Vaz
33 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.
34 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.
35 1 Txinto Vaz
36 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 
37 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.
38 1 Txinto Vaz
39 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.
40 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).
41 1 Txinto Vaz
42 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  
43 1 Txinto Vaz
44 1 Txinto Vaz
h2. Retrolib: Árbol de directorios con librerías de los ordenadores retro
45 1 Txinto Vaz
46 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.
47 1 Txinto Vaz
48 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.
49 1 Txinto Vaz
50 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.
51 1 Txinto Vaz
52 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 
53 1 Txinto Vaz
54 1 Txinto Vaz
h3. Primera propuesta para la estructura
55 1 Txinto Vaz
56 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:
57 1 Txinto Vaz
* proyecto1
58 1 Txinto Vaz
** src (fuentes del usuario)
59 1 Txinto Vaz
*** main.c
60 1 Txinto Vaz
*** func1.c
61 1 Txinto Vaz
*** func2.c
62 1 Txinto Vaz
** lib (librería del usuario)
63 1 Txinto Vaz
*** modulo1
64 1 Txinto Vaz
**** include
65 1 Txinto Vaz
**** src
66 1 Txinto Vaz
**** lib
67 1 Txinto Vaz
*** modulo2
68 1 Txinto Vaz
**** ...
69 1 Txinto Vaz
** build (directorio para la compilación)
70 1 Txinto Vaz
*** Makefile
71 1 Txinto Vaz
*** dist (directorio para el/los ejecutables) y sus ficheros de configuración/despliegue
72 1 Txinto Vaz
* retrolib (librería retro unificada)
73 1 Txinto Vaz
** cpus
74 1 Txinto Vaz
*** cpu1 (p.e. z80)
75 1 Txinto Vaz
**** include
76 1 Txinto Vaz
**** src
77 1 Txinto Vaz
**** lib
78 1 Txinto Vaz
*** cpu2
79 1 Txinto Vaz
***** include
80 1 Txinto Vaz
***** src
81 1 Txinto Vaz
***** lib
82 1 Txinto Vaz
*** ...
83 1 Txinto Vaz
** computers (podrían estar cada uno dentro de su CPU, pero de momento está bien ahí)
84 1 Txinto Vaz
*** msx (en el primer nivel está la “familia”)
85 1 Txinto Vaz
**** system (librerías de MSX globales)
86 1 Txinto Vaz
***** include
87 1 Txinto Vaz
***** src
88 1 Txinto Vaz
***** lib
89 1 Txinto Vaz
***** msx.mk
90 1 Txinto Vaz
**** versions
91 1 Txinto Vaz
***** msx1
92 1 Txinto Vaz
****** include
93 1 Txinto Vaz
****** src
94 1 Txinto Vaz
****** lib
95 1 Txinto Vaz
****** msx1.mk
96 1 Txinto Vaz
***** msx2
97 1 Txinto Vaz
****** include
98 1 Txinto Vaz
****** src
99 1 Txinto Vaz
****** lib
100 1 Txinto Vaz
****** msx2.mk
101 1 Txinto Vaz
**** targets
102 1 Txinto Vaz
***** com
103 1 Txinto Vaz
****** include
104 1 Txinto Vaz
****** src
105 1 Txinto Vaz
****** lib
106 1 Txinto Vaz
****** com.mk
107 1 Txinto Vaz
****** variants
108 1 Txinto Vaz
******* standard_startup
109 1 Txinto Vaz
******** include
110 1 Txinto Vaz
******** src
111 1 Txinto Vaz
******** lib
112 1 Txinto Vaz
******** standard_startup.mk
113 1 Txinto Vaz
******* advanced_startup
114 1 Txinto Vaz
******** include
115 1 Txinto Vaz
******** src
116 1 Txinto Vaz
******** lib
117 1 Txinto Vaz
******** advanced_startup.mk
118 1 Txinto Vaz
***** rom
119 1 Txinto Vaz
****** include
120 1 Txinto Vaz
****** src
121 1 Txinto Vaz
****** lib
122 1 Txinto Vaz
****** rom.mk
123 1 Txinto Vaz
****** variants
124 1 Txinto Vaz
******* rom32k
125 1 Txinto Vaz
******** include
126 1 Txinto Vaz
******** src
127 1 Txinto Vaz
******** lib
128 1 Txinto Vaz
******** rom32k.mk
129 1 Txinto Vaz
******* megarom
130 1 Txinto Vaz
******** include
131 1 Txinto Vaz
******** src
132 1 Txinto Vaz
******** lib
133 1 Txinto Vaz
******** megarom.mk
134 1 Txinto Vaz
*** spectrum
135 1 Txinto Vaz
**** system
136 1 Txinto Vaz
***** include
137 1 Txinto Vaz
***** src
138 1 Txinto Vaz
***** ...
139 1 Txinto Vaz
140 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.
141 1 Txinto Vaz
142 1 Txinto Vaz
h3. Estructura de Makefiles
143 1 Txinto Vaz
144 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.
145 1 Txinto Vaz
146 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:
147 1 Txinto Vaz
148 1 Txinto Vaz
<pre>
149 1 Txinto Vaz
../../retrolib/cpus/z80/z80.mk
150 1 Txinto Vaz
../../retrolib/computers/msx/msx.mk
151 1 Txinto Vaz
../../retrolib/computers/msx/targets/com/com.mk
152 1 Txinto Vaz
../../retrolib/computers/msx/targets/com/variants/advanced/advanced.mk
153 1 Txinto Vaz
</pre>
154 1 Txinto Vaz
155 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:
156 1 Txinto Vaz
157 1 Txinto Vaz
<pre>
158 1 Txinto Vaz
STARTUPFLAGS += --no-std-crt0 $(COMPPATH)/targets/$(TARGET)/startups/$(STARTUP)/lib/crt0msx_msxdos_advanced.rel --code-loc 0x0178
159 1 Txinto Vaz
</pre>
160 1 Txinto Vaz
161 1 Txinto Vaz
mientras que si hubiésemos tomado la opción “standard” se habría incluído el fichero
162 1 Txinto Vaz
163 1 Txinto Vaz
<pre>
164 1 Txinto Vaz
../../retrolib/computers/msx/targets/com/variants/standard/standard.mk
165 1 Txinto Vaz
</pre>
166 1 Txinto Vaz
de contenido:
167 1 Txinto Vaz
168 1 Txinto Vaz
<pre>
169 1 Txinto Vaz
STARTUPFLAGS += --no-std-crt0 $(COMPPATH)/targets/$(TARGET)/startups/$(STARTUP)/lib/crt0msx_msxdos.rel --code-loc 0x0107
170 1 Txinto Vaz
</pre>
171 1 Txinto Vaz
172 1 Txinto Vaz
Aquí también pueden encontrarse tareas de compilación, etc.
173 1 Txinto Vaz
174 1 Txinto Vaz
h3. Makefile de proyecto
175 1 Txinto Vaz
176 1 Txinto Vaz
h2. Programación en comunidad
177 1 Txinto Vaz
178 1 Txinto Vaz
h3. Sistemas de control de versiones
179 1 Txinto Vaz
180 1 Txinto Vaz
h4. Uso local
181 1 Txinto Vaz
182 1 Txinto Vaz
h4. Uso básico
183 1 Txinto Vaz
184 1 Txinto Vaz
h4. Uso concurrente
185 1 Txinto Vaz
186 1 Txinto Vaz
h4. Opciones disponibles
187 1 Txinto Vaz
188 1 Txinto Vaz
h5. SVN
189 1 Txinto Vaz
190 1 Txinto Vaz
h5. Mercurial
191 1 Txinto Vaz
192 1 Txinto Vaz
h5. Git
193 1 Txinto Vaz
194 1 Txinto Vaz
h3. Sistemas de control de incidencias
195 1 Txinto Vaz
196 1 Txinto Vaz
h3. Forjas de proyectos
197 1 Txinto Vaz
198 1 Txinto Vaz
...
199 4 Txinto Vaz
200 4 Txinto Vaz
h2. Agradecimientos
201 4 Txinto Vaz
202 4 Txinto Vaz
Queremos agradecer a los verdaderos creadores del contenido, que son los que han mantenido durante éstos años el desarrollo de 8 bits vivo.
203 4 Txinto Vaz
204 4 Txinto Vaz
Para empezar:
205 4 Txinto Vaz
* Txinto quiere agradecer a Alberto Orante su pasión y sus fantásticas herramientas para MSX.
206 4 Txinto Vaz
207 4 Txinto Vaz
Y luego en general:
208 4 Txinto Vaz
* A Avelino Herrera Morales y su página http://msx.atlantes.org/index_es.html, nuestro punto de inicio.
209 4 Txinto Vaz
* A Konamiman.
210 4 Txinto Vaz
* A TenerifeGoRetro (www.tenerifegoretro.com).