Für den heutigen Beitrag eröffne ich keinen neuen Thread, obwohl das Thema nur indirekt mit der Überschrift zusammenhängt.
Zum Debuggen von PASM benutze ich Gear, solange sich das zu untersuchende Code-Stück gut isolieren lässt. Selbst Spin kann man mit etwas Übung in Gear debuggen. Ist aber Peripherie beteiligt, im Fall von Regnatix z.B. XRAM, Bellatrix oder Administra, kann man schlecht unterwegs und ohne Hive testen. Dann falle ich wieder auf print & Co. zurück. In Spin geht das ganz einfach. Das bisschen wird auch in PASM leicht umzusetzen sein, dachte ich. Und?: Denkste.
Folgende Prozedur aus reg-ios.spin habe ich 1:1 in PASM umgesetzt:
Code: Alles auswählen
PUB bus_putchar2(c) 'bus: byte an prop1 (bellatrix) senden
{{bus_putchar2(c) - bus: byte senden an prop2 (bellatrix)}}
outa := %00001000_00111000_00000000_00000000 'prop2=0, wr=0
dira := db_out 'datenbus auf ausgabe stellen
outa[7..0] := c 'daten --> dbus
outa[busclk] := 1 'busclk=1
waitpeq(%00000000_00000000_00000000_00000000,%00001000_00000000_00000000_00000000,0) 'hs=0?
dira := db_in 'bus freigeben
outa := %00001100_01111000_00000000_00000000 'wr=1, prop2=1, busclk=0
...und zwar so:
Code: Alles auswählen
putc_par_c long 0
putc ' parameter: putc_par_c IN char (!) to send to screen. Bits 8..31 must be 0!
mov outa, BEL_WRITE
mov dira, DB_OUT_MASK
or outa, putc_par_c
or outa, DBUS_CLK
waitpeq ZERO, DBUS_HSHAKE
mov dira, DB_IN_MASK
mov outa, BEL_OFF
putc_ret ret
'
BEL_WRITE long %00001000_00111000_00000000_00000000
BEL_OFF long %00001100_01111000_00000000_00000000
DB_IN_MASK long %00000111_11111111_11111111_00000000
DB_OUT_MASK long %00000111_11111111_11111111_11111111
DBUS_CLK long 1 << 25
DBUS_HSHAKE long 1 << 27
ZERO long 0
Ergebnis: Das erste Zeichen wird ausgegeben, folgende Aufrufe laufen ins Leere, obwohl das Programm nicht am waitpeq stehen bleibt. An der Stelle musste ich nach einem anderen PASM-Debugger suchen und fand ClusoDebugger_276.spin im OBEX. Hut ab, da hat sein Autor richtig tief in die Trickkiste gegriffen. Die Einbindung ins eigene Programm ist relativ einfach.
Wenn der zu untersuchende PASM-Code nicht im Hauptobjekt steht, fügt man in die Datei des eingebundenen Objekts eine Funktion wie diese ein:
Code: Alles auswählen
PUB get_dbg_addr
return @sha256_preproc
DAT
org 0
sha256_preproc ' <-- soll debuggt werden
...
und im Hauptobjekt nur:
Code: Alles auswählen
OBJ
pdbg: "ClusoDebugger_276"
s2: "sha256"
PUB main
...
pdbg.StartDebugger( -1, @Debug_Block, s2.get_dbg_addr, 0) 'start debugger in a new cog
Die PASM-Routine wird wie immer mit cognew gestartet. Will man den Debugger mal für einen Testlauf abklemmen, ist nur der Aufruf pdbg.StartDebugger auszukommentieren.
Zurück zum eigentlichen Problem:
Ein Auszug aus bel-bus.spin. Bellatrix signalisiert die Zeichenübernahme mit Handshake auf 0 (3), wartet dann auf das Rücksetzen des Bustaktes (4) und setzt Handshake auf 1 (5):
Code: Alles auswählen
PUB getchar : zeichen '(0) 'chip: ein byte von regnatix empfangen
waitpeq(M1,M2,0) '(1) 'busclk=1? & prop2=0?
zeichen := ina[7..0] '(2) 'daten einlesen
outa[gc#bus_hs] := 0 '(3) 'daten quittieren
waitpeq(M3,M4,0) '(4) 'busclk=0?
outa[gc#bus_hs] := 1 '(5)
Regnatix (siehe putc weiter oben) rennt nach Erhalt der Handshake-0 ungebremst weiter, setzt den Bustakt auf 0, dreht den Kreis (außerhalb von putc) bis zur Ausgabe des nächsten Zeichens, sricht Bella an, legt das Zeichen auf den Bus, setzt den Bustakt wieder auf 1 und wartet darauf, dass Handshake eine 0 präsentiert. PASM ist deutlich schneller als Spin. Für mich ist die einzige Erklärung für das Verschlucken des 2 Zeichens, dass der eben skizzierte PASM-Ablauf in Regnatix zwischen (4) und (5) von bel_bus passiert.
Folgerung: Im PASM-Code fehlt das waitpeq auf die Handshake-1. In meinem Fall kamen die Zeichen danach auf dem Bildschirm an.
Code: Alles auswählen
putc ' parameter: putc_par_c IN char (!) to send to screen. Bits 8..31 must be 0!
waitpeq DBUS_HSHAKE, DBUS_HSHAKE
mov outa, BEL_WRITE
mov dira, DB_OUT_MASK
or outa, putc_par_c
or outa, DBUS_CLK
waitpeq ZERO, DBUS_HSHAKE
mov dira, DB_IN_MASK
mov outa, BEL_OFF
putc_ret ret
Wirklich überprüfen kann ich den Ablauf nicht, dazu fehlt mir ein Werkzeug, das die Code-Abarbeitung in verschiedenen Cogs und auf verschiedenen Propellern zeitlich richtig (exakt) protokolliert.
Warum funktioniert aber der Code mit nur einem waitpeq in reg-ios seit Jahren?! Ich vermute, weil reg-ios, da in Spin geschrieben, ausreichend langsam ist, um auch ohne das zusätzliche waitpeq mit bel-bus zu harmonieren.
Fazit: Und wieder zeigt sich, dass man selbst geschriebene Debug-Helferlein erst mal debuggen muss, ehe sie funktionieren.