mercoledì 7 ottobre 2026

CEDev e CEmu TI-84 Plus CE

Programmazione di TI-84 Plus CE (identica alla TI-83 Premium CE, versione francese) con un emulatore 

 

Per prima cosa si inizia con il compilare l'emulatore

sudo apt update sudo apt install liblua5.4-dev libpng-dev 


git clone https://github.com/ThePhD/sol2.git
cd sol2
mkdir build && cd build
cmake .. -Dsol2_BUILD_TESTS=OFF -Dsol2_BUILD_EXAMPLES=OFF
sudo cmake --install . 

git clone --recursive https://github.com/CE-Programming/CEmu.git 

cd CEmu

cmake ../gui/qt

cmake -DLUA_VERSION=5.4 ../gui/qt 


mkdir build && cd build
cmake ..

Per il funzionamento dell'emulatore si deve scaricare il firmware in formato .rom. Il link seguente e' per il firmware 5.3 

https://web.archive.org/web/20231217022137/https://tiroms.weebly.com/uploads/1/1/0/5/110560031/ti-84ce.rom

successivamente si puo' aggiornare il firmware alla versione 5.8.3  da

https://tiplanet.org/forum/archives_voir.php?id=4601907 

ed inviandolo all'emulatore tramite 

~/CEmu/build/CEmu --send /home/luca/Downloads/os_prd_48.8eu 

messo a punto l'emulatore si passa al compilatore

sudo mkdir -p /opt/CEdev
cd /opt/CEdev
curl -sL https://github.com/CE-Programming/toolchain/releases/latest/download/CEdev-Linux.tar.gz | sudo tar -xz 

echo 'export CEDEV=/opt/CEdev' >> ~/.bashrc
echo 'export PATH=$CEDEV/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
 

 

in /opt/CEDev/examples ci sono numerosi esempi che si compilano tramite make come hello world. Dopo la compilazione si trova il file /bin/DEMO.8xp che si puo' inviare all'emulatore tramite

 ~/CEmu/build/CEmu --send ./bin/DEMO.8xp 

 

per lanciare il programma si preme il tasto prgm (quarta fila dall'alto, terzo da sinistra), si ha la lista dei programmi installati, si sceglie il numero relativo al programma (si avra' prgmDEMO) e si preme enter  

se si ha l'errore libload si deve inviare il file clibs.8xg scaricato da qui

https://github.com/CE-Programming/libraries/releases/tag/v15.0 

tramite 

~/CEmu/build/CEmu --send ~/Downloads/clibs.8xg

di seguito un esempio di Mandelbrot scritto 

/*
* Mandelbrot per TI-84 Plus CE - CE C Toolchain (CEdev)
*
* Usa solo gli header del toolchain (ti/getcsc.h, ti/screen.h): nessuna
* libreria esterna, quindi sulla calcolatrice non serve LibLoad.
*
* Virgola fissa con 8 bit frazionari (1.0 = 256). Sull'ez80 `int` e' a
* 24 bit: con |valore| < 1700 il prodotto resta sotto 2^23, quindi non
* c'e' overflow nemmeno nell'iterazione in cui il punto diverge.
*
* Ottimizzazioni (le stesse di mandelf.asm):
* - test algebrico per cardioide e bulbo di periodo 2 (niente iterazioni);
* - simmetria rispetto all'asse reale: si calcolano le righe 0..120 e le
* righe 1..119 vengono copiate in 239..121.
*/

#include <stdint.h>
#include <string.h>
#include <ti/getcsc.h>
#include <ti/screen.h>

#define LCD_WIDTH 320
#define LCD_HEIGHT 240

#define F 8 /* bit frazionari */
#define ONE (1 << F)
#define STEP 3 /* passo per pixel (3/256) */
#define MAXITER 30
#define X0 (-640) /* c_re iniziale: -2.5 */
#define Y0 (-360) /* c_im iniziale: -1.406 */

#define VRAM ((uint16_t *)0xD40000)
#define LCD_UPBASE (*(volatile uint24_t *)0xE30010)
#define LCD_CTRL (*(volatile uint8_t *)0xE30018)

static uint16_t palette[MAXITER + 1];

static uint16_t rgb565(int r, int g, int b)
{
return (uint16_t)(((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3));
}

/* 1 se c sta nel bulbo di periodo 2 o nella cardioide principale */
static int in_main_bulbs(int cx, int cy2)
{
int t = cx + ONE;
int xm, q;

if (((t * t) >> F) + cy2 < ONE / 16) /* (x+1)^2 + y^2 < 1/16 */
return 1;

xm = cx - ONE / 4;
q = ((xm * xm) >> F) + cy2; /* (x-1/4)^2 + y^2 */
return ((q * (q + xm)) >> F) < (cy2 >> 2); /* q(q+x-1/4) < y^2/4 */
}

int main(void)
{
uint16_t *vram = VRAM;
int n, px, py;

os_ClrHomeFull();

/* LCD: buffer in vRam, 16 bpp (5:6:5) */
LCD_UPBASE = 0xD40000;
LCD_CTRL = 0x2D;

/* colori: blu per i punti che divergono subito, arancio vicino al bordo */
palette[0] = 0;
for (n = 1; n < MAXITER; n++) {
int t = n * 255 / MAXITER;
palette[n] = rgb565(t, (t * t) >> 8, 255 - t);
}
palette[MAXITER] = 0; /* interno: nero */

for (py = 0; py <= LCD_HEIGHT / 2; py++) {
int cy = Y0 + py * STEP;
int cy2 = (cy * cy) >> F;
int near_axis = cy2 < 112; /* |y| < ~0.66 */
int cx = X0;
uint16_t *row = vram + py * LCD_WIDTH;

for (px = 0; px < LCD_WIDTH; px++, cx += STEP) {
if (near_axis && cx < ONE * 3 / 8 && cx >= -(ONE * 5 / 4)
&& in_main_bulbs(cx, cy2)) {
n = MAXITER;
} else {
int x = 0, y = 0, x2 = 0, y2 = 0;

for (n = 0; n < MAXITER && x2 + y2 < 4 * ONE; n++) {
y = ((x * y) >> (F - 1)) + cy; /* 2xy + cy */
x = x2 - y2 + cx;
x2 = (x * x) >> F;
y2 = (y * y) >> F;
}
}
row[px] = palette[n];
}

/* specchio: riga py -> riga 240-py (per py = 1..119) */
if (py > 0 && py < LCD_HEIGHT / 2) {
memcpy(vram + (LCD_HEIGHT - py) * LCD_WIDTH, row,
LCD_WIDTH * sizeof(uint16_t));
}
}

while (os_GetCSC()) { } /* aspetta il rilascio dei tasti */
while (!os_GetCSC()) { } /* poi un nuovo tasto */

os_ClrHomeFull();
os_DrawStatusBar();
return 0;
}


  

# ----------------------------
# Makefile per CE C Toolchain
# ----------------------------

NAME = MANDELC
DESCRIPTION = "Mandelbrot"
COMPRESSED = NO

CFLAGS = -Wall -Wextra -O3
CXXFLAGS = -Wall -Wextra -O3

# ----------------------------

include $(CEDEV)/meta/makefile.mk


Sulla calcolatrice si possono esegire anche programmi in Assembler ma c'e' un dettaglio importante. Texas Instruments da un firmware in poi ha rimosso questa opzione e questo succede anche l'emulare...ho quindi dovuto fare il downgrade alla versione 5.3 per effettuare questa prova (tecnicamente non e' vero..esiste un jailbreak per continuare ad usare programmi compilati in assembler su firmware moderni)

 per compilare si usa fasmg programma.asm MANDEL.8xp

; Mandelbrot per TI-84 Plus CE (CEdev / fasmg)
; Schermo 320x240 a 16 bpp (modalita' predefinita dell'OS), scrittura diretta in vRam.
;
; Aritmetica in virgola fissa con segno: 3 bit interi + 9 bit frazionari (1.0 = 512).
; I valori sono tenuti come interi a 24 bit con segno esteso.
; c_re : da -2.25 a +0.875 (passo 5/512, 320 colonne)
; c_im : da -1.17 a +1.17 (passo 5/512, 240 righe)
; Colore = iterazioni * 0x0841 (sfumatura di grigio); interno dell'insieme = nero.

include 'include/ez80.inc'
include 'include/ti84pceg.inc'
include 'include/tiformat.inc'

format ti executable 'MANDEL'

MAXITER := 30

call ti.ClrScrnFull

; LCD: buffer in vRam, 16 bpp (5:6:5)
ld hl, ti.vRam
ld (0E30010h), hl ; mpLcdUpbase
ld a, 02Dh
ld (0E30018h), a ; mpLcdCtrl

; --- TEST: riempie lo schermo di grigio-viola. Se NON lo vedi cambiare
; --- subito, le scritture in vRam non arrivano allo schermo. ---
ld hl, ti.vRam
ld de, ti.vRam+1
ld bc, 320*240*2-1
ld (hl), 0A5h
ldir

ld hl, ti.vRam
ld (pixptr), hl
ld hl, -600 ; cy iniziale (-1.17)
ld (cy), hl

row_loop:
ld hl, -1152 ; cx iniziale (-2.25)
ld (cx), hl

col_loop:
ld hl, 0
ld (zx), hl
ld (zy), hl
xor a, a
ld (iter), a

iter_loop:
ld hl, (zx)
ld de, (zx)
call fmul
ld (zx2), hl ; x^2
ld hl, (zy)
ld de, (zy)
call fmul
ld (zy2), hl ; y^2

ld de, (zx2)
add hl, de ; x^2 + y^2
ld de, 4*512
or a, a
sbc hl, de
jp nc, escaped ; >= 4.0 -> divergente

ld hl, (zx)
ld de, (zy)
call fmul ; x*y
add hl, hl ; 2xy
ld de, (cy)
add hl, de
ld (zy), hl ; y = 2xy + cy

ld hl, (zx2)
ld de, (zy2)
or a, a
sbc hl, de ; x^2 - y^2
ld de, (cx)
add hl, de
ld (zx), hl ; x = x^2 - y^2 + cx

ld a, (iter)
inc a
ld (iter), a
cp a, MAXITER
jp nz, iter_loop

ld hl, 0 ; non e' scappato: nero
jr put_pixel

escaped:
ld a, (iter)
ld hl, 0
ld l, a
ld h, 65
mlt hl ; n*65 = n + (n << 6)
ld de, 0
ld d, a
ld e, 8
mlt de ; n*8
ld d, e
ld e, 0 ; n << 11
add hl, de ; colore RGB565 = n*0x0841

put_pixel:
ex de, hl
ld hl, (pixptr)
ld (hl), e
inc hl
ld (hl), d
inc hl
ld (pixptr), hl

ld hl, (cx)
ld de, 5
add hl, de
ld (cx), hl
ld de, 448 ; -1152 + 320*5
or a, a
sbc hl, de
jp nz, col_loop

ld hl, (cy)
ld de, 5
add hl, de
ld (cy), hl
ld de, 600 ; -600 + 240*5
or a, a
sbc hl, de
jp nz, row_loop

wait_release: ; aspetta che tutti i tasti siano rilasciati
call ti.GetCSC
or a, a
jr nz, wait_release
wait_press: ; poi aspetta un nuovo tasto
call ti.GetCSC
or a, a
jr z, wait_press
call ti.ClrScrnFull
call ti.HomeUp
call ti.DrawStatusBar
ret

; ---------------------------------------------------------------
; HL = (HL * DE) >> 9 con segno, |HL|,|DE| < 4096
; Distrugge AF, BC, DE, HL, IX
; ---------------------------------------------------------------
fmul:
ld a, h
xor a, d ; bit 7 = segno del risultato
push af
bit 7, h
call nz, negHL
ex de, hl
bit 7, h
call nz, negHL
ex de, hl ; ora HL=H:L e DE=D:E sono positivi

ld ix, 0
ld bc, 0
ld b, l
ld c, e
mlt bc ; L*E
ld c, b
ld b, 0 ; (L*E) >> 8
add ix, bc
ld bc, 0
ld b, h
ld c, e
mlt bc ; H*E
add ix, bc
ld bc, 0
ld b, l
ld c, d
mlt bc ; L*D
add ix, bc
ld bc, 0
ld b, h
ld c, d
mlt bc ; H*D (< 256)
ld b, c
ld c, 0 ; (H*D) << 8
add ix, bc ; IX = prodotto >> 8
push ix
pop hl
srl h
rr l ; HL = prodotto >> 9
pop af
bit 7, a
call nz, negHL
ret

negHL: ; HL = -HL, DE preservato
push de
ex de, hl
or a, a
sbc hl, hl
sbc hl, de
pop de
ret

; ---------------------------------------------------------------
; Variabili (24 bit)
; ---------------------------------------------------------------
pixptr: dl 0
cx: dl 0
cy: dl 0
zx: dl 0
zy: dl 0
zx2: dl 0
zy2: dl 0
iter: db 0


https://www.ticalc.org/pub/84plusce/asm/ 

Se si crea una versione in TiBasic la velocita' di esecuzione crolla miseramente

Per caricare il softare da PC sull'emulatore si deve usare un editor compatibile come https://www.cemetech.net/sc/ esportare il file e inviarlo all'emulatore (il formato non e' un semplice ascii)  salvando con nome tutto maiuscolo ed estensione 8xp

/////////////////////////////////////////////////////////////////////////////////////////

AxesOff
ClrDraw
24→N
1→S
For(R,0,82,S)
(82-R)*.0125→B
B²→D
For(C,0,264,S)
C*.0125-2.2→A
(A-.25)²+D→Q
If Q*(Q+A-.25)<.25D or (A+1)²+D<.0625
Then
N→K
Else
0→X
0→Y
0→K
While K<N and X²+Y²<4
X²-Y²+A→T
2XY+B→Y
T→X
K+1→K
End
End
If K>2
Then
20+(K>2)+(K>6)+(K>12)+(K>19)→E
If K=N
12→E
Pxl-On(R,C,E)
Pxl-On(164-R,C,E)
End
End
End
Repeat getKey
End
 

 

 




Nessun commento:

Posta un commento

CEDev e CEmu TI-84 Plus CE

Programmazione di TI-84 Plus CE (identica alla TI-83 Premium CE, versione francese) con un emulatore    Per prima cosa si inizia con il comp...