sabato 29 gennaio 2022

Setpixel su C64 (2)

 In un precedente post  avevo gia' affrontato il problema ...leggendo su codebase64 viene proposta una variante che usa delle tabelle di lookup per velocizzare il programma ma non viene presentato il codice completo. Questa e' una implementazione


.macro ClearScreen(screen, clearByte) {
lda #clearByte
ldx #0
!loop:
sta screen, x
sta screen + $100, x
sta screen + $200, x
sta screen + $300, x
sta screen + $400, x
sta screen + $500, x
sta screen + $600, x
sta screen + $700, x
sta screen + $800, x
sta screen + $900, x
sta screen + $a00, x
sta screen + $b00, x
sta screen + $c00, x
sta screen + $d00, x
sta screen + $e00, x
sta screen + $f00, x
sta screen + $1000, x
sta screen + $1100, x
sta screen + $1200, x
sta screen + $1300, x
sta screen + $1400, x
sta screen + $1500, x
sta screen + $1600, x
sta screen + $1700, x
sta screen + $1800, x
sta screen + $1900, x
sta screen + $1a00, x
sta screen + $1b00, x
sta screen + $1c00, x
sta screen + $1d00, x
sta screen + $1e00, x
sta screen + $1f00, x
inx
bne !loop-
}

.macro ClearColorRam(clearByte) {
lda #clearByte
ldx #0
!loop:
sta $0400, x
sta $0400 + $100, x
sta $0400 + $200, x
sta $0400 + $300, x
inx
bne !loop-
}


.macro Hires (){
lda $D018
//ora #%1000
ora #8
sta $D018 // VIC_ADDR + 24
}

.macro BMM (){
lda $D011
//ora #%100000
ora #32
sta $D011 // VIC_ADDR + 17
}


// costanti per la generazioni delle tabelle
// di lookup per calcolare la posizione del pixel
.const GFX_MEM = $2000

.const BitMask = $0a00
.const X_Table = $0b00
.const Y_Table_Lo = $0c00
.const Y_Table_Hi = $0d00

*=$0801 "Loader"
BasicUpstart($0810)


*=$0810 "Main" // SYS 2064

// generazione delle tabelle di lookup
ldx #$00
lda #$80
Loop1:
sta BitMask,x
ror
bcc Skip1
ror
Skip1:
tay
txa
and #%11111000
sta X_Table,x
tya
inx
bne Loop1

lda #<GFX_MEM // Can be replaced with a TXA if GFX_MEM is page aligned
Loop2:
ldy #$07
Loop3:
sta Y_Table_Lo,x
pha
SMC1:
lda #>GFX_MEM
sta Y_Table_Hi,x
pla
inx
dey
bpl Loop3
inc SMC1+1
clc
adc #$40
bcc Skip2
inc SMC1+1
Skip2:
cpx #8*25
bne Loop2

// ********************************************************
jsr $e544 // kernal clear screen
//:SetBorderColor(BLACK)
//:SetBackgroundColor(BLACK)


:Hires()
:BMM()

:ClearScreen($2000,0)
:ClearColorRam($3)



ldx #100 //posizione X del pixel
ldy #100 //posizione Y del pixel
jsr Plott

looper:
jmp looper
rts

Plott:
lda Y_Table_Hi,y
sta $fc
lda Y_Table_Lo,y
sta $fb

ldy X_Table,x
lda BitMask,x
ora ($fb),y
sta ($fb),y
rts





giovedì 27 gennaio 2022

Visual Code Assembler C64

Qualche tempo fa avevo provato CBM Prg Studio ma aveva diverse limitazioni (la prima fra tutte girare solo su Windows)



Per una soluzione multi piattaforma si puo' usare Visual Studio con l'estensione Kick Assembler 8-bit Retro Studio, Kick Assembler, Vice e C64 Debugger

Una volta installata la estensione si devono impostare nei settaggi del plugin le path dei vari componenti

Su Debian ho avuto diversi problemi con C64Debugger...installando la versione binaria viene generato il seguente errore 


sudo ln -sf libxcb-util.so.0 libxcb-util.so.1

il problema e' che la libreria non e' disponibile in apt e fare un symlink semplicemente blocca X al riavvio successivo

Per installare C64debugger da sorgenti si devono seguire i passi seguenti


apt install upx-ucl

git clone git://git.code.sf.net/p/c64-debugger/code c64-debugger-code
cd MTEngine

modificare Makefile aggiungendo -fcommon alle CFlags

make

Grandi poteri fanno grandi casini

 Stavo cercando di installare un software su Linux che viene distribuito in binario e che lamentava una versione di libxcb-util che ho disponibile in apt solo alla versione precedente


Speranzoso ho fatto un symlink con la release precedente ed ho per la prima volta visto questa schermata....libxcb-util e' una parte fondamentale di X ed ha inchiodato tutto  
Ripartito da Grub in recovery si deve prima riattivare a mano la rete (mi sono collegato via cavo) e poi ho forzato la reinstallazione della libreria

/etc/init.d/networking start
dhclient enp0s25
apt --reinstall install libxcb-util1




M5Stack StickC

Aggiornamento

************************************************************

sono riuscito a modificare lo sketch usando la modalita' deepsleep
per allungare la durata della batteria. Al primo avvio viene solo mostrato
la grafica al video...i boot seguenti fatti a seguito di wake up da deep sleep
viene avviata la tastiera BLE 
L'aspetto piu' critico e' stato quello di inserire un delay al riavvio perche' sono necessari
4 secondi per riavviare la riconnessione al Bluetooth e 4 secondi per l'invio del messaggio
(tempi piu' brevi portano a connessioni non affidabili)

#include <BleKeyboard.h>
#include <M5StickC.h>

RTC_DATA_ATTR int bootCount = 0;
BleKeyboard bleKeyboard;
String player = "1"; // set player 1 or player2
void setup() {
  ++bootCount;
  if (bootCount >1 )
    {
      delay(4000);
      bleKeyboard.begin();111
      delay(4000);
      if(bleKeyboard.isConnected()) {
              bleKeyboard.print("1");1
      }
      pinMode(10, OUTPUT);
      digitalWrite(10, LOW); // accende il led
      delay(100);
      digitalWrite(10, HIGH);
    }
    else
    {
    M5.begin();
    pinMode(10, OUTPUT); // red led
    digitalWrite(10, HIGH);
    
    M5.Lcd.setRotation(3);  
    pinMode(37, INPUT); 
  
    M5.Lcd.setTextSize(3);
    M5.Lcd.setCursor(5, 18);  
    M5.Lcd.print("Player "+player);
    delay(1000);
    M5.Axp.SetLDO2(false); // spenge lo schermo      
    }
    
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_37,0);//Configure GPIO37 as ext0 wake up source for low logic level
  esp_deep_sleep_start();
}
void loop() {
}

************************************************************


M5Stack Stickc e' un indossabile (piu' o meno) con a bordo un Esp 32 Pico programmabile

Ha una batteria da soli 80 mAh ed in condizioni normali resta acceso meno di 10 minuti...volevo trasformarlo in un pulsante remoto come tastiera BLE HID per comandare un PC 



Spengendo lo schermo e riducendo il clock a 80 MHz si puo' avere una durata della batteria di circa 75 minuti...ho provato a gestire la modalita' lightsleep dell'ESP32 ma con risultati non sempre affidabili. (non so se a causa di Esp32 o del controllo del widget bluetooth di Gnome su Debian che fa parecchi capricci....se avro' tempo provero' a migliorare)
#include <M5StickC.h>
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
int last_value = 0;
int cur_value = 0;
String player = "1"; // set player 1 or player2
void setup() {
bleKeyboard.begin();
setCpuFrequencyMhz(80); // downscale la frequenza da 240 a 80 Mhz
M5.begin();
pinMode(10, OUTPUT); // red led
digitalWrite(10, HIGH);
M5.Lcd.setRotation(3);
pinMode(37, INPUT);
M5.Lcd.setTextSize(3);
M5.Lcd.setCursor(5, 18);
M5.Lcd.print("Player "+player);
delay(1000);
M5.Axp.SetLDO2(false); // spenge lo schermo
}
void loop() {
M5.update();
delay(300); // per evitare la doppia pressione
cur_value = digitalRead(37);
if(cur_value != last_value){
if(cur_value==0){
if(bleKeyboard.isConnected()) {
bleKeyboard.print(player);
/*M5.Axp.SetLDO2(true);
M5.Lcd.fillScreen(RED);
delay(100);
M5.Lcd.fillScreen(BLACK);
M5.Axp.SetLDO2(false);*/
digitalWrite(10, LOW); // accende il led
delay(100);
digitalWrite(10, HIGH);
}
}
else{
}
last_value = cur_value;
}
}

domenica 23 gennaio 2022

Github Pages

Github permette di ospitare delle applicazioni web oltre che il repository dei sorgenti mediante il servizio GitHub Pages

In estrema sintesi e' sufficiente creare un nuovo branch denominato gh-pages e puntare il browser all'indirizzo del progetto



dopo aver creato aver fatto il primo commit si puo' procedere con 

git checkout -b gh-pages 

git push https://TOKEN@github.com/c1p81/tabellone.git 

Total 0 (delta 0), reused 0 (delta 0), pack-reused 0

remote: 

remote: Create a pull request for 'gh-pages' on GitHub by visiting:

remote:      https://github.com/c1p81/tabellone/pull/new/gh-pages

remote: 

To https://github.com/c1p81/tabellone.git

 * [new branch]      gh-pages -> gh-pages

La applicazione e' quindi disponibile

https://c1p81.github.io/tabellone/

domenica 16 gennaio 2022

Esplosione Hunga-Tonga-Hunga-Ha'apai registrata in Toscana

Il giorno 15 gennaio alle ore UTC 04:27 e' avvenuta l'esplosione del vulcano Hunga-Tonga-Hunga-Ha'apai alle isole Tonga

Le immagini dal satellite sono impressionanti ma ancora piu' impressionante e' che circa 16 ore quasi dalla parte opposta del mondo e a circa 17000 Km di distanza ovvero in Toscana e' stata registrato un sensibile aumento della pressione atmosferica dovuto alla propagazione dell'onda di pressione. La velocita' con tutte le approssimazioni introdotte e' quella del suono 

Prendendo dati di stazioni meteo pubbliche si puo' vedere 

Stazione di Molin del Piano (Fi)

Una anomalia del sensore?


Aulla

Carrara

Bordighera






venerdì 14 gennaio 2022

Web bluetooth e ITag

Sto facendo un po' di esperimenti con il supporto bluetooth per browser in relazione ad dispositivo ITag (non quello di Apple...la versione cinese)


ITag Anti Lost smart bluetooth tracker

Il dispositivo espone alcuni servizi .. a me interessa il Custom Service che corrisponde ad una notifica legata alla pressione del pulsante




da questo link si osserva che l'UUID del servizio e della caratteristica non e' costante  tra i vari dispositivi che sono in vendita

#define SERVICE_UUID1 "0000ffe0-0000-1000-8000-00805f9b34fb"
#define SERVICE_UUID2 "0000fff0-0000-1000-8000-00805f9b34fb"

#define CHAR_UUID1 "0000ffe1-0000-1000-8000-00805f9b34fb"
#define CHAR_UUID2 "0000fff1-0000-1000-8000-00805f9b34fb"


Per accendere si preme il pulsante per 3 secondi e si sente un doppio beep, per spengere sempre 3 secondi di pulsante con lungo segnale acustico. Per alcune impostazione, come la disattivazione della suoneria si puo' usare la app Kindelf per Android ed IOS


Per prima cosa c'e' da dire che non e' una passeggiata ed il supporto delle API al momento e' molto limitato ...praticamente solo Chrome 


 In ogni caso anche per Chrome si deve abilitare esplicitamente le API tramite

chrome://flags/#enable-experimental-web-platform-features

nonostante avere abilitato la flag non ho trovato il sistema per rendere affidabile la comunicazione tra il pulsante e il computer...inoltre c'e' da segnalare che Chrome su IOS non ha la possibilita' di abilitare questo flag (non e' presente nella lista)

Utilizzando chrome://bluetooth-internals/#adapter si puo' verificare che non tutte le funzionalita' sono ancora implementate (se si apre il widget di ricerca del sistema operativo per fare una scansione il discovering da browser diventa rosso)



questa schermata e' stata fatta su un Lenovo T470 con RHEL 

Per i test ho trovato questa applicazione in ReactJS
Per installarla si inizia con 


git clone https://github.com/rdeprey/web-bluetooth-starter

npm install -g create-react-app

npm install --global yarn

npm install (per scaricare le librerie collegate)

npm start (per lanciare il programma)

per creare una versione da inserire in produzione si puo' digitare npm run build oppure yarn build (verra' creata una directory build in cui sono contenuti i file da mettere sul server di produzione)

Ho modificato la funzione di subscribe to notification per impostare il service e la characteristic sulla base del pulsante

const connectToDeviceAndSubscribeToUpdates = async () => {
try {
// Search for Bluetooth devices that advertise a battery service
const device = await navigator.bluetooth
.requestDevice({
filters: [{
namePrefix: "iTAG"
//services: ['battery_service']
}],
//0000FFF0-0000-1000-8000-00805F9B34FB
optionalServices: ["0000ffe0-0000-1000-8000-00805f9b34fb"]
});

setIsDisconnected(false);

// Add an event listener to detect when a device disconnects
device.addEventListener('gattserverdisconnected', onDisconnected);

// Try to connect to the remote GATT Server running on the Bluetooth device
const server = await device.gatt.connect();

// Get service from the Bluetooth device
const service = await server.getPrimaryService('0000ffe0-0000-1000-8000-00805f9b34fb');

// Get the characteristic from the Bluetooth device
const characteristic = await service.getCharacteristic('0000ffe1-0000-1000-8000-00805f9b34fb');

// Subscribe to notifications
characteristic.startNotifications();

// When the battery level changes, call a function
characteristic.addEventListener('characteristicvaluechanged',
handleCharacteristicValueChanged);
const reading = await characteristic.readValue();

// Show the initial reading on the web page
//setBatteryLevel(reading.getUint8(0));
} catch(error) {
console.log(`There was an error: ${error}`);
}
};

Una volta avviato il programma si riesce ad ottenere la prima notifica di pressione del pulsante e subito dopo viene generato l'errore


index.js:1 Uncaught Error: The error you provided does not contain a stack trace.

at M (index.js:1:1)

at ee (index.js:1:1)

at index.js:1:1

at index.js:1:1

at l (index.js:1:1)

M @ index.js:1

ee @ index.js:1

(anonymous) @ index.js:1

(anonymous) @ index.js:1

l @ index.js:1

localhost/:1 Uncaught (in promise) DOMException: GATT Error: Not supported


Il problema sembra legato alla funzione characteristic.startNotifications()). I valori possono essere letti dal dispositivo ma non possono essere ricevuti come notifica bluetooth
Peraltro il valore della characteristic della pressione pulsante rimane settata ad 1 dopo le pressione e non ritorna  a zero quando il pulsante viene rilasciato

Ho provato anche un pulsante di remote shutter per la video camera (AB Shutter 3 su Amazon) che funziona in modo differente..in pratica si comporta come un dispositivo HID  Bluetooth...in pratica una tastiera con un solo tasto...accoppiando il pulsante con GNOME il risultato e' che si attiva la funzione di alzare il volume e quindi non e' utile per lo scopo che mi ero prefisso






Eth0 su LuckFox Pico Mini A

 Le schede Luckfox Pico Mini A (a differenza delle sorelle maggiori) non hanno un connettore RJ45 e nonostante i pin da saldare non sembrano...