Du coup je me suis dit qu'il serait intéressant de faire une librairie contenant des routines assez pratiques pour rendre la programmation en C sur TI z80 accessible et attrayante pour tous (un peu comme la Monochrome-Lib sur casio).
Voici les routines que j'ai déjà adapté ou codé :
- TL_random(max) : renvoi un nombre compris entre 0 et la valeur maximale spécifiée (pour l'instant 255)
- TL_cpu_full_speed() : fout le processeur à fond (15 MHz) sur les calto qui le permettent (non testé)
- TL_cpu_normal_speed() : idem met à 6MHz pour toutes les calc (non testé)
- TL_get_contrast() : renvoi la valeur du contraste de l'écran (non testé)
- TL_set_contrast(value) : change la valeur du contraste de l'écran (non testé)
- TL_delay(delay) : crée une pause en ms (bug : la pause est trop longue)
- TL_small_sprite(x, y, height, *sprite, logic) : affiche un sprite de 8 pixel de large et à hauteur variable ORé/XORé/ANDé dans le gbuf (marche niquel)
- TL_large_sprite(x, y, width, height, *sprite, logic) : idem mais les deux dimensions du sprite sont spécifiables (marche nickel)
- TL_large_clipped_sprite(x, y, width, height, *sprite, logic) : ne marche pas et le dernier paramètre n'est pas encore pris en compte :/
- TL_gbuf_to_lcd() : copie le gbuf à l'écran
- TL_direct_input(keygroup) : renvoi un octet dont les bits représentent l'état des touches du groupe spécifié (utilise les DKEY de mon TI83p.h)
- TL_get_key() : équivalent du TI-Basic mais non bloquant (utilise les SKEY de mon TI83p.h)
- TL_is_key_up(key) : renvoie 1 si la touche testée est relevée sinon 0
- TL_is_key_down(key) : inverse
- TL_get_pixel(x, y) : renvoie la valeur du pixel testé dans le gbuf
- TL_set_pixel(x, y, color) : change la valeur d'un pixel dans le gbuf (allumé/éteint/inversé)
- TL_draw_rectangle_filled(x, y, width, height, color) : affiche un rectangle plein noir/blanc/inversé dans le gbuf (merci chickendude )
- TL_draw_line(start_x, start_y, end_x, end_y, color) : affiche une ligne noire/blanche/inversée dans le gbuf
- TL_dialog(x, y, *dialog, is_typed, typing_speed) : affiche un texte caractère par caractère à l'écran à une certaine vitesse avec la prise en compte de plusieurs tokens (changer les coordonnées, faire une pause avec 2nd etc...) (remerci !)
- TL_put_val(x, y, val) : affiche une valeur 16-bits dans le gbuf
Routines qu'il reste à faire :
- TL_small_clipped_sprite(x, y, height, *sprite, logic)
- battery check
- scaled sprite
- flipped sprite
- rotated sprite
- screen invert
- option invert pour les dialog (res/set textinverse,(iy+textflags))
- RLE decode(/encode ?)
- installation d'interruptions (createthread() ?)
Si vous avez d'autres routines intéressantes ou que vous avez du code plus optimisé, faites moi signe
Ah et aussi, j'ai adapté GBA Lib 2 pour pouvoir l'utiliser en C. Il faudra simplement que je présente ses routines (l'auteur, Martin Bousquet, avait fait un tuto qu'il faudra que j'adapte un peu).
J'aurai besoin de personnes prêtes à m'aider à déboguer/compléter la lib.
Pour l'instant le plus simple pour pouvoir l'utiliser c'est de se servir de z88dk, car il permet de facilement générer des programmes TI z80 (bien que wabbitemu refuse de les manger ensuite à cause d'un mauvais header, mais ça c'est peut être à cause de bin2var, il faudra vérifier :/), et surtout parce que certaines notations du code sont spécifiques à son compilateur z80 (z80ASM, bien que j'aurai aimé pouvoir utiliser spasm2, qui lui reconnait au moins le caractère '$' pour le SMC et les macro !! D'ailleurs je suis en train de tenter d'adapter le code asm généré par z88dk avec l'option -a au lieu de -o pour spasm grâce à un programme PureBasic, mais ça ne fonctionne pas encore).
Pour compiler ensuite, le mieux c'est de créer un sous-dossier dans le dossier de z88dk, qu'on nommera par exemple 'dev', d'y coller bin2var et un fichier .bat dans lequel on aura mis (pour compiler sous windows un fichier appelé 'test.c') :
@echo off
cd .. call z88dkenv.bat
cd bin
zcc +ti8x -lm -o ..\dev\test.bin ..\dev\test.c
cd ..\dev
bin2var test.bin test.8xp
del test.bin >nulpause
(Sous linux aucune idée, mais si quelqu'un veut bien poster la marche à suivre ce serait sympa ).
Les fichiers :
dev.zip
Donc en gros dans l'immédiat, outre les nouvelles routines à coder, il me faudrait de l'aide pour réparer certaines routines. Par exemple, j'ai essayé de coder une routine qui fait une pause d'1ms à 6MHz, mais j'ai l'impression que la pause est plus longue que prévue (c'est ce que teste le programme test.c dans l'archive) :
TL_delay()
#if defined TL_DELAY
char __FASTCALL__ TL_delay(unsigned int delay){
#asm
; delay = ~1 ms (without interrupts !)
; 1 cycle = 240 ns at 6 MHz
TL_delay:
ld b,231 ; 2 cycles (480 ns)
TL_delay_loop:
rlc (ix+0) ; 7 cycles (1680 ns)
rrc (ix+0) ; 7 cycles (1680 ns)
djnz TL_delay_loop ; 4 cycles (960 ns) if nz, else 3 cycles (720 ns)
dec hl ; 2 cycles (480 ns)
ld a,h ; 1 cycle (240 ns)
or a ; 1 cycle (240 ns)
jr nz,TL_delay ; 3 cycles (720 ns) if nz, else 2 cycles (480 ns)
ld a,l ; 1 cycle (240 ns)
or a ; 1 cycle (240 ns)
jr nz,TL_delay ; 3 cycles (720 ns) if nz, else 2 cycles (480 ns)
#endasm
}
#endif
J'ai peut être mal compris la durée d'exécution des instructions mais pourtant c'est ce que semble indiquer cet article : http://www.ganssle.com/articles/abuscyc.htm
Et sinon il y a aussi la routine TL_large_clipped_sprite() qui ne marche pas encore (j'ai essayé d'adapter celle là), pourtant j'ai passé des heures à tenter de la déboguer :/