commit 8f2077df1b5d0a6a5f5cd74c41bf11fb474cf42a Author: Joerg Deckert Date: Tue Dec 10 15:32:47 2013 +0100 Initial checkin of TriOS R56 diff --git a/flash/administra/admflash.spin b/flash/administra/admflash.spin new file mode 100644 index 0000000..7e36c71 --- /dev/null +++ b/flash/administra/admflash.spin @@ -0,0 +1,1631 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Administra-Flash +Chip : Administra +Typ : Flash +Version : 00 +Subversion : 02 + +Funktion : Dieser Code wird von Administra nach einem Reset aus dem EEProm in den hRAM kopiert + und gestartet. Im Gegensatz zu Bellatrix und Regnatix, die einen Loader aus dem EEProm + laden und entsprechende Systemdateien vom SD-Cardlaufwerk booten, also im + wesentlichen vor dem Bootvorgang keine weiter Funktionalität als die Ladeprozedur + besitzen, muß das EEProm-Bios von Administra mindestens die Funktionalität des + SD-Cardlaufwerkes zur Verfügung stellen können. Es erscheint deshalb sinnvoll, dieses + BIOS gleich mit einem ausgewogenen Funktionsumfang auszustatten, welcher alle Funktionen + für das System bietet. Durch eine Bootoption kann dieses BIOS aber zur Laufzeit + ausgetauscht werden, um das Funktionssetup an konkrete Anforderungen anzupassen. + + Chip-Managment-Funktionen + - Bootfunktion für Administra + - Abfrage und Verwaltung des aktiven Soundsystems + - Abfrage Version und Spezifikation + + SD-Funktionen: + - FAT32 oder FAT16 + - Partitionen bis 1TB und Dateien bis 2GB + - Verzeichnisse + - Verwaltung aller Dateiattribute + - DIR-Marker System + - Verwaltung eines Systemordners + - Achtung: Keine Verwaltung von mehreren geöffneten Dateien! + + HSS-Funktionen: + - 4-Kanal Tracker Engine + - 2-Kanal Sound FX Synthesizer + - 1-Kanal 1Bit ADPCM Sample Engine + - Puffer für HSS-Datei; Modul benötigt während der Wiedergabe also keinen + exklusiven SD-Laufwerkszugriff + + WAV-Funktionen: + - Wiedergabe von WAV-Dateien bis 22050 Hz direkt von SD-Card + - Achtung: Der WAV-Player belegt exclusiv das SDCard-Laufwerk - SD-Funktionen + währendes des Abspielvorgangs führen zu einem undefinierten Verhalten von + Administra! + + RTC-Funktionen: + - Datum, Uhrzeit auslesen + - Datum, Uhrzeit schreiben + - NVRAM auslesen + - NVRAM schreiben + - Wartefunktionen + +Komponenten : HSS 1.2 Andrew Arsenault Lizenz unklar + DACEngine 01/11/2010 Kwabena W. Agyeman MIT Lizenz + FATEngine 01/18/2009 Kwabena W. Agyeman MIT Lizenz + RTCEngine 11/22/2009 Kwabena W. Agyeman MIT Lizenz + +COG's : MANAGMENT 1 COG + FAT/RTC 1 COG + HSS 2 COG's + WAV 2 COG + ------------------- + 4 Cogs (WAV und HSS werden alternativ verwendet!) + +Logbuch : + +14-11-2008-dr235 - erste version erstellt +13-03-2009-dr235 - sd_eof eingefügt +25-01-2009-dr235 - komfortableres interface für hss-player eingefügt +19-03-2009-dr235 - seek, ftime, fattrib und fsize eingefügt +22-08-2009-dr235 - getcogs eingefügt +09-01-2010-dr235 - fehler in sfx_fire korrigiert +10-01-2010-dr235 - fehler in sdw_stop - hss wurde nicht wieder gestartet +15-03-2010-dr235 - start trios +21-03-2010-dr235 - screeninterface entfernt +24-03-2010-dr235 - start einbindung fatengine + - per flashcli laufen schon die ersten kommandos +25-03-2010-dr235 - umstellung fatengine auf fehlernummern +27-03-2010-dr235 - ich hab geburtstag :) + - test mount ok (fat16 + 32, div. sd-cards, fehlermeldungen) + - sd_volname eingefügt + test + - sd_checkmounted/sd_checkused/sd_checkfree eingefügt + test + - sd_checkopen eingefügt (test später) +28-03-2010-dr235 - fehler in der anbindung sd_open --> openFile: der modus + wurde als 0-term-string übergeben! änderung in einen normalen + 1-zeichen-parameter +02-04-2010-dr235 - sd_putblk/sd_getblk eingefügt und getestet +03-04-2010-dr235 - sd_opendit, sd_nextfile, sd_fattrib umgearbeitet und getestet +04-04-2010-dr235 - sd_newdir, sd_del, sd_rename eingefügt und getestet + - test sd_seek ok + - sd_chattrib, sd_chdir eingefügt und getestet + - mgr_getver, mgr_getspec, mgr_getcogs eingefügt + getestet + - mgr_aload eingefügt und getestet + - administra hat jetzt einen bootloader! :) +08-04-2010-dr235 - erster test dir-marker-system +12-04-2010-dr235 - neues soundsystem für wav eingebunden +16-04-2010-dr235 - komplexfehler im wav-system aufgelöst +21-04-2010-dr235 - pausen-modus positionsabfrage im wav-player eingefügt & getestet +29-04-2010-dr235 - wav-player: verwendung der dateigröße statt dem headerwert, da einige + programme definitiv den headerwert falsch setzen! +09-06-2010-dr085 - frida hat den fehler gefunden, welcher eine korrekte funktion der fatengine + nach einem bootvorgang von administra verhinderte :) +13-06-2010-dr235 - fehler in sd_volname korrigiert + - free/used auf fast umgestellt +18-06-2010-dr085 - fehler bei der businitialisierung: beim systemstart wurde ein kurzer impuls + auf der hs-leitung erzeugt, wodurch ein buszyklus verloren ging (symptom: + flashte man admin, so lief das system erst nach einem reset an) + - fatengine: endgültige beseitigung der feherhaften volname-abfrage +27-06-2010-dr085 - automount nach boot +19-07-2010-dr235 - booten eines alternativen administra-codes: befindet sich auf der karte + in der root eine datei "adm.sys", so wird diese datei automatisch in + administra geladen +18-09-2010-dr235 - funktion zur abfrage von eof eingefügt +29-10-2010-dr235 - grundlegende routinen für den plexbus eingefügt +03-12-2010-stepha - RTC Datums- und Zeit Funktionen +04-12-2010-stepha - NVRAM Funktionen +17-04-2013-dr235 - konstanten für administra-funktionen komplett ausgelagert + +Kommandoliste : + +Notizen : + + +}} + + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_01_02 + +CHIP_SPEC = gc#A_FAT|gc#A_LDR|gc#A_HSS|gc#A_WAV|gc#A_COM + +' +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| |+------------------------ adm-p22 +' |||| ||+----------------------- adm-p21 (io) +' |||| |||+---------------------- adm-p20 (rx) +' |||| ||||+--------------------- adm-p19 (tx) +' |||| ||||| +------+ d0..d7 +' |||| ||||| | | +DB_IN = %00001001_00100000_00000000_00000000 'dira-wert für datenbuseingabe +DB_OUT = %00001001_00100000_00000000_11111111 'dira-wert für datenbusausgabe + +M1 = %00000010_00000000_00000000_00000000 'busclk=1? & /prop1=0? +M2 = %00000010_10000000_00000000_00000000 'maske: busclk & /cs (/prop1) + +M3 = %00000000_00000000_00000000_00000000 'busclk=0? +M4 = %00000010_00000000_00000000_00000000 'maske: busclk + +LED_OPEN = gc#HBEAT 'led-pin für anzeige "dateioperation" +SD_BASE = gc#A_SDD0 'baspin cardreader +CNT_HBEAT = 5_000_0000 'blinkgeschw. front-led + +MPLEN = 12000 'größe des hss-musikpuffers + +'index für dmarker +#0, RMARKER 'root + SMARKER 'system + UMARKER 'programmverzeichnis + AMARKER + BMARKER + CMARKER + +OBJ + sdfat : "adm-fat" 'fatengine + hss : "adm-hss" 'hydra-sound-system + wav : "adm-wav" 'sd-wave + rtc : "adm-rtc" 'RTC-Engine + com : "adm-com" 'serielle schnittstelle + gc : "glob-con" 'globale konstanten + +VAR + + long dmarker[6] 'speicher für dir-marker + byte tbuf[20] 'stringpuffer + byte tbuf2[20] + byte bgmusic[MPLEN] 'hss-puffer + byte sfxdat[16 * 32] 'sfx-slotpuffer + byte fl_syssnd '1 = systemtöne an + byte fl_sdwav + byte st_sound '0 = aus, 1 = hss, 2 = wav + long com_baud + + ' variablen für sdwav-player + + long leftVolume + long rightVolume + long DACCog 'cog-nummer das da-wandlers + long PlayCog 'cog-nummer des players + long PlayStack[50] 'stack für player + byte runPlayerFlag 'flag um player zu steuern: 0:stop, 1: run, 2: pause + long wavLen 'länge der abgespielten wav / 512 + long wavPointer 'aktuelle position des players / 512 + + +CON ''------------------------------------------------- ADMINISTRA + +PUB main | cmd,err 'chip: kommandointerpreter +''funktionsgruppe : chip +''funktion : kommandointerpreter +''eingabe : - +''ausgabe : - + + init_chip 'bus/vga/keyboard/maus initialisieren + repeat + cmd := bus_getchar 'kommandocode empfangen + err := 0 + case cmd + 0: !outa[LED_OPEN] 'led blinken + +' ---------------------------------------------- SD-FUNKTIONEN + gc#a_sdMount: sd_mount("M") 'sd-card mounten ' + gc#a_sdOpenDir: sd_opendir 'direktory öffnen + gc#a_sdNextFile: sd_nextfile 'verzeichniseintrag lesen + gc#a_sdOpen: sd_open 'datei öffnen + gc#a_sdClose: sd_close 'datei schließen + gc#a_sdGetC: sd_getc 'zeichen lesen + gc#a_sdPutC: sd_putc 'zeichen schreiben + gc#a_sdGetBlk: sd_getblk 'block lesen + gc#a_sdPutBlk: sd_putblk 'block schreiben + gc#a_sdSeek: sd_seek 'zeiger in datei positionieren + gc#a_sdFAttrib: sd_fattrib 'dateiattribute übergeben + gc#a_sdVolname: sd_volname 'volumelabel abfragen + gc#a_sdCheckMounted: sd_checkmounted 'test ob volume gemounted ist + gc#a_sdCheckOpen: sd_checkopen 'test ob eine datei geöffnet ist + gc#a_sdCheckUsed: sd_checkused 'test wie viele sektoren benutzt sind + gc#a_sdCheckFree: sd_checkfree 'test wie viele sektoren frei sind + gc#a_sdNewFile: sd_newfile 'neue datei erzeugen + gc#a_sdNewDir: sd_newdir 'neues verzeichnis wird erzeugt + gc#a_sdDel: sd_del 'verzeichnis oder datei löschen + gc#a_sdRename: sd_rename 'verzeichnis oder datei umbenennen + gc#a_sdChAttrib: sd_chattrib 'attribute ändern + gc#a_sdChDir: sd_chdir 'verzeichnis wechseln + gc#a_sdFormat: sd_format 'medium formatieren + gc#a_sdUnmount: sd_unmount 'medium abmelden + gc#a_sdDmAct: sd_dmact 'dir-marker aktivieren + gc#a_sdDmSet: sd_dmset 'dir-marker setzen + gc#a_sdDmGet: sd_dmget 'dir-marker status abfragen + gc#a_sdDmClr: sd_dmclr 'dir-marker löschen + gc#a_sdDmPut: sd_dmput 'dir-marker status setzen + gc#a_sdEOF: sd_eof 'eof abfragen + +' ---------------------------------------------- COM-FUNKTIONEN + gc#a_comInit: com_init + gc#a_comTx: com_tx + gc#a_comRx: com_rx + +' ---------------------------------------------- RTC-FUNKTIONEN + gc#a_rtcGetSeconds: rtc_getSeconds 'Returns the current second (0 - 59) from the real time clock. + gc#a_rtcGetMinutes: rtc_getMinutes 'Returns the current minute (0 - 59) from the real time clock. + gc#a_rtcGetHours: rtc_getHours 'Returns the current hour (0 - 23) from the real time clock. + gc#a_rtcGetDay: rtc_getDay 'Returns the current day (1 - 7) from the real time clock. + gc#a_rtcGetDate: rtc_getDate 'Returns the current date (1 - 31) from the real time clock. + gc#a_rtcGetMonth: rtc_getMonth 'Returns the current month (1 - 12) from the real time clock. + gc#a_rtcGetYear: rtc_getYear 'Returns the current year (2000 - 2099) from the real time clock. + gc#a_rtcSetSeconds: rtc_setSeconds 'Sets the current real time clock seconds. Seconds - Number to set the seconds to between 0 - 59. + gc#a_rtcSetMinutes: rtc_setMinutes 'Sets the current real time clock minutes. Minutes - Number to set the minutes to between 0 - 59. + gc#a_rtcSetHours: rtc_setHours 'Sets the current real time clock hours. Hours - Number to set the hours to between 0 - 23. + gc#a_rtcSetDay: rtc_setDay 'Sets the current real time clock day. Day - Number to set the day to between 1 - 7. + gc#a_rtcSetDate: rtc_setDate 'Sets the current real time clock date. Date - Number to set the date to between 1 - 31. + gc#a_rtcSetMonth: rtc_setMonth 'Sets the current real time clock month. Month - Number to set the month to between 1 - 12. + gc#a_rtcSetYear: rtc_setYear 'Sets the current real time clock year. Year - Number to set the year to between 2000 - 2099. + gc#a_rtcSetNVSRAM: rtc_setNVSRAM 'Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). + gc#a_rtcGetNVSRAM: rtc_getNVSRAM 'Gets the selected NVSRAM value at the index (0 - 55). + gc#a_rtcPauseForSec: rtc_pauseForSeconds 'Pauses execution for a number of seconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of seconds to pause for between 0 and 2,147,483,647. + gc#a_rtcPauseForMSec: rtc_pauseForMilliseconds 'Pauses execution for a number of milliseconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of milliseconds to pause for between 0 and 2,147,483,647. + +' ---------------------------------------------- CHIP-MANAGMENT + gc#a_mgrSetSound: mgr_setsound 'soundsubsysteme verwalten + gc#a_mgrGetSpec: mgr_getspec 'spezifikation abfragen + gc#a_mgrSetSysSound: mgr_setsyssound 'systemsound ein/ausschalten + gc#a_mgrGetSoundSys: mgr_getsoundsys 'abfrage welches soundsystem aktiv ist + gc#a_mgrALoad: mgr_aload 'neuen code booten + gc#a_mgrGetCogs: mgr_getcogs 'freie cogs abfragen + gc#a_mgrGetVer: mgr_getver 'codeversion abfragen + gc#a_mgrReboot: reboot 'neu starten + +' ---------------------------------------------- HSS-FUNKTIONEN + gc#a_hssLoad: hss_load 'hss-datei in puffer laden + gc#a_hssPlay: hss.hmus_load(@bgmusic) 'play + hss.hmus_play + gc#a_hssStop: hss.hmus_stop 'stop + gc#a_hssPause: hss.hmus_pause 'pause + gc#a_hssPeek: hss_peek 'register lesen + gc#a_hssIntReg: hss_intreg 'interfaceregister auslesen + gc#a_hssVol: hss_vol 'lautstärke setzen + gc#a_sfxFire: sfx_fire 'sfx abspielen + gc#a_sfxSetSlot: sfx_setslot 'sfx-slot setzen + gc#a_sfxKeyOff: sfx_keyoff + gc#a_sfxStop: sfx_stop + +' ---------------------------------------------- WAV-FUNKTIONEN + gc#a_sdwStart: sdw_start 'spielt wav-datei direkt von sd-card ab + gc#a_sdwStop: sdw_stop 'stopt wav-cog + gc#a_sdwStatus: sdw_status 'fragt status des players ab + gc#a_sdwLeftVol: sdw_leftvol 'lautstärke links + gc#a_sdwRightVol: sdw_rightvol 'lautstärke rechts + gc#a_sdwPause: sdw_pause 'player pause/weiter-modus + gc#a_sdwPosition: sdw_position + +' ---------------------------------------------- DEBUG-FUNKTIONEN + 255: mgr_debug 'debugfunktion + +PRI init_chip | err,i,j 'chip: initialisierung des administra-chips +''funktionsgruppe : chip +''funktion : - initialisierung des businterface +'' - grundzustand definieren (hss aktiv, systemklänge an) +''eingabe : - +''ausgabe : - + + 'businterface initialisieren + outa[gc#bus_hs] := 1 'handshake inaktiv ,frida + dira := db_in 'datenbus auf eingabe schalten ,frida + + 'grundzustand herstellen (hss aktiv + systemklänge an) + + 'hss starten + hss.start 'soundsystem starten + st_sound := 1 'hss aktiviert + fl_syssnd := 1 'systemsound an + + 'sd-card starten + clr_dmarker 'dir-marker löschen + sdfat.FATEngine + repeat + waitcnt(cnt + clkfreq/10) + until sd_mount("B") == 0 + 'err := sd_mount("B") + 'siglow(err) + + 'wav starten + leftVolume := 100 + rightVolume := 100 + PlayCog~ + + 'RTC initialisieren + rtc.setSQWOUTFrequency(3) 'RTC Uhrenquarzt Frequenz wählen + rtc.setSQWOUTState(0) 'RT Zähler ein + + 'adm-code booten? + ifnot \sdfat.openFile(string("adm.sys"), "R") 'test ob adm.sys vorhanden ist + \sdfat.bootPartition(string("adm.sys"), ".") 'neuen code booten + + 'serielle schnittstelle starten + com_baud := 9600 + com.start(gc#SER_RX,gc#SER_TX,0,com_baud) ' start the default serial interface + +PRI bus_putchar(zeichen) 'chip: ein byte über bus ausgeben +''funktionsgruppe : chip +''funktion : senderoutine für ein byte zu regnatix über den systembus +''eingabe : byte zeichen +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & /prop1=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[gc#bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + outa[gc#bus_hs] := 1 'daten ungültig + dira := db_in 'bus freigeben + +PRI bus_getchar : zeichen 'chip: ein byte über bus empfangen +''funktionsgruppe : chip +''funktion : emfangsroutine für ein byte von regnatix über den systembus +''eingabe : - +''ausgabe : byte zeichen + + waitpeq(M1,M2,0) 'busclk=1? & /prop1=0? + zeichen := ina[7..0] 'daten einlesen + outa[gc#bus_hs] := 0 'daten quittieren + outa[gc#bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + +PRI sighigh(err) 'chip: schneller hbeat | fehlersound +''funktionsgruppe : chip +''funktion : schneller hbeat | fehlersound +''eingabe : - +''ausgabe : - + + if fl_syssnd == 1 + if err == 0 + hss.sfx_play(1, @SoundFX3) 'Heartbeat High + else + hss.sfx_play(1, @SoundFX7) 'Error + +PRI siglow(err) 'chip: langsamer hbeat | fehlersound +''funktionsgruppe : chip +''funktion : langsamer hbeat | fehlersound +''eingabe : - +''ausgabe : - + + if fl_syssnd == 1 + if err == 0 + hss.sfx_play(1, @SoundFX4) 'Heartbeat High + else + hss.sfx_play(1, @SoundFX7) 'Error + +PRI clr_dmarker| i 'chip: dmarker-tabelle löschen +''funktionsgruppe : chip +''funktion : dmarker-tabelle löschen +''eingabe : - +''ausgabe : - + + i := 0 + repeat 6 'alle dir-marker löschen + dmarker[i++] := TRUE + +CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN + +PRI sub_getstr | i,len 'sub: string einlesen +''funktionsgruppe : sub +''funktion : subprotokoll um einen string von regnatix zu empfangen und im +'' : textpuffer (tbuf) zu speichern +''eingabe : - +''ausgabe : - +''busprotokoll : [get.len][get.byte(1)]..[get.byte(len)] +'' : len - länge des dateinamens + + repeat i from 0 to 19 'puffer löschen und kopieren + tbuf2[i] := tbuf[i] + tbuf[i] := 0 + len := bus_getchar 'längenbyte name empfangen + repeat i from 0 to len - 1 'dateiname einlesen + tbuf[i] := bus_getchar + +PRI sub_putstr(strptr)|len,i 'sub: string senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen string an regnatix zu senden +''eingabe : strptr - zeiger auf einen string (0-term) +''ausgabe : - +''busprotokoll : [put.len][put.byte(1)]..[put.byte(len)] +'' : len - länge des dateinamens + + len := strsize(strptr) + bus_putchar(len) + repeat i from 0 to len - 1 'string übertragen + bus_putchar(byte[strptr][i]) + +PRI sub_putword(wert) 'sub: long senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen 16bit-wert an regnatix zu senden +''eingabe : 16bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2] +'' : [ hsb ][ lsb ] + + bus_putchar(wert >> 8) + bus_putchar(wert) + +PRI sub_getword:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen 16bit-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 16bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2] +'' : [ hsb ][ lsb ] + + wert := wert + bus_getchar << 8 + wert := wert + bus_getchar + +PRI sub_putlong(wert) 'sub: long senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert an regnatix zu senden +''eingabe : 32bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2][put.byte3][put.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + bus_putchar(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar(wert >> 16) + bus_putchar(wert >> 8) + bus_putchar(wert) + +PRI sub_getlong:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := bus_getchar << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar << 16 + wert := wert + bus_getchar << 8 + wert := wert + bus_getchar + + +CON ''------------------------------------------------- CHIP-MANAGMENT-FUNKTIONEN + +PRI mgr_setsound|sndstat 'cmgr: soundsubsysteme verwalten +''funktionsgruppe : cmgr +''funktion : soundsubsysteme an- bzw. abschalten +''eingabe : - +''ausgabe : - +''busprotokoll : [150][get.funktion][put.sndstat] +'' : funktion - 0: hss-engine abschalten +'' : 1: hss-engine anschalten +'' : 2: dac-engine abschalten +'' : 3: dac-engine anschalten +'' : sndstat - status/cognr startvorgang + + sndstat := 0 + case bus_getchar + 0: if st_sound == 1 + hss.hmus_stop + hss.sfx_stop(0) + hss.sfx_stop(1) + hss.stop + st_sound := 0 + + 1: if st_sound == 0 + sndstat := hss.start + st_sound := 1 + + 2: if st_sound == 2 + cogstop(DACCog) + st_sound := 0 + + 3: if st_sound == 0 + sndstat := DACCog := wav.DACEngine(0) + st_sound := 2 + bus_putchar(sndstat) + +PRI mgr_setsyssound 'cmgr: systemsound ein/ausschalten +''funktionsgruppe : cmgr +''funktion : systemklänge steuern +''eingabe : +''ausgabe : +''busprotokoll : [094][get.fl_syssnd] +'' : fl_syssnd - flag zur steuerung der systemsounds +'' : 0 - systemtöne aus +'' : 1 - systemtöne an + + fl_syssnd := bus_getchar + +PRI mgr_getsoundsys 'cmgr: abfrage welches soundsystem aktiv ist +''funktionsgruppe : cmgr +''funktion : abfrage welches soundsystem aktiv ist +''eingabe : +''ausgabe : +''busprotokoll : [095][put.st_sound] +'' : st_sound - status des soundsystems +'' : 0 - sound aus +'' : 1 - hss +'' : 2 - wav + + bus_putchar(st_sound) + +PRI mgr_aload | err 'cmgr: neuen administra-code booten +''funktionsgruppe : cmgr +''funktion : administra mit neuem code booten +''eingabe : +''ausgabe : +''busprotokoll : [096][sub_getstr.fn] +'' : fn - dateiname des neuen administra-codes + sub_getstr + err := \sdfat.bootPartition(@tbuf, ".") + sighigh(err) 'fehleranzeige + +PRI mgr_getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind +''funktionsgruppe : cmgr +''funktion : abfrage wie viele cogs in benutzung sind +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [097][put.cogs] +'' : cogs - anzahl der belegten cogs + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + bus_putchar(cogs) + +PRI mgr_getver 'cmgr: abfrage der version +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [098][sub_putlong.ver] +'' : ver - version +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''version : $00_00_00_00 +'' + + sub_putlong(CHIP_VER) + +PRI mgr_getspec 'cmgr: abfrage der spezifikation des chips +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [089][sub_putlong.spec] +'' : spec - spezifikation +'' +'' +---------- com +'' | +-------- i2c +'' | |+------- rtc +'' | ||+------ lan +'' | |||+----- sid +'' | ||||+---- wav +'' | |||||+--- hss +'' | ||||||+-- bootfähig +'' | |||||||+- dateisystem +''spezifikation : %00000000_00000000_00000000_01001111 + + sub_putlong(CHIP_SPEC) + +PRI mgr_debug 'cmgr: debug +' adresse der ersten variable senden + + sub_putlong(@dmarker) 'adresse erste variable als marker + +CON ''------------------------------------------------- SD-LAUFWERKS-FUNKTIONEN + +PRI sd_mount(mode) | err 'sdcard: sd-card mounten frida +''funktionsgruppe : sdcard +''funktion : eingelegtes volume mounten +''eingabe : - +''ausgabe : - +''busprotokoll : [001][put.error] +'' : error - fehlernummer entspr. list + + ifnot sdfat.checkPartitionMounted 'frida + err := \sdfat.mountPartition(0,0) 'karte mounten + siglow(err) + 'bus_putchar(err) 'fehlerstatus senden + if mode == "M" 'frida + bus_putchar(err) 'fehlerstatus senden + + ifnot err + dmarker[RMARKER] := sdfat.getDirCluster 'root-marker setzen + + err := \sdfat.changeDirectory(string("system")) + ifnot err + dmarker[SMARKER] := sdfat.getDirCluster 'system-marker setzen + + sdfat.setDirCluster(dmarker[RMARKER]) 'root-marker wieder aktivieren + hss.sfx_play(1, @SoundFX8) 'on-sound + else 'frida + bus_putchar(0) 'frida + +PRI sd_opendir | err 'sdcard: verzeichnis öffnen +''funktionsgruppe : sdcard +''funktion : verzeichnis öffnen +''eingabe : - +''ausgabe : - +''busprotokoll : [002] + + err := \sdfat.listReset + siglow(err) + +PRI sd_nextfile | strpt 'sdcard: nächsten eintrag aus verzeichnis holen +''funktionsgruppe : sdcard +''funktion : nächsten eintrag aus verzeichnis holen +''eingabe : - +''ausgabe : - +''busprotokoll : [003][put.status=0] +'' : [003][put.status=1][sub_putstr.fn] +'' : status - 1 = gültiger eintrag +'' : 0 = es folgt kein eintrag mehr +'' : fn - verzeichniseintrag string + + strpt := \sdfat.listName 'nächsten eintrag holen + if strpt 'status senden + bus_putchar(1) 'kein eintrag mehr + sub_putstr(strpt) + else + bus_putchar(0) 'gültiger eintrag folgt + +PRI sd_open | err,modus 'sdcard: datei öffnen +''funktionsgruppe : sdcard +''funktion : eine bestehende datei öffnen +''eingabe : - +''ausgabe : - +''busprotokoll : [004][get.modus][sub_getstr.fn][put.error] +'' : modus - "A" Append, "W" Write, "R" Read +'' : fn - name der datei +'' : error - fehlernummer entspr. list + + modus := bus_getchar 'modus empfangen + sub_getstr + err := \sdfat.openFile(@tbuf, modus) + sighigh(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + outa[LED_OPEN] := 1 + +PRI sd_close | err 'sdcard: datei schließen +''funktionsgruppe : sdcard +''funktion : die aktuell geöffnete datei schließen +''eingabe : - +''ausgabe : - +''busprotokoll : [005][put.error] +'' : error - fehlernummer entspr. list + + err := \sdfat.closeFile + siglow(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + outa[LED_OPEN] := 0 + +PRI sd_getc | n 'sdcard: zeichen aus datei lesen +''funktionsgruppe : sdcard +''funktion : zeichen aus datei lesen +''eingabe : - +''ausgabe : - +''busprotokoll : [006][put.char] +'' : char - gelesenes zeichen + + n := \sdfat.readCharacter + bus_putchar(n) + +PRI sd_putc 'sdcard: zeichen in datei schreiben +''funktionsgruppe : sdcard +''funktion : zeichen in datei schreiben +''eingabe : - +''ausgabe : - +''busprotokoll : [007][get.char] +'' : char - zu schreibendes zeichen + + \sdfat.writeCharacter(bus_getchar) + + +PRI sd_eof 'sdcard: eof abfragen +''funktionsgruppe : sdcard +''funktion : eof abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [030][put.eof] +'' : eof - eof-flag + + bus_putchar(sdfat.getEOF) + +PRI sd_getblk 'sdcard: block aus datei lesen +''funktionsgruppe : sdcard +''funktion : block aus datei lesen +''eingabe : - +''ausgabe : - +''busprotokoll : [008][sub_getlong.count][put.char(1)]..[put.char(count)] +'' : count - anzahl der zu lesenden zeichen +'' : char - gelesenes zeichen + + repeat sub_getlong + bus_putchar(\sdfat.readCharacter) + + +PRI sd_putblk 'sdcard: block in datei schreiben +''funktionsgruppe : sdcard +''funktion : block in datei schreiben +''eingabe : - +''ausgabe : - +''busprotokoll : [009][sub_getlong.count][put.char(1)]..[put.char(count)] +'' : count - anzahl der zu schreibenden zeichen +'' : char - zu schreibende zeichen + + repeat sub_getlong + \sdfat.writeCharacter(bus_getchar) + +PRI sd_seek | wert 'sdcard: zeiger in datei positionieren +''funktionsgruppe : sdcard +''funktion : zeiger in datei positionieren +''eingabe : - +''ausgabe : - +''busprotokoll : [010][sub_getlong.pos] +'' : pos - neue zeichenposition in der datei + + wert := sub_getlong + \sdfat.setCharacterPosition(wert) + +PRI sd_fattrib | anr,wert 'sdcard: dateiattribute übergeben +''funktionsgruppe : sdcard +''funktion : dateiattribute abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [011][get.anr][sub_putlong.wert] +'' : anr - 0 = Dateigröße +'' : 1 = Erstellungsdatum - Tag +'' : 2 = Erstellungsdatum - Monat +'' : 3 = Erstellungsdatum - Jahr +'' : 4 = Erstellungsdatum - Sekunden +'' : 5 = Erstellungsdatum - Minuten +'' : 6 = Erstellungsdatum - Stunden +'' : 7 = Zugriffsdatum - Tag +'' : 8 = Zugriffsdatum - Monat +'' : 9 = Zugriffsdatum - Jahr +'' : 10 = Änderungsdatum - Tag +'' : 11 = Änderungsdatum - Monat +'' : 12 = Änderungsdatum - Jahr +'' : 13 = Änderungsdatum - Sekunden +'' : 14 = Änderungsdatum - Minuten +'' : 15 = Änderungsdatum - Stunden +'' : 16 = Read-Only-Bit +'' : 17 = Hidden-Bit +'' : 18 = System-Bit +'' : 19 = Direktory +'' : 20 = Archiv-Bit +'' : wert - wert des abgefragten attributes + + anr := bus_getchar + case anr + 0: wert := \sdfat.listSize + 1: wert := \sdfat.listCreationDay + 2: wert := \sdfat.listCreationMonth + 3: wert := \sdfat.listCreationYear + 4: wert := \sdfat.listCreationSeconds + 5: wert := \sdfat.listCreationMinutes + 6: wert := \sdfat.listCreationHours + 7: wert := \sdfat.listAccessDay + 8: wert := \sdfat.listAccessMonth + 9: wert := \sdfat.listAccessYear + 10: wert := \sdfat.listModificationDay + 11: wert := \sdfat.listModificationMonth + 12: wert := \sdfat.listModificationYear + 13: wert := \sdfat.listModificationSeconds + 14: wert := \sdfat.listModificationMinutes + 15: wert := \sdfat.listModificationHours + 16: wert := \sdfat.listIsReadOnly + 17: wert := \sdfat.listIsHidden + 18: wert := \sdfat.listIsSystem + 19: wert := \sdfat.listIsDirectory + 20: wert := \sdfat.listIsArchive + sub_putlong(wert) + +PRI sd_volname 'sdcard: volumenlabel abfragen +''funktionsgruppe : sdcard +''funktion : name des volumes überragen +''eingabe : - +''ausgabe : - +''busprotokoll : [012][sub_putstr.volname] +'' : volname - name des volumes +'' : len - länge des folgenden strings + + sub_putstr(\sdfat.listVolumeLabel) 'label holen und senden + +PRI sd_checkmounted 'sdcard: test ob volume gemounted ist +''funktionsgruppe : sdcard +''funktion : test ob volume gemounted ist +''eingabe : - +''ausgabe : - +''busprotokoll : [013][put.flag] +'' : flag - 0 = unmounted, 1 mounted + + bus_putchar(\sdfat.checkPartitionMounted) + +PRI sd_checkopen 'sdcard: test ob eine datei geöffnet ist +''funktionsgruppe : sdcard +''funktion : test ob eine datei geöffnet ist +''eingabe : - +''ausgabe : - +''busprotokoll : [014][put.flag] +'' : flag - 0 = not open, 1 open + + bus_putchar(\sdfat.checkFileOpen) + +PRI sd_checkused 'sdcard: anzahl der benutzten sektoren senden +''funktionsgruppe : sdcard +''funktion : anzahl der benutzten sektoren senden +''eingabe : - +''ausgabe : - +''busprotokoll : [015][sub_putlong.used] +'' : used - anzahl der benutzten sektoren + + sub_putlong(\sdfat.checkUsedSectorCount("F")) + +PRI sd_checkfree 'sdcard: anzahl der freien sektoren senden +''funktionsgruppe : sdcard +''funktion : anzahl der freien sektoren senden +''eingabe : - +''ausgabe : - +''busprotokoll : [016][sub_putlong.free] +'' : free - anzahl der freien sektoren + + sub_putlong(\sdfat.checkFreeSectorCount("F")) + +PRI sd_newfile | err 'sdcard: eine neue datei erzeugen +''funktionsgruppe : sdcard +''funktion : eine neue datei erzeugen +''eingabe : - +''ausgabe : - +''busprotokoll : [017][sub_getstr.fn][put.error] +'' : fn - name der datei +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.newFile(@tbuf) + sighigh(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_newdir | err 'sdcard: ein neues verzeichnis erzeugen +''funktionsgruppe : sdcard +''funktion : ein neues verzeichnis erzeugen +''eingabe : - +''ausgabe : - +''busprotokoll : [018][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.newDirectory(@tbuf) + sighigh(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_del | err 'sdcard: eine datei oder ein verzeichnis löschen +''funktionsgruppe : sdcard +''funktion : eine datei oder ein verzeichnis löschen +''eingabe : - +''ausgabe : - +''busprotokoll : [019][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses oder der datei +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.deleteEntry(@tbuf) + sighigh(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_rename | err 'sdcard: datei oder verzeichnis umbenennen +''funktionsgruppe : sdcard +''funktion : datei oder verzeichnis umbenennen +''eingabe : - +''ausgabe : - +''busprotokoll : [020][sub_getstr.fn1][sub_getstr.fn2][put.error] +'' : fn1 - alter name +'' : fn2 - neuer name +'' : error - fehlernummer entspr. liste + + sub_getstr 'fn1 + sub_getstr 'fn2 + err := \sdfat.renameEntry(@tbuf2,@tbuf) + sighigh(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_chattrib | err 'sdcard: attribute ändern +''funktionsgruppe : sdcard +''funktion : attribute einer datei oder eines verzeichnisses ändern +''eingabe : - +''ausgabe : - +''busprotokoll : [021][sub_getstr.fn][sub_getstr.attrib][put.error] +'' : fn - dateiname +'' : attrib - string mit attributen +'' : error - fehlernummer entspr. liste + + sub_getstr + sub_getstr + err := \sdfat.changeAttributes(@tbuf2,@tbuf) + siglow(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_chdir | err 'sdcard: verzeichnis wechseln +''funktionsgruppe : sdcard +''funktion : verzeichnis wechseln +''eingabe : - +''ausgabe : - +''busprotokoll : [022][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. list + sub_getstr + err := \sdfat.changeDirectory(@tbuf) + siglow(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_format | err 'sdcard: medium formatieren +''funktionsgruppe : sdcard +''funktion : medium formatieren +''eingabe : - +''ausgabe : - +''busprotokoll : [023][sub_getstr.vlabel][put.error] +'' : vlabel - volumelabel +'' : error - fehlernummer entspr. list + + sub_getstr + err := \sdfat.formatPartition(0,@tbuf,0) + siglow(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + +PRI sd_unmount | err 'sdcard: medium abmelden +''funktionsgruppe : sdcard +''funktion : medium abmelden +''eingabe : - +''ausgabe : - +''busprotokoll : [024][put.error] +'' : error - fehlernummer entspr. list + + err := \sdfat.unmountPartition + siglow(err) 'fehleranzeige + bus_putchar(err) 'ergebnis der operation senden + ifnot err + clr_dmarker + hss.sfx_play(1, @SoundFX9) 'off-sound + +PRI sd_dmact|markernr 'sdcard: einen dir-marker aktivieren +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker wird aktiviert +''eingabe : - +''ausgabe : - +''busprotokoll : [025][get.dmarker][put.error] +'' : dmarker - dir-marker +'' : error - fehlernummer entspr. list + markernr := bus_getchar + ifnot dmarker[markernr] == TRUE + sdfat.setDirCluster(dmarker[markernr]) + bus_putchar(sdfat#err_noError) + else + bus_putchar(sdfat#err_noError) + + +PRI sd_dmset|markernr 'sdcard: einen dir-marker setzen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker mit dem aktuellen verzeichnis setzen +''eingabe : - +''ausgabe : - +''busprotokoll : [026][get.dmarker] +'' : dmarker - dir-marker + + markernr := bus_getchar + dmarker[markernr] := sdfat.getDirCluster + +PRI sd_dmget|markernr 'sdcard: einen dir-marker abfragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [027][get.dmarker][sub_putlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + markernr := bus_getchar + sub_putlong(dmarker[markernr]) + +PRI sd_dmput|markernr 'sdcard: einen dir-marker übertragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker übertragen +''eingabe : - +''ausgabe : - +''busprotokoll : [029][get.dmarker][sub_getlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + markernr := bus_getchar + dmarker[markernr] := sub_getlong + +PRI sd_dmclr|markernr 'sdcard: einen dir-marker löschen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker löschen +''eingabe : - +''ausgabe : - +''busprotokoll : [028][get.dmarker] +'' : dmarker - dir-marker + + markernr := bus_getchar + dmarker[markernr] := TRUE + +CON ''------------------------------------------------- COM-FUNKTIONEN + +PRI com_init 'com: serielle schnittstelle initialisieren +''funktionsgruppe : com +''funktion : serielle schnittstelle initialisieren +''eingabe : - +''ausgabe : - +''busprotokoll : [031][sub_getlong.baudrate] + + + com_baud := sub_getlong + com.start(gc#SER_RX,gc#SER_TX,0,com_baud) ' start the default serial interface + +PRI com_tx 'com: zeichen senden +''funktionsgruppe : com +''funktion : zeichen senden +''eingabe : - +''ausgabe : - +''busprotokoll : [032][get.char] + + com.tx(bus_getchar) + +PRI com_rx 'com: zeichen empfangen +''funktionsgruppe : com +''funktion : zeichen empfangen +''eingabe : - +''ausgabe : - +''busprotokoll : [033][put.char] + + bus_putchar(com.rx) + +CON ''------------------------------------------------- HSS-FUNKTIONEN + +PRI sfx_fire | slot, chan, slotadr 'sfx: effekt im puffer abspielen +''funktionsgruppe : sfx +''funktion : effekt aus einem effektpuffer abspielen +''eingabe : - +''ausgabe : - +''busprotokoll : [107][get.slot][get.chan] +'' : slot - $00..$0f nummer der freien effektpuffer +'' : slot - $f0..ff vordefinierte effektslots +'' : chan - 0/1 stereokanal auf dem der effekt abgespielt werden soll +''vordefinierte effekte : &f0 - warnton +'' : $f1 - signalton +'' : $f2 - herzschlag schnell +'' : $f3 - herzschlag langsam +'' : $f4 - telefon +'' : $f5 - phaser :) +'' : $f6 - pling +'' : $f7 - on +'' : $f8 - off + + slot := bus_getchar + chan := bus_getchar 'channelnummer lesen + case slot + $f0: hss.sfx_play(1, @SoundFX1) 'warnton + $f1: hss.sfx_play(1, @SoundFX2) 'signalton + $f2: hss.sfx_play(1, @SoundFX3) 'herzschlag schnell + $f3: hss.sfx_play(1, @SoundFX4) 'herzschlag schnell + $f4: hss.sfx_play(1, @SoundFX5) 'telefon + $f5: hss.sfx_play(1, @SoundFX6) 'phase + $f6: hss.sfx_play(1, @SoundFX7) 'pling + $f7: hss.sfx_play(1, @SoundFX8) 'on + $f8: hss.sfx_play(1, @SoundFX9) 'off + other: + if slot < $f0 + slotadr := @sfxdat + (slot * 32) 'slotnummer lesen und adresse berechnen + hss.sfx_play(chan, slotadr) + +PRI sfx_setslot | slotadr, i 'sfx: daten in sfx-slotpuffer schreiben +''funktionsgruppe : sfx +''funktion : die daten für ein sfx-slot werden werden von regnatix gesetzt +''eingabe : - +''ausgabe : - +''busprotokoll : [108][get.slot][32:get.daten] +'' : slot - $00..$0f nummer der freien effektpuffer +'' : daten - 32 byte effektdaten +'' +''struktur der effektdaten: +'' +''[wav ][len ][freq][vol ] grundschwingung +''[lfo ][lfw ][fma ][ama ] modulation +''[att ][dec ][sus ][rel ] hüllkurve +''[seq ] (optional) +'' +''[wav] wellenform +'' 0 sinus (0..500hz) +'' 1 schneller sinus (0..1khz) +'' 2 dreieck (0..500hz) +'' 3 rechteck (0..1khz) +'' 4 schnelles rechteck (0..4khz) +'' 5 impulse (0..1,333hz) +'' 6 rauschen +''[len] tonlänge $0..$fe, $ff endlos +''[freq] frequenz $00..$ff +''[vol] lautstärke $00..$0f +'' +''[lfo] low frequency oscillator $ff..$01 +''[lfw] low frequency waveform +'' $00 sinus (0..8hz) +'' $01 fast sine (0..16hz) +'' $02 ramp up (0..8hz) +'' $03 ramp down (0..8hz) +'' $04 square (0..32hz) +'' $05 random +'' $ff sequencer data (es folgt eine sequenzfolge [seq]) +''[fma] frequency modulation amount +'' $00 no modulation +'' $01..$ff +''[ama] amplitude modulation amount +'' $00 no modulation +'' $01..$ff +''[att] attack $00..$ff +''[dec] decay $00..$ff +''[sus] sustain $00..$ff +''[rel] release $00..$ff + + slotadr := @sfxdat + (bus_getchar * 32) 'slotnummer lesen und adresse berechnen + repeat i from 0 to 31 + byte[slotadr + i] := bus_getchar 'sfx-daten einlesen + +PRI sfx_keyoff | chan 'sfx: release-phase einleiten um den effekt zu beenden +''funktionsgruppe : sfx +''funktion : für den aktuell abgespielten effekt wird die release-phase der +'' : adsr-hüllkurve eingeleitet, um ihn zu beenden +''eingabe : - +''ausgabe : - +''busprotokoll : [109][get.chan] +'' : chan - 0/1 stereokanal auf dem der effekt abgespielt werden soll + + chan := bus_getchar 'channelnummer lesen + hss.sfx_keyoff(chan) + +PRI sfx_stop | chan 'sfx: effekt sofort beenden +''funktionsgruppe : sfx +''funktion : der aktuell abgespielte effekt wird sofort beendet +''eingabe : - +''ausgabe : - +''busprotokoll : [110][get.chan] +'' : chan - 0/1 stereokanal auf dem der effekt abgespielt werden soll + + chan := bus_getchar 'channelnummer lesen + hss.sfx_stop(chan) + +PRI hss_vol 'hss: volume 0..15 einstellen +''funktionsgruppe : hss +''funktion : lautstärke des hss-players wird eingestellt +''eingabe : - +''ausgabe : - +''busprotokoll : [106][get.vol] +'' : vol - 0..15 gesamtlautstärke des hss-players + hss.hmus_vol(bus_getchar) + +PRI hss_intreg | regnr,wert 'hss: auslesen der player-register +''funktionsgruppe : hss +''funktion : abfrage eines hss-playerregisters (16bit) durch regnatix +''eingabe : - +''ausgabe : - +''busprotokoll : [105][get.regnr][put.reghwt][put.regnwt] +'' : regnr - 0..24 (5 x 5 register) +'' : reghwt - höherwertiger teil des 16bit-registerwertes +'' : regnwt - niederwertiger teil des 16bit-registerwertes +'' +''0 iEndFlag iRowFlag iEngineC iBeatC iRepeat globale Playerwerte +''5 iNote iOktave iVolume iEffekt iInstrument Soundkanal 1 +''10 iNote iOktave iVolume iEffekt iInstrument Soundkanal 2 +''15 iNote iOktave iVolume iEffekt iInstrument Soundkanal 3 +''20 iNote iOktave iVolume iEffekt iInstrument Soundkanal 4 +'' +''iEndFlag Repeat oder Ende wurde erreicht +''iRowFlag Trackerzeile (Row) ist fertig +''iEngineC Patternzähler +''iBeatC Beatzähler (Anzahl der Rows) +''iRepeat Zähler für Loops + + regnr := bus_getchar 'registernummer einlesen + wert := hss.intread(regnr) + bus_putchar(wert >> 8) '16-bit-wert senden hsb/lsb + bus_putchar(wert) + +PRI hss_peek 'hss: zugriff auf alle internen playerregister +''funktionsgruppe : hss +''funktion : zugriff auf die internen playerregister; leider sind die register +'' : nicht dokumentiert; 48 long-register +''eingabe : - +''ausgabe : - +''busprotokoll : [104][get.regnr][sub_putlong.regwert] +'' : regnr - registernummer +'' : regwert - long + + sub_putlong(hss.peek(bus_getchar)) + +PRI hss_load | err 'hss: musikdatei in puffer laden +''funktionsgruppe : hss +''funktion : hss-datei wird in den modulpuffer geladen +''eingabe : - +''ausgabe : - +''busprotokoll : [100][sub_getstr.fn][put.err] +'' : fn - dateiname +'' : err - fehlernummer entspr. liste + + sub_getstr 'dateinamen einlesen + err := \sdfat.openFile(@tbuf, "r") 'datei öffnen + bus_putchar(err) 'ergebnis der operation senden + if err == 0 + outa[LED_OPEN] := 1 + \sdfat.readData(@bgmusic, MPLEN) 'datei laden + \sdfat.closeFile + outa[LED_OPEN] := 0 + + +CON ''------------------------------------------------- WAV-FUNKTIONEN + +PRI sdw_start | err 'sdw: startet extra cog mit sdwav-engine +''funktionsgruppe : sdw +''funktion : wav-datei von sd-card abspielen +''eingabe : - +''ausgabe : - +''busprotokoll : [150][sub.getstr][put.err] +'' : err - fehlernummer entspr. liste + + + sub_getstr 'dateinamen empfangen + err := \sdfat.openFile(@tbuf, "r") 'datei öffnen + bus_putchar(err) 'ergebnis der operation senden + if err == 0 'player starten + runPlayerFlag := 0 + PlayCog := cognew(sdw_player,@PlayStack) 'player-cog starten + +PRI sdw_stop 'sdw: stopt cog mit sdwav-engine +''funktionsgruppe : sdw +''funktion : wav-player signal zum stoppen senden +'' : wartet bis player endet und quitiert erst dann +''eingabe : - +''ausgabe : - +''busprotokoll : [151][put.err] +'' : err - fehlernummer entspr. liste + + runPlayerFlag := 1 + repeat until fl_sdwav == 0 + bus_putchar(0) + + +PRI sdw_status 'sdw: sendet status des wav-players +''funktionsgruppe : sdw +''funktion : status des wav-players abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [152][put.status] +'' : status - status des wav-players +'' : 0: wav fertig (player beendet) +'' : 1: wav wird abgespielt + + bus_putchar(fl_sdwav) + +PRI sdw_player 'sdw: player-cog +''funktionsgruppe : sdw +''funktion : player-cog +'' : - diese routine wird in einer extra-cog gestartet +'' : - beschickt die DACEngine mit den sounddaten aus der +'' : geöffneten datei +'' : +''eingabe : geöffnete wav-datei +''ausgabe : - +''ACHTUNG : während der player aktiv ist (fl_sdwav == 1) ist die sd-card +'' : exclusiv belegt! jede dateioperation führt zum crash von +'' : administra! + + dira[LED_OPEN] := 1 + fl_sdwav := 1 'flag setzen das player aktiv ist + 'headerdaten einlesen + \sdfat.setCharacterPosition(22) + wav.changeNumberOfChannels(result := (sdfat.readCharacter | (sdfat.readCharacter << 8))) + wav.changeSampleRate(sdfat.readCharacter | (sdfat.readCharacter << 8) | (sdfat.readCharacter << 16) | (sdfat.readCharacter << 24)) + \sdfat.setCharacterPosition(34) + wav.changeBitsPerSample(result := (sdfat.readCharacter | (sdfat.readCharacter << 8))) + wav.changeSampleSign(result == 16) + wav.changeLeftChannelVolume(leftVolume) + wav.changeRightChannelVolume(rightVolume) + \sdfat.setCharacterPosition(40) + wavLen := (\sdfat.listSize - 44) / 512 'abfrage der dateigröße, ist robuster als der dateiheader, da einige + 'den header nicht richtig setzen! + wavPointer := 0 + wav.startPlayer + 'wav abspielen + repeat (wavLen) + !outa[LED_OPEN] + \sdfat.readData(result := wav.transferData, 512) + wavPointer++ + case runPlayerFlag + 1: quit 'player stoppen + 2: wav.changeLeftChannelVolume(0) 'player pause + wav.changeRightChannelVolume(0) + repeat while runPlayerFlag == 2 + wav.changeLeftChannelVolume(leftVolume) + wav.changeRightChannelVolume(rightVolume) + +' if runPlayerFlag 'signal player stoppen? +' quit + + 'player beednen + wav.stopPlayer 'dacengine signal stop senden + wav.clearData + \sdfat.closeFile + fl_sdwav := 0 'flag setzen player inaktiv + dira[LED_OPEN] := 0 + +PRI sdw_leftvol 'sdw: lautstärke links +''funktionsgruppe : sdw +''funktion : lautstärke links einstellen +''eingabe : - +''ausgabe : - +''busprotokoll : [153][get.vol] +'' : vol - lautstärke 0..100 + + leftVolume := bus_getchar + +PRI sdw_rightvol 'sdw: lautstärke rechts +''funktionsgruppe : sdw +''funktion : lautstärke rechts einstellen +''eingabe : - +''ausgabe : - +''busprotokoll : [154][get.vol] +'' : vol - lautstärke 0..100 + + rightVolume := bus_getchar + +PRI sdw_pause 'sdw: versetzt player in pause-modus +''funktionsgruppe : sdw +''funktion : wav-player signal zum für pause/weiter +'' : +''eingabe : - +''ausgabe : - +''busprotokoll : [155][put.err] +'' : err - fehlernummer entspr. liste + + case runPlayerFlag + 0: runPlayerFlag := 2 + 2: runPlayerFlag := 0 + bus_putchar(0) + +PRI sdw_position 'sdw: position des players abfragen +''funktionsgruppe : sdw +''funktion : position des players abfragen +'' : +''eingabe : - +''ausgabe : - +''busprotokoll : [156][sub_putlong.pointer][sub_putlong.len] +'' : pointer - position des players im wav / 512 +'' : len - länge der wav / 512 + + sub_putlong(wavPointer) + sub_putlong(wavLen) + +CON ''------------------------------------------------- RTC-FUNKTIONEN + +PRI rtc_getSeconds 'rtc: Returns the current second (0 - 59) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [041][sub_putlong.seconds] +'' : seconds - current second (0 - 59) + sub_putlong(rtc.getSeconds) + +PRI rtc_getMinutes 'rtc: Returns the current minute (0 - 59) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [042][sub_putlong.minutes] +'' : minutes - current minute (0 - 59) + sub_putlong(rtc.getMinutes) + +PRI rtc_getHours 'rtc: Returns the current hour (0 - 23) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [043][sub_putlong.hours] +'' : hours - current hour (0 - 23) + sub_putlong(rtc.getHours) + +PRI rtc_getDay 'rtc: Returns the current day of the week (1 - 7) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [044][sub_putlong.day] +'' : day - current day (1 - 7) of the week + sub_putlong(rtc.getDay) + +PRI rtc_getDate 'rtc: Returns the current date (1 - 31) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [045][sub_putlong.date] +'' : date - current date (1 - 31) of the month + sub_putlong(rtc.getDate) + +PRI rtc_getMonth 'rtc: Returns the current month (1 - 12) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [046][sub_putlong.month] +'' : month - current month (1 - 12) + sub_putlong(rtc.getMonth) + +PRI rtc_getYear 'rtc: Returns the current year (2000 - 2099) from the real time clock. +''funktionsgruppe : rtc +''busprotokoll : [047][sub_putlong.year] +'' : year - current year (2000 - 2099) + sub_putlong(rtc.getYear) + +PRI rtc_setSeconds : seconds 'rtc: Sets the current real time clock seconds. +''funktionsgruppe : rtc +''busprotokoll : [048][sub_getlong.seconds] +'' : seconds - Number to set the seconds to between 0 - 59. + rtc.setSeconds(sub_getlong) + +PRI rtc_setMinutes : minutes 'rtc: Sets the current real time clock minutes. +''funktionsgruppe : rtc +''busprotokoll : [049][sub_getlong.minutes] +'' : minutes - Number to set the minutes to between 0 - 59. + rtc.setMinutes(sub_getlong) + +PRI rtc_setHours 'rtc: Sets the current real time clock hours. +''funktionsgruppe : rtc +''busprotokoll : [050][sub_getlong.hours] +'' : hours - Number to set the hours to between 0 - 23.51: + rtc.setHours(sub_getlong) + +PRI rtc_setDay 'rtc: Sets the current real time clock day. +''funktionsgruppe : rtc +''busprotokoll : [051][sub_getlong.day] +'' : day - Number to set the day to between 1 - 7. + rtc.setDay(sub_getlong) + +PRI rtc_setDate 'rtc: Sets the current real time clock date. +''funktionsgruppe : rtc +''busprotokoll : [052][sub_getlong.date] +'' : date - Number to set the date to between 1 - 31. + rtc.setDate(sub_getlong) + +PRI rtc_setMonth 'rtc: Sets the current real time clock month. +''funktionsgruppe : rtc +''busprotokoll : [053][sub_getlong.month] +'' : month - Number to set the month to between 1 - 12. + rtc.setMonth(sub_getlong) + +PRI rtc_setYear 'rtc: Sets the current real time clock year. +''funktionsgruppe : rtc +''busprotokoll : [054][sub_getlong.year] +'' : year - Number to set the year to between 2000 - 2099. + rtc.setYear(sub_getlong) + +PRI rtc_setNVSRAM | index, value 'rtc: Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). +''funktionsgruppe : rtc +''busprotokoll : [055][sub_getlong.index][sub_getlong.value] +'' : index - The location in NVRAM to set (0 - 55). │ +'' : value - The value (0 - 255) to change the location to. │ + index := sub_getlong + value := sub_getlong + rtc.setNVSRAM(index, value) + +PRI rtc_getNVSRAM 'rtc: Gets the selected NVSRAM value at the index (0 - 55). +''funktionsgruppe : rtc +''busprotokoll : [056][sub_getlong.index][sub_getlong.value] +'' : index - The location in NVRAM to get (0 - 55). │ + sub_putlong(rtc.getNVSRAM(sub_getlong)) + +PRI rtc_pauseForSeconds 'rtc: Pauses execution for a number of seconds. +''funktionsgruppe : rtc +''busprotokoll : [057][sub_getlong.number][sub_putlong.number] +'' : Number - Number of seconds to pause for between 0 and 2,147,483,647. +'' : Returns a puesdo random value derived from the current clock frequency and the time when called. + + sub_putlong(rtc.pauseForSeconds(sub_getlong)) + +PRI rtc_pauseForMilliseconds 'rtc: Pauses execution for a number of milliseconds. +''funktionsgruppe : rtc +''busprotokoll : [058][sub_getlong.number][sub_putlong.number] +'' : Number - Number of milliseconds to pause for between 0 and 2,147,483,647. +'' : Returns a puesdo random value derived from the current clock frequency and the time when called. + sub_putlong(rtc.pauseForMilliseconds(sub_getlong)) + +DAT 'dummyroutine für getcogs + org +' +' Entry: dummy-assemblercode fuer cogtest +' +entry jmp entry 'just loops + + + +DAT 'feste sfx-slots + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa +SoundFX1 byte $01, $FF, $80, $0F, $0F, $00, $07, $90 + 'Att 'Dec 'Sus 'Rel + byte $FF, $10, $00, $FF + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa +SoundFX2 byte $05, $FF, $00, $0F, $04, $FF, $01, $05 + 'Att 'Dec 'Sus 'Rel + byte $F1, $24, $00, $FF + '16step Sequencer Table + byte $F1, $78, $3C, $00, $00, $00, $F1, $78, $3C, $00, $00, $00, $00, $00, $00, $00 + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa 'Heartbeat +SoundFX3 byte $00, $FF, $06, $0F, $09, $FF, $04, $05 + 'Att 'Dec 'Sus 'Rel + byte $F1, $F4, $F0, $0F + byte $F1, $78, $3C, $00, $00, $00, $F1, $78, $3C, $00, $00, $00, $00, $00, $00, $00 + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa 'Heartbeat low +SoundFX4 byte $00, $FE, $06, $0f, $15, $FF, $04, $05 + 'Att 'Dec 'Sus 'Rel + byte $F1, $F4, $F0, $0F + byte $F1, $78, $3C, $00, $00, $00, $F1, $78, $3C, $00, $00, $00, $00, $00, $00, $00 + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa 'Telefon +SoundFX5 byte $05, $15, $4F, $0F, $01, $04, $05, $00 + 'Att 'Dec 'Sus 'Rel + byte $FF, $00, $00, $FF + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa +SoundFX6 byte $06, $FF, $5F, $0F, $01, $03, $01, $00 'Teleport + 'Att 'Dec 'Sus 'Rel + byte $FF, $14, $00, $FF + +SoundFX7 'pling +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $04,$01,$80,$0F,$00,$00,$00,$00,$FF,$00,$00,$80 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +SoundFX8 'on +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $00,$05,$10,$0F,$08,$02,$05,$00,$FF,$00,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +SoundFX9 'off +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $00,$05,$33,$0F,$05,$03,$10,$00,$FF,$00,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, PRIlish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + diff --git a/flash/bellatrix/belf-tv.spin b/flash/bellatrix/belf-tv.spin new file mode 100644 index 0000000..a8827a4 --- /dev/null +++ b/flash/bellatrix/belf-tv.spin @@ -0,0 +1,132 @@ +{{ TV-Spezifika für belflash + +}} + +CON + +COLS = 40 +ROWS = 13 +TLINES_PER_ROW = 1 +DEFAULT_Y0 = 0 ' bei 13 Zeilen ist kein Platz für eine dauerhafte Überschrift +SPACETILE = $220 + +TV_BASPORT = 23 + +OBJ + + tv : "bel-tv" + +CON + +TV_COUNT = 14 ' Anzahl der long-Variablen ab tv_status + +VAR + + long colors[8 * 2] + + long tv_status '0/1/2 = off/invisible/visible read-only (14 longs) + long tv_enable '0/non-0 = off/on write-only + long tv_pins '%pppmmmm = pin group, pin group mode write-only + long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_ht 'horizontal tiles write-only + long tv_vt 'vertical tiles write-only + long tv_hx 'horizontal tile expansion write-only + long tv_vx 'vertical tile expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + long vid_arr ' Kopie des Pointers auf den "Bildwiederholspeicher" + long ccolor ' aktuelle Anzeigefarbe + +PUB start(array) + vid_arr := array + start_tv(TV_BASPORT, array) + +PUB start_tv(basepin, array) : okay + +'' Start terminal - starts a cog +'' returns false if no cog available + + setcolors(@palette) + 'out(0) + + longmove(@tv_status, @tv_params, TV_COUNT) + tv_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101 + tv_screen := array + tv_colors := @colors + + okay := tv.start(@tv_status) + +PUB setcolors(colorptr) | i, fore, back + +'' Override default color palette +'' colorptr must point to a list of up to 8 colors +'' arranged as follows: +'' +'' fore back +'' ------------ +'' palette byte color, color 'color 0 +'' byte color, color 'color 1 +'' byte color, color 'color 2 +'' ... + + repeat i from 0 to 7 + fore := byte[colorptr][i << 1] + back := byte[colorptr][i << 1 + 1] + colors[i << 1] := fore << 24 + back << 16 + fore << 8 + back + colors[i << 1 + 1] := fore << 24 + fore << 16 + back << 8 + back + + +PUB set_dscr(scr_ptr) + tv_screen := scr_ptr + +PUB get_color(cnr) + return long[colors][cnr & $F] + +PUB set_color(cnr, colr) + long[colors][cnr & $F] := colr + +PUB set_ccolor(colr) + ccolor := colr + +PUB get_ccolor + return ccolor + +PUB schar(offset, c) + word[vid_arr][offset] := (ccolor << 1 + c & 1) << 10 + $200 + c & $FE + + +DAT + +tv_params long 0 'status + long 1 'enable + long 0 'pins + long %10010 'mode + long 0 'screen + long 0 'colors + long cols 'hc + long rows 'vc + long 4 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 0 'broadcast + long 0 'auralcog + + + ' fore back + ' color color +palette byte $07, $0A '0 white / dark blue + byte $07, $BB '1 white / red + byte $9E, $9B '2 yellow / brown + byte $04, $07 '3 grey / white + byte $3D, $3B '4 cyan / dark cyan + byte $6B, $6E '5 green / gray-green + byte $BB, $CE '6 red / pink + byte $3C, $0A '7 cyan / blue + + diff --git a/flash/bellatrix/belf-vga.spin b/flash/bellatrix/belf-vga.spin new file mode 100644 index 0000000..34b45e8 --- /dev/null +++ b/flash/bellatrix/belf-vga.spin @@ -0,0 +1,310 @@ +{{ VGA-Spezifika für belflash + +}} + +CON + +COLS = 64 +ROWS = 48 +TLINES_PER_ROW = 2 +DEFAULT_Y0 = TLINES_PER_ROW ' 1 Zeile Platz lassen für HIVE-Logo +COLORANZ = 8 +SPACETILE = $8000 + $20 << 6 + +VGA_BASPORT = 8 'vga startport + +OBJ + + vga : "bel-vga" + +VAR + + long vid_arr ' Kopie des Pointers auf den "Bildwiederholspeicher" + long ccolor ' aktuelle Anzeigefarbe + +PUB start(array) + vid_arr := array + vga.start(VGA_BASPORT, array, @vgacolors, 0, 0, 0) 'vga-treiber starten + +PUB set_dscr(scr_ptr) + vga.set_scrpointer(scr_ptr) 'screenpointer für den displaytreiber neu setzen + +PUB get_color(cnr) + return long[@vgacolors][cnr] + +PUB set_color(cnr, colr) + long[@vgacolors][cnr] := colr + +PUB set_ccolor(colr) + ccolor := colr + +PUB get_ccolor + return ccolor + +PUB schar(offset, c) | i + i := $8000 + (c & $FE) << 6 + (ccolor << 1 + c & 1) + word[vid_arr][offset] := i 'oberes tile setzen + word[vid_arr][offset + cols] := i | $40 'unteres tile setzen + + +DAT +{{ + +'' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down, +'' which will serve as the tile array. Each word specifies a tile bitmap and +'' a color palette for its tile area. The top 10 bits of each word form the +'' base address of a 16-long tile bitmap, while the lower 6 bits select a +'' color palette for the bitmap. For example, $B2E5 would specify the tile +'' bitmap spanning $B2C0..$B2FF and color palette $25. + +'' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data +'' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0 +'' providing the color data for pixel values %11..%00, respectively: +'' +'' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold +'' + %% ist quaternary-darstellung; jedes digit von 0 bis 3, also 4-wertigkeit + + bildaufbau: 24 zeilen zu je 64 zeichen; jedes zeichen wird durch zwei tiles gebildet + die ?bereinander liegen. + jedes tile belegt ein word: 10 bit bitmap und 6 bit color. zwei tiles ein long. + + +'0 %%RGBx_RGBx_RGBx_RGBx + long %%0330_0010_0330_0010 + long %%0330_0330_0010_0010 + + + long $3C043C04 'grau/blau erste - hive-version + long $3C3C0404 + +Color-Calculator: + +http://www.rayslogic.com/propeller/Programming/Colors.htm + +For the 1024x768 VGA tile driver: +2 longs are required for each text foreground/background color combo, arranged as: + $ff_bb_ff_bb + $ff_ff_bb_bb + where 'ff' is the foreground color and 'bb' is the background color + 2 longs needed because characters are in an interleaved pair + The first long is the color for the first character in a pair, the second long is for the second character in a pair. + Demo routine "print()" only allows for 8 fore/back combinations (using longs 0 to 15) + +1 long required for box colors, arranged as: + $tl_br_fi_bb + where 'tl' is top-left edge, 'br' is bottom-right edge, 'fi' is focus indicators, and 'bb' is background color + The demo "box()" procedure hardwired to add 16 to input color number to pick box color and adds 5 to input + color number to pick text color for box... + So, "box(left,top,clr,str)" uses color number 16+clr for box colors and 5+clr for text color. You probably want + the 'bb' background colors of these two to match! Note that this limits you to 4 box colors. + +1 long used for graphics colors, arranged as + $00_11_22_33 + where 00,11,22,33 are the selectable graphics colors 0,1,2,3 + Demo hardwired to use the 21st long (last one) for the graphics colors + +The Propeller's "tile driver" video uses 32-bit (long) values to define a four color palette +The "color_ptr" parameter, given to the tile driver, specifies the location of the data block of up to 64 different +long palette values +Each long palette represents 4 different colors, one byte each. Each color byte uses 2 bits for each primary colors, +RGB, arranged as RGBx. The "x" represents the two least significant bits, which are ignored. +Parallax gives this example of a 32-bit long palette, represented as a 16-digit quaternary (2-bit) number: + %%3330_0110_0020_3300 or $FC1408F0 +The first byte, %%3330 (binary %11111100), is the color white +The second byte, %%0110, is the color dark cyan + +}} + +vgacolors long 'farbpalette + +'============================================================ +' v h v h ' v=Vordergrund, h=Hintergrund +' long $ 3C 04 3C 04 'Muster +' v v h h +' long $ 3C 3C 04 04 'Muster +'0 %%RGBx_RGBx_RGBx_RGBx +' long %%0330_0010_0330_0010 +' long %%0330_0330_0010_0010 +'============================================================ + +'set 1 - grau auf weiß +{ + long $54FC54FC 'grau/weiß + long $5454FCFC + long $58FC58FC 'hellblau/weiß + long $5858FCFC + long $64FC64FC 'hellgrün/weiß + long $6464FCFC + long $94FC94FC 'hellrot/weiß + long $9494FCFC + long $00FC00FC 'schwarz/weiß + long $0000FCFC + long $0CFC0CFC 'blau/weiß + long $0C0CFCFC + long $30FC30FC 'grün/weiß + long $3030FCFC + long $C0FCC0FC 'rot/weiß + long $C0C0FCFC + + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + +'set 2 - weiß auf schwarz +{ + long $FC00FC00 'schwarz/weiß + long $FCFC0000 + long $A800A800 'schwarz/hellgrau + long $A8A80000 + long $54005400 'schwarz/dunkelgrau + long $54540000 + long $30043004 'grün/blau + long $30300404 + long $043C043C 'Color 0 reverse + long $04043C3C + long $FC04FC04 'weiss/blau + long $FCFC0404 + long $FF80FF80 'red/white + long $FFFF8080 + long $88048804 'magenta/blau + long $88880404 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + + +'set 3 - hellblau auf dunkelblau +{ + long $3C043C04 'grau/blau erste - hive-version + long $3C3C0404 + long $F004F004 'yellow/blue + long $F0F00404 + long $C004C004 'rot/blau + long $C0C00404 + long $30043004 'grün/blau + long $30300404 + long $043C043C 'Color 0 reverse + long $04043C3C + long $FC04FC04 'weiss/blau + long $FCFC0404 + long $FF80FF80 'red/white + long $FFFF8080 + long $88048804 'magenta/blau + long $88880404 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + +'set 4 - chess +{ +'0..1: text color 0: + long $F010F010 '0: Yellow on Green + long $F0F01010 +'2..3: text color 1: + long $C0FCC0FC '1: red on white + long $C0C0FCFC +'4..5: text color 2: + long $00FC00FC '2: black on white + long $0000FCFC + +'6..7: text color 3: + long $F010F010 '3: Yellow on Green + long $F0F01010 + + long $043C043C 'Color 0 reverse + long $04043C3C + long $FC04FC04 'weiss/blau + long $FCFC0404 + long $FF80FF80 'red/white + long $FFFF8080 + long $88048804 'magenta/blau + long $88880404 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + +'set 5 - grün auf schwarz +' v h v h ' v=Vordergrund, h=Hintergrund +' long $ 3C 04 3C 04 'Muster +' v v h h +' long $ 3C 3C 04 04 'Muster + + long $30003000 'color 0: grün auf schwarz + long $30300000 + + long $C000C000 'color 1: rot auf schwarz + long $C0C00000 + + long $0C000C00 'color 2: blau auf schwarz + long $0C0C0000 + + long $E000E000 'color 3: gelb auf schwarz + long $E0E00000 + + long $D000D000 'color 4: orange auf schwarz + long $D0D00000 + + long $3C003C00 'color 5: cyan auf schwarz + long $3C3C0000 + + long $FC00FC00 'color 6: weiß auf schwarz + long $FCFC0000 + + long $C800C800 'color 7: magenta auf schwarz + long $C8C80000 + + + long $00300030 'color 8: schwarz auf grün + long $00003030 + + long $00C000C0 'color 9: schwarz auf rot + long $0000C0C0 + + long $000C000C 'color 10: schwarz auf blau + long $00000C0C + + long $00E000E0 'color 11: schwarz auf gelb + long $0000E0E0 + + long $00D000D0 'color 12: schwarz auf orange + long $0000D0D0 + + long $003C003C 'color 13: schwarz aufcyan + long $00003C3C + + long $00FC00FC 'color 14: schwarz auf weiß + long $0000FCFC + + long $00C800C8 'color 15: schwarz auf magenta + long $0000C8C8 + + diff --git a/flash/bellatrix/belflash.spin b/flash/bellatrix/belflash.spin new file mode 100644 index 0000000..9a78a6c --- /dev/null +++ b/flash/bellatrix/belflash.spin @@ -0,0 +1,977 @@ +{{ VGA-MULTISCREEN +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : Hive +Name : VGA-Text-Treiber 1024x768 Pixel, 64x24 Zeichen +Chip : Bellatrix +Typ : Treiber +Version : 00 +Subversion : 01 +Funktion : Standard VGA-Text- und Tastatur-Treiber + +Dieser Bellatrix-Code kann als Stadardcode im EEPROM gespeichert werden und bietet drei getrennt +ansteuerbare Textbildschirme und Tastaturfunktionen. Mit dem integrierten Loader kann Bellatrix +mit einem beliebigen andern Code geladen werden. + +Komponenten : VGA 1024x768 Tile Driver v0.9 Chip Gracey MIT + PS/2 Keyboard Driver v1.0.1 Chip Gracey, ogg MIT + +COG's : MANAGMENT 1 COG + VGA 2 COG's + KEYB 1 COG + ------------------- + 4 COG's + +oder : MANAGMENT 1 COG + TV 1 COG + KEYB 1 COG + ------------------- + 3 COG's + + +Logbuch : + +23-10-2008-dr235 - erste funktionsfähige version erstellt + - cursor eingebaut +06-11-2008-dr235 - keyb auf deutsche zeichenbelegung angepasst (ohne umlaute) +24-11-2008-dr235 - tab, setcur, pos1, setx, sety, getx, gety, setcol, sline, screeninit + curon, curoff + - beltest +13-03-2009-dr235 - LF als Zeichencode ausgeblendet +22-03-2009-dr235 - abfrage für statustasten eingefügt +05-09-2009-dr235 - abfrage der laufenden cogs eingefügt + - deutschen tastaturtreiber mit vollständiger belegung! von ogg eingebunden +22-03-2010-dr235 - anpassung trios +01-05-2010-dr235 - scrollup/scrolldown eingebunden & getestet +03-05-2010-dr235 - settab/getcols/getrows/getresx/getresy eingefügt & getestet + - hive-logo eingefügt +------------------- +26-01-2011-dr235 - übernahme und anpassung des treibers aus trios +31-01-2011-dr235 - backspace als direktes steuerzeichen ($C8) eingefügt +01-02-2011-dr235 - multiscreenfähigkeit implementiert + - 88 - mgr_wscr: steuert, in welchen screen zeichen geschrieben werden + - 89 - mgr_dscr: steuert welcher screen angezeigt wird +05-02-2011-dr235 - umwandlung backspace $c8 --> $08 +06-03-2011-dr235 - revision der steuercodes; nur noch funktionen mit parameter + werden über eine 0-sequenz aufgerufen, alle anderen steuerzeichen + werden auf 1-byte-zeichen abgebildet +20-04-2011-dr235 - integration einer kompatiblen loaderroutine, damit kann der treiber + jetzt direkt aus dem rom gestartet und dennoch bella-code nachgeladen + werden kann +31.12.2011-dr235 - anpassung für verschiedene zeilenumbrüche in print_char eingefügt +28.06.2012-dr235 - fehler im loader behoben (cog0 wurde nicht in allen fällen beendet) + dank dafür geht an pic :) +02-10-2012-uheld - verzögertes Scrolling bei abgeschaltetem Cursor +21-10-2012-uheld - Window-Funktionen +28-11-2012-uheld - wahlweise Einbindung von VGA- oder TV-Treiber über #define +15-04-2013-dr235 - konstanten für bellatrix-funktionen komplett ausgelagert + +Notizen: +- setheader + +ACHTUNG: Mit VGA-Treiber ist row nicht die Zeilenposition, da zwei Tiles untereinander ein +Zeichen bilden. Vielmehr ist die reale Zeilenposition row/2. +...oder allgemeingültig für VGA und TV: row/vdrv#TLINES_PER_ROW + + +}} + +{{ STEUERCODES + +Byte1 Byte2 Byte3 Byte4 Byte5 + +0 1 get.stat KEY_STAT Tastaturstatus abfragen +0 2 get.key KEY_CODE Tastaturcode abfragen +0 3 $01 put.curchar SETCUR Cursorzeichen setzen +0 3 $02 put.col SETX Cursor in Spalte n setzen +0 3 $03 put.row SETY Cursor in Zeile n setzen +0 3 $04 get.col GETX Cursorspalte abfragen +0 3 $05 get.row GETY Cursorzeile abfragen +0 3 $06 put.color SETCOL Farbe setzen +0 3 $09 SINIT Screeninit +0 3 $0A put.tabnr put.tabpos TABSET Tabulatoren setzen +0 4 get.keyspec KEY_SPEC Sondertasten abfragen +0 5 put.x put.y SCR_LOGO Hive-Logo anzeigen +0 6 put.char SCR_CHAR Zeichen ohne Steuerzeichen ausgeben + +0 58 put.wscrnr MGR_WSCR Schreibscreen setzen +0 59 put.wscrnr MGR_DSCR Anzeigescreen setzen +0 5A put.cnr getlong.color MGR_GETCOLOR Farbregister auslesen +0 5B put.cnr putlong.color MGR_SETCOLOR Farbregister setzen +0 5C getlong.resx MGR_GETRESX Abfrage der X-Auflösung +0 5D getlong.resy MGR_GETRESY Abfrage der Y-Auflösung +0 5E get.cols MGR_GETCOLS Abfrage der Textspalten +0 5F get.rows MGR_GETROWS Abfrage der Textzeilen +0 60 get.cogs MGR_GETCOGS Abfrage der anzahl belegter COG's +0 61 getlong.spec MGR_GETSPEC Abfrage der Funktionsspezifikationen +0 62 getlong.ver MGR_GETVER Abfrage der Version +0 63 MGR_LOAD Bellatrix-Code laden + +$01 CLS Bildschirm löschen +$02 HOME Cursor in obere linke Ecke +$03 POS1 Cursor an Zeilenanfang setzen +$04 CURON Cursor anschalten +$05 CUROFF Cursor abschalten +$06 SCRLUP Zeile nach oben scrollen +$07 SCRLDOWN Zeile nach unten scrollen +$08 BS Rückschritt (Backspace) +$09 TAB Tabulatorschritt + +$0A..FF CHAR Zeichenausgabe + + +}} + +'#define __TV +'#define __VGA + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_02_02 + +#ifdef __TV +CHIP_SPEC = gc#b_tv|gc#b_key|gc#b_txt|gc#b_win +#endif +#ifdef __VGA +CHIP_SPEC = gc#b_vga|gc#b_key|gc#b_txt|gc#b_win +#endif + +RESX = vdrv#COLS * 16 +RESY = vdrv#ROWS * 16 + +TILES = vdrv#COLS * vdrv#ROWS + +USERCHARS = 16 '8x2 logo + +TABANZ = 8 +SCROLLDIFF = vdrv#TLINES_PER_ROW * vdrv#COLS + +CURSORCHAR = $0E 'cursorzeichen +SCREENS = 3 'anzahl der screens +WIN_P_SCR = 8 'Anzahl der Windows per Screen + + +OBJ + +#ifdef __TV + vdrv : "belf-tv" +#endif +#ifdef __VGA + vdrv : "belf-vga" +#endif + keyb : "bel-keyb" + bus : "bel-bus" + gc : "glob-con" 'globale konstanten + +VAR + + long wind 'index des screens, in welchen aktuell geschrieben wird + long dind 'index des screens, der aktuell dargestellt wird + long keycode 'letzter tastencode + long array[TILES/vdrv#TLINES_PER_ROW*SCREENS] 'bildschirmpuffer + byte tab[TABANZ] 'tabulatorpositionen + word user_charbase 'adresse der userzeichen + byte wscrnr 'nummer ausgabescreens + word lchar 'letztes zeichen + byte this_win[SCREENS] 'Nr. des aktuellen Windows pro Screen + + byte col[SCREENS*WIN_P_SCR] 'spaltenposition + byte row[SCREENS*WIN_P_SCR] 'zeilenposition + long color[SCREENS*WIN_P_SCR] 'zeichenfarbe + byte cursor[SCREENS*WIN_P_SCR] 'cursorzeichen + byte curstat[SCREENS*WIN_P_SCR] 'cursorstatus 1 = ein + byte needs_nl[SCREENS] 'Flag für verzögertes newline, falls curoff + ' needs_nl ist ein Bit-Feld!! WIN_P_SCR darf deshalb nicht >8 sein!! + byte nnl_idx 'Bitmaske für Operationen auf needs_nl + byte windows[SCREENS*WIN_P_SCR*4] 'Window-Grenzen (x0,y0,xn,yn pro Window) + + byte ccol, crow 'current... werden durch win_set gefüllt +' long ccolor ' muss in vdrv definiert werden!! 'current... werden durch win_set gefüllt + byte ccursor, ccurstat 'current... + byte cwcols, cwrows 'current..., Breite und Höhe des aktuellen Window + byte cx0, cy0, cxn, cyn 'Koordinaten des aktuellen Windows + byte cneeds_nl + + long plen 'länge datenblock loader + byte proghdr[16] 'puffer für objektkopf + +CON ''------------------------------------------------- BELLATRIX + + +PUB main | zeichen,n 'chip: kommandointerpreter +''funktionsgruppe : chip +''funktion : kommandointerpreter +''eingabe : - +''ausgabe : - + + init_subsysteme 'bus/vga/keyboard/maus initialisieren + repeat + zeichen := bus.getchar '1. zeichen empfangen + if zeichen ' > 0 + print_char(zeichen) + else + zeichen := bus.getchar '2. zeichen kommando empfangen + case zeichen + gc#b_keystat: key_stat 'tastaturstatus senden + gc#b_keycode: key_code 'tastaturzeichen senden + gc#b_printctrl: print_ctrl(bus.getchar) 'steuerzeichen ($100..$1FF) ausgeben + gc#b_keyspec: key_spec 'statustasten ($100..$1FF) abfragen + gc#b_printlogo: print_logo 'hive-logo ausgeben + gc#b_printqchar: pchar(bus.getchar) 'zeichen ohne steuerzeichen augeben +' ---------------------------------------------- WINDOW + gc#b_wdef: win_define + gc#b_wset: win_set(wscrnr) + gc#b_wgetcols: win_getcols + gc#b_wgetrows: win_getrows + gc#b_woframe: win_oframe +' ---------------------------------------------- CHIP-MANAGMENT + gc#b_mgrload: mgr_load 'neuen bellatrix-code laden + gc#b_mgrwscr: mgr_wscr 'setzt screen, in welchen geschrieben wird + gc#b_mgrdscr: mgr_dscr 'setzt screen, welcher angezeigt wird + gc#b_mgrgetcol: mgr_getcolor 'farbregister auslesen + gc#b_mgrsetcol: mgr_setcolor 'farbregister setzen + gc#b_mgrgetresx: mgr_getresx 'x-auflösung abfragen + gc#b_mgrgetresy: mgr_getresy 'y-auflösung abfragen + gc#b_mgrgetcols: mgr_getcols 'spaltenanzahl abfragen + gc#b_mgrgetrows: mgr_getrows 'zeilenanzahl abfragen + gc#b_mgrgetcogs: mgr_getcogs 'freie cogs abfragen + gc#b_mgrgetspec: mgr_getspec 'spezifikation abfragen + gc#b_mgrgetver: mgr_getver 'codeversion abfragen + gc#b_mgrreboot: reboot 'bellatrix neu starten + + +PUB init_subsysteme|i 'chip: initialisierung des bellatrix-chips +''funktionsgruppe : chip +''funktion : - initialisierung des businterface +'' : - vga & keyboard-treiber starten +''eingabe : - +''ausgabe : - + + bus.init_bus + keyb.start(gc#b_keybd, gc#b_keybc) 'tastaturport starten + + wind := dind := wscrnr := 0 'auf ersten screen stellen + repeat i from 0 to SCREENS-1 + screen_init(i) + set_current_win ' wscrnr = 0 --> Window 1 von Screen 0 aktivieren + + vdrv.start(@array) + repeat i from 0 to TABANZ-1 'tabulatoren setzen + tab[i] := i * 4 + + ' Ein schönes Logo gibt's z.Z. nur bei VGA + user_charbase := @uchar & $FFC0 'berechnet die nächste 64-byte-grenze hinter dem zeichensatz + longmove(user_charbase,@uchar,16*USERCHARS) 'verschiebt den zeichensatz auf die nächste 64-byte-grenze + + repeat i from 0 to SCREENS-1 + wind := TILES*i 'ausgabe-index berechnen + _print_logo(0,0) 'hive-logo anzeigen + schar(cursor[wscrnr]) 'cursor an + wind := 0 + +PRI screen_init(i) | x, w ' alle Windows von Screen i auf Standardgröße setzen, Window 1 wählen + wordfill(@array.word[i*TILES], vdrv#SPACETILE, tiles) ' CLS + cursor[i*WIN_P_SCR] := CURSORCHAR 'cursorzeichen setzen + curstat[i*WIN_P_SCR] := 1 'cursor anschalten + needs_nl[i] := 0 'darf nur am Bildschirmende 1 sein + x := i * WIN_P_SCR * 4 + windows[x++] := 0 ' x0 + windows[x++] := 0 ' y0 + windows[x++] := vdrv#COLS - 1 ' xn + windows[x++] := vdrv#ROWS - vdrv#TLINES_PER_ROW ' yn + repeat w from 1 to WIN_P_SCR - 1 + windows[x++] := 0 ' x0 + windows[x++] := vdrv#DEFAULT_Y0 ' y0 + windows[x++] := vdrv#COLS - 1 ' xn + windows[x++] := vdrv#ROWS - vdrv#TLINES_PER_ROW ' yn + cursor[i*WIN_P_SCR+w] := CURSORCHAR + curstat[i*WIN_P_SCR+w] := 1 + row[i*WIN_P_SCR+w] := vdrv#DEFAULT_Y0 'home + col[i*WIN_P_SCR+w] := 0 'pos1 + color[i*WIN_P_SCR+w] := 0 + this_win[i] := 1 + + +CON ''------------------------------------------------- CHIP-MANAGMENT-FUNKTIONEN + +PRI mgr_wscr|scrnr, oldscr 'cmgr: setzt screen, in welchen geschrieben wird +''funktionsgruppe : cmgr +''funktion : schaltet die ausgabe auf einen bestimmten screen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][088][get.wscrnr] +'' : wscrnr - nummer des screens 1..SCREENS + + scrnr := bus.getchar - 1 + if scrnr => 0 and scrnr < SCREENS + oldscr := wscrnr + wscrnr := scrnr + wind := TILES*wscrnr 'ausgabe-index berechnen + win_set_int(oldscr, this_win[wscrnr]) + +PRI mgr_dscr|scrnr 'cmgr: setzt screen, welcher angezeigt wird +''funktionsgruppe : cmgr +''funktion : schaltet die anzeige auf einen bestimmten screen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][089][get.scrnr] +'' : scrnr - nummer des screens 1..SCREENS + + scrnr := bus.getchar - 1 + if scrnr => 0 and scrnr < SCREENS +' dind := TILES * vdrv#TLINES_PER_ROW * scrnr 'display-index berechnen + dind := TILES * 2 * scrnr 'display-index berechnen + vdrv.set_dscr(@array+dind) + +PUB mgr_getcolor|cnr 'cmgr: farbregister auslesen +''funktionsgruppe : cmgr +''funktion : farbregister auslesen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][090][get.cnr][bus.putlong.color] +'' : cnr - nummer des farbregisters 0..15 +'' : color - erster wert + + cnr := bus.getchar + bus.putlong(vdrv.get_color(cnr)) + +PUB mgr_setcolor|cnr, colr 'cmgr: farbregister setzen +''funktionsgruppe : cmgr +''funktion : farbregister setzen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][091][get.cnr][bus.getlong.color] +'' : cnr - nummer des farbregisters 0..15 +'' : color - farbwert + + cnr := bus.getchar + colr := bus.getlong + vdrv.set_color(cnr, colr) + +PUB mgr_getresx 'cmgr: abfrage der x-auflösung +''funktionsgruppe : cmgr +''funktion : abfrage der x-auflösung +''eingabe : - +''ausgabe : - +''busprotokoll : [0][092][put.resx] +'' : resx - x-auflösung + + bus.putlong(RESX) + +PUB mgr_getresy 'cmgr: abfrage der y-auflösung +''funktionsgruppe : cmgr +''funktion : abfrage der y-auflösung +''eingabe : - +''ausgabe : - +''busprotokoll : [0][093][put.resy] +'' : resy - y-auflösung + + bus.putlong(RESY) + + +PUB mgr_getcols 'cmgr: abfrage der Textspalten +''funktionsgruppe : cmgr +''funktion : abfrage der textspalten +''eingabe : - +''ausgabe : - +''busprotokoll : [0][094][put.cols] +'' : cols - anzahl der textspalten + + bus.putchar(vdrv#COLS) + + +PUB mgr_getrows 'cmgr: abfrage der textzeilen +''funktionsgruppe : cmgr +''funktion : abfrage der textzeilen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][095][put.rows] +'' : rows - anzahl der textzeilen + + bus.putchar(vdrv#ROWS/vdrv#TLINES_PER_ROW) + +PUB mgr_getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind +''funktionsgruppe : cmgr +''funktion : abfrage wie viele cogs in benutzung sind +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [0][096][put.cogs] +'' : cogs - anzahl der belegten cogs + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + bus.putchar(cogs) + +PUB mgr_getspec 'cmgr: abfrage der spezifikation des chips +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [097][bus.putlong.spec] +'' : spec - spezifikation +'' +'' +'' +---------- +'' | +-------- window +'' | |+------- vektor +'' | ||+------ grafik +'' | |||+----- text +'' | ||||+---- maus +'' | |||||+--- tastatur +'' | ||||||+-- vga +'' | |||||||+- tv +''CHIP_SPEC = %00000000_00000000_00000000_10010110 + + bus.putlong(CHIP_SPEC) + +PUB mgr_getver 'cmgr: abfrage der version +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [098][bus.putlong.ver] +'' : ver - version +'' +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''CHIP_VER = $00_01_02_01 + + bus.putlong(CHIP_VER) + + +PUB mgr_load|i 'cmgr: bellatrix-loader +''funktionsgruppe : cmgr +''funktion : funktion um einen neuen code in bellatrix zu laden +'' +''bekanntes problem: einige wenige bel-dateien werden geladen aber nicht korrekt gestartet +''lösung: diese datei als eeprom-image speichern + +' kopf der bin-datei einlesen ------------------------------------------------------ + repeat i from 0 to 15 '16 bytes --> proghdr + byte[@proghdr][i] := bus.getchar + + plen := 0 + plen := byte[@proghdr + $0B] << 8 + plen := plen + byte[@proghdr + $0A] + plen := plen - 8 + +' objektlänge an regnatix senden + bus.putchar(plen >> 8) 'hsb senden + bus.putchar(plen & $FF) 'lsb senden + + repeat i from 0 to 7 'alle anderen cogs anhalten + ifnot i == cogid + cogstop(i) + + dira := 0 'diese cog vom bus trennen + cognew(@loader, plen) + + cogstop(cogid) 'cog 0 anhalten + +DAT + org 0 + +loader + mov outa, M_0 'bus inaktiv + mov dira, DINP 'bus auf eingabe schalten + mov reg_a, PAR 'parameter = plen + mov reg_b, #0 'adresse ab 0 + + ' datenblock empfangen +loop + call #get 'wert einlesen + wrbyte in, reg_b 'wert --> hubram + add reg_b, #1 'adresse + 1 + djnz reg_a, #loop + + ' neuen code starten + + rdword reg_a, #$A ' Setup the stack markers. + sub reg_a, #4 ' + wrlong SMARK, reg_a ' + sub reg_a, #4 ' + wrlong SMARK, reg_a ' + + rdbyte reg_a, #$4 ' Switch to new clock mode. + clkset reg_a ' + + coginit SINT ' Restart running new code. + + + cogid reg_a + cogstop reg_a 'cog hält sich selbst an + + +get + waitpeq M_1, M_2 'busclk=1? & /cs=0? + mov in, ina 'daten einlesen + and in, DMASK 'wert maskieren + mov outa, M_3 'hs=0 + waitpeq M_3, M_4 'busclk=0? + mov outa, M_0 'hs=1 +get_ret ret + + +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+|||+------------------------- /cs +' ||||| -------- d0..d7 +DINP long %00001001000000000000000000000000 'constant dinp hex \ bus input +DOUT long %00001001000000000000000011111111 'constant dout hex \ bus output + +M_0 long %00001000000000000000000000000000 'bus inaktiv + +M_1 long %00000010000000000000000000000000 +M_2 long %00000010100000000000000000000000 'busclk=1? & /cs=0? + +M_3 long %00000000000000000000000000000000 +M_4 long %00000010000000000000000000000000 'busclk=0? + + +DMASK long %00000000000000000000000011111111 'datenmaske + +SINT long ($0001 << 18) | ($3C01 << 4) ' Spin interpreter boot information. +SMARK long $FFF9FFFF ' Stack mark used for spin code. + +in res 1 +reg_a res 1 +reg_b res 1 + + + +CON ''------------------------------------------------- KEYBOARD-FUNKTIONEN + +PUB key_stat 'key: tastaturstatus abfragen + + bus.putchar(keyb.gotkey) + +PUB key_code 'key: tastencode abfragen + + keycode := keyb.key + case keycode + $c8: keycode := $08 'backspace wandeln + bus.putchar(keycode) + +PUB key_spec 'key: statustaten vom letzten tastencode abfragen + + bus.putchar(keycode >> 8) + + +CON ''------------------------------------------------- WINDOW-FUNKTIONEN + +PUB win_define | w, x0, y0, xn, yn, x + w := bus.getchar + x0 := bus.getchar #> 0 <# vdrv#COLS-1 + y0 := (bus.getchar * vdrv#TLINES_PER_ROW) #> 0 <# vdrv#ROWS-1 + xn := bus.getchar #> x0 <# vdrv#COLS-1 + yn := (bus.getchar * vdrv#TLINES_PER_ROW) #> y0 <# vdrv#ROWS-1 + if w < 1 or w => WIN_P_SCR ' Window 0 wird nicht überschrieben! + return + x := wscrnr*WIN_P_SCR*4 + w*4 + windows[x++] := x0 + windows[x++] := y0 + windows[x++] := xn + windows[x] := yn + x := wscrnr*WIN_P_SCR + w + col[x] := x0 + row[x] := y0 + +PUB win_set(oldscr) | w + w := bus.getchar + if w < 0 or w => WIN_P_SCR + return + win_set_int(oldscr, w) + +PRI win_set_int(oldscr, w) | x + ' current-Werte in altes Window sichern + x := oldscr*WIN_P_SCR + this_win[oldscr] + col[x] := ccol + row[x] := crow + color[x] := vdrv.get_ccolor + cursor[x] := ccursor + curstat[x] := ccurstat + needs_nl[oldscr] := cneeds_nl + if ccurstat == 1 + schar($20) + + ' current-Werte für neues Window setzen + this_win[wscrnr] := w + set_current_win + if ccurstat == 1 + schar(ccursor) + +PRI set_current_win | x + x := wscrnr*WIN_P_SCR + this_win[wscrnr] + ccol := col[x] + crow := row[x] + vdrv.set_ccolor(color[x]) + ccursor := cursor[x] + ccurstat := curstat[x] + x := wscrnr*WIN_P_SCR*4 + this_win[wscrnr]*4 + cx0 := windows[x++] + cy0 := windows[x++] + cxn := windows[x++] + cyn := windows[x] + cwcols := cxn - cx0 + 1 + cwrows := cyn - cy0 + vdrv#TLINES_PER_ROW + nnl_idx := 1 << this_win[wscrnr] + cneeds_nl := needs_nl[wscrnr] + +PUB win_getcols + bus.putchar(cwcols) + +PUB win_getrows + bus.putchar(cwrows / vdrv#TLINES_PER_ROW) + +PUB win_oframe | c, r + c := ccol ' aktuelle Werte aufheben und am Ende zuruecksetzen + r := crow + + if cy0 ' oberer Rand ist sichtbar + crow := cy0 - vdrv#TLINES_PER_ROW + if cx0 + ccol := cx0 - 1 + schar(159) + repeat ccol from cx0 to cxn + schar(144) '- + if cxn < vdrv#COLS-1 + ccol := cxn + 1 + schar(158) + if cx0 ' linke Seite ist sichtbar + ccol := cx0 - 1 + repeat crow from cy0 to cyn step vdrv#TLINES_PER_ROW + schar(145) '| + if cxn < vdrv#COLS-1 ' rechte Seite ist sichtbar + ccol := cxn + 1 + repeat crow from cy0 to cyn step vdrv#TLINES_PER_ROW + schar(145) '| + if cyn < vdrv#ROWS - vdrv#TLINES_PER_ROW ' unterer Rand ist sichtbar + crow := cyn + vdrv#TLINES_PER_ROW + if cx0 + ccol := cx0 - 1 + schar(157) + repeat ccol from cx0 to cxn + schar(144) '- + if cxn < vdrv#COLS-1 + ccol := cxn + 1 + schar(156) + ccol := c + crow := r + +CON ''------------------------------------------------- SCREEN-FUNKTIONEN + +PUB print_char(c) | code,n 'screen: zeichen auf bildschirm ausgeben +{{zeichen auf bildschirm ausgeben}} + + 'anpassung für die verschiedenen zeilenumbrüche + 'damit sollten alle drei versionen funktionieren: + 'dos/win: $0d $0a + 'unix/linux: $0a + 'mac: $0d + if c == $0a and lchar == $0d + c := 0 + lchar := c + + case c + $0E..$FF: 'character? + pchar(c) + if ccurstat == 1 + schar(ccursor) + return + gc#b_cls: 'clear screen? + n := wind + cy0 * vdrv#COLS + cx0 ' links oben + repeat cwrows + wordfill(@array.word[n], vdrv#SPACETILE, cwcols) + n += vdrv#COLS + crow := cy0 + ccol := cx0 + needs_nl[wscrnr] &= !nnl_idx + if ccurstat == 1 'cursor einschalten + schar(ccursor) + gc#b_home: 'home? + cneeds_nl &= !nnl_idx + if ccurstat == 1 + schar($20) + crow := cy0 + ccol := cx0 + if ccurstat == 1 + schar(ccursor) + gc#b_pos1: 'pos1 + cneeds_nl &= !nnl_idx + if ccurstat == 1 + schar($20) + ccol := cx0 + if ccurstat == 1 + schar(ccursor) + gc#b_curon: 'curon + if cneeds_nl & nnl_idx + newline + cneeds_nl ^= nnl_idx + ccurstat := 1 + schar(ccursor) + gc#b_curoff: 'curoff + if ccurstat == 1 + schar($20) + ccurstat := 0 + gc#b_scrollup: 'scrollup + if ccurstat == 1 + schar($20) + scrollup + if ccurstat == 1 + schar(ccursor) + gc#b_scrolldown: 'scrolldown + if ccurstat == 1 + schar($20) + scrolldown + if ccurstat == 1 + schar(ccursor) + gc#b_backspace: 'backspace? + cneeds_nl &= !nnl_idx + if ccol > cx0 + if ccurstat == 1 + schar($20) + ccol-- + if ccurstat == 1 + schar(ccursor) + gc#b_tab: 'tab + repeat n from 0 to TABANZ-1 + if ccol < tab[n] + cx0 + if ccurstat == 1 + schar($20) + ccol := tab[n] + cx0 + if ccurstat == 1 + schar(ccursor) + quit + gc#b_lf: 'LF ausblenden + cneeds_nl &= !nnl_idx + if ccurstat == 1 + schar($20) + newline + if ccurstat == 1 + schar(ccursor) + gc#b_crlf: 'return? + if ccurstat == 1 + schar($20) + newline + if ccurstat == 1 + schar(ccursor) + + +PUB print_ctrl(c) | code,n,m 'screen: steuerzeichen ausgeben + case c + gc#b_setcur: 'setcur + code := bus.getchar + ccursor := code + if ccurstat == 1 + schar(code) + gc#b_setx: 'setx + if ccurstat == 1 + schar($20) + cneeds_nl &= !nnl_idx + ccol := bus.getchar #> 0 <# vdrv#COLS-1 + if ccurstat == 1 + schar(ccursor) + gc#b_sety: 'sety + if ccurstat == 1 + schar($20) + cneeds_nl &= !nnl_idx + crow := (bus.getchar * vdrv#TLINES_PER_ROW) #> 0 <# vdrv#ROWS-vdrv#TLINES_PER_ROW + if ccurstat == 1 + schar(ccursor) + gc#b_getx: 'getx + bus.putchar(ccol) + gc#b_gety: 'gety + bus.putchar(crow / vdrv#TLINES_PER_ROW) + gc#b_setcol: 'setcolor + vdrv.set_ccolor(bus.getchar) + gc#b_sinit: 'screeninit + screen_init(wscrnr) + set_current_win + gc#b_tabset: 'tabulator setzen + n := bus.getchar + m := bus.getchar + if n =< (TABANZ-1) + tab[n] := m + gc#b_wsetx: 'winsetx + if ccurstat == 1 + schar($20) + cneeds_nl &= !nnl_idx + code := bus.getchar + ccol := ~code #> -cwcols <# cwcols-1 ' negativ --> Abstand von rechts+1 + if code < 0 + ccol += cxn + 1 + else + ccol += cx0 + if ccurstat == 1 + schar(ccursor) + gc#b_wsety: 'winsety + if ccurstat == 1 + schar($20) + cneeds_nl &= !nnl_idx + code := bus.getchar + ~code + crow := (code * vdrv#TLINES_PER_ROW) #> -cwrows <# cwrows-vdrv#TLINES_PER_ROW '2 tiles pro zeichen! + if code < 0 + crow += cyn + vdrv#TLINES_PER_ROW + else + crow += cy0 + if ccurstat == 1 + schar(ccursor) + gc#b_wgetx: 'wingetx + bus.putchar(ccol - cx0) + gc#b_wgety: 'wingety + bus.putchar((crow - cy0) / vdrv#TLINES_PER_ROW) + +PRI schar(c) + vdrv.schar(crow * vdrv#COLS + ccol + wind, c) + +PRI pchar(c) 'screen: schreibt zeichen mit cursor an aktuelle position + if cneeds_nl & nnl_idx + newline + cneeds_nl ^= nnl_idx + schar(c) + if ++ccol > cxn + if ccurstat == 1 + newline + else + cneeds_nl |= nnl_idx + +PUB newline | i 'screen: zeilenwechsel, inkl. scrolling am screenende + ccol := cx0 + if (crow += vdrv#TLINES_PER_ROW) > cyn + crow -= vdrv#TLINES_PER_ROW + scrollup + +PUB scrollup | zadr 'screen: scrollt den screen nach oben +' Start: linke obere Ecke, Breite: Window-Breite, Schrittweite: absolute Screen-Breite + zadr := wind + cy0 * vdrv#COLS + cx0 ' links oben + repeat cwrows-vdrv#TLINES_PER_ROW + wordmove(@array.word[zadr], @array.word[zadr+SCROLLDIFF], cwcols) + zadr += vdrv#COLS + 'clear new line + wordfill(@array.word[zadr], vdrv#SPACETILE, cwcols) + if vdrv#TLINES_PER_ROW > 1 + wordfill(@array.word[zadr+vdrv#COLS], vdrv#SPACETILE, cwcols) + +PUB scrolldown | zadr 'screen: scrollt den screen nach unten + zadr := wind + (cyn+vdrv#TLINES_PER_ROW-1) * vdrv#COLS + cx0 ' links unten + repeat cwrows-vdrv#TLINES_PER_ROW + wordmove(@array.word[zadr], @array.word[zadr-SCROLLDIFF], cwcols) + zadr -= vdrv#COLS + 'clear new line + wordfill(@array.word[zadr], vdrv#SPACETILE, cwcols) + if vdrv#TLINES_PER_ROW > 1 + wordfill(@array.word[zadr-vdrv#COLS], vdrv#SPACETILE, cwcols) + +PRI print_logo|x,y 'screen: hive-logo ausgeben + + x := bus.getchar + y := bus.getchar + _print_logo(x,y) + +#ifdef __TV +PRI _print_logo(x,y)|c, r + c := ccol + r := crow + ccol := x #> 0 <# vdrv#COLS-1 + crow := (y * vdrv#TLINES_PER_ROW) #> 0 <# vdrv#ROWS-vdrv#TLINES_PER_ROW '2 tiles pro zeichen! + pchar(" ") + pchar("H") + pchar("i") + pchar("v") + pchar("e") + ccol := c + crow := r +#endif +#ifdef __VGA +PRI _print_logo(x,y)|padr + padr := @hive+user_charbase-@uchar + print_uchar(padr, x, y, 8, 2, 1) 'logo zeichnen +#endif + +PRI print_uchar(pBMP,xPos,yPos,xSize,ySize,clr)|c,i,j,t 'screen: zeichnet ein einzelnes tilefeld +{ +- setzt in der tilemap des vga-treibers die adressen auf das entsprechende zeichen +- setzt mehrer tiles je nach xSize und ySize +- jedes tile besteht aus 16x16 pixel, weshalb die adresse jedes tiles mit c<<6 gebildet wird +- alle 64 byte (c<<6) beginnt im bitmap ein tile +} + t:=xPos + c:=0 + repeat j from 0 to (ySize-1) + repeat i from 0 to (xSize-1) + array.word[yPos * vdrv#COLS + xPos + wind] := pBMP + (c<<6) + clr + c++ + xPos++ + yPos++ + xPos:=t + + +DAT + + org +' +' Entry: dummy-assemblercode fuer cogtest +' +entry jmp entry 'just loops + + + +DAT + +padding long 1[16] '64-byte raum für die ausrichtung des zeichensatzes +uchar long + +hive long +file "logo-hive-8x2.dat" '8x2=16 + + +DAT + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/flash/bellatrix/logo-hive-8x2.dat b/flash/bellatrix/logo-hive-8x2.dat new file mode 100644 index 0000000..109ef59 Binary files /dev/null and b/flash/bellatrix/logo-hive-8x2.dat differ diff --git a/flash/bellatrix/logo-hive-8x2/dat.rtf b/flash/bellatrix/logo-hive-8x2/dat.rtf new file mode 100644 index 0000000..e758f9d --- /dev/null +++ b/flash/bellatrix/logo-hive-8x2/dat.rtf @@ -0,0 +1,275 @@ +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fcharset0 Arial;}} +{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1031\f0\fs20 char y=0, x=0 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=0, x=1 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0003_3333_3300_0000\par + LONG %%0033_3000_3330_0000\par + LONG %%0330_0000_0033_0000\par + LONG %%3300_0000_0003_3000\par + LONG %%3300_0000_0000_3000\par + LONG %%3000_0000_0000_3300\par + LONG %%3000_0000_0000_3300\par + LONG %%3300_0000_0000_3000\par + LONG %%3300_0000_0003_3000\par + LONG %%0330_0000_0033_0000\par + LONG %%0033_3000_0333_0000\par + LONG %%0033_3333_3330_0000\par + LONG %%0333_0000_0333_0000\par +char y=0, x=2 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=0, x=3 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3003_3330_0333_3300\par + LONG %%3033_3333_0333_3300\par + LONG %%3033_3333_0333_3300\par +char y=0, x=4 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%3000_3333_0000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3000_3333_0000_3333\par + LONG %%3000_0000_0000_3333\par + LONG %%3000_0000_0000_3333\par +char y=0, x=5 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par +char y=0, x=6 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3333_3000_0000_0033\par + LONG %%3333_3333_0000_0033\par + LONG %%3333_3333_3000_0033\par + LONG %%3333_3333_3300_0033\par + LONG %%3333_3333_3330_0033\par + LONG %%0000_3333_3330_0033\par + LONG %%0000_0033_3333_0033\par + LONG %%3333_0003_3333_0033\par +char y=0, x=7 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=0 \par + LONG %%0000_0000_0000_0000\par + LONG %%3330_0000_0000_0000\par + LONG %%0033_3000_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0003_3000_0000_0000\par + LONG %%0333_0000_0000_0000\par + LONG %%3330_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=1 \par + LONG %%3330_0000_0033_3000\par + LONG %%3300_0000_0003_3333\par + LONG %%3300_0000_0003_3300\par + LONG %%0330_0000_0033_0000\par + LONG %%0033_0000_0030_0000\par + LONG %%0033_0000_0330_0000\par + LONG %%0003_3333_3330_0000\par + LONG %%0003_3333_3330_0000\par + LONG %%0033_0000_0330_0000\par + LONG %%0033_0000_0030_0000\par + LONG %%0330_0000_0033_0000\par + LONG %%3300_0000_0003_3330\par + LONG %%0000_0000_0000_0333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=2 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0033_3333\par + LONG %%0000_0000_3330_0000\par + LONG %%0000_0000_3300_0000\par + LONG %%0000_0003_3000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0033_0000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0003_3000_0000\par + LONG %%0000_0000_3300_0000\par + LONG %%0000_0000_0333_3033\par + LONG %%0000_0000_0003_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=3 \par + LONG %%3033_3333_0333_3300\par + LONG %%3033_3333_0333_3300\par + LONG %%3003_3330_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=4 \par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=5 \par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0003_3333\par + LONG %%3330_0000_0003_3333\par + LONG %%3330_0000_0033_3333\par + LONG %%3333_3333_3333_3333\par + LONG %%3333_3333_3333_3330\par + LONG %%3333_3333_3333_3300\par + LONG %%3333_3333_3333_3000\par + LONG %%3333_3333_3330_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=6 \par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_0033_3333_0033\par + LONG %%0000_3333_3330_0033\par + LONG %%3333_3333_3330_0033\par + LONG %%3333_3333_3300_0033\par + LONG %%3333_3333_3000_0033\par + LONG %%3333_3333_0000_0033\par + LONG %%3333_3000_0000_0033\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=7 \par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +} + \ No newline at end of file diff --git a/flash/bellatrix/logo-hive-8x2/logo-hive-8x2.dat b/flash/bellatrix/logo-hive-8x2/logo-hive-8x2.dat new file mode 100644 index 0000000..109ef59 Binary files /dev/null and b/flash/bellatrix/logo-hive-8x2/logo-hive-8x2.dat differ diff --git a/flash/regnatix/regflash.spin b/flash/regnatix/regflash.spin new file mode 100644 index 0000000..d1a4e21 --- /dev/null +++ b/flash/regnatix/regflash.spin @@ -0,0 +1,5956 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Regnatix-Flash +Chip : Regnatix +Typ : Flash +Version : 01 +Subversion : 1 +Beschreibung : Residenter Bootloader des Systems. Läuft auf der ersten COG und startet BIN-Dateien + von SD-Card. Gesteuert wird er von den Programmen über ein einfaches Interface: Im + eRAM übergibt der Loader einen Pointer auf das Loaderflag und einen anschließenden + Puffer von 16 Byte für einen Dateinamen. Ein Programm kann also einen Dateinamen + hinterlegen und das Flag auf 1 setzen, worauf der Loader die COGs 1..7 stoppt, die + BIN-Datei in den Heap lädt und startet. + Bootvorgang: Bei Systemstart wird die Datei "reg.sys" in den Heap geladen und + gestartet. + +Logbuch: + +19-11-2008-dr235 - erste version startet sys.bin + - steuerung durch anwendung integriert +22-03-2010-dr235 - anpassung trios +26-04-2010-dr235 - fehlerabfrage beim mount (in einigen fällen war die fatengine noch nicht so weit) +16-05-2011-dr235 - umstellung blocktransfer zu administra + - einbindung propforth :) + + +header einer bin-datei + +00 00 b400 ' clkfreq low +02 02 04c4 ' clkfreq hi +04 04 ca6f ' sum byte, clkmode byte +06 06 0010 ' (obj) object start addr +08 08 005c ' (vars) variables start +10 0A 0088 ' (stk) stack start +12 0C 002c ' (PUB) obchain first PUB method start +14 0E 008c ' (isp) initial stack pointer value + +word[3] - PBASE - Program base. This is the start of the DAT variables and program code after the 16-byte header. It always has a value of 16, or $10 +word[4] - VBASE - Variable base. This starts immediately after the program code. It should always be the same as the file size. +word[5] - DBASE - Stack variable base. This points to the first variable on the stack at program start, which is the RESULT variable. +word[6] - PCURR - Current program counter. This points at the starting address of the first instruction to be executed. +word[7] - DCURR - Stack pointer. This is the initial value of the stack pointer. + + + --------------------------------------------------------------------------------------------------------- }} + + +CON ' KONFIGURATION +{ + Achtung: Nur eine Konfiguration wählen! +} + +'#define forth ' forth + spin-loader +#define regime ' spin-loader OHNE FORTH, reg.sys wird sofort automatisch gestartet + +CON ' LOADER-KONSTANTEN + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +COGMAX = 8 +INTERPRETER = $f004 'interpreteradresse (rom) + +'signaldefinition regnatix +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10 'adressbus +#19, REG_RAM1,REG_RAM2 'selektionssignale rambank 1 und 2 +#21, REG_PROP1,REG_PROP2 'selektionssignale für administra und bellatrix +#23, REG_AL 'strobesignal für adresslatch +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +'system +LOADERPTR = $0FFFFB 'eram-adresse mit pointer auf loader-register +MAGIC = $0FFFFA 'Warmstartflag + +'prop 1 - administra (bus_putchar1, bus_getchar1) +'prop 2 - bellatrix (bus_putchar2, bus_getchar2) +' +------------------------- al +' |+------------------------ /prop2 +' hbeat --------+ ||+----------------------- /prop1 +' clk -------+| |||+---------------------- /ram2 +' /wr ------+|| ||||+--------------------- /ram1 +' /hs -----+||| ||||| +--------- a0..a10 +' |||| ||||| | +' |||| |||||-----------+ -------- d0..d7 +DB_OFF = %00000000_00000000_00000000_00000000 'maske: bus inaktiv +DB_IN = %00000111_11111111_11111111_00000000 'maske: dbus-eingabe +DB_OUT = %00000111_11111111_11111111_11111111 'maske: dbus-ausgabe + +M1 = %00000000_01011000_00000000_00000000 '/prop1=0, /wr=0, busclk=0 frida +M2 = %00000110_01011000_00000000_00000000 '/prop1=0, /wr=1, busclk=1 frida +M3 = %00000100_01111000_00000000_00000000 '/prop1=1, /wr=1, busclk=0 frida + +M4 = %00000000_00000000_00000000_00000000 +M5 = %00001000_00000000_00000000_00000000 '/hs=0? + +#0, OPT + SD_MOUNT + SD_DIROPEN + SD_NEXTFILE + SD_OPEN + SD_CLOSE + SD_GETC + SD_PUTC + SD_GETBLK + SD_PUTBLK + SD_SEEK + SD_FATTRIB + SD_VOLNAME + SD_CHECKMOUNTED + SD_CHECKOPEN + SD_CHECKUSED + SD_CHECKFREE + SD_NEWFILE + SD_NEWDIR + SD_DEL + SD_RENAME + SD_CHATTRIB + SD_CHDIR + SD_FORMAT + SD_UNMOUNT + SD_DMACT + SD_DMSET + SD_DMGET + SD_DMCLR + SD_DMPUT + SD_EOF + +CON ' FORTH-KONSTANTEN + + _cogDataSize = 224 ' _cdsz forth word + _wordMASK = $FFFF +' for the serial driver + _buffer_length = 128 ' 32 64 OR 128 + _buffer_mask = _buffer_length - 1 ' bitmaske für ringpuffer + + +VAR + + byte proghdr[16] 'puffer für objektkopf + +' achtung: reihenfolge der folgenden zwei variablen nicht ändern! + + byte lflag 'flag zur steuerung des loaders + byte lname[16] 'stringpuffer für dateinamen + +PUB main | spinbin,i 'loader: hauptroutine +{{main - loader: hauptroutine}} + + bus_init 'bus initialisieren + wr_long(@lflag,LOADERPTR) 'zeiger auf loader-register setzen + +' ----------------------------------------------------- FORTH +#ifdef forth + + word[@ldvarVAL] := @lflag 'zeiger auf loader-register für forth setzen + bus_off 'bus für loader deaktivieren + +' allocate locks 0 and 1 for PropForth + i := locknew + i := locknew + +' and the memory variables + if WORD[ @herePFA + 2] == 0 + WORD[ @herePFA + 2] := @wfreespacestart + $10 + bytefill( @cogdataPFA, 0, 8 * _cogDataSize) + WORD[ @_finitPFA + 2] := 0 + + WORD[ @dictendPFA + 2] := @ForthDictEnd + $10 + WORD[ @memendPFA + 2] := @ForthMemoryEnd + $10 + WORD[ @_cdszPFA + 2] := _cogdatasize + +' start forth cog + coginit(6, @entryPFA, @cogdataPFA + (6 * _cogDataSize)) + +#endif + +' ----------------------------------------------------- REGIME +#ifdef regime + + waitcnt(cnt + clkfreq) 'kurze pause für slaves + spinbin := load(@sysname) 'start-bin laden + bus_off 'bus deaktivieren + run(spinbin) 'sys-objekt ausführen + +#endif + +' ----------------------------------------------------- LOADER + + repeat 'kommandoschleife + repeat until lflag <> 0 'warte das flag gesetzt ist + lflag := 0 + repeat i from 1 to 7 'cog 1..7 anhalten + cogstop(i) + bus_init 'objekt laden und ausführen + spinbin := load(@lname) + bus_off + run(spinbin) + +PRI errorled(time) 'loader: fehleranzeige über cardreader-led +{{errorled(time) - loader: fehleranzeige über cardreader-led}} + + repeat + bus_putchar1(OPT) + waitcnt(clkfreq / 4 * time + cnt) + +PRI run(spinptr) 'loader: bin-datei bei adresse starten +{{run(spinprt) - loader: bin-datei bei adresse starten}} + + if spinptr + cognew(INTERPRETER, spinptr+4) 'neuen cog mit objekt starten + +PRI load(fname) | rc,ii,plen,progptr 'loader: datei in heap laden +{{load(fname) - loader: datei in heap laden}} + +' kopf der bin-datei einlesen ------------------------------------------------------ + rc := sdopen("r",fname) 'datei öffnen + if rc > 0 'fehler bei öffnen? + errorled(1) + repeat ii from 0 to 15 '16 bytes --> proghdr + byte[@proghdr][ii] := sdgetc + plen := word[@proghdr+$A] '$a ist stackposition und damit länge der objektdatei + if plen > (@heapend - @heap) 'objekt größer als verfügbarer speicher? + errorled(1) + sdclose 'bin-datei schießen + +' bin-datei einlesen ------------------------------------------------------ + progptr := @heap + progptr := (progptr + 4) & !3 + sdopen("r",fname) 'bin-datei öffnen + +' repeat ii from 0 to plen-1 'datei --> heap +' byte[progptr][ii] := sdgetc + sdgetblk(plen,progptr) + sdclose + +' zeiger im header mit offset versehen ------------------------------------------------------ + Repeat ii from 0 to 4 + Word[progptr+6+ii<<1] += progptr + +' variablenbereich löschen ------------------------------------------------------ + rc := word[@proghdr+$8] + Repeat ii from rc to plen step 4 + long[progptr + ii] := 0 + +' stackwerte setzen? ------------------------------------------------------ + long[progptr+plen-4] := $fff9ffff + long[progptr+plen-8] := $fff9ffff + + return progptr + +CON ' SYSTEMROUTINEN +PUB sdgetblk(count,bufadr) | i 'sd-card: block lesen +''funktionsgruppe : sdcard +''funktion : block aus datei lesen +''busprotokoll : [008][sub_putlong.count][get.char(1)]..[get.char(count)] +'' : count - anzahl der zu lesenden zeichen +'' : char - gelesenes zeichen + + i := 0 + bus_putchar1(SD_GETBLK) + bus_putlong1(count) + repeat count + byte[bufadr][i++] := bus_getchar1 + +PUB sdgetc: char 'sd-card: liest ein byte aus geöffneter datei +{{sdgetc: char - sd-card: liest ein byte aus geöffneter datei}} + bus_putchar1(SD_GETC) + char := bus_getchar1 + +PUB sdclose:err 'sd-card: schließt datei +{{sdclose: err - sd-card: schließt datei}} + bus_putchar1(SD_CLOSE) + err := bus_getchar1 + +PUB sdopen(modus,stradr):err | len,i 'sd-card: öffnet eine datei +{{sdopen(modus,stradr - sd-card: öffnet eine datei}} + bus_putchar1(SD_OPEN) + bus_putchar1(modus) + len := strsize(stradr) + bus_putchar1(len) + repeat i from 0 to len - 1 + bus_putchar1(byte[stradr++]) + err := bus_getchar1 + +PUB bus_putlong1(wert) 'bus: long zu administra senden hsb/lsb + + bus_putchar1(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar1(wert >> 16) + bus_putchar1(wert >> 8) + bus_putchar1(wert) + +PUB bus_putchar1(c) 'bus: byte an prop1 (administra) senden 'frida prop2 --> prop1 +{{bus_putchar1(c) - bus: byte senden an prop1 (administra)}} + outa := M1 '/prop1=0, /wr=0, busclk=0 + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := c 'daten --> dbus + outa[busclk] := 1 'busclk=1 + waitpeq(M4,M5,0) '/hs=0? + dira := db_in 'bus freigeben + outa := M3 '/prop1=1, /wr=1, busclk=0 + +PUB bus_getchar1:wert 'bus: byte vom prop1 (administra) empfangen 'frida prop2 --> prop1 +{{bus_getchar1:wert - bus: byte empfangen von prop1 (administra)}} + outa := M2 '/prop1=0, /wr=1, busclk=1 + waitpeq(M4,M5,0) 'hs=0? + wert := ina[7..0] 'daten einlesen + outa := M3 '/prop1=1, /wr=1, busclk=0 + +PUB ram_write(wert,adresse) 'schreibt ein byte in eram +{{ram_write(wert,adresse) - ein byte in externen ram schreiben}} +'rambank 1 000000 - 07FFFF +'rambank 2 080000 - 0FFFFF + outa[bus_wr] := 0 'schreiben aktivieren + dira := db_out 'datenbus --> ausgang + outa[7..0] := wert 'wert --> datenbus + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + outa[reg_al] := 1 'obere adresse in adresslatch übernehmen frida + outa[reg_al] := 0 'frida + outa[18..8] := adresse 'niederwertige adresse setzen + if adresse < $080000 'rambank 1? + outa[reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben) + outa[reg_ram1] := 1 'ram1 deselektieren + else + outa[reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben) + outa[reg_ram2] := 1 'ram2 deselektieren + dira := db_in 'datenbus --> eingang + outa[bus_wr] := 1 'schreiben deaktivieren + +PUB wr_long(wert,eadr) | n 'schreibt long ab eadr +{{wr_long(wert,eadr) - schreibt long ab eadr}} + n := wert & $FF + ram_write(n,eadr) + n := (wert >> 8) & $FF + ram_write(n,eadr + 1) + n := (wert >> 16) & $FF + ram_write(n,eadr + 2) + n := (wert >> 24) & $FF + ram_write(n,eadr + 3) + +PUB bus_off 'bus: bus komplett abschalten +{{bus_off - bus: bus kompeltt abschalten}} + dira := db_off ' datenbus auf eingabe schalten + + +PUB bus_init 'bus: initialisiert bussystem +{{bus_init - bus: initialisierung aller bussignale }} + outa[18..8] := 0 ' adresse a0..a10 auf 0 setzen + outa[reg_ram1] := 1 ' ram1 inaktiv + outa[reg_ram2] := 1 ' ram2 inaktiv + outa[reg_prop1] := 1 ' prop1 inaktiv + outa[reg_prop2] := 1 ' prop2 inaktiv + outa[busclk] := 0 ' busclk startwert + outa[bus_wr] := 1 ' schreiben inaktiv + dira := db_in ' datenbus auf eingabe schalten frida + outa[reg_al] := 1 ' obere adresse in adresslatch übernehmen frida + outa[reg_al] := 0 'frida + +DAT + +sysname byte "reg.sys", 0 'name der systemdatei + +DAT ' HEAP FORTH-KONF +#ifdef forth + +heap +a_base + org 0 +{{ + +Assembler Code + +Assembler routines which correspond to forth words are documented in the forth area + +}} +entryPFA + + jmp #a_next +a__execasmtwogtone + rdword treg1, IP + movi a__execasmtwogtonei, treg1 + add IP, #2 + call #a_stpoptreg +a__execasmtwogtonei + and stTOS, treg1 + jmp #a_next + +a__execasmonegtone + rdword treg1, IP + movi a__execasmonegtonei, treg1 + add IP, #2 +a__execasmonegtonei + abs stTOS, stTOS + jmp #a_next + +a__execasmtwogtz + rdword treg1, IP + movi a__execasmtwogtzi, treg1 + add IP, #2 + call #a_stpoptreg +a__execasmtwogtzi + abs stTOS, treg1 +a_drop + call #a_stPop + jmp #a_next + +a_COGat + movs a_COGatget, stTOS + nop ' necessary, really needs to be documented +a_COGatget mov stTOS, stTOS + jmp #a_next +a_COGbang + movd a_COGbangput, stTOS + call #a_stPop +a_COGbangput mov stTOS, stTOS + jmp #a_drop +a_branch + rdword treg1,IP ' the next word + add IP, treg1 ' add the offset + and IP , fAddrMask + jmp #a_next +a_doconw + call #a_stPush + rdword stTOS, IP + jmp #a_exit +a_dovarl + add IP, #3 + andn IP, #3 ' align to a long boundary +a_dovarw + call #a_stPush + mov stTOS, IP + jmp #a_exit +a_litl + call #a_stPush + add IP, #3 + andn IP, #3 ' align to a long boundary + rdlong stTOS, IP + add IP, #4 + jmp #a_next +a_doconl + call #a_stPush + add IP, #3 + andn IP, #3 ' align to a long boundary + rdlong stTOS, IP + jmp #a_exit +a_dup + call #a_stPush + jmp #a_next + +' treg1 - cstr2 (name) +' stTOS - cstr1 (name) +' uses treg2, treg4, and treg5 +' z flag set if strings are equal + +c_streq +c_streq5 + mov treg4 , # $1F +' length of cstr2 (name) + rdbyte treg2 , treg1 wz +' length of cstr2 (name) - truncate to appropriate length + if_nz and treg2 , treg4 wz +' length of cstr1 (name) + if_nz rdbyte treg5 , stTOS wz +' length of cstr1 (name) - truncate to appropriate length + if_nz and treg5 , treg4 wz +' if either length is 0, move -1 into length of cstr1 to cause a mismatch + if_z mov treg5 , fLongMask + cmp treg2 , treg5 wz + if_nz jmp # c_streq7 +a_cstreqloop + add stTOS , # 1 + rdbyte treg4 , stTOS + add treg1 , # 1 +a_cstreqlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + rdbyte treg5 , treg1 + cmp treg4 , treg5 wz + if_z djnz treg2 , # a_cstreqloop +c_streq7 +c_streq_ret + ret + +' a_nameeq (name name -- t/f) +a_nameeq + movs c_streq5 , # $1F + jmp # a_nameeq4 +' a_cstreq (cstr1 cstr2 -- t/f) +a_cstreq + movs c_streq5 , # $FF +a_nameeq4 + call #a_stpoptreg +' treg1 - cstr2 +' stTOS - dict cstr1 + jmpret c_streq_ret , # c_streq + muxz stTOS , fLongMask + jmp # a_next + +a__dictsearch + call #a_stpoptreg + mov treg6 , treg1 + mov treg3 , stTOS + movs c_streq5 , # $1F +' treg6 - cstr +' treg3 - nfa +a__dictsearchlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched +' treg1 - nfa +' stTOS - cstr + mov treg1 , treg6 + mov stTOS , treg3 + jmpret c_streq_ret , # c_streq + if_nz jmp # a__dictsearch2 +a__dictsearch1 + mov stTOS , treg3 + jmp # a_next +a__dictsearch2 + mov treg2 , treg3 + sub treg2 , # 2 + rdword treg3 , treg2 wz + if_z jmp # a__dictsearch1 + jmp # a__dictsearchlp + +a_eq + call #a_stpoptreg + cmp treg1, stTOS wz, wc + muxz stTOS, fLongMask + jmp #a_next +a_gt + '( n1 n2 -- flag ) + call #a_stpoptreg ' flag is true if and only if n1 is greater than n2 + cmps stTOS, treg1 wz, wc + if_a neg stTOS, #1 + if_be mov stTOS, #0 + jmp #a_next +a_hubop + call #a_stpoptreg + hubop stTOS, treg1 wr,wc + muxc treg1, fLongMask + call #a_stPush + mov stTOS, treg1 + jmp #a_next +a_litw + call #a_stPush + rdword stTOS, IP +a_litw1 + add IP, #2 + jmp #a_next +a_lt + '( n1 n2 -- flag ) + call #a_stpoptreg ' flag is true if and only if n1 is less than n2 + cmps stTOS, treg1 wz, wc + if_b neg stTOS, #1 + if_ae mov stTOS, #0 + jmp #a_next +a_exit + call #a_rsPop + mov IP, treg5 +' jmp #a_next SINCE WE ARE ALREADY There +a_next + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched +a_debugonoff + if_never jmpret a_dum_ret, # a_dum ' when debug is loaded this address will be patched + + rdword treg1,IP ' the next word + test treg1, fMask wz + if_z add IP, #2 ' if the one of the hi bits is not set, it is an assembler word, inc IP + if_z jmp treg1 + rdword treg1, IP ' otherwise it is a forth word + mov treg5, IP + add treg5, #2 + mov IP, treg1 + call #a_rsPush + jmp #a_next +a_over + call #a_stpoptreg + mov treg2, stTOS + call #a_stPush + mov stTOS, treg1 + call #a_stPush + mov stTOS, treg2 + jmp #a_next +a__maskin + and stTOS, ina wz + muxnz stTOS, fLongMask + jmp # a_next + +a__maskouthi + jmp # a__maskoutex wz + +a__maskoutlo + test stTOS, #0 wz +a__maskoutex + muxnz outa, stTOS + jmp # a_drop + +a_rot + call #a_stpoptreg + mov treg2, stTOS + call #a_stPop + mov treg3, stTOS + + mov stTOS, treg2 + call #a_stPush + mov stTOS, treg1 + call #a_stPush + mov stTOS, treg3 + jmp #a_next +a_rgt + call #a_rsPop + call #a_stPush + mov stTOS, treg5 + jmp #a_next +a_twogtr + mov treg5, stTOS + call #a_stPop + call #a_rsPush +a_gtr + mov treg5, stTOS + call #a_stPop + call #a_rsPush + jmp #a_next +a_lparenlooprparen + mov treg1, #1 + jmp #a_lparenpluslooprparen1 +a_lparenpluslooprparen + call #a_stpoptreg +a_lparenpluslooprparen1 + call #a_rsPop + mov treg2, treg5 + call #a_rsPop + add treg5, treg1 + cmp treg2, treg5 wc ,wz + if_a call #a_rsPush ' branch + if_a mov treg5, treg2 ' branch + if_a call #a_rsPush ' branch + if_a jmp #a_branch + jmp #a_litw1 + +a_swap + call #a_stpoptreg + mov treg2, stTOS + mov stTOS, treg1 + call #a_stPush + mov stTOS, treg2 + jmp #a_next + +a_umstar + call #a_stpoptreg + mov treg4, #0 + mov treg2, #0 + mov treg3, #0 +a_umstarlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + shr stTOS, #1 wz,wc + if_nc jmp #a_umstar1 + add treg4, treg1 wc + addx treg2, treg3 +a_umstar1 + shl treg1, #1 wc + rcl treg3, #1 + if_nz jmp #a_umstarlp + mov stTOS, treg4 + call #a_stPush + mov stTOS, treg2 + jmp #a_next +a_umslashmod + call #a_stpoptreg + mov treg6, stTOS + call #a_stPop + mov treg3, #$40 + mov treg2, #0 +a_umslashmodlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + shl stTOS, #1 wc ' dividend + rcl treg6, #1 wc + + rcl treg2, #1 wc ' hi bit from dividend + + if_c sub treg2, treg1 + if_nc cmpsub treg2, treg1 wc ' cmp divisor + + rcl treg4, #1 ' treg1 - quotient + djnz treg3, #a_umslashmodlp + mov stTOS, treg2 + call #a_stPush + mov stTOS, treg4 + jmp #a_next +a_zbranch + call #a_stpoptreg + cmp treg1, #0 wz ' is the TOS zero? + if_z jmp #a_branch + jmp #a_litw1 + +a_reset + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses will be patched + wrword fLongMask , par + wrbyte treg6 , par + coginit resetDreg + +{{ + +a_stPush - push stTOS on to stack + +}} +a_stPush + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + movd a_stPush1, stPtr + cmp stPtr, #stBot wc + if_b mov treg6 , # $11 + if_b jmp # a_reset +a_stPush1 mov stPtr, stTOS + sub stPtr, #1 +a_stPush_ret + ret +{{ + +a_rsPush - push treg5 on to return stack + +}} +a_rsPush + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + movd a_rsPush1, rsPtr + cmp rsPtr, #rsBot wc + if_b mov treg6 , # $12 + if_b jmp # a_reset +a_rsPush1 mov treg1, treg5 + sub rsPtr, #1 +a_rsPush_ret + ret + +{{ + +a_stpoptreg - move stTOS to treg1, and pop stTOS from stack + +}} +a_stpoptreg + mov treg1, stTOS +{{ + +a_stPop - pop stTOS from stack + +}} +a_stPop + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + add stPtr, #1 + movs a_stPop1, stPtr + cmp stPtr, #stTop wc,wz + if_ae mov treg6 , # $21 + if_ae jmp # a_reset +a_stPop1 mov stTOS, stPtr +a_stPop_ret +a_stpoptreg_ret + ret + +{{ + +a_rsPop - pop treg5 from return stack + +}} +a_rsPop + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + add rsPtr, #1 + movs a_rsPop1, rsPtr + cmp rsPtr, #rsTop wc,wz + if_ae mov treg6 , # $22 + if_ae jmp # a_reset +a_rsPop1 +a_dum + mov treg5, treg1 +a_dum_ret +a_rsPop_ret + ret + + +' +' variables used by the forth interpreter, do not change the order or size -- or if you do, be really careful and update the forth code +' +varStart +fMask long $FE00 ' 0 +fAddrMask long $7FFF ' 1 +fLongMask long $FFFFFFFF ' 2 +resetDreg long 0 ' 3 +IP long @fstartPFA + $10 ' 4 +stPtr long ((@stTop - @a_base) /4) - 1 ' 5 +rsPtr long ((@rsTop - @a_base) /4) - 1 ' 6 +stTOS long 0 ' 7 + +{{ +These variables are overlapped with the cog data area variables to save space +}} +cogdataPFA +treg1 long 0 ' 8 working reg +treg2 long 0 ' 9 working reg +treg3 long 0 ' a working reg +treg4 long 0 ' b working reg +treg5 long 0 ' c working reg / call parameter reg +treg6 long 0 ' d working reg +stBot ' e + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' e + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 1e + + +stTop ' 2e +rsBot + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 2e + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 3e +rsTop ' 4e + + +varEnd + +{{ + +cogdata + +This data area is used for variables which are unique to each instance of forth, like +inbyte, emitptr, >in, pad, etc... + +}} +'cogdataPFA long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 0 +' long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +' long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +' long 0,0, 0,0, 0,0, 0,0, +' long 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 1 +' long 0,0, 0,0, 0,0, + long 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 2 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 3 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 4 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 5 long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 6 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0 ' 224 bytes cog 7 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + +{{ + +Start of the Forth Dicitonary + +Dictionary Entry Structure + - there is no code pointer, it is inherent +LinkField - points to the previous name field in the dictionary + word +NameField + byte - length of the name field (lo 5 bits) + - bit 7 ($80) set if it is a forth word + - bit 6 ($40) set if it is an immediate word + - bit 5 ($20) set if it is an eXecute word - execute this word in interactive mode as well + if the immediate flag is set + bytes - the actual name + - if the name is a word constant, and it starts with $C_ the spinMaker assumes it to be a reference to the cog data + space and sets the constant to be (name - a_base) /4. If it starts with $H_ it is assumed to be a main memory + reference and the constant is set to be namePFA +$10 + if the name is an assembler word the address is set to (a_name - a_base)/4 assembler names are not constants, they + are a different type of dictionary entry + +ParameterField - the list of addresses to execute, and literals for a forth word + - if it is a forth word one ofthe hi bit ($FE00) will be set + - assembler addresses are always < 512 + - this of course means that the ForthDictStart must have at least 512 bytes used before it, since this is only + 128 longs, and the assembler code, and forth stacks are before this, this is not an issue + - if it is an assembler word there is only 1 word and it is the assembler address + + +Generated form forth code from here on in - written in forth spin generated +*************************************************************************************************************** +*************************************************************************************************************** +*************************************************************************************************************** +}} + +ForthDictStart + + word 0 +hereNFA byte $84,"here" +herePFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @hereNFA + $10 +dictendNFA byte $87,"dictend" +dictendPFA word (@a_dovarw - @a_base)/4 + word $7F40 + + word @dictendNFA + $10 +memendNFA byte $86,"memend" +memendPFA word (@a_dovarw - @a_base)/4 + word $7F40 + + word @memendNFA + $10 +propidNFA byte $86,"propid" +propidPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @propidNFA + $10 +lparenproprparenNFA byte $86,"(prop)" +lparenproprparenPFA word @cqPFA + $10 + byte $04,"Prop" + word (@a_exit - @a_base)/4 + + word @lparenproprparenNFA + $10 +lparenversionrparenNFA byte $89,"(version)" +lparenversionrparenPFA word @cqPFA + $10 + byte $20,"PropForth v4.0 2010NOV28 13:00 0" + word (@a_exit - @a_base)/4 + + word @lparenversionrparenNFA + $10 +propNFA byte $84,"prop" +propPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @propNFA + $10 +versionNFA byte $87,"version" +versionPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @versionNFA + $10 +_finitNFA byte $86,"_finit" +_finitPFA word (@a_dovarw - @a_base)/4 + word $FFFF + + word @_finitNFA + $10 +_cdszNFA byte $85,"_cdsz" +_cdszPFA word (@a_doconw - @a_base)/4 + word $00E0 + + word @_cdszNFA + $10 +conNFA byte $83,"con" +conPFA word (@a_doconw - @a_base)/4 + word $0007 + + word @conNFA + $10 +dlrH_serentryNFA byte $8B,"$H_serentry" +dlrH_serentryPFA word (@a_doconw - @a_base)/4 + word @serentryPFA + $10 + + word @dlrH_serentryNFA + $10 +dlrH_entryNFA byte $88,"$H_entry" +dlrH_entryPFA word (@a_doconw - @a_base)/4 + word @entryPFA + $10 + + word @dlrH_entryNFA + $10 +dlrH_cogdataNFA byte $8A,"$H_cogdata" +dlrH_cogdataPFA word (@a_doconw - @a_base)/4 + word @cogdataPFA + $10 + + word @dlrH_cogdataNFA + $10 +dlrH_cqNFA byte $85,"$H_cq" +dlrH_cqPFA word (@a_doconw - @a_base)/4 + word @cqPFA + $10 + + word @dlrH_cqNFA + $10 +dlrH_dqNFA byte $85,"$H_dq" +dlrH_dqPFA word (@a_doconw - @a_base)/4 + word @dqPFA + $10 + + word @dlrH_dqNFA + $10 +dlrC_a_exitNFA byte $89,"$C_a_exit" +dlrC_a_exitPFA word (@a_doconw - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @dlrC_a_exitNFA + $10 +dlrC_a_dovarwNFA byte $8B,"$C_a_dovarw" +dlrC_a_dovarwPFA word (@a_doconw - @a_base)/4 + word (@a_dovarw - @a_base)/4 + + word @dlrC_a_dovarwNFA + $10 +dlrC_a_doconwNFA byte $8B,"$C_a_doconw" +dlrC_a_doconwPFA word (@a_doconw - @a_base)/4 + word (@a_doconw - @a_base)/4 + + word @dlrC_a_doconwNFA + $10 +dlrC_a_branchNFA byte $8B,"$C_a_branch" +dlrC_a_branchPFA word (@a_doconw - @a_base)/4 + word (@a_branch - @a_base)/4 + + word @dlrC_a_branchNFA + $10 +dlrC_a_litwNFA byte $89,"$C_a_litw" +dlrC_a_litwPFA word (@a_doconw - @a_base)/4 + word (@a_litw - @a_base)/4 + + word @dlrC_a_litwNFA + $10 +dlrC_a_twogtrNFA byte $88,"$C_a_2>r" +dlrC_a_twogtrPFA word (@a_doconw - @a_base)/4 + word (@a_twogtr - @a_base)/4 + + word @dlrC_a_twogtrNFA + $10 +dlrC_a_lparenlooprparenNFA byte $8B,"$C_a_(loop)" +dlrC_a_lparenlooprparenPFA word (@a_doconw - @a_base)/4 + word (@a_lparenlooprparen - @a_base)/4 + + word @dlrC_a_lparenlooprparenNFA + $10 +dlrC_a_lparenpluslooprparenNFA byte $8C,"$C_a_(+loop)" +dlrC_a_lparenpluslooprparenPFA word (@a_doconw - @a_base)/4 + word (@a_lparenpluslooprparen - @a_base)/4 + + word @dlrC_a_lparenpluslooprparenNFA + $10 +dlrC_a_zbranchNFA byte $8C,"$C_a_0branch" +dlrC_a_zbranchPFA word (@a_doconw - @a_base)/4 + word (@a_zbranch - @a_base)/4 + + word @dlrC_a_zbranchNFA + $10 +dlrC_a_dovarlNFA byte $8B,"$C_a_dovarl" +dlrC_a_dovarlPFA word (@a_doconw - @a_base)/4 + word (@a_dovarl - @a_base)/4 + + word @dlrC_a_dovarlNFA + $10 +dlrC_a_doconlNFA byte $8B,"$C_a_doconl" +dlrC_a_doconlPFA word (@a_doconw - @a_base)/4 + word (@a_doconl - @a_base)/4 + + word @dlrC_a_doconlNFA + $10 +dlrC_a_litlNFA byte $89,"$C_a_litl" +dlrC_a_litlPFA word (@a_doconw - @a_base)/4 + word (@a_litl - @a_base)/4 + + word @dlrC_a_litlNFA + $10 +dlrC_a_debugonoffNFA byte $8F,"$C_a_debugonoff" +dlrC_a_debugonoffPFA word (@a_doconw - @a_base)/4 + word (@a_debugonoff - @a_base)/4 + + word @dlrC_a_debugonoffNFA + $10 +dlrC_a_resetNFA byte $8A,"$C_a_reset" +dlrC_a_resetPFA word (@a_doconw - @a_base)/4 + word (@a_reset - @a_base)/4 + + word @dlrC_a_resetNFA + $10 +dlrC_a__execasmtwogtoneNFA byte $90,"$C_a__execasm2>1" +dlrC_a__execasmtwogtonePFA word (@a_doconw - @a_base)/4 + word (@a__execasmtwogtone - @a_base)/4 + + word @dlrC_a__execasmtwogtoneNFA + $10 +dlrC_a__execasmonegtoneNFA byte $90,"$C_a__execasm1>1" +dlrC_a__execasmonegtonePFA word (@a_doconw - @a_base)/4 + word (@a__execasmonegtone - @a_base)/4 + + word @dlrC_a__execasmonegtoneNFA + $10 +dlrC_a__execasmtwogtzNFA byte $90,"$C_a__execasm2>0" +dlrC_a__execasmtwogtzPFA word (@a_doconw - @a_base)/4 + word (@a__execasmtwogtz - @a_base)/4 + + word @dlrC_a__execasmtwogtzNFA + $10 +dlrC_a_umstarlpNFA byte $8D,"$C_a_umstarlp" +dlrC_a_umstarlpPFA word (@a_doconw - @a_base)/4 + word (@a_umstarlp - @a_base)/4 + + word @dlrC_a_umstarlpNFA + $10 +dlrC_a_umslashmodlpNFA byte $91,"$C_a_umslashmodlp" +dlrC_a_umslashmodlpPFA word (@a_doconw - @a_base)/4 + word (@a_umslashmodlp - @a_base)/4 + + word @dlrC_a_umslashmodlpNFA + $10 +dlrC_a_cstreqlpNFA byte $8D,"$C_a_cstreqlp" +dlrC_a_cstreqlpPFA word (@a_doconw - @a_base)/4 + word (@a_cstreqlp - @a_base)/4 + + word @dlrC_a_cstreqlpNFA + $10 +dlrC_a__dictsearchlpNFA byte $92,"$C_a__dictsearchlp" +dlrC_a__dictsearchlpPFA word (@a_doconw - @a_base)/4 + word (@a__dictsearchlp - @a_base)/4 + + word @dlrC_a__dictsearchlpNFA + $10 +dlrC_a_stpushNFA byte $8B,"$C_a_stpush" +dlrC_a_stpushPFA word (@a_doconw - @a_base)/4 + word (@a_stpush - @a_base)/4 + + word @dlrC_a_stpushNFA + $10 +dlrC_a_stpush_retNFA byte $8F,"$C_a_stpush_ret" +dlrC_a_stpush_retPFA word (@a_doconw - @a_base)/4 + word (@a_stpush_ret - @a_base)/4 + + word @dlrC_a_stpush_retNFA + $10 +dlrC_a_rspushNFA byte $8B,"$C_a_rspush" +dlrC_a_rspushPFA word (@a_doconw - @a_base)/4 + word (@a_rspush - @a_base)/4 + + word @dlrC_a_rspushNFA + $10 +dlrC_a_rspush_retNFA byte $8F,"$C_a_rspush_ret" +dlrC_a_rspush_retPFA word (@a_doconw - @a_base)/4 + word (@a_rspush_ret - @a_base)/4 + + word @dlrC_a_rspush_retNFA + $10 +dlrC_a_stpopNFA byte $8A,"$C_a_stpop" +dlrC_a_stpopPFA word (@a_doconw - @a_base)/4 + word (@a_stpop - @a_base)/4 + + word @dlrC_a_stpopNFA + $10 +dlrC_a_stpoptregNFA byte $8E,"$C_a_stpoptreg" +dlrC_a_stpoptregPFA word (@a_doconw - @a_base)/4 + word (@a_stpoptreg - @a_base)/4 + + word @dlrC_a_stpoptregNFA + $10 +dlrC_a_stpop_retNFA byte $8E,"$C_a_stpop_ret" +dlrC_a_stpop_retPFA word (@a_doconw - @a_base)/4 + word (@a_stpop_ret - @a_base)/4 + + word @dlrC_a_stpop_retNFA + $10 +dlrC_a_stpoptreg_retNFA byte $92,"$C_a_stpoptreg_ret" +dlrC_a_stpoptreg_retPFA word (@a_doconw - @a_base)/4 + word (@a_stpoptreg_ret - @a_base)/4 + + word @dlrC_a_stpoptreg_retNFA + $10 +dlrC_a_rspopNFA byte $8A,"$C_a_rspop" +dlrC_a_rspopPFA word (@a_doconw - @a_base)/4 + word (@a_rspop - @a_base)/4 + + word @dlrC_a_rspopNFA + $10 +dlrC_a_rspop_retNFA byte $8E,"$C_a_rspop_ret" +dlrC_a_rspop_retPFA word (@a_doconw - @a_base)/4 + word (@a_rspop_ret - @a_base)/4 + + word @dlrC_a_rspop_retNFA + $10 +dlrC_a_nextNFA byte $89,"$C_a_next" +dlrC_a_nextPFA word (@a_doconw - @a_base)/4 + word (@a_next - @a_base)/4 + + word @dlrC_a_nextNFA + $10 +dlrC_varstartNFA byte $8B,"$C_varstart" +dlrC_varstartPFA word (@a_doconw - @a_base)/4 + word (@varstart - @a_base)/4 + + word @dlrC_varstartNFA + $10 +dlrC_varendNFA byte $89,"$C_varend" +dlrC_varendPFA word (@a_doconw - @a_base)/4 + word (@varend - @a_base)/4 + + word @dlrC_varendNFA + $10 +_cvNFA byte $83,"_cv" +_cvPFA word @dlrC_varstartPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @_cvNFA + $10 +_fmaskNFA byte $86,"_fmask" +_fmaskPFA word @zPFA + $10 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @_fmaskNFA + $10 +_resetdregNFA byte $8A,"_resetdreg" +_resetdregPFA word (@a_litw - @a_base)/4 + word $0003 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @_resetdregNFA + $10 +ipNFA byte $82,"ip" +ipPFA word (@a_litw - @a_base)/4 + word $0004 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @ipNFA + $10 +_rsptrNFA byte $86,"_rsptr" +_rsptrPFA word (@a_litw - @a_base)/4 + word $0006 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @_rsptrNFA + $10 +_rstopNFA byte $86,"_rstop" +_rstopPFA word (@a_litw - @a_base)/4 + word $004E + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @_rstopNFA + $10 +blNFA byte $82,"bl" +blPFA word (@a_doconw - @a_base)/4 + word $0020 + + word @blNFA + $10 +minusoneNFA byte $82,"-1" +minusonePFA word (@a_litl - @a_base)/4 + long $FFFFFFFF + word (@a_exit - @a_base)/4 + + word @minusoneNFA + $10 +zNFA byte $81,"0" +zPFA word (@a_doconw - @a_base)/4 + word $0000 + + word @zNFA + $10 +parNFA byte $83,"par" +parPFA word (@a_doconw - @a_base)/4 + word $01F0 + + word @parNFA + $10 +cntNFA byte $83,"cnt" +cntPFA word (@a_doconw - @a_base)/4 + word $01F1 + + word @cntNFA + $10 +inaNFA byte $83,"ina" +inaPFA word (@a_doconw - @a_base)/4 + word $01F2 + + word @inaNFA + $10 +outaNFA byte $84,"outa" +outaPFA word (@a_doconw - @a_base)/4 + word $01F4 + + word @outaNFA + $10 +diraNFA byte $84,"dira" +diraPFA word (@a_doconw - @a_base)/4 + word $01F6 + + word @diraNFA + $10 +_wkeytoNFA byte $87,"_wkeyto" +_wkeytoPFA word (@a_dovarw - @a_base)/4 + word $2000 + + word @_wkeytoNFA + $10 +_crfNFA byte $84,"_crf" +_crfPFA word (@a_dovarw - @a_base)/4 + word $FFFF + + word @_crfNFA + $10 +_cnipNFA byte $C5,"_cnip" +_cnipPFA word @herePFA + $10 + word @WatPFA + $10 + word @twominusPFA + $10 + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_over - @a_base)/4 + word @twominusPFA + $10 + word @WbangPFA + $10 + word @herePFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @_cnipNFA + $10 +_execasmtwogtoneNFA byte $0B,"_execasm2>1" +_execasmtwogtonePFA word (@a__execasmtwogtone - @a_base)/4 + + word @_execasmtwogtoneNFA + $10 +_execasmonegtoneNFA byte $0B,"_execasm1>1" +_execasmonegtonePFA word (@a__execasmonegtone - @a_base)/4 + + word @_execasmonegtoneNFA + $10 +_execasmtwogtzNFA byte $0B,"_execasm2>0" +_execasmtwogtzPFA word (@a__execasmtwogtz - @a_base)/4 + + word @_execasmtwogtzNFA + $10 +_dictsearchNFA byte $0B,"_dictsearch" +_dictsearchPFA word (@a__dictsearch - @a_base)/4 + + word @_dictsearchNFA + $10 +_maskinNFA byte $07,"_maskin" +_maskinPFA word (@a__maskin - @a_base)/4 + + word @_maskinNFA + $10 +_maskoutloNFA byte $0A,"_maskoutlo" +_maskoutloPFA word (@a__maskoutlo - @a_base)/4 + + word @_maskoutloNFA + $10 +_maskouthiNFA byte $0A,"_maskouthi" +_maskouthiPFA word (@a__maskouthi - @a_base)/4 + + word @_maskouthiNFA + $10 +nameeqNFA byte $05,"name=" +nameeqPFA word (@a_nameeq - @a_base)/4 + + word @nameeqNFA + $10 +cstreqNFA byte $05,"cstr=" +cstreqPFA word (@a_cstreq - @a_base)/4 + + word @cstreqNFA + $10 +andNFA byte $83,"and" +andPFA word (@a__execasmtwogtone - @a_base)/4 + word $00C1 + word (@a_exit - @a_base)/4 + + word @andNFA + $10 +andnNFA byte $84,"andn" +andnPFA word (@a__execasmtwogtone - @a_base)/4 + word $00C9 + word (@a_exit - @a_base)/4 + + word @andnNFA + $10 +LatNFA byte $82,"L@" +LatPFA word (@a__execasmonegtone - @a_base)/4 + word $0011 + word (@a_exit - @a_base)/4 + + word @LatNFA + $10 +CatNFA byte $82,"C@" +CatPFA word (@a__execasmonegtone - @a_base)/4 + word $0001 + word (@a_exit - @a_base)/4 + + word @CatNFA + $10 +WatNFA byte $82,"W@" +WatPFA word (@a__execasmonegtone - @a_base)/4 + word $0009 + word (@a_exit - @a_base)/4 + + word @WatNFA + $10 +COGatNFA byte $04,"COG@" +COGatPFA word (@a_COGat - @a_base)/4 + + word @COGatNFA + $10 +LbangNFA byte $82,"L!" +LbangPFA word (@a__execasmtwogtz - @a_base)/4 + word $0010 + word (@a_exit - @a_base)/4 + + word @LbangNFA + $10 +CbangNFA byte $82,"C!" +CbangPFA word (@a__execasmtwogtz - @a_base)/4 + word $0000 + word (@a_exit - @a_base)/4 + + word @CbangNFA + $10 +WbangNFA byte $82,"W!" +WbangPFA word (@a__execasmtwogtz - @a_base)/4 + word $0008 + word (@a_exit - @a_base)/4 + + word @WbangNFA + $10 +COGbangNFA byte $04,"COG!" +COGbangPFA word (@a_COGbang - @a_base)/4 + + word @COGbangNFA + $10 +branchNFA byte $06,"branch" +branchPFA word (@a_branch - @a_base)/4 + + word @branchNFA + $10 +hubopNFA byte $05,"hubop" +hubopPFA word (@a_hubop - @a_base)/4 + + word @hubopNFA + $10 +doconwNFA byte $06,"doconw" +doconwPFA word (@a_doconw - @a_base)/4 + + word @doconwNFA + $10 +doconlNFA byte $06,"doconl" +doconlPFA word (@a_doconl - @a_base)/4 + + word @doconlNFA + $10 +dovarwNFA byte $06,"dovarw" +dovarwPFA word (@a_dovarw - @a_base)/4 + + word @dovarwNFA + $10 +dovarlNFA byte $06,"dovarl" +dovarlPFA word (@a_dovarl - @a_base)/4 + + word @dovarlNFA + $10 +dropNFA byte $04,"drop" +dropPFA word (@a_drop - @a_base)/4 + + word @dropNFA + $10 +dupNFA byte $03,"dup" +dupPFA word (@a_dup - @a_base)/4 + + word @dupNFA + $10 +eqNFA byte $01,"=" +eqPFA word (@a_eq - @a_base)/4 + + word @eqNFA + $10 +exitNFA byte $04,"exit" +exitPFA word (@a_exit - @a_base)/4 + + word @exitNFA + $10 +gtNFA byte $01,">" +gtPFA word (@a_gt - @a_base)/4 + + word @gtNFA + $10 +litwNFA byte $04,"litw" +litwPFA word (@a_litw - @a_base)/4 + + word @litwNFA + $10 +litlNFA byte $04,"litl" +litlPFA word (@a_litl - @a_base)/4 + + word @litlNFA + $10 +lshiftNFA byte $86,"lshift" +lshiftPFA word (@a__execasmtwogtone - @a_base)/4 + word $0059 + word (@a_exit - @a_base)/4 + + word @lshiftNFA + $10 +ltNFA byte $01,"<" +ltPFA word (@a_lt - @a_base)/4 + + word @ltNFA + $10 +maxNFA byte $83,"max" +maxPFA word (@a__execasmtwogtone - @a_base)/4 + word $0081 + word (@a_exit - @a_base)/4 + + word @maxNFA + $10 +minNFA byte $83,"min" +minPFA word (@a__execasmtwogtone - @a_base)/4 + word $0089 + word (@a_exit - @a_base)/4 + + word @minNFA + $10 +minusNFA byte $81,"-" +minusPFA word (@a__execasmtwogtone - @a_base)/4 + word $0109 + word (@a_exit - @a_base)/4 + + word @minusNFA + $10 +orNFA byte $82,"or" +orPFA word (@a__execasmtwogtone - @a_base)/4 + word $00D1 + word (@a_exit - @a_base)/4 + + word @orNFA + $10 +overNFA byte $04,"over" +overPFA word (@a_over - @a_base)/4 + + word @overNFA + $10 +plusNFA byte $81,"+" +plusPFA word (@a__execasmtwogtone - @a_base)/4 + word $0101 + word (@a_exit - @a_base)/4 + + word @plusNFA + $10 +rotNFA byte $03,"rot" +rotPFA word (@a_rot - @a_base)/4 + + word @rotNFA + $10 +rshiftNFA byte $86,"rshift" +rshiftPFA word (@a__execasmtwogtone - @a_base)/4 + word $0051 + word (@a_exit - @a_base)/4 + + word @rshiftNFA + $10 +rashiftNFA byte $87,"rashift" +rashiftPFA word (@a__execasmtwogtone - @a_base)/4 + word $0071 + word (@a_exit - @a_base)/4 + + word @rashiftNFA + $10 +rgtNFA byte $02,"r>" +rgtPFA word (@a_rgt - @a_base)/4 + + word @rgtNFA + $10 +gtrNFA byte $02,">r" +gtrPFA word (@a_gtr - @a_base)/4 + + word @gtrNFA + $10 +twogtrNFA byte $03,"2>r" +twogtrPFA word (@a_twogtr - @a_base)/4 + + word @twogtrNFA + $10 +zbranchNFA byte $07,"0branch" +zbranchPFA word (@a_zbranch - @a_base)/4 + + word @zbranchNFA + $10 +lparenlooprparenNFA byte $06,"(loop)" +lparenlooprparenPFA word (@a_lparenlooprparen - @a_base)/4 + + word @lparenlooprparenNFA + $10 +lparenpluslooprparenNFA byte $07,"(+loop)" +lparenpluslooprparenPFA word (@a_lparenpluslooprparen - @a_base)/4 + + word @lparenpluslooprparenNFA + $10 +swapNFA byte $04,"swap" +swapPFA word (@a_swap - @a_base)/4 + + word @swapNFA + $10 +umstarNFA byte $03,"um*" +umstarPFA word (@a_umstar - @a_base)/4 + + word @umstarNFA + $10 +umslashmodNFA byte $06,"um/mod" +umslashmodPFA word (@a_umslashmod - @a_base)/4 + + word @umslashmodNFA + $10 +uslashmodNFA byte $85,"u/mod" +uslashmodPFA word @zPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_umslashmod - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @uslashmodNFA + $10 +xorNFA byte $83,"xor" +xorPFA word (@a__execasmtwogtone - @a_base)/4 + word $00D9 + word (@a_exit - @a_base)/4 + + word @xorNFA + $10 +rebootNFA byte $86,"reboot" +rebootPFA word (@a_litw - @a_base)/4 + word $00FF + word @zPFA + $10 + word (@a_hubop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @rebootNFA + $10 +cogstopNFA byte $87,"cogstop" +cogstopPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word (@a_hubop - @a_base)/4 + word @twodropPFA + $10 + word @cogioPFA + $10 + word @fourplusPFA + $10 + word @_cdszPFA + $10 + word @twominusPFA + $10 + word @twominusPFA + $10 + word @zPFA + $10 + word @fillPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogstopNFA + $10 +cogresetNFA byte $88,"cogreset" +cogresetPFA word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_dup - @a_base)/4 + word @cogidPFA + $10 + word @ltgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word (@a_dup - @a_base)/4 + word @cogstopPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_dup - @a_base)/4 + word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @dlrH_entryPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @lshiftPFA + $10 + word @orPFA + $10 + word @orPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word (@a_hubop - @a_base)/4 + word @twodropPFA + $10 + word @cogstatePFA + $10 + word (@a_litw - @a_base)/4 + word $8000 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEE + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cogresetNFA + $10 +resetNFA byte $85,"reset" +resetPFA word @mydictlockPFA + $10 + word @CatPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word @lockclrPFA + $10 + word (@a_drop - @a_base)/4 + word @cogidPFA + $10 + word @cogresetPFA + $10 + word (@a_exit - @a_base)/4 + + word @resetNFA + $10 +clkfreqNFA byte $87,"clkfreq" +clkfreqPFA word @zPFA + $10 + word @LatPFA + $10 + word (@a_exit - @a_base)/4 + + word @clkfreqNFA + $10 +paratNFA byte $85,"parat" +paratPFA word @parPFA + $10 + word (@a_COGat - @a_base)/4 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @paratNFA + $10 +cogioNFA byte $85,"cogio" +cogioPFA word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word @_cdszPFA + $10 + word @ustarPFA + $10 + word @dlrH_cogdataPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogioNFA + $10 +cogiochanNFA byte $89,"cogiochan" +cogiochanPFA word (@a_over - @a_base)/4 + word @cognchanPFA + $10 + word @oneminusPFA + $10 + word @minPFA + $10 + word @fourstarPFA + $10 + word (@a_swap - @a_base)/4 + word @cogioPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogiochanNFA + $10 +iogtcogchanNFA byte $8A,"io>cogchan" +iogtcogchanPFA word @dlrH_cogdataPFA + $10 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word @zltPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_dup - @a_base)/4 + word (@a_branch - @a_base)/4 + word $001A + word @_cdszPFA + $10 + word @uslashmodPFA + $10 + word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_dup - @a_base)/4 + word @cognchanPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0004 + word @uslashPFA + $10 + word @minPFA + $10 + word (@a_exit - @a_base)/4 + + word @iogtcogchanNFA + $10 +iogtcogNFA byte $86,"io>cog" +iogtcogPFA word @iogtcogchanPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @iogtcogNFA + $10 +ioNFA byte $82,"io" +ioPFA word @parPFA + $10 + word (@a_COGat - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @ioNFA + $10 +ERRNFA byte $83,"ERR" +ERRPFA word @clearkeysPFA + $10 + word @ioPFA + $10 + word @WbangPFA + $10 + word @resetPFA + $10 + word (@a_exit - @a_base)/4 + + word @ERRNFA + $10 +lpareniodisrparenNFA byte $87,"(iodis)" +lpareniodisrparenPFA word @cogiochanPFA + $10 + word @twoplusPFA + $10 + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_swap - @a_base)/4 + word @zPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000E + word @zPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @lpareniodisrparenNFA + $10 +iodisNFA byte $85,"iodis" +iodisPFA word @zPFA + $10 + word @lpareniodisrparenPFA + $10 + word (@a_exit - @a_base)/4 + + word @iodisNFA + $10 +lparenioconnrparenNFA byte $88,"(ioconn)" +lparenioconnrparenPFA word @twodupPFA + $10 + word @lpareniodisrparenPFA + $10 + word (@a_gtr - @a_base)/4 + word (@a_gtr - @a_base)/4 + word @twodupPFA + $10 + word @lpareniodisrparenPFA + $10 + word (@a_rgt - @a_base)/4 + word (@a_rgt - @a_base)/4 + word @cogiochanPFA + $10 + word @rottwoPFA + $10 + word @cogiochanPFA + $10 + word @twodupPFA + $10 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @lparenioconnrparenNFA + $10 +ioconnNFA byte $86,"ioconn" +ioconnPFA word @zPFA + $10 + word @tuckPFA + $10 + word @lparenioconnrparenPFA + $10 + word (@a_exit - @a_base)/4 + + word @ioconnNFA + $10 +lpareniolinkrparenNFA byte $88,"(iolink)" +lpareniolinkrparenPFA word @cogiochanPFA + $10 + word @rottwoPFA + $10 + word @cogiochanPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word @twoplusPFA + $10 + word @WatPFA + $10 + word (@a_over - @a_base)/4 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @lpareniolinkrparenNFA + $10 +iolinkNFA byte $86,"iolink" +iolinkPFA word @zPFA + $10 + word @tuckPFA + $10 + word @lpareniolinkrparenPFA + $10 + word (@a_exit - @a_base)/4 + + word @iolinkNFA + $10 +lpareniounlinkrparenNFA byte $8A,"(iounlink)" +lpareniounlinkrparenPFA word @cogiochanPFA + $10 + word @twoplusPFA + $10 + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word @twoplusPFA + $10 + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_rot - @a_base)/4 + word @WbangPFA + $10 + word @zPFA + $10 + word (@a_swap - @a_base)/4 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @lpareniounlinkrparenNFA + $10 +iounlinkNFA byte $88,"iounlink" +iounlinkPFA word @zPFA + $10 + word @lpareniounlinkrparenPFA + $10 + word (@a_exit - @a_base)/4 + + word @iounlinkNFA + $10 +debugcmdNFA byte $88,"debugcmd" +debugcmdPFA word (@a_litw - @a_base)/4 + word $0006 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @debugcmdNFA + $10 +cogdebugcmdNFA byte $8B,"cogdebugcmd" +cogdebugcmdPFA word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $0006 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogdebugcmdNFA + $10 +debugvalueNFA byte $8A,"debugvalue" +debugvaluePFA word (@a_litw - @a_base)/4 + word $0008 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @debugvalueNFA + $10 +cogdebugvalueNFA byte $8D,"cogdebugvalue" +cogdebugvaluePFA word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogdebugvalueNFA + $10 +baseNFA byte $84,"base" +basePFA word (@a_litw - @a_base)/4 + word $000C + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @baseNFA + $10 +coghereNFA byte $87,"coghere" +cogherePFA word (@a_litw - @a_base)/4 + word $000E + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @coghereNFA + $10 +execwordNFA byte $88,"execword" +execwordPFA word (@a_litw - @a_base)/4 + word $0010 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @execwordNFA + $10 +executeNFA byte $87,"execute" +executePFA word (@a_dup - @a_base)/4 + word @_fmaskPFA + $10 + word (@a_COGat - @a_base)/4 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @ipPFA + $10 + word (@a_COGbang - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0014 + word @execwordPFA + $10 + word @WbangPFA + $10 + word @dlrC_a_exitPFA + $10 + word @execwordPFA + $10 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word @execwordPFA + $10 + word @ipPFA + $10 + word (@a_COGbang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @executeNFA + $10 +gtoutNFA byte $84,">out" +gtoutPFA word (@a_litw - @a_base)/4 + word $0014 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @gtoutNFA + $10 +gtinNFA byte $83,">in" +gtinPFA word (@a_litw - @a_base)/4 + word $0016 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @gtinNFA + $10 +padNFA byte $83,"pad" +padPFA word (@a_litw - @a_base)/4 + word $0018 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @padNFA + $10 +cogpadNFA byte $86,"cogpad" +cogpadPFA word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $0018 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogpadNFA + $10 +padgtinNFA byte $86,"pad>in" +padgtinPFA word @gtinPFA + $10 + word @WatPFA + $10 + word @padPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @padgtinNFA + $10 +namemaxNFA byte $87,"namemax" +namemaxPFA word (@a_litw - @a_base)/4 + word $001F + word (@a_exit - @a_base)/4 + + word @namemaxNFA + $10 +padsizeNFA byte $87,"padsize" +padsizePFA word (@a_doconw - @a_base)/4 + word $0080 + + word @padsizeNFA + $10 +tzNFA byte $82,"t0" +tzPFA word (@a_litw - @a_base)/4 + word $0098 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @tzNFA + $10 +toneNFA byte $82,"t1" +tonePFA word (@a_litw - @a_base)/4 + word $009A + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @toneNFA + $10 +tbufNFA byte $84,"tbuf" +tbufPFA word (@a_litw - @a_base)/4 + word $009C + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @tbufNFA + $10 +numpadNFA byte $86,"numpad" +numpadPFA word (@a_litw - @a_base)/4 + word $00BC + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @numpadNFA + $10 +cognumpadNFA byte $89,"cognumpad" +cognumpadPFA word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $00BC + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cognumpadNFA + $10 +padgtoutNFA byte $87,"pad>out" +padgtoutPFA word @gtoutPFA + $10 + word @WatPFA + $10 + word @numpadPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @padgtoutNFA + $10 +numpadsizeNFA byte $8A,"numpadsize" +numpadsizePFA word (@a_doconw - @a_base)/4 + word $0022 + + word @numpadsizeNFA + $10 +mydictlockNFA byte $8A,"mydictlock" +mydictlockPFA word (@a_litw - @a_base)/4 + word $00DE + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mydictlockNFA + $10 +stateNFA byte $85,"state" +statePFA word (@a_litw - @a_base)/4 + word $00DF + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @stateNFA + $10 +cogstateNFA byte $88,"cogstate" +cogstatePFA word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $00DF + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogstateNFA + $10 +cognchanNFA byte $88,"cognchan" +cognchanPFA word @cogstatePFA + $10 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $0005 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cognchanNFA + $10 +gtconNFA byte $84,">con" +gtconPFA word @conPFA + $10 + word @ioconnPFA + $10 + word (@a_exit - @a_base)/4 + + word @gtconNFA + $10 +compileqNFA byte $88,"compile?" +compileqPFA word @statePFA + $10 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @compileqNFA + $10 +emitqNFA byte $85,"emit?" +emitqPFA word @ioPFA + $10 + word @twoplusPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0010 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word @zltgtPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @emitqNFA + $10 +femitqNFA byte $86,"femit?" +femitqPFA word @ioPFA + $10 + word @twoplusPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $002A + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0014 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word @WbangPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word @twodropPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word @twodropPFA + $10 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @femitqNFA + $10 +emitNFA byte $84,"emit" +emitPFA word (@a_dup - @a_base)/4 + word @femitqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFA + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @emitNFA + $10 +keyqNFA byte $84,"key?" +keyqPFA word @ioPFA + $10 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_exit - @a_base)/4 + + word @keyqNFA + $10 +fkeyqNFA byte $85,"fkey?" +fkeyqPFA word @ioPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $0100 + word @ioPFA + $10 + word @WbangPFA + $10 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @fkeyqNFA + $10 +keyNFA byte $83,"key" +keyPFA word @zPFA + $10 + word (@a_drop - @a_base)/4 + word @fkeyqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFA + word (@a_exit - @a_base)/4 + + word @keyNFA + $10 +twodupNFA byte $84,"2dup" +twodupPFA word (@a_over - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @twodupNFA + $10 +twodropNFA byte $85,"2drop" +twodropPFA word (@a_drop - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @twodropNFA + $10 +threedropNFA byte $85,"3drop" +threedropPFA word @twodropPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @threedropNFA + $10 +uslashNFA byte $82,"u/" +uslashPFA word @uslashmodPFA + $10 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @uslashNFA + $10 +ustarNFA byte $82,"u*" +ustarPFA word (@a_umstar - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @ustarNFA + $10 +invertNFA byte $86,"invert" +invertPFA word @minusonePFA + $10 + word @xorPFA + $10 + word (@a_exit - @a_base)/4 + + word @invertNFA + $10 +negateNFA byte $86,"negate" +negatePFA word (@a__execasmonegtone - @a_base)/4 + word $0149 + word (@a_exit - @a_base)/4 + + word @negateNFA + $10 +zeqNFA byte $82,"0=" +zeqPFA word @zPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @zeqNFA + $10 +ltgtNFA byte $82,"<>" +ltgtPFA word (@a_eq - @a_base)/4 + word @invertPFA + $10 + word (@a_exit - @a_base)/4 + + word @ltgtNFA + $10 +zltgtNFA byte $83,"0<>" +zltgtPFA word @zeqPFA + $10 + word @invertPFA + $10 + word (@a_exit - @a_base)/4 + + word @zltgtNFA + $10 +zltNFA byte $82,"0<" +zltPFA word @zPFA + $10 + word (@a_lt - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @zltNFA + $10 +zgtNFA byte $82,"0>" +zgtPFA word @zPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @zgtNFA + $10 +oneplusNFA byte $82,"1+" +oneplusPFA word (@a_litw - @a_base)/4 + word $0001 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @oneplusNFA + $10 +oneminusNFA byte $82,"1-" +oneminusPFA word (@a_litw - @a_base)/4 + word $0001 + word @minusPFA + $10 + word (@a_exit - @a_base)/4 + + word @oneminusNFA + $10 +twoplusNFA byte $82,"2+" +twoplusPFA word (@a_litw - @a_base)/4 + word $0002 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @twoplusNFA + $10 +twominusNFA byte $82,"2-" +twominusPFA word (@a_litw - @a_base)/4 + word $0002 + word @minusPFA + $10 + word (@a_exit - @a_base)/4 + + word @twominusNFA + $10 +fourplusNFA byte $82,"4+" +fourplusPFA word (@a_litw - @a_base)/4 + word $0004 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @fourplusNFA + $10 +twostarNFA byte $82,"2*" +twostarPFA word (@a_litw - @a_base)/4 + word $0001 + word @lshiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @twostarNFA + $10 +fourstarNFA byte $82,"4*" +fourstarPFA word (@a_litw - @a_base)/4 + word $0002 + word @lshiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @fourstarNFA + $10 +twoslashNFA byte $82,"2/" +twoslashPFA word (@a_litw - @a_base)/4 + word $0001 + word @rashiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @twoslashNFA + $10 +rottwoNFA byte $84,"rot2" +rottwoPFA word (@a_rot - @a_base)/4 + word (@a_rot - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @rottwoNFA + $10 +nipNFA byte $83,"nip" +nipPFA word (@a_swap - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @nipNFA + $10 +tuckNFA byte $84,"tuck" +tuckPFA word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @tuckNFA + $10 +gteqNFA byte $82,">=" +gteqPFA word @twodupPFA + $10 + word (@a_gt - @a_base)/4 + word @rottwoPFA + $10 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @gteqNFA + $10 +lteqNFA byte $82,"<=" +lteqPFA word @twodupPFA + $10 + word (@a_lt - @a_base)/4 + word @rottwoPFA + $10 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @lteqNFA + $10 +zgteqNFA byte $83,"0>=" +zgteqPFA word (@a_dup - @a_base)/4 + word @zPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_swap - @a_base)/4 + word @zeqPFA + $10 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @zgteqNFA + $10 +WplusbangNFA byte $83,"W+!" +WplusbangPFA word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_rot - @a_base)/4 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @WplusbangNFA + $10 +orCbangNFA byte $84,"orC!" +orCbangPFA word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word (@a_rot - @a_base)/4 + word @orPFA + $10 + word (@a_swap - @a_base)/4 + word @CbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @orCbangNFA + $10 +andnCbangNFA byte $86,"andnC!" +andnCbangPFA word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word (@a_rot - @a_base)/4 + word @andnPFA + $10 + word (@a_swap - @a_base)/4 + word @CbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @andnCbangNFA + $10 +betweenNFA byte $87,"between" +betweenPFA word @rottwoPFA + $10 + word (@a_over - @a_base)/4 + word @lteqPFA + $10 + word @rottwoPFA + $10 + word @gteqPFA + $10 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @betweenNFA + $10 +crNFA byte $82,"cr" +crPFA word (@a_litw - @a_base)/4 + word $000D + word @emitPFA + $10 + word @_crfPFA + $10 + word @WatPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $000A + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @crNFA + $10 +spaceNFA byte $85,"space" +spacePFA word @blPFA + $10 + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @spaceNFA + $10 +spacesNFA byte $86,"spaces" +spacesPFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0010 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @spacePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFFC + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @spacesNFA + $10 +dothexNFA byte $84,".hex" +dothexPFA word (@a_litw - @a_base)/4 + word $000F + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0039 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $0007 + word @plusPFA + $10 + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @dothexNFA + $10 +dotbyteNFA byte $85,".byte" +dotbytePFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0004 + word @rshiftPFA + $10 + word @dothexPFA + $10 + word @dothexPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotbyteNFA + $10 +dotwordNFA byte $85,".word" +dotwordPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @rshiftPFA + $10 + word @dotbytePFA + $10 + word @dotbytePFA + $10 + word (@a_exit - @a_base)/4 + + word @dotwordNFA + $10 +boundsNFA byte $86,"bounds" +boundsPFA word (@a_over - @a_base)/4 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @boundsNFA + $10 +alignlNFA byte $86,"alignl" +alignlPFA word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_litl - @a_base)/4 + long $FFFFFFFC + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @alignlNFA + $10 +alignwNFA byte $86,"alignw" +alignwPFA word @oneplusPFA + $10 + word (@a_litl - @a_base)/4 + long $FFFFFFFE + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @alignwNFA + $10 +CatplusplusNFA byte $84,"C@++" +CatplusplusPFA word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @CatplusplusNFA + $10 +ctoupperNFA byte $88,"ctoupper" +ctoupperPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0061 + word (@a_litw - @a_base)/4 + word $007A + word @betweenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $00DF + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @ctoupperNFA + $10 +todigitNFA byte $87,"todigit" +todigitPFA word @ctoupperPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0009 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0018 + word (@a_litw - @a_base)/4 + word $0007 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000A + word (@a_lt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @todigitNFA + $10 +isdigitNFA byte $87,"isdigit" +isdigitPFA word @todigitPFA + $10 + word (@a_dup - @a_base)/4 + word @zgteqPFA + $10 + word (@a_swap - @a_base)/4 + word @basePFA + $10 + word @WatPFA + $10 + word (@a_lt - @a_base)/4 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @isdigitNFA + $10 +isunumberNFA byte $89,"isunumber" +isunumberPFA word @boundsPFA + $10 + word @minusonePFA + $10 + word @rottwoPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @CatPFA + $10 + word @isdigitPFA + $10 + word @andPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word (@a_exit - @a_base)/4 + + word @isunumberNFA + $10 +unumberNFA byte $87,"unumber" +unumberPFA word @boundsPFA + $10 + word @zPFA + $10 + word @rottwoPFA + $10 + word (@a_twogtr - @a_base)/4 + word @basePFA + $10 + word @WatPFA + $10 + word @ustarPFA + $10 + word @iPFA + $10 + word @CatPFA + $10 + word @todigitPFA + $10 + word @plusPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF0 + word (@a_exit - @a_base)/4 + + word @unumberNFA + $10 +numberNFA byte $86,"number" +numberPFA word (@a_over - @a_base)/4 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $002D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0016 + word @oneminusPFA + $10 + word @zPFA + $10 + word @maxPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @unumberPFA + $10 + word @negatePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @unumberPFA + $10 + word (@a_exit - @a_base)/4 + + word @numberNFA + $10 +isnumberNFA byte $88,"isnumber" +isnumberPFA word (@a_over - @a_base)/4 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $002D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000E + word @oneminusPFA + $10 + word @zPFA + $10 + word @maxPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @isunumberPFA + $10 + word (@a_exit - @a_base)/4 + + word @isnumberNFA + $10 +dotstrNFA byte $84,".str" +dotstrPFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @CatPFA + $10 + word @emitPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_branch - @a_base)/4 + word $0004 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotstrNFA + $10 +npfxNFA byte $84,"npfx" +npfxPFA word @namelenPFA + $10 + word (@a_rot - @a_base)/4 + word @namelenPFA + $10 + word (@a_rot - @a_base)/4 + word @twodupPFA + $10 + word @gteqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0024 + word @minPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @CatplusplusPFA + $10 + word @iPFA + $10 + word @CatPFA + $10 + word @ltgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEC + word @zltgtPFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @twodropPFA + $10 + word @twodropPFA + $10 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @npfxNFA + $10 +namelenNFA byte $87,"namelen" +namelenPFA word @CatplusplusPFA + $10 + word @namemaxPFA + $10 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @namelenNFA + $10 +cmoveNFA byte $85,"cmove" +cmovePFA word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @threedropPFA + $10 + word (@a_branch - @a_base)/4 + word $0010 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @CatplusplusPFA + $10 + word @iPFA + $10 + word @CbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cmoveNFA + $10 +namecopyNFA byte $88,"namecopy" +namecopyPFA word (@a_over - @a_base)/4 + word @namelenPFA + $10 + word @oneplusPFA + $10 + word @nipPFA + $10 + word @cmovePFA + $10 + word (@a_exit - @a_base)/4 + + word @namecopyNFA + $10 +ccopyNFA byte $85,"ccopy" +ccopyPFA word (@a_over - @a_base)/4 + word @CatPFA + $10 + word @oneplusPFA + $10 + word @cmovePFA + $10 + word (@a_exit - @a_base)/4 + + word @ccopyNFA + $10 +cappendNFA byte $87,"cappend" +cappendPFA word (@a_dup - @a_base)/4 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word @plusPFA + $10 + word @oneplusPFA + $10 + word @rottwoPFA + $10 + word (@a_over - @a_base)/4 + word @CatPFA + $10 + word (@a_over - @a_base)/4 + word @CatPFA + $10 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word @CbangPFA + $10 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word @rottwoPFA + $10 + word @cmovePFA + $10 + word (@a_exit - @a_base)/4 + + word @cappendNFA + $10 +cappendnNFA byte $88,"cappendn" +cappendnPFA word (@a_swap - @a_base)/4 + word @lthashPFA + $10 + word @hashsPFA + $10 + word @hashgtPFA + $10 + word (@a_swap - @a_base)/4 + word @cappendPFA + $10 + word (@a_exit - @a_base)/4 + + word @cappendnNFA + $10 +lparennfcogrparenNFA byte $87,"(nfcog)" +lparennfcogrparenPFA word @minusonePFA + $10 + word @minusonePFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @cogstatePFA + $10 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0018 + word @iPFA + $10 + word @cogioPFA + $10 + word @twoplusPFA + $10 + word @WatPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @twodropPFA + $10 + word @iPFA + $10 + word @zPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFD8 + word (@a_exit - @a_base)/4 + + word @lparennfcogrparenNFA + $10 +nfcogNFA byte $85,"nfcog" +nfcogPFA word @lparennfcogrparenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0012 + word (@a_drop - @a_base)/4 + word @lparencogplusrparenPFA + $10 + word @lparennfcogrparenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $8001 + word @ERRPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfcogNFA + $10 +cogxNFA byte $84,"cogx" +cogxPFA word @ioPFA + $10 + word @twoplusPFA + $10 + word @WatPFA + $10 + word @rottwoPFA + $10 + word @cogioPFA + $10 + word @ioPFA + $10 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word @dotcstrPFA + $10 + word @crPFA + $10 + word @ioPFA + $10 + word @twoplusPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogxNFA + $10 +dotstrnameNFA byte $88,".strname" +dotstrnamePFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000A + word @namelenPFA + $10 + word @dotstrPFA + $10 + word (@a_branch - @a_base)/4 + word $000A + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $003F + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotstrnameNFA + $10 +dotcstrNFA byte $85,".cstr" +dotcstrPFA word @CatplusplusPFA + $10 + word @dotstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotcstrNFA + $10 +dqNFA byte $82,"dq" +dqPFA word (@a_rgt - @a_base)/4 + word @CatplusplusPFA + $10 + word @twodupPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word (@a_gtr - @a_base)/4 + word @dotstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dqNFA + $10 +iNFA byte $81,"i" +iPFA word @_rsptrPFA + $10 + word (@a_COGat - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_COGat - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @iNFA + $10 +iboundNFA byte $86,"ibound" +iboundPFA word @_rsptrPFA + $10 + word (@a_COGat - @a_base)/4 + word @twoplusPFA + $10 + word (@a_COGat - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @iboundNFA + $10 +setiNFA byte $84,"seti" +setiPFA word @_rsptrPFA + $10 + word (@a_COGat - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_COGbang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @setiNFA + $10 +fillNFA byte $84,"fill" +fillPFA word @rottwoPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @iPFA + $10 + word @CbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @fillNFA + $10 +nfagtlfaNFA byte $87,"nfa>lfa" +nfagtlfaPFA word @twominusPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfagtlfaNFA + $10 +nfagtpfaNFA byte $87,"nfa>pfa" +nfagtpfaPFA word (@a_litw - @a_base)/4 + word $7FFF + word @andPFA + $10 + word @namelenPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfagtpfaNFA + $10 +nfagtnextNFA byte $88,"nfa>next" +nfagtnextPFA word @nfagtlfaPFA + $10 + word @WatPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfagtnextNFA + $10 +lastnfaNFA byte $87,"lastnfa" +lastnfaPFA word @wlastnfaPFA + $10 + word @WatPFA + $10 + word (@a_exit - @a_base)/4 + + word @lastnfaNFA + $10 +isnamecharNFA byte $8A,"isnamechar" +isnamecharPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0020 + word (@a_gt - @a_base)/4 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word (@a_lt - @a_base)/4 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @isnamecharNFA + $10 +_forthpfagtnfaNFA byte $8D,"_forthpfa>nfa" +_forthpfagtnfaPFA word (@a_litw - @a_base)/4 + word $7FFF + word @andPFA + $10 + word @oneminusPFA + $10 + word @oneminusPFA + $10 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word @isnamecharPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word (@a_exit - @a_base)/4 + + word @_forthpfagtnfaNFA + $10 +_asmpfagtnfaNFA byte $8B,"_asmpfa>nfa" +_asmpfagtnfaPFA word @lastnfaPFA + $10 + word @twodupPFA + $10 + word @nfagtpfaPFA + $10 + word @WatPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_over - @a_base)/4 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @andPFA + $10 + word @zeqPFA + $10 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @nfagtnextPFA + $10 + word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFD8 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @_asmpfagtnfaNFA + $10 +pfagtnfaNFA byte $87,"pfa>nfa" +pfagtnfaPFA word (@a_dup - @a_base)/4 + word @_fmaskPFA + $10 + word (@a_COGat - @a_base)/4 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @_forthpfagtnfaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_asmpfagtnfaPFA + $10 + word (@a_exit - @a_base)/4 + + word @pfagtnfaNFA + $10 +acceptNFA byte $86,"accept" +acceptPFA word (@a_litw - @a_base)/4 + word $0003 + word @maxPFA + $10 + word @twodupPFA + $10 + word @blPFA + $10 + word @fillPFA + $10 + word @oneminusPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @boundsPFA + $10 + word @zPFA + $10 + word @keyPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000A + word (@a_eq - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000D + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @crPFA + $10 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $006E + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word (@a_eq - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $002E + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0020 + word (@a_litw - @a_base)/4 + word $0008 + word @emitPFA + $10 + word @blPFA + $10 + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @emitPFA + $10 + word @oneminusPFA + $10 + word (@a_swap - @a_base)/4 + word @oneminusPFA + $10 + word @blPFA + $10 + word (@a_over - @a_base)/4 + word @CbangPFA + $10 + word (@a_swap - @a_base)/4 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $002C + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0009 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @blPFA + $10 + word (@a_dup - @a_base)/4 + word @emitPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_gtr - @a_base)/4 + word (@a_over - @a_base)/4 + word @CbangPFA + $10 + word @oneplusPFA + $10 + word @twodupPFA + $10 + word @oneplusPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_rgt - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FF70 + word @nipPFA + $10 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @acceptNFA + $10 +parseNFA byte $85,"parse" +parsePFA word @padsizePFA + $10 + word @gtinPFA + $10 + word @WatPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0020 + word @zPFA + $10 + word @twodupPFA + $10 + word @padgtinPFA + $10 + word @plusPFA + $10 + word @CatPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word @oneplusPFA + $10 + word @zPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFE6 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @parseNFA + $10 +skipblNFA byte $86,"skipbl" +skipblPFA word @padgtinPFA + $10 + word @CatPFA + $10 + word @blPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0016 + word @gtinPFA + $10 + word @WatPFA + $10 + word @oneplusPFA + $10 + word (@a_dup - @a_base)/4 + word @gtinPFA + $10 + word @WbangPFA + $10 + word @padsizePFA + $10 + word (@a_eq - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFDC + word (@a_exit - @a_base)/4 + + word @skipblNFA + $10 +nextwordNFA byte $88,"nextword" +nextwordPFA word @padsizePFA + $10 + word @gtinPFA + $10 + word @WatPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word @padgtinPFA + $10 + word @CatPFA + $10 + word @gtinPFA + $10 + word @WatPFA + $10 + word @plusPFA + $10 + word @oneplusPFA + $10 + word @gtinPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @nextwordNFA + $10 +parsewordNFA byte $89,"parseword" +parsewordPFA word @skipblPFA + $10 + word @parsePFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @gtinPFA + $10 + word @WatPFA + $10 + word @oneminusPFA + $10 + word @twodupPFA + $10 + word @padPFA + $10 + word @plusPFA + $10 + word @CbangPFA + $10 + word @gtinPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @parsewordNFA + $10 +parseblNFA byte $87,"parsebl" +parseblPFA word @blPFA + $10 + word @parsewordPFA + $10 + word @zltgtPFA + $10 + word (@a_exit - @a_base)/4 + + word @parseblNFA + $10 +parsenwNFA byte $87,"parsenw" +parsenwPFA word @parseblPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @padgtinPFA + $10 + word @nextwordPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @parsenwNFA + $10 +findNFA byte $84,"find" +findPFA word @lastnfaPFA + $10 + word (@a_over - @a_base)/4 + word (@a__dictsearch - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0048 + word @nipPFA + $10 + word (@a_dup - @a_base)/4 + word @nfagtpfaPFA + $10 + word (@a_over - @a_base)/4 + word @CatPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @WatPFA + $10 + word (@a_swap - @a_base)/4 + word @CatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0040 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $001C + word (@a_litw - @a_base)/4 + word $0020 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $0002 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_litw - @a_base)/4 + word $0001 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @findNFA + $10 +lthashNFA byte $82,"<#" +lthashPFA word @numpadsizePFA + $10 + word @gtoutPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @lthashNFA + $10 +hashgtNFA byte $82,"#>" +hashgtPFA word (@a_drop - @a_base)/4 + word @numpadsizePFA + $10 + word @gtoutPFA + $10 + word @WatPFA + $10 + word @minusPFA + $10 + word @minusonePFA + $10 + word @gtoutPFA + $10 + word @WplusbangPFA + $10 + word @padgtoutPFA + $10 + word @CbangPFA + $10 + word @padgtoutPFA + $10 + word (@a_exit - @a_base)/4 + + word @hashgtNFA + $10 +tocharNFA byte $86,"tochar" +tocharPFA word (@a_litw - @a_base)/4 + word $001F + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0039 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $0007 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @tocharNFA + $10 +hashNFA byte $81,"#" +hashPFA word @basePFA + $10 + word @WatPFA + $10 + word @uslashmodPFA + $10 + word (@a_swap - @a_base)/4 + word @tocharPFA + $10 + word @minusonePFA + $10 + word @gtoutPFA + $10 + word @WplusbangPFA + $10 + word @padgtoutPFA + $10 + word @CbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @hashNFA + $10 +hashsNFA byte $82,"#s" +hashsPFA word @hashPFA + $10 + word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF8 + word (@a_exit - @a_base)/4 + + word @hashsNFA + $10 +dotbvalueNFA byte $87,".bvalue" +dotbvaluePFA word @lthashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashgtPFA + $10 + word @dotcstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotbvalueNFA + $10 +dotaddrNFA byte $85,".addr" +dotaddrPFA word @lthashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashgtPFA + $10 + word @dotcstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotaddrNFA + $10 +dotvalueNFA byte $86,".value" +dotvaluePFA word @lthashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashPFA + $10 + word @hashgtPFA + $10 + word @dotcstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotvalueNFA + $10 +dotNFA byte $81,"." +dotPFA word (@a_dup - @a_base)/4 + word @zltPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $002D + word @emitPFA + $10 + word @negatePFA + $10 + word @lthashPFA + $10 + word @hashsPFA + $10 + word @hashgtPFA + $10 + word @dotcstrPFA + $10 + word (@a_litw - @a_base)/4 + word $0020 + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotNFA + $10 +cogidNFA byte $85,"cogid" +cogidPFA word @minusonePFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word (@a_hubop - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cogidNFA + $10 +locksetNFA byte $87,"lockset" +locksetPFA word (@a_litw - @a_base)/4 + word $0006 + word (@a_hubop - @a_base)/4 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @locksetNFA + $10 +lockclrNFA byte $87,"lockclr" +lockclrPFA word (@a_litw - @a_base)/4 + word $0007 + word (@a_hubop - @a_base)/4 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @lockclrNFA + $10 +lockdictqNFA byte $89,"lockdict?" +lockdictqPFA word @mydictlockPFA + $10 + word @CatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @oneplusPFA + $10 + word (@a_litw - @a_base)/4 + word $00FF + word @minPFA + $10 + word @mydictlockPFA + $10 + word @CbangPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0018 + word @locksetPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $0001 + word @mydictlockPFA + $10 + word @CbangPFA + $10 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @lockdictqNFA + $10 +freedictNFA byte $88,"freedict" +freedictPFA word @mydictlockPFA + $10 + word @CatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $001A + word @oneminusPFA + $10 + word (@a_dup - @a_base)/4 + word @mydictlockPFA + $10 + word @CbangPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word @lockclrPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @freedictNFA + $10 +lockdictNFA byte $88,"lockdict" +lockdictPFA word @lockdictqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFC + word (@a_exit - @a_base)/4 + + word @lockdictNFA + $10 +checkdictNFA byte $89,"checkdict" +checkdictPFA word @herePFA + $10 + word @WatPFA + $10 + word @plusPFA + $10 + word @dictendPFA + $10 + word @WatPFA + $10 + word @gteqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $8002 + word @ERRPFA + $10 + word (@a_exit - @a_base)/4 + + word @checkdictNFA + $10 +lparencreatebeginrparenNFA byte $8D,"(createbegin)" +lparencreatebeginrparenPFA word @lockdictPFA + $10 + word @wlastnfaPFA + $10 + word @WatPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word @twoplusPFA + $10 + word @wlastnfaPFA + $10 + word @WbangPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word @WbangPFA + $10 + word @twoplusPFA + $10 + word (@a_exit - @a_base)/4 + + word @lparencreatebeginrparenNFA + $10 +lparencreateendrparenNFA byte $8B,"(createend)" +lparencreateendrparenPFA word (@a_over - @a_base)/4 + word @namecopyPFA + $10 + word @namelenPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word @herePFA + $10 + word @WbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @lparencreateendrparenNFA + $10 +ccreateNFA byte $87,"ccreate" +ccreatePFA word @lparencreatebeginrparenPFA + $10 + word (@a_swap - @a_base)/4 + word @lparencreateendrparenPFA + $10 + word (@a_exit - @a_base)/4 + + word @ccreateNFA + $10 +createNFA byte $86,"create" +createPFA word @blPFA + $10 + word @parsewordPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @lparencreatebeginrparenPFA + $10 + word @padgtinPFA + $10 + word @lparencreateendrparenPFA + $10 + word @nextwordPFA + $10 + word (@a_exit - @a_base)/4 + + word @createNFA + $10 +clabelNFA byte $86,"clabel" +clabelPFA word @lockdictPFA + $10 + word @ccreatePFA + $10 + word @dlrC_a_doconwPFA + $10 + word @wcommaPFA + $10 + word @cogherePFA + $10 + word @WatPFA + $10 + word @wcommaPFA + $10 + word @forthentryPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @clabelNFA + $10 +herewalNFA byte $87,"herewal" +herewalPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @checkdictPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @alignwPFA + $10 + word @herePFA + $10 + word @WbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @herewalNFA + $10 +allotNFA byte $85,"allot" +allotPFA word @lockdictPFA + $10 + word (@a_dup - @a_base)/4 + word @checkdictPFA + $10 + word @herePFA + $10 + word @WplusbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @allotNFA + $10 +wcommaNFA byte $82,"w," +wcommaPFA word @lockdictPFA + $10 + word @herewalPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @WbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @allotPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @wcommaNFA + $10 +ccommaNFA byte $82,"c," +ccommaPFA word @lockdictPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @CbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @allotPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @ccommaNFA + $10 +herelalNFA byte $87,"herelal" +herelalPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @checkdictPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @alignlPFA + $10 + word @herePFA + $10 + word @WbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @herelalNFA + $10 +lcommaNFA byte $82,"l," +lcommaPFA word @lockdictPFA + $10 + word @herelalPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @LbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @allotPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @lcommaNFA + $10 +orlnfaNFA byte $86,"orlnfa" +orlnfaPFA word @lockdictPFA + $10 + word @lastnfaPFA + $10 + word @orCbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @orlnfaNFA + $10 +forthentryNFA byte $8A,"forthentry" +forthentryPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @orlnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @forthentryNFA + $10 +immediateNFA byte $89,"immediate" +immediatePFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0040 + word @orlnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @immediateNFA + $10 +execNFA byte $84,"exec" +execPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0060 + word @orlnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @execNFA + $10 +leaveNFA byte $85,"leave" +leavePFA word (@a_rgt - @a_base)/4 + word (@a_rgt - @a_base)/4 + word (@a_rgt - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_twogtr - @a_base)/4 + word (@a_gtr - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @leaveNFA + $10 +clearkeysNFA byte $89,"clearkeys" +clearkeysPFA word (@a_litw - @a_base)/4 + word $0001 + word @statePFA + $10 + word @andnCbangPFA + $10 + word @minusonePFA + $10 + word @_wkeytoPFA + $10 + word @WatPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @keyqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @keyPFA + $10 + word @twodropPFA + $10 + word @zPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF0 + word (@a_zbranch - @a_base)/4 + word $FFE2 + word (@a_exit - @a_base)/4 + + word @clearkeysNFA + $10 +wgtlNFA byte $83,"w>l" +wgtlPFA word (@a_litw - @a_base)/4 + word $FFFF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @wgtlNFA + $10 +lgtwNFA byte $83,"l>w" +lgtwPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @rshiftPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @lgtwNFA + $10 +colonNFA byte $81,":" +colonPFA word @lockdictPFA + $10 + word @createPFA + $10 + word (@a_litw - @a_base)/4 + word $3741 + word (@a_litw - @a_base)/4 + word $0001 + word @statePFA + $10 + word @orCbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @colonNFA + $10 +_mmcsNFA byte $85,"_mmcs" +_mmcsPFA word @dqPFA + $10 + byte $1F,"MISMATCHED CONTROL STRUCTURE(S)" + word @crPFA + $10 + word @clearkeysPFA + $10 + word (@a_exit - @a_base)/4 + + word @_mmcsNFA + $10 +_scolonNFA byte $82,"_;" +_scolonPFA word @wcommaPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @statePFA + $10 + word @andnCbangPFA + $10 + word @forthentryPFA + $10 + word (@a_litw - @a_base)/4 + word $3741 + word @ltgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @_scolonNFA + $10 +scolonscolonNFA byte $C2,";;" +scolonscolonPFA word @dlrC_a_exitPFA + $10 + word @_scolonPFA + $10 + word (@a_exit - @a_base)/4 + + word @scolonscolonNFA + $10 +scolonNFA byte $C1,";" +scolonPFA word @dlrC_a_exitPFA + $10 + word @_scolonPFA + $10 + word (@a_exit - @a_base)/4 + + word @scolonNFA + $10 +dothenNFA byte $86,"dothen" +dothenPFA word @lgtwPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1235 + word (@a_eq - @a_base)/4 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1239 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0014 + word (@a_dup - @a_base)/4 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_swap - @a_base)/4 + word @minusPFA + $10 + word (@a_swap - @a_base)/4 + word @WbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word (@a_exit - @a_base)/4 + + word @dothenNFA + $10 +thenNFA byte $C4,"then" +thenPFA word @dothenPFA + $10 + word (@a_exit - @a_base)/4 + + word @thenNFA + $10 +thensNFA byte $C5,"thens" +thensPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word @andPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1235 + word (@a_eq - @a_base)/4 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1239 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @dothenPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFD6 + word (@a_exit - @a_base)/4 + + word @thensNFA + $10 +ifNFA byte $C2,"if" +ifPFA word @dlrC_a_zbranchPFA + $10 + word @wcommaPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $1235 + word @wgtlPFA + $10 + word @zPFA + $10 + word @wcommaPFA + $10 + word (@a_exit - @a_base)/4 + + word @ifNFA + $10 +elseNFA byte $C4,"else" +elsePFA word @dlrC_a_branchPFA + $10 + word @wcommaPFA + $10 + word @zPFA + $10 + word @wcommaPFA + $10 + word @dothenPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @twominusPFA + $10 + word (@a_litw - @a_base)/4 + word $1239 + word @wgtlPFA + $10 + word (@a_exit - @a_base)/4 + + word @elseNFA + $10 +untilNFA byte $C5,"until" +untilPFA word @lgtwPFA + $10 + word (@a_litw - @a_base)/4 + word $1317 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word @dlrC_a_zbranchPFA + $10 + word @wcommaPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @minusPFA + $10 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word (@a_exit - @a_base)/4 + + word @untilNFA + $10 +beginNFA byte $C5,"begin" +beginPFA word @herePFA + $10 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $1317 + word @wgtlPFA + $10 + word (@a_exit - @a_base)/4 + + word @beginNFA + $10 +doloopNFA byte $86,"doloop" +doloopPFA word (@a_swap - @a_base)/4 + word @lgtwPFA + $10 + word (@a_litw - @a_base)/4 + word $2329 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word (@a_swap - @a_base)/4 + word @wcommaPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word @minusPFA + $10 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word (@a_exit - @a_base)/4 + + word @doloopNFA + $10 +loopNFA byte $C4,"loop" +loopPFA word @dlrC_a_lparenlooprparenPFA + $10 + word @doloopPFA + $10 + word (@a_exit - @a_base)/4 + + word @loopNFA + $10 +plusloopNFA byte $C5,"+loop" +plusloopPFA word @dlrC_a_lparenpluslooprparenPFA + $10 + word @doloopPFA + $10 + word (@a_exit - @a_base)/4 + + word @plusloopNFA + $10 +doNFA byte $C2,"do" +doPFA word @dlrC_a_twogtrPFA + $10 + word @wcommaPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $2329 + word @wgtlPFA + $10 + word (@a_exit - @a_base)/4 + + word @doNFA + $10 +_ecsNFA byte $84,"_ecs" +_ecsPFA word (@a_litw - @a_base)/4 + word $003A + word @emitPFA + $10 + word @spacePFA + $10 + word (@a_exit - @a_base)/4 + + word @_ecsNFA + $10 +_udfNFA byte $84,"_udf" +_udfPFA word @dqPFA + $10 + byte $0F,"UNDEFINED WORD " + word (@a_exit - @a_base)/4 + + word @_udfNFA + $10 +_spNFA byte $83,"_sp" +_spPFA word @wcommaPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @gtinPFA + $10 + word @WplusbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0022 + word @parsePFA + $10 + word (@a_dup - @a_base)/4 + word @ccommaPFA + $10 + word (@a_dup - @a_base)/4 + word @padgtinPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_rot - @a_base)/4 + word @cmovePFA + $10 + word (@a_dup - @a_base)/4 + word @allotPFA + $10 + word @oneplusPFA + $10 + word @gtinPFA + $10 + word @WplusbangPFA + $10 + word @herewalPFA + $10 + word (@a_exit - @a_base)/4 + + word @_spNFA + $10 +dotquoteNFA byte $C2,".",$22 +dotquotePFA word @dlrH_dqPFA + $10 + word @_spPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotquoteNFA + $10 +fisnumberNFA byte $89,"fisnumber" +fisnumberPFA word @isnumberPFA + $10 + word (@a_exit - @a_base)/4 + + word @fisnumberNFA + $10 +fnumberNFA byte $87,"fnumber" +fnumberPFA word @numberPFA + $10 + word (@a_exit - @a_base)/4 + + word @fnumberNFA + $10 +interpretpadNFA byte $8C,"interpretpad" +interpretpadPFA word @zPFA + $10 + word @gtinPFA + $10 + word @WbangPFA + $10 + word @blPFA + $10 + word @parsewordPFA + $10 + word (@a_zbranch - @a_base)/4 + word $00C0 + word @padgtinPFA + $10 + word @nextwordPFA + $10 + word @findPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0062 + word (@a_dup - @a_base)/4 + word @minusonePFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0018 + word (@a_drop - @a_base)/4 + word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @executePFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $003E + word (@a_litw - @a_base)/4 + word $0002 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000A + word @executePFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $002C + word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @executePFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $001E + word @pfagtnfaPFA + $10 + word @dqPFA + $10 + byte $0F,"IMMEDIATE WORD " + word @dotstrnamePFA + $10 + word @clearkeysPFA + $10 + word @crPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0050 + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word @CatplusplusPFA + $10 + word @fisnumberPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0030 + word @CatplusplusPFA + $10 + word @fnumberPFA + $10 + word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0020 + word (@a_dup - @a_base)/4 + word @zPFA + $10 + word (@a_litw - @a_base)/4 + word $FFFF + word @betweenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @dlrC_a_litwPFA + $10 + word @wcommaPFA + $10 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @dlrC_a_litlPFA + $10 + word @wcommaPFA + $10 + word @lcommaPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0016 + word (@a_litw - @a_base)/4 + word $0001 + word @statePFA + $10 + word @andnCbangPFA + $10 + word @freedictPFA + $10 + word @_udfPFA + $10 + word @dotstrnamePFA + $10 + word @crPFA + $10 + word @clearkeysPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FF36 + word (@a_exit - @a_base)/4 + + word @interpretpadNFA + $10 +interpretNFA byte $89,"interpret" +interpretPFA word @padPFA + $10 + word @padsizePFA + $10 + word @acceptPFA + $10 + word (@a_drop - @a_base)/4 + word @interpretpadPFA + $10 + word (@a_exit - @a_base)/4 + + word @interpretNFA + $10 +_wconeNFA byte $84,"_wc1" +_wconePFA word @lockdictPFA + $10 + word @createPFA + $10 + word @dlrC_a_doconwPFA + $10 + word @wcommaPFA + $10 + word @wcommaPFA + $10 + word @forthentryPFA + $10 + word @lastnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @_wconeNFA + $10 +wconstantNFA byte $89,"wconstant" +wconstantPFA word @_wconePFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @wconstantNFA + $10 +wvariableNFA byte $89,"wvariable" +wvariablePFA word @lockdictPFA + $10 + word @createPFA + $10 + word @dlrC_a_dovarwPFA + $10 + word @wcommaPFA + $10 + word @zPFA + $10 + word @wcommaPFA + $10 + word @forthentryPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @wvariableNFA + $10 +asmlabelNFA byte $88,"asmlabel" +asmlabelPFA word @lockdictPFA + $10 + word @createPFA + $10 + word @wcommaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @asmlabelNFA + $10 +hexNFA byte $83,"hex" +hexPFA word (@a_litw - @a_base)/4 + word $0010 + word @basePFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @hexNFA + $10 +decimalNFA byte $87,"decimal" +decimalPFA word (@a_litw - @a_base)/4 + word $000A + word @basePFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @decimalNFA + $10 +delmsNFA byte $85,"delms" +delmsPFA word (@a_litl - @a_base)/4 + long $7FFFFFFF + word @clkfreqPFA + $10 + word (@a_litw - @a_base)/4 + word $03E8 + word @uslashPFA + $10 + word @uslashPFA + $10 + word @minPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @maxPFA + $10 + word @clkfreqPFA + $10 + word (@a_litw - @a_base)/4 + word $03E8 + word @uslashPFA + $10 + word @ustarPFA + $10 + word @cntPFA + $10 + word (@a_COGat - @a_base)/4 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @cntPFA + $10 + word (@a_COGat - @a_base)/4 + word @minusPFA + $10 + word @zltPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @delmsNFA + $10 +delsecNFA byte $86,"delsec" +delsecPFA word (@a_litw - @a_base)/4 + word $0010 + word @uslashmodPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $3E80 + word @delmsPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $03E8 + word @delmsPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @delsecNFA + $10 +gtmNFA byte $82,">m" +gtmPFA word (@a_litw - @a_base)/4 + word $0001 + word (@a_swap - @a_base)/4 + word @lshiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @gtmNFA + $10 +pininNFA byte $85,"pinin" +pininPFA word @gtmPFA + $10 + word @invertPFA + $10 + word @diraPFA + $10 + word (@a_COGat - @a_base)/4 + word @andPFA + $10 + word @diraPFA + $10 + word (@a_COGbang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pininNFA + $10 +pinoutNFA byte $86,"pinout" +pinoutPFA word @gtmPFA + $10 + word @diraPFA + $10 + word (@a_COGat - @a_base)/4 + word @orPFA + $10 + word @diraPFA + $10 + word (@a_COGbang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pinoutNFA + $10 +pinloNFA byte $85,"pinlo" +pinloPFA word @gtmPFA + $10 + word (@a__maskoutlo - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pinloNFA + $10 +pinhiNFA byte $85,"pinhi" +pinhiPFA word @gtmPFA + $10 + word (@a__maskouthi - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pinhiNFA + $10 +pxNFA byte $82,"px" +pxPFA word (@a_swap - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @pinhiPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @pinloPFA + $10 + word (@a_exit - @a_base)/4 + + word @pxNFA + $10 +_sdaiNFA byte $85,"_sdai" +_sdaiPFA word (@a_litw - @a_base)/4 + word $001D + word @pininPFA + $10 + word (@a_exit - @a_base)/4 + + word @_sdaiNFA + $10 +_sdaoNFA byte $85,"_sdao" +_sdaoPFA word (@a_litw - @a_base)/4 + word $001D + word @pinoutPFA + $10 + word (@a_exit - @a_base)/4 + + word @_sdaoNFA + $10 +_scliNFA byte $85,"_scli" +_scliPFA word (@a_litw - @a_base)/4 + word $001C + word @pininPFA + $10 + word (@a_exit - @a_base)/4 + + word @_scliNFA + $10 +_scloNFA byte $85,"_sclo" +_scloPFA word (@a_litw - @a_base)/4 + word $001C + word @pinoutPFA + $10 + word (@a_exit - @a_base)/4 + + word @_scloNFA + $10 +_sdalNFA byte $85,"_sdal" +_sdalPFA word (@a_litl - @a_base)/4 + long $20000000 + word (@a__maskoutlo - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sdalNFA + $10 +_sdahNFA byte $85,"_sdah" +_sdahPFA word (@a_litl - @a_base)/4 + long $20000000 + word (@a__maskouthi - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sdahNFA + $10 +_scllNFA byte $85,"_scll" +_scllPFA word (@a_litl - @a_base)/4 + long $10000000 + word (@a__maskoutlo - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_scllNFA + $10 +_sclhNFA byte $85,"_sclh" +_sclhPFA word (@a_litl - @a_base)/4 + long $10000000 + word (@a__maskouthi - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sclhNFA + $10 +_sdaqNFA byte $85,"_sda?" +_sdaqPFA word (@a_litl - @a_base)/4 + long $20000000 + word (@a__maskin - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sdaqNFA + $10 +_eestartNFA byte $88,"_eestart" +_eestartPFA word @_sclhPFA + $10 + word @_scloPFA + $10 + word @_sdahPFA + $10 + word @_sdaoPFA + $10 + word @_sdalPFA + $10 + word @_scllPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eestartNFA + $10 +_eestopNFA byte $87,"_eestop" +_eestopPFA word @_sclhPFA + $10 + word @_sdahPFA + $10 + word @_scllPFA + $10 + word @_scliPFA + $10 + word @_sdaiPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eestopNFA + $10 +_eewriteNFA byte $88,"_eewrite" +_eewritePFA word (@a_litw - @a_base)/4 + word $0080 + word (@a_litw - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @twodupPFA + $10 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @_sdahPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_sdalPFA + $10 + word @_sclhPFA + $10 + word @_scllPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @rshiftPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFE4 + word @twodropPFA + $10 + word @_sdaiPFA + $10 + word @_sclhPFA + $10 + word @_sdaqPFA + $10 + word @_scllPFA + $10 + word @_sdalPFA + $10 + word @_sdaoPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eewriteNFA + $10 +eewritepageNFA byte $8B,"eewritepage" +eewritepagePFA word (@a_litw - @a_base)/4 + word $0001 + word @locksetPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF6 + word (@a_litw - @a_base)/4 + word $0001 + word @maxPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @lshiftPFA + $10 + word @_eestartPFA + $10 + word (@a_litw - @a_base)/4 + word $00A0 + word @orPFA + $10 + word @_eewritePFA + $10 + word (@a_swap - @a_base)/4 + word @_eewritePFA + $10 + word @orPFA + $10 + word (@a_swap - @a_base)/4 + word @_eewritePFA + $10 + word @orPFA + $10 + word @rottwoPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @CatPFA + $10 + word @_eewritePFA + $10 + word @orPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word @_eestopPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @delmsPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @lockclrPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @eewritepageNFA + $10 +EWbangNFA byte $83,"EW!" +EWbangPFA word (@a_swap - @a_base)/4 + word @tzPFA + $10 + word @WbangPFA + $10 + word @tzPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @eewritepagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $8003 + word @ERRPFA + $10 + word (@a_exit - @a_base)/4 + + word @EWbangNFA + $10 +bsNFA byte $E1,"\" +bsPFA word @padsizePFA + $10 + word @gtinPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @bsNFA + $10 +cboNFA byte $81,"{" +cboPFA word @fkeyqPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word (@a_exit - @a_base)/4 + + word @cboNFA + $10 +cbcNFA byte $81,"}" +cbcPFA word (@a_exit - @a_base)/4 + + word @cbcNFA + $10 +sboifNFA byte $83,"[if" +sboifPFA word @parsenwPFA + $10 + word @nipPFA + $10 + word @findPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0010 + word @fkeyqPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $005D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word (@a_exit - @a_base)/4 + + word @sboifNFA + $10 +sbcNFA byte $81,"]" +sbcPFA word (@a_exit - @a_base)/4 + + word @sbcNFA + $10 +tickNFA byte $81,"'" +tickPFA word @parseblPFA + $10 + word (@a_zbranch - @a_base)/4 + word $001A + word @padgtinPFA + $10 + word @nextwordPFA + $10 + word @findPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @_udfPFA + $10 + word @crPFA + $10 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @tickNFA + $10 +cqNFA byte $82,"cq" +cqPFA word (@a_rgt - @a_base)/4 + word (@a_dup - @a_base)/4 + word @CatplusplusPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word (@a_gtr - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cqNFA + $10 +cquoteNFA byte $E2,"c",$22 +cquotePFA word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @dlrH_cqPFA + $10 + word @_spPFA + $10 + word (@a_branch - @a_base)/4 + word $0018 + word (@a_litw - @a_base)/4 + word $0022 + word @parsePFA + $10 + word @oneminusPFA + $10 + word @padgtinPFA + $10 + word @twodupPFA + $10 + word @CbangPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @gtinPFA + $10 + word @WplusbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @cquoteNFA + $10 +fl_lockNFA byte $87,"fl_lock" +fl_lockPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @fl_lockNFA + $10 +fl_inNFA byte $85,"fl_in" +fl_inPFA word (@a_dovarw - @a_base)/4 + word $69D6 + + word @fl_inNFA + $10 +lparenfloutrparenNFA byte $87,"(flout)" +lparenfloutrparenPFA word @ioPFA + $10 + word @twoplusPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word @dictendPFA + $10 + word @WatPFA + $10 + word @fl_inPFA + $10 + word @WatPFA + $10 + word (@a_lt - @a_base)/4 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0018 + word @dictendPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word @oneplusPFA + $10 + word @dictendPFA + $10 + word @WbangPFA + $10 + word @CatPFA + $10 + word (@a_swap - @a_base)/4 + word @WbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @lparenfloutrparenNFA + $10 +lparenflrparenNFA byte $84,"(fl)" +lparenflrparenPFA word @dictendPFA + $10 + word @WatPFA + $10 + word @twominusPFA + $10 + word @tzPFA + $10 + word @WbangPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @fl_inPFA + $10 + word @WbangPFA + $10 + word @dictendPFA + $10 + word @WbangPFA + $10 + word @_wkeytoPFA + $10 + word @WatPFA + $10 + word @minusonePFA + $10 + word @fkeyqPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_drop - @a_base)/4 + word @lparenfloutrparenPFA + $10 + word (@a_branch - @a_base)/4 + word $00CA + word @fl_inPFA + $10 + word @WatPFA + $10 + word @tzPFA + $10 + word @WatPFA + $10 + word @gteqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $8004 + word @ERRPFA + $10 + word (@a_branch - @a_base)/4 + word $009E + word (@a_swap - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $007E + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $005C + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0018 + word (@a_drop - @a_base)/4 + word @fkeyqPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0058 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007B + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0032 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word @oneplusPFA + $10 + word (@a_litw - @a_base)/4 + word $001F + word (@a_over - @a_base)/4 + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $001F + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0004 + word @lparenfloutrparenPFA + $10 + word @fkeyqPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FFDE + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $001C + word (@a_dup - @a_base)/4 + word @fl_inPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0001 + word @plusPFA + $10 + word @fl_inPFA + $10 + word @WbangPFA + $10 + word @CbangPFA + $10 + word (@a_litw - @a_base)/4 + word $000D + word (@a_eq - @a_base)/4 + word (@a_branch - @a_base)/4 + word $001C + word (@a_dup - @a_base)/4 + word @fl_inPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0001 + word @plusPFA + $10 + word @fl_inPFA + $10 + word @WbangPFA + $10 + word @CbangPFA + $10 + word (@a_litw - @a_base)/4 + word $000D + word (@a_eq - @a_base)/4 + word @lparenfloutrparenPFA + $10 + word @fkeyqPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FF44 + word (@a_drop - @a_base)/4 + word @nipPFA + $10 + word @_wkeytoPFA + $10 + word @WatPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_swap - @a_base)/4 + word @oneminusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FF1C + word @twodropPFA + $10 + word @dictendPFA + $10 + word @WatPFA + $10 + word @fl_inPFA + $10 + word @WatPFA + $10 + word (@a_lt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $001C + word @fl_inPFA + $10 + word @WatPFA + $10 + word @dictendPFA + $10 + word @WatPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word @emitPFA + $10 + word @dictendPFA + $10 + word @WbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF2 + word (@a_litw - @a_base)/4 + word $000D + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $000D + word @emitPFA + $10 + word @tzPFA + $10 + word @WatPFA + $10 + word @twoplusPFA + $10 + word @dictendPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @lparenflrparenNFA + $10 +flNFA byte $82,"fl" +flPFA word @lockdictPFA + $10 + word @fl_lockPFA + $10 + word @WatPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @freedictPFA + $10 + word (@a_branch - @a_base)/4 + word $001C + word @minusonePFA + $10 + word @fl_lockPFA + $10 + word @WbangPFA + $10 + word @cogidPFA + $10 + word @nfcogPFA + $10 + word @iolinkPFA + $10 + word @freedictPFA + $10 + word @lparenflrparenPFA + $10 + word @cogidPFA + $10 + word @iounlinkPFA + $10 + word @zPFA + $10 + word @fl_lockPFA + $10 + word @WbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @flNFA + $10 +saveforthNFA byte $89,"saveforth" +saveforthPFA word @cqPFA + $10 + byte $04,"here" + word @findPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0066 + word @versionPFA + $10 + word @WatPFA + $10 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @CatPFA + $10 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @CbangPFA + $10 + word @pfagtnfaPFA + $10 + word @herePFA + $10 + word @WatPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_dup - @a_base)/4 + word @WatPFA + $10 + word (@a_over - @a_base)/4 + word @EWbangPFA + $10 + word @twoplusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $003F + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFEA + word (@a_twogtr - @a_base)/4 + word @iboundPFA + $10 + word @iPFA + $10 + word @minusPFA + $10 + word (@a_litw - @a_base)/4 + word $0040 + word @minPFA + $10 + word (@a_dup - @a_base)/4 + word @iPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_rot - @a_base)/4 + word @eewritepagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $8003 + word @ERRPFA + $10 + word (@a_litw - @a_base)/4 + word $002E + word @emitPFA + $10 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFD8 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @saveforthNFA + $10 +fstartNFA byte $86,"fstart" +fstartPFA word @ioPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @dlrH_entryPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @lshiftPFA + $10 + word @orPFA + $10 + word @cogidPFA + $10 + word @orPFA + $10 + word @_resetdregPFA + $10 + word (@a_COGbang - @a_base)/4 + word @ioPFA + $10 + word @WatPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @ioPFA + $10 + word @WbangPFA + $10 + word @_fmaskPFA + $10 + word (@a_COGat - @a_base)/4 + word @debugcmdPFA + $10 + word @WbangPFA + $10 + word @parPFA + $10 + word (@a_COGat - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @plusPFA + $10 + word @_cdszPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @minusPFA + $10 + word @zPFA + $10 + word @fillPFA + $10 + word @hexPFA + $10 + word @dlrC_varendPFA + $10 + word @cogherePFA + $10 + word @WbangPFA + $10 + word @lockdictPFA + $10 + word @_finitPFA + $10 + word @WatPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0024 + word @zPFA + $10 + word @fl_lockPFA + $10 + word @WbangPFA + $10 + word @minusonePFA + $10 + word @_finitPFA + $10 + word @WbangPFA + $10 + word @freedictPFA + $10 + word @cqPFA + $10 + byte $06,"onboot" + word @findPFA + $10 + word (@a_drop - @a_base)/4 + word @executePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @freedictPFA + $10 + word @_rstopPFA + $10 + word @oneminusPFA + $10 + word @_rsptrPFA + $10 + word (@a_COGbang - @a_base)/4 + word @cqPFA + $10 + byte $07,"onreset" + word @tbufPFA + $10 + word @ccopyPFA + $10 + word @cogidPFA + $10 + word @tbufPFA + $10 + word @cappendnPFA + $10 + word @tbufPFA + $10 + word @findPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @executePFA + $10 + word (@a_branch - @a_base)/4 + word $0014 + word (@a_drop - @a_base)/4 + word @cqPFA + $10 + byte $07,"onreset" + word @findPFA + $10 + word (@a_drop - @a_base)/4 + word @executePFA + $10 + word @compileqPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0020 + word @propPFA + $10 + word @WatPFA + $10 + word @dotcstrPFA + $10 + word @propidPFA + $10 + word @WatPFA + $10 + word @dotPFA + $10 + word @dqPFA + $10 + byte $03,"Cog" + word @cogidPFA + $10 + word @dotPFA + $10 + word @dqPFA + $10 + byte $02,"ok" + word @crPFA + $10 + word @interpretPFA + $10 + word @zPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFD4 + word (@a_exit - @a_base)/4 + + word @fstartNFA + $10 +lparencogplusrparenNFA byte $86,"(cog+)" +lparencogplusrparenPFA word (@a_litw - @a_base)/4 + word $0008 + +' word @zPFA + $10 'hive: erste cog frei lassen + word (@a_litw - @a_base)/4 + word $0001 + + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @cogstatePFA + $10 + word @CatPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @iPFA + $10 + word @cogresetPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEC + word (@a_exit - @a_base)/4 + + word @lparencogplusrparenNFA + $10 +startserialcogNFA byte $8E,"startserialcog" +startserialcogPFA word (@a_dup - @a_base)/4 + word (@a_gtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @cogstopPFA + $10 + word @cogioPFA + $10 + word (@a_swap - @a_base)/4 + word @clkfreqPFA + $10 + word (@a_swap - @a_base)/4 + word @uslashPFA + $10 + word (@a_over - @a_base)/4 + word @LbangPFA + $10 + word @fourplusPFA + $10 + word (@a_swap - @a_base)/4 + word @gtmPFA + $10 + word (@a_over - @a_base)/4 + word @LbangPFA + $10 + word @fourplusPFA + $10 + word (@a_swap - @a_base)/4 + word @gtmPFA + $10 + word (@a_swap - @a_base)/4 + word @LbangPFA + $10 + word (@a_rgt - @a_base)/4 + word (@a_dup - @a_base)/4 + word @cogstatePFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word (@a_swap - @a_base)/4 + word @CbangPFA + $10 + word @cqPFA + $10 + byte $07,"drv:ext" + word (@a_over - @a_base)/4 + word @cognumpadPFA + $10 + word @ccopyPFA + $10 + word (@a_dup - @a_base)/4 + word @cogioPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @dlrH_serentryPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @lshiftPFA + $10 + word @orPFA + $10 + word @orPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word (@a_hubop - @a_base)/4 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @startserialcogNFA + $10 +onbootNFA byte $86,"onboot" +onbootPFA word @lparenversionrparenPFA + $10 + word @versionPFA + $10 + word @WbangPFA + $10 + word @lparenproprparenPFA + $10 + word @propPFA + $10 + word @WbangPFA + $10 + word (@a_litw - @a_base)/4 + word $001E + word (@a_litw - @a_base)/4 + word $001F + word (@a_litw - @a_base)/4 + word $E100 'hive: baudrate + word (@a_litw - @a_base)/4 + word $0007 + word @startserialcogPFA + $10 + word @cogidPFA + $10 + word @gtconPFA + $10 + word @lparencogplusrparenPFA + $10 + word @lparencogplusrparenPFA + $10 + word @lparencogplusrparenPFA + $10 + word @lparencogplusrparenPFA + $10 + word @lparencogplusrparenPFA + $10 +' word @lparencogplusrparenPFA + $10 'hive: eine cog weniger belegen + word (@a_exit - @a_base)/4 + + word @onbootNFA + $10 +onresetNFA byte $87,"onreset" +onresetPFA word (@a_litw - @a_base)/4 + word $0004 + word @statePFA + $10 + word @orCbangPFA + $10 + word @crPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $8000 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @dotaddrPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @dqPFA + $10 + byte $07," RESET " + word (@a_exit - @a_base)/4 + + word @onresetNFA + $10 'hive: konstante mit +ldvarNFA byte $85,"ldvar" 'adresse der loadervariablen +ldvarPFA word (@a_doconw - @a_base)/4 'wert wird in main gesetzt +ldvarVAL word 0 + + word @ldvarNFA + $10 +wlastnfaNFA byte $88,"wlastnfa" +wlastnfaPFA word (@a_dovarw - @a_base) /4 + word @wlastnfaNFA + $10 +wfreespacestart + + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +{ + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +} +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org 0 + +serentryPFA + mov t1 , par + mov v_rxbuff , par + add v_rxbuff , # 4 'adresse pufferanfang hinter v_in/out + rdlong v_bitticks , t1 '1. long baudrate + add t1 , # 4 + rdlong v_rxmask , t1 '2. long rx-pin + add t1 , # 4 + rdlong v_txmask , t1 '3. long tx-pin + mov v_in , par '1. wort ab jetzt input + mov v_out , v_in + add v_out , #2 '2. wort ab jetzt output + + mov t1 , # $100 + wrlong t1 , par + + mov task1Ptr,#transmit + mov task2Ptr,#task2Code + or dira , v_txmask +' +' Receive +' +receive jmpret task0Ptr, task1Ptr + + test v_rxmask , ina wz + if_nz jmp # receive + + mov rxbits , # 9 +' mov 1/4 of the way into the bit slot + mov rxcnt , v_bitticks + shr rxcnt , # 2 + add rxcnt , cnt + +:bit add rxcnt , v_bitticks +:wait jmpret task0Ptr, task1Ptr + + mov t1 , rxcnt 'soft-waitcnt: + sub t1 , cnt 'wartet eine zeit unter + cmps t1 , # 0 wc 'einbeziehung anderer tasks + if_nc jmp #:wait + + test v_rxmask , ina wc + rcr rxdata , # 1 'schieb c-flag in emfangsbyte + djnz rxbits , # :bit + + if_nc jmp # receive + + shr rxdata , # 32-9 'bits im long ausrichten + and rxdata , # $FF 'und maskieren + + add v_rxh , v_rxbuff 'pufferadresse bestimmen + wrbyte rxdata , v_rxh 'zeichen in puffer schreiben + sub v_rxh , v_rxbuff ' + add v_rxh ,# 1 'pufferstand erhöhen + and v_rxh , # _buffer_mask + + jmp # receive +' +' +' Transmit +' +transmit jmpret task1Ptr, task2Ptr + rdword txdata, v_in + test txdata, #$100 wz + if_nz jmp #transmit + mov t1 , #$100 + wrword t1 , v_in + + or txdata,#$100 + shl txdata,#2 + or txdata,#1 + mov txbits,#11 + mov txcnt,cnt + +:bit shr txdata,#1 wc + muxc outa , v_txmask + add txcnt , v_bitticks + +:wait jmpret task1Ptr, task2Ptr + mov t1,txcnt + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit + + jmp #transmit + +task2Code + jmpret task2Ptr, task0Ptr + cmp v_rxh , v_rxt wz 'zeichen empfangen? + if_z jmp #task2Code + mov t1 , v_out + rdword t2 , t1 wz + if_nz rdword t3 , t2 + if_nz test t3 , # $100 wz + if_z jmp #task2Code + + add v_rxt , v_rxbuff + rdbyte t3 , v_rxt + sub v_rxt , v_rxbuff + add v_rxt ,# 1 + wrword t3 , t2 + and v_rxt , # _buffer_mask + jmp #task2Code + +v_rxh long 0 'pufferstand empfang +v_rxt long 0 'pufferstand auslesen +' +' Uninitialized data +' +v_bitticks res 1 +v_rxmask res 1 +v_txmask res 1 +v_rxbuff res 1 +v_in res 1 +v_out res 1 + +task0Ptr res 1 +task1Ptr res 1 +task2Ptr res 1 +t1 res 1 +t2 res 1 +t3 res 1 + +rxdata res 1 +rxbits res 1 +rxcnt res 1 + + +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 + + +ForthDictEnd +ForthMemoryEnd +heapend +#endif + +DAT ' HEAP REGIME-KONF +#ifdef regime + +heap + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +heapend +#endif + +DAT +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + diff --git a/forth/adm.lib b/forth/adm.lib new file mode 100644 index 0000000..68c66d4 --- /dev/null +++ b/forth/adm.lib @@ -0,0 +1,90 @@ + +hex + +ifnot: lib:adm +: lib:adm ; + +\ kommandoformen + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ 0 [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!l@ \ ( fkt -- l ) +: adm:fkt!l@ b[ [a!] [a.l@] ]b ; + +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +\ administra-chipmanagment-funktionen + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + +\ adm:getspec ( -- spec ) - chipspezifikation abfragen +\ +\ +---------- com +\ | +-------- i2c +\ | |+------- rtc +\ | ||+------ lan +\ | |||+----- sid +\ | ||||+---- wav +\ | |||||+--- hss +\ | ||||||+-- bootfhig +\ | |||||||+- dateisystem +\ %00000000_00000000_00000000_01001111 +ifnot: adm:getspec +: adm:getspec + 5D adm:fkt!l@ ; + +\ adm:setsyssound ( syssnd -- ) - systemklnge +\ syssnd = 0 - systemklnge aus +\ syssnd = 1 - systemklnge an +ifnot: adm:setsyssound +: adm:setsyssound + 5E adm:fkt!b! ; + +\ adm:getsoundsys ( -- sndsys ) - abfrage aktives soundsystem +\ 0 - sound aus +\ 1 - hss +\ 2 - wav +ifnot: adm:getsoundsys +: adm:getsoundsys + 5F adm:fkt!b@ ; + +\ adm:load ( cstr -- ) - neuen administra-code laden +ifnot: adm:aload +: adm:aload + 60 adm:fkt!s! ; + +\ adm:getcogs ( -- cogs ) - anzahl der belegten cogs +ifnot: adm:getcogs +: adm:getcogs + 61 adm:fkt!b@ ; + +\ adm:getver ( -- ver ) - abfrage der codeversion +ifnot: adm:getver +: adm:getver + 62 adm:fkt!l@ ; + +\ adm:reset ( -- ) - reset administra +ifnot: adm:reset +: adm:reset + 63 adm:fkt! ; + diff --git a/forth/ari.lib b/forth/ari.lib new file mode 100644 index 0000000..8b1e1c4 --- /dev/null +++ b/forth/ari.lib @@ -0,0 +1,55 @@ + +hex + +ifnot: lib:ari +: lib:ari ; + +\ abs ( n1 -- abs_n1 ) absolute value of n1 +ifnot: abs +: abs _execasm1>1 151 _cnip ; + +\ u*/mod ( u1 u2 u3 -- u4 u5 ) u5 = (u1*u2)/u3, u4 is the +\ remainder. Uses a 64bit intermediate result. +ifnot: u*/mod +: u*/mod rot2 um* rot um/mod ; + +\ u*/ ( u1 u2 u3 -- u4 ) u4 = (u1*u2)/u3 Uses a 64bit +\ intermediate result. +ifnot: u*/ +: u*/ rot2 um* rot um/mod nip ; + +\ sign ( n1 n2 -- n3 ) n3 is the xor of the sign bits of +\ n1 and n2 +ifnot: sign +: sign xor 80000000 and ; + +\ */mod ( n1 n2 n3 -- n4 n5 ) n5 = (n1*n2)/n3, n4 is the +\ remainder. Uses a 64bit intermediate result. +ifnot: */mod +: */mod 2dup sign >r abs rot dup r> sign >r abs rot abs + um* rot um/mod r> if negate swap negate swap then ; + +\ */ ( n1 n2 n3 -- n4 ) n4 = (n1*n2)/n3. Uses a 64bit +\ intermediate result. +ifnot: */ +: */ */mod nip ; + +\ /mod ( n1 n2 -- n3 n4 ) \ signed divide & mod n4 = n1/n2, +\ n3 is the remainder +ifnot: /mod +: /mod 2dup sign >r abs swap abs swap u/mod r> if negate swap + negate swap then ; + +\ * ( n1 n2 -- n1*n2) n1 multiplied by n2 +ifnot: * +: * um* drop ; + +\ / ( n1 n2 -- n1/n2) n1 divided by n2 +ifnot: / +: / /mod nip ; + +\ rnd ( -- n1 ) n1 is a random number from 00 - FF +ifnot: rnd +: rnd cnt COG@ 8 rshift cnt COG@ xor FF and ; + + diff --git a/forth/basics.mod b/forth/basics.mod new file mode 100644 index 0000000..a1b636b --- /dev/null +++ b/forth/basics.mod @@ -0,0 +1,485 @@ +fl + +hex + +: mod:basics ; + +\ Copyright (c) 2010 Sal Sanci +\ Anpassung fr Hive-System 2011 dr235 + +\ ------------------------------------------------------ BASICS + +\ this words needs to align with the assembler code +: _stptr 5 _cv ; +: _sttop 2e _cv ; + +\ _words ( cstr -- ) +: _words lastnfa + begin + 2dup swap dup if npfx else 2drop -1 then + if dup .strname space then + nfa>next dup 0= + until 2drop cr ; + +\ words name ( -- ) prints the words in the forth dictionary +: words parsenw _words ; + +\ .long ( n -- ) emit 8 hex digits +: .long dup 10 rshift .word .word ; + +\ st? ( -- ) prints out the stack +: st? ." ST: " _stptr COG@ 2+ dup _sttop < + if _sttop swap - 0 + do _sttop 2- i - COG@ .long space loop + else drop + then cr ; + +\ variable ( -- ) skip blanks parse the next word and create +\ a variable, allocate a long, 4 bytes +: variable + lockdict create $C_a_dovarl w, 0 l, forthentry freedict ; + +\ constant ( x -- ) skip blanks parse the next word and create +\ a constant, allocate a long, 4 bytes +: constant + lockdict create $C_a_doconl w, l, forthentry freedict ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to +\ ina anded with n2 +: waitpeq _execasm2>0 1E0 _cnip ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 +\ if unsuccessful +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ (forget) ( cstr -- ) wind the dictionary back to the word +\ which follows - caution +: (forget) dup +if + find if + pfa>nfa nfa>lfa dup here W! W@ wlastnfa W! + else .cstr 3f emit cr then +else drop then ; + +\ forget ( -- ) wind the dictionary back to the word which +\ follows - caution +: forget parsenw (forget) ; + +\ free ( -- ) display free main bytes and current cog longs +: free dictend W@ here W@ - . ." bytes free - " par + coghere W@ - . ." cog longs free" cr ; + +\ ifnot: name ( -- ) - bedingte compilierung; wenn name schon +\ im wrterbuch vorhanden, wird bis zum nchsten semikolon +\ der eingabestrom ignoriert +: ifnot: parsenw nip find if begin key 3B = until + key drop then ; +\ bei konstrukte, die keine doppelpunkdefinition sind, muss der +\ block mit diesem Wort abgeschlossen werden +: :; ; + +\ --------------------------------------------------------- BUS + +\ bin ( -- ) - umschaltung auf duales zahlensystem +\ : bin 2 base W! ; +\ +---------------------------- /hs +\ |+--------------------------- /wr +\ ||+-------------------------- busclk +\ |||+------------------------- hbeat +\ ||||+------------------------ al +\ |||||+----------------------- /bel +\ ||||||+---------------------- /adm +\ |||||||+--------------------- /ram2 +\ ||||||||+-------------------- /ram1 +\ ||||||||| +--------- a0..10 +\ ||||||||| | +\ ||||||||| | +- d0..7 +\ |||||||||+---------++------+ +\ 00000000000000000000000000000000 +\ bin 00000111111111111111111100000000 constant dinp hex +\ bin 00000111111111111111111111111111 constant dout hex +\ bin 00000010000000000000000000000000 constant boff hex +\ bin 00000100011110000000000000000000 constant _s1 hex +\ bin 00000000001110000000000000000000 constant _b1 hex +\ bin 00000010001110000000000000000000 constant _b2 hex +\ bin 00000110001110000000000000000000 constant _b3 hex +\ bin 00000000010110000000000000000000 constant _a1 hex +\ bin 00000010010110000000000000000000 constant _a2 hex +\ bin 00000110010110000000000000000000 constant _a3 hex +\ bin 00001000000000000000000000000000 constant ?hs hex + +8000000 constant ?hs + +: [inp] \ ( -- ) bus eingabe + 7FFFF00 dira COG! ; \ dinp + +: [out] \ ( -- ) bus ausgabe + 7FFFFFF dira COG! ; \ dout + +: [off] \ ( -- ) bus aus + 2000000 dira COG! 0 outa COG! ; \ boff + +: [end] \ ( -- ) buskommunikation beendet + 4780000 outa COG! [inp] ; \ _s1 + +: [hs=1] \ ( -- ) wartet auf hs = 1 + ?hs dup waitpeq ; + +: [hs=0] \ ( -- ) warten auf hs = 0 + 0 ?hs waitpeq ; + +: [s!] \ ( c ctrl -- ) sende 8 bit an einen slave + [out] [hs=1] swap ff and or outa COG! [hs=0] [end] ; + +: [s@] \ ( ctrl -- c ) empfngt 8 bit von einem slave + [inp] [hs=1] outa COG! [hs=0] ina COG@ ff and [end] ; + +: [b!] \ ( c -- ) sende 8 bit an bellatrix + 2380000 [s!] ; \ _b2 + +: [a!] \ ( c -- ) sende 8 bit an administra + 2580000 [s!] ; \ _a2 + +: [b@] \ ( -- c ) empfngt 8 bit von bellatrix + 6380000 [s@] ; \ _b3 + +: [a@] \ ( -- c ) empfngt 8 bit von administra + 6580000 [s@] ; \ _a3 + +: <8 \ ( -- ) + 8 lshift ; + +\ [b.l!] ( 32b -- ) - long an bellatrix senden +: [b.l!] + dup 18 rshift [b!] + dup 10 rshift [b!] + dup 8 rshift [b!] + [b!] ; + +\ [b.l@] ( -- 32b ) - long von bellatrix einlesen +: [b.l@] + [b@] <8 + [b@] or <8 + [b@] or <8 + [b@] or ; + +\ [a.s@] ( -- ) - einen cstring von administra empfangen +\ und im pad speichern +: [a.s@] + [a@] pad 2dup C! 1+ swap + 0 do dup [a@] swap C! 1+ loop drop ; + +\ [a.s!] ( cstr -- ) - einen cstring an administra senden +: [a.s!] + dup C@ dup [a!] \ ( -- cstr len ) len senden + 0 do \ ( cstr len -- cstr ) + 1+ dup C@ [a!] \ ( cstr -- cstr+1 ) zeichen senden + loop drop ; \ ( cstr -- ) + +\ [a.w@] ( -- 16b ) - 16bit-wert von administra einlesen +: [a.w@] + [a@] <8 [a@] or ; + +\ [a.l!] ( 32b -- ) - long an administra senden +: [a.l!] + dup 18 rshift [a!] + dup 10 rshift [a!] + dup 8 rshift [a!] + [a!] ; + +\ [a.l@] ( -- 32b ) - long von administra einlesen +: [a.l@] + [a@] <8 + [a@] or <8 + [a@] or <8 + [a@] or ; + +wvariable b[lock] \ nummer der semaphore fr den + \ zugriff auf die bus-hardware + +\ b[ ( -- ) bus belegen; wartet bis semaphore freigegeben ist +: b[ begin b[lock] W@ lockset -1 <> until [inp] ; + +\ ]b ( -- ) bus freigeben +\ ! busclk bleibt auf ausgabe, da dieses signal sonst +\ kein definierten pegel besitzt ! +: ]b [off] b[lock] W@ lockclr drop ; + +\ administra-kommandoformate + +: b[a! b[ [a!] ; +: b[a!a! b[ [a!] [a!] ; +: adm:fkt! b[a! ]b ; \ ( fkt -- ) +: adm:fkt!b@ b[a! [a@] ]b ; \ ( fkt -- b ) +: adm:fkt!b! b[a!a! ]b ; \ ( b fkt -- ) +: adm:fkt!b!b@ b[a!a! [a@] ]b ; \ ( b fkt -- b ) +: adm:fkt!s@ b[a! [a.s@] ]b ; \ ( fkt -- ) +: adm:fkt!s!b@ b[a! [a.s!] [a@] ]b ; \ ( s fkt -- b ) +: adm:fkt!b!l@ b[a!a! [a.l@] ]b ; \ ( b fkt -- l ) + +\ ----------------------------------------------------- SD0.LIB + +\ marker-funktionen + +\ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm:dmset ( dmnr -- ) - marker setzen +: adm:dmset 1A adm:fkt!b! ; + +\ dateisystem-funktionen + +\ adm:volname ( -- ) - name des volumes im pad ablegen +: adm:volname 0C adm:fkt!s@ ; + +\ adm:mount ( -- err ) - medium mounten +: adm:mount 01 adm:fkt!b@ ; + +\ adm:unmount ( -- err ) - medium unmounten +: adm:unmount 18 adm:fkt!b@ ; + +\ adm:checkmounted ( -- t/f ) +: adm:checkmounted 0D adm:fkt!b@ ; + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +: adm:diropen 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gltige datei +\ st = 1 - dateiname im pad gltig +\ bei gltigem eintrag befindet sich der dateiname im pad +: adm:nextfile b[ 3 [a!] [a@] dup if [a.s@] then ]b ; + +\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen +: adm:fattrib 0B adm:fkt!b!l@ ; + +\ adm:chdir ( cstr -- err ) - verzeichnis ffnen +: adm:chdir 16 adm:fkt!s!b@ ; + +\ adm:getc ( -- c ) - ein zeichen aus der geffneten datei lesen +: adm:getc 06 adm:fkt!b@ ; + +\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist +: adm:eof 1E adm:fkt!b@ ; + +\ adm:open ( cstr modus -- err ) - datei ffnen +\ modus "R" $52 - Read +\ modus "W" $57 - Write +\ modus "A" $41 - Append +: adm:open b[ 4 [a!] [a!] [a.s!] [a@] ]b ; + +\ adm:close ( -- ) - datei schlieen +: adm:close 05 adm:fkt!b@ ; + +\ ----------------------------------------------------- SCR.LIB + +\ [dscr] ( scrnr -- ) display-screen setzen +: [dscr] 0 [b!] 59 [b!] [b!] ; + +\ [wscr] ( scrnr -- ) schreib-screen setzen +: [wscr] 0 [b!] 58 [b!] [b!] ; + +\ [key?] ( -- c ) - ungekapselte tastaturstatusabfrage +: [key?] 0 [b!] 1 [b!] [b@] ; + +\ [key] ( -- c ) - ungekapselte tastaturabfrage +: [key] 0 [b!] 2 [b!] [b@] ; + +\ [emit] ( c -- ) - ungekapselte zeichenausgabe +: [emit] emit? if emit then ; + +\ ----------------------------------------------------- TOOLS + +\ cls ( -- ) - screen lschen +: cls 01 emit ; + +\ .tab ( -- ) - tabulator +: .tab 09 emit ; + +\ .err ( err -- ) - fehlermeldung ausgeben +\ 0 no error +\ 1 fsys unmounted +\ 2 fsys corrupted +\ 3 fsys unsupported +\ 4 not found +\ 5 file not found +\ 6 dir not found +\ 7 file read only +\ 8 end of file +\ 9 end of directory +\ 10 end of root +\ 11 dir is full +\ 12 dir is not empty +\ 13 checksum error +\ 14 reboot error +\ 15 bpb corrupt +\ 16 fsi corrupt +\ 17 dir already exist +\ 18 file already exist +\ 19 out of disk free space +\ 20 disk io error +\ 21 command not found +\ 22 timeout +\ 23 parameter error +: .err dup if ERR then drop ; + +\ .pad ( -- ) - ausgabe eines strings im pad +: .pad pad .cstr ; + +\ .vname ( -- ) - ausgabe des namens der eingelegten sd-card +: .vname adm:volname .pad ; + +\ mount ( -- ) - sd-card mounten +: mount adm:mount .err ." Medium : " .vname cr ; + +\ unmount ( -- ) - sd-card unmounten +: unmount adm:unmount .err ; + +\ mount? ( -- ) - test ob medium mounted ist +\ wird als exception gewertet +: mount? adm:checkmounted 0= if 1 .err then ; + +\ padbl ( -- ) fills this cogs pad with blanks +: padbl pad padsize bl fill ; + +\ .entry ( -- st ) - einen verzeichniseintrag ausgeben +: .entry + adm:nextfile 13 adm:fattrib if 0F emit else space then + dup if .pad .tab then ; + +\ .len ( st -- st ) - dateilnge ausgeben +: .len dup if 0 adm:fattrib . then ; + +\ lscnt ( cnt1 st -- cnt2 st ) - spaltenformatierung fr ls +\ cnt - spaltenzhler, st - flag verzeichnisende +: lscnt + swap 1+ dup 4 = if cr drop 0 else .tab then swap ; + +\ lsl ( -- ) - verzeichnis anzeigen, long-format +: lsl mount? + adm:diropen begin .entry .len cr 0= until padbl ; + +\ ls ( -- ) - verzeichnis in spalten anzeigen +: ls mount? + adm:diropen 0 begin .entry lscnt 0= until drop padbl cr ; + +\ cd name ( -- ) - verzeichnis wechseln +: cd mount? parsenw adm:chdir .err ; + +\ open name ( -- ) - datei lesend ffnen und auf fehler prfen +: open + mount? parsenw dup + if 52 adm:open else drop 23 then .err ; + +\ close ( -- ) - geffnete datei schlieen +: close adm:close .err ; + +\ dload name - datei compilieren; log im gleichen screen +\ load name - datei compilieren; log screen 3 +\ sys name - datei aus sys compilieren; log screen 3 +\ die datei wird in der nchsten freien cog compiliert +\ fl ist fr load nicht ntig und bringt in dem kontext +\ die cog-zuordnung durcheinander + +: (load) + begin adm:getc emit adm:eof until ; + +: (dload) + open cogid nfcog iolink + (load) + cogid iounlink close ; + +: (sload) + open cogid 3 dup b[ [wscr] ]b iolink + (load) + cogid dup b[ [wscr] ]b iounlink close ; + +: load + ." Loading... " (sload) ; + +: dload + (dload) ; + +: sys + 2 adm:dmset 1 adm:dmact ." Loading... " (sload) 2 adm:dmact ; + +\ ------------------------------------------------- SPIN-LOADER + +\ (spin) ( cstr -- ) - c" reg.sys" (spin) +: (spin) + dup C@ 1+ + 0 do + dup i + C@ + ldvar 1+ i + C! + loop drop + 1 ldvar C! +; + +\ spin name ( -- ) - spinobjekt "name" starten +: spin + parsenw (spin) ; + +\ regime ( -- ) - startet dir trios-cli "regime" +: regime + 0 adm:dmact + c" reg.sys" (spin) ; + +\ ----------------------------------------------------- DRV:INT + + +wvariable icog \ nummer der drv:int-cog +wvariable lcog \ nummer interaktiven cog + +\ xint ( n -- ) io von cog n auf drv:int umschalten +: xint icog W@ ioconn ; + +\ [cogscr] ( nr -- ) - umschaltung screen + cog +: [cogscr] + dup 2dup lcog W! xint [dscr] [wscr] ; + +\ =n ( n1 n2 -- n1 n1=n2 ) +: =n 2dup = swap drop ; + +\ [esc] ( -- ) - manager fr esc-funktionen im drv:int +: [esc] + begin [key?] until [key] + 71 =n if 1b [emit] then \ esc - q : esc-char/quit + 31 =n if 1 [cogscr] then \ esc - 1 : cog-screen 0 + 32 =n if 2 [cogscr] then \ esc - 2 : cog-screen 1 + 33 =n if 3 [cogscr] then \ esc - 3 : cog-screen 2 + 62 =n if lcog W@ cogreset then \ esc - b : break (cog) + 72 =n if reboot then \ esc - r : reset (chip) + drop ; \ esc - esc : pause + +\ drv:int ( -- ) treiber fr bellatrix-terminal +\ diese cog fragt in einer endlosschleife ab, ob zeichen +\ versendet oder empfangen werden sollen. um die zeichenausgabe +\ zu beschleunigen, findet ausgabe und eingabe in einem +\ verhltnis von 512:1 statt. per esc-code knnen spezielle +\ funktionen im driver ausgelst werden. +: drv:int + \ name und typ der cog einstellen + cogid dup cogstate 10 swap C! c" drv:int" over + cognumpad ccopy + 20 delms 0D emit \ verzgertes cr fr prompt + begin + \ input --> vga/video + 200 0 do key? \ eingabezeichen vorhanden? + if key b[ [b!] ]b then loop \ cog ---> bel.vga + \ output <-- keyboard + b[ [key?] \ tastenstatus bellatrix? + if [key] dup 1b = if drop [esc] else [emit] thens ]b + 0 until ; + +\ ----------------------------------------------------- SYSINIT + +: start \ ( -- ) initialisierung hive + locknew b[lock] W! \ b-semaphore + 0 dup cogstate 10 swap C! c" drv:ldr" over + cognumpad ccopy + 5 dup icog W! c" drv:int" swap cogx 1 b[ [cogscr] ]b ; +: _ob onboot ; +: onboot _ob start ; + + + diff --git a/forth/bel.lib b/forth/bel.lib new file mode 100644 index 0000000..4cfec29 --- /dev/null +++ b/forth/bel.lib @@ -0,0 +1,81 @@ + +hex + +ifnot: lib:bel +: lib:bel ; + +ifnot: [b.w!] +: [b.w!] \ ( 16b -- ) - word an bellatrix senden + dup 8 rshift [b!] [b!] ; + +\ kommandoformate + +ifnot: bel:fkt! \ ( fkt -- ) +: bel:fkt! b[ 0 [b!] [b!] ]b ; + +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; + +ifnot: bel:fkt!b!l@ \ ( b fkt -- l ) +: bel:fkt!b!l@ b[ 0 [b!] [b!] [b!] [b.l@] ]b ; + +ifnot: bel:fkt!b!l! \ ( l b fkt -- ) +: bel:fkt!b!l! b[ 0 [b!] [b!] [b!] [b.l!] ]b ; + +ifnot: bel:fkt!l@ \ ( fkt -- l ) +: bel:fkt!l@ b[ 0 [b!] [b!] [b.l@] ]b ; + +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +\ chipmanagment-funktionen + +ifnot: bel:wscr \ ( scrnr -- ) - schreibscreen setzen +: bel:wscr 58 bel:fkt!b! ; + +ifnot: bel:dscr \ ( scrnr -- ) - displayscreen setzen +: bel:dscr 59 bel:fkt!b! ; + +ifnot: bel:getcol \ ( colnr -- col ) - farbe abfragen +: bel:getcol 5A bel:fkt!b!l@ ; + +ifnot: bel:setcol \ ( col colnr -- ) - farbe setzen +: bel:setcol 5B bel:fkt!b!l! ; + +ifnot: bel:getresx \ ( -- resx ) - abfrage x-auflsung +: bel:getresx 5C bel:fkt!l@ ; + +ifnot: bel:getresy \ ( -- resy ) - abfrage y-auflsung +: bel:getresy 5D bel:fkt!l@ ; + +ifnot: bel:getcols \ ( -- cols ) - abfrage textspalten +: bel:getcols 5E bel:fkt!b@ ; + +ifnot: bel:getrows \ ( -- rows ) - abfrage textzeilen +: bel:getrows 5F bel:fkt!b@ ; + +ifnot: bel:getcogs \ ( -- cogs ) - abfrage belegte cogs +: bel:getcogs 60 bel:fkt!b@ ; + +ifnot: bel:getspec \ ( -- spec ) - abfrage codespezifikation +: bel:getspec 61 bel:fkt!l@ ; + +ifnot: bel:getver \ ( -- ver ) - abfrage codeversion +: bel:getver 62 bel:fkt!l@ ; + +ifnot: bel:load \ ( cstr -- ) - bellatrix-code laden +: bel:load + 52 adm:open .err \ datei ffnen + b[ + 0 [b!] 57 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilnge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schlieen +; + + + + diff --git a/forth/cog.lib b/forth/cog.lib new file mode 100644 index 0000000..14b69d9 --- /dev/null +++ b/forth/cog.lib @@ -0,0 +1,74 @@ + +hex + +ifnot: lib:cog +: lib:cog ; + +\ cog special register + +ifnot: ctra 1F8 wconstant ctra :; +ifnot: ctrb 1F9 wconstant ctrb :; +ifnot: frqa 1FA wconstant frqa :; +ifnot: frqb 1FB wconstant frqb :; +ifnot: phsa 1FC wconstant phsa :; +ifnot: phsb 1FD wconstant phsb :; +ifnot: vcfg 1FE wconstant vcfg :; +ifnot: vscl 1FF wconstant vscl :; + +\ this words needs to align with the assembler code + +ifnot: _faddrmask : _faddrmask 1 _cv ; +ifnot: _flongmask : _flongmask 2 _cv ; +ifnot: _stptr : _stptr 5 _cv ; +ifnot: _sttos : _sttos 7 _cv ; +ifnot: _treg1 : _treg1 8 _cv ; +ifnot: _treg2 : _treg2 9 _cv ; +ifnot: _treg3 : _treg3 a _cv ; +ifnot: _treg4 : _treg4 b _cv ; +ifnot: _treg5 : _treg5 c _cv ; +ifnot: _treg6 : _treg6 d _cv ; +ifnot: _stbot : _stbot e _cv ; +ifnot: _sttop : _sttop 2e _cv ; +ifnot: _rsbot : _rsbot _sttop ; + +\ waitcnt ( n1 n2 -- n1 ) \ wait until n1, add n2 to n1 +ifnot: waitcnt +: waitcnt _execasm2>1 1F1 _cnip ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to +\ ina anded with n2 +ifnot: waitpeq +: waitpeq _execasm2>0 1E0 _cnip ; + +\ waitpne ( n1 n2 -- ) \ wait until state n1 is not equal +\ to ina anded with n2 +ifnot: waitpne +: waitpne _execasm2>0 1E8 _cnip ; + +\ lockret ( n1 -- ) deallocate a lock, previously allocated +\ via locknew +ifnot: lockret +: lockret 5 hubop 2drop ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 +\ if unsuccessful +ifnot: locknew +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ cog+ ( -- ) add a forth cog +ifnot: cog+ +: cog+ (cog+) ; + +\ (cog-) ( -- ) stop first forth cog, cannot be executed form +\ the first forth cog +ifnot: (cog-) +: (cog-) nfcog cogstop ; + +\ cog- ( -- ) stop first forth cog, cannot be executed form +\ the first forth cog +ifnot: cog- +: cog- (cog-) ; + + + + diff --git a/forth/debug.mod b/forth/debug.mod new file mode 100644 index 0000000..9a08f6e --- /dev/null +++ b/forth/debug.mod @@ -0,0 +1,65 @@ + +hex + +ifnot: mod:debug +: mod:debug ; + +\ keycode ( -- ) - anzeige der tastaturcodes +ifnot: keycode +: keycode + begin + 0 key? if + drop key dup dup ." code : " emit ." : " . cr 1B = + then until ; + +\ +\ Noisy reset messages +\ +\ print out a reset message to the console +\ (rsm) ( n -- ) n is the last status +\ 0011FFFF - stack overflow +\ 0012FFFF - return stack overflow +\ 0021FFFF - stack underflow +\ 0022FFFF - return stack underflow +\ 8100FFFF - no free cogs +\ 8200FFFF - no free main memory +\ 8400FFFF - fl no free main memory +\ 8500FFFF - no free cog memory +\ 8800FFFF - eeprom write error +\ 9000FFFF - eeprom read error + +: (rsm) state W@ 2 and 0= swap +\ process the last status + dup 0= if c" ok" else + dup FF11 = if c" DST OVER" else + dup FF12 = if c" RST OVER" else + dup FF21 = if c" DST LOW" else + dup FF22 = if c" RST LOW" else + dup 8001 = if c" COGs OUT" else + dup 8002 = if c" hMEM OUT" else + dup 8003 = if c" ROM WR" else + dup 8004 = if c" FL" else + dup 8005 = if c" cMEM OUT" else + dup 8006 = if c" ROM RD" else + c" ?" + thens + rot if + lockdict cr c" ERR : " .cstr swap . .cstr cr freedict + else 2drop then ; +: onreset (rsm) 4 state orC! ; + +\ .byte ( n1 -- ) +: .byte <# # # #> .cstr ; + +\ [if (dumpb) +: (dumpb) cr over .addr space dup .addr _ecs bounds ; ] + +\ [if (dumpm) +: (dumpm) cr .word _ecs ; ] + +\ [if (dumpe) +: (dumpe) tbuf 8 bounds do i C@ .byte space loop 2 spaces tbuf 8 bounds do i C@ dup bl < if drop 2e then emit loop ; ] + +\ dump ( adr cnt -- ) uses tbuf +[if dump +: dump (dumpb) do i (dumpm) i tbuf 8 cmove (dumpe) 8 +loop cr ; ] diff --git a/forth/fib.mod b/forth/fib.mod new file mode 100644 index 0000000..b82b493 --- /dev/null +++ b/forth/fib.mod @@ -0,0 +1,22 @@ + +: mod:fib ; + +\ ( n -- f ) berechnet die nte fibonacci-zahl +: fib + 0 1 rot 0 do over + swap loop drop ; + +\ benchmark ber n fibonacci-zahlen +: fibo-bench + 1+ 1 do + i ." fibo(" . ." ) = " + i cnt COG@ swap fib cnt COG@ swap . + swap - ." , ticks : " . + cr + loop ; + +decimal 40 fibo-bench hex + + + + + \ No newline at end of file diff --git a/forth/g0.lib b/forth/g0.lib new file mode 100644 index 0000000..3bdb6cb --- /dev/null +++ b/forth/g0.lib @@ -0,0 +1,59 @@ +\ require ari.lib + +ifnot: lib:g0 +: lib:g0 ; + +hex + +10 constant g0:xtiles +0C constant g0:ytiles +5000 constant g0:disp_base + +decimal + +ifnot: g0:load +: g0:load + c" g0key.bel" bel:load ; + +ifnot: g0:reboot +: g0:reboot 99 b[ [b!] ]b ; + +hex + +ifnot: g0:setcolortab +: g0:setcolortab \ ( addr -- ) + 5D b[ [b!] + 40 0 do dup L@ [b.l!] 4 + loop + ]b drop ; + +ifnot: g0:settilescreen +: g0:settilescreen \ ( addr -- ) + 5E b[ [b!] + g0:ytiles 0 do + g0:xtiles 0 do dup W@ [b.w!] 2 + loop + loop ]b drop ; + +decimal + +\ ifnot: g0:setscreen +: g0:setscreen \ ( addr addr -- ) + g0:setcolortab g0:settilescreen ; + +ifnot: g0:static +: g0:static 98 b[ [b!] ]b ; + +ifnot: g0:dynamic +: g0:dynamic 97 b[ [b!] ]b ; + +ifnot: g0:clear \ ( -- ) - bildschirm loeschen +: g0:clear 10 b[ [b!] ]b ; + +ifnot: g0:color \ ( color -- ) - zeichenfarbe setzen +: g0:color 12 b[ [b!] [b!] ]b ; + +ifnot: g0:width \ ( x -- ) - punktgroesse setzen +: g0:width 13 b[ [b!] [b!] ]b ; + +ifnot: g0:plot \ ( y x -- ) - punkt setzen +: g0:plot 15 b[ [b!] [b!] [b!] ]b ] ; + diff --git a/forth/hplay.mod b/forth/hplay.mod new file mode 100644 index 0000000..9342fcb --- /dev/null +++ b/forth/hplay.mod @@ -0,0 +1,155 @@ + +hex + +ifnot: mod:hplay +: mod:hplay ; + +\ kommandoformate + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!w@ \ ( b fkt -- w ) +: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; + +\ hss-funktionen + +ifnot: hss:load \ ( cstr -- err ) - hss-datei laden +: hss:load dup if 64 adm:fkt!s!b@ then ; + +ifnot: hss:play \ ( -- ) - datei im puffer abspielen +: hss:play 65 adm:fkt! ; + +ifnot: hss:stop \ ( -- ) - player stop +: hss:stop 66 adm:fkt! ; + +ifnot: hss:reg \ hreg ( regnr -- 16b ) +: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ; + +ifnot: hss:vol \ hvol ( vol -- ) - lautstrke 0..15 +: hss:vol 6A adm:fkt!b! ; + +\ keyboard-funktionen + +ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen +: key:stat 1 bel:fkt!b@ ; + +\ steuerzeichen + +ifnot: scr:cls \ ( -- ) - screen lschen +: scr:cls 01 bel:char ; + +ifnot: scr:home \ ( -- ) - cursor oben links +: scr:home 02 bel:char ; + +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; + +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; + +\ sd0-funktionen + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +ifnot: adm:diropen +: adm:diropen + 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gltige datei +\ st = 1 - dateiname im pad gltig +\ bei gltigem eintrag befindet sich der dateiname im pad +ifnot: adm:nextfile +: adm:nextfile + b[ 03 [a!] [a@] dup if [a.s@] then ]b ; + +\ metafunktionen + +\ hload name ( -- ) - hss-datei in player laden + +ifnot: hload +: hload mount? parsenw hss:load .err ; + +ifnot: .hset +: .hset \ ( shift -- ) - eine registersatz ausgeben + 5 0 do dup i + hss:reg .word space loop drop ; + +ifnot: .hreg +: .hreg \ ( -- ) - register ausgeben + 14 0 do i .hset cr 5 +loop ; + +ifnot: fadeout +: fadeout \ ( -- ) - sound langsam ausblenden + f 0 do e i - hss:vol 50 delms loop ; + +ifnot: end? +: end? \ ( cnt -- flag ) - abfrage nach cnt wiederholungen + 4 hss:reg = ; + +ifnot: hwait +: hwait \ ( -- flag ) - wartet auf songende oder taste + begin 50 delms key? 2 end? or until key drop ; + +ifnot: hreg.. +: hreg.. \ ( -- ) - fortlaufende anzeige register + scr:curoff scr:cls begin scr:home .hreg 2 end? until + scr:curon fadeout hss:stop ; + +ifnot: (hplay) +: (hplay) \ ( cstr -- ) + ." Datei : " dup .cstr hss:load .err f hss:vol hss:play + hwait fadeout hss:stop 100 delms cr ; + +\ hplay name ( -- ) - datei abspielen +ifnot: hplay +: hplay + hload hss:play ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ hdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis drfen nur hss-dateien sein! +ifnot: hdirplay +: hdirplay + decimal files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (hplay) loop padbl hex ; + +: (hp) ." play : " dup .cstr hss:load .err ; + +ifnot: playliste +: playliste + c" kw.hss" (hplay) + c" genes.hss" (hplay) + c" greenpuz.hss" (hplay) + c" hssintro.hss" (hplay) + c" kali766.hss" (hplay) + c" machine.hss" (hplay) + c" metroid.hss" (hplay) + c" mrboss.hss" (hplay) + c" mrevil.hss" (hplay) + c" raind.hss" (hplay) + c" sytrus.hss" (hplay) + c" tbellsp1.hss" (hplay) ; + diff --git a/forth/hss.lib b/forth/hss.lib new file mode 100644 index 0000000..314ab75 --- /dev/null +++ b/forth/hss.lib @@ -0,0 +1,60 @@ + +hex + +ifnot: lib:hss +: lib:hss ; + +\ kommandoformate + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b! \ ( b b fkt -- ) +: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ; + +ifnot: adm:fkt!b!w@ \ ( b fkt -- w ) +: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +\ hss-funktionen + +\ ( cstr -- err ) - hss-datei laden +ifnot: hss:load +: hss:load dup if 64 adm:fkt!s!b@ then ; + +\ ( -- ) - datei im puffer abspielen +ifnot: hss:play +: hss:play 65 adm:fkt! ; + +\ ( -- ) - player stop +ifnot: hss:stop +: hss:stop 66 adm:fkt! ; + +\ ( -- ) - player pause +ifnot: hss:pause +: hss:pause 67 adm:fkt! ; + +\ hreg ( regnr -- 16b ) +\ 0 iEndFlag iRowFlag iEngineC iBeatC iRepeat Player +\ 5 iNote iOktave iVolume iEffekt iInstrument Kanal 1 +\ 10 iNote iOktave iVolume iEffekt iInstrument Kanal 2 +\ 15 iNote iOktave iVolume iEffekt iInstrument Kanal 3 +\ 20 iNote iOktave iVolume iEffekt iInstrument Kanal 4 +\ +\ iEndFlag Repeat oder Ende wurde erreicht +\ iRowFlag Trackerzeile (Row) ist fertig +\ iEngineC Patternzhler +\ iBeatC Beatzhler (Anzahl der Rows) +\ iRepeat Zhler fr Loops +ifnot: hss:reg +: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ; + +\ hvol ( vol -- ) - lautstrke 0..15 +ifnot: hss:vol +: hss:vol 6A adm:fkt!b! ; + diff --git a/forth/key.lib b/forth/key.lib new file mode 100644 index 0000000..06698da --- /dev/null +++ b/forth/key.lib @@ -0,0 +1,17 @@ + +hex + +ifnot: lib:key +: lib:key ; + +\ kommandoformate +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; + +\ keyboard-funktionen +ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen +: key:stat 1 bel:fkt!b@ ; +ifnot: key:code \ ( -- code ) - tastencode abfragen +: key:code 2 bel:fkt!b@ ; +ifnot: key:spec \ ( -- spec ) - spezialtasten abfragen +: key:spec 4 bel:fkt!b@ ; diff --git a/forth/rom.mod b/forth/rom.mod new file mode 100644 index 0000000..290cb16 --- /dev/null +++ b/forth/rom.mod @@ -0,0 +1,206 @@ + +\ ACHTUNG: Diese Modifikation nicht bei einer Installation im +\ HI-EEPROM verwenden! + +hex +[if mod:rom +: mod:rom ; ] + +\ constant ( x -- ) skip blanks parse the next word and create a constant, allocate a long, 4 bytes +[if constant +: constant lockdict create $C_a_doconl w, l, forthentry freedict ; ] + +\ +\ CONFIG PARAMETERS BEGIN +\ +40 wconstant fsps \ a page size which works with 32kx8 & 64kx8 eeproms + \ and should work with larger as well. + + +8000 constant fsbot \ file-system bottom: the start adress in eeprom for the file system + + \ file system top: the end address of the file system + \ uncomment the line for your comfiguration +\ 8000 constant fstop \ the end address for the file system with one 24LC256 32k eeprom +10000 constant fstop \ the end address for the file system with one 24LC512 64k eeprom +\ 20000 constant fstop \ the end address for the file system with two 24LC512 64k eeprom +\ 30000 constant fstop \ the end address for the file system with 3 24LC512 64k eeprom +\ 40000 constant fstop \ the end address for the file system with 4 24LC512 64k eeprom +\ 50000 constant fstop \ the end address for the file system with 5 24LC512 64k eeprom +\ 60000 constant fstop \ the end address for the file system with 6 24LC512 64k eeprom +\ 70000 constant fstop \ the end address for the file system with 7 24LC512 64k eeprom + +\ NOTE IF you have DEMOBOARD or any system with 32K EEPROM, you will step on your spin image +\ when you write to the EEPROM. You can still use it (if you are tricky), but KNOW WHAT YOUR DOING!!! + +\ +\ CONFIG PARAMETERS END +\ + + +\ lasti? ( -- t/f ) true if this is the last value of i in this loop +[if lasti? +: lasti? _rsptr COG@ 2+ COG@ 1- _rsptr COG@ 3 + COG@ = ; ] + +\ padbl ( -- ) fills this cogs pad with blanks +[if padbl +: padbl pad padsize bl fill ; ] +\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop +swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ] + +\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +[if eereadpage : eereadpage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eestart A0 or _eewrite swap _eewrite or swap _eewrite or +_eestart r> A1 or _eewrite or +rot2 bounds +do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ] + +\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop +swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ] + +\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +[if eereadpage : eereadpage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eestart A0 or _eewrite swap _eewrite or swap _eewrite or +_eestart r> A1 or _eewrite or +rot2 bounds +do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ] + +\ EW@ ( eeAddr -- n1 ) +[if EW@ +: EW@ t0 2 eereadpage if 8006 ERR then t0 W@ ; ] + +\ EC@ ( eeAddr -- c1 ) +[if EC@ +: EC@ EW@ FF and ; ] + +\ (fspa) ( addr1 -- addr2) addr2 is the next page aligned address after addr1 +: (fspa) fsps 1- + fsps 1- andn ; + +\ (fsnext) ( addr1 -- addr2 t/f) addr - the current file address, addr2 - the next addr, t/f - true if we have +\ gone past the end of the eeprom. t0 -length of the current file +\ t1 - length of the file name (char) +: (fsnext) t0 W@ t1 C@ + 2+ 1+ + (fspa) dup fstop >= ; + + +\ (fswr) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to write, addr2 - the address to write from +\ n1 - the number of bytes to write +: (fswr) dup >r rot dup r> + fstop 1- > if A0 ERR then rot2 eewritepage if 88 ERR then ; + +\ (fsrd) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to read, addr2 - the address of the read buffer +\ n1 - the number of bytes to read +: (fsrd) dup >r rot dup r> + fstop 1- > if C0 ERR then rot2 eereadpage if 90 ERR then ; + +\ (fsfree) ( -- n1 ) n1 is the first location in the file system, -1 if there are none +: (fsfree) -1 fsbot begin +\ read 3 bytes into t0, t1 and process + dup t0 3 (fsrd) t0 W@ FFFF = if nip dup -1 else (fsnext) then +until drop ; + +\ (fsfind) ( cstr -- addr ) find the last file named cstr, addr is the eeprom address, 0 if not found +: (fsfind) fsbot 0 >r begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + over t1 cstr= if r> drop dup >r then + (fsnext) + then +until 2drop r> ; + +\ (fslast) ( -- addr ) find the last file, 0 if not found +: (fslast) 0 fsbot begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + nip dup + (fsnext) + then +until drop ; + +\ fsclear ( -- ) +: fsclr padbl fsbot 400 + fsbot do i pad fsps (fswr) 2e emit fsps +loop -1 fsbot EW! ; +: fsclear -1 fsbot EW! ; + +\ fsfree ( -- ) +: fsfree (fsfree) dup -1 = if 0 else fstop swap - then . ." bytes free in fs" cr ; + +\ fsls ( -- ) list the files +: fsls cr fsbot begin +\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf + dup t0 22 (fsrd) t0 W@ FFFF = if -1 else + dup .addr space t0 W@ .addr space t1 .cstr cr + (fsnext) + then +until fstop swap - cr . ." bytes free in files system" cr cr ; + +\ (fsread) ( cstr -- ) +: (fsread) (fsfind) dup if +\ read 3 bytes into t0, t1 and process + dup t0 3 (fsrd) + t1 C@ + 2+ 1+ t0 W@ bounds do + ibound i - fsps >= if + i pad fsps (fsrd) pad fsps bounds + do i C@ emit loop i fsps 1- + seti + else + i EC@ emit + then + loop +else drop then padbl ; + +\ fsread ( -- ) filename +: fsread parsenw dup if (fsread) else drop then ; + +\ (fsload) ( ctsr -- ) +: (fsload) cogid nfcog iolink (fsread) d emit d emit cogid iounlink ; + +\ fsload filename ( -- ) send the file to the next free forth cog +: fsload parsenw dup if (fsload) else drop then ; + +\ (fsk) ( n1 -- n2) +: (fsk) 8 lshift key or ; + +\ fswrite filename ( -- ) writes a file until ... followed immediately by a cr is encountered +: fswrite (fsfree) dup -1 <> parsenw dup rot and if +\ set the file length to 0, copy in the file name + 0 pad W! dup C@ 2+ 1+ pad + swap pad 2+ ccopy +\ find the first free page + 0 swap key (fsk) (fsk) (fsk) +\ ( eaddr1 n1 addr2 n2 ) eaddr - start of file in the eeprom, n1 - bytes written so far, addr2 - next addr in the pad, +\ n2 - a 4 byte key buffer + begin +\ check to see if we have a ... at the end of a line + 2E2E2E0D over = if + -1 + else +\ get a key from the key buffer, write it the the pad + swap over 18 rshift dup dup d = if drop cr else emit then over C! 1+ tuck pad - fsps = if +\ we have a page worth of data, write it out + nip rot2 2dup + pad fsps (fswr) fsps + rot pad swap + then +\ get another key + (fsk) 0 + then + until +\ any keys left? + drop pad - dup 0> if +\ write the leftover, not a full page + >r 2dup + pad r> dup >r (fswr) r> + + else + drop + then +\ write the length of FFFF for the next file + 2dup + FFFF swap (fspa) dup fstop 1- < if EW! else 2drop then +\ subtract the length of the filename +1, and the 2 bytes which are the length of the file, and update the length of the file + over 2+ EC@ 2+ 1+ - swap EW! +else 2drop clearkeys then padbl +; + +\ fsdrop ( -- ) deletes last file +: fsdrop (fslast) dup -1 = if drop else FFFF swap EW! then ; + + diff --git a/forth/scr.lib b/forth/scr.lib new file mode 100644 index 0000000..471c928 --- /dev/null +++ b/forth/scr.lib @@ -0,0 +1,69 @@ + +hex + +ifnot: lib:scr +: lib:scr ; + +\ kommandoformate +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl! \ ( ctrl -- ) +: bel:ctrl! b[ 0 [b!] 3 [b!] [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl!b@ \ ( ctrl -- b@ ) +: bel:ctrl!b@ b[ 0 [b!] 3 [b!] [b!] [b@] ]b ; +ifnot: bel:ctrl!b!b! \ ( b b ctrl -- ) +: bel:ctrl!b!b! b[ 0 [b!] 3 [b!] [b!] [b!] [b!] [b!] ]b ; + +\ einfache steuerzeichen +ifnot: scr:cls \ ( -- ) - screen lschen +: scr:cls 01 bel:char ; +ifnot: scr:home \ ( -- ) - cursor oben links +: scr:home 02 bel:char ; +ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang +: scr:pos1 03 bel:char ; +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; +ifnot: scr:scrlu \ ( -- ) - screen nach oben scrollen +: scr:scrlu 06 bel:char ; +ifnot: scr:scrld \ ( -- ) - screen nach unten scrollen +: scr:scrld 07 bel:char ; +ifnot: scr:bs \ ( -- ) - backspace +: scr:bs 08 bel:char ; +ifnot: scr:tab \ ( -- ) - tabulator +: scr:tab 09 bel:char ; + +\ screen-funktionen +ifnot: scr:logo \ ( y x -- ) - hive logo +: scr:logo 5 bel:fkt!b!b! ; +ifnot: scr:char \ ( char -- ) - zeichensatz direkt ausgeben +: scr:char 6 bel:fkt!b! ; + +\ parametrisierte steuerzeichen +ifnot: scr:setcur \ ( cur -- ) - cursorzeichen setzen +: scr:setcur 01 bel:ctrl!b! ; +ifnot: scr:setx \ ( x -- ) - cursor position x setzen +: scr:setx 02 bel:ctrl!b! ; +ifnot: scr:sety \ ( y -- ) - cursor position y setzen +: scr:sety 03 bel:ctrl!b! ; +ifnot: scr:getx \ ( -- x ) - cursor position x abfragen +: scr:getx 04 bel:ctrl!b@ ; +ifnot: scr:gety \ ( -- y ) - cursor position y abfragen +: scr:gety 05 bel:ctrl!b@ ; +ifnot: scr:setcol \ ( colnr -- ) - farbe whlen 0..15 +: scr:setcol 06 bel:ctrl!b! ; +ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich +: scr:sline 07 bel:ctrl!b! ; +ifnot: scr:eline \ ( row -- ) - endzeile scrollbereich +: scr:eline 08 bel:ctrl!b! ; +ifnot: scr:sinit \ ( -- ) - +: scr:sinit 09 bel:ctrl! ; +ifnot: scr:tabset \ ( pos nr -- ) - tabulatorposition setzen 0..7 +: scr:tabset 0A bel:ctrl!b!b! ; diff --git a/forth/sd0.lib b/forth/sd0.lib new file mode 100644 index 0000000..94d49ee --- /dev/null +++ b/forth/sd0.lib @@ -0,0 +1,176 @@ + +hex + +ifnot: lib:sd0 +: lib:sd0 ; + +\ ------------------------------------ lib:sd0 + +\ kommandoformate + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; + +ifnot: adm:fkt!l! \ ( l fkt -- ) +: adm:fkt!l! b[ [a!] [a.l!] ]b ; + +ifnot: adm:fkt!l@ \ ( fkt -- l ) +: adm:fkt!l@ b[ [a!] [a.l@] ]b ; + +ifnot: adm:fkt!b!l! \ ( l b fkt -- ) +: adm:fkt!b!l! b[ [a!] [a!] [a.l!] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!b!s!b@ \ ( s b fkt -- b ) +: adm:fkt!b!s!b@ b[ [a!] [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!s!s!b@ \ ( s s fkt -- b ) +: adm:fkt!s!s!b@ b[ [a!] [a.s!] [a.s!] [a@] ]b ; + +\ dateisystem-funktionen + +\ adm:mount ( -- err ) - medium mounten +ifnot: adm:mount +: adm:mount + 01 adm:fkt!b@ ; + +\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren +ifnot: adm:diropen +: adm:diropen + 02 adm:fkt! ; + +\ adm:nextfile ( -- st ) +\ st = 0 - keine gltige datei +\ st = 1 - dateiname im pad gltig +\ bei gltigem eintrag befindet sich der dateiname im pad +ifnot: adm:nextfile +: adm:nextfile + b[ 03 [a!] [a@] dup if [a.s@] then ]b ; + +\ adm:open ( cstr modus -- err ) - datei ffnen +\ modus "R" $52 - Read +\ modus "W" $57 - Write +\ modus "A" $41 - Append +ifnot: adm:open +: adm:open + 04 adm:fkt!b!s!b@ ; + +\ adm:close ( -- ) - datei schlieen +ifnot: adm:close +: adm:close + 05 adm:fkt!b@ ; + +\ adm:getc ( -- c ) - ein zeichen aus datei lesen +ifnot: adm:getc +: adm:getc + 06 adm:fkt!b@ ; + +\ adm:putc ( c -- ) - ein zeichen in datei schreiben +ifnot: adm:putc +: adm:putc + 07 adm:fkt!b! ; + +\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist +ifnot: adm:eof +: adm:eof + 1E adm:fkt!b@ ; + +\ adm:getblk ( adr cnt -- ) - datenblock aus datei lesen + +\ adm:putblk ( adr cnt -- ) - datenblock in datei schreiben + +\ adm:seek ( pos -- ) - position in datei setzen +: adm:seek + 0A adm:fkt!l! ; + +\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen +ifnot: adm:fattrib +: adm:fattrib + 0B adm:fkt!b!l@ ; + +\ adm:volname ( -- ) - name des volumes im pad ablegen +ifnot: adm:volname +: adm:volname + 0C adm:fkt!s@ ; + +\ adm:checkmounted ( -- t/f ) +ifnot: adm:checkmounted +: adm:checkmounted + 0D adm:fkt!b@ ; + +\ adm:checkopen ( -- t/f ) +ifnot: adm:checkopen +: adm:checkopen + 0E adm:fkt!b@ ; + +\ adm:checkused ( -- used ) - anzahl benutzte sektoren +ifnot: adm:checkused +: adm:checkused + 0F adm:fkt!l@ ; + +\ adm:checkfree ( -- free ) - anzahl freie sektoren +ifnot: adm:checkfree +: adm:checkfree + 10 adm:fkt!l@ ; + +\ adm:newfile ( cstr -- err ) - neue datei erstellen +ifnot: adm:newfile +: adm:newfile + 11 adm:fkt!s!b@ ; + +\ adm:newdir ( cstr -- err ) - neues verzeichnis erstellen +ifnot: adm:newdir +: adm:newdir + 12 adm:fkt!s!b@ ; + +\ adm:del ( cstr -- err ) - datei/verzeichnis lschen +ifnot: adm:del +: adm:del + 13 adm:fkt!s!b@ ; + +\ adm:rename ( cstr1.fn1 cstr2.fn2 -- err ) +ifnot: adm:rename +: adm:rename + 14 adm:fkt!s!s!b@ ; + +\ adm:chattrib ( cstr1.fn cstr2.attrib -- err ) +ifnot: adm:chattrib +: adm:chattrib + 15 adm:fkt!s!s!b@ ; + +\ adm:chdir ( cstr -- err ) - verzeichnis ffnen +ifnot: adm:chdir +: adm:chdir + 16 adm:fkt!s!b@ ; + +\ adm:format ( cstr.label -- err ) - medium formatieren +ifnot: adm:format +: adm:format + 17 adm:fkt!s!b@ ; + +\ adm:unmount ( -- err ) - medium unmounten +ifnot: adm:unmount +: adm:unmount + 18 adm:fkt!b@ ; + +\ marker-funktionen + +ifnot: adm:dmact \ ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ .err ; +ifnot: adm:dmset \ ( dmnr -- ) - marker setzen +: adm:dmset 1A adm:fkt!b! ; +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; +ifnot: adm:dmclr \ ( dmnr -- ) - marker lschen +: adm:dmclr 1C adm:fkt!b! ; +ifnot: adm:dmput \ ( dm dmnr -- ) - marker schreiben +: adm:dmput 1D adm:fkt!b!l! ; + diff --git a/forth/sfx.lib b/forth/sfx.lib new file mode 100644 index 0000000..74c9658 --- /dev/null +++ b/forth/sfx.lib @@ -0,0 +1,93 @@ + +hex + +ifnot: lib:sfx +: lib:sfx ; + +\ kommandoformen + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b!b! \ ( b b fkt -- ) +: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ; + +ifnot: adm:fkt!b!64b! \ ( ptr b fkt -- ) +: adm:fkt!b!64b! b[ [a!] [a!] + 31 0 do dup i + C@ [a!] loop drop ]b ; + +\ sfx-funktionen + +\ sfx:fire( chan slot -- ) - sfx abspielen +\ slot - $00..$0f nummer der freien effektpuffer +\ slot - $f0..f5 vordefinierte effektslots +\ chan - 0/1 stereokanal +\ vordefinierte effekte +\ &f0 - warnton +\ $f1 - signalton +\ $f2 - herzschlag schnell +\ $f3 - herzschlag langsam +\ $f4 - telefon +\ $f5 - phaser :) +\ $f6 - pling +\ $f7 - on +\ $f8 - off +ifnot: sfx:fire +: sfx:fire 6B adm:fkt!b!b! ; + +\ ( ptr slot -- ) - sfx setzen +\ slot - $00..$0f nummer der freien effektpuffer +\ ptr - zeiger auf 32 byte effektdaten +\ +\ struktur der effektdaten: +\ +\ [wav ][len ][freq][vol ] grundschwingung +\ [lfo ][lfw ][fma ][ama ] modulation +\ [att ][dec ][sus ][rel ] hllkurve +\ [seq ] (optional) +\ +\ [wav] wellenform +\ 0 sinus (0..500hz) +\ 1 schneller sinus (0..1khz) +\ 2 dreieck (0..500hz) +\ 3 rechteck (0..1khz) +\ 4 schnelles rechteck (0..4khz) +\ 5 impulse (0..1,333hz) +\ 6 rauschen +\ [len] tonlnge $0..$fe, $ff endlos +\ [freq] frequenz $00..$ff +\ [vol] lautstrke $00..$0f +\ +\ [lfo] low frequency oscillator $ff..$01 +\ [lfw] low frequency waveform +\ $00 sinus (0..8hz) +\ $01 fast sine (0..16hz) +\ $02 ramp up (0..8hz) +\ $03 ramp down (0..8hz) +\ $04 square (0..32hz) +\ $05 random +\ $ff sequencer data (es folgt eine sequenzfolge [seq]) +\ [fma] frequency modulation amount +\ $00 no modulation +\ $01..$ff +\ [ama] amplitude modulation amount +\ $00 no modulation +\ $01..$ff +\ [att] attack $00..$ff +\ [dec] decay $00..$ff +\ [sus] sustain $00..$ff +\ [rel] release $00..$ff +ifnot: sfx:setslot +: sfx:setslot + 6C adm:fkt!b!64b! ; + +\ sfx:keyoff ( chan -- ) - release-phase einleiten +ifnot: sfx:keyoff +: sfx:keyoff + 6D adm:fkt!b! ; + +\ sfx:stop ( chan -- ) +ifnot: sfx:stop +: sfx:stop + 6E adm:fkt!b! ; + diff --git a/forth/splay.mod b/forth/splay.mod new file mode 100644 index 0000000..e28aa6c --- /dev/null +++ b/forth/splay.mod @@ -0,0 +1,116 @@ + +\ achtung: vor verwendung muss der administra-code mit sidcog +\ geladen werden: +\ sys tools.mod +\ sys splay.mod <--- sid-player laden +\ aload admsid.adm <--- administra-code mit sidcog laden +\ splay xyz.dmp <--- sid-datei abspielen + + +hex + +ifnot: mod:splay +: mod:splay ; + +\ kommandoformen + +ifnot: adm:fkt! \ ( fkt -- ) +: adm:fkt! b[ [a!] ]b ; + +ifnot: adm:fkt!b! \ ( b fkt -- ) +: adm:fkt!b! b[ [a!] [a!] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ 0 [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- err ) +: adm:fkt!s! b[ [a!] [a.s!] [b@] ]b ; + +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; + +\ dm-funktionen +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; + +\ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm-funktionen + +\ adm:aload ( cstr -- ) - neuen administra-code laden +ifnot: adm:aload +: adm:aload + 60 adm:fkt!s! ; + +\ tools + +ifnot: aload +: aload + mount? parsenw dup + if 1 adm:dmact adm:aload 0 else drop 23 then .err ; + +\ sid-funktionen + +ifnot: sid:play +: sid:play \ ( cstr -- err ) + 9E adm:fkt!s!b@ ; + +ifnot: sid:stop +: sid:stop \ ( -- ) + 9F adm:fkt! ; + +ifnot: sid:status +: sid:status \ ( -- status ) + A1 adm:fkt!b@ ; + +ifnot: sid:mute +\ 1 - sid1 +\ 2 - sid2 +\ 3 - sid1 & sid2 +: sid:mute \ ( sidnr -- ) + A3 adm:fkt!b! ; + +\ send? ( -- t/f ) +ifnot: send? +: send? + begin 50 delms key? dup if key drop then sid:status 0= or + until ; + +\ (splay) ( cstr -- ) +ifnot: (splay) +: (splay) \ ( cstr -- ) + ." Datei : " dup .cstr cr sid:play .err + send? sid:stop 3 sid:mute adm:close drop ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ splay name.dmp ( -- ) - sid-datei abspielen +ifnot: splay +: splay + parsenw (splay) ; + +\ sdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis drfen nur sid-dateien sein! +ifnot: sdirplay +: sdirplay + files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (splay) loop padbl ; + +ifnot: smute +: smute + sid:stop 3 sid:mute ; + \ No newline at end of file diff --git a/forth/tools.mod b/forth/tools.mod new file mode 100644 index 0000000..cd9ca0e --- /dev/null +++ b/forth/tools.mod @@ -0,0 +1,152 @@ + +hex + +ifnot: mod:tools +: mod:tools ; + +\ kommandoformen +ifnot: adm:fkt!b!l@ \ ( b fkt -- l ) +: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ; +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; +ifnot: adm:fkt!s! \ ( s fkt -- ) +: adm:fkt!s! b[ [a!] [a.s!] ]b ; + +\ dm-funktionen +ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen +: adm:dmget 1B adm:fkt!b!l@ ; + +ifnot: adm:dmact \ adm:dmact ( dmnr -- ) - marker aktivieren +: adm:dmact 19 adm:fkt!b!b@ drop ; + +\ adm-funktionen + +\ adm:aload ( cstr -- ) - neuen administra-code laden +ifnot: adm:load +: adm:load + 60 adm:fkt!s! ; + +\ bel-funktionen + +\ bel:load ( cstr -- ) - bellatrix-code laden +\ achtung: die gesamte loader-operation ist eine atomare +\ operation ber alle drei propellerchips, kann also auch +\ nicht aufgetrennt werden! +ifnot: bel:load +: bel:load + 52 adm:open .err \ datei ffnen + b[ + 0 [b!] 57 [b!] \ bella-loader starten + 10 0 do 06 [a!] [a@] [b!] loop \ header einlesen + 0A [a!] 0 [a.l!] \ 0 adm:seek + [b@] <8 [b@] or \ dateilnge empfangen + 0 do 06 [a!] [a@] [b!] loop \ datei senden + ]b + adm:close .err \ datei schlieen +; + +\ ------------------------------------ mod:tools + +ifnot: aload +: aload \ name ( -- ) - administra-code laden + mount? parsenw dup + if adm:load 0 else drop 23 then .err ; + +ifnot: bload +: bload \ name ( -- ) - bellatrix-code laden + mount? parsenw dup + if bel:load 0 else drop 23 then .err ; + +ifnot: .dmstatus \ ( dm -- ) - ausgabe marker-status +: .dmstatus -1 = if ." frei" else ." gesetzt" then cr ; + +ifnot: dm? +: dm? + ." [root] : " 0 adm:dmget .dmstatus + ." [sys ] : " 1 adm:dmget .dmstatus + ." [usr ] : " 2 adm:dmget .dmstatus + ." [ A ] : " 3 adm:dmget .dmstatus + ." [ B ] : " 4 adm:dmget .dmstatus + ." [ C ] : " 5 adm:dmget .dmstatus ; + +\ open name ( -- ) - datei lesend ffnen und auf fehler prfen +ifnot: open +: open + mount? parsenw dup + if 52 adm:open else drop 23 then .err ; + +\ close ( -- ) - geffnete datei schlieen +ifnot: close +: close + adm:close .err ; + +\ (cat) ( -- ) - alle zeichen der geffneten datei ab +\ lesemarke auf ausgabekanal bis zum eof ausgeben +ifnot: (cat) +: (cat) begin adm:getc emit adm:eof until ; + +\ cat name ( -- ) - datei "name" komplett ausgeben +ifnot: cat +: cat open (cat) close ; + +\ nextline ( -- ) - ausgabe der nchsten textzeile aus der +\ geffneten datei +ifnot: nextline +: nextline + begin adm:getc dup emit 0d = adm:eof or until ; + +\ nextlines ( n -- ) - ausgabe von n zeilen +ifnot: nextlines +: nextlines + 0 do adm:eof 0= if nextline then loop ; + +\ less name ( -- ) - zeilenweise ausgabe der datei +ifnot: less +: less + open begin 10 nextlines key 71 = adm:eof or until close ; + +\ #C ( c1 -- ) prepend the character c1 to the number +\ currently being formatted +ifnot: #C +: #C -1 >out W+! pad>out C! ; + +\ .cogch ( n1 n2 -- ) print as x(y) +ifnot: .cogch +: .cogch <# 29 #C # 28 #C drop # #> .cstr ; + +\ j ( -- n1 ) the second most current loop counter +ifnot: j +: j _rsptr COG@ 5 + COG@ ; + +\ cog? ( -- ) +ifnot: cog? +: cog? + 8 0 do ." Cog:" i dup . ." #io chan:" + dup cognchan . cogstate C@ + dup 4 and if version W@ .cstr then + dup 10 and if i cognumpad version W@ C@ over C@ - + spaces .cstr then + 14 and if i cogio i cognchan 0 do + i 4* over + 2+ W@ dup 0= if drop else + space space j i .cogch ." ->" io>cogchan .cogch + then + loop +drop then cr loop ; + +\ jede erweiterung legt ein wort als startmarke +\ nmit folgendem namen an: +\ mod:xxx - softwaremodule +\ drv:xxx - treiber +\ lib:xxx - bibliotheken +\ so kann mit den folgenden kommandos eine schnelle liste der +\ vorhandenen erweiterungen abgerufen und mit forget +\ aus dem system entfernt werden + +\ mod? ( -- ) - anzeige der module +ifnot: mod? +: mod? c" mod:" _words ; + +\ lib? ( -- ) - anzeige der bibliotheken +ifnot: lib? +: lib? c" lib:" _words ; + diff --git a/forth/tpix.f b/forth/tpix.f new file mode 100644 index 0000000..6f56866 --- /dev/null +++ b/forth/tpix.f @@ -0,0 +1,48 @@ +\ requires bel.lib +\ requires g0.lib +\ requires ari.lib + +hex + +: it ; \ fuer forget + +variable colortab 40 4* 4 - allot +variable tiletab g0:xtiles g0:ytiles * 2* 4 - allot + +: fillcolortab + colortab + 40 0 do + i dup + 4 + 0F and 00001010 * 0D060D02 + + over L! 4+ + loop drop +; + +: filltilescreen + tiletab g0:disp_base 6 rshift + g0:ytiles 0 do + g0:xtiles 0 do + swap 2dup W! 2+ swap g0:ytiles + + loop 341 + + loop 2drop ; + +decimal + +: setscreen + fillcolortab filltilescreen + tiletab colortab g0:setscreen +; + +: tpix + g0:load setscreen g0:static + g0:clear 14 g0:width 1 g0:color + g0:xtiles 0 do i 16 * 8 + + g0:ytiles 0 do i 16 * 8 + over g0:plot loop drop + loop + key g0:clear + 2000 0 do + rnd 31 and g0:width rnd 3 and g0:color + rnd rnd g0:plot + loop + key g0:reboot + cr ." erledigt" cr +; diff --git a/forth/v1.mod b/forth/v1.mod new file mode 100644 index 0000000..cd22a89 --- /dev/null +++ b/forth/v1.mod @@ -0,0 +1,325 @@ + +: mod:vortrag ; + +24 constant rows +64 constant cols + +wvariable lcol 7 lcol W! + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; + +ifnot: scr:bs \ ( -- ) - backspace +: scr:bs 08 bel:char ; +ifnot: scr:tab \ ( -- ) - tabulator +: scr:tab 09 bel:char ; +ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang +: scr:pos1 03 bel:char ; +ifnot: scr:setcol \ ( colnr -- ) - farbe whlen 0..15 +: scr:setcol 06 bel:ctrl!b! ; +ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich +: scr:sline 07 bel:ctrl!b! ; +ifnot: scr:setx \ ( x -- ) - cursor position x setzen +: scr:setx 02 bel:ctrl!b! ; +ifnot: scr:sety \ ( y -- ) - cursor position y setzen +: scr:sety 03 bel:ctrl!b! ; +ifnot: scr:curon \ ( -- ) - cursor anschalten +: scr:curon 04 bel:char ; +ifnot: scr:curoff \ ( -- ) - cursor abschalten +: scr:curoff 05 bel:char ; +ifnot: scr:logo \ ( y x -- ) - hive logo +: scr:logo 5 bel:fkt!b!b! ; + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ won +ifnot: won +: won + 0 adm:setsound 3 adm:setsound 2drop ; + +\ woff +ifnot: woff +: woff + 2 adm:setsound 1 adm:setsound 2drop ; + +: lcol@ lcol W@ ; \ ( -- col ) + +: lines \ ( n -- ) + 0 do cr loop ; + +: waitkey + scr:curoff cr key drop scr:bs scr:bs scr:bs scr:curon ; + +: nextpage + scr:curoff scr:pos1 lcol@ spaces ." -->" key drop scr:bs scr:bs scr:bs scr:curon ; + +: .head \ ( -- ) + 4 scr:setcol scr:pos1 lcol@ spaces ; + +: .bullet \ ( -- ) + 0 scr:setcol scr:pos1 lcol@ spaces 0f emit space ; + +: .number \ ( n -- n ) + 0 scr:setcol scr:pos1 lcol@ spaces dup . 1+ + 2e emit space ; + +: .line \ ( -- ) + cr 0 scr:setcol scr:pos1 lcol@ 2+ spaces ; + +: .sub \ ( -- ) + 0 scr:setcol scr:pos1 lcol@ 2+ spaces ; + +wvariable xpos 1 xpos W! +wvariable ypos 1 ypos W! + +: pos! \ ( x y -- ) + ypos W! xpos W! ; + +: pos@ \ ( -- x y ) + xpos W@ ypos W@ ; + +: nextline + ypos W@ 1+ ypos W! ; + +: move \ ( x y -- ) + 1 delms pos@ scr:sety scr:setx ; + + +: btop0 \ ( -- ) + move 9f emit 6 0 do 90 emit loop 9e emit nextline ; + +: bbot0 \ ( -- ) + move 9d emit 6 0 do 90 emit loop 9c emit nextline ; + +: btop1 \ ( -- ) + move 2 spaces 9f emit 6 0 do 90 emit loop 9e emit nextline ; + +: bbot1 \ ( -- ) + move 2 spaces 9d emit 6 0 do 90 emit loop 9c emit nextline ; + +: bmid0 \ ( -- ) + move 91 emit ." COG " 95 emit 90 emit bb emit nextline + move 91 emit ." " 95 emit 90 emit aa emit nextline ; + +: bmid1 \ ( -- ) + move a9 emit 90 emit 94 emit ." COG " 91 emit nextline + move ba emit 90 emit 94 emit ." " 91 emit nextline ; + +: bmid2 \ ( -- ) + move a9 emit 90 emit 94 emit ." SER " + 95 emit 90 emit bb emit ." [TERMINAL]" nextline + move ba emit 90 emit 94 emit ." " 91 emit nextline ; + +: bmid3 \ ( -- ) + move a9 emit 90 emit 94 emit ." VGA " + 95 emit 90 emit bb emit ." [BELLATRIX]" nextline + move ba emit 90 emit 94 emit ." KBD " 91 emit nextline ; + +: bmid4 \ ( -- ) + move 91 emit ." COG " 95 emit 90 emit bb emit + ." Zeichenausgabekanal (emit)" nextline + move 91 emit ." " 95 emit 90 emit aa emit + ." Zeicheneingabekanal (key)" nextline ; + +: cog0 \ ( x y -- ) + 0 scr:setcol pos! btop0 bmid0 bbot0 ; + +: cog1 \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid1 bbot1 ; + +: cog3 \ ( x y -- ) + 0 scr:setcol pos! btop0 bmid4 bbot0 ; + +: cogext \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid2 bbot1 ; + +: cogint \ ( x y -- ) + 0 scr:setcol pos! btop1 bmid3 bbot1 ; + +: drvser + 0 scr:setcol 2dup cog0 swap a + swap cogext ; + +: drvint + 0 scr:setcol 2dup cog0 swap a + swap cogint ; + +: p0 + 0 scr:sline cls 5 lines + 14 1c scr:curoff scr:logo won c" woodz.wav" wav:start drop + key drop scr:curon wav:stop woff ; + +: i1 + 0 scr:sline cls 3 lines + .head ." Implementierungsvarianten" cr waitkey + .bullet ." Forth-Diamond: Master & Slaves = PropForth" waitkey cr + .sub ." Nachteil: Programmierung aller Treiber in Forth" waitkey cr + .bullet ." Forth-Spin: Forth mit SPIN-Interface" waitkey cr + .sub ." Vorteil: Nutzung fertiger Treiber" waitkey + .sub ." Nachteil: hoher Ressourcenverbrauch" waitkey cr + .bullet ." Forth-Funktionskomplexe: " cr cr + .sub ." Master = Forth" cr + .sub ." Slaves = Spin-Funktionsbibliotheken" cr + .sub ." Interface Forth <--> Spin = 8Bit-Bus" cr cr + nextpage ; + +: i2 + 0 scr:sline cls 3 lines + .head ." Implementierungsvarianten" cr cr + .bullet ." Forth-Funktionskomplexe: " cr cr + .sub ." Master = Forth" cr + .sub ." Slaves = Spin-Funktionsbibliotheken" cr + .sub ." Interface Forth <--> Spin = 8Bit-Bus" cr waitkey + .bullet ." Nachteile:" cr cr + .sub ." Spin --> Compiler noch auf Host" cr waitkey + .bullet ." Vorteile:" cr cr + .sub ." Code ist schon vorhanden (TriOS)" waitkey + .sub ." Gegenseitige Befruchtung von Forth & TriOS" waitkey + .sub ." Maximale Ressourcen fr Forth im Master" waitkey + .sub ." Spin-Code kann spter auch durch Forth ersetzt werden" cr + nextpage ; + +: i3 + 0 scr:sline cls 3 lines + .head ." Ablauf der Implementierung" cr waitkey + .bullet ." Ausgangslage: " cr cr + .sub ." Forth mit Terminalzugriff" cr waitkey + .bullet ." Plan:" cr cr + .sub ." 1. Busroutine um auf Slaves zuzugreifen" waitkey + .sub ." 2. Integration VGA/Keyboard/SD-Card" waitkey + .sub ." 3. Autostart" cr cr + nextpage ; + + +: p1 + 0 scr:sline cls 1 lines + .head ." Buszugriff" cr cr + .bullet ." ! ( n adr -- ) store - Wert im RAM speichern" cr + .bullet ." @ ( adr -- n ) fetch - Wert aus RAM lesen" cr waitkey + .bullet ." c! c@ p! p@ - Abwandlungen der Grundform" cr waitkey + .bullet ." s! ( c adr -- ) - Byte an Slave senden" cr + .bullet ." s@ ( adr -- c ) - Byte von Slave empfangen" cr waitkey + .bullet ." b! ( c -- ) - Byte an Bellatrix senden" cr + .bullet ." b@ ( -- c ) - Byte von Bellatrix empfangen" cr + .bullet ." a! ( c -- ) - Byte an Administra senden" cr + .bullet ." a@ ( -- c ) - Byte von Administra empfangen" cr cr + .head ." Beispiele :" cr cr + .bullet ." 01 b! - Bildschirm lschen" waitkey + .bullet ." : cls 01 b! ; " waitkey + .bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr + nextpage ; + +: p2 + 0 scr:sline cls 5 lines + .head ." IO-Kanle/Pipes" cr waitkey + 9 8 cog3 key drop + 9 c cog3 + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p3 + 0 scr:sline cls 5 lines + .head ." Serieller Treiber" cr cr + 9 8 drvser + 9 c cog3 + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p4 + 0 scr:sline cls 5 lines + .head ." VGA/Keyboard-Treiber" cr cr + 9 8 drvser + 9 c drvint + .line ." ..." + 9 11 cog3 + cr cr + nextpage ; + +: p5 + 0 scr:sline cls 5 lines + .head ." Treiber: VGA" cr cr + 9 8 drvint cr + .line ." : drv-vga " + .line ." begin" + .line ." key?" + .line ." if key b! then" + .line ." 0 until ;" + cr cr + nextpage ; + +: p6 + 0 scr:sline cls 5 lines + .head ." Treiber: Keyboard" cr cr + 9 8 drvint cr + .line ." : drv-key" + .line ." begin" + .line ." bel:keystat" + .line ." if bel:key emit then" + .line ." 0 until ;" + cr cr + nextpage ; + +: p7 + 0 scr:sline cls 5 lines + .head ." Treiber: Gesamt" cr cr + 9 8 drvint cr + .line ." : drv:int" + .line ." begin" + .line ." \ input --> vga/video" + .line ." 200 0 do key?" + .line ." if key b[ [b!] ]b then loop" + .line ." \ output <-- keyboard" + .line ." b[ [key?]" + .line ." if [key] [emit] then ]b" + .line ." 0 until ;" + cr cr + nextpage ; + +: p8 + 0 scr:sline cls 5 lines + .head ." Semaphoren" cr waitkey + .bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr waitkey + .bullet ." : bel:key bon 0 b! 2 b! b@ boff ;" cr waitkey + .bullet ." [ ... ]" cr waitkey + .bullet ." b[ ... ]b" cr waitkey + .bullet ." : bel:key b[ 0 b! 2 b! b@ ]b ;" cr waitkey + .bullet ." : bel:key b[ 0 [b!] 2 [b!] [b@] ]b ;" cr waitkey + .bullet ." : bel:key 2 0 b[ [b!] [b!] [b@] ]b ;" cr cr + cr cr + nextpage ; + +: run + begin p0 i1 i2 i3 p1 p2 p3 p4 p5 p6 p7 p8 0 until ; + diff --git a/forth/wav.lib b/forth/wav.lib new file mode 100644 index 0000000..97234bb --- /dev/null +++ b/forth/wav.lib @@ -0,0 +1,54 @@ + +hex + +ifnot: lib:wav +: lib:wav ; + +\ kommandoformen + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!l@l@ \ ( fkt -- l l ) +: adm:fkt!l@l@ b[ [a!] [a.l@] [a.l@] ]b ; + +\ wave-funktionen + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ wav:status ( -- status ) +ifnot: wav:status +: wav:status + 98 adm:fkt!b@ ; + +\ wav:leftvol ( vol -- ) +ifnot: wav:leftvol +: wav:leftvol + 99 adm:fkt!b! ; + +\ wav:rightvol ( vol -- ) +ifnot: wav:rightvol +: wav:rightvol + 9A adm:fkt!b! ; + +\ wav:pause ( -- ) +ifnot: wav:pause +: wav:pause + 9B adm:fkt!b@ drop ; + +\ wav:position ( -- len pos ) +ifnot: wav:position +: wav:position + 9C adm:fkt!l@l@ ; + diff --git a/forth/win.lib b/forth/win.lib new file mode 100644 index 0000000..6650be5 --- /dev/null +++ b/forth/win.lib @@ -0,0 +1,49 @@ + +hex + +ifnot: lib:win +: lib:win ; + +\ kommandoformate + +ifnot: bel:char \ ( b -- ) +: bel:char b[ [b!] ]b ; +ifnot: bel:fkt! \ ( fkt -- ) +: bel:fkt! b[ 0 [b!] [b!] ]b ; +ifnot: bel:fkt!b! \ ( b fkt -- ) +: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!b@ \ ( fkt -- b ) +: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ; +ifnot: bel:fkt!b!b! \ ( b b fkt -- ) +: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ; +ifnot: bel:fkt!5b! \ ( b b b b b fkt -- ) +: bel:fkt!5b! b[ 0 [b!] [b!] [b!] [b!] [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl! \ ( ctrl -- ) +: bel:ctrl! b[ 0 [b!] 3 [b!] [b!] ]b ; +ifnot: bel:ctrl!b! \ ( b ctrl -- ) +: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ; +ifnot: bel:ctrl!b@ \ ( ctrl -- b@ ) +: bel:ctrl!b@ b[ 0 [b!] 3 [b!] [b!] [b@] ]b ; +ifnot: bel:ctrl!b!b! \ ( b b ctrl -- ) +: bel:ctrl!b!b! b[ 0 [b!] 3 [b!] [b!] [b!] [b!] [b!] ]b ; + + +\ fensterfunktionen + +ifnot: win:define \ ( yn xn y0 x0 w ) - fenster definieren +: win:define + 50 bel:fkt!5b! ; + +ifnot: win:set \ ( w -- ) - fenster auswhlen +: win:set 52 bel:fkt!b! ; + +ifnot: win:getcols \ ( -- cols ) - anzahl spalten im fenster abfragen +: win:getcols 54 bel:fkt!b@ ; + +ifnot: win:getrows \ ( -- rows ) - anzahl zeilen im fenster abfragen +: win:getrows 55 bel:fkt!b@ ; + +ifnot: win:oframe \ ( -- ) - rahmen um fenster zeichnen +: win:oframe 56 bel:fkt! ; + + diff --git a/forth/words.mod b/forth/words.mod new file mode 100644 index 0000000..92e2175 --- /dev/null +++ b/forth/words.mod @@ -0,0 +1,16 @@ + +fl + +\ _words ( cstr -- ) prints the words in the forth dictionary starting with cstr, 0 prints all +: _words lastnfa +begin + 2dup swap dup if npfx else 2drop -1 then + if dup .strname space then + nfa>next dup 0= +until 2drop cr ; + +\ words ( -- ) prints the words in the forth dictionary, if the pad has another string following, with that prefix +: words parsenw _xwords ; + +: t1 1000 0 do i . loop ; +: t2 1000 0 do ." test " loop ; diff --git a/forth/wplay.mod b/forth/wplay.mod new file mode 100644 index 0000000..fccf4b8 --- /dev/null +++ b/forth/wplay.mod @@ -0,0 +1,93 @@ + +hex + +ifnot: mod:wplay +: mod:wplay ; + +\ kommandoformate + +ifnot: adm:fkt!s!b@ \ ( s fkt -- b ) +: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ; + +ifnot: adm:fkt!b!b@ \ ( b fkt -- b ) +: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ; + +ifnot: adm:fkt!b@ \ ( fkt -- b ) +: adm:fkt!b@ b[ [a!] [a@] ]b ; + +\ wave-funktionen + +\ wav:start ( cstr -- err ) +ifnot: wav:start +: wav:start + 96 adm:fkt!s!b@ ; + +\ wav:stop ( -- ) +ifnot: wav:stop +: wav:stop + 97 adm:fkt!b@ drop ; + +\ wav:status ( -- status ) +ifnot: wav:status +: wav:status + 98 adm:fkt!b@ ; + +\ adm-funktionen + +\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten +\ sfkt: +\ 0: hss-engine abschalten +\ 1: hss-engine anschalten +\ 2: dac-engine abschalten +\ 3: dac-engine anschalten +\ sstat - status/cognr startvorgang +ifnot: adm:setsound +: adm:setsound + 5C adm:fkt!b!b@ ; + + +\ metafunktionen + +\ won +ifnot: won +: won + 0 adm:setsound 3 adm:setsound 2drop ; + +\ woff +ifnot: woff +: woff + 2 adm:setsound 1 adm:setsound 2drop ; + +\ wend? ( -- t/f ) +ifnot: wend? +: wend? + begin 50 delms key? dup if key drop then wav:status 0= or until ; + +\ (wplay) ( cstr -- ) +ifnot: (wplay) +: (wplay) \ ( cstr -- ) + ." Datei : " dup .cstr cr wav:start .err wend? wav:stop ; + +\ wplay name ( -- ) +ifnot: wplay +: wplay + won parsenw (wplay) woff ; + +\ files? ( -- cnt ) - anzahl dateien im dir +ifnot: files? +: files? + adm:diropen + 0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ; + +\ filenr? ( nr -- ) +ifnot: filenr? +: filenr? + adm:diropen + 0 do adm:nextfile drop loop ; + +\ wdirplay ( -- ) - gesamtes verzeichnis abspielen +\ im verzeichnis drfen nur wav-dateien sein! +ifnot: wdirplay +: wdirplay + won files? dup ." Dateien : " . cr + 0 do i dup 1 + . 3 + filenr? pad (wplay) loop padbl woff ; diff --git a/installation.txt b/installation.txt new file mode 100644 index 0000000..d88d821 --- /dev/null +++ b/installation.txt @@ -0,0 +1,275 @@ + +1. Installation des Grundsystems +2. Regime im Überblick +3. Forth im Überblick + + + + +1. Installation des Grundsystems: +================================= + +TriOS kann in zwei Versionen installiert werden: Mit oder ohne Forth als integrierte Programmiersprache. Als Standard wird das System ohne Forth installiert. Die Installation ist so für den Einsteiger einfacher. Möchte man auch PropForth installieren, muß nur eine Konfiguration geändert werden und ein Basiswortschatz im Forth selbst kompiliert werden. + +WICHTIG: Das System kann nur mit Brat's Spin Tool - kurz BST - compiliert werden. In den Einstellungen des Compilers (Tools/Compiler Preferences/Search Paths) muss das lib-Verzeichnis eingetragen werden. + +Downloadlink BST: http://www.fnarfbargle.com/bst.html + + + +Installation ohne Forth (Standard): +----------------------------------- + +1. Mikrocontroller flashen: + +\flash\administra\admflash.spin --> Administra +\flash\bellatrix\belflash.spin --> Bellatrix +\flash\regnatix\regflash.spin --> Regnatix + + +Installation mit Forth: +----------------------- + +1. Mikrocontroller flashen: + +\flash\administra\admflash.spin --> Administra +\flash\bellatrix\belflash.spin --> Bellatrix +\flash\regnatix\regflash.spin --> Regnatix + +2. Der Schalter bleibt ab jetzt auf Regnatix stehen. Ein Terminalprogramm (ich verwende Tera Term) starten und 57600 Baud auf die Schnittstelle vom Hive (DIP steht auf Regnatix!) einstellen. Nach einem Reset meldet sich das Propforth im Terminalprogramm auf dem Hostcomputer. Datei "forth\basics.mod" in einem Editor öffnen, alles markieren, kopieren und im Terminal einfügen. Der Quelltext wird jetzt im Forth compiliert. + +3. Im Terminalfenster, also im Forth, dass Kommendo "saveforth" eingeben. Damit wird das gesamte Forthsystem mit der gerade neu compilierten Erweiterungen wieder im EEPROM als Image gespeichert. + +Nach einem Reset sollte sich das Forth jetzt komplett mit seinem Prompt sowohl auf dem angeschlossenen VGA-Monitor, als auch im Terminal melden. Im Prinzip benötigen wir nun das Terminalprogramm nicht mehr und können direkt am Hive arbeiten. Später, wenn man in Forth programmiert, ist die vorhandene Terminalschnittstelle aber manchmal sehr nützlich. + + + +Erstellen der SDCard: +--------------------- + +Im Prinzip kann jede normale FAT16/32 Karte verwendet werden. Lange Dateinamen werden nicht verwendet, Unterverzeichnisse sind kein Problem. Es ist sinnvoll, alle Dateien aus dem Verzeichnis "bin\sd-card\" auf die SD-Karte zu kopieren. + +Das Verzeichnis "system" hat eine besondere Bedeutung: Hier sollten sich die Tools, Erweiterungen und Bibliotheken befinden. Im PropForth: Mit dem Kommando "sys name.f" kann aus jedem anderen Verzeichnis ohne Wechsel eine Datei name.f im Verzeichnis System geladen und compiliert werden. + + + +Systemstart: +------------ + +Beim Systemstart wird immer das Forth aus dem EEPROM gestartet. So kann, wie mit den klassischen Homecomputern, sofort unkompliziert programmiert werden. Neben dem Forth gibt es im TriOS noch ein in Spin programmiertes Betriebssystem, welches sich dem Benutzer durch den Kommandointerpreter Regime präsentiert. Aus dem Forth kann diese mit dem Kommando "regime" gestartet werden. Im Gegenzug kann im laufenden Regime mit dem Kommando "forth" wieder zur integrierten Programmiersprache gewechselt werden. + +Wurde TriOS ohne Forth installiert, wird der Loader aus dem EEPROM gestartet und sofort die Kommandozeile "Regime" aus der Datei reg.sys gestartet. + + + + +3. Regime im Überblick +====================== + +Da wir ja drei verschiedene Teilsystem in unserem Computer haben, muss Regime wissen, für welchen Chip eine ausführbare Datei bestimmt ist. Den Typ ausführbarer Dateien kann Regime automatisch anhand der Dateinamenserweiterung unterscheiden: + +*.bin Regnatix-Code +*.bel Bellatrix-Code +*.adm Administra-Code + +Dabei genügt es, den Namen ohne Erweiterung einzugeben. Dennoch kann es vorkommen, das man eine normale Spin-Datei mit einer beliebigen Erweiterung gespeichert hat. Diese Datei kann man dann mit den Kommandos rload, aload oder bload ganz gezielt in einen Chip laden. + + - bin/adm/bel-datei wird gestartet +mount - SD-aufwerk mounten +unmount - SD-Laufwerk freigeben +dir wh - Verzeichnis anzeigen +type - Anzeige einer Textdatei +aload - Administra-Code laden +bload - Bellatrix-Code laden +rload - Regnatix-Code laden +del - Datei löschen +cls - Bildschirm löschen +free - Anzeige des freien Speichers auf SD-Card +attrib ashr - Dateiattribute ändern +cd - Verzeichnis wechseln +mkdir - Verzeichnis erstellen +rename - datei/verzeichnis umbenennen +format - SD-Laufwerk formatieren +reboot - Hive neu starten +sysinfo - Systeminformationen +color <0..7> - Farbe wählen +cogs - Belegung der COG's anzeigen +dmlist - Anzeige der Verzeichnis-Marker +dm - Marker-Verzeichnis wechseln +dmset - Marker setzen +dmclr - Marker löschen +forth - Forth starten + +Marker: +r - Marker für Root-Verzeichnis +s - Marker für System-Verzeichnis +u - Marker für User-Verzeichnis +a/b/c - Benutzerdefinierte Verzeichnismarker + +Die r, s, u-Marker werden vom System automatisch gesetzt und intern verwendet. + +RAMDISK: + +xload - Datei von SD-Laufwerk in RAM laden +xsave - Datei aus RAM auf SD-Laufwerk speichern +xdir - Verzeichnis im RAM anzeigen +xrename - Datei im RAM umbenennen +xdel - Datei im RAM löschen +xtype - Textdatei im RAM anzeigen + + + +EXTERNE KOMMANDOS: +------------------ + +Die meisten Kommandozeilentools zeigen mit dem Parameter /? eine Liste der Optionen an. + +sysconf - Systemeinstellungen +hplay - HSS-Player +wplay - WAV-Player +splay - SID-Player +yplay - Yamaha-Soundchip-Player +sfxtool - HSS-Soundeffekte erstellen + +vga.bin - VGA 1024 x 768 Pixel, 64 x 24 Zeichen +htext.bin - VGA 1024 x 768 Pixel, 128 x 48 Zeichen +tv.bin - TV-Textmodus 40 x 13 Zeichen + + + + +2. Forth im Überblick: +====================== + +Einige nützliche Kommandos befinden sich in dem Modul tools.mod. In den meisten Fällen ist es sinnvoll dieses Modul mit der Befehlssequenz "sys tools.mod saveforth" fest im Forth einzubinden. + + + +Wichtige Tastencodes: +--------------------- + +[ESC]-1 Screen 1, COG 1 +[ESC]-2 Screen 2, COG 2 +[ESC]-3 Screen 3, COG 3 +[ESC]-b Break, Reset der aktuellen COG +[ESC]-r Reset, Neustart Regnatix + + + +Wichtige Kommandos: +------------------- + +load - Datei laden und comilieren, Ausgabe Screen 3 +dload - wie load, aber Ausgabe aktueller Screen +sys - Datei aus sys-Verzeichnis laden und compilieren +ls - Dateiliste +lsl - Dateiliste- Long-Format +cd - in Verzeichniss wechseln +mount - SD-Card einbinden +unmount - SD-Card freigeben +words - Anzeige Wöterbuch +mod? - (tools.mod) Anzeige compilierter Erweiterungen +lib? - (tools.mod) Anzeige compilierter Bibliotheken +cog? - (tools.mod) Anzeige COG-Liste +cat - (tools.mod) Ausgabe einer Textdatei +less - (tools.mod) Zeilenweise Textausgabe +dm? - (tools.mod) Anzeige der Systemverzeichnisse +regime - CLI starten +aload - Adminsitra-Code laden +bload - Bellatrix-Code laden +spin - Spin-Programm starten + + + +Wichtige Dateien: +----------------- + +Die Dateien *.mod und *.lib enthalten ganz normale Forth-Quelltexte. Damit hat man schnell eine Übersicht über die grobe Funktion dieser Quellen: Lib's sind halt reine Sammlungen von Worten zu einer bestimmten Funktionsgruppe und MOD's sind mehr oder weniger fertige und abgeschlossene Programme. Ein Beispiel: + +Die Datei hss.lib enthält Worte um die HSS-Funktionen von Administra anzusprechen. Mit diesen Funktionen kann man nun ein Modul (Programm) wie einen HSS-Soundplayer schreiben. + +Im Gegensatz dazu die Datei splay.mod: Mit diesem Modul wird ein HSS-Soundplayer ins System eingefügt, welcher Funktionen aus der hss.lib verwendet. + +Die Datei benötigt man aber mehr oder weniger nur zur Entwicklung, ein fertiges Modul wie splay.mod enthält dann schon die die entsprechenden HSS-Worte die benötigt werden. + +Die ifnot: ... Anweisung sorgt dabei dafür, dass keine Funktionen doppelt in das Wörterbuch compiliert werden. Das ist quasi ein verteiltes und fein granuliertes Konzept analog zu einer DLL. Die Forth-Version funktioniert dabei aber im Gegensatz zu DLL's nicht auf Bibliotheks-, sondern auf Funktionsebene. + +*.mod Module, Forth-Erweiterungen für das System +*.lib Bibliotheken, grundlegende Wortsammlungen +*.adm Administra-Code (z.Bsp. admsid.adm für SIDCog-Code) +*.bel Bellatrix-Code +*.bin Spin-Code, im Normalfall zur Ausführung in Regnatix + +basics.f - (mod:basics) Hive-Core für PropForth +ari.lib - (lib:ari) Zusätzliche arithmetische Funktionen +cog.lib - (lib:cog) Zusätzliche COG-Funktionen +adm.lib - (lib:adm) Administra-Chipmanagment-Funktionen +hss.lib - (lib:hss) Bibliothek für Hydra-Sound-System +sfx.lib - (lib:sfx) Soundeffekt-Bibliothek +wav.lib - (lib:wav) Wave-Soundbibliothek + +bel.lib - (lib:bel) Bellatrix-Chipmanagment-Funktionen +key.lib - (lib:key) Tastatur-Bibliothek +scr.lib - (lib:scr) Screen-Bibliothek +sd0.lib - (lib:sd0) SD-Card-Bibliothek + +debug.f - Nützliche Worte zur Fehlersuche und Entwicklung +rom.f - EEPROM-Dateisystem +tools.f - Nützliche Tools (cat, less, dm?...) +hplay.f - HSS-Player +wplay.f - WAV-Player +splay.f - SID-Player + +Administra-Codedateien im SYS-Verzeichnis: + +admled.adm Testprogramm - HBeat-LED blinken lassen +admsid.adm SidCog-Version (wird von splay benötigt) +admsys.adm Standardcode für ADM mit SD/HSS/WAV +admym.adm Yamaha-Soundchip-Version +aterm96.adm Mini-OS für Administra (Testzwecke) + + + +Reset-Fehlercodes: +------------------ + +0011FFFF - stack overflow +0012FFFF - return stack overflow +0021FFFF - stack underflow +0022FFFF - return stack underflow +8100FFFF - no free cogs +8200FFFF - no free main memory +8400FFFF - fl no free main memory +8500FFFF - no free cog memory +8800FFFF - eeprom write error +9000FFFF - eeprom read error + + + +.err-Fehlercodes: +----------------- + +0 no error +1 fsys unmounted +2 fsys corrupted +3 fsys unsupported +4 not found +5 file not found +6 dir not found +7 file read only +8 end of file +9 end of directory +10 end of root +11 dir is full +12 dir is not empty +13 checksum error +14 reboot error +15 bpb corrupt +16 fsi corrupt +17 dir already exist +18 file already exist +19 out of disk free space +20 disk io error +21 command not found +22 timeout +23 parameter error diff --git a/lib/adm-ay.spin b/lib/adm-ay.spin new file mode 100644 index 0000000..a1218db --- /dev/null +++ b/lib/adm-ay.spin @@ -0,0 +1,327 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ AYcog - AY-3-891X / YM2149 emulator V0.22 (C) 2010-05 Johannes Ahlebrand │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ TERMS OF USE: Parallax Object Exchange License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} +CON + + PSG_FREQ = 2_000_000.0 ' Clock frequency input to the chip (Colour Genie EG2000 computer runs at 2.2Mhz) + + ' WARNING !! + ' Don't alter the constants below unless you know what you are doing + '------------------------------------------------------------------- + SAMPLE_RATE = 125_000 ' Sample rate of AYcog + OSC_CORR = trunc(1.05 * PSG_FREQ) ' Calibrates the relative oscillator frequency + NOISE_CORR = OSC_CORR>>1 ' Calibrates the relative noise frequency + ENV_CORR = OSC_CORR>>6 ' Calibrates the relative envelope timing +' +' Reg bits function +' ----------------------------------- +' 00 7..0 channel A fine tune +' 01 3..0 channel A coarse tune +' 02 7..0 channel B fine tune +' 03 3..0 channel B coarse tune +' 04 7..0 channel C fine tune +' 05 3..0 channel C coarse tune +' 06 4..0 noise period +' 07 7..0 enable register +' 08 4..0 channel A volume +' 09 4..0 channel B volume +' 10 4..0 channel C volume +' 11 7..0 envelope fine tune +' 12 7..0 envelope coarse tune +' 13 3..0 envelope shape +' 14 7..0 I/O port A value +' 15 7..0 I/O port B value + +VAR + long cog + +PUB start(right,left,AYregisters) + if (AYregisters & 1) <> 0 ' we need word aligned registers + abort(-1) + arg1 := $18000000 | left + arg2 := $18000000 | right + r1 := ((1< envelopeAmplitude +'─────────────────────────────────────────────────────────── +Envelope sub envCounter, envSubValue wc ' Handles envelope incrementing + if_c add envCounter, envelopePeriod + if_c add envelopeValue, envelopeInc +'─────────────────────────────────────────────────────────── + test envelopeShape, #16 wz ' Handle envelope reset bit ( Extra bit added by Ahle2 ) + if_z neg envelopeValue, #0 + if_z mov envelopeInc, #1 + if_z mov envCounter, envelopePeriod + if_z or envelopeShape, #16 + if_z wrbyte envelopeShape, tempValue '<-IMPORTANT, sets bit 5 in hub ram +'─────────────────────────────────────────────────────────── + test envelopeShape, #8 wc ' Handle continue = 0 + test envelopeShape, #4 wz + if_nc_and_z mov envelopeShape, #9 + if_nc_and_nz mov envelopeShape, #15 +'─────────────────────────────────────────────────────────── + test envelopeShape, #2 wz ' Sets the envelope hold level + muxz envHoldLevel, #15 ' +'─────────────────────────────────────────────────────────── + test envelopeValue, #16 wz ' Check if > 15 + test envelopeShape, #1 wc ' Check hold bit + if_nz_and_c mov envelopeInc, #0 ' Hold envelope + if_nz_and_c mov envelopeValue, envHoldLevel ' +'─────────────────────────────────────────────────────────── + if_nz test envelopeShape, #2 wc ' Check and handle alternation + if_nz_and_c neg envelopeInc, envelopeInc + if_nz_and_c add envelopeValue, envelopeInc +'─────────────────────────────────────────────────────────── + mov envelopeAmplitude, envelopeValue + test envelopeShape, #4 wc ' Check and handle invertion (attack) + if_nc xor envelopeAmplitude, #15 '(Move Value or ~Value to envelopeAmplitude) + +'─────────────────────────────────────────────────────────── +' Waveform shaping noise -> bit 3 of oscValues +'─────────────────────────────────────────────────────────── +Noise1 sub phaseAccumulatorN, noiseSubValue wc ' Noise generator + if_c add phaseAccumulatorN, noisePeriod + if_c add noiseValue, noiseAdd + if_c ror noiseValue, #15 wc + if_c xor oscValues, #8 + +'─────────────────────────────────────────────────────────── +' Waveform shaping channel 1 -> out1 +'─────────────────────────────────────────────────────────── +Env1 test amplitude1, #16 wz ' Selects envelope or fixed amplitude + if_nz mov amplitude1, envelopeAmplitude ' depending on bit 5 of amplitude register 1 + mov arg1, amplitude1 + call #getAmplitude +'─────────────────────────────────────────────────────────── +Square1 cmp frequency1, freqRef wc + if_nc sub phaseAccumulator1, oscSubValue wc ' Square wave generator + if_c add phaseAccumulator1, frequency1 ' channel 1 + if_c xor oscValues, #1 +'─────────────────────────────────────────────────────────── + test oscValues, mask513 wz ' Handles mixing of channel 1 + negnz out1, r1 ' Tone on/off, Noice on/off + test oscValues, mask4104 wz + if_z mov out1, r1 ' arg2 = (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable) + +'─────────────────────────────────────────────────────────── +' Waveform shaping channel 2 -> out2 +'─────────────────────────────────────────────────────────── +Env2 test amplitude2, #16 wz ' Selects envelope or fixed amplitude + if_nz mov amplitude2, envelopeAmplitude ' depending on bit 5 of amplitude register 2 + mov arg1, amplitude2 + call #getAmplitude +'─────────────────────────────────────────────────────────── +Square2 cmp frequency2, freqRef wc + if_nc sub phaseAccumulator2, oscSubValue wc ' Square wave generator + if_c add phaseAccumulator2, frequency2 ' channel 2 + if_c xor oscValues, #2 +'─────────────────────────────────────────────────────────── + test oscValues, mask1026 wz ' Handles mixing of channel 2 + negz out2, r1 ' Tone on/off, Noice on/off + test oscValues, mask8200 wz + if_z mov out2, r1 ' arg2 = (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable) + +'─────────────────────────────────────────────────────────── +' Waveform shaping channel 3 -> out3 +'─────────────────────────────────────────────────────────── +Env3 test amplitude3, #16 wz ' Selects envelope or fixed amplitude + if_nz mov amplitude3, envelopeAmplitude ' depending on bit 5 of amplitude register 3 + mov arg1, amplitude3 + call #getAmplitude +'─────────────────────────────────────────────────────────── +Square3 cmp frequency3, freqRef wc + if_nc sub phaseAccumulator3, oscSubValue wc ' Square wave generator + if_c add phaseAccumulator3, frequency3 ' channel 3 + if_c xor oscValues, #4 +'─────────────────────────────────────────────────────────── + test oscValues, mask2052 wz ' Handles mixing of channel 2 + negz out3, r1 ' Tone on/off, Noice on/off + test oscValues, mask16392 wz + if_z mov out3, r1 ' arg2 = (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable) +AY_ret ret + +' +' Mix channels and update FRQA/FRQB PWM-values +' +mixer mov r1, val31bit ' DC offset + add r1, out1 + add r1, out2 + add r1, out3 + waitcnt waitCounter, sampleRate ' Wait until the right time to update + mov FRQA, r1 '| Update PWM values in FRQA/FRQB + mov FRQB, r1 '| +mixer_ret ret + +' +' Get amplitude table r1 = amplitudTable[arg1] +' +getAmplitude and arg1, #15 + add arg1, #amplitudeTable ' Lookup the amplitude according + movs :indexed1, arg1 ' to the current state of the envelope + nop +:indexed1 mov r1, 0 +getAmplitude_ret ret + + +' +' Variables, tables, masks and reference values +' +amplitudeTable long 1634706 + long 2452059 + long 3678089 + long 5517133 + long 8275700 + long 12413550 + long 18620325 + long 27930488 + long 41895733 + long 62843600 + long 94265400 + long 141398100 + long 212097150 + long 318145725 + long 477218588 + long 715827882 + +'Masks and reference values +mask513 long 513 +mask1026 long 1026 +mask2052 long 2052 +mask4104 long 4104 +mask8200 long 8200 +mask16392 long 16392 + +mask32bit long $ffffffff +mask16bit long $ffff +half_period long $00008000 +val31bit long $80000000 +noiseAdd long $88008800 'Value to add to the noise generator every noise update +sampleRate long 0 +freqRef long 10<<20 + +'Setup and subroutine parameters +arg1 long 0 +arg2 long 0 +r1 long 0 +AY_Address long 0 + +'AY variables +envCounter long 1 +envSubValue long ENV_CORR +oscSubValue long OSC_CORR +noiseSubValue long NOISE_CORR +envelopeValue long 0 +envelopeInc long 1 +envHoldLevel res 1 +oscValues res 1 +amplitude1 res 1 +amplitude2 res 1 +amplitude3 res 1 +envelopeAmplitude res 1 +enableRegister res 1 +envelopeShape res 1 +frequency1 res 1 +frequency2 res 1 +frequency3 res 1 +envelopePeriod res 1 +noisePeriod res 1 +phaseAccumulatorN res 1 +phaseAccumulator1 res 1 +phaseAccumulator2 res 1 +phaseAccumulator3 res 1 +noiseValue res 1 +noiseOut res 1 +out1 res 1 +out2 res 1 +out3 res 1 +waitCounter res 1 +tempValue res 1 +temp1 res 1 + fit diff --git a/lib/adm-com.spin b/lib/adm-com.spin new file mode 100644 index 0000000..3a6fd2f --- /dev/null +++ b/lib/adm-com.spin @@ -0,0 +1,334 @@ +'' Singleton version of: +'' +''******************************************** +''* Full-Duplex Serial Driver v1.2 * +''* Author: Chip Gracey, Jeff Martin * +''* Copyright (c) 2006-2009 Parallax, Inc. * +''* See end of file for terms of use. * +''******************************************** + +{-----------------REVISION HISTORY----------------- + v1.2 - 5/7/2009 fixed bug in dec method causing largest negative value (-2,147,483,648) to be output as -0. + v1.1 - 3/1/2006 first official release. +} +CON EOL = $a +CON CR = $d + +VAR + + long cog 'cog flag/id + +DAT + + rx_head long 0 '9 contiguous longs + rx_tail long 0 + tx_head long 0 + tx_tail long 0 + rx_pin long 0 + tx_pin long 0 + rxtx_mode long 0 + bit_ticks long 0 + buffer_ptr long 0 + + rx_buffer byte 0 [16] 'transmit and receive buffers + tx_buffer byte 0 [16] + + +PUB start(rxpin, txpin, mode, baudrate) : okay + +'' Start serial driver - starts a cog +'' returns false if no cog available +'' +'' mode bit 0 = invert rx +'' mode bit 1 = invert tx +'' mode bit 2 = open-drain/source tx +'' mode bit 3 = ignore tx echo on rx + + stop + longfill(@rx_head, 0, 4) + longmove(@rx_pin, @rxpin, 3) + bit_ticks := clkfreq / baudrate + buffer_ptr := @rx_buffer + okay := cog := cognew(@entry, @rx_head) + 1 + + +PUB stop + +'' Stop serial driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@rx_head, 0, 9) + + +PUB rxflush + +'' Flush receive buffer + + repeat while rxcheck => 0 + +PUB rxready + return rx_tail <> rx_head + +PUB rxcheck : rxbyte + +'' Check if byte received (never waits) +'' returns -1 if no byte received, $00..$FF if byte + + rxbyte-- + if rx_tail <> rx_head + rxbyte := rx_buffer[rx_tail] + rx_tail := (rx_tail + 1) & $F + + +PUB rxtime(ms) : rxbyte | t + +'' Wait ms milliseconds for a byte to be received +'' returns -1 if no byte received, $00..$FF if byte + + t := cnt + repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms + + +PUB rx : rxbyte + +'' Receive byte (may wait for byte) +'' returns $00..$FF + + repeat while (rxbyte := rxcheck) < 0 + +PUB out(txbyte) + tx(txbyte) + +PUB tx(txbyte) + + if txbyte == EOL + tx(CR) + +'' Send byte (may wait for room in buffer) + + repeat until (tx_tail <> (tx_head + 1) & $F) + tx_buffer[tx_head] := txbyte + tx_head := (tx_head + 1) & $F + + if rxtx_mode & %1000 + rx + + +PUB str(stringptr) + +'' Send string + + repeat while byte[stringptr] + tx(byte[stringptr++]) + + +PUB dec(value) | i, x + +'' Print a decimal number + + x := value == NEGX 'Check for max negative + if value < 0 + value := ||(value+x) 'If negative, make positive; adjust for max negative + tx("-") 'and output sign + + i := 1_000_000_000 'Initialize divisor + + repeat 10 'Loop for 10 digits + if value => i + tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative + value //= i 'and digit from value + result~~ 'flag non-zero found + elseif result or i == 1 + tx("0") 'If zero digit (or only digit) output it + i /= 10 'Update divisor + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + tx((value <-= 1) & 1 + "0") + + +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org +' +' +' Entry +' +entry mov t1,par 'get structure address + add t1,#4 << 2 'skip past heads and tails + + rdlong t2,t1 'get rx_pin + mov rxmask,#1 + shl rxmask,t2 + + add t1,#4 'get tx_pin + rdlong t2,t1 + mov txmask,#1 + shl txmask,t2 + + add t1,#4 'get rxtx_mode + rdlong rxtxmode,t1 + + add t1,#4 'get bit_ticks + rdlong bitticks,t1 + + add t1,#4 'get buffer_ptr + rdlong rxbuff,t1 + mov txbuff,rxbuff + add txbuff,#16 + + test rxtxmode,#%100 wz 'init tx pin according to mode + test rxtxmode,#%010 wc + if_z_ne_c or outa,txmask + if_z or dira,txmask + + mov txcode,#transmit 'initialize ping-pong multitasking +' +' +' Receive +' +receive jmpret rxcode,txcode 'run a chunk of transmit code, then return + + test rxtxmode,#%001 wz 'wait for start bit on rx pin + test rxmask,ina wc + if_z_eq_c jmp #receive + + mov rxbits,#9 'ready to receive byte + mov rxcnt,bitticks + shr rxcnt,#1 + add rxcnt,cnt + +:bit add rxcnt,bitticks 'ready next bit period + +:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return + + mov t1,rxcnt 'check if bit receive period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + test rxmask,ina wc 'receive bit on rx pin + rcr rxdata,#1 + djnz rxbits,#:bit + + shr rxdata,#32-9 'justify and trim received byte + and rxdata,#$FF + test rxtxmode,#%001 wz 'if rx inverted, invert byte + if_nz xor rxdata,#$FF + + rdlong t2,par 'save received byte and inc head + add t2,rxbuff + wrbyte rxdata,t2 + sub t2,rxbuff + add t2,#1 + and t2,#$0F + wrlong t2,par + + jmp #receive 'byte done, receive next byte +' +' +' Transmit +' +transmit jmpret txcode,rxcode 'run a chunk of receive code, then return + + mov t1,par 'check for head <> tail + add t1,#2 << 2 + rdlong t2,t1 + add t1,#1 << 2 + rdlong t3,t1 + cmp t2,t3 wz + if_z jmp #transmit + + add t3,txbuff 'get byte and inc tail + rdbyte txdata,t3 + sub t3,txbuff + add t3,#1 + and t3,#$0F + wrlong t3,t1 + + or txdata,#$100 'ready byte to transmit + shl txdata,#2 + or txdata,#1 + mov txbits,#11 + mov txcnt,cnt + +:bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode + test rxtxmode,#%010 wc + if_z_and_c xor txdata,#1 + shr txdata,#1 wc + if_z muxc outa,txmask + if_nz muxnc dira,txmask + add txcnt,bitticks 'ready next cnt + +:wait jmpret txcode,rxcode 'run a chunk of receive code, then return + + mov t1,txcnt 'check if bit transmit period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit 'another bit to transmit? + + jmp #transmit 'byte done, transmit next byte +' +' +' Uninitialized data +' +t1 res 1 +t2 res 1 +t3 res 1 + +rxtxmode res 1 +bitticks res 1 + +rxmask res 1 +rxbuff res 1 +rxdata res 1 +rxbits res 1 +rxcnt res 1 +rxcode res 1 + +txmask res 1 +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 +txcode res 1 + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} diff --git a/lib/adm-fat.spin b/lib/adm-fat.spin new file mode 100644 index 0000000..95d5ba7 --- /dev/null +++ b/lib/adm-fat.spin @@ -0,0 +1,2450 @@ +{{ +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ File Allocation Table Engine │ +│ │ +│ Author: Kwabena W. Agyeman │ +│ Updated: 1/18/2009 │ +│ Designed For: P8X32A │ +│ │ +│ Copyright (c) 2009 Kwabena W. Agyeman │ +│ See end of file for terms of use. │ +│ │ +│ Driver Info: │ +│ │ +│ The FATEngine runs a SD/SDHC/MMC driver in the next free cog on the propeller chip when called. │ +│ │ +│ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │ +│ so port B will not be operational. │ +│ │ +│ Nyamekye, │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + +{{ + +ANPASSUNGEN HIVE-PROJECT + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Komponente von Administra-Flash +Chip : Administra +Version : 00 +Subversion : 01 + +Hinweise : + +Alle Änderungen am Originalquelltext sind mit der Marke "@hive" gekennzeichnet. Die unveränderte +Originalquelle wird nur auskommentiert. + +Logbuch : + +25-03-2010-dr235 - änderung der fehlerstrings in fehlernummern für eine bessere auswertung +27-03-2010-dr235 - listVolumeLabel eingefügt +28-03-2010-dr235 - änderung des openFile parameters "modus" von 0-term-string zu 8bit-parameter +12-04-2010-dr235 - getDirCluster & setDirCluster für dir-marker system zugefügt +09-06-2010-dr085 - frida hat den fehler gefunden, welcher eine korrekte funktion der fatengine + nach einem bootvorgang von administra verhinderte :) +14-06-2010-dr085 - löschen der semaphore vor dem bootvorgang +10-07-2010 - provisorische behebung eines fehlers in readData (siehe admsid) +02-02-2012-dr235 - fehler in setCharacterPosition: bei einem wechsel von einer position > 0 + auf position = 0 wurde der erste sektor mit falschen daten überschrieben + +Notizen : + + +}} +CON + '' + Data_Out_Pin = 10 '' ─ Data Out - To SD Card DO Pin. + '' + Clock_Pin = 11 '' ─ Clock - To SD Card CLK Pin. + '' + Data_In_Pin = 12 '' ─ Data In - To SD Card DI Pin. + '' + Chip_Select_Pin = 13 '' ─ Chip Select - To SD Card CS. + +'frida HUB_Lock = 0 ' Hub Lock To use for multiple files open with multiple copies of this object at once. + +' FEHLERNUMMERN '@hive + + err_noError = 0 + err_fsysUnmounted = 1 + err_fsysCorrupted = 2 + err_fsysUnsupported = 3 + err_notFound = 4 + err_fileNotFound = 5 + err_dirNotFound = 6 + err_fileReadOnly = 7 + err_endOfFile = 8 + err_endOfDirectory = 9 + err_endOfRoot = 10 + err_dirIsFull = 11 + err_dirIsNotEmpty = 12 + err_checksumError = 13 + err_rebootError = 14 + err_bpbCorrupt = 15 + err_fsiCorrupt = 16 + err_dirAlreadyExist = 17 + err_fileAlreadyExist = 18 + err_outOfDiskFreeSpace = 19 + err_diskIOError = 20 + + +OBJ + + rtc : "adm-rtc.spin" +' debugx : "pterm" 'debug + +VAR + + byte dataBlock[512] + + word cardTime + word cardDate + + byte cardUniqueIDCopy[17] + byte partitionMountedFlag + + byte fileOpenFlag + byte fileReadWriteFlag + + long partitionStart + long partitionSize + + byte sectorsPerCluster + byte numberOfFATs + word reservedSectorCount + + long FATSectorSize + + word rootDirectorySectors + word rootDirectorySectorNumber + + long hiddenSectors + + long firstDataSector + long countOfClusters + + long FATType + long rootCluster + + word fileSystemInfo + word backupBootSector + + long freeClusterCount + long nextFreeCluster + + long volumeIdentification + + word externalFlags + byte mediaType + byte unformatedNameBuffer[13] + byte formatedNameBuffer[12] + + byte directoryEntryName[12] + byte directoryEntry[32] + + long currentDirectory + long currentFile + + long currentCluster + long currentByte + +' long previousDirectory + long currentSize + + long previousCluster + long previousByte + + byte sdvolumeLabel[12] 'frida + +PUB readShort '' 28 Stack Longs + + readData(@result, 2) + +PUB readLong '' 28 Stack Longs + + readData(@result, 4) + +PUB writeShort(value) '' 29 Stack Longs + + writeData(@value, 2) + +PUB writeLong(value) '' 29 Stack Longs + + writeData(@value, 4) + +PUB readData(addressToPut, count) | index '' 25 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Reads data from the file that is currently open for reading and advances the position by that amount of data. │ +'' │ │ +'' │ Will do nothing if a file is not currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ AddressToPut - A pointer to the start of a data buffer to read to from disk. │ +'' │ Count - The amount of data to read from disk. The data buffer must be atleast this large. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + count #>= 0 + +'##################################################################### +' repeat while((count > 0) and readWriteCurrentCluster("R", "F")) + + repeat while (count > 0) ' änderung um 4096-Fehler im dmp-player + if(readWriteCurrentCluster("R", "F")) ' zu beheben + +'##################################################################### + + index := (currentByte & $1FF) + result := (count <# (512 - index)) + + bytemove(addressToPut, @dataBlock[index], result) + + count -= result + currentByte += result + addressToPut += result + currentByte <#= (currentSize - 1) + +PUB writeData(addressToGet, count) | index '' 25 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Writes data to the file that is currently open for writing and advances the position by that amount of data. │ +'' │ │ +'' │ Will do nothing if a file is not currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ This throws an error if the file is open for reading only. │ +'' │ │ +'' │ Max writable file size is 2,147,483,136 bytes. Exceeding this throws an error. │ +'' │ │ +'' │ AddressToGet - A pointer to the start of a data buffer to write to disk. │ +'' │ Count - The amount of data to write to disk. The data buffer must be atleast this large. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + count #>= 0 + repeat while((count > 0) and readWriteCurrentCluster("W", "F")) + + index := (currentByte & $1FF) + result := (count <# (512 - index)) + + bytemove(@dataBlock[index], addressToGet, result) + flushCharacters + + count -= result + currentByte += result + addressToGet += result + currentSize #>= currentByte + +PUB readCharacter '' 22 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Reads a character from the file that is currently open for reading and advances the position by one. │ +'' │ │ +'' │ Will do nothing if a file is not currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ Returns the next character to read from the file. At the end of file returns the last character in the file repeatedly. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(readWriteCurrentCluster("R", "F")) + + result := blockToByte(currentByte++) + currentByte <#= (currentSize - 1) + +PUB writeCharacter(character) '' 23 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Writes a character to the file that is currently open for writing and advances the position by one. │ +'' │ │ +'' │ Will do nothing if a file is not currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ This throws an error if the file is open for reading only. │ +'' │ │ +'' │ Max writable file size is 2,147,483,136 bytes. Exceeding this throws an error. │ +'' │ │ +'' │ Character - A character to write to the file. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(readWriteCurrentCluster("W", "F")) + + byteToBlock(currentByte++, character) + + ifnot($1FF & currentByte--) + flushCharacters + + currentSize #>= ++currentByte + +PUB writeCharacters(characters) '' 27 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Writes a string of characters to the file that is currently open for writing and advances the position by string length. │ +'' │ │ +'' │ Will do nothing if a file is not currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ This throws an error if the file is open for reading only. │ +'' │ │ +'' │ Max writable file size is 2,147,483,136 bytes. Exceeding this throws an error. │ +'' │ │ +'' │ Characters - A pointer to a string of characters to write to the file. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(characters) + writeCharacter(byte[characters++]) + +PUB flushCharacters '' 12 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Writes buffered data to disk. All file writes are buffered and are not written to disk immediantly. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(partitionMountedFlag and fileOpenFlag and fileReadWriteFlag) + readWriteCurrentSector("W") + +PUB getEOF + + result := currentByte => currentSize-1 + +PUB getCharacterPosition '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the current character position within a file for reading and writing. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (currentByte & (partitionMountedFlag and fileOpenFlag)) + +PUB setCharacterPosition(position) | backUpPosition '' 17 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current character position within a file for reading and writing. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ Position - A character position in the file. Set to false to go to the begining of the file and true to go to the end. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(partitionMountedFlag and fileOpenFlag) + + position := ((position <# (currentSize - 1)) #> 0) + backUpPosition := position + + if(position <> currentByte) '@hive: fehlerkorrektur vom originalcode + flushCharacters + + currentByte >>= 9 + position >>= 9 + +' if(position <> currentByte) 'dieser abschnitt muss nach oben verschoben werden +' flushCharacters 'da flashCharacter in sonderfällen auf currentByte zugreift! + + currentByte /= sectorsPerCluster + position /= sectorsPerCluster + + if(position <> currentByte) + if(position < currentByte) + currentByte := 0 + currentCluster := currentFile + + repeat until(position == currentByte++) + + readWriteFATBlock(currentCluster, "R") + currentCluster := readFATEntry(currentCluster) + + if((currentCluster =< 1) or (FATEndOfClusterValue =< currentCluster)) + partitionMountedFlag := false +' abort @FSCorrupted '@hive + abort err_fsysCorrupted + + result := true + + currentByte := backUpPosition + + if(result) + readWriteCurrentSector("R") + +PUB closeFile '' 15 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Closes the currently open file in the current directory. Files opened for writing that are not closed will be corrupted. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + flushCharacters + if(partitionMountedFlag and fileOpenFlag~) + + currentByte := previousByte + currentCluster := previousCluster + + readWriteCurrentSector("R") + + wordToBlock((currentByte + 18), readClock) + + if(fileReadWriteFlag) + + wordToBlock((currentByte + 22), cardTime) + wordToBlock((currentByte + 24), cardDate) + longToBlock((currentByte + 28), currentSize) + + dataBlock[(currentByte + 11) & $1FF] |= $20 + + readWriteCurrentSector("W") + +PUB openFile(fileName, mode) '' 33 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Opens a file in the current directory for reading or writing. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ The "." and ".." entries are ignored by this function. │ +'' │ │ +'' │ Returns a pointer to the name of the file. │ +'' │ │ +'' │ FileName - The name of the file to open for reading or writing. │ +'' │ Mode - A string of characters containing the mode to open the file in. R-Read, W-Write, A-Append. Default read. │ +'' │ │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' result := unformatName(listFind(formatName(fileName), @fileNotFound)) + result := unformatName(listFind(formatName(fileName), err_fileNotFound)) '@hive + + if(listIsDirectory) +' abort @fileNotFound '@hive + abort err_fileNotFound + + currentFile := listCluster + + ifnot(currentFile) + currentFile := createClusterChain(0) + + readWriteCurrentSector("R") + dataBlock[(currentByte + 11) & $1FF] |= $20 + wordToBlock((currentByte + 18), readClock) + wordToBlock((currentByte + 26), (currentFile & $FFFF)) + wordToBlock((currentByte + 20), (currentFile >> 16)) + readWriteCurrentSector("W") + +' fileReadWriteFlag := findCharacter(mode, "W") '@hive + fileReadWriteFlag := mode == "W" + + if(listIsReadOnly and fileReadWriteFlag) +' abort string("File Read Only") '@hive + abort err_fileReadOnly + + currentSize := listSize + previousByte := currentByte + previousCluster := currentCluster +' currentByte := ((findCharacter(mode, "A") and fileReadWriteFlag) & currentSize) '@hive + currentByte := (( (mode == "A") and fileReadWriteFlag) & currentSize) + currentCluster := currentFile + + readWriteCurrentSector("R") + fileOpenFlag := true + +PUB newFile(fileName) '' 40 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Creates a new file in the current directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ Returns a pointer to the name of the file. List functions are not valid after calling this function. │ +'' │ │ +'' │ FileName - The name of the new file to create. Must be a new unique name in the current directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' result := unformatName(listNew(formatName(fileName), $20, readClock, cardTime, 0, "F")) '@hive + unformatName(listNew(formatName(fileName), $20, readClock, cardTime, 0, "F")) '@hive + listReset + +PUB newDirectory(directoryName) '' 40 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Creates a new directory in the current directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ Returns a pointer to the name of the directory. List functions are not valid after calling this function. │ +'' │ │ +'' │ DirectoryName - The name of the new directory to create. Must be a new unique name in the current directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' result := unformatName(listNew(formatName(directoryName), $30, readClock, cardTime, 0, "D")) '@hive + unformatName(listNew(formatName(directoryName), $30, readClock, cardTime, 0, "D")) + + directoryName := currentDirectory + currentDirectory := currentFile + + listNew(@dot, $10, cardDate, cardTime, currentDirectory, "F") + listNew(@dotdot, $10, cardDate, cardTime, directoryName, "F") + + currentDirectory := directoryName + listReset + +PUB deleteEntry(entryName) '' 32 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Deletes a file or directory in the current directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ Cannot delete non empty directories. This throws and error. │ +'' │ │ +'' │ The "." and ".." entries are ignored by this function. │ +'' │ │ +'' │ Returns a pointer to the name of the file or directory. List functions are not valid after calling this function. │ +'' │ │ +'' │ EntryName - The name of the file or directory to delete. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' result := unformatName(listFind(formatName(entryName), @fileOrDirectoryNotFound)) '@hive + result := unformatName(listFind(formatName(entryName), err_notFound)) + + if(listIsDirectory) + + previousByte := currentByte~ + previousCluster := currentCluster + currentCluster := listCluster + + repeat + entryName := listDirectory("R") + + ifnot(entryName) + quit + + if(byte[entryName] <> ".") +' abort string("Directory Is Not Empty") '@hive + abort err_dirIsNotEmpty + + currentByte := previousByte + currentCluster := previousCluster + + readWriteCurrentSector("R") + + byteToBlock(currentByte, $E5) + readWriteCurrentSector("W") + + destroyClusterChain(listCluster) + listReset + +PUB renameEntry(entryNameToChange, entryNameToChangeTo) '' 33 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Renames a file or directory in the current directory. The new name must be unique in the current directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ The "." and ".." entries are ignored by this function. │ +'' │ │ +'' │ Returns a pointer to the name of the file or directory. List functions are not valid after calling this function. │ +'' │ │ +'' │ EntryNameToChange - The name of the file or directory to change. │ +'' │ EntryNameToChangeTo - The name of the file or directory to change to. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + listDuplicate(formatName(entryNameToChangeTo)) +' result := unformatName(listFind(formatName(entryNameToChange), @fileOrDirectoryNotFound)) '@hive + result := unformatName(listFind(formatName(entryNameToChange), err_notFound)) + + bytemove(@dataBlock[currentByte & $1FF], formatName(entryNameToChangeTo), 11) + + wordToBlock((currentByte + 18), readClock) + wordToBlock((currentByte + 22), cardTime) + wordToBlock((currentByte + 24), cardDate) + dataBlock[(currentByte + 11) & $1FF] |= $20 + + readWriteCurrentSector("W") + listReset + +PUB changeAttributes(entryName, newAttributes) '' 33 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the attributes of a file or directory in the current directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ The "." and ".." entries are ignored by this function. │ +'' │ │ +'' │ Returns a pointer to the name of the file or directory. List functions are not valid after calling this function. │ +'' │ │ +'' │ EntryName - The name of the file or directory to change the attributes of. │ +'' │ NewAttributes - A string of characters containing the new set of attributes. A-Archive, S-System, H-Hidden, R-Read Only. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' result := unformatName(listFind(formatName(entryName), @fileOrDirectoryNotFound)) '@hive + result := unformatName(listFind(formatName(entryName), err_notFound)) + + byteToBlock((currentByte + 11), (($20 & findCharacter(newAttributes, "A")) | (listIsDirectory & $10) | ($4 & findCharacter(newAttributes, "S")) | ($2 & findCharacter(newAttributes, "H")) | ($1 & findCharacter(newAttributes, "R")))) + wordToBlock((currentByte + 18), readClock) + wordToBlock((currentByte + 22), cardTime) + wordToBlock((currentByte + 24), cardDate) + + readWriteCurrentSector("W") +' listReset '@hive + +PUB changeDirectory(directoryName) '' 32 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches the current directory for the specified directory and enters that directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ Returns a pointer to the name of the direcotry. List functions are not valid after calling this function. │ +'' │ │ +'' │ DirectoryName - The name of the directory to search for in the current directory and enter into. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' result := unformatName(listFind(listCase(directoryName, formatName(directoryName)), @directoryNotFound)) '@hive + result := unformatName(listFind(listCase(directoryName, formatName(directoryName)), err_dirNotFound)) + + ifnot(listIsDirectory) +' abort @directoryNotFound '@hive + abort err_dirNotFound + + currentDirectory := listCluster + listReset + +PUB getDirCluster:cluster + + result := currentDirectory + +PUB setDirCluster(cluster) + + currentDirectory := cluster + listReset + +PUB listSearch(entryName) '' 32 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns a pointer to the name of the serached for file or direcotry in the current directory. │ +'' │ │ +'' │ Additionally this function validates the other listing functions to get information about the next file or directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ EntryName - The name of the file or directory to search for in the current directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +' return unformatName(listFind(listCase(entryName, formatName(entryName)), @fileOrDirectoryNotFound)) '@hive + return unformatName(listFind(listCase(entryName, formatName(entryName)), err_notFound)) + +PUB listName '' 26 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns a pointer to the name of the next file or direcotry in the current directory. Returns zero on wrap arround. │ +'' │ │ +'' │ Additionally this function validates the other listing functions to get information about the next file or directory. │ +'' │ │ +'' │ If the partition is not mounted or an error occurs this function will abort and return a string describing that error. │ +'' │ │ +'' │ After listing the last file or directory "listReset" must be called to to list from the first file or direcotry again. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return unformatName(listDirectory("R")) + +PUB listReset '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Resets "listName" to list from the first file or directory in the current directory. │ +'' │ │ +'' │ List functions are not valid after calling this function. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + ifnot(fileOpenFlag) + + currentByte := 0 + currentCluster := currentDirectory + + bytefill(@directoryEntry, 0, 32) + bytefill(@directoryEntryName, 0, 12) + +PUB listSize '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the size of current file or directory pointed to by "listName". Directories have no size. │ +'' │ │ +'' │ If a file is currently open this function will retrieve that files information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the size of the file or directory in bytes. Maximum file size is 2,147,483,136 bytes. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[28] | (directoryEntry[29] << 8) | (directoryEntry[30] << 16) | (directoryEntry[31] << 24)) <# $7FFFFE00) #> 0) + +PUB listCreationDay '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the creation day of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the creation day of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (directoryEntry[16] & $1F) + +PUB listCreationMonth '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the creation month of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the creation month of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[17] & $1) << 3) | (directoryEntry[16] >> 5)) + +PUB listCreationYear '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the creation year of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the creation year of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return ((directoryEntry[17] >> 1) + 1980) + +PUB listCreationSeconds '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the creation second of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the creation second of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[14] & $1F) << 1) + (directoryEntry[13] / 100)) + +PUB listCreationMinutes '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the creation minute of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the creation minute of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[15] & $7) << 3) | (directoryEntry[14] >> 5)) + +PUB listCreationHours '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the creation hour of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the creation hour of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (directoryEntry[15] >> 3) + +PUB listAccessDay '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last day of access of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the last acess day of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (directoryEntry[18] & $1F) + +PUB listAccessMonth '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last month of access of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the last acess month of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[19] & $1) << 3) | (directoryEntry[18] >> 5)) + +PUB listAccessYear '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last year of access of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the last acess year of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return ((directoryEntry[19] >> 1) + 1980) + +PUB listModificationDay '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last day of modification of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the modification day of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (directoryEntry[24] & $1F) + +PUB listModificationMonth '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last month of modification of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the modification month of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[25] & $1) << 3) | (directoryEntry[24] >> 5)) + +PUB listModificationYear '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last year of modification of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the modification year of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return ((directoryEntry[25] >> 1) + 1980) + +PUB listModificationSeconds '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last second of modification of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the modification second of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return ((directoryEntry[22] & $1F) << 1) + +PUB listModificationMinutes '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last minute of modification of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the modification minute of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (((directoryEntry[23] & $7) << 3) | (directoryEntry[22] >> 5)) + +PUB listModificationHours '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the last hour of modification of the current file or directory pointed to by "listName". │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns the modification hour of the file or directory. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (directoryEntry[23] >> 3) + +PUB listIsReadOnly '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns whether or not the current file or directory pointed to by "listName" is read only. │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns true or false. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= (directoryEntry[11] & $1) + +PUB listIsHidden '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns whether or not the current file or directory pointed to by "listName" is hidden. │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns true or false. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= (directoryEntry[11] & $2) + +PUB listIsSystem '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns whether or not the current file or directory pointed to by "listName" is a system file. │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns true or false. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= (directoryEntry[11] & $4) + +PUB listIsDirectory '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns whether or not the current file or directory pointed to by "listName" is a directory. │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns true or false. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= (directoryEntry[11] & $10) + +PUB listIsArchive '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns whether or not the current file or directory pointed to by "listName" has been modified since the last backup. │ +'' │ │ +'' │ If a file is currently open this function will retrieve that file's information. │ +'' │ │ +'' │ If "listName" did not succed or was not previously called the value returned is invalid. │ +'' │ │ +'' │ Returns true or false. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= (directoryEntry[11] & $20) + +PUB listVolumeLabel +'' return: zeiger auf string mit volume-label + + 'return unformatName(listDirectory("V")) 'frida + if(partitionMountedFlag) 'frida + return @sdvolumeLabel 'frida + + +PUB checkPartitionMounted '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if the file system is still currently mounted and false if not. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= partitionMountedFlag + +PUB checkFileOpen '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if a file is still currently open and false if not. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= fileOpenFlag + +PUB checkUsedSectorCount(mode) '' 18 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current used sector count on this partition. │ +'' │ │ +'' │ Will do nothing if a file is currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ In fast mode this function will return the last valid used sector count if avialable. This is an estimate value. │ +'' │ │ +'' │ In slow mode this function will compute the used sector count by scanning the entire FAT. This can take a long time. │ +'' │ │ +'' │ One sector is equal to 512 bytes. Multiply the used sector count by 512 to determine the number of used bytes. │ +'' │ │ +'' │ This function also finds the next free cluster for creating new files and directories. │ +'' │ │ +'' │ Call this function when running out of disk space to find the next free cluster if available. │ +'' │ │ +'' │ If the last valid used sector count is not avialable when using fast mode this function will enter slow mode, │ +'' │ │ +'' │ Mode - A character specifing the mode to use. F-Fast, S-Slow. Default slow. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(partitionMountedFlag) + return ((countOfClusters * sectorsPerCluster) - checkFreeSectorCount(mode)) + +PUB checkFreeSectorCount(mode) '' 14 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current free sector count on this partition. │ +'' │ │ +'' │ Will do nothing if a file is currently open or if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ In fast mode this function will return the last valid free sector count if avialable. This is an estimate value. │ +'' │ │ +'' │ In slow mode this function will compute the free sector count by scanning the entire FAT. This can take a long time. │ +'' │ │ +'' │ One sector is equal to 512 bytes. Multiply the free sector count by 512 to determine the number of free bytes. │ +'' │ │ +'' │ This function also finds the next free cluster for creating new files and directories. │ +'' │ │ +'' │ Call this function when running out of disk space to find the next free cluster if available. │ +'' │ │ +'' │ If the last valid free sector count is not avialable when using fast mode this function will enter slow mode, │ +'' │ │ +'' │ Mode - A character specifing the mode to use. F-Fast, S-Slow. Default slow. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(partitionMountedFlag) + flushCharacters + + if(findByte(mode, "f", "F") and (freeClusterCount <> $FFFFFFFF)) + result := freeClusterCount + + else + repeat mode from 0 to (countOfClusters + 1) + + ifnot(FATEntryNumber(mode)) + readWriteFATBlock(mode, "R") + + result -= (not(readFATEntry(mode))) + + ifnot(result) + nextFreeCluster := ((mode + 1) <# (countOfClusters + 1)) + + freeClusterCount := result + readWriteCurrentSector("R") + + result *= sectorsPerCluster + +PUB bootPartition(fileName, checkDisk) | bootSectors[64] '' 102 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Reboots the propeller chip to run the selected file from memory. The file should be a valid spin BIN or EEPROM file. │ +'' │ │ +'' │ Will do nothing if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ FileName - The name of the file to reboot from. │ +'' │ CheckDisk - Unmounts the partition before booting if "C". │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + longfill(@bootSectors, 0, 64) + openFile(fileName~, string("R")) + + repeat (listSize <# 32768) + result += readCharacter + + ifnot($1FF & fileName++) + bootSectors[fileName >> 9] := (partitionStart + FATFirstSectorInCluster(currentCluster) + FATWorkingSectorInCluster) + + result &= $FF + setCharacterPosition(6) + fileName := readShort + closeFile + + if((result and (result <> $14)) or (fileName <> $10)) +' abort string("Checksum Error") '@hive + abort err_checksumError + + if(findByte(checkDisk, "c", "C")) + unmountPartition + + readWriteBlock(@bootSectors, "B") +' abort string("Reboot Error") '@hive + abort err_rebootError + +PUB formatPartition(partition, volumeLabel, checkDisk) '' 34 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Permanetly deletes all information on the loaded FAT16/32 file system. Unloads the loaded FAT16/32 file system. │ +'' │ │ +'' │ Will do nothing if the card is not mounted. This throws an error. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + mountPartition(partition, checkdisk) + + repeat while(readWriteCurrentCluster("R", "D")) + bytefill(@dataBlock, 0, 512) + readWriteCurrentSector("W") + currentByte += 512 + +' result := unformatName(listNew(formatName(volumeLabel), $8, readClock, cardTime, 0, 0)) '@hive + unformatName(listNew(formatName(volumeLabel), $8, readClock, cardTime, 0, 0)) '@hive + + bytefill(@dataBlock, 0, 512) + repeat volumeLabel from reservedSectorCount to (rootDirectorySectorNumber - 1) + readWriteBlock(volumeLabel, "W") + + readWriteFATBlock(0, "R") + writeFATEntry(0, ($0FFFFF00 | mediaType)) + writeFATEntry(1, $0FFFFFFF) + readWriteFATBlock(0, "W") + + listReset + +PUB mountPartition(partition, checkDisk) '' 28 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Loads a FAT16/32 file system with up to 1,099,511,627,776 bytes for use. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' │ │ +'' │ File sizes up to 2,147,483,136 bytes are supported. │ +'' │ │ +'' │ Directory sizes up to 65,536 entries are supported. │ +'' │ │ +'' │ Additionally check disk flags can be setup so that check disk is called on any improperly unmounted partition. │ +'' │ │ +'' │ Returns a pointer to the volume label. │ +'' │ │ +'' │ Parition - Partition number to mount (between 0 and 3). The default partition number is 0. │ +'' │ CheckDisk - Raises the check disk flag upon mounting. C-Raise Flag │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +'' @hive: +'' return: fehlernummer + + unmountPartition + + partitionStart := 0 + readWriteBlock(0, "M") + + bytemove(@cardUniqueIDCopy, @cardUniqueID, 17) + readWriteBlock(0, "R") + + if(blockToWord(510) <> $AA55) +' abort @FSCorrupted '@hive + abort err_fsysCorrupted + + partition := (((partition <# 3) #> 0) << 4) + if((blockToByte(0) <> $EB) and (blockToByte(0) <> $E9)) + + 'case(blockToByte(450 + partition) & $F) + ' $0 .. $3, $5, $7 .. $A, $D, $F: abort @FSUnsupported + + 'volumeIdentification := blockToLong(440) + 'partitionSize := blockToLong(458 + partition) + + partitionStart := blockToLong(454 + partition) + readWriteBlock(0, "R") + + if(blockToWord(510) <> $AA55) +' abort string("BPB Corrupt") '@hive + abort err_bpbCorrupt + + + + if(blockToWord(11) <> 512) +' abort @FSUnsupported '@hive + abort err_fsysUnsupported + + sectorsPerCluster := blockToByte(13) + reservedSectorCount := blockToWord(14) + numberOfFATs := blockToByte(16) + externalFlags := 0 + + partitionSize := blockToWord(19) + ifnot(partitionSize) + partitionSize := blockToLong(32) + + FATSectorSize := blockToWord(22) + ifnot(FATSectorSize) + FATSectorSize := blockToLong(36) + + mediaType := blockToByte(21) + hiddenSectors := blockToLong(28) + + rootDirectorySectors := (blockToWord(17) >> 4) + rootDirectorySectorNumber := (reservedSectorCount + (numberOfFATs * FATSectorSize)) + + firstDataSector := (rootDirectorySectorNumber + rootDirectorySectors) + countOfClusters := ((partitionSize - firstDataSector) / sectorsPerCluster) + + nextFreeCluster := 2 + freeClusterCount := $FFFFFFFF + + if(countOfClusters < 4085) +' abort @FSUnsupported '@hive + abort err_fsysUnsupported + + FATType := false + if(countOfClusters => 65525) + FATType := true + + volumeIdentification := blockToLong(39 + (28 & FATType)) + dataBlock[37 + (28 & FATType)] |= ($3 & findByte(checkDisk, "c", "C")) + readWriteBlock(0, "W") + + if(FATType) + if(blockToWord(40) & $80) + numberOfFATs := 1 + externalFlags := (blockToWord(40) & $F) + + if(blockToWord(42)) +' abort @FSUnsupported '@hive + abort err_fsysUnsupported + + rootCluster := blockToLong(44) + fileSystemInfo := blockToWord(48) + backupBootSector := blockToWord(50) + + readWriteBlock(fileSystemInfo, "R") + + if(blockToWord(510) <> $AA55) +' abort string("FSI Corrupt") '@hive + abort err_fsiCorrupt + + freeClusterCount := blockToLong(488) + nextFreeCluster := blockToLong(492) + + if(nextFreeCluster == $FFFFFFFF) + nextFreeCluster := 2 + + partitionMountedFlag := true + + currentDirectory := 0 + listReset + +' return unformatName(listDirectory("V")) '@hive + result := listDirectory("V") 'frida + bytemove(@sdvolumeLabel, result, 12) 'frida + return 0 + +PUB unmountPartition '' 18 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Unloads the loaded FAT16/32 file system. Closes the currently open file in the current directory. │ +'' │ │ +'' │ If an error occurs this function will abort and return a pointer to a string describing that error. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + closeFile + if(partitionMountedFlag~) + + currentDirectory := 0 + listReset + + readWriteBlock(0, "R") + dataBlock[37 + (28 & FATType)] &= $FC + readWriteBlock(0, "W") + + if(FATType) + readWriteBlock(fileSystemInfo, "R") + longToBlock(freeClusterCount, 488) + longToBlock(nextFreeCluster, 492) + readWriteBlock(fileSystemInfo, "W") + +PUB FATEngine '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Initializes the file system driver to run on a new cog. │ +'' │ │ +'' │ Returns the new cog's ID on sucess or -1 on failure. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + cardLockID := locknew 'frida + + 'debugverbindung + 'debugx.start(115200) ' Start des Debug-Terminals + + slowTiming := ((constant(250_000 << 12) / clkfreq) << 20) + fastTiming := ((constant(2_500_000 << 8) / clkfreq) << 24) + + CCFAddress := @cardCommandFlag + CEFAddress := @cardErrorFlag + + CDBAddress := @cardDataBlockAddress + CSAAddress := @cardSectorAddress + + CUIDAddress := @cardUniqueID + return cognew(@initialization, @cardSectorCount) + +PRI listDuplicate(entryName) ' 27 Stack Longs + + closeFile + listReset + + repeat + + result := listDirectory("R") + + if(strcomp(result, entryName)) + + if(listIsDirectory) +' abort string("Directory Already Exist") '@hive + abort err_dirAlreadyExist + +' abort string("File Already Exist") '@hive + abort err_fileAlreadyExist + + while(result) + +{ +PRI listFind(entryName, errorMessage) ' 28 Stack Longs '@hive + + closeFile + listReset + + repeat + + result := listDirectory("R") + + ifnot(result) + abort errorMessage + + until(strcomp(entryName, result)) + + currentByte -= 32 +} + +PRI listFind(entryName, errorMessage) | strptr ' 28 Stack Longs + + closeFile + listReset + + repeat + result := err_noError + strptr := listDirectory("R") + + ifnot(strptr) + abort errorMessage + + until(strcomp(entryName, strptr)) + + currentByte -= 32 + +PRI listNew(entryName, entryAttributes, entryDate, entryTime, entryCluster, entryType) ' 36 Stack Longs + + listDuplicate(entryName) + listReset + + repeat while(readWriteCurrentCluster("W", "D")) + + if((blockToByte(currentByte) <> $E5) and blockToByte(currentByte)) + currentByte += 32 + + else + + if(entryType == "D") + entryCluster := createClusterChain(0) + currentFile := entryCluster + readWriteCurrentSector("R") + + bytefill(@dataBlock[currentByte & $1FF], 0, 32) + bytemove(@dataBlock[currentByte & $1FF], entryName, 11) + + byteToBlock((currentByte + 11), entryAttributes) + + wordToBlock((currentByte + 14), entryTime) + wordToBlock((currentByte + 16), entryDate) + wordToBlock((currentByte + 18), entryDate) + wordToBlock((currentByte + 22), entryTime) + wordToBlock((currentByte + 24), entryDate) + + wordToBlock((currentByte + 26), (entryCluster & $FFFF)) + wordToBlock((currentByte + 20), (entryCluster >> 16)) + + readWriteCurrentSector("W") + return entryName + +' abort string("Directory Is Full") '@hive + abort err_dirIsFull + +PRI listDirectory(volumeIDAttribute) ' 23 Stack Longs + + if(fileOpenFlag) + closeFile + 'listReset 'frida + + repeat while(readWriteCurrentCluster("R", "D") and blockToByte(currentByte)) + + if((blockToByte(currentByte) == $E5) or (((volumeIDAttribute == "V") ^ blockToByte(currentByte + 11)) & $8)) + currentByte += 32 + + else + + bytemove(@directoryEntry, @dataBlock[currentByte & $1FF], 32) + bytemove(@directoryEntryName, @directoryEntry, 11) + + if(directoryEntryName == $5) + directoryEntryName := $E5 + + currentByte += 32 + return @directoryEntryName + + listReset + +PRI listCluster ' 3 Stack Longs + + result := directoryEntry[26] + result.byte[1] := directoryEntry[27] + result.byte[2] := directoryEntry[20] + result.byte[3] := directoryEntry[21] + + if((result == 1) or (FATEndOfClusterValue =< result)) +' abort @FSCorrupted '@hive + abort err_fsysCorrupted + +PRI listCase(unformatedName, formatedName) ' 5 Stack Longs + + if(byte[unformatedName++] == ".") + result := @dot + + if(byte[unformatedName++] == ".") + result := @dotdot + + repeat strsize(unformatedName) + case byte[unformatedName++] + 9 .. 10, 13, 32: + other: + result := formatedName + quit + +PRI readWriteCurrentCluster(readWrite, fileOrDirectory) ' 19 Stack Longs + + ifnot((fileOrDirectory <> "D") or partitionMountedFlag) +' abort @FSUnmounted '@hive + abort err_fsysUnmounted + + 'Needs to return true if it got the data and false if it didn't. + + ifnot(currentByte & $1FF) + + if(fileOpenFlag and (currentByte => $7FFFFE00)) + return false 'abort string("End of File") + + ifnot(fileOpenFlag or (currentByte < constant(65536 * 32))) + return false 'abort string("End of Directory") + + ifnot(currentcluster or FATType or ((currentByte >> 9) < rootDirectorySectors)) + return false 'abort string("End of Root") + + if(currentByte and (not(FATWorkingSectorInCluster)) and (FATType or currentcluster)) + + result := currentCluster + ifnot(result) + result := rootCluster + + readWriteFATBlock(result, "R") + fileOrDirectory := readFATEntry(result) + + if(fileOrDirectory =< 1) + partitionMountedFlag := false +' abort @FSCorrupted '@hive + abort err_fsysCorrupted + + if(fileOrDirectory => FATEndOfClusterValue) + 'if(fileOpenFlag and (currentByte < (currentSize - 1))) + ' partitionMountedFlag := false + ' abort @FSCorrupted + + if(readWrite == "R") + ifnot(fileOpenFlag) + ifnot(currentCluster) +' abort string("End of Root") '@hive + abort err_endOfRoot + +' abort string("End of Directory") '@hive + abort err_endOfDirectory + + else +' abort string("End of File") '@hive + abort err_endOfFile + + fileOrDirectory := createClusterChain(result) + currentCluster := fileOrDirectory + readWriteCurrentSector("R") + + return true + +PRI readWriteCurrentSector(readWrite) ' 9 Stack Longs + + result := FATFirstSectorInCluster(currentCluster) + FATWorkingSectorInCluster + + ifnot(currentCluster) + result := rootDirectorySectorNumber + (currentByte >> 9) + + if(FATType) + result := FATFirstSectorInCluster(rootCluster) + FATWorkingSectorInCluster + + readWriteBlock(result, readWrite) + +PRI findByte(byteToCompare, thisByte, thatByte) ' 6 Stack Longs + + if((byteToCompare == thisByte) or (byteToCompare == thatByte)) + return true + +PRI findCharacter(charactersToSearch, characterToFind) | convertedCharacter ' 6 Stack Longs + + repeat strsize(charactersToSearch) + + convertedCharacter := byte[charactersToSearch++] + case convertedCharacter + "a" .. "z": convertedCharacter -= 32 + + if(convertedCharacter == characterToFind) + return true + +PRI unformatName(name) ' 4 Stack Longs + + if(name) + + unformatedNameBuffer[12] := 0 + + bytefill(@unformatedNameBuffer, " ", 12) + bytemove(@unformatedNameBuffer, name, 8) + + repeat while(unformatedNameBuffer[++result] <> " ") + unformatedNameBuffer[result++] := "." + + bytemove(@unformatedNameBuffer[result], @byte[name][8], 3) + + if(unformatedNameBuffer[result] == " ") + unformatedNameBuffer[--result] := " " + + return @unformatedNameBuffer + +PRI formatName(name) ' 4 Stack Longs + + formatedNameBuffer[11] := 0 + + bytefill(@formatedNameBuffer, " ", 11) + + repeat strsize(name--) + + if(byte[++name] == ".") + result := 0 + + repeat strsize(++name) + + if((result < 3) and (byte[name] > 31)) + formatedNameBuffer[8 + result++] := byte[name++] + + quit + + if((result < 8) and (byte[name] > 31)) + formatedNameBuffer[result++] := byte[name] + + repeat result from 0 to 10 + + case formatedNameBuffer[result] + "a" .. "z": formatedNameBuffer[result] -= 32 + $22, "*" .. ",", "." .. "/", ":" .. "?", "[" .. "]", "|", $7F: formatedNameBuffer[result] := "_" + + if(formatedNameBuffer == " ") + formatedNameBuffer := "_" + + if(formatedNameBuffer == $E5) + formatedNameBuffer := $5 + + return @formatedNameBuffer + +PRI createClusterChain(clusterToLink) ' 14 Stack Longs + + readWriteFATBlock(nextFreeCluster, "R") + repeat result from nextFreeCluster to (countOfClusters + 1) + + ifnot(FATEntryNumber(result)) + readWriteFATBlock(result, "R") + + ifnot(readFATEntry(result)) + + writeFATEntry(result, true) + readWriteFATBlock(result, "W") + + nextFreeCluster := ((result + 1) <# (countOfClusters + 1)) + + if(clusterToLink) + + readWriteFATBlock(clusterToLink, "R") + writeFATEntry(clusterToLink, result) + readWriteFATBlock(clusterToLink, "W") + + bytefill(@dataBlock, 0, 512) + + repeat clusterToLink from 0 to (sectorsPerCluster - 1) + readWriteBlock((FATFirstSectorInCluster(result) + clusterToLink), "W") + + quit + + if(result => (countOfClusters + 1)) +' abort string("Out Of Disk Free Space") '@hive + abort err_outOfDiskFreeSpace + +PRI destroyClusterChain(clusterToDestroy) ' 14 Stack Longs + + repeat while((1 < clusterToDestroy) and (clusterToDestroy < FATEndOfClusterValue)) + + ifnot(result and (FATBlockNumber(result) == FATBlockNumber(clusterToDestroy))) + readWriteFATBlock(clusterToDestroy, "R") + + result := clusterToDestroy + clusterToDestroy := readFATEntry(clusterToDestroy) + writeFATEntry(result, false) + + if(FATBlockNumber(result) <> FATBlockNumber(clusterToDestroy)) + readWriteFATBlock(result, "W") + + if(result) + readWriteFATBlock(result, "W") + +PRI readFATEntry(cluster) ' 8 Stack Longs + + cluster := FATEntryNumber(cluster) + + ifnot(FATType) + return blockToWord(cluster) + + return (blockTolong(cluster) & $0FFFFFFF) + +PRI writeFATEntry(cluster, value) ' 10 Stack Longs + + cluster := FATEntryNumber(cluster) + + ifnot(FATType) + wordToBlock(cluster, value) + else + longToBlock(cluster, ((value & $0FFFFFFF) | (blockTolong(cluster) & $F0000000))) + +PRI readWriteFATBlock(cluster, readWrite) ' 10 Stack Longs + + cluster := FATBlockNumber(cluster) + result := externalFlags + + repeat ((numberOfFATs & (readWrite == "W")) | (-(readWrite == "R"))) + readWriteBlock((reservedSectorCount + cluster + (FATSectorSize * result++)), readWrite) + +PRI FATBlockNumber(cluster) ' 4 Stack Longs + + return (cluster >> (8 + FATType)) + +PRI FATEntryNumber(cluster) ' 4 Stack Longs + + return ((cluster & ($FF >> (-FATType))) << (1 - FATType)) + +PRI FATEndOfClusterValue ' 3 Stack Longs + + return ($FFF0 | (FATType & $0FFFFFF0)) + +PRI FATWorkingSectorInCluster ' 3 Stack Longs + + return ((currentByte >> 9) // sectorsPerCluster) + +PRI FATFirstSectorInCluster(cluster) ' 4 Stack Longs + + return (((cluster - 2) * sectorsPerCluster) + firstDataSector) + +PRI blockToLong(index) ' 4 Stack Longs + + bytemove(@result, @dataBlock[index & $1FF], 4) + +PRI blockToWord(index) ' 4 Stack Longs + + bytemove(@result, @dataBlock[index & $1FF], 2) + +PRI blockToByte(index) ' 4 Stack Longs + + return dataBlock[index & $1FF] + +PRI longToBlock(index, value) ' 5 Stack Longs + + bytemove(@dataBlock[index & $1FF], @value, 4) + +PRI wordToBlock(index, value) ' 5 Stack Longs + + bytemove(@dataBlock[index & $1FF], @value, 2) + +PRI byteToBlock(index, value) ' 5 Stack Longs + + dataBlock[index & $1FF] := value + +PRI readClock ' 3 + 11 Stack Longs + + repeat while(lockset(cardLockID)) + cardTime := ((rtc.getSeconds >> 1) | (rtc.getMinutes << 5) | (rtc.getHours << 11)) + cardDate := (rtc.getDate | (rtc.getMonth << 5) | ((rtc.getYear - 1980) << 9)) + + lockclr(cardLockID) + return cardDate + +PRI readWriteBlock(address, command) ' 5 Stack Longs + + if(strcomp(@cardUniqueID, @cardUniqueIDCopy) or (command == "M")) + repeat while(lockset(cardLockID)) + + if command == "B" 'frida + lockclr(cardLockID) 'frida + lockret(cardLockID) 'frida + + cardSectorAddress := (address + (partitionStart & (command <> "B"))) + cardDataBlockAddress := (@dataBlock & (command <> "B")) + cardCommandFlag := command + repeat while(cardCommandFlag) + + command := cardErrorFlag~ + lockclr(cardLockID) + + if(command) + partitionMountedFlag := false +' abort string("Disk I/O Error") '@hive + abort err_diskIOError + +DAT 'ASM-Code + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' SD/SDHC/MMC Driver +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + org + +' //////////////////////Initialization///////////////////////////////////////////////////////////////////////////////////////// + +initialization neg phsa, #1 ' Setup clock counter. + movs ctra, #((Clock_Pin <# 31) #> 0) ' + movi ctra, #%0_00100_000 ' + + mov outa, chipSelectPin ' Setup I/O Pins. + or outa, dataInPin ' + mov dira, chipSelectPin ' + or dira, dataInPin ' + or dira, clockPin ' + + mov cardCounter, fiveHundredAndTwelve ' Skip to instruction handle. + jmp #instructionWait ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Command Center +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +instructionRetry cmp cardBuffer, #"M" wc, wz ' Try at most 8 more times to mount the card. +if_c cmp cardBuffer, #"F" wc, wz ' +if_nc_or_z djnz cardBuffer, #mountCard ' + + cmp cardBuffer, #"R" wz ' Try at most twice to read the specified block. +if_z djnz cardBuffer, #readBlock ' + + cmp cardBuffer, #"W" wz ' Try at most twice to write the specified block. +if_z djnz cardBuffer, #writeBlock ' + + cmp cardBuffer, #"B" wz ' Reboot the chip if booting failure. +if_z mov buffer, #$80 ' +if_z clkset buffer ' + +instructionError wrbyte maxPositiveInteger, CEFAddress ' Assert Error Flag and unmount card. +instructionUnmount mov cardMounted, #0 ' + +' //////////////////////Instruction Handle///////////////////////////////////////////////////////////////////////////////////// + +instructionLoop wrbyte fiveHundredAndTwelve, CCFAddress ' Wait for a command to come. +instructionWait rdbyte cardBuffer, CCFAddress ' + test cardMounted, maxPositiveInteger wc ' + + cmp cardBuffer, #"B" wz ' If rebooting was requested do it. +if_z_and_nc jmp #instructionError ' +if_z_and_c jmp #rebootChip ' + + cmp cardBuffer, #"R" wz ' If read block was requested do it. +if_z_and_nc jmp #instructionError ' +if_z_and_c jmp #readBlock ' + + cmp cardBuffer, #"W" wz ' If write block was requested do it. +if_z_and_nc jmp #instructionError ' +if_z_and_c jmp #writeBlock ' + + djnz cardCounter, #instructionSkip ' Poll the card every so often. + mov cardCounter, fiveHundredAndTwelve ' +if_nc jmp #instructionSkip ' + call #cardStatus ' + +instructionSkip cmp cardBuffer, #"M" wz ' If mounting was requested do it. +if_nz jmp #instructionWait ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Mount Card +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +mountCard mov SPITiming, slowTiming ' Setup SPI parameters. + + mov counter, #80 ' Send out for more than 1 millisecond. +seventyFourClocks call #readSPI ' + djnz counter, #seventyFourClocks ' + +' //////////////////////Go Idle State////////////////////////////////////////////////////////////////////////////////////////// + + mov counter, #80 ' Setup counter to try a few times. + +enterIdleStateLoop mov SPICommandOut, #($40 | 0) ' Send out command 0. + mov SPIParameterOut, #0 ' + movs commandSPICRC, #$95 ' + call #commandSPI ' + call #shutdownSPI ' + + cmp SPIResponceIn, #1 wz ' Try a few times. +if_nz djnz counter, #enterIdleStateLoop ' + tjz counter, #instructionRetry ' + +' //////////////////////Send Interface Condition/////////////////////////////////////////////////////////////////////////////// + + mov SPICommandOut, #($40 | 8) ' Send out command 8. + mov SPIParameterOut, #$1AA ' + movs commandSPICRC, #$87 ' + call #commandSPI ' + call #longSPI ' + call #shutdownSPI ' + + test SPIResponceIn, #$7E wz ' If failure goto SD 1.X initialization. +if_nz jmp #exitIdleState_SD ' + + and SPILongIn, #$1FF ' SD 2.0 initialization. + cmp SPILongIn, #$1AA wz ' +if_nz jmp #instructionRetry ' + +' //////////////////////Send Operating Condition/////////////////////////////////////////////////////////////////////////////// + +exitIdleState_SD mov cardType, #0 ' Card type is MMC. + + mov counter, #80 ' Setup counter to try a few times. + +exitIdleStateLoop_SD mov SPICommandOut, #($40 | 55) ' Send out command 55. + mov SPIParameterOut, #0 ' + call #commandSPI ' + call #shutdownSPI ' + + test SPIResponceIn, #$7E wz ' If failure goto MMC initialization. ' +if_nz jmp #exitIdleState_MMC ' + + mov SPICommandOut, #($40 | 41) ' Send out command 41 with HCS bit set. + mov SPIParameterOut, HCSBitMask ' + call #commandSPI ' + call #shutdownSPI ' + + cmp SPIResponceIn, #0 wz ' Try a few times. +if_nz djnz counter, #exitIdleStateLoop_SD ' + tjz counter, #instructionRetry ' + + djnz cardType, #readOCR ' Card type is SD and skip MMC initialization. + +' //////////////////////Send Operating Condition/////////////////////////////////////////////////////////////////////////////// + +exitIdleState_MMC mov counter, #80 ' Setup counter to try a few times. + +exitIdleStateLoop_MMC mov SPICommandOut, #($40 | 1) ' Send out command 1. + mov SPIParameterOut, #0 ' + call #commandSPI ' + call #shutdownSPI ' + + cmp SPIResponceIn, #0 wz ' Try a few times. +if_nz djnz counter, #exitIdleStateLoop_MMC ' + tjz counter, #instructionRetry ' + +' //////////////////////Read OCR Register////////////////////////////////////////////////////////////////////////////////////// + +readOCR mov SPICommandOut, #($40 | 58) ' Ask the card for its OCR register. + mov SPIParameterOut, #0 ' + call #commandSPI ' + call #longSPI ' + call #shutdownSPI ' + + tjnz SPIResponceIn, #instructionRetry ' If failure abort. + + test SPILongIn, OCRCheckMask wz ' If voltage not supported abort. + shl SPILongIn, #1 wc ' +if_z_or_nc jmp #instructionRetry ' + + shl SPILongIn, #1 wc ' SDHC supported or not. +if_c mov SPIShift, #0 ' +if_nc mov SPIShift, #9 ' + +' //////////////////////Set Block Length/////////////////////////////////////////////////////////////////////////////////////// + + mov SPICommandOut, #($40 | 16) ' Send out command 16. + mov SPIParameterOut, fiveHundredAndTwelve ' + call #commandSPI ' + call #shutdownSPI ' + + tjnz SPIResponceIn, #instructionRetry ' If failure abort. + +' //////////////////////Read CSD Register////////////////////////////////////////////////////////////////////////////////////// + + mov SPICommandOut, #($40 | 9) ' Ask the card for its CSD register. + mov SPIParameterOut, #0 ' + call #commandSPI ' + + tjnz SPIResponceIn, #instructionRetry ' If failure abort. + call #repsonceSPI ' + cmp SPIResponceIn, #$FE wz ' +if_nz jmp #instructionRetry ' + + mov counter, #16 ' Setup to read the CSD register. + movd readCSDModify, #CSDRegister ' + +readCSDLoop call #readSPI ' Read the CSD register in. +readCSDModify mov 0, SPIDataIn ' + add readCSDModify, fiveHundredAndTwelve ' + djnz counter, #readCSDLoop ' + + call #wordSPI ' Shutdown SPI clock. + call #shutdownSPI ' + +' //////////////////////Read CID Register////////////////////////////////////////////////////////////////////////////////////// + + mov SPICommandOut, #($40 | 10) ' Ask the card for its CID register. + mov SPIParameterOut, #0 ' + call #commandSPI ' + + tjnz SPIResponceIn, #instructionRetry ' If failure abort. + call #repsonceSPI ' + cmp SPIResponceIn, #$FE wz ' +if_nz jmp #instructionRetry ' + + mov counter, #16 ' Setup to read the CID register. + mov buffer, CUIDAddress ' + +readCIDLoop call #readSPI ' Read the CID register in. + wrbyte SPIDataIn, buffer ' + add buffer, #1 ' + djnz counter, #readCIDLoop ' + + wrbyte fiveHundredAndTwelve, buffer ' Clear the last byte for string compare. + + call #wordSPI ' Shutdown SPI clock. + call #shutdownSPI ' + +' //////////////////////Setup Card Variables/////////////////////////////////////////////////////////////////////////////////// + + mov SPITiming, fastTiming ' Setup SPI parameters. + + testn cardType, #0 wz, wc ' Determine CSD structure version. +if_nz test CSDRegister, #$40 wc ' +if_nz test CSDRegister, #$80 wz ' + +if_nc_and_z mov counter, (CSDRegister + 6) ' Extract card size. +if_nc_and_z and counter, #$3 ' +if_nc_and_z shl counter, #10 ' +if_nc_and_z mov buffer, (CSDRegister + 7) ' +if_nc_and_z shl buffer, #2 ' +if_nc_and_z mov cardSize, (CSDRegister + 8) ' +if_nc_and_z shr cardSize, #6 ' +if_nc_and_z or cardSize, counter ' +if_nc_and_z or cardSize, buffer ' + +if_c_and_z mov counter, (CSDRegister + 7) ' Extract card size. +if_c_and_z and counter, #$3F ' +if_c_and_z shl counter, #16 ' +if_c_and_z mov buffer, (CSDRegister + 8) ' +if_c_and_z shl buffer, #8 ' +if_c_and_z mov cardSize, (CSDRegister + 9) ' +if_c_and_z or cardSize, counter ' +if_c_and_z or cardSize, buffer ' + +if_nc_and_z mov buffer, (CSDRegister + 9) ' Extract card size multiplier. +if_nc_and_z and buffer, #$3 ' +if_nc_and_z shl buffer, #1 ' +if_nc_and_z mov cardSizeMultiplier, (CSDRegister + 10) ' +if_nc_and_z shr cardSizeMultiplier, #7 ' +if_nc_and_z or cardSizeMultiplier, buffer ' + +if_nc_and_z mov cardReadBlockLength, (CSDRegister + 5) ' Extract read block length. +if_nc_and_z and cardReadBlockLength, #$F ' + +if_nc_and_z sub cardReadBlockLength, #9 ' Compute card sector count for version 1.0 CSD. +if_nc_and_z add cardSizeMultiplier, #2 ' +if_z add cardSize, #1 ' +if_nc_and_z shl cardSize, cardReadBlockLength ' +if_nc_and_z shl cardSize, cardSizeMultiplier ' + +if_c_and_z shl cardSize, #10 ' Compute card sector count for version 2.0 CSD. + + max cardSize, maxPositiveInteger ' Limit maximum partition size. + +if_nz neg cardSize, #1 ' Unknown CSD structure. Card size to -1. + + wrlong cardSize, par ' Update Card Size. + + mov cardSizeMinusOne, cardSize ' Compute maximum allowed addressable sector. + sub cardSizeMinusOne, #1 ' + + neg cardMounted, #1 ' Return. + jmp #instructionLoop ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Read Block +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +readBlock rdlong SPIParameterOut, CSAAddress ' Read a block. + max SPIParameterOut, cardSizeMinusOne ' + shl SPIParameterOut, SPIShift ' + mov SPICommandOut, #($40 | 17) ' + call #commandSPI ' + + tjnz SPIResponceIn, #instructionRetry ' If failure abort. + call #repsonceSPI ' + cmp SPIResponceIn, #$FE wz ' +if_nz jmp #instructionRetry ' + + mov counter, fiveHundredAndTwelve ' Setup loop. +readBlockModify rdlong buffer, CDBAddress ' + +readBlockLoop call #readSPI ' Read data into memory. + wrbyte SPIDataIn, buffer ' + add buffer, #1 ' + djnz counter, #readBlockLoop ' + + call #wordSPI ' Shutdown SPI clock. + call #shutdownSPI ' + +readBlock_ret jmp #instructionLoop ' Return. Become RET instruction when rebooting. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Write Block +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +writeBlock rdlong SPIParameterOut, CSAAddress ' Write a block. + max SPIParameterOut, cardSizeMinusOne ' + shl SPIParameterOut, SPIShift ' + mov SPICommandOut, #($40 | 24) ' + call #commandSPI ' + + tjnz SPIResponceIn, #instructionRetry ' If failure abort. + + mov SPIDataOut, #$FE ' Send start of data token. + call #writeSPI ' + + mov counter, fiveHundredAndTwelve ' Setup loop. + rdlong buffer, CDBAddress ' + +writeBlockLoop rdbyte SPIDataOut, buffer ' Write data out from memory. + add buffer, #1 ' + call #writeSPI ' + djnz counter, #writeBlockLoop ' + + call #wordSPI ' Write out the 16 bit CRC. + + call #repsonceSPI ' If failure abort. + and SPIDataIn, #$1F ' + cmp SPIDataIn, #$5 wz ' +if_nz jmp #instructionRetry ' + + call #cardBusy ' Shutdown SPI clock. + call #shutdownSPI ' + + jmp #instructionLoop ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Reboot Chip +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +rebootChip rdlong buffer, CDBAddress ' Check to make sure a reboot was requested. + tjnz buffer, #instructionError ' + +' //////////////////////Shutdown Cogs////////////////////////////////////////////////////////////////////////////////////////// + + mov counter, #8 ' Setup cog stop loop. + cogid buffer ' + +rebootCogLoop sub counter, #1 ' Stop all cogs but this one. + cmp counter, buffer wz ' +if_nz cogstop counter ' + tjnz counter, #rebootCogLoop ' + +' //////////////////////Setup Memory/////////////////////////////////////////////////////////////////////////////////////////// + + mov counter, #64 ' Setup to grab all sector addresses. + rdlong buffer, CSAAddress ' + +rebootSectorLoadLoop rdlong cardRebootSectors, buffer ' Get all addresses of the 64 sectors of new code into memory. + add buffer, #4 ' + add rebootSectorLoadLoop, fiveHundredAndTwelve ' + djnz counter, #rebootSectorLoadLoop ' + +' //////////////////////Clear Memory/////////////////////////////////////////////////////////////////////////////////////////// + + mov counter, fiveHundredAndTwelve ' Clear all memory. Leave buffer the pointer at 0. + shl counter, #6 ' + mov buffer, #0 ' +rebootCodeClearLoop sub counter, #4 ' + wrlong buffer, counter ' + tjnz counter, #rebootCodeClearLoop ' + +' //////////////////////Fill Memory//////////////////////////////////////////////////////////////////////////////////////////// + + mov readBlock, #0 ' Fill these two commands with NOPs. + mov readBlockModify, #0 ' + + mov cardCounter, #64 ' Ready to fill all memory. Pointer already at 0. + +rebootCodeFillLoop mov SPIParameterOut, cardRebootSectors ' Reuse read block code. Finish if next sector is 0. + tjz SPIParameterOut, #rebootReady ' + add rebootCodeFillLoop, #1 ' + call #readBlock ' + djnz cardCounter, #rebootCodeFillLoop ' + +' //////////////////////Boot Interpreter/////////////////////////////////////////////////////////////////////////////////////// + +rebootReady rdword buffer, #$A ' Setup the stack markers. + sub buffer, #4 ' + wrlong rebootStackMark, buffer ' + sub buffer, #4 ' + wrlong rebootStackMark, buffer ' + + rdbyte buffer, #$4 ' Switch to new clock mode. + clkset buffer ' + + coginit rebootInterpreter ' Restart running new code. + + cogid buffer ' Shutdown. + cogstop buffer ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Card Status +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +cardStatus mov SPICommandOut, #($40 | 13) ' Send out command 13. + mov SPIParameterOut, #0 ' + call #commandSPI ' + call #byteSPI ' + call #shutdownSPI ' + + tjnz SPIResponceIn, #instructionUnmount ' If failure abort. + tjnz SPILongIn, #instructionUnmount ' + +cardStatus_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Card Busy +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +cardBusy mov counter, writeTimeout ' Setup loop. + +cardBusyLoop call #readSPI ' Wait until card is not busy. + cmp SPIDataIn, #0 wz ' +if_z djnz counter, #cardBusyLoop ' + tjz counter, #instructionRetry ' + +cardBusy_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Command SPI +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +commandSPI andn outa, chipSelectPin ' Activate the SPI bus. + call #readSPI ' + + mov SPIDataOut, SPICommandOut ' Send out command. + call #writeSPI ' + + movs writeSPI, #32 ' Send out parameter. + mov SPIDataOut, SPIParameterOut ' + call #writeSPI ' + movs writeSPI, #8 ' + +commandSPICRC mov SPIDataOut, #0 ' Send out CRC token. + call #writeSPI ' + + call #repsonceSPI ' Read in responce. + +commandSPI_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Responce SPI +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +repsonceSPI mov SPIResponceIn, readTimeout ' Setup responce poll counter. + +repsonceSPILoop call #readSPI ' Poll for responce. + cmp SPIDataIn, #$FF wz ' +if_z djnz SPIResponceIn, #repsonceSPILoop ' + + mov SPIResponceIn, SPIDataIn ' Move responce into return value. + +repsonceSPI_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Long SPI +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +longSPI add readSPI, #16 ' Read in 32, 16, or 8 bits. +wordSPI add readSPI, #8 ' +byteSPI call #readSPI ' + movs readSPI, #8 ' + + mov SPILongIn, SPIDataIn ' Move long into return value. + +byteSPI_ret ' Return. +wordSPI_ret ' +longSPI_ret ret ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Shutdown SPI +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +shutdownSPI call #readSPI ' Shutdown SPI bus. + or outa, chipSelectPin ' + call #readSPI ' + +shutdownSPI_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Read SPI +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +readSPI mov SPICounter, #8 ' Setup counter to read in 1 - 32 bits. Default 8. + mov SPIDataIn, #0 wc ' + + mov phsa, #0 ' Start clock low. + mov frqa, SPITiming ' + +readSPILoop waitpne clockPin, clockPin ' Get bit. + rcl SPIDataIn, #1 ' + waitpeq clockPin, clockPin ' + test dataOutPin, ina wc ' + + djnz SPICounter, #readSPILoop ' Loop + + mov frqa, #0 ' Stop clock high. + rcl SPIDataIn, #1 ' + +readSPI_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Write SPI +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +writeSPI mov SPICounter, #8 ' Setup counter to write out 1 - 32 bits. Default 8. + ror SPIDataOut, SPICounter ' + + mov phsa, #0 ' Start clock low. + mov frqa, SPITiming ' + +writeSPILoop shl SPIDataOut, #1 wc ' Set bit. + waitpne clockPin, clockPin ' + muxc outa, dataInPin ' + waitpeq clockPin, clockPin ' + + djnz SPICounter, #writeSPILoop ' Loop. + + mov frqa, #0 ' Stop clock high. + or outa, dataInPin ' + +writeSPI_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' CRC7 Augmentation +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CRC7 mov CRCCounter, #7 ' Get variables ready. + +CRC7Loop shl CRCBuffer, #1 ' Do the CRC7 calculation. + test CRCBuffer, #$80 wc ' +if_c xor CRCBuffer, #$9 ' + djnz CRCCounter, #CRC7Loop ' + +CRC7_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' CRC16 Augmentation +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CRC16 mov CRCCounter, #16 ' Get variables ready. + +CRC16Loop shl CRCBuffer, #1 ' Do the CRC16 calculation. + test CRCBuffer, CRC16TestBit wc ' +if_c xor CRCBuffer, CRC16Polynomial ' + djnz CRCCounter, #CRC16Loop ' + +CRC16_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Data +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +cardMounted long 0 + +' //////////////////////Constants////////////////////////////////////////////////////////////////////////////////////////////// + +fiveHundredAndTwelve long $200 ' Constant 512. +maxPositiveInteger long $7FFFFFFF ' Constant 2,147,483,647. + +CRC16TestBit long $10000 ' The CRC16 test bit mask. +CRC16Polynomial long $1021 ' The CRC16 polynomial bit mask. + +OCRCheckMask long %00_000000_00110000_00000000_00000000 ' Parameter check mask for OCR bits. +HCSBitMask long %01_000000_00000000_00000000_00000000 ' Parameter bit mask for HCS bit. + +rebootInterpreter long ($0001 << 18) | ($3C01 << 4) ' Spin interpreter boot information. +rebootStackMark long $FFF9FFFF ' Stack mark used for spin code. + +' //////////////////////Configuration Settings///////////////////////////////////////////////////////////////////////////////// + +slowTiming long 0 ' 250KHz Clock speed. +fastTiming long 0 ' 2.5MHz Clock speed. + +readTimeout long 250_000 ' Read timeout of 100 milliseconds at 2.5Mhz clock. +writeTimeout long 625_000 ' Write timeout of 250 milliseconds at 2.5Mhz clock. + +' //////////////////////Pin Masks////////////////////////////////////////////////////////////////////////////////////////////// + +dataOutPin long (|<((Data_Out_Pin <# 31) #> 0)) +clockPin long (|<((Clock_Pin <# 31) #> 0)) +dataInPin long (|<((Data_In_Pin <# 31) #> 0)) +chipSelectPin long (|<((Chip_Select_Pin <# 31) #> 0)) +dataOutOff long 0 + +' //////////////////////Addresses////////////////////////////////////////////////////////////////////////////////////////////// + +CCFAddress long 0 +CEFAddress long 0 + +CUIDAddress long 0 + +CDBAddress long 0 +CSAAddress long 0 + + +DAT 'Variable Array + +' //////////////////////Variable Array///////////////////////////////////////////////////////////////////////////////////////// + +cardCommandFlag byte 0 +cardErrorFlag byte 0 + +cardLockID byte 0 'frida ((HUB_Lock <# 7) #> 0) +cardUniqueID byte 0[17] + +cardDataBlockAddress long 0 +cardSectorAddress long 0 +cardSectorCount long 0 + +DAT 'String Array + +' //////////////////////String Array/////////////////////////////////////////////////////////////////////////////////////////// + +dot byte ". ", 0 +dotdot byte ".. ", 0 + +{ '@hive +FSUnmounted byte "File System Unmounted", 0 +FSCorrupted byte "File System Corrupted", 0 +FSUnsupported byte "File System Unsupported", 0 + +fileOrDirectoryNotFound byte "File Or Directory Not Found", 0 +fileNotFound byte "File Not Found", 0 +directoryNotFound byte "Directory Not Found", 0 +} + +' //////////////////////Run Time Variables///////////////////////////////////////////////////////////////////////////////////// + +buffer res 1 +counter res 1 + +' //////////////////////Card Variables///////////////////////////////////////////////////////////////////////////////////////// + +cardBuffer res 1 +cardCounter res 1 + +cardType res 1 +cardSize res 1 + +cardSizeMultiplier res 1 +cardSizeMinusOne res 1 + +cardReadBlockLength res 1 +cardWriteBlockLength res 1 + +CSDRegister res 16 +CIDRegister res 16 + +cardRebootSectors res 64 + +' //////////////////////SPI Variables////////////////////////////////////////////////////////////////////////////////////////// + +SPICommandOut res 1 +SPIParameterOut res 1 +SPIResponceIn res 1 +SPILongIn res 1 + +SPIShift res 1 +SPITiming res 1 + +SPIDataIn res 1 +SPIDataOut res 1 + +SPIBuffer res 1 +SPICounter res 1 + +' //////////////////////CRC Variables////////////////////////////////////////////////////////////////////////////////////////// + +CRCBuffer res 1 +CRCCounter res 1 + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + fit 496 + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +{{ + +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the │ +│Software is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the │ +│Software. │ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/adm-hss.spin b/lib/adm-hss.spin new file mode 100644 index 0000000..51eb0a8 --- /dev/null +++ b/lib/adm-hss.spin @@ -0,0 +1,738 @@ +''***************************** +''* Hydra Sound System v1.2 * +''* (C)2007 Andrew Arsenault * +''***************************** +''http://www.andrewarsenault.com/hss/ +''e-mail: ym2413a@yahoo.com +'' +'' Cogs used: 2 +'' HUB-RAM: ~2.7k + +'' Please visit the website for the latest version, documentation, examples and media files. +'' Thank you! --Ym2413a + +'' 25.01.2009 Anpassungen für ein komfortableres Interface zur Visualisierung und Steuerung + +CON +#0, iEndFlag 'Repeat oder Ende wurde erreicht + iRowFlag 'Flag das Songzeile fertig ist + iEngineC 'Patternzähler + iBeatC 'Beatzähler + iRepeat 'zähler für loops +#5, iChannel +#5, iChannel1 +#10, iChannel2 +#15, iChannel3 +#16, iChannel4 +#0, iNote + iOktave + iVolume + iEffekt + iInstrument + +VAR + +'Interface + word intreg[5 * 5] + +'Sound Engine Stack + long hsnd_stack[18] + long cog1, cog2 + +'WavSynth Parameters + long snd_regs[48] 'Regs for Sound Hardware (8x6)+5dpcm + long dpcm_regs[5] + +'DPCM Command Variables + word dpcmreg_ptr + +'Global Hmus Player Vars + word tempo + word song_pc + word song_div + word song_ptr + word chfre[4] + byte chfx[4] + byte chvol[4] + byte hmus_state + byte hmvol + byte fxphs + +'Sound FX Variables + word runlen[2] + word envamp[2] + word sfx_ptr[2] + byte envphs[2] + byte fmcnt[2], fmfreq[2] + byte loadsfx[2] + +CON + +'' Hss Master Control + +PUB start: okay + + okay := cog1 := cognew(@entry, @snd_regs) + okay := cog2 := cognew(hsound, @hsnd_stack) + +PUB stop + + cogstop(cog2) + cogstop(cog1) + +PUB peek(addrptr) : var1 + + var1 := LONG[@snd_regs][addrptr] + +PUB intread(index): wert 'interface: auslesen eines interfaceregisters + + wert := intreg[index] + + +CON + +'' Hydra Music Commands + +PUB hmus_load(songptr) | z + + hmvol := 15 + song_div := 0 + song_ptr := songptr + song_pc := WORD[songptr][8] + tempo := WORD[songptr][12] + repeat z from 0 to 3 + chfx[z] := 0 + + repeat z from 0 to 5*5 'interface: playerinterface alle werte löschen + intreg[z] := 0 + + +PUB hmus_play + + hmus_state := 1 + +PUB hmus_stop | z + + hmus_state := 0 + repeat z from 0 to 3 + chvol[z] := 0 + +PUB hmus_pause + + hmus_state := 0 + +PUB hmus_tempo(var1) + + tempo := var1 + +PUB get_hmus_tempo : var1 + + var1 := tempo + +PUB hmus_vol(var1) + + hmvol := var1 <# 15 #> 0 + +PUB get_hmus_vol : var1 + + var1 := hmvol + +CON + +'' FXsynth Commands + +PUB sfx_play(chan, soundptr) + + if(chan == 1) + sfx_ptr[0] := soundptr + loadsfx[0] := 0 + if(chan == 2) + sfx_ptr[1] := soundptr + loadsfx[1] := 0 + +PUB sfx_stop(chan) + + if(chan == 1) + sfx_ptr[0] := 0 + if(chan == 2) + sfx_ptr[1] := 0 + +PUB sfx_keyoff(chan) + + if(chan == 1) + envphs[0] := 3 + if(chan == 2) + envphs[1] := 3 + +CON + +'' Hydra DPCM Commands + +PUB dpcm_play(soundptr) + + dpcmreg_ptr := soundptr + +PUB dpcm_stop + + dpcmreg_ptr := 1 + +CON +''***************************** +''* Hss Sound Engine * +''***************************** +PRI Hsound +repeat + 'Update Music Engine + UpdateMus(song_ptr, Hmus_state) 'Update Music Player + 'volume/frequenzwerte werden in die soundregister geschrieben + VolumeInterpol 'Delay and Interpolate Volume to Remove Pops and Clicks. + + 'Update DPCM Engine + if(dpcmreg_ptr) + DpcmUpdate 'Update the DPCM registers + + 'Update SoundFX Engine + + 'FX channel A + FXSynth(0,32) + 'FX channel B + FXSynth(1, 40) + +PRI VolumeInterpol | z, channelmul, musvar, freqval + + fxphs += 5 + +'Volume Interpolation + repeat z from 0 to 3 step 1 + channelmul := 4+(8*z) + musvar := (chvol[z]*(hmvol+1))&$F0 + snd_regs[channelmul] := (snd_regs[channelmul] & 15)+musvar + + 'Freq Interpolation + channelmul -= 1 'Jump down a REG to Freq + musvar := chfre[z]<<16 + + if(chfx[z] == 0) 'None + snd_regs[channelmul] := musvar + + elseif(chfx[z] < 3) 'Vibrato (light/hard) + if(fxphs < 128) + snd_regs[channelmul] := musvar+(chfre[z]<<(7+chfx[z])) + else + snd_regs[channelmul] := musvar-(chfre[z]<<(7+chfx[z])) + + elseif(chfx[z] == 3) 'Tremolo + if(fxphs < 128) + snd_regs[channelmul] := musvar + else + snd_regs[channelmul] := musvar<<1 + + else 'Portamento + freqval := snd_regs[channelmul]>>16 + if(freqval & $F000 == chfre[z] & $F000) + snd_regs[channelmul] := musvar + elseif(freqval < chfre[z]) + snd_regs[channelmul] := snd_regs[channelmul]+(chfx[z]<<22) + else + snd_regs[channelmul] := snd_regs[channelmul]-(chfx[z]<<22) + +PRI UpdateMus(songptr, state) | i, channel, channelmul, scrdat, freq, freqoct, flag + + if(state == 0) + return ''Song is not playing. + + song_div++ 'zeitfaktor; wird erhöht bis... + + if(song_div => tempo) 'Tempo Divider 'schwellwert erreicht, dann nächster beat + song_div := 0 + flag := 0 + intreg[iBeatC] := intreg[iBeatC] + 1 'interface: beatconter erhöhen + intreg[iRowFlag] := 0 'interface: Kennung das Zeile bearbeitet wird + repeat i from 5 to 5*5 'interface: channelwerte löschen + intreg[i] := 0 + + repeat 'Score Decoder and Processor + scrdat := BYTE[song_ptr][song_pc] 'song_pc ist zeiger auf wert in MusicDat + channel := scrdat & 3 'untere zwei bit enthalten die kanalnummer + channelmul := channel<<3 'jedem channel sind 8 registerwerte zugeordent + intreg[iEngineC] := song_pc 'interface: enginecounter setzen + song_pc++ 'zeiger auf nächsten wert setzen + + ''Base Commands + if(scrdat == 0) 'End Row 'nächste trackerzeile + intreg[iRowFlag] := 1 'interface: Zeile fertig bearbeitet + quit + + if(scrdat == 1) 'Repeat Song 'wiederholt ab MusicLoop (MusicDat ist also die einleitung) + song_pc := WORD[songptr][9] + intreg[iRepeat] := intreg[iRepeat] + 1 'interface: flag das songende erreicht wurde + quit + + if(scrdat == 2) 'End Song 'status wird auf 0 gesetzt + intreg[iEndFlag] := 1 'interface: flag das songende erreicht wurde + hmus_stop + quit + + if(scrdat == 3) 'Set Flag + flag := 1 + next + + if((scrdat & $3C) == $20) 'Patch HI Note 'oktave erhöhen und veränderung zu "Change Note" + flag := 2 + scrdat := scrdat>>3 + scrdat += 64+channel + + if(scrdat & 4) 'Change Note + freq := scrdat>>3 'note Bit3 bis Bit7 (32 Noten) + freqoct := freq/12 + freq -= freqoct*12 + case flag + 1 : freqoct += 2 + 2 : freqoct += 6 + other : freqoct += 4 + flag := 0 + snd_regs[4+channelmul] := snd_regs[4+channelmul] & $FE + intreg[(channel*iChannel)+iChannel+iNote] := freq + 1 'interface: note setzen (0 ist erste note!) + intreg[(channel*iChannel)+iChannel+iOktave] := freqoct 'interface: oktave setzen + 'frequenz aus tabelle holen + 'je nach oktave wird nach rechts verschoben (/2) + chfre[channel] := NoteFreqs[freq]>>(6-freqoct) + snd_regs[4+channelmul] := (snd_regs[4+channelmul] & $FE)+1 + next 'Repeat To Next Datum + + if(scrdat & 8) 'Change Evelope / Channel Effect + if(flag) + intreg[(channel*iChannel)+iChannel+iEffekt] := scrdat>>4 + 1 'interface: effektwert setzen + chfx[channel] := scrdat>>4 + flag := 0 + else + intreg[(channel*iChannel)+iChannel+iVolume] := scrdat>>4 'interface: volume setzen + chvol[channel] := scrdat>>4 + next 'Repeat To Next Datum + + if(scrdat & 16) 'Change Instrument + freq := (scrdat & $E0)>>3 + freq += flag<<5 + flag := 0 + intreg[(channel*iChannel)+iChannel+iInstrument] := freq>>2 + 1 'interface: instrument setzen + snd_regs[0+channelmul] := songptr+WORD[songptr+32][freq] 'zeiger auf neues instrumentensample + snd_regs[1+channelmul] := WORD[songptr+32][freq+1] 'ende des samples + snd_regs[2+channelmul] := WORD[songptr+32][freq+2] 'loop + snd_regs[4+channelmul] := WORD[songptr+32][freq+3] & $0F 'flags? + next 'Repeat To Next Datum + + if(scrdat & 64) 'Detune + chfre[channel] := chfre[channel]+(chfre[channel]>>8) + + + +PRI DpcmUpdate + + if(dpcmreg_ptr > 15) 'Play Sample. + dpcm_regs[2] := 65535 'End sample if one was playing + dpcm_regs[0] := dpcmreg_ptr+8 + dpcm_regs[4] := 128 + dpcm_regs[3] := LONG[dpcmreg_ptr][1] 'Get sampling rate + dpcm_regs[1] := WORD[dpcmreg_ptr][1] 'Get length + dpcm_regs[2] := 0 'Reset play counter + elseif(dpcmreg_ptr == 1) 'Stop Sample + dpcm_regs[2] := 65535 'End sample + dpcm_regs[4] := 128 + + dpcmreg_ptr := 0 + +PRI FXSynth(SoundVars, ChannelFX) | TimeCnt, SoundFX, Modwav, FMwav, AMwav + TimeCnt := Cnt + SoundFX := sfx_ptr[SoundVars] + + if(loadsfx[SoundVars] == 0) + 'Setup OSC WaveForm + case BYTE[SoundFX][0] + $00: 'Sine + snd_regs[ChannelFX] := @SineTable + snd_regs[1+ChannelFX] := 64 + $01: 'Fast Sine + snd_regs[ChannelFX] := @FastSine + snd_regs[1+ChannelFX] := 32 + $02: 'Sawtooth + snd_regs[ChannelFX] := @Sawtooth + snd_regs[1+ChannelFX] := 64 + $03: 'Square + snd_regs[ChannelFX] := @SqrTable + snd_regs[1+ChannelFX] := 32 + $04: 'Fast Square + snd_regs[ChannelFX] := @FastSqr + snd_regs[1+ChannelFX] := 8 + $05: 'Buzz + snd_regs[ChannelFX] := @NoteFreqs + snd_regs[1+ChannelFX] := 24 + $06: 'Noise + snd_regs[ChannelFX] := $F002 + snd_regs[1+ChannelFX] := 3000 + + snd_regs[2+ChannelFX] := 0 + snd_regs[4+ChannelFX] := $01 + + loadsfx[SoundVars] := 1 + runlen[SoundVars] := 0 + fmcnt[SoundVars] := 0 + fmfreq[SoundVars] := 0 + envamp[SoundVars] := 0 + envphs[SoundVars] := 0 + +''Modulation Code + fmfreq[SoundVars]++ + if(fmfreq[SoundVars] => BYTE[SoundFX][4]) + fmfreq[SoundVars] := 0 + fmcnt[SoundVars]++ + fmcnt[SoundVars] := fmcnt[SoundVars] & $3F + + case BYTE[SoundFX][5] + $00: + Modwav := BYTE[@SineTable][fmcnt[SoundVars]] + $01: + Modwav := BYTE[@FastSine][fmcnt[SoundVars] & 31] + $02: + Modwav := fmcnt[SoundVars]<<2 + $03: + Modwav := !fmcnt[SoundVars]<<2 + $04: + if(fmcnt[SoundVars] & 8) + Modwav := $ff + else + Modwav := $00 + $05: + Modwav := BYTE[$F002][fmcnt[SoundVars]] + $FF: + Modwav := BYTE[SoundFX+12][fmcnt[SoundVars] & 15] + + fmwav := Modwav/(BYTE[SoundFX][6]) 'FM amount + amwav := 256-(Modwav/(BYTE[SoundFX][7])) 'AM amount + amwav := (BYTE[SoundFX][3]*amwav)>>8 + +''Envelope Generator + if(envphs[SoundVars] == 0) 'Attack + envamp[SoundVars] += BYTE[SoundFX][8] + if(envamp[SoundVars] > 8191) + envamp[SoundVars] := 8191 + envphs[SoundVars] := 1 + if(BYTE[SoundFX][8] == $ff) + envamp[SoundVars] := 8191 + if(envphs[SoundVars] == 1) 'Decay + envamp[SoundVars] -= BYTE[SoundFX][9] + if(envamp[SoundVars] & $8000) + envphs[SoundVars] := 2 + if(envamp[SoundVars] =< (BYTE[SoundFX][10]<<5)) + envphs[SoundVars] := 2 + if(envphs[SoundVars] == 2) 'Sustain + envamp[SoundVars] := (BYTE[SoundFX][10]<<5) + if(envphs[SoundVars] == 3) 'Release + envamp[SoundVars] -= BYTE[SoundFX][11] + if(envamp[SoundVars] & $8000) + envamp[SoundVars] := 4 + + amwav := ((envamp[SoundVars]>>9)*(amwav+1))>>4 + +''Run Length and Outputing + if(SoundFX > 15) + runlen[SoundVars]++ + snd_regs[3+ChannelFX] := (BYTE[SoundFX][2]+fmwav)<<24 'Update Frequency + snd_regs[4+ChannelFX] := (amwav<<4)+(snd_regs[4+ChannelFX] & $0F) 'Update Amplitude + else + snd_regs[4+ChannelFX] := $00 'Mute + + if(BYTE[SoundFX][1] == $ff) '$ff = never stop + runlen[SoundVars] := 0 + + if(runlen[SoundVars] > (BYTE[SoundFX][1]<<5)) 'Duration KeyOff + envphs[SoundVars] := 3 + +WaitCnt(TimeCnt + 52_000) ''Delay for Synth Engine Update. + +DAT + +SineTable byte $80, $8c, $98, $a5, $b0, $bc, $c6, $d0 + byte $da, $e2, $ea, $f0, $f5, $fa, $fd, $fe + byte $ff, $fe, $fd, $fa, $f5, $f0, $ea, $e2 + byte $da, $d0, $c6, $bc, $b0, $a5, $98, $8c + byte $80, $73, $67, $5a, $4f, $43, $39, $2f + byte $25, $1d, $15, $0f, $0a, $05, $02, $01 + byte $00, $01, $02, $05, $0a, $0f, $15, $1d + byte $25, $2f, $39, $43, $4f, $5a, $67, $73 + +Sawtooth byte $ff, $fb, $f7, $f3, $ef, $eb, $e7, $e3 + byte $df, $db, $d7, $d3, $cf, $cb, $c7, $c3 + byte $bf, $bb, $b7, $b3, $af, $ab, $a7, $a3 + byte $9f, $9b, $97, $93, $8f, $8b, $87, $83 + byte $80, $7c, $78, $74, $70, $6c, $68, $64 + byte $60, $5c, $58, $54, $50, $4c, $48, $44 + byte $40, $3c, $38, $34, $30, $2c, $28, $24 + byte $20, $1c, $18, $14, $10, $0c, $08, $04 + +FastSine byte $80, $98, $b0, $c6, $da, $ea, $f5, $fd + byte $ff, $fd, $f5, $ea, $da, $c6, $b0, $98 + byte $80, $67, $4f, $39, $25, $15, $0a, $02 + byte $00, $02, $0a, $15, $25, $39, $4f, $67 + +SqrTable byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $00, $00, $00, $00, $00, $00, $00, $00 + byte $00, $00, $00, $00, $00, $00, $00, $00 + +FastSqr byte $ff, $ff, $ff, $ff, $00, $00, $00, $00 + +'Note LookupTable. +NoteFreqs word $85F3, $8DEA, $965B, $9F4B, $A8C4, $B2CD, $BD6F, $C8B3, $D4A2, $E147, $EEAC, $FCDE 'Top Octave Lookup + +CON +''***************************** +''* WaveTable Synth v1.2 * +''* DPCM Synth v1.1 * +''* (C)2006 Andrew Arsenault * +''***************************** +DAT + org +entry mov dira,Port_Pins 'Setup output pins + + mov ctra,Right_ctra 'Setup Right Audio Channel + mov ctrb,Left_ctra 'Setup Left Audio Channel + + mov ChlA_wave,#256 'Set channel signals. + mov ChlA_offset,#0 'Set channel's offset. + mov ChlA_counter,#0 + + mov Time,#10 + add Time,cnt 'Prepare for asm type WAITCNT loop. + +'MAIN LOOP +update waitcnt Time,Timing_delay 'Wait for CNT = D, then add S into D + + 'Transfer Sound Registers + mov addrregs,par + mov y,NumberOfChannels + + 'Fetch Channel's Registers +transferchl rdlong ChlAp_sampptr,addrregs + add addrregs,#4 + rdlong ChlAp_sampend,addrregs + add addrregs,#4 + rdlong Ch1Ap_samplpp,addrregs + add addrregs,#4 + rdlong Ch1Ap_freq,addrregs + add addrregs,#4 + rdlong ChlAp_keyon,addrregs + + 'Fetch Channel's Static Variables + add addrregs,#8 + rdlong ChlA_offset,addrregs + add addrregs,#4 + rdlong ChlA_counter,addrregs + + 'Run Synth Engine on Channel + call #wvsynth + + 'Store Channel's Static Variables (Tucked Center X move to Wave) + wrlong ChlA_counter,addrregs + sub addrregs,#4 + sub x,#256 + wrlong ChlA_offset,addrregs + sub addrregs,#4 + mov ChlA_wave,x 'Doesn't Waste anything doing this. + wrlong ChlA_wave,addrregs + add addrregs,#12 + + 'Loop Until All Channel's Are Done. + djnz y,#transferchl + + 'Run DPCM Engine + call #dpcm + + 'Mix Channels Together + mov addrregs,par + mov ChlA_wave,#0 + add addrregs,#5*4 + mov y,NumberOfChannels + +mixchls rdlong x,addrregs + add ChlA_wave,x + add addrregs,#8*4 + djnz y,#mixchls + + mov x,DPCM_wave 'Add DPCM + shl x,#2 + add ChlA_wave,x + + shl ChlA_wave,#20 'Convert 12bit singal into a 32bit one. + + 'Update output Channels then repeat again. + mov frqa,ChlA_wave + mov frqb,ChlA_wave + + jmp #update + + + + +'-------------------------Dpcm Engine-------------------------' + +dpcm mov addrregs,par + add addrregs,#192 + + rdlong DPCM_address,addrregs 'Start Address + add addrregs,#4 + rdlong DPCM_runlen,addrregs 'File Lenght + add addrregs,#4 + rdlong DPCM_offset,addrregs 'File Offset + add addrregs,#4 + rdlong DPCM_freq,addrregs 'Playback Speed + add addrregs,#4 + rdlong DPCM_wave,addrregs 'Waveform Amp + + 'Check for if keyon/length is set. + cmp DPCM_offset,DPCM_runlen wc + if_ae jmp #mute_dpcm 'End of file + + 'Freq Timer/Divider and Increase sampling offset + add DPCM_counter,DPCM_freq wc + if_nc jmp #done_dpcm + + 'Decode DPCM + add DPCM_address,DPCM_offset + rdbyte x,DPCM_address 'Fetch Datum + + mov DPCM_delta,x + shr DPCM_delta,#6 + mov y,#1 + shl y,DPCM_delta + mov DPCM_delta,y + + mov y,#1 + shl y,DPCM_phs + test x,y wc + if_c add DPCM_wave,DPCM_delta + if_nc sub DPCM_wave,DPCM_delta + + add DPCM_phs,#1 + cmp DPCM_phs,#6 wc + if_b jmp #done_dpcm + + mov DPCM_phs,#0 + add DPCM_offset,#1 + jmp #done_dpcm + +mute_dpcm mov DPCM_wave, #128 + +done_dpcm mov addrregs,par + add addrregs,#200 + wrlong DPCM_offset,addrregs 'File Offset + add addrregs,#8 + wrlong DPCM_wave,addrregs 'Wave +dpcm_ret ret + +'-----------------------Dpcm Engine End-----------------------' + + + +'-------------------------Sound Engine-------------------------' + + 'Freq Timer/Divider and Increase sampling offset +wvsynth add ChlA_counter,Ch1Ap_freq wc + if_c add ChlA_offset,#1 + + 'Reset sample position and lock at zero if Keyoff. + test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_offset,#0 + + 'Reset(loop) if needed + cmp ChlA_offset,ChlAp_sampend wc + if_ae mov ChlA_offset,Ch1Ap_samplpp + + 'Check BitRate and Set Offset + mov x,ChlA_offset + test ChlAp_keyon,#%0010 wc + if_c shr x,#1 + + 'Fetch WaveTable + mov ChlA_wave,ChlAp_sampptr + add ChlA_wave,x + rdbyte ChlA_wave,ChlA_wave + + 'Check BitRate and Skip if 8bit + test ChlAp_keyon,#%0010 wc + if_nc jmp #skip_4bitsam + + 'Convert 4bit to 8bit + test ChlA_offset,#%0001 wc + if_c shr ChlA_wave,#4 + if_nc and ChlA_wave,#%00001111 + + mov x,ChlA_wave + shl ChlA_wave,#4 + add ChlA_wave,x + + 'Center Amplitude and mute if Keyoff. +skip_4bitsam test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_wave,#128 + + 'Volume Multiply + mov x,#0 + test ChlAp_keyon,#%10000000 wc + if_c add x,ChlA_wave + if_nc add x,#128 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%01000000 wc + if_c add x,ChlA_wave + if_nc add x,#64 + add x,#64 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00100000 wc + if_c add x,ChlA_wave + if_nc add x,#32 + add x,#96 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00010000 wc + if_c add x,ChlA_wave + if_nc add x,#16 + add x,#112 + +'Return Audio as X. +wvsynth_ret ret + +'-----------------------Sound Engine End-----------------------' + +Port_Pins long %00000000_00000000_00000011_00000000 + + '- CTR PLL -------- BPIN --- APIN +Right_ctra long %0_00110_000_00000000_000000_000_001000 +Left_ctra long %0_00110_000_00000000_000000_000_001001 + +Timing_delay long 2500 'Sampling Rate = 32,000.00hz +NumberOfChannels long 6 + +Time res 1 +addrregs res 1 +x res 1 +y res 1 + +'WaveTable Synth Accumulators +ChlA_wave res 1 +ChlA_offset res 1 +ChlA_counter res 1 +ChlAp_sampptr res 1 +ChlAp_sampend res 1 +Ch1Ap_samplpp res 1 +Ch1Ap_freq res 1 +ChlAp_keyon res 1 + +'DPCM Accumulators +DPCM_wave res 1 +DPCM_address res 1 +DPCM_offset res 1 +DPCM_counter res 1 +DPCM_freq res 1 +DPCM_runlen res 1 +DPCM_phs res 1 +DPCM_delta res 1 \ No newline at end of file diff --git a/lib/adm-plx.spin b/lib/adm-plx.spin new file mode 100644 index 0000000..d0820fb --- /dev/null +++ b/lib/adm-plx.spin @@ -0,0 +1,140 @@ +''******************************************************************* +''* Simple Asynchronous Serial Driver v1.3 * +''* Authors: Chip Gracey, Phil Pilgrim, Jon Williams, Jeff Martin * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''******************************************************************* +'' +'' Performs asynchronous serial input/output at low baud rates (~19.2K or lower) using high-level code +'' in a blocking fashion (ie: single-cog (serial-process) rather than multi-cog (parallel-process)). +'' +'' To perform asynchronous serial communication as a parallel process, use the FullDuplexSerial object instead. +'' +'' +'' v1.3 - May 7, 2009 - Updated by Jeff Martin to fix rx method bug, noted by Mike Green and others, where uninitialized +'' variable would mangle received byte. +'' v1.2 - March 26, 2008 - Updated by Jeff Martin to conform to Propeller object initialization standards and compress by 11 longs. +'' v1.1 - April 29, 2006 - Updated by Jon Williams for consistency. +'' +'' +'' The init method MUST be called before the first use of this object. +'' Optionally call finalize after final use to release transmit pin. +'' +'' Tested to 19.2 kbaud with clkfreq of 80 MHz (5 MHz crystal, 16x PLL) + + +VAR + + long sin, sout, inverted, bitTime, rxOkay, txOkay + + +PUB init(rxPin, txPin, baud): Okay +{{Call this method before first use of object to initialize pins and baud rate. + + • For true mode (start bit = 0), use positive baud value. Ex: serial.init(0, 1, 9600) + For inverted mode (start bit = 1), use negative baud value. Ex: serial.init(0, 1, -9600) + • Specify -1 for "unused" rxPin or txPin if only one-way communication desired. + • Specify same value for rxPin and txPin for bi-directional communication on that pin and connect a pull-up/pull-down resistor + to that pin (depending on true/inverted mode) since pin will set it to hi-z (input) at the end of transmission to avoid + electrical conflicts. See "Same-Pin (Bi-Directional)" examples, below. + + EXAMPLES: + + Standard Two-Pin Bi-Directional True/Inverted Modes Standard One-Pin Uni-Directional True/Inverted Mode + Ex: serial.init(0, 1, ±9600) Ex: serial.init(0, -1, ±9600) -or- serial.init(-1, 0, ±9600) + ┌────────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ + │Propeller P0├─────────────┤I/O Device│ │Propeller P0├───────────────┤I/O Device│ + │ P1├─────────────┤ │ └────────────┘ └──────────┘ + └────────────┘ └──────────┘ + + + + Same-Pin (Bi-Directional) True Mode Same-Pin (Bi-Directional) Inverted Mode + Ex: serial.init(0, 0, 9600) Ex: serial.init(0, 0, -9600) +  ┌────────────┐ ┌──────────┐ + │ │Propeller P0├─────┳─────┤I/O Device│ +  4.7 kΩ └────────────┘ │ └──────────┘ + ┌────────────┐ │ ┌──────────┐  4.7 kΩ + │Propeller P0├─────┻─────┤I/O Device│ │ + └────────────┘ └──────────┘  +}} + + finalize ' clean-up if restart + + rxOkay := rxPin > -1 ' receiving? + txOkay := txPin > -1 ' transmitting? + + sin := rxPin & $1F ' set rx pin + sout := txPin & $1F ' set tx pin + + inverted := baud < 0 ' set inverted flag + bitTime := clkfreq / ||baud ' calculate serial bit time + + return rxOkay | TxOkay + + +PUB finalize +{{Call this method after final use of object to release transmit pin.}} + + if txOkay ' if tx enabled + dira[sout]~ ' float tx pin + rxOkay := txOkay := false + + +PUB rx: rxByte | t +{{ Receive a byte; blocks caller until byte received. }} + + if rxOkay + dira[sin]~ ' make rx pin an input + waitpeq(inverted & |< sin, |< sin, 0) ' wait for start bit + t := cnt + bitTime >> 1 ' sync + 1/2 bit + repeat 8 + waitcnt(t += bitTime) ' wait for middle of bit + rxByte := ina[sin] << 7 | rxByte >> 1 ' sample bit + waitcnt(t + bitTime) ' allow for stop bit + + rxByte := (rxByte ^ inverted) & $FF ' adjust for mode and strip off high bits + + +PUB tx(txByte) | t +{{ Transmit a byte; blocks caller until byte transmitted. }} + + if txOkay + outa[sout] := !inverted ' set idle state + dira[sout]~~ ' make tx pin an output + txByte := ((txByte | $100) << 2) ^ inverted ' add stop bit, set mode + t := cnt ' sync + repeat 10 ' start + eight data bits + stop + waitcnt(t += bitTime) ' wait bit time + outa[sout] := (txByte >>= 1) & 1 ' output bit (true mode) + + if sout == sin + dira[sout]~ ' release to pull-up/pull-down + + +PUB str(strAddr) +{{ Transmit z-string at strAddr; blocks caller until string transmitted. }} + + if txOkay + repeat strsize(strAddr) ' for each character in string + tx(byte[strAddr++]) ' write the character + +{{ + + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/adm-rtc.spin b/lib/adm-rtc.spin new file mode 100644 index 0000000..f588caa --- /dev/null +++ b/lib/adm-rtc.spin @@ -0,0 +1,352 @@ +{{ +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Real Time Clock Engine │ +│ │ +│ Author: Kwabena W. Agyeman │ +│ Updated: 11/22/2009 │ +│ Designed For: P8X32A │ +│ │ +│ Copyright (c) 2009 Kwabena W. Agyeman │ +│ See end of file for terms of use. │ +│ │ +│ Driver Info: │ +│ │ +│ The RTCEngine interfaces with the DS1307RTC. │ +│ │ +│ The driver is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │ +│ so port B will not be operational. │ +│ │ +│ Nyamekye, │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + +CON + '' + '' 3.3V + ''  + '' │ + ''  10KΩ + '' │ + Data_Pin = 29 '' ─┻─ SDA + '' + '' 3.3V + ''  + '' │ + ''  10KΩ + '' │ + Clock_Pin = 28 '' ─┻─ SCL + + RTC_Address = %1101000 + +CON + + ' For use with "getDay" and "setDay". + + #1, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday + + ' For use with "getMonth" and "setMonth". + + #1, January, February, March, April, May, June, July, August, September, October, November, December + +PUB getSeconds '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current second (0 - 59) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return BCDToNumber(getRAM(0)) + +PUB getMinutes '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current minute (0 - 59) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return BCDToNumber(getRAM(1)) + +PUB getHours '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current hour (0 - 23) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return BCDToNumber(getRAM(2)) + +PUB getDay '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current day (1 - 7) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return BCDToNumber(getRAM(3)) + +PUB getDate '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current date (1 - 31) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return BCDToNumber(getRAM(4)) + +PUB getMonth '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current month (1 - 12) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return BCDToNumber(getRAM(5)) + +PUB getYear '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the current year (2000 - 2099) from the real time clock. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (BCDToNumber(getRAM(6)) + 2000) + +PUB setSeconds(seconds) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock seconds. │ +'' │ │ +'' │ Seconds - Number to set the seconds to between 0 - 59. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(0, numberToBCD(((seconds <# 59) #> 0))) + +PUB setMinutes(minutes) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock minutes. │ +'' │ │ +'' │ Minutes - Number to set the minutes to between 0 - 59. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(1, numberToBCD(((minutes <# 59) #> 0))) + +PUB setHours(hours) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock hours. │ +'' │ │ +'' │ Hours - Number to set the hours to between 0 - 23. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(2, numberToBCD(((hours <# 23) #> 0))) + +PUB setDay(day) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock day. │ +'' │ │ +'' │ Day - Number to set the day to between 1 - 7. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(3, numberToBCD(((day <# 7) #> 1))) + +PUB setDate(date) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock date. │ +'' │ │ +'' │ Date - Number to set the date to between 1 - 31. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(4, numberToBCD(((date <# 31) #> 1))) + +PUB setMonth(month) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock month. │ +'' │ │ +'' │ Month - Number to set the month to between 1 - 12. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(5, numberToBCD(((month <# 12) #> 1))) + +PUB setYear(year) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the current real time clock year. │ +'' │ │ +'' │ Year - Number to set the year to between 2000 - 2099. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(6, numberToBCD((((year - 2000) <# 99) #> 0))) + +PUB setSQWOUTFrequency(frequency) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Turns the square wave on. │ +'' │ │ +'' │ Frequency - Selects the frequency of the square wave pin. (0 - 1HZ), (1 - 4.096KHZ), (2 - 8.192KHZ), (3 - 32.768KHZ). │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(7, ($10 | ((frequency <# 3) #> 0))) + +PUB setSQWOUTState(state) '' 13 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Turns the square wave off. │ +'' │ │ +'' │ State - Selects the state of the square wave pin. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRAM(7, ((not(not(state))) & $80)) + +PUB setNVSRAM(index, value) '' 14 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). │ +'' │ │ +'' │ Index - The location in NVRAM to set (0 - 55). │ +'' │ Value - The value (0 - 255) to change the location to. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + setRam((((index <# 55) #> 0) + 8), value) + +PUB getNVSRAM(index) '' 12 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Gets the selected NVSRAM value at the index (0 - 55). │ +'' │ │ +'' │ Returns the selected location's value (0 - 255). │ +'' │ │ +'' │ Index - The location in NVRAM to get (0 - 55). │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return getRam(((index <# 55) #> 0) + 8) + +PUB pauseForSeconds(number) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Pauses execution for a number of seconds. │ +'' │ │ +'' │ Returns a puesdo random value derived from the current clock frequency and the time when called. │ +'' │ │ +'' │ Number - Number of seconds to pause for between 0 and 2,147,483,647. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result := cnt + + repeat (number #> 0) + result += clkfreq + waitcnt(result) + +PUB pauseForMilliseconds(number) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Pauses execution for a number of milliseconds. │ +'' │ │ +'' │ Returns a puesdo random value derived from the current clock frequency and the time when called. │ +'' │ │ +'' │ Number - Number of milliseconds to pause for between 0 and 2,147,483,647. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result := cnt + + repeat (number #> 0) + result += (clkfreq / 1000) + waitcnt(result) + +PRI BCDToNumber(BCD) ' 4 Stack Longs + + return (((BCD >> 4) * 10) + (BCD & $F)) + +PRI numberToBCD(number) ' 4 Stack Longs + + return (((number / 10) << 4) + (number // 10)) + +PRI setRAM(index, value) ' 9 Stack Longs + + startDataTransfer + transmitPacket(constant(RTC_Address << 1)) + transmitPacket(index) + transmitPacket(value) + stopDataTransfer + +PRI getRAM(index) ' 8 Stack Longs + + startDataTransfer + transmitPacket(constant(RTC_Address << 1)) + transmitPacket(index) + stopDataTransfer + + ' Repeated Start + + startDataTransfer + transmitPacket(constant((RTC_Address << 1) | 1)) + result := receivePacket(false) + stopDataTransfer + +PRI transmitPacket(value) ' 4 Stack Longs + + value := ((!value) >< 8) + + repeat 8 + + dira[constant(((Data_Pin <# 31) #> 0))] := value + + dira[constant(((Clock_Pin <# 31) #> 0))] := false + + dira[constant(((Clock_Pin <# 31) #> 0))] := true + + value >>= 1 + + dira[constant(((Data_Pin <# 31) #> 0))] := false + + dira[constant(((Clock_Pin <# 31) #> 0))] := false + dira[constant(((Clock_Pin <# 31) #> 0))] := true + + dira[constant(((Data_Pin <# 31) #> 0))] := true + +PRI receivePacket(aknowledge) ' 4 Stack Longs + + dira[constant(((Data_Pin <# 31) #> 0))] := false + + repeat 8 + + result <<= 1 + + dira[constant(((Clock_Pin <# 31) #> 0))] := false + + result |= ina[constant(((Data_Pin <# 31) #> 0))] + + dira[constant(((Clock_Pin <# 31) #> 0))] := true + + dira[constant(((Data_Pin <# 31) #> 0))] := aknowledge + + dira[constant(((Clock_Pin <# 31) #> 0))] := false + dira[constant(((Clock_Pin <# 31) #> 0))] := true + + dira[constant(((Data_Pin <# 31) #> 0))] := true + +PRI startDataTransfer ' 3 Stack Longs + + dira[constant(((Data_Pin <# 31) #> 0))] := true + dira[constant(((Clock_Pin <# 31) #> 0))] := true + +PRI stopDataTransfer ' 3 Stack Longs + + dira[constant(((Clock_Pin <# 31) #> 0))] := false + dira[constant(((Data_Pin <# 31) #> 0))] := false + +{{ + +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the │ +│Software is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the │ +│Software. │ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/adm-sid-combined-waveforms.bin b/lib/adm-sid-combined-waveforms.bin new file mode 100644 index 0000000..d95fe68 Binary files /dev/null and b/lib/adm-sid-combined-waveforms.bin differ diff --git a/lib/adm-sid.spin b/lib/adm-sid.spin new file mode 100644 index 0000000..1372c4d --- /dev/null +++ b/lib/adm-sid.spin @@ -0,0 +1,795 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ SIDcog - SID/MOS8580 emulator V0.80 (C) 2010-02 Johannes Ahlebrand │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ TERMS OF USE: Parallax Object Exchange License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} +{ + +11-07-2010-dr235 - änderung in setWaveform + +} + + +CON + PAL = 985248.0 + NTSC = 1022727.0 + MAXF = 1031000.0 + TRIANGLE = 16 + SAW = 32 + SQUARE = 64 + NOISE = 128 + + C64_CLOCK_FREQ = PAL + ' ___ + CUTOFF_LIMIT = 1300' │ + LP_MAX_CUTOFF = 10' │ + BP_MAX_CUTOFF = 11' │ Don't alter these unless you know what you are doing. ;) + FILTER_OFFSET = 27' │ + DECAY_DIVIDE_REF = $6C6C6C6C' │ + NOISE_ADD = $979D21B5' │ + NOISE_ROTATE = 28' ___│ + +PUB start(right,left) + arg1 := $18000000 | left + arg2 := $18000000 | right + r1 := ((1<>3 + +PUB setFilterMask(ch1,ch2,ch3) + byte[@Filter3] := (byte[@Filter3]&$F0) | (ch1&1) | (ch2&2) | (ch3&4) + +PUB setFilterType(lp,bp,hp) + byte[@volume] := (byte[@volume]&$0F) | (lp&16) | (bp&32) | (hp&64) + +PUB enableRingmod(ch1,ch2,ch3) + byte[@ch1_controlRegister] := (byte[@ch1_controlRegister]&$FB) | (ch1&4) + byte[@ch2_controlRegister] := (byte[@ch2_controlRegister]&$FB) | (ch2&4) + byte[@ch3_controlRegister] := (byte[@ch3_controlRegister]&$FB) | (ch3&4) + +PUB enableSynchronization(ch1,ch2,ch3) + byte[@ch1_controlRegister] := (byte[@ch1_controlRegister]&$FD) | (ch1&2) + byte[@ch2_controlRegister] := (byte[@ch2_controlRegister]&$FD) | (ch2&2) + byte[@ch3_controlRegister] := (byte[@ch3_controlRegister]&$FD) | (ch3&2) + +dat org 0 +' +' Assembly SID emulator +' +SIDEMU mov dira, r1 + mov ctra, arg1 + mov ctrb, arg2 + mov waitCounter, cnt + add waitCounter, sampleRate +'----------------------------------------------------------- +mainLoop call #getRegisters + call #SID + call #filter + call #mixer + jmp #mainLoop +'----------------------------------------------------------- + +' +' Read all SID-registers from hub memory and convert +' them to more convenient representations. +' +getRegisters mov tempValue, par ' Read in first long ( 16bit frequency / 16bit pulse-width ) + rdlong frequency1, tempValue + mov pulseWidth1, frequency1 + shl pulseWidth1, #4 ' Shift in "12 bit" pulse width value( make it 32 bits ) + andn pulseWidth1, mask20bit + and frequency1, mask16bit ' Mask out 16 bit frequency value + shl frequency1, #13 +'----------------------------------------------------------- + add tempValue, #4 ' Read in next long ( Control register / ADSR ) + rdlong selectedWaveform1, tempValue + mov controlRegister1, selectedWaveform1 +'----------------------------------------------------------- + mov arg1, selectedWaveform1 '| + shr arg1, #8 '| + call #getDecay '| + mov decay1, r1 '| + shr arg1, #4 '| + call #getAttack '| + mov attack1, r1 '| Convert 4bit ADSR "presets" to their corresponding + shr arg1, #4 '| 32bit values using attack/decay tables. + call #getDecay '| + mov release1, r1 '| + mov sustain1, selectedWaveform1 '| + shl sustain1, #8 '| + andn sustain1, mask28bit '| +'----------------------------------------------------------- + shr selectedWaveform1, #4 ' Mask out waveform selection + and selectedWaveform1, #15 wz, wc +'----------------------------------------------------------- + test controlRegister1, #1 wc + cmp envelopeState1, #2 wz + if_z_and_c mov envelopeState1, #0 + if_nz_and_nc mov envelopeState1, #2 + +'─────────────────────────────────────────────────────────── +' Channel 2 +'─────────────────────────────────────────────────────────── + add tempValue, #4 ' Read in first long ( 16bit frequency / 16bit pulse-width ) + rdlong frequency2, tempValue + mov pulseWidth2, frequency2 + shl pulseWidth2, #4 ' Shift in "12 bit" pulse width value( make it 32 bits ) + andn pulseWidth2, mask20bit + and frequency2, mask16bit ' Mask out 16 bit frequency value + shl frequency2, #13 +'----------------------------------------------------------- + add tempValue, #4 ' Read in next long ( Control register / ADSR ) + rdlong selectedWaveform2, tempValue + mov controlRegister2, selectedWaveform2 +'----------------------------------------------------------- + mov arg1, selectedWaveform2 '| + shr arg1, #8 '| + call #getDecay '| + mov decay2, r1 '| + shr arg1, #4 '| + call #getAttack '| + mov attack2, r1 '| Convert 4bit ADSR "presets" to their corresponding + shr arg1, #4 '| 32bit values using attack/decay tables. + call #getDecay '| + mov release2, r1 '| + mov sustain2, selectedWaveform2 '| + shl sustain2, #8 '| + andn sustain2, mask28bit '| +'----------------------------------------------------------- + shr selectedWaveform2, #4 ' Mask out waveform selection + and selectedWaveform2, #15 wz, wc +'----------------------------------------------------------- + test controlRegister2, #1 wc + cmp envelopeState2, #2 wz + if_z_and_c mov envelopeState2, #0 + if_nz_and_nc mov envelopeState2, #2 + +'─────────────────────────────────────────────────────────── +' Channel 3 +'─────────────────────────────────────────────────────────── + add tempValue, #4 ' Read in first long ( 16bit frequency / 16bit pulse-width ) + rdlong frequency3, tempValue ' + mov pulseWidth3, frequency3 + shl pulseWidth3, #4 ' Shift in "12 bit" pulse width value( make it 32 bits ) + andn pulseWidth3, mask20bit + and frequency3, mask16bit ' Mask out 16 bit frequency value + shl frequency3, #13 +'----------------------------------------------------------- + add tempValue, #4 ' Read in next long ( Control register / ADSR ) + rdlong selectedWaveform3, tempValue + mov controlRegister3, selectedWaveform3 +'----------------------------------------------------------- + mov arg1, selectedWaveform3 '| + shr arg1, #8 '| + call #getDecay '| + mov decay3, r1 '| + shr arg1, #4 '| + call #getAttack '| + mov attack3, r1 '| Convert 4bit ADSR "presets" to their corresponding + shr arg1, #4 '| 32bit values using attack/decay tables. + call #getDecay '| + mov release3, r1 '| + mov sustain3, selectedWaveform3 '| + shl sustain3, #8 '| + andn sustain3, mask28bit '| +'----------------------------------------------------------- + shr selectedWaveform3, #4 ' Mask out waveform selection + and selectedWaveform3, #15 wz, wc +'----------------------------------------------------------- + test controlRegister3, #1 wc + cmp envelopeState3, #2 wz + if_z_and_c mov envelopeState3, #0 + if_nz_and_nc mov envelopeState3, #2 + +'─────────────────────────────────────────────────────────── +' Filter / Volume +'─────────────────────────────────────────────────────────── + add tempValue, #4 '| + rdlong filterControl, tempValue '| + mov filterCutoff, filterControl '| +'----------------------------------------------------------- + shr filterControl, #16 '| Filter control +'----------------------------------------------------------- + shr filterCutoff, #5 '| + andn filterCutoff, #7 '| + mov tempValue, filterControl '| + and tempValue, #7 '| Filter cutoff frequency + or filterCutoff, tempValue '| + and filterCutoff, mask11bit '| + add filterCutoff, filterOffset '| +'----------------------------------------------------------- + mov filterMode_Volume, filterControl '| Main volume and filter mode + shr filterMode_Volume, #8 '| +'----------------------------------------------------------- + mov filterResonance,filterControl '| + and filterResonance,#$F0 '| + shr filterResonance,#5 '| + add filterResonance,#resTable '| Filter Resonance level (Ariba) + movs rdRes,filterResonance '| + nop '| +rdRes mov filterResonance,0-0 '| + +getRegisters_ret ret + +' +' Calculate sid samples channel 1-3 and store in out1-out3 +' + +'─────────────────────────────────────────────────────────── +' Increment phase accumulator 1-3 and handle syncing +'─────────────────────────────────────────────────────────── +SID add phaseAccumulator1, frequency1 wc ' Add frequency value to phase accumulator 1 + if_nc andn controlRegister2, #2 + test controlRegister2, #10 wz ' Sync oscilator 2 to oscilator 1 if sync = on + if_nz mov phaseAccumulator2, #0 ' Or reset counter 2 when bit 4 of control register is 1 +'----------------------------------------------------------- + add phaseAccumulator2, frequency2 wc + if_nc andn controlRegister3, #2 + test controlRegister3, #10 wz ' Sync oscilator 3 to oscilator 2 if sync = on + if_nz mov phaseAccumulator3, #0 ' Or reset oscilator 3 when bit 4 of control register is 1 +'----------------------------------------------------------- + add phaseAccumulator3, frequency3 wc + if_nc andn controlRegister1, #2 + test controlRegister1, #10 wz ' Sync oscilator 1 to oscilator 3 if sync = on + if_nz mov phaseAccumulator1, #0 ' Or reset oscilator 1 when bit 4 of control register is 1 + +'─────────────────────────────────────────────────────────── +' Waveform shaping channel 1 -> arg1 +'─────────────────────────────────────────────────────────── +Triangle1 tjz selectedWaveform1, #Triangle2 + cmp selectedWaveform1, #1 wz + if_nz jmp #Saw1 + abs arg1, phaseAccumulator1 + max arg1, mask31bit + test controlRegister1, #4 wc '| + if_c test phaseAccumulator3, val31bit wc '| These 3 lines handles ring modulation + if_c xor arg1, mask32bit '| + shl arg1, #1 + jmp #Env_Attack1 +'----------------------------------------------------------- +Saw1 cmp selectedWaveform1, #2 wz + if_z mov arg1, phaseAccumulator1 + if_z jmp #Env_Attack1 +'----------------------------------------------------------- +Square1 cmp selectedWaveform1, #4 wz + if_z sub pulseWidth1, phaseAccumulator1 wc ' C holds the pulse width modulated square wave + if_z muxc arg1, mask32bit + if_z jmp #Env_Attack1 +'----------------------------------------------------------- +Noise1 cmp selectedWaveform1, #8 wz + if_nz jmp #Combined1 + mov tempValue, phaseAccumulator1 + and tempValue, mask28bit + sub tempValue, frequency1 wc + if_z_and_c ror noiseValue1, NOISE_ROTATE + if_z_and_c add noiseValue1, noiseAdd + if_z mov arg1, noiseValue1 + jmp #Env_Attack1 +'----------------------------------------------------------- +Combined1 sub selectedWaveform1, #4 + mins selectedWaveform1, #0 + shl selectedWaveform1, #8 + mov tempValue, phaseAccumulator1 + shr tempValue, #24 + add selectedWaveform1, tempValue + add selectedWaveform1, combTableAddr + rdbyte arg1, selectedWaveform1 + shl arg1, #24 + +'─────────────────────────────────────────────────────────── +' Envelope shaping channel 1 -> arg2 +'─────────────────────────────────────────────────────────── +Env_Attack1 cmp envelopeState1, #0 wz + if_nz jmp #InitDecay1 + add envelopeLevel1, attack1 wc + if_c mov envelopeLevel1, mask32bit + if_c mov envelopeState1, #1 + mov decayDivide1, #0 + jmp #Amplitude1 +'----------------------------------------------------------- +InitDecay1 mov tempValue, decayDivideRef + shr tempValue, decayDivide1 + cmp envelopeLevel1, tempValue wc + if_c add decayDivide1, #1 +'----------------------------------------------------------- +Env_Decay1 cmp envelopeState1, #1 wz + if_nz jmp #Env_Release1 + shr decay1, decayDivide1 + sub envelopeLevel1, decay1 + min envelopeLevel1, sustain1 wc + jmp #Amplitude1 +'----------------------------------------------------------- +Env_Release1 cmp envelopeState1, #2 wz + if_nz jmp #Amplitude1 + shr release1, decayDivide1 + cmpsub envelopeLevel1, release1 + +'─────────────────────────────────────────────────────────── +'Calculate sample out1 = arg1 * arg2 (waveform * amplitude) +'─────────────────────────────────────────────────────────── +Amplitude1 shr arg1, #16 + sub arg1, val15bit + mov arg2, envelopeLevel1 + shr arg2, #22 + call #multiply + mov out1, r1 + +'─────────────────────────────────────────────────────────── +' Waveform shaping channel 2 -> arg1 +'─────────────────────────────────────────────────────────── +Triangle2 tjz selectedWaveform2, #Triangle3 + cmp selectedWaveform2, #1 wz + if_nz jmp #Saw2 + abs arg1, phaseAccumulator2 + max arg1, mask31bit + test controlRegister2, #4 wc '| + if_c test phaseAccumulator1, val31bit wc '| These 3 lines handles ring modulation + if_c xor arg1, mask32bit '| + shl arg1, #1 + jmp #Env_Attack2 +'----------------------------------------------------------- +Saw2 cmp selectedWaveform2, #2 wz + if_z mov arg1, phaseAccumulator2 + if_z jmp #Env_Attack2 +'----------------------------------------------------------- +Square2 cmp selectedWaveform2, #4 wz + if_z sub pulseWidth2, phaseAccumulator2 wc ' C holds the pulse width modulated square wave + if_z muxc arg1, mask32bit + if_z jmp #Env_Attack2 +'----------------------------------------------------------- +Noise2 cmp selectedWaveform2, #8 wz + if_nz jmp #Combined2 + mov tempValue, phaseAccumulator2 + and tempValue, mask28bit + sub tempValue, frequency2 wc + if_z_and_c ror noiseValue2, NOISE_ROTATE + if_z_and_c add noiseValue2, noiseAdd + if_z mov arg1, noiseValue2 + jmp #Env_Attack2 +'----------------------------------------------------------- +Combined2 sub selectedWaveform2, #4 + mins selectedWaveform2, #0 + shl selectedWaveform2, #8 + mov tempValue, phaseAccumulator2 + shr tempValue, #24 + add selectedWaveform2, tempValue + add selectedWaveform2, combTableAddr + rdbyte arg1, selectedWaveform2 + shl arg1, #24 + +'─────────────────────────────────────────────────────────── +' Envelope shaping channel 2 -> arg2 +'─────────────────────────────────────────────────────────── +Env_Attack2 cmp envelopeState2, #0 wz + if_nz jmp #InitDecay2 + add envelopeLevel2, attack2 wc + if_c mov envelopeLevel2, mask32bit + if_c mov envelopeState2, #1 + mov decayDivide2, #0 + jmp #Amplitude2 +'----------------------------------------------------------- +InitDecay2 mov tempValue, decayDivideRef + shr tempValue, decayDivide2 + cmp envelopeLevel2, tempValue wc + if_c add decayDivide2, #1 +'----------------------------------------------------------- +Env_Decay2 cmp envelopeState2, #1 wz + if_nz jmp #Env_Release2 + shr decay2, decayDivide2 + sub envelopeLevel2, decay2 + min envelopeLevel2, sustain2 wc + jmp #Amplitude2 +'----------------------------------------------------------- +Env_Release2 cmp envelopeState2, #2 wz + if_nz jmp #Amplitude2 + shr release2, decayDivide2 + cmpsub envelopeLevel2, release2 + +'─────────────────────────────────────────────────────────── +'Calculate sample out2 = arg1 * arg2 (waveform * amplitude) +'─────────────────────────────────────────────────────────── +Amplitude2 shr arg1, #16 + sub arg1, val15bit + mov arg2, envelopeLevel2 + shr arg2, #22 + call #multiply + mov out2, r1 + +'─────────────────────────────────────────────────────────── +' Waveform shaping channel 3 -> arg1 +'─────────────────────────────────────────────────────────── +Triangle3 tjz selectedWaveform3, #SID_ret + cmp selectedWaveform3, #1 wz + if_nz jmp #Saw3 + abs arg1, phaseAccumulator3 + max arg1, mask31bit + test controlRegister3, #4 wc '| + if_c test phaseAccumulator2, val31bit wc '| These 3 lines handles ring modulation + if_c xor arg1, mask32bit '| + shl arg1, #1 + jmp #Env_Attack3 +'----------------------------------------------------------- +Saw3 cmp selectedWaveform3, #2 wz + if_z mov arg1, phaseAccumulator3 + if_z jmp #Env_Attack3 +'----------------------------------------------------------- +Square3 cmp selectedWaveform3, #4 wz + if_z sub pulseWidth3, phaseAccumulator3 wc ' C holds the pulse width modulated square wave + if_z muxc arg1, mask32bit + if_z jmp #Env_Attack3 +'----------------------------------------------------------- +Noise3 cmp selectedWaveform3, #8 wz + if_nz jmp #Combined3 + mov tempValue, phaseAccumulator3 + and tempValue, mask28bit + sub tempValue, frequency3 wc + if_z_and_c ror noiseValue3, NOISE_ROTATE + if_z_and_c add noiseValue3, noiseAdd + if_z mov arg1, noiseValue3 + jmp #Env_Attack3 +'----------------------------------------------------------- +Combined3 sub selectedWaveform3, #4 + mins selectedWaveform3, #0 + shl selectedWaveform3, #8 + mov tempValue, phaseAccumulator3 + shr tempValue, #24 + add selectedWaveform3, tempValue + add selectedWaveform3, combTableAddr + rdbyte arg1, selectedWaveform3 + shl arg1, #24 + +'─────────────────────────────────────────────────────────── +' Envelope shaping channel 3 -> arg2 +'─────────────────────────────────────────────────────────── +Env_Attack3 cmp envelopeState3, #0 wz + if_nz jmp #InitDecay3 + add envelopeLevel3, attack3 wc + if_c mov envelopeLevel3, mask32bit + if_c mov envelopeState3, #1 + mov decayDivide3, #0 + jmp #Amplitude3 +'----------------------------------------------------------- +InitDecay3 mov tempValue, decayDivideRef + shr tempValue, decayDivide3 + cmp envelopeLevel3, tempValue wc + if_c add decayDivide3, #1 +'----------------------------------------------------------- +Env_Decay3 cmp envelopeState3, #1 wz + if_nz jmp #Env_Release3 + shr decay3, decayDivide3 + sub envelopeLevel3, decay3 + min envelopeLevel3, sustain3 wc + jmp #Amplitude3 +'----------------------------------------------------------- +Env_Release3 cmp envelopeState3, #2 wz + if_nz jmp #Amplitude3 + shr release3, decayDivide3 + cmpsub envelopeLevel3, release3 + +'─────────────────────────────────────────────────────────── +'Calculate sample out3 = arg1 * arg2 (waveform * amplitude) +'─────────────────────────────────────────────────────────── +Amplitude3 shr arg1, #16 + sub arg1, val15bit + mov arg2, envelopeLevel3 + shr arg2, #22 + call #multiply + mov out3, r1 +SID_ret ret + +' +' Handle multi-mode filtering +' +filter mov ordinaryOutput, #0 '| + mov highPassFilter, #0 '| + test filterControl, #1 wc '| + if_c add highPassFilter, out1 '| + if_nc add ordinaryOutput, out1 '| + test filterControl, #2 wc '| Route channels trough the filter + if_c add highPassFilter, out2 '| or bypass them + if_nc add ordinaryOutput, out2 '| + test filterControl, #4 wc '| + if_c add highPassFilter, out3 '| + if_nc add ordinaryOutput, out3 '| +'----------------------------------------------------------- + mov tempValue, bandPassFilter '| + sar tempValue, filterResonance '| High pass filter + sub highPassFilter, tempValue '| + sub highPassFilter, lowPassFilter '| +'----------------------------------------------------------- + mov arg1, highPassFilter '| + sar arg1, #BP_MAX_CUTOFF '| + mov arg2, filterCutoff '| Band pass filter + max arg2, maxCutoff + call #multiplyNS '| + add bandPassFilter, r1 '| +'----------------------------------------------------------- + mov arg1, bandPassFilter '| + sar arg1, #LP_MAX_CUTOFF '| + mov arg2, filterCutoff '| Low pass filter + call #multiplyNS '| + add lowPassFilter, r1 '| +'----------------------------------------------------------- + mov filterOutput, #0 '| + test filterMode_Volume, #16 wc '| + if_c add filterOutput, lowPassFilter '| + test filterMode_Volume, #32 wc '| Enable/Disable + if_c add filterOutput, bandPassFilter '| Low/Band/High pass filtering + test filterMode_Volume, #64 wc '| + if_c add filterOutput, highPassFilter '| +filter_ret ret + +' +' Mix channels and update FRQA/FRQB PWM-values +' +mixer mov arg1, filterOutput + add arg1, ordinaryOutput +'----------------------------------------------------------- + maxs arg1, clipLevelHigh '| + mins arg1, clipLevelLow '| + mov arg2, filterMode_Volume '| Main volume adjustment + and arg2, #15 '| + call #multiplyNS '| +'----------------------------------------------------------- + add r1, val31bit ' DC offset + waitcnt waitCounter, sampleRate ' Wait until the right time to update + mov FRQA, r1 '| Update PWM values in FRQA/FRQB + mov FRQB, r1 '| + mov tempValue, par + add tempValue, #28 + wrlong r1, tempValue '| Write the sample to hub ram +mixer_ret ret + +' +' Get attack value r1 = attackTable[arg1] +' +getAttack mov arg2, arg1 + and arg1, #15 + add arg1, #ADSRTable + movs :indexed1, arg1 + mov arg1, arg2 +:indexed1 mov r1, 0 +getAttack_ret ret + +' +' Get decay value r1 = decayTable[arg1] +' +getDecay mov arg2, arg1 + and arg1, #15 + add arg1, #ADSRTable + movs :indexed2, arg1 + mov arg1, arg2 +:indexed2 mov r1, 0 +getDecay_ret ret + +' +' Multiplication r1(I32) = arg1(I32) * arg2(I32) +' +multiply cmp arg1, arg2 wc 'If arg1 is less than arg2 C is set + if_c xor arg1, arg2 'Swap arguments + if_c xor arg2, arg1 + if_c xor arg1, arg2 +multiplyNS mov r1, #0 'Clear 32-bit product +:multiLoop shr arg2, #1 wc, wz 'Half multiplyer and get LSB of it + if_c add r1, arg1 'Add multiplicand to product on C + shl arg1, #1 'Double multiplicand + if_nz jmp #:multiLoop 'Check nonzero multiplier to continue multiplication +multiplyNS_ret +multiply_ret ret + +' +' Variables, tables, masks and reference values +' + +ADSRTable long 68719476 '2 ms + long 17179870 '8 ms + long 8589934 '16 ms + long 5726622 '24 ms + long 3616814 '38 ms + long 2454268 '56 ms + long 2021160 '68 ms + long 1717986 '80 ms + long 1374390 '100 ms + long 549754 '250 ms + long 274876 '500 ms + long 171798 '800 ms + long 137438 '1 s + long 45812 '3 s + long 27486 '5 s + long 17180 '8 s + +resTable long 0,1,1,1,1,1,2,2 '(Ariba) + +'Masks and reference values +mask32bit long $ffffffff +mask31bit long $7fffffff +mask28bit long $fffffff +mask24bit long $ffffff +mask20bit long $fffff +mask16bit long $ffff +mask11bit long $7ff +val31bit long $80000000 +val28bit long $10000000 +val27bit long $8000000 +val16bit long $10000 +val15bit long $8000 +clipLevelHigh long $8000000 +clipLevelLow long-$8000000 +noiseAdd long NOISE_ADD 'Value to add to the noise generator every noise update +filterOffset long FILTER_OFFSET +decayDivideRef long DECAY_DIVIDE_REF +maxCutoff long CUTOFF_LIMIT +sampleRate long 0 'clocks between samples ( ~31.250 khz ) +combTableAddr long 0 + +'Setup and subroutine parameters +arg1 long 1 +arg2 long 1 +r1 long 1 + +'Sid variables +envelopeLevel1 long 1 +envelopeLevel2 long 1 +envelopeLevel3 long 1 +controlRegister1 res 1 +controlRegister2 res 1 +controlRegister3 res 1 +frequency1 res 1 +frequency2 res 1 +frequency3 res 1 +phaseAccumulator1 res 1 +phaseAccumulator2 res 1 +phaseAccumulator3 res 1 +pulseWidth1 res 1 +pulseWidth2 res 1 +pulseWidth3 res 1 +selectedWaveform1 res 1 +selectedWaveform2 res 1 +selectedWaveform3 res 1 +envelopeState1 res 1 +envelopeState2 res 1 +envelopeState3 res 1 +noiseValue1 res 1 +noiseValue2 res 1 +noiseValue3 res 1 +attack1 res 1 +attack2 res 1 +attack3 res 1 +decay1 res 1 +decay2 res 1 +decay3 res 1 +sustain1 res 1 +sustain2 res 1 +sustain3 res 1 +release1 res 1 +release2 res 1 +release3 res 1 +decayDivide1 res 1 +decayDivide2 res 1 +decayDivide3 res 1 +out1 res 1 +out2 res 1 +out3 res 1 +filterResonance res 1 +filterCutoff res 1 +highPassFilter res 1 +bandPassFilter res 1 +lowPassFilter res 1 +filterMode_Volume res 1 +filterControl res 1 +filterOutput res 1 +ordinaryOutput res 1 + +'Working variables +waitCounter res 1 +tempValue res 1 + fit + +dat + combinedWaveforms file "adm-sid-combined-waveforms.bin" + +VAR + byte ch1_frequencyLo + byte ch1_frequencyHi + byte ch1_pulseWidthLo + byte ch1_pulseWidthHi + byte ch1_controlRegister + byte ch1_attackDecay + byte ch1_sustainRelease + byte ch1_dummy + byte ch2_frequencyLo + byte ch2_frequencyHi + byte ch2_pulseWidthLo + byte ch2_pulseWidthHi + byte ch2_controlRegister + byte ch2_attackDecay + byte ch2_sustainRelease + byte ch2_dummy + byte ch3_frequencyLo + byte ch3_frequencyHi + byte ch3_pulseWidthLo + byte ch3_pulseWidthHi + byte ch3_controlRegister + byte ch3_attackDecay + byte ch3_sustainRelease + byte ch3_dummy + byte Filter1 + byte Filter2 + byte Filter3 + byte Volume + long SIDSample + byte cog + diff --git a/lib/adm-wav.spin b/lib/adm-wav.spin new file mode 100644 index 0000000..65d0f05 --- /dev/null +++ b/lib/adm-wav.spin @@ -0,0 +1,364 @@ +{{ +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Digital To Analog Converter Engine │ +│ │ +│ Author: Kwabena W. Agyeman │ +│ Updated: 1/11/2010 │ +│ Designed For: P8X32A │ +│ │ +│ Copyright (c) 2010 Kwabena W. Agyeman │ +│ See end of file for terms of use. │ +│ │ +│ Driver Info: │ +│ │ +│ The DACEngine runs a stereo digital to analog converter driver in the next free cog on the propeller chip when called. │ +│ │ +│ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │ +│ so port B will not be operational. │ +│ │ +│ Nyamekye, │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + +CON + '' + '' 100Ω 1µF + DAC_Left_Pin = 08 '' ───┳─── Left Out + '' │ + '' 10nF + '' │ + ''  + '' + '' 100Ω 1µF + DAC_Right_Pin = 09 '' ───┳─── Right Out + '' │ + '' 10nF + '' │ + ''  + +VAR + + word dataBlock[512] + + word callerPointer + word callePointer + + byte stopedOrStarted + byte signedOrUnsigned + byte bitsPerSample + byte numberOfChannels + + word leftVolume + word rightVolume + + long sampleRate + +PUB getDataBlockAddress + + return @dataBlock + +PUB startPlayer '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Starts/Unpauses the stereo DAC player. The player will begin at whatever point it stopped at before. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + stopedOrStarted := true + +PUB stopPlayer '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Stops/pauses the stereo DAC. The player will remember whatever point it stopped at. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + stopedOrStarted := false + +PUB transferData '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Helps reliably transfers data to the stero DAC to play. Throttles data transfer speed to that of data play speed. │ +'' │ │ +'' │ Returns address of next data buffer to transfer data to. Does not return until data buffer is ready for transfer. │ +'' │ │ +'' │ At 8 bits per sample using 1 channel each data buffer is composed of 512 bytes with 512 samples per transfer. │ +'' │ │ +'' │ At 8 bits per sample using 2 channels each data buffer is composed of 512 bytes with 256 samples per transfer. │ +'' │ │ +'' │ At 16 bits per sample using 1 channel each data buffer is composed of 256 words with 256 samples per transfer. │ +'' │ │ +'' │ At 16 bits per sample using 2 channels each data buffer is composed of 256 words with 128 samples per transfer. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat while(callerPointer == callePointer) + result := @dataBlock[256 & callerPointer] + not callerPointer + +PUB clearData '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Clears all data in all player data buffers. │ +'' │ │ +'' │ Helps prevent old data from being played when changing to a new data transfer source. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + bytefill(@dataBlock, ((not(signedOrUnsigned)) & $80), 1024) + +PUB changeLeftChannelVolume(newVolume) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the volume of the left channel. (0 to 100) │ +'' │ │ +'' │ NewVolume - New volume to output samples at. Samples are scaled by this value. Zero mutes the channel. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + leftVolume := (((newVolume <# 100) #> 0) * constant(65536 / 100)) + +PUB changeRightChannelVolume(newVolume) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the volume of the right channel. (0 to 100) │ +'' │ │ +'' │ NewVolume - New volume to output samples at. Samples are scaled by this value. Zero mutes the channel. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + rightVolume := (((newVolume <# 100) #> 0) * constant(65536 / 100)) + +PUB changeSampleSign(signed) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes whether samples are signed or not. │ +'' │ │ +'' │ Signed - True to make all samples be interpreted as signed. False to make all samples be interpreted as unsigned. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + signedOrUnsigned := signed + +PUB changeBitsPerSample(newWidth) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the bits per sample, 8 bits or 16 bits. │ +'' │ │ +'' │ NewWidth - New bits per sample to output samples at. Samples are sized by this value. (8 or 16) │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + bitsPerSample := (newWidth == 16) + +PUB changeNumberOfChannels(newNumber) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the number of channels, 1 channel or 2 channels. │ +'' │ │ +'' │ When set to 1 channel mode the driver will output samples to both channels at once. │ +'' │ │ +'' │ When set to 2 channel mode the driver will output samples to both channels at simultaneously. │ +'' │ │ +'' │ NewNumber - New number of channels to output samples at. Samples are grouped by this value. (1 or 2) │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + numberOfChannels := (newNumber == 2) + +PUB changeSampleRate(newRate) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the sample rate. The stereo DAC supportes samples rates from 1HZ to 88.2KHZ. │ +'' │ │ +'' │ NewRate - New sample rate to out samples at. Samples are outputted at the frequency specified by this value. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + sampleRate := (clkfreq / ((newRate <# 88200) #> 1)) + +PUB DACEngine(newRate) '' 4 Stack longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Initializes the stereo digital to analog converter driver to run on a new cog. │ +'' │ │ +'' │ Default mode is 8 bits per sample with unsigned samples, 1 channel with muted volume, and playing stopped. │ +'' │ │ +'' │ Returns the new cog's ID on sucess or -1 on failure. │ +'' │ │ +'' │ NewRate - New sample rate to out samples at. Samples are outputted at the frequency specified by this value. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + changeSampleRate(newRate) + + dataBlockAddress := @dataBlock + + callePointerAddress := @callePointer + + stopedOrStartedAddress := @stopedOrStarted + unsignedOrSignedAddress := @signedOrUnsigned + bitsPerSampleAddress := @bitsPerSample + numberOfChannelsAddress := @NumberOfChannels + + leftVolumeAddress := @leftVolume + rightVolumeAddress := @rightVolume + + return cognew(@initialization, @sampleRate) + +DAT + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Stereo Digital To Analog Converter Driver +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + org + +' //////////////////////Initialization///////////////////////////////////////////////////////////////////////////////////////// + +initialization mov ctra, #((DAC_Left_Pin <# 31) #> 0) ' Setup counter I/O pins. + mov ctrb, #((DAC_Right_Pin <# 31) #> 0) ' + + movi ctra, #%0_00110_000 ' Setup counter modes to duty cycle mode. + movi ctrb, #%0_00110_000 ' + + mov dira, outputMask ' Setup I/O pin directions. + + mov playerPointer, dataBlockAddress ' Setup data block pointer. + + rdlong timeCounter, par ' Setup timing. + add timeCounter, cnt ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Player +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +outerLoop rdbyte buffer, numberOfChannelsAddress wz ' Setup player mode. + muxz playerMode, #$1 ' + rdbyte buffer, bitsPerSampleAddress wz ' + muxz playerMode, #$2 ' + + test playerMode, #$1 wc ' Setup counter. + mov counter, #128 ' +if_c_or_z add counter, #128 ' +if_c_and_z add counter, #256 ' + +' //////////////////////Inner Loop///////////////////////////////////////////////////////////////////////////////////////////// + +innerLoop rdlong buffer, par ' Wait until next sample output period. + waitcnt timeCounter, buffer ' + + rdbyte buffer, stopedOrStartedAddress ' If stopped loop continously. + tjz buffer, #innerLoop ' + + movs multiplicand, #leftVolumeAddress ' Get and output value. + call #decode ' + mov frqa, sampleBuffer ' + + test playerMode, #1 wc ' Check number of channels. +if_c mov frqb, frqa ' +if_c jmp #nextLoop ' + + movs multiplicand, #rightVolumeAddress ' Get and output value. + call #decode ' + mov frqb, sampleBuffer ' + +nextLoop djnz counter, #innerLoop ' Loop. + +' //////////////////////Outer Loop///////////////////////////////////////////////////////////////////////////////////////////// + + rdword buffer, callePointerAddress wz ' Switch data block pointer. +if_z neg buffer, #1 ' +if_nz mov buffer, #0 ' + wrword buffer, callePointerAddress ' + +if_nz mov playerPointer, dataBlockAddress ' Setup data block pointer. + + jmp #outerLoop ' Loop. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Decode Value +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +decode test playerMode, #$2 wc ' Read data depending on size. +if_c rdbyte multiplyBuffer, playerPointer ' +if_c add playerPointer, #1 ' +if_nc rdword multiplyBuffer, playerPointer ' +if_nc add playerPointer, #2 ' + + rdbyte buffer, unsignedOrSignedAddress wz ' Modify data depending on sign and size. +if_z_and_c sub multiplyBuffer, #$80 ' +if_c shl multiplyBuffer, #24 ' +if_c sar multiplyBuffer, #16 ' +if_z_and_nc sub multiplyBuffer, wordAdjust ' +if_nc shl multiplyBuffer, #16 ' +if_nc sar multiplyBuffer, #16 ' + +multiplicand rdword multiplyCounter, 0 ' Setup inputs. + mov sampleBuffer, #0 ' + + abs multiplyBuffer, multiplyBuffer wc ' Backup sign. + rcr sampleBuffer, #1 wz, nr ' + +multiplyLoop shr multiplyCounter, #1 wc ' Preform multiplication. +if_c add sampleBuffer, multiplyBuffer ' + shl multiplyBuffer, #1 wc ' + tjnz multiplyCounter, #multiplyLoop ' + + negnz sampleBuffer, sampleBuffer ' Restore sign. + + add sampleBuffer, longAdjust ' Center output value. + +decode_ret ret ' Return. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Data +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +wordAdjust long $8000 ' Edits word signed value. +longAdjust long $80000000 ' Edits long unsigend value. + +' //////////////////////Pin Masks////////////////////////////////////////////////////////////////////////////////////////////// + +outputMask long ((|<((DAC_Left_Pin <# 31) #> 0)) | (|<((DAC_Right_Pin <# 31) #> 0))) ' DAC Outputs. + +' //////////////////////Addresses////////////////////////////////////////////////////////////////////////////////////////////// + +dataBlockAddress long 0 + +callePointerAddress long 0 + +stopedOrStartedAddress long 0 +unsignedOrSignedAddress long 0 +bitsPerSampleAddress long 0 +numberOfChannelsAddress long 0 + +leftVolumeAddress long 0 +rightVolumeAddress long 0 + +' //////////////////////Run Time Variables///////////////////////////////////////////////////////////////////////////////////// + +buffer res 1 +counter res 1 + +playerPointer res 1 +playerMode res 1 + +sampleBuffer res 1 +timeCounter res 1 + +multiplyBuffer res 1 +multiplyCounter res 1 + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + fit 496 + +{{ + +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the │ +│Software is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the │ +│Software. │ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-bus.spin b/lib/bel-bus.spin new file mode 100644 index 0000000..28de9fe --- /dev/null +++ b/lib/bel-bus.spin @@ -0,0 +1,87 @@ +{{ Bus-Funktionen für Bellatrix }} + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + + +OBJ + + gc : "glob-con" 'globale konstanten + +PUB init_bus + dira := db_in 'datenbus auf eingabe schalten + outa[gc#bus_hs] := 1 'handshake inaktiv + +PUB putchar(zeichen) 'chip: ein byte an regnatix senden +''funktionsgruppe : chip +''funktion : ein byte an regnatix senden +''eingabe : byte +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[gc#bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[gc#bus_hs] := 1 'daten ungültig + +PUB getchar : zeichen 'chip: ein byte von regnatix empfangen +''funktionsgruppe : chip +''funktion : ein byte von regnatix empfangen +''eingabe : - +''ausgabe : byte + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[gc#bus_hs] := 0 'daten quittieren + waitpeq(M3,M4,0) 'busclk=0? + outa[gc#bus_hs] := 1 + + +CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN + +PUB putlong(wert) 'sub: long senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert an regnatix zu senden +''eingabe : 32bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2][put.byte3][put.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + putchar(wert >> 24) '32bit wert senden hsb/lsb + putchar(wert >> 16) + putchar(wert >> 8) + putchar(wert) + +PUB getlong:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := getchar << 24 '32 bit empfangen hsb/lsb + wert := wert + getchar << 16 + wert := wert + getchar << 8 + wert := wert + getchar + + diff --git a/lib/bel-gfx1.spin b/lib/bel-gfx1.spin new file mode 100644 index 0000000..5a7c8c8 --- /dev/null +++ b/lib/bel-gfx1.spin @@ -0,0 +1,178 @@ +DAT +{ + video-treiber-frame + - basiert auf dem tollen tutorial von bamse + +30-09-2009-dr235 driver 1 - originalcode, anpassung an hive + driver 2 - senkrechte balken + driver 3 - einfarbige fläche + driver 4 - wandernde farbbalken, 1 byte pro pixel :) + driver 5 - + + +} + +CON + _CLKMODE = xtal1 + pll16x + _XINFREQ = 5_000_000 + +PUB start + + cognew(@entry,0) ' neue cog mit video-treiber starten + +DAT org 0 +entry jmp #Start_of_driver ' Start here... + +' NTSC sync stuff. +NTSC_color_freq long 3_579_545 ' NTSC Color Frequency +NTSC_hsync_VSCL long 39 << 12 + 624 ' Used for the Horisontal Sync +NTSC_active_VSCL long 188 << 12 + 3008 ' Used for the Vertical sync +NTSC_hsync_pixels long %%11_0000_1_2222222_11 ' Horizontal sync pixels +NTSC_vsync_high_1 long %%1111111_2222222_11 ' Vertical sync signal part one for lines 1-6 and 13 to 18 +NTSC_vsync_high_2 long %%1111111111111111 ' Vertical sync signal part two for lines 1-6 and 13 to 18 +NTSC_vsync_low_1 long %%2222222222222222 ' Vertical sync signal part one for lines 7-12 +NTSC_vsync_low_2 long %%22_1111111_2222222 ' Vertical sync signal part two for lines 7-12 +NTSC_sync_signal_palette long $00_00_02_8A ' The sync Palette + +' hbeat --------+ +------------------------- /cs +' clk -------+| | +' /wr ------+|| | +---------------------- videopins +' /hs -----+||| | | +' |||| |--+ -------- d0..d7 +tvport_mask long %00000000_01110000_00000000_00000000 ' Maske für Video-Pins am Hive +vsu_cfg long %01110100_00000000_00000100_01110000 ' Wert für VCFG-Register + +NTSC_Graphic_Lines long 244 ' Anzahl der sichtbaren Zeilen +NTSC_Graphics_Pixels_VSCL long 16 << 12 + 16 ' 16 clocks per pixel, 64 clocks per frame. + + +PAL0 long $01 +PAL1 long $0E +PAL2 long $0D +PAL3 long $0C +PAL4 long $0B +DIF1 long $00_10 +CNT_ANIM long $4 + +' Loop counters. +line_loop long $0 ' Line counter... +pix_loop long $0 +anim_loop long $0 + +' General Purpose Registers +r0 long $0 ' Initialize to 0 +r1 long $0 +r2 long $0 +r3 long $0 +c1 long $0 ' colorregister +c2 long $0 +c3 long $0 + +'========================== Start of the actual driver ============================================= + +Start_of_driver + ' VCFG, setup Video Configuration register and 3-bit tv DAC pins to output + mov VCFG, vsu_cfg ' Konfiguration der VSU + or DIRA, tvport_mask ' Set DAC pins to output + + ' CTRA, setup Frequency to Drive Video + movi CTRA,#%00001_111 ' pll internal routed to Video, PHSx+=FRQx (mode 1) + pll(16x) + mov r1, NTSC_color_freq ' r1: Color frequency in Hz (3.579_545MHz) + rdlong r2, #0 ' Copy system clock from main memory location 0. (80Mhz) + ' perform r3 = 2^32 * r1 / r2 + mov r0,#32+1 +:loop cmpsub r1,r2 wc + rcl r3,#1 + shl r1,#1 + djnz r0,#:loop + mov FRQA, r3 ' Set frequency for counter A + + +'========================== Start of Frame Loop ============================================== + +frame_loop + mov anim_loop, CNT_ANIM +frame_loop2 + +'========================== Screen ============================================= + + mov line_loop, NTSC_Graphic_Lines ' anzahl der zeilen laden (244) + +user_lines + '------ zeilensynchronisation + mov VSCL, NTSC_hsync_VSCL ' Setup VSCL for horizontal sync. + waitvid NTSC_sync_signal_palette, NTSC_hsync_pixels ' Generate sync. + + + '------ sichtbarer zeileninhalt + mov VSCL, NTSC_Graphics_Pixels_VSCL ' Setup VSCL for user pixels. + + '------ verschiedenfarbige balken ausgeben + mov c1, PAL4 + add c1, c3 + mov pix_loop, #23 +bar_loop + add c1, #$10 ' 8 x pixel einzeln! ausgeben + mov c2, c1 ' also 2 tiles + waitvid c2, #0 ' 8 bit pro pixel! + add c2, #1 + waitvid c2, #0 + add c2, #1 + waitvid c2, #0 + add c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + + djnz pix_loop, #bar_loop + + sub c2, #1 + waitvid c2, #0 ' 4 mal extrapixel, für das timing + sub c2, #1 ' also insgesamt 188 pixel pro zeile + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + + djnz line_loop, #user_lines ' schleife durch alle zeilen + +'========================== The 16 lines of Horizontal sync ================================== + + mov line_loop, #6 ' Line 244, start of first high sync. +vsync_high1 mov VSCL, NTSC_hsync_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_1 + mov VSCL, NTSC_active_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_2 + djnz line_loop, #vsync_high1 + + mov line_loop, #6 ' Line 250, start of the Seration pulses. +vsync_low mov VSCL, NTSC_active_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_low_1 + mov VSCL,NTSC_hsync_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_low_2 + djnz line_loop, #vsync_low + + mov line_loop, #6 ' Line 256, start of second high sync. +vsync_high2 mov VSCL, NTSC_hsync_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_1 + mov VSCL, NTSC_active_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_2 + djnz line_loop, #vsync_high2 + +'========================== End of Frame Loop ============================================= + djnz anim_loop, #frame_loop2 + add c3, #$10 + + +'========================== Animation ================================== + + jmp #frame_loop ' And repeat for ever... +FIT + \ No newline at end of file diff --git a/lib/bel-graphics-xor.spin b/lib/bel-graphics-xor.spin new file mode 100644 index 0000000..74614e6 --- /dev/null +++ b/lib/bel-graphics-xor.spin @@ -0,0 +1,2013 @@ +{{ +┌──────────────────────────────────────────┐ +│ SDM_graphics_XOR_025 │ +│ Author: Steven Messenger mod, │ +│ Chip Garcy original │ +│ Copyright (c) 2008 Steven Messenger and │ +│ Parallax, Inc │ +│ See end of file for terms of use. │ +└──────────────────────────────────────────┘ +}} +'' +''Original copyright +''***************************** +''* Graphics Driver v1.0 * +''* (C) 2005 Parallax, Inc. * +''***************************** + +''This version has been modified by Steven Messenger (stevenmess2004) with input from deSilva +''It can now do XOR operations, draw glyphs using the ROM font and maybe some other things will get +''added +''New functions are +''setFont +''boxXOR +''setXOR +''setOverWrite +''setFontPtr +''drawGlyph +''pixelColor + + + +'' +'' Theory of Operation: +'' +'' A cog is launched which processes commands via the PUB routines. +'' +'' Points, lines, arcs, sprites, text, and polygons are rasterized into +'' a specified stretch of memory which serves as a generic bitmap buffer. +'' +'' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. +'' +'' See GRAPHICS_DEMO.spin or MPE_XORGA_114_SDM_mods5 for usage example. +'' +CON +'Font types +#0,Vector,ROM,Clemens + +VAR + + long cog + + long command + + long bitmap_base 'bitmap data + long bitmap_longs + word bases[32] + + long pixel_width 'pixel data + long slices[8] + + long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) + + word xOffset,yOffset,xTiles,yTiles + +PUB start : okay + +'' Start graphics driver - starts a cog +'' returns false if no cog available + + fontptr := @font 'set font pointer (same for all instances) + + glyphAddress:=@theGlyph 'set glyph address + pixBase:=@clemensBuffer + + stop + okay := cog := cognew(@waste, @command) + 1 + +PUB stop + +'' Stop graphics driver - frees a cog + + if cog + cogstop(cog~ - 1) + + command~ + +PUB setup(x_tiles, y_tiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr + +'' Set bitmap parameters +'' +'' x_tiles - number of x tiles (tiles are 16x16 pixels each) +'' y_tiles - number of y tiles +'' x_origin - relative-x center pixel +'' y_origin - relative-y center pixel +'' base_ptr - base address of bitmap + + yTiles:=y_tiles + xTiles:=x_tiles + yOffset:=y_tiles*16-y_origin + xOffset:=x_origin + + setcommand(constant((@loop-@waste)>>2), 0) 'make sure last command finished + repeat bases_ptr from 0 to x_tiles - 1 <# 31 'write bases + bases[bases_ptr] := base_ptr + bases_ptr * y_tiles << 6 + + y_tiles <<= 4 'adjust arguments and do setup command + y_origin := y_tiles - y_origin - 1 + bases_ptr := @bases + slices_ptr := @slices + setcommand(constant((@setup_-@waste)>>2), @x_tiles) + + bitmap_base := base_ptr 'retain high-level bitmap data + bitmap_longs := x_tiles * y_tiles + + +PUB clear + +'' Clear bitmap + + setcommand(constant((@loop-@waste)>>2), 0) 'make sure last command finished + + longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap + + +PUB copy(dest_ptr) + +'' Copy bitmap +'' use for double-buffered display (flicker-free) +'' +'' dest_ptr - base address of destination bitmap + + setcommand(constant((@loop-@waste)>>2), 0) 'make sure last command finished + + longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap + + +PUB color(c)|_arg1,_arg2 + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + longmove(@_arg1,@color_,2) + c:=colors[c&3] + + setcommand(constant((@arg1-@waste)>>2), @c) + +PUB width(w) | pixel_passes,_arg2,_arg3,_arg4, r, i, p + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + r := not w & $10 'determine pixel shape/width + w &= $F + pixel_width := w + pixel_passes := w >> 1 + 1 + + longmove(@_arg2,@width_,3) 'do width command now to avoid updating slices when busy + setcommand(constant((@arg2-@waste)>>2), @w) + + p := w ^ $F 'update slices to new shape/width + repeat i from 0 to w >> 1 + slices[i] := true >> (p << 1) << (p & $E) + if r and pixels[w] & |< i + p += 2 + if r and i == pixel_passes - 2 + p += 2 + + +PUB colorwidth(c, w) + +'' Set pixel color and width + + color(c) + width(w) + + +PUB plot(x, y) + +'' Plot point +'' +'' x,y - point + + setcommand(constant((@plot_-@waste)>>2), @x) + +PUB line(x, y) + +'' Draw a line to point +'' +'' x,y - endpoint + + setcommand(constant((@line_-@waste)>>2), @x) + +PUB arc(x, y, xr, yr, angle, anglestep, steps, arcmode) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + setcommand(constant((@arc_-@waste)>>2), @x) + +PUB vec(x, y, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + setcommand(constant((@vec_-@waste)>>2), @x) + +PUB vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition + + setcommand(constant((@vecarc_-@waste)>>2), @x) + +PUB pix(x, y, pixrot, pixdef_ptr) + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + setcommand(constant((@pixCall_-@waste)>>2), @x) + +PUB pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition + + setcommand(constant((@pixArcCall_-@waste)>>2), @x) + +PUB text(x, y, string_ptr) | justx, justy + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(constant((@text_-@waste)>>2), @x) + +PUB textarc(x, y, xr, yr, angle, string_ptr) | justx, justy + +'' Draw text at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(constant((@textarc_-@waste)>>2), @x) + +PUB textmode(x_scale, y_scale, spacing, justification)|_arg4,_arg5,_arg6,_arg7 + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + longmove(@text_xs, @x_scale, 4) 'retain high-level text data + + longmove(@_arg5, @textmode_,3) + setcommand(constant((@arg5-@waste)>>2), @x_scale) 'set text mode + +PUB setFont(fontType) + +''Sets font type +'' +'' fontType - Vector - Uses the orignal vector font - doesn't work well at the moment in XOR mode +'' ROM - Uses the ROM font - You should set spacing to 16 +'' Clemens - Uses a variant Clemens 16x8 font - You should set spacint to 8 + + case fontType + Vector: + hubPtr:=@replaceStart + counter:=60 + setcommand(constant((@arg2-@waste)>>2),@setFont_) + ROM: + 'set ROM font + hubPtr:=@drawGlyphText_ + counter:=60 + setcommand(constant((@arg2-@waste)>>2),@setFont_) + Clemens: + 'set Clemens font + hubPtr:=@clemensStart + counter:=60 + setcommand(constant((@arg2-@waste)>>2),@setFont_) + +PUB box(x, y, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + if box_width > pixel_width and box_height > pixel_width + + pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max + + x += pmin 'adjust coordinates to accomodate width + y += pmin + x2 := x + box_width - 1 - pixel_width + y2 := y + box_height - 1 - pixel_width + + plot(x, y) 'plot round/square corners + plot(x, y2) + plot(x2, y) + plot(x2, y2) + + fill(x, y2 + pmax, 0, (x2 - x) << 16, 0, 0, pmax) 'fill gaps + fill(x, y, 0, (x2 - x) << 16, 0, 0, pmin) + fill(x - pmin, y2, 0, (x2 - x + pixel_width) << 16, 0, 0, y2 - y) + +PUB boxXOR(x, y, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with square corners +'' +'' x,y - box left, box bottom + + fill(x,y+box_height-1,0,box_width<<16,0,0,box_height-1) + +PUB quad(x1, y1, x2, y2, x3, y3, x4, y4)|tx3,ty3,tx1,ty1 + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + +''x1 must be the bottom right + + tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon + if y4>y3 + ty3:=y3+1 + tx3:=(x4-x3)/(y4-y3)+x3 + else + ty3:=y3-1 + tx3:=-(x4-x3)/(y4-y3)+x3 + + if x4>x1 + tx1:=x1+1 + ty1:=(y4-y1)/(x4-x1)+y1 + else + tx1:=x1-1 + ty1:=-(y4-y1)/(x4-x1)+y1 + + tri(tx3, ty3, x4, y4, tx1, ty1) + +PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] + +'' Draw a solid triangle + +' reorder vertices by descending y + + case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 + %000: + longmove(@xy, @x1, 2) + longmove(@x1, @x3, 2) + longmove(@x3, @xy, 2) + %010: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 4) + longmove(@x3, @xy, 2) + %011: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 2) + longmove(@x2, @xy, 2) + %100: + longmove(@xy, @x3, 2) + longmove(@x2, @x1, 4) + longmove(@x1, @xy, 2) + %101: + longmove(@xy, @x2, 2) + longmove(@x2, @x3, 2) + longmove(@x3, @xy, 2) + +' draw triangle + + fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) + + +PUB finish + +'' Wait for any current graphics command to finish +'' use this to insure that it is safe to manually manipulate the bitmap + + setcommand(constant((@loop-@waste)>>2), 0) 'make sure last command finished + +PUB setXOR + +'' Sets XOR mode. In this mode the pixel to be written is read from the bitmap and than +'' XORed with the color value. +'' +'' This mode looks bad when using a width other than 0, and the quad and box methods do +'' not work well. The boxXOR method can be used for drawing boxes. + + setcommand(constant((@arg0-@waste)>>2),@setXOR_) + +PUB setOverWrite + +'' Sets OverWrite or normal mode. In this mode the color is written directly to the bitmap +'' in the desired location. + + setcommand(constant((@arg0-@waste)>>2),@setOverWrite_) + +PUB setFontPtr(fontBase)|_arg1,_arg2 + +'' Sets the pointer to the base of the Vector font. This could be useful if you wanted to have +'' more than one Vector font. Not tested. +'' +'' The data should start with "!". The data can be either lines or curves. See the Vector font +'' below for info. + + longmove(_arg1,setFontPtr_,2) + setcommand(constant((@arg1-@waste)>>2),@fontBase) + +PUB drawGlyph(x,y,xr,yr,angle,pixrot,pixdef_ptr,glyph) + +'' Draws a Glyph using the ROM font. +'' +'' x,y - position to draw glyph +'' xr - x radius if you want to do an arc +'' yr - y radius if you want to do an arc (MUST be non-zero), otherwise MUST be 0 +'' pixrot - see pix +'' pixdef_ptr - pointer to a buffer for the glyph +'' glyph - the character you want to draw + + if angle==0 + setcommand(constant((@drawGlyph_-@waste)>>2),@x) + else + setcommand(constant((@drawGlyphArc_-@waste)>>2),@x) + +PUB pixelColor(x,y): temp' | sad + +'' Returns the color of a pixel at x,y + + temp:=(long[bitmap_base+(((x+xOffset)>>4)*yTiles+(yOffset-y)>>4)<<6+((yOffset-y-1)&15)<<2]>>(((x+xOffset)&15)<<1))&3 + +PRI fill(x, y, da, db, db2, linechange, lines_minus_1) + + setcommand(constant((@fill_-@waste)>>2), @x) + +PRI justify(string_ptr, justptr) | x + + x := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 + long[justptr] := -lookupz(text_just >> 2 & 3: 0, x >> 1, x, 0) + long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) + + +PRI setcommand(cmd, argptr) + + command := cmd <<16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + + +CON + + ' Vector font primitives + + xa0 = %000 << 0 'x line start / arc center + xa1 = %001 << 0 + xa2 = %010 << 0 + xa3 = %011 << 0 + xa4 = %100 << 0 + xa5 = %101 << 0 + xa6 = %110 << 0 + xa7 = %111 << 0 + + ya0 = %0000 << 3 'y line start / arc center + ya1 = %0001 << 3 + ya2 = %0010 << 3 + ya3 = %0011 << 3 + ya4 = %0100 << 3 + ya5 = %0101 << 3 + ya6 = %0110 << 3 + ya7 = %0111 << 3 + ya8 = %1000 << 3 + ya9 = %1001 << 3 + yaA = %1010 << 3 + yaB = %1011 << 3 + yaC = %1100 << 3 + yaD = %1101 << 3 + yaE = %1110 << 3 + yaF = %1111 << 3 + + xb0 = %000 << 7 'x line end + xb1 = %001 << 7 + xb2 = %010 << 7 + xb3 = %011 << 7 + xb4 = %100 << 7 + xb5 = %101 << 7 + xb6 = %110 << 7 + xb7 = %111 << 7 + + yb0 = %0000 << 10 'y line end + yb1 = %0001 << 10 + yb2 = %0010 << 10 + yb3 = %0011 << 10 + yb4 = %0100 << 10 + yb5 = %0101 << 10 + yb6 = %0110 << 10 + yb7 = %0111 << 10 + yb8 = %1000 << 10 + yb9 = %1001 << 10 + ybA = %1010 << 10 + ybB = %1011 << 10 + ybC = %1100 << 10 + ybD = %1101 << 10 + ybE = %1110 << 10 + ybF = %1111 << 10 + + ax1 = %0 << 7 'x arc radius + ax2 = %1 << 7 + + ay1 = %00 << 8 'y arc radius + ay2 = %01 << 8 + ay3 = %10 << 8 + ay4 = %11 << 8 + + a0 = %0000 << 10 'arc start/length + a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0°, 90°, 180°, 270°) + a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360°, 270°, 180°, 90°) + a3 = %0011 << 10 + a4 = %0100 << 10 + a5 = %0101 << 10 + a6 = %0110 << 10 + a7 = %0111 << 10 + a8 = %1000 << 10 + a9 = %1001 << 10 + aA = %1010 << 10 + aB = %1011 << 10 + aC = %1100 << 10 + aD = %1101 << 10 + aE = %1110 << 10 + aF = %1111 << 10 + + fline = %0 << 14 'line command + farc = %1 << 14 'arc command + + more = %1 << 15 'another arc/line + + +DAT + +' Color codes + +colors long %%0000000000000000 + long %%1111111111111111 + long %%2222222222222222 + long %%3333333333333333 + +' Round pixel recipes + +pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 + byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 + byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B + byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F + +' Vector font - standard ascii characters ($21-$7E) + +font word fline + xa2 + yaC + xb2 + yb7 + more '! + word fline + xa2 + ya5 + xb2 + yb4 + + word fline + xa1 + yaD + xb1 + ybC + more '" + word fline + xa3 + yaD + xb3 + ybC + + word fline + xa1 + yaA + xb1 + yb6 + more '# + word fline + xa3 + yaA + xb3 + yb6 + more + word fline + xa0 + ya9 + xb4 + yb9 + more + word fline + xa0 + ya7 + xb4 + yb7 + + word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ + word farc + xa2 + ya7 + aB + ax2 + ay1 + more + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + yaA + xb4 + ybA + more + word fline + xa2 + yaA + xb2 + ybB + more + word fline + xa2 + ya6 + xb2 + yb5 + + word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% + word farc + xa3 + ya6 + a0 + ax1 + ay1 + more + word fline + xa0 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& + word farc + xa2 + ya7 + a5 + ax2 + ay2 + more + word fline + xa1 + yaA + xb4 + yb5 + + word fline + xa2 + yaD + xb2 + ybC ' ' + + word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( + word farc + xa3 + ya7 + aE + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') + word farc + xa1 + ya7 + aF + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word fline + xa4 + ya6 + xb0 + ybA + more '* + word fline + xa0 + ya6 + xb4 + ybA + more + word fline + xa2 + yaB + xb2 + yb5 + + word fline + xa0 + ya8 + xb4 + yb8 + more '+ + word fline + xa2 + yaA + xb2 + yb6 + + word fline + xa2 + ya4 + xb1 + yb3 ', + + word fline + xa0 + ya8 + xb4 + yb8 '- + + word fline + xa2 + ya5 + xb2 + yb4 '. + + word fline + xa0 + ya4 + xb4 + ybC '/ + + word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 + + word fline + xa0 + ya4 + xb4 + yb4 + more '1 + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa0 + yaA + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 + word farc + xa2 + yaA + aF + ax2 + ay3 + more + word farc + xa2 + ya4 + aD + ax2 + ay3 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + yaC + xb0 + yb7 + more '4 + word fline + xa0 + ya7 + xb4 + yb7 + more + word fline + xa3 + ya4 + xb3 + yb8 + + word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 + word fline + xa4 + yaC + xb0 + ybC + more + word fline + xa0 + yaC + xb0 + yb8 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + ya4 + xb2 + yb4 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 + word farc + xa2 + ya8 + aD + ax2 + ay4 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa2 + yaC + xb3 + ybC + + word fline + xa0 + yaC + xb4 + ybC + more '7 + word fline + xa1 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 + word farc + xa2 + yaA + a0 + ax2 + ay2 + + word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 + word farc + xa2 + ya8 + aF + ax2 + ay4 + more + word fline + xa4 + ya8 + xb4 + ybA + more + word fline + xa1 + ya4 + xb2 + yb4 + + word fline + xa2 + ya6 + xb2 + yb7 + more ': + word fline + xa2 + yaA + xb2 + yb9 + + word fline + xa2 + ya4 + xb1 + yb3 + more '; + word fline + xa2 + ya8 + xb2 + yb7 + + word fline + xa0 + ya8 + xb4 + ybA + more '< + word fline + xa0 + ya8 + xb4 + yb6 + + word fline + xa0 + yaA + xb4 + ybA + more '= + word fline + xa0 + ya6 + xb4 + yb6 + + word fline + xa4 + ya8 + xb0 + ybA + more '> + word fline + xa4 + ya8 + xb0 + yb6 + + word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? + word farc + xa3 + yaB + aF + ax1 + ay2 + more + word farc + xa3 + ya7 + aD + ax1 + ay2 + more + word fline + xa2 + ya5 + xb2 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ + word farc + xa2 + ya8 + a4 + ax2 + ay3 + more + word farc + xa3 + ya8 + aF + ax1 + ay1 + more + word farc + xa2 + ya6 + aF + ax2 + ay1 + more + word fline + xa3 + ya7 + xb3 + yb9 + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A + word fline + xa0 + ya4 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + ybA + more + word fline + xa0 + ya8 + xb4 + yb8 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B + word farc + xa2 + ya6 + aB + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + + word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D + word farc + xa2 + ya6 + aF + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + yaC + xb2 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'E + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'F + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + yb7 + more + word fline + xa3 + ya7 + xb4 + yb7 + + word fline + xa0 + ya4 + xb0 + ybC + more 'H + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa0 + ya8 + xb4 + yb8 + + word fline + xa2 + ya4 + xb2 + ybC + more 'I + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'K + word fline + xa4 + yaC + xb0 + yb8 + more + word fline + xa4 + ya4 + xb0 + yb8 + + word fline + xa0 + ya4 + xb0 + ybC + more 'L + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa0 + ya4 + xb0 + ybC + more 'M + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa2 + ya8 + xb0 + ybC + more + word fline + xa2 + ya8 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'N + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa4 + ya4 + xb0 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa2 + ya6 + xb4 + yb3 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + more + word fline + xa4 + ya4 + xb2 + yb8 + + word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + ya4 + xb2 + ybC + more 'T + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U + word fline + xa0 + ya6 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa2 + ya4 + xb0 + ybC + more 'V + word fline + xa2 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb0 + yb4 + more 'W + word fline + xa4 + yaC + xb4 + yb4 + more + word fline + xa2 + ya8 + xb0 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb4 + + word fline + xa4 + ya4 + xb0 + ybC + more 'X + word fline + xa0 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb2 + yb8 + more 'Y + word fline + xa4 + yaC + xb2 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb8 + + word fline + xa0 + yaC + xb4 + ybC + more 'Z + word fline + xa0 + ya4 + xb4 + ybC + more + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb4 + ybD + more + word fline + xa2 + ya3 + xb4 + yb3 + + word fline + xa4 + ya4 + xb0 + ybC '\ + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb0 + ybD + more + word fline + xa2 + ya3 + xb0 + yb3 + + word fline + xa2 + yaA + xb0 + yb6 + more '^ + word fline + xa2 + yaA + xb4 + yb6 + + word fline + xa0 + ya1 + xa4 + yb1 '_ + + word fline + xa1 + ya9 + xb3 + yb7 '` + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a + word fline + xa4 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b + word fline + xa0 + ya4 + xb0 + ybC + + word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c + word fline + xa2 + ya4 + xb4 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd + word fline + xa4 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e + word fline + xa0 + ya6 + xb4 + yb6 + more + word fline + xa2 + ya4 + xb4 + yb4 + + word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya4 + xb2 + ybA + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya4 + xb4 + yb6 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'i + word fline + xa2 + ya4 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j + word fline + xa2 + ya3 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word fline + xa0 + ya4 + xb0 + ybC + more 'k + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + ya6 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb4 + yb4 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'l + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa1 + yaC + xb2 + ybC + + word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm + word farc + xa3 + ya7 + a8 + ax1 + ay1 + more + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb7 + more + word fline + xa4 + ya4 + xb4 + yb7 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb6 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 'o + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p + word fline + xa0 + ya1 + xb0 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q + word fline + xa4 + ya1 + xb4 + yb8 + + word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r + word fline + xa0 + ya4 + xb0 + yb8 + + word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's + word farc + xa2 + ya5 + aB + ax2 + ay1 + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb2 + ybA + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb8 + + word fline + xa0 + ya8 + xb2 + yb4 + more 'v + word fline + xa4 + ya8 + xb2 + yb4 + + word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w + word farc + xa3 + ya5 + aA + ax1 + ay1 + more + word fline + xa0 + ya5 + xb0 + yb8 + more + word fline + xa2 + ya5 + xb2 + yb6 + more + word fline + xa4 + ya5 + xb4 + yb8 + + word fline + xa0 + ya8 + xb4 + yb4 + more 'x + word fline + xa0 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word fline + xa0 + ya8 + xb4 + yb8 + more 'z + word fline + xa4 + ya8 + xb0 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ + word farc + xa1 + ya6 + aC + ax1 + ay2 + more + word farc + xa1 + yaA + aF + ax1 + ay2 + more + word farc + xa3 + ya6 + aE + ax1 + ay3 + + word fline + xa2 + ya3 + xb2 + ybD '| + + word farc + xa1 + yaA + aC + ax1 + ay3 + more '} + word farc + xa3 + ya6 + aD + ax1 + ay2 + more + word farc + xa3 + yaA + aE + ax1 + ay2 + more + word farc + xa1 + ya6 + aF + ax1 + ay3 + + word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ + word farc + xa3 + ya8 + aA + ax1 + ay1 + +' Vector font - custom characters ($7F+) + + word fline + xa2 + ya9 + xb0 + yb4 + more 'delta + word fline + xa2 + ya9 + xb4 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega + word farc + xa1 + ya7 + aE + ax1 + ay2 + more + word farc + xa3 + ya7 + aF + ax1 + ay2 + more + word fline + xa1 + ya5 + xb1 + yb4 + more + word fline + xa3 + ya5 + xb3 + yb4 + more + word fline + xa0 + ya4 + xb1 + yb4 + more + word fline + xa4 + ya4 + xb3 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet + + +CON fx = 3 'number of custom characters + +DAT + +'************************************* +'* Assembly language graphics driver * +'************************************* + + org 0 +' +' +' Graphics driver - main loop +' +waste long 0 +loop rdlong t1,par wz 'wait for command + if_z jmp #loop + + movd :arg,#arg0 'get 8 arguments + mov t2,t1 + mov t3,#8 +:arg rdlong arg0,t2 'this gets modified by the next instruction + add :arg,d0 'this changes where we store the argument + add t2,#4 'this changes where we read the argument from + djnz t3,#:arg + + wrlong zero,par 'zero command to signify received + + call #setd 'set dx,dy from arg0,arg1 + + ror t1,#16 'get the cog location of the command + jmp t1 'and jump to it + +' +' +' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr +' +setup_ mov xlongs,arg0 'set xlongs, ylongs + mov ylongs,arg1 + mov xorigin,arg2 'set xorigin, yorigin 'set these to 0 so we don't need them + mov yorigin,arg3 + mov basesptr,arg5 'set pointers + mov slicesptr,arg6 + + jmp #loop + +' +' +' plot(x, y) +' +plot_ call #plotd + + jmp #loop +' +' +' line(x, y) +' +line_ call #linepd + + jmp #loop + +pixCall_ JMPRET pixret_,#pix_ + jmp #loop + +pixArcCall_ JMPRET pixret_,#pixArc_ + jmp #loop +' +' +' arc(x, y, xr, yr, angle, anglestep, iterations, mode) +' +arc_ and arg7,#3 'limit mode + +:loop call #arca 'get arc dx,dy + + cmp arg7,#1 wz 'if not mode 1, set px,py + if_nz mov px,dx + if_nz mov py,dy + + tjz arg6,#loop 'if no points exit with new px,py + + cmp arg7,#3 wz 'if mode 3, set center + if_z call #setd + + test arg7,#1 wz 'if mode 0 or 2, plot point + if_z call #plotp + + test arg7,#1 wz 'if mode 1 or 3, plot line + if_nz call #linepd + + cmp arg7,#2 wz 'if mode 2, set mode 1 + if_z mov arg7,#1 + + add arg4,arg5 'step angle + djnz arg6,#:loop 'loop if more iterations + + jmp #loop +' +' +' vec(x, y, vecscale, vecangle, vecdef_ptr) +' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) +' +' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +' word length 'vector length +' ... 'more vectors +' ... +' word 0 'end of definition +' +vecarc_ call #arcmod + +vec_ tjz arg2,#loop 'if scale 0, exit + +:loop rdword t7,arg4 wz 'get vector mode+angle + add arg4,#2 + + if_z jmp #loop 'if mode+angle 0, exit + + rdword t1,arg4 'get vector length + add arg4,#2 'setup for next read + + abs t2,arg2 wc 'add/sub(scale for normal) vector angle to/from angle + mov t6,arg3 + sumc t6,t7 + + call #multiply 'multiply length by scale + add t1,#$80 'round up 1/2 lsb + shr t1,#8 + + mov t4,t1 'get arc dx,dy + mov t5,t1 + call #arcd + + test t7,h8000 wc 'plot pixel or draw line? + if_nc call #plotd + test t7,h8000 wc + if_c call #linepd + + jmp #:loop 'get next vector +' +' +' pix(x, y, pixrot, pixdef_ptr) +' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) +' +' pixdef: word +' byte xwords, ywords, xorigin, yorigin +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' ... +' +pixarc_ call #arcmod + +pix_ mov t6,pcolor 'save color + + mov px,dx 'get center into px,py + mov py,dy + + mov sy,pwidth 'get actual pixel width + add sy,#1 + + rdbyte dx,arg3 'get dimensions into dx,dy + add arg3,#1 + rdbyte dy,arg3 + add arg3,#1 + + rdbyte t1,arg3 'get origin and adjust px,py + add arg3,#1 + rdbyte t2,arg3 + add arg3,#1 + neg t2,t2 + sub t2,#1 + add t2,dy + mov t3,sy +:adjust test arg2,#%001 wz + test arg2,#%110 wc + if_z sumnc px,t1 + if_nz sumc py,t1 + test arg2,#%010 wc + if_nz sumnc px,t2 + if_z sumnc py,t2 + djnz t3,#:adjust + +:yline mov sx,#0 'plot entire pix + mov t3,dx +:xword rdword t4,arg3 'read next pix word + add arg3,#2 + shl t4,#16 + mov t5,#8 +:xpixel rol t4,#2 'plot pixel within word + test t4,#1 wc 'set color + muxc pcolor,color1 + test t4,#2 wc + muxc pcolor,color2 wz '(z=1 if color=0) + if_nz call #plotp + test arg2,#%001 wz 'update px,py for next x + test arg2,#%110 wc + if_z sumc px,sy + if_nz sumnc py,sy + add sx,sy + djnz t5,#:xpixel 'another x pixel? + djnz t3,#:xword 'another x word? + if_z sumnc px,sx 'update px,py for next y + if_nz sumc py,sx + test arg2,#%010 wc + if_nz sumc px,sy + if_z sumc py,sy + djnz dy,#:yline 'another y line? + + mov pcolor,t6 'restore color + + ' jmp #loop +pixret_ ret +' +' +' text(x, y, @string) justx, justy +' 0 1 2 3 4 +' textarc(x, y, xr, yr, angle, @string) justx, justy +' 0 1 2 3 4 5 6 7 +textarc_ call #arcmod + +text_ add arg3,arg0 'add x into justx + add arg4,arg1 'add y into justy + +chr rdbyte t1,arg2 wz 'get chr + add arg2,#1 'increment chr pointer + + if_z jmp #loop 'if 0, done + 'would replace from here down to setd +replaceStart sub t1,#$21 'if chr out of range, skip + cmp t1,#$7F-$21+fx wc + if_nc jmp #skip1 + + mov arg5,fontptr 'scan font for chr definition +scan tjz t1,#def 't1 is character-21 + rdword t2,arg5 'goes through t1 times which will get to the + add arg5,#2 'start of the desired character + test t2,h8000 wc + if_nc sub t1,#1 + jmp #scan + +def rdword t7,arg5 'get font definition word + add arg5,#2 'point to next word + + call #fontxy 'extract initial x,y + + test t7,#$80 wc 'arc or line? + if_nc jmp #line1 + + + mov t2,textsx 'arc, extract x radius + mov t3,#%0001_0001_1 + call #fontb + mov t4,t1 + + mov t2,textsy 'extract y radius + mov t3,#%0010_0011_1 + call #fontb + mov t5,t1 + + mov t2,#1 'extract starting angle + mov t3,#%0010_0011_0 + call #fontb + shl t1,#11 + + mov t6,t1 'extract angle sweep + mov t3,#%0010_0011_0 + call #fontb + neg arg6,t1 + shl arg6,#4 + add arg6,#65 + + call #arcd 'plot initial arc point + call #plotd + +arc1 call #arcd 'connect subsequent arc points with lines + call #linepd + add t6,#$80 + djnz arg6,#arc1 + + jmp #more1 + + +line1 call #plotd 'line, plot initial x,y + + call #fontxy 'extract terminal x,y + + call #linepd 'draw line + + +more1 test t7,#$02 wc 'more font definition? + if_c jmp #def + + +skip1 mov t1,textsp 'advance x to next chr position + mov t2,textsx + call #multiply + add arg3,t1 + + jmp #chr 'get next chr + + +fontxy mov t2,textsx 'extract x + mov t3,#%0011_0111_0 + call #fontb 't2 - x_scale + mov arg0,t1 + add arg0,arg3 + + mov t2,textsy 'extract y + mov t3,#%0100_1111_0 + call #fontb + mov arg1,t1 + add arg1,arg4 'may have to put a jmp to setd here + + 'can use down to here which is I think 60 longs +setd mov dx,xorigin 'set dx,dy from arg0,arg1 + add dx,arg0 'have to make sure that this does not get + mov dy,yorigin 'overwritten as it gets called at the start + sub dy,arg1 'of every operation +setd_ret +fontxy_ret ret + + +fontb mov t1,t7 'extract bitrange from font word + shr t3,#1 wc 't1 - t7 - font definition work + and t1,t3 't3 - mask - %0100_1111 + if_c add t1,#1 + shr t3,#4 't3 - %0100 or %0011 + shr t7,t3 'shift right 4 or 3 + + shl t1,#32-4 'multiply t1[3..0] by t2 + mov t3,#4 +:loop shl t1,#1 wc + if_c add t1,t2 + djnz t3,#:loop + +fontb_ret ret + +' +' +' fill(x, y, da, db, db2, linechange, lines_minus_1) +' 0 1 2 3 4 5 6 +fill_ shl dx,#16 'get left and right fractions + or dx,h8000 'dx:=(dx<<16)|$8000 + mov t1,dx 't1:=dx + + mov t2,xlongs 'get x pixels + shl t2,#4 't2:=xlongs<<4 + + add arg6,#1 'pre-increment line counter + 'arg6++ + +yloop add dx,arg2 'adjust left and right fractions + 'dx:=dx+da + add t1,arg3 't1:=t1+db + + cmps dx,t1 wc 'get left and right integers + if_c mov base0,dx + if_c mov base1,t1 + if_nc mov base0,t1 + if_nc mov base1,dx + sar base0,#16 + sar base1,#16 + + cmps base0,t2 wc 'left out of range? + if_c cmps hFFFFFFFF,base1 wc 'right out of range? + if_c cmp dy,ylongs wc 'y out of range? + if_nc jmp #skip2 'if any, skip + + mins base0,#0 'limit left and right + maxs base1,t2 wc + if_nc sub base1,#1 + + shl base0,#1 'make left mask + neg mask0,#1 + shl mask0,base0 + shr base0,#5 + + shl base1,#1 'make right mask + xor base1,#$1E + neg mask1,#1 + shr mask1,base1 + shr base1,#5 + + sub base1,base0 wz 'ready long count + add base1,#1 + + if_z and mask0,mask1 'if single long, merge masks + + shl base0,#1 'get long base + add base0,basesptr + rdword base0,base0 + shl dy,#2 + add base0,dy + shr dy,#2 + + mov bits0,mask0 'ready left mask +xloop mov bits1,pcolor 'make color mask + and bits1,bits0 + rdlong pass,base0 'read-modify-write long +fill1 andn pass,bits0 +fill2 or pass,bits1 + wrlong pass,base0 + shl ylongs,#2 'advance to next long + add base0,ylongs + shr ylongs,#2 + cmp base1,#2 wz 'one more? + if_nz neg bits0,#1 'if not, ready full mask + if_z mov bits0,mask1 'if one more, ready right mask + djnz base1,#xloop 'loop if more longs + +skip2 sub arg5,#1 wc 'delta change? + if_c mov arg3,arg4 'if so, set new deltas +{:same} + add dy,#1 'adjust y + djnz arg6,#yloop 'another y? + + jmp #loop +' +' +' Plot line from px,py to dx,dy +' +linepd cmps dx,px wc, wr 'get x difference + negc sx,#1 'set x direction + + cmps dy,py wc, wr 'get y difference + negc sy,#1 'set y direction + + abs dx,dx 'make differences absolute + abs dy,dy + + cmp dx,dy wc 'determine dominant axis + if_nc tjz dx,#:last 'if both differences 0, plot single pixel + if_nc mov count,dx 'set pixel count + if_c mov count,dy + mov ratio,count 'set initial ratio + shr ratio,#1 + if_c jmp #:yloop 'x or y dominant? + + +:xloop + add px,sx 'move plotp to end + sub ratio,dy wc + if_c add ratio,dx + if_c add py,sy + call #plotp + djnz count,#:xloop + + jmp #:last 'plot last pixel + + +:yloop + add py,sy + sub ratio,dx wc + if_c add ratio,dy + if_c add px,sx + call #plotp + djnz count,#:yloop + +:last + +linepd_ret ret +' +' +' Plot pixel at px,py +' +plotd mov px,dx 'set px,py to dx,dy + mov py,dy + +plotp tjnz pwidth,#wplot 'if width > 0, do wide plot + + mov t1,px 'compute pixel mask + shl t1,#1 + mov mask0,#%11 + shl mask0,t1 + shr t1,#5 + + cmp t1,xlongs wc 'if x or y out of bounds, exit + if_c cmp py,ylongs wc + if_nc jmp #plotp_ret + + mov bits0,pcolor 'compute pixel bits + and bits0,mask0 + + shl t1,#1 'get address of pixel long + add t1,basesptr + mov t2,py + rdword t1,t1 + shl t2,#2 + add t1,t2 + + rdlong t2,t1 'write pixel +plotp1 andn t2,mask0 +plotp2 or t2,bits0 + wrlong t2,t1 +plotp_ret +plotd_ret ret +' +' +' Plot wide pixel +' +wplot mov t1,py 'if y out of bounds, exit + add t1,#7 + mov t2,ylongs + add t2,#7+8 + cmp t1,t2 wc + if_nc jmp #plotp_ret + + mov t1,px 'determine x long pair + sub t1,#8 + sar t1,#4 + cmp t1,xlongs wc + muxc waste,#%01 '(use jumps[1..0] to store writes) + add t1,#1 + cmp t1,xlongs wc + muxc waste,#%10 + + test waste,#%11 wz 'if x out of bounds, exit + if_z jmp #plotp_ret + + shl t1,#1 'get base pair + add t1,basesptr + rdword base1,t1 + sub t1,#2 + rdword base0,t1 + + mov t1,px 'determine pair shifts + shl t1,#1 + movs :shift1,t1 + xor :shift1,#7<<1 + add t1,#9<<1 + movs :shift0,t1 + test t1,#$F<<1 wz '(account for special case) + if_z andn waste,#%01 + + mov pass,#0 'ready to plot slices + mov slice,slicesptr + +:loop rdlong mask0,slice 'get next slice + mov mask1,mask0 + +:shift0 shl mask0,#0 'position slice +:shift1 shr mask1,#0 + + mov bits0,pcolor 'colorize slice + and bits0,mask0 + mov bits1,pcolor + and bits1,mask1 + + mov t1,py 'plot lower slice + add t1,pass + cmp t1,ylongs wc + if_c call #wslice + + mov t1,py 'plot upper slice + test pwidth,#1 wc + subx t1,pass + cmp t1,ylongs wc + if_c call #wslice + + add slice,#4 'next slice + add pass,#1 + cmp pass,passes wz + if_nz jmp #:loop + + jmp #plotp_ret +' +' +' Plot wide pixel slice +' +wslice shl t1,#2 'ready long offset + + add base0,t1 'plot left slice + test waste,#%01 wc + if_c rdlong t2,base0 +wslice1 if_c andn t2,mask0 +wslice2 if_c or t2,bits0 + + if_c wrlong t2,base0 + + add base1,t1 'plot right slice + test waste,#%10 wc + if_c rdlong t2,base1 +wslice3 if_c andn t2,mask1 +wslice4 if_c or t2,bits1 + if_c wrlong t2,base1 + + sub base0,t1 'restore bases + sub base1,t1 + +wslice_ret ret +' +' +' Get arc point from args and then move args 5..7 to 2..4 +' +arcmod call #arca 'get arc using first 5 args + + mov arg0,dx 'set arg0,arg1 + sub arg0,xorigin + mov arg1,yorigin + sub arg1,dy + + mov arg2,arg5 'move args 5..7 to 2..4 + mov arg3,arg6 + mov arg4,arg7 + +arcmod_ret ret +' +' +' Get arc dx,dy from arg0,arg1 +' +' in: arg0,arg1 = center x,y +' arg2/t4 = x length +' arg3/t5 = y length +' arg4/t6 = 13-bit angle +' +' out: dx,dy = arc point +' +arca mov t4,arg2 'use args + mov t5,arg3 + mov t6,arg4 + +arcd call #setd 'reset dx,dy to arg0,arg1 + + mov t1,t6 'get arc dx + mov t2,t4 + call #polarx + add dx,t1 + + mov t1,t6 'get arc dy + mov t2,t5 + call #polary + sub dy,t1 +arcd_ret +arca_ret ret +' +' +' Polar to cartesian +' +' in: t1 = 13-bit angle +' t2 = 16-bit length +' +' out: t1 = x|y +' +polarx add t1,sine_90 'cosine, add 90° for sine lookup +polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz + test t1,sine_90 wc 'get sine quadrant 2|4 into c + negc t1,t1 'if sine quadrant 2|4, negate table offset + or t1,sine_table 'or in sine table address >> 1 + shl t1,#1 'shift left to get final word address + rdword t1,t1 'read sine/cosine word + call #multiply 'multiply sine/cosine by length to get x|y + add t1,h8000 'add 1/2 lsb to round up x|y fraction + shr t1,#16 'justify x|y integer + negnz t1,t1 'if sine quadrant 3|4, negate x|y +polary_ret +polarx_ret ret + +sine_90 long $0800 '90° bit +sine_180 long $1000 '180° bit +sine_table long $E000 >> 1 'sine table address shifted right +' +' +' Multiply +' +' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) +' t2 = 16-bit multiplier +' +' out: t1 = 32-bit product +' +multiply mov t3,#16 + shl t2,#16 + shr t1,#1 wc + +:loop if_c add t1,t2 wc + rcr t1,#1 wc + djnz t3,#:loop + +multiply_ret ret + +' +'drawGlyphArc(x, y, xr, yr, angle, pixrot, pixdef_ptr, glyph) +'drawGlyph (x, y, pixrot, 0, 0, 0, pixdef_ptr, glyph) +' arg 0 1 2 3 4 5 6 7 +drawGlyph_ +drawGlyphArc_ + ROR arg7,#1 WC + SHL arg7,#7 + ADD arg7,h8000 + MOV t2,#64 + MOV t1,arg6 + ADD t1,#4 + +:loop RDWORD t3,arg7 + REV t3,#16 + IF_NC SHR t3,#1 + AND t3,color1':_11111111 + 'MOV t4,t3 'don't need? + 'SHL t4,#1 'don't need? + 'OR t3,t4 'don't need? + WRWORD t3,t1 + ADD t1,#2 + ADD arg7,#2 + DJNZ t2,#:loop + + MOVS pixret_,#drawGlyphRet_ + TJNZ arg3,#pixarc_ + MOV arg3,arg6 + JMP #pix_ + +drawGlyphRet_ JMP #loop + + +' +' +' Defined data +' +zero long 0 'constants +d0 long $200 +h8000 long $8000 +hFFFFFFFF long $FFFFFFFF +color1 long %%1111111111111111 +color2 long %%2222222222222222 + +fontptr long 0 'font pointer (set before cognew command) + +pcolor long %%1111111111111111 'pixel color +pwidth long 0 'pixel width +passes long 1 'pixel passes +textsx long 1 'text scale x +textsy long 1 'text scale y +textsp long 6 'text spacing + +arg0 long 1 'arguments passed from high-level +arg1 long 1 +arg2 long 1 +arg3 long 1 +arg4 long 1 +arg5 long 1 +arg6 long 1 +arg7 long 1 + + jmp #loop 'so we don't need the jmp in what we pass in +' +' +' Undefined data +' +t1 res 1 'temps +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 + + + +basesptr res 1 'pointers +slicesptr res 1 + +xlongs res 1 'bitmap metrics +ylongs res 1 +xorigin res 1 +yorigin res 1 + +dx res 1 'line/plot coordinates +dy res 1 +px res 1 +py res 1 + +sx res 1 'line +sy res 1 +count res 1 +ratio res 1 + +pass res 1 'plot +slice res 1 +base0 res 1 +base1 res 1 +mask0 res 1 +mask1 res 1 +bits0 res 1 +bits1 res 1 + +fit 496 + + ' instr zcr +setXOR_ movi plotp1,#%011001_000 'andn nr + movi plotp2,#%011011_001 'xor wr + movi wslice1,#%011001_000 'andn nr + movi wslice2,#%011011_001 'xor wr + movi wslice3,#%011001_000 'andn nr + movi wslice4,#%011011_001 'xor wr + movi fill1,#%011001_000 'andn nr + movi fill2,#%011011_001 'xor wr + +setOverWrite_ movi plotp1,#%011001_001 'andn wr + movi plotp2,#%011010_001 'or wr + movi wslice1,#%011001_001 'andn wr + movi wslice2,#%011010_001 'or wr + movi wslice3,#%011001_001 'andn wr + movi wslice4,#%011010_001 'or wr + movi fill1,#%011001_001 'andn wr + movi fill2,#%011010_001 'or wr + +' +' +' textmode(x_scale, y_scale, spacing, justification) did move this out of cog (4 longs) +' +textmode_ mov textsx,arg0 'set text x scale + mov textsy,arg1 'set text y scale + mov textsp,arg2 'set text spacing + +' +' +' color(c) did move this out of cog (2 longs) +' +color_ mov pcolor,arg0 'set pixel color + jmp #loop + +' +' +' width(w) pixel_passes did move this out of cog (3 longs) +' +width_ mov pwidth,arg0 'set pixel width + mov passes,arg1 'set pixel passes + jmp #loop + +' +' +' setFontPtr(c) did move this out of cog (2 longs) +' +setFontPtr_ mov fontptr,arg0 'set pixel color + jmp #loop + +theGlyph 'LONG 0 +pixdef word 'crosshair + byte 2,32,0,0 + word 0[64] + + +' +' +' setFont(type) +' type VECTOR, ROM or Clemens +' This just copies some code into the cog + org arg0 +setFont_ +hubPtr long 0-0 'points to current long +counter long 0-0 'length of code to copy +icogptr movd cogPtr,#replaceStart 'allows to be used in other places if wanted +cogPtr rdlong replaceStart,hubPtr + add cogPtr,#$100 'increment cog pointer + add cogPtr,#$100 + add hubPtr,#4 'increment hub pointer + djnz counter,#cogPtr + 'jmp #loop 'is after args + fit arg7+1 + + + +' +' +' code used for drawing strings with the rom font +' + org replaceStart + +drawGlyphText_ ROR t1,#1 WC + SHL t1,#7 + ADD t1,h8000 + MOV t2,#64 + MOV t5,glyphAddress + ADD t5,#4 + +:loop RDWORD t3,t1 + REV t3,#16 + IF_NC SHR t3,#1 + AND t3,color1 + MOV t4,t3 'don't need? + SHL t4,#1 'don't need? + OR t3,t4 'don't need? + WRWORD t3,t5 + ADD t5,#2 + ADD t1,#2 + DJNZ t2,#:loop + + MOVS pixret_,#drawGlyphEnd + + MOV s1,arg2 'need to save this, set it to 0 and then restore it + MOV arg2,#0 + CALL #setd + MOV arg3,glyphAddress + JMP #pix_ + +drawGlyphEnd MOV arg2,s1 + ADD arg0,textsp + JMP #chr + +glyphAddress long 0 + +s1 res 1 + +' +' +' code used for drawing strings with Clemens font +' it is copied into the cog for use + + org replaceStart + 'cbase:=glyph/2*128+$8000 +ClemensStart MOV tmp1,t1 + ROR romBase,#1 wc + SHL romBase,#7 + ADD romBase,h8000 + + 'repeat i from 0 to 11 + MOV loopC1,#0 + MOV hubAddr, pixBase + ADD hubAddr,#4 + + + + 'line:=LOOKUPZ(i:1,4,6,9,11,14,17,20,22,25,27,28,31) +:loop1 MOVS :try,#clemensTable + ADD :try,loopC1 + 'pattern2~ + MOV pattern2,#0 +:try MOV pattern,0-0 + + 'pattern:=long[cbase][line] + ADD pattern,romBase + RDLONG pattern,pattern + + 'if glyph&1 + ' pattern >>=1 + if_c SHR pattern,#1 + + + 'repeat 8 + MOV loopC2,#8 + + MOV tempClemens,#10 +:charLoop ADD :charmov,tempClemens + SUB :charmov,tempClemens +:charmov MOV tmp2,clemensTable + SHR tmp2,#16 + CMP tmp1,tmp2 wz + if_z SHR pattern,#2 + if_nz DJNZ tempClemens,#:charLoop + + 'pattern2<<=2 +:loop2 SHL pattern2,#2 + 'if pattern&1 + TEST pattern,#1 wz 'test to see it there is a pixel + 'pattern2+=3 + if_nz ADD pattern2,#3 'if there is a pixel then add 3 + + 'pattern>>=4 + SHR pattern,#4 'move the char data two because of interleaved chars + DJNZ loopC2,#:loop2 'loop again + + 'pixDef2[i+2]:=pattern2 + WRWORD pattern2,hubAddr + ADD hubAddr,#2 + + ADD loopC1,#1 'increment loop + CMP loopC1,#11 wz 'test for end of loop + if_nz JMP #:loop1 'do loop again + + MOV tmpArg2,arg2 + MOV arg2,#0 + CALL #setd + MOV arg3,pixBase + JMPRET pixret_,#pix_ + + +someLab MOV arg2,tmpArg2 + ADD arg0,textsp + JMP #chr + + + +pixBase long 0 'need to set this during setup +clemensTable long 4+"1"<<16,16+"4"<<16,24+"I"<<16,36+"i"<<16,44+"l"<<16,14*4+"Y"<<16,17*4+"Z"<<16,20*4+"7"<<16,22*4+"V"<<16,25*4+"T"<<16,27*4,28*4,31*4 +tmpArg2 long 0 '14IilYZ7VT +tmp1 long 0 +tmp2 long 0 + + fit replaceStart+60 + + org t1 + +romBase res 1 't1 - where glyph was stored +loopC1 res 1 't2 - how many times we have done loop1 +pattern res 1 't3 +tempClemens res 1 't4 +pattern2 res 1 't5 +loopC2 res 1 't6 +hubAddr res 1 't7 + +clemensBuffer word + byte 1,12,0,0 + word 0[12] + +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-graphics.spin b/lib/bel-graphics.spin new file mode 100644 index 0000000..58b394b --- /dev/null +++ b/lib/bel-graphics.spin @@ -0,0 +1,1669 @@ +''*************************************** +''* Graphics Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2005 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +'' +'' Theory of Operation: +'' +'' A cog is launched which processes commands via the PUB routines. +'' +'' Points, lines, arcs, sprites, text, and polygons are rasterized into +'' a specified stretch of memory which serves as a generic bitmap buffer. +'' +'' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. +'' +'' See GRAPHICS_DEMO.SRC for usage example. +'' + +CON + + #1, _setup, _color, _width, _plot, _line, _arc, _vec, _vecarc, _pix, _pixarc, _text, _textarc, _textmode, _fill, _loop + +VAR + + long cog + + long command + + long bitmap_base 'bitmap data + long bitmap_longs + word bases[32] + + long pixel_width 'pixel data + long slices[8] + + long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) + + +PUB start : okay + +'' Start graphics driver - starts a cog +'' returns false if no cog available + + fontptr := @font 'set font pointer (same for all instances) + + stop + okay := cog := cognew(@loop, @command) + 1 + + +PUB stop + +'' Stop graphics driver - frees a cog + + if cog + cogstop(cog~ - 1) + + command~ + + +PUB setup(x_tiles, y_tiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr + +'' Set bitmap parameters +'' +'' x_tiles - number of x tiles (tiles are 16x16 pixels each) +'' y_tiles - number of y tiles +'' x_origin - relative-x center pixel +'' y_origin - relative-y center pixel +'' base_ptr - base address of bitmap + + setcommand(_loop, 0) 'make sure last command finished + + repeat bases_ptr from 0 to x_tiles - 1 <# 31 'write bases + bases[bases_ptr] := base_ptr + bases_ptr * y_tiles << 6 + + y_tiles <<= 4 'adjust arguments and do setup command + y_origin := y_tiles - y_origin - 1 + bases_ptr := @bases + slices_ptr := @slices + setcommand(_setup, @x_tiles) + + bitmap_base := base_ptr 'retain high-level bitmap data + bitmap_longs := x_tiles * y_tiles + + +PUB clear + +'' Clear bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap + + +PUB copy(dest_ptr) + +'' Copy bitmap +'' use for double-buffered display (flicker-free) +'' +'' dest_ptr - base address of destination bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap + + +PUB color(c) + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + setcommand(_color, @colors[c & 3]) 'set color + + +PUB width(w) | pixel_passes, r, i, p + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + r := not w & $10 'determine pixel shape/width + w &= $F + pixel_width := w + pixel_passes := w >> 1 + 1 + + setcommand(_width, @w) 'do width command now to avoid updating slices when busy + + p := w ^ $F 'update slices to new shape/width + repeat i from 0 to w >> 1 + slices[i] := true >> (p << 1) << (p & $E) + if r and pixels[w] & |< i + p += 2 + if r and i == pixel_passes - 2 + p += 2 + + +PUB colorwidth(c, w) + +'' Set pixel color and width + + color(c) + width(w) + + +PUB plot(x, y) + +'' Plot point +'' +'' x,y - point + + setcommand(_plot, @x) + + +PUB line(x, y) + +'' Draw a line to point +'' +'' x,y - endpoint + + setcommand(_line, @x) + + +PUB arc(x, y, xr, yr, angle, anglestep, steps, arcmode) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + setcommand(_arc, @x) + + +PUB vec(x, y, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + setcommand(_vec, @x) + + +PUB vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition + + setcommand(_vecarc, @x) + + +PUB pix(x, y, pixrot, pixdef_ptr) + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + setcommand(_pix, @x) + + +PUB pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition + + setcommand(_pixarc, @x) + + +PUB text(x, y, string_ptr) | justx, justy + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_text, @x) + + +PUB textarc(x, y, xr, yr, angle, string_ptr) | justx, justy + +'' Draw text at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_textarc, @x) + + +PUB textmode(x_scale, y_scale, spacing, justification) + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + longmove(@text_xs, @x_scale, 4) 'retain high-level text data + + setcommand(_textmode, @x_scale) 'set text mode + + +PUB box(x, y, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + if box_width > pixel_width and box_height > pixel_width + + pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max + + x += pmin 'adjust coordinates to accomodate width + y += pmin + x2 := x + box_width - 1 - pixel_width + y2 := y + box_height - 1 - pixel_width + + plot(x, y) 'plot round/square corners + plot(x, y2) + plot(x2, y) + plot(x2, y2) + + fill(x, y2 + pmax, 0, (x2 - x) << 16, 0, 0, pmax) 'fill gaps + fill(x, y, 0, (x2 - x) << 16, 0, 0, pmin) + fill(x - pmin, y2, 0, (x2 - x + pixel_width) << 16, 0, 0, y2 - y) + + +PUB quad(x1, y1, x2, y2, x3, y3, x4, y4) + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + + tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon + tri(x3, y3, x4, y4, x1, y1) + + +PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] + +'' Draw a solid triangle + +' reorder vertices by descending y + + case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 + %000: + longmove(@xy, @x1, 2) + longmove(@x1, @x3, 2) + longmove(@x3, @xy, 2) + %010: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 4) + longmove(@x3, @xy, 2) + %011: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 2) + longmove(@x2, @xy, 2) + %100: + longmove(@xy, @x3, 2) + longmove(@x2, @x1, 4) + longmove(@x1, @xy, 2) + %101: + longmove(@xy, @x2, 2) + longmove(@x2, @x3, 2) + longmove(@x3, @xy, 2) + +' draw triangle + + fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) + + +PUB finish + +'' Wait for any current graphics command to finish +'' use this to insure that it is safe to manually manipulate the bitmap + + setcommand(_loop, 0) 'make sure last command finished + + +PRI fill(x, y, da, db, db2, linechange, lines_minus_1) + + setcommand(_fill, @x) + + +PRI justify(string_ptr, justptr) | x + + x := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 + long[justptr] := -lookupz(text_just >> 2 & 3: 0, x >> 1, x, 0) + long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) + + +PRI setcommand(cmd, argptr) + + command := cmd << 16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + + +CON + + ' Vector font primitives + + xa0 = %000 << 0 'x line start / arc center + xa1 = %001 << 0 + xa2 = %010 << 0 + xa3 = %011 << 0 + xa4 = %100 << 0 + xa5 = %101 << 0 + xa6 = %110 << 0 + xa7 = %111 << 0 + + ya0 = %0000 << 3 'y line start / arc center + ya1 = %0001 << 3 + ya2 = %0010 << 3 + ya3 = %0011 << 3 + ya4 = %0100 << 3 + ya5 = %0101 << 3 + ya6 = %0110 << 3 + ya7 = %0111 << 3 + ya8 = %1000 << 3 + ya9 = %1001 << 3 + yaA = %1010 << 3 + yaB = %1011 << 3 + yaC = %1100 << 3 + yaD = %1101 << 3 + yaE = %1110 << 3 + yaF = %1111 << 3 + + xb0 = %000 << 7 'x line end + xb1 = %001 << 7 + xb2 = %010 << 7 + xb3 = %011 << 7 + xb4 = %100 << 7 + xb5 = %101 << 7 + xb6 = %110 << 7 + xb7 = %111 << 7 + + yb0 = %0000 << 10 'y line end + yb1 = %0001 << 10 + yb2 = %0010 << 10 + yb3 = %0011 << 10 + yb4 = %0100 << 10 + yb5 = %0101 << 10 + yb6 = %0110 << 10 + yb7 = %0111 << 10 + yb8 = %1000 << 10 + yb9 = %1001 << 10 + ybA = %1010 << 10 + ybB = %1011 << 10 + ybC = %1100 << 10 + ybD = %1101 << 10 + ybE = %1110 << 10 + ybF = %1111 << 10 + + ax1 = %0 << 7 'x arc radius + ax2 = %1 << 7 + + ay1 = %00 << 8 'y arc radius + ay2 = %01 << 8 + ay3 = %10 << 8 + ay4 = %11 << 8 + + a0 = %0000 << 10 'arc start/length + a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0°, 90°, 180°, 270°) + a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360°, 270°, 180°, 90°) + a3 = %0011 << 10 + a4 = %0100 << 10 + a5 = %0101 << 10 + a6 = %0110 << 10 + a7 = %0111 << 10 + a8 = %1000 << 10 + a9 = %1001 << 10 + aA = %1010 << 10 + aB = %1011 << 10 + aC = %1100 << 10 + aD = %1101 << 10 + aE = %1110 << 10 + aF = %1111 << 10 + + fline = %0 << 14 'line command + farc = %1 << 14 'arc command + + more = %1 << 15 'another arc/line + + +DAT + +' Color codes + +colors long %%0000000000000000 + long %%1111111111111111 + long %%2222222222222222 + long %%3333333333333333 + +' Round pixel recipes + +pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 + byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 + byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B + byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F + +' Vector font - standard ascii characters ($21-$7E) + +font word fline + xa2 + yaC + xb2 + yb7 + more '! + word fline + xa2 + ya5 + xb2 + yb4 + + word fline + xa1 + yaD + xb1 + ybC + more '" + word fline + xa3 + yaD + xb3 + ybC + + word fline + xa1 + yaA + xb1 + yb6 + more '# + word fline + xa3 + yaA + xb3 + yb6 + more + word fline + xa0 + ya9 + xb4 + yb9 + more + word fline + xa0 + ya7 + xb4 + yb7 + + word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ + word farc + xa2 + ya7 + aB + ax2 + ay1 + more + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + yaA + xb4 + ybA + more + word fline + xa2 + yaA + xb2 + ybB + more + word fline + xa2 + ya6 + xb2 + yb5 + + word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% + word farc + xa3 + ya6 + a0 + ax1 + ay1 + more + word fline + xa0 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& + word farc + xa2 + ya7 + a5 + ax2 + ay2 + more + word fline + xa1 + yaA + xb4 + yb5 + + word fline + xa2 + yaD + xb2 + ybC ' ' + + word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( + word farc + xa3 + ya7 + aE + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') + word farc + xa1 + ya7 + aF + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word fline + xa4 + ya6 + xb0 + ybA + more '* + word fline + xa0 + ya6 + xb4 + ybA + more + word fline + xa2 + yaB + xb2 + yb5 + + word fline + xa0 + ya8 + xb4 + yb8 + more '+ + word fline + xa2 + yaA + xb2 + yb6 + + word fline + xa2 + ya4 + xb1 + yb3 ', + + word fline + xa0 + ya8 + xb4 + yb8 '- + + word fline + xa2 + ya5 + xb2 + yb4 '. + + word fline + xa0 + ya4 + xb4 + ybC '/ + + word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 + + word fline + xa0 + ya4 + xb4 + yb4 + more '1 + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa0 + yaA + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 + word farc + xa2 + yaA + aF + ax2 + ay3 + more + word farc + xa2 + ya4 + aD + ax2 + ay3 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + yaC + xb0 + yb7 + more '4 + word fline + xa0 + ya7 + xb4 + yb7 + more + word fline + xa3 + ya4 + xb3 + yb8 + + word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 + word fline + xa4 + yaC + xb0 + ybC + more + word fline + xa0 + yaC + xb0 + yb8 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + ya4 + xb2 + yb4 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 + word farc + xa2 + ya8 + aD + ax2 + ay4 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa2 + yaC + xb3 + ybC + + word fline + xa0 + yaC + xb4 + ybC + more '7 + word fline + xa1 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 + word farc + xa2 + yaA + a0 + ax2 + ay2 + + word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 + word farc + xa2 + ya8 + aF + ax2 + ay4 + more + word fline + xa4 + ya8 + xb4 + ybA + more + word fline + xa1 + ya4 + xb2 + yb4 + + word fline + xa2 + ya6 + xb2 + yb7 + more ': + word fline + xa2 + yaA + xb2 + yb9 + + word fline + xa2 + ya4 + xb1 + yb3 + more '; + word fline + xa2 + ya8 + xb2 + yb7 + + word fline + xa0 + ya8 + xb4 + ybA + more '< + word fline + xa0 + ya8 + xb4 + yb6 + + word fline + xa0 + yaA + xb4 + ybA + more '= + word fline + xa0 + ya6 + xb4 + yb6 + + word fline + xa4 + ya8 + xb0 + ybA + more '> + word fline + xa4 + ya8 + xb0 + yb6 + + word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? + word farc + xa3 + yaB + aF + ax1 + ay2 + more + word farc + xa3 + ya7 + aD + ax1 + ay2 + more + word fline + xa2 + ya5 + xb2 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ + word farc + xa2 + ya8 + a4 + ax2 + ay3 + more + word farc + xa3 + ya8 + aF + ax1 + ay1 + more + word farc + xa2 + ya6 + aF + ax2 + ay1 + more + word fline + xa3 + ya7 + xb3 + yb9 + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A + word fline + xa0 + ya4 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + ybA + more + word fline + xa0 + ya8 + xb4 + yb8 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B + word farc + xa2 + ya6 + aB + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + + word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D + word farc + xa2 + ya6 + aF + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + yaC + xb2 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'E + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'F + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + yb7 + more + word fline + xa3 + ya7 + xb4 + yb7 + + word fline + xa0 + ya4 + xb0 + ybC + more 'H + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa0 + ya8 + xb4 + yb8 + + word fline + xa2 + ya4 + xb2 + ybC + more 'I + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'K + word fline + xa4 + yaC + xb0 + yb8 + more + word fline + xa4 + ya4 + xb0 + yb8 + + word fline + xa0 + ya4 + xb0 + ybC + more 'L + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa0 + ya4 + xb0 + ybC + more 'M + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa2 + ya8 + xb0 + ybC + more + word fline + xa2 + ya8 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'N + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa4 + ya4 + xb0 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa2 + ya6 + xb4 + yb3 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + more + word fline + xa4 + ya4 + xb2 + yb8 + + word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + ya4 + xb2 + ybC + more 'T + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U + word fline + xa0 + ya6 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa2 + ya4 + xb0 + ybC + more 'V + word fline + xa2 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb0 + yb4 + more 'W + word fline + xa4 + yaC + xb4 + yb4 + more + word fline + xa2 + ya8 + xb0 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb4 + + word fline + xa4 + ya4 + xb0 + ybC + more 'X + word fline + xa0 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb2 + yb8 + more 'Y + word fline + xa4 + yaC + xb2 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb8 + + word fline + xa0 + yaC + xb4 + ybC + more 'Z + word fline + xa0 + ya4 + xb4 + ybC + more + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb4 + ybD + more + word fline + xa2 + ya3 + xb4 + yb3 + + word fline + xa4 + ya4 + xb0 + ybC '\ + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb0 + ybD + more + word fline + xa2 + ya3 + xb0 + yb3 + + word fline + xa2 + yaA + xb0 + yb6 + more '^ + word fline + xa2 + yaA + xb4 + yb6 + + word fline + xa0 + ya1 + xa4 + yb1 '_ + + word fline + xa1 + ya9 + xb3 + yb7 '` + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a + word fline + xa4 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b + word fline + xa0 + ya4 + xb0 + ybC + + word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c + word fline + xa2 + ya4 + xb4 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd + word fline + xa4 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e + word fline + xa0 + ya6 + xb4 + yb6 + more + word fline + xa2 + ya4 + xb4 + yb4 + + word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya4 + xb2 + ybA + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya4 + xb4 + yb6 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'i + word fline + xa2 + ya4 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j + word fline + xa2 + ya3 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word fline + xa0 + ya4 + xb0 + ybC + more 'k + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + ya6 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb4 + yb4 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'l + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa1 + yaC + xb2 + ybC + + word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm + word farc + xa3 + ya7 + a8 + ax1 + ay1 + more + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb7 + more + word fline + xa4 + ya4 + xb4 + yb7 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb6 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 'o + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p + word fline + xa0 + ya1 + xb0 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q + word fline + xa4 + ya1 + xb4 + yb8 + + word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r + word fline + xa0 + ya4 + xb0 + yb8 + + word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's + word farc + xa2 + ya5 + aB + ax2 + ay1 + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb2 + ybA + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb8 + + word fline + xa0 + ya8 + xb2 + yb4 + more 'v + word fline + xa4 + ya8 + xb2 + yb4 + + word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w + word farc + xa3 + ya5 + aA + ax1 + ay1 + more + word fline + xa0 + ya5 + xb0 + yb8 + more + word fline + xa2 + ya5 + xb2 + yb6 + more + word fline + xa4 + ya5 + xb4 + yb8 + + word fline + xa0 + ya8 + xb4 + yb4 + more 'x + word fline + xa0 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word fline + xa0 + ya8 + xb4 + yb8 + more 'z + word fline + xa4 + ya8 + xb0 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ + word farc + xa1 + ya6 + aC + ax1 + ay2 + more + word farc + xa1 + yaA + aF + ax1 + ay2 + more + word farc + xa3 + ya6 + aE + ax1 + ay3 + + word fline + xa2 + ya3 + xb2 + ybD '| + + word farc + xa1 + yaA + aC + ax1 + ay3 + more '} + word farc + xa3 + ya6 + aD + ax1 + ay2 + more + word farc + xa3 + yaA + aE + ax1 + ay2 + more + word farc + xa1 + ya6 + aF + ax1 + ay3 + + word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ + word farc + xa3 + ya8 + aA + ax1 + ay1 + +' Vector font - custom characters ($7F+) + + word fline + xa2 + ya9 + xb0 + yb4 + more 'delta + word fline + xa2 + ya9 + xb4 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega + word farc + xa1 + ya7 + aE + ax1 + ay2 + more + word farc + xa3 + ya7 + aF + ax1 + ay2 + more + word fline + xa1 + ya5 + xb1 + yb4 + more + word fline + xa3 + ya5 + xb3 + yb4 + more + word fline + xa0 + ya4 + xb1 + yb4 + more + word fline + xa4 + ya4 + xb3 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet + +CON fx = 3 'number of custom characters + +DAT + +'************************************* +'* Assembly language graphics driver * +'************************************* + + org +' +' +' Graphics driver - main loop +' +loop rdlong t1,par wz 'wait for command + if_z jmp #loop + + movd :arg,#arg0 'get 8 arguments + mov t2,t1 + mov t3,#8 +:arg rdlong arg0,t2 + add :arg,d0 + add t2,#4 + djnz t3,#:arg + + wrlong zero,par 'zero command to signify received + + call #setd 'set dx,dy from arg0,arg1 + + ror t1,#16+2 'lookup command address + add t1,#jumps + movs :table,t1 + rol t1,#2 + shl t1,#3 +:table mov t2,0 + shr t2,t1 + and t2,#$FF + jmp t2 'jump to command + + +jumps byte 0 '0 + byte setup_ '1 + byte color_ '2 + byte width_ '3 + byte plot_ '4 + byte line_ '5 + byte arc_ '6 + byte vec_ '7 + byte vecarc_ '8 + byte pix_ '9 + byte pixarc_ 'A + byte text_ 'B + byte textarc_ 'C + byte textmode_ 'D + byte fill_ 'E + byte loop 'F +' +' +' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr +' +setup_ mov xlongs,arg0 'set xlongs, ylongs + mov ylongs,arg1 + mov xorigin,arg2 'set xorigin, yorigin + mov yorigin,arg3 + mov basesptr,arg5 'set pointers + mov slicesptr,arg6 + + jmp #loop +' +' +' color(c) +' +color_ mov pcolor,arg0 'set pixel color + + jmp #loop +' +' +' width(w) pixel_passes +' +width_ mov pwidth,arg0 'set pixel width + mov passes,arg1 'set pixel passes + + jmp #loop +' +' +' plot(x, y) +' +plot_ call #plotd + + jmp #loop +' +' +' line(x, y) +' +line_ call #linepd + + jmp #loop +' +' +' arc(x, y, xr, yr, angle, anglestep, iterations, mode) +' +arc_ and arg7,#3 'limit mode + +:loop call #arca 'get arc dx,dy + + cmp arg7,#1 wz 'if not mode 1, set px,py + if_nz mov px,dx + if_nz mov py,dy + + tjz arg6,#loop 'if no points exit with new px,py + + cmp arg7,#3 wz 'if mode 3, set center + if_z call #setd + + test arg7,#1 wz 'if mode 0 or 2, plot point + if_z call #plotp + + test arg7,#1 wz 'if mode 1 or 3, plot line + if_nz call #linepd + + cmp arg7,#2 wz 'if mode 2, set mode 1 + if_z mov arg7,#1 + + add arg4,arg5 'step angle + djnz arg6,#:loop 'loop if more iterations + + jmp #loop +' +' +' vec(x, y, vecscale, vecangle, vecdef_ptr) +' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) +' +' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +' word length 'vector length +' ... 'more vectors +' ... +' word 0 'end of definition +' +vecarc_ call #arcmod + +vec_ tjz arg2,#loop 'if scale 0, exit + +:loop rdword t7,arg4 wz 'get vector mode+angle + add arg4,#2 + + if_z jmp #loop 'if mode+angle 0, exit + + rdword t1,arg4 'get vector length + add arg4,#2 + + abs t2,arg2 wc 'add/sub vector angle to/from angle + mov t6,arg3 + sumc t6,t7 + + call #multiply 'multiply length by scale + add t1,#$80 'round up 1/2 lsb + shr t1,#8 + + mov t4,t1 'get arc dx,dy + mov t5,t1 + call #arcd + + test t7,h8000 wc 'plot pixel or draw line? + if_nc call #plotd + test t7,h8000 wc + if_c call #linepd + + jmp #:loop 'get next vector +' +' +' pix(x, y, pixrot, pixdef_ptr) +' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) +' +' pixdef: word +' byte xwords, ywords, xorigin, yorigin +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' ... +' +pixarc_ call #arcmod + +pix_ mov t6,pcolor 'save color + + mov px,dx 'get center into px,py + mov py,dy + + mov sy,pwidth 'get actual pixel width + add sy,#1 + + rdbyte dx,arg3 'get dimensions into dx,dy + add arg3,#1 + rdbyte dy,arg3 + add arg3,#1 + + rdbyte t1,arg3 'get origin and adjust px,py + add arg3,#1 + rdbyte t2,arg3 + add arg3,#1 + neg t2,t2 + sub t2,#1 + add t2,dy + mov t3,sy +:adjust test arg2,#%001 wz + test arg2,#%110 wc + if_z sumnc px,t1 + if_nz sumc py,t1 + test arg2,#%010 wc + if_nz sumnc px,t2 + if_z sumnc py,t2 + djnz t3,#:adjust + +:yline mov sx,#0 'plot entire pix + mov t3,dx +:xword rdword t4,arg3 'read next pix word + add arg3,#2 + shl t4,#16 + mov t5,#8 +:xpixel rol t4,#2 'plot pixel within word + test t4,#1 wc 'set color + muxc pcolor,color1 + test t4,#2 wc + muxc pcolor,color2 wz '(z=1 if color=0) + if_nz call #plotp + test arg2,#%001 wz 'update px,py for next x + test arg2,#%110 wc + if_z sumc px,sy + if_nz sumnc py,sy + add sx,sy + djnz t5,#:xpixel 'another x pixel? + djnz t3,#:xword 'another x word? + if_z sumnc px,sx 'update px,py for next y + if_nz sumc py,sx + test arg2,#%010 wc + if_nz sumc px,sy + if_z sumc py,sy + djnz dy,#:yline 'another y line? + + mov pcolor,t6 'restore color + + jmp #loop +' +' +' text(x, y, @string) justx, justy +' textarc(x, y, xr, yr, angle, @string) justx, justy +' +textarc_ call #arcmod + +text_ add arg3,arg0 'add x into justx + add arg4,arg1 'add y into justy + +:chr rdbyte t1,arg2 wz 'get chr + add arg2,#1 + + if_z jmp #loop 'if 0, done + + sub t1,#$21 'if chr out of range, skip + cmp t1,#$7F-$21+fx wc + if_nc jmp #:skip + + mov arg5,fontptr 'scan font for chr definition +:scan tjz t1,#:def + rdword t2,arg5 + add arg5,#2 + test t2,h8000 wc + if_nc sub t1,#1 + jmp #:scan + +:def rdword t7,arg5 'get font definition word + add arg5,#2 + + call #fontxy 'extract initial x,y + + test t7,#$80 wc 'arc or line? + if_nc jmp #:line + + + mov t2,textsx 'arc, extract x radius + mov t3,#%0001_0001_1 + call #fontb + mov t4,t1 + + mov t2,textsy 'extract y radius + mov t3,#%0010_0011_1 + call #fontb + mov t5,t1 + + mov t2,#1 'extract starting angle + mov t3,#%0010_0011_0 + call #fontb + shl t1,#11 + + mov t6,t1 'extract angle sweep + mov t3,#%0010_0011_0 + call #fontb + neg arg6,t1 + shl arg6,#4 + add arg6,#65 + + call #arcd 'plot initial arc point + call #plotd + +:arc call #arcd 'connect subsequent arc points with lines + call #linepd + add t6,#$80 + djnz arg6,#:arc + + jmp #:more + + +:line call #plotd 'line, plot initial x,y + + call #fontxy 'extract terminal x,y + + call #linepd 'draw line + + +:more test t7,#$02 wc 'more font definition? + if_c jmp #:def + +:skip mov t1,textsp 'advance x to next chr position + mov t2,textsx + call #multiply + add arg3,t1 + + jmp #:chr 'get next chr + + +fontxy mov t2,textsx 'extract x + mov t3,#%0011_0111_0 + call #fontb + mov arg0,t1 + add arg0,arg3 + + mov t2,textsy 'extract y + mov t3,#%0100_1111_0 + call #fontb + mov arg1,t1 + add arg1,arg4 + +setd mov dx,xorigin 'set dx,dy from arg0,arg1 + add dx,arg0 + mov dy,yorigin + sub dy,arg1 +setd_ret +fontxy_ret ret + + +fontb mov t1,t7 'extract bitrange from font word + shr t3,#1 wc + and t1,t3 + if_c add t1,#1 + shr t3,#4 + shr t7,t3 + + shl t1,#32-4 'multiply t1[3..0] by t2 + mov t3,#4 +:loop shl t1,#1 wc + if_c add t1,t2 + djnz t3,#:loop + +fontb_ret ret +' +' +' textmode(x_scale, y_scale, spacing, justification) +' +textmode_ mov textsx,arg0 'set text x scale + mov textsy,arg1 'set text y scale + mov textsp,arg2 'set text spacing + + jmp #loop +' +' +' fill(x, y, da, db, db2, linechange, lines_minus_1) +' +fill_ shl dx,#16 'get left and right fractions + or dx,h8000 + mov t1,dx + + mov t2,xlongs 'get x pixels + shl t2,#4 + + add arg6,#1 'pre-increment line counter + +:yloop add dx,arg2 'adjust left and right fractions + add t1,arg3 + + cmps dx,t1 wc 'get left and right integers + if_c mov base0,dx + if_c mov base1,t1 + if_nc mov base0,t1 + if_nc mov base1,dx + sar base0,#16 + sar base1,#16 + + cmps base0,t2 wc 'left out of range? + if_c cmps hFFFFFFFF,base1 wc 'right out of range? + if_c cmp dy,ylongs wc 'y out of range? + if_nc jmp #:skip 'if any, skip + + mins base0,#0 'limit left and right + maxs base1,t2 wc + if_nc sub base1,#1 + + shl base0,#1 'make left mask + neg mask0,#1 + shl mask0,base0 + shr base0,#5 + + shl base1,#1 'make right mask + xor base1,#$1E + neg mask1,#1 + shr mask1,base1 + shr base1,#5 + + sub base1,base0 wz 'ready long count + add base1,#1 + + if_z and mask0,mask1 'if single long, merge masks + + shl base0,#1 'get long base + add base0,basesptr + rdword base0,base0 + shl dy,#2 + add base0,dy + shr dy,#2 + + mov bits0,mask0 'ready left mask +:xloop mov bits1,pcolor 'make color mask + and bits1,bits0 + rdlong pass,base0 'read-modify-write long + andn pass,bits0 + or pass,bits1 + wrlong pass,base0 + shl ylongs,#2 'advance to next long + add base0,ylongs + shr ylongs,#2 + cmp base1,#2 wz 'one more? + if_nz neg bits0,#1 'if not, ready full mask + if_z mov bits0,mask1 'if one more, ready right mask + djnz base1,#:xloop 'loop if more longs + +:skip sub arg5,#1 wc 'delta change? + if_c mov arg3,arg4 'if so, set new deltas +:same + add dy,#1 'adjust y + djnz arg6,#:yloop 'another y? + + jmp #loop +' +' +' Plot line from px,py to dx,dy +' +linepd cmps dx,px wc, wr 'get x difference + negc sx,#1 'set x direction + + cmps dy,py wc, wr 'get y difference + negc sy,#1 'set y direction + + abs dx,dx 'make differences absolute + abs dy,dy + + cmp dx,dy wc 'determine dominant axis + if_nc tjz dx,#:last 'if both differences 0, plot single pixel + if_nc mov count,dx 'set pixel count + if_c mov count,dy + mov ratio,count 'set initial ratio + shr ratio,#1 + if_c jmp #:yloop 'x or y dominant? + + +:xloop call #plotp 'dominant x line + add px,sx + sub ratio,dy wc + if_c add ratio,dx + if_c add py,sy + djnz count,#:xloop + + jmp #:last 'plot last pixel + + +:yloop call #plotp 'dominant y line + add py,sy + sub ratio,dx wc + if_c add ratio,dy + if_c add px,sx + djnz count,#:yloop + +:last call #plotp 'plot last pixel + +linepd_ret ret +' +' +' Plot pixel at px,py +' +plotd mov px,dx 'set px,py to dx,dy + mov py,dy + +plotp tjnz pwidth,#wplot 'if width > 0, do wide plot + + mov t1,px 'compute pixel mask + shl t1,#1 + mov mask0,#%11 + shl mask0,t1 + shr t1,#5 + + cmp t1,xlongs wc 'if x or y out of bounds, exit + if_c cmp py,ylongs wc + if_nc jmp #plotp_ret + + mov bits0,pcolor 'compute pixel bits + and bits0,mask0 + + shl t1,#1 'get address of pixel long + add t1,basesptr + mov t2,py + rdword t1,t1 + shl t2,#2 + add t1,t2 + + rdlong t2,t1 'write pixel + andn t2,mask0 + or t2,bits0 + wrlong t2,t1 +plotp_ret +plotd_ret ret +' +' +' Plot wide pixel +' +wplot mov t1,py 'if y out of bounds, exit + add t1,#7 + mov t2,ylongs + add t2,#7+8 + cmp t1,t2 wc + if_nc jmp #plotp_ret + + mov t1,px 'determine x long pair + sub t1,#8 + sar t1,#4 + cmp t1,xlongs wc + muxc jumps,#%01 '(use jumps[1..0] to store writes) + add t1,#1 + cmp t1,xlongs wc + muxc jumps,#%10 + + test jumps,#%11 wz 'if x out of bounds, exit + if_z jmp #plotp_ret + + shl t1,#1 'get base pair + add t1,basesptr + rdword base1,t1 + sub t1,#2 + rdword base0,t1 + + mov t1,px 'determine pair shifts + shl t1,#1 + movs :shift1,t1 + xor :shift1,#7<<1 + add t1,#9<<1 + movs :shift0,t1 + test t1,#$F<<1 wz '(account for special case) + if_z andn jumps,#%01 + + mov pass,#0 'ready to plot slices + mov slice,slicesptr + +:loop rdlong mask0,slice 'get next slice + mov mask1,mask0 + +:shift0 shl mask0,#0 'position slice +:shift1 shr mask1,#0 + + mov bits0,pcolor 'colorize slice + and bits0,mask0 + mov bits1,pcolor + and bits1,mask1 + + mov t1,py 'plot lower slice + add t1,pass + cmp t1,ylongs wc + if_c call #wslice + + mov t1,py 'plot upper slice + test pwidth,#1 wc + subx t1,pass + cmp t1,ylongs wc + if_c call #wslice + + add slice,#4 'next slice + add pass,#1 + cmp pass,passes wz + if_nz jmp #:loop + + jmp #plotp_ret +' +' +' Plot wide pixel slice +' +wslice shl t1,#2 'ready long offset + + add base0,t1 'plot left slice + test jumps,#%01 wc + if_c rdlong t2,base0 + if_c andn t2,mask0 + if_c or t2,bits0 + if_c wrlong t2,base0 + + add base1,t1 'plot right slice + test jumps,#%10 wc + if_c rdlong t2,base1 + if_c andn t2,mask1 + if_c or t2,bits1 + if_c wrlong t2,base1 + + sub base0,t1 'restore bases + sub base1,t1 + +wslice_ret ret +' +' +' Get arc point from args and then move args 5..7 to 2..4 +' +arcmod call #arca 'get arc using first 5 args + + mov arg0,dx 'set arg0,arg1 + sub arg0,xorigin + mov arg1,yorigin + sub arg1,dy + + mov arg2,arg5 'move args 5..7 to 2..4 + mov arg3,arg6 + mov arg4,arg7 + +arcmod_ret ret +' +' +' Get arc dx,dy from arg0,arg1 +' +' in: arg0,arg1 = center x,y +' arg2/t4 = x length +' arg3/t5 = y length +' arg4/t6 = 13-bit angle +' +' out: dx,dy = arc point +' +arca mov t4,arg2 'use args + mov t5,arg3 + mov t6,arg4 + +arcd call #setd 'reset dx,dy to arg0,arg1 + + mov t1,t6 'get arc dx + mov t2,t4 + call #polarx + add dx,t1 + + mov t1,t6 'get arc dy + mov t2,t5 + call #polary + sub dy,t1 +arcd_ret +arca_ret ret +' +' +' Polar to cartesian +' +' in: t1 = 13-bit angle +' t2 = 16-bit length +' +' out: t1 = x|y +' +polarx add t1,sine_90 'cosine, add 90° for sine lookup +polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz + test t1,sine_90 wc 'get sine quadrant 2|4 into c + negc t1,t1 'if sine quadrant 2|4, negate table offset + or t1,sine_table 'or in sine table address >> 1 + shl t1,#1 'shift left to get final word address + rdword t1,t1 'read sine/cosine word + call #multiply 'multiply sine/cosine by length to get x|y + add t1,h8000 'add 1/2 lsb to round up x|y fraction + shr t1,#16 'justify x|y integer + negnz t1,t1 'if sine quadrant 3|4, negate x|y +polary_ret +polarx_ret ret + +sine_90 long $0800 '90° bit +sine_180 long $1000 '180° bit +sine_table long $E000 >> 1 'sine table address shifted right +' +' +' Multiply +' +' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) +' t2 = 16-bit multiplier +' +' out: t1 = 32-bit product +' +multiply mov t3,#16 + shl t2,#16 + shr t1,#1 wc + +:loop if_c add t1,t2 wc + rcr t1,#1 wc + djnz t3,#:loop + +multiply_ret ret +' +' +' Defined data +' +zero long 0 'constants +d0 long $200 +h8000 long $8000 +hFFFFFFFF long $FFFFFFFF +color1 long %%1111111111111111 +color2 long %%2222222222222222 + +fontptr long 0 'font pointer (set before cognew command) + +pcolor long %%1111111111111111 'pixel color +pwidth long 0 'pixel width +passes long 1 'pixel passes +textsx long 1 'text scale x +textsy long 1 'text scale y +textsp long 6 'text spacing +' +' +' Undefined data +' +t1 res 1 'temps +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 + +arg0 res 1 'arguments passed from high-level +arg1 res 1 +arg2 res 1 +arg3 res 1 +arg4 res 1 +arg5 res 1 +arg6 res 1 +arg7 res 1 + +basesptr res 1 'pointers +slicesptr res 1 + +xlongs res 1 'bitmap metrics +ylongs res 1 +xorigin res 1 +yorigin res 1 + +dx res 1 'line/plot coordinates +dy res 1 +px res 1 +py res 1 + +sx res 1 'line +sy res 1 +count res 1 +ratio res 1 + +pass res 1 'plot +slice res 1 +base0 res 1 +base1 res 1 +mask0 res 1 +mask1 res 1 +bits0 res 1 +bits1 res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-htext.spin b/lib/bel-htext.spin new file mode 100644 index 0000000..cea10ae --- /dev/null +++ b/lib/bel-htext.spin @@ -0,0 +1,548 @@ +''*************************************** +''* VGA High-Res Text Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** +'' +'' This object generates a 1024x768 VGA signal which contains 128 columns x 64 +'' rows of 8x12 characters. Each row can have a unique forground/background +'' color combination and each character can be inversed. There are also two +'' cursors which can be independently controlled (ie. mouse and keyboard). A +'' sync indicator signals each time the screen is refreshed (you may ignore). +'' +'' You must provide buffers for the screen, colors, cursors, and sync. Once +'' started, all interfacing is done via memory. To this object, all buffers are +'' read-only, with the exception of the sync indicator which gets written with +'' -1. You may freely write all buffers to affect screen appearance. Have fun! +'' + +CON + +'{ +' 1024 x 768 @ 57Hz settings: 128 x 64 characters + + hp = 1024 'horizontal pixels + vp = 768 'vertical pixels + hf = 16 'horizontal front porch pixels + hs = 96 'horizontal sync pixels + hb = 176 'horizontal back porch pixels + vf = 1 'vertical front porch lines + vs = 3 'vertical sync lines + vb = 28 'vertical back porch lines + hn = 1 'horizontal normal sync state (0|1) + vn = 1 'vertical normal sync state (0|1) + pr = 60 'pixel rate in MHz at 80MHz system clock (5MHz granularity) + +'} +{ +' 800 x 600 @ 75Hz settings: 100 x 50 characters + + hp = 800 'horizontal pixels + vp = 600 'vertical pixels + hf = 40 'horizontal front porch pixels + hs = 128 'horizontal sync pixels + hb = 88 'horizontal back porch pixels + vf = 1 'vertical front porch lines + vs = 4 'vertical sync lines + vb = 23 'vertical back porch lines + hn = 0 'horizontal normal sync state (0|1) + vn = 0 'vertical normal sync state (0|1) + pr = 50 'pixel rate in MHz at 80MHz system clock (5MHz granularity) +} +{ +' 640 x 480 @ 69Hz settings: 80 x 40 characters + + hp = 640 'horizontal pixels + vp = 480 'vertical pixels + hf = 24 'horizontal front porch pixels + hs = 40 'horizontal sync pixels + hb = 128 'horizontal back porch pixels + vf = 9 'vertical front porch lines + vs = 3 'vertical sync lines + vb = 28 'vertical back porch lines + hn = 1 'horizontal normal sync state (0|1) + vn = 1 'vertical normal sync state (0|1) + pr = 30 'pixel rate in MHz at 80MHz system clock (5MHz granularity) +} + +' columns and rows + + cols = hp / 8 + rows = vp / 12 + + +VAR long cog[2] + +PUB start(BasePin, ScreenPtr, ColorPtr, CursorPtr, SyncPtr) : okay | i, j + +'' Start VGA driver - starts two COGs +'' returns false if two COGs not available +'' +'' BasePin = VGA starting pin (0, 8, 16, 24, etc.) +'' +'' ScreenPtr = Pointer to 8,192 bytes containing ASCII codes for each of the +'' 128x64 screen characters. Each byte's top bit controls color +'' inversion while the lower seven bits provide the ASCII code. +'' Screen memory is arranged left-to-right, top-to-bottom. +'' +'' screen byte example: %1_1000001 = inverse "A" +'' +'' ColorPtr = Pointer to 64 words which define the foreground and background +'' colors for each row. The lower byte of each word contains the +'' foreground RGB data for that row, while the upper byte +'' contains the background RGB data. The RGB data in each byte is +'' arranged as %RRGGBB00 (4 levels each). +'' +'' color word example: %%0020_3300 = gold on blue +'' +'' CursorPtr = Pointer to 6 bytes which control the cursors: +'' +'' bytes 0,1,2: X, Y, and MODE of cursor 0 +'' bytes 3,4,5: X, Y, and MODE of cursor 1 +'' +'' X and Y are in terms of screen characters +'' (left-to-right, top-to-bottom) +'' +'' MODE uses three bottom bits: +'' +'' %x00 = cursor off +'' %x01 = cursor on +'' %x10 = cursor on, blink slow +'' %x11 = cursor on, blink fast +'' %0xx = cursor is solid block +'' %1xx = cursor is underscore +'' +'' cursor example: 127, 63, %010 = blinking block in lower-right +'' +'' SyncPtr = Pointer to long which gets written with -1 upon each screen +'' refresh. May be used to time writes/scrolls, so that chopiness +'' can be avoided. You must clear it each time if you want to see +'' it re-trigger. + + 'if driver is already running, stop it + stop + + 'implant pin settings + reg_vcfg := $200000FF + (BasePin & %111000) << 6 + i := $FF << (BasePin & %011000) + j := BasePin & %100000 == 0 + reg_dira := i & j + reg_dirb := i & !j + + 'implant CNT value to sync COGs to + sync_cnt := cnt + $10000 + + 'implant pointers + longmove(@screen_base, @ScreenPtr, 3) + font_base := @font + + 'implant unique settings and launch first COG + vf_lines.byte := vf + vb_lines.byte := vb + font_third := 1 + cog[1] := cognew(@d0, SyncPtr) + 1 + + 'allow time for first COG to launch + waitcnt($2000 + cnt) + + 'differentiate settings and launch second COG + vf_lines.byte := vf+4 + vb_lines.byte := vb-4 + font_third := 0 + cog[0] := cognew(@d0, SyncPtr) + 1 + + 'if both COGs launched, return true + if cog[0] and cog[1] + return true + + 'else, stop any launched COG and return false + else + stop + + +PUB stop | i + +'' Stop VGA driver - frees two COGs + + repeat i from 0 to 1 + if cog[i] + cogstop(cog[i]~ - 1) + + +CON + + #1, scanbuff[128], scancode[128*2-1+3], maincode 'enumerate COG RAM usage + + main_size = $1F0 - maincode 'size of main program + + hv_inactive = (hn << 1 + vn) * $0101 'H,V inactive states + + +DAT + +'***************************************************** +'* Assembly language VGA high-resolution text driver * +'***************************************************** + +' This program runs concurrently in two different COGs. +' +' Each COG's program has different values implanted for front-porch lines and +' back-porch lines which surround the vertical sync pulse lines. This allows +' timed interleaving of their active display signals during the visible portion +' of the field scan. Also, they are differentiated so that one COG displays +' even four-line groups while the other COG displays odd four-line groups. +' +' These COGs are launched in the PUB 'start' and are programmed to synchronize +' their PLL-driven video circuits so that they can alternately prepare sets of +' four scan lines and then display them. The COG-to-COG switchover is seemless +' due to two things: exact synchronization of the two video circuits and the +' fact that all COGs' driven output states get OR'd together, allowing one COG +' to output lows during its preparatory state while the other COG effectively +' drives the pins to create the visible and sync portions of its scan lines. +' During non-visible scan lines, both COGs output together in unison. +' +' COG RAM usage: $000 = d0 - used to inc destination fields for indirection +' $001-$080 = scanbuff - longs which hold 4 scan lines +' $081-$182 = scancode - stacked WAITVID/SHR for fast display +' $183-$1EF = maincode - main program loop which drives display + + org 'set origin to $000 for start of program + +d0 long 1 << 9 'd0 always resides here at $000, executes as NOP + + +' Initialization code and data - after execution, space gets reused as scanbuff + + 'Move main program into maincode area + +:move mov $1EF,main_begin+main_size-1 + sub :move,d0s0 '(do reverse move to avoid overwrite) + djnz main_ctr,#:move + + 'Build scanbuff display routine into scancode + +:waitvid mov scancode+0,i0 'org scancode +:shr mov scancode+1,i1 'waitvid color,scanbuff+0 + add :waitvid,d1 'shr scanbuff+0,#8 + add :shr,d1 'waitvid color,scanbuff+1 + add i0,#1 'shr scanbuff+1,#8 + add i1,d0 '... + djnz scan_ctr,#:waitvid 'waitvid color,scanbuff+cols-1 + + mov scancode+cols*2-1,i2 'mov vscl,#hf + mov scancode+cols*2+0,i3 'waitvid hvsync,#0 + mov scancode+cols*2+1,i4 'jmp #scanret + + 'Init I/O registers and sync COGs' video circuits + + mov dira,reg_dira 'set pin directions + mov dirb,reg_dirb + movi frqa,#(pr / 5) << 2 'set pixel rate + mov vcfg,reg_vcfg 'set video configuration + mov vscl,#1 'set video to reload on every pixel + waitcnt sync_cnt,colormask 'wait for start value in cnt, add ~1ms + movi ctra,#%00001_110 'COGs in sync! enable PLLs now - NCOs locked! + waitcnt sync_cnt,#0 'wait ~1ms for PLLs to stabilize - PLLs locked! + mov vscl,#100 'insure initial WAITVIDs lock cleanly + + 'Jump to main loop + + jmp #vsync 'jump to vsync - WAITVIDs will now be locked! + + 'Data + +d0s0 long 1 << 9 + 1 +d1 long 1 << 10 +main_ctr long main_size +scan_ctr long cols + +i0 waitvid x,scanbuff+0 +i1 shr scanbuff+0,#8 +i2 mov vscl,#hf +i3 waitvid hvsync,#0 +i4 jmp #scanret + +reg_dira long 0 'set at runtime +reg_dirb long 0 'set at runtime +reg_vcfg long 0 'set at runtime +sync_cnt long 0 'set at runtime + + 'Directives + + fit scancode 'make sure initialization code and data fit +main_begin org maincode 'main code follows (gets moved into maincode) + + +' Main loop, display field - each COG alternately builds and displays four scan lines + +vsync mov x,#vs 'do vertical sync lines + call #blank_vsync + +vb_lines mov x,#vb 'do vertical back porch lines (# set at runtime) + call #blank_vsync + + mov screen_ptr,screen_base 'reset screen pointer to upper-left character + mov color_ptr,color_base 'reset color pointer to first row + mov row,#0 'reset row counter for cursor insertion + mov fours,#rows * 3 / 2 'set number of 4-line builds for whole screen + + 'Build four scan lines into scanbuff + +fourline mov font_ptr,font_third 'get address of appropriate font section + shl font_ptr,#7+2 + add font_ptr,font_base + + movd :pixa,#scanbuff-1 'reset scanbuff address (pre-decremented) + movd :pixb,#scanbuff-1 + + mov y,#2 'must build scanbuff in two sections because + mov vscl,vscl_line2x '..pixel counter is limited to twelve bits + +:halfrow waitvid underscore,#0 'output lows to let other COG drive VGA pins + mov x,#cols/2 '..for 2 scan lines, ready for half a row + +:column rdbyte z,screen_ptr 'get character from screen memory + ror z,#7 'get inverse flag into bit 0, keep chr high + shr z,#32-7-2 wc 'get inverse flag into c, chr into bits 8..2 + add z,font_ptr 'add font section address to point to 8*4 pixels + add :pixa,d0 'increment scanbuff destination addresses + add :pixb,d0 + add screen_ptr,#1 'increment screen memory address +:pixa rdlong scanbuff,z 'read pixel long (8*4) into scanbuff +:pixb if_nc xor scanbuff,longmask 'invert pixels according to inverse flag + djnz x,#:column 'another character in this half-row? + + djnz y,#:halfrow 'loop to do 2nd half-row, time for 2nd WAITVID + + sub screen_ptr,#cols 'back up to start of same row in screen memory + + 'Insert cursors into scanbuff + + mov z,#2 'ready for two cursors + +:cursor rdbyte x,cursor_base 'x in range? + add cursor_base,#1 + cmp x,#cols wc + + rdbyte y,cursor_base 'y match? + add cursor_base,#1 + cmp y,row wz + + rdbyte y,cursor_base 'get cursor mode + add cursor_base,#1 + + if_nc_or_nz jmp #:nocursor 'if cursor not in scanbuff, no cursor + + add x,#scanbuff 'cursor in scanbuff, set scanbuff address + movd :xor,x + + test y,#%010 wc 'get mode bits into flags + test y,#%001 wz + if_nc_and_z jmp #:nocursor 'if cursor disabled, no cursor + + if_c_and_z test slowbit,cnt wc 'if blink mode, get blink state + if_c_and_nz test fastbit,cnt wc + + test y,#%100 wz 'get box or underscore cursor piece + if_z mov x,longmask + if_nz mov x,underscore + if_nz cmp font_third,#2 wz 'if underscore, must be last font section + +:xor if_nc_and_z xor scanbuff,x 'conditionally xor cursor into scanbuff + +:nocursor djnz z,#:cursor 'second cursor? + + sub cursor_base,#3*2 'restore cursor base + + 'Display four scan lines from scanbuff + + rdword x,color_ptr 'get color pattern for current row + and x,colormask 'mask away hsync and vsync signal states + or x,hv 'insert inactive hsync and vsync states + + mov y,#4 'ready for four scan lines + +scanline mov vscl,vscl_chr 'set pixel rate for characters + jmp #scancode 'jump to scanbuff display routine in scancode +scanret mov vscl,#hs 'do horizontal sync pixels + waitvid hvsync,#1 '#1 makes hsync active + mov vscl,#hb 'do horizontal back porch pixels + waitvid hvsync,#0 '#0 makes hsync inactive + shr scanbuff+cols-1,#8 'shift last column's pixels right by 8 + djnz y,#scanline 'another scan line? + + 'Next group of four scan lines + + add font_third,#2 'if font_third + 2 => 3, subtract 3 (new row) + cmpsub font_third,#3 wc 'c=0 for same row, c=1 for new row + if_c add screen_ptr,#cols 'if new row, advance screen pointer + if_c add color_ptr,#2 'if new row, advance color pointer + if_c add row,#1 'if new row, increment row counter + djnz fours,#fourline 'another 4-line build/display? + + 'Visible section done, do vertical sync front porch lines + + wrlong longmask,par 'write -1 to refresh indicator + +vf_lines mov x,#vf 'do vertical front porch lines (# set at runtime) + call #blank + + jmp #vsync 'new field, loop to vsync + + 'Subroutine - do blank lines + +blank_vsync xor hvsync,#$101 'flip vertical sync bits + +blank mov vscl,hx 'do blank pixels + waitvid hvsync,#0 + mov vscl,#hf 'do horizontal front porch pixels + waitvid hvsync,#0 + mov vscl,#hs 'do horizontal sync pixels + waitvid hvsync,#1 + mov vscl,#hb 'do horizontal back porch pixels + waitvid hvsync,#0 + djnz x,#blank 'another line? +blank_ret +blank_vsync_ret ret + + 'Data + +screen_base long 0 'set at runtime (3 contiguous longs) +color_base long 0 'set at runtime +cursor_base long 0 'set at runtime + +font_base long 0 'set at runtime +font_third long 0 'set at runtime + +hx long hp 'visible pixels per scan line +vscl_line2x long (hp + hf + hs + hb) * 2 'total number of pixels per 2 scan lines +vscl_chr long 1 << 12 + 8 '1 clock per pixel and 8 pixels per set +colormask long $FCFC 'mask to isolate R,G,B bits from H,V +longmask long $FFFFFFFF 'all bits set +slowbit long 1 << 25 'cnt mask for slow cursor blink +fastbit long 1 << 24 'cnt mask for fast cursor blink +underscore long $FFFF0000 'underscore cursor pattern +hv long hv_inactive '-H,-V states +hvsync long hv_inactive ^ $200 '+/-H,-V states + + 'Uninitialized data + +screen_ptr res 1 +color_ptr res 1 +font_ptr res 1 + +x res 1 +y res 1 +z res 1 + +row res 1 +fours res 1 + + +' 8 x 12 font - characters 0..127 +' +' Each long holds four scan lines of a single character. The longs are arranged into +' groups of 128 which represent all characters (0..127). There are three groups which +' each contain a vertical third of all characters. They are ordered top, middle, and +' bottom. + +' jedes zeichen besteht aus 3 x 4 zeilen zu je 8 pixeln. in den drei unteren blöcken +' ist je für eines der 128 zeichen ein long, welches 4 scanzeilen enthält. der erste +' long jedes blockes enthält also 3 x 4 zeilen des ersten zeichens. +' +' damit ergibt sich 1024 / 8 = 128 Zeichen +' 768 / 12 = 64 Zeilen +' +' erstes zeichen: +' $0C080000 oben +' $080C7E7E mitte +' $00000000 unten +' +' 0C 00001100 +' 08 00001000 +' 00 00000000 +' 00 00000000 +' 08 00001000 +' 0C 00001100 +' 7E 01111110 +' 7E 01111110 +' 00 00000000 +' 00 00000000 +' 00 00000000 +' 00 00000000 + + + + +font long + +long $0C080000,$30100000,$7E3C1800,$18181800,$81423C00,$99423C00,$8181FF00,$E7C3FF00 'top +long $1E0E0602,$1C000000,$00000000,$00000000,$18181818,$18181818,$00000000,$18181818 +long $00000000,$18181818,$18181818,$18181818,$18181818,$00FFFF00,$CC993366,$66666666 +long $AA55AA55,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$00000000,$00000000,$00000000 +long $00000000,$3C3C1800,$77666600,$7F363600,$667C1818,$46000000,$1B1B0E00,$1C181800 +long $0C183000,$180C0600,$66000000,$18000000,$00000000,$00000000,$00000000,$60400000 +long $73633E00,$1E181000,$66663C00,$60663C00,$3C383000,$06067E00,$060C3800,$63637F00 +long $66663C00,$66663C00,$1C000000,$00000000,$18306000,$00000000,$180C0600,$60663C00 +long $63673E00,$66663C00,$66663F00,$63663C00,$66361F00,$06467F00,$06467F00,$63663C00 +long $63636300,$18183C00,$30307800,$36666700,$06060F00,$7F776300,$67636300,$63361C00 +long $66663F00,$63361C00,$66663F00,$66663C00,$185A7E00,$66666600,$66666600,$63636300 +long $66666600,$66666600,$31637F00,$0C0C3C00,$03010000,$30303C00,$361C0800,$00000000 +long $0C000000,$00000000,$06060700,$00000000,$30303800,$00000000,$0C6C3800,$00000000 +long $06060700,$00181800,$00606000,$06060700,$18181E00,$00000000,$00000000,$00000000 +long $00000000,$00000000,$00000000,$00000000,$0C080000,$00000000,$00000000,$00000000 +long $00000000,$00000000,$00000000,$18187000,$18181800,$18180E00,$73DBCE00,$18180000 + +long $080C7E7E,$10307E7E,$18181818,$7E181818,$81818181,$99BDBDBD,$81818181,$E7BD99BD 'middle +long $1E3E7E3E,$1C3E3E3E,$30F0C000,$0C0F0300,$00C0F030,$00030F0C,$00FFFF00,$18181818 +long $18FFFF00,$00FFFF18,$18F8F818,$181F1F18,$18FFFF18,$00FFFF00,$CC993366,$66666666 +long $AA55AA55,$FFFF0F0F,$F0F00F0F,$0F0F0F0F,$00000F0F,$FFFF0000,$F0F00000,$0F0F0000 +long $00000000,$0018183C,$00000033,$7F363636,$66603C06,$0C183066,$337B5B0E,$0000000C +long $0C060606,$18303030,$663CFF3C,$18187E18,$00000000,$00007E00,$00000000,$060C1830 +long $676F6B7B,$18181818,$0C183060,$60603860,$307F3336,$60603E06,$66663E06,$0C183060 +long $66763C6E,$60607C66,$1C00001C,$00001C1C,$180C060C,$007E007E,$18306030,$00181830 +long $033B7B7B,$66667E66,$66663E66,$63030303,$66666666,$06263E26,$06263E26,$63730303 +long $63637F63,$18181818,$33333030,$36361E36,$66460606,$63636B7F,$737B7F6F,$63636363 +long $06063E66,$7B636363,$66363E66,$66301C06,$18181818,$66666666,$66666666,$366B6B63 +long $663C183C,$18183C66,$43060C18,$0C0C0C0C,$30180C06,$30303030,$00000063,$00000000 +long $0030381C,$333E301E,$6666663E,$0606663C,$3333333E,$067E663C,$0C0C3E0C,$3333336E +long $66666E36,$1818181C,$60606070,$361E3666,$18181818,$6B6B6B3F,$6666663E,$6666663C +long $6666663B,$3333336E,$066E7637,$300C663C,$0C0C0C7E,$33333333,$66666666,$6B6B6363 +long $1C1C3663,$66666666,$0C30627E,$180C060C,$18181818,$18306030,$00000000,$0018187E + +long $00000000,$00000000,$00001818,$0000183C,$00003C42,$00003C42,$0000FF81,$0000FFC3 'bottom +long $0002060E,$00000000,$18181818,$18181818,$00000000,$00000000,$00000000,$18181818 +long $18181818,$00000000,$18181818,$18181818,$18181818,$00FFFF00,$CC993366,$66666666 +long $AA55AA55,$FFFFFFFF,$F0F0F0F0,$0F0F0F0F,$00000000,$FFFFFFFF,$F0F0F0F0,$0F0F0F0F +long $00000000,$00001818,$00000000,$00003636,$0018183E,$00006266,$00006E3B,$00000000 +long $00003018,$0000060C,$00000000,$00000000,$0C181C1C,$00000000,$00001C1C,$00000103 +long $00003E63,$00007E18,$00007E66,$00003C66,$00007830,$00003C66,$00003C66,$00000C0C +long $00003C66,$00001C30,$0000001C,$0C181C1C,$00006030,$00000000,$0000060C,$00001818 +long $00003E07,$00006666,$00003F66,$00003C66,$00001F36,$00007F46,$00000F06,$00007C66 +long $00006363,$00003C18,$00001E33,$00006766,$00007F66,$00006363,$00006363,$00001C36 +long $00000F06,$00603C36,$00006766,$00003C66,$00003C18,$00003C66,$0000183C,$00003636 +long $00006666,$00003C18,$00007F63,$00003C0C,$00004060,$00003C30,$00000000,$FFFF0000 +long $00000000,$00006E33,$00003B66,$00003C66,$00006E33,$00003C66,$00001E0C,$1E33303E +long $00006766,$00007E18,$3C666660,$00006766,$00007E18,$00006B6B,$00006666,$00003C66 +long $0F063E66,$78303E33,$00000F06,$00003C66,$0000386C,$00006E33,$0000183C,$00003636 +long $00006336,$1C30607C,$00007E46,$00007018,$00001818,$00000E18,$00000000,$0000007E + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-keyb.spin b/lib/bel-keyb.spin new file mode 100644 index 0000000..a5771e9 --- /dev/null +++ b/lib/bel-keyb.spin @@ -0,0 +1,1161 @@ +''*************************************** +''* PS/2 Keyboard Driver v1.0.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +{-----------------REVISION HISTORY--------------------------------- + v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96 + ------------------------------------------------------------------} + +{-----------------KEYBOARD LAYOUT HISTORY-------------------------- + 2009-08-31 (Y-M-D) + Patch for german keyboard layout + Author: oog + Added german keyboard layout. + Original layout is commented as keyboard-us-en (US-English). + German layout is commented as keyboard-de (de = deutsch = "german"). + + Now there are two tables for keys with and without SHIFT-Key. + It should be easier to implement different international layouts. + However, it's bigger now and uses more memory. + + 2009-09-05 (Y-M-D) + Fixed bugs + - code bug on home-key fixed + new replace-codes for de_ae, de_ou and de_ue + + New + - Documentation of control-key bits + This should be helpful for translatíons of this driver into + different languages. + - table_alt_r + This table contains characters for the german "AltGr" key. + - AltGr+F1..F12 + Returns line-characters, selected from $90..$9f + + 2009-09-06 (Y-M-D) + Fixed bugs + - patch table_shift for "?" + + Differences to Parallax driver: + - Different codes for NumLock, CapsLock and ScrLock to avoid + conflict with german "ß" + Codes are defined as constants and easy to change + - Easy Cursor codes implemented to avoit conflict with the "Ä"-key + Easy Cursor codes are easy to understand, + for example "Cursor Left" is the character "←" + + ------------------------------------------------------------------} + +con + de_ae = $A6 'replace code - not used on keyboard + de_oe = $A7 'replace code - not used on keyboard + de_ue = $A8 'replace code - not used on keyboard + lock = $BC 'Parallax used codes $DD, $DE and $DF + 'There was a conflict between $DF=NumLock="ß" + ScrLk = lock + CpsLk = lock+1 + NumLk = lock+2 + +' +'Uncomment one of the next constant blocks +' +' + +{{Parallax cursor codes start}} +{{ + CrsLt = $C0E4 + CrsRt = $C1E6 + CrsUp = $C2E8 + CrsDn = $C3E2 + CrsHm = $C4E7 'Conflict with key "Ä" ($C4) + CrsEn = $C5E1 + PgUp = $C6E9 + PgDn = $C7E3 + Bksp = $00C8 + Del = $C9EA + Ins = $CAE0 + Esc = $00CB + Apps = $CC00 + Power = $CD00 + Sleep = $CE00 + WkUp = $CF00 +}} +{{Parallax cursor codes end}} + + +{{Easy cursor codes start}} + + CrsLt = $02E4 '← + CrsRt = $03E6 '→ + CrsUp = $04E8 '↑ + CrsDn = $05E2 '↓ + CrsHm = $06E7 '◀ + CrsEn = $07E1 '▶ + PgUp = $A0E9 ' + PgDn = $A2E3 ' + Bksp = $00C8 'È + Del = $BAEA ' + Ins = $BBE0 ' + Esc = $001B ' + Apps = $CC00 'Ì + Power = $CD00 'Í + Sleep = $CE00 'Î + WkUp = $CF00 'Ï + +{{Easy cursor codes end}} + +VAR + + long cog + + long par_tail 'key buffer tail read/write (19 contiguous longs) + long par_head 'key buffer head read-only + long par_present 'keyboard present read-only + long par_states[8] 'key states (256 bits) read-only + long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters) + + +PUB start(dpin, cpin) : okay + +'' Start keyboard driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS +'' +'' all lock-keys will be enabled, NumLock will be initially 'on', +'' and auto-repeat will be set to 15cps with a delay of .5s + + okay := startx(dpin, cpin, %0_000_000, %01_01000) + + +PUB startx(dpin, cpin, locks, auto) : okay + +'' Like start, but allows you to specify lock settings and auto-repeat +'' +'' locks = lock setup +'' bit 6 disallows shift-alphas (case set soley by CapsLock) +'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state +'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock +'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') +'' +'' auto = auto-repeat setup +'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) +'' bits 4..0 specify repeat rate (0=30cps..31=2cps) +'' (eg %01_00000 = .5s delay, 30cps repeat) + + stop + longmove(@par_keys, @dpin, 4) + okay := cog := cognew(@entry, @par_tail) + 1 + + +PUB stop + +'' Stop keyboard driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@par_tail, 0, 19) + + +PUB present : truefalse + +'' Check if keyboard present - valid ~2s after start +'' returns t|f + + truefalse := -par_present + + +PUB key : keycode + +'' Get key (never waits) +'' returns key (0 if buffer empty) + + if par_tail <> par_head + keycode := par_keys.word[par_tail] + par_tail := ++par_tail & $F + + +PUB getkey : keycode + +'' Get next key (may wait for keypress) +'' returns key + + repeat until (keycode := key) + + +PUB newkey : keycode + +'' Clear buffer and get new key (always waits for keypress) +'' returns key + + par_tail := par_head + keycode := getkey + + +PUB gotkey : truefalse + +'' Check if any key in buffer +'' returns t|f + + truefalse := par_tail <> par_head + + +PUB clearkeys + +'' Clear key buffer + + par_tail := par_head + + +PUB keystate(k) : state + +'' Get the state of a particular key +'' returns t|f + + state := -(par_states[k >> 5] >> k & 1) + + +DAT + +'****************************************** +'* Assembly language PS/2 keyboard driver * +'****************************************** + + org +' +' +' Entry +' +entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto + mov x,par + add x,#11*4 + mov y,#4 +:par rdlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + mov _head,#0 'reset output parameter _head +' +' +' Reset keyboard +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + movd :par,#_present 'reset output parameters _present/_states[8] + mov x,#1+8 +:par mov 0,#0 + add :par,dlsb + djnz x,#:par + + mov stat,#8 'set reset flag +' +' +' Update parameters +' +update movd :par,#_head 'update output parameters _head/_present/_states[8] + mov x,par + add x,#1*4 + mov y,#1+1+8 +:par wrlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + test stat,#8 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get scancode +' +newcode mov stat,#0 'reset state + +:same call #receive 'receive byte from keyboard + + cmp data,#$83+1 wc 'scancode? + + if_nc cmp data,#$AA wz 'powerup/reset? + if_nc_and_z jmp #configure + + if_nc cmp data,#$E0 wz 'extended? + if_nc_and_z or stat,#1 + if_nc_and_z jmp #:same + + if_nc cmp data,#$F0 wz 'released? + if_nc_and_z or stat,#2 + if_nc_and_z jmp #:same + + if_nc jmp #newcode 'unknown, ignore +' +' +' Translate scancode and enter into buffer +' + test stat,#1 wc 'lookup code with extended flag + rcl data,#1 + mov data_s,data 'keyboard-de: store scancode for next table lookup with shift + call #look + + cmp data,#0 wz 'if unknown, ignore + if_z jmp #newcode + + mov t,_states+6 'remember lock keys in _states + + mov x,data 'set/clear key bit in _states + shr x,#5 + add x,#_states + movd :reg,x + mov y,#1 + shl y,data + test stat,#2 wc +:reg muxnc 0,y + + if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done + if_c jmp #update + + mov y,_states+7 'get shift/ctrl/alt/win bit pairs + shr y,#16 + + cmpsub data,#$E0 wc 'translate keypad, considering numlock + if_c test _locks,#%100 wz + if_c_and_z add data,#@keypad1-@table + if_c_and_nz add data,#@keypad2-@table + if_c call #look + if_c jmp #:flags + + 'for keyboard-de changed #$DD to #lock + 'in next code segment + + cmpsub data,#lock wc 'handle scrlock/capslock/numlock + if_c mov x,#%001_000 + if_c shl x,data + if_c andn x,_locks + if_c shr x,#3 + if_c shr t,#29 'ignore auto-repeat + if_c andn x,t wz + if_c xor _locks,x + if_c add data,#lock + if_c_and_nz or stat,#4 'if change, set configure flag to update leds + +{{ for keyboard-us-en start }} +{{ + + test y,#%11 wz 'get shift into nz +' +'Translate scan-codes $5B..$60 with characters from table "shift1" +' + if_nz cmp data,#$60+1 wc 'check shift1 + if_nz_and_c cmpsub data,#$5B wc + if_nz_and_c add data,#@shift1-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + +' +'Translate scan-codes $27..$3D with characters from table "shift2" +' + if_nz cmp data,#$3D+1 wc 'check shift2 + if_nz_and_c cmpsub data,#$27 wc + if_nz_and_c add data,#@shift2-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + test _locks,#%010 wc 'check shift-alpha, considering capslock + muxnc :shift,#$20 + test _locks,#$40 wc + if_nz_and_nc xor :shift,#$20 + cmp data,#"z"+1 wc + if_c cmpsub data,#"a" wc +:shift if_c add data,#"A" + if_c andn y,#%11 +}} +{{ for keyboard-us-en end }} + +{{ for keyboard-de start }} + + cmp data,#de_ae wz 'replace ae + if_z mov data,#"ä" + cmp data,#de_oe wz 'replace oe + if_z mov data,#"ö" + cmp data,#de_ue wz 'replace ue + if_z mov data,#"ü" + +' +'Documentation of control-key bits +' +' test y,#%00000011 wz 'get SHIFT into nz +' test y,#%00000100 wz 'get CTRL-L into nz +' test y,#%00001000 wz 'get CTRL-R into nz +' test y,#%00010000 wz 'get ALT-L into nz +' test y,#%00100000 wz 'get ALT-R into nz +' test y,#%01000000 wz 'get WIN-L into nz +' test y,#%10000000 wz 'get WIN-R into nz + + +' +'Translate scan-codes with characters from "table_shift" +' + + test y,#%00000011 wz 'get shift into nz + test _locks,#$40 wc + if_nz_and_nc mov data,data_s 'reload scancode + if_nz_and_nc call #look_shift 'translate by table_shift + + +' +'Translate scan-codes with characters from "table_alt_r" +' + + test y,#%00100000 wz 'get ALT-R (AltGr) into nz + if_nz mov data,data_s 'reload scancode + if_nz call #look_alt_r 'translate by table_alt_r + + +{{ for keyboard-de end }} + + +:flags ror data,#8 'add shift/ctrl/alt/win flags + mov x,#4 '+$100 if shift +:loop test y,#%11 wz '+$200 if ctrl + shr y,#2 '+$400 if alt + if_nz or data,#1 '+$800 if win + ror data,#1 + djnz x,#:loop + rol data,#12 + + rdlong x,par 'if room in buffer and key valid, enter + sub x,#1 + and x,#$F + cmp x,_head wz + if_nz test data,#$FF wz + if_nz mov x,par + if_nz add x,#11*4 + if_nz add x,_head + if_nz add x,_head + if_nz wrword data,x + if_nz add _head,#1 + if_nz and _head,#$F + + test stat,#4 wc 'if not configure flag, done + if_nc jmp #update 'else configure to update leds +' +' +' Configure keyboard +' +configure mov data,#$F3 'set keyboard auto-repeat + call #transmit + mov data,_auto + and data,#%11_11111 + call #transmit + + mov data,#$ED 'set keyboard lock-leds + call #transmit + mov data,_locks + rev data,#-3 & $1F + test data,#%100 wc + rcl data,#1 + and data,#%111 + call #transmit + + mov x,_locks 'insert locks into _states + and x,#%111 + shl _states+7,#3 + or _states+7,x + ror _states+7,#3 + + mov _present,#1 'set _present + + jmp #update 'done + +{{ for keyboard-de start }} +' +' Lookup byte in table_shift +' +look_shift ror data,#2 'perform lookup + movs :reg,data + add :reg,#table_shift + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + and data,#$FF 'isolate byte +look_shift_ret ret + +' +' Lookup byte in table_alt_r +' +look_alt_r ror data,#2 'perform lookup + movs :reg,data + add :reg,#table_alt_r + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + and data,#$FF 'isolate byte +look_alt_r_ret ret + +{{ for keyboard-de end }} + +' +' +' Lookup byte in table +' +look ror data,#2 'perform lookup + movs :reg,data + add :reg,#table + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + + jmp #rand 'isolate byte +' +' +' Transmit byte to keyboard +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov x,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz x,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset keyboard + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from keyboard +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov x,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz x,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset keyboard + if_nc jmp #reset +rand and data,#$FF 'isolate byte + +look_ret +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov y,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz y,#reset 'if timeout, reset keyboard +wait_ret +wait_c0_ret ret + + +c0 if_c djnz y,#wloop '(if_never replacements) +c1 if_nc djnz y,#wloop +c0d0 if_c_or_nz djnz y,#wloop +c1d1 if_nc_or_z djnz y,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +' +' +' Lookup table +' ascii scan extkey regkey ()=keypad +' + +{{keyboard-us-en start}} +{{ +table + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D8,$0000,$00D4,$00D2,$00D0,$00D1,$00DB + + ' + '$08 --- F10 F8 F6 F4 TAB ` --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D9,$00D7,$00D5,$00D3,$0009,$0060,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L q 1 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2,$0071,$0031,$0000 + + ' WIN-L + '$18 --- --- z s a w 2 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$007A,$0073,$0061,$0077,$0032,$F600 + + ' WIN-R + '$20 --- c x d e 4 3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0063,$0078,$0064,$0065,$0034,$0033,$F700 + + ' Apps + '$28 --- Spc v f t r 5 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0020,$0076,$0066,$0074,$0072,$0035,$CC00 + + ' Power + '$30 --- n b h g y 6 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$006E,$0062,$0068,$0067,$0079,$0036,$CD00 + + ' Sleep + '$38 --- --- m j u 7 8 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$006D,$006A,$0075,$0037,$0038,$CE00 + + ' + '$40 --- , k i o 0 9 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002C,$006B,$0069,$006F,$0030,$0039,$0000 + + ' (/) + '$48 --- . / l } p + --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002E,$EF2F,$006C,$003B,$0070,$002D,$0000 + + ' + '$50 --- --- { --- [ = --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0027,$0000,$005B,$003D,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER ] --- \ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DE,$00F1,$EB0D,$005D,$0000,$005C,$CF00,$0000 + + ' + '$60 --- --- --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$00C8,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$C5E1,$0000,$C0E4,$C4E7,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $CAE0,$C9EA,$C3E2,$00E5,$C1E6,$C2E8,$00CB,$00DF + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DA,$00EC,$C7E3,$00ED,$DCEE,$C6E9,$00DD,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$00D6 + + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + +' +'Table "shift1" for scan-codes $5B..$60 +' +shift1 byte "{|}", 0, 0, "~" + +' +'Table "shift1" for scan-codes $27..$3D +' +shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" +}} +{{keyboard-us-en end}} + + +{{keyboard-de start}} + +table + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D8,$0000,$00D4,$00D2,$00D0,$00D1,$00DB + + ' + '$08 --- F10 F8 F6 F4 TAB _^_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D9,$00D7,$00D5,$00D3,$0009,$005E,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L q 1 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2,$0071,$0031,$0000 + + ' WIN-L + '$18 --- --- _y_ s a w 2 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0079,$0073,$0061,$0077,$0032,$F600 + + ' WIN-R + '$20 --- c x d e 4 3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0063,$0078,$0064,$0065,$0034,$0033,$F700 + + ' Apps + '$28 --- Spc v f t r 5 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0020,$0076,$0066,$0074,$0072,$0035,Apps + + ' Power + '$30 --- n b h g _z_ 6 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$006E,$0062,$0068,$0067,$007A,$0036,Power + + ' Sleep + '$38 --- --- m j u 7 8 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$006D,$006A,$0075,$0037,$0038,Sleep + + ' + '$40 --- , k i o 0 9 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002C,$006B,$0069,$006F,$0030,$0039,$0000 + + ' (/) + '$48 --- . _-_ l _oe_ p _sz_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002E,$EF2D,$006C,de_oe,$0070,$00DF,$0000 + + ' + '$50 --- --- _ae_ --- _ue_ _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,de_ae,$0000,de_ue,$0060,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER _+_ --- # --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word CpsLk,$00F1,$EB0D,$002B,$0000,$0023,WkUp ,$0000 + + ' + '$60 --- _<_ --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003C,$0000,$0000,$0000,$0000,BkSp ,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,CrsEn,$0000,CrsLt,CrsHm,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word Ins , Del ,CrsDn,$00E5,CrsRt,CrsUp, Esc ,NumLk + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DA,$00EC,PgDn ,$00ED,$DCEE,PgUp ,ScrLk,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$00D6 + + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + + +table_shift + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D8,$0000,$00D4,$00D2,$00D0,$00D1,$00DB + + ' + '$08 --- F10 F8 F6 F4 TAB _°_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D9,$00D7,$00D5,$00D3,$0009,$00B0,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L Q ! --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2,$0051,$0021,$0000 + + ' WIN-L + '$18 --- --- _Y_ S A W " --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0059,$0053,$0041,$0057,$0022,$F600 + + ' WIN-R + '$20 --- C X D E $ SHF+3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0043,$0058,$0044,$0045,$0024,$0014,$F700 + + ' Apps + '$28 --- Spc V F T R % --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0020,$0056,$0046,$0054,$0052,$0025,Apps + + ' Power + '$30 --- N B H G _Z_ & --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$004E,$0042,$0048,$0047,$005A,$0026,Power + + ' Sleep + '$38 --- --- M J U / ( --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$004D,$004A,$0055,$002F,$0028,Sleep + + ' + '$40 --- ; K I O _=_ ) --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003B,$004B,$0049,$004F,$003D,$0029,$0000 + + ' (/) + '$48 --- : ___ L _OE_ P _sz_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003A,$EF5F,$004C,$00D6,$0050,$003F,$0000 + + ' + '$50 --- --- _AE_ --- _UE_ _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$00C4,$0000,$00DC,$0060,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER _*_ --- _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word CpsLk,$00F1,$EB0D,$002A,$0000,$0027,WkUp ,$0000 + + ' + '$60 --- _>_ --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003E,$0000,$0000,$0000,$0000,BkSp ,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,CrsEn,$0000,CrsLt,CrsHm,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word Ins , Del ,CrsDn,$00E5,CrsRt,CrsUp, Esc ,NumLk + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DA,$00EC,PgDn ,$00ED,$DCEE,PgUp ,ScrLk,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$00D6 + + + +table_alt_r + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0097,$0000,$0090,$009D,$009F,$009E,$0094 + + ' + '$08 --- F10 F8 F6 F4 TAB _^_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0096,$0093,$0091,$009C,$0009,$0000,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L q 1 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2, "@", "¹", $0000 + + ' WIN-L + '$18 --- --- _y_ s a w 2 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000, "²", $F600 + + ' WIN-R + '$20 --- c x d e 4 3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000, "€", $0000, "³", $F700 + + ' Apps + '$28 --- Spc v f t r 5 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$0000,Apps + + ' Power + '$30 --- n b h g _z_ 6 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$0000,Power + + ' Sleep + '$38 --- --- m j u 7 8 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000, "µ", $0000,$0000, "{" , "[" ,Sleep + + ' + '$40 --- , k i o 0 9 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000, "}", "]", $0000 + + ' (/) + '$48 --- . _-_ l _oe_ p _sz_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000, "\", $0000 + + ' + '$50 --- --- _ae_ --- _ue_ _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER _+_ --- # --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word CpsLk,$00F1,$EB0D, "~", $0000,$0000,WkUp ,$0000 + + ' + '$60 --- _<_ --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000, "|", $0000,$0000,$0000,$0000,BkSp ,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,CrsEn,$0000,CrsLt,CrsHm,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word Ins , Del ,CrsDn,$00E5,CrsRt,CrsUp, Esc ,NumLk + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0095,$00EC,PgDn ,$00ED,$DCEE,PgUp ,ScrLk,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$0092 + + +{{keyboard-de end}} + +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +data_s res 1 'Scancode-Storage (for keyboard-de) +x res 1 +y res 1 +t res 1 + +_head res 1 'write-only +_present res 1 'write-only +_states res 8 'write-only +_dpin res 1 'read-only at start +_cpin res 1 'read-only at start +_locks res 1 'read-only at start +_auto res 1 'read-only at start + +'' +'' +'' _________ +'' Key Codes +'' +'' 00..DF = keypress and keystate +'' E0..FF = keystate only +'' +'' +'' 09 Tab +'' 0D Enter +'' 20 Space +'' 21 ! +'' 22 " +'' 23 # +'' 24 $ +'' 25 % +'' 26 & +'' 27 ' +'' 28 ( +'' 29 ) +'' 2A * +'' 2B + +'' 2C , +'' 2D - +'' 2E . +'' 2F / +'' 30 0..9 +'' 3A : +'' 3B ; +'' 3C < +'' 3D = +'' 3E > +'' 3F ? +'' 40 @ +'' 41..5A A..Z +'' 5B [ +'' 5C \ +'' 5D ] +'' 5E ^ +'' 5F _ +'' 60 ` +'' 61..7A a..z +'' 7B { +'' 7C | +'' 7D } +'' 7E ~ +'' +'' 80-BF (future international character support) +'' +'' C0 Left Arrow +'' C1 Right Arrow +'' C2 Up Arrow +'' C3 Down Arrow +'' C4 Home +'' C5 End +'' C6 Page Up +'' C7 Page Down +'' C8 Backspace +'' C9 Delete +'' CA Insert +'' CB Esc +'' CC Apps +'' CD Power +'' CE Sleep +'' CF Wakeup +'' +'' D0..DB F1..F12 +'' DC Print Screen +'' DD Scroll Lock +'' DE Caps Lock +'' DF Num Lock +'' +'' E0..E9 Keypad 0..9 +'' EA Keypad . +'' EB Keypad Enter +'' EC Keypad + +'' ED Keypad - +'' EE Keypad * +'' EF Keypad / +'' +'' F0 Left Shift +'' F1 Right Shift +'' F2 Left Ctrl +'' F3 Right Ctrl +'' F4 Left Alt +'' F5 Right Alt +'' F6 Left Win +'' F7 Right Win +'' +'' FD Scroll Lock State +'' FE Caps Lock State +'' FF Num Lock State +'' +'' +100 if Shift +'' +200 if Ctrl +'' +400 if Alt +'' +800 if Win +'' +'' eg. Ctrl-Alt-Delete = $6C9 +'' +'' +'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-mouse.spin b/lib/bel-mouse.spin new file mode 100644 index 0000000..fb7f470 --- /dev/null +++ b/lib/bel-mouse.spin @@ -0,0 +1,492 @@ +''*************************************** +''* PS/2 Mouse Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects + + +VAR + + long cog + + long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs) + + long par_x 'absolute x read-only (7 contiguous longs) + long par_y 'absolute y read-only + long par_z 'absolute z read-only + long par_buttons 'button states read-only + long par_present 'mouse present read-only + long par_dpin 'data pin write-only + long par_cpin 'clock pin write-only + + long bx_min, by_min, bz_min 'min/max must be contiguous + long bx_max, by_max, bz_max + long bx_div, by_div, bz_div + long bx_acc, by_acc, bz_acc + + +PUB start(dpin, cpin) : okay + +'' Start mouse driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS + + stop + par_dpin := dpin + par_cpin := cpin + okay := cog := cognew(@entry, @par_x) + 1 + + +PUB stop + +'' Stop mouse driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@oldx, 0, 10) + + +PUB present : type + +'' Check if mouse present - valid ~2s after start +'' returns mouse type: +'' +'' 3 = five-button scrollwheel mouse +'' 2 = three-button scrollwheel mouse +'' 1 = two-button or three-button mouse +'' 0 = no mouse connected + + type := par_present + + +PUB button(b) : state + +'' Get the state of a particular button +'' returns t|f + + state := -(par_buttons >> b & 1) + + +PUB buttons : states + +'' Get the states of all buttons +'' returns buttons: +'' +'' bit4 = right-side button +'' bit3 = left-side button +'' bit2 = center/scrollwheel button +'' bit1 = right button +'' bit0 = left button + + states := par_buttons + + +PUB abs_x : x + +'' Get absolute-x + + x := par_x + + +PUB abs_y : y + +'' Get absolute-y + + y := par_y + + +PUB abs_z : z + +'' Get absolute-z (scrollwheel) + + z := par_z + + +PUB delta_reset + +'' Reset deltas + + oldx := par_x + oldy := par_y + oldz := par_z + + +PUB delta_x : x | newx + +'' Get delta-x + + newx := par_x + x := newx - oldx + oldx := newx + + +PUB delta_y : y | newy + +'' Get delta-y + + newy := par_y + y := newy - oldy + oldy := newy + + +PUB delta_z : z | newz + +'' Get delta-z (scrollwheel) + + newz := par_z + z := newz - oldz + oldz := newz + + +PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i + +'' Set bounding limits + + longmove(@bx_min, @xmin, 6) + + +PUB bound_scales(x_scale, y_scale, z_scale) + +'' Set bounding scales (usually +/-1's, bigger values divide) + + longmove(@bx_div, @x_scale, 3) + + +PUB bound_preset(x, y, z) | i, d + +'' Preset bound coordinates + + repeat i from 0 to 2 + d := ||bx_div[i] + bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1 + + +PUB bound_x : x + +'' Get bound-x + + x := bound(0, delta_x) + + +PUB bound_y : y + +'' Get bound-y + + y := bound(1, delta_y) + + +PUB bound_z : z + +'' Get bound-z + + z := bound(2, delta_z) + + +PRI bound(i, delta) : b | d + + d := bx_div[i] + b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d + + +DAT + +'*************************************** +'* Assembly language PS/2 mouse driver * +'*************************************** + + org +' +' +' Entry +' +entry mov p,par 'load input parameters: + add p,#5*4 '_dpin/_cpin + rdlong _dpin,p + add p,#4 + rdlong _cpin,p + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + movd :par,#_x 'reset output parameters: + mov p,#5 '_x/_y/_z/_buttons/_present +:par mov 0,#0 + add :par,dlsb + djnz p,#:par +' +' +' Reset mouse +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + mov stat,#1 'set reset flag +' +' +' Update parameters +' +update movd :par,#_x 'update output parameters: + mov p,par '_x/_y/_z/_buttons/_present + mov q,#5 +:par wrlong 0,p + add :par,dlsb + add p,#4 + djnz q,#:par + + test stat,#1 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get data packet +' + mov stat,#0 'reset state + + call #receive 'receive first byte + + cmp data,#$AA wz 'powerup/reset? + if_z jmp #init + + mov _buttons,data 'data packet, save buttons + + call #receive 'receive second byte + + test _buttons,#$10 wc 'adjust _x + muxc data,signext + add _x,data + + call #receive 'receive third byte + + test _buttons,#$20 wc 'adjust _y + muxc data,signext + add _y,data + + and _buttons,#%111 'trim buttons + + cmp _present,#2 wc 'if not scrollwheel mouse, update parameters + if_c jmp #update + + + call #receive 'scrollwheel mouse, receive fourth byte + + cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons + if_z test data,#$10 wc + if_z_and_c or _buttons,#%01000 + if_z test data,#$20 wc + if_z_and_c or _buttons,#%10000 + + shl data,#28 'adjust _z + sar data,#28 + sub _z,data + + jmp #update 'update parameters +' +' +' Initialize mouse +' +init call #receive '$AA received, receive id + + movs crate,#100 'try to enable 3-button scrollwheel type + call #checktype + movs crate,#200 'try to enable 5-button scrollwheel type + call #checktype + shr data,#1 'if neither, 3-button type + add data,#1 + mov _present,data + + movs srate,#200 'set 200 samples per second + call #setrate + + mov data,#$F4 'enable data reporting + call #transmit + + jmp #update +' +' +' Check mouse type +' +checktype movs srate,#200 'perform "knock" sequence to enable + call #setrate '..scrollwheel and extra buttons + +crate movs srate,#200/100 + call #setrate + + movs srate,#80 + call #setrate + + mov data,#$F2 'read type + call #transmit + call #receive + +checktype_ret ret +' +' +' Set sample rate +' +setrate mov data,#$F3 + call #transmit +srate mov data,#0 + call #transmit + +setrate_ret ret +' +' +' Transmit byte to mouse +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov p,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz p,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset mouse + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from mouse +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov p,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz p,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset mouse + if_nc jmp #reset + and data,#$FF 'isolate byte + +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov q,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz q,#reset 'if timeout, reset mouse +wait_ret +wait_c0_ret ret + + +c0 if_c djnz q,#wloop '(if_never replacements) +c1 if_nc djnz q,#wloop +c0d0 if_c_or_nz djnz q,#wloop +c1d1 if_nc_or_z djnz q,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +signext long $FFFFFF00 +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +p res 1 +q res 1 +t res 1 + +_x res 1 'write-only +_y res 1 'write-only +_z res 1 'write-only +_buttons res 1 'write-only +_present res 1 'write-only +_dpin res 1 'read-only +_cpin res 1 'read-only + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-tv.spin b/lib/bel-tv.spin new file mode 100644 index 0000000..ba3e11b --- /dev/null +++ b/lib/bel-tv.spin @@ -0,0 +1,711 @@ +''*************************************** +''* TV Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient +' character displays utilizing the internal font - see 'tv_mode' + + +CON + + fntsc = 3_579_545 'NTSC color frequency + lntsc = 3640 'NTSC color cycles per line * 16 + sntsc = 624 'NTSC color cycles per sync * 16 + + fpal = 4_433_618 'PAL color frequency + lpal = 4540 'PAL color cycles per line * 16 + spal = 848 'PAL color cycles per sync * 16 + + paramcount = 14 + colortable = $180 'start of colortable inside cog + + +VAR + + long cog + + +PUB start(tvptr) : okay + +'' Start TV driver - starts a cog +'' returns false if no cog available +'' +'' tvptr = pointer to TV parameters + + stop + okay := cog := cognew(@entry, tvptr) + 1 + + +PUB stop + +'' Stop TV driver - frees a cog + + if cog + cogstop(cog~ - 1) + + +DAT + +'******************************* +'* Assembly language TV driver * +'******************************* + + org +' +' +' Entry +' +entry mov taskptr,#tasks 'reset tasks + + mov x,#10 'perform task sections initially +:init jmpret taskret,taskptr + djnz x,#:init +' +' +' Superfield +' +superfield mov taskptr,#tasks 'reset tasks + + test _mode,#%0001 wc 'if ntsc, set phaseflip + if_nc mov phaseflip,phasemask + + test _mode,#%0010 wz 'get interlace into nz +' +' +' Field +' +field mov x,vinv 'do invisible back porch lines +:black call #hsync 'do hsync + waitvid burst,sync_high2 'do black + jmpret taskret,taskptr 'call task section (z undisturbed) + djnz x,#:black 'another black line? + + wrlong visible,par 'set status to visible + + mov x,vb 'do visible back porch lines + call #blank_lines + + mov screen,_screen 'point to first tile (upper-leftmost) + mov y,_vt 'set vertical tiles +:line mov vx,_vx 'set vertical expand +:vert if_z xor interlace,#1 'interlace skip? + if_z tjz interlace,#:skip + + call #hsync 'do hsync + + mov vscl,hb 'do visible back porch pixels + xor tile,colortable + waitvid tile,#0 + + mov x,_ht 'set horizontal tiles + mov vscl,hx 'set horizontal expand + +:tile rdword tile,screen 'read tile + or tile,line 'set pointer bits into tile + rol tile,#6 'read tile pixels + rdlong pixels,tile '(2 instructions between reads) + shr tile,#10+6 'set tile colors + movs :color,tile + add screen,#2 'point to next tile + mov tile,phaseflip +:color xor tile,colortable + waitvid tile,pixels 'pass colors and pixels to video + djnz x,#:tile 'another tile? + + sub screen,hc2x 'repoint to first tile in same line + + mov vscl,hf 'do visible front porch pixels + mov tile,phaseflip + xor tile,colortable + waitvid tile,#0 + +:skip djnz vx,#:vert 'vertical expand? + ror line,linerot 'set next line + add line,lineadd wc + rol line,linerot + if_nc jmp #:line + add screen,hc2x 'point to first tile in next line + djnz y,#:line 'another tile line? + + if_z xor interlace,#1 wz 'get interlace and field1 into z + + test _mode,#%0001 wc 'do visible front porch lines + mov x,vf + if_nz_and_c add x,#1 + call #blank_lines + + if_nz wrlong invisible,par 'unless interlace and field1, set status to invisible + + if_z_eq_c call #hsync 'if required, do short line + if_z_eq_c mov vscl,hrest + if_z_eq_c waitvid burst,sync_high2 + if_z_eq_c xor phaseflip,phasemask + + call #vsync_high 'do high vsync pulses + + movs vsync1,#sync_low1 'do low vsync pulses + movs vsync2,#sync_low2 + call #vsync_low + + call #vsync_high 'do high vsync pulses + + if_nz mov vscl,hhalf 'if odd frame, do half line + if_nz waitvid burst,sync_high2 + + if_z jmp #field 'if interlace and field1, display field2 + jmp #superfield 'else, new superfield +' +' +' Blank lines +' +blank_lines call #hsync 'do hsync + + xor tile,colortable 'do background + waitvid tile,#0 + + djnz x,#blank_lines + +blank_lines_ret ret +' +' +' Horizontal sync +' +hsync test _mode,#%0001 wc 'if pal, toggle phaseflip + if_c xor phaseflip,phasemask + + mov vscl,sync_scale1 'do hsync + mov tile,phaseflip + xor tile,burst + waitvid tile,sync_normal + + mov vscl,hvis 'setup in case blank line + mov tile,phaseflip + +hsync_ret ret +' +' +' Vertical sync +' +vsync_high movs vsync1,#sync_high1 'vertical sync + movs vsync2,#sync_high2 + +vsync_low mov x,vrep + +vsyncx mov vscl,sync_scale1 +vsync1 waitvid burst,sync_high1 + + mov vscl,sync_scale2 +vsync2 waitvid burst,sync_high2 + + djnz x,#vsyncx +vsync_low_ret +vsync_high_ret ret +' +' +' Tasks - performed in sections during invisible back porch lines +' +tasks mov t1,par 'load parameters + movd :par,#_enable '(skip _status) + mov t2,#paramcount - 1 +:load add t1,#4 +:par rdlong 0,t1 + add :par,d0 + djnz t2,#:load '+119 + + mov t1,_pins 'set video pins and directions + test t1,#$08 wc + if_nc mov t2,pins0 + if_c mov t2,pins1 + test t1,#$40 wc + shr t1,#1 + shl t1,#3 + shr t2,t1 + movs vcfg,t2 + shr t1,#6 + movd vcfg,t1 + shl t1,#3 + and t2,#$FF + shl t2,t1 + if_nc mov dira,t2 + if_nc mov dirb,#0 + if_c mov dira,#0 + if_c mov dirb,t2 '+18 + + tjz _enable,#disabled '+2, disabled? + + jmpret taskptr,taskret '+1=140, break and return later + + movs :rd,#wtab 'load ntsc/pal metrics from word table + movd :wr,#hvis + mov t1,#wtabx - wtab + test _mode,#%0001 wc +:rd mov t2,0 + add :rd,#1 + if_nc shl t2,#16 + shr t2,#16 +:wr mov 0,t2 + add :wr,d0 + djnz t1,#:rd '+54 + + if_nc movs :ltab,#ltab 'load ntsc/pal metrics from long table + if_c movs :ltab,#ltab+1 + movd :ltab,#fcolor + mov t1,#(ltabx - ltab) >> 1 +:ltab mov 0,0 + add :ltab,d0s1 + djnz t1,#:ltab '+17 + + rdlong t1,#0 'get CLKFREQ + shr t1,#1 'if CLKFREQ < 16MHz, cancel _broadcast + cmp t1,m8 wc + if_c mov _broadcast,#0 + shr t1,#1 'if CLKFREQ < color frequency * 4, disable + cmp t1,fcolor wc + if_c jmp #disabled '+11 + + jmpret taskptr,taskret '+1=83, break and return later + + mov t1,fcolor 'set ctra pll to fcolor * 16 + call #divide 'if ntsc, set vco to fcolor * 32 (114.5454 MHz) + test _mode,#%0001 wc 'if pal, set vco to fcolor * 16 (70.9379 MHz) + if_c movi ctra,#%00001_111 'select fcolor * 16 output (ntsc=/2, pal=/1) + if_nc movi ctra,#%00001_110 + if_nc shl t2,#1 + mov frqa,t2 '+147 + + jmpret taskptr,taskret '+1=148, break and return later + + mov t1,_broadcast 'set ctrb pll to _broadcast + mov t2,#0 'if 0, turn off ctrb + tjz t1,#:off + min t1,m8 'limit from 8MHz to 128MHz + max t1,m128 + mov t2,#%00001_100 'adjust _broadcast to be within 4MHz-8MHz +:scale shr t1,#1 '(vco will be within 64MHz-128MHz) + cmp m8,t1 wc + if_c add t2,#%00000_001 + if_c jmp #:scale +:off movi ctrb,t2 + call #divide + mov frqb,t2 '+165 + + jmpret taskptr,taskret '+1=166, break and return later + + mov t1,#%10100_000 'set video configuration + test _pins,#$01 wc '(swap broadcast/baseband output bits?) + if_c or t1,#%01000_000 + test _mode,#%1000 wc '(strip chroma from broadcast?) + if_nc or t1,#%00010_000 + test _mode,#%0100 wc '(strip chroma from baseband?) + if_nc or t1,#%00001_000 + and _auralcog,#%111 '(set aural cog) + or t1,_auralcog + movi vcfg,t1 '+10 + + mov hx,_hx 'compute horizontal metrics + shl hx,#8 + or hx,_hx + shl hx,#4 + + mov hc2x,_ht + shl hc2x,#1 + + mov t1,_ht + mov t2,_hx + call #multiply + mov hf,hvis + sub hf,t1 + shr hf,#1 wc + mov hb,_ho + addx hb,hf + sub hf,_ho '+52 + + mov t1,_vt 'compute vertical metrics + mov t2,_vx + call #multiply + test _mode,#%10000 wc 'consider tile size + muxc linerot,#1 + mov lineadd,lineinc + if_c shr lineadd,#1 + if_c shl t1,#1 + test _mode,#%0010 wc 'consider interlace + if_c shr t1,#1 + mov vf,vvis + sub vf,t1 + shr vf,#1 wc + neg vb,_vo + addx vb,vf + add vf,_vo '+53 + + xor _mode,#%0010 '+1, flip interlace bit for display + +:colors jmpret taskptr,taskret '+1=117/160, break and return later + + mov t1,#13 'load next 13 colors into colortable +:colorloop mov t2,:colorreg '5 times = 65 (all 64 colors loaded) + shr t2,#9-2 + and t2,#$FC + add t2,_colors +:colorreg rdlong colortable,t2 + add :colorreg,d0 + andn :colorreg,d6 + djnz t1,#:colorloop '+158 + + jmp #:colors '+1, keep loading colors +' +' +' Divide t1/CLKFREQ to get frqa or frqb value into t2 +' +divide rdlong m1,#0 'get CLKFREQ + + mov m2,#32+1 +:loop cmpsub t1,m1 wc + rcl t2,#1 + shl t1,#1 + djnz m2,#:loop + +divide_ret ret '+140 +' +' +' Multiply t1 * t2 * 16 (t1, t2 = bytes) +' +multiply shl t2,#8+4-1 + + mov m1,#8 +:loop shr t1,#1 wc + if_c add t1,t2 + djnz m1,#:loop + +multiply_ret ret '+37 +' +' +' Disabled - reset status, nap ~4ms, try again +' +disabled mov ctra,#0 'reset ctra + mov ctrb,#0 'reset ctrb + mov vcfg,#0 'reset video + + wrlong outa,par 'set status to disabled + + rdlong t1,#0 'get CLKFREQ + shr t1,#8 'nap for ~4ms + min t1,#3 + add t1,cnt + waitcnt t1,#0 + + jmp #entry 'reload parameters +' +' +' Initialized data +' +m8 long 8_000_000 +m128 long 128_000_000 +d0 long 1 << 9 << 0 +d6 long 1 << 9 << 6 +d0s1 long 1 << 9 << 0 + 1 << 1 +interlace long 0 +invisible long 1 +visible long 2 +phaseflip long $00000000 +phasemask long $F0F0F0F0 +line long $00060000 +lineinc long $10000000 +linerot long 0 +pins0 long %11110000_01110000_00001111_00000111 +pins1 long %11111111_11110111_01111111_01110111 +sync_high1 long %0101010101010101010101_101010_0101 +sync_high2 long %01010101010101010101010101010101 'used for black +sync_low1 long %1010101010101010101010101010_0101 +sync_low2 long %01_101010101010101010101010101010 +' +' +' NTSC/PAL metrics tables +' ntsc pal +' ---------------------------------------------- +wtab word lntsc - sntsc, lpal - spal 'hvis + word lntsc / 2 - sntsc, lpal / 2 - spal 'hrest + word lntsc / 2, lpal / 2 'hhalf + word 243, 286 'vvis + word 10, 18 'vinv + word 6, 5 'vrep + word $02_8A, $02_AA 'burst +wtabx +ltab long fntsc 'fcolor + long fpal + long sntsc >> 4 << 12 + sntsc 'sync_scale1 + long spal >> 4 << 12 + spal + long 67 << 12 + lntsc / 2 - sntsc 'sync_scale2 + long 79 << 12 + lpal / 2 - spal + long %0101_00000000_01_10101010101010_0101 'sync_normal + long %010101_00000000_01_101010101010_0101 +ltabx +' +' +' Uninitialized data +' +taskptr res 1 'tasks +taskret res 1 +t1 res 1 +t2 res 1 +m1 res 1 +m2 res 1 + +x res 1 'display +y res 1 +hf res 1 +hb res 1 +vf res 1 +vb res 1 +hx res 1 +vx res 1 +hc2x res 1 +screen res 1 +tile res 1 +pixels res 1 +lineadd res 1 + +hvis res 1 'loaded from word table +hrest res 1 +hhalf res 1 +vvis res 1 +vinv res 1 +vrep res 1 +burst res 1 + +fcolor res 1 'loaded from long table +sync_scale1 res 1 +sync_scale2 res 1 +sync_normal res 1 +' +' +' Parameter buffer +' +_enable res 1 '0/non-0 read-only +_pins res 1 '%pppmmmm read-only +_mode res 1 '%tccip read-only +_screen res 1 '@word read-only +_colors res 1 '@long read-only +_ht res 1 '1+ read-only +_vt res 1 '1+ read-only +_hx res 1 '4+ read-only +_vx res 1 '1+ read-only +_ho res 1 '0+- read-only +_vo res 1 '0+- read-only +_broadcast res 1 '0+ read-only +_auralcog res 1 '0-7 read-only + + fit colortable 'fit underneath colortable ($180-$1BF) +'' +''___ +''VAR 'TV parameters - 14 contiguous longs +'' +'' long tv_status '0/1/2 = off/invisible/visible read-only +'' long tv_enable '0/non-0 = off/on write-only +'' long tv_pins '%pppmmmm = pin group, pin group mode write-only +'' long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only +'' long tv_screen 'pointer to screen (words) write-only +'' long tv_colors 'pointer to colors (longs) write-only +'' long tv_ht 'horizontal tiles write-only +'' long tv_vt 'vertical tiles write-only +'' long tv_hx 'horizontal tile expansion write-only +'' long tv_vx 'vertical tile expansion write-only +'' long tv_ho 'horizontal offset write-only +'' long tv_vo 'vertical offset write-only +'' long tv_broadcast 'broadcast frequency (Hz) write-only +'' long tv_auralcog 'aural fm cog write-only +'' +''The preceding VAR section may be copied into your code. +''After setting variables, do start(@tv_status) to start driver. +'' +''All parameters are reloaded each superframe, allowing you to make live +''changes. To minimize flicker, correlate changes with tv_status. +'' +''Experimentation may be required to optimize some parameters. +'' +''Parameter descriptions: +'' _________ +'' tv_status +'' +'' driver sets this to indicate status: +'' 0: driver disabled (tv_enable = 0 or CLKFREQ < requirement) +'' 1: currently outputting invisible sync data +'' 2: currently outputting visible screen data +'' _________ +'' tv_enable +'' +'' 0: disable (pins will be driven low, reduces power) +'' non-0: enable +'' _______ +'' tv_pins +'' +'' bits 6..4 select pin group: +'' %000: pins 7..0 +'' %001: pins 15..8 +'' %010: pins 23..16 +'' %011: pins 31..24 +'' %100: pins 39..32 +'' %101: pins 47..40 +'' %110: pins 55..48 +'' %111: pins 63..56 +'' +'' bits 3..0 select pin group mode: +'' %0000: %0000_0111 - baseband +'' %0001: %0000_0111 - broadcast +'' %0010: %0000_1111 - baseband + chroma +'' %0011: %0000_1111 - broadcast + aural +'' %0100: %0111_0000 broadcast - +'' %0101: %0111_0000 baseband - +'' %0110: %1111_0000 broadcast + aural - +'' %0111: %1111_0000 baseband + chroma - +'' %1000: %0111_0111 broadcast baseband +'' %1001: %0111_0111 baseband broadcast +'' %1010: %0111_1111 broadcast baseband + chroma +'' %1011: %0111_1111 baseband broadcast + aural +'' %1100: %1111_0111 broadcast + aural baseband +'' %1101: %1111_0111 baseband + chroma broadcast +'' %1110: %1111_1111 broadcast + aural baseband + chroma +'' %1111: %1111_1111 baseband + chroma broadcast + aural +'' ----------------------------------------------------------- +'' active pins top nibble bottom nibble +'' +'' the baseband signal nibble is arranged as: +'' bit 3: chroma signal for s-video (attach via 560-ohm resistor) +'' bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' +'' the broadcast signal nibble is arranged as: +'' bit 3: aural subcarrier (sum 560-ohm resistor into network below) +'' bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' _______ +'' tv_mode +'' +'' bit 4 selects between 16x16 and 16x32 pixel tiles: +'' 0: 16x16 pixel tiles (tileheight = 16) +'' 1: 16x32 pixel tiles (tileheight = 32) +'' +'' bit 3 controls chroma mixing into broadcast: +'' 0: mix chroma into broadcast (color) +'' 1: strip chroma from broadcast (black/white) +'' +'' bit 2 controls chroma mixing into baseband: +'' 0: mix chroma into baseband (composite color) +'' 1: strip chroma from baseband (black/white or s-video) +'' +'' bit 1 controls interlace: +'' 0: progressive scan (243 display lines for NTSC, 286 for PAL) +'' less flicker, good for motion +'' 1: interlaced scan (486 display lines for NTSC, 572 for PAL) +'' doubles the vertical display lines, good for text +'' +'' bit 0 selects NTSC or PAL format +'' 0: NTSC +'' 3016 horizontal display ticks +'' 243 or 486 (interlaced) vertical display lines +'' CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)* +'' 1: PAL +'' 3692 horizontal display ticks +'' 286 or 572 (interlaced) vertical display lines +'' CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)* +'' +'' * driver will disable itself while CLKFREQ is below requirement +'' _________ +'' tv_screen +'' +'' pointer to words which define screen contents (left-to-right, top-to-bottom) +'' number of words must be tv_ht * tv_vt +'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr +'' bits 15..10: select the colorset* for the associated pixel tile +'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15) +'' +'' * colorsets are longs which each define four 8-bit colors +'' +'' ** pixelgroups are longs which define (left-to-right, top-to-bottom) the 2-bit +'' (four color) pixels that make up a 16x16 or a 32x32 pixel tile +'' _________ +'' tv_colors +'' +'' pointer to longs which define colorsets +'' number of longs must be 1..64 +'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels +'' first long's bottom color is also used as the screen background color +'' 8-bit color fields are as follows: +'' bits 7..4: chroma data (0..15 = blue..green..red..)* +'' bit 3: controls chroma modulation (0=off, 1=on) +'' bits 2..0: 3-bit luminance level: +'' values 0..1: reserved for sync - don't use +'' values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7) +'' value 0 may be modulated to produce a saturated color toggling between levels 1 and 7 +'' +'' * because of TV's limitations, it doesn't look good when chroma changes abruptly - +'' rather, use luminance - change chroma only against a black or white background for +'' best appearance +'' _____ +'' tv_ht +'' +'' horizontal number pixel tiles - must be at least 1 +'' practical limit is 40 for NTSC, 50 for PAL +'' _____ +'' tv_vt +'' +'' vertical number of pixel tiles - must be at least 1 +'' practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL) +'' _____ +'' tv_hx +'' +'' horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL +'' +'' make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks +'' _____ +'' tv_vx +'' +'' vertical tile expansion factor - must be at least 1 +'' +'' make sure * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines +'' _____ +'' tv_ho +'' +'' horizontal offset in ticks - pos/neg value (0 for centered image) +'' shifts the display right/left +'' _____ +'' tv_vo +'' +'' vertical offset in lines - pos/neg value (0 for centered image) +'' shifts the display up/down +'' ____________ +'' tv_broadcast +'' +'' broadcast frequency expressed in Hz (ie channel 2 is 55_250_000) +'' if 0, modulator is turned off - saves power +'' +'' broadcasting requires CLKFREQ to be at least 16_000_000 +'' while CLKFREQ is below 16_000_000, modulator will be turned off +'' ___________ +'' tv_auralcog +'' +'' selects cog to supply aural fm signal - 0..7 +'' uses ctra pll output from selected cog +'' +'' in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz +'' in PAL, the offset frequency and max bandwidth vary by PAL type + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/bel-vga.spin b/lib/bel-vga.spin new file mode 100644 index 0000000..ac92291 --- /dev/null +++ b/lib/bel-vga.spin @@ -0,0 +1,574 @@ +{{ +┌────────────────────────────────────────┬────────────────┬────────────────────────┬──────────────────┐ +│ VGA 1024x768 Tile Driver v0.9 │ by Chip Gracey │ (C)2006 Parallax, Inc. │ 11 November 2006 │ +├────────────────────────────────────────┴────────────────┴────────────────────────┴──────────────────┤ +│ │ +│ This object generates a 1024x768 VGA display from a 64x48 array of 16x16-pixel 4-color tiles. │ +│ It requires two cogs (or three with optional cursor enabled) and at least 80 MHz. │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +}} + +{{ + +01-02-2011-dr235 - erweiterung des treibers, um mit einem parameter den anfangszeiger + des bildwiederholspeichers dynamisch zu ändern; wichtig zur + verwaltung von mehreren screens + +}} + +CON + +' 1024 x 768 @ 60Hz settings + + hp = 1024 'horizontal pixels + vp = 768 'vertical pixels + hf = 16 'horizontal front porch pixels + hs = 96 'horizontal sync pixels + hb = 176 'horizontal back porch pixels + vf = 1 'vertical front porch lines + vs = 3 'vertical sync lines + vb = 28 'vertical back porch lines + pr = 60 'pixel rate in MHz at 80MHz system clock (5MHz granularity) + + ht = hp + hf + hs + hb 'total scan line pixels + +' Tile array + + xtiles = hp / 16 + ytiles = vp / 16 + +VAR + + long cog[3] + + long dira_ '9 contiguous longs + long dirb_ + long vcfg_ + long cnt_ + long array_ptr_ + long color_ptr_ + long cursor_ptr_ + long sync_ptr_ + long mode_ + long scrind_ 'dr235: screenindex + +DAT +'' Start driver - starts two or three cogs +'' returns false if cogs not available +'' +'' base_pin = First of eight VGA pins, must be a multiple of eight (0, 8, 16, 24, etc): +'' +'' 240Ω 240Ω 240Ω 240Ω +'' +7 ───┳─ Red +5 ───┳─ Green +3 ───┳─ Blue +1 ── H +'' 470Ω │ 470Ω │ 470Ω │ 240Ω +'' +6 ───┘ +4 ───┘ +2 ───┘ +0 ── V +'' +'' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down, +'' which will serve as the tile array. Each word specifies a tile bitmap and +'' a color palette for its tile area. The top 10 bits of each word form the +'' base address of a 16-long tile bitmap, while the lower 6 bits select a +'' color palette for the bitmap. For example, $B2E5 would specify the tile +'' bitmap spanning $B2C0..$B2FF and color palette $25. +'' +'' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data +'' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0 +'' providing the color data for pixel values %11..%00, respectively: +'' +'' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold +'' +'' cursor_ptr = Pointer to 4 longs which will control the cursor, or 0 to disable the +'' cursor. If a pointer is given, an extra cog will be started to generate +'' the cursor overlay. Here are the 4 longs that control the cursor: +'' +'' cursor_x - X position of cursor: ..0..1023.. (left to right) +'' cursor_y - Y position of cursor: ..0..767.. (bottom to top) +'' +'' cursor_color - Cursor color to be OR'd to background color as %%RGBx: +'' %%3330=white, %%2220 or %%1110=translucent, %%0000=off +'' +'' cursor_shape - 0 for arrow, 1 for crosshair, or pointer to a cursor +'' definition. A cursor definition consists of 32 longs +'' containing a 32x32 pixel cursor image, followed by two +'' bytes which define the X and Y center-pixel offsets +'' within the image. +'' +'' sync_ptr = Pointer to a long which will be set to -1 after each refresh, or 0 to +'' disable this function. This is useful in advanced applications where +'' awareness of display timing is important. +'' +'' mode = 0 for normal 16x16 pixel tiles or 1 for taller 16x32 pixel tiles. Mode 1 +'' is useful for displaying the internal font while requiring half the array +'' memory; however, the 3-D bevel characters will not be usable because of +'' the larger vertical tile granularity of this mode. + +PUB start(base_pin, array_ptr, color_ptr, cursor_ptr, sync_ptr, mode) : okay | i, j + + 'If driver is already running, stop it + stop + + 'Ready i/o settings + i := $FF << (base_pin & %011000) + j := base_pin & %100000 == 0 + dira_ := i & j + dirb_ := i & !j + vcfg_ := $300000FF + (base_pin & %111000) << 6 + + 'Ready cnt value to sync cogs by + cnt_ := cnt + $100000 + + 'Ready pointers and mode + longmove(@array_ptr_, @array_ptr, 5) + scrind_ := array_ptr_ + + 'Launch cogs, abort if error + repeat i from 0 to 2 + if i == 2 'cursor cog? + ifnot cursor_ptr 'cursor enabled? + quit 'if not, quit loop + waitcnt($2000 + cnt) 'cursor cog, allow prior cog to launch + vcfg_ ^= $10000000 'set two-color mode + array_ptr_~ 'flag cursor function + ifnot cog[i] := cognew(@entry, @dira_ + i << 15) + 1 + stop + return {false} + + 'Successful + return true + + +PUB stop | i + +'' Stop driver - frees cogs + + 'If already running, stop any VGA cogs + repeat i from 0 to 2 + if cog[i] + cogstop(cog[i]~ - 1) + +PUB set_scrpointer(array_ptr) +' zeiger auf screenanfang wird neu gesetzt um mehrere screens verwalten zu können + + scrind_ := array_ptr + +DAT + +' ┌─────────────────────────────┐ +' │ Initialization - all cogs │ +' └─────────────────────────────┘ + + org + +' Move field loop into position + +entry mov field,field_code + add entry,d0s0_ + djnz regs,#entry + +' Acquire settings + + mov scrind,par 'dr235: adresse screenindex speichern + cmpsub scrind,bit15 'dr235: bit15 ausblenden + add scrind,#36 'dr235: adresse in scrind speichern + + + mov regs,par '00 dira_ ─ dira + cmpsub regs,bit15 wc '04 dirb_ ─ dirb +:next movd :read,sprs '08 vcfg_ ─ vcfg + or :read,d8_d4 '12 cnt_ ─ cnt + shr sprs,#4 '16 array_ptr_ ─ ctrb +:read rdlong dira,regs '20 color_ptr_ ─ frqb + add regs,#4 '24 cursor_ptr_ ─ vscl + tjnz sprs,#:next '28 sync_ptr_ ─ phsb + '32 mode_ + '36 scrind_ --> scrind + + sumc vf_lines,#2 'alter scan line settings by cog + sumnc vb_lines,#2 + sumnc tile_line,#2 * 4 + + rdlong regs,regs wz 'if mode not 0, set tile size to 16 x 32 pixels + if_nz movs tile_bytes,#32 * 4 + if_nz shr array_bytes,#1 + + mov regs,vscl 'save cursor pointer + +' Synchronize all cogs' video circuits so that waitvid's will be pixel-locked + + movi frqa,#(pr / 5) << 2 'set pixel rate (VCO runs at 2x) + mov vscl,#1 'set video shifter to reload on every pixel + waitcnt cnt,d8_d4 'wait for sync count, add ~3ms - cogs locked! + movi ctra,#%00001_110 'enable PLLs now - NCOs locked! + waitcnt cnt,#0 'wait ~3ms for PLLs to stabilize - PLLs locked! + mov vscl,#100 'subsequent WAITVIDs will now be pixel-locked! + +' Determine if this cog is to perform one of two field functions or the cursor function + + tjnz ctrb,#vsync 'if array ptr, jump to field function + 'else, cursor function follows + +' ┌─────────────────────────┐ +' │ Cursor Loop - one cog │ +' └─────────────────────────┘ + +' Do vertical sync lines minus three + +cursor mov par,#vf + vs + vb - 6 + +:loop mov vscl,vscl_line +:vsync waitvid ccolor,#0 + djnz par,#:vsync + +' Do three lines minus horizontal back porch pixels to buy a big block of time + + mov vscl,vscl_three_lines_mhb + waitvid ccolor,#0 + +' Get cursor data + + rdlong cx,regs 'get cursor x + add regs,#4 + rdlong cy,regs 'get cursor y + add regs,#4 + rdlong ccolor,regs 'get cursor color + add regs,#4 + rdlong cshape,regs 'get cursor shape + sub regs,#3 * 4 + + and ccolor,#$FC 'trim and justify cursor color + shl ccolor,#8 + +' Build cursor pixels + + mov par,#32 'ready for 32 cursor segments + movd :pix,#cpix + mov cnt,cshape + +:pixloop cmp cnt,#1 wc, wz 'arrow, crosshair, or custom cursor? + if_a jmp #:custom + if_e jmp #:crosshair + + cmp par,#32 wz 'arrow + cmp par,#32-21 wc + if_z mov cseg,h80000000 + if_nz_and_nc sar cseg,#1 + if_nz_and_c shl cseg,#2 + mov coff,#0 + jmp #:pix + +:crosshair cmp par,#32-15 wz 'crosshair + if_ne mov cseg,h00010000 + if_e neg cseg,#2 + cmp par,#1 wz + if_e mov cseg,#0 + mov coff,h00000F0F + jmp #:pix + +:custom rdlong cseg,cshape 'custom + add cshape,#4 + rdlong coff,cshape + +:pix mov cpix,cseg 'save segment into pixels + add :pix,d0 + + djnz par,#:pixloop 'another segment? + +' Compute cursor position + + mov cseg,coff 'apply cursor center-pixel offsets + and cseg,#$FF + sub cx,cseg + shr coff,#8 + and coff,#$FF + add cy,coff + + cmps cx,neg31 wc 'if x out of range, hide cursor via y + if_nc cmps pixels_m1,cx wc + if_c neg cy,#1 + + mov cshr,#0 'adjust for left-edge clipping + cmps cx,#0 wc + if_c neg cshr,cx + if_c mov cx,#0 + + mov cshl,#0 'adjust for right-edge clipping + cmpsub cx,pixels_m32 wc + if_c mov cshl,cx + if_c mov cx,pixels_m32 + + add cx,#hb 'bias x and y for display + sub cy,lines_m1 + +' Do visible lines with cursor + + mov par,lines 'ready for visible scan lines + +:line andn cy,#$1F wz, nr 'check if scan line in cursor range + + if_z movs :seg,cy 'if in range, get cursor pixels + if_z add :seg,#cpix + if_nz mov cseg,#0 'if out of range, use blank pixels +:seg if_z mov cseg,cpix + if_z rev cseg,#0 'reverse pixels so they map sensibly + if_z shr cseg,cshr 'perform any edge clipping on pixels + if_z shl cseg,cshl + + mov vscl,cx 'do left blank pixels (hb+cx) + waitvid ccolor,#0 + + mov vscl,vscl_cursor 'do cursor pixels (32) + waitvid ccolor,cseg + + mov vscl,vscl_line_m32 'do right blank pixels (hp+hf+hs-32-cx) + sub vscl,cx + waitvid ccolor,#0 + + add cy,#1 'another scan line? + djnz par,#:line + +' Do horizontal back porch pixels and loop + + mov vscl,#hb + waitvid ccolor,#0 + + mov par,#vf + vs + vb - 3 'ready to do vertical sync lines + jmp #:loop + +' Cursor data + +vscl_line long ht 'total pixels per scan line +vscl_three_lines_mhb long ht * 3 - hb 'total pixels per three scan lines minus hb +vscl_line_m32 long ht - 32 'total pixels per scan line minus 32 +vscl_cursor long 1 << 12 + 32 '32 pixels per cursor with 1 clock per pixel +lines long vp 'visible scan lines +lines_m1 long vp - 1 'visible scan lines minus 1 +pixels_m1 long hp - 1 'visible pixels minus 1 +pixels_m32 long hp - 32 'visible pixels minus 32 +neg31 long -31 + +h80000000 long $80000000 'arrow/crosshair cursor data +h00010000 long $00010000 +h00000F0F long $00000F0F + +' Initialization data + +d0s0_ long 1 << 9 + 1 'd and s field increments +regs long $1F0 - field 'number of registers in field loop space +sprs long $DFB91E76 'phsb/vscl/frqb/ctrb/cnt/vcfg/dirb/dira nibbles +bit15 long $8000 'bit15 mask used to differentiate cogs in par +d8_d4 long $0003E000 'bit8..bit4 mask for d field + +field_code 'field loop code begins at this offset + +' Undefined cursor data + +cx res 1 +cy res 1 +ccolor res 1 +cshape res 1 +coff res 1 +cseg res 1 +cshr res 1 +cshl res 1 +cpix res 32 + + +' ┌─────────────────────────┐ +' │ Field Loop - two cogs │ +' └─────────────────────────┘ + + org + +' Allocate buffers + +palettes res 64 'palettes of colors +colors res xtiles 'colors for tile row +pixels0 res xtiles 'pixels for tile row line +0 +pixels1 res xtiles 'pixels for tile row line +1 +pixels2 res xtiles 'pixels for tile row line +2 +pixels3 res xtiles 'pixels for tile row line +3 + +' Each cog alternately builds and displays four scan lines + +field mov cnt,#ytiles * 4 / 2 'ready number of four-scan-line builds/displays + +' Build four scan lines + +build_4y movd col0,#colors+0 'reset pointers for scan line buffers + movd col1,#colors+1 + movd pix0,#pixels0+0 + movd pix1,#pixels1+0 + movd pix2,#pixels2+0 + movd pix3,#pixels3+0 + movd pix4,#pixels0+1 + movd pix5,#pixels1+1 + movd pix6,#pixels2+1 + movd pix7,#pixels3+1 + + mov ina,#2 'four scan lines require two waitvid's + +build_32x mov vscl,vscl_two_lines 'output lows for two scan lines so other cog +:zero waitvid :zero,#0 '..can display while this cog builds (twice) + + mov inb,#xtiles / 2 / 2 'build four scan lines for half a row + +build_2x rdlong vscl,ctrb 'get pair of words from the tile array + + movs col0,vscl 'get color bits from even tile + andn col0,#$1C0 + + andn vscl,#$3F 'strip color bits and add tile line offset + add vscl,tile_line + +col0 mov colors+0,palettes 'get even tile color + add col0,d1 + +pix0 rdlong pixels0+0,vscl 'get line +0 even tile pixels + add pix0,d1 + add vscl,#4 + +pix1 rdlong pixels1+0,vscl 'get line +1 even tile pixels + add pix1,d1 + add vscl,#4 + +pix2 rdlong pixels2+0,vscl 'get line +2 even tile pixels + add pix2,d1 + add vscl,#4 + +pix3 rdlong pixels3+0,vscl 'get line +3 even tile pixels + add pix3,d1 + + add ctrb,#2 * 2 'point to next pair of tile words + shr vscl,#16 'shift odd tile word into position + + movs col1,vscl 'get color bits from odd tile + andn col1,#$1C0 + + andn vscl,#$3F 'strip color bits and add tile line offset + add vscl,tile_line + +col1 mov colors+1,palettes 'get odd tile color + add col1,d1 + +pix4 rdlong pixels0+1,vscl 'get line +0 odd tile pixels + add pix4,d1 + add vscl,#4 + +pix5 rdlong pixels1+1,vscl 'get line +1 odd tile pixels + add pix5,d1 + add vscl,#4 + +pix6 rdlong pixels2+1,vscl 'get line +2 odd tile pixels + add pix6,d1 + add vscl,#4 + +pix7 rdlong pixels3+1,vscl 'get line +3 odd tile pixels + add pix7,d1 + djnz inb,#build_2x 'loop for next tile pair (48 inst/loop) + + djnz ina,#build_32x 'if first half done, loop for 2nd waitvid + + sub ctrb,#xtiles * 2 'back up to start of same row + +' Display four scan lines + + mov inb,#4 'ready for four scan lines + movs :waitvid,#pixels0 'reset waitvid pixel pointer + +:line mov ina,#xtiles 'ready for tiles + movd :waitvid,#colors 'reset waitvid color pointer + mov vscl,vscl_tile 'set pixel rate for tiles + +:tile cmp ina,#1 wz 'check if last tile + add :waitvid,d0s0 'advance pointers (waitvid already read) +:waitvid waitvid colors,pixels0 'do tile slice + if_nz djnz ina,#:tile 'strange loop allows hsync timing and ina=1 + + call #hsync 'do horizontal sync (ina=1) + + djnz inb,#:line 'another scan line? + +' Another four scan lines? + + add tile_line,#8 * 4 'advance eight scan lines within tile row +tile_bytes cmpsub tile_line,#16 * 4 wc 'tile row done? (# doubled for mode 1) + if_c add ctrb,#xtiles * 2 'if done, advance array pointer to next row + + djnz cnt,#build_4y 'another four scan lines? + +' hier kann der index eingearbeitet werden + 'sub ctrb,array_bytes 'display done, reset array pointer to top row + + rdlong ctrb,scrind 'dr235: stelle pointer wieder auf screenanfang + + + +' Visible section done, handle sync indicator + + cmp cnt,phsb wz 'sync enabled? (cnt=0) + if_nz wrlong neg1,phsb 'if so, write -1 to sync indicator + +' Do vertical sync lines and loop + +vf_lines mov ina,#vf + 2 'do vertical front porch lines (adjusted ±2) + call #blank + +vsync mov ina,#vs 'do vertical sync lines + call #blank_vsync + +vb_lines mov ina,#vb - 2 'do vertical back porch lines (adjusted ±2) + movs blank_vsync_ret,#field '(loop to field, blank_vsync follows) + +' Subroutine - do blank lines + +blank_vsync xor hv_sync,#$0101 'flip vertical sync bits + +blank mov vscl,vscl_blank 'do horizontal blank pixels + waitvid hv_sync,#0 + +hsync mov vscl,#hf 'do horizontal front porch pixels + waitvid hv_sync,#0 + + mov vscl,#hs 'do horizontal sync pixels + waitvid hv_sync,#1 + + rdlong vscl,frqb 'update another palette + and vscl,color_mask +:palette mov palettes,vscl + add :palette,d0 + add frqb,#4 + add par,count_64 wc + if_c movd :palette,#palettes + if_c sub frqb,#64 * 4 + + mov vscl,#hb 'do horizontal back porch pixels + waitvid hv_sync,#0 + + djnz ina,#blank 'another blank line? +hsync_ret +blank_ret +blank_vsync_ret ret + +' Data + +d0s0 long 1 << 9 + 1 'd and s field increments +d0 long 1 << 9 'd field increment +d1 long 2 << 9 'd field double increment + +tile_line long 2 * 4 'tile line offset (adjusted ±2 * 4) +array_bytes long xtiles * ytiles * 2 'number of bytes in tile array + +vscl_two_lines long ht * 2 'total pixels per two scan lines +vscl_tile long 1 << 12 + 16 '16 pixels per tile with 1 clock per pixel +vscl_blank long hp 'visible pixels per scan line + +hv_sync long $0200 '+/-H,-V states +count_64 long $04000000 'addend that sets carry every 64th addition +color_mask long $FCFCFCFC 'mask to isolate R,G,B bits from H,V +neg1 long $FFFFFFFF 'negative 1 to be written to sync indicator +scrind long 0 'dr235: adresse des screenindex + + + + diff --git a/lib/fm-con.spin b/lib/fm-con.spin new file mode 100644 index 0000000..440d4b0 --- /dev/null +++ b/lib/fm-con.spin @@ -0,0 +1,60 @@ +'' Konstanten + +CON + +W1X1 = 1 +W1X2 = 30 +W2X1 = 33 +W2X2 = 62 + +W1Y1 = 2 +W1Y2 = 20 +W2Y1 = 2 +W2Y2 = 20 + +W3X1 = 0 +W3X2 = 63 +W3Y1 = 1 +W3Y2 = 22 + +W4X1 = 15 +W4X2 = 45 +W4Y1 = 10 +W4Y2 = 13 + +WROWS = W2Y2 - 2 + +W0X_MENU = 8 +W0Y_MENU = 0 +W0X_STAT = 0 +W0Y_STAT = 23 + +W0X_INFO = 1 +W0Y_INFO = 22 +W1X_INFO = 33 +W1Y_INFO = 22 + +WAIT_SEC = 5 + +COL_DEFAULT = 0 +COL_MENU = 8 +COL_STAT = 8 +COL_FOCUS = 3 +COL_LOGO = 2 +COL_SELECT = 3 + +MAX_FILES = 128 +MAX_LEN = 12 '12345678.123 +MAX_BUFFER = MAX_FILES * MAX_LEN + +FL_DIR = %1000_0000 'eintrag ist verzeichnisname +FL_SEL = %0000_0001 'eintrag ist selektiert + +FL_FOCUS = %0000_0001 'box ist selektiert + +DR_SD = 0 +DR_RAM = 1 +DR_BLK = 2 + +PUB dummy + diff --git a/lib/glob-com.spin b/lib/glob-com.spin new file mode 100644 index 0000000..1d24d75 --- /dev/null +++ b/lib/glob-com.spin @@ -0,0 +1,456 @@ +{{ +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Communications Engine │ +│ │ +│ Author: Kwabena W. Agyeman │ +│ Updated: 8/4/2009 │ +│ Designed For: P8X32A │ +│ │ +│ Copyright (c) 2009 Kwabena W. Agyeman │ +│ See end of file for terms of use. │ +│ │ +│ Driver Info: │ +│ │ +│ The COMEngine runs a COM driver in the next free cog on the propeller chip when called. │ +│ │ +│ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │ +│ so port B will not be operational. │ +│ │ +│ Nyamekye, │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + +CON + '' + RX_Pin = 31 '' ── RX Line - This line is driven by the interface chip. + '' + TX_Pin = 30 '' ── TX Line - This line is driven by the propeller chip. + + Stop_Bits = 1 + +CON + + ' For use with "receiveCharacter", "receiveCheck", "transmitCharacter", "transmitCharacters" + + #0, Null + + #1, Start_Of_Heading, Start_Of_Text, End_Of_Text, End_Of_Transmission + + #5, Enquiry, Acknowledge + + #7, Bell, Backspace, Horizontal_Tab, Line_Feed, Vertical_Tab, Form_Feed, Carriage_Return + + #14, Shift_Out, Shift_In, Data_Link_Escape + + #17, Device_Control_1, Device_Control_2, Device_Control_3, Device_Control_4 + + #21, Negative_Aknowledge, Synchronous_Idle, End_Of_Transmission_Block, Cancel, End_Of_Medium, Substitute, Escapse + + #28, File_Seperaor, Group_Seperator, Record_Seperator, Unit_Seperator + + #127, Delete + + #17, XON, #19, XOFF + +VAR + + long baudRate + + byte inputHead + byte inputTail + + byte outputHead + byte outputTail + + byte inputBuffer[256] + byte outputBuffer[256] + +PUB generateEvenParity(character) '' 8 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Generates an even parity for a character and returns that character with the new parity attached. │ +'' │ │ +'' │ Character - A character. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (character ^ evenOrOdd(character)) + +PUB generateOddParity(character) '' 8 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Generates an odd parity for a character and returns that character with the new parity attached. │ +'' │ │ +'' │ Character - A character. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (character ^ evenOrOdd(character) ^ $80) + +PUB generateMarkParity(character) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Generates an mark parity for a character and returns that character with the new parity attached. │ +'' │ │ +'' │ Character - A character. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (character | $80) + +PUB generateSpaceParity(character) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Generates an space parity for a character and returns that character with the new parity attached. │ │ +'' │ │ +'' │ Character - A character. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (character & $7F) + +PUB checkEvenParity(character) '' 8 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if the parity is correct and false if it is not. │ +'' │ │ +'' │ Character - A character with an even parity. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (not(evenOrOdd(character))) + +PUB checkOddParity(character) '' 8 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if the parity is correct and false if it is not. │ +'' │ │ +'' │ Character - A character with an odd parity. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= evenOrOdd(character) + +PUB checkMarkParity(character) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if the parity is correct and false if it is not. │ +'' │ │ +'' │ Character - A character with an mark parity. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result or= (character & $80) + +PUB checkSpaceParity(character) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if the parity is correct and false if it is not. │ +'' │ │ +'' │ Character - A character with an space parity. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (not(character & $80)) + +PUB receiveCharacter '' 6 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the next character in the receiver buffer. │ +'' │ │ +'' │ Waits until there is a character to return if the receiver buffer is empty. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat until(receiveNumber) + + return inputBuffer[inputTail++] + +PUB receiveNumber '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns the number of characters in the receiver buffer. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return ((inputHead - inputTail) & $FF) + +PUB receiveCheck(character) '' 7 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Compares the last character in the receiver buffer with the specified character for equality. │ +'' │ │ +'' │ Returns true if they are equal and false otherwise. │ +'' │ │ +'' │ Character - The character to compare the last received character with for equality. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (receiveNumber and (inputBuffer[(inputHead - 1) & $FF] == character)) + +PUB receiveFull '' 6 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Returns true if the receiver buffer is full and false if it is not. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (receiveNumber == 255) + +PUB receiveFlush '' 3 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Empties the receiver buffer. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + inputTail := inputHead + +PUB transmitCharacter(character) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Transmits a character at the speed of the currently specified baud rate. │ +'' │ │ +'' │ Character - A character to transmit. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat until(outputTail <> ((outputHead + 1) & $FF)) + + outputBuffer[outputHead++] := character + +PUB transmitCharacters(characters) '' 8 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Transmits a string characters at the speed of the currently specified baud rate. │ +'' │ │ +'' │ Characters - A pointer to the string of characters to transmit. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(characters) + + transmitCharacter(byte[characters++]) + +PUB changeBaudRate(newBaudRate) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Changes the current baud rate. │ +'' │ │ +'' │ NewBaudRate - The new baud rate to transmit and receive at. Between 1 BPS and 250000 BPS. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat while(outputHead <> outputTail) + + if(baudRate) + + waitcnt((baudRate * constant((((Stop_Bits <# 32) #> 1) + 8) * 4)) + cnt) + + baudRate := ((clkfreq / ((newBaudRate <# 250000) #> 1)) >> 2) + +PUB COMEngine(newBaudRate) '' 8 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Initializes the COM driver to run on a new cog. │ +'' │ │ +'' │ Returns the new cog's ID on sucess or -1 on failure. │ +'' │ │ +'' │ NewBaudRate - The new baud rate to transmit and receive at. Between 1 BPS and 250000 BPS. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + inputHeadAddress := @inputHead + inputTailAddress := @inputTail + + outputHeadAddress := @outputHead + outputTailAddress := @outputTail + + inputBufferAddress := @inputBuffer + outputBufferAddress := @outputBuffer + + changeBaudRate(newBaudRate) + + return cognew(@initialization, @baudRate) + +PRI evenOrOdd(character) ' 4 Stack Longs + + repeat 8 + + result += (character & 1) + character >>= 1 + + return ((result & 1) << 7) + +DAT + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' COM Driver +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + org + +' //////////////////////Initialization///////////////////////////////////////////////////////////////////////////////////////// + +initialization mov transmitterPC, #transmitter ' Setup transmitter. + movi ctra, #%0_00100_000 ' + movs ctra, #((TX_Pin <# 31) #> 0) ' + neg phsa, #1 ' + mov dira, TXPin ' + + rdlong counter, par ' Setup synchronization. + add counter, cnt ' + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Receiver +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +receiver rdlong quarterRate, par ' Get new settings. + add counter, quarterRate ' + + waitcnt counter, quarterRate ' Wait for transmitter. + jmpret receiverPC, transmitterPC ' + + waitcnt counter, quarterRate ' Wait for start bit. + test RXPin, ina wz ' + +if_nz waitcnt counter, quarterRate ' Wait for start bit. +if_nz test RXPin, ina wc ' + +if_nz_and_c jmp #receiver ' Repeat. + +' //////////////////////Receiver Setup///////////////////////////////////////////////////////////////////////////////////////// + + mov receiverCounter, #9 ' Setup loop to receive the packet. + +' //////////////////////Receive Packet///////////////////////////////////////////////////////////////////////////////////////// + +receive waitcnt counter, quarterRate ' Input bits. + test RXPin, ina wc ' + rcl receiverBuffer, #1 ' + +if_z add counter, quarterRate ' Wait for transmitter. + waitcnt counter, quarterRate ' + jmpret receiverPC, transmitterPC ' +if_nz add counter, quarterRate ' + waitcnt counter, quarterRate ' + + djnz receiverCounter, #receive ' Ready next bit. + + rev receiverBuffer, #24 ' Reverse backwards bits. + +' //////////////////////Update Packet////////////////////////////////////////////////////////////////////////////////////////// + + rdbyte receiverTail, inputTailAddress ' Check if the buffer is full. + mov buffer, receiverHead ' + sub buffer, receiverTail ' + and buffer, #$FF ' + cmp buffer, #255 wc ' + +' //////////////////////Set Packet///////////////////////////////////////////////////////////////////////////////////////////// + +if_z add counter, quarterRate ' Set packet and synchronize. +if_c mov buffer, inputBufferAddress ' +if_c add buffer, receiverHead ' +if_c wrbyte receiverBuffer, buffer ' + +if_c add receiverHead, #1 ' Update receiver head pointer. +if_c and receiverHead, #$FF ' +if_c wrbyte receiverHead, inputHeadAddress ' + +' //////////////////////Repeat///////////////////////////////////////////////////////////////////////////////////////////////// + + jmp #receiver ' Repeat + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Transmitter +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +transmitter jmpret transmitterPC, receiverPC ' Run some code. + +loop rdbyte buffer, outputHeadAddress ' Check if the buffer is empty. + sub buffer, transmitterTail ' + tjz buffer, #transmitter ' + +' //////////////////////Get Packet///////////////////////////////////////////////////////////////////////////////////////////// + + mov transmitterBuffer, outputBufferAddress ' Get packet and output start bit. + add transmitterBuffer, transmitterTail ' + jmpret transmitterPC, receiverPC ' + rdbyte phsa, transmitterBuffer ' + + add transmitterTail, #1 ' Update transmitter tail pointer. + and transmitterTail, #$FF ' + wrbyte transmitterTail, outputTailAddress ' + +' //////////////////////Transmitter Setup/////////////////////////////////////////////////////////////////////////////////////// + + mov transmitterCounter, #(((Stop_Bits <# 32) #> 1) + 8) ' Setup loop to transmit the packet. + +' //////////////////////Transmit Packet//////////////////////////////////////////////////////////////////////////////////////// + +transmit or phsa, #$100 ' Output bits. + jmpret transmitterPC, receiverPC ' + ror phsa, #1 ' + + djnz transmitterCounter, #transmit ' Ready next bit. + +' //////////////////////Repeat///////////////////////////////////////////////////////////////////////////////////////////////// + + jmp #loop ' Repeat. + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +' Data +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +receiverHead long 0 +transmitterTail long 0 + +' //////////////////////Pin Masks////////////////////////////////////////////////////////////////////////////////////////////// + +RXPin long (|<((RX_Pin <# 31) #> 0)) ' Receiving pin mask. +TXPin long (|<((TX_Pin <# 31) #> 0)) ' Transmitting pin mask. + +' //////////////////////Addresses////////////////////////////////////////////////////////////////////////////////////////////// + +inputHeadAddress long 0 +inputTailAddress long 0 + +outputHeadAddress long 0 +outputTailAddress long 0 + +inputBufferAddress long 0 +outputBufferAddress long 0 + +' //////////////////////Run Time Variables///////////////////////////////////////////////////////////////////////////////////// + +buffer res 1 +counter res 1 + +halfRate res 1 +quarterRate res 1 + +' //////////////////////Receiver Variables///////////////////////////////////////////////////////////////////////////////////// + +receiverBuffer res 1 +receiverCounter res 1 + +receiverTail res 1 + +receiverPC res 1 + +' //////////////////////Transmitter Variables////////////////////////////////////////////////////////////////////////////////// + +transmitterBuffer res 1 +transmitterCounter res 1 + +transmitterHead res 1 + +transmitterPC res 1 + +' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + fit 496 + +{{ + +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the │ +│Software is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the │ +│Software. │ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/glob-con.spin b/lib/glob-con.spin new file mode 100644 index 0000000..41ccdf7 --- /dev/null +++ b/lib/glob-con.spin @@ -0,0 +1,389 @@ +{{ Bellatrix-Code +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2012 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : trios +Name : +Chip : global +Typ : konstanten + + +}} + +CON 'Signaldefinitionen -------------------------------------------------------------------------- + +'signaldefinitionen global + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + I2C_SCL + I2C_SDA + SER_TX + SER_RX + + +'signaldefinitionen bellatrix + +#8, B_VGABASE 'vga-signale (8pin) +#16, B_KEYBC,B_KEYBD 'keyboard-signale +#18, B_MOUSEC,B_MOUSED 'maus-signale +#20, B_VIDBASE 'video-signale(3pin) +#23, B_SELECT 'belatrix-auswahlsignal + + +'signaldefinitionen administra + +#8, A_SOUNDL,A_SOUNDR 'sound (stereo 2 pin) +#10, A_SDD0,A_SDCLK,A_SDCMD,A_SDD3 'sd-cardreader (4 pin) +#23, A_SELECT 'administra-auswahlsignal + +CON 'KEY_CODES ------------------------------------------------------------------------------------- + +KEY_CTRL = 2 +KEY_ALT = 4 +KEY_OS = 8 + +KEY_ESC = 27 +KEY_TAB = 9 +KEY_RETURN = 13 +KEY_BS = 8 +KEY_POS1 = 6 + +KEY_CURUP = 04 +KEY_CURDOWN = 05 +KEY_CURLEFT = 02 +KEY_CURRIGHT = 03 +KEY_PAGEUP = 160 +KEY_PAGEDOWN = 162 +KEY_SPACE = 32 + +KEY_F01 = 208 +KEY_F02 = 209 +KEY_F03 = 210 +KEY_F04 = 211 +KEY_F05 = 212 +KEY_F06 = 213 +KEY_F07 = 214 +KEY_F08 = 215 +KEY_F09 = 216 +KEY_F10 = 217 +KEY_F11 = 218 +KEY_F12 = 219 + + +CON 'ADMINISTRA-FUNKTIONEN -------------------------------------------------------------------------- + +' +----------- ays +' |+---------- com +' || +-------- plexbus +' || |+------- rtc +' || ||+------ lan +' || |||+----- sid +' || ||||+---- wav +' || |||||+--- hss +' || ||||||+-- chiploader +' || |||||||+- dateisystem +A_FAT = %00000000_00000000_00000000_00000001 +A_LDR = %00000000_00000000_00000000_00000010 +A_HSS = %00000000_00000000_00000000_00000100 +A_WAV = %00000000_00000000_00000000_00001000 +A_SID = %00000000_00000000_00000000_00010000 +A_LAN = %00000000_00000000_00000000_00100000 +A_RTC = %00000000_00000000_00000000_01000000 +A_PLX = %00000000_00000000_00000000_10000000 +A_COM = %00000000_00000000_00000001_00000000 +A_AYS = %00000000_00000000_00000010_00000000 +' | +' ym + + +' ---------------------------------------------- SD-FUNKTIONEN +#1, a_sdMount 'sd-card mounten ' + a_sdOpenDir 'direktory öffnen + a_sdNextFile 'verzeichniseintrag lesen + a_sdOpen 'datei öffnen + a_sdClose 'datei schließen + a_sdGetC 'zeichen lesen + a_sdPutC 'zeichen schreiben + a_sdGetBlk 'block lesen + a_sdPutBlk 'block schreiben + a_sdSeek 'zeiger in datei positionieren + a_sdFAttrib 'dateiattribute übergeben + a_sdVolname 'volumelabel abfragen + a_sdCheckMounted 'test ob volume gemounted ist + a_sdCheckOpen 'test ob eine datei geöffnet ist + a_sdCheckUsed 'test wie viele sektoren benutzt sind + a_sdCheckFree 'test wie viele sektoren frei sind + a_sdNewFile 'neue datei erzeugen + a_sdNewDir 'neues verzeichnis wird erzeugt + a_sdDel 'verzeichnis oder datei löschen + a_sdRename 'verzeichnis oder datei umbenennen + a_sdChAttrib 'attribute ändern + a_sdChDir 'verzeichnis wechseln + a_sdFormat 'medium formatieren + a_sdUnmount 'medium abmelden + a_sdDmAct 'dir-marker aktivieren + a_sdDmSet 'dir-marker setzen + a_sdDmGet 'dir-marker status abfragen + a_sdDmClr 'dir-marker löschen + a_sdDmPut 'dir-marker status setzen + a_sdEOF '30 'eof abfragen + +' ---------------------------------------------- COM-FUNKTIONEN +#31, a_comInit + a_comTx + a_comRx '33 + +' ---------------------------------------------- RTC-FUNKTIONEN +#41, a_rtcGetSeconds 'Returns the current second (0 - 59) from the real time clock. + a_rtcGetMinutes 'Returns the current minute (0 - 59) from the real time clock. + a_rtcGetHours 'Returns the current hour (0 - 23) from the real time clock. + a_rtcGetDay 'Returns the current day (1 - 7) from the real time clock. + a_rtcGetDate 'Returns the current date (1 - 31) from the real time clock. + a_rtcGetMonth 'Returns the current month (1 - 12) from the real time clock. + a_rtcGetYear 'Returns the current year (2000 - 2099) from the real time clock. + a_rtcSetSeconds 'Sets the current real time clock seconds. Seconds - Number to set the seconds to between 0 - 59. + a_rtcSetMinutes 'Sets the current real time clock minutes. Minutes - Number to set the minutes to between 0 - 59. + a_rtcSetHours 'Sets the current real time clock hours. Hours - Number to set the hours to between 0 - 23. + a_rtcSetDay 'Sets the current real time clock day. Day - Number to set the day to between 1 - 7. + a_rtcSetDate 'Sets the current real time clock date. Date - Number to set the date to between 1 - 31. + a_rtcSetMonth 'Sets the current real time clock month. Month - Number to set the month to between 1 - 12. + a_rtcSetYear 'Sets the current real time clock year. Year - Number to set the year to between 2000 - 2099. + a_rtcSetNVSRAM 'Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). + a_rtcGetNVSRAM 'Gets the selected NVSRAM value at the index (0 - 55). + a_rtcPauseForSec 'Pauses execution for a number of seconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of seconds to pause for between 0 and 2,147,483,647. + a_rtcPauseForMSec '58 'Pauses execution for a number of milliseconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of milliseconds to pause for between 0 and 2,147,483,647. + +' ---------------------------------------------- CHIP-MANAGMENT +#92, a_mgrSetSound 'soundsubsysteme verwalten + a_mgrGetSpec 'spezifikation abfragen + a_mgrSetSysSound 'systemsound ein/ausschalten + a_mgrGetSoundSys 'abfrage welches soundsystem aktiv ist + a_mgrALoad 'neuen code booten + a_mgrGetCogs 'freie cogs abfragen + a_mgrGetVer 'codeversion abfragen + a_mgrReboot '99 'neu starten + +' ---------------------------------------------- HSS-FUNKTIONEN +#100, a_hssLoad 'hss-datei in puffer laden + a_hssPlay 'play + a_hssStop 'stop + a_hssPause 'pause + a_hssPeek 'register lesen + a_hssIntReg 'interfaceregister auslesen + a_hssVol 'lautstärke setzen + a_sfxFire 'sfx abspielen + a_sfxSetSlot 'sfx-slot setzen + a_sfxKeyOff + a_sfxStop '110 + +' ---------------------------------------------- WAV-FUNKTIONEN +#150, a_sdwStart 'spielt wav-datei direkt von sd-card ab + a_sdwStop 'stopt wav-cog + a_sdwStatus 'fragt status des players ab + a_sdwLeftVol 'lautstärke links + a_sdwRightVol 'lautstärke rechts + a_sdwPause 'player pause/weiter-modus + a_sdwPosition '156 + +' ---------------------------------------------- AY-SOUNDFUNKTIONEN +#200, a_ayStart + a_ayStop + a_ayUpdateRegisters + +' ---------------------------------------------- SIDCog: DMP-Player-Funktionen (SIDCog2) +#157, a_s_mdmpplay 'dmp-file mono auf sid2 abspielen + a_s_sdmpplay 'dmp-file stereo auf beiden sids abspielen + a_s_dmpstop 'dmp-player beenden + a_s_dmppause 'dmp-player pausenmodus + a_s_dmpstatus 'dmp-player statusabfrage + a_s_dmppos 'player-position im dumpfile + a_s_mute 'alle register löschen + +' ---------------------------------------------- SIDCog1-Funktionen + a_s1_setRegister + a_s1_updateRegisters + a_s1_setVolume + a_s1_play + a_s1_noteOn + a_s1_noteOff + a_s1_setFreq + a_s1_setWaveform + a_s1_setPWM + a_s1_setADSR + a_s1_setResonance + a_s1_setCutoff + a_s1_setFilterMask + a_s1_setFilterType + a_s1_enableRingmod + a_s1_enableSynchronization + +' ---------------------------------------------- SIDCog2-Funktionen + a_s2_setRegister + a_s2_updateRegisters + a_s2_setVolume + a_s2_play + a_s2_noteOn + a_s2_noteOff + a_s2_setFreq + a_s2_setWaveform + a_s2_setPWM + a_s2_setADSR + a_s2_setResonance + a_s2_setCutoff + a_s2_setFilterMask + a_s2_setFilterType + a_s2_enableRingmod + a_s2_enableSynchronization + +' ---------------------------------------------- Zusatzfunktionen + a_s_dmpreg '196 'soundinformationen senden + +CON 'BELLATRIX-FUNKTIONEN -------------------------------------------------------------------------- + +' +---------- +' | +-------- window +' | |+------- vektor +' | ||+------ grafik +' | |||+----- text +' | ||||+---- maus +' | |||||+--- tastatur +' | ||||||+-- vga +' | |||||||+- tv +B_TV = %00000000_00000000_00000000_00000001 +B_VGA = %00000000_00000000_00000000_00000010 +B_KEY = %00000000_00000000_00000000_00000100 +B_MOUSE = %00000000_00000000_00000000_00001000 +B_TXT = %00000000_00000000_00000000_00010000 +B_PIX = %00000000_00000000_00000000_00100000 +B_VEC = %00000000_00000000_00000000_01000000 +B_WIN = %00000000_00000000_00000000_10000000 + + +#1, B_KEYSTAT 'tastaturstatus senden + B_KEYCODE 'tastaturzeichen senden + B_PRINTCTRL 'steuerzeichen ($100..$1FF) ausgeben + B_KEYSPEC 'statustasten ($100..$1FF) abfragen + B_PRINTLOGO 'hive-logo ausgeben + B_PRINTQCHAR '6 'zeichen ohne steuerzeichen augeben + +#80, B_WDEF + B_WSET + B_WGETCOLS + B_WGETROWS + B_WOFRAME '84 + +#87, B_MGRLOAD 'neuen bellatrix-code laden + B_MGRWSCR 'setzt screen, in welchen geschrieben wird + B_MGRDSCR 'setzt screen, welcher angezeigt wird + B_MGRGETCOL 'farbregister auslesen + B_MGRSETCOL 'farbregister setzen + B_MGRGETRESX 'x-auflösung abfragen + B_MGRGETRESY 'y-auflösung abfragen + B_MGRGETCOLS 'spaltenanzahl abfragen + B_MGRGETROWS 'zeilenanzahl abfragen + B_MGRGETCOGS 'freie cogs abfragen + B_MGRGETSPEC 'spezifikation abfragen + B_MGRGETVER 'codeversion abfragen + B_MGRREBOOT '99 'bellatrix neu starten + +' steuerzeichen +#0, B_CMD 'esc-code für zweizeichen-steuersequenzen + B_CLS + B_HOME + B_POS1 + B_CURON + B_CUROFF + B_SCROLLUP + B_SCROLLDOWN + B_BACKSPACE + B_TAB + B_LF + B_FREE1 + B_FREE2 + B_CRLF + +' dreizeichen-steuersequenzen +' [B_CMD][B_SCRCMD][...] + +#01, B_SETCUR + B_SETX + B_SETY + B_GETX + B_GETY + B_SETCOL + B_FREE3 + B_FREE4 + B_SINIT + B_TABSET + B_WSETX + B_WSETY + B_WGETX + B_WGETY + +CON 'G0-FUNKTIONEN -------------------------------------------------------------------------- + +#1, G0_KEYSTAT + G0_KEYCODE + G0_KEYSPEC + +#10, G0_CLEAR + G0_COPY + G0_COLOR + G0_WIDTH + G0_COLORWIDTH + G0_PLOT + G0_LINE + G0_ARC + G0_VEC + G0_VECARC + G0_PIX + G0_PIXARC + G0_TEXT + G0_TEXTARC + G0_TEXTMODE + G0_BOX + G0_QUAD + G0_TRI + +#93, G0_COLORTAB + G0_SCREEN + G0_DATBLK + G0_DATLEN + G0_DYNAMIC + G0_STATIC + G0_REBOOT + +PUB glob_con_dummy + return + +DAT + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/glob-fds.spin b/lib/glob-fds.spin new file mode 100644 index 0000000..f731c4d --- /dev/null +++ b/lib/glob-fds.spin @@ -0,0 +1,322 @@ +''******************************************** +''* Full-Duplex Serial Driver v1.2 * +''* Author: Chip Gracey, Jeff Martin * +''* Copyright (c) 2006-2009 Parallax, Inc. * +''* See end of file for terms of use. * +''******************************************** + +{-----------------REVISION HISTORY----------------- + v1.2 - 5/7/2009 fixed bug in dec method causing largest negative value (-2,147,483,648) to be output as -0. + v1.1 - 3/1/2006 first official release. +} + + +VAR + + long cog 'cog flag/id + + long rx_head '9 contiguous longs + long rx_tail + long tx_head + long tx_tail + long rx_pin + long tx_pin + long rxtx_mode + long bit_ticks + long buffer_ptr + + byte rx_buffer[16] 'transmit and receive buffers + byte tx_buffer[16] + + +PUB start(rxpin, txpin, mode, baudrate) : okay + +'' Start serial driver - starts a cog +'' returns false if no cog available +'' +'' mode bit 0 = invert rx +'' mode bit 1 = invert tx +'' mode bit 2 = open-drain/source tx +'' mode bit 3 = ignore tx echo on rx + + stop + longfill(@rx_head, 0, 4) + longmove(@rx_pin, @rxpin, 3) + bit_ticks := clkfreq / baudrate + buffer_ptr := @rx_buffer + okay := cog := cognew(@entry, @rx_head) + 1 + + +PUB stop + +'' Stop serial driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@rx_head, 0, 9) + + +PUB rxflush + +'' Flush receive buffer + + repeat while rxcheck => 0 + + +PUB rxcheck : rxbyte + +'' Check if byte received (never waits) +'' returns -1 if no byte received, $00..$FF if byte + + rxbyte-- + if rx_tail <> rx_head + rxbyte := rx_buffer[rx_tail] + rx_tail := (rx_tail + 1) & $F + + +PUB rxtime(ms) : rxbyte | t + +'' Wait ms milliseconds for a byte to be received +'' returns -1 if no byte received, $00..$FF if byte + + t := cnt + repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms + + +PUB rx : rxbyte + +'' Receive byte (may wait for byte) +'' returns $00..$FF + + repeat while (rxbyte := rxcheck) < 0 + + +PUB tx(txbyte) + +'' Send byte (may wait for room in buffer) + + repeat until (tx_tail <> (tx_head + 1) & $F) + tx_buffer[tx_head] := txbyte + tx_head := (tx_head + 1) & $F + + if rxtx_mode & %1000 + rx + + +PUB str(stringptr) + +'' Send string + + repeat strsize(stringptr) + tx(byte[stringptr++]) + + +PUB dec(value) | i, x + +'' Print a decimal number + + x := value == NEGX 'Check for max negative + if value < 0 + value := ||(value+x) 'If negative, make positive; adjust for max negative + tx("-") 'and output sign + + i := 1_000_000_000 'Initialize divisor + + repeat 10 'Loop for 10 digits + if value => i + tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative + value //= i 'and digit from value + result~~ 'flag non-zero found + elseif result or i == 1 + tx("0") 'If zero digit (or only digit) output it + i /= 10 'Update divisor + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + tx((value <-= 1) & 1 + "0") + + +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org +' +' +' Entry +' +entry mov t1,par 'get structure address + add t1,#4 << 2 'skip past heads and tails + + rdlong t2,t1 'get rx_pin + mov rxmask,#1 + shl rxmask,t2 + + add t1,#4 'get tx_pin + rdlong t2,t1 + mov txmask,#1 + shl txmask,t2 + + add t1,#4 'get rxtx_mode + rdlong rxtxmode,t1 + + add t1,#4 'get bit_ticks + rdlong bitticks,t1 + + add t1,#4 'get buffer_ptr + rdlong rxbuff,t1 + mov txbuff,rxbuff + add txbuff,#16 + + test rxtxmode,#%100 wz 'init tx pin according to mode + test rxtxmode,#%010 wc + if_z_ne_c or outa,txmask + if_z or dira,txmask + + mov txcode,#transmit 'initialize ping-pong multitasking +' +' +' Receive +' +receive jmpret rxcode,txcode 'run a chunk of transmit code, then return + + test rxtxmode,#%001 wz 'wait for start bit on rx pin + test rxmask,ina wc + if_z_eq_c jmp #receive + + mov rxbits,#9 'ready to receive byte + mov rxcnt,bitticks + shr rxcnt,#1 + add rxcnt,cnt + +:bit add rxcnt,bitticks 'ready next bit period + +:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return + + mov t1,rxcnt 'check if bit receive period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + test rxmask,ina wc 'receive bit on rx pin + rcr rxdata,#1 + djnz rxbits,#:bit + + shr rxdata,#32-9 'justify and trim received byte + and rxdata,#$FF + test rxtxmode,#%001 wz 'if rx inverted, invert byte + if_nz xor rxdata,#$FF + + rdlong t2,par 'save received byte and inc head + add t2,rxbuff + wrbyte rxdata,t2 + sub t2,rxbuff + add t2,#1 + and t2,#$0F + wrlong t2,par + + jmp #receive 'byte done, receive next byte +' +' +' Transmit +' +transmit jmpret txcode,rxcode 'run a chunk of receive code, then return + + mov t1,par 'check for head <> tail + add t1,#2 << 2 + rdlong t2,t1 + add t1,#1 << 2 + rdlong t3,t1 + cmp t2,t3 wz + if_z jmp #transmit + + add t3,txbuff 'get byte and inc tail + rdbyte txdata,t3 + sub t3,txbuff + add t3,#1 + and t3,#$0F + wrlong t3,t1 + + or txdata,#$100 'ready byte to transmit + shl txdata,#2 + or txdata,#1 + mov txbits,#11 + mov txcnt,cnt + +:bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode + test rxtxmode,#%010 wc + if_z_and_c xor txdata,#1 + shr txdata,#1 wc + if_z muxc outa,txmask + if_nz muxnc dira,txmask + add txcnt,bitticks 'ready next cnt + +:wait jmpret txcode,rxcode 'run a chunk of receive code, then return + + mov t1,txcnt 'check if bit transmit period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit 'another bit to transmit? + + jmp #transmit 'byte done, transmit next byte +' +' +' Uninitialized data +' +t1 res 1 +t2 res 1 +t3 res 1 + +rxtxmode res 1 +bitticks res 1 + +rxmask res 1 +rxbuff res 1 +rxdata res 1 +rxbits res 1 +rxcnt res 1 +rxcode res 1 + +txmask res 1 +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 +txcode res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/glob-numbers.spin b/lib/glob-numbers.spin new file mode 100644 index 0000000..405a047 --- /dev/null +++ b/lib/glob-numbers.spin @@ -0,0 +1,819 @@ +{{ +************************************* +* Numbers v1.1 * +* Author: Jeff Martin * +* Copyright (c) 2005 Parallax, Inc. * +* See end of file for terms of use. * +************************************* + +{-----------------REVISION HISTORY----------------- + v1.1 - 5/5/2009 fixed formatting bug caused by specifying field width smaller than location of first grouping character.} + +}} + +VAR + long BCX0, BCX1, BCX2, BCX3 'BCX Workspace + byte Symbols[7] 'Special symbols (7 characters) + byte StrBuf[49] 'Internal String Buffer + +PUB Init +''Initialize to default settings. Init MUST be called before first object use. +'' ┌──────────────────────────────────────────────────┐ +'' │ DEFAULT SPECIAL SYMBOLS │ +'' ├─────┬──────┬─────────────────────────────────────┤ +'' │ ID │ Char │ Usage │ +'' ├─────┼──────┼─────────────────────────────────────┤ +'' │ 1 │ , │ Comma (digit group separator) │ +'' │ 2 │ _ │ Underscore (digit group separator) │ +'' │ 3 │ $ │ Dollar Sign (Hexadecimal indicator) │ +'' │ 4 │ % │ Percent Sign (Binary indicator) │ +'' │ 5-7 │ │ Unused (User definable via Config) │ +'' └─────┴──────┴─────────────────────────────────────┘ + Config(@DefaultSymbols) + + +PUB Config(SymAddr) +{{Configure for custom symbols. + PARAMETERS: SymAddr = Address of a string of characters (7 or less) to be used as Special Symbols (indexed from 1 to 7). New symbols can be added or + existing symbols can be modified based on regional customs. Note: The first four symbols must always be the logical: 1) digit group separator + (default is ','), 2) general separator (default is '_'), 3) hexadecimal base indicator (default is '$'), and 4) binary base indicator + (default is '%').}} + bytemove(@Symbols, SymAddr, 7) + + +PUB ToStr(Num, Format): StrAddr +{{Convert long Num to z-string using Format; returns string address. + PARAMETERS: Num = 32-bit signed value to translate to ASCII string. + Format = Indicates output format: base, width, grouping, etc. See "FORMAT SYNTAX" for more information. + RETURNS: Actual length of output string, not including null terminator.}} + BCXToText(Format >> 19 & 7, Format >> 13 & $3F, Format >> 12 & 1, Format >> 11 & 1, Format >> 5 & $3F, BinToBCX(Num, Format & $1F #> 2 <# 16)) + StrAddr := @StrBuf + + +PUB FromStr(StrAddr, Format): Num | Idx, N, Val, Char, Base, GChar, IChar, Field +''Convert z-string (at StrAddr) to long Num using Format. +''PARAMETERS: StrAddr = Address of string buffer containing the numeric string to convert. +'' Format = Indicates input format: base, width, etc. See "FORMAT SYNTAX" for more information. Note: three Format elements are ignored by +'' FromStr(): Zero/Space Padding, Hide/Show Plus Sign, and Digit Group Size. All other elements are actively used during translation. +''RETURNS: Long containing 32-bit signed result. + Base := Format & $1F #> 2 <# 16 'Get base + if GChar := Format >> 13 & 7 'Get grouping character + GChar := Symbols[--GChar #> 0] + if IChar := Format >> 19 & 7 'Get indicator character + IChar := Symbols[--IChar #> 0] + Field := Format >> 5 & $3F - 1 'Get field size, if any (subtract out sign char) + longfill(@Idx, 0, 3) 'Clear Idx, N and Val + repeat while Char := byte[StrAddr][Idx] 'While not null + if (not IChar or (IChar and Val)) and InBaseRange(Char, Base) > 0 'Found first valid digit? (with prefix indicator if required)? + quit ' exit to process digits + else 'else + if not Val := IChar and (Char == IChar) ' look for indicator character (if required) + N := Char == "-" 'Update N flag if not indicator + Idx++ + Field += Val 'Subract indicator character from remaining field size + repeat while (Field--) and (Char := byte[StrAddr][Idx++]) and ((Val := InBaseRange(Char, Base)) > 0 or (GChar and (Char == GChar))) + if Val 'While not null and valid digit or grouping char + Num := Num * Base + --Val 'Accumulate if valid digit + if N + -Num 'Negate if necessary + + +PRI BinToBCX(Num, Base): Digits | N +'Convert signed binary Num to signed BCX value (Binary Coded X ;where X (2..16) is determined by Base) +'Returns: Number of significant Digits (not counting zero-left-padding). + longfill(@BCX0, 0, 4) 'Clear BCX Workspace + N := (Num < 0) & $10000000 'Remember if Num negative + repeat 'Calc all BCX digits + byte[@BCX0][Digits++ >> 1] += ||(Num // Base) << (4 * Digits&1) + while Num /= Base + BCX3 |= N 'If negative, set flag (highest digit of BCX Workspace) + + +PRI BCXToText(IChar, Group, ShowPlus, SPad, Field, Digits): Size | Idx, GCnt, SChar, GChar, X +'Convert BCX Buffer contents to z-string at StrBuf. +'IChar..Field each correspond to elements of Format. See "FORMAT SYNTAX" for more information. +'If Field = 0, Digits+1+Group is the effective field (always limited to max of 49). +'Digits : Number of significant digits (not counting zero-left-padding). +'RETURNS: Actual Size (length) of output string, not including null terminator. + X := 1-(IChar > 0) 'Xtra char count (1 or 2, for sign and optional base indicator) + IChar := Symbols[--IChar] 'Get base indicator character + SChar := "+" + 2*(BCX3 >> 28) + 11*(not (ShowPlus | (BCX3 >> 28)) or ((Digits == 1) and (BCX0 == 0))) 'Determine sign character ('+', ' ' or '-') + GChar := Symbols[Group & 7 - 1 #> 0] 'Get group character + if Field > 0 and SPad^1 and Digits < 32 'Need to add extra zero-padding? + BCX3 &= $0FFFFFFF ' then clear negative flag and set to 32 digits + Digits := 32 + Group := -((Group >>= 3)-(Group > 0))*(Group+1 < Digits) 'Get group size (0 if not enough Digits) + Size := (Field - (Field==0)*(Digits+X+((Digits-1)/Group))) <# 49 'Field = 0? Set Size to Digits+X+Group (max 49). + if Group 'Insert group chars + bytefill(@StrBuf+(Size-Digits-(Digits-1)/Group #> 2), GChar, Digits+(Digits-1)/Group <# Size) + Idx~~ 'Insert digits + repeat while (++Idx < Digits) and (Idx + (GCnt := Idx/Group) < Size-X) + byte[@StrBuf][Size-Idx-1-GCnt] := lookupz(byte[@BCX0][Idx>>1] >> (4 * Idx&1) // 16: "0".."9","A".."F") + bytefill(@StrBuf, " ", Size-Idx-(Idx-1)/Group #> 0) 'Left pad with spaces, if necessary + byte[@StrBuf][Size-X-Idx-(Idx-1)/Group #> 0] := SChar 'Insert sign + if X == 2 + byte[@StrBuf][Size-1-Idx-(Idx-1)/Group #> 1] := IChar 'Insert base indicator, if necessary + byte[@StrBuf][Size] := 0 'Zero-terminate string + + +PRI InBaseRange(Char, Base): Value +'Compare Char against valid characters for Base (1..16) (adjusting for lower-case automatically). +'Returns 0 if Char outside valid Base chars or, if valid, returns corresponding Value+1. + Value := ( Value -= (Char - $2F) * (Char => "0" and Char =< "9") + ((Char &= $DF) - $36) * (Char => "A" and Char =< "F") ) * -(Value < ++Base) + + +DAT + DefaultSymbols byte ",_$%xxx" 'Special, default, symbols ("x" means unused) + + +'' +'' +''************************** +''* FUNCTIONAL DESCRIPTION * +''************************** +'' +''The Numbers object converts values in variables (longs) to strings and vice-versa in any base from 2 to 16. +'' +''Standard/Default Features: +'' * supports full 32-bit signed values +'' * converts using any base from 2 to 16 (binary to hexadecimal) +'' * defaults to variable widths (ouputs entire number, regardless of size) +'' * uses ' ' or '-' for sign character +'' +''Optional Features +'' * allows fixed widths (1 to 49 characters); left padded with either zeros (left justified) or spaces (right justified) +'' * can show plus sign for values > 0 +'' * allows digit grouping (each 2 to 8 characters) with customizable separators; ex: 1000000 becomes 1,000,000 and 7AB14B9C becomes 7AB1_4B9C +'' * allows base indicator character (inserted right after sign) with customizable characters; ex: 7AB1 becomes $7AB1 and -1011 becomes -%1011 +'' * all special symbols can be customized +'' +'' +''************************** +''* FORMAT SYNTAX * +''************************** +'' +''The Format parameter of ToStr() and FromStr() is a 22-bit value indicating the desired output or input format. Custom values can be used for the Format +''parameter, however, a series of pre-defined constants for common formats as well as each of the elemental building blocks have already been defined by this +''object. These pre-defined constants are listed below, followed by a detailed explanation of the syntax of the Format parameter. +'' +''┌────────────────────────────────────────────────────────────────────────────────────────┐ ┌───────────────────────────────────────┐ +''│ COMMON FORMAT CONSTANTS │ │ Working Examples │ +''├─────────────────────┬───────────┬────────────┬─────────┬─────────────┬─────────────────┤ ├────────────┬────────┬─────────────────┤ +''│ CONSTANT │ INDICATED │ DELIMITING │ PADDING │ BASE │ WIDTH │ │ Long Value │ Format │ String Result │ +''│ │ BASE │ │ │ │ (incl. symbols) │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DEC │ -1234 │ +''│ BIN │ │ │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ DEC │ 1234 │ +''│ IBIN │ % │ │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ HEX │ 4D2 │ +''│ DBIN │ │ Underscore │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ IHEX │ -$4D2 │ +''│ IDBIN │ % │ Underscore │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ BIN │ 10011010010 │ +''│ BIN2..BIN33 │ │ │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ IBIN │ -%10011010010 │ +''│ IBIN3..IBIN34 │ % │ │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ DDEC │ 1,234 │ +''│ DBIN7..DBIN40 │ │ Underscore │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DDEC8 │ -001,234 │ +''│ IDBIN8..IDBIN41 │ % │ Underscore │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DSDEC8 │ -1,234 │ +''│ SBIN3..SBIN33 │ │ │ Space │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ DBIN │ 100_1101_0010 │ +''│ ISBIN4..ISBIN34 │ % │ │ Space │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DBIN15 │ -0100_1101_0010 │ +''│ DSBIN7..DSBIN40 │ │ Underscore │ Space │ Binary │ Fixed │ └────────────┴────────┴─────────────────┘ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ *Note: In these examples, all positive +''│ IDSBIN8..IDSBIN41 │ % │ Underscore │ Space │ Binary │ Fixed │ values' output strings have a space +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ for the sign character. Don't forget +''│ DEC │ │ │ │ Decimal │ Variable │ that fact when sizing string buffer +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ or otherwise using result. +''│ DDEC │ │ Comma │ │ Decimal │ Variable │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ DEC2..DEC11 │ │ │ Zero │ Decimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ SDEC3..SDEC11 │ │ │ Space │ Decimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ DSDEC6..DSDEC14 │ │ Comma │ Space │ Decimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ HEX │ │ │ │ Hexadecimal │ Variable │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ IHEX │ $ │ │ │ Hexadecimal │ Variable │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ DHEX │ │ Underscore │ │ Hexadecimal │ Variable │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ IDHEX │ $ │ Underscore │ │ Hexadecimal │ Variable │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ HEX2..HEX9 │ │ │ Zero │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ IHEX3..IHEX10 │ $ │ │ Zero │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ DHEX7..DHEX10 │ │ Underscore │ Zero │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ IDHEX8..IDHEX11 │ $ │ Underscore │ Zero │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ SHEX3..SHEX9 │ │ │ Space │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ ISHEX4..ISHEX10 │ $ │ │ Space │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ DSHEX7..DSHEX10 │ │ Underscore │ Space │ Hexadecimal │ Fixed │ +''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ +''│ IDSHEX8..IDSHEX11 │ $ │ Underscore │ Space │ Hexadecimal │ Fixed │ +''└─────────────────────┴───────────┴────────────┴─────────┴─────────────┴─────────────────┘ +'' +'' +''If the desired format was not already defined by the Common Format Constants, above, you may use the following constants as building blocks to create +''the customer format you need. +'' +''┌─────────────────────────────────────────────────────┐ +''│ FORMAT CONSTANT "BUILDING BLOCKS" │ +''│ (use these if no equivelant common format exisits) │ +''├────────────────────┬────────────────────────────────┤ +''│ CONSTANT │ DESCRIPTION │ +''├────────────────────┼────────────────────────────────┤ +''│ BIN, DEC or HEX │ Binary, Decimal or Hexadecimal │ +''├────────────────────┼────────────────────────────────┤ +''│ CHAR1..CHAR48 │ Field Width (includes symbols) │ +''├────────────────────┼────────────────────────────────┤ +''│ / SPCPAD │ Zero / Space Pad │ +''├────────────────────┼────────────────────────────────┤ +''│ / PLUS │ Hide / Show Plus │ +''├────────────────────┼────────────────────────────────┤ +''│ COMMA, USCORE │ Group Character │ +''├────────────────────┼────────────────────────────────┤ +''│ GROUP2..GROUP8 │ Group Size │ +''├────────────────────┼────────────────────────────────┤ +''│ BINCHAR or HEXCHAR │ Indicator Character │ +''└────────────────────┴────────────────────────────────┘ +'' +'' +''The detailed syntax of the Format parameter is described below. +'' +''There are 7 elements of the Format parameter: +'' 1) Base, +'' 2) Field Width, +'' 3) Zero/Space Padding, +'' 4) Hide/Show Plus Sign, +'' 5) Grouping Character ID, +'' 6) Digit Group Size, +'' 7) Indicator Character +''Only the Base element is required, all others are optional. +'' +''The 22-bit syntax is as follows: +'' +'' III ZZZ GGG P S FFFFFF BBBBB +'' +''I : Indicator Character ID (0-7). 0 = no indicator character, 1 = Comma, 2 = Underscore, 3 = Dollar Sign, 4 = Percent Sign, etc., as defined by default Init; may be customized via call to Config(). +''Z : Digit Group Size (0-7). 0 = no digit group characters, 1 = every 2 chars, 2 = every 3 chars, etc. +''G : Grouping Character ID (0-7). 0 or 1 = Comma, 2 = Underscore, etc., as defined by default Init; may be customized via call to Config(). +''P : Hide/Show Plus Sign (0-1). For Num values > 0, sign char is: ' ' (if P = 0), or '+' (if P = 1). +''S : Zero/Space Pad (0-1). [Ignored unless Field Width > 0]. 0 = left pad with zeros (left justified), 1 = left pad with spaces (right justified). +''F : Field Width (0-48). String field width, including sign character and any special characters (not including zero terminator). +''B : Base (2-16). Base to convert number to; 2 = binary, 10 = decimal, 16 = hexadecimal, etc. This element is required. +'' +''Examples: +'' +''Conversion to variable-width decimal value: +'' Use Format of: %000_000_000_0_0_000000_01010, or simply %1010 (decimal 10). +'' +''Conversion to 5-character wide, fixed-width hexadecimal value (left padded with zeros): +'' Use Format of: %000_000_000_0_0_000101_10000 +'' +''Conversion to 5-character wide, fixed-width hexadecimal value (left padded with spaces): +'' Use Format of: %000_000_000_0_1_000101_10000 +'' +''Conversion to variable-width decimal value comma-separated at thousands: +'' Use Format of: %000_010_001_0_0_000000_01010 +'' +''Conversion to Indicated, 6-character wide, fixed-width hexadecimal value (left padded with spaces): +'' Use Format of: %011_000_000_0_1_000110_10000 +'' +''For convenience and code readability, a number of pre-defined symbolic constants are included that can be added together for any format +''combination imaginable. See "FORMAT CONSTANT 'BUILDING BLOCKS'", above. For example, using these constants, the above example format values become +''the following, respectively: +'' DEC +'' HEX+CHAR5 +'' HEX+CHAR5+SPCPAD +'' DEC+GROUP3+COMMA +'' HEX+CHAR6+HEXCHAR+SPCPAD +'' +'' +''┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +''│ 32-Bit Statistics for Bases 2 to 16 │ +''├──────┬────────────┬────────────────────────────────────────────────────────────────────────────┬───────────────────┤ +''│ Base │ Max Digits │ Range (Signed) │ Range Is Shown │ +''│ │ w/o symbols│ Minimum │ Maximum │ Grouped By │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 2 │ 32 │ -10000000_00000000_00000000_00000000 │ +1111111_11111111_11111111_11111111 │ Bytes (exact) │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 3 │ 20 │ -12112_12221_21102_02102 │ +12112_12221_21102_02101 │ Bytes │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 4 │ 16 │ -2000_0000_0000_0000 │ +1333_3333_3333_3333 │ Bytes (exact) │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 5 │ 14 │ -13_344223_434043 │ +13_344223_434042 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 6 │ 12 │ -553032_005532 │ +553032_005531 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 7 │ 12 │ -10_41342_11162 │ +10_41342_11161 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 8 │ 11 │ -2_00000_00000 │ +1_77777_77777 │ Words (15 bits) │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 9 │ 10 │ -54787_73672 │ +54787_73671 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 10 │ 10 │ -2,147,483,648 │ +2,147,483,647 │ Thousands (exact) │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 11 │ 9 │ -A_0222_0282 │ +A_0222_0281 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 12 │ 9 │ -4_BB23_08A8 │ +4_BB23_08A7 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 13 │ 9 │ -2_82BA_4AAB │ +2_82BA_4AAA │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 14 │ 9 │ -1_652C_A932 │ +1_652C_A931 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 15 │ 8 │ -C87D_66B8 │ +C87D_66B7 │ Words │ +''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤ +''│ 16 │ 8 │ -8000_0000 │ +7FFF_FFFF │ Words (exact) │ +''└──────┴────────────┴──────────────────────────────────────┴─────────────────────────────────────┴───────────────────┘ + + + +CON +'┌──────────────────────────────────────────┐ +'│ Format "Building Blocks" │ +'└──────────────────────────────────────────┘ +' III ZZZ GGG P S FFFFFF BBBBB + CHAR2 = %000_000_000_0_0_000010_00000 'Fixed Width (includes sign and special symbols) + CHAR3 = %000_000_000_0_0_000011_00000 + CHAR4 = %000_000_000_0_0_000100_00000 + CHAR5 = %000_000_000_0_0_000101_00000 + CHAR6 = %000_000_000_0_0_000110_00000 + CHAR7 = %000_000_000_0_0_000111_00000 + CHAR8 = %000_000_000_0_0_001000_00000 + CHAR9 = %000_000_000_0_0_001001_00000 + CHAR10 = %000_000_000_0_0_001010_00000 + CHAR11 = %000_000_000_0_0_001011_00000 + CHAR12 = %000_000_000_0_0_001100_00000 + CHAR13 = %000_000_000_0_0_001101_00000 + CHAR14 = %000_000_000_0_0_001110_00000 + CHAR15 = %000_000_000_0_0_001111_00000 + CHAR16 = %000_000_000_0_0_010000_00000 + CHAR17 = %000_000_000_0_0_010001_00000 + CHAR18 = %000_000_000_0_0_010010_00000 + CHAR19 = %000_000_000_0_0_010011_00000 + CHAR20 = %000_000_000_0_0_010100_00000 + CHAR21 = %000_000_000_0_0_010101_00000 + CHAR22 = %000_000_000_0_0_010110_00000 + CHAR23 = %000_000_000_0_0_010111_00000 + CHAR24 = %000_000_000_0_0_011000_00000 + CHAR25 = %000_000_000_0_0_011001_00000 + CHAR26 = %000_000_000_0_0_011010_00000 + CHAR27 = %000_000_000_0_0_011011_00000 + CHAR28 = %000_000_000_0_0_011100_00000 + CHAR29 = %000_000_000_0_0_011101_00000 + CHAR30 = %000_000_000_0_0_011110_00000 + CHAR31 = %000_000_000_0_0_011111_00000 + CHAR32 = %000_000_000_0_0_100000_00000 + CHAR33 = %000_000_000_0_0_100001_00000 + CHAR34 = %000_000_000_0_0_100010_00000 + CHAR35 = %000_000_000_0_0_100011_00000 + CHAR36 = %000_000_000_0_0_100100_00000 + CHAR37 = %000_000_000_0_0_100101_00000 + CHAR38 = %000_000_000_0_0_100110_00000 + CHAR39 = %000_000_000_0_0_100111_00000 + CHAR40 = %000_000_000_0_0_101000_00000 + CHAR41 = %000_000_000_0_0_101001_00000 + CHAR42 = %000_000_000_0_0_101010_00000 + CHAR43 = %000_000_000_0_0_101011_00000 + CHAR44 = %000_000_000_0_0_101100_00000 + CHAR45 = %000_000_000_0_0_101101_00000 + CHAR46 = %000_000_000_0_0_101110_00000 + CHAR47 = %000_000_000_0_0_101111_00000 + CHAR48 = %000_000_000_0_0_110000_00000 + CHAR49 = %000_000_000_0_0_110001_00000 + + SPCPAD = %000_000_000_0_1_000000_00000 'Space padded + + PLUS = %000_000_000_1_0_000000_00000 'Show plus sign '+' for num > 0 + + COMMA = %000_000_001_0_0_000000_00000 'Comma delimiter + USCORE = %000_000_010_0_0_000000_00000 'Underscore delimiter + + HEXCHAR = %011_000_000_0_0_000000_00000 'Hexadecimal prefix '$' + BINCHAR = %100_000_000_0_0_000000_00000 'Binary prefix '%' + + GROUP2 = %000_001_000_0_0_000000_00000 'Group digits + GROUP3 = %000_010_000_0_0_000000_00000 + GROUP4 = %000_011_000_0_0_000000_00000 + GROUP5 = %000_100_000_0_0_000000_00000 + GROUP6 = %000_101_000_0_0_000000_00000 + GROUP7 = %000_110_000_0_0_000000_00000 + GROUP8 = %000_111_000_0_0_000000_00000 + + +'┌──────────────────────────────────────────┐ +'│ Common Decimal Formatters │ +'└──────────────────────────────────────────┘ + + DEC = %000_000_000_0_0_000000_01010 'Decimal, variable widths + + DDEC = DEC+GROUP3+COMMA 'Decimal, variable widths, delimited with commas + + DEC2 = DEC+CHAR2 'Decimal, fixed widths, zero padded + DEC3 = DEC+CHAR3 + DEC4 = DEC+CHAR4 + DEC5 = DEC+CHAR5 + DEC6 = DEC+CHAR6 + DEC7 = DEC+CHAR7 + DEC8 = DEC+CHAR8 + DEC9 = DEC+CHAR9 + DEC10 = DEC+CHAR10 + DEC11 = DEC+CHAR11 + + SDEC3 = DEC3+SPCPAD 'Decimal, fixed widths, space padded + SDEC4 = DEC4+SPCPAD + SDEC5 = DEC5+SPCPAD + SDEC6 = DEC6+SPCPAD + SDEC7 = DEC7+SPCPAD + SDEC8 = DEC8+SPCPAD + SDEC9 = DEC9+SPCPAD + SDEC10 = DEC10+SPCPAD + SDEC11 = DEC11+SPCPAD + + DSDEC6 = SDEC6+GROUP3+COMMA 'Decimal, fixed widths, space padded, delimited with commas + DSDEC7 = SDEC7+GROUP3+COMMA + DSDEC8 = SDEC8+GROUP3+COMMA + DSDEC9 = SDEC9+GROUP3+COMMA + DSDEC10 = SDEC10+GROUP3+COMMA + DSDEC11 = SDEC11+GROUP3+COMMA + DSDEC12 = DEC+CHAR12+SPCPAD+GROUP3+COMMA + DSDEC13 = DEC+CHAR13+SPCPAD+GROUP3+COMMA + DSDEC14 = DEC+CHAR14+SPCPAD+GROUP3+COMMA + + +'┌──────────────────────────────────────────┐ +'│ Common Hexadecimal Formatters │ +'└──────────────────────────────────────────┘ + + HEX = %000_000_000_0_0_000000_10000 'Hexadecimal, variable widths + + DHEX = HEX+GROUP4+USCORE 'Hexadecimal, variable widths, delimited with underscore + + HEX2 = HEX+CHAR2 'Hexadecimal, fixed widths, zero padded + HEX3 = HEX+CHAR3 + HEX4 = HEX+CHAR4 + HEX5 = HEX+CHAR5 + HEX6 = HEX+CHAR6 + HEX7 = HEX+CHAR7 + HEX8 = HEX+CHAR8 + HEX9 = HEX+CHAR9 + + SHEX3 = HEX3+SPCPAD 'Hexadecimal, fixed widths, space padded + SHEX4 = HEX4+SPCPAD + SHEX5 = HEX5+SPCPAD + SHEX6 = HEX6+SPCPAD + SHEX7 = HEX7+SPCPAD + SHEX8 = HEX8+SPCPAD + SHEX9 = HEX9+SPCPAD + + DHEX7 = HEX7+GROUP4+USCORE 'Hexadecimal, fixed widths, zero padded, delimited with underscore + DHEX8 = HEX8+GROUP4+USCORE + DHEX9 = HEX9+GROUP4+USCORE + DHEX10 = HEX+CHAR10+GROUP4+USCORE + + DSHEX7 = DHEX7+SPCPAD 'Hexadecimal, fixed widths, space padded, delimited with underscore + DSHEX8 = DHEX8+SPCPAD + DSHEX9 = DHEX9+SPCPAD + DSHEX10 = DHEX10+SPCPAD + + IHEX = HEX+HEXCHAR 'Indicated hexadecimal, variable widths + + IDHEX = DHEX+HEXCHAR 'Indicated hexadecimal, variable widths, delimited with underscore + + IHEX3 = HEX3+HEXCHAR 'Indicated hexadecimal, fixed widths, zero padded + IHEX4 = HEX4+HEXCHAR + IHEX5 = HEX5+HEXCHAR + IHEX6 = HEX6+HEXCHAR + IHEX7 = HEX7+HEXCHAR + IHEX8 = HEX8+HEXCHAR + IHEX9 = HEX9+HEXCHAR + IHEX10 = HEX+CHAR10+HEXCHAR + + ISHEX4 = SHEX4+HEXCHAR 'Indicated hexadecimal, fixed widths, space padded + ISHEX5 = SHEX5+HEXCHAR + ISHEX6 = SHEX6+HEXCHAR + ISHEX7 = SHEX7+HEXCHAR + ISHEX8 = SHEX8+HEXCHAR + ISHEX9 = SHEX9+HEXCHAR + ISHEX10 = HEX+CHAR10+SPCPAD+HEXCHAR + + IDHEX8 = DHEX8+HEXCHAR 'Indicated hexadecimal, fixed widths, zero padded, delimited with underscore + IDHEX9 = DHEX9+HEXCHAR + IDHEX10 = DHEX10+HEXCHAR + IDHEX11 = HEX+CHAR11+GROUP4+USCORE+HEXCHAR + + IDSHEX8 = DSHEX8+HEXCHAR 'Indicated hexadecimal, fixed widths, space padded, delimited with underscore + IDSHEX9 = DSHEX9+HEXCHAR + IDSHEX10 = DSHEX10+HEXCHAR + IDSHEX11 = HEX+CHAR11+GROUP4+USCORE+HEXCHAR + +'┌──────────────────────────────────────────┐ +'│ Common Binary Formatters │ +'└──────────────────────────────────────────┘ + + BIN = %000_000_000_0_0_000000_00010 'Binary, variable widths + + DBIN = BIN+GROUP4+USCORE 'Binary, variable widths, delimited with underscores + + BIN2 = BIN+CHAR2 'Binary, fixed widths, zero padded + BIN3 = BIN+CHAR3 + BIN4 = BIN+CHAR4 + BIN5 = BIN+CHAR5 + BIN6 = BIN+CHAR6 + BIN7 = BIN+CHAR7 + BIN8 = BIN+CHAR8 + BIN9 = BIN+CHAR9 + BIN10 = BIN+CHAR10 + BIN11 = BIN+CHAR11 + BIN12 = BIN+CHAR12 + BIN13 = BIN+CHAR13 + BIN14 = BIN+CHAR14 + BIN15 = BIN+CHAR15 + BIN16 = BIN+CHAR16 + BIN17 = BIN+CHAR17 + BIN18 = BIN+CHAR18 + BIN19 = BIN+CHAR19 + BIN20 = BIN+CHAR20 + BIN21 = BIN+CHAR21 + BIN22 = BIN+CHAR22 + BIN23 = BIN+CHAR23 + BIN24 = BIN+CHAR24 + BIN25 = BIN+CHAR25 + BIN26 = BIN+CHAR26 + BIN27 = BIN+CHAR27 + BIN28 = BIN+CHAR28 + BIN29 = BIN+CHAR29 + BIN30 = BIN+CHAR30 + BIN31 = BIN+CHAR31 + BIN32 = BIN+CHAR32 + BIN33 = BIN+CHAR33 + + SBIN3 = BIN3+SPCPAD 'Binary, fixed widths, space padded + SBIN4 = BIN4+SPCPAD + SBIN5 = BIN5+SPCPAD + SBIN6 = BIN6+SPCPAD + SBIN7 = BIN7+SPCPAD + SBIN8 = BIN8+SPCPAD + SBIN9 = BIN9+SPCPAD + SBIN10 = BIN10+SPCPAD + SBIN11 = BIN11+SPCPAD + SBIN12 = BIN12+SPCPAD + SBIN13 = BIN13+SPCPAD + SBIN14 = BIN14+SPCPAD + SBIN15 = BIN15+SPCPAD + SBIN16 = BIN16+SPCPAD + SBIN17 = BIN17+SPCPAD + SBIN18 = BIN18+SPCPAD + SBIN19 = BIN19+SPCPAD + SBIN20 = BIN20+SPCPAD + SBIN21 = BIN21+SPCPAD + SBIN22 = BIN22+SPCPAD + SBIN23 = BIN23+SPCPAD + SBIN24 = BIN24+SPCPAD + SBIN25 = BIN25+SPCPAD + SBIN26 = BIN26+SPCPAD + SBIN27 = BIN27+SPCPAD + SBIN28 = BIN28+SPCPAD + SBIN29 = BIN29+SPCPAD + SBIN30 = BIN30+SPCPAD + SBIN31 = BIN31+SPCPAD + SBIN32 = BIN32+SPCPAD + SBIN33 = BIN33+SPCPAD + + DBIN7 = BIN7+GROUP4+USCORE 'Binary, fixed widths, zero padded, delimited with underscores + DBIN8 = BIN8+GROUP4+USCORE + DBIN9 = BIN9+GROUP4+USCORE + DBIN10 = BIN10+GROUP4+USCORE + DBIN11 = BIN11+GROUP4+USCORE + DBIN12 = BIN12+GROUP4+USCORE + DBIN13 = BIN13+GROUP4+USCORE + DBIN14 = BIN14+GROUP4+USCORE + DBIN15 = BIN15+GROUP4+USCORE + DBIN16 = BIN16+GROUP4+USCORE + DBIN17 = BIN17+GROUP4+USCORE + DBIN18 = BIN18+GROUP4+USCORE + DBIN19 = BIN19+GROUP4+USCORE + DBIN20 = BIN20+GROUP4+USCORE + DBIN21 = BIN21+GROUP4+USCORE + DBIN22 = BIN22+GROUP4+USCORE + DBIN23 = BIN23+GROUP4+USCORE + DBIN24 = BIN24+GROUP4+USCORE + DBIN25 = BIN25+GROUP4+USCORE + DBIN26 = BIN26+GROUP4+USCORE + DBIN27 = BIN27+GROUP4+USCORE + DBIN28 = BIN28+GROUP4+USCORE + DBIN29 = BIN29+GROUP4+USCORE + DBIN30 = BIN30+GROUP4+USCORE + DBIN31 = BIN31+GROUP4+USCORE + DBIN32 = BIN32+GROUP4+USCORE + DBIN33 = BIN33+GROUP4+USCORE + DBIN34 = BIN+CHAR34+GROUP4+USCORE + DBIN35 = BIN+CHAR35+GROUP4+USCORE + DBIN36 = BIN+CHAR36+GROUP4+USCORE + DBIN37 = BIN+CHAR37+GROUP4+USCORE + DBIN38 = BIN+CHAR38+GROUP4+USCORE + DBIN39 = BIN+CHAR39+GROUP4+USCORE + DBIN40 = BIN+CHAR40+GROUP4+USCORE + + DSBIN7 = DBIN7+SPCPAD 'Binary, fixed widths, space padded, delimited with underscores + DSBIN8 = DBIN8+SPCPAD + DSBIN9 = DBIN9+SPCPAD + DSBIN10 = DBIN10+SPCPAD + DSBIN11 = DBIN11+SPCPAD + DSBIN12 = DBIN12+SPCPAD + DSBIN13 = DBIN13+SPCPAD + DSBIN14 = DBIN14+SPCPAD + DSBIN15 = DBIN15+SPCPAD + DSBIN16 = DBIN16+SPCPAD + DSBIN17 = DBIN17+SPCPAD + DSBIN18 = DBIN18+SPCPAD + DSBIN19 = DBIN19+SPCPAD + DSBIN20 = DBIN20+SPCPAD + DSBIN21 = DBIN21+SPCPAD + DSBIN22 = DBIN22+SPCPAD + DSBIN23 = DBIN23+SPCPAD + DSBIN24 = DBIN24+SPCPAD + DSBIN25 = DBIN25+SPCPAD + DSBIN26 = DBIN26+SPCPAD + DSBIN27 = DBIN27+SPCPAD + DSBIN28 = DBIN28+SPCPAD + DSBIN29 = DBIN29+SPCPAD + DSBIN30 = DBIN30+SPCPAD + DSBIN31 = DBIN31+SPCPAD + DSBIN32 = DBIN32+SPCPAD + DSBIN33 = DBIN33+SPCPAD + DSBIN34 = DBIN34+SPCPAD + DSBIN35 = DBIN35+SPCPAD + DSBIN36 = DBIN36+SPCPAD + DSBIN37 = DBIN37+SPCPAD + DSBIN38 = DBIN38+SPCPAD + DSBIN39 = DBIN39+SPCPAD + DSBIN40 = DBIN40+SPCPAD + + IBIN = BIN+BINCHAR 'Indicated binary, variable widths + + IDBIN = DBIN+BINCHAR 'Indicated binary, variable widths, delimited with underscores + + IBIN3 = BIN3+BINCHAR 'Indicated binary, fixed widths, zero padded + IBIN4 = BIN4+BINCHAR + IBIN5 = BIN5+BINCHAR + IBIN6 = BIN6+BINCHAR + IBIN7 = BIN7+BINCHAR + IBIN8 = BIN8+BINCHAR + IBIN9 = BIN9+BINCHAR + IBIN10 = BIN10+BINCHAR + IBIN11 = BIN11+BINCHAR + IBIN12 = BIN12+BINCHAR + IBIN13 = BIN13+BINCHAR + IBIN14 = BIN14+BINCHAR + IBIN15 = BIN15+BINCHAR + IBIN16 = BIN16+BINCHAR + IBIN17 = BIN17+BINCHAR + IBIN18 = BIN18+BINCHAR + IBIN19 = BIN19+BINCHAR + IBIN20 = BIN20+BINCHAR + IBIN21 = BIN21+BINCHAR + IBIN22 = BIN22+BINCHAR + IBIN23 = BIN23+BINCHAR + IBIN24 = BIN24+BINCHAR + IBIN25 = BIN25+BINCHAR + IBIN26 = BIN26+BINCHAR + IBIN27 = BIN27+BINCHAR + IBIN28 = BIN28+BINCHAR + IBIN29 = BIN29+BINCHAR + IBIN30 = BIN30+BINCHAR + IBIN31 = BIN31+BINCHAR + IBIN32 = BIN32+BINCHAR + IBIN33 = BIN33+BINCHAR + IBIN34 = BIN+CHAR34+BINCHAR + + ISBIN4 = SBIN4+BINCHAR 'Indicated binary, fixed widths, space padded + ISBIN5 = SBIN5+BINCHAR + ISBIN6 = SBIN6+BINCHAR + ISBIN7 = SBIN7+BINCHAR + ISBIN8 = SBIN8+BINCHAR + ISBIN9 = SBIN9+BINCHAR + ISBIN10 = SBIN10+BINCHAR + ISBIN11 = SBIN11+BINCHAR + ISBIN12 = SBIN12+BINCHAR + ISBIN13 = SBIN13+BINCHAR + ISBIN14 = SBIN14+BINCHAR + ISBIN15 = SBIN15+BINCHAR + ISBIN16 = SBIN16+BINCHAR + ISBIN17 = SBIN17+BINCHAR + ISBIN18 = SBIN18+BINCHAR + ISBIN19 = SBIN19+BINCHAR + ISBIN20 = SBIN20+BINCHAR + ISBIN21 = SBIN21+BINCHAR + ISBIN22 = SBIN22+BINCHAR + ISBIN23 = SBIN23+BINCHAR + ISBIN24 = SBIN24+BINCHAR + ISBIN25 = SBIN25+BINCHAR + ISBIN26 = SBIN26+BINCHAR + ISBIN27 = SBIN27+BINCHAR + ISBIN28 = SBIN28+BINCHAR + ISBIN29 = SBIN29+BINCHAR + ISBIN30 = SBIN30+BINCHAR + ISBIN31 = SBIN31+BINCHAR + ISBIN32 = SBIN32+BINCHAR + ISBIN33 = SBIN33+BINCHAR + ISBIN34 = BIN+CHAR34+SPCPAD+BINCHAR + + IDBIN8 = DBIN8+BINCHAR 'Indicated binary, fixed widths, zero padded, delimited with underscores + IDBIN9 = DBIN9+BINCHAR + IDBIN10 = DBIN10+BINCHAR + IDBIN11 = DBIN11+BINCHAR + IDBIN12 = DBIN12+BINCHAR + IDBIN13 = DBIN13+BINCHAR + IDBIN14 = DBIN14+BINCHAR + IDBIN15 = DBIN15+BINCHAR + IDBIN16 = DBIN16+BINCHAR + IDBIN17 = DBIN17+BINCHAR + IDBIN18 = DBIN18+BINCHAR + IDBIN19 = DBIN19+BINCHAR + IDBIN20 = DBIN20+BINCHAR + IDBIN21 = DBIN21+BINCHAR + IDBIN22 = DBIN22+BINCHAR + IDBIN23 = DBIN23+BINCHAR + IDBIN24 = DBIN24+BINCHAR + IDBIN25 = DBIN25+BINCHAR + IDBIN26 = DBIN26+BINCHAR + IDBIN27 = DBIN27+BINCHAR + IDBIN28 = DBIN28+BINCHAR + IDBIN29 = DBIN29+BINCHAR + IDBIN30 = DBIN30+BINCHAR + IDBIN31 = DBIN31+BINCHAR + IDBIN32 = DBIN32+BINCHAR + IDBIN33 = DBIN33+BINCHAR + IDBIN34 = DBIN34+BINCHAR + IDBIN35 = DBIN35+BINCHAR + IDBIN36 = DBIN36+BINCHAR + IDBIN37 = DBIN37+BINCHAR + IDBIN38 = DBIN38+BINCHAR + IDBIN39 = DBIN39+BINCHAR + IDBIN40 = DBIN40+BINCHAR + IDBIN41 = BIN+CHAR41+GROUP4+USCORE+BINCHAR + + IDSBIN8 = DSBIN8+BINCHAR 'Indicated binary, fixed widths, space padded, delimited with underscores + IDSBIN9 = DSBIN9+BINCHAR + IDSBIN10 = DSBIN10+BINCHAR + IDSBIN11 = DSBIN11+BINCHAR + IDSBIN12 = DSBIN12+BINCHAR + IDSBIN13 = DSBIN13+BINCHAR + IDSBIN14 = DSBIN14+BINCHAR + IDSBIN15 = DSBIN15+BINCHAR + IDSBIN16 = DSBIN16+BINCHAR + IDSBIN17 = DSBIN17+BINCHAR + IDSBIN18 = DSBIN18+BINCHAR + IDSBIN19 = DSBIN19+BINCHAR + IDSBIN20 = DSBIN20+BINCHAR + IDSBIN21 = DSBIN21+BINCHAR + IDSBIN22 = DSBIN22+BINCHAR + IDSBIN23 = DSBIN23+BINCHAR + IDSBIN24 = DSBIN24+BINCHAR + IDSBIN25 = DSBIN25+BINCHAR + IDSBIN26 = DSBIN26+BINCHAR + IDSBIN27 = DSBIN27+BINCHAR + IDSBIN28 = DSBIN28+BINCHAR + IDSBIN29 = DSBIN29+BINCHAR + IDSBIN30 = DSBIN30+BINCHAR + IDSBIN31 = DSBIN31+BINCHAR + IDSBIN32 = DSBIN32+BINCHAR + IDSBIN33 = DSBIN33+BINCHAR + IDSBIN34 = DSBIN34+BINCHAR + IDSBIN35 = DSBIN35+BINCHAR + IDSBIN36 = DSBIN36+BINCHAR + IDSBIN37 = DSBIN37+BINCHAR + IDSBIN38 = DSBIN38+BINCHAR + IDSBIN39 = DSBIN39+BINCHAR + IDSBIN40 = DSBIN40+BINCHAR + IDSBIN41 = BIN+CHAR41+SPCPAD+GROUP4+USCORE+BINCHAR + + + +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/glob-pst.spin b/lib/glob-pst.spin new file mode 100644 index 0000000..aab7911 --- /dev/null +++ b/lib/glob-pst.spin @@ -0,0 +1,528 @@ +{{ +───────────────────────────────────────────────── +File: Parallax Serial Terminal.spin +Version: 1.0 +Copyright (c) 2009 Parallax, Inc. +See end of file for terms of use. + +Authors: Jeff Martin, Andy Lindsay, Chip Gracey +───────────────────────────────────────────────── +}} + +{ +HISTORY: + This object is made for direct use with the Parallax Serial Terminal; a simple serial communication program + available with the Propeller Tool installer and also separately via the Parallax website (www.parallax.com). + + This object is heavily based on FullDuplexSerialPlus (by Andy Lindsay), which is itself heavily based on + FullDuplexSerial (by Chip Gracey). + +USAGE: + • Call Start, or StartRxTx, first. + • Be sure to set the Parallax Serial Terminal software to the baudrate specified in Start, and the proper COM port. + • At 80 MHz, this object properly receives/transmits at up to 250 Kbaud, or performs transmit-only at up to 1 Mbaud. + +} + +CON +'' +'' Parallax Serial Terminal +'' Control Character Constants +''───────────────────────────────────── + CS = 16 ''CS: Clear Screen + CE = 11 ''CE: Clear to End of line + CB = 12 ''CB: Clear lines Below + + HM = 1 ''HM: HoMe cursor + PC = 2 ''PC: Position Cursor in x,y + PX = 14 ''PX: Position cursor in X + PY = 15 ''PY: Position cursor in Y + + NL = 13 ''NL: New Line + LF = 10 ''LF: Line Feed + ML = 3 ''ML: Move cursor Left + MR = 4 ''MR: Move cursor Right + MU = 5 ''MU: Move cursor Up + MD = 6 ''MD: Move cursor Down + TB = 9 ''TB: TaB + BS = 8 ''BS: BackSpace + + BP = 7 ''BP: BeeP speaker + +CON + + BUFFER_LENGTH = 64 'Recommended as 64 or higher, but can be 2, 4, 8, 16, 32, 64, 128 or 256. + BUFFER_MASK = BUFFER_LENGTH - 1 + MAXSTR_LENGTH = 49 'Maximum length of received numerical string (not including zero terminator). + +VAR + + long cog 'Cog flag/id + + long rx_head '9 contiguous longs (must keep order) + long rx_tail + long tx_head + long tx_tail + long rx_pin + long tx_pin + long rxtx_mode + long bit_ticks + long buffer_ptr + + byte rx_buffer[BUFFER_LENGTH] 'Receive and transmit buffers + byte tx_buffer[BUFFER_LENGTH] + + byte str_buffer[MAXSTR_LENGTH+1] 'String buffer for numerical strings + +PUB Start(baudrate) : okay +{{Start communication with the Parallax Serial Terminal using the Propeller's programming connection. +Waits 1 second for connection, then clears screen. + Parameters: + baudrate - bits per second. Make sure it matches the Parallax Serial Terminal's + Baud Rate field. + Returns : True (non-zero) if cog started, or False (0) if no cog is available.}} + + okay := StartRxTx(31, 30, 0, baudrate) + waitcnt(clkfreq + cnt) 'Wait 1 second for PST + Clear 'Clear display + +PUB StartRxTx(rxpin, txpin, mode, baudrate) : okay +{{Start serial communication with designated pins, mode, and baud. + Parameters: + rxpin - input pin; receives signals from external device's TX pin. + txpin - output pin; sends signals to external device's RX pin. + mode - signaling mode (4-bit pattern). + bit 0 - inverts rx. + bit 1 - inverts tx. + bit 2 - open drain/source tx. + bit 3 - ignore tx echo on rx. + baudrate - bits per second. + Returns : True (non-zero) if cog started, or False (0) if no cog is available.}} + + stop + longfill(@rx_head, 0, 4) + longmove(@rx_pin, @rxpin, 3) + bit_ticks := clkfreq / baudrate + buffer_ptr := @rx_buffer + okay := cog := cognew(@entry, @rx_head) + 1 + +PUB Stop +{{Stop serial communication; frees a cog.}} + + if cog + cogstop(cog~ - 1) + longfill(@rx_head, 0, 9) + +PUB Char(bytechr) +{{Send single-byte character. Waits for room in transmit buffer if necessary. + Parameter: + bytechr - character (ASCII byte value) to send.}} + + repeat until (tx_tail <> ((tx_head + 1) & BUFFER_MASK)) + tx_buffer[tx_head] := bytechr + tx_head := (tx_head + 1) & BUFFER_MASK + + if rxtx_mode & %1000 + CharIn + +PUB Chars(bytechr, count) +{{Send multiple copies of a single-byte character. Waits for room in transmit buffer if necessary. + Parameters: + bytechr - character (ASCII byte value) to send. + count - number of bytechrs to send.}} + + repeat count + Char(bytechr) + +PUB CharIn : bytechr +{{Receive single-byte character. Waits until character received. + Returns: $00..$FF}} + + repeat while (bytechr := RxCheck) < 0 + +PUB Str(stringptr) +{{Send zero terminated string. + Parameter: + stringptr - pointer to zero terminated string to send.}} + + repeat strsize(stringptr) + Char(byte[stringptr++]) + +PUB StrIn(stringptr) +{{Receive a string (carriage return terminated) and stores it (zero terminated) starting at stringptr. +Waits until full string received. + Parameter: + stringptr - pointer to memory in which to store received string characters. + Memory reserved must be large enough for all string characters plus a zero terminator.}} + + StrInMax(stringptr, -1) + +PUB StrInMax(stringptr, maxcount) +{{Receive a string of characters (either carriage return terminated or maxcount in length) and stores it (zero terminated) +starting at stringptr. Waits until either full string received or maxcount characters received. + Parameters: + stringptr - pointer to memory in which to store received string characters. + Memory reserved must be large enough for all string characters plus a zero terminator (maxcount + 1). + maxcount - maximum length of string to receive, or -1 for unlimited.}} + + repeat while (maxcount--) 'While maxcount not reached + if (byte[stringptr++] := CharIn) == NL 'Get chars until NL + quit + byte[stringptr+(byte[stringptr-1] == NL)]~ 'Zero terminate string; overwrite NL or append 0 char + +PUB Dec(value) | i, x +{{Send value as decimal characters. + Parameter: + value - byte, word, or long value to send as decimal characters.}} + + x := value == NEGX 'Check for max negative + if value < 0 + value := ||(value+x) 'If negative, make positive; adjust for max negative + Char("-") 'and output sign + + i := 1_000_000_000 'Initialize divisor + + repeat 10 'Loop for 10 digits + if value => i + Char(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative + value //= i 'and digit from value + result~~ 'flag non-zero found + elseif result or i == 1 + Char("0") 'If zero digit (or only digit) output it + i /= 10 'Update divisor + +PUB DecIn : value +{{Receive carriage return terminated string of characters representing a decimal value. + Returns: the corresponding decimal value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 10) + +PUB Bin(value, digits) +{{Send value as binary characters up to digits in length. + Parameters: + value - byte, word, or long value to send as binary characters. + digits - number of binary digits to send. Will be zero padded if necessary.}} + + value <<= 32 - digits + repeat digits + Char((value <-= 1) & 1 + "0") + +PUB BinIn : value +{{Receive carriage return terminated string of characters representing a binary value. + Returns: the corresponding binary value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 2) + +PUB Hex(value, digits) +{{Send value as hexadecimal characters up to digits in length. + Parameters: + value - byte, word, or long value to send as hexadecimal characters. + digits - number of hexadecimal digits to send. Will be zero padded if necessary.}} + + value <<= (8 - digits) << 2 + repeat digits + Char(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + +PUB HexIn : value +{{Receive carriage return terminated string of characters representing a hexadecimal value. + Returns: the corresponding hexadecimal value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 16) + +PUB Clear +{{Clear screen and place cursor at top-left.}} + + Char(CS) + +PUB ClearEnd +{{Clear line from cursor to end of line.}} + + Char(CE) + +PUB ClearBelow +{{Clear all lines below cursor.}} + + Char(CB) + +PUB Home +{{Send cursor to home position (top-left).}} + + Char(HM) + +PUB Position(x, y) +{{Position cursor at column x, row y (from top-left).}} + + Char(PC) + Char(x) + Char(y) + +PUB PositionX(x) +{{Position cursor at column x of current row.}} + Char(PX) + Char(x) + +PUB PositionY(y) +{{Position cursor at row y of current column.}} + Char(PY) + Char(y) + +PUB NewLine +{{Send cursor to new line (carriage return plus line feed).}} + + Char(NL) + +PUB LineFeed +{{Send cursor down to next line.}} + + Char(LF) + +PUB MoveLeft(x) +{{Move cursor left x characters.}} + + repeat x + Char(ML) + +PUB MoveRight(x) +{{Move cursor right x characters.}} + + repeat x + Char(MR) + +PUB MoveUp(y) +{{Move cursor up y lines.}} + + repeat y + Char(MU) + +PUB MoveDown(y) +{{Move cursor down y lines.}} + + repeat y + Char(MD) + +PUB Tab +{{Send cursor to next tab position.}} + + Char(TB) + +PUB Backspace +{{Delete one character to left of cursor and move cursor there.}} + + Char(BS) + +PUB Beep +{{Play bell tone on PC speaker.}} + + Char(BP) + +PUB RxCount : count +{{Get count of characters in receive buffer. + Returns: number of characters waiting in receive buffer.}} + + count := rx_head - rx_tail + count -= BUFFER_LENGTH*(count < 0) + +PUB RxFlush +{{Flush receive buffer.}} + + repeat while rxcheck => 0 + +PRI RxCheck : bytechr +{Check if character received; return immediately. + Returns: -1 if no byte received, $00..$FF if character received.} + + bytechr~~ + if rx_tail <> rx_head + bytechr := rx_buffer[rx_tail] + rx_tail := (rx_tail + 1) & BUFFER_MASK + +PRI StrToBase(stringptr, base) : value | chr, index +{Converts a zero terminated string representation of a number to a value in the designated base. +Ignores all non-digit characters (except negative (-) when base is decimal (10)).} + + value := index := 0 + repeat until ((chr := byte[stringptr][index++]) == 0) + chr := -15 + --chr & %11011111 + 39*(chr > 56) 'Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range + if (chr > -1) and (chr < base) 'Accumulate valid values into result; ignore others + value := value * base + chr + if (base == 10) and (byte[stringptr] == "-") 'If decimal, address negative sign; ignore otherwise + value := - value + +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org +' +' +' Entry +' +entry mov t1,par 'get structure address + add t1,#4 << 2 'skip past heads and tails + + rdlong t2,t1 'get rx_pin + mov rxmask,#1 + shl rxmask,t2 + + add t1,#4 'get tx_pin + rdlong t2,t1 + mov txmask,#1 + shl txmask,t2 + + add t1,#4 'get rxtx_mode + rdlong rxtxmode,t1 + + add t1,#4 'get bit_ticks + rdlong bitticks,t1 + + add t1,#4 'get buffer_ptr + rdlong rxbuff,t1 + mov txbuff,rxbuff + add txbuff,#BUFFER_LENGTH + + test rxtxmode,#%100 wz 'init tx pin according to mode + test rxtxmode,#%010 wc + if_z_ne_c or outa,txmask + if_z or dira,txmask + + mov txcode,#transmit 'initialize ping-pong multitasking +' +' +' Receive +' +receive jmpret rxcode,txcode 'run chunk of tx code, then return + + test rxtxmode,#%001 wz 'wait for start bit on rx pin + test rxmask,ina wc + if_z_eq_c jmp #receive + + mov rxbits,#9 'ready to receive byte + mov rxcnt,bitticks + shr rxcnt,#1 + add rxcnt,cnt + +:bit add rxcnt,bitticks 'ready next bit period + +:wait jmpret rxcode,txcode 'run chunk of tx code, then return + + mov t1,rxcnt 'check if bit receive period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + test rxmask,ina wc 'receive bit on rx pin + rcr rxdata,#1 + djnz rxbits,#:bit + + shr rxdata,#32-9 'justify and trim received byte + and rxdata,#$FF + test rxtxmode,#%001 wz 'if rx inverted, invert byte + if_nz xor rxdata,#$FF + + rdlong t2,par 'save received byte and inc head + add t2,rxbuff + wrbyte rxdata,t2 + sub t2,rxbuff + add t2,#1 + and t2,#BUFFER_MASK + wrlong t2,par + + jmp #receive 'byte done, receive next byte +' +' +' Transmit +' +transmit jmpret txcode,rxcode 'run chunk of rx code, then return + + mov t1,par 'check for head <> tail + add t1,#2 << 2 + rdlong t2,t1 + add t1,#1 << 2 + rdlong t3,t1 + cmp t2,t3 wz + if_z jmp #transmit + + add t3,txbuff 'get byte and inc tail + rdbyte txdata,t3 + sub t3,txbuff + add t3,#1 + and t3,#BUFFER_MASK + wrlong t3,t1 + + or txdata,#$100 'ready byte to transmit + shl txdata,#2 + or txdata,#1 + mov txbits,#11 + mov txcnt,cnt + +:bit test rxtxmode,#%100 wz 'output bit on tx pin + test rxtxmode,#%010 wc 'according to mode + if_z_and_c xor txdata,#1 + shr txdata,#1 wc + if_z muxc outa,txmask + if_nz muxnc dira,txmask + add txcnt,bitticks 'ready next cnt + +:wait jmpret txcode,rxcode 'run chunk of rx code, then return + + mov t1,txcnt 'check if bit transmit period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit 'another bit to transmit? + + jmp #transmit 'byte done, transmit next byte +' +' +' Uninitialized data +' +t1 res 1 +t2 res 1 +t3 res 1 + +rxtxmode res 1 +bitticks res 1 + +rxmask res 1 +rxbuff res 1 +rxdata res 1 +rxbits res 1 +rxcnt res 1 +rxcode res 1 + +txmask res 1 +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 +txcode res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this │ +│software and associated documentation files (the "Software"), to deal in the Software │ +│without restriction, including without limitation the rights to use, copy, modify, │ +│merge, publish, distribute, sublicense, and/or sell copies of the Software, and to │ +│permit persons to whom the Software is furnished to do so, subject to the following │ +│conditions: │ │ +│ │ │ +│The above copyright notice and this permission notice shall be included in all copies │ +│or substantial portions of the Software. │ +│ │ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, │ +│INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A │ +│PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT │ +│HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION │ +│OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │ +│SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/glob-sdspi.spin b/lib/glob-sdspi.spin new file mode 100644 index 0000000..8321b50 --- /dev/null +++ b/lib/glob-sdspi.spin @@ -0,0 +1,883 @@ +{{ +Modified Tiny Basic for use with Propeller Demo Board and Hydra. +I2C and SPI driver initialization & interface object derived from Propeller OS. + +Copyright (c) 2009 Michael Green. See end of file for terms of use. +}} + +'' 2006/09/24 - Corrected action table for i2cRead0Cmd +'' 2006/10/02 - Improved assembly comments. Changed i2cReset, i2cStop +'' 2006/11/02 - Changed data setup time. Changed i2cReset timing +'' 2006/11/03 - Changed read/write method speed to 100KHz +'' 2006/11/04 - Added checkPresence, writeWait, and computeTimes methods +'' 2006/11/06 - Limited boot loading to 32K - 16 (OS uses last 16 bytes) +'' Added ioVerifyCmd and verifyEEPROM method +'' 2006/11/09 - Modified boot and verify to use the minimum of the actual +'' length of the program stored in vbase ($0008) or the +'' specified byte count. +'' Note also that these routines don't know about option bits. +'' 2006/11/10 - Now control block address is passed to start routine +'' 2007/01/09 - Added SPI routines for SD card FAT access +'' 2007/01/13 - Corrected checksum when ioBoot or ioVerify +'' 2007/01/13 - Stores stack marker & clears VAR area on ioBootCmd +'' 2007/02/06 - Stores stack marker & clears VAR area on ioSpiBoot +'' 2007/02/13 - Changed the way verify mode was done, combined code +'' 2007/02/20 - Added ioStopLdr option to stop the loader's cog +'' 2007/02/22 - Corrected bootSDCard. Needs start and initSDCard calls first. +'' 2009/04/04 - spiDoStop modified per Cluso99 to turn off card +'' 2009/07/21 - I2C setup times modified per Nick Mueller's timing tests +'' Default I2C bus timing changed to 400KHz. Thanks Nick. + +'' This portion is normally run only once during initialization and the driver remains +'' resident in a cog. These routines can be used completely independently of the rest +'' of the Propeller OS. The start routine here expects the address of a 2 long area +'' to be used for passing information to the I/O routines in the COG. This area should +'' be located in an area of memory not expected to be overlaid by data or a program that +'' might be loaded since the COG routines will be accessing this information after an +'' operation has completed. + +'' This object provides an I2C EEPROM read/write routine that can handle both 100KHz and +'' 400KHz bus speeds and EEPROM page sizes of 64, 128, or 256 bytes (or no paging/no delay +'' as with Ramtron serial RAM). The SPIN interpreter can be started after reading, either +'' in the same COG used by these routines or in a free COG. The control information is +'' passed in a 2 long parameter block whose address is passed to the COG when it is started. +'' The parameter block is updated when the operation is completed. Note that these are shown +'' here as they appear in a long value rather than the order of the bytes in memory. + +'' ------------------------------------------------------------------- +'' | cmd/status | I/O pin / device / address | +'' ------------------------------------------------------------------- +'' | byte count | HUB address | +'' ------------------------------------------------------------------- + +'' The EEPROM address is in the same format used by other routines with the I/O pin pair +'' in bits 21..19, the device address in bits 18..16, and the 64K address in bits 15..0. +'' Note that the I/O pin pair is the number of the SCL pin divided by 2. The SDA pin is +'' always the next higher numbered pin. The command code is in the low order bits of the +'' high order byte of the first long (see ioCmdMask). This is always non-zero to indicate +'' that a command is to be performed by the COG routines. When the command is finished, +'' this is set to zero. The errorFlag bit is set to one if a NAK was read after a write +'' transfer. This is the only error reported by these routines. A read operation and +'' zero-length writes do involve several write transfers for addressing, but the data +'' read transfer has no error checking. When the command is completed, the device address, +'' byte count, and HUB address are all updated to their values at that time. For the +'' verify operation (ioVerifyCmd), an error is reported if the checksum is not zero and +'' the HUB address field is not incremented. It may be used for some other checksum +'' reporting in the future. + +'' The pins used for the boot EEPROM I2C bus (at least on Parallax's Demo Board) do not +'' have a pullup on SCL. This requires that SCL be driven both high and low. If the bus +'' used is on pins 28 and 29, SCL is actively driven at all times. + +'' These EEPROM read/write routines do not provide for waiting for the write to complete +'' nor do they check for paged writes. All bytes in a multi-byte write must lie within +'' a single EEPROM page since the EEPROM write address counter wraps around at a page +'' boundary. Similarly, for multi-byte reads, all requested bytes must lie within the +'' same device since the sequential read counter wraps around at the device boundary. + +'' Command codes are provided for devices with zero, one, or two address bytes following +'' the device selection byte. As for all I2C devices, addressing is done using write +'' mode and the device is reselected in read mode after the last address byte. In the +'' case of ioRead0Cmd, the device is initially selected in read mode. For 8-bit addresses, +'' the device select code is taken from bits 15-8 of the address value. For the case +'' without address bytes, the device select code is taken from bits 7-0 of the address value. +'' These device select codes must have their least significant bit set to zero (for write +'' mode) except in the case of ioRead0Cmd where it must be set to one for proper operation. + +'' SPI data is handled a little differently. For ioSpiInit, the 6 bit pin numbers for DO, +'' Clk, DI, and CS are given from MSB to LSB of the 24 bit address field of the command and +'' are used for all further I/O operations (until an ioSpiStop is done). + +CON +'' Command code and error information for I2C driver +'' (For convenience in using just OS_loaderInit, these are included here. The "master" +'' copies are considered the ones in OS_loader and these must be kept up-to-date). + + ioReadCmd = %00000001 ' Read from EEPROM to HUB RAM (16 bit addresses) + ioWriteCmd = %00000010 ' Write to EEPROM from HUB RAM (16 bit addresses) + ioRead1Cmd = %00000011 ' Read from a device with only 8-bit addresses + ioWrite1Cmd = %00000100 ' Write to a device with only 8-bit addresses + ioRead0Cmd = %00000101 ' Read from a device without address bytes + ioWrite0Cmd = %00000110 ' Write to a device without address bytes + ioBootCmd = %00001000 ' Read from EEPROM to HUB RAM, then start a + ' new SPIN interpreter in the COG whose ID is + ' supplied in the lower 3 bits of this command + ' This COG is stopped before the read is done + ' unless it's the one used to execute the loader + ioSpiInit = %00010000 ' Initialize the specified SPI bus and SD card + ioSpiStop = %00010001 ' Change all SD card pins to inputs + ioSpiRead = %00010010 ' Read one or more bytes from the SD card + ioSpiWrite = %00010011 ' Write one or more bytes from the SD card + ioSpiBoot = %00011000 ' Like ioBootCmd, but uses ioSpiRead for loading + ioCmdMask = %00011111 ' Used to mask off command bits + ioSpiMask = %00010000 ' Used to test for SPI command codes + +' Options for commands + + ioNoStore = %00100000 ' If set, data is not stored into main memory + ' If ioBootCmd or ioSpiBoot, no cogs are + ' stopped and a new cog is not started. + ioLowSpeed = %01000000 ' If set, I2C runs at 100KHz rather than 400KHz + ioStopLdr = %10000000 ' If set, the loader's cog is stopped after a boot + +' Return status + + ioWriteErr = %10000000 ' An error occurred during an I2C write (NAK) + + ioTestRdy = ioCmdMask << 24 ' Used to test 1st control long for ready + ioTestErr = ioWriteErr << 24 ' Used to test 1st control long for write error + +'' Other constants from OS_loader + + i2cBootSCL = 28 ' Boot EEPROM SCL pin + bootAddr = i2cBootSCL << 18 ' Address of boot EEPROM + clkfreqVal = $0000 ' Current CLKFREQ value stored here + clksetVal = $0004 ' Current CLKSET value stored here + chksumVal = $0005 ' Checksum over memory stored here + vbase = $0008 ' Length of Spin program loaded (# longs * 4) + dbase = $000A ' Address of start of stack (marker below) + +VAR + long cog, control + +PUB bootEEPROM(addr) | t, c0, c1 '' Load and run a new SPIN program + if not start(@c0) ' Start up the I/O routines using a + abort ' local control block + long[control][1] := 0 ' Check for the presence of EEPROM + long[control][0] := ioReadCmd << 24 | (addr & $FFFFFF) + repeat while long[control][0] & ioTestRdy ' Wait for check to complete and + if long[control][0] & ioTestErr ' abort if there's an error + abort + repeat t from 0 to 7 ' Stop all COGs except this one and + if (t <> cogid) and (t <> (cog-1)) ' the one with the I2C driver in it + cogstop(t) + t := ioBootCmd | ioStopLdr | cogid ' Tell the I2C driver to load 32K + long[control][1] := $80000000 ' into HUB RAM after stopping + long[control][0] := (t << 24) | (addr & $FFFFFF) ' this calling cog + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB readEEPROM(addr,buffer,count) | t '' Read a block from EEPROM to RAM + t := ioReadCmd + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := (count << 16) | (buffer & $FFFF) + long[control][0] := (t << 24) | (addr & $FFFFFF) + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB writeEEPROM(addr,buffer,count) | t '' Write a block to EEPROM from RAM + t := ioWriteCmd + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := (count << 16) | (buffer & $FFFF) + long[control][0] := (t << 24) | (addr & $FFFFFF) + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB checkPresence(addr) | t +'' This routine checks to be sure there is an I2C bus and an EEPROM at the +'' specified address. Note that this routine cannot distinguish between a +'' 32Kx8 and a 64Kx8 EEPROM since the 16th address bit is a "don't care" +'' for the 32Kx8 devices. Return true if EEPROM present, false otherwise. + t := ioReadCmd + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := 0 ' Attempt to address the device + long[control][0] := (t << 24) | (addr & $FFFFFF) + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) == 0 ' Return false on error + +PUB writeWait(addr) | t '' Wait for EEPROM to complete write + t := cnt + repeat until checkPresence(addr) ' Maximum wait time is 20ms + if (cnt - t) > (clkfreq / 50) + return true ' Return true if a timeout occurred + return false ' Otherwise return false + +PUB computeTimes '' Set up timing constants in assembly + ' (Done this way to avoid overflow) + i2cDataSet1 := ((clkfreq / 10000) * 900) / 100000 ' Data setup time - 900ns (100KHz) + i2cClkLow1 := ((clkfreq / 10000) * 4700) / 100000 ' Clock low time - 4700ns (100KHz) + i2cClkHigh1 := ((clkfreq / 10000) * 4000) / 100000 ' Clock high time - 4000ns (100KHz) + i2cDataSet4 := ((clkfreq / 10000) * 550) / 100000 ' Data setup time - 550ns (400KHz) + i2cClkLow4 := ((clkfreq / 10000) * 1300) / 100000 ' Clock low time - 1300ns (400KHz) + i2cClkHigh4 := ((clkfreq / 10000) * 1000) / 100000 ' Clock high time - 1000ns (400KHz) + i2cPause := clkfreq / 100000 ' Pause between checks for operations + +PUB initSDCard(DO,Clk,DI,CS) | t '' Initialize SD card access + t := cnt + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := 0 + long[control][0] := ioSpiInit << 24 | DO << 18 | Clk << 12 | DI << 6 | CS + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB stopSDCard '' Stop SD card access + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := 0 + long[control][0] := ioSpiStop << 24 + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB readSDCard(addr,buffer,count) '' Read block(s) from SD card to RAM + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := (count << 16) | (buffer & $FFFF) + long[control][0] := (ioSpiRead << 24) | (addr & $FFFFFF) + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB writeSDCard(addr,buffer,count) '' Write block(s) to SD card from RAM + repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish + long[control][1] := (count << 16) | (buffer & $FFFF) + long[control][0] := (ioSpiWrite << 24) | (addr & $FFFFFF) + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB bootSDCard(addr,count) | t '' Boot from an SD card + if count < 16 ' Must load at least 16 bytes + return true + repeat t from 0 to 7 ' Stop all COGs except this one and + if (t <> cogid) and (t <> (cog-1)) ' the one with the I2C/SPI driver + cogstop(t) + t := ioSpiBoot | ioStopLdr | cogid ' Tell the SD card driver to load + long[control][1] := count << 16 ' into HUB RAM after stopping + long[control][0] := (t << 24) | (addr & $FFFFFF) ' this calling cog + repeat while long[control][0] & ioTestRdy ' Wait for this to finish + return (long[control][0] & ioTestErr) <> 0 ' Return any error code + +PUB start(ctrlBlk) | t '' Start the I2C I/O driver (standalone) + control := ctrlBlk '' using address of 2 longs for control + stop ' Stop a previous copy + computeTimes + long[control][0] := 0 ' Initialize the control block + long[control][1] := 0 + cog := cognew(@i2cEntryPoint,control) + 1 ' Start a new cog with the I2C driver + return cog > 0 ' Indicate success + +PUB stop '' Stop the I2C I/O driver (standalone) + if cog > 0 + cogstop(cog - 1) + +PUB getControl(i) '' Return a long from the control block + return long[control][i] ' Check for operation completed first + +PUB setControl(i,value) '' Set value of a long in the control block + long[control][i] := value ' Always set the first long last + +DAT + org 0 +i2cEntryPoint mov i2cTemp,i2cPause + add i2cTemp,CNT ' Wait 10us before checking + waitcnt i2cTemp,#0 +i2cNewOpFetch rdlong i2cAddr,PAR ' Fetch control information + mov i2cCmd,i2cAddr + shr i2cCmd,#24 ' Isolate command code + mov Options,i2cCmd + and i2cAddr,i2cAddrMask ' Only need address at this point + and i2cCmd,#ioCmdMask wz + if_z jmp #i2cEntryPoint ' Wait for a new operation + mov i2cTemp,PAR + add i2cTemp,#4 ' Now get 2nd long of packet + rdlong i2cCount,i2cTemp + mov i2cBufAdr,i2cCount ' Byte count + rdlong SaveClkFreq,#clkfreqVal ' Save clock frequency and mode + shr i2cCount,#16 + and i2cBufAdr,i2cWordMask ' HUB RAM address of buffer + rdbyte SaveClkMode,#clksetVal + movs ShiftData,#0 ' Initialize for saving Preamble + mov StoreLocal,initStore ' on I2C and SPI reads + mov Preamble+0,#0 + mov Preamble+1,#0 + mov Preamble+2,#0 + mov Preamble+3,#0 + mov CheckSum,#$EC ' Adjust checksum for stack marker + test Options,#ioNoStore wc + test i2cCmd,#ioBootCmd wz + if_nz_and_nc mov i2cTemp,i2cCmd ' Stop the caller's COG unless + if_nz_and_nc and i2cTemp,#%111 ' it's this one + if_nz_and_nc cogid i2cCogId + if_nz_and_nc cmp i2cCogId,i2cTemp wz + if_nz_and_nc cogstop i2cTemp + test i2cCmd,#ioSpiMask wz ' Check for SPI commands + if_nz jmp #spiEntryPoint + movs :getAction,i2cCmd ' Get command specific action + test i2cCmd,#ioBootCmd wz ' bit sequence. ioBootCmd is + if_nz movs :getAction,#ioReadCmd ' treated as ioReadCmd here + add :getAction,#ActionTbl + mov i2cDataSet,i2cDataSet1 + mov i2cClkLow,i2cClkLow1 + mov i2cClkHigh,i2cClkHigh1 +:getAction mov Action,0-0 + test Options,#ioLowSpeed wc ' Set bus speed based on option + if_nc mov i2cDataSet,i2cDataSet4 + if_nc mov i2cClkLow,i2cClkLow4 + if_nc mov i2cClkHigh,i2cClkHigh4 + mov i2cTemp,i2cAddr + shr i2cTemp,#18 ' Determine bit masks for + and i2cTemp,#%11110 ' I/O pins for I2C bus + mov i2cSCL,#1 + shl i2cSCL,i2cTemp + mov i2cSDA,i2cSCL ' SDA is next higher pin + shl i2cSDA,#1 + test FirstCall,i2cSCL wz ' Is this our first call? + andn FirstCall,i2cSCL ' if so, do a reset + if_nz call #i2cReset + call #i2cStart ' Do a start sequence + test Action,#%000000001 wz + if_z jmp #:skipAction0 + mov i2cData,i2cAddr ' Construct a device select + shr i2cData,#15 ' code for EEPROM write mode + and i2cData,#%00001110 ' with 2 address bytes + or i2cData,#%10100000 + mov i2cMask,#%10000000 + call #i2cWrite ' Send device select code + if_c jmp #:doStop ' Failure if NAK received +:skipAction0 test Action,#%000000010 wz + if_z jmp #:skipAction1 + mov i2cData,i2cAddr ' First address byte is most + shr i2cData,#8 ' significant byte of address + mov i2cMask,#%10000000 + call #i2cWrite ' Send first address byte + if_c jmp #:doStop ' Failure if NAK received +:skipAction1 test Action,#%000000100 wz + if_z jmp #:skipAction2 + mov i2cData,i2cAddr ' Second address byte is least + mov i2cMask,#%10000000 ' significant byte of address + call #i2cWrite ' Send second address byte + if_c jmp #:doStop ' Failure if NAK received +:skipAction2 tjz i2cCount,#:doStop ' If byte count == 0, we're done + test Action,#%000001000 wz + if_nz call #i2cStart ' Do a start sequence if readdressing +:doReadWrite test Action,#%000010000 wz + if_nz rdbyte i2cData,i2cBufAdr ' If writing, fetch the data value + if_nz add i2cBufAdr,#1 ' and increment the hub address + test Action,#%000100000 wz + if_z jmp #:skipAction5 + mov i2cData,i2cAddr ' If reading, construct a device select + shr i2cData,#15 ' code for EEPROM read mode with + and i2cData,#%00001110 ' 2 address bytes + or i2cData,#%10100001 +:skipAction5 test Action,#%001000000 wz + if_z jmp #:skipAction6 + mov i2cData,i2cAddr ' If reading using a single byte address + shr i2cData,#8 ' construct a device select code for + or i2cData,#%00000001 ' read mode given one for write mode +:skipAction6 test Action,#%010000000 wz + if_z jmp #:skipAction7 + mov i2cMask,#%10000000 ' Either readdress device for reading + call #i2cWrite ' or write a data value at this point + if_c jmp #:doStop ' Failure if NAK received +:skipAction7 test Action,#%100000000 wz + if_z jmp #:skipAction8 + cmp i2cCount,#2 wc ' Carry true if this is the last byte + mov i2cMask,#%10000000 + mov i2cData,#0 + call #i2cRead + call #StoreData ' Now force carry false to show success + or i2cZero,#0 nr,wc + andn Action,#%011100000 ' No readdressing on subsequent reads +:skipAction8 add i2cAddr,#1 + djnz i2cCount,#:doReadWrite ' Repeat for number of bytes requested +:doStop call #i2cStop + if_c or i2cAddr,errorFlag ' Carry true indicates error + jmp #checkEndIO + +'' Low level I2C routines. These are designed to work either with a standard I2C bus +'' (with pullups on both SCL and SDA) or the Propellor Demo Board (with a pullup only +'' on SDA). Timing can be set by the caller to 100KHz or 400KHz. + +'' Do I2C Reset Sequence. Clock up to 9 cycles. Look for SDA high while SCL +'' is high. Device should respond to next Start Sequence. Leave SCL high. + +i2cReset andn dira,i2cSDA ' Pullup drive SDA high + mov i2cBitCnt,#9 ' Number of clock cycles + mov i2cTime,i2cClkLow + add i2cTime,cnt ' Allow for minimum SCL low +:i2cResetClk andn outa,i2cSCL ' Active drive SCL low + or dira,i2cSCL + waitcnt i2cTime,i2cClkHigh + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,i2cClkLow ' Allow minimum SCL high + test i2cSDA,ina wz ' Stop if SDA is high + if_z djnz i2cBitCnt,#:i2cResetClk ' Stop after 9 cycles +i2cReset_ret ret ' Should be ready for Start + +'' Do I2C Start Sequence. This assumes that SDA is a floating input and +'' SCL is also floating, but may have to be actively driven high and low. +'' The start sequence is where SDA goes from HIGH to LOW while SCL is HIGH. + +i2cStart andn dira,i2cSDA ' Pullup drive SDA high + andn outa,i2cSDA ' SDA set to drive low + mov i2cTime,i2cClkLow + add i2cTime,cnt ' Allow for bus free time + waitcnt i2cTime,i2cClkHigh + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,i2cClkHigh ' Allow for start setup time + or dira,i2cSDA ' Active drive SDA low + waitcnt i2cTime,#0 ' Allow for start hold time + andn outa,i2cSCL ' Active drive SCL low + or dira,i2cSCL +i2cStart_ret ret + +'' Do I2C Stop Sequence. This assumes that SCL is low and SDA is indeterminant. +'' The stop sequence is where SDA goes from LOW to HIGH while SCL is HIGH. +'' i2cStart must have been called prior to calling this routine for initialization. +'' The state of the (c) flag is maintained so a write error can be reported. + +i2cStop or dira,i2cSDA ' Active drive SDA low + mov i2cTime,i2cClkLow + add i2cTime,cnt ' Wait for minimum clock low + waitcnt i2cTime,i2cClkLow + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,i2cClkHigh ' Wait for minimum setup time + andn dira,i2cSDA ' Pullup drive SDA high + waitcnt i2cTime,#0 ' Allow for bus free time + andn dira,i2cSCL ' Leave SCL and SDA high +i2cStop_ret ret + +'' Write I2C data. This assumes that i2cStart has been called and that SCL is low, +'' SDA is indeterminant. The (c) flag will be set on exit from ACK/NAK with ACK == false +'' and NAK == true. Bytes are handled in "little-endian" order so these routines can be +'' used with words or longs although the bits are in msb..lsb order. + +i2cWrite mov i2cBitCnt,#8 + mov i2cTime,i2cClkLow + add i2cTime,cnt ' Wait for minimum SCL low +:i2cWriteBit waitcnt i2cTime,i2cDataSet + test i2cData,i2cMask wz + if_z or dira,i2cSDA ' Copy data bit to SDA + if_nz andn dira,i2cSDA + waitcnt i2cTime,i2cClkHigh ' Wait for minimum setup time + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,i2cClkLow + andn outa,i2cSCL ' Active drive SCL low + or dira,i2cSCL + ror i2cMask,#1 ' Go do next bit if not done + djnz i2cBitCnt,#:i2cWriteBit + andn dira,i2cSDA ' Switch SDA to input and + waitcnt i2cTime,i2cClkHigh ' wait for minimum SCL low + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,#0 ' Wait for minimum high time + test i2cSDA,ina wc ' Sample SDA (ACK/NAK) then + andn outa,i2cSCL ' active drive SCL low + or dira,i2cSCL + or dira,i2cSDA ' Leave SDA low + rol i2cMask,#16 ' Prepare for multibyte write +i2cWrite_ret ret + +'' Read I2C data. This assumes that i2cStart has been called and that SCL is low, +'' SDA is indeterminant. ACK/NAK will be copied from the (c) flag on entry with +'' ACK == low and NAK == high. Bytes are handled in "little-endian" order so these +'' routines can be used with words or longs although the bits are in msb..lsb order. + +i2cRead mov i2cBitCnt,#8 + andn dira,i2cSDA ' Make sure SDA is set to input + mov i2cTime,i2cClkLow + add i2cTime,cnt ' Wait for minimum SCL low +:i2cReadBit waitcnt i2cTime,i2cClkHigh + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,i2cClkLow ' Wait for minimum clock high + test i2cSDA,ina wz ' Sample SDA for data bits + andn outa,i2cSCL ' Active drive SCL low + or dira,i2cSCL + if_nz or i2cData,i2cMask ' Accumulate data bits + if_z andn i2cData,i2cMask + ror i2cMask,#1 ' Shift the bit mask and + djnz i2cBitCnt,#:i2cReadBit ' continue until done + waitcnt i2cTime,i2cDataSet ' Wait for end of SCL low + if_c andn dira,i2cSDA ' Copy the ACK/NAK bit to SDA + if_nc or dira,i2cSDA + waitcnt i2cTime,i2cClkHigh ' Wait for minimum setup time + test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus + if_nz or outa,i2cSCL ' Active drive SCL high + if_nz or dira,i2cSCL + if_z andn dira,i2cSCL ' Pullup drive SCL high + waitcnt i2cTime,#0 ' Wait for minimum clock high + andn outa,i2cSCL ' Active drive SCL low + or dira,i2cSCL + or dira,i2cSDA ' Leave SDA low + rol i2cMask,#16 ' Prepare for multibyte read +i2cRead_ret ret + +'' SPI routines for Rokicki's SD card FAT file system driver + +spiEntryPoint test i2cCmd,#ioBootCmd wc ' Check for boot + if_c jmp #spiDoRead ' (Treat like read) + cmp i2cCmd,#ioSpiStop wc,wz + if_c jmp #spiDoInit ' Decode operation + if_z jmp #spiDoStop + cmp i2cCmd,#ioSpiWrite wc + if_c jmp #spiDoRead + jmp #spiDoWrite + +'' Initialize SPI communications. The pin numbers of the 4 I/O pins are +'' provided in the 24 bit address field of the control packet. From MSB to +'' LSB, these are DO - Data Out, Clk - Clock, DI - Data In, CS - Card Select. + +spiDoInit movd :moveIt,#spiMaskCS + mov spiBlkCnt,#4 +:makeMask mov i2cMask,#1 + mov i2cTemp,i2cAddr ' Only use lower 5 bits of + and i2cTemp,#%11111 ' 6 bit shift count field + shl i2cMask,i2cTemp +:moveIt mov 0-0,i2cMask ' Store the bit mask for the pin + cmp spiBlkCnt,#1 wz + if_ne or outa,i2cMask ' Make all pins high outputs + if_ne or dira,i2cMask ' except DO is an input since + if_e andn dira,i2cMask ' input/output is card relative + sub :moveIt,incrDst + ror i2cAddr,#6 + djnz spiBlkCnt,#:makeMask + rol i2cAddr,#24 ' Leave i2cAddr unchanged + mov i2cTime,cnt ' Set up a 1 second timeout + mov spiBlkCnt,spiInitCnt +:initRead call #spiRecvByte ' Output a stream of 32K clocks + djnz spiBlkCnt,#:initRead ' in case SD card left in some + mov spiOp,#0 ' undefined state + mov spiParm,#0 + call #spiSendCmd ' Send a reset command and deselect + or outa,spiMaskCS ' to get SD card into SPI mode +:waitIdle mov spiOp,#55 + call #spiSendCmd ' APP_CMD (Application Specific) + mov spiOp,#41 + call #spiSendCmd ' SEND_OP_COND (Initialization) + or outa,spiMaskCS + cmp i2cData,#1 wz ' Wait until response not In Idle + if_e jmp #:waitIdle + tjz i2cData,#i2cGoUpdate ' Initialization complete + or i2cAddr,errorFlag + jmp #i2cGoUpdate ' Could not initialize the card + +'' Stop SPI communications. Any previously used I/O pins are set to input mode and +'' the masks for the I/O pins are zeroed. The card is clocked so it turns off. + +spiDoStop or outa,spiMaskCS ' Make sure /CS is high + call #spiRecvByte ' Put out a few clocks + call #spiRecvByte ' to turn off the card + andn dira,spiMaskDO + andn dira,spiMaskDI ' Set all the card pins + andn dira,spiMaskCS ' to inputs so they can + andn dira,spiMaskClk ' be used for some other + mov spiMaskDO,#0 ' purpose when the card + mov spiMaskDI,#0 ' is removed. All should + mov spiMaskCS,#0 ' have pullups to +3.3V. + mov spiMaskClk,#0 + jmp #i2cGoUpdate + +'' Read one or more 512 byte blocks and store the specified number of bytes +'' into the HUB location given. The block number is provided in the 24 bit +'' address field and incremented after every block is read. Partial blocks are +'' allowed and any extra bytes read are discarded. + +spiDoRead mov spiOp,#17 ' READ_SINGLE_BLOCK +:readRepeat mov i2cTime,cnt ' Save start of timeout + mov spiParm,i2cAddr + call #spiSendCmd ' Read from specified block + call #spiResponse + mov spiBlkCnt,spiBlkSize ' Transfer a block at a time +:getRead call #spiRecvByte + tjz i2cCount,#:skipStore ' Check for count exhausted + call #StoreData + sub i2cCount,#1 +:skipStore djnz spiBlkCnt,#:getRead ' Are we done with the block? + call #spiRecvByte + call #spiRecvByte ' Yes, finish with 16 clocks + add i2cAddr,#1 + or outa,spiMaskCS ' Increment address, deselect card + tjnz i2cCount,#:readRepeat ' and check for more blocks to do +checkEndIO test i2cCmd,#ioBootCmd wc + if_nc jmp #i2cGoUpdate ' If not booting, we're done + test i2cAddr,errorFlag wc + and CheckSum,#$FF wz ' If booting, no errors can occur + if_z_and_nc jmp #nowBootSpin ' and checksum must be zero + or i2cAddr,errorFlag + test Options,#noStore wc + if_c jmp #i2cGoUpdate ' Return error status if noStore + +stopThisCOG cogid i2cCogId ' If an unrecoverable error occurs, + cogstop i2cCogId ' stop this cog + +'' Write one or more 512 byte blocks with the specified number of bytes from +'' the HUB location given. The block number is provided in the 24 bit address +'' field and incremented after every block is written. Partial blocks are +'' allowed and are padded with zeroes. + +spiDoWrite mov spiOp,#24 ' WRITE_BLOCK + mov i2cTime,cnt ' Setup timeout + mov spiParm,i2cAddr + call #spiSendCmd ' Write to specified block + mov i2cData,#$FE ' Ask to start data transfer + call #spiSendByte + mov spiBlkCnt,spiBlkSize ' Transfer a block at a time +:putWrite mov i2cData,#0 ' padding with zeroes if needed + tjz i2cCount,#:padWrite ' Check for count exhausted + rdbyte i2cData,i2cBufAdr ' If not, get the next data byte + add i2cBufAdr,#1 + sub i2cCount,#1 +:padWrite call #spiSendByte + djnz spiBlkCnt,#:putWrite ' Are we done with the block? + call #spiRecvByte + call #spiRecvByte ' Yes, finish with 16 clocks + call #spiResponse + and i2cData,#$1F ' Check the response status + cmp i2cData,#5 wz + if_ne or i2cAddr,errorFlag ' Must be Data Accepted + if_ne jmp #i2cGoUpdate + movs spiWaitData,#0 ' Wait until not busy + call #spiWaitBusy + add i2cAddr,#1 + or outa,spiMaskCS ' Increment block address and go + tjnz i2cCount,#spiDoWrite ' to next if more data remains + jmp #i2cGoUpdate + +'' Mid level SPI I/O + +spiSendCmd andn outa,spiMaskCS ' Send command sequence. Begin by + call #spiRecvByte ' selecting card and clocking + mov i2cData,spiOp + or i2cData,#$40 ' Send command byte (1st 2 bits %01) + call #spiSendByte + mov i2cData,spiParm + shr i2cData,#15 ' Supplied address is sector number + call #spiSendByte + mov i2cData,spiParm ' Send to SD card as byte address, + shr i2cData,#7 ' in multiples of 512 bytes + call #spiSendByte + mov i2cData,spiParm ' Total length of this address is + shl i2cData,#1 ' four bytes + call #spiSendByte + mov i2cData,#0 + call #spiSendByte + mov i2cData,#$95 ' CRC code (for 1st command only) + call #spiSendByte +spiResponse movs spiWaitData,#$FF ' Wait for response from card +spiWaitBusy call #spiRecvByte + mov i2cTemp,cnt + sub i2cTemp,i2cTime ' Check for expired timeout (1 sec) + cmp i2cTemp,SaveClkFreq wc + if_nc or i2cAddr,errorFlag + if_nc jmp #i2cGoUpdate +spiWaitData cmp i2cData,#0-0 wz ' Wait for some other response + if_e jmp #spiWaitBusy ' than that specified +spiSendCmd_ret +spiResponse_ret +spiWaitBusy_ret ret + +'' Low level byte I/O + +spiSendByte mov i2cMask,#%10000000 +:sendBit test i2cMask,i2cData wc + andn outa,spiMaskClk ' Send data bytes MSB first + muxc outa,spiMaskDI + or outa,spiMaskClk + shr i2cMask,#1 ' When mask shifted out, we're done + tjnz i2cMask,#:sendBit + or outa,spiMaskDI ' Leave DI in idle (high) state +spiSendByte_ret ret + +spiRecvByte mov i2cMask,#%10000000 +:recvBit andn outa,spiMaskClk ' Receive data bytes MSB first + or outa,spiMaskClk ' Copy DO to data bit + test spiMaskDO,ina wc + muxc i2cData,i2cMask + shr i2cMask,#1 ' When mask shifted out, we're done + tjnz i2cMask,#:recvBit + and i2cData,#%11111111 ' Eight bits received +spiRecvByte_ret ret + +'' For both I2C and SPI, store data on a read operation unless ioNoStore is set. +'' Accumulate a checksum and always save a copy of the first 16 bytes read. +'' If this is an ioBootCmd or ioSpiBoot, adjust the amount to be read based +'' on the value in the program preamble in the word at vbase ($0008). + +StoreData test Options,#ioNoStore wc + if_nc wrbyte i2cData,i2cBufAdr ' Store data in specified location + add i2cBufAdr,#1 ' and increment the address + add CheckSum,i2cData ' Accumulate checksum for ioBootCmd +ShiftData shl i2cData,#0-0 +StoreLocal or Preamble+0,i2cData ' Store a local copy of the program + add ShiftData,#8 ' preamble for when we're reading + cmp ShiftData,testIns wz ' in a new Spin program + if_z movs ShiftData,#0 ' Pack the data into successive longs + if_z add StoreLocal,incrDst + if_z cmp StoreLocal,testDst wz ' Stop after saving $0010 bytes + if_z mov StoreLocal,noStore + if_z test i2cCmd,#ioBootCmd wc ' If we're reading in a new program, + if_c_and_z mov i2cCount,Preamble+2 ' change i2cCount to vbase adjusted + if_c_and_z and i2cCount,i2cWordMask ' by number of bytes loaded so far. + if_c_and_z sub i2cCount,#16 - 1 ' i2cCount will be decremented again +StoreData_ret ret + +'' After reading is finished for a boot, the stack marker is added below dbase +'' and memory is cleared between that and vbase (the end of the loaded program). +'' Memory beyond the stack marker is not cleared. Note that if ioNoStore is set, +'' we go through the motions, but don't actually change memory or the clock. + +nowBootSpin test Options,#ioNoStore wc + mov i2cTemp,Preamble+2 + shr i2cTemp,#16 ' Get dbase value + sub i2cTemp,#4 + if_nc wrlong StackMark,i2cTemp ' Place stack marker at dbase + sub i2cTemp,#4 + if_nc wrlong StackMark,i2cTemp + mov i2cOther,Preamble+2 ' Get vbase value + and i2cOther,i2cWordMask + sub i2cTemp,i2cOther + shr i2cTemp,#2 wz ' Compute number of longs between +:zeroIt if_nz_and_nc wrlong i2cZero,i2cOther ' vbase and below stack marker + if_nz_and_nc add i2cOther,#4 + if_nz_and_nc djnz i2cTemp,#:zeroIt ' Zero that space (if any) + mov i2cTemp,Preamble + cmp i2cTemp,SaveClkFreq wz ' Is the clock frequency the same? + mov i2cTemp,Preamble+1 + and i2cTemp,#$FF ' Is the clock mode the same also? + if_ne jmp #:changeClock + cmp i2cTemp,SaveClkMode wz ' If both same, just go start COG + if_e jmp #:justStartUp +:changeClock and i2cTemp,#$F8 ' Force use of RCFAST clock while + if_nc clkset i2cTemp ' letting requested clock start + mov i2cTemp,time_xtal +:startupDelay djnz i2cTemp,#:startupDelay ' Allow 20ms@20MHz for xtal/pll to settle + mov i2cTemp,Preamble+1 + and i2cTemp,#$FF ' Then switch to selected clock + if_nc clkset i2cTemp +:justStartUp mov i2cOther,i2cCmd ' Use the COG supplied as the caller's + and i2cOther,#%111 ' to start up the SPIN interpreter + test Options,#ioStopLdr wz ' If ioStopLdr is set and ioNoStore is + if_nz cogid i2cOther ' clear, then use this cog for SPIN + or i2cOther,interpreter + if_nc coginit i2cOther + +'' The operation has completed, with or without errors. Update the control block +'' in main memory and wait for the next operation to be requested. + +i2cGoUpdate and i2cBufAdr,i2cWordMask ' Copy updated information + shl i2cCount,#16 ' back to control packet + or i2cCount,i2cBufAdr + mov i2cTemp,PAR + add i2cTemp,#4 + wrlong i2cCount,i2cTemp + wrlong i2cAddr,PAR ' Indicate operation is done + jmp #i2cEntryPoint ' and go wait for a new one + +'' This action table contains bit sequences for controlling device addressing and read/write +'' mode selection for each of the commands possible. From LSB to MSB, the actions are: +'' 0 - Write the EEPROM device select code for write mode and 2 address bytes +'' 1 - Write the MSB device address or (for ioRead1Cmd/ioWrite1Cmd) a device select code +'' 2 - Write the LSB device address or (for ioRead0Cmd/ioWrite0Cmd) a device select code +'' 3 - Output a Start Sequence prior to reselecting in read mode +'' 4 - Fetch a data value for writing +'' 5 - Construct an EEPROM device select code for read mode and 2 address bytes +'' 6 - Construct a read mode device select code from the MSB of the 16 bit device address +'' 7 - Write the data value or read mode device select code +'' 8 - Read a byte of data from the device and store it + +i2cZero +ActionTbl long %0000000000 ' Command not used (indicates done) + long %0110101111,%0010010111 ' Read/Write with 2 bytes of addressing + long %0111001110,%0010010110 ' Read/Write with 1 byte of addressing + long %0100000100,%0010010100 ' Read/Write data only + +'' Constants for all routines + +i2cWordMask long $0000FFFF +i2cAddrMask long $00FFFFFF +errorFlag long $80000000 ' NAK received during write cycle +speedMask long $40000000 ' One if 100KHz bus, zero if 400KHz +time_xtal long 20 * 20000 / 4 / 1 ' 20ms (@20MHz, 1 inst/loop) +interpreter long ($0004 << 16) | ($F004 << 2) | %0000 +i2cBootSCLm long | byte[charactersBefore]) + return true + + ifnot(byte[characters] and byte[charactersBefore] and (byte[characters++] > byte[charactersBefore++])) + quit + +PUB alphabeticallyAfter(characters, charactersAfter) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Compares two strings to see if one comes alphabetically after the other. │ +'' │ │ +'' │ Returns true if yes and false if no. │ +'' │ │ +'' │ Characters - A pointer to a string of characters. │ +'' │ CharactersAfter - A pointer to a string of characters that comes alphabetically after the other string of characters. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat + + if(byte[characters] < byte[charactersAfter]) + return true + + ifnot(byte[characters] and byte[charactersAfter] and (byte[characters++] < byte[charactersAfter++])) + quit + +PUB startsWithCharacter(charactersToSearch, characterToFind) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Checks if the string of characters begins with the specified character. │ +'' │ │ +'' │ Returns true if yes and false if no. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharacterToFind - The character to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (byte[charactersToSearch] == characterToFind) + +PUB startsWithCharacters(charactersToSearch, charactersToFind) + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Checks if the string of characters begins with the specified characters. │ +'' │ │ +'' │ Returns true if yes and false if no. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharactersToFind - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (charactersToSearch == findCharacters(charactersToSearch, charactersToFind)) + +PUB endsWithCharacter(charactersToSearch, characterToFind) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Checks if the string of characters ends with the specified character. │ +'' │ │ +'' │ Returns true if yes and false if no. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharacterToFind - The character to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return (byte[charactersToSearch + strsize(charactersToSearch) - 1] == characterToFind) + +PUB endsWithCharacters(charactersToSearch, charactersToFind) + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Checks if the string of characters ends with the specified characters. │ +'' │ │ +'' │ Returns true if yes and false if no. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharactersToFind - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + return ((charactersToSearch + (strsize(charactersToSearch) - strsize(charactersToFind)) - 2) == findCharacters(charactersToSearch, charactersToFind)) + +PUB findCharacter(charactersToSearch, characterToFind) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches a string of characters for the first occurence of the specified character. │ +'' │ │ +'' │ Returns the address of that character if found and zero if not found. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharacterToFind - The character to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(charactersToSearch--) + + if(byte[++charactersToSearch] == characterToFind) + + return charactersToSearch + +PUB replaceCharacter(charactersToSearch, characterToReplace, characterToReplaceWith) '' 11 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Replaces the first occurence of the specified character in a string of characters with another character. │ +'' │ │ +'' │ Returns the address of the next character after the character replaced sucess and zero on failure. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharacterToReplace - The character to find in the string of characters to search. │ +'' │ CharacterToReplaceWith - The character to replace the character found in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result := findCharacter(charactersToSearch, characterToReplace) + + if(result) + + byte[result++] := characterToReplaceWith + +PUB replaceAllCharacter(charactersToSearch, characterToReplace, characterToReplaceWith) '' 17 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Replaces all occurences of the specified character in a string of characters with another character. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharacterToReplace - The character to find in the string of characters to search. │ +'' │ CharacterToReplaceWith - The character to replace the character found in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat while(charactersToSearch) + + charactersToSearch := replaceCharacter(charactersToSearch, characterToReplace, characterToReplaceWith) + +PUB findCharacters(charactersToSearch, charactersToFind) : buffer | counter '' 6 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches a string of characters for the first occurence of the specified string of characters. │ +'' │ │ +'' │ Returns the address of that string of characters if found and zero if not found. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharactersToFind - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(charactersToSearch--) + + if(byte[++charactersToSearch] == byte[CharactersToFind]) + + repeat counter from 0 to (strsize(charactersToFind) - 1) + + if(byte[charactersToSearch][counter] <> byte[charactersToFind][counter]) + buffer~~ + + ifnot(buffer~) + return charactersToSearch + +PUB replaceCharacters(charactersToSearch, charactersToReplace, charactersToReplaceWith) '' 12 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Replaces the first occurence of the specified string of characters in a string of characters with another string of │ +'' │ characters. Will not enlarge or shrink a string of characters. │ +'' │ │ +'' │ Returns the address of the next character after the string of characters replaced on sucess and zero on failure. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharactersToReplace - A pointer to the string of characters to find in the string of characters to search. │ +'' │ CharactersToReplaceWith - A pointer to the string of characters that will replace the string of characters found in the │ +'' │ string characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + result := findCharacters(charactersToSearch, charactersToReplace) + + if(result) + + charactersToSearch := strsize(charactersToReplaceWith) + + if(strsize(charactersToReplace) < charactersToSearch) + charactersToSearch := strsize(charactersToReplace) + + repeat charactersToSearch + + byte[result++] := byte[charactersToReplaceWith++] + +PUB replaceAllCharacters(charactersToSearch, charactersToReplace, charactersToReplaceWith) '' 18 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Replaces all occurences of the specified string of characters in a string of characters with another string of │ +'' │ characters. Will not enlarge or shrink a string of characters. │ +'' │ │ +'' │ CharactersToSearch - A pointer to the string of characters to search. │ +'' │ CharactersToReplace - A pointer to the string of characters to find in the string of characters to search. │ +'' │ CharactersToReplaceWith - A pointer to the string of characters that will replace the string of characters found in the │ +'' │ string characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat while(charactersToSearch) + + charactersToSearch := replaceCharacters(charactersToSearch, charactersToReplace, charactersToReplaceWith) + +PUB trimCharacters(characters) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Removes white space and new lines from the begining and end of a string of characters. │ +'' │ │ +'' │ Returns a pointer to the trimed string of characters. │ +'' │ │ +'' │ Characters - A pointer to a string of characters to be trimed. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat while((1 =< byte[characters]) and (byte[characters] =< 32) or (byte[characters] == 127)) + + characters += 1 + + result := characters + + characters := (characters + strsize(characters) - 1) + + repeat while((1 =< byte[characters]) and (byte[characters] =< 32) or (byte[characters] == 127)) + + byte[characters--] := 0 + +PUB tokenizeCharacters(characters) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Removes white space and new lines from in between of a string of characters. │ +'' │ │ +'' │ Through repeated calls on the same string of characters a new string to each sub string of characters is returned. │ +'' │ │ +'' │ Returns a pointer to a new tokenized sub string on each call and null when out of sub strings. │ +'' │ │ +'' │ Characters - A pointer to a string of characters to be tokenized. Null after the first call to continue. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + if(characters) + + charactersPointer := characters + + characterIndex := 0 + + result := (charactersPointer + characterIndex) + + repeat while((33 =< byte[charactersPointer][characterIndex]) and (byte[charactersPointer][characterIndex] =< 126)) + + characterIndex += 1 + + repeat while((1 =< byte[charactersPointer][characterIndex]) and (byte[charactersPointer][characterIndex] =< 32) or (byte[charactersPointer][characterIndex] == 127)) + + byte[charactersPointer][characterIndex++] := 0 + +PUB charactersToLowerCase(characters) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Demotes all upper case characters in the set of ("A","Z") to their lower case equivalents. │ +'' │ │ +'' │ Characters - A pointer to a string of characters to convert to lowercase. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(characters--) + + result := byte[++characters] + + if((result => "A") and (result =< "Z")) + + byte[characters] := (result + 32) + +PUB charactersToUpperCase(characters) '' 4 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Promotes all lower case characters in the set of ("a","z") to their upper case equivalents. │ +'' │ │ +'' │ Characters - A pointer to a string of characters to convert to uppercase. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(characters--) + + result := byte[++characters] + + if((result => "a") and (result =< "z")) + + byte[characters] := (result - 32) + +PUB numberToDecimal(number, length) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Converts an integer number to the decimal string of that number padded with zeros. │ +'' │ │ +'' │ Returns a pointer to the converted string. │ +'' │ │ +'' │ Number - A 32 bit signed integer number to be converted to a string. │ +'' │ Length - The length of the number in the converted string. " " or "-" will be tacked onto the front of the string. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + length := ((length <# 10) #> 0) + + decimalCharacters := " " + + if(number < 0) + -number + decimalCharacters := "-" + + if(number == negx) + + bytemove(@decimalCharacters, string("-2147483648"), 12) + + else + + repeat result from 10 to 1 + decimalCharacters[result] := ((number // 10) + "0") + number /= 10 + + bytemove(@decimalCharacters[1], @decimalCharacters[(11 - length)], (length + 1)) + + return @decimalCharacters + +PUB numberToHexadecimal(number, length) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Converts an integer number to the hexadecimal string of that number padded with zeros. │ +'' │ │ +'' │ Returns a pointer to the converted string. │ +'' │ │ +'' │ Number - A 32 bit signed integer number to be converted to a string. │ +'' │ Length - The length of the converted string, negative numbers need a length of 8 for sign extension. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat result from 7 to 0 + hexadecimalCharacters[result] := lookupz((number & $F): "0".."9", "A".."F") + number >>= 4 + + return @hexadecimalCharacters[(8 - ((length <# 8) #> 0))] + +PUB numberToBinary(number, length) '' 5 Stack Longs + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Converts an integer number to the binary string of that number padded with zeros. │ +'' │ │ +'' │ Returns a pointer to the converted string. │ +'' │ │ +'' │ Number - A 32 bit signed integer number to be converted to a string. │ +'' │ Length - The length of the converted string, negative numbers need a length of 32 for sign extension. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat result from 31 to 0 + binaryCharacters[result] := ((number & $1) + "0") + number >>= 1 + + return @binaryCharacters[(32 - ((length <# 32) #> 0))] + +PUB decimalToNumber(characters) | buffer, counter '' 6 Stack Longs. + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Converts a decimal string into an integer number. │ +'' │ │ +'' │ Returns the converted integer. │ +'' │ │ +'' │ Characters - A pointer to the decimal string to convert. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + buffer := byte[characters] + + counter := (strsize(characters) <# 11) + + repeat while(counter--) + result *= 10 + result += lookdownz(byte[characters++]: "0".."9") + + if(buffer == "-") + -result + +PUB hexadecimalToNumber(characters) : buffer | counter '' 5 Stack Longs. + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Converts a hexadecimal string into an integer number. │ +'' │ │ +'' │ Returns the converted integer. │ +'' │ │ +'' │ Characters - A pointer to the hexadecimal string to convert. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + counter := (strsize(characters) <# 8) + + repeat while(counter--) + buffer <<= 4 + buffer += lookdownz(byte[characters++]: "0".."9", "A".."F") + +PUB binaryToNumber(characters) : buffer | counter '' 5 Stack Longs. + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Converts a binary string into an integer number. │ +'' │ │ +'' │ Returns the converted integer. │ +'' │ │ +'' │ Characters - A pointer to the binary string to convert. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + counter := (strsize(characters) <# 32) + + repeat while(counter--) + buffer <<= 1 + buffer += lookdownz(byte[characters++]: "0", "1") + +{{ + +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the │ +│Software is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the │ +│Software. │ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/lib/gui-dlbox.spin b/lib/gui-dlbox.spin new file mode 100644 index 0000000..db399f2 --- /dev/null +++ b/lib/gui-dlbox.spin @@ -0,0 +1,150 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + + ios : "reg-ios" + fm : "fm-con" + +CON + + +VAR + + byte box_win,box_x0,box_y0,box_x1,box_y1 + long box_ladr,box_fadr + byte box_view,box_maxpos,box_pos + byte box_cols + byte box_stat + +PUB define(win,x0,y0,x1,y1,ladr,fadr,view,maxpos) + + box_win := win 'fensternummer + box_x0 := x0 'koordinaten + box_x1 := x1 + box_y0 := y0 + box_y1 := y1 + box_view := view 'position in der liste + box_pos := 0 'position im fenster + box_maxpos := maxpos 'max. anzahl in liste + box_ladr := ladr 'adresse dateinamenliste + box_fadr := fadr 'adresse dateiflags + box_cols := (box_x1-box_x0)/(fm#MAX_LEN+2) + box_stat := 0 + ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1) + ios.winset(box_win) + ios.printcls + +PUB draw + + ios.winset(box_win) + ios.printcls + redraw + +PUB redraw | i + + ios.winset(box_win) + if box_stat & fm#FL_FOCUS + ios.setcolor(fm#COL_FOCUS) + ios.winoframe + ios.curhome + ios.curoff + ios.setcolor(fm#COL_DEFAULT) + i := 0 + repeat fm#WROWS + repeat box_cols + print_file(box_view+i,i) + i++ + ios.printnl + +PUB setpos(pos) + + box_pos := pos + redraw + +PUB setview(view) + + box_view := view + redraw + +PUB getcols: cols + + return box_cols + +PUB focus + + ios.winset(box_win) + box_stat := box_stat | fm#FL_FOCUS + redraw + +PUB defocus + + ios.winset(box_win) + box_stat := box_stat & !fm#FL_FOCUS + redraw + +PRI print_file(fnr,posnr) | i,c + + i := 0 + c := fm#COL_DEFAULT + + if byte[box_fadr+fnr] & fm#FL_SEL 'eintrag selektiert? + c := fm#COL_SELECT + + if (posnr == box_pos) & (box_stat & fm#FL_FOCUS) 'eintrag an cursorpos? + ios.setcolor(c+8) + else + ios.setcolor(c) + + if byte[box_fadr+fnr] & fm#FL_DIR 'eintrag verzeichnis? + ios.printq(string(" ▶")) + else + ios.print(string(" ")) + + repeat fm#MAX_LEN + ios.bus_putchar2(byte[box_ladr][fnr*fm#MAX_LEN+i]) + i++ + ios.setcolor(fm#COL_DEFAULT) + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/gui-input.spin b/lib/gui-input.spin new file mode 100644 index 0000000..9a87a3b --- /dev/null +++ b/lib/gui-input.spin @@ -0,0 +1,96 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + + ios : "reg-ios" + fm : "fm-con" + gc : "glob-con" + +CON + + +VAR + + byte box_win,box_x0,box_y0,box_x1,box_y1 + byte input_len + byte input_str[64] + +PUB define(win,x0,y0,x1,y1,len) + + box_win := win 'fensternummer + box_x0 := x0 'koordinaten + box_x1 := x1 + box_y0 := y0 + box_y1 := y1 + input_len := len + ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1) + ios.winset(box_win) + ios.printcls + +PUB draw(stradr1):stradr2 | key,bnr + + input_str[0] := 0 + ios.winset(box_win) + ios.printcls + ios.winoframe + ios.curhome + ios.curoff + ios.setcolor(fm#COL_DEFAULT) + ios.printchar(" ") + ios.print(stradr1) + ios.printnl + ios.printnl + ios.printchar(" ") + repeat input_len + ios.printchar("_") + ios.curpos1 + ios.printchar(" ") + ios.curon + ios.input(@input_str,input_len) + ios.curoff + return @input_str + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/gui-pbar.spin b/lib/gui-pbar.spin new file mode 100644 index 0000000..745df2f --- /dev/null +++ b/lib/gui-pbar.spin @@ -0,0 +1,119 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + + ios : "reg-ios" + fm : "fm-con" + +CON + + +VAR + + byte box_win,box_x0,box_y0,box_x1,box_y1 + long box_maxbar + byte box_barlen + byte box_bar + byte box_skal + +PUB define(win,x0,y0,x1,y1) + + box_win := win 'fensternummer + box_x0 := x0 'koordinaten + box_x1 := x1 + box_y0 := y0 + box_y1 := y1 + box_barlen := x1 - x0 - 4 + box_bar := 0 + box_skal := 1 + ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1) + ios.winset(box_win) + ios.printcls + +PUB setmaxbar(maxbar) + + box_maxbar := maxbar + box_skal := 1 + if box_maxbar => box_barlen + box_skal := box_maxbar / box_barlen + +PUB draw(stradr1,stradr2,bar) + + ios.winset(box_win) + ios.printcls + ios.winoframe + ios.curhome + ios.curoff + ios.setcolor(fm#COL_DEFAULT) + ios.printchar(" ") + ios.print(stradr1) + ios.printnl + ios.printchar(" ") + ios.print(stradr2) + ios.printnl + update(bar) +{ + box_bar := bar / box_skal + ios.printchar(" [") + repeat box_bar + ios.printqchar("‣") + repeat box_barlen - box_bar + ios.printqchar(" ") + ios.printchar("]") +} + +PUB update(bar) + + ios.winset(box_win) + ios.curpos1 + box_bar := bar / box_skal + ios.print(string(" [")) + repeat box_bar <# box_barlen + ios.printqchar("‣") + repeat box_barlen - box_bar #> 0 + ios.printqchar(" ") + ios.printchar("]") + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/gui-wbox.spin b/lib/gui-wbox.spin new file mode 100644 index 0000000..bd2e27b --- /dev/null +++ b/lib/gui-wbox.spin @@ -0,0 +1,112 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + + ios : "reg-ios" + fm : "fm-con" + gc : "glob-con" + +CON + + +VAR + + byte box_win,box_x0,box_y0,box_x1,box_y1 + +PUB define(win,x0,y0,x1,y1) + + box_win := win 'fensternummer + box_x0 := x0 'koordinaten + box_x1 := x1 + box_y0 := y0 + box_y1 := y1 + ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1) + ios.winset(box_win) + ios.printcls + +PUB draw(stradr1,stradr2,stradr3):button | key,bnr + + ios.winset(box_win) + ios.printcls + ios.winoframe + ios.curhome + ios.curoff + ios.setcolor(fm#COL_DEFAULT) + ios.printchar(" ") + ios.print(stradr1) + ios.printnl + ios.printnl + bnr := 1 + repeat + draw_buttons(stradr2,stradr3,bnr) + key := ios.keywait + case key + gc#KEY_CURLEFT: bnr := 1 + gc#KEY_CURRIGHT: bnr := 2 + + until key == gc#KEY_RETURN + return bnr + +PRI draw_buttons(stradr2,stradr3,bnr) + + ios.curpos1 + ios.setcolor(fm#COL_DEFAULT) + ios.printchar(" ") + if bnr == 1 + ios.setcolor(fm#COL_DEFAULT + 8) + else + ios.setcolor(fm#COL_DEFAULT) + ios.print(stradr2) + ios.setcolor(fm#COL_DEFAULT) + ios.print(string(" ")) + if bnr == 2 + ios.setcolor(fm#COL_DEFAULT + 8) + else + ios.setcolor(fm#COL_DEFAULT) + ios.print(stradr3) +ios.setcolor(fm#COL_DEFAULT) + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/lib/m-glob-con.spin b/lib/m-glob-con.spin new file mode 100644 index 0000000..913ddd5 --- /dev/null +++ b/lib/m-glob-con.spin @@ -0,0 +1,227 @@ +{{ Bellatrix-Code +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2012 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : mental +Name : +Chip : global +Typ : Konstanten + + +}} + +con ' signaldefinitionen + +'signaldefinitionen global + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + I2C_SCL + I2C_SDA + SER_TX + SER_RX + + +'signaldefinitionen bellatrix + +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal + + +'signaldefinitionen administra + +#8, ADM_SOUNDL,ADM_SOUNDR 'sound (stereo 2 pin) +#10, ADM_SDD0,ADM_SDCLK,ADM_SDCMD,ADM_SDD3 'sd-cardreader (4 pin) +#23, ADM_SELECT 'administra-auswahlsignal + +con ' administra-funktionen + +ADM_OPT = 0 + +'sdcard-funktionen +ADM_SD_MOUNT = 1 +ADM_SD_CHECKMOUNTED = 2 +ADM_SD_UNMOUNT = 3 +ADM_SD_OPEN = 4 +ADM_SD_CLOSE = 5 +ADM_SD_GETC = 6 +ADM_SD_PUTC = 7 +ADM_SD_EOF = 8 +ADM_SD_GETBLK = 9 + +ADM_SCR_FILL = 11 'screenpuffer mit zeichen füllen +ADM_SCR_READ = 12 'screen in den puffer laden +ADM_SCR_WRITE = 13 'screen auf disk schreiben +ADM_SCR_GETNR = 14 'nummer des aktuellen screens abfragen +ADM_SCR_SETPOS = 15 'zeiger auf position im puffer setzen +ADM_SCR_GETPOS = 16 'aktuelle position im puffer abfragen +ADM_SCR_GETC = 17 'zeichen wird aus dem puffer gelesen +ADM_SCR_PUTC = 18 'zeichen wird in den puffer geschrieben +ADM_SCR_ERR = 19 'fehlerstatus abfragen +ADM_SCR_MAXSCR = 20 'anzahl screens des containers abfragen +ADM_SCR_EOS = 21 'end of screen abfragen +ADM_SCR_CALL = 22 'subscreen aufrufen +ADM_SCR_RET = 23 'subscreen beenden +ADM_SCR_USE = 24 'tape öffnen +ADM_SCR_TAPES = 25 'tapeliste abfragen + +ADM_M_PARSE = 30 'nächstes token aus screen parsen +ADM_M_SETBASE = 31 'zahlenbasis setzen + +ADM_COM_TX = 40 'com: zeichen senden +ADM_COM_RX = 41 'com: zeichen empfangen + +adm_m_run = 50 'plx: polling aktivieren +adm_m_halt = 51 'plx: polling anhalten +adm_m_setctrl = 52 +adm_m_in = 53 +adm_m_out = 54 +adm_m_ad_ch = 55 +adm_m_getreg = 56 +adm_m_setreg = 57 +adm_m_start = 58 +adm_m_stop = 59 +adm_m_write = 60 +adm_m_read = 61 +adm_m_ping = 62 +adm_m_joy = 63 +adm_m_paddle = 64 +adm_m_pad = 65 +adm_m_setjoy = 66 +adm_m_setpad = 67 + +adm_m_getspec = 97 'spezifikation abfragen +adm_m_getver = 98 'codeversion abfragen +adm_m_reboot = 99 'neu starten + +'plexbus +adm_sda = 19 'i2c-datenpin +adm_scl = 20 'i2c-clockpin +adm_int1 = 21 'interrupt port 1&2 +adm_int2 = 22 'interrupt port 3 + + +con ' bellatrix-funktionen + +' ---------------------------------------------- FUNKTIONEN + +bel_key_stat = 1 'tastaturstatus abfragen +bel_key_code = 2 'tastaturzeichen abfragen +bel_key_spec = 3 'sondertasten abfragen +bel_key_wait = 4 'auf tastaturzeichen warten +bel_pchar = 5 'zeichen ohne steuerzeichen augeben +bel_setx = 6 'x-position setzen +bel_sety = 7 'y-position setzen +bel_getx = 8 'x-position abfragen +bel_gety = 9 'y-position abfragen +bel_color = 10 'farbe setzen +bel_sline = 11 'startzeile scrollbereich +bel_eline = 12 'endzeile scrollbereich +bel_settab = 13 'tabulatorposition setzen + +bel_cls = 1 +bel_home = 2 +bel_pos1 = 3 +bel_curon = 4 +bel_curoff = 5 +bel_up = 6 +bel_down = 7 +bel_bs = 8 +bel_tab = 9 +bel_nl = 13 + +' ---------------------------------------------- M-FUNKTIONEN + +bel_m_parse = 20 'nächstes token von eingabezeile parsen +bel_m_setbase = 21 'base setzen +bel_m_dot = 22 'formatierte ausgabe eines zahlenwertes +bel_m_error = 23 'm fehlermeldung + +' ---------------------------------------------- SCREENEDITOR + +bel_scr_edit = 24 'screeneditor +bel_scr_put = 25 'screen empfangen +bel_scr_get = 26 'screen senden +bel_scr_setnr = 27 'screennummer setzen + +' ---------------------------------------------- CHIP-MANAGMENT + +bel_mgr_setcolor= 97 'neuen bellatrix-code laden +bel_mgr_load = 98 'farbregister setzen +bel_reboot = 99 'bellatrix neu starten + +con ' color-tags + + M_C_TAG1 = $16 'wort ausführen + M_C_TAG2 = $17 'wort definieren + M_C_TAG3 = $18 'wort compilieren + M_C_TAG4 = $19 'zahl + M_C_TAG5 = $1A 'zahl literal + M_C_TAG6 = $1B 'string + M_C_TAG7 = $1C 'string literal + M_C_TAG8 = $1D 'data + M_C_TAG9 = $1E 'kommentar + M_C_TAG10 = $1F 'eos/cursor + + + M_C_EXECUTE = M_C_TAG1 + M_C_CREATE = M_C_TAG2 + M_C_COMPILE = M_C_TAG3 + M_C_NUMBER = M_C_TAG4 + M_C_NUMBERLIT = M_C_TAG5 + M_C_STRING = M_C_TAG6 + M_C_STRINGLIT = M_C_TAG7 + M_C_DATA = M_C_TAG8 + M_C_REMARK = M_C_TAG9 + + M_C_MAX = M_C_TAG9 ' tag mit höchstem wert + + M_C_EOS = M_C_TAG10 ' end of screen tag für den adm-parser + +con ' farbzuordnung + C_EXECUTE = 0 + C_CREATE = 1 + C_COMPILE = 2 + C_NUMBER = 3 + C_NUMBERLIT = 4 + C_STRING = 5 + C_STRINGLIT = 6 + C_DATA = 7 + C_REMARK = 8 + + C_CURSOR = 15 ' cursorfarbe + C_NORMAL = 0 ' normale ausgabefarbe + C_INFO = 8 ' farbe für infos + C_ATTENTION = 1 ' farbe für hinweise + +con ' fehlercodes + +M_ERR_NO = 0 ' kein fehler +M_ERR_RS = 1 ' returnstack fehler +M_ERR_DS = 2 ' datenstack fehler +M_ERR_IN = 3 ' fehler interpreter +M_ERR_CP = 4 ' fehler compiler +M_ERR_SI = 5 ' strukturfehler +M_ERR_SD = 6 ' datenträgerfehler +M_ERR_RW = 7 ' schreib/lesefehler +M_ERR_NF = 8 ' not found +M_ERR_ST = 9 ' stackfehler + + +pub dummy + +' diese routine muss vorhanden sein, +' da sonst kein objekt erzeugt und eingebunden wird + diff --git a/lib/reg-ios.spin b/lib/reg-ios.spin new file mode 100644 index 0000000..a76f073 --- /dev/null +++ b/lib/reg-ios.spin @@ -0,0 +1,2993 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : [I]nput-[O]utput-[S]ystem - System-API +Chip : Regnatix +Typ : Objekt +Version : 01 +Subversion : 2 +Funktion : System-API - Schnittstelle der Anwendungen zu allen Systemfunktionen + +Regnatix + system : Systemübergreifende Routinen + loader : Routinen um BIN-Dateien zu laden + ramdisk : Strukturierte Speicherverwaltung/Ramdisk + eram : Einfache Speicherverwaltung: Usermem + bus : Kommunikation zu Administra und Bellatrix + +Administra + sd-card : FAT16 Dateisystem auf SD-Card + scr : Screeninterface + hss : Hydra-Soundsystem + sfx : Sound-FX + +Bellatrix + key : Keyboardroutinen + screen : Bildschirmsteuerung + g0 : grafikmodus 0,TV-Modus 256 x 192 Pixel, Vektorengine + +Komponenten : - +COG's : - +Logbuch : + +19-11-2008-dr235 - erste version aus dem ispin-projekt extrahiert +13-03-2009-dr235 - string für parameterübergabe zwischen programmen im eram eingerichtet +26-03-2010-dr235 - errormeldungen entfernt (mount) +05-08-2010-dr235 - speicherverwaltung für eram eingefügt +18-09-2010-dr235 - fehler in bus_init behoben: erste eram-zelle wurde gelöscht durch falsche initialisierung +25-11-2011-dr235 - funktionsset für grafikmodus 0 eingefügt +28-11-2011-dr235 - sfx_keyoff, sfx_stop eingefügt +01-12-2011-dr235 - printq zugefügt: ausgabe einer zeichenkette ohne steuerzeichen +25-01-2012-dr235 - korrektur char_ter_bs +06-04-2012-dr235 - fehler in g0_printdec behoben +14-11-2012-uheld - window-funktionen eingefügt, ansatzweise globale konstanten ausgelagert +15-04-2013-dr235 - konstanten für bellatrix-funktionen komplett ausgelagert + +Notizen : + + --------------------------------------------------------------------------------------------------------- }} + +OBJ + + gc: "glob-con" + +CON 'Signaldefinitionen +'signaldefinition regnatix +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10 'adressbus +#19, REG_RAM1,REG_RAM2 'selektionssignale rambank 1 und 2 +#21, REG_PROP1,REG_PROP2 'selektionssignale für administra und bellatrix +#23, REG_AL 'strobesignal für adresslatch +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +CON 'Zeichencodes +'zeichencodes +CHAR_RETURN = $0D 'eingabezeichen +CHAR_NL = $0D 'newline +CHAR_SPACE = $20 'leerzeichen +CHAR_BS = $08 'tastaturcode backspace +CHAR_TER_BS = $08 'terminalcode backspace +CHAR_ESC = $1B + +KEY_CTRL = $02 +KEY_ALT = $04 +KEY_OS = $08 + +KEY_CURUP = 04 +KEY_CURDOWN = 05 +KEY_CURLEFT = 02 +KEY_CURRIGHT = 03 + +CON 'Systemvariablen +'systemvariablen + +LOADERPTR = $0FFFFF - 4 'Zeiger auf Loader-Register im hRAM +MAGIC = LOADERPTR - 1 'Warmstartflag +SIFLAG = MAGIC - 1 'Screeninit-Flag +BELDRIVE = SIFLAG - 12 'Dateiname aktueller Grafiktreiber +PARAM = BELDRIVE - 65 'Parameterstring +TIB2 = PARAM - 65 +RAMDRV = TIB2 - 1 'Ramdrive-Flag +RAMEND = RAMDRV - 4 'Zeiger auf oberstes freies Byte (einfache Speicherverwaltung) +RAMBAS = RAMEND - 4 'Zeiger auf unterstes freies Byte (einfache Speicherverwaltung) + +SYSVAR = RAMBAS - 1 'Adresse des obersten freien Bytes, darüber folgen Systemvariablen + +{ +LOADERPTR = $0FFFFB '4 Byte 'Zeiger auf Loader-Register im hRAM +MAGIC = $0FFFFA '1 Byte 'Warmstartflag +SIFLAG = $0FFFF9 '1 byte 'Screeninit-Flag +BELDRIVE = $0FFFED '12 Byte 'Dateiname aktueller Grafiktreiber +PARAM = $0FFFAD '64 Byte 'Parameterstring +RAMDRV = $0FFFAC '1 Byte 'Ramdrive-Flag +RAMEND = $0FFFA8 '4 Byte 'Zeiger auf oberstes freies Byte (einfache Speicherverwaltung) +RAMBAS = $0FFFA4 '4 Byte 'Zeiger auf unterstes freies Byte (einfache Speicherverwaltung) + +SYSVAR = $0FFFA3 'Adresse des obersten freien Bytes, darüber folgen Systemvariablen +} +CON 'Sonstiges +CNT_HBEAT = 5_000_0000 'blinkgeschw. front-led +DB_IN = %00000111_11111111_11111111_00000000 'maske: dbus-eingabe +DB_OUT = %00000111_11111111_11111111_11111111 'maske: dbus-ausgabe + +OS_TIBLEN = 64 'größe des inputbuffers +ERAM = 1024 * 512 * 2 'größe eram +HRAM = 1024 * 32 'größe hram + +RMON_ZEILEN = 16 'speichermonitor - angezeigte zeilen +RMON_BYTES = 8 'speichermonitor - zeichen pro byte + +STRCOUNT = 64 'größe des stringpuffers + +VGA = 0 +TV = 1 + +CON 'ADMINISTRA-FUNKTIONEN -------------------------------------------------------------------------- + +'soundeinstellungen +#0, SND_HSSOFF + SND_HSSON + SND_WAVOFF + SND_WAVON + + +#0, NVRAM_LANG +#0, LANG_DE + LANG_EN + +#1, NVRAM_DATEFORMAT +#0, DATEFORMAT_DE 'DD.MM.YYY (DE DIN 1355-1) + DATEFORMAT_CANONICAL 'YYYY-MM-DD (ISO 8601) + DATEFORMAT_UK 'DD/MM/YYYY + DATEFORMAT_US 'MM/DD/YYYY + +#2, NVRAM_TIMEFORMAT +#0, TIMEFORMAT_24 'HH:MM:SS + TIMEFORMAT_12 'HH:MM:SS[PM|AM] + TIMEFORMAT_12UK 'HH.MM.SS[PM|AM] + +'dateiattribute +#0, F_SIZE + F_CRDAY + F_CRMONTH + F_CRYEAR + F_CRSEC + F_CRMIN + F_CRHOUR + F_ADAY + F_AMONTH + F_AYEAR + F_CDAY + F_CMONTH + F_CYEAR + F_CSEC + F_CMIN + F_CHOUR + F_READONLY + F_HIDDEN + F_SYSTEM + F_DIR + F_ARCHIV + +'dir-marker +#0, DM_ROOT + DM_SYSTEM + DM_USER + DM_A + DM_B + DM_C + +'interface zum hss-player +#0, iEndFlag 'Repeat oder Ende wurde erreicht + iRowFlag 'Flag das Songzeile fertig ist + iEngineC 'Patternzähler + iBeatC 'Beatzähler + iRepeat 'zähler für loops +#5, iChannel +#5, iChannel1 +#10, iChannel2 +#15, iChannel3 +#20, iChannel4 +#0, iNote + iOktave + iVolume + iEffekt + iInstrument + + +CON 'BELLATRIX-FUNKTIONEN -------------------------------------------------------------------------- + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_01_02 +' +' +---------- +' | +-------- +' | |+------- +' | ||+------ +' | |||+----- +' | ||||+---- +' | |||||+--- +' | ||||||+-- multi +' | |||||||+- loader +CHIP_SPEC = %00000000_00000000_00000000_00000001 + +LIGHTBLUE = 0 +YELLOW = 1 +RED = 2 +GREEN = 3 +BLUE_REVERSE = 4 +WHITE = 5 +RED_INVERSE = 6 +MAGENTA = 7 + +' konstante parameter für die sidcog's + +scog_pal = 985248.0 +scog_ntsc = 1022727.0 +scog_maxf = 1031000.0 +scog_triangle = 16 +scog_saw = 32 +scog_square = 64 +scog_noise = 128 + + +VAR + long lflagadr 'adresse des loaderflag + long rbas 'einfaches speichermodell: virtuelle startadresse + long rend 'einfaches speichermodell: speicherende + byte dname[16] 'puffer für dateiname + byte strpuffer[STRCOUNT] 'stringpuffer + byte parapos 'position im parameterstring + +PUB start: wflag | i 'system: ios initialisieren +''funktionsgruppe : system +''funktion : ios initialisieren +''eingabe : - +''ausgabe : wflag - 0: kaltstart +'' : 1: warmstart +''busprotokoll : - + + bus_init 'bus initialisieren + + sddmact(DM_USER) 'wieder in userverzeichnis wechseln + lflagadr := ram_rdlong(sysmod,LOADERPTR) 'adresse der loader-register setzen + + if ram_rdbyte(sysmod,MAGIC) == 235 + 'warmstart + wflag := 1 + + else + 'kaltstart + ram_wrbyte(sysmod,235,MAGIC) + ram_wrlong(sysmod,SYSVAR,RAMEND) 'Zeiger auf letzte freie Speicherzelle setzen + ram_wrlong(sysmod,0,RAMBAS) 'Zeiger auf erste freie Speicherzelle setzen + wflag := 0 + ram_wrbyte(sysmod,0,RAMDRV) 'Ramdrive ist abgeschaltet + ram_wrbyte(sysmod,0,TIB2) 'tib-puffer mit leerstrin belegen + + rbas := ram_rdlong(sysmod,RAMBAS) + rend := ram_rdlong(sysmod,RAMEND) + rd_init + +PUB stop 'loader: beendet anwendung und startet os +''funktionsgruppe : system +''funktion : beendet die laufende anwendung und kehrt zum os (reg.sys) zurück +''eingabe : - +''ausgabe : - +''busprotokoll : - + + sddmact(DM_ROOT) + ldbin(@regsys) + repeat + +PUB startram 'system: initialisierung des systems bei ram-upload +''funktionsgruppe : system +''funktion : ios initialisieren - wenn man zu testzwecken das programm direkt in den ram +'' : überträgt und startet, bekommen alle props ein reset, wodurch bellatrix auf +'' : einen treiber wartet. für testzwecke erledigt diese routine den upload des +'' : standard-vga-treibers. +''eingabe : - +''ausgabe : - +''busprotokoll : - + + sdmount 'sd-karte mounten + bload(@belsys) 'vga-treiber zu bellatrix übertragen + +PUB paraset(stradr) | i,c 'system: parameter --> eram +''funktionsgruppe : system +''funktion : parameter --> eram - werden programme mit dem systemloader gestartet, so kann +'' : mit dieser funktion ein parameterstring im eram übergeben werden. das gestartete +'' : programm kann diesen dann mit "parastart" & "paranext" auslesen und verwenden +''eingabe : - +''ausgabe : stradr - adresse des parameterstrings +''busprotokoll : - + + paradel 'parameterbereich löschen + repeat i from 0 to 63 'puffer ist mx. 64 zeichen lang + c := byte[stradr+i] + ram_wrbyte(0,c,PARAM+i) + if c == 0 'bei stringende vorzeitig beenden + return + +PUB paradel | i 'system: parameterbereich löschen +''funktionsgruppe : system +''funktion : parameterbereich im eram löschen +''eingabe : - +''ausgabe : - +''busprotokoll : - + + repeat i from 0 to 63 + ram_wrbyte(0,0,PARAM+i) + +PUB parastart 'system: setzt den zeiger auf parameteranfangsposition +''funktionsgruppe : system +''funktion : setzt den index auf die parameteranfangsposition +''eingabe : - +''ausgabe : - +''busprotokoll : - + + parapos := 0 + +PUB paranext(stradr): err | i,c 'system: überträgt den nächsten parameter in stringdatei +''funktionsgruppe : system +''funktion : überträgt den nächsten parameter in stringdatei +''eingabe : stradr - adresse einer stringvariable für den nächsten parameter +''ausgabe : err - 0: kein weiterer parameter +'' : 1: parameter gültig +''busprotokoll : - + + if ram_rdbyte(0,PARAM+parapos) <> 0 'stringende? + repeat until ram_rdbyte(0,PARAM+parapos) > CHAR_SPACE 'führende leerzeichen ausblenden + parapos++ + i := 0 + repeat 'parameter kopieren + c := ram_rdbyte(0,PARAM + parapos++) + if c <> CHAR_SPACE 'space nicht kopieren + byte[stradr++] := c + until (c == CHAR_SPACE) or (c == 0) + byte[stradr] := 0 'string abschließen + return 1 + else + return 0 + +PUB reggetcogs:regcogs |i,c,cog[8] 'system: fragt freie cogs von regnatix ab +''funktionsgruppe : system +''funktion : fragt freie cogs von regnatix ab +''eingabe : - +''ausgabe : regcogs - anzahl der belegten cogs +''busprotokoll : - + + regcogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + regcogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + +PUB ldbin(stradr) | len,i,stradr1,stradr2 'loader: startet bin-datei über loader +''funktionsgruppe : system +''funktion : startet bin-datei über den systemloader +''eingabe : stradr - adresse eines strings mit dem dateinamen der bin-datei +''ausgabe : - +''busprotokoll : - + + len := strsize(stradr) + stradr2 := lflagadr + 1 'adr = flag, adr + 1 = string + repeat i from 0 to len - 1 'string in loadervariable kopieren + byte[stradr2][i] := byte[stradr][i] + byte[stradr2][++i] := 0 'string abschließen + byte[lflagadr][0] := 1 'loader starten + +PUB os_error(err):error 'sys: fehlerausgabe + + if err + printnl + print(string("Fehlernummer : ")) + printdec(err) + print(string(" : $")) + printhex(err,2) + printnl + print(string("Fehler : ")) + case err + 0: print(string("no error")) + 1: print(string("fsys unmounted")) + 2: print(string("fsys corrupted")) + 3: print(string("fsys unsupported")) + 4: print(string("not found")) + 5: print(string("file not found")) + 6: print(string("dir not found")) + 7: print(string("file read only")) + 8: print(string("end of file")) + 9: print(string("end of directory")) + 10: print(string("end of root")) + 11: print(string("dir is full")) + 12: print(string("dir is not empty")) + 13: print(string("checksum error")) + 14: print(string("reboot error")) + 15: print(string("bpb corrupt")) + 16: print(string("fsi corrupt")) + 17: print(string("dir already exist")) + 18: print(string("file already exist")) + 19: print(string("out of disk free space")) + 20: print(string("disk io error")) + 21: print(string("command not found")) + 22: print(string("timeout")) + 23: print(string("out of memory")) + OTHER: print(string("undefined")) + printnl + error := err + +OBJ '' A D M I N I S T R A + +CON ''------------------------------------------------- CHIP-MANAGMENT + +PUB admsetsound(sndfunktion):sndstat 'chip-mgr: soundsubsysteme verwalten +''funktionsgruppe : cmgr +''funktion : soundsubsysteme an- bzw. abschalten +''busprotokoll : [150][put.funktion][get.sndstat] +'' : funktion - 0: hss-engine abschalten SND_HSSOFF +'' : 1: hss-engine anschalten SND_HSSON +'' : 2: dac-engine abschalten SND_WAVOFF +'' : 3: dac-engine anschalten SND_WAVON +'' : sndstat - status/cognr startvorgang + + bus_putchar1(gc#a_mgrSetSound) + bus_putchar1(sndfunktion) + sndstat := bus_getchar1 + +PUB admsetsyssnd(status) 'chip-mgr: systemklänge ein/ausschalten +''funktionsgruppe : cmgr +''funktion : systemklänge steuern +''busprotokoll : [094][put.fl_syssnd] +'' : fl_syssnd - flag zur steuerung der systemsounds +'' : 0 - systemtöne aus +'' : 1 - systemtöne an + + bus_putchar1(gc#a_mgrSetSysSound) + bus_putchar1(status) + +PUB admgetsndsys: status 'chip-mgr: status des soundsystems abfragen +''funktionsgruppe : cmgr +''funktion : abfrage welches soundsystem aktiv ist +''busprotokoll : [095][get.status] +'' : status - status des soundsystems +'' : 0 - sound aus +'' : 1 - hss +'' : 2 - wav + + bus_putchar1(gc#a_mgrGetSoundSys) + status := bus_getchar1 + +PUB admload(stradr)|dmu 'chip-mgr: neuen administra-code booten +''funktionsgruppe : cmgr +''funktion : administra mit neuem code booten +''busprotokoll : [096][sub_putstr.fn] +'' : fn - dateiname des neuen administra-codes + + bus_putchar1(gc#a_mgrALoad) 'aktuelles userdir retten + bus_putstr1(stradr) + waitcnt(cnt + clkfreq*3) 'warte bis administra fertig ist + +PUB admgetver:ver 'chip-mgr: version abfragen +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''busprotokoll : [098][sub_getlong.ver] +'' : ver - version +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''version : $00_00_00_00 +'' + + bus_putchar1(gc#a_mgrGetVer) + ver := bus_getlong1 + +PUB admgetspec:spec 'chip-mgr: spezifikation abfragen +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''busprotokoll : [089][sub_getlong.spec] +'' : spec - spezifikation +'' +'' +---------- com +'' | +-------- i2c +'' | |+------- rtc +'' | ||+------ lan +'' | |||+----- sid +'' | ||||+---- wav +'' | |||||+--- hss +'' | ||||||+-- bootfähig +'' | |||||||+- dateisystem +''spezifikation : %00000000_00000000_00000000_01001111 + + bus_putchar1(gc#a_mgrGetSpec) + spec := bus_getlong1 + +PUB admgetcogs:cogs 'chip-mgr: verwendete cogs abfragen +''funktionsgruppe : cmgr +''funktion : abfrage wie viele cogs in benutzung sind +''busprotokoll : [097][get.cogs] +'' : cogs - anzahl der belegten cogs + + bus_putchar1(gc#a_mgrGetCogs) + cogs := bus_getchar1 + +PUB admreset 'chip-mgr: administra reset +''funktionsgruppe : cmgr +''funktion : reset im administra-chip auslösen - loader aus dem eeprom wird neu geladen +''busprotokoll : - + + bus_putchar1(gc#a_mgrReboot) + +CON ''------------------------------------------------- SD_LAUFWERKSFUNKTIONEN + +PUB sdmount: err 'sd-card: mounten +''funktionsgruppe : sdcard +''funktion : eingelegtes volume mounten +''busprotokoll : [001][get.err] +'' : err - fehlernummer entspr. list + + bus_putchar1(gc#a_sdMount) + err := bus_getchar1 + +PUB sddir 'sd-card: verzeichnis wird geöffnet +''funktionsgruppe : sdcard +''funktion : verzeichnis öffnen +''busprotokoll : [002] + + bus_putchar1(gc#a_sdOpenDir) + +PUB sdnext: stradr | flag 'sd-card: nächster dateiname aus verzeichnis +''funktionsgruppe : sdcard +''funktion : nächsten eintrag aus verzeichnis holen +''busprotokoll : [003][get.status=0] +'' : [003][get.status=1][sub_getstr.fn] +'' : status - 1 = gültiger eintrag +'' : 0 = es folgt kein eintrag mehr +'' : fn - verzeichniseintrag string + + bus_putchar1(gc#a_sdNextFile) 'kommando: nächsten eintrag holen + flag := bus_getchar1 'flag empfangen + if flag + return bus_getstr1 + else + return 0 + +PUB sdopen(modus,stradr):err | len,i 'sd-card: datei öffnen +''funktionsgruppe : sdcard +''funktion : eine bestehende datei öffnen +''busprotokoll : [004][put.modus][sub_putstr.fn][get.error] +'' : modus - "A" Append, "W" Write, "R" Read (Großbuchstaben!) +'' : fn - name der datei +'' : error - fehlernummer entspr. list + + bus_putchar1(gc#a_sdOpen) + bus_putchar1(modus) + len := strsize(stradr) + bus_putchar1(len) + repeat i from 0 to len - 1 + bus_putchar1(byte[stradr++]) + err := bus_getchar1 + +PUB sdclose:err 'sd-card: datei schließen +''funktionsgruppe : sdcard +''funktion : die aktuell geöffnete datei schließen +''busprotokoll : [005][get.error] +'' : error - fehlernummer entspr. list + + bus_putchar1(gc#a_sdClose) + err := bus_getchar1 + +PUB sdgetc: char 'sd-card: zeichen aus datei lesen +''funktionsgruppe : sdcard +''funktion : zeichen aus datei lesen +''busprotokoll : [006][get.char] +'' : char - gelesenes zeichen + + bus_putchar1(gc#a_sdGetC) + char := bus_getchar1 + +PUB sdputc(char) 'sd-card: zeichen in datei schreiben +{{sdputc(char) - sd-card: zeichen in datei schreiben}} + bus_putchar1(gc#a_sdPutC) + bus_putchar1(char) + +PUB sdgetstr(stringptr,len) 'sd-card: eingabe einer zeichenkette + repeat len + byte[stringptr++] := bus_getchar1 + +PUB sdputstr(stringptr) 'sd-card: ausgabe einer zeichenkette (0-terminiert) +{{sdstr(stringptr) - sd-card: ausgabe einer zeichenkette (0-terminiert)}} + repeat strsize(stringptr) + sdputc(byte[stringptr++]) + +PUB sddec(value) | i 'sd-card: dezimalen zahlenwert auf bildschirm ausgeben +{{sddec(value) - sd-card: dezimale bildschirmausgabe zahlenwertes}} + if value < 0 'negativer zahlenwert + -value + sdputc("-") + i := 1_000_000_000 + repeat 10 'zahl zerlegen + if value => i + sdputc(value / i + "0") + value //= i + result~~ + elseif result or i == 1 + sdputc("0") + i /= 10 'n?chste stelle + +PUB sdeof: eof 'sd-card: eof abfragen +''funktionsgruppe : sdcard +''funktion : eof abfragen +''busprotokoll : [030][get.eof] +'' : eof - eof-flag + + bus_putchar1(gc#a_sdEOF) + eof := bus_getchar1 + +PUB sdgetblk(count,bufadr) | i 'sd-card: block lesen +''funktionsgruppe : sdcard +''funktion : block aus datei lesen +''busprotokoll : [008][sub_putlong.count][get.char(1)]..[get.char(count)] +'' : count - anzahl der zu lesenden zeichen +'' : char - gelesenes zeichen + + i := 0 + bus_putchar1(gc#a_sdGetBlk) + bus_putlong1(count) + repeat count + byte[bufadr][i++] := bus_getchar1 + +PUB sdputblk(count,bufadr) | i 'sd-card: block schreiben +''funktionsgruppe : sdcard +''funktion : zeichen in datei schreiben +''busprotokoll : [007][put.char] +'' : char - zu schreibendes zeichen + + i := 0 + bus_putchar1(gc#a_sdPutBlk) + bus_putlong1(count) + repeat count + bus_putchar1(byte[bufadr][i++]) + +PUB sdxgetblk(fnr,count)|i 'sd-card: block lesen --> eRAM +''funktionsgruppe : sdcard +''funktion : block aus datei lesen und in ramdisk speichern +''busprotokoll : [008][sub_putlong.count][get.char(1)]..[get.char(count)] +'' : count - anzahl der zu lesenden zeichen +'' : char - gelesenes zeichen + + i := 0 + bus_putchar1(gc#a_sdGetBlk) + bus_putlong1(count) + repeat count + rd_put(fnr,bus_getchar1) + +PUB sdxputblk(fnr,count)|i 'sd-card: block schreiben <-- eRAM +''funktionsgruppe : sdcard +''funktion : zeichen aus ramdisk in datei schreiben +''busprotokoll : [007][put.char] +'' : char - zu schreibendes zeichen + + i := 0 + bus_putchar1(gc#a_sdPutBlk) + bus_putlong1(count) + repeat count + bus_putchar1(rd_get(fnr)) + +PUB sdseek(wert) 'sd-card: zeiger auf byteposition setzen +''funktionsgruppe : sdcard +''funktion : zeiger in datei positionieren +''busprotokoll : [010][sub_putlong.pos] +'' : pos - neue zeichenposition in der datei + + bus_putchar1(gc#a_sdSeek) + bus_putlong1(wert) + +PUB sdfattrib(anr): attrib 'sd-card: dateiattribute abfragen +''funktionsgruppe : sdcard +''funktion : dateiattribute abfragen +''busprotokoll : [011][put.anr][sub_getlong.wert] +'' : anr - 0 = Dateigröße +'' : 1 = Erstellungsdatum - Tag +'' : 2 = Erstellungsdatum - Monat +'' : 3 = Erstellungsdatum - Jahr +'' : 4 = Erstellungsdatum - Sekunden +'' : 5 = Erstellungsdatum - Minuten +'' : 6 = Erstellungsdatum - Stunden +'' : 7 = Zugriffsdatum - Tag +'' : 8 = Zugriffsdatum - Monat +'' : 9 = Zugriffsdatum - Jahr +'' : 10 = Änderungsdatum - Tag +'' : 11 = Änderungsdatum - Monat +'' : 12 = Änderungsdatum - Jahr +'' : 13 = Änderungsdatum - Sekunden +'' : 14 = Änderungsdatum - Minuten +'' : 15 = Änderungsdatum - Stunden +'' : 16 = Read-Only-Bit +'' : 17 = Hidden-Bit +'' : 18 = System-Bit +'' : 19 = Direktory +'' : 20 = Archiv-Bit +'' : wert - wert des abgefragten attributes + + + bus_putchar1(gc#a_sdFAttrib) + bus_putchar1(anr) + attrib := bus_getlong1 + + +PUB sdvolname: stradr | len,i 'sd-card: volumelabel abfragen +''funktionsgruppe : sdcard +''funktion : name des volumes überragen +''busprotokoll : [012][sub_getstr.volname] +'' : volname - name des volumes +'' : len - länge des folgenden strings + + bus_putchar1(gc#a_sdVolname) 'kommando: volumelabel abfragen + return bus_getstr1 + +PUB sdcheckmounted: flag 'sd-card: test ob volume gemounted ist +''funktionsgruppe : sdcard +''funktion : test ob volume gemounted ist +''busprotokoll : [013][get.flag] +'' : flag - 0: unmounted +'' : 1: mounted + + bus_putchar1(gc#a_sdCheckMounted) + return bus_getchar1 + +PUB sdcheckopen: flag 'sd-card: test ob datei geöffnet ist +''funktionsgruppe : sdcard +''funktion : test ob eine datei geöffnet ist +''busprotokoll : [014][get.flag] +'' : flag - 0: not open +'' : 1: open + + bus_putchar1(gc#a_sdCheckOpen) + return bus_getchar1 + +PUB sdcheckused 'sd-card: abfrage der benutzten sektoren +''funktionsgruppe : sdcard +''funktion : anzahl der benutzten sektoren senden +''busprotokoll : [015][sub_getlong.used] +'' : used - anzahl der benutzten sektoren + + bus_putchar1(gc#a_sdCheckUsed) + return bus_getlong1 + +PUB sdcheckfree 'sd_card: abfrage der freien sektoren +''funktionsgruppe : sdcard +''funktion : anzahl der freien sektoren senden +''busprotokoll : [016][sub_getlong.free] +'' : free - anzahl der freien sektoren + + bus_putchar1(gc#a_sdCheckFree) + return bus_getlong1 + +PUB sdnewfile(stradr):err 'sd_card: neue datei erzeugen +''funktionsgruppe : sdcard +''funktion : eine neue datei erzeugen +''busprotokoll : [017][sub_putstr.fn][get.error] +'' : fn - name der datei +'' : error - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdNewFile) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sdnewdir(stradr):err 'sd_card: neues verzeichnis erzeugen +''funktionsgruppe : sdcard +''funktion : ein neues verzeichnis erzeugen +''busprotokoll : [018][sub_putstr.fn][get.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdNewDir) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sddel(stradr):err 'sd_card: datei/verzeichnis löschen +''funktionsgruppe : sdcard +''funktion : eine datei oder ein verzeichnis löschen +''busprotokoll : [019][sub_putstr.fn][get.error] +'' : fn - name des verzeichnisses oder der datei +'' : error - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdDel) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sdrename(stradr1,stradr2):err 'sd_card: datei/verzeichnis umbenennen +''funktionsgruppe : sdcard +''funktion : datei oder verzeichnis umbenennen +''busprotokoll : [020][sub_putstr.fn1][sub_putstr.fn2][get.error] +'' : fn1 - alter name +'' : fn2 - neuer name +'' : error - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdRename) + bus_putstr1(stradr1) + bus_putstr1(stradr2) + err := bus_getchar1 + +PUB sdchattrib(stradr1,stradr2):err 'sd-card: attribute ändern +''funktionsgruppe : sdcard +''funktion : attribute einer datei oder eines verzeichnisses ändern +''busprotokoll : [021][sub_putstr.fn][sub_putstr.attrib][get.error] +'' : fn - dateiname +'' : attrib - string mit attributen (AHSR) +'' : error - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdChAttrib) + bus_putstr1(stradr1) + bus_putstr1(stradr2) + err := bus_getchar1 + +PUB sdchdir(stradr):err 'sd-card: verzeichnis wechseln +''funktionsgruppe : sdcard +''funktion : verzeichnis wechseln +''busprotokoll : [022][sub_putstr.fn][get.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. list + + bus_putchar1(gc#a_sdChDir) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sdformat(stradr):err 'sd-card: medium formatieren +''funktionsgruppe : sdcard +''funktion : medium formatieren +''busprotokoll : [023][sub_putstr.vlabel][get.error] +'' : vlabel - volumelabel +'' : error - fehlernummer entspr. list + + bus_putchar1(gc#a_sdFormat) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sdunmount:err 'sd-card: medium abmelden +''funktionsgruppe : sdcard +''funktion : medium abmelden +''busprotokoll : [024][get.error] +'' : error - fehlernummer entspr. list + + bus_putchar1(gc#a_sdUnmount) + err := bus_getchar1 + +PUB sddmact(marker):err 'sd-card: dir-marker aktivieren +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker wird aktiviert +''busprotokoll : [025][put.dmarker][get.error] +'' : dmarker - dir-marker +'' : error - fehlernummer entspr. list + + bus_putchar1(gc#a_sdDmAct) + bus_putchar1(marker) + err := bus_getchar1 + +PUB sddmset(marker) 'sd-card: dir-marker setzen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker mit dem aktuellen verzeichnis setzen +''busprotokoll : [026][put.dmarker] +'' : dmarker - dir-marker + + bus_putchar1(gc#a_sdDmSet) + bus_putchar1(marker) + +PUB sddmget(marker):status 'sd-card: dir-marker abfragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker abfragen +''busprotokoll : [027][put.dmarker][sub_getlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + bus_putchar1(gc#a_sdDmGet) + bus_putchar1(marker) + status := bus_getlong1 + +PUB sddmclr(marker) 'sd-card: dir-marker löschen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker löschen +''busprotokoll : [028][put.dmarker] +'' : dmarker - dir-marker + + bus_putchar1(gc#a_sdDmClr) + bus_putchar1(marker) + +PUB sddmput(marker,status) 'sd-card: dir-marker status setzen +''funktionsgruppe : sdcard +''funktion : dir-marker status setzen +''busprotokoll : [027][put.dmarker][sub_putlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + bus_putchar1(gc#a_sdDmPut) + bus_putchar1(marker) + bus_putlong1(status) + +CON ''------------------------------------------------- DATE TIME FUNKTIONEN + +PUB getSeconds 'Returns the current second (0 - 59) from the real time clock. + bus_putchar1(gc#a_rtcGetSeconds) + return bus_getlong1 + +PUB getMinutes 'Returns the current minute (0 - 59) from the real time clock. + bus_putchar1(gc#a_rtcGetMinutes) + return bus_getlong1 + +PUB getHours 'Returns the current hour (0 - 23) from the real time clock. + bus_putchar1(gc#a_rtcGetHours) + return bus_getlong1 + +PUB getDay 'Returns the current day (1 - 7) from the real time clock. + bus_putchar1(gc#a_rtcGetDay) + return bus_getlong1 + +PUB getDate 'Returns the current date (1 - 31) from the real time clock. + bus_putchar1(gc#a_rtcGetDate) + return bus_getlong1 + +PUB getMonth 'Returns the current month (1 - 12) from the real time clock. + bus_putchar1(gc#a_rtcGetMonth) + return bus_getlong1 + +PUB getYear 'Returns the current year (2000 - 2099) from the real time clock. + bus_putchar1(gc#a_rtcGetYear) + return bus_getlong1 + +PUB setSeconds(seconds) 'Sets the current real time clock seconds. + 'seconds - Number to set the seconds to between 0 - 59. + if seconds => 0 and seconds =< 59 + bus_putchar1(gc#a_rtcSetSeconds) + bus_putlong1(seconds) + +PUB setMinutes(minutes) 'Sets the current real time clock minutes. + 'minutes - Number to set the minutes to between 0 - 59. + if minutes => 0 and minutes =< 59 + bus_putchar1(gc#a_rtcSetMinutes) + bus_putlong1(minutes) + +PUB setHours(hours) 'Sets the current real time clock hours. + 'hours - Number to set the hours to between 0 - 23. + + if hours => 0 and hours =< 23 + bus_putchar1(gc#a_rtcSetHours) + bus_putlong1(hours) + +PUB setDay(day) 'Sets the current real time clock day. + 'day - Number to set the day to between 1 - 7. + if day => 1 and day =< 7 + bus_putchar1(gc#a_rtcSetDay) + bus_putlong1(day) + +PUB setDate(date) 'Sets the current real time clock date. + 'date - Number to set the date to between 1 - 31. + if date => 1 and date =< 31 + bus_putchar1(gc#a_rtcSetDate) + bus_putlong1(date) + +PUB setMonth(month) 'Sets the current real time clock month. + 'month - Number to set the month to between 1 - 12. + if month => 1 and month =< 12 + bus_putchar1(gc#a_rtcSetMonth) + bus_putlong1(month) + +PUB setYear(year) 'Sets the current real time clock year. + 'year - Number to set the year to between 2000 - 2099. + if year => 2000 and year =< 2099 + bus_putchar1(gc#a_rtcSetYear) + bus_putlong1(year) + +PUB setNVSRAM(index, value) 'Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). + 'index - The location in NVRAM to set (0 - 55). + 'value - The value (0 - 255) to change the location to. + if index => 0 AND index =< 55 AND value => 0 AND value =< 255 + bus_putchar1(gc#a_rtcSetNVSRAM) + bus_putlong1(index) + bus_putlong1(value) + +PUB getNVSRAM(index) 'Gets the selected NVSRAM value at the index (0 - 55). + 'Returns the selected location's value (0 - 255). + 'index - The location in NVRAM to get (0 - 55). + bus_putchar1(gc#a_rtcGetNVSRAM) + bus_putlong1(index) + return bus_getlong1 + +PUB pauseForSeconds(number) 'Pauses execution for a number of seconds. + 'number - Number of seconds to pause for between 0 and 2,147,483,647. + bus_putchar1(gc#a_rtcPauseForSec) + return bus_getlong1 + +PUB pauseForMilliseconds(number) 'Pauses execution for a number of milliseconds. + 'Returns a puesdo random value derived from the current clock frequency and the time when called. + 'number - Number of milliseconds to pause for between 0 and 2,147,483,647. + bus_putchar1(gc#a_rtcPauseForMSec) + return bus_getlong1 + + + + +CON ''------------------------------------------------- Hydra Sound System + +PUB hss_playfile(stradr) | status 'hss: spielt übergebene hss-datei von sd-card +''funktionsgruppe : hss +''funktion : hss-datei wird in den puffer in administra geladen und der player gestartet +'' : stradr - stringadresse zu dateinamen + + status := hss_load(stradr) + hss_play + +PUB hss_stop 'hss: stopt aktuellen song +''funktionsgruppe : hss +''funktion : hss-player stoppen; datei bleibt im puffer + + bus_putchar1(gc#a_hssStop) + +PUB hss_pause 'hss: pausiert aktuellen song +''funktionsgruppe : hss +''funktion : hss-player pause (funktion noch unklar) + + bus_putchar1(gc#a_hssPause) + +PUB hss_load(stradr): status | len,i 'hss: lädt hss-datei von sd-card in songpuffer +''funktionsgruppe : hss +''funktion : hss-datei wird in den modulpuffer geladen +''busprotokoll : [100][sub_putstr.fn][get.err] +'' : fn - dateiname +'' : err - fehlernummer entspr. liste + + bus_putchar1(gc#a_hssLoad) + bus_putstr1(stradr) + status := bus_getchar1 + +PUB hss_play 'hss: spielt song im puffer ab +''funktionsgruppe : hss +''funktion : hss-player starten und modul im puffer wiedergeben + + bus_putchar1(gc#a_hssPlay) + +PUB hss_vol(vol) 'hss: volume einstellen 0..15 +''funktionsgruppe : hss +''funktion : lautstärke des hss-players wird eingestellt +''busprotokoll : [106][put.vol] +'' : vol - 0..15 gesamtlautstärke des hss-players + + bus_putchar1(gc#a_hssVol) + bus_putchar1(vol) + +PUB hss_peek(n): wert 'hss: registerwert auslesen +''funktionsgruppe : hss +''funktion : zugriff auf die internen playerregister; leider sind die register +'' : nicht dokumentiert; 48 long-register +''eingabe : - +''ausgabe : - +''busprotokoll : [104][put.regnr][sub_getlong.regwert] +'' : regnr - registernummer +'' : regwert - long + + bus_putchar1(gc#a_hssPeek) 'kommando peek senden + bus_putchar1(n) 'kommando peek senden + wert := bus_getlong1 '32-bit-wert lesen + +PUB hss_intreg(n): wert 'hss: interfaceregister auslesen +''funktionsgruppe : hss +''funktion : abfrage eines hss-playerregisters (16bit) durch regnatix +''busprotokoll : [105][put.regnr][get.reghwt][get.regnwt] +'' : regnr - 0..24 (5 x 5 register) +'' : reghwt - höherwertiger teil des 16bit-registerwertes +'' : regnwt - niederwertiger teil des 16bit-registerwertes +'' +''0 iEndFlag iRowFlag iEngineC iBeatC iRepeat globale Playerwerte +''5 iNote iOktave iVolume iEffekt iInstrument Soundkanal 1 +''10 iNote iOktave iVolume iEffekt iInstrument Soundkanal 2 +''15 iNote iOktave iVolume iEffekt iInstrument Soundkanal 3 +''20 iNote iOktave iVolume iEffekt iInstrument Soundkanal 4 +'' +''iEndFlag Repeat oder Ende wurde erreicht +''iRowFlag Trackerzeile (Row) ist fertig +''iEngineC Patternzähler +''iBeatC Beatzähler (Anzahl der Rows) +''iRepeat Zähler für Loops + + bus_putchar1(gc#a_hssIntReg) 'kommando peek senden + bus_putchar1(n) 'kommando peek senden + wert := bus_getchar1 '16-bit-wert lesen, hsb/lsb + wert := (wert<<8) + bus_getchar1 + +PUB sfx_setslot(adr,slot) | i,n 'sfx: sendet sfx-daten in sfx-slot +''funktionsgruppe : sfx +''funktion : die daten für ein sfx-slot werden werden von regnatix gesetzt +''eingabe : - +''ausgabe : - +''busprotokoll : [108][put.slot][put.daten(0)]..[put.daten(31)] +'' : slot - $00..$0f nummer der freien effektpuffer +'' : daten - 32 byte effektdaten +'' +''struktur der effektdaten: +'' +''[wav ][len ][freq][vol ] grundschwingung +''[lfo ][lfw ][fma ][ama ] modulation +''[att ][dec ][sus ][rel ] hüllkurve +''[seq ] (optional) +'' +''[wav] wellenform +'' 0 sinus (0..500hz) +'' 1 schneller sinus (0..1khz) +'' 2 dreieck (0..500hz) +'' 3 rechteck (0..1khz) +'' 4 schnelles rechteck (0..4khz) +'' 5 impulse (0..1,333hz) +'' 6 rauschen +''[len] tonlänge $0..$fe, $ff endlos +''[freq] frequenz $00..$ff +''[vol] lautstärke $00..$0f +'' +''[lfo] low frequency oscillator $ff..$01 +''[lfw] low frequency waveform +'' $00 sinus (0..8hz) +'' $01 fast sine (0..16hz) +'' $02 ramp up (0..8hz) +'' $03 ramp down (0..8hz) +'' $04 square (0..32hz) +'' $05 random +'' $ff sequencer data (es folgt eine sequenzfolge [seq]) +''[fma] frequency modulation amount +'' $00 no modulation +'' $01..$ff +''[ama] amplitude modulation amount +'' $00 no modulation +'' $01..$ff +''[att] attack $00..$ff +''[dec] decay $00..$ff +''[sus] sustain $00..$ff +''[rel] release $00..$ff + + bus_putchar1(gc#a_sfxSetSlot) + bus_putchar1(slot) 'slotnummer senden + repeat i from 0 to 31 '32 byte sfx-daten senden + n := byte[adr + i] + bus_putchar1(n) + +PUB sfx_fire(slot,chan) 'sfx: triggert einen bestimmten soundeffekt +''funktionsgruppe : sfx +''funktion : effekt aus einem effektpuffer abspielen +''busprotokoll : [107][put.slot][put.chan] +'' : slot - $00..$0f nummer der freien effektpuffer +'' : slot - $f0..ff vordefinierte effektslots +'' : chan - 0/1 stereokanal auf dem der effekt abgespielt werden soll +''vordefinierte effekte : &f0 - warnton +'' : $f1 - signalton +'' : $f2 - herzschlag schnell +'' : $f3 - herzschlag langsam +'' : $f4 - telefon +'' : $f5 - phaser :) +'' : $f6 - pling +'' : $f7 - on +'' : $f8 - off + + bus_putchar1(gc#a_sfxFire) + bus_putchar1(slot) 'slotnummer senden + bus_putchar1(chan) 'channel senden + +PUB sfx_keyoff(chan) 'sfx: release-phase wird eingeleitet +''funktionsgruppe : sfx +''funktion : release-phase wird eingeleitet +''busprotokoll : [108][put.chan] +'' : chan - 0/1 stereokanal auf dem der effekt abgespielt werden soll + + bus_putchar1(gc#a_sfxKeyOff) + bus_putchar1(chan) 'slotnummer senden + +PUB sfx_stop(chan) 'sfx: effekt wird augenblicklich beendet +''funktionsgruppe : sfx +''funktion : effekt wird augenblicklich beendet +''busprotokoll : [108][put.chan] +'' : chan - 0/1 stereokanal auf dem der effekt abgespielt werden soll + + bus_putchar1(gc#a_sfxStop) + bus_putchar1(chan) 'slotnummer senden + + +CON ''------------------------------------------------- Wave + +PUB wav_play(stradr): status | len,i 'sdw: spielt wav-datei direkt von sd-card +''funktionsgruppe : sdw +''funktion : wav-datei von sd-card abspielen +''busprotokoll : [150][sub.putstr][get.err] +'' : err - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdwStart) + bus_putstr1(stradr) + status := bus_getchar1 + +PUB wav_stop:status 'sdw: wave-wiedergabe beenden +''funktionsgruppe : sdw +''funktion : wav-player signal zum stoppen senden +'' : wartet bis player endet und quitiert erst dann +''busprotokoll : [151][get.err] +'' : err - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdwStop) + status := bus_getchar1 + +PUB wav_status: status 'sdw: status des players abfragen +''funktionsgruppe : sdw +''funktion : status des wav-players abfragen +''busprotokoll : [152][get.status] +'' : status - status des wav-players +'' : 0: wav fertig (player beendet) +'' : 1: wav wird abgespielt + + bus_putchar1(gc#a_sdwStatus) + status := bus_getchar1 + +PUB wav_lvol(vol) 'sdw: linke lautstärke einstellen +''funktionsgruppe : sdw +''funktion : lautstärke links einstellen +''busprotokoll : [153][get.vol] +'' : vol - lautstärke 0..100 + + bus_putchar1(gc#a_sdwLeftVol) + bus_putchar1(vol) + +PUB wav_rvol(vol) 'sdw: rechte lautstärke einstellen +''funktionsgruppe : sdw +''funktion : lautstärke rechts einstellen +''busprotokoll : [154][get.vol] +'' : vol - lautstärke 0..100 + + bus_putchar1(gc#a_sdwRightVol) + bus_putchar1(vol) + +PUB wav_pause:status 'sdw: wave-pause +''funktionsgruppe : sdw +''funktion : wav-player signal für pause/weiter senden +'' : wartet bis player endet und quitiert erst dann +''busprotokoll : [151][get.err] +'' : err - fehlernummer entspr. liste + + bus_putchar1(gc#a_sdwPause) + status := bus_getchar1 + +PUB wav_len:len 'sdw: wav-länge abfragen +''funktionsgruppe : sdw +''funktion : wav-länge abfragen +''busprotokoll : [154][sub_getlong.pos][sub_getlong.len] +'' : len - länge wav-datei +'' : pos - position in der wav-datei + + bus_putchar1(gc#a_sdwPosition) + bus_getlong1 + len := bus_getlong1 + +PUB wav_pos:pos 'sdw: wav-position abfragen +''funktionsgruppe : sdw +''funktion : wav-länge abfragen +''busprotokoll : [154][sub_getlong.pos][sub_getlong.len] +'' : len - länge wav-datei +'' : pos - position in der wav-datei + + bus_putchar1(gc#a_sdwPosition) + pos := bus_getlong1 + bus_getlong1 + +CON ''------------------------------------------------- SIDCog DMP-Player + +PUB sid_mdmpplay(stradr): err 'sid: dmp-datei mono auf sid2 abspielen +''funktionsgruppe : sid +''funktion : dmp-datei auf sid2 von sd-card abspielen +''busprotokoll : [157][sub.putstr][get.err] +'' : err - fehlernummer entspr. liste + + bus_putchar1(gc#a_s_mdmpplay) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sid_sdmpplay(stradr): err 'sid: dmp-datei stereo auf beiden sid's abspielen +''funktionsgruppe : sid +''funktion : sid: dmp-datei stereo auf beiden sid's abspielen +''busprotokoll : [158][sub.putstr][get.err] +'' : err - fehlernummer entspr. liste + + bus_putchar1(gc#a_s_sdmpplay) + bus_putstr1(stradr) + err := bus_getchar1 + +PUB sid_dmpstop + bus_putchar1(gc#a_s_dmpstop) + +PUB sid_dmppause + bus_putchar1(gc#a_s_dmppause) + +PUB sid_dmpstatus: status + bus_putchar1(gc#a_s_dmpstatus) + status := bus_getchar1 + +PUB sid_dmppos: wert + bus_putchar1(gc#a_s_dmppos) + wert := bus_getlong1 + bus_getlong1 + +PUB sid_dmplen: wert + bus_putchar1(gc#a_s_dmppos) + bus_getlong1 + wert := bus_getlong1 + +PUB sid_mute(sidnr) 'sid: chips stummschalten + bus_putchar1(gc#a_s_mute) + bus_putchar1(sidnr) + +PUB sid_dmpreg: stradr | i 'sid: dmp-register empfangen +' daten im puffer +' word frequenz kanal 1 +' word frequenz kanal 2 +' word frequenz kanal 3 +' byte volume + + i := 0 + bus_putchar1(gc#a_s_dmpreg) + repeat 7 + byte[@strpuffer + i++] := bus_getchar1 + return @strpuffer + +CON ''------------------------------------------------- SIDCog1-Funktionen + +PUB sid1_setRegister(reg,val) + bus_putchar1(gc#a_s1_setRegister) + bus_putchar1(reg) + bus_putchar1(val) + +PUB sid1_updateRegisters(regadr)|i + bus_putchar1(gc#a_s1_updateRegisters) + repeat 25 + bus_putchar1(byte[regadr++]) + +PUB sid1_setVolume(vol) + bus_putchar1(gc#a_s1_setVolume) + bus_putchar1(vol) + +PUB sid1_play(channel, freq, waveform, attack, decay, sustain, release) + bus_putchar1(gc#a_s1_play) + bus_putchar1(channel) + bus_putlong1(freq) + bus_putchar1(waveform) + bus_putchar1(attack) + bus_putchar1(decay) + bus_putchar1(sustain) + bus_putchar1(release) + +PUB sid1_noteOn(channel, freq) + bus_putchar1(gc#a_s1_noteOn) + bus_putchar1(channel) + bus_putlong1(freq) + +PUB sid1_noteOff(channel) + bus_putchar1(gc#a_s1_noteOff) + bus_putchar1(channel) + +PUB sid1_setFreq(channel,freq) + bus_putchar1(gc#a_s1_setFreq) + bus_putchar1(channel) + bus_putlong1(freq) + +PUB sid1_setWaveform(channel,waveform) + bus_putchar1(gc#a_s1_setWaveform) + bus_putchar1(channel) + bus_putchar1(waveform) + +PUB sid1_setPWM(channel, val) + bus_putchar1(gc#a_s1_setPWM) + bus_putchar1(channel) + bus_putlong1(val) + +PUB sid1_setADSR(channel, attack, decay, sustain, release ) + bus_putchar1(gc#a_s1_setADSR) + bus_putchar1(channel) + bus_putchar1(attack) + bus_putchar1(decay) + bus_putchar1(sustain) + bus_putchar1(release) + +PUB sid1_setResonance(val) + bus_putchar1(gc#a_s1_setResonance) + bus_putchar1(val) + +PUB sid1_setCutoff(freq) + bus_putchar1(gc#a_s1_setCutoff) + bus_putlong1(freq) + +PUB sid1_setFilterMask(ch1,ch2,ch3) + bus_putchar1(gc#a_s1_setFilterMask) + bus_putchar1(ch1) + bus_putchar1(ch2) + bus_putchar1(ch3) + +PUB sid1_setFilterType(lp,bp,hp) + bus_putchar1(gc#a_s1_setFilterType) + bus_putchar1(lp) + bus_putchar1(bp) + bus_putchar1(hp) + +PUB sid1_enableRingmod(ch1,ch2,ch3) + bus_putchar1(gc#a_s1_enableRingmod) + bus_putchar1(ch1) + bus_putchar1(ch2) + bus_putchar1(ch3) + +PUB sid1_enableSynchronization(ch1,ch2,ch3) + bus_putchar1(gc#a_s1_enableSynchronization) + bus_putchar1(ch1) + bus_putchar1(ch2) + bus_putchar1(ch3) +CON ''------------------------------------------------- SIDCog2-Funktionen + +PUB sid2_setRegister(reg,val) + bus_putchar1(gc#a_s2_setRegister) + bus_putchar1(reg) + bus_putchar1(val) + +PUB sid2_updateRegisters(regadr)|i + bus_putchar1(gc#a_s2_updateRegisters) + repeat 25 + bus_putchar1(byte[regadr++]) + +PUB sid2_setVolume(vol) + bus_putchar1(gc#a_s2_setVolume) + bus_putchar1(vol) + +PUB sid2_play(channel, freq, waveform, attack, decay, sustain, release) + bus_putchar1(gc#a_s2_play) + bus_putchar1(channel) + bus_putlong1(freq) + bus_putchar1(waveform) + bus_putchar1(attack) + bus_putchar1(decay) + bus_putchar1(sustain) + bus_putchar1(release) + +PUB sid2_noteOn(channel, freq) + bus_putchar1(gc#a_s2_noteOn) + bus_putchar1(channel) + bus_putlong1(freq) + +PUB sid2_noteOff(channel) + bus_putchar1(gc#a_s2_noteOff) + bus_putchar1(channel) + +PUB sid2_setFreq(channel,freq) + bus_putchar1(gc#a_s2_setFreq) + bus_putchar1(channel) + bus_putlong1(freq) + +PUB sid2_setWaveform(channel,waveform) + bus_putchar1(gc#a_s2_setWaveform) + bus_putchar1(channel) + bus_putchar1(waveform) + +PUB sid2_setPWM(channel, val) + bus_putchar1(gc#a_s2_setPWM) + bus_putchar1(channel) + bus_putlong1(val) + +PUB sid2_setADSR(channel, attack, decay, sustain, release ) + bus_putchar1(gc#a_s2_setADSR) + bus_putchar1(channel) + bus_putchar1(attack) + bus_putchar1(decay) + bus_putchar1(sustain) + bus_putchar1(release) + +PUB sid2_setResonance(val) + bus_putchar1(gc#a_s2_setResonance) + bus_putchar1(val) + +PUB sid2_setCutoff(freq) + bus_putchar1(gc#a_s2_setCutoff) + bus_putlong1(freq) + +PUB sid2_setFilterMask(ch1,ch2,ch3) + bus_putchar1(gc#a_s2_setFilterMask) + bus_putchar1(ch1) + bus_putchar1(ch2) + bus_putchar1(ch3) + +PUB sid2_setFilterType(lp,bp,hp) + bus_putchar1(gc#a_s2_setFilterType) + bus_putchar1(lp) + bus_putchar1(bp) + bus_putchar1(hp) + +PUB sid2_enableRingmod(ch1,ch2,ch3) + bus_putchar1(gc#a_s2_enableRingmod) + bus_putchar1(ch1) + bus_putchar1(ch2) + bus_putchar1(ch3) + +PUB sid2_enableSynchronization(ch1,ch2,ch3) + bus_putchar1(gc#a_s2_enableSynchronization) + bus_putchar1(ch1) + bus_putchar1(ch2) + bus_putchar1(ch3) + +CON ''------------------------------------------------- COM-Funktionen + +PUB com_init(baud) 'com: serielle schnittstele neu initialisieren + + bus_putchar1(gc#a_comInit) + bus_putlong1(baud) + +PUB com_tx(char) 'com: zeichen senden + + bus_putchar1(gc#a_comTx) + bus_putchar1(char) + +PUB com_rx:char 'com: zeichen empfangen + + bus_putchar1(gc#a_comRx) + char := bus_getchar1 + +OBJ '' B E L L A T R I X + +CON ''------------------------------------------------- CHIP-MANAGMENT + +PUB belsetcolor(cnr,color) 'chip-mgr: farbregister setzen +''funktionsgruppe : cmgr +''funktion : farbregister setzen +''busprotokoll : [cmd][put.cnr][sub_putlong.color] +'' : cnr - nummer des farbregisters 0..15 +'' : color - erster wert + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrsetcol) + bus_putchar2(cnr) + bus_putlong2(color) + +PUB belgetcolor(cnr):color 'chip-mgr: farbregister abfragen +''funktionsgruppe : cmgr +''funktion : farbregister abfragen +''busprotokoll : [cmd][put.cnr][sub_getong.color] +'' : cnr - nummer des farbregisters 0..15 +'' : color - erster wert + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetcol) + bus_putchar2(cnr) + color := bus_getlong2 + + +PUB belgetresx:resx 'chip-mgr: x-auflösung abfragen +''funktionsgruppe : cmgr +''funktion : x-auflösung abfragen +''busprotokoll : [cmd][sub_getlong.resx] +'' : resx - x-auflösung + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetresx) + resx := bus_getlong2 + +PUB belgetresy:resy 'chip-mgr: y-auflösung abfragen +''funktionsgruppe : cmgr +''funktion : y-auflösung abfragen +''busprotokoll : [cmd][sub_getlong.resy] +'' : resy - y-auflösung + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetresy) + resy := bus_getlong2 + +PUB belgetcols:cols 'chip-mgr: anzahl der textspalten abfragen +''funktionsgruppe : cmgr +''funktion : anzahl der textspalten abfragen +''busprotokoll : [cmd][get.cols] +'' : rows - anzahl der textspalten + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetcols) + cols := bus_getchar2 + +PUB belgetrows:rows 'chip-mgr: anzahl der textzeilen abfragen +''funktionsgruppe : cmgr +''funktion : anzahl der textzeilen abfragen +''busprotokoll : [cmd][get.rows] +'' : rows - anzahl der textzeilen + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetrows) + rows := bus_getchar2 + +PUB belgetver:ver 'chip-mgr: version abfragen +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''busprotokoll : [cmd][sub_getlong.ver] +'' : ver - version +'' +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''version = $00_01_01_01 + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetver) + ver := bus_getlong2 + +PUB belgetspec:spec 'chip-mgr: spezifikationen abfragen +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''busprotokoll : [089][sub_getlong.spec] +'' : spec - spezifikation +'' +'' +'' +---------- +'' | +-------- +'' | |+------- vektor +'' | ||+------ grafik +'' | |||+----- text +'' | ||||+---- maus +'' | |||||+--- tastatur +'' | ||||||+-- vga +'' | |||||||+- tv +''spezifikation = %00000000_00000000_00000000_00010110 + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetspec) + spec := bus_getlong2 + +PUB belgetcogs:belcogs 'chip-mgr: verwendete cogs abfragen + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrgetcogs) 'code 5 = freie cogs + belcogs := bus_getchar2 'statuswert empfangen + +PUB belreset 'chip-mgr: bellatrix reset +{{breset - bellatrix neu starten}} + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrreboot) 'code 99 = reboot + +PUB belload(stradr)| n,rc,ii,plen 'chip-mgr: neuen bellatrix-code booten + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrload) 'code 87 = code laden + waitcnt(cnt + 2_000_000) 'warte bis bel fertig ist + bload(stradr) + waitcnt(cnt + 2_000_000) 'warte bis bel fertig ist + +PUB bload(stradr) | n,rc,ii,plen 'system: bellatrix mit grafiktreiber initialisieren +{{bload(stradr) - bellatrix mit grafiktreiber initialisieren + wird zusätzlich zu belload gebraucht, da situationen auftreten, in denen bella ohne reset (kaltstart) mit + einem treiber versorgt werden muß. ist der bella-loader aktiv, reagiert er nicht auf das reset-kommando. + stradr - adresse eines 0-term-strings mit dem dateinamen des bellatrixtreibers +}} + +' kopf der bin-datei einlesen ------------------------------------------------------ + rc := sdopen("r",stradr) 'datei öffnen + repeat ii from 0 to 15 '16 bytes header --> bellatrix + n := sdgetc + bus_putchar2(n) + sdclose 'bin-datei schießen + +' objektgröße empfangen + plen := bus_getchar2 << 8 'hsb empfangen + plen := plen + bus_getchar2 'lsb empfangen + +' bin-datei einlesen ------------------------------------------------------ + sdopen("r",stradr) 'bin-datei öffnen + repeat ii from 0 to plen-1 'datei --> bellatrix + n := sdgetc + bus_putchar2(n) + sdclose + +CON ''------------------------------------------------- KEYBOARD + +PUB key:wert 'key: holt tastaturcode +{{key:wert - key: übergibt tastaturwert}} + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_keycode) 'code 2 = tastenwert holen + wert := bus_getchar2 'tastenwert empfangen + +PUB keyspec:wert 'key: statustasten zum letzten tastencode + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_keyspec) 'code 2 = tastenwert holen + wert := bus_getchar2 'wert empfangen + + +PUB keystat:status 'key: übergibt tastaturstatus +{{keystat:status - key: übergibt tastaturstatus}} + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_keystat) 'code 1 = tastaturstatus + status := bus_getchar2 'statuswert empfangen + +PUB keywait:n 'key: wartet bis taste gedrückt wird +{{keywait: n - key: wartet bis eine taste gedrückt wurde}} + repeat + until keystat > 0 + return key + +PUB input(stradr,anz) | curpos,i,n 'key: stringeingabe +{{input(stradr,anz) - key: stringeingabe}} + + curpos := curgetx 'cursorposition merken + i := 0 + repeat + n := keywait 'auf taste warten + if n == $0d + quit + if (n == CHAR_BS)&(i>0) 'backspace + printbs + i-- + byte[stradr][i] := 0 + elseif i < anz 'normales zeichen + printchar(n) + byte[stradr][i] := n + i++ + byte[stradr][i] := 0 + +CON ''------------------------------------------------- SCREEN + +PUB debug_belval(q) + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(255) + bus_putchar2(q) + return bus_getlong2 + +PUB print(stringptr) 'screen: bildschirmausgabe einer zeichenkette (0-terminiert) +{{print(stringptr) - screen: bildschirmausgabe einer zeichenkette (0-terminiert)}} + repeat strsize(stringptr) + bus_putchar2(byte[stringptr++]) + +PUB printq(stringptr) 'screen: zeichenkette ohne steuerzeichen (0-terminiert) +{{print(stringptr) - screen: bildschirmausgabe einer zeichenkette (0-terminiert)}} + repeat strsize(stringptr) + bus_putchar2(gc#b_cmd) + bus_putchar2(gc#b_printqchar) + bus_putchar2(byte[stringptr++]) + +PUB printcstr(eadr) | i,len 'screen: bildschirmausgabe einer zeichenkette im eram! (mit längenbyte) +{{printcstr(eadr) - screen: bildschirmausgabe einer zeichenkette im eram (mit längenbyte)}} + len := ram_rdbyte(1,eadr) + repeat i from 1 to len + eadr++ + bus_putchar2(ram_rdbyte(1,eadr)) + + +PUB printdec(value) | i 'screen: dezimalen zahlenwert auf bildschirm ausgeben +{{printdec(value) - screen: dezimale bildschirmausgabe zahlenwertes}} + if value < 0 'negativer zahlenwert + -value + printchar("-") + i := 1_000_000_000 + repeat 10 'zahl zerlegen + if value => i + printchar(value / i + "0") + value //= i + result~~ + elseif result or i == 1 + bus_putchar2("0") + i /= 10 'nächste stelle + +PUB printhex(value, digits) 'screen: hexadezimalen zahlenwert auf bildschirm ausgeben +{{hex(value,digits) - screen: hexadezimale bildschirmausgabe eines zahlenwertes}} + value <<= (8 - digits) << 2 + repeat digits + printchar(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + +PUB printbin(value, digits) 'screen: binären zahlenwert auf bildschirm ausgeben + + value <<= 32 - digits + repeat digits + printchar((value <-= 1) & 1 + "0") + +PUB printchar(c):c2 'screen: einzelnes zeichen auf bildschirm ausgeben +{{printchar(c) - screen: bildschirmausgabe eines zeichens}} + bus_putchar2(c) + c2 := c + +PUB printqchar(c):c2 'screen: zeichen ohne steuerzeichen ausgeben +{{printqchar(c) - screen: bildschirmausgabe eines zeichens}} + bus_putchar2(gc#b_cmd) + bus_putchar2(gc#b_printqchar) + bus_putchar2(c) + c2 := c + +PUB printctrl(c) 'screen: präfix für steuersequenzen +{{printctrl(c) - screen: steuerzeichen von $100 bis $1FF wird an terminal gesendet}} + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_printctrl) 'code 3 = sonderzeichen senden + bus_putchar2(c & $0FF) 'unteres byte senden ' + +PUB printnl 'screen: $0D - CR ausgeben +{{printnl - screen: $0D - CR ausgeben}} + bus_putchar2(gc#b_crlf) + +PUB printcls 'screen: screen löschen +{{printcls - screen: screen löschen}} + printchar(gc#b_cls) + +PUB curhome 'screen: cursorposition auf erste position setzen +{{curhome - screen: cursorposition auf erste position setzen}} + printchar(gc#b_home) + +PUB curpos1 'screen: setzt cursor auf spalte 1 in zeile +{{curpos1 - screen: setzt cursor auf spalte 1 in zeile}} + printchar(gc#b_pos1) + +PUB curon 'screen: schaltet cursor an +{{curon - screen: schaltet cursor an}} + printchar(gc#b_curon) + +PUB curoff 'screen: schaltet cursor aus +{{curon - screen: schaltet cursor aus}} + printchar(gc#b_curoff) + +PUB scrollup 'screen: scrollt screen eine zeile hoch +{{scrollup - screen: scrollt screen eine zeile hoch}} + printchar(gc#b_scrollup) + +PUB scrolldown 'screen: scrollt screen eine zeile runter +{{scrolldown - screen: scrollt screen eine zeile runter}} + printchar(gc#b_scrolldown) + +PUB printbs 'screen: backspace +{{curon - screen: backspace senden}} + printchar(gc#b_backspace) + +PUB printtab 'screen: zur nächsten tabulatorposition +{{printtab - screen: zur nächsten tabulatorposition}} + printchar(gc#b_tab) + +PUB printlogo(x,y) 'screen: logo ausgeben + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_printlogo) 'logo ausgeben + bus_putchar2(x) + bus_putchar2(y) + +PUB curchar(char) 'screen: setzt cursorzeichen +{{curchar - screen: setzt cursorzeichen}} + printctrl(gc#b_setcur) + bus_putchar2(char) + +PUB cursetx(x) 'screen: setzt cursorposition auf x +{{cursetx - screen: setzt cursorposition auf x}} + printctrl(gc#b_setx) + bus_putchar2(x) + +PUB cursety(y) 'screen: setzt cursorposition auf y +{{cursety - screen: setzt cursorposition auf y}} + printctrl(gc#b_sety) + bus_putchar2(y) + +PUB curgetx: x 'screen: abfrage x-position cursor +{{curgetx: x - 'screen: abfrage x-position cursor}} + printctrl(gc#b_getx) + return bus_getchar2 + +PUB curgety: y 'screen: abfrage y-position cursor +{{curgetx: y - 'screen: abfrage y-position cursor}} + printctrl(gc#b_gety) + return bus_getchar2 + +PUB setcolor(color) 'screen: farbe setzen +{{setcolor(color) - screen: setzt farbwert}} + printctrl(gc#b_setcol) + bus_putchar2(color) + +PUB settabs(tnr,tpos) 'screen: setzt eine tabulatorposition + printctrl(gc#b_tabset) + bus_putchar2(tnr) + bus_putchar2(tpos) + +PUB set_wscr(scrnr) 'setzt screen, in welchen geschrieben wird +''funktion : schaltet die ausgabe auf einen bestimmten screen +''eingabe : scrnr - nummer des screens 1..SCREENS +''ausgabe : - +''busprotokoll : [0][088][put.scrnr] + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrwscr) + bus_putchar2(scrnr) + +PUB set_dscr(scrnr) 'setzt screen, welcher angezeigt wird +''funktion : schaltet die anzeige auf einen bestimmten screen +''eingabe : scrnr - nummer des screens 1..SCREENS +''ausgabe : - +''busprotokoll : [0][088][put.scrnr] + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_mgrdscr) + bus_putchar2(scrnr) + +PUB windefine(w, x0, y0, xn, yn) 'window: fenster definieren +''funktionsgruppe : window +''funktion : Window (=Scroll-Region) festlegen +''busprotokoll : [cmd][put.winnum][put.x0][put.y0][put.xn][put.yn] + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_wdef) + bus_putchar2(w) + bus_putchar2(x0) + bus_putchar2(y0) + bus_putchar2(xn) + bus_putchar2(yn) + +PUB winset(w) 'window: aktives fenster wählen +''funktionsgruppe : window +''funktion : vordefiniertes Window (=Scroll-Region) auswählen +''busprotokoll : [cmd][put.winnum] + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_wset) + bus_putchar2(w) + +PUB wingetcols:cols 'window: anzahl der textspalten abfragen +''funktionsgruppe : window +''funktion : anzahl der textspalten abfragen +''busprotokoll : [cmd][get.wincols] +'' : cols - anzahl der textspalten + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_wgetcols) + cols := bus_getchar2 + +PUB wingetrows:rows 'window: anzahl der textzeilen abfragen +''funktionsgruppe : window +''funktion : anzahl der textzeilen abfragen +''busprotokoll : [cmd][get.winrows] +'' : rows - anzahl der textzeilen + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_wgetrows) + rows := bus_getchar2 + +PUB winoframe 'window: rahmen zeichnen +''funktionsgruppe : window +''funktion : Rahmen ausserhalb des aktuellen Window zeichnen +''busprotokoll : [cmd] + + bus_putchar2(gc#b_cmd) 'kommandosequenz einleiten + bus_putchar2(gc#b_woframe) + +PUB wincursetx(x) 'screen: setzt cursorposition auf x +{{cursetx - screen: setzt cursorposition auf x}} + printctrl(gc#b_wsetx) + bus_putchar2(x) + +PUB wincursety(y) 'screen: setzt cursorposition auf y +{{cursety - screen: setzt cursorposition auf y}} + printctrl(gc#b_wsety) + bus_putchar2(y) + +PUB wincurgetx: x 'screen: abfrage x-position cursor +{{curgetx: x - 'screen: abfrage x-position cursor}} + printctrl(gc#b_wgetx) + return bus_getchar2 + +PUB wincurgety: y 'screen: abfrage y-position cursor +{{curgetx: y - 'screen: abfrage y-position cursor}} + printctrl(gc#b_wgety) + return bus_getchar2 + + +PUB screeninit 'screen: löschen, kopfzeile ausgeben und setzen +{{screeninit(stradr,n) - screen löschen, kopfzeile ausgeben und setzen}} + curoff + printctrl(gc#b_sinit) + ifnot (belgetspec & 1) 'wenn kein tv-modus + printnl + printlogo(0,0) + curhome + curon + ram_wrbyte(0,0,SIFLAG) + + +OBJ '' R E G N A T I X + +CON ''------------------------------------------------- BUS +'prop 1 - administra (bus_putchar1, bus_getchar1) +'prop 2 - bellatrix (bus_putchar2, bus_getchar2) + +PUB bus_init 'bus: initialisiert bussystem +{{bus_init - bus: initialisierung aller bussignale }} + outa[bus_wr] := 1 ' schreiben inaktiv + outa[reg_ram1] := 1 ' ram1 inaktiv + outa[reg_ram2] := 1 ' ram2 inaktiv + outa[reg_prop1] := 1 ' prop1 inaktiv + outa[reg_prop2] := 1 ' prop2 inaktiv + outa[busclk] := 0 ' busclk startwert + outa[reg_al] := 0 ' strobe aus + dira := db_in ' datenbus auf eingabe schalten + outa[18..8] := 0 ' adresse a0..a10 auf 0 setzen + outa[23] := 1 ' obere adresse in adresslatch übernehmen + outa[23] := 0 + +PUB bus_putchar1(c) 'bus: byte an administra senden +{{bus_putchar1(c) - bus: byte senden an prop1 (administra)}} + outa := %00001000_01011000_00000000_00000000 'prop1=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, prop1=1, busclk=0 + +PUB bus_getchar1: wert 'bus: byte vom administra empfangen +{{bus_getchar1:wert - bus: byte empfangen von prop1 (administra)}} + outa := %00000110_01011000_00000000_00000000 'prop1=0, wr=1, busclk=1 + waitpeq(%00000000_00000000_00000000_00000000,%00001000_00000000_00000000_00000000,0) 'hs=0? + wert := ina[7..0] 'daten einlesen + outa := %00000100_01111000_00000000_00000000 'prop1=1, busclk=0 + +PUB bus_getword1: wert 'bus: 16 bit von administra empfangen hsb/lsb + + wert := bus_getchar1 << 8 + wert := wert + bus_getchar1 + +PUB bus_putword1(wert) 'bus: 16 bit an administra senden hsb/lsb + + bus_putchar1(wert >> 8) + bus_putchar1(wert) + +PUB bus_getlong1: wert 'bus: long von administra empfangen hsb/lsb + + wert := bus_getchar1 << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar1 << 16 + wert := wert + bus_getchar1 << 8 + wert := wert + bus_getchar1 + +PUB bus_putlong1(wert) 'bus: long zu administra senden hsb/lsb + + bus_putchar1(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar1(wert >> 16) + bus_putchar1(wert >> 8) + bus_putchar1(wert) + +PUB bus_getstr1: stradr | len,i 'bus: string von administra empfangen + + len := bus_getchar1 'längenbyte empfangen + repeat i from 0 to len - 1 '20 zeichen dateinamen empfangen + strpuffer[i] := bus_getchar1 + strpuffer[i] := 0 + return @strpuffer + +PUB bus_putstr1(stradr) | len,i 'bus: string zu administra senden + + len := strsize(stradr) + bus_putchar1(len) + repeat i from 0 to len - 1 + bus_putchar1(byte[stradr++]) + +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 + +PUB bus_getchar2: wert 'bus: byte vom prop1 (bellatrix) empfangen +{{bus_getchar2:wert - bus: byte empfangen von prop2 (bellatrix)}} + outa := %00000110_00111000_00000000_00000000 'prop2=0, wr=1, busclk=1 + waitpeq(%00000000_00000000_00000000_00000000,%00001000_00000000_00000000_00000000,0) 'hs=0? + wert := ina[7..0] 'daten einlesen + outa := %00000100_01111000_00000000_00000000 'prop2=1, busclk=0 + +PUB bus_getword2: wert 'bus: 16 bit von bellatrix empfangen hsb/lsb + + wert := bus_getchar2 << 8 + wert := wert + bus_getchar2 + +PUB bus_putword2(wert) 'bus: 16 bit an bellatrix senden hsb/lsb + + bus_putchar2(wert >> 8) + bus_putchar2(wert) + +PUB bus_getlong2: wert 'bus: long von bellatrix empfangen hsb/lsb + + wert := bus_getchar2 << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar2 << 16 + wert := wert + bus_getchar2 << 8 + wert := wert + bus_getchar2 + +PUB bus_putlong2(wert) 'bus: long an bellatrix senden hsb/lsb + + bus_putchar2(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar2(wert >> 16) + bus_putchar2(wert >> 8) + bus_putchar2(wert) + +CON ''------------------------------------------------- eRAM/SPEICHERVERWALTUNG +{ + +Und so funktioniert es: Der Speicher (hier geht es nur um den eRAM!) ist in drei Teile gesplittet: + + 1. Ramdisk + 2. Heap + 3. Systemvariablen + +Wofür ist das jetzt gut? + +Das unkomlizierte Speichermodell: Wenn man in seinem Programm unkompliziert Speicher braucht, der nicht resident +gehalten werden muss, nutzt man einfach die Routinen ram_* um auf diesen zuzugreifen. Nach dem Beenden +des Programms ist dieser Speicher (Heap) aber dann vogelfrei. Für die Adressierung mit diesen Routinen gibt es +zwei Modis: + + 1. sysmod - Hier entspricht die Adresse 0 auch der wirklichen physischen Adresse 0. + 2. usrmod - Hier entspricht die Adresse 0 dem Wert von "rbas" - ist also virtuell. + +In einem normalen Programm wird man den usrmod verwenden und nur auf den freien Speicher (Heap) zwischen rbas +und rend zugreifen. Das klingt im ersten Moment kompliziert, ist aber ganz einfach: wenn es einfach sein soll, +arbeite ich im usrmod und bekomme von Adresse 0000..nnnn den Bereich zwischen Ramdisk und den Systemvariablen +(rbas..rend) zu "sehen". Möchte aber ein Systemprogramm zum Beispiel auf die Systemvariablen oder die Internas +der Ramdisk zugreifen, so ist der sysmod gefragt. In diesem Modus wird der eRAM direkt adressiert. + +Die Ramdisk: Braucht die Anwendung aber residenten Speicher, so kann man sich einen Speicherblock als +Datei in der Ramdisk erzeugen und auf den Inhalt auch per direkter Adressierung mit rd_rdbyte/rd_wrbyte +zugreifen. In der Kommandozeile Regime ist es dann möglich, per xdir/xload und xsave auf diesen Speicher +bzw. Dateien zuzugreifen. + +Ach ja: Mit der Ramdisk ist es auch möglich mehrere Dateien zu öffnen und zu verwenden - rd_open liefert dafür +eine Filenummer fnr, die man bei allen Operationen benutzen muss! :) + +Wichtig ist es nur zu verstehen, dass der freie Speicher bei Verwendung der Ramdisk vogelfrei ist, +wenn die Anwendung beendet wird: Speichert ein Programm dort Daten und kehrt zur Kommandozeile zurück, +wird zum Beispiel durch laden oder speichern einer Datei in der Ramdisk die Variable "rbas" und +damit der freie Bereich in seiner Größe verändert ---> unsere Daten im freien Bereich befinden sich also nun +im usrmod an einer anderen Stelle oder sind überschrieben. + + + memory-map: + + 0000 --> datei 1 'ab adresse 0 liegen die dateien der ramdisk als + datei 2 'verkettete liste. das erste freie byte hinter der + ... 'wird mit der variable "rbas" definiert. + datei n + + rbas --> usermem start 'zwischen rbas und rend liegt der freie ram. + ... + rend --> usermen ende + + sysvar --> systemvariablen 'ab dieser adresse befinden sich die systemvariablem im eram + + + aufbau datei ramdisk: + + 1 long zeiger auf nächste datei (oder 0 bei letzter datei) + 1 long datenlänge + 12 byte dateiname 8+3-string + nn byte daten + + aufbau ftab: + + fnr dateinummer + + fnr 0 usermem + fnr 1..7 dateien + + fix := fnr * FCNT index in ftab + + ftab[fix+0] startadresse daten + ftab[fix+1] endadresse daten + ftab[fix+2] position in datei +} + +CON + + STARTRD = 0 'startadresse der ramdisk + FILES = 8 'maximale anzahl von RAMDisk-Dateien, die gleichzeitig geöffnet werden können + FTCNT = 3 'anzahl longs pro eintrag + + sysmod = 0 + usrmod = 1 + + RDHLEN = 20 ' 4+4+12 - headerlänge + +VAR + + long ftab[(files)*FTCNT] 'filedeskriptortabelle + '1. long = startadresse daten + '2. long = endadresse daten + '3. long = position in der datei + long dpos 'position im dir (dir/next) + byte dstr[13] 'string für dateinamen + +DAT + +'rdinit byte "ramdisk1.ram",0 +rdinit byte "[RAMDRIVE] ",0 + +PUB rd_open(stradr):fnr | adr,eadr,fix 'ramdisk: datei öffnen +'fnr = 0 - fehler +'fnr > 0 - nummer der geöffneten datei + + 'datei suchen, adresse ermitteln + ifnot adr := rd_searchadr(stradr) + return 0 + + 'freien eintrag in ftab suchen + fix := 0 + repeat FILES + if ftab[fix] == -1 + quit + fix += 3 + + if fix > FILES * FTCNT + return -1 + + 'eintrag setzen + if (eadr := ram_rdlong(sysmod,adr)) + eadr-- 'nicht letzte datei + else + eadr := rbas -1 'letzte datei (zeiger = 0), es folgt usermem + + ftab[fix+0] := adr + RDHLEN 'startadresse daten + ftab[fix+1] := eadr 'endadresse daten + ftab[fix+2] := 0 'position rücksetzen + + fnr := fix/3 + +PUB rd_close(fnr) | fix 'ramdisk: datei schliessen + + if (fnr > 0) AND (fnr =< FILES) + fix := fnr * FTCNT + ftab[fix+0] := -1 'startadresse daten + ftab[fix+1] := -1 'endadresse daten + ftab[fix+2] := -1 'position + +PUB rd_getftab(fix): wert 'ramdisk: ftab auslesen + + wert := ftab[fix] + +PUB rd_getinit: flag 'ramdisk: abfrage ob rd initialisiert ist + + return ram_rdbyte(sysmod,RAMDRV) + +PUB rd_newfile(stradr,len) | adr1,adr2,i,char,nx 'ramdisk: neue datei erzeugen +' +' dpos --> 4 byte - (zeiger auf next eintrag) +' 4 byte - dateilänge +' 12 byte - name 8+3 +' len byte - daten + + if ram_rdbyte(sysmod,RAMDRV) + + 'zeiger auf header der letzten datei setzen + adr1 := 0 + repeat + nx := ram_rdlong(sysmod,adr1) + if nx + adr1 := nx + until nx == 0 'letzter zeiger ist 0 + + 'header der neuen datei setzen + adr2 := adr1 + ram_rdlong(sysmod,adr1+4) + RDHLEN 'startadresse der neuen datei + ram_wrlong(sysmod,0,adr2) 'neuer zeiger wird nun 0 (letzte datei) + ram_wrlong(sysmod,len,adr2+4) 'länge der datei + + 'dateinamen setzen + i := adr2 + 8 + repeat 12 'alle zeichen löschen + ram_wrbyte(sysmod," ",i++) + i := 0 + repeat 12 'string mit namen übertragen + char := byte[stradr+i] + ifnot char + quit + ram_wrbyte(sysmod,char,adr2+8+i++) + + 'rbas hinter neue datei setzen + ram_setbas(adr2 + RDHLEN + len) + + 'pointer in vorigem header setzen + ram_wrlong(sysmod,adr2,adr1) + +PUB rd_init|i,j 'ramdisk: system initialisieren + + ifnot ram_rdbyte(sysmod,RAMDRV) + + i := STARTRD + ram_wrlong(sysmod,0,i) 'zeiger schreiben (letzter zeiger ist 0) + i += 4 + ram_wrlong(sysmod,1,i) 'dateilänge schreiben + i += 4 + repeat j from 0 to 11 'namen schreiben + ram_wrbyte(sysmod,byte[@rdinit+j],i++) + ram_wrbyte(sysmod,0,i++) '1 datenbyte + ram_setbas(i) 'neue basis für userbereich setzen + ram_wrbyte(sysmod,1,RAMDRV) 'globales Flag setzen + + 'ftab löschen + i := 0 + repeat files * FTCNT + ftab[i++] := -1 + + ftab[0] := ram_getbas 'erster eintrag ist userram + ftab[1] := ram_getend + ftab[2] := 0 + +PUB rd_del(stradr):err | adr,d,s,nx,len,blk 'ramdisk: datei löschen + + 'grösse berechnen + if (adr := rd_searchadr(stradr)) > 0 + err := 0 + len := ram_rdlong(sysmod, adr+4) + RDHLEN + nx := ram_rdlong(sysmod,adr) + blk := ram_getbas - nx + + 'block verschieben/löschen + if nx + d := adr + s := adr + len + repeat blk + ram_wrbyte(sysmod,ram_rdbyte(sysmod,s++),d++) + + 'fbas neu setzen + ram_setbas(ram_getbas - len) + + 'verlinkung in der liste aktualisieren + ifnot nx + 'neu letzte datei markieren, wenn gelöschte datei die letzte war + adr := 0 + repeat until ram_rdlong(sysmod,adr) == ram_getbas + adr := ram_rdlong(sysmod,adr) + ram_wrlong(sysmod,0,adr) + else + 'header der nachfolgenden dateien neu setzen + repeat while ram_rdlong(sysmod,adr) + nx := ram_rdlong(sysmod,adr) + nx := nx - len + ram_wrlong(sysmod,nx,adr) + adr := nx + else + err := 5 + return err + +PUB rd_rename(stradr1,stradr2): err | i,adr,char 'ramdisk: datei umbenennen + + err := 0 + 'datei suchen, adresse ermitteln + ifnot adr := rd_searchadr(stradr1) + return 5 + + 'neuen namen setzen + i := adr + 8 + repeat 12 'alle zeichen löschen + ram_wrbyte(sysmod," ",i++) + i := 0 + repeat 12 'string mit namen übertragen + char := byte[stradr2+i] + ifnot char + quit + ram_wrbyte(sysmod,char,adr+8+i++) + + +PUB rd_searchdat(stradr):adr 'ramdisk: name --> adresse daten + + if (adr := rd_searchadr(stradr)) + return adr + RDHLEN + +PUB rd_searchadr(stradr):adr | hp,nx,i,j,c 'ramdisk: name --> adresse header +' adr = 0 name nicht gefunden +' adr > 0 adresse des headers + + hp := STARTRD + adr := STARTRD + repeat + nx := ram_rdlong(sysmod,hp) + + 'string kopieren + i := 0 + j := hp + 8 + repeat + c := ram_rdbyte(sysmod,j+i) + if c == " " + c := 0 + dstr[i++] := c + until (i == 12) OR (c == " ") + dstr[i] := 0 + + 'string vergleichen + if strcomp(stradr,@dstr) + adr := hp + + hp := nx + + until (nx == 0) OR (adr > 0) + dpos := adr + return adr + +PUB rd_get(fnr): wert | adr,fix 'ramdisk: nächstes byte aus datei lesen + + fix := fnr * FTCNT + adr := ftab[fix+0] + ftab[fix+2] + wert := ram_rdbyte(sysmod,adr) + rd_seek(fnr,ftab[fix+2]+1) + +PUB rd_getback(fnr): wert | adr,fix 'ramdisk: voriges byte aus datei lesen + + fix := fnr * FTCNT + adr := ftab[fix+0] + ftab[fix+2] + wert := ram_rdbyte(sysmod,adr-1) + rd_seek(fnr,ftab[fix+2]-1) + +PUB rd_put(fnr,wert) | adr,fix 'ramdisk: nächstes byte in datei schreiben + + fix := fnr * FTCNT + adr := ftab[fix+0] + ftab[fix+2] + ram_wrbyte(sysmod,wert,adr) + rd_seek(fnr,ftab[fix+2]+1) + +PUB rd_seek(fnr,fpos) | len,fix 'ramdisk: position in datei setzen + + fix := fnr * FTCNT + len := ftab[fix+1] - ftab[fix] + if (fpos => 0) AND (fpos =< len) + ftab[fix+2] := fpos 'ramdisk: position in datei setzen + +PUB rd_rdbyte(fnr,adr):wert | fix 'ramdisk: byte aus datei lesen + + fix := fnr * FTCNT + adr := ftab[fix]+adr + if (adr =< ftab[fix+1]) + wert := ram_rdbyte(sysmod,adr) + +PUB rd_wrbyte(fnr,wert,adr) | fix 'ramdisk: byte in datei schreiben + fix := fnr * FTCNT + adr := ftab[fix]+adr + if (adr =< ftab[fix+1]) + ram_wrbyte(sysmod,wert,adr) + +PUB rd_len(fnr): len | fix 'ramdisk: dateilänge einer geöffgneten datei abfragen + + fix := fnr * FTCNT + len := ftab[fix+1] - ftab[fix+0] + 1 + +PUB rd_dlen: len 'ramdisk: verzeichnis dateilänge abfragen + + len := ram_rdlong(sysmod,dpos+4) + +PUB rd_dir 'ramdisk: verzeichnis öffnen + + dpos := STARTRD + +PUB rd_next:stradr | i,j 'ramdisk: verzeichniseintrag lesen + + 'ende erreicht? + if dpos == TRUE + return 0 + + 'namen kopieren + i := 0 + j := dpos + 8 + repeat 12 + dstr[i] := ram_rdbyte(sysmod,j+i) + i++ + byte[@dstr+i] := 0 + + 'zeiger auf nächste datei setzen + dpos := ram_rdlong(sysmod,dpos) + if dpos == 0 + dpos := TRUE 'nächster eintrag ungültig + return @dstr 'gültiger name + +PUB absadr(usradr): sysadr 'ramdisk: wandelt usermode-adr --> absolutadr + + sysadr := usradr - rbas + +PUB ram_getbas: adr 'ramdisk: virtuelle basisadresse abfragen + 'return rbas + return ram_rdlong(sysmod,RAMBAS) + +PUB ram_getend: adr 'ramdisk: endadresse abfragen + 'return rend + return ram_rdlong(sysmod,RAMEND) + +PUB ram_getfree: free 'ramdisk: freien speicher ermitteln + + return ram_rdlong(sysmod,RAMEND) - ram_rdlong(sysmod,RAMBAS) + +PUB ram_setbas(adr) 'ramdisk: virtuelle basisadresse setzen + ram_wrlong(sysmod,adr,RAMBAS) + rbas := adr + ftab[0] := adr 'erster eintrag ist userram + ftab[1] := SYSVAR - adr + +PUB ram_rdbyte(sys,adresse):wert 'eram: liest ein byte vom eram +{{ram_rdbyte(adresse):wert - eram: ein byte aus externem ram lesen}} +'rambank 1 000000 - 07FFFF +'rambank 2 080000 - 0FFFFF +'sys = 0 - systemmodus, keine virtualisierung +'sys = 1 - usermodus, virtualisierte adresse +'sysmodus: der gesamte speicher (2 x 512 KB) werden durchgängig adressiert +'usermodus: adresse 0 = rambas +' adresse max = ramend + + if sys 'usermodus? + adresse += rbas 'adresse virtualisieren + if adresse > rend 'adressbereich überschritten? + return 0 + + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + outa[23] := 1 'obere adresse in adresslatch übernehmen + outa[23] := 0 + outa[18..8] := adresse 'niederwertige adresse setzen + if adresse < $080000 'rambank 1? + outa[reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben) + wert := ina[7..0] 'speicherzelle einlesen + outa[reg_ram1] := 1 'ram1 deselektieren + else + outa[reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben) + wert := ina[7..0] 'speicherzelle einlesen + outa[reg_ram2] := 1 'ram2 deselektieren + +PUB ram_wrbyte(sys,wert,adresse) 'eram: schreibt ein byte in eram +{{ram_wrbyte(wert,adresse) - eram: ein byte in externen ram schreiben}} +'rambank 1 000000 - 07FFFF +'rambank 2 080000 - 08FFFF +'sys = 0 - systemmodus, keine virtualisierung +'sys = 1 - usermodus, virtualisierte adresse +'sysmodus: der gesamte speicher (2 x 512 KB) werden durchgängig adressiert +'usermodus: adresse 0 = rambas +' adresse max = ramend +' + + if sys 'usermodus? + adresse += rbas 'adresse virtualisieren + if adresse > rend 'adressbereich überschritten? + return + + outa[bus_wr] := 0 'schreiben aktivieren + dira := db_out 'datenbus --> ausgang + outa[7..0] := wert 'wert --> datenbus + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + outa[23] := 1 'obere adresse in adresslatch übernehmen + outa[23] := 0 + outa[18..8] := adresse 'niederwertige adresse setzen + if adresse < $080000 'rambank 1? + outa[reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben) + outa[reg_ram1] := 1 'ram1 deselektieren + else + outa[reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben) + outa[reg_ram2] := 1 'ram2 deselektieren + dira := db_in 'datenbus --> eingang + outa[bus_wr] := 1 'schreiben deaktivieren + +PUB ram_rdlong(sys,eadr): wert 'eram: liest long ab eadr +{{ram_rdlong - eram: liest long ab eadr}} +'sys = 0 - systemmodus, keine virtualisierung +'sys = 1 - usermodus, virtualisierte adresse + + wert := ram_rdbyte(sys,eadr) + wert += ram_rdbyte(sys,eadr + 1) << 8 + wert += ram_rdbyte(sys,eadr + 2) << 16 + wert += ram_rdbyte(sys,eadr + 3) << 24 + +PUB ram_rdword(sys,eadr): wert 'eram: liest word ab eadr +{{ram_rdlong(eadr):wert - eram: liest word ab eadr}} +'sys = 0 - systemmodus, keine virtualisierung +'sys = 1 - usermodus, virtualisierte adresse + + wert := ram_rdbyte(sys,eadr) + wert += ram_rdbyte(sys,eadr + 1) << 8 + +PUB ram_wrlong(sys,wert,eadr) | n 'eram: schreibt long ab eadr +{{ram_wrlong(wert,eadr) - eram: schreibt long ab eadr}} +'sys = 0 - systemmodus, keine virtualisierung +'sys = 1 - usermodus, virtualisierte adresse + + n := wert & $FF + ram_wrbyte(sys,n,eadr) + n := (wert >> 8) & $FF + ram_wrbyte(sys,n,eadr + 1) + n := (wert >> 16) & $FF + ram_wrbyte(sys,n,eadr + 2) + n := (wert >> 24) & $FF + ram_wrbyte(sys,n,eadr + 3) + +PUB ram_wrword(sys,wert,eadr) | n 'eram: schreibt word ab eadr +{{wr_word(wert,eadr) - eram: schreibt word ab eadr}} +'sys = 0 - systemmodus, keine virtualisierung +'sys = 1 - usermodus, virtualisierte adresse + + n := wert & $FF + ram_wrbyte(sys,n,eadr) + n := (wert >> 8) & $FF + ram_wrbyte(sys,n,eadr + 1) + +CON ''------------------------------------------------- TOOLS + +PUB hram_print(adr,rows) + + repeat rows + printnl + printhex(adr,4) + printchar(":") + printchar(" ") + repeat 8 + printhex(byte[adr++],2) + printchar(" ") + adr := adr - 8 + repeat 8 + printqchar(byte[adr++]) + +CON ''------------------------------------------------- G0-FUNKTIONEN + +CON 'G0-Konstanen + +g0_xtiles = 16 +g0_ytiles = 12 + +PUB g0_keystat:wert 'g0: tastaturstatus abfragen + bus_putchar2(gc#g0_keystat) + return bus_getchar2 + +PUB g0_keycode:wert 'g0: tastaturcode abfragen + bus_putchar2(gc#g0_keycode) + return bus_getchar2 + +PUB g0_keyspec:wert 'g0: sondertasten abfragen + bus_putchar2(gc#g0_keyspec) + return bus_getchar2 + +PUB g0_keywait:wert 'g0: warten auf taste + repeat until keystat > 0 + return g0_keycode + +PUB g0_clear 'g0: aktiven screenpuffer löschen + bus_putchar2(gc#g0_clear) + +PUB g0_copy 'g0: zeichenpuffer --> anzeigepuffer + bus_putchar2(gc#g0_copy) + +PUB g0_color(n) 'g0: zeichenfarbe wählen + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + bus_putchar2(gc#g0_color) + bus_putchar2(n) + +PUB g0_width(n) 'g0: stiftbreite setzen + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + bus_putchar2(gc#g0_width) + bus_putchar2(n) + +PUB g0_colorwidth(n,m) 'g0: zeichenfarbe/stiftbreite setzen + bus_putchar2(gc#g0_colorwidth) + bus_putchar2(n) + bus_putchar2(m) + +PUB g0_plot(x,y) 'g0: punkt zeichen + bus_putchar2(gc#g0_plot) + bus_putchar2(x) + bus_putchar2(y) + +PUB g0_line(x,y) 'g0: linie zu punkt zeichnen + +'' Draw a line to point +'' +'' x,y - endpoint + + bus_putchar2(gc#g0_line) + bus_putchar2(x) + bus_putchar2(y) + +PUB g0_arc(x,y,xr,yr,angle,anglestep,steps,arcmode) 'g0: kreis zeichnen +'17: gr.arc(gc,gc,gc,gc,gw,gw,gc,gc) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + bus_putchar2(gc#g0_arc) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(xr) + bus_putchar2(yr) + bus_putword2(angle) + bus_putword2(anglestep) + bus_putchar2(steps) + bus_putchar2(arcmode) + +PUB g0_vec(x,y,vecscale,vecangle,heap_index) 'g0: vektorsprite zeichnen + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' heap_index - heapindex to sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + bus_putchar2(gc#g0_vec) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(vecscale) + bus_putword2(vecangle) + bus_putword2(heap_index) + +PUB g0_vecarc(x,y,xr,yr,angle,vscale,vangle,heap_index) 'g0: vektorsprite an kreisposition zeichnen + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vscale - scale of vector sprite ($100 = 1x) +'' vangle - rotation angle of vector sprite in bits[12..0] +'' heap_index - heapindex to sprite definition + + bus_putchar2(gc#g0_vecarc) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(xr) + bus_putchar2(yr) + bus_putword2(angle) + bus_putchar2(vscale) + bus_putword2(vangle) + bus_putword2(heap_index) + +PUB g0_pix(x,y,pixrot,heap_index) 'g0: pixelsprite zeichnen + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' heap_index - heapindex to sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + bus_putchar2(gc#g0_pix) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(pixrot) + bus_putword2(heap_index) + +PUB g0_pixarc(x,y,xr,yr,angle,pixrot,heap_index) 'g0: pixelsprite an kreisposition zeichnen + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' heap_index - heapindex to sprite definition + + bus_putchar2(gc#g0_pixarc) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(xr) + bus_putchar2(yr) + bus_putword2(angle) + bus_putchar2(pixrot) + bus_putword2(heap_index) + +PUB g0_text(x,y,heap_index) 'g0: text zeichnen + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' heap_index - heapindex to 0term-sting + + bus_putchar2(gc#g0_text) + bus_putchar2(x) + bus_putchar2(y) + bus_putword2(heap_index) + +PUB g0_textarc(x,y,xr,yr,angle,heap_index) 'g0: text an kreisposition zeichnen + +'' Draw text at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' heap_index - heapindex to 0term-sting + + + bus_putchar2(gc#g0_textarc) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(xr) + bus_putchar2(yr) + bus_putword2(angle) + bus_putword2(heap_index) + +PUB g0_textmode(x_scale,y_scale,spacing,justification) 'g0: textparameter setzen + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + bus_putchar2(gc#g0_textmode) + bus_putchar2(x_scale) + bus_putchar2(y_scale) + bus_putchar2(spacing) + bus_putchar2(justification) + +PUB g0_box(x, y, box_width, box_height) 'g0: rechteck zeichnen + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + bus_putchar2(gc#g0_box) + bus_putchar2(x) + bus_putchar2(y) + bus_putchar2(box_width) + bus_putchar2(box_height) + +PUB g0_quad(x1, y1, x2, y2, x3, y3, x4, y4) 'g0: viereck zeichnen + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + + bus_putchar2(gc#g0_quad) + bus_putchar2(x1) + bus_putchar2(y1) + bus_putchar2(x2) + bus_putchar2(y2) + bus_putchar2(x3) + bus_putchar2(y3) + bus_putchar2(x4) + bus_putchar2(y4) + +PUB g0_tri(x1, y1, x2, y2, x3, y3) 'g0: dreieck zeichnen + +'' Draw a solid triangle + + bus_putchar2(gc#g0_tri) + bus_putchar2(x1) + bus_putchar2(y1) + bus_putchar2(x2) + bus_putchar2(y2) + bus_putchar2(x3) + bus_putchar2(y3) + +PUB g0_printdec(x,y,n,digit,string_ptr,heap_index)|i,j,m'g0: dezimalzahl ausgeben + + j := n + repeat i from digit-1 to 0 + m := j//10 + ifnot m < 0 + byte[string_ptr + heap_index][i] := m + "0" + j := j / 10 + byte[string_ptr + heap_index][digit] := 0 + g0_datblk(string_ptr,heap_index,digit+1) + g0_text(x,y,heap_index) + +PUB g0_colortab(ptr)|i 'g0: farbtabelle senden + + bus_putchar2(gc#g0_colortab) + i := 0 + repeat 64 + bus_putlong2(long[ptr][i++]) + + +PUB g0_screen(ptr)|i 'g0: tilescreen senden + + bus_putchar2(gc#g0_screen) + i := 0 + repeat g0_xtiles * g0_ytiles + bus_putword2(word[ptr][i++]) + +PUB g0_datblk(heapadr,index,len)|i 'g0: heapdaten senden + + bus_putchar2(gc#g0_datblk) + bus_putword2(index) + bus_putword2(len) + i := 0 + repeat len + bus_putchar2(byte[heapadr + index + i++]) + + + +PUB g0_datlen:len 'g0: heapgröße in bellatrix ermitteln + bus_putchar2(gc#g0_datlen) + len := bus_getword2 + +PUB g0_dynamic 'g0: dynamischen modus aktivieren (double buffer) + bus_putchar2(gc#g0_dynamic) + +PUB g0_static 'g0: statischen modus aktivieren + bus_putchar2(gc#g0_static) + +PUB g0_reboot 'g0: reboot chipcode + bus_putchar2(gc#g0_reboot) + +PUB g0_load 'g0: g0-code laden + + sddmset(DM_USER) 'u-marker setzen + sddmact(DM_SYSTEM) 's-marker aktivieren + belload(string("g0key.bel")) + sddmact(DM_USER) 'u-marker aktivieren + +DAT + org 0 +' +' Entry +' +entry jmp entry 'just loops + + +regsys byte "reg.sys",0 +belsys byte "bel.sys",0 +admsys byte "adm.sys",0 + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + + diff --git a/lizenz.txt b/lizenz.txt new file mode 100644 index 0000000..fade992 --- /dev/null +++ b/lizenz.txt @@ -0,0 +1,23 @@ + +Hive-Project +------------------------------------------------------------------------- +Der Hive ist ein Open-Hardware und Free-Software DIY-Computersystem auf +der Basis von drei Parallax P8X32 "Propeller" Mikrocontrollern. + + +Lizenze +------------------------------------------------------------------------- +Das Betriebssystem TriOS steht unter MIT-Lizenz. Die Schaltung und das +Board-Layout ist unter Creative-Commons CC-BY-SA 3.0 lizensiert. + +MIT-Lizenz: http://www.opensource.org/licenses/mit-license.php +CC-BY-SA 3.0: http://creativecommons.org/licenses/by-sa/3.0/de/ + +Informationen zum Projekt +------------------------------------------------------------------------- +http://hive-project.de + + +Urheberrechtsangabe +------------------------------------------------------------------------- +Copyright (c) 2009 Ingo Kripahle \ No newline at end of file diff --git a/logbuch.txt b/logbuch.txt new file mode 100644 index 0000000..f2af8f1 --- /dev/null +++ b/logbuch.txt @@ -0,0 +1,380 @@ +r56 - 11-05-2013-dr235 + +und weiter gehts mit dem frhjahresputz: + +- umstellung administra-codes (admflash, admay, admsid) auf externe konstantendefinitionen + +belflash: + +- fehler im loader behoben + +lib: + +- gui-objekte fr textoberflche eingefgt: + + gui-dlbox - listenbox fr dateien + gui-input - einfaches eingabefenster + gui-pbar - hinweisdialog mit progress-bar (z.bsp. fr kopieraktionen) + gui-wbox - warnbox mit auswahloptionen + +system/regnatix: + +- filemanager fm zugefgt +- metal-loader m zugefgt +- tool zum erstellen von tapes (mental-containerdateien) zugefgt +- wplay: kleinen darstellungsfehler behoben +- yplay: konstanten ausgelagert + +system/sonstiges: + +- manual zugefgt: error, fm + + + +r55 - 15-04-2013-dr235 + +fllige aufrumarbeitem im quelltext: +- umstellung bildschirmcodes/g0-treiber auf externe konstantendefinitionen +- umstellung signaldefinitionen fr belflash/g0key +- alle funktionsnummern fr bella werden nun in lib\glob-con.spin verwaltet und gepflegt +- screeninit gibt jetzt keine kopfzeile mehr aus, geht jetzt ber fensterfunktionen +- anpassung div. tools + +system\regnatix\regime: +- leere eingaben werden jetzt ignoriert +- mit der Cursortaste kann jetzt der letzte Befehl wiederholt werden + +r54 - 15-04-2013-dr235: + +flash\admflash.spin +- grundlegende com-funktionen eingefgt + +lib\reg-ios.spin +- com-funktionen +- ios.screeninit: kein logo im v-modus + +system\administra\admay\admay.spin +- sd_dmput eingefgt +- sd_eof eingefgt + +system\regnatix\admtest.spin +- korrektur bei fehlerhaftem screeninit + +system\regnatix\beltest.spin +- men eingefgt um einzelnen tests auszufhren +- anpassung an tv-modus +- neuer test fr fensterfunktionen + +system\regnatix +- tool man eingefgt +- umstrukturierung aller tool-hilfen an man +- anpassung der meisten tools an tv-modus + +system\sonstiges +- man-hilfetexte eingefgt + + +r53 - 20.02.2013 dr235/u-held: + +flash\admflash.spin +- scr-funktionen ausgefgt +flash\belflash.spin: +- fehler im loader behoben (cog0 wurde nicht in allen fllen beendet) dank dafr geht an pic :) +- farbtabellen auf 16 farben ergnzt, normalfarbe ist jetz mal retro-green :) +flash\regflash.spin: +- pause fr slaves zur initialisierung eingefgt, damit diese bei installation ohne forth sauber starten + +forth\bel.lib: +- korrektur wort bel:load +forth\sd0.lib: +- div. fehlerhafte stackkommentare korrigiert +forth\tools.lib: +- korrektur wort bel:load +forth\g0.lib: zugefgt +forth\tpix.f: zugefgt +forth\win.lib: zugefgt + +lib\reg-ios.spin: +- fehler in g0 printdec behoben +- neue sidcog-funktion: sid_dmpreg + +system\administra\admsid\admsid.spin: +- funktion sid_dmpreg eingefgt (fr triborg-player) +- funktion sd_dmput aus maincode bernommen +- funktion sd_eof aus maincode bernommen + +system\regnatix\g0test.spin: +- neue test's & effekte eingefgt + +system\regnatix\sysconf.spin: +- "sysconf /ci" zeigt nun alle 16 farben an + +system\sonstiges\green.col: +- grne retro-farbtabelle eingefgt + + +r52: +g0key.spin - Bug bei horizontaler Textzentrierung beseitigt +belflash.spin - Interface VGA/TV vereinheitlicht, umschaltbar beim Compilieren (siehe make.bat) +belf-tv.spin, belf-vga.spin - treiberspezifische Konstanten und Funktionen fr belflash.spin +bel-bus.spin - Auslagerung der Bus-Routinen aus Bellatrix-Sicht +beltest.spin - Anpassung an belflash.spin, auch im TV-Modus nutzbar +make.bat - tv.bel wird jetzt aus belflash.spin erzeugt; Einfhrung einer Variablen fr den Compiler-Aufruf +reg-ios.spin - hmm... habsch vergessen, was da gendert wurde :-( + +r51: +belflash.spin: +- verzgertes Scrolling bei abgeschaltetem Cursor +- Window-Funktionen +glob-con.spin: +- Auslagerung von globalen Konstanten (ansatzweise) +reg-ios.spin: +- Einbindung der neuen Bellatrix-Funktionen +beltest.spin: +- sline/eline-Test entfernt, Window-Test eingefgt + +27.11.2011-dr235 +- bellatrix-code fr grafikmodus 0 + keyboard hinzugefgt +- g0test - testprogramm fr g0-modus hinzugefgt +- reg-ios - g0-funktionen eingearbeitet +- make.bat angepasst + +13.11.2011-dr235 +- rtc-routinen neu eingefgt +- admterm entfernt, hat im trios keine funktion + +11.11.2011-dr235 +- umfangreicher umbau der verzeichnisstruktur: alle universellen quellen wie treiber oder klassische bibliotheken werden nun im verzeichnis "lib" gespeichert und knnen so an einer stelle gepflegt werden. +- alle anwendungen die nichts mit trios zu tun haben werden nun aus dem projekt entfernt und in einer toolbox-serie verffentlicht. damit wird trios stark entschlackt und wieder bersichtlich. +- berarbeitung der make.bat; es werden nun auch die alternativen slave-codes wie zum beispiel admsid erstellt. +- in der standardkonfiguration ist jetzt forth deaktiviert - das ist einfacher fr den einsteiger. forth ist dann "level 2". + +WICHTIG: im bst mu nun der compiler-suchpfad fr trios auf das verzeichnis "lib" eingestellt werden. + + +09.11.2011-dr235 +- fehler in regflash.spin behoben, konfiguration ohne forth konnte nicht compiliert werden +- standartkonfiguration ist jetzt ohne forth, ist einfacher fr den einstieg +- div. demos entfernt, diese werden spter getrennt in einer toolbox-serie verffentlicht + + +06.11.2011-dr235 +- fehlersuche zum problem mit dem neuen bella-loader: einige bel-dateien (guidemo, 4-boing) wurden nicht korrekt initialisiert, also starteten nicht sauber. parameter und ladevorgang ist korrekt, ursache ist wahrscheinlich eine falsche initialisierung der stackwerte im pasm-teil des loaders. als lsung kann man diese bel-dateien als eeprom-image abspeichern, diese starten korrekt. + + +23.04.2011-dr235 +- integration von propforth in trios + + +15-04-2011-dr235 +- flash-tool/rom: damit kann unter anderem eine bin-datei (z. bsp. basic) in den hi-rom (64k eeprom erforderlich!) gespeichert und mit rom gestartet werden +- bernahme der rtc-routinen von stephan +- time-kommando: anzeige/nderung datum/zeit +- perplex: experimentelles tool fr plexbus (scan/open/close/get/put) +- fterm: primitiv-terminal fr forth-hive + + +18-09-2010-dr235 +- regime: free zeigt jetzt auch die speicherbelegung des eram an +- speicherverwaltung/ramdisk integriert (beispielcode siehe eram.spin & regime.spin) +- eram.bin kann jetzt auch mit ramdisk umgehen +- regime: neue kommandos fr ramdisk +- egalisierung der namen fr den ramzugriff (lterer code mu leicht angepasst werden) +- user- und systemmode fr ramzugriff eingefgt +- erste version eine make-batch um das gesamte system zu kompilieren (nur grundsystem) +- nderung zur ios: da bst eine pfadliste zu bibliotheksordnern untersttzt, liegt (soweit das mglich ist) die ios nun nur noch unter system\regnatix + +WICHTIG: Pfad zur ios.spin im bst einstellen + + +23-08-2010-dr040 +- integration ay-emulator (admay.adm) und yplay + + +19-07-2010-dr235 +- booten eines alternativen administra-codes: befindet sich auf der karte in der root eine datei "adm.sys", so wird diese datei automatisch in administra geladen + + +11-07-2010-dr235 +- integration sid1/2-funktionen in admsid/ios +- anpassung sid-demo von ahle2 als regnatix-code (verzeichnis demo) +- diverse graphics-spielereien (verzeichnis demo) +- sysconf /af - administra neu booten (admflash.adm wird dadurch berflssig) + + +27-06-2010-dr085/235 +- admin mountet nun automatisch nach einem boot + + +26-06-2010-dr235 +- div. demos zugefgt +- shooter angepasst und eingefgt + + +20-06-2010-dr235 +- erste lauffhige SID-Player-Version fr die Kommandozeile (splay) + + +14-06-2010-dr085/235 +- Semaphoren in FATEngine korrekt eingesetzt +- Abfrage des Volume-Labels korrigiert + + +10-06-2010-dr235 +- Kommando "ramtest" zugefgt + + +09-06-2010-dr085 +- Fehler in Administra-Bootfunktion behoben + + +----------------------------------------------------------------------------------------------- + +23-04-2011-dr235 + +Ein neuer Meilenstein: PropForth ist jetzt in TriOS integriert. Als Nebeneffekt starten nun wieder, wie bei meiner ersten SpinOS-Version, alle drei Chips ihren initialen Code aus ihrem EEPROM und nicht mehr vom SD-Laufwerk. Damit gibt es vom Einschalten bis zum Forth-Prompt quasi keine fhlbare Bootzeit mehr. So gehrt es sich fr einen richtigen Homecomputer. Es ist nun mglich, unmittelbar nach dem Einschalten sofort zu programmieren. Erst wenn man zu Regime wechselt wird kurz reg.sys nachgeladen. Aber selbst die Ladezeiten sind nun durch Verwendung des SD-Blocktransfer erfreulich kurz. + +Obwohl das Grundsystem vom Forth den halben hRAM belegt, ist es als genormte Sprache doch eine wunderbare Geschichte im Hive. Viele der Ressourcen sind jetzt schon problemlos in Forth nutzbar und man kann sehr unkompliziert experimentieren. + + +02-10-2010-dr235 + +Speicherverwaltung: + +In dieser Version ist eine erste Beta-Version der Speicherverwaltung des externen RAM's enthalten. Der Speicher kann dabei in einem einfachen oder einem strukturierten Modus verwendet werden. Klingt kompliziert, ist aber ganz einfach. + +Einfacher Modus: + +Hierbei kann ein Programm auf den eRAM ber die IOS-Routinen ios.ram_* zugreifen. Wahlweise kann der Speicher im Systemmode direkt von 0 bis $07FFFF angesprochen werden, oder nur der Userbereich. Im Systemmodus ist darauf zu achten, dass eine eventuell vorhandene Ramdisk und die Systemvariablen nicht berschrieben werden, man sollte also wissen was man tut... ;) Die Ramdisk wird ab der physischen Adresse 0 als verkettete Liste verwaltet, die Systemvariablen befinden sich ab $07FFFF abwrts. + +ios.ram_wrbyte(ios#sysmod,0,ios#MAGIC) +- Schreibt den Wert 0 in die Systemvariable, um einen Kaltstart auszulsen. + +ios.ram_wrbyte(ios#sysmod,$20,$100) +- Schreibt den Wert $20 an die physische Adresse $100 im eRAM. + +Da es nun mhsam ist in einem kleinen Code solche Konflikte mit dem Systemspeicher zu vermeiden, gibt es den Usermodus. Im Usermodus wird nur genau jener freie Speicher adressiert, welcher sich zwischen Ramdisk und Systemvariablen befindet. In diesem Fall ist die Adressierung also virtualisiert. + +ios.ram_wrbyte(ios#usrmod,0,$100) +- Schreibt den Wert 0 an die Adresse $100 im Userspeicher! + +In Regime kann man mit dem Kommando "free" jetzt auch die wichtigsten Systemvariablen der Speicherverwaltung anzeigen. + +RBAS +- erste physische Adresse des Userspeichers + +REND +- Physische Adresse der letzten freien Speicherstelle des Userspeichers. + +USER +- Grsse des Userspeichers (REND - RBAS). + +RAMDRV +0 - Ramdisk ist nicht initialisiert +1 - Ramdisk ist initialisiert + +SYSVAR +- Erste physische Adresse der Systemvariablen. + +Noch genauer kann man sich die Speicherbelegung mit dem Tool "eram" anschauen. Nur ein paar Beispiele: + +"d" Anzeige des Speichers. Es werden zwei Adressspalten angezeigt. Die zweite schwarze Adresse in jeder Zeile zeigt die physische Adresse, die erste grne Adresse die virtuelle Adresse im Userspeicher. Man kann sehr gut erkennen, ab welcher Adrese der Userbereich anfngt und wo er endet. + +"d 100" Anzeige ab physischer Adresse $100 + +"d bas" Anzeige vom Start des Userspeichers. + +"n" Anzeige inkrementell fortsetzen + +Die Nutzung des Userspeichers ist sehr einfach. Es sind dabei nur folgende Regeln zu beachten: + +Man muss selbst darauf achten die Speichergrenzen nicht zu berschreiten. Bei berschreitung kann aber nichts passieren - die IOS-Routinen brechen einfach ab, allerdings werden die eigenen Daten halt nicht korrekt verarbeitet. Es werden also die Systemvariablen und die Daten in der Ramdisk geschtzt. +Der Userbereich im eRAM ist nur zur Laufzeit der Anwendung gltig. Wird die Anwendung beendet, so kann durch Regime oder eine andere Anwendung mit den Daten der Ramdisk gearbeitet werden, wodurch sich der physische Bereich des Userbereiches verndert. Wer also residente Daten ber die Laufzeit der Anwendung hinaus braucht, muss im strukturierten Modus mit der Ramdisk arbeiten. +In einer Anwendung nicht den einfachen oder strukturierten Modus mischen - das gibt Chaos, wenn man nicht ganz genau aufpasst + +Ansonsten kann man wie gehabt die schon bekannten IOS-Routinen verwenden, einzig der bergabeparameter zur Wahl des System- oder Usermodus sind hinzugekommen. Als Beispiel kann man sich die Soundplayer anschauen, die ihre Dateiliste im Userspeicher ablegen. + +Strukturierter Modus: + +Was ist aber, wenn wir einen kleinen Texteditor schreiben wollen, der seine Textdaten resident im eRAM speichern kann? Ich mchte also den Texteditor verlassen knnen, um in Regime zum Beispiel einen Assembler aufzurufen, welcher den Text dann assembliert. Darauf folgend mchte ich meinen Texteditor wieder starten und an dem Text weiter arbeiten. Dafr muss es meiner Anwendung - dem Textprogramm - mglich sein, einen Speicherbereich im eRAM zu reservieren, der von System und anderen Anwendungen respektvoll behandelt wird. + +Gedacht, getan: Im strukturierten Modus wird der Speicher in Form einer Ramdisk verwaltet. Die Dateien/Daten knnen ber ihren Namen angesprochen werden. Es kann mit put & get sequentiell, oder mit read & write direkt adressierbar auf die Daten in der Datei zugegriffen werden. + +Als erstes praktisches Beispiel mgen die neuen Kommandos in Regime selbst dienen, mit denen man die Ramdisk verwalten kann: +Neue Regime-Kommandos: + +xload - datei in ram laden +xsave - datei aus ram speichern +xdir - verzeichnis im ram anzeigen +xrename - datei im ram umbenennen +xdel - datei im ram lschen +xtype - text im ram anzeigen + +So ist es also mglich, sich in der Kommandozeile anzuschauen, welche residenten Daten die Programme aktuell angelegt haben. Sofern es Textdaten sind, knnen diese Daten auch einafch angezeigt werden. + +Die Speicherverwaltung ist allerdings noch sehr experimentell - was bedeutet, dass wohl noch einige Bugs drin sein drften. :) + +MAKE.BAT + +Diese Batchdatei im obersten Verzeichnis kompiliert das Grundsystem, bestehend aus den drei Flashdateien und den grundlegenden Kommandos im Systemverzeichnis. Ist ein erster Versuch. Was noch fehlt ist ein Fehlerlog und vielleicht noch die anderen Programme. + +09-06-2010-dr235 + +Nach nur zwei Tagen hat drohne085 (frida) das Geheimnis um die Bootroutine gelst: Die Ursache lag in einer von der FATEngine verwendeten Semaphore, welche fest auf den Lock 0 "verdrahtet" war. Diese Semaphore wird an diversen Stellen in der Engine verwendet, wurde aber beim Bootvorgang nicht gelscht oder freigegeben! Gedacht war sie, um den Bus zur SD-Card bei einem Zugriff zu verriegeln, falls mehrere Instanzen der Engine laufen, und gleichzeitig zugreifen wollen. Somit hat sich die Engine quasi selbst verriegelt und nach dem Bootvorgang als "neue Instanz" nun auch keinen Zugriff mehr - so schn kann praktische Parallelverarbeitung sein... ;) + +Hier nun eine neue und aktuelle Version mit einer temporren funktionierenden Lsung des Problems. + +Im System-Ordner gibt es jetzt folgende ausfhrbare Administra-Dateien: + +admflash.adm Standard-Flash, welches auch im EEProm gespeichert ist +admini.adm Mini-Flash ohne Sound, nor SDCard + Managment-Routinen +admled.adm Das Heartbeat-LED-Testprogramm zum direkten laden +aterm96.adm Die leicht modifizierte Kommandozeile vom Programmierer der FATEngine. Mit + diesem Administra-Code kann man direkt ber die Hostschnittstelle (9600 Baud) + mit dem Chip kommunizieren. Dokumentation der Kommandos findet man im + Verzeichnis "komponenten/fat/fatengine beta" + + +07-06-2010-dr235 + +Hier der aktuelle Stand von TriOS. Momentan kmpfe ich an einem +Komplexfehler mit dem Bootloader von Administra. Das Problem ist recht +einfach zu reproduzieren, aber leider (fr mich) nur schwer zu +erfasen: Die verwendete FATEngine besitzt eine Bootfunktion um einen +neuen BIN-Objektcode in den Propeller zu laden. Dieser Code funktioniert +auch teilweise. So kann man das Administra-Bios selbst laden und dann +auch per Regime-Kommandos verwenden: Die Kommandos "cogs" und "sysinfo" +sprechen Administra-Funktionen an, welche auch korrekt ausgefhrt werden. +Das Problem: Nach dem Bootprozess kann man keine SD-Card mehr mounten. + +Es ist auch mglich den Fehler noch weiter einzugrenzen: Wenn man die +originale FATEngine (im Verzeichnis komponenten/fat) vom Host direkt in +Administra startet, meldet sich diese in Form einer einfachen Kommando- +zeile per Hostschnittstelle. Versucht man dort eine erzeugte BIN-Datei +genau dieser Kommandozeile (demo.spin) zu booten, so hat man das gleiche +Ergebnis. + +Verzeichnisstruktur: + +bin - BIN-Dateien fr die Flash's und die SD-Card +doku - +flash - Quelltexte fr die Software in den EEProms +system - Quelltext fr ausfhrbare BIN-Dateien +zubehr - Kleine Zusatzprogramme (StarTracker, Boulder Dash...) +komponenten - Div. verwendete Objekte (FATEngine, SIDCog...) + +Installation: + +1. Flashen der drei EEProms mit den BIN-Dateien aus "bin/flash" oder + ber das Propellertool aus den Quellen "flash". + +2. SD-Card erstellen: Einfach alles aus "bin/sd-card" auf eine FAT16/32 + Karte kopieren. + +Das System bootet Regnatix und Bellatrix beim Systemstart aus den Dateien +"adm.sys", "reg.sys" bzw. "bel.sys". Diese Dateien knnen auch das Hidden-Bit gesetzt +haben. Externe Kommandos bzw. ausfhrbare BIN-Dateien werden im aktuellen +UND im System-Verzeichnis gesucht - alle Systemkommandos knnen also in das +System-Verzeichnis kopiert werden. + +Hilfe gibt es meist ber das Kommando "help" oder den Parameter "/h". diff --git a/make.bat b/make.bat new file mode 100644 index 0000000..a632071 --- /dev/null +++ b/make.bat @@ -0,0 +1,79 @@ +echo on +date /T +time /T + +REM Pfade +set sd=".\bin\sdcard" +set sd-sys=".\bin\sdcard\system" +set flash=".\bin\flash" +set libpath=".\lib" +set BSTC=bstc.exe + +REM ---------------------------------------------------------------- +REM Alte Versionen lschen + +del %flash%\*.* /Q +del %sd%\*.* /Q +del %sd-sys%\*.* /Q + +REM ---------------------------------------------------------------- +REM Flashdateien erzeugen +REM --> \bin\flash + +%BSTC% -L %libpath% -b -O a .\flash\administra\admflash.spin +copy admflash.binary %flash% +rename admflash.binary admsys.adm +move admsys.adm %sd-sys% + +%BSTC% -L %libpath% -D __VGA -b -O a .\flash\bellatrix\belflash.spin +copy belflash.binary %flash% +rename belflash.binary vga.bel +move vga.bel %sd-sys% + +%BSTC% -L %libpath% -D __TV -b -O a .\flash\bellatrix\belflash.spin +rename belflash.binary tv.bel +move tv.bel %sd-sys% + +%BSTC% -L %libpath% -b -O a .\flash\regnatix\regflash.spin +move regflash.binary %flash% + +REM ---------------------------------------------------------------- +REM Startdateie erzeugen +REM reg.sys (Regime) +REM --> \bin\sdcard\ + +%BSTC% -L %libpath% -b -O a .\system\regnatix\regime.spin +rename regime.binary reg.sys +move reg.sys %sd% + + +REM ---------------------------------------------------------------- +REM Slave-Dateien erzeugen +REM admsid, admay, admterm +REM htxt, g0key + +%BSTC% -L %libpath% -b -O a .\system\administra\admsid\admsid.spin +%BSTC% -L %libpath% -b -O a .\system\administra\admay\admay.spin +rename *.binary *.adm + +%BSTC% -L %libpath% -b -O a .\system\bellatrix\bel-htext\htext.spin +%BSTC% -L %libpath% -b -O a .\system\bellatrix\bel-g0\g0key.spin +rename *.binary *.bel + +move *.adm %sd-sys% +move *.bel %sd-sys% + + +REM ---------------------------------------------------------------- +REM Systemdateien erzeugen +REM - div. externe Kommandos +REM - div. Systemdateien (Farbtabellen usw.) +REM --> \bin\sdcard\system\ + +for %%x in (.\system\regnatix\*.spin) do %BSTC% -L %libpath% -b -O a %%x +rename *.binary *.bin +move *.bin %sd-sys% +copy .\forth\*.* %sd-sys% +copy .\system\sonstiges %sd-sys% + +echo off diff --git a/makelog.bat b/makelog.bat new file mode 100644 index 0000000..a94b4fd --- /dev/null +++ b/makelog.bat @@ -0,0 +1,6 @@ +echo off +echo Erstelle TriOS... +call make.bat > make.log +echo Fertig! +pause + diff --git a/system/administra/admay/admay.spin b/system/administra/admay/admay.spin new file mode 100644 index 0000000..a923fe6 --- /dev/null +++ b/system/administra/admay/admay.spin @@ -0,0 +1,871 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle, V.Pohlers (AY-Einbau) │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Administra-Flash +Chip : Administra +Typ : Flash +Version : 00 +Subversion : 01 + +Funktion : Diese Codeversion basiert auf admini.spin und wird durch eine YM-Chip-Emulation als + Soundfunktion erweitert. + + Dieser Code wird von Administra nach einem Reset aus dem EEProm in den hRAM kopiert + und gestartet. Im Gegensatz zu Bellatrix und Regnatix, die einen Loader aus dem EEProm + laden und entsprechende Systemdateien vom SD-Cardlaufwerk booten, also im + wesentlichen vor dem Bootvorgang keine weiter Funktionalität als die Ladeprozedur + besitzen, muß das EEProm-Bios von Administra mindestens die Funktionalität des + SD-Cardlaufwerkes zur Verfügung stellen können. Es erscheint deshalb sinnvoll, dieses + BIOS gleich mit einem ausgewogenen Funktionsumfang auszustatten, welcher alle Funktionen + für das System bietet. Durch eine Bootoption kann dieses BIOS aber zur Laufzeit + ausgetauscht werden, um das Funktionssetup an konkrete Anforderungen anzupassen. + + Chip-Managment-Funktionen + - Bootfunktion für Administra + - Abfrage und Verwaltung des aktiven Soundsystems + - Abfrage Version und Spezifikation + + SD-Funktionen: + - FAT32 oder FAT16 + - Partitionen bis 1TB und Dateien bis 2GB + - Verzeichnisse + - Verwaltung aller Dateiattribute + - DIR-Marker System + - Verwaltung eines Systemordners + - Achtung: Keine Verwaltung von mehreren geöffneten Dateien! + + + +Komponenten : FATEngine 01/18/2009 Kwabena W. Agyeman MIT Lizenz + RTCEngine 11/22/2009 Kwabena W. Agyeman MIT Lizenz + +COG's : MANAGMENT 1 COG + FAT/RTC 1 COG + ------------------- + 2 Cogs + +Logbuch : + +06-05-2010-dr235 - erste version aus admflash.spin extrahiert +09-06-2010-dr085 - frida hat den fehler gefunden, welcher eine korrekte funktion der fatengine + nach einem bootvorgang von administra verhinderte :) +13-06-2010-dr235 - fehler in sd_volname korrigiert + - free/used auf fast umgestellt +18-06-2010-dr085 - fehler bei der businitialisierung: beim systemstart wurde ein kurzer impuls + auf der hs-leitung erzeugt, wodurch ein buszyklus verloren ging (symptom: + flashte man admin, so lief das system erst nach einem reset an) + - fatengine: endgültige beseitigung der feherhaften volname-abfrage + +17-08-2010-dr040 - YM-Einschluss + +Kommandoliste : + +Notizen : + +Bekannte Fehler : + + +}} + + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_01_01 + +CHIP_SPEC = gc#A_FAT|gc#A_LDR|gc#A_AYS + +' +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | +------+ d0..d7 +' |||| | | | +DB_IN = %00001001_00000000_00000000_00000000 'dira-wert für datenbuseingabe +DB_OUT = %00001001_00000000_00000000_11111111 'dira-wert für datenbusausgabe + +M1 = %00000010_00000000_00000000_00000000 'busclk=1? & /prop1=0? +M2 = %00000010_10000000_00000000_00000000 'maske: busclk & /cs (/prop1) + +M3 = %00000000_00000000_00000000_00000000 'busclk=0? +M4 = %00000010_00000000_00000000_00000000 'maske: busclk + +LED_OPEN = gc#HBEAT 'led-pin für anzeige "dateioperation" +SD_BASE = gc#A_SDD0 'baspin cardreader + + +'index für dmarker +#0, RMARKER 'root + SMARKER 'system + UMARKER 'programmverzeichnis + AMARKER + BMARKER + CMARKER + +OBJ + sdfat : "adm-fat" 'fatengine + ay : "adm-ay" 'AYcog - AY-3-891X / YM2149 emulator + gc : "glob-con" 'globale konstanten + +VAR + + long dmarker[6] 'speicher für dir-marker + byte tbuf[20] 'stringpuffer + byte tbuf2[20] +' byte sfxdat[16 * 32] 'sfx-slotpuffer +' byte fl_eof '1 = eof + + byte AYregs[16] 'AY-Register + + +CON ''------------------------------------------------- ADMINISTRA + +PUB main | cmd,err 'chip: kommandointerpreter +''funktionsgruppe : chip +''funktion : kommandointerpreter +''eingabe : - +''ausgabe : - + + init_chip 'bus/vga/keyboard/maus initialisieren + repeat + cmd := bus_getchar 'kommandocode empfangen + err := 0 + case cmd + 0: !outa[LED_OPEN] 'led blinken + +' ---------------------------------------------- SD-FUNKTIONEN + gc#a_sdMount: sd_mount("M") 'sd-card mounten ' + gc#a_sdOpenDir: sd_opendir 'direktory öffnen + gc#a_sdNextFile: sd_nextfile 'verzeichniseintrag lesen + gc#a_sdOpen: sd_open 'datei öffnen + gc#a_sdClose: sd_close 'datei schließen + gc#a_sdGetC: sd_getc 'zeichen lesen + gc#a_sdPutC: sd_putc 'zeichen schreiben + gc#a_sdGetBlk: sd_getblk 'block lesen + gc#a_sdPutBlk: sd_putblk 'block schreiben + gc#a_sdSeek: sd_seek 'zeiger in datei positionieren + gc#a_sdFAttrib: sd_fattrib 'dateiattribute übergeben + gc#a_sdVolname: sd_volname 'volumelabel abfragen + gc#a_sdCheckMounted: sd_checkmounted 'test ob volume gemounted ist + gc#a_sdCheckOpen: sd_checkopen 'test ob eine datei geöffnet ist + gc#a_sdCheckUsed: sd_checkused 'test wie viele sektoren benutzt sind + gc#a_sdCheckFree: sd_checkfree 'test wie viele sektoren frei sind + gc#a_sdNewFile: sd_newfile 'neue datei erzeugen + gc#a_sdNewDir: sd_newdir 'neues verzeichnis wird erzeugt + gc#a_sdDel: sd_del 'verzeichnis oder datei löschen + gc#a_sdRename: sd_rename 'verzeichnis oder datei umbenennen + gc#a_sdChAttrib: sd_chattrib 'attribute ändern + gc#a_sdChDir: sd_chdir 'verzeichnis wechseln + gc#a_sdFormat: sd_format 'medium formatieren + gc#a_sdUnmount: sd_unmount 'medium abmelden + gc#a_sdDmAct: sd_dmact 'dir-marker aktivieren + gc#a_sdDmSet: sd_dmset 'dir-marker setzen + gc#a_sdDmGet: sd_dmget 'dir-marker status abfragen + gc#a_sdDmClr: sd_dmclr 'dir-marker löschen + gc#a_sdDmPut: sd_dmput 'dir-marker status setzen + gc#a_sdEOF: sd_eof 'eof abfragen + +' ---------------------------------------------- CHIP-MANAGMENT + gc#a_mgrGetSpec: mgr_getspec 'spezifikation abfragen + gc#a_mgrALoad: mgr_aload 'neuen code booten + gc#a_mgrGetCogs: mgr_getcogs 'freie cogs abfragen + gc#a_mgrGetVer: mgr_getver 'codeversion abfragen + gc#a_mgrReboot: reboot 'neu starten + +' ---------------------------------------------- AY-SOUNDFUNKTIONEN + gc#a_ayStart: ay_start + gc#a_ayStop: ay_stop + gc#a_ayUpdateRegisters: ay_updateRegisters + + + + +PUB init_chip|i 'chip: initialisierung des administra-chips +''funktionsgruppe : chip +''funktion : - initialisierung des businterface +'' - grundzustand definieren (hss aktiv, systemklänge an) +''eingabe : - +''ausgabe : - + + + repeat i from 0 to 7 'evtl. noch laufende cogs stoppen + ifnot i == cogid + cogstop(i) + + 'debugverbindung + 'debugx.start(115200) ' Start des Debug-Terminals + + 'businterface initialisieren + outa[gc#bus_hs] := 1 'handshake inaktiv ,frida + dira := db_in 'datenbus auf eingabe schalten ,frida + + 'sd-card starten + clr_dmarker 'dir-marker löschen + sdfat.FATEngine + sd_mount("B") + +PUB bus_putchar(zeichen) 'chip: ein byte über bus ausgeben +''funktionsgruppe : chip +''funktion : senderoutine für ein byte zu regnatix über den systembus +''eingabe : byte zeichen +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & /prop1=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[gc#bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + outa[gc#bus_hs] := 1 'daten ungültig + dira := db_in 'bus freigeben + +PUB bus_getchar : zeichen 'chip: ein byte über bus empfangen +''funktionsgruppe : chip +''funktion : emfangsroutine für ein byte von regnatix über den systembus +''eingabe : - +''ausgabe : byte zeichen + + waitpeq(M1,M2,0) 'busclk=1? & /prop1=0? + zeichen := ina[7..0] 'daten einlesen + outa[gc#bus_hs] := 0 'daten quittieren + outa[gc#bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + +PUB clr_dmarker| i 'chip: dmarker-tabelle löschen +''funktionsgruppe : chip +''funktion : dmarker-tabelle löschen +''eingabe : - +''ausgabe : - + + i := 0 + repeat 6 'alle dir-marker löschen + dmarker[i++] := TRUE + +CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN + +PUB sub_getstr | i,len 'sub: string einlesen +''funktionsgruppe : sub +''funktion : subprotokoll um einen string von regnatix zu empfangen und im +'' : textpuffer (tbuf) zu speichern +''eingabe : - +''ausgabe : - +''busprotokoll : [get.len][get.byte(1)]..[get.byte(len)] +'' : len - länge des dateinamens + + repeat i from 0 to 19 'puffer löschen und kopieren + tbuf2[i] := tbuf[i] + tbuf[i] := 0 + len := bus_getchar 'längenbyte name empfangen + repeat i from 0 to len - 1 'dateiname einlesen + tbuf[i] := bus_getchar + +PUB sub_putstr(strptr)|len,i 'sub: string senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen string an regnatix zu senden +''eingabe : strptr - zeiger auf einen string (0-term) +''ausgabe : - +''busprotokoll : [put.len][put.byte(1)]..[put.byte(len)] +'' : len - länge des dateinamens + + len := strsize(strptr) + bus_putchar(len) + repeat i from 0 to len - 1 'string übertragen + bus_putchar(byte[strptr][i]) + +PUB sub_putlong(wert) 'sub: long senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert an regnatix zu senden +''eingabe : 32bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2][put.byte3][put.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + bus_putchar(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar(wert >> 16) + bus_putchar(wert >> 8) + bus_putchar(wert) + +PUB sub_getlong:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := bus_getchar << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar << 16 + wert := wert + bus_getchar << 8 + wert := wert + bus_getchar + + +CON ''------------------------------------------------- CHIP-MANAGMENT-FUNKTIONEN + + +PUB mgr_aload | err 'cmgr: neuen administra-code booten +''funktionsgruppe : cmgr +''funktion : administra mit neuem code booten +''eingabe : +''ausgabe : +''busprotokoll : [096][sub_getstr.fn] +'' : fn - dateiname des neuen administra-codes + sub_getstr + err := \sdfat.bootPartition(@tbuf, "C") + +PUB mgr_getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind +''funktionsgruppe : cmgr +''funktion : abfrage wie viele cogs in benutzung sind +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [097][put.cogs] +'' : cogs - anzahl der belegten cogs + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + bus_putchar(cogs) + +PUB getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + +PUB mgr_getver 'cmgr: abfrage der version +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [098][sub_putlong.ver] +'' : ver - version +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''version : $00_00_00_00 +'' + + sub_putlong(CHIP_VER) + +PUB mgr_getspec 'cmgr: abfrage der spezifikation des chips +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [089][sub_putlong.spec] +'' : spec - spezifikation +'' +'' +---------- com +'' | +-------- i2c +'' | |+------- rtc +'' | ||+------ lan +'' | |||+----- sid +'' | ||||+---- wav +'' | |||||+--- hss +'' | ||||||+-- bootfähig +'' | |||||||+- dateisystem +''spezifikation : %00000000_00000000_00000000_01001111 + + sub_putlong(CHIP_SPEC) + +CON ''------------------------------------------------- SD-LAUFWERKS-FUNKTIONEN + +PUB sd_mount(mode) | err 'sdcard: sd-card mounten frida +''funktionsgruppe : sdcard +''funktion : eingelegtes volume mounten +''eingabe : - +''ausgabe : - +''busprotokoll : [001][put.error] +'' : error - fehlernummer entspr. list + + ifnot sdfat.checkPartitionMounted 'frida + err := \sdfat.mountPartition(0,0) 'karte mounten + 'bus_putchar(err) 'fehlerstatus senden + if mode == "M" 'frida + bus_putchar(err) 'fehlerstatus senden + + ifnot err + dmarker[RMARKER] := sdfat.getDirCluster 'root-marker setzen + + err := \sdfat.changeDirectory(string("system")) + ifnot err + dmarker[SMARKER] := sdfat.getDirCluster 'system-marker setzen + + sdfat.setDirCluster(dmarker[RMARKER]) 'root-marker wieder aktivieren + else 'frida + bus_putchar(0) 'frida + +PUB sd_opendir | err 'sdcard: verzeichnis öffnen +''funktionsgruppe : sdcard +''funktion : verzeichnis öffnen +''eingabe : - +''ausgabe : - +''busprotokoll : [002] + + err := \sdfat.listReset + +PUB sd_nextfile | strpt 'sdcard: nächsten eintrag aus verzeichnis holen +''funktionsgruppe : sdcard +''funktion : nächsten eintrag aus verzeichnis holen +''eingabe : - +''ausgabe : - +''busprotokoll : [003][put.status=0] +'' : [003][put.status=1][sub_putstr.fn] +'' : status - 1 = gültiger eintrag +'' : 0 = es folgt kein eintrag mehr +'' : fn - verzeichniseintrag string + + strpt := \sdfat.listName 'nächsten eintrag holen + if strpt 'status senden + bus_putchar(1) 'kein eintrag mehr + sub_putstr(strpt) + else + bus_putchar(0) 'gültiger eintrag folgt + +PUB sd_open | err,modus 'sdcard: datei öffnen +''funktionsgruppe : sdcard +''funktion : eine bestehende datei öffnen +''eingabe : - +''ausgabe : - +''busprotokoll : [004][get.modus][sub_getstr.fn][put.error] +'' : modus - "A" Append, "W" Write, "R" Read +'' : fn - name der datei +'' : error - fehlernummer entspr. list + + modus := bus_getchar 'modus empfangen + sub_getstr + err := \sdfat.openFile(@tbuf, modus) + bus_putchar(err) 'ergebnis der operation senden + outa[LED_OPEN] := 1 + +PUB sd_close | err 'sdcard: datei schließen +''funktionsgruppe : sdcard +''funktion : die aktuell geöffnete datei schließen +''eingabe : - +''ausgabe : - +''busprotokoll : [005][put.error] +'' : error - fehlernummer entspr. list + + err := \sdfat.closeFile + bus_putchar(err) 'ergebnis der operation senden + outa[LED_OPEN] := 0 + +PUB sd_getc | n 'sdcard: zeichen aus datei lesen +''funktionsgruppe : sdcard +''funktion : zeichen aus datei lesen +''eingabe : - +''ausgabe : - +''busprotokoll : [006][put.char] +'' : char - gelesenes zeichen + + n := \sdfat.readCharacter + bus_putchar(n) + +PUB sd_putc 'sdcard: zeichen in datei schreiben +''funktionsgruppe : sdcard +''funktion : zeichen in datei schreiben +''eingabe : - +''ausgabe : - +''busprotokoll : [007][get.char] +'' : char - zu schreibendes zeichen + + \sdfat.writeCharacter(bus_getchar) + +PRI sd_eof 'sdcard: eof abfragen +''funktionsgruppe : sdcard +''funktion : eof abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [030][put.eof] +'' : eof - eof-flag + + bus_putchar(sdfat.getEOF) + +PUB sd_getblk 'sdcard: block aus datei lesen +''funktionsgruppe : sdcard +''funktion : block aus datei lesen +''eingabe : - +''ausgabe : - +''busprotokoll : [008][sub_getlong.count][put.char(1)]..[put.char(count)] +'' : count - anzahl der zu lesenden zeichen +'' : char - gelesenes zeichen + + repeat sub_getlong + bus_putchar(\sdfat.readCharacter) + + +PUB sd_putblk 'sdcard: block in datei schreiben +''funktionsgruppe : sdcard +''funktion : block in datei schreiben +''eingabe : - +''ausgabe : - +''busprotokoll : [009][sub_getlong.count][put.char(1)]..[put.char(count)] +'' : count - anzahl der zu schreibenden zeichen +'' : char - zu schreibende zeichen + + repeat sub_getlong + \sdfat.writeCharacter(bus_getchar) + +PUB sd_seek | wert 'sdcard: zeiger in datei positionieren +''funktionsgruppe : sdcard +''funktion : zeiger in datei positionieren +''eingabe : - +''ausgabe : - +''busprotokoll : [010][sub_getlong.pos] +'' : pos - neue zeichenposition in der datei + + wert := sub_getlong + \sdfat.setCharacterPosition(wert) + +PUB sd_fattrib | anr,wert 'sdcard: dateiattribute übergeben +''funktionsgruppe : sdcard +''funktion : dateiattribute abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [011][get.anr][sub_putlong.wert] +'' : anr - 0 = Dateigröße +'' : 1 = Erstellungsdatum - Tag +'' : 2 = Erstellungsdatum - Monat +'' : 3 = Erstellungsdatum - Jahr +'' : 4 = Erstellungsdatum - Sekunden +'' : 5 = Erstellungsdatum - Minuten +'' : 6 = Erstellungsdatum - Stunden +'' : 7 = Zugriffsdatum - Tag +'' : 8 = Zugriffsdatum - Monat +'' : 9 = Zugriffsdatum - Jahr +'' : 10 = Änderungsdatum - Tag +'' : 11 = Änderungsdatum - Monat +'' : 12 = Änderungsdatum - Jahr +'' : 13 = Änderungsdatum - Sekunden +'' : 14 = Änderungsdatum - Minuten +'' : 15 = Änderungsdatum - Stunden +'' : 16 = Read-Only-Bit +'' : 17 = Hidden-Bit +'' : 18 = System-Bit +'' : 19 = Direktory +'' : 20 = Archiv-Bit +'' : wert - wert des abgefragten attributes + + anr := bus_getchar + case anr + 0: wert := \sdfat.listSize + 1: wert := \sdfat.listCreationDay + 2: wert := \sdfat.listCreationMonth + 3: wert := \sdfat.listCreationYear + 4: wert := \sdfat.listCreationSeconds + 5: wert := \sdfat.listCreationMinutes + 6: wert := \sdfat.listCreationHours + 7: wert := \sdfat.listAccessDay + 8: wert := \sdfat.listAccessMonth + 9: wert := \sdfat.listAccessYear + 10: wert := \sdfat.listModificationDay + 11: wert := \sdfat.listModificationMonth + 12: wert := \sdfat.listModificationYear + 13: wert := \sdfat.listModificationSeconds + 14: wert := \sdfat.listModificationMinutes + 15: wert := \sdfat.listModificationHours + 16: wert := \sdfat.listIsReadOnly + 17: wert := \sdfat.listIsHidden + 18: wert := \sdfat.listIsSystem + 19: wert := \sdfat.listIsDirectory + 20: wert := \sdfat.listIsArchive + sub_putlong(wert) + +PUB sd_volname 'sdcard: volumenlabel abfragen +''funktionsgruppe : sdcard +''funktion : name des volumes überragen +''eingabe : - +''ausgabe : - +''busprotokoll : [012][sub_putstr.volname] +'' : volname - name des volumes +'' : len - länge des folgenden strings + + sub_putstr(\sdfat.listVolumeLabel) 'label holen und senden + +PUB sd_checkmounted 'sdcard: test ob volume gemounted ist +''funktionsgruppe : sdcard +''funktion : test ob volume gemounted ist +''eingabe : - +''ausgabe : - +''busprotokoll : [013][put.flag] +'' : flag - 0 = unmounted, 1 mounted + + bus_putchar(\sdfat.checkPartitionMounted) + +PUB sd_checkopen 'sdcard: test ob eine datei geöffnet ist +''funktionsgruppe : sdcard +''funktion : test ob eine datei geöffnet ist +''eingabe : - +''ausgabe : - +''busprotokoll : [014][put.flag] +'' : flag - 0 = not open, 1 open + + bus_putchar(\sdfat.checkFileOpen) + +PUB sd_checkused 'sdcard: anzahl der benutzten sektoren senden +''funktionsgruppe : sdcard +''funktion : anzahl der benutzten sektoren senden +''eingabe : - +''ausgabe : - +''busprotokoll : [015][sub_putlong.used] +'' : used - anzahl der benutzten sektoren + + sub_putlong(\sdfat.checkUsedSectorCount("F")) + +PUB sd_checkfree 'sdcard: anzahl der freien sektoren senden +''funktionsgruppe : sdcard +''funktion : anzahl der freien sektoren senden +''eingabe : - +''ausgabe : - +''busprotokoll : [016][sub_putlong.free] +'' : free - anzahl der freien sektoren + + sub_putlong(\sdfat.checkFreeSectorCount("F")) + +PUB sd_newfile | err 'sdcard: eine neue datei erzeugen +''funktionsgruppe : sdcard +''funktion : eine neue datei erzeugen +''eingabe : - +''ausgabe : - +''busprotokoll : [017][sub_getstr.fn][put.error] +'' : fn - name der datei +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.newFile(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_newdir | err 'sdcard: ein neues verzeichnis erzeugen +''funktionsgruppe : sdcard +''funktion : ein neues verzeichnis erzeugen +''eingabe : - +''ausgabe : - +''busprotokoll : [018][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.newDirectory(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_del | err 'sdcard: eine datei oder ein verzeichnis löschen +''funktionsgruppe : sdcard +''funktion : eine datei oder ein verzeichnis löschen +''eingabe : - +''ausgabe : - +''busprotokoll : [019][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses oder der datei +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.deleteEntry(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_rename | err 'sdcard: datei oder verzeichnis umbenennen +''funktionsgruppe : sdcard +''funktion : datei oder verzeichnis umbenennen +''eingabe : - +''ausgabe : - +''busprotokoll : [020][sub_getstr.fn1][sub_getstr.fn2][put.error] +'' : fn1 - alter name +'' : fn2 - neuer name +'' : error - fehlernummer entspr. liste + + sub_getstr 'fn1 + sub_getstr 'fn2 + err := \sdfat.renameEntry(@tbuf2,@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_chattrib | err 'sdcard: attribute ändern +''funktionsgruppe : sdcard +''funktion : attribute einer datei oder eines verzeichnisses ändern +''eingabe : - +''ausgabe : - +''busprotokoll : [021][sub_getstr.fn][sub_getstr.attrib][put.error] +'' : fn - dateiname +'' : attrib - string mit attributen +'' : error - fehlernummer entspr. liste + + sub_getstr + sub_getstr + err := \sdfat.changeAttributes(@tbuf2,@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_chdir | err 'sdcard: verzeichnis wechseln +''funktionsgruppe : sdcard +''funktion : verzeichnis wechseln +''eingabe : - +''ausgabe : - +''busprotokoll : [022][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. list + sub_getstr + err := \sdfat.changeDirectory(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_format | err 'sdcard: medium formatieren +''funktionsgruppe : sdcard +''funktion : medium formatieren +''eingabe : - +''ausgabe : - +''busprotokoll : [023][sub_getstr.vlabel][put.error] +'' : vlabel - volumelabel +'' : error - fehlernummer entspr. list + + sub_getstr + err := \sdfat.formatPartition(0,@tbuf,0) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_unmount | err 'sdcard: medium abmelden +''funktionsgruppe : sdcard +''funktion : medium abmelden +''eingabe : - +''ausgabe : - +''busprotokoll : [024][put.error] +'' : error - fehlernummer entspr. list + + err := \sdfat.unmountPartition + bus_putchar(err) 'ergebnis der operation senden + ifnot err + clr_dmarker + +PUB sd_dmact|markernr 'sdcard: einen dir-marker aktivieren +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker wird aktiviert +''eingabe : - +''ausgabe : - +''busprotokoll : [025][get.dmarker][put.error] +'' : dmarker - dir-marker +'' : error - fehlernummer entspr. list + markernr := bus_getchar + ifnot dmarker[markernr] == TRUE + sdfat.setDirCluster(dmarker[markernr]) + bus_putchar(sdfat#err_noError) + else + bus_putchar(sdfat#err_noError) + + +PUB sd_dmset|markernr 'sdcard: einen dir-marker setzen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker mit dem aktuellen verzeichnis setzen +''eingabe : - +''ausgabe : - +''busprotokoll : [026][get.dmarker] +'' : dmarker - dir-marker + + markernr := bus_getchar + dmarker[markernr] := sdfat.getDirCluster + +PUB sd_dmget|markernr 'sdcard: einen dir-marker abfragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [027][get.dmarker][sub_putlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + markernr := bus_getchar + sub_putlong(dmarker[markernr]) + +PRI sd_dmput|markernr 'sdcard: einen dir-marker übertragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker übertragen +''eingabe : - +''ausgabe : - +''busprotokoll : [029][get.dmarker][sub_getlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + markernr := bus_getchar + dmarker[markernr] := sub_getlong + +PUB sd_dmclr|markernr 'sdcard: einen dir-marker löschen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker löschen +''eingabe : - +''ausgabe : - +''busprotokoll : [028][get.dmarker] +'' : dmarker - dir-marker + + markernr := bus_getchar + dmarker[markernr] := TRUE + +DAT ' AY-Routinen + +PUB ay_start + ay.start( gc#A_SOUNDR, gc#A_SOUNDL, @AYregs ) 'audioR, audioL, @AYregs + +PUB ay_stop + ay.stop + +PUB ay_updateRegisters | i + repeat i from 0 to 13 + AYregs[i] := bus_getchar + + ifnot AYregs[13] == 255 + AYregs[13] := AYregs[13]&15 + +DAT 'dummyroutine für getcogs + org +' +' Entry: dummy-assemblercode fuer cogtest +' +entry jmp entry 'just loops + + + + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + diff --git a/system/administra/admsid/admsid.spin b/system/administra/admsid/admsid.spin new file mode 100644 index 0000000..63eae50 --- /dev/null +++ b/system/administra/admsid/admsid.spin @@ -0,0 +1,1054 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Administra-Flash (SD,SID) +Chip : Administra +Typ : Flash +Version : 00 +Subversion : 01 + +Funktion : Diese Codeversion basiert auf admini.spin und wird durch eine SID-Chip-Emulation als + Soundfunktion erweitert. Geladen werden zwei SIDCogs, wodurch insgesamt sechs unabhängige + Soundkanäle nutzbar sind, oder eine Kombination von einer SIDCog für SFX und einer SIDCog + für die Wiedergabe einer DMP-Datei direkt UND gleichzeitig von SD-Card möglich wird. + Zusätzlich zu den DMP-Files wird später noch ein einfacher Tracker integriert, welcher + die Musi nicht von SD-Card, sondern aus einem Puffer im hRam abspielt. Dadurch werden + auch während der Musikwiedergabe wieder Dateioperationen möglich, was ja so bei der + DMP-Playerroutine nicht geht. + + Infos zur SIDCog: http://forums.parallax.com/forums/default.aspx?f=25&p=1&m=409209 + + Dieser Code wird von Administra nach einem Reset aus dem EEProm in den hRAM kopiert + und gestartet. Im Gegensatz zu Bellatrix und Regnatix, die einen Loader aus dem EEProm + laden und entsprechende Systemdateien vom SD-Cardlaufwerk booten, also im + wesentlichen vor dem Bootvorgang keine weiter Funktionalität als die Ladeprozedur + besitzen, muß das EEProm-Bios von Administra mindestens die Funktionalität des + SD-Cardlaufwerkes zur Verfügung stellen können. Es erscheint deshalb sinnvoll, dieses + BIOS gleich mit einem ausgewogenen Funktionsumfang auszustatten, welcher alle Funktionen + für das System bietet. Durch eine Bootoption kann dieses BIOS aber zur Laufzeit + ausgetauscht werden, um das Funktionssetup an konkrete Anforderungen anzupassen. + + Chip-Managment-Funktionen + - Bootfunktion für Administra + - Abfrage und Verwaltung des aktiven Soundsystems + - Abfrage Version und Spezifikation + + SD-Funktionen: + - FAT32 oder FAT16 + - Partitionen bis 1TB und Dateien bis 2GB + - Verzeichnisse + - Verwaltung aller Dateiattribute + - DIR-Marker System + - Verwaltung eines Systemordners + - Achtung: Keine Verwaltung von mehreren geöffneten Dateien! + + SIDCog-Funktionen: + + + + +Komponenten : SIDCog Ver. 080 Johannes Ahlebrand MIT Lizenz + FATEngine 01/18/2009 Kwabena W. Agyeman MIT Lizenz + RTCEngine 11/22/2009 Kwabena W. Agyeman MIT Lizenz + +COG's : MANAGMENT 1 COG + FAT/RTC 1 COG + SIDCog's 2 COG's + DMP/Tracker 1 COG (dynamisch) + ------------------- + 5 Cogs + +Logbuch : + +19-06-2010-dr235 - erste version aus admini.spin extrahiert +06-04-2012-dr235 - sid_dmpreg eingefügt + +Kommandoliste : + +Notizen : + +Bekannte Fehler : + + +}} + + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_01_01 + +CHIP_SPEC = gc#A_FAT|gc#A_LDR|gc#A_SID + +' +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | +------+ d0..d7 +' |||| | | | +DB_IN = %00001001_00000000_00000000_00000000 'dira-wert für datenbuseingabe +DB_OUT = %00001001_00000000_00000000_11111111 'dira-wert für datenbusausgabe + +M1 = %00000010_00000000_00000000_00000000 'busclk=1? & /prop1=0? +M2 = %00000010_10000000_00000000_00000000 'maske: busclk & /cs (/prop1) + +M3 = %00000000_00000000_00000000_00000000 'busclk=0? +M4 = %00000010_00000000_00000000_00000000 'maske: busclk + +LED_OPEN = gc#HBEAT 'led-pin für anzeige "dateioperation" +SD_BASE = gc#A_SDD0 'baspin cardreader + + +'index für dmarker +#0, RMARKER 'root + SMARKER 'system + UMARKER 'programmverzeichnis + AMARKER + BMARKER + CMARKER + +'sidcog + +playRate = 50 'Hz +detune = 1.006 + +OBJ + sdfat : "adm-fat" 'fatengine + sid1 : "adm-sid" 'SIDCog + sid2 : "adm-sid" 'SIDCog + gc : "glob-con" 'globale konstanten + +VAR + + long dmarker[6] 'speicher für dir-marker + byte tbuf[20] 'stringpuffer + byte tbuf2[20] + + long sidreg1 'adresse register der sidcog 1 + long sidreg2 'adresse register der sidcog 2 + long dmpcog 'id der dmp-player-cog + long dmpstack[50] 'stack für dmpcog + byte sidbuffer[25] 'puffer für dmpcog + byte dmpstatus '0 = inaktiv; 1 = play; 2 = pause + long dmppos 'position des players im dump + long dmplen 'länge des dmp-files (anzahl regsitersätze) + byte dmppause 'pauseflag + byte s1buffer[25] 'registerpuffer sid1 + byte s2buffer[25] 'registerpuffer sid2 + +CON ''------------------------------------------------- ADMINISTRA + +PUB main | cmd,err 'chip: kommandointerpreter +''funktionsgruppe : chip +''funktion : kommandointerpreter +''eingabe : - +''ausgabe : - + + init_chip 'bus/vga/keyboard/maus initialisieren + repeat + cmd := bus_getchar 'kommandocode empfangen + err := 0 + case cmd + 0: !outa[LED_OPEN] 'led blinken + +' ---------------------------------------------- SD-FUNKTIONEN + gc#a_sdMount: sd_mount("M") 'sd-card mounten ' + gc#a_sdOpenDir: sd_opendir 'direktory öffnen + gc#a_sdNextFile: sd_nextfile 'verzeichniseintrag lesen + gc#a_sdOpen: sd_open 'datei öffnen + gc#a_sdClose: sd_close 'datei schließen + gc#a_sdGetC: sd_getc 'zeichen lesen + gc#a_sdPutC: sd_putc 'zeichen schreiben + gc#a_sdGetBlk: sd_getblk 'block lesen + gc#a_sdPutBlk: sd_putblk 'block schreiben + gc#a_sdSeek: sd_seek 'zeiger in datei positionieren + gc#a_sdFAttrib: sd_fattrib 'dateiattribute übergeben + gc#a_sdVolname: sd_volname 'volumelabel abfragen + gc#a_sdCheckMounted: sd_checkmounted 'test ob volume gemounted ist + gc#a_sdCheckOpen: sd_checkopen 'test ob eine datei geöffnet ist + gc#a_sdCheckUsed: sd_checkused 'test wie viele sektoren benutzt sind + gc#a_sdCheckFree: sd_checkfree 'test wie viele sektoren frei sind + gc#a_sdNewFile: sd_newfile 'neue datei erzeugen + gc#a_sdNewDir: sd_newdir 'neues verzeichnis wird erzeugt + gc#a_sdDel: sd_del 'verzeichnis oder datei löschen + gc#a_sdRename: sd_rename 'verzeichnis oder datei umbenennen + gc#a_sdChAttrib: sd_chattrib 'attribute ändern + gc#a_sdChDir: sd_chdir 'verzeichnis wechseln + gc#a_sdFormat: sd_format 'medium formatieren + gc#a_sdUnmount: sd_unmount 'medium abmelden + gc#a_sdDmAct: sd_dmact 'dir-marker aktivieren + gc#a_sdDmSet: sd_dmset 'dir-marker setzen + gc#a_sdDmGet: sd_dmget 'dir-marker status abfragen + gc#a_sdDmClr: sd_dmclr 'dir-marker löschen + gc#a_sdDmPut: sd_dmput 'dir-marker status setzen + gc#a_sdEOF: sd_eof 'eof abfragen + +' ---------------------------------------------- CHIP-MANAGMENT + gc#a_mgrGetSpec: mgr_getspec 'spezifikation abfragen + gc#a_mgrALoad: mgr_aload 'neuen code booten + gc#a_mgrGetCogs: mgr_getcogs 'freie cogs abfragen + gc#a_mgrGetVer: mgr_getver 'codeversion abfragen + gc#a_mgrReboot: reboot 'neu starten + +' ---------------------------------------------- SIDCog: DMP-Player-Funktionen (SIDCog2) + gc#a_s_mdmpplay: sid_mdmpplay 'dmp-file mono auf sid2 abspielen + gc#a_s_sdmpplay: sid_sdmpplay 'dmp-file stereo auf beiden sids abspielen + gc#a_s_dmpstop: sid_dmpstop 'dmp-player beenden + gc#a_s_dmppause: sid_dmppause 'dmp-player pausenmodus + gc#a_s_dmpstatus: sid_dmpstatus 'dmp-player statusabfrage + gc#a_s_dmppos: sid_dmppos 'player-position im dumpfile + gc#a_s_mute: sid_mute 'alle register löschen + +' ---------------------------------------------- SIDCog1-Funktionen + gc#a_s1_setRegister: sid1.setRegister(bus_getchar,bus_getchar) + gc#a_s1_updateRegisters: sid1.updateRegisters(sub_getdat(25,@s1buffer)) + gc#a_s1_setVolume: sid1.setVolume(bus_getchar) + gc#a_s1_play: sid1.play(bus_getchar,sub_getlong,bus_getchar,bus_getchar,bus_getchar,bus_getchar,bus_getchar) + gc#a_s1_noteOn: sid1.noteOn(bus_getchar, sub_getlong) + gc#a_s1_noteOff: sid1.noteOff(bus_getchar) + gc#a_s1_setFreq: sid1.setFreq(bus_getchar,sub_getlong) + gc#a_s1_setWaveform: sid1.setWaveform(bus_getchar,bus_getchar) + gc#a_s1_setPWM: sid1.setPWM(bus_getchar,sub_getlong) + gc#a_s1_setADSR: sid1.setADSR(bus_getchar,bus_getchar,bus_getchar,bus_getchar,bus_getchar) + gc#a_s1_setResonance: sid1.setResonance(bus_getchar) + gc#a_s1_setCutoff: sid1.setCutoff(sub_getlong) + gc#a_s1_setFilterMask: sid1.setFilterMask(bus_getchar,bus_getchar,bus_getchar) + gc#a_s1_setFilterType: sid1.setFilterType(bus_getchar,bus_getchar,bus_getchar) + gc#a_s1_enableRingmod: sid1.enableRingmod(bus_getchar,bus_getchar,bus_getchar) + gc#a_s1_enableSynchronization: sid1.enableSynchronization(bus_getchar,bus_getchar,bus_getchar) + +' ---------------------------------------------- SIDCog2-Funktionen + gc#a_s2_setRegister: sid2.setRegister(bus_getchar,bus_getchar) + gc#a_s2_updateRegisters: sid2.updateRegisters(sub_getdat(25,@s1buffer)) + gc#a_s2_setVolume: sid2.setVolume(bus_getchar) + gc#a_s2_play: sid2.play(bus_getchar,sub_getlong,bus_getchar,bus_getchar,bus_getchar,bus_getchar,bus_getchar) + gc#a_s2_noteOn: sid2.noteOn(bus_getchar, sub_getlong) + gc#a_s2_noteOff: sid2.noteOff(bus_getchar) + gc#a_s2_setFreq: sid2.setFreq(bus_getchar,sub_getlong) + gc#a_s2_setWaveform: sid2.setWaveform(bus_getchar,bus_getchar) + gc#a_s2_setPWM: sid2.setPWM(bus_getchar,sub_getlong) + gc#a_s2_setADSR: sid2.setADSR(bus_getchar,bus_getchar,bus_getchar,bus_getchar,bus_getchar) + gc#a_s2_setResonance: sid2.setResonance(bus_getchar) + gc#a_s2_setCutoff: sid2.setCutoff(sub_getlong) + gc#a_s2_setFilterMask: sid2.setFilterMask(bus_getchar,bus_getchar,bus_getchar) + gc#a_s2_setFilterType: sid2.setFilterType(bus_getchar,bus_getchar,bus_getchar) + gc#a_s2_enableRingmod: sid2.enableRingmod(bus_getchar,bus_getchar,bus_getchar) + gc#a_s2_enableSynchronization: sid2.enableSynchronization(bus_getchar,bus_getchar,bus_getchar) + +' ---------------------------------------------- Zusatzfunktionen + gc#a_s_dmpreg: sid_dmpreg 'soundinformationen senden + + +PUB init_chip|i 'chip: initialisierung des administra-chips +''funktionsgruppe : chip +''funktion : - initialisierung des businterface +'' - grundzustand definieren (hss aktiv, systemklänge an) +''eingabe : - +''ausgabe : - + + + repeat i from 0 to 7 'evtl. noch laufende cogs stoppen + ifnot i == cogid + cogstop(i) + + 'debugverbindung + 'debugx.start(9600) ' Start des Debug-Terminals + + 'businterface initialisieren + outa[gc#bus_hs] := 1 'handshake inaktiv ,frida + dira := db_in 'datenbus auf eingabe schalten ,frida + + 'sd-card starten + clr_dmarker 'dir-marker löschen + sdfat.FATEngine + sd_mount("B") + + 'soundsystem initialisieren + sidreg1 := sid1.start(gc#A_SOUNDL,0) 'erste sidcog starten, adresse der register speichern + waitcnt(cnt+(clkfreq>>8)) ' + sidreg2 := sid2.start(gc#A_SOUNDR,0) 'zweite sidcog starten + + +PUB bus_putchar(zeichen) 'chip: ein byte über bus ausgeben +''funktionsgruppe : chip +''funktion : senderoutine für ein byte zu regnatix über den systembus +''eingabe : byte zeichen +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & /prop1=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[gc#bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + outa[gc#bus_hs] := 1 'daten ungültig + dira := db_in 'bus freigeben + +PUB bus_getchar : zeichen 'chip: ein byte über bus empfangen +''funktionsgruppe : chip +''funktion : emfangsroutine für ein byte von regnatix über den systembus +''eingabe : - +''ausgabe : byte zeichen + + waitpeq(M1,M2,0) 'busclk=1? & /prop1=0? + zeichen := ina[7..0] 'daten einlesen + outa[gc#bus_hs] := 0 'daten quittieren + outa[gc#bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + +PUB clr_dmarker| i 'chip: dmarker-tabelle löschen +''funktionsgruppe : chip +''funktion : dmarker-tabelle löschen +''eingabe : - +''ausgabe : - + + i := 0 + repeat 6 'alle dir-marker löschen + dmarker[i++] := TRUE + +CON ''------------------------------------------------- SIDCog: DMP-Player-Funktionen (SIDCog2) + +PRI sid_mdmpplay | err 'sid: dmp-datei mono auf sid2 abspielen +''funktionsgruppe : sid +''funktion : dmp-datei mono auf sid2 abspielen +''eingabe : - +''ausgabe : - +''busprotokoll : [157][sub_getstr.fn][put.error] +'' : fn - name der dmp-datei +'' : error - fehlernummer entspr. list + sub_getstr + err := \sdfat.openFile(@tbuf, "r") + if err == 0 + dmppause := 0 + dmpcog := cognew(sid_dmpmcog,@dmpstack) + 1 'player-cog starten + bus_putchar(err) 'ergebnis der operation senden + +PRI sid_sdmpplay | err 'sid: dmp-datei stereo auf beiden sid's abspielen + + sub_getstr + err := \sdfat.openFile(@tbuf, "r") + if err == 0 + dmppause := 0 + dmpcog := cognew(sid_dmpscog,@dmpstack) + 1 'player-cog starten + bus_putchar(err) 'ergebnis der operation senden + +PRI sid_dmpstop 'sid: dmp-player stoppen + if dmpcog + cogstop(dmpcog-1) + dmpstatus := 0 + +PRI sid_dmppause|i 'sid: dmp-player pause + case dmppause + 0: dmppause := 1 + repeat until dmpstatus == 2 + sid1.setVolume(0) + sid2.setVolume(0) + 1: dmppause := 0 + +PRI sid_dmpstatus 'sid: status des dmp-players abfragen + bus_putchar(dmpstatus) + +PRI sid_dmppos 'sid: position/länge des dmp-players abfragen + sub_putlong(dmppos) + sub_putlong(dmplen) + +PRI sid_mute|sidnr,i 'sid: ruhe! + + repeat i from 0 to 25 + sidbuffer[i] := 0 + sidnr := bus_getchar + case sidnr + 1: sid1.updateRegisters(@sidbuffer) + 2: sid2.updateRegisters(@sidbuffer) + 3: sid1.updateRegisters(@sidbuffer) + sid2.updateRegisters(@sidbuffer) + +PRI sid_dmpmcog | i 'sid: dmpcog - mono, sid2 + + dmpstatus := 1 'player läuft + dmplen := \sdfat.listSize / 25 + dmppos := 0 + repeat dmplen + waitcnt(cnt+(clkfreq/playRate)) 'warten auf den c64-vbl :) + + \sdfat.readData(@sidbuffer,25) '25 byte in den puffer einlesen + +' repeat i from 0 to 24 'da blocktransfer nicht sicher funktioniert +' sidbuffer[i] := sdfat.readCharacter 'füllen wir den puffer "manuell" + + sid2.updateRegisters(@sidbuffer) 'puffer in die sid-register schreiben + dmppos++ + if dmppause == 1 + dmpstatus := 2 + else + dmpstatus := 1 + repeat while dmppause == 1 'warten solange pause + dmpstatus := 0 'player beendet + +PRI sid_dmpscog | i 'sid: dmpcog - mono, sid2 + + dmpstatus := 1 'player läuft + dmplen := \sdfat.listSize / 25 + dmppos := 0 + repeat dmplen + waitcnt(cnt+(clkfreq/playRate)) 'warten auf den c64-vbl :) + + \sdfat.readData(@sidbuffer,25) '25 byte in den puffer einlesen + +' repeat i from 0 to 24 'da blocktransfer nicht sicher funktioniert +' sidbuffer[i] := sdfat.readCharacter 'füllen wir den puffer "manuell" + + sid1.updateRegisters(@sidbuffer) 'puffer in die sid-register schreiben + sid2.updateRegisters(@sidbuffer) 'puffer in die sid-register schreiben + 'eine sidcog etwas verstimmen + word[sidreg2+0 ] := (word[sidreg2+0 ]<<16)/trunc(65536.0/detune) + word[sidreg2+8 ] := (word[sidreg2+8 ]<<16)/trunc(65536.0/detune) + word[sidreg2+16] := (word[sidreg2+16]<<16)/trunc(65536.0/detune) + dmppos := dmppos + 1 + if dmppause == 1 + dmpstatus := 2 + else + dmpstatus := 1 + repeat while dmppause == 1 'warten solange pause + dmpstatus := 0 'player beendet +PRI sid_dmpreg 'sid: dmpregister senden + + bus_putchar(byte[@sidbuffer+1]) 'kanal 1 + bus_putchar(byte[@sidbuffer+0]) + bus_putchar(byte[@sidbuffer+8]) 'kanal 2 + bus_putchar(byte[@sidbuffer+7]) + bus_putchar(byte[@sidbuffer+15]) 'kanal 3 + bus_putchar(byte[@sidbuffer+14]) + + bus_putchar(byte[@sidbuffer+24]) 'volume + + + +CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN + +PUB sub_getstr | i,len 'sub: string einlesen +''funktionsgruppe : sub +''funktion : subprotokoll um einen string von regnatix zu empfangen und im +'' : textpuffer (tbuf) zu speichern +''eingabe : - +''ausgabe : - +''busprotokoll : [get.len][get.byte(1)]..[get.byte(len)] +'' : len - länge des dateinamens + + repeat i from 0 to 19 'puffer löschen und kopieren + tbuf2[i] := tbuf[i] + tbuf[i] := 0 + len := bus_getchar 'längenbyte name empfangen + repeat i from 0 to len - 1 'dateiname einlesen + tbuf[i] := bus_getchar + +PUB sub_getdat(len,datadr1):datadr2 | i 'sub: daten einlesen +''funktionsgruppe : sub +''funktion : subprotokoll um eine bestimmte anzahl bytes zu empfangen +''eingabe : len - anzahl der bytes +'' : datadr1 - adresse des datenspeichers +''ausgabe : datadr2 - adresse des datenspeichers +''busprotokoll : [get.byte(1)]..[get.byte(len)] + + repeat i from 0 to len - 1 'dateiname einlesen + tbuf[datadr1 + i] := bus_getchar + datadr2 := datadr1 + +PUB sub_putstr(strptr)|len,i 'sub: string senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen string an regnatix zu senden +''eingabe : strptr - zeiger auf einen string (0-term) +''ausgabe : - +''busprotokoll : [put.len][put.byte(1)]..[put.byte(len)] +'' : len - länge des dateinamens + + len := strsize(strptr) + bus_putchar(len) + repeat i from 0 to len - 1 'string übertragen + bus_putchar(byte[strptr][i]) + +PUB sub_putlong(wert) 'sub: long senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert an regnatix zu senden +''eingabe : 32bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2][put.byte3][put.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + bus_putchar(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar(wert >> 16) + bus_putchar(wert >> 8) + bus_putchar(wert) + +PUB sub_getlong:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := bus_getchar << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar << 16 + wert := wert + bus_getchar << 8 + wert := wert + bus_getchar + + +CON ''------------------------------------------------- CHIP-MANAGMENT-FUNKTIONEN + + +PUB mgr_aload | err 'cmgr: neuen administra-code booten +''funktionsgruppe : cmgr +''funktion : administra mit neuem code booten +''eingabe : +''ausgabe : +''busprotokoll : [096][sub_getstr.fn] +'' : fn - dateiname des neuen administra-codes + sub_getstr + err := \sdfat.bootPartition(@tbuf, "C") + +PUB mgr_getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind +''funktionsgruppe : cmgr +''funktion : abfrage wie viele cogs in benutzung sind +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [097][put.cogs] +'' : cogs - anzahl der belegten cogs + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + bus_putchar(cogs) + +PUB getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + +PUB mgr_getver 'cmgr: abfrage der version +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [098][sub_putlong.ver] +'' : ver - version +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''version : $00_00_00_00 +'' + + sub_putlong(CHIP_VER) + +PUB mgr_getspec 'cmgr: abfrage der spezifikation des chips +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [089][sub_putlong.spec] +'' : spec - spezifikation +'' +'' +---------- com +'' | +-------- i2c +'' | |+------- rtc +'' | ||+------ lan +'' | |||+----- sid +'' | ||||+---- wav +'' | |||||+--- hss +'' | ||||||+-- bootfähig +'' | |||||||+- dateisystem +''spezifikation : %00000000_00000000_00000000_01001111 + + sub_putlong(CHIP_SPEC) + +CON ''------------------------------------------------- SD-LAUFWERKS-FUNKTIONEN + +PUB sd_mount(mode) | err 'sdcard: sd-card mounten frida +''funktionsgruppe : sdcard +''funktion : eingelegtes volume mounten +''eingabe : - +''ausgabe : - +''busprotokoll : [001][put.error] +'' : error - fehlernummer entspr. list + + ifnot sdfat.checkPartitionMounted 'frida + err := \sdfat.mountPartition(0,0) 'karte mounten + 'bus_putchar(err) 'fehlerstatus senden + if mode == "M" 'frida + bus_putchar(err) 'fehlerstatus senden + + ifnot err + dmarker[RMARKER] := sdfat.getDirCluster 'root-marker setzen + + err := \sdfat.changeDirectory(string("system")) + ifnot err + dmarker[SMARKER] := sdfat.getDirCluster 'system-marker setzen + + sdfat.setDirCluster(dmarker[RMARKER]) 'root-marker wieder aktivieren + else 'frida + bus_putchar(0) 'frida + +PUB sd_opendir | err 'sdcard: verzeichnis öffnen +''funktionsgruppe : sdcard +''funktion : verzeichnis öffnen +''eingabe : - +''ausgabe : - +''busprotokoll : [002] + + err := \sdfat.listReset + +PUB sd_nextfile | strpt 'sdcard: nächsten eintrag aus verzeichnis holen +''funktionsgruppe : sdcard +''funktion : nächsten eintrag aus verzeichnis holen +''eingabe : - +''ausgabe : - +''busprotokoll : [003][put.status=0] +'' : [003][put.status=1][sub_putstr.fn] +'' : status - 1 = gültiger eintrag +'' : 0 = es folgt kein eintrag mehr +'' : fn - verzeichniseintrag string + + strpt := \sdfat.listName 'nächsten eintrag holen + if strpt 'status senden + bus_putchar(1) 'kein eintrag mehr + sub_putstr(strpt) + else + bus_putchar(0) 'gültiger eintrag folgt + +PUB sd_open | err,modus 'sdcard: datei öffnen +''funktionsgruppe : sdcard +''funktion : eine bestehende datei öffnen +''eingabe : - +''ausgabe : - +''busprotokoll : [004][get.modus][sub_getstr.fn][put.error] +'' : modus - "A" Append, "W" Write, "R" Read +'' : fn - name der datei +'' : error - fehlernummer entspr. list + + modus := bus_getchar 'modus empfangen + sub_getstr + err := \sdfat.openFile(@tbuf, modus) + bus_putchar(err) 'ergebnis der operation senden + outa[LED_OPEN] := 1 + +PUB sd_close | err 'sdcard: datei schließen +''funktionsgruppe : sdcard +''funktion : die aktuell geöffnete datei schließen +''eingabe : - +''ausgabe : - +''busprotokoll : [005][put.error] +'' : error - fehlernummer entspr. list + + err := \sdfat.closeFile + bus_putchar(err) 'ergebnis der operation senden + outa[LED_OPEN] := 0 + +PUB sd_getc | n 'sdcard: zeichen aus datei lesen +''funktionsgruppe : sdcard +''funktion : zeichen aus datei lesen +''eingabe : - +''ausgabe : - +''busprotokoll : [006][put.char] +'' : char - gelesenes zeichen + + n := \sdfat.readCharacter + bus_putchar(n) + +PUB sd_putc 'sdcard: zeichen in datei schreiben +''funktionsgruppe : sdcard +''funktion : zeichen in datei schreiben +''eingabe : - +''ausgabe : - +''busprotokoll : [007][get.char] +'' : char - zu schreibendes zeichen + + \sdfat.writeCharacter(bus_getchar) + +PRI sd_eof 'sdcard: eof abfragen +''funktionsgruppe : sdcard +''funktion : eof abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [030][put.eof] +'' : eof - eof-flag + + bus_putchar(sdfat.getEOF) + +PUB sd_getblk 'sdcard: block aus datei lesen +''funktionsgruppe : sdcard +''funktion : block aus datei lesen +''eingabe : - +''ausgabe : - +''busprotokoll : [008][sub_getlong.count][put.char(1)]..[put.char(count)] +'' : count - anzahl der zu lesenden zeichen +'' : char - gelesenes zeichen + + repeat sub_getlong + bus_putchar(\sdfat.readCharacter) + + +PUB sd_putblk 'sdcard: block in datei schreiben +''funktionsgruppe : sdcard +''funktion : block in datei schreiben +''eingabe : - +''ausgabe : - +''busprotokoll : [009][sub_getlong.count][put.char(1)]..[put.char(count)] +'' : count - anzahl der zu schreibenden zeichen +'' : char - zu schreibende zeichen + + repeat sub_getlong + \sdfat.writeCharacter(bus_getchar) + +PUB sd_seek | wert 'sdcard: zeiger in datei positionieren +''funktionsgruppe : sdcard +''funktion : zeiger in datei positionieren +''eingabe : - +''ausgabe : - +''busprotokoll : [010][sub_getlong.pos] +'' : pos - neue zeichenposition in der datei + + wert := sub_getlong + \sdfat.setCharacterPosition(wert) + +PUB sd_fattrib | anr,wert 'sdcard: dateiattribute übergeben +''funktionsgruppe : sdcard +''funktion : dateiattribute abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [011][get.anr][sub_putlong.wert] +'' : anr - 0 = Dateigröße +'' : 1 = Erstellungsdatum - Tag +'' : 2 = Erstellungsdatum - Monat +'' : 3 = Erstellungsdatum - Jahr +'' : 4 = Erstellungsdatum - Sekunden +'' : 5 = Erstellungsdatum - Minuten +'' : 6 = Erstellungsdatum - Stunden +'' : 7 = Zugriffsdatum - Tag +'' : 8 = Zugriffsdatum - Monat +'' : 9 = Zugriffsdatum - Jahr +'' : 10 = Änderungsdatum - Tag +'' : 11 = Änderungsdatum - Monat +'' : 12 = Änderungsdatum - Jahr +'' : 13 = Änderungsdatum - Sekunden +'' : 14 = Änderungsdatum - Minuten +'' : 15 = Änderungsdatum - Stunden +'' : 16 = Read-Only-Bit +'' : 17 = Hidden-Bit +'' : 18 = System-Bit +'' : 19 = Direktory +'' : 20 = Archiv-Bit +'' : wert - wert des abgefragten attributes + + anr := bus_getchar + case anr + 0: wert := \sdfat.listSize + 1: wert := \sdfat.listCreationDay + 2: wert := \sdfat.listCreationMonth + 3: wert := \sdfat.listCreationYear + 4: wert := \sdfat.listCreationSeconds + 5: wert := \sdfat.listCreationMinutes + 6: wert := \sdfat.listCreationHours + 7: wert := \sdfat.listAccessDay + 8: wert := \sdfat.listAccessMonth + 9: wert := \sdfat.listAccessYear + 10: wert := \sdfat.listModificationDay + 11: wert := \sdfat.listModificationMonth + 12: wert := \sdfat.listModificationYear + 13: wert := \sdfat.listModificationSeconds + 14: wert := \sdfat.listModificationMinutes + 15: wert := \sdfat.listModificationHours + 16: wert := \sdfat.listIsReadOnly + 17: wert := \sdfat.listIsHidden + 18: wert := \sdfat.listIsSystem + 19: wert := \sdfat.listIsDirectory + 20: wert := \sdfat.listIsArchive + sub_putlong(wert) + +PUB sd_volname 'sdcard: volumenlabel abfragen +''funktionsgruppe : sdcard +''funktion : name des volumes überragen +''eingabe : - +''ausgabe : - +''busprotokoll : [012][sub_putstr.volname] +'' : volname - name des volumes +'' : len - länge des folgenden strings + + sub_putstr(\sdfat.listVolumeLabel) 'label holen und senden + +PUB sd_checkmounted 'sdcard: test ob volume gemounted ist +''funktionsgruppe : sdcard +''funktion : test ob volume gemounted ist +''eingabe : - +''ausgabe : - +''busprotokoll : [013][put.flag] +'' : flag - 0 = unmounted, 1 mounted + + bus_putchar(\sdfat.checkPartitionMounted) + +PUB sd_checkopen 'sdcard: test ob eine datei geöffnet ist +''funktionsgruppe : sdcard +''funktion : test ob eine datei geöffnet ist +''eingabe : - +''ausgabe : - +''busprotokoll : [014][put.flag] +'' : flag - 0 = not open, 1 open + + bus_putchar(\sdfat.checkFileOpen) + +PUB sd_checkused 'sdcard: anzahl der benutzten sektoren senden +''funktionsgruppe : sdcard +''funktion : anzahl der benutzten sektoren senden +''eingabe : - +''ausgabe : - +''busprotokoll : [015][sub_putlong.used] +'' : used - anzahl der benutzten sektoren + + sub_putlong(\sdfat.checkUsedSectorCount("F")) + +PUB sd_checkfree 'sdcard: anzahl der freien sektoren senden +''funktionsgruppe : sdcard +''funktion : anzahl der freien sektoren senden +''eingabe : - +''ausgabe : - +''busprotokoll : [016][sub_putlong.free] +'' : free - anzahl der freien sektoren + + sub_putlong(\sdfat.checkFreeSectorCount("F")) + +PUB sd_newfile | err 'sdcard: eine neue datei erzeugen +''funktionsgruppe : sdcard +''funktion : eine neue datei erzeugen +''eingabe : - +''ausgabe : - +''busprotokoll : [017][sub_getstr.fn][put.error] +'' : fn - name der datei +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.newFile(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_newdir | err 'sdcard: ein neues verzeichnis erzeugen +''funktionsgruppe : sdcard +''funktion : ein neues verzeichnis erzeugen +''eingabe : - +''ausgabe : - +''busprotokoll : [018][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.newDirectory(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_del | err 'sdcard: eine datei oder ein verzeichnis löschen +''funktionsgruppe : sdcard +''funktion : eine datei oder ein verzeichnis löschen +''eingabe : - +''ausgabe : - +''busprotokoll : [019][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses oder der datei +'' : error - fehlernummer entspr. liste + + sub_getstr + err := \sdfat.deleteEntry(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_rename | err 'sdcard: datei oder verzeichnis umbenennen +''funktionsgruppe : sdcard +''funktion : datei oder verzeichnis umbenennen +''eingabe : - +''ausgabe : - +''busprotokoll : [020][sub_getstr.fn1][sub_getstr.fn2][put.error] +'' : fn1 - alter name +'' : fn2 - neuer name +'' : error - fehlernummer entspr. liste + + sub_getstr 'fn1 + sub_getstr 'fn2 + err := \sdfat.renameEntry(@tbuf2,@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_chattrib | err 'sdcard: attribute ändern +''funktionsgruppe : sdcard +''funktion : attribute einer datei oder eines verzeichnisses ändern +''eingabe : - +''ausgabe : - +''busprotokoll : [021][sub_getstr.fn][sub_getstr.attrib][put.error] +'' : fn - dateiname +'' : attrib - string mit attributen +'' : error - fehlernummer entspr. liste + + sub_getstr + sub_getstr + err := \sdfat.changeAttributes(@tbuf2,@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_chdir | err 'sdcard: verzeichnis wechseln +''funktionsgruppe : sdcard +''funktion : verzeichnis wechseln +''eingabe : - +''ausgabe : - +''busprotokoll : [022][sub_getstr.fn][put.error] +'' : fn - name des verzeichnisses +'' : error - fehlernummer entspr. list + sub_getstr + err := \sdfat.changeDirectory(@tbuf) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_format | err 'sdcard: medium formatieren +''funktionsgruppe : sdcard +''funktion : medium formatieren +''eingabe : - +''ausgabe : - +''busprotokoll : [023][sub_getstr.vlabel][put.error] +'' : vlabel - volumelabel +'' : error - fehlernummer entspr. list + + sub_getstr + err := \sdfat.formatPartition(0,@tbuf,0) + bus_putchar(err) 'ergebnis der operation senden + +PUB sd_unmount | err 'sdcard: medium abmelden +''funktionsgruppe : sdcard +''funktion : medium abmelden +''eingabe : - +''ausgabe : - +''busprotokoll : [024][put.error] +'' : error - fehlernummer entspr. list + + err := \sdfat.unmountPartition + bus_putchar(err) 'ergebnis der operation senden + ifnot err + clr_dmarker + +PUB sd_dmact|markernr 'sdcard: einen dir-marker aktivieren +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker wird aktiviert +''eingabe : - +''ausgabe : - +''busprotokoll : [025][get.dmarker][put.error] +'' : dmarker - dir-marker +'' : error - fehlernummer entspr. list + markernr := bus_getchar + ifnot dmarker[markernr] == TRUE + sdfat.setDirCluster(dmarker[markernr]) + bus_putchar(sdfat#err_noError) + else + bus_putchar(sdfat#err_noError) + + +PUB sd_dmset|markernr 'sdcard: einen dir-marker setzen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker mit dem aktuellen verzeichnis setzen +''eingabe : - +''ausgabe : - +''busprotokoll : [026][get.dmarker] +'' : dmarker - dir-marker + + markernr := bus_getchar + dmarker[markernr] := sdfat.getDirCluster + +PUB sd_dmget|markernr 'sdcard: einen dir-marker abfragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker abfragen +''eingabe : - +''ausgabe : - +''busprotokoll : [027][get.dmarker][sub_putlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + markernr := bus_getchar + sub_putlong(dmarker[markernr]) + +PRI sd_dmput|markernr 'sdcard: einen dir-marker übertragen +''funktionsgruppe : sdcard +''funktion : den status eines ausgewählter dir-marker übertragen +''eingabe : - +''ausgabe : - +''busprotokoll : [029][get.dmarker][sub_getlong.dmstatus] +'' : dmarker - dir-marker +'' : dmstatus - status des markers + + markernr := bus_getchar + dmarker[markernr] := sub_getlong + +PUB sd_dmclr|markernr 'sdcard: einen dir-marker löschen +''funktionsgruppe : sdcard +''funktion : ein ausgewählter dir-marker löschen +''eingabe : - +''ausgabe : - +''busprotokoll : [028][get.dmarker] +'' : dmarker - dir-marker + + markernr := bus_getchar + dmarker[markernr] := TRUE + + + + +DAT 'dummyroutine für getcogs + org +' +' Entry: dummy-assemblercode fuer cogtest +' +entry jmp entry 'just loops + + + + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + diff --git a/system/bellatrix/bel-g0/g0key.spin b/system/bellatrix/bel-g0/g0key.spin new file mode 100644 index 0000000..c67e49c --- /dev/null +++ b/system/bellatrix/bel-g0/g0key.spin @@ -0,0 +1,3098 @@ +{{ GR0KEY +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : Hive +Name : GRAPHICS-KEYBOARD +Chip : Bellatrix +Typ : Treiber +Version : 00 +Subversion : 01 +Funktion : Graphics + Keyboard + +Dieser Bellatrix-Code stellt Regnatix alle Graphics- und Keyboard-Funktionen +zur Verfügung. Der Speicher für den PASM-Code im hRAM wird nach dem Start der +Cogs als Heap verwendet. + +Logbuch : + +11-11-2011-dr235 - erste funktionsfähige version erstellt +23-11-2011-dr235 - keyboard-objekt in root-objekt eingefügt + - keyboard-pasm-code zu heap hinzugefügt + + + + + +}} +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 +_STACK = ($3000 + $3000 + 100) >> 2 + + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_01_01 + +CHIP_SPEC = gcon#b_tv|gcon#b_key|gcon#b_vec + +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + +x_tiles = 16 +y_tiles = 12 + +paramcount = 14 +bit_base = $2000 +disp_base = $5000 + +max_x = x_tiles * 16 +max_y = y_tiles * 16 + +OBJ + + tv : "bel-tv" + gcon : "glob-con" 'globale konstanten + +VAR + + long bel_key 'letzter tastencode + long datadr 'adresse des heap + + long tv_status '0/1/2 = off/visible/invisible read-only + long tv_enable '0/? = off/on write-only + long tv_pins '%ppmmm = pins write-only + long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_hc 'horizontal cells write-only + long tv_vc 'vertical cells write-only + long tv_hx 'horizontal cell expansion write-only + long tv_vx 'vertical cell expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + word screen[x_tiles * y_tiles] 'tilemap + long grcolors[64] 'farbregister + +CON ''------------------------------------------------- BELLATRIX + +PUB main | cmd,i,index 'chip: kommandointerpreter +''funktionsgruppe : chip +''funktion : kommandointerpreter +''eingabe : - +''ausgabe : - + + init_subsysteme 'bus/vga/keyboard/maus initialisieren + repeat + i := 0 + cmd := gc 'kommando empfangen + case cmd +' ---------------------------------------------- KEYBOARD + 1: key_stat '1: Tastaturstatus senden + 2: key_code '2: Tastaturzeichen senden + 4: key_spec '4: Statustasten ($100..$1FF) abfragen +' ---------------------------------------------- GRAPHICS + 'clear + 10: clear + 'copy(dest_ptr) + 11: copy(disp_base) + 'color(c) + 12: color(gc) + 'width(w) + 13: width(gc) + 'colorwidth(c, w) + 14: colorwidth(gc,gc) + 'plot(x, y) + 15: plot(gc,gc) + 'line(x, y) + 16: line(gc,gc) + 'arc(x, y, xr, yr, angle, anglestep, steps, arcmode) + 17: arc(gc,gc,gc,gc,gw,gw,gc,gc) + 'vec(x, y, vecscale, vecangle, vecdef_ptr) + 18: vec(gc,gc,gc,gw,datadr+gw) + 'vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + 19: vecarc(gc,gc,gc,gc,gw,gc,gw,datadr+gw) + 'pix(x, y, pixrot, pixdef_ptr) + 20: pix(gc,gc,gc,datadr+gw) + 'pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + 21: pixarc(gc,gc,gc,gc,gw,gc,datadr+gw) + 'text(x, y, string_ptr) + 22: text(gc,gc,datadr+gw) + 'textarc(x, y, xr, yr, angle, string_ptr) + 23: textarc(gc,gc,gc,gc,gw,datadr+gw) + 'textmode(x_scale, y_scale, spacing, justification) + 24: textmode(gc,gc,gc,gc) + 'box(x, y, box_width, box_height) + 25: box(gc,gc,gc,gc) + 'quad(x1, y1, x2, y2, x3, y3, x4, y4) + 26: quad(gc,gc,gc,gc,gc,gc,gc,gc) + 'tri(x1, y1, x2, y2, x3, y3) + 27: tri(gc,gc,gc,gc,gc,gc) +' ---------------------------------------------- CHIP-MANAGMENT + 93: repeat 64 'colortab empfangen + grcolors[i++] := gl + 94: repeat x_tiles * y_tiles 'screen empfangen + screen[i++] := gw + 95: index := gw + repeat gw 'heap empfangen + byte[datadr+index+i++] := gc + 96: pw(@grdatend-datadr) 'heapgrösse senden + 97: setup(tv_hc, tv_vc, 0, 0, bit_base) 'dynamischer modus + 98: setup(tv_hc, tv_vc, 0, 0, disp_base) 'statischer modus + 99: reboot 'bellatrix neu starten + +PUB init_subsysteme | i,tx,ty 'chip: initialisierung des bellatrix-chips +''funktionsgruppe : chip +''funktion : - initialisierung des businterface +'' : - vga & keyboard-treiber starten +''eingabe : - +''ausgabe : - + + dira := db_in 'datenbus auf eingabe schalten + outa[gcon#bus_hs] := 1 'handshake inaktiv + keystart(gcon#b_keybd, gcon#b_keybc) 'tastaturport starten + + 'tv-treiber starten + longmove(@tv_status, @tvparams, paramcount) + tv_screen := @screen + tv_colors := @grcolors + tv.start(@tv_status) + + 'start and setup graphics + grstart +' setup(tv_hc, tv_vc, 0, 0, disp_base) 'bitmap_base = puffer in welchen gezeichnet wird +' clear + + datadr := (@grdat+4) & $FFFD 'ausgerichtete datenadresse berechnen + + +PUB pc(zeichen) 'chip: ein byte an regnatix senden +''funktionsgruppe : chip +''funktion : ein byte an regnatix senden +''eingabe : byte +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[gcon#bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[gcon#bus_hs] := 1 'daten ungültig + +PUB gc : zeichen 'chip: ein byte von regnatix empfangen +''funktionsgruppe : chip +''funktion : ein byte von regnatix empfangen +''eingabe : - +''ausgabe : byte + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[gcon#bus_hs] := 0 'daten quittieren + waitpeq(M3,M4,0) 'busclk=0? + outa[gcon#bus_hs] := 1 + + + +CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN + +PUB pw(wert) 'sub: word senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert an regnatix zu senden +''eingabe : 16bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2] +'' : [ hsb ][ ] + + pc(wert >> 8) + pc(wert) + +PUB gw:wert 'sub: word empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen 16bit-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 16bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2] +'' : [ hsb ][ lsb ] + + wert := gc << 8 + wert := wert + gc + +PUB gl:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := gc << 24 '32 bit empfangen hsb/lsb + wert := wert + gc << 16 + wert := wert + gc << 8 + wert := wert + gc + +CON ''------------------------------------------------- KEYBOARD-FUNKTIONEN + +PUB key_stat 'key: tastaturstatus abfragen + + pc(gotkey) + +PUB key_code 'key: tastencode abfragen + + bel_key := key + case bel_key + $c8: bel_key := $08 'backspace wandeln + pc(bel_key) + +PUB key_spec 'key: statustaten vom letzten tastencode abfragen + + pc(bel_key >> 8) + +DAT ''tv-parameter + +tvparams long 0 'status + long 1 'enable + long %010_0101 'pins New Board + long %0000 'mode +pscreen long 0 'screen +pcolors long 0 'colors + long x_tiles 'hc - horizontale tiles + long y_tiles 'vc - vertikale tiles + long 10 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 60_000_000 '_xinfreq<<4 'broadcast + long 0 'auralcog + +CON ' Keyboard-Objekt +''*************************************** +''* PS/2 Keyboard Driver v1.0.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +{-----------------REVISION HISTORY--------------------------------- + v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96 + ------------------------------------------------------------------} + +{-----------------KEYBOARD LAYOUT HISTORY-------------------------- + 2009-08-31 (Y-M-D) + Patch for german keyboard layout + Author: oog + Added german keyboard layout. + Original layout is commented as keyboard-us-en (US-English). + German layout is commented as keyboard-de (de = deutsch = "german"). + + Now there are two tables for keys with and without SHIFT-Key. + It should be easier to implement different international layouts. + However, it's bigger now and uses more memory. + + 2009-09-05 (Y-M-D) + Fixed bugs + - code bug on home-key fixed + new replace-codes for de_ae, de_ou and de_ue + + New + - Documentation of control-key bits + This should be helpful for translatíons of this driver into + different languages. + - table_alt_r + This table contains characters for the german "AltGr" key. + - AltGr+F1..F12 + Returns line-characters, selected from $90..$9f + + 2009-09-06 (Y-M-D) + Fixed bugs + - patch table_shift for "?" + + Differences to Parallax driver: + - Different codes for NumLock, CapsLock and ScrLock to avoid + conflict with german "ß" + Codes are defined as constants and easy to change + - Easy Cursor codes implemented to avoit conflict with the "Ä"-key + Easy Cursor codes are easy to understand, + for example "Cursor Left" is the character "←" + + ------------------------------------------------------------------} + +CON + de_ae = $A6 'replace code - not used on keyboard + de_oe = $A7 'replace code - not used on keyboard + de_ue = $A8 'replace code - not used on keyboard + lock = $BC 'Parallax used codes $DD, $DE and $DF + 'There was a conflict between $DF=NumLock="ß" + ScrLk = lock + CpsLk = lock+1 + NumLk = lock+2 + +' +'Uncomment one of the next constant blocks +' +' + +{{Parallax cursor codes start}} +{{ + CrsLt = $C0E4 + CrsRt = $C1E6 + CrsUp = $C2E8 + CrsDn = $C3E2 + CrsHm = $C4E7 'Conflict with key "Ä" ($C4) + CrsEn = $C5E1 + PgUp = $C6E9 + PgDn = $C7E3 + Bksp = $00C8 + Del = $C9EA + Ins = $CAE0 + Esc = $00CB + Apps = $CC00 + Power = $CD00 + Sleep = $CE00 + WkUp = $CF00 +}} +{{Parallax cursor codes end}} + + +{{Easy cursor codes start}} + + CrsLt = $02E4 '← + CrsRt = $03E6 '→ + CrsUp = $04E8 '↑ + CrsDn = $05E2 '↓ + CrsHm = $06E7 '◀ + CrsEn = $07E1 '▶ + PgUp = $A0E9 ' + PgDn = $A2E3 ' + Bksp = $00C8 'È + Del = $BAEA ' + Ins = $BBE0 ' + Esc = $001B ' + Apps = $CC00 'Ì + Power = $CD00 'Í + Sleep = $CE00 'Î + WkUp = $CF00 'Ï + +{{Easy cursor codes end}} + +VAR + + long cog + + long par_tail 'key buffer tail read/write (19 contiguous longs) + long par_head 'key buffer head read-only + long par_present 'keyboard present read-only + long par_states[8] 'key states (256 bits) read-only + long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters) + + +PUB keystart(dpin, cpin) : okay + +'' Start keyboard driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS +'' +'' all lock-keys will be enabled, NumLock will be initially 'on', +'' and auto-repeat will be set to 15cps with a delay of .5s + + okay := startx(dpin, cpin, %0_000_000, %01_01000) + + +PUB startx(dpin, cpin, locks, auto) : okay + +'' Like start, but allows you to specify lock settings and auto-repeat +'' +'' locks = lock setup +'' bit 6 disallows shift-alphas (case set soley by CapsLock) +'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state +'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock +'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') +'' +'' auto = auto-repeat setup +'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) +'' bits 4..0 specify repeat rate (0=30cps..31=2cps) +'' (eg %01_00000 = .5s delay, 30cps repeat) + + longmove(@par_keys, @dpin, 4) + okay := cog := cognew(@entry, @par_tail) + 1 + + + +PUB present : truefalse + +'' Check if keyboard present - valid ~2s after start +'' returns t|f + + truefalse := -par_present + + +PUB key : keycode + +'' Get key (never waits) +'' returns key (0 if buffer empty) + + if par_tail <> par_head + keycode := par_keys.word[par_tail] + par_tail := ++par_tail & $F + + +PUB getkey : keycode + +'' Get next key (may wait for keypress) +'' returns key + + repeat until (keycode := key) + + +PUB newkey : keycode + +'' Clear buffer and get new key (always waits for keypress) +'' returns key + + par_tail := par_head + keycode := getkey + + +PUB gotkey : truefalse + +'' Check if any key in buffer +'' returns t|f + + truefalse := par_tail <> par_head + + +PUB clearkeys + +'' Clear key buffer + + par_tail := par_head + + +PUB keystate(k) : state + +'' Get the state of a particular key +'' returns t|f + + state := -(par_states[k >> 5] >> k & 1) + +CON ' Graphics-Objekt + +''*************************************** +''* Graphics Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2005 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +'' +'' Theory of Operation: +'' +'' A cog is launched which processes commands via the PUB routines. +'' +'' Points, lines, arcs, sprites, text, and polygons are rasterized into +'' a specified stretch of memory which serves as a generic bitmap buffer. +'' +'' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. +'' +'' See GRAPHICS_DEMO.SRC for usage example. +'' + +CON + + #1, _setup, _color, _width, _plot, _line, _arc, _vec, _vecarc, _pix, _pixarc, _text, _textarc, _textmode, _fill, _loop + +VAR + + long command + + long bitmap_base 'bitmap data + long bitmap_longs + word bases[32] + + long pixel_width 'pixel data + long slices[8] + + long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) + + +PUB grstart : okay + +'' Start graphics driver - starts a cog +'' returns false if no cog available + + fontptr := @font 'set font pointer (same for all instances) + cognew(@loop, @command) + 1 + +PUB setup(xtiles, ytiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr + +'' Set bitmap parameters +'' +'' xtiles - number of x tiles (tiles are 16x16 pixels each) +'' ytiles - number of y tiles +'' x_origin - relative-x center pixel +'' y_origin - relative-y center pixel +'' base_ptr - base address of bitmap + + setcommand(_loop, 0) 'make sure last command finished + + repeat bases_ptr from 0 to xtiles - 1 <# 31 'write bases + bases[bases_ptr] := base_ptr + bases_ptr * ytiles << 6 + + ytiles <<= 4 'adjust arguments and do setup command + y_origin := ytiles - y_origin - 1 + bases_ptr := @bases + slices_ptr := @slices + setcommand(_setup, @xtiles) + + bitmap_base := base_ptr 'retain high-level bitmap data + bitmap_longs := xtiles * ytiles + + +PUB clear + +'' Clear bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap + + +PUB copy(dest_ptr) + +'' Copy bitmap +'' use for double-buffered display (flicker-free) +'' +'' dest_ptr - base address of destination bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap + + +PUB color(c) + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + setcommand(_color, @colors[c & 3]) 'set color + + +PUB width(w) | pixel_passes, r, i, p + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + r := not w & $10 'determine pixel shape/width + w &= $F + pixel_width := w + pixel_passes := w >> 1 + 1 + + setcommand(_width, @w) 'do width command now to avoid updating slices when busy + + p := w ^ $F 'update slices to new shape/width + repeat i from 0 to w >> 1 + slices[i] := true >> (p << 1) << (p & $E) + if r and pixels[w] & |< i + p += 2 + if r and i == pixel_passes - 2 + p += 2 + + +PUB colorwidth(c, w) + +'' Set pixel color and width + + color(c) + width(w) + + +PUB plot(gx, gy) + +'' Plot point +'' +'' x,y - point + + setcommand(_plot, @gx) + + +PUB line(gx, gy) + +'' Draw a line to point +'' +'' x,y - endpoint + + setcommand(_line, @gx) + + +PUB arc(gx, gy, xr, yr, angle, anglestep, steps, arcmode) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + setcommand(_arc, @gx) + + +PUB vec(gx, gy, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + setcommand(_vec, @gx) + + +PUB vecarc(gx, gy, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition + + setcommand(_vecarc, @gx) + + +PUB pix(gx, gy, pixrot, pixdef_ptr) + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + setcommand(_pix, @gx) + + +PUB pixarc(gx, gy, xr, yr, angle, pixrot, pixdef_ptr) + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition + + setcommand(_pixarc, @gx) + + +PUB text(gx, gy, string_ptr) | justx, justy + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_text, @gx) + + +PUB textarc(gx, gy, xr, yr, angle, string_ptr) | justx, justy + +'' Draw text at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_textarc, @gx) + + +PUB textmode(x_scale, y_scale, spacing, justification) + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + longmove(@text_xs, @x_scale, 4) 'retain high-level text data + + setcommand(_textmode, @x_scale) 'set text mode + + +PUB box(gx, gy, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + if box_width > pixel_width and box_height > pixel_width + + pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max + + gx += pmin 'adjust coordinates to accomodate width + gy += pmin + x2 := gx + box_width - 1 - pixel_width + y2 := gy + box_height - 1 - pixel_width + + plot(gx, gy) 'plot round/square corners + plot(gx, y2) + plot(x2, gy) + plot(x2, y2) + + fill(gx, y2 + pmax, 0, (x2 - gx) << 16, 0, 0, pmax) 'fill gaps + fill(gx, y, 0, (x2 - gx) << 16, 0, 0, pmin) + fill(gx - pmin, y2, 0, (x2 - gx + pixel_width) << 16, 0, 0, y2 - gy) + + +PUB quad(x1, y1, x2, y2, x3, y3, x4, y4) + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + + tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon + tri(x3, y3, x4, y4, x1, y1) + + +PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] + +'' Draw a solid triangle + +' reorder vertices by descending y + + case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 + %000: + longmove(@xy, @x1, 2) + longmove(@x1, @x3, 2) + longmove(@x3, @xy, 2) + %010: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 4) + longmove(@x3, @xy, 2) + %011: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 2) + longmove(@x2, @xy, 2) + %100: + longmove(@xy, @x3, 2) + longmove(@x2, @x1, 4) + longmove(@x1, @xy, 2) + %101: + longmove(@xy, @x2, 2) + longmove(@x2, @x3, 2) + longmove(@x3, @xy, 2) + +' draw triangle + + fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) + + +PUB finish + +'' Wait for any current graphics command to finish +'' use this to insure that it is safe to manually manipulate the bitmap + + setcommand(_loop, 0) 'make sure last command finished + + +PRI fill(gx, gy, da, db, db2, linechange, lines_minus_1) + + setcommand(_fill, @gx) + + +PRI justify(string_ptr, justptr) | gx + + gx := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 + long[justptr] := -lookupz(text_just >> 2 & 3: 0, gx >> 1, gx, 0) + long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) + + +PRI setcommand(cmd, argptr) + + command := cmd << 16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + + +CON + + ' Vector font primitives + + xa0 = %000 << 0 'x line start / arc center + xa1 = %001 << 0 + xa2 = %010 << 0 + xa3 = %011 << 0 + xa4 = %100 << 0 + xa5 = %101 << 0 + xa6 = %110 << 0 + xa7 = %111 << 0 + + ya0 = %0000 << 3 'y line start / arc center + ya1 = %0001 << 3 + ya2 = %0010 << 3 + ya3 = %0011 << 3 + ya4 = %0100 << 3 + ya5 = %0101 << 3 + ya6 = %0110 << 3 + ya7 = %0111 << 3 + ya8 = %1000 << 3 + ya9 = %1001 << 3 + yaA = %1010 << 3 + yaB = %1011 << 3 + yaC = %1100 << 3 + yaD = %1101 << 3 + yaE = %1110 << 3 + yaF = %1111 << 3 + + xb0 = %000 << 7 'x line end + xb1 = %001 << 7 + xb2 = %010 << 7 + xb3 = %011 << 7 + xb4 = %100 << 7 + xb5 = %101 << 7 + xb6 = %110 << 7 + xb7 = %111 << 7 + + yb0 = %0000 << 10 'y line end + yb1 = %0001 << 10 + yb2 = %0010 << 10 + yb3 = %0011 << 10 + yb4 = %0100 << 10 + yb5 = %0101 << 10 + yb6 = %0110 << 10 + yb7 = %0111 << 10 + yb8 = %1000 << 10 + yb9 = %1001 << 10 + ybA = %1010 << 10 + ybB = %1011 << 10 + ybC = %1100 << 10 + ybD = %1101 << 10 + ybE = %1110 << 10 + ybF = %1111 << 10 + + ax1 = %0 << 7 'x arc radius + ax2 = %1 << 7 + + ay1 = %00 << 8 'y arc radius + ay2 = %01 << 8 + ay3 = %10 << 8 + ay4 = %11 << 8 + + a0 = %0000 << 10 'arc start/length + a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0°, 90°, 180°, 270°) + a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360°, 270°, 180°, 90°) + a3 = %0011 << 10 + a4 = %0100 << 10 + a5 = %0101 << 10 + a6 = %0110 << 10 + a7 = %0111 << 10 + a8 = %1000 << 10 + a9 = %1001 << 10 + aA = %1010 << 10 + aB = %1011 << 10 + aC = %1100 << 10 + aD = %1101 << 10 + aE = %1110 << 10 + aF = %1111 << 10 + + fline = %0 << 14 'line command + farc = %1 << 14 'arc command + + more = %1 << 15 'another arc/line + + +DAT + +' Color codes + +colors long %%0000000000000000 + long %%1111111111111111 + long %%2222222222222222 + long %%3333333333333333 + +' Round pixel recipes + +pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 + byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 + byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B + byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F + +' Vector font - standard ascii characters ($21-$7E) + +font word fline + xa2 + yaC + xb2 + yb7 + more '! + word fline + xa2 + ya5 + xb2 + yb4 + + word fline + xa1 + yaD + xb1 + ybC + more '" + word fline + xa3 + yaD + xb3 + ybC + + word fline + xa1 + yaA + xb1 + yb6 + more '# + word fline + xa3 + yaA + xb3 + yb6 + more + word fline + xa0 + ya9 + xb4 + yb9 + more + word fline + xa0 + ya7 + xb4 + yb7 + + word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ + word farc + xa2 + ya7 + aB + ax2 + ay1 + more + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + yaA + xb4 + ybA + more + word fline + xa2 + yaA + xb2 + ybB + more + word fline + xa2 + ya6 + xb2 + yb5 + + word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% + word farc + xa3 + ya6 + a0 + ax1 + ay1 + more + word fline + xa0 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& + word farc + xa2 + ya7 + a5 + ax2 + ay2 + more + word fline + xa1 + yaA + xb4 + yb5 + + word fline + xa2 + yaD + xb2 + ybC ' ' + + word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( + word farc + xa3 + ya7 + aE + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') + word farc + xa1 + ya7 + aF + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word fline + xa4 + ya6 + xb0 + ybA + more '* + word fline + xa0 + ya6 + xb4 + ybA + more + word fline + xa2 + yaB + xb2 + yb5 + + word fline + xa0 + ya8 + xb4 + yb8 + more '+ + word fline + xa2 + yaA + xb2 + yb6 + + word fline + xa2 + ya4 + xb1 + yb3 ', + + word fline + xa0 + ya8 + xb4 + yb8 '- + + word fline + xa2 + ya5 + xb2 + yb4 '. + + word fline + xa0 + ya4 + xb4 + ybC '/ + + word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 + + word fline + xa0 + ya4 + xb4 + yb4 + more '1 + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa0 + yaA + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 + word farc + xa2 + yaA + aF + ax2 + ay3 + more + word farc + xa2 + ya4 + aD + ax2 + ay3 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + yaC + xb0 + yb7 + more '4 + word fline + xa0 + ya7 + xb4 + yb7 + more + word fline + xa3 + ya4 + xb3 + yb8 + + word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 + word fline + xa4 + yaC + xb0 + ybC + more + word fline + xa0 + yaC + xb0 + yb8 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + ya4 + xb2 + yb4 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 + word farc + xa2 + ya8 + aD + ax2 + ay4 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa2 + yaC + xb3 + ybC + + word fline + xa0 + yaC + xb4 + ybC + more '7 + word fline + xa1 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 + word farc + xa2 + yaA + a0 + ax2 + ay2 + + word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 + word farc + xa2 + ya8 + aF + ax2 + ay4 + more + word fline + xa4 + ya8 + xb4 + ybA + more + word fline + xa1 + ya4 + xb2 + yb4 + + word fline + xa2 + ya6 + xb2 + yb7 + more ': + word fline + xa2 + yaA + xb2 + yb9 + + word fline + xa2 + ya4 + xb1 + yb3 + more '; + word fline + xa2 + ya8 + xb2 + yb7 + + word fline + xa0 + ya8 + xb4 + ybA + more '< + word fline + xa0 + ya8 + xb4 + yb6 + + word fline + xa0 + yaA + xb4 + ybA + more '= + word fline + xa0 + ya6 + xb4 + yb6 + + word fline + xa4 + ya8 + xb0 + ybA + more '> + word fline + xa4 + ya8 + xb0 + yb6 + + word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? + word farc + xa3 + yaB + aF + ax1 + ay2 + more + word farc + xa3 + ya7 + aD + ax1 + ay2 + more + word fline + xa2 + ya5 + xb2 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ + word farc + xa2 + ya8 + a4 + ax2 + ay3 + more + word farc + xa3 + ya8 + aF + ax1 + ay1 + more + word farc + xa2 + ya6 + aF + ax2 + ay1 + more + word fline + xa3 + ya7 + xb3 + yb9 + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A + word fline + xa0 + ya4 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + ybA + more + word fline + xa0 + ya8 + xb4 + yb8 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B + word farc + xa2 + ya6 + aB + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + + word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D + word farc + xa2 + ya6 + aF + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + yaC + xb2 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'E + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'F + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + yb7 + more + word fline + xa3 + ya7 + xb4 + yb7 + + word fline + xa0 + ya4 + xb0 + ybC + more 'H + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa0 + ya8 + xb4 + yb8 + + word fline + xa2 + ya4 + xb2 + ybC + more 'I + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'K + word fline + xa4 + yaC + xb0 + yb8 + more + word fline + xa4 + ya4 + xb0 + yb8 + + word fline + xa0 + ya4 + xb0 + ybC + more 'L + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa0 + ya4 + xb0 + ybC + more 'M + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa2 + ya8 + xb0 + ybC + more + word fline + xa2 + ya8 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'N + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa4 + ya4 + xb0 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa2 + ya6 + xb4 + yb3 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + more + word fline + xa4 + ya4 + xb2 + yb8 + + word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + ya4 + xb2 + ybC + more 'T + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U + word fline + xa0 + ya6 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa2 + ya4 + xb0 + ybC + more 'V + word fline + xa2 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb0 + yb4 + more 'W + word fline + xa4 + yaC + xb4 + yb4 + more + word fline + xa2 + ya8 + xb0 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb4 + + word fline + xa4 + ya4 + xb0 + ybC + more 'X + word fline + xa0 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb2 + yb8 + more 'Y + word fline + xa4 + yaC + xb2 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb8 + + word fline + xa0 + yaC + xb4 + ybC + more 'Z + word fline + xa0 + ya4 + xb4 + ybC + more + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb4 + ybD + more + word fline + xa2 + ya3 + xb4 + yb3 + + word fline + xa4 + ya4 + xb0 + ybC '\ + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb0 + ybD + more + word fline + xa2 + ya3 + xb0 + yb3 + + word fline + xa2 + yaA + xb0 + yb6 + more '^ + word fline + xa2 + yaA + xb4 + yb6 + + word fline + xa0 + ya1 + xa4 + yb1 '_ + + word fline + xa1 + ya9 + xb3 + yb7 '` + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a + word fline + xa4 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b + word fline + xa0 + ya4 + xb0 + ybC + + word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c + word fline + xa2 + ya4 + xb4 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd + word fline + xa4 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e + word fline + xa0 + ya6 + xb4 + yb6 + more + word fline + xa2 + ya4 + xb4 + yb4 + + word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya4 + xb2 + ybA + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya4 + xb4 + yb6 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'i + word fline + xa2 + ya4 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j + word fline + xa2 + ya3 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word fline + xa0 + ya4 + xb0 + ybC + more 'k + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + ya6 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb4 + yb4 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'l + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa1 + yaC + xb2 + ybC + + word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm + word farc + xa3 + ya7 + a8 + ax1 + ay1 + more + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb7 + more + word fline + xa4 + ya4 + xb4 + yb7 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb6 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 'o + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p + word fline + xa0 + ya1 + xb0 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q + word fline + xa4 + ya1 + xb4 + yb8 + + word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r + word fline + xa0 + ya4 + xb0 + yb8 + + word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's + word farc + xa2 + ya5 + aB + ax2 + ay1 + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb2 + ybA + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb8 + + word fline + xa0 + ya8 + xb2 + yb4 + more 'v + word fline + xa4 + ya8 + xb2 + yb4 + + word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w + word farc + xa3 + ya5 + aA + ax1 + ay1 + more + word fline + xa0 + ya5 + xb0 + yb8 + more + word fline + xa2 + ya5 + xb2 + yb6 + more + word fline + xa4 + ya5 + xb4 + yb8 + + word fline + xa0 + ya8 + xb4 + yb4 + more 'x + word fline + xa0 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word fline + xa0 + ya8 + xb4 + yb8 + more 'z + word fline + xa4 + ya8 + xb0 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ + word farc + xa1 + ya6 + aC + ax1 + ay2 + more + word farc + xa1 + yaA + aF + ax1 + ay2 + more + word farc + xa3 + ya6 + aE + ax1 + ay3 + + word fline + xa2 + ya3 + xb2 + ybD '| + + word farc + xa1 + yaA + aC + ax1 + ay3 + more '} + word farc + xa3 + ya6 + aD + ax1 + ay2 + more + word farc + xa3 + yaA + aE + ax1 + ay2 + more + word farc + xa1 + ya6 + aF + ax1 + ay3 + + word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ + word farc + xa3 + ya8 + aA + ax1 + ay1 + +' Vector font - custom characters ($7F+) + + word fline + xa2 + ya9 + xb0 + yb4 + more 'delta + word fline + xa2 + ya9 + xb4 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega + word farc + xa1 + ya7 + aE + ax1 + ay2 + more + word farc + xa3 + ya7 + aF + ax1 + ay2 + more + word fline + xa1 + ya5 + xb1 + yb4 + more + word fline + xa3 + ya5 + xb3 + yb4 + more + word fline + xa0 + ya4 + xb1 + yb4 + more + word fline + xa4 + ya4 + xb3 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet + +CON fx = 3 'number of custom characters + +CON ''------------------------------------------------- GRAPHICS-HEAP +' +' diese daten werden zur laufzeit nur wärend des systemstarts gebraucht +' nach dem start steht dieser bereich bis zum screenpuffer als +' dynamischer speicher für strings, vektorobjekte und sprites zur verfügung +' +DAT ' graphics-heap-start (temp. pasm-puffer) + +grdat + +DAT ' keyboard-pasm-code (wird nach start als heap genutzt) + +'****************************************** +'* Assembly language PS/2 keyboard driver * +'****************************************** + + org +' +' +' Entry +' +entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto + mov x,par + add x,#11*4 + mov y,#4 +:par rdlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + mov _head,#0 'reset output parameter _head +' +' +' Reset keyboard +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + movd :par,#_present 'reset output parameters _present/_states[8] + mov x,#1+8 +:par mov 0,#0 + add :par,dlsb + djnz x,#:par + + mov stat,#8 'set reset flag +' +' +' Update parameters +' +update movd :par,#_head 'update output parameters _head/_present/_states[8] + mov x,par + add x,#1*4 + mov y,#1+1+8 +:par wrlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + test stat,#8 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get scancode +' +newcode mov stat,#0 'reset state + +:same call #receive 'receive byte from keyboard + + cmp data,#$83+1 wc 'scancode? + + if_nc cmp data,#$AA wz 'powerup/reset? + if_nc_and_z jmp #configure + + if_nc cmp data,#$E0 wz 'extended? + if_nc_and_z or stat,#1 + if_nc_and_z jmp #:same + + if_nc cmp data,#$F0 wz 'released? + if_nc_and_z or stat,#2 + if_nc_and_z jmp #:same + + if_nc jmp #newcode 'unknown, ignore +' +' +' Translate scancode and enter into buffer +' + test stat,#1 wc 'lookup code with extended flag + rcl data,#1 + mov data_s,data 'keyboard-de: store scancode for next table lookup with shift + call #look + + cmp data,#0 wz 'if unknown, ignore + if_z jmp #newcode + + mov t,_states+6 'remember lock keys in _states + + mov x,data 'set/clear key bit in _states + shr x,#5 + add x,#_states + movd :reg,x + mov y,#1 + shl y,data + test stat,#2 wc +:reg muxnc 0,y + + if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done + if_c jmp #update + + mov y,_states+7 'get shift/ctrl/alt/win bit pairs + shr y,#16 + + cmpsub data,#$E0 wc 'translate keypad, considering numlock + if_c test _locks,#%100 wz + if_c_and_z add data,#@keypad1-@table + if_c_and_nz add data,#@keypad2-@table + if_c call #look + if_c jmp #:flags + + 'for keyboard-de changed #$DD to #lock + 'in next code segment + + cmpsub data,#lock wc 'handle scrlock/capslock/numlock + if_c mov x,#%001_000 + if_c shl x,data + if_c andn x,_locks + if_c shr x,#3 + if_c shr t,#29 'ignore auto-repeat + if_c andn x,t wz + if_c xor _locks,x + if_c add data,#lock + if_c_and_nz or stat,#4 'if change, set configure flag to update leds + +{{ for keyboard-us-en start }} +{{ + + test y,#%11 wz 'get shift into nz +' +'Translate scan-codes $5B..$60 with characters from table "shift1" +' + if_nz cmp data,#$60+1 wc 'check shift1 + if_nz_and_c cmpsub data,#$5B wc + if_nz_and_c add data,#@shift1-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + +' +'Translate scan-codes $27..$3D with characters from table "shift2" +' + if_nz cmp data,#$3D+1 wc 'check shift2 + if_nz_and_c cmpsub data,#$27 wc + if_nz_and_c add data,#@shift2-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + test _locks,#%010 wc 'check shift-alpha, considering capslock + muxnc :shift,#$20 + test _locks,#$40 wc + if_nz_and_nc xor :shift,#$20 + cmp data,#"z"+1 wc + if_c cmpsub data,#"a" wc +:shift if_c add data,#"A" + if_c andn y,#%11 +}} +{{ for keyboard-us-en end }} + +{{ for keyboard-de start }} + + cmp data,#de_ae wz 'replace ae + if_z mov data,#"ä" + cmp data,#de_oe wz 'replace oe + if_z mov data,#"ö" + cmp data,#de_ue wz 'replace ue + if_z mov data,#"ü" + +' +'Documentation of control-key bits +' +' test y,#%00000011 wz 'get SHIFT into nz +' test y,#%00000100 wz 'get CTRL-L into nz +' test y,#%00001000 wz 'get CTRL-R into nz +' test y,#%00010000 wz 'get ALT-L into nz +' test y,#%00100000 wz 'get ALT-R into nz +' test y,#%01000000 wz 'get WIN-L into nz +' test y,#%10000000 wz 'get WIN-R into nz + + +' +'Translate scan-codes with characters from "table_shift" +' + + test y,#%00000011 wz 'get shift into nz + test _locks,#$40 wc + if_nz_and_nc mov data,data_s 'reload scancode + if_nz_and_nc call #look_shift 'translate by table_shift + + +' +'Translate scan-codes with characters from "table_alt_r" +' + + test y,#%00100000 wz 'get ALT-R (AltGr) into nz + if_nz mov data,data_s 'reload scancode + if_nz call #look_alt_r 'translate by table_alt_r + + +{{ for keyboard-de end }} + + +:flags ror data,#8 'add shift/ctrl/alt/win flags + mov x,#4 '+$100 if shift +:loop test y,#%11 wz '+$200 if ctrl + shr y,#2 '+$400 if alt + if_nz or data,#1 '+$800 if win + ror data,#1 + djnz x,#:loop + rol data,#12 + + rdlong x,par 'if room in buffer and key valid, enter + sub x,#1 + and x,#$F + cmp x,_head wz + if_nz test data,#$FF wz + if_nz mov x,par + if_nz add x,#11*4 + if_nz add x,_head + if_nz add x,_head + if_nz wrword data,x + if_nz add _head,#1 + if_nz and _head,#$F + + test stat,#4 wc 'if not configure flag, done + if_nc jmp #update 'else configure to update leds +' +' +' Configure keyboard +' +configure mov data,#$F3 'set keyboard auto-repeat + call #transmit + mov data,_auto + and data,#%11_11111 + call #transmit + + mov data,#$ED 'set keyboard lock-leds + call #transmit + mov data,_locks + rev data,#-3 & $1F + test data,#%100 wc + rcl data,#1 + and data,#%111 + call #transmit + + mov x,_locks 'insert locks into _states + and x,#%111 + shl _states+7,#3 + or _states+7,x + ror _states+7,#3 + + mov _present,#1 'set _present + + jmp #update 'done + +{{ for keyboard-de start }} +' +' Lookup byte in table_shift +' +look_shift ror data,#2 'perform lookup + movs :reg,data + add :reg,#table_shift + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + and data,#$FF 'isolate byte +look_shift_ret ret + +' +' Lookup byte in table_alt_r +' +look_alt_r ror data,#2 'perform lookup + movs :reg,data + add :reg,#table_alt_r + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + and data,#$FF 'isolate byte +look_alt_r_ret ret + +{{ for keyboard-de end }} + +' +' +' Lookup byte in table +' +look ror data,#2 'perform lookup + movs :reg,data + add :reg,#table + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + + jmp #rand 'isolate byte +' +' +' Transmit byte to keyboard +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov x,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz x,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset keyboard + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from keyboard +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov x,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz x,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset keyboard + if_nc jmp #reset +rand and data,#$FF 'isolate byte + +look_ret +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov y,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz y,#reset 'if timeout, reset keyboard +wait_ret +wait_c0_ret ret + + +c0 if_c djnz y,#wloop '(if_never replacements) +c1 if_nc djnz y,#wloop +c0d0 if_c_or_nz djnz y,#wloop +c1d1 if_nc_or_z djnz y,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +' +' +' Lookup table +' ascii scan extkey regkey ()=keypad +' + +{{keyboard-us-en start}} +{{ +table + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D8,$0000,$00D4,$00D2,$00D0,$00D1,$00DB + + ' + '$08 --- F10 F8 F6 F4 TAB ` --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D9,$00D7,$00D5,$00D3,$0009,$0060,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L q 1 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2,$0071,$0031,$0000 + + ' WIN-L + '$18 --- --- z s a w 2 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$007A,$0073,$0061,$0077,$0032,$F600 + + ' WIN-R + '$20 --- c x d e 4 3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0063,$0078,$0064,$0065,$0034,$0033,$F700 + + ' Apps + '$28 --- Spc v f t r 5 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0020,$0076,$0066,$0074,$0072,$0035,$CC00 + + ' Power + '$30 --- n b h g y 6 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$006E,$0062,$0068,$0067,$0079,$0036,$CD00 + + ' Sleep + '$38 --- --- m j u 7 8 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$006D,$006A,$0075,$0037,$0038,$CE00 + + ' + '$40 --- , k i o 0 9 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002C,$006B,$0069,$006F,$0030,$0039,$0000 + + ' (/) + '$48 --- . / l } p + --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002E,$EF2F,$006C,$003B,$0070,$002D,$0000 + + ' + '$50 --- --- { --- [ = --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0027,$0000,$005B,$003D,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER ] --- \ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DE,$00F1,$EB0D,$005D,$0000,$005C,$CF00,$0000 + + ' + '$60 --- --- --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$00C8,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$C5E1,$0000,$C0E4,$C4E7,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $CAE0,$C9EA,$C3E2,$00E5,$C1E6,$C2E8,$00CB,$00DF + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DA,$00EC,$C7E3,$00ED,$DCEE,$C6E9,$00DD,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$00D6 + + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + +' +'Table "shift1" for scan-codes $5B..$60 +' +shift1 byte "{|}", 0, 0, "~" + +' +'Table "shift1" for scan-codes $27..$3D +' +shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" +}} +{{keyboard-us-en end}} + + +{{keyboard-de start}} + +table + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D8,$0000,$00D4,$00D2,$00D0,$00D1,$00DB + + ' + '$08 --- F10 F8 F6 F4 TAB _^_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D9,$00D7,$00D5,$00D3,$0009,$005E,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L q 1 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2,$0071,$0031,$0000 + + ' WIN-L + '$18 --- --- _y_ s a w 2 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0079,$0073,$0061,$0077,$0032,$F600 + + ' WIN-R + '$20 --- c x d e 4 3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0063,$0078,$0064,$0065,$0034,$0033,$F700 + + ' Apps + '$28 --- Spc v f t r 5 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0020,$0076,$0066,$0074,$0072,$0035,Apps + + ' Power + '$30 --- n b h g _z_ 6 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$006E,$0062,$0068,$0067,$007A,$0036,Power + + ' Sleep + '$38 --- --- m j u 7 8 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$006D,$006A,$0075,$0037,$0038,Sleep + + ' + '$40 --- , k i o 0 9 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002C,$006B,$0069,$006F,$0030,$0039,$0000 + + ' (/) + '$48 --- . _-_ l _oe_ p _sz_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$002E,$EF2D,$006C,de_oe,$0070,$00DF,$0000 + + ' + '$50 --- --- _ae_ --- _ue_ _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,de_ae,$0000,de_ue,$0060,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER _+_ --- # --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word CpsLk,$00F1,$EB0D,$002B,$0000,$0023,WkUp ,$0000 + + ' + '$60 --- _<_ --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003C,$0000,$0000,$0000,$0000,BkSp ,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,CrsEn,$0000,CrsLt,CrsHm,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word Ins , Del ,CrsDn,$00E5,CrsRt,CrsUp, Esc ,NumLk + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DA,$00EC,PgDn ,$00ED,$DCEE,PgUp ,ScrLk,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$00D6 + + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + + +table_shift + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D8,$0000,$00D4,$00D2,$00D0,$00D1,$00DB + + ' + '$08 --- F10 F8 F6 F4 TAB _°_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$00D9,$00D7,$00D5,$00D3,$0009,$00B0,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L Q ! --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2,$0051,$0021,$0000 + + ' WIN-L + '$18 --- --- _Y_ S A W " --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0059,$0053,$0041,$0057,$0022,$F600 + + ' WIN-R + '$20 --- C X D E $ SHF+3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0043,$0058,$0044,$0045,$0024,$0014,$F700 + + ' Apps + '$28 --- Spc V F T R % --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0020,$0056,$0046,$0054,$0052,$0025,Apps + + ' Power + '$30 --- N B H G _Z_ & --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$004E,$0042,$0048,$0047,$005A,$0026,Power + + ' Sleep + '$38 --- --- M J U / ( --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$004D,$004A,$0055,$002F,$0028,Sleep + + ' + '$40 --- ; K I O _=_ ) --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003B,$004B,$0049,$004F,$003D,$0029,$0000 + + ' (/) + '$48 --- : ___ L _OE_ P _sz_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003A,$EF5F,$004C,$00D6,$0050,$003F,$0000 + + ' + '$50 --- --- _AE_ --- _UE_ _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$00C4,$0000,$00DC,$0060,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER _*_ --- _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word CpsLk,$00F1,$EB0D,$002A,$0000,$0027,WkUp ,$0000 + + ' + '$60 --- _>_ --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$003E,$0000,$0000,$0000,$0000,BkSp ,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,CrsEn,$0000,CrsLt,CrsHm,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word Ins , Del ,CrsDn,$00E5,CrsRt,CrsUp, Esc ,NumLk + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $00DA,$00EC,PgDn ,$00ED,$DCEE,PgUp ,ScrLk,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$00D6 + + + +table_alt_r + ' + '$00 --- F9 --- F5 F3 F1 F2 F12 + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0097,$0000,$0090,$009D,$009F,$009E,$0094 + + ' + '$08 --- F10 F8 F6 F4 TAB _^_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0096,$0093,$0091,$009C,$0009,$0000,$0000 + + ' ALT-R Left CTRL-R + '$10 --- ALT-L SHIFT --- CTRL_L q 1 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$F5F4,$00F0,$0000,$F3F2, "@", "¹", $0000 + + ' WIN-L + '$18 --- --- _y_ s a w 2 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000, "²", $F600 + + ' WIN-R + '$20 --- c x d e 4 3 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000, "€", $0000, "³", $F700 + + ' Apps + '$28 --- Spc v f t r 5 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$0000,Apps + + ' Power + '$30 --- n b h g _z_ 6 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$0000,Power + + ' Sleep + '$38 --- --- m j u 7 8 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000, "µ", $0000,$0000, "{" , "[" ,Sleep + + ' + '$40 --- , k i o 0 9 --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000, "}", "]", $0000 + + ' (/) + '$48 --- . _-_ l _oe_ p _sz_ --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000, "\", $0000 + + ' + '$50 --- --- _ae_ --- _ue_ _'_ --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 + + ' CAPS Right (ENTER) Wk.up + '$58 LOCK SHIFT ENTER _+_ --- # --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word CpsLk,$00F1,$EB0D, "~", $0000,$0000,WkUp ,$0000 + + ' + '$60 --- _<_ --- --- --- --- BkSpc --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000, "|", $0000,$0000,$0000,$0000,BkSp ,$0000 + + ' End Left Home + '$68 --- (1) --- (4) (7) --- --- --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0000,CrsEn,$0000,CrsLt,CrsHm,$0000,$0000,$0000 + + ' Ins Del Down --- Right Up + '$70 (0) (.) (2) (5) (6) (8) Esc NumLock + ' ===== ===== ===== ===== ===== ===== ===== ===== + word Ins , Del ,CrsDn,$00E5,CrsRt,CrsUp, Esc ,NumLk + + ' PgDn PrScr PgUp + '$78 F11 (+) (3) (-) (*) (9) ScrLock --- + ' ===== ===== ===== ===== ===== ===== ===== ===== + word $0095,$00EC,PgDn ,$00ED,$DCEE,PgUp ,ScrLk,$0000 + + ' + '$80 --- --- --- F7 + ' ===== ===== ===== ===== + word $0000,$0000,$0000,$0092 + + +{{keyboard-de end}} + +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +data_s res 1 'Scancode-Storage (for keyboard-de) +x res 1 +y res 1 +t res 1 + +_head res 1 'write-only +_present res 1 'write-only +_states res 8 'write-only +_dpin res 1 'read-only at start +_cpin res 1 'read-only at start +_locks res 1 'read-only at start +_auto res 1 'read-only at start + +'' +'' +'' _________ +'' Key Codes +'' +'' 00..DF = keypress and keystate +'' E0..FF = keystate only +'' +'' +'' 09 Tab +'' 0D Enter +'' 20 Space +'' 21 ! +'' 22 " +'' 23 # +'' 24 $ +'' 25 % +'' 26 & +'' 27 ' +'' 28 ( +'' 29 ) +'' 2A * +'' 2B + +'' 2C , +'' 2D - +'' 2E . +'' 2F / +'' 30 0..9 +'' 3A : +'' 3B ; +'' 3C < +'' 3D = +'' 3E > +'' 3F ? +'' 40 @ +'' 41..5A A..Z +'' 5B [ +'' 5C \ +'' 5D ] +'' 5E ^ +'' 5F _ +'' 60 ` +'' 61..7A a..z +'' 7B { +'' 7C | +'' 7D } +'' 7E ~ +'' +'' 80-BF (future international character support) +'' +'' C0 Left Arrow +'' C1 Right Arrow +'' C2 Up Arrow +'' C3 Down Arrow +'' C4 Home +'' C5 End +'' C6 Page Up +'' C7 Page Down +'' C8 Backspace +'' C9 Delete +'' CA Insert +'' CB Esc +'' CC Apps +'' CD Power +'' CE Sleep +'' CF Wakeup +'' +'' D0..DB F1..F12 +'' DC Print Screen +'' DD Scroll Lock +'' DE Caps Lock +'' DF Num Lock +'' +'' E0..E9 Keypad 0..9 +'' EA Keypad . +'' EB Keypad Enter +'' EC Keypad + +'' ED Keypad - +'' EE Keypad * +'' EF Keypad / +'' +'' F0 Left Shift +'' F1 Right Shift +'' F2 Left Ctrl +'' F3 Right Ctrl +'' F4 Left Alt +'' F5 Right Alt +'' F6 Left Win +'' F7 Right Win +'' +'' FD Scroll Lock State +'' FE Caps Lock State +'' FF Num Lock State +'' +'' +100 if Shift +'' +200 if Ctrl +'' +400 if Alt +'' +800 if Win +'' +'' eg. Ctrl-Alt-Delete = $6C9 +'' +'' +'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. + +DAT ' graphics-pasm-code (wird nach start als heap genutzt) + +'************************************* +'* Assembly language graphics driver * +'************************************* + + org +' +' +' Graphics driver - main loop +' +loop rdlong t1,par wz 'wait for command + if_z jmp #loop + + movd :arg,#arg0 'get 8 arguments + mov t2,t1 + mov t3,#8 +:arg rdlong arg0,t2 + add :arg,d0 + add t2,#4 + djnz t3,#:arg + + wrlong zero,par 'zero command to signify received + + call #setd 'set dx,dy from arg0,arg1 + + ror t1,#16+2 'lookup command address + add t1,#jumps + movs :table,t1 + rol t1,#2 + shl t1,#3 +:table mov t2,0 + shr t2,t1 + and t2,#$FF + jmp t2 'jump to command + + +jumps byte 0 '0 + byte setup_ '1 + byte color_ '2 + byte width_ '3 + byte plot_ '4 + byte line_ '5 + byte arc_ '6 + byte vec_ '7 + byte vecarc_ '8 + byte pix_ '9 + byte pixarc_ 'A + byte text_ 'B + byte textarc_ 'C + byte textmode_ 'D + byte fill_ 'E + byte loop 'F +' +' +' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr +' +setup_ mov xlongs,arg0 'set xlongs, ylongs + mov ylongs,arg1 + mov xorigin,arg2 'set xorigin, yorigin + mov yorigin,arg3 + mov basesptr,arg5 'set pointers + mov slicesptr,arg6 + + jmp #loop +' +' +' color(c) +' +color_ mov pcolor,arg0 'set pixel color + + jmp #loop +' +' +' width(w) pixel_passes +' +width_ mov pwidth,arg0 'set pixel width + mov passes,arg1 'set pixel passes + + jmp #loop +' +' +' plot(x, y) +' +plot_ call #plotd + + jmp #loop +' +' +' line(x, y) +' +line_ call #linepd + + jmp #loop +' +' +' arc(x, y, xr, yr, angle, anglestep, iterations, mode) +' +arc_ and arg7,#3 'limit mode + +:loop call #arca 'get arc dx,dy + + cmp arg7,#1 wz 'if not mode 1, set px,py + if_nz mov px,dx + if_nz mov py,dy + + tjz arg6,#loop 'if no points exit with new px,py + + cmp arg7,#3 wz 'if mode 3, set center + if_z call #setd + + test arg7,#1 wz 'if mode 0 or 2, plot point + if_z call #plotp + + test arg7,#1 wz 'if mode 1 or 3, plot line + if_nz call #linepd + + cmp arg7,#2 wz 'if mode 2, set mode 1 + if_z mov arg7,#1 + + add arg4,arg5 'step angle + djnz arg6,#:loop 'loop if more iterations + + jmp #loop +' +' +' vec(x, y, vecscale, vecangle, vecdef_ptr) +' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) +' +' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +' word length 'vector length +' ... 'more vectors +' ... +' word 0 'end of definition +' +vecarc_ call #arcmod + +vec_ tjz arg2,#loop 'if scale 0, exit + +:loop rdword t7,arg4 wz 'get vector mode+angle + add arg4,#2 + + if_z jmp #loop 'if mode+angle 0, exit + + rdword t1,arg4 'get vector length + add arg4,#2 + + abs t2,arg2 wc 'add/sub vector angle to/from angle + mov t6,arg3 + sumc t6,t7 + + call #multiply 'multiply length by scale + add t1,#$80 'round up 1/2 lsb + shr t1,#8 + + mov t4,t1 'get arc dx,dy + mov t5,t1 + call #arcd + + test t7,h8000 wc 'plot pixel or draw line? + if_nc call #plotd + test t7,h8000 wc + if_c call #linepd + + jmp #:loop 'get next vector +' +' +' pix(x, y, pixrot, pixdef_ptr) +' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) +' +' pixdef: word +' byte xwords, ywords, xorigin, yorigin +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' ... +' +pixarc_ call #arcmod + +pix_ mov t6,pcolor 'save color + + mov px,dx 'get center into px,py + mov py,dy + + mov sy,pwidth 'get actual pixel width + add sy,#1 + + rdbyte dx,arg3 'get dimensions into dx,dy + add arg3,#1 + rdbyte dy,arg3 + add arg3,#1 + + rdbyte t1,arg3 'get origin and adjust px,py + add arg3,#1 + rdbyte t2,arg3 + add arg3,#1 + neg t2,t2 + sub t2,#1 + add t2,dy + mov t3,sy +:adjust test arg2,#%001 wz + test arg2,#%110 wc + if_z sumnc px,t1 + if_nz sumc py,t1 + test arg2,#%010 wc + if_nz sumnc px,t2 + if_z sumnc py,t2 + djnz t3,#:adjust + +:yline mov sx,#0 'plot entire pix + mov t3,dx +:xword rdword t4,arg3 'read next pix word + add arg3,#2 + shl t4,#16 + mov t5,#8 +:xpixel rol t4,#2 'plot pixel within word + test t4,#1 wc 'set color + muxc pcolor,color1 + test t4,#2 wc + muxc pcolor,color2 wz '(z=1 if color=0) + if_nz call #plotp + test arg2,#%001 wz 'update px,py for next x + test arg2,#%110 wc + if_z sumc px,sy + if_nz sumnc py,sy + add sx,sy + djnz t5,#:xpixel 'another x pixel? + djnz t3,#:xword 'another x word? + if_z sumnc px,sx 'update px,py for next y + if_nz sumc py,sx + test arg2,#%010 wc + if_nz sumc px,sy + if_z sumc py,sy + djnz dy,#:yline 'another y line? + + mov pcolor,t6 'restore color + + jmp #loop +' +' +' text(x, y, @string) justx, justy +' textarc(x, y, xr, yr, angle, @string) justx, justy +' +textarc_ call #arcmod + +text_ add arg3,arg0 'add x into justx + add arg4,arg1 'add y into justy + +:chr rdbyte t1,arg2 wz 'get chr + add arg2,#1 + + if_z jmp #loop 'if 0, done + + sub t1,#$21 'if chr out of range, skip + cmp t1,#$7F-$21+fx wc + if_nc jmp #:skip + + mov arg5,fontptr 'scan font for chr definition +:scan tjz t1,#:def + rdword t2,arg5 + add arg5,#2 + test t2,h8000 wc + if_nc sub t1,#1 + jmp #:scan + +:def rdword t7,arg5 'get font definition word + add arg5,#2 + + call #fontxy 'extract initial x,y + + test t7,#$80 wc 'arc or line? + if_nc jmp #:line + + + mov t2,textsx 'arc, extract x radius + mov t3,#%0001_0001_1 + call #fontb + mov t4,t1 + + mov t2,textsy 'extract y radius + mov t3,#%0010_0011_1 + call #fontb + mov t5,t1 + + mov t2,#1 'extract starting angle + mov t3,#%0010_0011_0 + call #fontb + shl t1,#11 + + mov t6,t1 'extract angle sweep + mov t3,#%0010_0011_0 + call #fontb + neg arg6,t1 + shl arg6,#4 + add arg6,#65 + + call #arcd 'plot initial arc point + call #plotd + +:arc call #arcd 'connect subsequent arc points with lines + call #linepd + add t6,#$80 + djnz arg6,#:arc + + jmp #:more + + +:line call #plotd 'line, plot initial x,y + + call #fontxy 'extract terminal x,y + + call #linepd 'draw line + + +:more test t7,#$02 wc 'more font definition? + if_c jmp #:def + +:skip mov t1,textsp 'advance x to next chr position + mov t2,textsx + call #multiply + add arg3,t1 + + jmp #:chr 'get next chr + + +fontxy mov t2,textsx 'extract x + mov t3,#%0011_0111_0 + call #fontb + mov arg0,t1 + add arg0,arg3 + + mov t2,textsy 'extract y + mov t3,#%0100_1111_0 + call #fontb + mov arg1,t1 + add arg1,arg4 + +setd mov dx,xorigin 'set dx,dy from arg0,arg1 + add dx,arg0 + mov dy,yorigin + sub dy,arg1 +setd_ret +fontxy_ret ret + + +fontb mov t1,t7 'extract bitrange from font word + shr t3,#1 wc + and t1,t3 + if_c add t1,#1 + shr t3,#4 + shr t7,t3 + + shl t1,#32-4 'multiply t1[3..0] by t2 + mov t3,#4 +:loop shl t1,#1 wc + if_c add t1,t2 + djnz t3,#:loop + +fontb_ret ret +' +' +' textmode(x_scale, y_scale, spacing, justification) +' +textmode_ mov textsx,arg0 'set text x scale + mov textsy,arg1 'set text y scale + mov textsp,arg2 'set text spacing + + jmp #loop +' +' +' fill(x, y, da, db, db2, linechange, lines_minus_1) +' +fill_ shl dx,#16 'get left and right fractions + or dx,h8000 + mov t1,dx + + mov t2,xlongs 'get x pixels + shl t2,#4 + + add arg6,#1 'pre-increment line counter + +:yloop add dx,arg2 'adjust left and right fractions + add t1,arg3 + + cmps dx,t1 wc 'get left and right integers + if_c mov base0,dx + if_c mov base1,t1 + if_nc mov base0,t1 + if_nc mov base1,dx + sar base0,#16 + sar base1,#16 + + cmps base0,t2 wc 'left out of range? + if_c cmps hFFFFFFFF,base1 wc 'right out of range? + if_c cmp dy,ylongs wc 'y out of range? + if_nc jmp #:skip 'if any, skip + + mins base0,#0 'limit left and right + maxs base1,t2 wc + if_nc sub base1,#1 + + shl base0,#1 'make left mask + neg mask0,#1 + shl mask0,base0 + shr base0,#5 + + shl base1,#1 'make right mask + xor base1,#$1E + neg mask1,#1 + shr mask1,base1 + shr base1,#5 + + sub base1,base0 wz 'ready long count + add base1,#1 + + if_z and mask0,mask1 'if single long, merge masks + + shl base0,#1 'get long base + add base0,basesptr + rdword base0,base0 + shl dy,#2 + add base0,dy + shr dy,#2 + + mov bits0,mask0 'ready left mask +:xloop mov bits1,pcolor 'make color mask + and bits1,bits0 + rdlong pass,base0 'read-modify-write long + andn pass,bits0 + or pass,bits1 + wrlong pass,base0 + shl ylongs,#2 'advance to next long + add base0,ylongs + shr ylongs,#2 + cmp base1,#2 wz 'one more? + if_nz neg bits0,#1 'if not, ready full mask + if_z mov bits0,mask1 'if one more, ready right mask + djnz base1,#:xloop 'loop if more longs + +:skip sub arg5,#1 wc 'delta change? + if_c mov arg3,arg4 'if so, set new deltas +:same + add dy,#1 'adjust y + djnz arg6,#:yloop 'another y? + + jmp #loop +' +' +' Plot line from px,py to dx,dy +' +linepd cmps dx,px wc, wr 'get x difference + negc sx,#1 'set x direction + + cmps dy,py wc, wr 'get y difference + negc sy,#1 'set y direction + + abs dx,dx 'make differences absolute + abs dy,dy + + cmp dx,dy wc 'determine dominant axis + if_nc tjz dx,#:last 'if both differences 0, plot single pixel + if_nc mov count,dx 'set pixel count + if_c mov count,dy + mov ratio,count 'set initial ratio + shr ratio,#1 + if_c jmp #:yloop 'x or y dominant? + + +:xloop call #plotp 'dominant x line + add px,sx + sub ratio,dy wc + if_c add ratio,dx + if_c add py,sy + djnz count,#:xloop + + jmp #:last 'plot last pixel + + +:yloop call #plotp 'dominant y line + add py,sy + sub ratio,dx wc + if_c add ratio,dy + if_c add px,sx + djnz count,#:yloop + +:last call #plotp 'plot last pixel + +linepd_ret ret +' +' +' Plot pixel at px,py +' +plotd mov px,dx 'set px,py to dx,dy + mov py,dy + +plotp tjnz pwidth,#wplot 'if width > 0, do wide plot + + mov t1,px 'compute pixel mask + shl t1,#1 + mov mask0,#%11 + shl mask0,t1 + shr t1,#5 + + cmp t1,xlongs wc 'if x or y out of bounds, exit + if_c cmp py,ylongs wc + if_nc jmp #plotp_ret + + mov bits0,pcolor 'compute pixel bits + and bits0,mask0 + + shl t1,#1 'get address of pixel long + add t1,basesptr + mov t2,py + rdword t1,t1 + shl t2,#2 + add t1,t2 + + rdlong t2,t1 'write pixel + andn t2,mask0 + or t2,bits0 + wrlong t2,t1 +plotp_ret +plotd_ret ret +' +' +' Plot wide pixel +' +wplot mov t1,py 'if y out of bounds, exit + add t1,#7 + mov t2,ylongs + add t2,#7+8 + cmp t1,t2 wc + if_nc jmp #plotp_ret + + mov t1,px 'determine x long pair + sub t1,#8 + sar t1,#4 + cmp t1,xlongs wc + muxc jumps,#%01 '(use jumps[1..0] to store writes) + add t1,#1 + cmp t1,xlongs wc + muxc jumps,#%10 + + test jumps,#%11 wz 'if x out of bounds, exit + if_z jmp #plotp_ret + + shl t1,#1 'get base pair + add t1,basesptr + rdword base1,t1 + sub t1,#2 + rdword base0,t1 + + mov t1,px 'determine pair shifts + shl t1,#1 + movs :shift1,t1 + xor :shift1,#7<<1 + add t1,#9<<1 + movs :shift0,t1 + test t1,#$F<<1 wz '(account for special case) + if_z andn jumps,#%01 + + mov pass,#0 'ready to plot slices + mov slice,slicesptr + +:loop rdlong mask0,slice 'get next slice + mov mask1,mask0 + +:shift0 shl mask0,#0 'position slice +:shift1 shr mask1,#0 + + mov bits0,pcolor 'colorize slice + and bits0,mask0 + mov bits1,pcolor + and bits1,mask1 + + mov t1,py 'plot lower slice + add t1,pass + cmp t1,ylongs wc + if_c call #wslice + + mov t1,py 'plot upper slice + test pwidth,#1 wc + subx t1,pass + cmp t1,ylongs wc + if_c call #wslice + + add slice,#4 'next slice + add pass,#1 + cmp pass,passes wz + if_nz jmp #:loop + + jmp #plotp_ret +' +' +' Plot wide pixel slice +' +wslice shl t1,#2 'ready long offset + + add base0,t1 'plot left slice + test jumps,#%01 wc + if_c rdlong t2,base0 + if_c andn t2,mask0 + if_c or t2,bits0 + if_c wrlong t2,base0 + + add base1,t1 'plot right slice + test jumps,#%10 wc + if_c rdlong t2,base1 + if_c andn t2,mask1 + if_c or t2,bits1 + if_c wrlong t2,base1 + + sub base0,t1 'restore bases + sub base1,t1 + +wslice_ret ret +' +' +' Get arc point from args and then move args 5..7 to 2..4 +' +arcmod call #arca 'get arc using first 5 args + + mov arg0,dx 'set arg0,arg1 + sub arg0,xorigin + mov arg1,yorigin + sub arg1,dy + + mov arg2,arg5 'move args 5..7 to 2..4 + mov arg3,arg6 + mov arg4,arg7 + +arcmod_ret ret +' +' +' Get arc dx,dy from arg0,arg1 +' +' in: arg0,arg1 = center x,y +' arg2/t4 = x length +' arg3/t5 = y length +' arg4/t6 = 13-bit angle +' +' out: dx,dy = arc point +' +arca mov t4,arg2 'use args + mov t5,arg3 + mov t6,arg4 + +arcd call #setd 'reset dx,dy to arg0,arg1 + + mov t1,t6 'get arc dx + mov t2,t4 + call #polarx + add dx,t1 + + mov t1,t6 'get arc dy + mov t2,t5 + call #polary + sub dy,t1 +arcd_ret +arca_ret ret +' +' +' Polar to cartesian +' +' in: t1 = 13-bit angle +' t2 = 16-bit length +' +' out: t1 = x|y +' +polarx add t1,sine_90 'cosine, add 90° for sine lookup +polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz + test t1,sine_90 wc 'get sine quadrant 2|4 into c + negc t1,t1 'if sine quadrant 2|4, negate table offset + or t1,sine_table 'or in sine table address >> 1 + shl t1,#1 'shift left to get final word address + rdword t1,t1 'read sine/cosine word + call #multiply 'multiply sine/cosine by length to get x|y + add t1,h8000 'add 1/2 lsb to round up x|y fraction + shr t1,#16 'justify x|y integer + negnz t1,t1 'if sine quadrant 3|4, negate x|y +polary_ret +polarx_ret ret + +sine_90 long $0800 '90° bit +sine_180 long $1000 '180° bit +sine_table long $E000 >> 1 'sine table address shifted right +' +' +' Multiply +' +' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) +' t2 = 16-bit multiplier +' +' out: t1 = 32-bit product +' +multiply mov t3,#16 + shl t2,#16 + shr t1,#1 wc + +:loop if_c add t1,t2 wc + rcr t1,#1 wc + djnz t3,#:loop + +multiply_ret ret +' +' +' Defined data +' +zero long 0 'constants +d0 long $200 +h8000 long $8000 +hFFFFFFFF long $FFFFFFFF +color1 long %%1111111111111111 +color2 long %%2222222222222222 + +fontptr long 0 'font pointer (set before cognew command) + +pcolor long %%1111111111111111 'pixel color +pwidth long 0 'pixel width +passes long 1 'pixel passes +textsx long 1 'text scale x +textsy long 1 'text scale y +textsp long 6 'text spacing +' +' +' Undefined data +' +t1 res 1 'temps +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 + +arg0 res 1 'arguments passed from high-level +arg1 res 1 +arg2 res 1 +arg3 res 1 +arg4 res 1 +arg5 res 1 +arg6 res 1 +arg7 res 1 + +basesptr res 1 'pointers +slicesptr res 1 + +xlongs res 1 'bitmap metrics +ylongs res 1 +xorigin res 1 +yorigin res 1 + +dx res 1 'line/plot coordinates +dy res 1 +px res 1 +py res 1 + +sx res 1 'line +sy res 1 +count res 1 +ratio res 1 + +pass res 1 'plot +slice res 1 +base0 res 1 +base1 res 1 +mask0 res 1 +mask1 res 1 +bits0 res 1 +bits1 res 1 + +DAT ' graphics-heap-ende + +grdatend + +{{ ' lizenz + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + + + diff --git a/system/bellatrix/bel-htext/htext.spin b/system/bellatrix/bel-htext/htext.spin new file mode 100644 index 0000000..43ad70d --- /dev/null +++ b/system/bellatrix/bel-htext/htext.spin @@ -0,0 +1,935 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : VGA-Text-Treiber 1024x768 Pixel, 128x64 Zeichen +Chip : Bellatrix +Typ : Treiber +Version : 00 +Subversion : 01 +Funktion : VGA-Text- und Tastatur-Treiber +Komponenten : VGA 1024x768 Tile Driver v0.9 Chip Gracey MIT + PS/2 Keyboard Driver v1.0.1 Chip Gracey, ogg MIT + +COG's : MANAGMENT 1 COG + VGA 2 COG's + KEYB 1 COG + ------------------- + 4 COG's + +Logbuch : + +23-10-2008-dr235 - erste funktionsfähige version erstellt + - cursor eingebaut +06-11-2008-dr235 - keyb auf deutsche zeichenbelegung angepasst (ohne umlaute) +24-11-2008-dr235 - tab, setcur, pos1, setx, sety, getx, gety, setcol, sline, screeninit + curon, curoff + - beltest +13-03-2009-dr235 - LF als Zeichencode ausgeblendet +22-03-2009-dr235 - abfrage für statustasten eingefügt +05-09-2009-dr235 - abfrage der laufenden cogs eingefügt + - deutschen tastaturtreiber mit vollständiger belegung! von ogg eingebunden +22-03-2010-dr235 - anpassung trios +01-05-2010-dr235 - scrollup/scrolldown eingebunden & getestet +03-05-2010-dr235 - settab/getcols/getrows/getresx/getresy eingefügt & getestet + - hive-logo eingefügt + +Kommandoliste: + +0 1 Tastaturstatus abfragen +0 2 Tastaturzeichen holen +0 3 n Screensteuerzeichen +0 3 0 CLS +0 3 1 Home +0 3 2 Backspace +0 3 3 TAB +0 3 4 n SETCUR Cursorzeichen auf n setzen +0 3 5 POS1 +0 3 6 x SETX +0 3 7 y SETY +0 3 8 (x) GETX +0 3 9 (y) GETY +0 3 10 c SETCOL +0 3 11 n SLINE +0 3 13 SCREENINIT +0 3 14 CURON +0 3 15 CUROFF +0 3 16 SCROLLUP +0 3 17 SCROLLDOWN +0 3 18 n0..n7 SETTABS +0 4 (status) Status der Sondertasten abfragen +0 5 x y Hive-Logo ausgeben +0 90 cnr (c0) (c1) Farbregister auslesen +0 91 cnr c0 c1 Farbregister setzen +0 92 (res-x) +0 93 (res-y) +0 94 (cols) +0 95 (rows) +0 96 (cogs) Status der belegten COG's abfragen +0 97 (spez) Spezifikation abfragen +0 98 (ver) Version abfragen +0 99 Reboot und neuen Treiber laden + + +1..255 Zeichenausgabe + + +Notizen: +- setheader + +ACHTUNG: row ist nicht die Zeilenposition, da zwei tiles untereinander ein zeichen +bilden. vielmehr ist die reale zeilenposition row/2. + + +}} + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +'signaldefinitionen bellatrixix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +' +---------- +' | +------- system +' | | +---- version (änderungen) +' | | | +- subversion (hinzufügungen) +CHIP_VER = $00_01_01_01 +' +' +---------- +' | +-------- +' | |+------- vektor +' | ||+------ grafik +' | |||+----- text +' | ||||+---- maus +' | |||||+--- tastatur +' | ||||||+-- vga +' | |||||||+- tv +CHIP_SPEC = %00000000_00000000_00000000_00010110 + +COLS = VGA#cols 'anzahl der spalten +ROWS = VGA#rows 'anzahl der zeilen +TILES = COLS * ROWS +RESX = 1024 +RESY = 768 +COLORANZ = 8 + +USERCHARS = 16 '8x2 logo + +TAB1 = 16 +TAB2 = 32 +TAB3 = 48 +TABANZ = 8 +SPACETILE = $8000 + $20 << 6 + +VGA_BASPORT = 8 'vga startport +VGA_RESX = COLS * 16 'vga anzahl pixel x +VGA_RESY = ROWS * 16 'vga anzahl pixel y +KEYB_DPORT = BEL_KEYBD 'tastatur datenport +KEYB_CPORT = BEL_KEYBC 'tastatur taktport +CURSORCHAR = $0E 'cursorzeichen + +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + + +OBJ + + vga : "bel-htext" + keyb : "bel-keyb" + +VAR + + long keycode 'letzter tastencode + long col, row, color 'spalten-, zeilenposition und zeichenfarbe + byte cursor 'cursorzeichen + byte curstat 'cursorstatus 1 = ein + byte sline 'startzeile des scrollfensters (0 = 1. zeile) + byte eline 'endzeile des scrollfensters (0 = 1. zeile) + byte tab[TABANZ] 'tabulatorpositionen + word user_charbase 'adresse der userzeichen + +' htext-variablen + byte array[TILES] 'bildschirmspeicher + byte VGACogStatus 'status des vga-treiber-cogs + byte cx0, cy0, cm0 'x, y, mode von cursor 0 + byte cx1, cy1, cm1 'x, y, mode von cursor 1 + word colors[rows] 'zeilenfarbenspeicher + long ScreenIndex 'index im bildschirmspeicher + long RowIndex 'zeilenindex + long ColumnIndex 'spaltenindex + long sync 'gets signal for vertical refresh sync + +CON ''------------------------------------------------- BELLATRIX + +PUB main | zeichen,n 'chip: kommandointerpreter +''funktionsgruppe : chip +''funktion : kommandointerpreter +''eingabe : - +''ausgabe : - + + init_subsysteme 'bus/vga/keyboard/maus initialisieren + repeat + zeichen := bus_getchar '1. zeichen empfangen + if zeichen > 0 + print_char(zeichen) + else + zeichen := bus_getchar '2. zeichen kommando empfangen + case zeichen + 1: key_stat '1: Tastaturstatus senden + 2: key_code '2: Tastaturzeichen senden + 3: print_ctrl(bus_getchar) '3: Steuerzeichen ($100..$1FF) ausgeben + 4: key_spec '4: Statustasten ($100..$1FF) abfragen + 5: print_logo '5: hive-logo ausgeben +' ---------------------------------------------- CHIP-MANAGMENT + 90: mgr_getcolor 'farbregister auslesen + 91: mgr_setcolor 'farbregister setzen + 92: mgr_getresx 'x-auflösung abfragen + 93: mgr_getresy 'y-auflösung abfragen + 94: mgr_getcols 'spaltenanzahl abfragen + 95: mgr_getrows 'zeilenanzahl abfragen + 96: mgr_getcogs 'freie cogs abfragen + 97: mgr_getspec 'codeversion abfragen + 98: mgr_getver '5: Belegte Cogs abfragen + 99: reboot '99: bellatrix neu starten + +PUB init_subsysteme|i 'chip: initialisierung des bellatrix-chips +''funktionsgruppe : chip +''funktion : - initialisierung des businterface +'' : - vga & keyboard-treiber starten +''eingabe : - +''ausgabe : - + + dira := db_in 'datenbus auf eingabe schalten + outa[bus_hs] := 1 'handshake inaktiv + keyb.start(keyb_dport, keyb_cport) 'tastaturport starten + start_htext(vga_basport, @sync) 'vga-treiber starten + print_char($100) 'bildschirm löschen + cursor := CURSORCHAR 'cursorzeichen setzen + curstat := 1 'cursor anschalten + sline := 2 'startzeile des scrollbereichs setzen + eline := rows 'enbdzeile des scrollbereichs setzen + repeat i from 0 to TABANZ-1 'tabulatoren setzen + tab[i] := i * 4 + + user_charbase := @uchar & $FFC0 'berechnet die nächste 64-byte-grenze hinter dem zeichensatz + longmove(user_charbase,@uchar,16*USERCHARS) 'verschiebt den zeichensatz auf die nächste 64-byte-grenze + +PUB start_htext(BasePin,pSyncAddress)| ColorIndex + vga.stop 'stopt ein bereits laufenden vga-task + cm0 := %000 'cursor 0 aus + cm1 := %110 'cursor 1 unterstrich blinkend + print_char($0E) 'bildschirm löschen + + ColorIndex := 0 'graue balken auf scharzem grund + repeat rows + colors[ColorIndex++] := %00000100_01101000 'rrggbb00_rrggbb00 + + VGACogStatus := VGA.Start(BasePin,@array, @colors, @cx0, pSyncAddress) 'startet vga-treiber (2cogs) + + return true + +PUB bus_putchar(zeichen) 'chip: ein byte an regnatix senden +''funktionsgruppe : chip +''funktion : ein byte an regnatix senden +''eingabe : byte +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[bus_hs] := 1 'daten ungültig + +PUB bus_getchar : zeichen 'chip: ein byte von regnatix empfangen +''funktionsgruppe : chip +''funktion : ein byte von regnatix empfangen +''eingabe : - +''ausgabe : byte + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[bus_hs] := 0 'daten quittieren + outa[bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + + + +CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN + +PUB sub_putlong(wert) 'sub: long senden +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert an regnatix zu senden +''eingabe : 32bit wert der gesendet werden soll +''ausgabe : - +''busprotokoll : [put.byte1][put.byte2][put.byte3][put.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + bus_putchar(wert >> 24) '32bit wert senden hsb/lsb + bus_putchar(wert >> 16) + bus_putchar(wert >> 8) + bus_putchar(wert) + +PUB sub_getlong:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := bus_getchar << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar << 16 + wert := wert + bus_getchar << 8 + wert := wert + bus_getchar + +CON ''------------------------------------------------- CHIP-MANAGMENT-FUNKTIONEN + +PUB mgr_getcolor|cnr 'cmgr: farbregister auslesen +''funktionsgruppe : cmgr +''funktion : farbregister auslesen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][091][get.cnr][sub_putlong.color] +'' : cnr - nummer des farbregisters 0..15 +'' : color - erster wert + + cnr := bus_getchar + sub_putlong(long[@vgacolors][cnr]) + +PUB mgr_setcolor|cnr 'cmgr: farbregister setzen +''funktionsgruppe : cmgr +''funktion : farbregister setzen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][091][get.cnr][sub_getlong.color] +'' : cnr - nummer des farbregisters 0..15 +'' : color - farbwert + + cnr := bus_getchar + long[@vgacolors][cnr] := sub_getlong + +PUB mgr_getresx 'cmgr: abfrage der x-auflösung +''funktionsgruppe : cmgr +''funktion : abfrage der x-auflösung +''eingabe : - +''ausgabe : - +''busprotokoll : [0][092][put.resx] +'' : resx - x-auflösung + + sub_putlong(RESX) + +PUB mgr_getresy 'cmgr: abfrage der y-auflösung +''funktionsgruppe : cmgr +''funktion : abfrage der y-auflösung +''eingabe : - +''ausgabe : - +''busprotokoll : [0][093][put.resy] +'' : resy - y-auflösung + + sub_putlong(RESY) + +PUB mgr_getcols 'cmgr: abfrage der Textspalten +''funktionsgruppe : cmgr +''funktion : abfrage der textspalten +''eingabe : - +''ausgabe : - +''busprotokoll : [0][094][put.cols] +'' : cols - anzahl der textspalten + + bus_putchar(COLS) + +PUB mgr_getrows 'cmgr: abfrage der textzeilen +''funktionsgruppe : cmgr +''funktion : abfrage der textzeilen +''eingabe : - +''ausgabe : - +''busprotokoll : [0][095][put.rows] +'' : rows - anzahl der textzeilen + + bus_putchar(ROWS/2) + +PUB mgr_getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind +''funktionsgruppe : cmgr +''funktion : abfrage wie viele cogs in benutzung sind +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [0][096][put.cogs] +'' : cogs - anzahl der belegten cogs + + cogs := i := 0 + repeat 'loads as many cogs as possible and stores their cog numbers + c := cog[i] := cognew(@entry, 0) + if c=>0 + i++ + while c => 0 + cogs := i + repeat 'unloads the cogs and updates the string + i-- + if i=>0 + cogstop(cog[i]) + while i=>0 + bus_putchar(cogs) + +PUB mgr_getspec 'cmgr: abfrage der spezifikation des chips +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [097][sub_putlong.spec] +'' : spec - spezifikation +'' +'' +'' +---------- +'' | +-------- +'' | |+------- vektor +'' | ||+------ grafik +'' | |||+----- text +'' | ||||+---- maus +'' | |||||+--- tastatur +'' | ||||||+-- vga +'' | |||||||+- tv +''CHIP_SPEC = %00000000_00000000_00000000_00010110 + + sub_putlong(CHIP_SPEC) + +PUB mgr_getver 'cmgr: abfrage der version +''funktionsgruppe : cmgr +''funktion : abfrage der version und spezifikation des chips +''eingabe : - +''ausgabe : cogs - anzahl der cogs +''busprotokoll : [098][sub_putlong.ver] +'' : ver - version +'' +'' +---------- +'' | +------- system +'' | | +---- version (änderungen) +'' | | | +- subversion (hinzufügungen) +''CHIP_VER = $00_01_01_01 + + sub_putlong(CHIP_VER) + +CON ''------------------------------------------------- KEYBOARD-FUNKTIONEN + +PUB key_stat 'key: tastaturstatus abfragen + + bus_putchar(keyb.gotkey) + +PUB key_code 'key: tastencode abfragen + + keycode := keyb.key + bus_putchar(keycode) + +PUB key_spec 'key: statustaten vom letzten tastencode abfragen + + bus_putchar(keycode >> 8) + +CON ''------------------------------------------------- SCREEN-FUNKTIONEN + +PUB print_char(c) | code,n 'screen: zeichen auf bildschirm ausgeben +{{zeichen auf bildschirm ausgeben}} + + case c + + $0A: 'LF ausblenden + return + + $00..$0C: + schar(c) + + $0D: 'return? + newline + + $0E..$FF: 'character? + schar(c) + +PUB home +'' move writing place to upper left without clearing screen + SetXY(0,sline) + +PUB SetXY(x,y) + ColumnIndex := x <# cols 'setzt spalte mit begrenzung auf spaltenzahl + RowIndex := y <# rows 'setzt zeile mit begrenzung auf zeilenzahl + ScreenIndex := ColumnIndex + (RowIndex * cols) 'berechnet bildschirmindex + +PUB print_ctrl(c) | code,n,m 'screen: steuerzeichen ausgeben + + case c + + $00: 'clear screen? + ScreenIndex := 0 + n := sline * cols + repeat TILES - n + array[n + ScreenIndex++] := 32 + home +{ + if curstat == 1 'cursor ausschalten? + schar($20) + n := sline * cols + 'wordfill(@array + n, spacetile, tiles - n) + wordfill(@array.word[n], spacetile, tiles-n) + row := sline + col := 0 + if curstat == 1 'cursor einschalten + schar(cursor) +} + $01: 'home? + row := sline + col := 0 + + $02: 'backspace? + if col + col-- + + $03: 'tab + repeat n from 0 to TABANZ-1 + if col < tab[n] + col := tab[n] + quit + + $04: 'setcur + code := bus_getchar + cursor := code + + $05: 'pos1 + col := 0 + + $06: 'setx + col := bus_getchar + + $07: 'sety + row := bus_getchar * 2 + sline '2 tiles pro zeichen! + + $08: 'getx + bus_putchar(col) + + $09: 'gety + bus_putchar(row / 2) + + $10: 'setcolor + color := bus_getchar + + $11: 'sline + sline := bus_getchar * 2 + + $12: 'eline + eline := bus_getchar * 2 + + $13: 'screeninit + ScreenIndex := 0 + repeat TILES + array[ScreenIndex++] := 32 + RowIndex := 0 + ColumnIndex := 0 + sline := 0 +{ + wordfill(@array, spacetile, tiles) + row := 0 + col := 0 + sline := 0 +} + $14: 'curon + curstat := 1 + + $15: 'curoff + curstat := 0 + + $16: 'scrollup + scrollup + + $17: 'scrolldown + scrolldown + + $18: 'tabulator setzen + n := bus_getchar + m := bus_getchar + if n =< (TABANZ-1) + tab[n] := m + +PRI xschar(c)| i,k 'screen: schreibt zeichen an aktuelle position ohne cursor + k := color << 1 + c & 1 + i := $8000 + (c & $FE) << 6 + k + array.word[row * cols + col] := i 'oberes tile setzen + array.word[(row + 1) * cols + col] := i | $40 'unteres tile setzen + +PRI schar(c) 'schreibt zeichen an aktuelle position ohne cursorposition zu verändern +array[RowIndex * cols + ColumnIndex] := c +if ++ColumnIndex == cols + newline +cx1 := ColumnIndex +cy1 := RowIndex + +PRI xpchar(c) 'screen: schreibt zeichen mit cursor an aktuelle position + schar(c) + if ++col == cols + newline + +PRI pchar(c) +'schreibt zeichen an aktuelle position z?hlt position weiter + schar(c) + if ++ColumnIndex == cols + newline + +PUB xnewline | i 'screen: zeilenwechsel, inkl. scrolling am screenende + + col := 0 + if (row += 2) => eline + row -= 2 + 'scroll lines + repeat i from sline to eline-3 + + wordmove(@array.word[i*cols], @array.word[(i+2)*cols], cols) 'wordmove(dest,src,cnt) + 'clear new line + wordfill(@array.word[(eline-2)*cols], spacetile, cols<<1) + +PUB newline | i + + ColumnIndex := 0 + if (RowIndex += 1) == rows + RowIndex -= 1 + 'scroll lines + repeat i from sline to rows-2 + bytemove(@array[i*cols], @array[(i+1)*cols], cols) 'BYTEMOVE (DestAddress, SrcAddress, Count) + + 'clear new line +' bytefill(@array[(rows-1)*cols], 32, cols<<1) 'BYTEFILL (StartAddress, Value, Count) +' code fehlerhaft, zähler ist falsch gesetzt! + + bytefill(@array[(rows-1)*cols], 32, cols) 'BYTEFILL (StartAddress, Value, Count) + +PUB scrollup | i 'screen: scrollt den screen nach oben + + 'scroll lines + wordmove(@array.word[sline*cols],@array.word[(sline+2)*cols],(eline-1-sline)*cols) 'wordmove(dest,src,cnt) + 'clear new line + wordfill(@array.word[(eline-2)*cols], spacetile, cols<<1) + +PUB scrolldown | i 'screen: scrollt den screen nach unten + 'scroll lines + i := eline - 1 + repeat eline-sline-1 + wordmove(@array.word[i*cols], @array.word[(i-2)*cols], cols) 'wordmove(dest,src,cnt) + i-- + 'clear new line + wordfill(@array.word[(sline)*cols], spacetile, cols<<1) + +PRI print_logo|padr,x,y 'screen: hive-logo ausgeben + + x := bus_getchar + y := bus_getchar + padr := @hive+user_charbase-@uchar + DrawBitmap(padr, x, y, 8, 2, 1) 'logo zeichnen + + +PRI DrawBitmap(pBitmap, xPos, yPos, xSize, ySize, clr)|c,i,j,pcol,prow 'screen: zeichnet ein einzelnes tilefeld +{ +- setzt in der tilemap des vga-treibers die adressen auf das entsprechende zeichen +- setzt mehrer tiles je nach xSize und ySize +- jedes tile besteht aus 16x16 pixel, weshalb die adresse jedes tiles mit c<<6 gebildet wird +- alle 64 byte (c<<6) beginnt im bitmap ein tile +} + prow:=yPos + pcol:=xPos + c:=0 + repeat j from 0 to (ySize-1) + repeat i from 0 to (xSize-1) + array.word[prow * cols + pcol] := pBitmap + (c<<6) + clr + c++ + pcol++ + prow++ + pcol:=xPos + +DAT +{{ + +'' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down, +'' which will serve as the tile array. Each word specifies a tile bitmap and +'' a color palette for its tile area. The top 10 bits of each word form the +'' base address of a 16-long tile bitmap, while the lower 6 bits select a +'' color palette for the bitmap. For example, $B2E5 would specify the tile +'' bitmap spanning $B2C0..$B2FF and color palette $25. + +'' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data +'' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0 +'' providing the color data for pixel values %11..%00, respectively: +'' +'' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold +'' + %% ist quaternary-darstellung; jedes digit von 0 bis 3, also 4-wertigkeit + + bildaufbau: 24 zeilen zu je 64 zeichen; jedes zeichen wird durch zwei tiles gebildet + die ?bereinander liegen. + jedes tile belegt ein word: 10 bit bitmap und 6 bit color. zwei tiles ein long. + + +'0 %%RGBx_RGBx_RGBx_RGBx + long %%0330_0010_0330_0010 + long %%0330_0330_0010_0010 + + + long $3C043C04 'grau/blau erste - hive-version + long $3C3C0404 + +Color-Calculator: + +http://www.rayslogic.com/propeller/Programming/Colors.htm + +For the 1024x768 VGA tile driver: +2 longs are required for each text foreground/background color combo, arranged as: + $ff_bb_ff_bb + $ff_ff_bb_bb + where 'ff' is the foreground color and 'bb' is the background color + 2 longs needed because characters are in an interleaved pair + The first long is the color for the first character in a pair, the second long is for the second character in a pair. + Demo routine "print()" only allows for 8 fore/back combinations (using longs 0 to 15) + +1 long required for box colors, arranged as: + $tl_br_fi_bb + where 'tl' is top-left edge, 'br' is bottom-right edge, 'fi' is focus indicators, and 'bb' is background color + The demo "box()" procedure hardwired to add 16 to input color number to pick box color and adds 5 to input + color number to pick text color for box... + So, "box(left,top,clr,str)" uses color number 16+clr for box colors and 5+clr for text color. You probably want + the 'bb' background colors of these two to match! Note that this limits you to 4 box colors. + +1 long used for graphics colors, arranged as + $00_11_22_33 + where 00,11,22,33 are the selectable graphics colors 0,1,2,3 + Demo hardwired to use the 21st long (last one) for the graphics colors + +The Propeller's "tile driver" video uses 32-bit (long) values to define a four color palette +The "color_ptr" parameter, given to the tile driver, specifies the location of the data block of up to 64 different +long palette values +Each long palette represents 4 different colors, one byte each. Each color byte uses 2 bits for each primary colors, +RGB, arranged as RGBx. The "x" represents the two least significant bits, which are ignored. +Parallax gives this example of a 32-bit long palette, represented as a 16-digit quaternary (2-bit) number: + %%3330_0110_0020_3300 or $FC1408F0 +The first byte, %%3330 (binary %11111100), is the color white +The second byte, %%0110, is the color dark cyan + +}} + + org +' +' Entry: dummy-assemblercode fuer cogtest +' +entry jmp entry 'just loops + +vgacolors long 'farbpalette + +'============================================================ +' v h v h ' v=Vordergrund, h=Hintergrund +' long $ 3C 04 3C 04 'Muster +' v v h h +' long $ 3C 3C 04 04 'Muster +'0 %%RGBx_RGBx_RGBx_RGBx +' long %%0330_0010_0330_0010 +' long %%0330_0330_0010_0010 +'============================================================ + +'set 1 - grau auf weiß + + long $54FC54FC 'grau/weiß + long $5454FCFC + long $58FC58FC 'hellblau/weiß + long $5858FCFC + long $64FC64FC 'hellgrün/weiß + long $6464FCFC + long $94FC94FC 'hellrot/weiß + long $9494FCFC + long $00FC00FC 'schwarz/weiß + long $0000FCFC + long $0CFC0CFC 'blau/weiß + long $0C0CFCFC + long $30FC30FC 'grün/weiß + long $3030FCFC + long $C0FCC0FC 'rot/weiß + long $C0C0FCFC + + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 + + +'set 2 - weiß auf schwarz +{ + long $FC00FC00 'schwarz/weiß + long $FCFC0000 + long $A800A800 'schwarz/hellgrau + long $A8A80000 + long $54005400 'schwarz/dunkelgrau + long $54540000 + long $30043004 'grün/blau + long $30300404 + long $043C043C 'Color 0 reverse + long $04043C3C + long $FC04FC04 'weiss/blau + long $FCFC0404 + long $FF80FF80 'red/white + long $FFFF8080 + long $88048804 'magenta/blau + long $88880404 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + + +'set 3 - hellblau auf dunkelblau +{ + long $3C043C04 'grau/blau erste - hive-version + long $3C3C0404 + long $F004F004 'yellow/blue + long $F0F00404 + long $C004C004 'rot/blau + long $C0C00404 + long $30043004 'grün/blau + long $30300404 + long $043C043C 'Color 0 reverse + long $04043C3C + long $FC04FC04 'weiss/blau + long $FCFC0404 + long $FF80FF80 'red/white + long $FFFF8080 + long $88048804 'magenta/blau + long $88880404 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + +'set 4 - chess +{ +'0..1: text color 0: + long $F010F010 '0: Yellow on Green + long $F0F01010 +'2..3: text color 1: + long $C0FCC0FC '1: red on white + long $C0C0FCFC +'4..5: text color 2: + long $00FC00FC '2: black on white + long $0000FCFC + +'6..7: text color 3: + long $F010F010 '3: Yellow on Green + long $F0F01010 + + long $043C043C 'Color 0 reverse + long $04043C3C + long $FC04FC04 'weiss/blau + long $FCFC0404 + long $FF80FF80 'red/white + long $FFFF8080 + long $88048804 'magenta/blau + long $88880404 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} + +' alte definitionen +{ + long $F010F010 'yellow on dk green + long $F0F01010 + long $C000C000 'red + long $C0C00000 + long $30003000 'green + long $30300000 + long $0C000C00 'blue + long $0C0C0000 + long $FC04FC04 'white + long $FCFC0404 + long $FF88FF88 'magenta/white + long $FFFF8888 + + long $C0408080 'redbox + long $CC440088 'magentabox + long $3C142828 'cyanbox + long $FC54A8A8 'greybox + long $3C14FF28 'cyanbox+underscore + long $F030C050 'graphics colors + long $881430FC + long $8008FCA4 +} +DAT + +padding long 1[16] '64-byte raum für die ausrichtung des zeichensatzes +uchar long + +hive long +file "logo-hive-8x2.dat" '8x2=16 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/bellatrix/bel-htext/logo-hive-8x2.dat b/system/bellatrix/bel-htext/logo-hive-8x2.dat new file mode 100644 index 0000000..109ef59 Binary files /dev/null and b/system/bellatrix/bel-htext/logo-hive-8x2.dat differ diff --git a/system/license.spin b/system/license.spin new file mode 100644 index 0000000..227f01a --- /dev/null +++ b/system/license.spin @@ -0,0 +1,75 @@ +{{ + +Template für TriOS-Quelltextdateien + +Diese Datei ist eine Vorlage für die Quelltexte. Alle Komponenten für das Hive-Projekt und auch alle +Objekte aus dem Object Exchange (OBEX) der Firma Parallax unterliegen durchgängig der MIT-Lizenz. + +Die Dateien bestehen aus drei Teilen: + +1. Urheberrechtsvermerk +2. Technische Informationen +3. Erlaubnisvermerk + +Urheberrechtsvermerk und die technischen Informationen befinden sich am Anfang, Erlaubnisvermerk am +Ende des Quelltextes. Die technischen Informationen sind in vielen Fällen nur in der Hauptdatei nötig +und werden in den Unterdateien von eingebundenen Objekten nicht benötigt - oder es sind dort eigene +spezifische technische Informationen nötig. Die Hauptdatei enthält in diesen Fällen aber als Teil der +technischen Informationen Verweise und Versionsinformationen der Unterdateien. + +Es ist wichtig, dass jede Datei korrekte Urheberrechts- und Erlaubnisvermerk enthält, um dem +Gesamtprojekt den Open Source Status zu gewähren. + +}} + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: │ +│ Copyright (c) │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : +System : TriOS +Name : +Chip : +Typ : +Version : +Subversion : +Funktion : +Komponenten : +COG's : +Logbuch : +Kommandoliste : +Notizen : + +}} + +CON +VAR +OBJ +PUB object_code +PRI private_code +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/system/regnatix/admtest.spin b/system/regnatix/admtest.spin new file mode 100644 index 0000000..30b7844 --- /dev/null +++ b/system/regnatix/admtest.spin @@ -0,0 +1,763 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Administra-Test +Chip : Regnatix +Typ : Programm +Version : 01 +Subversion : 01 +Funktion : Testroutinen für die Administra-Funktionen +Komponenten : stringEngine 7/10/2009 Kwabena W. Agyeman MIT Lizenz +COG's : - +Logbuch : + +21-03-2010-dr235 - erste version + +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + str: "glob-string" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +VAR + + byte tbuf[32] + +PUB main | fnr + + ios.start + + repeat + ios.screeninit + ios.print(string("Hive: Administra-Test [Auswahl Funktionskomplex]")) + ios.print(string(13,"1. chip-managment")) + ios.print(string(13,"2. sd-laufwerksfunktionen")) + ios.print(string(13,"3. hss-funktionen")) + ios.print(string(13,"4. wav-funktionen",13)) + ios.print(string(13,"99 testprogramm beenden",13,13)) + fnr := str.decimalToNumber(fInput(string("Funktion wählen : "))) + case fnr + 1: menu_mgr + 2: menu_sd + 3: menu_hss + 4: menu_wav + 99: ios.stop + +PUB menu_mgr | fnr + + repeat + ios.screeninit + ios.print(string("▶ Hive: Administra-Test [Chip-Managment]")) + ios.print(string(13,"1. getver, getspez, getcogs")) + ios.print(string(13,"2. neuen administra-code booten (admled.adm)")) + ios.print(string(13,"88 alle tests")) + ios.print(string(13,"99 zurück",13,13)) + fnr := str.decimalToNumber(fInput(string("Funktion wählen : "))) + case fnr + 1: \fTest10 + 2: \fTest11 + 88: + 99: return + + +PUB menu_sd | fnr + + repeat + ios.screeninit + ios.print(string("▶ Hive: Administra-Test [SD-Laufwerksfunktionen]")) + ios.print(string(13,"1. mount, volname, free, unused, checkmount")) + ios.print(string(13,"2. daten schreiben + lesen")) + ios.print(string(13,"3. block schreiben + lesen")) + ios.print(string(13,"4. inhaltsverzeichnis")) + ios.print(string(13,"5. dateien/verzeichnisse erzeugen, umbenennen, löschen")) + ios.print(string(13,"6. positionieren in der datei")) + ios.print(string(13,"7. dateiattribute verändern")) + ios.print(string(13,"8. verzeichnis wechseln")) + ios.print(string(13,"9. format + unmount",13)) + ios.print(string(13,"88 alle tests")) + ios.print(string(13,"99 zurück",13,13)) + fnr := str.decimalToNumber(fInput(string("Funktion wählen : "))) + case fnr + 1: \fTest1 + 2: \fTest2 + 3: \fTest3 + 4: \fTest4 + 5: \fTest5 + 6: \fTest6 + 7: \fTest7 + 8: \fTest8 + 9: \fTest9 + 88: \loop_sd + 99: return + +PUB menu_hss + +PUB menu_wav + +PUB loop_mgr + + repeat + fTest10 'getver,getspec,getcogs + fTest11 'administra-code booten + +PUB loop_sd + + repeat + fTest1 'mount, volname, free, unused, checkmounted + fTest2 'daten schreiben + lesen + fTest3 'block schreiben + lesen + fTest4 'inhaltsverzeichnis + fTest5 'dateien erzeugen, umbenennen, löschen + fTest6 'seek + fTest7 'attribute ändern + fTest8 'cd + fTest9 'format + unmount + +DAT 'test 1: mount & unmount +t1_s1 byte "Test1: Volume mounten",0 +t1_s2 byte "[sdmount]",0 +t1_s3 byte "[sdvolname] = ",0 +t1_s4 byte "[sdcheckmounted] = ",0 +t1_s5 byte "[sdcheckused] = ",0 +t1_s6 byte "[sdcheckfree] = ",0 + +PRI fTest1 | err + + fScreen(@t1_s1) + repeat + ios.print(@t1_s2) 'sdmount + err := ios.sdmount + fError(err) + fPrintResultDec(@t1_s4,ios.sdcheckmounted) + ifnot err + fPrintResultStr(@t1_s3,ios.sdvolname) + fPrintResultDec(@t1_s5,ios.sdcheckused) + fPrintResultDec(@t1_s6,ios.sdcheckfree) + until fAktion + + +DAT 'test 2: daten schreiben & lesen +t2_s1 byte "Test2: Daten schreiben und lesen ",0 +t2_s2 byte "[sdopen-w]",0 +t2_s3 byte "[sdputc] = ",0 +t2_s4 byte "[sdclose]",0 +t2_s5 byte "[sdnewfile]",0 +t2_s6 byte "[sdgetc] = ",0 +t2_s7 byte "[sdopen-r]",0 +t2_s8 byte "Daten lesen...",0 +t2_fn byte "admtest.dat",0 + +PRI fTest2 | err,i + + fScreen(@t2_s1) + repeat + + ios.print(@t1_s2) 'sdmount + err := ios.sdmount + fError(err) + + ios.print(@t2_s5) 'sdnewfile + err := ios.sdnewfile(@t2_fn) + fError(err) + + ios.print(@t2_s2) + err := ios.sdopen("W",@t2_fn) 'sdopen + fError(err) + ifnot err + ios.print(@t2_s3) + ios.printnl + i := 0 + repeat 256 + ios.printhex(i,2) + ios.printchar(" ") + ios.sdputc(i++) 'sdputc + ios.printnl + ios.print(@t2_s4) + fError(ios.sdclose) 'sdclose + + fPause(@t2_s8) + + ios.print(@t2_s7) + err := ios.sdopen("R",@t2_fn) 'sdopen + fError(err) + ifnot err + ios.print(@t2_s6) + ios.printnl + repeat 256 + ios.printhex(ios.sdgetc,2) 'sdgetc + ios.printchar(" ") + ios.printnl + ios.print(@t2_s4) + fError(ios.sdclose) 'sdclose + + + + until fAktion + +DAT 'test 3: Block schreiben & lesen +t3_s1 byte "Test3: Block schreiben & lesen",0 +t3_s2 byte "[sdnewfile]",0 +t3_s3 byte "[sdopen-w]",0 +t3_s4 byte "[sdopen-r]",0 +t3_s5 byte "[sdclose]",0 +t3_s6 byte "[sdputblk]",0 +t3_s7 byte "[sdgetblk]",0 +t3_s8 byte "Puffer mit Werten füllen...",0 +t3_s9 byte "Puffer löschen...",0 +t3_s10 byte "Puffer = ",0 +t3_fn byte "admtest.dat",0 + +CON +blkcount = 256 + +VAR +byte buffer[blkcount] + +PRI fTest3 | i,err + + fScreen(@t3_s1) + repeat + + i := 0 + ios.print(@t3_s8) 'puffer mit werten füllen + ios.printnl + repeat blkcount + byte[@buffer][i++] := i + + i := 0 + ios.print(@t3_s10) 'puffer anzeigen + repeat blkcount + ios.printhex(byte[@buffer][i++],2) + ios.printchar(":") + + fPause(@t3_s8) + + ios.print(@t3_s3) 'puffer --> datei + err := ios.sdopen("W",@t3_fn) + fError(err) + ifnot err + ios.print(@t3_s6) + ios.printnl + ios.sdputblk(blkcount,@buffer) + ios.print(@t3_s5) + ios.sdclose + ios.printnl + + i := 0 + ios.print(@t3_s9) 'puffer löschen + repeat blkcount + byte[@buffer][i++] := 0 + + ios.print(@t3_s4) 'puffer <-- datei + err := ios.sdopen("R",@t3_fn) + fError(err) + ifnot err + ios.print(@t3_s6) + ios.printnl + ios.sdgetblk(blkcount,@buffer) + ios.print(@t3_s5) + ios.sdclose + ios.printnl + + i := 0 + ios.print(@t3_s10) 'puffer anzeigen + repeat blkcount + ios.printhex(byte[@buffer][i++],2) + ios.printchar(":") + + until fAktion + +DAT 'test 4: Inhaltsverzeichnis +t4_s1 byte "Test4: Inhaltsverzeichnis (einfach)",0 +t4_s2 byte "[sddir] ",0 +t4_s3 byte "[sdnext] = ",0 +t4_s4 byte "Test4: Inhaltsverzeichnis (Attribute)",0 +t4_s5 byte "DIR ▶ ",0 +t4_s6 byte " ",0 + +PRI fTest4 | stradr + + fScreen(@t4_s1) + repeat + + fMount + ios.print(@t4_s2) + ios.sddir + repeat while (stradr := ios.sdnext) + ios.printnl + ios.print(@t4_s3) + ios.print(stradr) + + fPause(@t4_s4) + ios.print(@t4_s2) + ios.sddir + repeat while (stradr := ios.sdnext) + ios.printnl + if ios.sdfattrib(ios#F_DIR) 'verzeichnisname + ios.print(@t4_s5) + ios.print(stradr) + else 'dateiname + ios.print(@t4_S6) + ios.print(stradr) + + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_SIZE),10)) 'dateigröße + + ios.printchar(" ") 'attribute + if ios.sdfattrib(ios#F_READONLY) + ios.printchar("r") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_HIDDEN) + ios.printchar("h") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_SYSTEM) + ios.printchar("s") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_ARCHIV) + ios.printchar("a") + else + ios.printchar("-") + + ios.printchar(" ") 'änderungsdatum + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CDAY),2)) + ios.printchar(".") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMONTH),2) + 1) + ios.printchar(".") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CYEAR),4) + 1) + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CHOUR),2)) + ios.printchar(":") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMIN),2) + 1) + ios.printchar(":") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CSEC),2) + 1) + + + until fAktion + +DAT 'test 4: dateien/verzeichnisse erzeugen, umbenennen, löschen +t5_s1 byte "Test5: Dateien/Verzeichnisse erzeugen, umbenennen, löschen ",0 +t5_s2 byte "[sdnewdir] : admtest",0 +t5_s3 byte "[sdnewfile] : admtest.dat",0 +t5_s4 byte "[sddel] : admtest + admtest.dat",0 +t5_s5 byte "[sdrename] admtest -> admtest2",0 +t5_s6 byte "admtest",0 +t5_s7 byte 13,"pause ",0 +t5_s8 byte "admtest.dat",0 +t5_s9 byte "admtest2.dat",0 +t5_s10 byte "admtest2",0 + +PRI fTest5 | err + + fScreen(@t5_s1) + repeat + fMount + fPause(@t5_s7) + fDir + + fPause(@t5_s7) + ios.print(@t5_s2) + ios.printnl + fError(ios.sdnewdir(@t5_s6)) + fPause(@t5_s7) + fDir + + fPause(@t5_s7) + ios.print(@t5_s3) + ios.printnl + fError(ios.sdnewfile(@t5_s8)) + fPause(@t5_s7) + fDir + + fPause(@t5_s7) + ios.print(@t5_s5) + ios.printnl + fError(ios.sdrename(@t5_s6,@t5_s10)) + fError(ios.sdrename(@t5_s8,@t5_s9)) + fPause(@t5_s7) + fDir + + fPause(@t5_s7) + ios.print(@t5_s4) + ios.printnl + fError(ios.sddel(@t5_s10)) + fError(ios.sddel(@t5_s9)) + fPause(@t5_s7) + fDir + + + until fAktion + +DAT 'test 6: seek +t6_s1 byte "Test6: seek ",0 +t6_s2 byte "[sdopen] : test2.txt",0 +t6_s3 byte "test2.txt",0 +t6_s4 byte "Jetzt Test mit steigendem seek-Wert...",0 +t6_s5 byte "[seek] = ",0 + +PRI fTest6 | i + + fScreen(@t6_s1) + repeat + + fMount + + fError(ios.sdopen("R",@t6_s3)) + repeat 128 + ios.printchar(ios.sdgetc) + ios.sdclose + + ios.printnl + fPause(@t6_s4) + repeat i from 0 to 64 + ios.printcls + ios.print(@t6_s5) + ios.printdec(i) + ios.printnl + ios.printnl + ios.sdopen("R",@t6_s3) + ios.sdseek(i) + repeat 128 + ios.printchar(ios.sdgetc) + ios.sdclose +' fWait(1) + + until fAktion + + +DAT 'test 7: attribute ändern +t7_s1 byte "Test7: Attribute ändern ",0 +t7_s2 byte "Testdatei [admtest.dat] erzeugen ",0 +t7_s3 byte "admtest.dat",0 +t7_s4 byte 13,"Attributstring eingeben : ",0 + +PRI fTest7 + + fScreen(@t7_s1) + fMount + ios.print(@t7_s2) + ios.printnl + fError(ios.sdnewfile(@t7_s3)) + + repeat + fDir + fError(ios.sdchattrib(@t7_s3,fInput(@t7_s4))) + until fAktion + + fError(ios.sddel(@t7_s3)) + +DAT 'test 8: verzeichnis wechseln +t8_s1 byte "Test8: Verzeichnis wechseln ",0 +t8_s2 byte "Testverzeichnis [admtest] erzeugen ",0 +t8_s3 byte "admtest",0 +t8_s4 byte 13,"pause",13,0 +t8_s5 byte "..",0 + +PRI fTest8 + + fScreen(@t8_s1) + fMount 'medium mounten + ios.print(@t8_s2) + ios.printnl + fError(ios.sdnewdir(@t8_s3)) 'testverzeichnis erzeugen + repeat + + fDir + fPause(@t8_s4) + fError(ios.sdchdir(@t8_s3)) 'in testverzeichnis wechseln + fDir + fPause(@t8_s4) + fError(ios.sdchdir(@t8_s5)) 'und wieder zurück zur wurzel + fDir + + until fAktion + fError(ios.sddel(@t8_s3)) 'testverzeichnis löschen + +DAT 'test 9: medium formatieren + abmelden +t9_s1 byte "Test9: Medium formatieren + abmelden ",0 +t9_s2 byte "ACHTUNG: Medium wird jetzt formatiert!",13,"Testcard einlegen und bestätigen : ",0 +t9_s3 byte "JA",0 +t9_s4 byte "ADMTEST",0 +t9_s5 byte "[sdformat] ... ",13,0 +t9_s6 byte "[sdunmount] Medium wird jetzt abgemeldet...",13,0 + +PRI fTest9 | stradr + + fScreen(@t9_s1) + repeat + stradr := fInput(@t9_s2) + fMount + if strcomp(stradr, @t9_s3) + ios.print(@t9_s5) + fError(ios.sdformat(@t9_s4)) + ios.print(@t9_s6) + fError(ios.sdunmount) + until fAktion + +DAT 'test 10: getver, getpsec, getcogs +t10_s1 byte "Test10: getver, getspec, getcogs ",0 +t10_s2 byte 13,"Version : $",0 +t10_s3 byte 13,"Specifikation : %",0 +t10_s4 byte 13,"COGs : ",0 + +PRI fTest10 + + fScreen(@t10_s1) + repeat + ios.print(@t10_s2) + ios.printhex(ios.admgetver,8) + ios.print(@t10_s3) + ios.printbin(ios.admgetspec,32) + ios.print(@t10_s4) + ios.printhex(ios.admgetcogs,8) + + until fAktion + +DAT 'test 11: administra-code booten +t11_s1 byte "Test11: administra-code booten ",0 +t11_s2 byte "admled.adm",0 + +PRI fTest11 + + fScreen(@t11_s1) + fMount + repeat + + ios.admload(@t11_s2) + + until fAktion + +DAT 'test x: +tx_s1 byte "Testx: Beschreibung ",0 + +PRI fTestx + + repeat + + fPause(@tx_s1) + + until fAktion + +DAT 'fInput: stringeingabe + +PRI fInput(stradr1): stradr2 + + ios.print(stradr1) + ios.input(@tbuf,32) + return @tbuf + +DAT 'fWait: wartet eine def.zeit + +PUB fWait(sek) + + waitcnt(clkfreq * sek + cnt) + +DAT 'fDir: Verzeichnis anzeigen + +PUB fDir | stradr + + ios.sddir + repeat while (stradr := ios.sdnext) + ios.printnl + if ios.sdfattrib(ios#F_DIR) 'verzeichnisname + ios.print(@t4_s5) + ios.print(stradr) + else 'dateiname + ios.print(@t4_S6) + ios.print(stradr) + + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_SIZE),10)) 'dateigröße + + ios.printchar(" ") 'attribute + if ios.sdfattrib(ios#F_READONLY) + ios.printchar("r") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_HIDDEN) + ios.printchar("h") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_SYSTEM) + ios.printchar("s") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_ARCHIV) + ios.printchar("a") + else + ios.printchar("-") + + ios.printchar(" ") 'änderungsdatum + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CDAY),2)) + ios.printchar(".") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMONTH),2) + 1) + ios.printchar(".") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CYEAR),4) + 1) + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CHOUR),2)) + ios.printchar(":") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMIN),2) + 1) + ios.printchar(":") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CSEC),2) + 1) + +DAT 'fMount: Medium einbinden +i_s1 byte 13,"Medium wird eingebunden...",0 + +PRI fMount | err + + ios.print(@i_s1) 'sdmount + err := ios.sdmount + fError(err) + ifnot err + fPrintResultStr(@t1_s3,ios.sdvolname) + + +DAT 'fAktion: Aktion abfragen +a_s1 byte "nde, ochmal, eiter : ",0 + +PRI fAktion: aktion + + ios.printnl + ios.print(@a_s1) + case ios.keywait + "e": abort + "w": aktion := 1 + "n": aktion := 0 + + ios.printnl + +DAT 'fPause: Printausgabe und Pause +p_s1 byte "Weiter? <*> :",0 + +PRI fPause(strptr) + + ios.print(strptr) + ios.printnl + ios.print(@p_s1) + ios.keywait + ios.printnl + +DAT 'fScreen: Initialisierung neuer Test +s_s1 byte "Weiter? <*> :",0 + +PRI fScreen(strptr) + + ios.screeninit + ios.print(strptr) + ios.print(@s_s1) + ios.keywait + ios.printnl + +DAT 'fPrintResultStr: Testanzeige von Stringresultaten +PRI fPrintResultStr(strptr1,strptr2) + + ios.print(strptr1) + ios.print(strptr2) + ios.printnl + +DAT 'fPrintResultDec: Testanzeige von Dezimalwerten +PRI fPrintResultDec(strptr, wert) + + ios.print(strptr) + ios.printdec(wert) + ios.printnl + +DAT 'fError: Fehler ausgeben +f_s1 byte "Fehlernummer : ",0 +f_s2 byte "Fehler : ",0 + +err0 byte "no error",0 +err1 byte "fsys unmounted",0 +err2 byte "fsys corrupted",0 +err3 byte "fsys unsupported",0 +err4 byte "not found",0 +err5 byte "file not found",0 +err6 byte "dir not found",0 +err7 byte "file read only",0 +err8 byte "end of file",0 +err9 byte "end of directory",0 +err10 byte "end of root",0 +err11 byte "dir is full",0 +err12 byte "dir is not empty",0 +err13 byte "checksum error",0 +err14 byte "reboot error",0 +err15 byte "bpb corrupt",0 +err16 byte "fsi corrupt",0 +err17 byte "dir already exist",0 +err18 byte "file already exist",0 +err19 byte "out of disk free space",0 +err20 byte "disk io error",0 +errx byte "undefined",0 + + +PRI fError(err) + + ios.printnl + ios.print(@f_s1) + ios.printdec(err) + ios.print(string(" : $")) + ios.printhex(err,2) + ios.printnl + ios.print(@f_s2) + case err + 0: ios.print(@err0) + 1: ios.print(@err1) + 2: ios.print(@err2) + 3: ios.print(@err3) + 4: ios.print(@err4) + 5: ios.print(@err5) + 6: ios.print(@err6) + 7: ios.print(@err7) + 8: ios.print(@err8) + 9: ios.print(@err9) + 10: ios.print(@err10) + 11: ios.print(@err11) + 12: ios.print(@err12) + 13: ios.print(@err13) + 14: ios.print(@err14) + 15: ios.print(@err15) + 16: ios.print(@err16) + 17: ios.print(@err17) + 18: ios.print(@err18) + 19: ios.print(@err19) + 20: ios.print(@err20) + OTHER: ios.print(@errx) + ios.printnl + + +DAT + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/beltest.spin b/system/regnatix/beltest.spin new file mode 100644 index 0000000..85e3d11 --- /dev/null +++ b/system/regnatix/beltest.spin @@ -0,0 +1,572 @@ +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Bellatrix-Test +Chip : Regnatix +Typ : Programm +Version : 00 +Subversion : 01 +Funktion : Test für die grundlegenden Textausgabe- und Tastaturfunktionen. +Komponenten : - +COG's : - +Logbuch : + +22-03-2010-dr235 - anpassung trios + +Kommandoliste : + +Notizen : + +}} + +OBJ + ios: "reg-ios" + str: "glob-string" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OS_TIBLEN = 64 'größe des inputbuffers + +VAR +'systemvariablen + byte tib[OS_TIBLEN] 'tastatur-input-buffer + byte tibpos 'aktuelle position im tib + byte tbuf[32] + long cols,rows + byte vidmod 'videomodus: 0 - vga, 1 - tv + +PUB main|fnr + + ios.start + os_testvideo + + repeat + ios.print(string("0 - Alle Tests",13)) + ios.print(string("1 - Zeichensatz",13)) + ios.print(string("2 - Hive-Logo",13)) + ios.print(string("3 - Funktion TAB",13)) + ios.print(string("4 - Funktion CLS",13)) + ios.print(string("5 - Scrolling",13)) + ios.print(string("6 - Funktion SCREENINIT",13)) + ios.print(string("7 - Funktion SETCOLOR",13)) + ios.print(string("8 - Funktion SETX/SETY",13)) + ios.print(string("9 - Windows",13)) + ios.print(string("10 - Funktion INPUT/BACKSPACE",13)) + ios.print(string("11 - Funktion HOME/POS1/CURCHAR",13)) + ios.print(string("99 - Ende ")) + fnr := str.decimalToNumber(fInput(string(" Funktion : "))) + case fnr + 0: test_all + 1: test_charmap + 2: test_logo + 3: test_tab + 4: test_cls + 5: test_scroll + 6: test_screeninit + 7: test_setcolor + 8: test_setxy + 9: test_windows + 10: test_inputbackspace + 11: test_home + test_pos1 + test_curchar + 99: ios.stop + +pri os_testvideo 'sys: passt div. variablen an videomodus an + + vidmod := ios.belgetspec & 1 + rows := ios.belgetrows 'zeilenzahl bei bella abfragen + cols := ios.belgetcols 'spaltenzahl bei bella abfragen + +pri fInput(stradr1): stradr2 + + ios.setcolor(1) + ios.printq(string("▶")) + ios.print(stradr1) + ios.input(@tbuf,32) + ios.setcolor(0) + ios.printnl + return @tbuf + +pri test_all + + test_charmap + test_logo + test_tab + test_cls + test_scroll + test_screeninit + test_setcolor + test_setxy + test_windows + test_inputbackspace + test_home + test_pos1 + test_curchar + + +pri test_charmap|i,j + + ios.print(string("Zeichensatz:")) + ios.printnl + ios.print(string(" 0123456789ABCDEF0123456789ABCDEF")) + ios.printnl + ios.print(string(" ┌────────────────────────────────┐")) + + repeat i from 0 to 7 + ios.printnl + ios.printhex(i*j,2) + ios.printchar("│") + repeat j from 0 to 31 + ios.printqchar((i*31)+j) + ios.printchar("│") + ios.printnl + ios.print(string(" └────────────────────────────────┘")) + weiter + +pri test_logo + ios.print(string("Hive-Logo:")) + ios.printcls + ios.printlogo(0,0) + weiter + +pri test_tab|a,b,i,j + + ios.print(string("Test TAB:")) + if cols < 50 + a := 3 + b := 5 + else + a := 3 + b := 7 + repeat j from a to b + repeat i from 0 to 7 + ios.settabs(i,j*i) + ios.printcls + repeat 8 + ios.print(string("tab")) + ios.printtab + ios.printnl + repeat i from 1 to 5 + repeat 8 + ios.printdec(i) + ios.printtab + ios.printnl + waitcnt(10_000_000+cnt) + weiter + +pri test_cls + ios.print(string("Test CLS:")) + ios.printcls + repeat 10 + charset + ios.printnl + ios.printnl + ios.print(string("Bildschirm wird gleich gelöscht...")) + waitcnt(cnt + clkfreq*3) + ios.printcls + ios.print(string("Bildschirm löschen OK")) + weiter + +pri test_scroll + ios.print(string("Test ScrollUp:")) + repeat 10 + charset + repeat 20 + waitcnt(10_000_000+cnt) + ios.scrollup + ios.printnl + ios.printnl +'------------------------------------------------------------------------------------ + ios.print(string("Test ScrollDown:")) + weiter + repeat 10 + charset + repeat 15 <# rows - 2 + waitcnt(10_000_000+cnt) + ios.scrolldown + repeat 16 + repeat 15 <# rows - 2 + waitcnt(1_000_000+cnt) + ios.scrollup + repeat 15 <# rows - 2 + waitcnt(1_000_000+cnt) + ios.scrolldown + weiter + +pri test_screeninit + ios.print(string("Test SCREENINIT:")) + ios.screeninit + ios.print(string("▶Funktionstest Bellatrix-BIOS [SCREENINIT OK]")) + weiter + +pri test_setcolor|i,j,n + + if vidmod == ios#TV + n := 7 + else + n := 15 + ios.print(string("Test SETCOLOR:",13)) + repeat i from 0 to n + repeat j from 0 to 32 + ios.setcolor(i) + ios.printchar(j + 65) + ios.printchar(":") + ios.printdec(i) + ios.printchar(":") + ios.printhex(i,2) + ios.printnl + ios.setcolor(0) + weiter + +pri test_setxy|i,j,n + ios.print(string("Test SETX/SETY (CURON/CUROFF):")) + ios.printcls + ios.printnl + ios.curoff + repeat n from 1 to 50 + repeat j from 1 to 5 + repeat i from 1 to 8 <# cols/5-1 + ios.cursetx(i * 5) + ios.cursety(j * 2) + ios.printchar(":") + ios.printdec(n) + + ios.cursetx(5) + ios.cursety(12 <# rows) + ios.printchar(":") + ios.printdec(j) + ios.printchar(":") + ios.printdec(i) + ios.printchar(":") + ios.printdec(n) + ios.curon + ios.printnl + weiter + +pri test_windows + ios.print(string("Test Windows:")) + windows1 + windows2 + ios.printcls + weiter + +pri test_inputbackspace + ios.print(string("Test Eingabe/Backspace (bis Enter): ")) + input + ios.printnl + ios.print(string("Eingabe :")) + ios.print(@tib) + weiter + +pri test_home|i + ios.printcls + ios.print(string("Test Home:")) + repeat i from 0 to 1000 + ios.curhome + ios.printdec(i) + weiter + +pri test_pos1|i + ios.print(string("Test POS1:")) + ios.printnl + repeat i from 0 to 1000 + ios.curpos1 + ios.printdec(i) + weiter + +pri test_curchar|i + ios.print(string("Test CURCHAR: ")) + repeat i from 1 to 100 + ios.curchar(i) + waitcnt(cnt + clkfreq/20) + ios.curchar($0E) + weiter + +PRI weiter | tast + ios.printnl + ios.print(string("Weiter [q|*] : ")) + tast := ios.keywait + if tast == "q" OR tast == "Q" + ios.stop + ios.printnl + +PUB charset | i,j + + repeat i from 20 to 255 + ios.printchar(i) + +PUB input | charc + repeat + if ios.keystat > 0 'taste gedrückt? + charc := ios.key 'tastencode holen + if (tibpos + 1) < OS_TIBLEN 'tastaturpuffer voll? + case charc + ios#CHAR_BS: 'backspace + if tibpos > 0 + tibpos-- + tib[tibpos] := $0 'letztes zeichen im puffer löschen + ios.printbs 'steuerzeichen anterminal senden + other: ios.bus_putchar2(charc) 'sonstige zeichen + + if (charc <> ios#CHAR_NL) & (charc <> ios#CHAR_BS) 'ausser sonderzeichen alles in tib + if (tibpos + 1) < OS_TIBLEN 'tastaturpuffer voll? + tib[tibpos++] := charc + tib[tibpos] := $0 + until charc == $0D 'schleife bis RETURN + +VAR + long h[3], z[3], r[3] + +PUB windows1 | gx, gy, i, j, tast + cols := ios.belgetcols + rows := ios.belgetrows + gx := cols / 2 + gy := rows * 2 / 3 + ios.printcls + ios.print(string(" ### Window-Test ###")) + + ios.windefine(1, 2, 3, gx - 1, gy - 1) + ios.windefine(2, gx + 2, 3, cols - 2, gy - 1) + ios.windefine(3, 2, gy + 2, cols - 2, rows - 2) + repeat i from 1 to 3 + ios.winset(i) + ios.printcls + ios.winoframe + + waitcnt(cnt + clkfreq) + repeat i from 1 to 3 + ios.winset(i) + repeat 3 + charset + waitcnt(cnt + clkfreq) + + repeat i from 1 to 3 + ios.winset(i) + j := ios.wingetrows + repeat 8 + repeat 15 <# j - 2 + waitcnt(1_000_000+cnt) + ios.scrollup + repeat 15 <# j - 2 + waitcnt(1_000_000+cnt) + ios.scrolldown + + repeat i from 0 to 2 + ios.winset(i+1) + h[i] := ios.wingetrows - 2 + z[i] := 0 + r[i] := 1 + repeat 3 + charset + i := 0 + repeat 16*3*4 + i := (i + 1) // 3 + ios.winset(i+1) + z[i] += r[i] + if r[i] > 0 + ios.scrollup + else + ios.scrolldown + if z[i] == 0 or z[i] == h[i] + r[i] *= -1 + waitcnt(1_000_000+cnt) + + ios.winset(3) + ios.printcls + ios.print(string("Test Screen 2")) + weiter + screen2 + + repeat i from 1 to 3 + ios.winset(i) + ios.printcls + ios.curoff + + ios.winset(1) + ios.printcls + ios.print(string("Test relative Positionierung")) + weiter + + ios.winset(2) + repeat j from 2 to 3 + ios.winset(j) + repeat i from 1 to 3 + setpos(i, i) + waitcnt(cnt + clkfreq/2) + setpos(-i, -i) + waitcnt(cnt + clkfreq/2) + + ios.winset(1) + ios.curon + ios.printnl + ios.printnl + ios.print(string("Weiter */uit : ")) + tast := ios.keywait + ios.screeninit + if tast == "q" OR tast == "Q" + ios.stop + +PUB windows2 | gx, gy, i, j, tast + cols := ios.belgetcols + rows := ios.belgetrows + gx := cols / 2 + gy := rows * 2 / 3 + ios.printcls + ios.print(string(" ### Window-Test - Randkollision ###")) + + ios.windefine(1, 2, 3, gx - 1, gy - 1) + ios.windefine(2, gx + 2, 3, cols + 4, gy - 1) + ios.windefine(3, 2, gy + 2, cols + 4, rows + 4) + repeat i from 1 to 3 + ios.winset(i) + ios.printcls + ios.winoframe + + waitcnt(cnt + clkfreq) + repeat i from 1 to 3 + ios.winset(i) + repeat 3 + charset + waitcnt(cnt + clkfreq) + + repeat i from 1 to 3 + ios.winset(i) + j := ios.wingetrows + repeat 8 + repeat 15 <# j - 2 + waitcnt(1_000_000+cnt) + ios.scrollup + repeat 15 <# j - 2 + waitcnt(1_000_000+cnt) + ios.scrolldown + + repeat i from 0 to 2 + ios.winset(i+1) + h[i] := ios.wingetrows - 2 + z[i] := 0 + r[i] := 1 + repeat 3 + charset + i := 0 + repeat 16*3*4 + i := (i + 1) // 3 + ios.winset(i+1) + z[i] += r[i] + if r[i] > 0 + ios.scrollup + else + ios.scrolldown + if z[i] == 0 or z[i] == h[i] + r[i] *= -1 + waitcnt(1_000_000+cnt) + + ios.winset(3) + ios.printcls + ios.print(string("Test Screen 2")) + weiter + screen2 + + repeat i from 1 to 3 + ios.winset(i) + ios.printcls + ios.curoff + + ios.winset(1) + ios.printcls + ios.print(string("Test relative Positionierung")) + weiter + + ios.winset(2) + repeat j from 2 to 3 + ios.winset(j) + repeat i from 1 to 3 + setpos(i, i) + waitcnt(cnt + clkfreq/2) + setpos(-i, -i) + waitcnt(cnt + clkfreq/2) + + ios.winset(1) + ios.curon + ios.printnl + ios.printnl + ios.print(string("Weiter */uit : ")) + tast := ios.keywait + ios.screeninit + if tast == "q" OR tast == "Q" + ios.stop + +PRI setpos(x, y) + ios.wincursetx(x) + ios.wincursety(y) + printpos(x, y) + +PRI printpos(x, y) + ios.printqchar(15) + waitcnt(cnt + clkfreq/3) + if x < 0 + ios.curpos1 + else + ios.printqchar(2) + ios.printchar("(") + ios.printdec(x) + ios.printchar(",") + ios.printdec(y) + ios.printchar(")") + if x < 0 + ios.printqchar(3) + +PRI screen2 + ios.set_wscr(2) + ios.set_dscr(2) + + ios.print(string("hier ist Screen 2")) + ios.printnl +' Window anzeigen, Scrolling + ios.print(string("definiere Window 2 abweichend zu Screen 1: (8, 2)-(30, 8)")) + ios.printnl + ios.windefine(2, 8, 2, 30, 8) + ios.print(string("weiter mit beliebiger Taste...")) + ios.keywait + ios.winset(2) + ios.winoframe + ios.printcls + ios.print(string("Ausgabe in Window 2")) + ios.printnl + ios.print(string("zurück zu Screen 1 mit beliebiger Taste...")) + ios.keywait + ios.set_wscr(1) + ios.set_dscr(1) + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/charmap.spin b/system/regnatix/charmap.spin new file mode 100644 index 0000000..54af0c5 --- /dev/null +++ b/system/regnatix/charmap.spin @@ -0,0 +1,76 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Ausgabe einer Zeichentabelle +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +PUB main | c,i,j + + ios.start + 'ios.startram 'code für test im ram, sollte bei bin-datei auskommentiert werden + + ios.printnl + ios.print(string(" 0123456789ABCDEF0123456789ABCDEF")) + ios.printnl + ios.print(string(" ┌────────────────────────────────┐")) + + repeat i from 0 to 7 + ios.printnl + ios.printhex(i*j,2) + ios.printchar("│") + repeat j from 0 to 31 + ios.printqchar((i*31)+j) + ios.printchar("│") + ios.printnl + ios.print(string(" └────────────────────────────────┘")) + ios.printnl + + ios.stop + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/eram.spin b/system/regnatix/eram.spin new file mode 100644 index 0000000..dbe454a --- /dev/null +++ b/system/regnatix/eram.spin @@ -0,0 +1,686 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : eram-tool +Chip : Regnatix +Typ : Programm +Version : +Subversion : + +Logbuch : + +Kommandoliste: + +Notizen: + + + +}} + +OBJ + num: "glob-numbers" + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OS_TIBLEN = 64 'gr??e des inputbuffers +ERAM = 1024 * 512 * 2 'gr??e eram +HRAM = 1024 * 32 'gr??e hram + +RMON_ZEILEN = 16 'speichermonitor - angezeigte zeilen +RMON_BYTES = 8 'speichermonitor - zeichen pro byte + +VAR +'systemvariablen + byte tib[OS_TIBLEN] 'tastatur-input-buffer + byte cmdstr[OS_TIBLEN] 'kommandostring f?r interpreter + byte token1[OS_TIBLEN] 'parameterstring 1 für interpreter + byte token2[OS_TIBLEN] 'parameterstring 2 für interpreter + byte tibpos 'aktuelle position im tib + long ppos 'puffer für adresse + long pcnt 'puffer für zeilenzahl + +PUB main | wflag + + ios.start 'ios initialisieren +' ios.startram + ios.printnl + repeat + os_cmdinput 'kommandoeingabe + os_cmdint 'kommandozeileninterpreter + +PUB os_cmdinput | charc 'sys: stringeingabe eine zeile +''funktionsgruppe : sys +''funktion : stringeingabe eine zeile +''eingabe : - +''ausgabe : - +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib + + ios.print(@prompt2) + tibpos := 0 'tibposition auf anfang setzen + repeat until (charc := ios.keywait) == $0D 'tasten einlesen bis return + if (tibpos + 1) < OS_TIBLEN 'zeile noch nicht zu lang? + case charc + ios#CHAR_BS: 'backspace + if tibpos > 0 'noch nicht anfang der zeile erreeicht? + tib[tibpos--] := 0 'ein zeichen aus puffer entfernen + ios.printbs 'steuerzeichen an terminal senden + other: 'zeicheneingabe + tib[tibpos++] := charc 'zeichen speichern + ios.printchar(charc) 'zeichen ausgeben + ios.printnl + tib[tibpos] := 0 'string abschließen + tibpos := charc := 0 'werte rücksetzen + +PUB os_nxtoken1: stradr 'sys: token 1 von tib einlesen +''funktionsgruppe : sys +''funktion : nächsten token im eingabestring suchen und stringzeiger übergeben +''eingabe : - +''ausgabe : stradr - adresse auf einen string mit dem gefundenen token +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib +'' : token - tokenstring + + stradr := os_tokenize(@token1) + +PUB os_nxtoken2: stradr 'sys: token 2 von tib einlesen +''funktionsgruppe : sys +''funktion : nächsten token im eingabestring suchen und stringzeiger übergeben +''eingabe : - +''ausgabe : stradr - adresse auf einen string mit dem gefundenen token +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib +'' : token - tokenstring + + stradr := os_tokenize(@token2) + +PUB os_tokenize(token):stradr | i 'sys: liest nächsten token aus tib + + i := 0 + if tib[tibpos] <> 0 'abbruch bei leerem string + repeat until tib[tibpos] > ios#CHAR_SPACE 'führende leerzeichen ausbenden + tibpos++ + repeat until (tib[tibpos] == ios#CHAR_SPACE) or (tib[tibpos] == 0) 'wiederholen bis leerzeichen oder stringende + byte[token][i] := tib[tibpos] + tibpos++ + i++ + else + token := 0 + byte[token][i] := 0 + stradr := token + +PUB os_nextpos: tibpos2 'sys: setzt zeiger auf nächste position +''funktionsgruppe : sys +''funktion : tibpos auf nächstes token setzen +''eingabe : - +''ausgabe : tibpos2 - position des nächsten tokens in tib +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib + + if tib[tibpos] <> 0 + repeat until tib[tibpos] > ios#CHAR_SPACE 'führende leerzeichen ausbenden + tibpos++ + return tibpos + +PUB os_cmdint 'sys: kommandointerpreter +''funktionsgruppe : sys +''funktion : kommandointerpreter; zeichenkette ab tibpos wird als kommando interpretiert +'' : tibpos wird auf position hinter token gesetzt +''eingabe : - +''ausgabe : - +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib + + repeat 'kommandostring kopieren + cmdstr[tibpos] := tib[tibpos] + tibpos++ + until (tib[tibpos] == ios#CHAR_SPACE) or (tib[tibpos] == 0) 'wiederholen bis leerzeichen oder stringende + cmdstr[tibpos] := 0 'kommandostring abschließen + os_cmdexec(@cmdstr) 'interpreter aufrufen + tibpos := 0 'tastaturpuffer zurücksetzen + tib[0] := 0 + +PUB os_cmdexec(stradr) 'sys: kommando im ?bergebenen string wird als kommando interpretiert +{{os_smdexec - das kommando im ?bergebenen string wird als kommando interpretiert + stradr: adresse einer stringvariable die ein kommando enth?lt}} + if strcomp(stradr,string("help")) 'help + ios.print(string("help: man eram")) + elseif strcomp(stradr,string("d")) 'd display - speicheranzeige + ram_disp + elseif strcomp(stradr,string("dl")) 'd display long - speicheranzeige + ram_displong + elseif strcomp(stradr,string("n")) 'n next - anzeige fortsetzen + ram_next + elseif strcomp(stradr,string("m")) 'm modify - speicher modifizieren + ram_mod + elseif strcomp(stradr,string("l")) 'l modify - long + ram_lmod + elseif strcomp(stradr,string("info")) + ram_info + elseif strcomp(stradr,string("f")) + ram_fill + elseif strcomp(stradr,string("fu")) 'fill im userbereich + ram_fillusr + elseif strcomp(stradr,string("rbas")) + ram_setrbas + elseif strcomp(stradr,string("sysvar")) + ram_sysvar + elseif strcomp(stradr,string("load")) 'load - + ram_load + elseif strcomp(stradr,string("cls")) 'cls - + ios.printcls + elseif strcomp(stradr,string("bye")) 'bye + ios.stop + elseif strcomp(stradr,string("xinit")) 'rdisk initialisieren + rd_init + elseif strcomp(stradr,string("xnew")) 'neue ram-datei erstellen + rd_new + elseif strcomp(stradr,string("xhead")) 'header der dateien anzeigen + rd_header + elseif strcomp(stradr,string("xdel")) 'ram-datei löschen + rd_del + elseif strcomp(stradr,string("xren")) 'ram- datei umbenennen + rd_rename + elseif strcomp(stradr,string("xdir")) 'ram-dateien liste anzeigen + rd_dir + elseif strcomp(stradr,string("xftab")) 'tabelle geöffnete dateien anzeigen + rd_ftab + elseif strcomp(stradr,string("xopen")) 'ram-datei öffnen + rd_open + elseif strcomp(stradr,string("xsave")) 'ram-datei auf sd speichern + rd_save + elseif strcomp(stradr,string("xclose")) 'ram-datei schliessen + rd_close + elseif strcomp(stradr,string("xseek")) 'dateizeiger setzen + rd_seek + elseif strcomp(stradr,string("xput")) 'wert in geöffnete datei schreiben + rd_put + elseif strcomp(stradr,string("xget")) 'wert aus geöffneter datei lesen + rd_get + elseif strcomp(stradr,string("xwrite")) 'wert an def. adresse in datei schreiben + rd_write + elseif strcomp(stradr,string("xread")) 'wert von def. adresse aus datei lesen + rd_read + elseif strcomp(stradr,string("xload")) 'ram-datei von sd laden + rd_load + elseif strcomp(stradr,string("xtype")) 'ram-datei (text) ausgeben + rd_type + elseif strcomp(stradr,string("debug")) + debug + else 'kommando nicht gefunden + ios.print(stradr) + ios.print(@prompt3) + ios.printnl + +PRI debug + + ios.rd_init + ios.rd_newfile(string("d1"),8) + ios.rd_newfile(string("d2"),8) + ios.rd_newfile(string("d3"),8) + ios.rd_newfile(string("d4"),8) + ios.rd_newfile(string("d5"),8) + rd_dir + + +PRI rd_type | stradr,len,fnr 'rd: text ausgeben + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + fnr := ios.rd_open(stradr) 'datei öffnen + ifnot fnr == -1 + len := ios.rd_len(fnr) + ios.rd_seek(fnr,0) + repeat len + ios.printchar(ios.rd_get(fnr)) + ios.rd_close(fnr) + + +PRI rd_load | stradr,len,fnr 'rd: datei in ramdisk laden + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + ifnot os_error(ios.sdopen("r",stradr)) 'datei öffnen + len := ios.sdfattrib(ios#F_SIZE) + ios.rd_newfile(stradr,len) 'datei erzeugen + fnr := ios.rd_open(stradr) + ios.rd_seek(fnr,0) + repeat len 'datei einlesen + ios.rd_put(fnr,ios.sdgetc) + ios.sdclose + ios.rd_close(fnr) + +PRI rd_save | stradr, fnr, len 'rd: datei aus ramdisk speichern + + stradr := os_nxtoken1 + fnr := ios.rd_open(stradr) + ifnot fnr == -1 + len := ios.rd_len(fnr) + ifnot os_error(ios.sdnewfile(stradr)) + ifnot os_error(ios.sdopen("W",stradr)) + ios.print(string("Schreibe Datei...")) + repeat len + ios.sdputc(ios.rd_get(fnr)) + ios.sdclose + ios.print(string(" ok")) + ios.printnl + ios.rd_close(fnr) + +PRI rd_rename + + os_error(ios.rd_rename(os_nxtoken1,os_nxtoken2)) + + +PRI rd_seek | fnr,wert 'rd: dateizeiger setzen + + fnr := num.FromStr(os_nxtoken1,num#HEX) + wert := num.FromStr(os_nxtoken1,num#HEX) + ios.rd_seek(fnr,wert) + +PRI rd_put | fnr,wert,chars 'rd: werte ausgeben + + fnr := num.FromStr(os_nxtoken1,num#HEX) + wert := num.FromStr(os_nxtoken1,num#HEX) + chars := num.FromStr(os_nxtoken1,num#HEX) + + repeat chars + ios.rd_put(fnr,wert) + +PRI rd_get | fnr,chars,i,j 'rd: werte einlesen + + fnr := num.FromStr(os_nxtoken1,num#HEX) + chars := num.FromStr(os_nxtoken1,num#HEX) + + i := j := 0 + repeat chars + ifnot i + ios.printnl + ios.printhex(j,4) + ios.printchar(":") + ios.printhex(ios.rd_get(fnr),2) + ios.printchar(" ") + if i++ == 7 + i := 0 + j++ + ios.printnl + +PRI rd_write | fnr,adr,wert 'rd: wert schreiben + + fnr := num.FromStr(os_nxtoken1,num#HEX) + adr := num.FromStr(os_nxtoken1,num#HEX) + wert := num.FromStr(os_nxtoken1,num#HEX) + + ios.rd_wrbyte(fnr,wert,adr) + +PRI rd_read | fnr,adr 'rd: wert lesen + + fnr := num.FromStr(os_nxtoken1,num#HEX) + adr := num.FromStr(os_nxtoken1,num#HEX) + + ios.printhex(ios.rd_rdbyte(fnr,adr),2) + ios.printnl + + +PRI rd_close 'rd: datei schliessen + + ios.rd_close(num.FromStr(os_nxtoken1,num#HEX)) + +PRI rd_open 'rd: datei öffnen + + ifnot ios.rd_open(os_nxtoken1) + os_error(5) + +PRI rd_ftab | i 'rd: anzeige ftab + + i := 0 + repeat ios#FILES + ios.printnl + ios.printhex(i,2) + ios.printchar(":") + ios.printhex(ios.rd_getftab(i*3+0),6) + ios.printchar(" ") + ios.printhex(ios.rd_getftab(i*3+1),6) + ios.printchar(" ") + ios.printhex(ios.rd_getftab(i*3+2),6) + ifnot i + ios.print(string(" user")) + i++ + ios.printnl + +PRI rd_del | adr 'rd: datei löschen + + os_error(ios.rd_del(os_nxtoken1)) + +PRI rd_dir | stradr,len 'rd: dir anzeigen + +if ios.ram_rdbyte(ios#sysmod,ios#RAMDRV) + ios.rd_dir + repeat + len := ios.rd_dlen + stradr := ios.rd_next + if stradr + ios.print(stradr) + ios.printtab + ios.printdec(len) + ios.printnl + until stradr == 0 +else + os_error(1) + +PRI rd_header|hp,nx,len,i 'rd: header + + hp := ios#STARTRD + repeat + nx := ios.ram_rdlong(ios#sysmod,hp) + len := ios.ram_rdlong(ios#sysmod,hp+4) + ios.print(string("[adr-header] = $")) + ios.printhex(hp,8) + ios.printnl + ios.print(string("[adr-next ] = $")) + ios.printhex(nx,8) + ios.printnl + ios.print(string("[len ] = $")) + ios.printhex(len,8) + ios.printchar(" ") + ios.printdec(len) + ios.printnl + ios.print(string("[name ] = ")) + i := 0 + repeat 12 + ios.printchar(ios.ram_rdbyte(ios#sysmod,hp+8+i++)) + hp := nx + ios.print(string(" <*/q> : ")) + if ios.keywait == "q" + quit + ios.printnl + until nx == 0 + ios.printnl + +PRI rd_new 'rd: new file + + ios.rd_newfile(os_nxtoken1,num.FromStr(os_nxtoken2,num#DEC)) + +PRI rd_init 'rd: rdisk initialisieren + + ios.rd_init + +PRI ram_sysvar | i 'ram: systemvariablen anzeigen + + ios.print(string("LOADERPTR = ")) + ios.printchar("[") + ios.printhex(ios#LOADERPTR,6) + ios.print(string("] : ")) + ios.printhex(ios.ram_rdlong(0,ios#LOADERPTR),6) + ios.printnl + ios.print(string("MAGIC = ")) + ios.printchar("[") + ios.printhex(ios#MAGIC,6) + ios.print(string("] : ")) + ios.printhex(ios.ram_rdbyte(0,ios#MAGIC),6) + ios.printnl + ios.print(string("SIFLAG = ")) + ios.printchar("[") + ios.printhex(ios#SIFLAG,6) + ios.print(string("] : ")) + ios.printhex(ios.ram_rdbyte(0,ios#SIFLAG),6) + ios.printnl + ios.print(string("BELDRIVE = ")) + i := ios#BELDRIVE + repeat 12 + ios.printchar(ios.ram_rdbyte(0,i++)) + ios.printnl + ios.print(string("PARAM = ")) + i := ios#PARAM + repeat 32 + ios.printchar(ios.ram_rdbyte(0,i++)) + ios.printnl + ios.print(string("RAMEND = ")) + ios.printchar("[") + ios.printhex(ios#RAMEND,6) + ios.print(string("] : ")) + ios.printhex(ios.ram_getend,6) + ios.printnl + ios.print(string("RAMBAS = ")) + ios.printchar("[") + ios.printhex(ios#RAMBAS,6) + ios.print(string("] : ")) + ios.printhex(ios.ram_getbas,6) + ios.printnl + + +PRI ram_setrbas 'ram: basisadresse setzen + + ios.ram_setbas(num.FromStr(os_nxtoken1,num#HEX)) + +PRI ram_fill | adr,len,wert 'ram: speicherbereich füllen + + adr := ram_symbols + len := num.FromStr(os_nxtoken1,num#HEX) + wert := num.FromStr(os_nxtoken1,num#HEX) + + repeat len + ios.ram_wrbyte(ios#sysmod,wert,adr++) + +PRI ram_fillusr | adr,len,wert 'ram: speicherbereich füllen + + adr := ram_symbols + len := num.FromStr(os_nxtoken1,num#HEX) + wert := num.FromStr(os_nxtoken1,num#HEX) + + repeat len + ios.ram_wrbyte(ios#usrmod,wert,adr++) + +PRI ram_info 'ram: infos anzeigen + ios.print(string("RBAS : $")) + ios.printhex(ios.ram_getbas,6) + ios.print(string(" REND : $")) + ios.printhex(ios.ram_getend,6) + ios.print(string(" RLEN : $")) + ios.printhex(ios.ram_getend - ios.ram_getbas,6) + ios.print(string(" RDRV : $")) + ios.printhex(ios.ram_rdbyte(ios#sysmod,ios#RAMDRV),2) + ios.printnl + +PRI ram_mod | wert,adresse,stradr 'ram: rambereich beschreiben +{{rmodify - rambereich beschreiben, adresse und werte + folgen auf kommandozeile}} + + adresse := ram_symbols 'adresse von kommandozeile holen + repeat + if (stradr := os_nxtoken1) + wert := num.FromStr(stradr,num#HEX) 'nächstes byte von kommandozeile holen + ios.ram_wrbyte(0,wert,adresse++) 'wert in eram schreiben + until stradr == 0 'keine parameter mehr? + +PRI ram_lmod | wert,adresse,stradr 'ram: rambereich beschreiben (long) +{{rmodify - rambereich beschreiben, adresse und werte + folgen auf kommandozeile}} + + adresse := ram_symbols 'adresse von kommandozeile holen + repeat + if (stradr := os_nxtoken1) + wert := num.FromStr(stradr,num#HEX) 'nächstes byte von kommandozeile holen + ios.ram_wrlong(0,wert,adresse) 'long in eram schreiben + adresse := adresse + 4 + until stradr == 0 'keine parameter mehr? + +PRI ram_disp | adresse,zeilen,sadr 'ram: rambereich anzeigen +{{rdisplay - rambereich anzeigen, adresse und zeilenzahl folgt auf kommandozeile}} + + adresse := ram_symbols + + zeilen := num.FromStr(os_nxtoken1,num#HEX) 'zeilenzahl von kommandozeile holen + if zeilen == 0 + zeilen := RMON_ZEILEN + ram_print(adresse,zeilen) + +PRI ram_symbols:adresse | sadr 'ram: adresse auflösen + + sadr := os_nxtoken1 + if strcomp(sadr,string("bas")) + adresse := ios.ram_getbas + elseif strcomp(sadr,string("end")) + adresse := ios.ram_getend + elseif strcomp(sadr,string("sys")) + adresse := ios.ram_getend + 1 + elseif strcomp(sadr,string("rd:")) + adresse := ios.rd_searchdat(os_nxtoken1) + else + adresse := num.FromStr(sadr,num#HEX) 'adresse von kommandozeile holen + + +PRI ram_displong | sadr,adresse,wert 'ram: rambereich als long anzeigen + + adresse := ram_symbols + + repeat + ios.printnl + if (adresse => ios.ram_getbas) & (adresse =< ios.ram_getend) + ios.setcolor(2) + ios.printhex(adresse - ios.ram_getbas,6) + ios.setcolor(0) + else + ios.print(string("------")) + ios.printchar("-") + ios.printhex(adresse,6) 'adresse ausgeben + ios.printchar(" ") + + wert := ios.ram_rdlong(0,adresse) + ios.printhex(wert,6) + ios.printchar(":") + ios.printbin(wert,32) + ios.print(string(" <*/q> : ")) + adresse += 4 + until ios.keywait == "q" + ios.printnl + +PRI ram_next 'ram: anzeige fortsetzen + ram_print(ppos,pcnt) + +PRI ram_print(adresse,zeilen)|wert,pbas,pend 'ram: ausgabe + + pbas := ios.ram_getbas 'rbas vom system sichern + pend := ios.ram_getend + repeat zeilen 'zeilen + if (adresse => pbas) & (adresse =< pend) + ios.setcolor(2) + ios.printhex(adresse-pbas,6) + ios.setcolor(0) + else + ios.print(string("------")) + ios.printchar("-") + ios.printhex(adresse,6) 'adresse ausgeben + ios.printchar(ios#CHAR_SPACE) + repeat RMON_BYTES 'hexwerte ausgeben + wert := ios.ram_rdbyte(0,adresse++) + ios.printhex(wert,2) 'byte ausgeben + ios.printchar(":") + adresse := adresse - rmon_bytes + ios.printchar(ios#CHAR_SPACE) + repeat RMON_BYTES 'zeichen ausgeben + wert := ios.ram_rdbyte(0,adresse++) + if wert < $20 + wert := 46 + ios.printchar(wert) 'byte ausgeben + ios.printchar($0D) + ppos := adresse + pcnt := zeilen + +PRI ram_load | adr,len,stradr,status,char,i 'ram: lade datei nach eramadr +{{sdload - adr len dateiname lade datei nach eram-adr}} + + adr := num.FromStr(os_nxtoken1,num#HEX) 'adresse von kommandozeile holen + len := num.FromStr(os_nxtoken1,num#HEX) 'l?nge von kommandozeile holen + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + status := ios.sdopen("r",stradr) 'datei ?ffnen + if status > 0 + ios.print(string("Status : ")) + ios.printdec(status) + ios.printnl + if status == 0 + repeat i from 0 to len + char := ios.sdgetc + ios.ram_wrbyte(0,char,adr + i) + ios.sdclose + + + +PUB os_error(err):error 'sys: fehlerausgabe + + if err + ios.printnl + ios.print(@err_s1) + ios.printdec(err) + ios.print(string(" : $")) + ios.printhex(err,2) + ios.printnl + ios.print(@err_s2) + case err + 0: ios.print(@err0) + 1: ios.print(@err1) + 2: ios.print(@err2) + 3: ios.print(@err3) + 4: ios.print(@err4) + 5: ios.print(@err5) + 6: ios.print(@err6) + 7: ios.print(@err7) + 8: ios.print(@err8) + 9: ios.print(@err9) + 10: ios.print(@err10) + 11: ios.print(@err11) + 12: ios.print(@err12) + 13: ios.print(@err13) + 14: ios.print(@err14) + 15: ios.print(@err15) + 16: ios.print(@err16) + 17: ios.print(@err17) + 18: ios.print(@err18) + 19: ios.print(@err19) + 20: ios.print(@err20) + OTHER: ios.print(@errx) + ios.printnl + error := err + +DAT +prompt1 byte "ok ", $0d, 0 +prompt2 byte ": ", 0 +prompt3 byte "? ",0 +wait1 byte "",0 + +err_s1 byte "Fehlernummer : ",0 +err_s2 byte "Fehler : ",0 + +err0 byte "no error",0 +err1 byte "fsys unmounted",0 +err2 byte "fsys corrupted",0 +err3 byte "fsys unsupported",0 +err4 byte "not found",0 +err5 byte "file not found",0 +err6 byte "dir not found",0 +err7 byte "file read only",0 +err8 byte "end of file",0 +err9 byte "end of directory",0 +err10 byte "end of root",0 +err11 byte "dir is full",0 +err12 byte "dir is not empty",0 +err13 byte "checksum error",0 +err14 byte "reboot error",0 +err15 byte "bpb corrupt",0 +err16 byte "fsi corrupt",0 +err17 byte "dir already exist",0 +err18 byte "file already exist",0 +err19 byte "out of disk free space",0 +err20 byte "disk io error",0 +err21 byte "command not found",0 +errx byte "undefined",0 + diff --git a/system/regnatix/flash.spin b/system/regnatix/flash.spin new file mode 100644 index 0000000..4e7f6a1 --- /dev/null +++ b/system/regnatix/flash.spin @@ -0,0 +1,432 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : flash +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : Flash-Tool +Komponenten : - +COG's : - +Logbuch : + +09-04-2011-dr235 - erste version + +Kommandoliste : + +/? : Hilfe +/fh : Datei in HI-ROM flashen +/fl : Datei in LO-ROM flashen +/dh : Dump HI-ROM +/dl : Dump LO-ROM +/vh : Vergleich Datei <--> HI-ROM +/ch : HI-ROM löschen +/cl : LO-ROM löschen +/sh : HI-ROM speichern +/sl : LO-ROM speichern + +Notizen : + + +}} + +OBJ + ios : "reg-ios" + sdspi : "glob-sdspi" + num : "glob-numbers" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +DCOL = 8 'dump spaltenzahl +DROW = 16 'dump zeilenzahl + +PAGESIZE = 32 +BUFFERSIZE = DCOL * DROW +LO_EEPROM = $0000 ' based upon 24LC512 (64KB) +HI_EEPROM = $8000 +IMAGESIZE = $8000 'größe eines rom-images + + +VAR + +byte buffer[BUFFERSIZE] +byte parastr[64] +byte input[64] +long ioControl[2] + +PUB main + + ios.start 'ios initialisieren + ios.parastart 'parameterübergabe starten + sdspi.start(@iocontrol) 'spi-treiber starten + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: man flash")) '/? + "f": case byte[@parastr][2] + "h": flash(HI_EEPROM) '/fh - in oberen rom flashen + "l": flash(LO_EEPROM) '/fl - in unteren rom flashen + "d": case byte[@parastr][2] + "h": dump(HI_EEPROM) '/dh - dump des oberen rom + "l": dump(LO_EEPROM) '/dl - dump des unteren rom + "v": case byte[@parastr][2] + "h": verify(HI_EEPROM) '/vh - vergleih oberen rom + "c": case byte[@parastr][2] + "h": clear(HI_EEPROM) '/ch - oberen rom löschen + "l": clear(LO_EEPROM) '/cl - unteren rom löschen + "s": case byte[@parastr][2] + "h": save(HI_EEPROM) '/sh - oberen rom speichern + "l": save(LO_EEPROM) '/sl - unteren rom speichern + "t": testsave(HI_EEPROM) + + sdspi.stop +' ios.ram_wrbyte(ios#sysmod,0,ios#SIFLAG) +' reboot + ios.stop + +PRI dump(eeAdr)|key,i,j,n 'flash: azeige rom-inhalt + + eeAdr += sdspi#bootAddr ' always use boot EEPROM + + repeat + sdspi.readEEPROM(eeAdr,@buffer,BUFFERSIZE) + i := j := 0 + + repeat DROW 'zeilen + ios.printhex(eeAdr+j*DCOL,4) + ios.printchar(" ") + repeat DCOL 'bytes + n := byte[@buffer][i++] + ios.printhex(n,2) + ios.printchar(":") + ios.printchar(" ") + i := i - DCOL + repeat DCOL 'zeichen + n := byte[@buffer][i++] + ios.printqchar(n) + ios.printnl + j++ + + ios.print(string("CMD? [b]ack[q]uit[a]dr[n]ext : ")) + key := ios.keywait + case key + "b": eeAdr := eeAdr - BUFFERSIZE + "a": eeAdr := inputhex + sdspi#bootAddr + "n": eeAdr := eeAdr + BUFFERSIZE + ios.printnl + ios.printnl + until key == "q" + +PRI flash(eeAdr)|i,len,pos,dif,pcnt 'flash: datei flashen + + eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen + + if ios.paranext(@parastr) + ios.printnl + ios.print(@msg0) + ios.print(@msg1) + ios.print(@parastr) + ios.printnl + ifnot ios.sdopen("R",@parastr) + + 'programmlänge ermitteln + repeat i from 0 to PAGESIZE - 1 'erste page --> puffer + byte[@buffer][i] := ios.sdgetc + len := word[@buffer+$A] '$a ist stackposition und damit länge der objektdatei + ios.sdclose + + 'datei kpl. einlesen und flashen + ios.print(@msg8) + ios.printhex(eeAdr,8) + ios.printnl + ios.print(@msg4) + ios.printdec(len) + ios.printnl + ios.print(@msg5) + ios.printdec(len/PAGESIZE) + ios.printnl + ios.print(@msg2) + pcnt := len / PAGESIZE / 10 + ios.curchar("▶") + + ios.sdopen("R",@parastr) + repeat pos from 0 to len - 1 step PAGESIZE + dif := (len - pos) <# PAGESIZE + repeat i from 0 to dif - 1 'page --> puffer + byte[@buffer][i] := ios.sdgetc + sdspi.writeEEPROM(eeAdr+pos,@buffer,dif) 'puffer --> eeprom + sdspi.writeWait(eeAdr+pos) 'warte auf ende des schreibvorgangs + pcnt-- + if pcnt == 0 + ios.printchar("•") + pcnt := len / PAGESIZE / 10 + + ios.sdclose + ios.curchar("‣") + ios.print(@msg3) + + else + printErr(@err2) + else + printErr(@err1) + +PRI verify(eeAdr)|a,b,pos,len,i 'flash: vergleichen + + eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen + len := IMAGESIZE + + if ios.paranext(@parastr) + ios.printnl + ios.print(@msg0) + ios.print(@msg1) + ios.print(@parastr) + ios.printnl + ifnot ios.sdopen("R",@parastr) + + ios.print(@msg7) + ios.print(@msg4) + ios.printdec(IMAGESIZE) + ios.printnl + ios.print(@msg5) + ios.printdec(len/PAGESIZE) + ios.printnl + + 'vergleich starten + repeat pos from 0 to IMAGESIZE-1 step PAGESIZE + sdspi.readEEPROM(eeAdr+pos,@buffer,PAGESIZE) 'page einlesen + repeat i from 0 to PAGESIZE-1 + a := byte[@buffer][i] + b := ios.sdgetc + if a <> b + ios.printhex(eeAdr+pos+i,4) + ios.print(string(" : ")) + ios.printhex(a,2) + ios.print(string(" <> ")) + ios.printhex(b,2) + ios.print(string(" CMD? [q]uit[*]next : ")) + case ios.keywait + "q": return + ios.printnl + + ios.sdclose + + else + printErr(@err2) + else + printErr(@err1) + +PRI save(eeAdr)|pos,len,i,j,pcnt,blk 'flash: speichern + + eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen + len := IMAGESIZE + blk := len/BUFFERSIZE + pcnt := blk/10 + + if ios.paranext(@parastr) + ios.printnl + ios.print(@msg9) + ios.print(@msg1) + ios.print(@parastr) + ios.printnl + ifnot ios.sdnewfile(@parastr) + ios.sdopen("W",@parastr) + ios.print(@msg8) + ios.printhex(eeAdr,8) + ios.printnl + ios.print(@msg4) + ios.printdec(IMAGESIZE) + ios.printnl + ios.print(@msg5) + ios.printdec(blk) + ios.printnl + ios.print(@msgA) + ios.curchar("▶") + + j := 0 + repeat blk+1 + sdspi.readEEPROM(eeAdr,@buffer,BUFFERSIZE) 'puffer einlesen + ios.sdputblk(BUFFERSIZE,@buffer) + eeAdr := eeAdr + BUFFERSIZE + + pcnt-- + if pcnt == 0 + ios.printchar("•") + pcnt := len / BUFFERSIZE / 10 + + ios.sdputc(0) 'provisorischer patch für fatengine: + 'bei 32kb-grenze gibt es einen fehler! + ios.sdclose + ios.curchar("‣") + ios.print(@msg3) + + else + printErr(@err2) + else + printErr(@err1) + +PRI testsave(eeAdr)|pos,len,i,j,pcnt,blk 'flash: speichern + + eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen + len := IMAGESIZE + blk := len/BUFFERSIZE + pcnt := blk/10 + + if ios.paranext(@parastr) + ios.printnl + ios.print(@msg0) + ios.print(@msg1) + ios.print(@parastr) + ios.printnl + ifnot ios.sdnewfile(@parastr) + ios.sdopen("W",@parastr) + ios.print(@msg9) + ios.print(@msg8) + ios.printhex(eeAdr,8) + ios.printnl + ios.print(@msg4) + ios.printdec(IMAGESIZE) + ios.printnl + ios.print(@msg5) + ios.printdec(blk) + ios.printnl + ios.print(@msgA) + ios.curchar("▶") + + j := 0 + repeat blk+1 + repeat i from 0 to BUFFERSIZE-1 + ios.sdputc(j) + + ios.printdec(j++) + ios.printchar(" ") + + ios.sdclose + ios.curchar("‣") + ios.print(@msg3) + + else + printErr(@err2) + else + printErr(@err1) + +PRI printbuf(eeAdr)|i,j,n + + i := j := 0 + + repeat DROW 'zeilen + ios.printhex(eeAdr+j*DCOL,4) + ios.printchar(" ") + repeat DCOL 'bytes + n := byte[@buffer][i++] + ios.printhex(n,2) + ios.printchar(":") + ios.printchar(" ") + i := i - DCOL + repeat DCOL 'zeichen + n := byte[@buffer][i++] + ios.printqchar(n) + ios.printnl + j++ + +DAT 'sys: strings + +msg0 byte "Funktion : Datei --> ROM",13,0 +msg1 byte "Datei : ",0 +msg2 byte "Flash : ",0 +msg3 byte " ok",13,0 +msg4 byte "Länge : ",0 +msg5 byte "Blöcke : ",0 +msg6 byte "Funktion : ROM löschen",13,0 +msg7 byte "Funktion : Datei <--> ROM vergleichen",13,0 +msg8 byte "Adresse : $",0 +msg9 byte "Funktion : ROM --> Datei",13,0 +msgA byte "Image : ",0 + +PRI clear(eeAdr)|len,pcnt,i,pos 'flash: löschen + + eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen + len := IMAGESIZE + pcnt := len / PAGESIZE / 10 + + ios.printnl + ios.print(@msg6) + ios.print(@msg4) + ios.printdec(IMAGESIZE) + ios.printnl + ios.print(@msg5) + ios.printdec(len/PAGESIZE) + ios.printnl + ios.print(@msg2) + ios.curchar("▶") + + 'puffer löschen + repeat i from 0 to BUFFERSIZE-1 + byte[@buffer][i] := 0 + + 'rom löschen + repeat pos from 0 to IMAGESIZE-1 step PAGESIZE + sdspi.writeEEPROM(eeAdr+pos,@buffer,PAGESIZE) + sdspi.writeWait(eeAdr+pos) + pcnt-- + if pcnt == 0 + ios.printchar("•") + pcnt := len / PAGESIZE / 10 + + ios.curchar("‣") + ios.print(@msg3) + return + +DAT 'sys: fehermeldungen + +err0 byte 13,"Fehler : " +err1 byte "Zu wenig Parameter!",13,0 +err2 byte "Datei nicht gefunden!",13,0 + +PRI printErr(stradr) 'sys: feherbehandlung + + ios.print(@err0) + ios.print(stradr) + ios.print(string("help: man flash")) + +PRI inputhex:hexnum 'sys: eingabe hexwert + + ios.curchar("_") + ios.print(string("Adresse : $")) + ios.input(@input,8) 'nummer eingeben + ios.curchar("‣") + hexnum := num.FromStr(@input,num#HEX) 'string in hexwert wandeln + return + + +DAT 'lizenz + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/fm.spin b/system/regnatix/fm.spin new file mode 100644 index 0000000..7b50a76 --- /dev/null +++ b/system/regnatix/fm.spin @@ -0,0 +1,551 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Filemanager +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +- view nach f9 +- tab in wbox + +}} + +OBJ + + ios : "reg-ios" + dlbox[2] : "gui-dlbox" + pbar : "gui-pbar" + wbox : "gui-wbox" + input : "gui-input" + fm : "fm-con" + gc : "glob-con" + str : "glob-string" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +VAR + + byte rows,cols,vidmod + byte fname[fm#MAX_LEN+1] + byte dir 'richtung der cursorbewegung + byte fl_mounted '1 = sd mounted + byte fl_full '1 = linkes fenster maximiert + byte w_sel 'nr des fokusierten fensters + byte w_pos[2] 'positionen im fenster + byte w_view[2] 'startposition des fensters + byte w_cols[2] 'anzahl der spalten im fenster + byte w_drives[2] 'zugeordnete drives + + byte w0_list[fm#MAX_BUFFER] 'aktuelles verzeichnis + byte w0_flags[fm#MAX_FILES] 'selected, directory usw. + long w0_len[fm#MAX_FILES] 'dateilängen + byte w0_number 'anzahl der files + + byte w1_list[fm#MAX_BUFFER] + byte w1_flags[fm#MAX_FILES] + long w1_len[fm#MAX_FILES] + byte w1_number + +PUB main | key + + init + dlbox[0].focus + dlbox[0].draw + dlbox[1].draw + info_print + + repeat + key := ios.keywait + case key + gc#KEY_CURUP: f_curup + gc#KEY_CURDOWN: f_curdown + gc#KEY_CURLEFT: f_curleft + gc#KEY_CURRIGHT: f_curright + gc#KEY_PAGEUP: f_pageup + gc#KEY_PAGEDOWN: f_pagedown + gc#KEY_RETURN: f_open + gc#KEY_BS: f_back + gc#KEY_SPACE: f_select + gc#KEY_ESC: + gc#KEY_TAB: f_focus + gc#KEY_POS1: f_pos1 + gc#KEY_F01: f_view + gc#KEY_F02: f_del + gc#KEY_F03: f_load + gc#KEY_F04: f_save + gc#KEY_F05: f_empty + gc#KEY_F06: f_mount + gc#KEY_F07: f_mkdir + gc#KEY_F08: f_selall + gc#KEY_F09: f_full + gc#KEY_F10: f_quit + +PRI init + + ios.start + testvideo + + dir := 1 + fl_mounted := 1 + fl_full := 0 + w_sel := 0 + w_pos[0] := w_pos[1] := 0 + w_view[0] := w_view[1] := 0 + w_cols[0] := (fm#W1X2-fm#W1X1)/(fm#MAX_LEN+2) + w_cols[1] := (fm#W2X2-fm#W2X1)/(fm#MAX_LEN+2) + w_drives[0] := fm#DR_SD + w_drives[1] := fm#DR_RAM + fname[0] := 0 + + frame_draw + w0_clrlist + w1_clrlist + w0_readdir + w1_readdir + dlbox[0].define(1,fm#W1X1,fm#W1Y1,fm#W1X2,fm#W1Y2,@w0_list,@w0_flags,0,fm#MAX_FILES) 'linkes fenster + dlbox[1].define(2,fm#W2X1,fm#W2Y1,fm#W2X2,fm#W2Y2,@w1_list,@w1_flags,0,fm#MAX_FILES) 'rechtes fenster + ios.windefine(3,fm#W3X1,fm#W3Y1,fm#W3X2,fm#W3Y2) 'logfenster + pbar.define(4,fm#W4X1,fm#W4Y1,fm#W4X2,fm#W4Y2) + wbox.define(5,fm#W4X1,fm#W4Y1,fm#W4X2,fm#W4Y2) + input.define(6,fm#W4X1,fm#W4Y1,fm#W4X2,fm#W4Y2,12) + + +PRI f_mount + + if fl_mounted + ios.sdunmount + repeat + wbox.draw(@str5,@str2,@str3) == 1 + while ios.sdmount + dlbox[0].draw + dlbox[1].draw + info_print + +PRI f_mkdir + + ios.sdnewdir(input.draw(string("Name eingeben : "))) + w0_clrlist + w0_readdir + dlbox[0].draw + dlbox[1].draw + info_print + +PRI f_selall | i + + i := 0 + case w_sel + 0: repeat w0_number + w0_flags[i++] ^= fm#FL_SEL + 1: repeat w1_number + w1_flags[i++] ^= fm#FL_SEL + dlbox[w_sel].redraw + +PRI f_pos1 + + w_pos[w_sel] := 0 + dlbox[w_sel].setpos(w_pos[w_sel]) + +PRI f_full + + if w_sel + dlbox[1].defocus + + case fl_full + 0: fl_full := 1 + dlbox[0].define(1,fm#W1X1,fm#W1Y1,fm#W2X2,fm#W1Y2,@w0_list,@w0_flags,0,fm#MAX_FILES) 'volles fenster + dlbox[0].focus + w_cols[0] := (fm#W2X2-fm#W1X1)/(fm#MAX_LEN+2) + 1: fl_full := 0 + dlbox[0].define(1,fm#W1X1,fm#W1Y1,fm#W1X2,fm#W1Y2,@w0_list,@w0_flags,0,fm#MAX_FILES) 'linkes fenster + w_cols[0] := (fm#W1X2-fm#W1X1)/(fm#MAX_LEN+2) + dlbox[0].focus + dlbox[1].draw + w_sel := 0 + +PRI f_open + + 'nur fenster 1 und verzeichnisse + if (w_sel == 0) & (w0_flags[w_view[w_sel] + w_pos[w_sel]] & fm#FL_DIR) + ios.sdchdir(get_fname(w_view[w_sel] + w_pos[w_sel])) + w0_clrlist + w0_readdir + dlbox[w_sel].draw + info_print + +PRI f_back + + ios.sdchdir(string("..")) + w0_clrlist + w0_readdir + dlbox[w_sel].redraw + info_print + +PRI f_curup + + if w_pos[w_sel] > 1 + w_pos[w_sel] -= dlbox[w_sel].getcols + dlbox[w_sel].setpos(w_pos[w_sel]) + info_print + dir := 0 + +PRI f_curdown + + if w_pos[w_sel] < (fm#WROWS * w_cols[w_sel] - dlbox[w_sel].getcols) + w_pos[w_sel] += dlbox[w_sel].getcols + dlbox[w_sel].setpos(w_pos[w_sel]) + info_print + dir := 1 + +PRI f_curleft + + if w_pos[w_sel] + w_pos[w_sel]-- + dlbox[w_sel].setpos(w_pos[w_sel]) + info_print + dir := 0 + +PRI f_curright + + if w_pos[w_sel] < (fm#WROWS * w_cols[w_sel] - 1) + w_pos[w_sel]++ + dlbox[w_sel].setpos(w_pos[w_sel]) + info_print + dir := 1 + +PRI f_pageup + + if (w_view[w_sel] - fm#WROWS * w_cols[w_sel]) => 0 + w_view[w_sel] -= fm#WROWS * w_cols[w_sel] + dlbox[w_sel].setview(w_view[w_sel]) + info_print + w_pos[w_sel] := fm#WROWS * w_cols[w_sel] - 1 + dlbox[w_sel].setpos(w_pos[w_sel]) + +PRI f_pagedown | number + + case w_sel + 0: number := w0_number + 1: number := w1_number + if (w_view[w_sel] + fm#WROWS * w_cols[w_sel]) =< number '(fm#MAX_FILES) + w_view[w_sel] += fm#WROWS * w_cols[w_sel] + dlbox[w_sel].setview(w_view[w_sel]) + info_print + w_pos[w_sel] := 0 + dlbox[w_sel].setpos(w_pos[w_sel]) + +PRI f_select | i + + i := w_view[w_sel] + w_pos[w_sel] + case w_sel + 0: w0_flags[i] ^= fm#FL_SEL + 1: w1_flags[i] ^= fm#FL_SEL + dlbox[w_sel].redraw + case dir + 0: f_curleft + 1: f_curright + +PRI f_focus + +ifnot fl_full + dlbox[w_sel].defocus + if w_sel == 1 + w_sel := 0 + else + w_sel := 1 + dlbox[w_sel].focus + info_print + +PRI f_quit + + ios.sddmset(ios#DM_USER) 'regime soll in diesem verzeichnis landen + ios.winset(0) + ios.screeninit + ios.stop + +PRI f_load | i + + pbar.setmaxbar(w0_number) + i := 0 + repeat w0_number + if w0_flags[i] & fm#FL_SEL + pbar.draw(string("Lade Datei : "),get_fname(i),i) + load(get_fname(i)) + w0_flags[i] ^= fm#FL_SEL + info_print + i++ + pbar.update(i) + w1_readdir + dlbox[0].draw + dlbox[1].draw + +PRI f_save | i + + pbar.setmaxbar(w1_number) + i := 0 + repeat w1_number + if w1_flags[i] & fm#FL_SEL + pbar.draw(string("Speichere Datei : "),get_fname(i),i) + save(get_fname(i)) + w1_flags[i] ^= fm#FL_SEL + i++ + pbar.update(i) + w0_clrlist + w0_readdir + dlbox[0].draw + dlbox[1].draw + +PRI f_del | i + +if wbox.draw(@str1,@str2,@str3) == 1 + pbar.setmaxbar(w0_number) + i := 0 + repeat w0_number + if w0_flags[i] & fm#FL_SEL + pbar.draw(string("Lösche Datei : "),get_fname(i),i) + ios.sddel(get_fname(i)) + w0_flags[i] ^= fm#FL_SEL + i++ + pbar.update(i) + w0_clrlist + w0_readdir +dlbox[0].draw +dlbox[1].draw +info_print + +PRI f_empty + +if wbox.draw(@str4,@str2,@str3) == 1 + ios.ram_wrlong(ios#sysmod,ios#SYSVAR,ios#RAMEND) 'Zeiger auf letzte freie Speicherzelle setzen + ios.ram_wrlong(ios#sysmod,0,ios#RAMBAS) 'Zeiger auf erste freie Speicherzelle setzen + ios.ram_wrbyte(ios#sysmod,0,ios#RAMDRV) 'Ramdrive ist abgeschaltet + ios.rd_init + w1_clrlist + w1_readdir +dlbox[0].draw +w_pos[1] := 0 +w_view[1] := 0 +dlbox[1].setpos(w_pos[1]) +dlbox[w_sel].setview(w_view[1]) +info_print + + +PRI f_view | n,stradr + + ios.winset(3) + ios.curoff + ios.printcls + + stradr := get_fname(w_view[w_sel] + w_pos[w_sel]) + n := 1 + ifnot ios.os_error(ios.sdopen("r",stradr)) 'datei öffnen + repeat 'text ausgeben + if ios.printchar(ios.sdgetc) == ios#CHAR_NL 'zeilenzahl zählen und stop + if ++n == (fm#W3Y2 - 2) + n := 1 + if ios.keywait == "q" + ios.sdclose + ios.printcls + dlbox[0].redraw + dlbox[1].redraw + return + until ios.sdeof 'ausgabe bis eof + ios.print(string(13,"[EOF]")) + ios.keywait + ios.sdclose 'datei schließen + + ios.printcls + dlbox[0].draw + dlbox[1].draw + info_print + +PRI w0_clrlist | i + + i := 0 + repeat fm#MAX_FILES + w0_flags[i] := 0 + w0_len[i] := 0 + i++ + i := 0 + repeat fm#MAX_BUFFER + w0_list[i] := " " + i++ + + +PRI w1_clrlist | i + + i := 0 + repeat fm#MAX_FILES + w1_flags[i] := 0 + w1_len[i] := 0 + i++ + i := 0 + repeat fm#MAX_BUFFER + w1_list[i] := " " + i++ + +PRI w0_readdir | stradr,i,j + + i := 0 + ios.sddir + repeat while (stradr := ios.sdnext) + if ios.sdfattrib(ios#F_DIR) + w0_flags[i] := fm#FL_DIR + j := 0 + repeat fm#MAX_LEN + w0_list[i*fm#MAX_LEN+j] := byte[stradr+j] + j++ + w0_len[i] := ios.sdfattrib(ios#F_SIZE) + if i++ => fm#MAX_FILES - 1 + return + + w0_number := i + +PRI w1_readdir | stradr,i,j + + i := 0 + ios.rd_dir + repeat while (stradr := ios.rd_next) + j := 0 + repeat fm#MAX_LEN + w1_list[i*fm#MAX_LEN+j] := byte[stradr+j] + j++ + i++ + w1_len[i] := ios.rd_dlen + w1_number := i + +PRI get_fname(fnr):adrdat | i,stradr + + i := fm#MAX_LEN * fnr + case w_sel + 0: stradr := @w0_list + i + 1: stradr := @w1_list + i + i := 0 + repeat + fname[i] := byte[stradr+i] + i++ + until byte[stradr+i] == " " OR i == fm#MAX_LEN + fname[i] := 0 + return @fname + +PRI load(stradr) | len,fnr,i + + ifnot ios.sdopen("r",stradr) 'datei öffnen + len := ios.sdfattrib(ios#F_SIZE) + ios.rd_newfile(stradr,len) 'datei erzeugen + fnr := ios.rd_open(stradr) + ios.rd_seek(fnr,0) + i := 0 + ios.sdxgetblk(fnr,len) 'daten als block direkt in ext. ram einlesen + ios.sdclose + ios.rd_close(fnr) + +PRI save(stradr) | fnr,len,i + + fnr := ios.rd_open(stradr) + ifnot fnr == -1 + len := ios.rd_len(fnr) + ifnot ios.sdnewfile(stradr) + ifnot ios.sdopen("W",stradr) + i := 0 + ios.sdxputblk(fnr,len) 'daten als block schreiben + ios.sdclose + ios.rd_close(fnr) + + +PRI frame_draw + + ios.winset(0) + ios.curoff + ios.printcls + ios.cursetx(fm#W0X_MENU) + ios.cursety(fm#W0Y_MENU) + ios.setcolor(fm#COL_MENU) +' ios.print(string(" ")) + ios.print(string(" 6: Mount | 7: MkDir | 8: ALL | 9: Full | 10: Quit ")) + ios.printlogo(0,0) + ios.cursetx(fm#W0X_STAT) + ios.cursety(fm#W0Y_STAT) + ios.setcolor(fm#COL_STAT) + ios.printq(string(" 1: View | 2: Del | 3: SD>>RAM ◀▶ 4: SD< -1 + case rxchar + $08: 'backspace empfangen + ios.printctrl(ios#CHAR_TER_BS) + other: + if rxchar > $05 + ios.printchar(rxchar) 'textzeichen empfangen + + if ios.keystat + keychar := ios.key + case keychar + ios#CHAR_BS: 'backspace senden + ser.tx($08) + ios#CHAR_ESC: 'esc - programm beenden + return + other: 'textzeichen senden + ser.tx(keychar) + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/g0test.spin b/system/regnatix/g0test.spin new file mode 100644 index 0000000..42aa07b --- /dev/null +++ b/system/regnatix/g0test.spin @@ -0,0 +1,741 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : g0test +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +XMAX = 256 +YMAX = 192 + +x_tiles = 16 +y_tiles = 12 + +bit_base = $2000 +disp_base = $5000 +len_colblk = (x_tiles * y_tiles) * 2 + 256 + +'ademo1 +lines = 5 +thickness = 2 +s_obj = 200 'scale +d_obj = 64 'durchmesser +r_obj = d_obj/2 'radius +rotvar = 14 'rotationsvarianz + +VAR + + 'achtung, folgende reihenfolge darf nicht verändert werden! + word screen[x_tiles * y_tiles] 'tilemap + long colortab[64] 'farbregister + + long heap_len + long heap_use + +PUB main|i,x,y,n,len + + ios.start + + 'g0-code laden + ios.g0_load + + screenset1 'farben und tiles setzen + + ios.g0_static + heap_len := ios.g0_datlen + heap_use := @grdatend - @grdat + ios.g0_datblk(@grdat,0,heap_len) 'heapdaten senden + repeat + +' -------------------------------------------------------------------------- heap + ios.g0_static + ios.g0_clear + ios.g0_colorwidth(2,0) + ios.g0_textmode(2,2,6,0) + ios.g0_text(10,100,@string3 - @grdat) + ios.g0_printdec(150,100,heap_len,4,@strstart,@strstart - @grdat) + ios.g0_text(10, 70,@string4 - @grdat) + ios.g0_printdec(150, 70,heap_use,4,@strstart,@strstart - @grdat) + esc_key + waitcnt(cnt+clkfreq*5) + +' -------------------------------------------------------------------------- plot + ios.g0_clear + repeat 2000 + ios.g0_width(?n&%11111) + ios.g0_color(?n&%0011) + ios.g0_plot(?n&$ff,?n&$ff) + esc_key + +' -------------------------------------------------------------------------- line + ios.g0_clear + ios.g0_width(0) + repeat 2000 + ios.g0_color(?n&%0011) + ios.g0_line(?n&$ff,?n&$ff) + esc_key + +' -------------------------------------------------------------------------- arc + ios.g0_clear + ios.g0_width(0) + repeat 2000 + ios.g0_color(?n&%0011) + 'ios.g0_arc(x,y,xr,yr,angle,anglestep,steps,arcmode) + ios.g0_arc(?n&$ff,?n&$ff,?n&$1f,?n&$1f,?n&$1fff,?n&$1fff,?n&$1f,?n&%0011) + esc_key + +' -------------------------------------------------------------------------- tri + ios.g0_clear + ios.g0_width(0) + repeat 2000 + ios.g0_colorwidth(?n&%0011,?n&%11111) + ios.g0_tri(?n&$ff,?n&$ff,?n&$ff,?n&$ff,?n&$ff,?n&$ff) + esc_key + +' -------------------------------------------------------------------------- box + ios.g0_clear + ios.g0_width(0) + repeat 2000 + ios.g0_colorwidth(?n&%0011,?n&%11111) + ios.g0_box(?n&$ff,?n&$ff,?n&$ff,?n&$ff) + esc_key + +' -------------------------------------------------------------------------- vec + ios.g0_clear + ios.g0_width(0) + repeat 2000 'stern + ios.g0_color(?n&%0011) + 'ios.g0_vec(x, y, vecscale, vecangle, vecdef_ptr) + ios.g0_vec(?n&$ff,?n&$ff,?n&$ff,cnt>>14,@star - @grdat) + 'ios.g0_vec(100,100,200,0,0) + esc_key + + ios.g0_clear + repeat 2000 'rombus + ios.g0_color(?n&%0011) + ios.g0_vec(?n&$ff,?n&$ff,?n&$ff,cnt>>14,@rombus - @grdat) + esc_key + +' -------------------------------------------------------------------------- vecarc + ios.g0_clear + ios.g0_width(0) + repeat 2000 + ios.g0_color(?n&%0011) + 'vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + ios.g0_vecarc(XMAX/2,YMAX/2,70,70,cnt>>4,100,cnt>>14,@rombus - @grdat ) + esc_key + +' -------------------------------------------------------------------------- pix + ios.g0_clear + ios.g0_colorwidth(2,1) + ios.g0_pix(XMAX/2,YMAX/2,0,@oldbit1 - @grdat) + waitcnt(cnt+clkfreq*2) + ios.g0_colorwidth(2,0) + repeat x from 0 to 7 + repeat y from 0 to 5 + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(x*30+10,y*30+10,0,@oldbit1 - @grdat) + esc_key + waitcnt(cnt+clkfreq*2) + + + ios.g0_dynamic + n := 0 + repeat 400 + ios.g0_clear + ios.g0_colorwidth(2,1) + ios.g0_pixarc(XMAX/2,YMAX/2,50,50,cnt>>14,0,@oldbit1 - @grdat) + 'ios.g0_pix(XMAX/2,YMAX/2,0,@oldbit1 - @grdat) + ios.g0_colorwidth(2,0) + repeat x from 0 to 7 + repeat y from 0 to 5 + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(x*30+10+n*y,y*30+10,0,@oldbit1 - @grdat) + ios.g0_copy + n++ + esc_key + + + + ios.g0_dynamic + ios.g0_colorwidth(2,1) + repeat 10 + ios.g0_clear + repeat x from 0 to 7 + repeat y from 0 to 5 + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(x*30+10,y*30+10,0,@monkey1 - @grdat) + ios.g0_copy + esc_key + waitcnt(cnt+clkfreq/3) + ios.g0_clear + repeat x from 0 to 7 + repeat y from 0 to 5 + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(x*30+10,y*30+10,0,@monkey2 - @grdat) + ios.g0_copy + esc_key + waitcnt(cnt+clkfreq/3) + + repeat i from 0 to 31 + ios.g0_clear + ios.g0_colorwidth(1,i) + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(60,70,0,@monkey1 - @grdat) + ios.g0_copy + esc_key + waitcnt(cnt+clkfreq/7) + + ios.g0_static + +' -------------------------------------------------------------------------- pixarc + ios.g0_dynamic + ios.g0_colorwidth(2,1) + repeat 1000 + ios.g0_clear + 'ios.g0_pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + ios.g0_pixarc(XMAX/2,YMAX/2,50,50,cnt>>14,0,@monkey1 - @grdat) + ios.g0_copy + ios.g0_clear + 'ios.g0_pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + ios.g0_pixarc(XMAX/2,YMAX/2,50,50,cnt>>14,0,@monkey2 - @grdat) + ios.g0_copy + esc_key + ios.g0_static + +' -------------------------------------------------------------------------- text + ios.g0_dynamic + 'ios.g0_textmode(x_scale, y_scale, spacing, justification) + repeat 150 + ios.g0_clear + ios.g0_colorwidth(2,1) + repeat x from 0 to 7 + repeat y from 0 to 3 + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(x*30+10,y*30+70,0,@monkey1 - @grdat) + ios.g0_colorwidth(2,8) + ios.g0_textmode(5,5,6,0) + ios.g0_text(700 - (cnt>>20 & $fff),60,@string1 - @grdat) + ios.g0_colorwidth(1,6) + ios.g0_textmode(5,4,6,0) + ios.g0_text(700 - (cnt>>24 & $fff),0,@string2 - @grdat) + ios.g0_copy + esc_key + ios.g0_static + +' -------------------------------------------------------------------------- textarc + ios.g0_dynamic + ios.g0_colorwidth(2,1) + repeat 150 + ios.g0_clear + ios.g0_colorwidth(2,1) + repeat x from 0 to 7 + repeat y from 0 to 5 + 'ios.g0_pix(x, y, pixrot, pixdef_ptr) + ios.g0_pix(x*30+10,y*30+10,0,@monkey1 - @grdat) + ios.g0_colorwidth(0,8) + ios.g0_textmode(5,5,6,0) + 'ios.g0_textarc(x, y, xr, yr, angle, string_ptr) + ios.g0_textarc(XMAX/4,YMAX/4,50,50,cnt>>14,@string1 - @grdat) + ios.g0_copy + esc_key + ios.g0_static + +' -------------------------------------------------------------------------- animation + ademo1 + ademo2 + +' -------------------------------------------------------------------------- colorset + ios.g0_clear + screenset2 + + 'draw color samples + ios.g0_width(29)'(29) + + 'draw saturated samples + ios.g0_color(3) + repeat x from 0 to 15 + ios.g0_plot(x << 4 + 7, 183) + + 'draw gradient samples + repeat y from 2 to 6 + ios.g0_color(y & 1 | 2) + repeat x from 0 to 15 + ios.g0_plot(x << 4 + 7, 183 - y << 4) + + 'draw monochrome samples + ios.g0_color(3) + repeat x from 5 to 10 + ios.g0_plot(x << 4 + 7, 55) + + esc_key + waitcnt(cnt + clkfreq * 2) + screenset1 +PUB esc_key + + if ios.g0_keystat + ios.g0_reboot + ios.stop + repeat + +PUB screenset1|i,tx,ty + + 'tilescreen setzen + repeat tx from 0 to x_tiles - 1 + repeat ty from 0 to y_tiles - 1 + screen[ty * x_tiles + tx] := disp_base >> 6 + ty + tx * y_tiles + ((ty & $3F) << 10) + + 'farbtabelle füllen + repeat i from 0 to 63 + colortab[i] := $00001010 * (i<<1+4) & $F + $0D060D02 + + ios.g0_colortab(@colortab) + ios.g0_screen(@screen) + +PUB screenset2|x, y, i, c + + 'init colors + repeat i from $00 to $0F + case i + 5..10 : c := $01000000 * (i - 5) + $02020507 + other : c := $07020504 + colortab[i] := c + repeat i from $10 to $1F + colortab[i] := $10100000 * (i & $F) + $0B0A0507 + repeat i from $20 to $2F + colortab[i] := $10100000 * (i & $F) + $0D0C0507 + repeat i from $30 to $3F + colortab[i] := $10100000 * (i & $F) + $080E0507 + + 'init tile screen + repeat x from 0 to x_tiles - 1 + repeat y from 0 to y_tiles - 1 + case y + 0, 2 : i := $30 + x + 3..4 : i := $20 + x + 5..6 : i := $10 + x + 8 : i := x + other: i := 0 + screen[x + y * x_tiles] := i << 10 + disp_base >> 6 + x * y_tiles + y + + ios.g0_colortab(@colortab) + ios.g0_screen(@screen) + + +PUB ademo1 | x,y,i,j,k,kk,dx,dy,pp,pq,rr,numx,numchr + + x := XMAX/2 + y := YMAX/2 + dx := 1 + dy := 1 + k := 0 + + ios.g0_dynamic + + repeat 500 + + 'clear bitmap + ios.g0_clear + + 'draw spinning triangles + ios.g0_colorwidth(1,0) + repeat i from 1 to 16 + ios.g0_vec(XMAX/2 + k & $FF, YMAX/2, s_obj-i*60, k << 6 + i << 8, @triangle - @grdat) + + 'draw expanding pixel halo + ios.g0_colorwidth(1,k) + ios.g0_arc(XMAX/2, YMAX/2,80,30,-k<<5,$2000/9,10,0) + + 'draw boing-star + ios.g0_colorwidth(1, 1) + repeat j from 0 to 5 + ios.g0_vec(x+j*2, y+j*5, s_obj-j*40, cnt>>rotvar,@star - @grdat) + + 'kollisionsabfrage + if (x + dx - r_obj) < 0 + dx := dx * -1 + else + if (x + dx + r_obj + 5) > XMAX + dx := dx * -1 + if (y + dy - r_obj) < 0 + dy := dy * -1 + else + if (y + dy + r_obj + 5) > YMAX + dy := dy * -1 + + x += dx + y += dy + + + 'draw spinning stars and revolving crosshairs and dogs + ios.g0_colorwidth(2,0) + repeat i from 0 to 7 + ios.g0_vecarc(40,50,30,30,-(i<<10+k<<6),$40,-(k<<7),@star - @grdat) + ios.g0_pixarc(190,140,30,30,i<<10+k<<6,0,@monkey1 - @grdat) + ios.g0_pixarc(190,140,20,20,-(i<<10+k<<6),0,@monkey1 - @grdat) + + 'draw text + ios.g0_textmode(5,5,6,0) + ios.g0_colorwidth(1,8) + ios.g0_text(5,120,@string1 - @grdat) + + 'draw text + 'ios.g0_colorwidth(2,0) + 'ios.g0_textmode(5,5,6,0) + 'ios.g0_text(150,5,@string1 - @grdat) + + 'draw counter + ios.g0_colorwidth(2,16-k&$f) + ios.g0_textmode(3,3,6,0) + ios.g0_printdec(160,10,k,4,@strstart,@strstart - @grdat) + + 'copy bitmap to display + ios.g0_copy + + 'increment counter that makes everything change + k++ + esc_key + + ios.g0_static + +PUB ademo2 | i,k,x,y,dx,dy,rad + + x := XMAX/2 + y := YMAX/2 + dx := 6 + dy := 6 + rad := 8 + k := 0 + + ios.g0_dynamic + + repeat 500 + + 'clear bitmap + ios.g0_clear + + 'draw spinning triangles + ios.g0_colorwidth(1,0) + repeat i from 1 to 8 + ios.g0_vec(k & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 64 & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 128 & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 192 & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + repeat i from 1 to 8 + ios.g0_vec(k + 32 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 96 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 160 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 224 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + repeat i from 1 to 8 + ios.g0_vec(k & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 64 & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 128 & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + ios.g0_vec(k + 192 & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat) + + ios.g0_colorwidth(2,15) + ios.g0_plot(x,y) + + 'kollisionsabfrage + if (x + dx - rad) < 0 + dx := dx * -1 + ios.sfx_fire($f1,0) + else + if (x + dx + rad + 5) > XMAX + dx := dx * -1 + ios.sfx_fire($f1,0) + if (y + dy - rad) < 0 + dy := dy * -1 + ios.sfx_fire($f1,0) + else + if (y + dy + rad + 5) > YMAX + dy := dy * -1 + ios.sfx_fire($f1,0) + + x += dx + y += dy + + 'copy bitmap to display + ios.g0_copy + + 'increment counter that makes everything change + k++ + esc_key + + ios.g0_static + + +DAT 'heap-daten + +grdat + +strstart 'stringpuffer für zahlenausgabe +byte "00000000",0 '8 digits +byte 0 'wichtig: auf wortgrenze auffüllen! +strend + +star +byte word $4000+$2000/12*0 'star +byte word 50 +byte word $8000+$2000/12*1 +byte word 20 +byte word $8000+$2000/12*2 +byte word 50 +byte word $8000+$2000/12*3 +byte word 20 +byte word $8000+$2000/12*4 +byte word 50 +byte word $8000+$2000/12*5 +byte word 20 +byte word $8000+$2000/12*6 +byte word 50 +byte word $8000+$2000/12*7 +byte word 20 +byte word $8000+$2000/12*8 +byte word 50 +byte word $8000+$2000/12*9 +byte word 20 +byte word $8000+$2000/12*10 +byte word 50 +byte word $8000+$2000/12*11 +byte word 20 +byte word $8000+$2000/12*0 +byte word 50 +byte word 0 + +triangle +byte word $4000+$2000/3*0 'triangle +byte word 50 +byte word $8000+$2000/3*1+1 +byte word 50 +byte word $8000+$2000/3*2-1 +byte word 50 +byte word $8000+$2000/3*0 +byte word 50 +byte word 0 + +rombus +byte word $4000+$2000/4*0 'rombus +byte word 50 +byte word $8000+$2000/4*1 +byte word 30 +byte word $8000+$2000/4*2 +byte word 50 +byte word $8000+$2000/4*3 +byte word 30 +byte word $8000+$2000/4*0 +byte word 50 +byte word 0 + +oldbit1 +byte 3,24,12,12 +byte word %%00000000 +byte word %%00000000 +byte word %%00000000 +byte word %%00000000 +byte word %%00000000 +byte word %%00000000 +byte word %%12121212 +byte word %%12121212 +byte word %%12222212 +byte word %%12121212 +byte word %%12121212 +byte word %%12222212 +byte word %%12121212 +byte word %%12121212 +byte word %%12222212 +byte word %%00000000 +byte word %%00000000 +byte word %%00000000 +byte word %%00110000 +byte word %%00000111 +byte word %%11110000 +byte word %%00110000 +byte word %%00111001 +byte word %%12330000 +byte word %%00110001 +byte word %%11113300 +byte word %%11120000 +byte word %%00100011 +byte word %%11111230 +byte word %%11110000 +byte word %%00100011 +byte word %%11111120 +byte word %%00010000 +byte word %%00100011 +byte word %%11111110 +byte word %%13000000 +byte word %%00100011 +byte word %%11001110 +byte word %%11013233 +byte word %%00100011 +byte word %%00110110 +byte word %%11011111 +byte word %%00100011 +byte word %%00230110 +byte word %%11000000 +byte word %%00100011 +byte word %%00110110 +byte word %%00010000 +byte word %%00100011 +byte word %%10000110 +byte word %%11110000 +byte word %%00110001 +byte word %%11111100 +byte word %%11110000 +byte word %%00110000 +byte word %%00111001 +byte word %%11110000 +byte word %%00110000 +byte word %%00000011 +byte word %%11110000 +byte word %%00000000 +byte word %%00000000 +byte word %%00000000 +byte word %%12121212 +byte word %%12121212 +byte word %%22121212 +byte word %%12121212 +byte word %%12121212 +byte word %%22121212 +byte word %%12121212 +byte word %%12121212 +byte word %%22121212 + +monkey1 +'byte 2,11,3,3 +'word %%00011111,%%00000000 +'word %%00321112,%%23000000 +'word %%00322112,%%21110000 +'word %%02222211,%%11111000 +'word %%03222111,%%11111100 +'word %%00000111,%%11111110 +'word %%00000111,%%11111110 +'word %%00000111,%%11111110 +'word %%00000111,%%11111110 +'word %%00002120,%%01111200 +'word %%00001220,%%22222100 + +byte 2,11,3,3 +byte word %%00011111 +byte word %%00000000 +byte word %%00321112 +byte word %%23000000 +byte word %%00322112 +byte word %%21110000 +byte word %%02222211 +byte word %%11111000 +byte word %%03222111 +byte word %%11111100 +byte word %%00000111 +byte word %%11111110 +byte word %%00000111 +byte word %%11111110 +byte word %%00000111 +byte word %%11111110 +byte word %%00000111 +byte word %%11111110 +byte word %%00002120 +byte word %%01111200 +byte word %%00001220 +byte word %%22222100 + +monkey2 +'byte 2,11,3,3 +'word %%00011111,%%00000000 +'word %%00321112,%%23000000 +'word %%00322112,%%21110000 +'word %%02222211,%%11111000 +'word %%03222111,%%11111100 +'word %%00000111,%%11111110 +'word %%00000111,%%11111110 +'word %%00000111,%%11111110 +'word %%00001110,%%11111110 +'word %%00021200,%%01111200 +'word %%00122000,%%00222220 + +byte 2,11,3,3 +byte word %%00011111 +byte word %%00000000 +byte word %%00321112 +byte word %%23000000 +byte word %%00322112 +byte word %%21110000 +byte word %%02222211 +byte word %%11111000 +byte word %%03222111 +byte word %%11111100 +byte word %%00000111 +byte word %%11111110 +byte word %%00000111 +byte word %%11111110 +byte word %%00000111 +byte word %%11111110 +byte word %%00001110 +byte word %%11111110 +byte word %%00021200 +byte word %%01111200 +byte word %%00122000 +byte word %%00222220 + +string1 +byte "HIVE",0 + +string2 +byte "abcdefghijklmnopqrstuvwxyz 0123456789",0 + +string3 +byte "heap-len : ",0 + +string4 +byte "heap-use : ",0 + +grdatend + + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/hplay.spin b/system/regnatix/hplay.spin new file mode 100644 index 0000000..3682b32 --- /dev/null +++ b/system/regnatix/hplay.spin @@ -0,0 +1,418 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : HSS-Player +Chip : Regnatix +Typ : Programm +Version : 00 +Subversion : 02 + +Funktion : HSS-Player für die Kommandozeile + +Logbuch : + +08-04-2010-dr235 - fork aus regime + - anpassung an trios +16-04-2010-dr235 - umwandlung in reine kommandozeilenanwendung + +Kommandoliste : + +/? : hilfetext +/p name.wav : hss-datei abspielen +/d : verzeichnis abspielen +/s : wiedergabe stoppen +/t : anzeige trackerliste +/r : anzeige engine-register +/i : anzeige interface-register + + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OS_TIBLEN = 64 'größe des inputbuffers +ERAM = 1024 * 512 * 2 'größe eram +HRAM = 1024 * 32 'größe hram + +RMON_ZEILEN = 16 'speichermonitor - angezeigte zeilen +RMON_BYTES = 8 'speichermonitor - zeichen pro byte + +VAR + + long datcnt 'zeiger für dateiliste + byte fn[12] 'puffer für dateinamen + byte parastr[64] 'parameterstring + byte fl_bye + byte fl_next + +DAT 'PARAMETER + +PUB main + + ios.start 'ios initialisieren + ios.parastart 'parameterübergabe starten + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: man hplay")) '/? - hilfetext + "p": play_hss '/p - hss-datei wiedergeben + "d": play_dir '/d - verzeichnis wiedergeben + "t": disp_tracker '/t - anzeige tracker + "r": disp_reg '/r - anzeige register + "i": disp_ireg '/i - anzeige interfaceregister + "s": ios.hss_stop '/s - wiedergabe stoppen + ios.stop + + +DAT 'PLAY_FILE + +PUB play_hss 'hss: player starten + + if ios.paranext(@parastr) 'parameter? + ios.hss_playfile(@parastr) + else 'kein parameter: fehlermeldung + printErr(@err1) + +DAT 'PLAY_DIR + +PUB play_dir | stradr,len,fcnt,i 'hss: alle songs auf der sd-card abspielen + + ios.sddir 'kommando: verzeichnis öffnen + hss_startlist 'zum listenanfang + fcnt := 0 'zähler für dateianzahl + fl_bye := fl_next := 0 + repeat while (stradr := ios.sdnext) 'dateiliste einlesen +' ios.print(stradr) + if str_find(stradr,@ext1) +' ios.printchar("◀") + fcnt++ + hss_wrfn(stradr) +' ios.printnl + ios.print(string("Anzahl Dateien : ")) + ios.printdec(fcnt) + ios.printnl + hss_startlist 'zum listenanfang + if fcnt + repeat i from 0 to fcnt-1 'dateiliste abspielen + ios.printdec(i+1) + ios.printchar("/") + ios.printdec(fcnt) + ios.printchar(" ") + hss_rdfn(@fn) + hss_playsong(@fn) + if fl_bye + quit + if fl_next + fl_next := 0 + else + hss_fadeout + ios.hss_stop + +PUB hss_playsong(stradr) | n,q,key 'hss: spielt die musikdatei bis zum ende + + ios.curoff + ios.print(string("PlaySong : ")) + ios.print(stradr) + ios.printnl + ios.hss_stop + ios.hss_playfile(stradr) + repeat + n := ios.hss_intreg(ios#iRepeat) 'anzahl der schleifendurchläufe abfragen + q := ios.hss_intreg(ios#iEndFlag) + ios.curpos1 + ios.print(string("iRepeat : ")) + ios.printdec(n) + ios.print(string(" iEndFlag : ")) + ios.printdec(q) + if key := ios.key + case key + "n": fl_next := 1 + quit + "q": fl_bye := 1 + quit + until n == 3 or q == 1 + ios.printnl + ios.curon + +PUB hss_fadeout | i 'hss: song langsam ausblenden + repeat i from 0 to 15 + ios.hss_vol(15 - i) + waitcnt(cnt + 60_000_000) + waitcnt(cnt + 30_000_000) + +PUB hss_wrfn(stradr) | len,i 'hss: kopiert dateinamen in eram + len := strsize(stradr) + repeat i from 0 to len-1 + ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++) + ios.ram_wrbyte(ios#usrmod,0,datcnt++) + + +PUB hss_rdfn(stradr) | i,n 'hss: liest dateinamen aus eram + i := 0 + repeat + n := ios.ram_rdbyte(ios#usrmod,datcnt++) + byte[stradr][i++] := n + while n <> 0 + +PUB hss_startlist 'hss: zeiger auf listenanfang (dateinamen) + datcnt := 0 + + +DAT 'DISPLAY + +PUB disp_tracker | i,n 'disp: trackerliste ausgeben + repeat + repeat + until ios.hss_intreg(ios#iRowFlag) == 0 + repeat + until ios.hss_intreg(ios#iRowFlag) == 1 'synchronisation bis zeile fertig bearbeitet + + ios.printhex(ios.hss_intreg(ios#iBeatC),4) + ios.printchar("-") + ios.printhex(ios.hss_intreg(ios#iEngineC),4) + ios.printchar(":") + ios.printchar(" ") + + repeat i from 1 to 4 + + hss_printnote(ios.hss_intreg(i*5+ios#iNote)) 'note + + n := ios.hss_intreg(i*5+ios#iOktave) + if n + ios.printhex(n,1) 'oktave + else + ios.printchar("-") + ios.printchar(" ") + + n := ios.hss_intreg(i*5+ios#iVolume) + if n + ios.printhex(n,1) 'volume + else + ios.printchar("-") + ios.printchar(" ") + + n := ios.hss_intreg(i*5+ios#iEffekt) + if n + ios.printhex(n,1) 'effekt + else + ios.printchar("-") + ios.printchar(" ") + + n := ios.hss_intreg(i*5+ios#iInstrument) + if n + ios.printhex(n,1) 'instrument + else + ios.printchar("-") + ios.printchar(" ") + + + ios.printnl + + until ios.keystat > 0 'taste gedrückt? + ios.key + ios.curon + ios.printnl + +PUB hss_printnote(n) 'disp: notenwert ausgeben +'C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,H1 + + case n + 0: ios.print(string(" ")) + 1: ios.print(string("C ")) + 2: ios.print(string("C#")) + 3: ios.print(string("D ")) + 4: ios.print(string("D#")) + 5: ios.print(string("E ")) + 6: ios.print(string("F ")) + 7: ios.print(string("F#")) + 8: ios.print(string("G ")) + 9: ios.print(string("G#")) + 10: ios.print(string("A ")) + 11: ios.print(string("A#")) + 12: ios.print(string("H ")) + + + +PUB disp_ireg | i,j,n,wert 'disp: anzeige interfaceregister + ios.printcls + repeat + ios.curhome + ios.curoff + ios.printnl + repeat i from 0 to 4 + ios.printhex(i*8,2) + ios.printchar(":") + repeat j from 0 to 4 + n := (i*5)+j + wert := ios.hss_intreg(n) + ios.printhex(wert,4) + ios.printchar(" ") + ios.printnl + until ios.keystat > 0 'taste gedrückt? + ios.key + ios.curon + ios.printnl + +PUB disp_reg | wert,i,j,n 'disp: kontinuierliche anzeige der regsiterwerte +{{ + 8 x 6 register long + + 0 kanal a + 3>>16 f + 4 v + + 8 kanal b + 16 kanal c + 24 kanal d + +}} + ios.printcls + repeat + ios.curhome + ios.curoff + repeat j from 0 to 3 + ios.printnl + ios.printnl + ios.printhex(j*8,2) + ios.printchar(":") + repeat i from 0 to 3 + n := (j*8)+i + wert := ios.hss_peek(n) + ios.printhex(wert,8) + ios.printchar(" ") + ios.printnl + ios.printhex(j*8+4,2) + ios.printchar(":") + repeat i from 4 to 7 + n := (j*8)+i + wert := ios.hss_peek(n) + ios.printhex(wert,8) + ios.printchar(" ") + + ios.printnl + ios.printnl + ios.print(string("Channel A F: ")) + wert := ios.hss_peek(0+3) + ios.printhex(wert>>16,4) + ios.print(string(" V: ")) + wert := ios.hss_peek(0+4) + ios.printhex(wert,2) + + ios.printnl + ios.print(string("Channel B F: ")) + wert := ios.hss_peek(8+3) + ios.printhex(wert>>16,4) + ios.print(string(" V: ")) + wert := ios.hss_peek(8+4) + ios.printhex(wert,2) + + ios.printnl + ios.print(string("Channel C F: ")) + wert := ios.hss_peek(16+3) + ios.printhex(wert>>16,4) + ios.print(string(" V: ")) + wert := ios.hss_peek(16+4) + ios.printhex(wert,2) + + ios.printnl + ios.print(string("Channel D F: ")) + wert := ios.hss_peek(24+3) + ios.printhex(wert>>16,4) + ios.print(string(" V: ")) + wert := ios.hss_peek(24+4) + ios.printhex(wert,2) + + until ios.keystat > 0 'taste gedrückt? + ios.key + ios.curon + ios.printnl + +DAT 'TOOLS + +PRI printErr(stradr) + + ios.print(@err0) + ios.print(stradr) + ios.print(string("help: man hplay")) + +PUB str_find(string1, string2) : buffer | counter 'sys: string suchen + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches a string of characters for the first occurence of the specified string of characters. │ +'' │ │ +'' │ Returns the address of that string of characters if found and zero if not found. │ +'' │ │ +'' │ string1 - A pointer to the string of characters to search. │ +'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(string1--) + + if(byte[++string1] == byte[string2]) + + repeat counter from 0 to (strsize(string2) - 1) + + if(byte[string1][counter] <> byte[string2][counter]) + buffer~~ + + ifnot(buffer~) + return string1 + +PUB str_lower(characters) '' 4 Stack Longs 'sys: in kleine zeichen wandeln + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Demotes all upper case characters in the set of ("A","Z") to their lower case equivalents. │ +'' │ │ +'' │ Characters - A pointer to a string of characters to convert to lowercase. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(characters--) + + result := byte[++characters] + + if((result => "A") and (result =< "Z")) + + byte[characters] := (result + 32) + + +DAT 'strings + +ext1 byte ".HSS",0 + +err0 byte 13,"Fehler : ",0 +err1 byte "Zu wenig Parameter!",13,0 + +DAT 'lizenz +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + diff --git a/system/regnatix/keycode.spin b/system/regnatix/keycode.spin new file mode 100644 index 0000000..da461a0 --- /dev/null +++ b/system/regnatix/keycode.spin @@ -0,0 +1,86 @@ +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : keycode +Chip : Regnatix +Typ : Programm +Version : 00 +Subversion : 01 +Funktion : Kleines Tool um Tastencodes auszugeben +Komponenten : - +COG's : - +Logbuch : + +22-03-2010-dr235 - anpassung trios + +Kommandoliste : + +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +PUB main | key,spec + ios.start + +' code für test im ram, sollte bei bin-datei auskommentiert werden +' ios.startram + + repeat + ios.print(string("[q] keycode : ")) + key := ios.keywait + spec := ios.keyspec + ios.printhex(key,2) + ios.print(@str1) + ios.printdec(key) + ios.printtab + ios.print(@str1) + ios.printtab + ios.printqchar(key) + ios.print(@str1) + ios.printhex(spec,2) + ios.printnl + until key == "q" + + ios.stop + +DAT + +str1 byte " : ",0 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/m.spin b/system/regnatix/m.spin new file mode 100644 index 0000000..141139b --- /dev/null +++ b/system/regnatix/m.spin @@ -0,0 +1,320 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : mental-Loader für TriOS +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + mgc: "m-glob-con" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +VAR + + long plen 'länge datenblock loader + byte proghdr[16] 'puffer für objektkopf + byte debug + +pub main | err,sys + + debug := 0 + err := 0 + sys := 0 + ios.start + ios.sddmact(ios#DM_ROOT) + ios.print(string(13,"Wir sind Borg. Widerstand ist zwecklos.",13)) + ios.print(string("Assimilation wird gestartet...",13,13)) + err |= need_file(string("Check ADM-Code : "),string("adm")) + err |= need_file(string("Check BEL-Code : "),string("bel")) + err |= need_file(string("Check REG-Code : "),string("reg")) + sys := need_file(string("Check USR-Tape : "),string("usr")) + sys := need_file(string("Check SYS-Tape : "),string("sys")) + pause(3) + ifnot err + if sys + ios.print(string(13,"SYS-Tape nicht vorhanden, mental wird dennoch gestartet!",13)) + timer(10) + mload + else + ios.print(string(13,"Abbruch: System nicht korrekt installiert!",13)) + ios.stop + +pri timer(sec) + + ios.curoff + ios.printnl + repeat sec + ios.curpos1 + ios.print(string("Weiter in ")) + ios.printdec(sec--) + ios.print(string(" Sekunden ")) + waitcnt(cnt+clkfreq) + ios.curon + +pri pause(sec) + + if debug + waitcnt(cnt+clkfreq*sec) + +pri mload | i + + '---------------------------------------------------------- slavecode starten + ios.print(string(13,"System wird nun gestartet...",13)) + pause(2) + + ios.belload(string("bel")) + ios.print(string(" BEL-Code wurde gestartet: ok",13)) + ios.sdclose + pause(2) + + ios.print(string(" ADM-Code wird gestartet: ")) + ios.admload(string("adm")) + ios.print(string(" ok")) + + pause(2) + ios.printnl + ios.print(string(" REG-Code wird gestartet: ")) + + '---------------------------------------------------------- m-core starten + m_sdopen("r",string("reg")) 'datei öffnen + repeat i from 0 to 15 '16 bytes header --> bellatrix + byte[@proghdr][i] := m_sdgetc + m_sdclose + + plen := 0 + plen := byte[@proghdr + $0B] << 8 + plen := plen + byte[@proghdr + $0A] + plen := plen - 8 'korrekte dateilänge berechnen + + m_sdopen("r",string("reg")) 'datei öffnen + ios.bus_putchar1(mgc#adm_sd_getblk) 'adm:sd_getblk + ios.bus_putlong1(plen) 'blocklänge senden + + dira := 0 'diese cog vom bus trennen + repeat i from 0 to 7 'alle anderen cogs stoppen + if i <> cogid + cogstop(i) + cognew(@loader, plen) 'pasm-loader übernimmt + cogstop(cogid) 'spin-loader beenden + + +dat org 0 + +loader + mov outa, _S1 'bus inaktiv + mov dira, DINP 'bus auf eingabe schalten + mov reg_cnt, PAR 'parameter = plen + mov reg_adr, #0 'adresse ab 0 + + ' datenblock empfangen +loop + call #m_aget 'wert einlesen + wrbyte reg_a, reg_adr 'wert --> hubram + + add reg_adr, #1 'adresse + 1 + djnz reg_cnt, #loop + + mov dira, #0 + + ' neuen code starten + + rdword reg_a, #$A ' Setup the stack markers. + sub reg_a, #4 ' + wrlong SMARK, reg_a ' + sub reg_a, #4 ' + wrlong SMARK, reg_a ' + + rdbyte reg_a, #$4 ' Switch to new clock mode. + clkset reg_a ' + + coginit SINT ' Restart running new code. + + + cogid reg_a + cogstop reg_a 'cog hält sich selbst an + +' --------------------------------------------------------------------- +' businterface +' --------------------------------------------------------------------- + +' reg_a io-zeichen +' reg_b temp +' reg_c temp + +m_aput ' zeichen zu administra senden + waitpeq _hs,_hs ' warte auf hs=1 (slave bereit) + and reg_a,#$ff ' wert maskieren + or reg_a,_a1 ' + bel=0 wr=0 clk=0 + mov outa,reg_a ' daten + signale ausgeben + mov dira,dout ' bus auf ausgabe schalten + or outa,_a2 ' clk=0 --> clk=1 + waitpeq _zero,_hs ' warte auf hs=0 + mov dira,dinp ' bus auf eingabe schalten + mov outa,_s1 ' bussignale inaktiv +m_aput_ret ret + +m_bput ' zeichen zu bellatrix senden + waitpeq _hs,_hs ' warte auf hs=1 (slave bereit) + and reg_a,#$ff ' wert maskieren + or reg_a,_b1 ' + bel=0 wr=0 clk=0 + mov outa,reg_a ' daten + signale ausgeben + mov dira,dout ' bus auf ausgabe schalten + or outa,_b2 ' clk=0 --> clk=1 + waitpeq _zero,_hs ' warte auf hs=0 + mov dira,dinp ' bus auf eingabe schalten + mov outa,_s1 ' bussignale inaktiv +m_bput_ret ret + +m_aget ' zeichen von administra empfangen + waitpeq _hs,_hs ' warte auf hs=1 (slave bereit) + mov outa,_a3 ' bel=0 wr=1 clk=1 + waitpeq _zero,_hs ' warte auf hs=0 + mov reg_a,ina ' daten einlesen + and reg_a,#$ff ' wert maskieren + mov outa,_s1 ' bussignale inaktiv +m_aget_ret ret + +m_bget ' zeichen von belatrix empfangen + waitpeq _hs,_hs ' warte auf hs=1 (slave bereit) + mov outa,_b3 ' bel=0 wr=1 clk=1 + waitpeq _zero,_hs ' warte auf hs=0 + mov reg_a,ina ' daten einlesen + and reg_a,#$ff ' wert maskieren + mov outa,_s1 ' bussignale inaktiv +m_bget_ret ret + + + + +' +------------------------------- /hs +' |+------------------------------ /wr +' ||+----------------------------- busclk +' |||+---------------------------- hbeat +' |||| +-------------------------- al +' |||| |+------------------------- /bel +' |||| ||+------------------------ /adm +' |||| |||+----------------------- /ram2 +' |||| ||||+---------------------- /ram1 +' |||| ||||| +---------- a0..10 +' |||| ||||| | +' |||| ||||| | +- d0..7 +' |||| |||||+----------+ +------+ +_al long %00000000_10000000_00000000_00000000 ' /al bitmaske +_bwr long %00000100_00000000_00000000_00000000 ' /wr bitmaske +_ram1 long %00000000_00001000_00000000_00000000 ' /ram1 bitmaske +_latch long %00000000_00000000_11111111_00000000 ' latch bitmaske +_adr long %00000000_00000111_11111111_00000000 ' adrbus bistmaske + +dinp long %00000111_11111111_11111111_00000000 ' bus input +dout long %00000111_11111111_11111111_11111111 ' bus output +_s1 long %00000100_01111000_00000000_00000000 ' bus inaktiv +_b1 long %00000000_00111000_00000000_00000000 ' adm=1, bel=0, wr=0, busclk=0 +_b2 long %00000010_00111000_00000000_00000000 ' adm=1, bel=0, wr=0, busclk=1 +_b3 long %00000110_00111000_00000000_00000000 ' adm=1, bel=0, wr=1, busclk=1 +_a1 long %00000000_01011000_00000000_00000000 ' adm=0, bel=1, wr=0, busclk=0 +_a2 long %00000010_01011000_00000000_00000000 ' adm=0, bel=1, wr=0, busclk=1 +_a3 long %00000110_01011000_00000000_00000000 ' adm=0, bel=1, wr=1, busclk=1 +_hs long %00001000_00000000_00000000_00000000 ' hs=1? +_zero long %00000000_00000000_00000000_00000000 ' + +SINT long ($0001 << 18) | ($3C01 << 4) ' Spin interpreter boot information. +SMARK long $FFF9FFFF ' Stack mark used for spin code. + +reg_adr res 1 +reg_cnt res 1 +reg_a res 1 +reg_b res 1 +reg_c res 1 + +pri need_file(strptr1,strptr2): err + + ios.print(strptr1) + ios.printtab + ios.printtab + err := ios.sdopen("R",strptr2) + ios.sdclose + ifnot err + ios.print(string("ok")) + else + ios.setcolor(1) + ios.print(string("fail")) + ios.setcolor(0) + ios.printnl + +pri m_sdopen(modus,stradr):err | len,i 'sd-card: datei öffnen +''funktionsgruppe : sdcard +''funktion : eine bestehende datei öffnen +''busprotokoll : [004][put.modus][sub_putstr.fn][get.error] +'' : modus - "A" Append, "W" Write, "R" Read (Großbuchstaben!) +'' : fn - name der datei +'' : error - fehlernummer entspr. list + + ios.bus_putchar1(mgc#adm_sd_open) + ios.bus_putchar1(modus) + len := strsize(stradr) + ios.bus_putchar1(len) + repeat i from 0 to len - 1 + ios.bus_putchar1(byte[stradr++]) + err := ios.bus_getchar1 + +pri m_sdclose:err 'sd-card: datei schließen +''funktionsgruppe : sdcard +''funktion : die aktuell geöffnete datei schließen +''busprotokoll : [005][get.error] +'' : error - fehlernummer entspr. list + + ios.bus_putchar1(mgc#adm_sd_close) + err := ios.bus_getchar1 + +pri m_sdgetc: char 'sd-card: zeichen aus datei lesen +''funktionsgruppe : sdcard +''funktion : zeichen aus datei lesen +''busprotokoll : [006][get.char] +'' : char - gelesenes zeichen + + ios.bus_putchar1(mgc#adm_sd_getc) + char := ios.bus_getchar1 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/man.spin b/system/regnatix/man.spin new file mode 100644 index 0000000..782dab6 --- /dev/null +++ b/system/regnatix/man.spin @@ -0,0 +1,138 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Hallo Hive! +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + str: "glob-string" + +VAR + + byte parastr[64] + byte rows 'aktuelle anzahl der nutzbaren zeilen + byte cols 'aktuelle Anzahl der nutzbaren spalten + byte vidmod 'videomodus: 0 - vga, 1 - tv + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +PUB main | i,n,len + + n := 1 + ios.start + ios.parastart + ios.paranext(@parastr) + vidmod := ios.belgetspec & 1 + rows := ios.belgetrows 'zeilenzahl bei bella abfragen + cols := ios.belgetcols 'spaltenzahl bei bella abfragen + len := strsize(@parastr) + ios.sddmset(ios#DM_USER) 'u-marker setzen + ios.sddmact(ios#DM_SYSTEM) 's-marker aktivieren + repeat i from 0 to 3 'extender anhängen + byte[@parastr][len + i] := byte[@ext1][i] + byte[@parastr][len + i] := 0 + ifnot ios.sdopen("r",@parastr) + repeat 'text ausgeben + if ios.printchar(ios.sdgetc) == ios#CHAR_NL 'zeilenzahl zählen und stop + if ++n == (rows - 2) + n := 1 + if ios.keywait == "q" + ios.sdclose + ios.sddmact(ios#DM_USER) 'u-marker aktivieren + ios.stop + until ios.sdeof 'ausgabe bis eof + else + 'ios.print(string("Hilfetexte : ",$0d)) + cmd_dir_w(1) + ios.sdclose 'datei schließen + ios.sddmact(ios#DM_USER) 'u-marker aktivieren + ios.stop + +PRI cmd_dir_w(hflag):fcnt|stradr,lcnt,wcnt,len,i,j + + fcnt := 0 + wcnt := (cols / 9) - 1 '3 + lcnt := (rows - 2) * (cols / 15) + ios.printnl + repeat while (stradr := ios.sdnext) + len := strsize(stradr) + + i := j := 0 + repeat until byte[stradr + i] == "." 'extender finden + i++ + repeat until byte[stradr + i + j] == " " 'endesuchen/terminieren + j++ + byte[stradr + i + j] := 0 +{ + ios.print(stradr) + ios.print(stradr+i) + ios.print(@ext1) + ios.printdec(i) + ios.printdec(strcomp(@ext1,(stradr+i))) + ios.printnl +} + if strcomp(@ext1,(stradr+i)) + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + byte[stradr + i] := 0 'extender abtrennen + ios.print(stradr) + ifnot wcnt-- + wcnt := (cols / 15) - 1 '3 + ios.printnl + else + 'ios.printtab + fcnt++ + ifnot --lcnt + lcnt := (rows - 2) * (cols / 15) + if ios.keywait == "q" + return + + +DAT + +ext1 byte ".MAN",0 + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/ramtest.spin b/system/regnatix/ramtest.spin new file mode 100644 index 0000000..49a4605 --- /dev/null +++ b/system/regnatix/ramtest.spin @@ -0,0 +1,362 @@ +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : ramtest +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : Testroutinen für die externen RAM-Bänke +Komponenten : +COG's : +Logbuch : +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +VAR + +word cnt_err 'gesamtzähler +word cnt_test1 +word cnt_test2 +word cnt_test3 +word cnt_testx +word cnt_loop + + + +PUB main | tast + + ios.start + 'ios.startram 'nur für test im ram + ios.print(string("RAMTest - 10-06-2010-dr235")) + ios.printnl + ios.print(string("ACHTUNG: Endlostest - Alle Daten im eRam werden komplett überschrieben!")) + ios.printnl + ios.print(string("Eingabe */bbruch : ")) + tast := ios.keywait + repeat + if tast <> "a" + statistik + ramtest1 '1:1 random + statistik + ramtestx(0) '1:1, 0 + statistik + ramtestx($FF) '1:1, 255 + statistik + ramtestx($55) '1:1, $55 + statistik + ramtestx($AA) '1:1, $AA + statistik + ramtest2 'test adresskontinuität + statistik + ramtest3 '1:1 negierte bänke + statistik + +' ios.printnl +' ios.print(string("Fertig. ")) +' ios.stop + +PUB statistik 'ausgabe der fehlerstatistik + + cnt_err := cnt_err + cnt_test1 + cnt_test2 + cnt_test3 + cnt_testx + ios.setcolor(4) + ios.printcls + ios.printnl + ios.print(string("Statistik eRAM-Test:", $0d, $0d)) + ios.print(string("Testdurchläufe : ")) + ios.printdec(cnt_loop) + ios.printnl + ios.print(string("Fehler Gesamt : ")) + ios.printdec(cnt_err) + ios.printnl + ios.print(string("Fehler Test 1:1, Random : ")) + ios.printdec(cnt_test1) + ios.printnl + ios.print(string("Fehler Test Adresskontinuität : ")) + ios.printdec(cnt_test2) + ios.printnl + ios.print(string("Fehler Test 1:1, Negierte Bänke : ")) + ios.printdec(cnt_test3) + ios.printnl + ios.print(string("Fehler Test Div. Testmuster : ")) + ios.printdec(cnt_testx) + ios.printnl + ios.printnl + ios.print(string("Aktueller Test:", $0d)) + ios.printnl + ios.printnl + cnt_test1 := 0 + cnt_test2 := 0 + cnt_test3 := 0 + cnt_testx := 0 + cnt_loop++ + ios.setcolor(0) + +PUB ramtest1 | adr,wert1,a +{{ramtest2 - zufallswerte werden gleichzeitig in beide rambänke geschrieben und im zweiten +schritt miteinander verglichen}} + ios.print(string("RAMTest - 1:1 Random",$0D)) + ios.print(string("Speicher beschreiben...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat ios#ERAM/2-1 + wert1? + ram_write1(wert1,adr) + ram_write2(wert1,adr) + if a++ == (ios#ERAM/2-1)/16 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + adr++ + ios.print(string("ok",$0d,"Speicher vergleichen...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat ios#ERAM/2-1 + if ram_read1(adr) <> ram_read2(adr) + ios.setcolor(3) + ios.printchar($0d) + ios.print(string("Ramfehler : ")) + ios.printhex(adr,6) + ios.printchar(":") + ios.printhex(ram_read1(adr),2) + ios.printchar(":") + ios.printhex(ram_read2(adr),2) + ios.printchar(" ") + ios.sfx_fire($f3,0) + cnt_test1++ + ios.setcolor(0) + if a++ == (ios#ERAM/2-1)/16 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + adr++ + ios.print(string("ok",$0d)) + +PUB ramtest2 | adr,wert1,a +{{ramtest2 - adresswert wird long in den speicher geschrieben und verglichen}} + ios.print(string("RAMTest - Test Adresskontinuität",$0D)) + ios.print(string("Speicher beschreiben...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat (ios#ERAM)/4 + ios.ram_wrlong(ios#sysmod,adr,adr) + if a == ios#ERAM/64 + a := 1 + ios.printhex(adr,6) + ios.printchar("-") + else + a++ + adr := adr + 4 + ios.print(string("ok",$0d,"Speicher vergleichen...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat (ios#ERAM)/4 + if ios.ram_rdlong(ios#sysmod,adr) <> adr + ios.setcolor(3) + ios.printchar($0d) + ios.print(string("Ramfehler : ")) + ios.printhex(adr,8) + ios.printchar(":") + ios.printhex(ios.ram_rdlong(ios#sysmod,adr),8) + ios.printchar(" ") + ios.sfx_fire($f3,0) + cnt_test2++ + ios.setcolor(0) + if a == ios#ERAM/64 + a := 1 + ios.printhex(adr,6) + ios.printchar("-") + else + a++ + adr := adr + 4 + ios.print(string("ok",$0d)) + + +PUB ramtest3 | adr,wert1,wert2,a +{{ramtest3 - }} + ios.print(string("RAMTest - Random/Negierte Bänke",$0D)) + ios.print(string("Speicher beschreiben...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat ios#ERAM/2-1 + wert1? + wert2 := !wert1 + ram_write1(wert1,adr) + ram_write2(wert2,adr) + if a++ == (ios#ERAM/2-1)/16 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + adr++ + ios.print(string("ok",$0d,"Speicher vergleichen...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat ios#ERAM/2-1 + wert1 := ram_read1(adr) + wert2 := !ram_read2(adr) & $0ff + if wert1 <> wert2 + ios.setcolor(3) + ios.printchar($0d) + ios.print(string("Ramfehler : ")) + ios.printhex(adr,6) + ios.printchar(":") + ios.printhex(wert1,2) + ios.printchar(":") + ios.printhex(wert2,2) + ios.printchar(" ") + ios.sfx_fire($f3,0) + cnt_test3++ + ios.setcolor(0) + if a++ == (ios#ERAM/2-1)/16 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + adr++ + ios.print(string("ok",$0d)) + +PUB ramtestx(wert) | adr,a +{{ramtest2 - zufallswerte werden gleichzeitig in beide ramb?nke geschrieben und im zweiten +schritt miteinander verglichen}} + ios.print(string("RAMTest - 1:1 Testwert: $")) + ios.printhex(wert,2) + ios.printnl + ios.print(string("Speicher beschreiben...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat ios#ERAM/2-1 + ram_write1(wert,adr) + ram_write2(wert,adr) + if a++ == (ios#ERAM/2-1)/16 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + adr++ + ios.print(string("ok",$0d,"Speicher vergleichen...",$0D)) + adr := 0 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + repeat ios#ERAM/2-1 + if ram_read1(adr) <> ram_read2(adr) + ios.setcolor(3) + ios.printchar($0d) + ios.print(string("Ramfehler : ")) + ios.printhex(adr,6) + ios.printchar(":") + ios.printhex(ram_read1(adr),2) + ios.printchar(":") + ios.printhex(ram_read2(adr),2) + ios.printchar(" ") + ios.sfx_fire($f3,0) + cnt_testx++ + ios.setcolor(0) + if a++ == (ios#ERAM/2-1)/16 + a := 0 + ios.printhex(adr,6) + ios.printchar("-") + adr++ + ios.print(string("ok",$0d)) + +PUB ram_read1(adresse):wert +{{ein byte aus rambank1 lesen}} + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + set_latch + outa[18..8] := adresse 'niederwertige adresse setzen + outa[ios#reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben) + wert := ina[7..0] 'speicherzelle einlesen + outa[ios#reg_ram1] := 1 'ram1 deselektieren + +PUB ram_read2(adresse):wert +{{ein byte aus rambank2 lesen}} + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + set_latch + outa[18..8] := adresse 'niederwertige adresse setzen + outa[ios#reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben) + wert := ina[7..0] 'speicherzelle einlesen + outa[ios#reg_ram2] := 1 'ram2 deselektieren + +PUB ram_write1(wert,adresse) +{{ein byte in rambank1 schreiben}} + outa[ios#bus_wr] := 0 'schreiben aktivieren + dira := ios#db_out 'datenbus --> ausgang + outa[7..0] := wert 'wert --> datenbus + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + set_latch + outa[18..8] := adresse 'niederwertige adresse setzen + outa[ios#reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben) + outa[ios#reg_ram1] := 1 'ram1 deselektieren + dira := ios#db_in 'datenbus --> eingang + outa[ios#bus_wr] := 1 'schreiben deaktivieren + +PUB ram_write2(wert,adresse) +{{ein byte in rambank2 schreiben}} + outa[ios#bus_wr] := 0 'schreiben aktivieren + dira := ios#db_out 'datenbus --> ausgang + outa[7..0] := wert 'wert --> datenbus + outa[15..8] := adresse >> 11 'höherwertige adresse setzen + set_latch + outa[18..8] := adresse 'niederwertige adresse setzen + outa[ios#reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben) + outa[ios#reg_ram2] := 1 'ram2 deselektieren + dira := ios#db_in 'datenbus --> eingang + outa[ios#bus_wr] := 1 'schreiben deaktivieren + +PRI set_latch +{{set_latch - übernimmt a0..a7 in adresslatch (obere adresse a11..18)}} + outa[23] := 1 + outa[23] := 0 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/regime.spin b/system/regnatix/regime.spin new file mode 100644 index 0000000..be7b185 --- /dev/null +++ b/system/regnatix/regime.spin @@ -0,0 +1,1146 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : Regime +Chip : Regnatix +Typ : Programm +Version : 00 +Subversion : 02 + +Funktion : "Regime" ist ein einfacher Kommandozeileninterpreter für das Betriebssystem TriOS. + +help - diese hilfe + - bin/adm/bel-datei wird gestartet +mount - sd-card mounten +unmount - sd-card abmelden +dir - verzeichnis anzeigen +type - anzeige einer textdatei +aload - administra-code laden +bload - bellatrix-treiber laden +rload - regnatix-code laden +del - datei löschen +cls - bildschirm löschen +free - freier speicher auf sd-card +attrib - attribute ändern +cd - verzeichnis wechseln +mkdir - verzeichnis erstellen +rename - datei/verzeichnis umbenennen +format - sd-card formatieren +reboot - hive neu starten +sysinfo - systeminformationen +color <0..7> - farbe wählen +cogs - belegung der cogs anzeigen +dmlist - anzeige der verzeichnis-marker +dm - in das entsprechende marker- + verzeichnis wechseln +dmset - setzt den entsprechenden marker + auf das aktuelle verzeichnis +dmclr - marker löschen +forth - forth starten + +marker: +r - root-verzeichnis +s - system-verzeichnis +u - user-verzeichnis +a/b/c - benutzerdefinierte verzeichnismarker +r, s, u-marker werden vom system automatisch gesetzt und +intern verwendet. + +RAMDISK: + +xload - datei in ram laden +xsave - datei aus ram speichern +xdir - verzeichnis im ram anzeigen +xrename - datei im ram umbenennen +xdel - datei im ram löschen +xtype - text im ram anzeigen + +Logbuch : + +22-03-2010-dr235 - anpassung trios +10-04-2010-dr235 - alternatives dir-marker-system eingefügt +17-04-2010-dr235 - dm-user wird jetzt auch beim start aus dem aktuellen dir gesetzt +30-04-2010-dr235 - mount robuster gestaltet +19-09-2010-dr235 - integration ramdisk + - kommandos: xdir, xdel, xrename, xload, xsave, xtype +20-09-2010-dr235 - blocktransfer für xload/xsave (wesentlich bessere geschwindigkeit!!!) +07.04.2013-dr235 - div. anpassungen für alternative videomodis (tv) + + +}} + +OBJ + ios: "reg-ios" + str: "glob-string" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OS_TIBLEN = 64 'größe des inputbuffers +OS_MLEN = 8 +ERAM = 1024 * 512 * 2 'größe eram +HRAM = 1024 * 32 'größe hram + +RMON_ZEILEN = 16 'speichermonitor - angezeigte zeilen +RMON_BYTES = 8 'speichermonitor - zeichen pro byte + +VGA = 0 +TV = 1 + +VAR +'systemvariablen + byte tib[OS_TIBLEN] 'tastatur-input-buffer + byte cmdstr[OS_TIBLEN] 'kommandostring für interpreter + byte token1[OS_TIBLEN] 'parameterstring 1 für interpreter + byte token2[OS_TIBLEN] 'parameterstring 2 für interpreter + byte tibpos 'aktuelle position im tib + byte rows 'aktuelle anzahl der nutzbaren zeilen + byte cols 'aktuelle Anzahl der nutzbaren spalten + byte cog[8] 'array for free-cog counter + byte act_color 'Speicher für gewählte zeichenfarbe + byte vidmod 'videomodus: 0 - vga, 1 - tv + +PUB main | flag + + flag := ios.start 'ios initialisieren + + if flag == 0 'kaltstart? + ios.screeninit 'systemmeldung + ios.ram_wrbyte(0,1,ios#SIFLAG) 'screeninit-flag setzen + ios.os_error(ios.sdmount) 'sd-card mounten + + if 0 == ios.ram_rdbyte(0,ios#SIFLAG) 'screen neu initialisieren? + ios.screeninit 'systemmeldung + ios.ram_wrbyte(0,1,ios#SIFLAG) + + ios.sddmact(ios#DM_USER) 'wieder in userverzeichnis wechseln + + ios.printnl + ios.print(@prompt1) + repeat + os_testvideo 'neuer videomodus? + os_cmdinput 'kommandoeingabe + os_cmdint 'kommandozeileninterpreter + + +CON ''------------------------------------------------- INTERPRETER + +PRI os_cmdinput | charc 'sys: stringeingabe eine zeile +''funktionsgruppe : sys +''funktion : stringeingabe eine zeile +''eingabe : - +''ausgabe : - +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib + + ios.print(@prompt3) + tibpos := 0 'tibposition auf anfang setzen + repeat until (charc := ios.keywait) == $0D 'tasten einlesen bis return + if (tibpos + 1) < OS_TIBLEN 'zeile noch nicht zu lang? + case charc + ios#CHAR_BS: 'backspace + if tibpos > 0 'noch nicht anfang der zeile erreeicht? + tib[tibpos--] := 0 'ein zeichen aus puffer entfernen + ios.printbs 'backspace an terminal senden + ios#KEY_CURUP: os_tibpop + ios#KEY_CURDOWN: os_tibclear + other: 'zeicheneingabe + tib[tibpos++] := charc 'zeichen speichern + ios.printchar(charc) 'zeichen ausgeben + ios.printnl + tib[tibpos] := 0 'string abschließen + tibpos := charc := 0 'werte rücksetzen + if tib[tibpos] + os_tibpush + +PRI os_tibpush | i + + i := 0 + repeat OS_TIBLEN + 'tib2[i] := tib[i] + ios.ram_wrbyte(0,tib[i],ios#TIB2+i) + i++ + +PRI os_tibpop | i + + i := 0 + os_tibclear + repeat OS_TIBLEN + tib[i] := ios.ram_rdbyte(0,ios#TIB2+i) + i++ + ios.curpos1 + ios.print(@prompt3) + ios.print(@tib) + tibpos := strsize(@tib) + +PRI os_tibclear | i + + i := 0 + ios.curoff + repeat OS_TIBLEN + tib[i] := 0 + i++ + ios.curpos1 + repeat 63 + ios.printchar(" ") + ios.curpos1 + ios.print(@prompt3) + ios.print(@tib) + tibpos := strsize(@tib) + ios.curon + +PRI os_nxtoken1: stradr 'sys: token 1 von tib einlesen +''funktionsgruppe : sys +''funktion : nächsten token im eingabestring suchen und stringzeiger übergeben +''eingabe : - +''ausgabe : stradr - adresse auf einen string mit dem gefundenen token +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib +'' : token - tokenstring + + stradr := os_tokenize(@token1) + +PRI os_nxtoken2: stradr 'sys: token 2 von tib einlesen +''funktionsgruppe : sys +''funktion : nächsten token im eingabestring suchen und stringzeiger übergeben +''eingabe : - +''ausgabe : stradr - adresse auf einen string mit dem gefundenen token +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib +'' : token - tokenstring + + stradr := os_tokenize(@token2) + +PRI os_tokenize(token):stradr | i 'sys: liest nächsten token aus tib + + i := 0 + if tib[tibpos] <> 0 'abbruch bei leerem string + repeat until tib[tibpos] > ios#CHAR_SPACE 'führende leerzeichen ausbenden + tibpos++ + repeat until (tib[tibpos] == ios#CHAR_SPACE) or (tib[tibpos] == 0) 'wiederholen bis leerzeichen oder stringende + byte[token][i] := tib[tibpos] + tibpos++ + i++ + byte[token][i] := 0 + stradr := token + +PRI os_nextpos: tibpos2 'sys: setzt zeiger auf nächste position +''funktionsgruppe : sys +''funktion : tibpos auf nächstes token setzen +''eingabe : - +''ausgabe : tibpos2 - position des nächsten tokens in tib +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib + + if tib[tibpos] <> 0 + repeat until tib[tibpos] > ios#CHAR_SPACE 'führende leerzeichen ausbenden + tibpos++ + return tibpos + +PRI os_cmdint 'sys: kommandointerpreter +''funktionsgruppe : sys +''funktion : kommandointerpreter; zeichenkette ab tibpos wird als kommando interpretiert +'' : tibpos wird auf position hinter token gesetzt +''eingabe : - +''ausgabe : - +''variablen : tib - eingabepuffer zur string +'' : tibpos - aktuelle position im tib + +if tib[tibpos] + repeat 'kommandostring kopieren + cmdstr[tibpos] := tib[tibpos] + tibpos++ + until (tib[tibpos] == ios#CHAR_SPACE) or (tib[tibpos] == 0) 'wiederholen bis leerzeichen oder stringende + cmdstr[tibpos] := 0 'kommandostring abschließen + os_cmdexec(@cmdstr) 'interpreter aufrufen + tibpos := 0 'tastaturpuffer zurücksetzen + tib[0] := 0 + +DAT ''------------------------------------------------- Kommandostrings + +cmd1 byte "help",0 +cmd2 byte "mount",0 +cmd3 byte "dir",0 +cmd4 byte "type",0 +cmd5 byte "rload",0 +cmd6 byte "cls",0 +cmd7 byte "bload",0 +cmd8 byte "del",0 +cmd9 byte "unmount",0 +cmd10 byte "free",0 +cmd11 byte "attrib",0 +cmd12 byte "cd",0 +cmd13 byte "aload",0 +cmd14 byte "mkdir",0 +cmd15 byte "rename",0 +cmd16 byte "format",0 +cmd17 byte "reboot",0 +cmd18 byte "sysinfo",0 +cmd19 byte "color",0 +cmd20 byte "cogs",0 +cmd21 byte "dm",0 +cmd22 byte "dmset",0 +cmd23 byte "dmclr",0 +cmd24 byte "dmlist",0 +cmd25 byte "debug",0 +cmd26 byte "xload",0 +cmd27 byte "xsave",0 +cmd28 byte "xdir",0 +cmd29 byte "xrename",0 +cmd30 byte "xdel",0 +cmd31 byte "xtype",0 +cmd32 byte "forth",0 +cmd33 byte "vga",0 + +PRI os_cmdexec(stradr) 'sys: kommando ausführen +{{os_smdexec - das kommando im übergebenen string wird als kommando interpretiert + stradr: adresse einer stringvariable die ein kommando enthält}} + + +if strcomp(stradr,@cmd14) 'mkdir - verzeichnis erstellen + cmd_mkdir +elseif strcomp(stradr,@cmd15) 'rename - datei/verzeichnis umbenennen + cmd_rename +elseif strcomp(stradr,@cmd16) 'format - sd-card formatieren + cmd_format +elseif strcomp(stradr,@cmd17) 'reboot + cmd_reboot +elseif strcomp(stradr,@cmd18) 'sysinfo + cmd_sysinfo +elseif strcomp(stradr,@cmd19) 'color + cmd_color +elseif strcomp(stradr,@cmd20) 'cogs + cmd_cogs +elseif strcomp(stradr,@cmd21) 'dm + cmd_dm +elseif strcomp(stradr,@cmd22) 'dmset + cmd_dmset +elseif strcomp(stradr,@cmd23) 'dmclr + cmd_dmclr +elseif strcomp(stradr,@cmd24) 'dmlist + cmd_dmlist +elseif strcomp(stradr,@cmd25) 'debug + cmd_debug +elseif strcomp(stradr,@cmd1) 'help + cmd_help +elseif strcomp(stradr,@cmd2) 'mount - sd-card mounten + cmd_mount +elseif strcomp(stradr,@cmd3) 'dir - verzeichnis anzeigen + cmd_dir +elseif strcomp(stradr,@cmd4) 'type - textdatei auf bildschirm ausgeben + cmd_type +elseif strcomp(stradr,@cmd5) 'rload - lade regnatix-code + os_load +elseif strcomp(stradr,@cmd6) 'cls - bildschirm löschen + ios.printcls +elseif strcomp(stradr,@cmd7) 'bload - lade bellatrix-code + cmd_bload +elseif strcomp(stradr,@cmd8) 'del - datei löschen + cmd_del +elseif strcomp(stradr,@cmd9) 'unmount - medium abmelden + cmd_unmount +elseif strcomp(stradr,@cmd10) 'free - anzeige datenträgerbelegung + cmd_free +elseif strcomp(stradr,@cmd11) 'attrib - attribute ändern + cmd_attrib +elseif strcomp(stradr,@cmd12) 'cd - verzeichnis wechseln + cmd_cd +elseif strcomp(stradr,@cmd13) 'aload - lade administra-code + cmd_aload +elseif strcomp(stradr,@cmd26) 'xload + rd_load +elseif strcomp(stradr,@cmd27) 'xsave + rd_save +elseif strcomp(stradr,@cmd28) 'xdir + rd_dir +elseif strcomp(stradr,@cmd29) 'xrename + rd_rename +elseif strcomp(stradr,@cmd30) 'xdel + rd_del +elseif strcomp(stradr,@cmd31) 'xtype + rd_type +elseif strcomp(stradr,@cmd32) 'forth + reboot +elseif strcomp(stradr,@cmd33) 'vga + ios.belreset +elseif os_testbin(stradr) '.bin +elseif os_testadm(stradr) '.adm +elseif os_testbel(stradr) '.bel +else 'kommando nicht gefunden + ios.print(stradr) + ios.print(@msg3) +ios.print(@prompt1) + +{ +PUB os_error(err):error 'sys: fehlerausgabe + + if err + ios.printnl + ios.print(@err_s1) + ios.printdec(err) + ios.print(string(" : $")) + ios.printhex(err,2) + ios.printnl + ios.print(@err_s2) + case err + 0: ios.print(@err0) + 1: ios.print(@err1) + 2: ios.print(@err2) + 3: ios.print(@err3) + 4: ios.print(@err4) + 5: ios.print(@err5) + 6: ios.print(@err6) + 7: ios.print(@err7) + 8: ios.print(@err8) + 9: ios.print(@err9) + 10: ios.print(@err10) + 11: ios.print(@err11) + 12: ios.print(@err12) + 13: ios.print(@err13) + 14: ios.print(@err14) + 15: ios.print(@err15) + 16: ios.print(@err16) + 17: ios.print(@err17) + 18: ios.print(@err18) + 19: ios.print(@err19) + 20: ios.print(@err20) + OTHER: ios.print(@errx) + ios.printnl + error := err +} +PRI os_load | len,i,stradr1,stradr2 'sys: startet bin-datei über loader +{{ldbin - startet bin-datei über loader}} + ios.paraset(@tib + os_nextpos) 'parameterstring kopieren + ios.ldbin(os_nxtoken1) + +PRI os_testbin(stradr): flag | status,i,len 'sys: testet ob das kommando als bin-datei vorliegt +{{testbin(stradr): flag - testet ob das kommando als bin-datei vorliegt + - string bei stradr wird um .bin erweitert + - flag = TRUE - kommando gefunden}} + + flag := FALSE + len := strsize(stradr) + repeat i from 0 to 3 '.bin anhängen + byte[stradr][len + i] := byte[@ext1][i] + byte[stradr][len + i] := 0 + +' im aktuellen dir suchen + ios.sddmset(ios#DM_USER) 'u-marker setzen + status := ios.sdopen("r",stradr) 'datei vorhanden? + if status == 0 'datei gefunden + flag := TRUE + ios.paraset(@tib + os_nextpos) 'parameterstring kopieren + ios.ldbin(stradr) 'anwendung starten + ios.sdclose + +'im system-dir suchen + ios.sddmset(ios#DM_USER) 'u-marker setzen + ios.sddmact(ios#DM_SYSTEM) 's-marker aktivieren + status := ios.sdopen("r",stradr) 'datei vorhanden? + if status == 0 'datei gefunden + flag := TRUE + ios.paraset(@tib + os_nextpos) 'parameterstring kopieren + ios.ldbin(stradr) 'anwendung starten + ios.sdclose + ios.sddmact(ios#DM_USER) 'u-marker aktivieren + +'vorbereiten für suche nach anderen dateien + byte[stradr][len] := 0 'extender wieder abschneiden + +PRI os_testadm(stradr): flag | status,i,len,dmu 'sys: test ob kommando als adm-datei vorliegt + + flag := FALSE + len := strsize(stradr) + repeat i from 0 to 3 '.bel anhängen + byte[stradr][len + i] := byte[@ext2][i] + byte[stradr][len + i] := 0 + +' im aktuellen dir suchen + status := ios.sdopen("r",stradr) 'datei vorhanden? + if status == 0 'datei gefunden + flag := TRUE + ios.admload(stradr) 'administra-code laden + else 'datei nicht gefunden + ios.sdclose + +'im system-dir suchen + ios.sddmset(ios#DM_USER) 'u-marker setzen + ios.sddmact(ios#DM_SYSTEM) 's-marker aktivieren + status := ios.sdopen("r",stradr) 'datei vorhanden? + if status == 0 'datei gefunden + flag := TRUE + dmu := ios.sddmget(ios#DM_USER) 'usermarker von administra holen + ios.admload(stradr) 'administra-code laden + ios.sddmput(ios#DM_USER,dmu) 'usermarker wieder in administra setzen + else 'datei nicht gefunden + ios.sdclose + ios.sddmact(ios#DM_USER) 'u-marker aktivieren + + byte[stradr][len] := 0 'extender wieder abschneiden + +PRI os_testbel(stradr): flag | status,i,len 'sys: test ob kommando als bel-datei vorliegt + + flag := FALSE + len := strsize(stradr) + repeat i from 0 to 3 '.bel anhängen + byte[stradr][len + i] := byte[@ext3][i] + byte[stradr][len + i] := 0 + +' im aktuellen dir suchen + status := ios.sdopen("r",stradr) 'datei vorhanden? + if status == 0 'datei gefunden + flag := TRUE + ios.belload(stradr) 'bellatrix-code laden + ios.screeninit 'systemmeldung + else 'datei nicht gefunden + ios.sdclose + +'im system-dir suchen + ios.sddmset(ios#DM_USER) 'u-marker setzen + ios.sddmact(ios#DM_SYSTEM) 's-marker aktivieren + status := ios.sdopen("r",stradr) 'datei vorhanden? + if status == 0 'datei gefunden + flag := TRUE + ios.belload(stradr) 'bellatrix-code laden + ios.screeninit 'systemmeldung + else 'datei nicht gefunden + ios.sdclose + ios.sddmact(ios#DM_USER) 'u-marker aktivieren + + byte[stradr][len] := 0 'extender wieder abschneiden + +PRI os_printstr(strptr1,strptr2):strptr3 + + ios.print(strptr1) + ios.print(strptr2) + ios.printnl + strptr3 := strptr2 + +PRI os_printdec(strptr, wert):wert2 + + ios.print(strptr) + ios.printdec(wert) + ios.printnl + wert2 := wert + +PRI os_testvideo 'sys: passt div. variablen an videomodus an + + vidmod := ios.belgetspec & 1 + rows := ios.belgetrows 'zeilenzahl bei bella abfragen + cols := ios.belgetcols 'spaltenzahl bei bella abfragen + +PRI os_tvwait + + if vidmod == TV + ios.keywait + +CON ''------------------------------------------------- KOMMANDOS + +PRI rd_dir | stradr,len 'rd: dir anzeigen + +if ios.ram_rdbyte(ios#sysmod,ios#RAMDRV) + ios.rd_dir + repeat + len := ios.rd_dlen + stradr := ios.rd_next + if stradr + ios.print(stradr) + ios.printtab + ios.printdec(len) + ios.printnl + until stradr == 0 +else + ios.os_error(1) + +PRI rd_load | stradr,len,fnr,i 'rd: datei in ramdisk laden + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + ifnot ios.os_error(ios.sdopen("r",stradr)) 'datei öffnen + len := ios.sdfattrib(ios#F_SIZE) + ios.rd_newfile(stradr,len) 'datei erzeugen + fnr := ios.rd_open(stradr) + ios.rd_seek(fnr,0) + ios.print(string("Datei laden... ")) + i := 0 + ios.sdxgetblk(fnr,len) 'daten als block direkt in ext. ram einlesen + ios.sdclose + ios.rd_close(fnr) + +PRI rd_save | stradr,fnr,len,i 'rd: datei aus ramdisk speichern + + stradr := os_nxtoken1 + fnr := ios.rd_open(stradr) + ifnot fnr == -1 + len := ios.rd_len(fnr) + ifnot ios.os_error(ios.sdnewfile(stradr)) + ifnot ios.os_error(ios.sdopen("W",stradr)) + ios.print(string("Datei schreiben... ")) + i := 0 + ios.sdxputblk(fnr,len) 'daten als block schreiben + ios.sdclose + ios.printnl + ios.rd_close(fnr) + +PRI rd_rename 'rd: datei in ramdisk umbenennen + + ios.os_error(ios.rd_rename(os_nxtoken1,os_nxtoken2)) + +PRI rd_del | adr 'rd: datei löschen + + ios.os_error(ios.rd_del(os_nxtoken1)) + +PRI rd_type | stradr,len,fnr,n 'rd: text ausgeben + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + fnr := ios.rd_open(stradr) 'datei öffnen + ifnot fnr == -1 + len := ios.rd_len(fnr) + ios.rd_seek(fnr,0) + repeat len + if ios.printchar(ios.rd_get(fnr)) == ios#CHAR_NL 'zeilenzahl zählen und stop + if ++n == (rows - 2) + n := 1 + if ios.keywait == "q" + ios.sdclose + return + ios.rd_close(fnr) + + +PRI cmd_debug|stradr,len,fnr,i,x 'cmd: temporäre debugfunktion + + ios.print(string("Debug : ")) + ios.printnl + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + ifnot ios.os_error(ios.sdopen("r",stradr)) 'datei öffnen + len := ios.sdfattrib(ios#F_SIZE) + ios.rd_newfile(stradr,len) 'datei erzeugen + fnr := ios.rd_open(stradr) + ios.rd_seek(fnr,0) + ios.print(string("Datei laden... ")) + i := 0 + x := ios.curgetx + ios.curoff + ios.sdxgetblk(fnr,len) 'daten als block direkt in ext. ram einlesen + ios.print(string("ok")) + ios.curon + ios.sdclose + ios.rd_close(fnr) + +PRI cmd_dm|wert 'cmd: dir-marker aktivieren + + ios.os_error(ios.sddmact(cmd_dm_nr)) + +PRI cmd_dmset 'cmd: dir-marker setzen + + ios.sddmset(cmd_dm_nr) + +PRI cmd_dmclr 'cmd: dir-marker löschen + + ios.sddmclr(cmd_dm_nr) + +PRI cmd_dmlist 'cmd: dir-marker auflisten + + ios.setcolor(ios#YELLOW) + ios.print(@msg25) + cmd_dm_status(ios#DM_ROOT) + ios.print(@msg24) + cmd_dm_status(ios#DM_SYSTEM) + ios.print(@msg26) + cmd_dm_status(ios#DM_USER) + ios.setcolor(act_color) + ios.print(@msg27) + cmd_dm_status(ios#DM_A) + ios.print(@msg28) + cmd_dm_status(ios#DM_B) + ios.print(@msg29) + cmd_dm_status(ios#DM_C) + +PRI cmd_dm_status(markernr) + + if ios.sddmget(markernr) == TRUE + ios.print(@msg31) + else + ios.print(@msg30) + +PRI cmd_dm_nr:wert + + case byte[os_nxtoken1] + "r": wert := 0 'root + "s": wert := 1 'system + "u": wert := 2 'user + "a": wert := 3 'marker a + "b": wert := 4 'marker b + "c": wert := 5 'marker c + other: wert := 0 + +PRI cmd_color 'cmd: zeichenfarbe wählen + + ios.setcolor(str.decimalToNumber(act_color := os_nxtoken1)) + +PRI cmd_sysinfo 'cmd: systeminformationen anzeigen + + ios.printnl + os_printstr(@msg22,@syst) + os_printstr(@msg14,@prog) + os_printstr(@msg23,@copy) + if ios.sdcheckmounted 'test ob medium gemounted ist + os_printstr(@msg21,ios.sdvolname) + ios.printnl + os_tvwait + + os_printstr(@msg15,str.numberToBinary(ios#CHIP_VER,32)) + os_printstr(@msg16,str.numberToBinary(ios#CHIP_SPEC,32)) + os_printstr(@msg17,str.numberToBinary(ios.admgetver,32)) + os_printstr(@msg18,str.numberToBinary(ios.admgetspec,32)) + os_tvwait + + os_printstr(@msg19,str.numberToBinary(ios.belgetver,32)) + os_printstr(@msg20,str.numberToBinary(ios.belgetspec,32)) + os_printstr(@msg32,str.numberToDecimal(ios.belgetcols,4)) + os_printstr(@msg33,str.numberToDecimal(ios.belgetrows,4)) + os_printstr(@msg34,str.numberToDecimal(ios.belgetresx,4)) + os_printstr(@msg35,str.numberToDecimal(ios.belgetresy,4)) + + if vidmod == VGA + os_printstr(@msg36,@msg37) + else + os_printstr(@msg36,@msg38) + +PRI cmd_mount | err 'cmd: mount + + repeat 16 + err := ios.sdmount + ifnot err + quit + ios.os_error(err) + ifnot err + ios.setcolor(ios#YELLOW) + ios.print(@msg4) + ios.print(ios.sdvolname) + ios.printnl + ios.print(@msg25) + cmd_dm_status(ios#DM_ROOT) + ios.print(@msg24) + cmd_dm_status(ios#DM_SYSTEM) + ios.printnl + ios.setcolor(act_color) + +PRI cmd_unmount 'cmd: unmount + + ios.os_error(ios.sdunmount) + +PRI cmd_free | wert 'cmd: anzeige freier speicher + + os_printstr(@msg5,ios.sdvolname) + wert := os_printdec(@msg6,ios.sdcheckfree*512/1024) + wert += os_printdec(@msg7,ios.sdcheckused*512/1024) + os_printdec(@msg8,wert) + + ios.printnl + ios.print(string("RBAS : $")) + ios.printhex(ios.ram_rdlong(ios#sysmod,ios#RAMBAS),8) + ios.printnl + ios.print(string("REND : $")) + ios.printhex(ios.ram_rdlong(ios#sysmod,ios#RAMEND),8) + ios.printnl + ios.print(string("USER : $")) + wert := ios.ram_rdlong(ios#sysmod,ios#RAMEND) + wert := wert - ios.ram_rdlong(ios#sysmod,ios#RAMBAS) + ios.printhex(wert,8) + ios.printnl + ios.print(string("RAMDRV : $")) + ios.printhex(ios.ram_rdbyte(ios#sysmod,ios#RAMDRV),2) + ios.printnl + ios.print(string("SYSVAR : $")) + ios.printhex(ios#SYSVAR,8) + ios.printnl + +PRI cmd_attrib 'cmd: dateiattribute ändern +' A-Archive, S-System, H-Hidden, R-Read Only. + + ios.os_error(ios.sdchattrib(os_nxtoken1,os_nxtoken2)) + +PRI cmd_rename 'cmd: datei/verzeichnis umbenennen + + ios.os_error(ios.sdrename(os_nxtoken1,os_nxtoken2)) + +PRI cmd_cd 'cmd: verzeichnis wechseln + + ios.os_error(ios.sdchdir(os_nxtoken1)) + +PRI cmd_mkdir 'cmd: verzeichnis erstellen + + ios.os_error(ios.sdnewdir(os_nxtoken1)) + +PRI cmd_del | stradr,char 'cmd: datei auf sdcard löschen +{{sddel - datei auf sdcard löschen}} + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + ios.print(@msg2) + if ios.keywait == "j" + ios.os_error(ios.sddel(stradr)) + +PRI cmd_format | stradr 'cmd: sd-card formatieren + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + ios.print(@msg12) + if ios.keywait == "j" + ios.os_error(ios.sdformat(stradr)) + +PRI cmd_reboot | key, stradr 'cmd: reboot + + ios.print(@msg13) + key := ios.keywait + case key + "c": ios.ram_wrbyte(ios#sysmod,0,ios#MAGIC) + ios.ram_wrbyte(ios#sysmod,0,ios#RAMDRV) + ios.admreset + ios.belreset + waitcnt(cnt+clkfreq*3) + reboot + "w": ios.ram_wrbyte(ios#sysmod,0,ios#SIFLAG) + reboot + +PRI cmd_aload|status,stradr 'cmd: administra-code laden + + stradr := os_nxtoken1 + status := ios.sdopen("r",stradr) + if status == 0 + ios.admload(stradr) 'administra-code laden + else + ios.os_error(status) + +PRI cmd_bload | stradr,status 'cmd: bellatrix-code laden +{{bload - treiber für bellatrix laden}} + + stradr := os_nxtoken1 + status := ios.sdopen("r",stradr) + if status == 0 + ios.belload(stradr) 'treiberupload + ios.screeninit 'systemmeldung + ios.print(@prog) 'programmversion + else + ios.os_error(status) + +PRI cmd_type | stradr,char,n 'cmd: textdatei ausgeben +{{sdtype - textdatei ausgeben}} + + stradr := os_nxtoken1 'dateinamen von kommandozeile holen + n := 1 + ifnot ios.os_error(ios.sdopen("r",stradr)) 'datei öffnen + repeat 'text ausgeben + if ios.printchar(ios.sdgetc) == ios#CHAR_NL 'zeilenzahl zählen und stop + if ++n == (rows - 2) + n := 1 + if ios.keywait == "q" + ios.sdclose + return + until ios.sdeof 'ausgabe bis eof + ios.sdclose 'datei schließen + +PRI cmd_help | i,char,n 'cmd: textdatei ausgeben + + ios.print(string("help: man regime")) + +{ + n := i := 1 + repeat until (char := byte[@help1][i++]) == 0 'text ausgeben + ios.printchar(char) + if char == ios#CHAR_NL 'zeilenzahl zählen und stop + if ++n == (rows - 2) + n := 1 + if ios.keywait == "q" + return +} + +PRI cmd_dir|fcnt,stradr,hflag 'cmd: verzeichnis anzeigen +{{sddir - anzeige verzeichnis}} + + if ios.sdcheckmounted 'test ob medium gemounted ist + + hflag := 1 + stradr := os_nxtoken1 'parameter einlesen + ios.print(@msg10) + ios.print(@msg5) + ios.print(ios.sdvolname) + ifnot ios.os_error(ios.sddir) 'verzeichnis öffnen + if str.findCharacter(stradr,"h") + hflag := 0 + if str.findCharacter(stradr,"w") + fcnt := cmd_dir_w(hflag) + else + fcnt := cmd_dir_l(hflag) 'dir l + ios.printnl + ios.print(@msg10) + ios.print(@msg9) + ios.printdec(fcnt) + else + ios.os_error(1) + +PRI cmd_dir_w(hflag):fcnt|stradr,lcnt,wcnt + + fcnt := 0 + wcnt := (cols / 14) - 1 '3 + lcnt := (rows - 2) * (cols / 15) + ios.printnl + repeat while (stradr := ios.sdnext) + ifnot ios.sdfattrib(ios#F_HIDDEN) & hflag 'versteckte dateien anzeigen? + if ios.sdfattrib(ios#F_DIR) 'verzeichnisname + ios.setcolor(1) + ios.printqchar("▶") + ios.printchar(" ") + ios.print(stradr) + ios.setcolor(0) + elseif ios.sdfattrib(ios#F_HIDDEN) + ios.setcolor(3) + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + ios.print(stradr) + ios.setcolor(0) + else 'dateiname + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + ios.print(stradr) + ifnot wcnt-- + wcnt := (cols / 15) - 1 '3 + ios.printnl + else + 'ios.printtab + fcnt++ + ifnot --lcnt + lcnt := (rows - 2) * (cols / 15) + if ios.keywait == "q" + return + +PRI cmd_dir_l(hflag):fcnt|stradr,lcnt + + fcnt := 0 + lcnt := rows - 2 + repeat while (stradr := ios.sdnext) + ifnot ios.sdfattrib(ios#F_HIDDEN) & hflag 'versteckte dateien anzeigen? + ios.printnl + if ios.sdfattrib(ios#F_DIR) 'verzeichnisname + ios.setcolor(1) + ios.printqchar("▶") + ios.printchar(" ") + ios.print(stradr) + ios.setcolor(0) + elseif ios.sdfattrib(ios#F_HIDDEN) + ios.setcolor(3) + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + ios.print(stradr) + ios.setcolor(0) + else 'dateiname + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + ios.print(stradr) + + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_SIZE),10)) 'dateigröße + + ios.printchar(" ") 'attribute + if ios.sdfattrib(ios#F_READONLY) + ios.printchar("r") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_HIDDEN) + ios.printchar("h") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_SYSTEM) + ios.printchar("s") + else + ios.printchar("-") + if ios.sdfattrib(ios#F_ARCHIV) + ios.printchar("a") + else + ios.printchar("-") + + if vidmod == TV + ios.printnl + --lcnt + + ios.printchar(" ") 'änderungsdatum + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CDAY),2)) + ios.printchar(".") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMONTH),2) + 1) + ios.printchar(".") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CYEAR),4) + 1) + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CHOUR),2)) + ios.printchar(":") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMIN),2) + 1) + ios.printchar(":") + ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CSEC),2) + 1) + fcnt++ + --lcnt + if lcnt < 1 + lcnt := rows - 2 + if ios.keywait == "q" + return + +PRI cmd_cogs | i,l 'cmd: belegung der cogs anzeigen + + ios.print(@cogs4) + ios.printnl + + i := ios.reggetcogs 'regnatix + cmd_cogs_print(8-i,i,@cogs1) + + i := ios.admgetcogs 'administra + cmd_cogs_print(8-i,i,@cogs2) + + i := ios.belgetcogs 'bellatrix + cmd_cogs_print(8-i,i,@cogs3) + + ios.setcolor(act_color) + ios.print(@cogs4) + ios.printnl + ios.print(string(" (")) + ios.setcolor(ios#RED) + ios.print(string("•")) + ios.setcolor(act_color) + ios.print(@cogs5) + ios.printnl + +PRI cmd_cogs_print(used,free,stradr) + + ios.print(stradr) + if used > 0 + repeat + ios.setcolor(ios#RED) + ios.print(string("•")) + used-- + until used == 0 + if free > 0 + repeat + ios.setcolor(ios#GREEN) + ios.print(string("•")) + free-- + until free == 0 + ios.setcolor(act_color) + ios.printnl + +DAT 'strings +system1 byte "▶Hive: Regime", 0 +syst byte "TriOS • 07-04-2013",0 +prog byte "Regime",0 +copy byte "drohne235 • 06-04-2012",0 +prompt1 byte " ok ", $0d, 0 +prompt2 byte "~ ", 0 +prompt3 byte "∞ ", 0 +msg1 byte "Datei nicht gefunden!",0 +msg2 byte "Datei löschen? : ",0 +msg3 byte " ? ",0 +msg4 byte "Volume : ",0 +msg5 byte "Datenträger : ",0 +msg6 byte "Frei : ",0 +msg7 byte "Belegt : ",0 +msg8 byte "Gesamt : ",0 +msg9 byte "Anzahl der Dateien : ",0 +msg10 byte "• ",0 +msg11 byte " KB",0 +msg12 byte "SD-Card formatieren? : ",0 +msg13 byte "Hive neu starten? <[c]old/[w]arm/*> : ",0 +msg14 byte "CLI : ",0 +msg15 byte "Regnatix Version : ",0 +msg16 byte "Regnatix Spezifikation : ",0 +msg17 byte "Administra Version : ",0 +msg18 byte "Administra Spezifikation : ",0 +msg19 byte "Bellatrix Version : ",0 +msg20 byte "Bellatrix Spezifikation : ",0 +msg21 byte "Medium : ",0 +msg22 byte "OS : ",0 +msg23 byte "Copyright : ",0 +msg24 byte "[S]ystem : ",0 +msg25 byte "[R]oot : ",0 +msg26 byte "[U]ser : ",0 +msg27 byte "Marker [A] : ",0 +msg28 byte "Marker [B] : ",0 +msg29 byte "Marker [C] : ",0 +msg30 byte "gesetzt",13,0 +msg31 byte "frei",13,0 +msg32 byte "Bellatrix Textspalten :",0 +msg33 byte "Bellatrix Textzeilen :",0 +msg34 byte "Bellatrix Auflösung X :",0 +msg35 byte "Bellatrix Auflösung Y :",0 +msg36 byte "Bellatrix Videomodus : ",0 +msg37 byte "VGA",0 +msg38 byte "TV",0 + +ext1 byte ".BIN",0 +ext2 byte ".ADM",0 +ext3 byte ".BEL",0 +wait1 byte "",0 + +cstr byte "••••••••",0 +cogs1 byte "Regnatix : ",0 +cogs2 byte "Administra: ",0 +cogs3 byte "Bellatrix : ",0 +cogs4 byte "────────────────────",0 +cogs5 byte " = running cog)",0 + +gdriver byte "bel.sys", 0 'name des grafiktreibers + +{ +help1 file "regime.txt" + byte 13,0 +} +DAT 'systemfehler +err_s1 byte "Fehlernummer : ",0 +err_s2 byte "Fehler : ",0 +{ +err0 byte "no error",0 +err1 byte "fsys unmounted",0 +err2 byte "fsys corrupted",0 +err3 byte "fsys unsupported",0 +err4 byte "not found",0 +err5 byte "file not found",0 +err6 byte "dir not found",0 +err7 byte "file read only",0 +err8 byte "end of file",0 +err9 byte "end of directory",0 +err10 byte "end of root",0 +err11 byte "dir is full",0 +err12 byte "dir is not empty",0 +err13 byte "checksum error",0 +err14 byte "reboot error",0 +err15 byte "bpb corrupt",0 +err16 byte "fsi corrupt",0 +err17 byte "dir already exist",0 +err18 byte "file already exist",0 +err19 byte "out of disk free space",0 +err20 byte "disk io error",0 +err21 byte "command not found",0 +err22 byte "timeout",0 +errx byte "undefined",0 +} +DAT 'lizenz +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} + diff --git a/system/regnatix/rom.spin b/system/regnatix/rom.spin new file mode 100644 index 0000000..fdbd2f0 --- /dev/null +++ b/system/regnatix/rom.spin @@ -0,0 +1,72 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : rom +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : Kommandozeilentool um ein Image aus dem HI-EEPROM zu starten +Komponenten : - +COG's : - +Logbuch : + +09-04-2011-dr235 - erste version + +Kommandoliste : + + +Notizen : + +}} + +OBJ + ios : "reg-ios" + sdspi : "glob-sdspi" ' SPIN program loader and support routines + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +VAR + +long ioControl[2] + +PUB main + + ios.start 'ios initialisieren + ios.parastart 'parameterübergabe starten + sdspi.start(@iocontrol) + sdspi.bootEEPROM(sdspi#bootAddr + $8000) + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/sfxtool.spin b/system/regnatix/sfxtool.spin new file mode 100644 index 0000000..0a8897e --- /dev/null +++ b/system/regnatix/sfxtool.spin @@ -0,0 +1,499 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : sfxtool +Chip : Regnatix +Typ : Programm +Version : 00 +Subversion : 01 + +Funktion : Einfaches Tool um interaktiv HSS-Soundeffekte zu erstellen und als Spin-Quelltext + zu exportieren. + +Logbuch : + +19-04-2010-dr235 - erste version + +Kommandoliste : + +sfx-struktur: + +wav len freq vol grundschwingung +lfo lfw fma ama modulation +att dec sus rel hüllkurve +seq (optional) + +wav wellenform + 0 sinus (0..500hz) + 1 schneller sinus (0..1khz) + 2 dreieck (0..500hz) + 3 rechteck (0..1khz) + 4 schnelles rechteck (0..4khz) + 5 impulse (0..1,333hz) + 6 rauschen +len tonlänge $0..$fe, $ff endlos +freq frequenz $00..$ff +vol lautstärke $00..$0f + +lfo low frequency oscillator $ff..$01 +lfw low frequency waveform + $00 sinus (0..8hz) + $01 fast sine (0..16hz) + $02 ramp up (0..8hz) + $03 ramp down (0..8hz) + $04 square (0..32hz) + $05 random + $ff sequencer data +fma frequency modulation amount + $00 no modulation + $01..$ff +ama amplitude modulation amount + $00 no modulation + $01..$ff +att attack $00..$ff +dec decay $00..$ff +sus sustain $00..$ff +rel release $00..$ff + + + +}} + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OBJ + ios: "reg-ios" + num: "glob-numbers" + str: "glob-string" + +CON + +TIBLEN = 32 +FNLEN = 12 + +VAR + + byte tib[TIBLEN] 'tastatur-input-buffer + byte rows 'aktuelle anzahl der nutzbaren zeilen + byte cols 'aktuelle Anzahl der nutzbaren spalten + byte vidmod + +PUB main | a,b,c,key,n + + ios.start + rows := 23 'zeilenzahl temp. setzen + cols := 64 + screeninit(@prompt1,4) + repeat + ios.sfx_setslot(@fx_puffer,15) + ios.sfx_fire(15,1) + printfx(@fx_puffer) + key := ios.keywait + case key + "1": + ios.printchar($0d) + ios.print(string("Basisschwingung Waveform (0..6): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer] := n + "2": + ios.printchar($0d) + ios.print(string("Basisschwingung Länge (0..FE, FF endlos):")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+1] := n + "3": + ios.printchar($0d) + ios.print(string("Basisschwingung Frequenz (0..FF): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+2] := n + "4": + ios.printchar($0d) + ios.print(string("Basisschwingung Volume (0..F): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+3] := n + "5": + ios.printchar($0d) + ios.print(string("Modulation LFO (Speed 01..FF): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+4] := n + "6": + ios.printchar($0d) + ios.print(string("Modulation LFW (Waveform 0..5): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+5] := n + "7": + ios.printchar($0d) + ios.print(string("Modulation FMa (Stärke der FM 0 - off, 01..FF, 01 - MAX): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+6] := n + "8": + ios.printchar($0d) + ios.print(string("Modulation AMa (Stärke der AM 0 - off, 01..FF, 01 - MAX): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+7] := n + "9": + ios.printchar($0d) + ios.print(string("Hüllkurve Attack - Anstieg (0 - off, 1..FF, 1 - lansamster Anstieg): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+8] := n + "a": + ios.printchar($0d) + ios.print(string("Hüllkurve Decay - Abfall (0 - off, 1..FF, 1 - lansamster Abfall): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+9] := n + "b": + ios.printchar($0d) + ios.print(string("Hüllkurve Sustain - Halten Volume (0 - Mute, 1..FF, 1 - Leise): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+10] := n + "c": + ios.printchar($0d) + ios.print(string("Hüllkurve Release - Freigabe (0 - off, 1..FF, 1 - Langsamste Freigabe): ")) + ios.input(@tib,TIBLEN) + n := num.FromStr(@tib,num#HEX) + byte[@fx_puffer+11] := n + "m": + menu2 + screeninit(@prompt1,4) + +pri screeninit(stradr,n) + + os_testvideo + ios.windefine(1,0,0,cols,n) + ios.winset(1) + ios.printcls + ios.print(stradr) + ios.windefine(2,0,n+1,cols,rows) + ios.winset(2) + ios.printcls + +pri os_testvideo 'sys: passt div. variablen an videomodus an + + vidmod := ios.belgetspec & 1 + rows := ios.belgetrows 'zeilenzahl bei bella abfragen + cols := ios.belgetcols 'spaltenzahl bei bella abfragen + +pub menu2 | key,a + screeninit(@prompt2,4) + key := ios.keywait + case key + "s": save + "l": load + "e": export + "r": menu3 + "q": ios.winset(0) + ios.screeninit + ios.stop + +pub save|i + + ios.printnl + ios.print(string("Effekt speichern - Dateiname : ")) + ios.input(@tib,FNLEN) + printerr(ios.sdnewfile(@tib)) + ifnot printerr(ios.sdopen("W",@tib)) + i := 0 + repeat 32 + ios.sdputc(byte[@fx_puffer + i++]) + ios.sdclose + +pub load|i + + cmd_dir + ios.printnl + ios.print(string("Effekt laden - Dateiname : ")) + ios.input(@tib,FNLEN) + ifnot printerr(ios.sdopen("R",@tib)) + i := 0 + repeat 32 + byte[@fx_puffer + i++] := ios.sdgetc + ios.sdclose + +pub export | i + + ios.printnl + ios.print(string("Effekt exportieren - Dateiname : ")) + ios.input(@tib,FNLEN) + printerr(ios.sdnewfile(@tib)) + ifnot printerr(ios.sdopen("W",@tib)) + ios.print(string(" Name : ")) + ios.input(@tib,FNLEN) + sd_print(@tib) + sd_printchar($0d) + i := 0 + sd_print(string("' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel")) + sd_printchar($0d) + sd_print(string("byte ")) + sd_printchar("$") + sd_printhex(byte[@fx_puffer + i++],2) + repeat 11 + sd_printchar(",") + sd_printchar("$") + sd_printhex(byte[@fx_puffer + i++],2) + sd_printchar($0d) + sd_print(string("byte ")) + sd_printchar("$") + sd_printhex(byte[@fx_puffer + i++],2) + repeat 20 + sd_printchar(",") + sd_printchar("$") + sd_printhex(byte[@fx_puffer + i++],2) + ios.sdclose + +pub menu3 | key,a,n,c,w + + screeninit(@prompt3,4) + w := 0 + c := 32 + repeat + key := ios.keywait + case key + "r": + repeat c + a? + a := a & $FF + byte[@fx_puffer+2] := a + ios.sfx_setslot(@fx_puffer,15) + ios.sfx_fire(15,1) + printfx(@fx_puffer) + if w > 0 + waitcnt(clkfreq / w + cnt) + "c": + ios.printchar($0d) + ios.print(string("Anzahl = ")) + ios.printdec(c) + ios.print(string(" : ")) + ios.input(@tib,TIBLEN) + c := num.FromStr(@tib,num#DEC) + ios.print(string(" ok",$0d)) + "w": + ios.printchar($0d) + ios.print(string("Wait = ")) + ios.printdec(w) + ios.print(string(" : ")) + ios.input(@tib,TIBLEN) + w := num.FromStr(@tib,num#DEC) + ios.print(string(" ok",$0d)) + "b": quit + +pub printfx(adr)| i,a + ios.printchar(ios#char_nl) + repeat i from 0 to 11 + a := byte[adr+i] + ios.print(string("$")) + ios.printhex(a,2) + ios.print(string(" ")) + +PUB printerr(err):error 'sys: fehlerausgabe + + if err + ios.printnl + ios.print(@err_s1) + ios.printdec(err) + ios.print(string(" : $")) + ios.printhex(err,2) + ios.printnl + ios.print(@err_s2) + case err + 0: ios.print(@err0) + 1: ios.print(@err1) + 2: ios.print(@err2) + 3: ios.print(@err3) + 4: ios.print(@err4) + 5: ios.print(@err5) + 6: ios.print(@err6) + 7: ios.print(@err7) + 8: ios.print(@err8) + 9: ios.print(@err9) + 10: ios.print(@err10) + 11: ios.print(@err11) + 12: ios.print(@err12) + 13: ios.print(@err13) + 14: ios.print(@err14) + 15: ios.print(@err15) + 16: ios.print(@err16) + 17: ios.print(@err17) + 18: ios.print(@err18) + 19: ios.print(@err19) + 20: ios.print(@err20) + OTHER: ios.print(@errx) + ios.printnl + ios.print(string("")) + ios.keywait + error := err + +PUB cmd_dir|fcnt,stradr,hflag 'cmd: verzeichnis anzeigen +{{sddir - anzeige verzeichnis}} + + ifnot printerr(ios.sddir) 'verzeichnis öffnen + fcnt := cmd_dir_w(hflag) + +PRI cmd_dir_w(hflag):fcnt|stradr,lcnt,wcnt + + fcnt := 0 + wcnt := (cols / 14) - 1 '3 + lcnt := (rows - 2) * (cols / 15) + ios.printnl + repeat while (stradr := ios.sdnext) + ifnot ios.sdfattrib(ios#F_HIDDEN) & hflag 'versteckte dateien anzeigen? + if ios.sdfattrib(ios#F_DIR) 'verzeichnisname + ios.setcolor(1) + ios.printqchar("▶") + ios.printchar(" ") + ios.print(stradr) + ios.setcolor(0) + elseif ios.sdfattrib(ios#F_HIDDEN) + ios.setcolor(3) + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + ios.print(stradr) + ios.setcolor(0) + else 'dateiname + ios.print(string(" ")) + str.charactersToLowerCase(stradr) + ios.print(stradr) + ifnot wcnt-- + wcnt := (cols / 15) - 1 '3 + ios.printnl + else + 'ios.printtab + fcnt++ + ifnot --lcnt + lcnt := (rows - 2) * (cols / 15) + if ios.keywait == "q" + return + +PRI str_lowercase(characters) + + repeat strsize(characters--) + result := byte[++characters] + if((result => "A") and (result =< "Z")) + byte[characters] := (result + 32) + +PUB sd_print(stringptr) 'screen: bildschirmausgabe einer zeichenkette (0-terminiert) +{{print(stringptr) - screen: bildschirmausgabe einer zeichenkette (0-terminiert)}} + repeat strsize(stringptr) + ios.sdputc(byte[stringptr++]) + +PUB sd_printdec(value) | i 'screen: dezimalen zahlenwert auf bildschirm ausgeben +{{printdec(value) - screen: dezimale bildschirmausgabe zahlenwertes}} + if value < 0 'negativer zahlenwert + -value + ios.sdputc("-") + i := 1_000_000_000 + repeat 10 'zahl zerlegen + if value => i + ios.sdputc(value / i + "0") + value //= i + result~~ + elseif result or i == 1 + ios.sdputc("0") + i /= 10 'nächste stelle + +PUB sd_printhex(value, digits) 'screen: hexadezimalen zahlenwert auf bildschirm ausgeben +{{hex(value,digits) - screen: hexadezimale bildschirmausgabe eines zahlenwertes}} + value <<= (8 - digits) << 2 + repeat digits + ios.sdputc(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + +PUB sd_printchar(c):c2 'screen: einzelnes zeichen auf bildschirm ausgeben +{{printchar(c) - screen: bildschirmausgabe eines zeichens}} + ios.sdputc(c) + c2 := c + +DAT + +prompt1 byte "▶Hive: SFX-Tool" + byte $0d,"Basisschwingung Modulation Hüllkurve " + byte $0d,"Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel" + byte $0d,"[01] [02] [03] [04] [05] [06] [07] [08] [09] [0A] [0B] [0C] [M] ",$0 + +prompt2 byte "▶SFX-Tool - Menü" + byte $0d," " + byte $0d," " + byte $0d,"[S]ave [L]oad [E]xport [R]and [Q]uit",$0 + +prompt3 byte "▶SFX-Tool - Random Freq" + byte $0d," " + byte $0d," " + byte $0d,"[R]un [C]ount [W]ait [B]ack",$0 + +mod1 byte "bd1.hss ",0 +mod2 byte "bd2.hss ",0 + +err_s1 byte "Fehlernummer : ",0 +err_s2 byte "Fehler : ",0 + +err0 byte "no error",0 +err1 byte "fsys unmounted",0 +err2 byte "fsys corrupted",0 +err3 byte "fsys unsupported",0 +err4 byte "not found",0 +err5 byte "file not found",0 +err6 byte "dir not found",0 +err7 byte "file read only",0 +err8 byte "end of file",0 +err9 byte "end of directory",0 +err10 byte "end of root",0 +err11 byte "dir is full",0 +err12 byte "dir is not empty",0 +err13 byte "checksum error",0 +err14 byte "reboot error",0 +err15 byte "bpb corrupt",0 +err16 byte "fsi corrupt",0 +err17 byte "dir already exist",0 +err18 byte "file already exist",0 +err19 byte "out of disk free space",0 +err20 byte "disk io error",0 +err21 byte "command not found",0 +errx byte "undefined",0 + + + 'basisschwingung modulation hüllkurve + 'Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +fx_puffer byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 + byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + + + + +DAT 'lizenz +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/splay.spin b/system/regnatix/splay.spin new file mode 100644 index 0000000..d11d486 --- /dev/null +++ b/system/regnatix/splay.spin @@ -0,0 +1,240 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : splay +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : sid-player für kommandozeile +Komponenten : - +COG's : - +Logbuch : + +19-04-2010-dr235 - sid-time: start des projektes :) + +Kommandoliste : + +/? : Hilfetext +/m name.dmp : DMP-Datei mono auf SID2 abspielen +/s name.dmp : DMP-Datei stereo auf SID2 abspielen +/d : Alle DMP-Dateien im Verzeichnis wiedergeben + q - quit + n - next + p - pause + +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +SIDMASK = %00000000_00000000_00000000_00010000 + + +VAR + + byte fl_bye 'flag player beenden + byte parastr[64] 'parameterstring + byte fn[12] 'puffer für dateinamen + long datcnt 'zeiger für dateiliste + + +DAT 'PARAMETER + +PUB main + + ios.start 'ios initialisieren + ios.parastart 'parameterübergabe starten + if (ios.admgetspec & SIDMASK) + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: man splay")) '/? + "m": playm_dmp '/p + "s": plays_dmp '/s + "d": play_dir '/d + else + printErr(@err2) + ios.stop + +DAT 'PLAY_DIR + +PUB play_dir|stradr,len,fcnt,i 'hss: alle songs auf der sd-card abspielen + + ios.sddir 'kommando: verzeichnis öffnen + datcnt := 0 'zum listenanfang + fcnt := 0 'zähler für dateianzahl + fl_bye := 0 + repeat while (stradr := ios.sdnext) 'dateiliste einlesen + if str_find(stradr,@ext1) + fcnt++ + play_dir_wrlst(stradr) + ios.print(string("Anzahl Dateien : ")) + ios.printdec(fcnt) + ios.printnl + datcnt := 0 'zum listenanfang + repeat i from 0 to fcnt-1 'dateiliste abspielen + ios.printdec(i+1) + ios.printchar("/") + ios.printdec(fcnt) + ios.printtab + play_dir_rdlst(@fn) + play_dir_file(@fn) + if fl_bye 'player beenden + quit + ios.printnl + +PRI play_dir_file(stradr)|err + + ios.print(stradr) + ios.printchar(" ") + if err := ios.sid_sdmpplay(stradr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + play_status 'warten, solange wav gespielt wird (sd belegt) + ios.printnl + +PUB play_dir_wrlst(stradr)|len,i 'kopiert dateinamen in liste + len := strsize(stradr) + repeat i from 0 to len-1 + ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++) + ios.ram_wrbyte(ios#usrmod,0,datcnt++) + +PUB play_dir_rdlst(stradr)|i,n 'liest dateinamen aus list + i := 0 + repeat + n := ios.ram_rdbyte(ios#usrmod,datcnt++) + byte[stradr][i++] := n + while n <> 0 + +DAT 'PLAY_DMP + +PRI playm_dmp|err 'dmp-datei mono auf einem sid abspielen + + if ios.paranext(@parastr) 'parameter? + if err := ios.sid_mdmpplay(@parastr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + play_status 'warten, solange wav gespielt wird (sd belegt) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PRI plays_dmp|err 'dmp-datei quasi-stereo auf zwei sidcogs abspielen + + if ios.paranext(@parastr) 'parameter? + if err := ios.sid_sdmpplay(@parastr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + play_status 'warten, solange wav gespielt wird (sd belegt) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PUB play_status|status,curpos,key,l,p 'warten bis player fertig, oder abbruch + + ios.print(string(" : ")) + ios.curoff + curpos := ios.curgetx + repeat + status := ios.sid_dmpstatus + ios.cursetx(curpos) + ios.printdec(ios.sid_dmplen) + ios.printchar("/") + ios.printdec(ios.sid_dmppos) + if key := ios.key 'bei taste stopsignal an player senden + case key + "n": ios.sid_dmpstop 'next wav + "p": ios.sid_dmppause 'pause + "q": fl_bye := 1 + ios.sid_dmpstop + while status 'schleife solange player aktiv + ios.sid_mute(3) + ios.curon + +DAT 'TOOLS + +PRI printErr(stradr) + + ios.print(@err0) + ios.print(stradr) + ios.print(string("help: man splay")) + +PUB str_find(string1, string2) : buffer | counter 'sys: string suchen + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches a string of characters for the first occurence of the specified string of characters. │ +'' │ │ +'' │ Returns the address of that string of characters if found and zero if not found. │ +'' │ │ +'' │ string1 - A pointer to the string of characters to search. │ +'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(string1--) + + if(byte[++string1] == byte[string2]) + + repeat counter from 0 to (strsize(string2) - 1) + + if(byte[string1][counter] <> byte[string2][counter]) + buffer~~ + + ifnot(buffer~) + return string1 + +PUB str2dec(stradr)|buffer,counter + + buffer := byte[stradr] + counter := (strsize(stradr) <# 11) + repeat while(counter--) + result *= 10 + result += lookdownz(byte[stradr++]: "0".."9") + if(buffer == "-") + -result + +DAT + +ext1 byte ".DMP",0 + +err0 byte 13,"Fehler : ",0 +err1 byte "Zu wenig Parameter!",13,0 +err2 byte "Administra-Code unterstützt keine SID-Emulation!",13,0 + + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/sysconf.spin b/system/regnatix/sysconf.spin new file mode 100644 index 0000000..e4cb799 --- /dev/null +++ b/system/regnatix/sysconf.spin @@ -0,0 +1,388 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : sysconf +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : Kommandozeilentool für TriOS-Systemeinstellungen +Komponenten : - +COG's : - +Logbuch : + +16-04-2010-dr235 - erste version +24-10-2010-dr235 - port input/output + +Kommandoliste : + +/? : Hilfe +/l : list konf +/ap : Konfiguration anzeigen +/ah 0|1 : hss ab-/anschalten +/aw 0|1 : wav ab-/anschalten +/as 0|1 : systemklänge ab-/anschalten +/al 0..100: wav-lautstärke links +/ar 0..100: wav-lautstärke rechts +/ah 0..15 : hss-lautstärke +/ci : farbtabelle anzeigen +/cs datei : farbtabelle speichern +/cl datei : farbtabelle laden +/po p a : port ausgabe portnummer anzahl impulse +/pi : port eingabe portnummer + + +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +VAR + +byte parastr[64] +byte vidmod 'videomodus: 0 - vga, 1 - tv +long cols,rows + +PUB main + + ios.start 'ios initialisieren + vidmod := ios.belgetspec & 1 + rows := ios.belgetrows 'zeilenzahl bei bella abfragen + cols := ios.belgetcols 'spaltenzahl bei bella abfragen + ios.parastart 'parameterübergabe starten + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: man sysconf")) '/? + "l": printConf + "a": case byte[@parastr][2] 'administra + "h": setHSS '/ah - hss + "w": setWAV '/aw - wav + "s": setSYS '/as - systemklänge + "l": set_lvol '/al - wav-lautstärke links + "r": set_rvol '/ar - wav-lautstärke rechts + "v": set_hvol '/av - hss-lautstärke + "f": ios.admreset '/ab - administra reset, flash wird neu gebootet + "t": busTransfer '/at - transfergeschwindigkeit messen + "c": case byte[@parastr][2] 'color + "i": col_info '/ci - farbregister anzeigen + "l": col_load '/cl - farbregister laden + "s": col_save '/cs - farbregister speichern + "p": case byte[@parastr][2] 'portfunktionen + "o": port_out '/po - impulse am port ausgeben + "i": port_in '/pi - portstatus einlesen + ios.stop + +DAT 'PORT + +PRI port_out|pnr,anz,time,fak,i + + if ios.paranext(@parastr) + pnr := str2dec(@parastr) + if ios.paranext(@parastr) + anz := str2dec(@parastr) + if ios.paranext(@parastr) + fak := str2dec(@parastr) + else + printErr(@err1) + return + else + printErr(@err1) + return + else + printErr(@err1) + return + + ios.print(string("Port Nr(0..31): ")) + ios.printdec(pnr) + ios.printnl + ios.print(string("Impulse : ")) + ios.printdec(anz) + ios.printnl + ios.print(string("Faktor : ")) + ios.printdec(fak) + ios.printnl +' ------------------------ + dira[pnr]~~ + time := cnt + i := 0 + repeat anz + outa[pnr] := 1 + waitcnt(time += clkfreq/fak) + outa[pnr] := 0 + waitcnt(time += clkfreq/fak) + ios.bus_init +' ------------------------ + +PRI port_in|pnr,wert + + ios.printnl +' ------------------------ + dira := 0 + wert := ina[0..31] + ios.bus_init +' ------------------------ + ios.print(string("Status : ")) + ios.printbin(wert,32) + + +DAT 'COLOR + +PRI col_info|i,n + + if vidmod == ios#TV + n := 7 + else + n := 15 + repeat i from 0 to n + ios.printhex(ios.belgetcolor(i*2),8) + ios.printchar(" ") + ios.printhex(ios.belgetcolor(i*2+1),8) + ios.setcolor(i) + ios.print(string(" Farbe : ")) + ios.setcolor(0) + ios.printdec(i) + ios.printnl + +PRI col_save|i,color + + if ios.paranext(@parastr) + ios.printnl + ios.print(string("Farbtabelle speichern : ")) + ios.print(@parastr) + ios.sdnewfile(@parastr) + ifnot ios.sdopen("W",@parastr) + repeat i from 0 to 15 + color := ios.belgetcolor(i) + ios.sdputc(color >> 24) + ios.sdputc(color >> 16) + ios.sdputc(color >> 8) + ios.sdputc(color ) + ios.sdclose + else + printErr(@err1) + +PRI col_load|i,color + + if ios.paranext(@parastr) + ios.printnl + ios.print(string("Farbtabelle laden : ")) + ios.print(@parastr) + ifnot ios.sdopen("R",@parastr) + repeat i from 0 to 15 + color := ios.sdgetc << 24 + color += ios.sdgetc << 16 + color += ios.sdgetc << 8 + color += ios.sdgetc + ios.belsetcolor(i,color) + ios.sdclose + else + printErr(@err1) + +DAT 'VOLUME + +PRI set_lvol + + if ios.paranext(@parastr) 'parameter? + ios.wav_lvol(str2dec(@parastr)) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PRI set_rvol + + if ios.paranext(@parastr) 'parameter? + ios.wav_rvol(str2dec(@parastr)) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PRI set_hvol + + if ios.paranext(@parastr) 'parameter? + ios.hss_vol(str2dec(@parastr)) + else 'kein parameter: fehlermeldung + printErr(@err1) + +DAT 'SOUNDSYSTEM + +PRI setHSS + + if ios.paranext(@parastr) 'parameter? + case byte[@parastr][0] + "0": ios.admsetsound(0) + ios.print(@msg4) + ios.print(@msg2) + "1": ios.admsetsound(1) + ios.print(@msg4) + ios.print(@msg1) + else + printErr(@err1) + +PRI setWAV + + if ios.paranext(@parastr) 'parameter? + case byte[@parastr][0] + "0": ios.admsetsound(2) + ios.print(@msg5) + ios.print(@msg2) + "1": ios.admsetsound(3) + ios.print(@msg5) + ios.print(@msg1) + else + printErr(@err1) + +PRI setSYS + + if ios.paranext(@parastr) 'parameter? + case byte[@parastr][0] + "0": ios.admsetsyssnd(0) + ios.print(@msg7) + ios.print(@msg2) + "1": ios.admsetsyssnd(1) + ios.print(@msg7) + ios.print(@msg1) + else + printErr(@err1) + +VAR + +long tcnt1,tcnt2 'transferzähler +byte tflag 'transferflag + +CON + + tbytes = 32768 + +PRI busTransfer|sec + + ios.print(@msg8) + + 'zeit für reinen schleifendurchlauf berechnen + tcnt1 := cnt + repeat tbytes + busTransferDummy1 + tcnt1 := cnt - tcnt1 + + 'messvorgang + tcnt2 := cnt + repeat tbytes + ios.admgetsndsys + tcnt2 := cnt - tcnt2 + + ios.print(@msg10) + ios.print(@msg9) + sec := (tcnt2 - tcnt1) / clkfreq 'zeit der übertragung in sekunden + ios.printdec((tbytes*2)/sec) + ios.print(@msg11) + +PRI busTransferDummy1 + + busTransferDummy2 + return busTransferDummy2 + +PRI busTransferDummy2 + + return 1 + +PRI printConf + + ios.printnl + ios.print(@msg3) 'soundsystem + case ios.admgetsndsys + 0: ios.print(@msg6) + 1: ios.print(@msg4) + 2: ios.print(@msg5) + ios.printnl + + ios.print(@msg12) 'ramdisk + if ios.rd_getinit + ios.print(@msg14) + else + ios.print(@msg15) + ios.printnl + + ios.print(@msg13) 'usermem + ios.printdec(ios.ram_getend - ios.ram_getbas) + ios.printnl + + ios.print(@msg16) + ios.printbin(ios.belgetspec,16) + ios.printnl + + ios.print(@msg17) + ios.printbin(ios.admgetspec,16) + ios.printnl + +PRI printErr(stradr) + + ios.print(@err0) + ios.print(stradr) + ios.print(string("help: man sysconf")) + +PRI str2dec(stradr)|buffer,counter + + buffer := byte[stradr] + counter := (strsize(stradr) <# 11) + repeat while(counter--) + result *= 10 + result += lookdownz(byte[stradr++]: "0".."9") + if(buffer == "-") + -result + +DAT + +msg1 byte "EIN ", 0 +msg2 byte "AUS ", 0 +msg3 byte "Soundsystem : ",0 +msg12 byte "Ramdisk : ",0 +msg13 byte "Usermem : ",0 +msg16 byte "Bellatrix : ",0 +msg17 byte "Administra : ",0 +msg14 byte "aktiviert",0 +msg15 byte "deaktiviert",0 +msg4 byte "HSS-Engine ",0 +msg5 byte "WAV-Engine ",0 +msg6 byte "Soundsystem deaktiviert ",0 +msg7 byte "Systemklänge ",0 +msg8 byte "Transfergeschwindigkeit Regnatix <--> Administra messen... ",0 +msg9 byte "Geschwindigkeit : ",0 +msg10 byte "ok",13,0 +msg11 byte " Bytes/Sekunde",13,0 + +err0 byte 13,"Fehler : " +err1 byte "Zu wenig Parameter!",13,0 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/tapecut.spin b/system/regnatix/tapecut.spin new file mode 100644 index 0000000..f0b3630 --- /dev/null +++ b/system/regnatix/tapecut.spin @@ -0,0 +1,166 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : tapecut - erzeugt leere tapedateien +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : +Komponenten : - +COG's : - +Logbuch : +Kommandoliste : +Notizen : + + +Notizen: +- parameter c - create, erzeugt neue tape-datei + a - append, hängt screens an + n - screens nummerieren + + + --------------------------------------------------------------------------------------------------------- }} + +OBJ + ios: "reg-ios" + num: "glob-numbers" + gc : "m-glob-con" + + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +SCREENSIZE = 1024 + +VAR + +byte parastr1[32] 'dateiname +byte parastr2[32] 'größe +long screens 'anzahl der screens + +PUB main2 | i,n + + ios.start + ios.parastart + parastr1[0] := 0 + parastr2[0] := 0 + ios.printnl + ifnot rd_parameter 'parameter einlesen + ios.print(@msg1) + if ios.keywait <> "j" 'abbruch? + ios.print(string("nein")) + ios.printnl + else 'container erzeugen + ios.print(string("ja")) + ios.printnl + create + ios.stop + +PRI rd_parameter + if ios.paranext(@parastr1) 'parameter dateiname einlesen + ios.print(@msg5) + ios.print(@parastr1) + ios.printnl + if ios.paranext(@parastr2) 'parameter screenzahl einlesen + screens := num.FromStr(@parastr2,num#DEC) + ios.print(@msg8) + ios.printdec(screens) + ios.printnl + ios.print(@msg4) + ios.printnl + ios.print(@msg6) + ios.printdec(screens * SCREENSIZE) + ios.print(@msg7) + else + ios.print(@err2) + ios.print(@msg3) + return -1 + + else + ios.print(@err1) + ios.print(@msg3) + return -1 + return + +PRI create | i,status,curpos,numstr,len 'erzeugt containerdatei + + status := ios.sdopen("R",@parastr1) 'test ob datei vorhanden + ios.sdclose 'datei gleich wieder schlie?en + if status == 0 'datei ist schon vorhanden + ios.print(@msg12) + if ios.keywait <> "j" + ios.print(string("nein")) 'nicht ?berschreiben + ios.printnl + return + ios.printnl + ios.print(@msg10) + ios.sdnewfile(@parastr1) + ios.sdopen("W",@parastr1) 'datei erzeugen + ios.print(@msg11) + ios.print(@msg13) + curpos := ios.curgetx 'cursorposition x merken + repeat i from 1 to screens 'screens schreiben + numstr := num.ToStr(i-1,num#dec) + len := strsize(numstr) + fprint(string(gc#m_c_remark,"screen nr : ")) + fprint(numstr) 'screennummer in erste zeile + repeat SCREENSIZE - len - 13 'screen auffüllen + ios.sdputc(gc#m_c_remark) + ios.cursetx(curpos) 'position setzen + ios.printdec(i) + ios.sdclose + ios.print(@msg11) + +PUB fprint(stringptr) 'dateiausgabe einer zeichenkette (0-terminiert) + repeat strsize(stringptr) + ios.sdputc(byte[stringptr++]) + + +DAT + +msg1 byte 13,"Parameter korrekt? : ", 0 +msg2 byte " : ", 0 +msg3 byte "Format : tapecut ",13,0 +msg4 byte "Screengröße : 1024 Byte",0 +msg5 byte "Containerdatei : ",0 +msg6 byte "Größe : ",0 +msg7 byte " Bytes ",13,0 +msg8 byte "Screens : ",0 +msg10 byte "Datei wird geöffnet... ",0 +msg11 byte " ok ",13,0 +msg12 byte 13,"Vorhandene Datei überschreiben? : ", 0 +msg13 byte "Schreibe Screen : ",0 + +err1 byte "Fehler : Keine Parameter.",13,0 +err2 byte "Fehler : Keine Größe definiert.",13,0 + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/time.spin b/system/regnatix/time.spin new file mode 100644 index 0000000..f5f74c0 --- /dev/null +++ b/system/regnatix/time.spin @@ -0,0 +1,282 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : flash +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : RTC-Funktionen Date/Time +Komponenten : - +COG's : - +Logbuch : + +05.12.2010-stephan - DateTime Funktionen +09-04-2011-dr235 - auskopplung aus regime + +Kommandoliste : + + +Notizen : + + +}} + +OBJ + ios: "reg-ios" + str: "glob-string" + num: "glob-numbers" 'Number Engine + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + + +VAR + +byte parastr[64] + +PUB main + + ios.start 'ios initialisieren + ios.parastart 'parameterübergabe starten + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(@help) + "d": cmd_date + "l": cmd_date_long + "t": cmd_time + "s": cmd_setDateTime + other: ios.print(@help) + ios.stop + +CON ''------------------------------------------------- DATE TIME FUNKTIONEN + +PUB cmd_date | stringpointer, format 'rtc: aktuelles Datum zurückgeben + + format := ios.getNVSRAM(ios#NVRAM_DATEFORMAT) + + case format + ios#DATEFORMAT_DE: 'YYYY-MM-DD + ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2))) + ios.print(string(".")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2))) + ios.print(string(".")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4))) + ios.printnl + + ios#DATEFORMAT_UK: 'DD/MM/YYYY + ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2))) + ios.print(string("/")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2))) + ios.print(string("/")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4))) + ios.printnl + + ios#DATEFORMAT_US: 'MM/DD/YYYY + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2))) + ios.print(string("/")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2))) + ios.print(string("/")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4))) + ios.printnl + + other: 'DATEFORMAT_CANONICAL 'YYYY-MM-DD + ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4))) + ios.print(string("-")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2))) + ios.print(string("-")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2))) + ios.printnl + +PRI cmd_date_long | stringpointer, month, weekday 'rtc: aktuelles Datum zurückgeben + + case ios.getNVSRAM(ios#NVRAM_LANG) + ios#LANG_EN: + weekday := lookup(ios.getDay: string("Sunday"), string("Monday"), string("Tuesday"), string("Wednesday"), string("Thursday"), string("Friday"), string("Saturday")) + month := lookup(ios.getMonth: string("January"), string("February"), string("March"), string("April"), string("May"), string("June"), string("July"), string("August"), string("September"), string("October"), string("November"), string("December")) + other: + weekday := lookup(ios.getDay: string("Montag"), string("Dienstag"), string("Mittwoch"), string("Donnerstag"), string("Freitag"), string("Samstag"), string("Sonntag")) + month := lookup(ios.getMonth: string("Januar"), string("Februar"), string("März"), string("April"), string("Mai"), string("Juni"), string("Juli"), string("August"), string("September"), string("Oktober"), string("November"), string("Dezember")) + + case ios.getNVSRAM(ios#NVRAM_DATEFORMAT) + ios#DATEFORMAT_DE: 'YYYY-MM-DD + ios.print(weekday) + ios.print(string(", ")) + ios.print(str.trimCharacters(num.ToStr(ios.getDate, num#DEC))) + ios.print(string(". ")) + ios.print(month) + ios.print(string(" ")) + ios.print(str.trimCharacters(num.ToStr(ios.getYear, num#DEC))) + ios.print(string(" ")) + cmd_time + + ios#DATEFORMAT_UK: 'DD/MM/YYYY + ios.print(weekday) + ios.print(string(", ")) + ios.print(str.trimCharacters(num.ToStr(ios.getDate, num#DEC))) + ios.print(string(" ")) + ios.print(month) + ios.print(string(" ")) + ios.print(str.trimCharacters(num.ToStr(ios.getYear, num#DEC))) + ios.print(string(" ")) + cmd_time + + ios#DATEFORMAT_US: 'MM/DD/YYYY + ios.print(weekday) + ios.print(string(", ")) + ios.print(month) + ios.print(string(" ")) + ios.print(str.trimCharacters(num.ToStr(ios.getDate, num#DEC))) + ios.print(string(", ")) + ios.print(str.trimCharacters(num.ToStr(ios.getYear, num#DEC))) + ios.print(string(" ")) + cmd_time + +PUB cmd_time | stringpointer, value, suffix 'rtc: aktuelle Zeit zurückgeben + 'time - aktuelle Zeit + + case ios.getNVSRAM(ios#NVRAM_TIMEFORMAT) + ios#TIMEFORMAT_12: 'HH:MM:SS[PM|AM] + value := ios.getHours + if(value > 12) + suffix := string("PM") + value -= 12 + else + suffix := string("AM") + ios.print(str.trimCharacters(str.numberToDecimal(value, 2))) + ios.print(string(":")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMinutes, 2))) + ios.print(string(":")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getSeconds, 2))) + ios.print(suffix) + + ios#TIMEFORMAT_12UK: 'HH.MM.SS[PM|AM] + value := ios.getHours + if(value > 12) + suffix := string("PM") + value -= 12 + else + suffix := string("AM") + ios.print(str.trimCharacters(str.numberToDecimal(value, 2))) + ios.print(string(".")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMinutes, 2))) + ios.print(string(".")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getSeconds, 2))) + ios.print(suffix) + + other: 'ios#TIMEFORMAT_24: 'HH:MM:SS + ios.print(str.trimCharacters(str.numberToDecimal(ios.getHours, 2))) + ios.print(string(":")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getMinutes, 2))) + ios.print(string(":")) + ios.print(str.trimCharacters(str.numberToDecimal(ios.getSeconds, 2))) + + ios.printnl + +PRI cmd_setDateTime | buffer, changed 'rtc: Datum/Zeit setzen + + buffer := string(" ") + + 'bytefill(buffer, 0, 5) + + ios.print(string("aktuelles Datum: ")) + cmd_Date_long + + ios.print(string("neues Datum eingeben? (j/n): ")) + if ios.keywait == "j" + ios.printnl + ios.print(string("Jahr (2000 - 2127): ")) + ios.input(buffer, 4) + ios.setYear(num.FromStr(buffer, num#DEC)) + ios.printnl + ios.print(string("Monat (1 - 12): ")) + ios.input(buffer, 2) + ios.setMonth(num.FromStr(buffer, num#DEC)) + ios.printnl + ios.print(string("Wochentag (1(Mo) - 7(So)): ")) + ios.input(buffer, 1) + ios.setDay(num.FromStr(buffer, num#DEC)) + ios.printnl + ios.print(string("Tag (1 - 31): ")) + ios.input(buffer, 2) + ios.setDate(num.FromStr(buffer, num#DEC)) + changed := 1 + + ios.printnl + ios.print(string("neue Uhrzeit eingeben? (j/n): ")) + if ios.keywait == "j" + ios.printnl + ios.print(string("Stunden (0 - 23): ")) + ios.input(buffer, 2) + ios.setHours(num.FromStr(buffer, num#DEC)) + ios.printnl + ios.print(string("Minuten (0 - 59): ")) + ios.input(buffer, 2) + ios.setMinutes(num.FromStr(buffer, num#DEC)) + ios.printnl + ios.print(string("Sekunden (0 - 59): ")) + ios.input(buffer, 2) + ios.setSeconds(num.FromStr(buffer, num#DEC)) + changed := 1 + + ios.printnl + ios.print(string("Datumsformat ändern? (j/n): ")) + if ios.keywait == "j" + ios.printnl + ios.print(string("Datumsformat (0-DE, 1-Canonical, 2-UK, 3-US): ")) + ios.input(buffer, 1) + ios.setNVSRAM(ios#NVRAM_DATEFORMAT, num.FromStr(buffer, num#DEC)) + ios.printnl + ios.print(string("Zeitformat (0-24, 1-12, 2-12UK): ")) + ios.input(buffer, 2) + ios.setNVSRAM(ios#NVRAM_TIMEFORMAT, num.FromStr(buffer, num#DEC)) + changed := 1 + + if changed == 1 + ios.printnl + ios.print(string("neues Datum: ")) + cmd_Date_long + ios.printnl + +DAT 'sys: helptext + + +help byte "/? : Hilfe",13 + byte "/d : Datum anzeigen",13 + byte "/l : Datum Langformat anzeigen",13 + byte "/t : Zeit anzeigen",13 + byte "/s : Datum/Zeit stellen",13 + byte 0 + +DAT 'lizenz + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/wplay.spin b/system/regnatix/wplay.spin new file mode 100644 index 0000000..ceb426b --- /dev/null +++ b/system/regnatix/wplay.spin @@ -0,0 +1,271 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : wplay +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : wav-player für kommandozeile +Komponenten : - +COG's : - +Logbuch : + +16-04-2010-dr235 - erste trios-version +21-04-2010-dr235 - pausenmodus & anzeige wav-position +29-04-2010-dr235 - /i eingefügt, da offensichtlich einige konwerter den len-parameter im header falsch setzen! + +Kommandoliste : + +/? : Hilfetext +/p name.wav : WAV-Datei abspielen +/d : Verzeichnis wiedergeben + : q - quit + : n - next + : p - pause +/l 0..100 : Lautstärke links +/r 0..100 : Lautstärke rechts +/i name.wav : Info zur Datei anzeigen + + +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +VAR + + byte fl_bye 'flag player beenden + byte parastr[64] 'parameterstring + byte fn[12] 'puffer für dateinamen + long datcnt 'zeiger für dateiliste + + +DAT 'PARAMETER + +PUB main + + ios.start 'ios initialisieren + ios.parastart 'parameterübergabe starten + ios.admsetsound(ios#SND_HSSOFF) 'hss ausschalten + ios.admsetsound(ios#SND_WAVON) 'wav einschalten + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: man wplay")) '/? + "p": play_wav '/p + "d": play_dir '/r + "l": set_lvol '/l + "r": set_rvol '/r + "i": print_info + ios.admsetsound(ios#SND_WAVOFF) 'wav ausschalten + ios.admsetsound(ios#SND_HSSON) 'hss anschalten + ios.stop + +DAT 'VOLUME + +PUB set_lvol + + if ios.paranext(@parastr) 'parameter? + ios.wav_lvol(str2dec(@parastr)) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PUB set_rvol + + if ios.paranext(@parastr) 'parameter? + ios.wav_rvol(str2dec(@parastr)) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PUB print_info|err + + if ios.paranext(@parastr) 'parameter? + if err := ios.sdopen("R",@parastr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + ios.sdseek(22) + ios.print(string(13,"Anzahl der Kanäle : ")) + ios.printdec(ios.sdgetc | (ios.sdgetc << 8)) + ios.sdseek(34) + ios.print(string(13,"Bits per Sample : ")) + ios.printdec(ios.sdgetc | (ios.sdgetc << 8)) + ios.sdseek(40) + ios.print(string(13,"Länge : ")) + ios.printdec(ios.sdgetc | (ios.sdgetc << 8) | (ios.sdgetc << 16) | (ios.sdgetc << 24)) + ios.printnl + ios.sdclose + + else 'kein parameter: fehlermeldung + printErr(@err1) + + +DAT 'PLAY_DIR + +PUB play_dir|stradr,len,fcnt,i 'hss: alle songs auf der sd-card abspielen + + ios.sddir 'kommando: verzeichnis öffnen + datcnt := 0 'zum listenanfang + fcnt := 0 'zähler für dateianzahl + fl_bye := 0 + repeat while (stradr := ios.sdnext) 'dateiliste einlesen + if str_find(stradr,@ext1) + fcnt++ + play_dir_wrlst(stradr) + ios.print(string("Anzahl Dateien : ")) + ios.printdec(fcnt) + ios.printnl + datcnt := 0 'zum listenanfang + repeat i from 0 to fcnt-1 'dateiliste abspielen + ios.printdec(i+1) + ios.printchar("/") + ios.printdec(fcnt) + ios.printtab + play_dir_rdlst(@fn) + play_dir_file(@fn) + if fl_bye 'player beenden + quit + ios.printnl + +PRI play_dir_file(stradr)|err + + ios.print(stradr) + ios.printchar(" ") + if err := ios.wav_play(stradr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + play_wav_status 'warten, solange wav gespielt wird (sd belegt) + ios.printnl + +PUB play_dir_wrlst(stradr)|len,i 'kopiert dateinamen in liste + len := strsize(stradr) + repeat i from 0 to len-1 + ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++) + ios.ram_wrbyte(ios#usrmod,0,datcnt++) + +PUB play_dir_rdlst(stradr)|i,n 'liest dateinamen aus list + i := 0 + repeat + n := ios.ram_rdbyte(ios#usrmod,datcnt++) + byte[stradr][i++] := n + while n <> 0 + +DAT 'PLAY_WAV + +PRI play_wav|err 'wav abspielen + + if ios.paranext(@parastr) 'parameter? + if err := ios.wav_play(@parastr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + play_wav_status 'warten, solange wav gespielt wird (sd belegt) + else 'kein parameter: fehlermeldung + printErr(@err1) + +PUB play_wav_status|status,curpos,key,l,p 'warten bis player fertig, oder abbruch + + ios.print(string(" : ")) + ios.curoff + curpos := ios.curgetx + repeat + status := ios.wav_status + ios.cursetx(curpos) + ios.printdec(ios.wav_len) + ios.printchar("/") + ios.printdec(ios.wav_pos) + ios.print(string(" ")) + if key := ios.key 'bei taste stopsignal an player senden + case key + "n": ios.wav_stop 'next wav + "p": ios.wav_pause 'pause + "q": fl_bye := 1 + ios.wav_stop + while status 'schleife solange player aktiv + ios.curon + +DAT 'TOOLS + +PRI printErr(stradr) + + ios.print(@err0) + ios.print(stradr) + ios.print(string("help: man wplay")) + +PUB str_find(string1, string2) : buffer | counter 'sys: string suchen + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches a string of characters for the first occurence of the specified string of characters. │ +'' │ │ +'' │ Returns the address of that string of characters if found and zero if not found. │ +'' │ │ +'' │ string1 - A pointer to the string of characters to search. │ +'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(string1--) + + if(byte[++string1] == byte[string2]) + + repeat counter from 0 to (strsize(string2) - 1) + + if(byte[string1][counter] <> byte[string2][counter]) + buffer~~ + + ifnot(buffer~) + return string1 + +PUB str2dec(stradr)|buffer,counter + + buffer := byte[stradr] + counter := (strsize(stradr) <# 11) + repeat while(counter--) + result *= 10 + result += lookdownz(byte[stradr++]: "0".."9") + if(buffer == "-") + -result + +DAT + +ext1 byte ".WAV",0 + +err0 byte 13,"Fehler : ",0 +err1 byte "Zu wenig Parameter!",13,0 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/regnatix/yplay.spin b/system/regnatix/yplay.spin new file mode 100644 index 0000000..0afb667 --- /dev/null +++ b/system/regnatix/yplay.spin @@ -0,0 +1,360 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Volker Pohlers +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : +System : TriOS +Name : yplay +Chip : Regnatix +Typ : Programm +Version : +Subversion : +Funktion : ay-ym-player für kommandozeile +Komponenten : - +COG's : - +Logbuch : + +17-08-2010-dr040 - start des projektes :) +22.08.2010-dr040 - Timing geändert + +Notizen : based on splay.bin by Ingo Kripahle + ,YM6player.spin by Juergen Buchmueller + +}} + +OBJ + ios : "reg-ios" + gc : "glob-con" 'globale konstanten + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + + +VAR + + byte fl_bye 'flag player beenden + byte parastr[64] 'parameterstring + byte fn[12] 'puffer für dateinamen + long datcnt 'zeiger für dateiliste + +VAR + byte buffer[128] + long nvbl + long attr + long ndrums + long clock + long rate + long loop + long extra + long bytes + long fileNumber + long nextsong + long wait + + +DAT 'PARAMETER + +PUB main + + ios.start 'ios initialisieren + +{ ios.startram 'ios initialisieren (f. Start aus Propeller Tool heraus) + ios.admload(@admsys) + ios.bus_putchar1(200) ' ay_start + play_dir +} + + ios.parastart 'parameterübergabe starten + if (ios.admgetspec & gc#A_AYS) + ios.bus_putchar1(200) ' ay_start + + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: man yplay")) '/? + "p": play_file '/p + "d": play_dir '/d + else + printErr(@err2) + + ios.bus_putchar1(201) ' ay_stop + ios.stop + +DAT 'PLAY_DIR + +PUB play_dir|stradr,len,fcnt,i 'alle songs auf der sd-card abspielen + + ios.sddir 'kommando: verzeichnis öffnen + datcnt := 0 'zum listenanfang + fcnt := 0 'zähler für dateianzahl + fl_bye := 0 + repeat while (stradr := ios.sdnext) 'dateiliste einlesen + if str_find(stradr,@ext1) + fcnt++ + play_dir_wrlst(stradr) + ios.print(string("Anzahl Dateien : ")) + ios.printdec(fcnt) + ios.printnl + datcnt := 0 'zum listenanfang + repeat i from 0 to fcnt-1 'dateiliste abspielen + ios.printdec(i+1) + ios.printchar("/") + ios.printdec(fcnt) + ios.printtab + play_dir_rdlst(@fn) + play_dir_file(@fn) + if fl_bye 'player beenden + quit + ios.printnl + +PRI play_file|err 'datei abspielen + + if ios.paranext(@parastr) 'parameter? + play_dir_file(@parastr) + else 'kein parameter: fehlermeldung + printErr(@err1) + + +PUB play_dir_wrlst(stradr)|len,i 'kopiert dateinamen in liste + len := strsize(stradr) + repeat i from 0 to len-1 + ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++) + ios.ram_wrbyte(ios#usrmod,0,datcnt++) + +PUB play_dir_rdlst(stradr)|i,n 'liest dateinamen aus list + i := 0 + repeat + n := ios.ram_rdbyte(ios#usrmod,datcnt++) + byte[stradr][i++] := n + while n <> 0 + +PRI play_dir_file(stradr)|err, k,curpos,key,vblframe,timecnt + + ios.print(stradr) + ios.printchar(" ") + ios.printnl + + openFile(stradr) +{ if err := ios.sid_sdmpplay(stradr) 'fehler bei start des players? + ios.print(@err0) 'fehlernummer ausgeben + ios.printdec(err) + else + play_status 'warten, solange wav gespielt wird (sd belegt) +} + + ios.print(string("Status : ")) + ios.curoff + curpos := ios.curgetx + + timecnt := cnt + + repeat + timecnt += clkFreq / rate + ios.sdeof ' eof? + ifnot ios.bus_getchar1 + + ios.sdgetblk(16, @buffer) + + ios.bus_putchar1(202) ' ay_updateRegisters + repeat k from 0 to 13 + ios.bus_putchar1(buffer[k]) + + waitcnt(timecnt) + + else + quit + + ios.cursetx(curpos) + ios.printdec(++vblframe) + ios.printchar("/") + ios.printdec(nvbl) + if key := ios.key 'bei taste stopsignal an player senden + case key + "n": quit + "q": fl_bye := 1 + quit + + ios.curon + ios.sdclose + ios.printnl + +DAT 'PLAY_AY + + +PRI get_word | buff + ios.sdgetblk(2, @buff) + return byte[@buff][0] << 8 + byte[@buff][1] + +PRI get_dword | buff + ios.sdgetblk(4, @buff) + return byte[@buff][0] << 24 + byte[@buff][1] << 16 + byte[@buff][2] << 8 + byte[@buff][3] + +PRI get_string | n + repeat n from 0 to 127 + if (buffer[n] := ios.sdgetc) =< 0 + buffer[n] := 0 + return + + +PUB openFile(filename) | i, j, m + + ios.sdopen( "R", filename ) + + ios.sdgetblk(4, @buffer) ' 00 - read "YM6!" header + ios.sdgetblk(8, @buffer) ' 04 - read "LeOnArD!" identifier + nvbl := get_dword ' 0c - number of VBL frames +' ios.print(string("VBL frames : ")) +' ios.printdec(nvbl) +' ios.printnl + attr := get_dword ' 10 - attributes +' ios.print(string("Attributes : ")) +' ios.printhex(attr,8) +' ios.printnl + ndrums := get_word ' 14 - number of digi drum samples +' ios.print(string("Digi-Drums : ")) +' ios.printdec(ndrums) +' ios.printnl + clock := get_dword ' 16 - YM2149 external frequency in Hz +' ios.print(string("Clock : ")) +' ios.printdec(clock) +' ios.printnl + rate := get_word ' 1a - player frequency in Hz +' ios.print(string("Play rate : ")) +' ios.printdec(rate) +' ios.printnl + loop := get_dword ' 1c - frame where looping starts +' ios.print(string("Loop : ")) +' ios.printdec(loop) +' ios.printnl + extra := get_word ' 20 - extra bytes following (should be 0) +' ios.print(string("Extra : ")) +' ios.printdec(extra) +' ios.printnl + + ' skip over extra data + repeat while extra > 0 + m := extra <# 128 + ios.sdgetblk(m, @buffer) + extra -= m + if ndrums > 0 + ' read digi drum samples + repeat ndrums + bytes := get_dword + repeat while bytes > 0 + m := bytes <# 128 + ios.sdgetblk(m, @buffer) + bytes -= m + + get_string ' read song name + ios.print(string("Song name : ")) + ios.print(@buffer) + ios.printnl + get_string ' read author name + ios.print(string("Author : ")) + ios.print(@buffer) + ios.printnl + get_string ' read comments / software + ios.print(string("Comments : ")) + ios.print(@buffer) + ios.printnl + + +PUB play_status|status,curpos,key,l,p 'warten bis player fertig, oder abbruch + + ios.print(string("Status : ")) + ios.curoff + curpos := ios.curgetx + repeat + status := ios.sid_dmpstatus + ios.cursetx(curpos) + ios.printdec(ios.sid_dmplen) + ios.printchar("/") + ios.printdec(ios.sid_dmppos) + if key := ios.key 'bei taste stopsignal an player senden + case key + "n": ios.sid_dmpstop 'next wav + "p": ios.sid_dmppause 'pause + "q": fl_bye := 1 + ios.sid_dmpstop + while status 'schleife solange player aktiv + ios.sid_mute(3) + ios.curon + + +DAT 'TOOLS + +PRI printErr(stradr) + + ios.print(@err0) + ios.print(stradr) + ios.print(string("help: man yplay")) + +PUB str_find(string1, string2) : buf | counter 'sys: string suchen + +'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +'' │ Searches a string of characters for the first occurence of the specified string of characters. │ +'' │ │ +'' │ Returns the address of that string of characters if found and zero if not found. │ +'' │ │ +'' │ string1 - A pointer to the string of characters to search. │ +'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │ +'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + + repeat strsize(string1--) + + if(byte[++string1] == byte[string2]) + + repeat counter from 0 to (strsize(string2) - 1) + + if(byte[string1][counter] <> byte[string2][counter]) + buf~~ + + ifnot(buf~) + return string1 + +PUB str2dec(stradr)|buf,counter + + buf := byte[stradr] + counter := (strsize(stradr) <# 11) + repeat while(counter--) + result *= 10 + result += lookdownz(byte[stradr++]: "0".."9") + if(buf == "-") + -result + +DAT + +admsys byte "admym.adm",0 + +ext1 byte ".YM",0 + +err0 byte 13,"Fehler : ",0 +err1 byte "Zu wenig Parameter!",13,0 +err2 byte "Administra-Code unterstützt keine AY/YM-Emulation!",13,0 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/system/sonstiges/BLUE.COL b/system/sonstiges/BLUE.COL new file mode 100644 index 0000000..0d8d9d8 --- /dev/null +++ b/system/sonstiges/BLUE.COL @@ -0,0 +1 @@ +<<<<0000<<<< \ No newline at end of file diff --git a/system/sonstiges/BW.COL b/system/sonstiges/BW.COL new file mode 100644 index 0000000..ecbace2 Binary files /dev/null and b/system/sonstiges/BW.COL differ diff --git a/system/sonstiges/BWHALF.COL b/system/sonstiges/BWHALF.COL new file mode 100644 index 0000000..d23a6fe Binary files /dev/null and b/system/sonstiges/BWHALF.COL differ diff --git a/system/sonstiges/CHESS.COL b/system/sonstiges/CHESS.COL new file mode 100644 index 0000000..1bd21ce Binary files /dev/null and b/system/sonstiges/CHESS.COL differ diff --git a/system/sonstiges/GREEN.COL b/system/sonstiges/GREEN.COL new file mode 100644 index 0000000..30cd71d Binary files /dev/null and b/system/sonstiges/GREEN.COL differ diff --git a/system/sonstiges/PAR.COL b/system/sonstiges/PAR.COL new file mode 100644 index 0000000..6ead846 Binary files /dev/null and b/system/sonstiges/PAR.COL differ diff --git a/system/sonstiges/eram.man b/system/sonstiges/eram.man new file mode 100644 index 0000000..6fec287 --- /dev/null +++ b/system/sonstiges/eram.man @@ -0,0 +1,34 @@ + +cls - bildschirm lschen +bye - player beenden +d - anzeige eram +n - anzeige fortsetzen +s - sucht wert +m ... - ram modifizieren (byte) +l ... - ram modifizieren (long) +load - ladei datei in eram +sysvar - anzeige systemvariablen +rbas - basisadresse setzen +info - speicheraufteilung anzeigen +f - speicherbereich fllen (sysmod) +fu - speicherbereich fllen (usermod) +xinit - rdisk initialisieren +xnew - neue datei anlegen +xhead - header anzeigen +xdir - dir anzeigen +xdel - datei lschen +xren - datei umbenennen +xftab - ftab anzeigen +xopen - datei ffnen +xseek - zeiger positionieren +xput - zeichen in datei schreiben +xget - zeichenh aus datei lesen +xwrite - wert schreiben +xread - wert lesen +xload - datei in rd laden +xsave - datei fn1 auf sd fn2 speichern + +bas - basisadresse +end - endadresse (startsysvar) +sys - start systemvariablen +rd: - daten datei diff --git a/system/sonstiges/error.man b/system/sonstiges/error.man new file mode 100644 index 0000000..3788b8d --- /dev/null +++ b/system/sonstiges/error.man @@ -0,0 +1,40 @@ + +Reset-Fehlercodes: + +0011FFFF - stack overflow +0012FFFF - return stack overflow +0021FFFF - stack underflow +0022FFFF - return stack underflow +8100FFFF - no free cogs +8200FFFF - no free main memory +8400FFFF - fl no free main memory +8500FFFF - no free cog memory +8800FFFF - eeprom write error +9000FFFF - eeprom read error + +.err-Fehlercodes: + +0 no error +1 fsys unmounted +2 fsys corrupted +3 fsys unsupported +4 not found +5 file not found +6 dir not found +7 file read only +8 end of file +9 end of directory +10 end of root +11 dir is full +12 dir is not empty +13 checksum error +14 reboot error +15 bpb corrupt +16 fsi corrupt +17 dir already exist +18 file already exist +19 out of disk free space +20 disk io error +21 command not found +22 timeout +23 parameter error diff --git a/system/sonstiges/flash.man b/system/sonstiges/flash.man new file mode 100644 index 0000000..433d868 --- /dev/null +++ b/system/sonstiges/flash.man @@ -0,0 +1,10 @@ +/? : Hilfe +/fh : Datei in HI-ROM flashen +/fl : Datei in LO-ROM flashen +/dh : Dump HI-ROM +/dl : Dump LO-ROM +/vh : Vergleich Datei <--> HI-ROM +/ch : HI-ROM lschen +/cl : LO-ROM lschen +/sh : HI-ROM speichern +/sl : LO-ROM speichern diff --git a/system/sonstiges/fm.man b/system/sonstiges/fm.man new file mode 100644 index 0000000..2156b53 --- /dev/null +++ b/system/sonstiges/fm.man @@ -0,0 +1,21 @@ +linkes fenster - sd-card +rechtes fenster - ramdisk + +pfeiltasten - cursor bewegen +bild hoch/runter - nächste/vorige fensterseite +return - verzeichnis öffnen +backspace - verzeichnis schließen +space - eintrag selektieren +tab - fenster wechseln +pos1 - cursor auf ersten eintrag + +f1 - textdatei anzeigen +f2 - selektierte dateien auf sd löschen +f3 - selektierte dateien von sd in ram laden +f4 - selektierte dateien von ram auf sd speichern +f5 - gesamten ram löschen +f6 - sd auswerfen +f7 - verzeichnis erstellen +f8 - alle einträge selektieren/deselektieren +f9 - lenkes fenster maximieren/verkleinern +f10 - filemanager verlassen diff --git a/system/sonstiges/hplay.man b/system/sonstiges/hplay.man new file mode 100644 index 0000000..0f992aa --- /dev/null +++ b/system/sonstiges/hplay.man @@ -0,0 +1,7 @@ +/? : hilfetext +/p name.wav : hss-datei abspielen +/d : verzeichnis abspielen +/s : wiedergabe stoppen +/t : anzeige trackerliste +/r : anzeige engine-register +/i : anzeige interface-register diff --git a/system/sonstiges/regime.man b/system/sonstiges/regime.man new file mode 100644 index 0000000..9e72c77 --- /dev/null +++ b/system/sonstiges/regime.man @@ -0,0 +1,57 @@ +help - diese hilfe + - bin/adm/bel-datei wird gestartet +mount - sd-card mounten +unmount - sd-card abmelden +dir wh - verzeichnis anzeigen +type - anzeige einer textdatei +aload - administra-code laden +bload - bellatrix-treiber laden +rload - regnatix-code laden +del - datei lschen +cls - bildschirm lschen +free - freier speicher auf sd-card +attrib ashr - attribute ndern +cd - verzeichnis wechseln +mkdir - verzeichnis erstellen +rename - datei/verzeichnis umbenennen +format - sd-card formatieren +reboot - hive neu starten +sysinfo - systeminformationen +color <0..7> - farbe whlen +cogs - belegung der cogs anzeigen +dmlist - anzeige der verzeichnis-marker +dm - in das entsprechende marker- + verzeichnis wechseln +dmset - setzt den entsprechenden marker + auf das aktuelle verzeichnis +dmclr - marker lschen +forth - forth starten + +marker: +r - root-verzeichnis +s - system-verzeichnis +u - user-verzeichnis +a/b/c - benutzerdefinierte verzeichnismarker +r, s, u-marker werden vom system automatisch gesetzt und +intern verwendet. + +RAMDISK: + +xload - datei in ram laden +xsave - datei aus ram speichern +xdir - verzeichnis im ram anzeigen +xrename - datei im ram umbenennen +xdel - datei im ram lschen +xtype - text im ram anzeigen + +EXTERNE KOMMANDOS: + +sysconf - systemeinstellungen +hplay - hss-player +wplay - wav-player +sfxtool - hss-soundeffekte erstellen + +vga.bel - vga 1024 x 768 pixel, 64 x 24 zeichen +htext.bel - vga 1024 x 768 pixel, 128 x 48 zeichen +tv.bel - tv-textmodus 40 x 13 zeichen + diff --git a/system/sonstiges/splay.man b/system/sonstiges/splay.man new file mode 100644 index 0000000..55039e9 --- /dev/null +++ b/system/sonstiges/splay.man @@ -0,0 +1,8 @@ +/? : Hilfetext +/m name.dmp : DMP-Datei mono auf SID2 abspielen +/s name.dmp : DMP-Datei stereo auf beiden SIDs abspielen +/d : Verzeichnis wiedergeben + q - quit + n - next + p - pause + diff --git a/system/sonstiges/sysconf.man b/system/sonstiges/sysconf.man new file mode 100644 index 0000000..ba0a18b --- /dev/null +++ b/system/sonstiges/sysconf.man @@ -0,0 +1,18 @@ +/? : Hilfe +/l : Konfiguration anzeigen +----------- Administra-Funktionen +/ah 0|1 : hss ab-/anschalten +/aw 0|1 : wav ab-/anschalten +/as 0|1 : systemklnge ab-/anschalten +/al 0..100 : wav-lautstrke links +/ar 0..100 : wav-lautstrke rechts +/ah 0..15 : hss-lautstrke +/af : administra reset, flash booten +/at : transfergeschwindigkeit messen +----------- Bellatrix-Funktionen +/ci : farbtabelle anzeigen +/cs datei : farbtabelle speichern +/cl datei : farbtabelle laden +----------- Port-Funktionen +/po nr anz : Impulse an port ausgeben +/pi : Status der Port abfragen \ No newline at end of file diff --git a/system/sonstiges/test1.txt b/system/sonstiges/test1.txt new file mode 100644 index 0000000..b5aa1b3 --- /dev/null +++ b/system/sonstiges/test1.txt @@ -0,0 +1,7 @@ + +"Die Bltentrume +Von Faltern, wie ich hrte, +So lautlos wie sie -" +Reikan + + diff --git a/system/sonstiges/test2.txt b/system/sonstiges/test2.txt new file mode 100644 index 0000000..bd9d21b --- /dev/null +++ b/system/sonstiges/test2.txt @@ -0,0 +1,115 @@ +Johann Wolfgang Goethe + +Der Zauberlehrling + +Hat der alte Hexenmeister +Sich doch einmal wegbegeben! +Und nun sollen seine Geister +Auch nach meinem Willen leben! +Seine Wort' und Werke +Merkt' ich und den Brauch, +Und mit Geistesstrke +Tu' ich Wunder auch. + +Walle! Walle +Manche Strecke, +Dass, zum Zwecke, +Wasser fliee +Und mit reichem, vollem Schwalle +Zu dem Bade sich ergiee. + +Und nun komm, du alter Besen! +Nimm die schlechten Lumpenhllen! +Bist schon lange Knecht gewesen; +Nun erflle meinen Willen! +Auf zwei Beinen stehe, +Oben sei ein Kopf, +Eile nun und gehe +Mit dem Wassertopf! + +Walle! Walle +Manche Strecke, +Dass, zum Zwecke, +Wasser fliee +Und mit reichem, vollem Schwalle +Zu dem Bade sich ergiee. + +Seht, er luft zum Ufer nieder; +Wahrlich! ist schon an dem Flusse, +Und mit Blitzesschnelle wieder +Ist er hier mit raschem Gusse. +Schon zum zweiten Male! +Wie das Becken schwillt! +Wie sich jede Schale +Voll mit Wasser fllt! + +Stehe! Stehe! +Denn wir haben +Deiner Gaben +Voll gemessen! +Ach, ich merk' es! Wehe! Wehe! +Hab' ich doch das Wort vergessen! + +Ach, das Wort, worauf am Ende +Er das wird, was er gewesen. +Ach, er luft und bringt behnde! +Wrst du doch der alte Besen! +Immer neue Gsse +Bringt er schnell herein, +Ach! und hundert Flsse +Strzen auf mich ein. + +Nein, nicht lnger +Kann ich's lassen; +Will ihn fassen. +Das ist Tcke! +Ach! nun wird mir immer bnger! +Welche Miene! Welche Blicke! + +Oh, du Ausgeburt der Hlle! +Soll das ganze Haus ersaufen? +Seh' ich ber jede Schwelle +Doch schon Wasserstrme laufen. +Ein verruchter Besen, +Der nicht hren will! +Stock, der du gewesen, +Steh doch wieder still! + +Willst's am Ende +Gar nicht lassen? +Will dich fassen, +Will dich halten +Und das alte Holz behnde +Mit dem scharfen Beile spalten. + +Seht, da kommt er schleppend wieder! +Wie ich mich nun auf dich werfe, +Gleich, o Kobold, liegst du nieder; +Krachend trifft die glatte Schrfe! +Wahrlich, brav getroffen! +Seht, er ist entzwei! +Und nun kann ich hoffen +Und ich atme frei! + +Wehe! Wehe! +Beide Teile +Stehn in Eile +Schon als Knechte +Vllig fertig in die Hhe! +Helft mir, ach! ihr hohen Mchte! + +Und sie laufen! Nass und nsser +Wird's im Saal und auf den Stufen. +Welch entsetzliches Gewsser! +Herr und Meister! Hr' mich rufen! - +Ach, da kommt der Meister! +Herr, die Not ist gro! +Die ich rief, die Geister, +Werd' ich nun nicht los. + +In die Ecke, +Besen! Besen! +Seid's gewesen! +Denn als Geister +Ruft euch nur, zu seinem Zwecke, +Erst hervor der alte Meister." \ No newline at end of file diff --git a/system/sonstiges/wplay.man b/system/sonstiges/wplay.man new file mode 100644 index 0000000..ea4a353 --- /dev/null +++ b/system/sonstiges/wplay.man @@ -0,0 +1,9 @@ +/? : Hilfetext +/p name.wav : WAV-Datei abspielen +/d : Verzeichnis wiedergeben + q - quit + n - next + p - pause +/l 0..100 : Lautstrke links +/r 0..100 : Lautstrke rechts +/i name.wav : Info zur Datei anzeigen diff --git a/system/sonstiges/yplay.man b/system/sonstiges/yplay.man new file mode 100644 index 0000000..393e25e --- /dev/null +++ b/system/sonstiges/yplay.man @@ -0,0 +1,8 @@ +Wiedergabe von YM-Dateien mittels AY-3-891X / YM2149 emulator + +/? : Hilfetext +/p name.YM : YM-Datei abspielen +/d : Verzeichnis wiedergeben + q - quit + n - next + p - pause