Olá pessoal, um artigo que achei interessante e quero reproduzir aqui pra vocês é do Giovanni Nunes sobre programar em C no MSX, realmente vale a pena a leitura.
É possível programar em C no MSX? Claro que sim, no MSX Archive é até possível baixar tanto o Hitech-C quanto o MSX-C. Este último foi desenvolvido pela japonesa ASCII e “tecnicamente” é o C oficial do MSX — se você ficou interessado o Javier Lavandeira tem uma uma série intitulada relearning MSX em seu blog onde ele resolveu um fazer guia passo a passo sobre desenvolvimento para MSX partindo bem do princípio e tratando deste compilador.
Porém, se preferir algo mais “moderno” há o Small Device C Compiler, ou simplesmente SDCC, que é um compilador padrão ANSI C que suporta uma série de microcontroladores e microprocessadores de “pequeno porte” e entre eles o Z80. E seguindo uma sugestão feita pelo Rogério Machado via grupo GDMSX do Google+ resolvi montar um passo a passo sobre como configurar este compilador para ser usado no MSX.
Antes de começar
Se preferir, prepare um ambiente separado, seja utilizando uma máquina virtual,contêiner, chroot etc. Vá lá que eu espero 🙂
Instalando o SDCC
Claro, a primeira coisa é instalar o SDCC e também algumas ferramentas que serão utilizadas para a geração dos programas, nas distribuições que usam apt-get faça:
$ sudo apt-get --yes install make sdcc wget
As dependências serão resolvidas pelo apt-get portanto é só aguardar o download e a instalação terminarem.
Adicionando suporte ao MSX
O SDCC tem um suporte para geração de código para o processadores Z80 mas para que ele produza executáveis específicos para o hardware do MSX é necessário “ensiná-lo” corretamente sobre como fazê-lo. Isto significa basicamente que você precisará baixar e compilar os arquivos preparados pelo Avelino Herreras Morales na pagina dele. Mas se preferir eu preparei este script para fazer a tarefa:
#!/bin/bash
# configure MSX support in SDCC
function Create_Directories() {
OLDPWD=$( pwd )
for DIR in ${SDCC_INC_DIR}; do
if [ ! -d ${DIR} ]; then
echo -n "Creating directory ./${DIR}..."
mkdir ${DIR}
Return_Status ${?}
fi
done
cd ${OLDPWD}
}
function Compile_Libraries() {
ASM=$( which sdasz80 )
CC=$( which sdcc )
OLDPWD=$( pwd )
cd ${DESTINATION_PATH}
for S in $( ls *.s ); do
echo "Assembling ${S}..."
${ASM} -o ${S}
#Return_Status ${?}
done
for C in $( ls *.c | sed 's/\.c//g' ); do
echo "Compiling ${C}.c...."
${CC} -mz80 -o ${C}.rel ${C}.c
#Return_Status ${?}
done
cd ${OLDPWD}
}
function Download_Files() {
OLDPWD=$( pwd )
if [ -d ${DESTINATION_PATH} ]; then
cd ${DESTINATION_PATH}
for FILE in ${FILELIST}; do
echo -n "Downloading ${FILE}... "
echo $( HTTP_Download ${REPOSITORY} ${FILE} 2>/dev/null )
done
else
echo "---FAIL--- DESTINATION_PATH not found!"
exit 2
fi
cd ${OLDPWD}
}
function HTTP_Download() {
FETCH=$( basename $( which curl || which wget || which lynx ) )
URL=${1}
FILE=${2}
case ${FETCH} in
curl)
curl -L -o ${FILE} ${URL}/${FILE} -C -
;;
lynx)
lynx -source ${URL}/${FILE} >${FILE}
;;
wget)
wget -c ${URL}/${FILE}
;;
*)
echo "---FAIL--- I can't download files! :("
exit 1
esac
echo "OK"
}
function Return_Status() {
STATUS=${1}
if [ ${STATUS} -eq 0 ]; then
echo ${OKEY}
else
echo ${FAIL}
fi
}
OKEY="OK"
FAIL="FAIL"
DESTINATION_PATH='msx'
DIRECTORIES=${DESTINATION_PATH}
REPOSITORY="http://msx.atlantes.org/sdcc_msx"
FILELIST="crt0msx_msxdos.s crt0msx_msxdos_advanced.s
types.h putchar.s getchar.s dos.s dos.h dos2.s dos2.h
interrupt.s interrupt.h ioport.s ioport.h conio.c conio.h
heap.c heap.h keyboard.s keyboard.h vdp.s vdp.h mem.c mem.h"
Create_Directories
Download_Files ${DESTINATION_PATH}
Compile_Libraries
Compile_Libraries
exit 0
Crie um diretório, mova o script para lá e o execute. Ele se encarregará de baixar todos os arquivos necessários e compilá-los:
$ mkdir -p ~/Projetos/msx
$ cd ~/Projetos$
$ ./sdcc_enable_msx_support ./msx
Downloading crt0msx_msxdos.s... OK
Downloading crt0msx_msxdos_advanced.s... OK
Downloading types.h... OK
...
Assembling keyboard.s...
Assembling putchar.s...
Assembling vdp.s...
Compiling conio.c....
Compiling heap.c....
Compiling mem.c....
Não se preocupe com as mensagens de aviso — os ?ASlink-Warning… — é normal.
No final da execução ele terá criado um diretório específico, o “./msx” contendo os arquivos baixados, compilados e também os cabeçalhos para serem usados no compilador C.
Ah sim, male a pena uma leitura na página do Avelino para entender as diferenças entre o crt0msx_msxdos e o crt0msx_msxdos_advanced.
Convertendo o IHX para binário
Os programas compilados pelo SDCC são gerados em Intel HEX — 😀 Yey! 😀 — e precisam ser convertidos em binário para rodar no MSX. Você pode baixar e utilizar o hex2bin mas acabei montando um conversor bem xexelento em Python para cuidar desta tarefa.
Daí será necessário também instalar:
$ sudo apt-get install python python-pip
$ pip install bincopy
Para executar estas mal traçadas linhas:
with open(inputfile, “r“) as fin: |
if __name__ == “__main__“: |
Como ele foi feito para ser integrado ao Makefile, não sofistiquei muito mas contribuições são sempre bem vindas. 🙂
Montando um Makefile
Mas por que? Porque, como já disse em outra oportunidade, é muito chato ficar tendo de lembar a toda hora a sintaxe e os parâmetros do compilador:
PARAMS=-mz80 –no-std-crt0 –data-loc 0 |
NORMAL=–code-loc 0x107 ../msx/crt0msx_msxdos.rel |
ADVANCED=–code-loc 0x178 ../msx/crt0msx_msxdos_advanced.rel |
RELOCATE=../msx/putchar.rel ../msx/getchar.rel ../msx/dos.rel ../msx/conio.rel |
.PHONY: normal advanced clean superclean |
${CC} ${INCLUDE} ${PARAMS} ${NORMAL} ${RELOCATE} ${INFILE} |
${HEXBIN} ${OUTFILE}.ihx >${OUTFILE}.com |
${CC} ${INCLUDE} ${PARAMS} ${ADVANCED} ${RELOCATE} ${INFILE} |
${HEXBIN} ${OUTFILE}.ihx >${OUTFILE}.com |
${RM} ${OUTFILE}.com ${OUTFILE}.ihx |
${RM} -f ${OUTFILE}.asm ${OUTFILE.com ${OUTFILE}.ihx ${OUTFILE}.lk ${OUTFILE}.lst ${OUTFILE}.map ${OUTFILE}.noi ${OUTFILE}.rel ${OUTFILE}.sym |
Ele está está pronto para compilar programas em C e retornar um “.com”, por padrão ele utiliza o crt0msx_msxdos_advanced mas você pode usar “make normal” ou trocar para que este seja o padrão.
Fazendo um teste
E claro é preciso testar se está tudo certo com o compilador:
#include "conio.h"
#include "dos.h"
void main(void) {
puts("Hello, world :-)\r\n");
exit(0);
}
Este é o mesmo programa de testes da página do Avelino e para compilar use simplesmente make:
Daí é transferir o arquivo para um disquete ou imagem de disco com MSX-DOS e rodar, mais ou menos isto aqui para as imagens de disco:
$ sudo mount msxdos.dsk /mnt -t msdos -o rw,loop
$ sudo cp hello.com /mnt/hello.com && sync
$ sudo umount /mnt
Para o caso do disquetes remova o “,loop” e substitua o “msxdos.dsk” pelo dispositivo que corresponde a unidade de disquetes.
Aliás estes procedimentos podem ser acrescentados ao Makefile fazendo-o gerar uma imagem de disco, acrescentando o(s) arquivo(s) e executando o emulador, mas isto fica como exercício. 🙂
E para terminar
Na página do Avelino há outros exemplos de código e bibliotecas, além dos arquivos para suporte a geração de imagens de cartucho (ROM) diretamente pelo SDCC. Outra fonte interessante é na página do Nestor Soriano (o Konamiman) com uma biblioteca alternativa para as funções básicas de console, suporte para as pilhas TCP/IP que ele desenvolveu entre outras coisas. E como o SDCC usa é compatível com o padrão ANSI-C, há uma grande quantidade de códigos em C que pode ser compilado com pouca/nenhuma modificação para o MSX!
O link original do artigo vocês podem encontrar em;
Programando em C no MSX
Por enquanto é isso pessoal
[]´s
Dex