{{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 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 : 02 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 Komponenten : - COG's : - Logbuch : 13-03-2009-dr235 - string für parameterübergabe zwischen programmen im eram eingerichtet 19-11-2008-dr235 - erste version aus dem ispin-projekt extrahiert 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 03-12-2010-stephan - Date Time Funktionen 04-12-2010-stephan - NVRAM Funktionen Kommandoliste : Notizen : --------------------------------------------------------------------------------------------------------- }} 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 = $C8 'tastaturcode backspace CHAR_TER_BS = $102 'terminalcode backspace CHAR_ESC = $1B KEY_CTRL = $02 KEY_ALT = $04 KEY_OS = $08 CON 'Systemvariablen '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 = %00000110_11111111_11111111_00000000 'maske: dbus-eingabe DB_OUT = %00000110_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 CON 'ADMINISTRA-FUNKTIONEN -------------------------------------------------------------------------- 'chip-managment #92, AMGR_SETSOUND AMGR_GETSPEC AMGR_SETSYSSOUND AMGR_GETSOUNDSYS AMGR_ALOAD AMGR_GETCOGS AMGR_GETVER AMGR_REBOOT AMGR_DEBUG = 255 'soundeinstellungen #0, SND_HSSOFF SND_HSSON SND_WAVOFF SND_WAVON 'sdcard-funktionen #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 'plexbus-funktionen #31, P_OPEN P_CLOSE P_PUT P_GET P_RESET 'RTC - Datums und Zeitfunktionen #41, RTC_GETSECONDS 'Returns the current second (0 - 59) from the real time clock. RTC_GETMINUTES 'Returns the current minute (0 - 59) from the real time clock. RTC_GETHOURS 'Returns the current hour (0 - 23) from the real time clock. RTC_GETDAY 'Returns the current day (1 - 7) from the real time clock. RTC_GETDATE 'Returns the current date (1 - 31) from the real time clock. RTC_GETMONTH 'Returns the current month (1 - 12) from the real time clock. RTC_GETYEAR 'Returns the current year (2000 - 2099) from the real time clock. RTC_SETSECONDS 'Sets the current real time clock seconds. RTC_SETMINUTES 'Sets the current real time clock minutes. RTC_SETHOURS 'Sets the current real time clock hours. RTC_SETDAY 'Sets the current real time clock day. RTC_SETDATE 'Sets the current real time clock date. RTC_SETMONTH 'Sets the current real time clock month. RTC_SETYEAR 'Sets the current real time clock year. RTC_SETNVSRAM 'Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). RTC_GETNVSRAM 'Gets the selected NVSRAM value at the index (0 - 55). RTC_PAUSEFORSECONDS 'Pauses execution for a number of seconds. RTC_PAUSEFORMILLISECONDS 'Pauses execution for a number of milliseconds. #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 'hss-funktionen #100, CHSS_LOAD CHSS_PLAY CHSS_STOP CHSS_PAUSE CHSS_PEEK CHSS_INTREG CHSS_VOL CSFX_FIRE CSFX_SETSLOT 'wav-funktionen #150, SDW_START 'wav direkt von sdcard abspielen SDW_STOP SDW_STATUS SDW_LVOL SDW_RVOL SDW_PAUSE SDW_POS 'sidcog-funktionen #157, SCOG_MDMPPLAY 'dmp auf sid2 von sdcard abspielen SCOG_SDMPPLAY SCOG_DMPSTOP SCOG_DMPPAUSE SCOG_DMPSTATUS SCOG_DMPPOS SCOG_MUTE SCOG1_setRegister SCOG1_updateRegisters SCOG1_setVolume SCOG1_play SCOG1_noteOn SCOG1_noteOff SCOG1_setFreq SCOG1_setWaveform SCOG1_setPWM SCOG1_setADSR SCOG1_setResonance SCOG1_setCutoff SCOG1_setFilterMask SCOG1_setFilterType SCOG1_enableRingmod SCOG1_enableSynchronization SCOG2_setRegister SCOG2_updateRegisters SCOG2_setVolume SCOG2_play SCOG2_noteOn SCOG2_noteOff SCOG2_setFreq SCOG2_setWaveform SCOG2_setPWM SCOG2_setADSR SCOG2_setResonance SCOG2_setCutoff SCOG2_setFilterMask SCOG2_setFilterType SCOG2_enableRingmod SCOG2_enableSynchronization '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 -------------------------------------------------------------------------- #0, BEL_CMD KEY_STAT KEY_GET PRN_CTRL KEY_FKEY PRN_LOGO #90, BMGR_GETCOLOR BMGR_SETCOLOR BMGR_GETRESX BMGR_GETRESY BMGR_GETCOLS BMGR_GETROWS BMGR_GETCOGS BMGR_GETSPEC BMGR_GETVER BMGR_REBOOT ' +---------- ' | +------- 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 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 OBJ ' debugx : "pterm" 'debug PUB start: wflag | i 'system: ios initialisieren ''funktionsgruppe : system ''funktion : ios initialisieren ''eingabe : - ''ausgabe : wflag - 0: kaltstart '' : 1: warmstart ''busprotokoll : - bus_init 'bus initialisieren 'debugverbindung 'debugx.start(115200) ' Start des Debug-Terminals 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 rbas := ram_rdlong(sysmod,RAMBAS) rend := ram_rdlong(sysmod,RAMEND) i := BELDRIVE repeat 12 ram_wrbyte(sysmod,0,i++) 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 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) 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 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(AMGR_SETSOUND) 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(AMGR_SETSYSSOUND) 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(AMGR_GETSOUNDSYS) 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(AMGR_ALOAD) '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(AMGR_GETVER) 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(AMGR_GETSPEC) 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(AMGR_GETCOGS) 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(AMGR_REBOOT) PUB admdebug: wert 'chip-mgr: debug-funktion bus_putchar1(AMGR_DEBUG) wert := bus_getlong1 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(SD_MOUNT) err := bus_getchar1 PUB sddir 'sd-card: verzeichnis wird geöffnet ''funktionsgruppe : sdcard ''funktion : verzeichnis öffnen ''busprotokoll : [002] bus_putchar1(SD_DIROPEN) 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(SD_NEXTFILE) '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(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 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(SD_CLOSE) 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(SD_GETC) char := bus_getchar1 PUB sdputc(char) 'sd-card: zeichen in datei schreiben {{sdputc(char) - sd-card: zeichen in datei schreiben}} bus_putchar1(SD_PUTC) 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(SD_EOF) 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(SD_GETBLK) 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(SD_PUTBLK) 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(SD_GETBLK) 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(SD_PUTBLK) 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(SD_SEEK) 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(SD_FATTRIB) 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(SD_VOLNAME) '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(SD_CHECKMOUNTED) 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(SD_CHECKOPEN) 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(SD_CHECKUSED) 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(SD_CHECKFREE) 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(SD_NEWFILE) 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(SD_NEWDIR) 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(SD_DEL) 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(SD_RENAME) 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(SD_CHATTRIB) 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(SD_CHDIR) 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(SD_FORMAT) 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(SD_UNMOUNT) 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(SD_DMACT) 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(SD_DMSET) 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(SD_DMGET) 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(SD_DMCLR) 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(SD_DMPUT) bus_putchar1(marker) bus_putlong1(status) CON ''------------------------------------------------- PlexBus PUB plx_open(plxnr):err 'plx: plexus öffnen bus_putchar1(P_OPEN) bus_putchar1(plxnr) err := bus_getchar1 PUB plx_close:err 'plx: plexus schliessen bus_putchar1(P_CLOSE) err := bus_getchar1 PUB plx_put(char) 'plx: zeichen an plexus senden bus_putchar1(P_PUT) bus_putchar1(char) PUB plx_get:char 'plx: zeichen vom plexus empfangen bus_putchar1(P_GET) char := bus_getchar1 PUB plx_reset 'plx: plexbus rücksetzen bus_putchar1(P_RESET) CON ''------------------------------------------------- DATE TIME FUNKTIONEN PUB getSeconds 'Returns the current second (0 - 59) from the real time clock. bus_putchar1(RTC_GETSECONDS) return bus_getlong1 PUB getMinutes 'Returns the current minute (0 - 59) from the real time clock. bus_putchar1(RTC_GETMINUTES) return bus_getlong1 PUB getHours 'Returns the current hour (0 - 23) from the real time clock. bus_putchar1(RTC_GETHOURS) return bus_getlong1 PUB getDay 'Returns the current day (1 - 7) from the real time clock. bus_putchar1(RTC_GETDAY) return bus_getlong1 PUB getDate 'Returns the current date (1 - 31) from the real time clock. bus_putchar1(RTC_GETDATE) return bus_getlong1 PUB getMonth 'Returns the current month (1 - 12) from the real time clock. bus_putchar1(RTC_GETMONTH) return bus_getlong1 PUB getYear 'Returns the current year (2000 - 2099) from the real time clock. bus_putchar1(RTC_GETYEAR) 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(RTC_SETSECONDS) 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(RTC_SETMINUTES) 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(RTC_SETHOURS) 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(RTC_SETDAY) 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(RTC_SETDATE) 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(RTC_SETMONTH) 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(RTC_SETYEAR) 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(RTC_SETNVSRAM) 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(RTC_GETNVSRAM) 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(RTC_PAUSEFORSECONDS) 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(RTC_PAUSEFORMILLISECONDS) 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(CHSS_STOP) PUB hss_pause 'hss: pausiert aktuellen song ''funktionsgruppe : hss ''funktion : hss-player pause (funktion noch unklar) bus_putchar1(CHSS_PAUSE) 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(CHSS_LOAD) 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(CHSS_PLAY) 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(CHSS_VOL) 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(CHSS_PEEK) '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(CHSS_INTREG) '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(CSFX_SETSLOT) 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..f5 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 :) bus_putchar1(CSFX_FIRE) bus_putchar1(slot) 'slotnummer senden bus_putchar1(chan) 'channel 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(SDW_START) 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(SDW_STOP) 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(SDW_STATUS) 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(SDW_LVOL) 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(SDW_RVOL) 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(SDW_PAUSE) 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(SDW_POS) 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(SDW_POS) 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(SCOG_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(SCOG_SDMPPLAY) bus_putstr1(stradr) err := bus_getchar1 PUB sid_dmpstop bus_putchar1(SCOG_DMPSTOP) PUB sid_dmppause bus_putchar1(SCOG_DMPPAUSE) PUB sid_dmpstatus: status bus_putchar1(SCOG_DMPSTATUS) status := bus_getchar1 PUB sid_dmppos: wert bus_putchar1(SCOG_DMPPOS) wert := bus_getlong1 bus_getlong1 PUB sid_dmplen: wert bus_putchar1(SCOG_DMPPOS) bus_getlong1 wert := bus_getlong1 PUB sid_mute(sidnr) 'sid: chips stummschalten bus_putchar1(SCOG_MUTE) bus_putchar1(sidnr) CON ''------------------------------------------------- SIDCog1-Funktionen PUB sid1_setRegister(reg,val) bus_putchar1(SCOG1_setRegister) bus_putchar1(reg) bus_putchar1(val) PUB sid1_updateRegisters(regadr)|i bus_putchar1(SCOG1_setRegister) repeat 25 bus_putchar1(byte[regadr++]) PUB sid1_setVolume(vol) bus_putchar1(SCOG1_setVolume) bus_putchar1(vol) PUB sid1_play(channel, freq, waveform, attack, decay, sustain, release) bus_putchar1(SCOG1_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(SCOG1_noteOn) bus_putchar1(channel) bus_putlong1(freq) PUB sid1_noteOff(channel) bus_putchar1(SCOG1_noteOff) bus_putchar1(channel) PUB sid1_setFreq(channel,freq) bus_putchar1(SCOG1_setFreq) bus_putchar1(channel) bus_putlong1(freq) PUB sid1_setWaveform(channel,waveform) bus_putchar1(SCOG1_setWaveform) bus_putchar1(channel) bus_putchar1(waveform) PUB sid1_setPWM(channel, val) bus_putchar1(SCOG1_setPWM) bus_putchar1(channel) bus_putlong1(val) PUB sid1_setADSR(channel, attack, decay, sustain, release ) bus_putchar1(SCOG1_setADSR) bus_putchar1(channel) bus_putchar1(attack) bus_putchar1(decay) bus_putchar1(sustain) bus_putchar1(release) PUB sid1_setResonance(val) bus_putchar1(SCOG1_setResonance) bus_putchar1(val) PUB sid1_setCutoff(freq) bus_putchar1(SCOG1_setCutoff) bus_putlong1(freq) PUB sid1_setFilterMask(ch1,ch2,ch3) bus_putchar1(SCOG1_setFilterMask) bus_putchar1(ch1) bus_putchar1(ch2) bus_putchar1(ch3) PUB sid1_setFilterType(lp,bp,hp) bus_putchar1(SCOG1_setFilterType) bus_putchar1(lp) bus_putchar1(bp) bus_putchar1(hp) PUB sid1_enableRingmod(ch1,ch2,ch3) bus_putchar1(SCOG1_enableRingmod) bus_putchar1(ch1) bus_putchar1(ch2) bus_putchar1(ch3) PUB sid1_enableSynchronization(ch1,ch2,ch3) bus_putchar1(SCOG1_enableSynchronization) bus_putchar1(ch1) bus_putchar1(ch2) bus_putchar1(ch3) CON ''------------------------------------------------- SIDCog2-Funktionen PUB sid2_setRegister(reg,val) bus_putchar1(SCOG2_setRegister) bus_putchar1(reg) bus_putchar1(val) PUB sid2_updateRegisters(regadr)|i bus_putchar1(SCOG2_setRegister) repeat 25 bus_putchar1(byte[regadr++]) PUB sid2_setVolume(vol) bus_putchar1(SCOG2_setVolume) bus_putchar1(vol) PUB sid2_play(channel, freq, waveform, attack, decay, sustain, release) bus_putchar1(SCOG2_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(SCOG2_noteOn) bus_putchar1(channel) bus_putlong1(freq) PUB sid2_noteOff(channel) bus_putchar1(SCOG2_noteOff) bus_putchar1(channel) PUB sid2_setFreq(channel,freq) bus_putchar1(SCOG2_setFreq) bus_putchar1(channel) bus_putlong1(freq) PUB sid2_setWaveform(channel,waveform) bus_putchar1(SCOG2_setWaveform) bus_putchar1(channel) bus_putchar1(waveform) PUB sid2_setPWM(channel, val) bus_putchar1(SCOG2_setPWM) bus_putchar1(channel) bus_putlong1(val) PUB sid2_setADSR(channel, attack, decay, sustain, release ) bus_putchar1(SCOG2_setADSR) bus_putchar1(channel) bus_putchar1(attack) bus_putchar1(decay) bus_putchar1(sustain) bus_putchar1(release) PUB sid2_setResonance(val) bus_putchar1(SCOG2_setResonance) bus_putchar1(val) PUB sid2_setCutoff(freq) bus_putchar1(SCOG2_setCutoff) bus_putlong1(freq) PUB sid2_setFilterMask(ch1,ch2,ch3) bus_putchar1(SCOG2_setFilterMask) bus_putchar1(ch1) bus_putchar1(ch2) bus_putchar1(ch3) PUB sid2_setFilterType(lp,bp,hp) bus_putchar1(SCOG2_setFilterType) bus_putchar1(lp) bus_putchar1(bp) bus_putchar1(hp) PUB sid2_enableRingmod(ch1,ch2,ch3) bus_putchar1(SCOG2_enableRingmod) bus_putchar1(ch1) bus_putchar1(ch2) bus_putchar1(ch3) PUB sid2_enableSynchronization(ch1,ch2,ch3) bus_putchar1(SCOG2_enableSynchronization) bus_putchar1(ch1) bus_putchar1(ch2) bus_putchar1(ch3) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_SETCOLOR) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETCOLOR) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETRESX) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETRESY) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETCOLS) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETROWS) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETVER) 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(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETSPEC) spec := bus_getlong2 PUB belgetcogs:belcogs 'chip-mgr: verwendete cogs abfragen bus_putchar2(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_GETCOGS) 'code 5 = freie cogs belcogs := bus_getchar2 'statuswert empfangen PUB belreset 'chip-mgr: bellatrix reset {{breset - bellatrix neu starten}} bus_putchar2(BEL_CMD) 'kommandosequenz einleiten bus_putchar2(BMGR_REBOOT) 'code 99 = reboot PUB belload(stradr)| n,rc,ii,plen 'chip-mgr: neuen bellatrix-code booten belreset 'bellatrix neu starten waitcnt(cnt + 200_000_000) 'warte bis bel fertig ist bload(stradr) waitcnt(cnt + 200_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($0) 'kommandosequenz einleiten bus_putchar2($2) 'code 2 = tastenwert holen wert := bus_getchar2 'tastenwert empfangen PUB keyspec:wert 'key: statustasten zum letzten tastencode bus_putchar2($0) 'kommandosequenz einleiten bus_putchar2($4) 'code 2 = tastenwert holen wert := bus_getchar2 'wert empfangen PUB keystat:status 'key: übergibt tastaturstatus {{keystat:status - key: übergibt tastaturstatus}} bus_putchar2($0) 'kommandosequenz einleiten bus_putchar2($1) '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 printctrl(CHAR_TER_BS) i-- byte[stradr][i] := 0 elseif i < anz 'normales zeichen printchar(n) byte[stradr][i] := n i++ byte[stradr][i] := 0 CON ''------------------------------------------------- SCREEN 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 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(0) bus_putchar2(6) bus_putchar2(c) c2 := c PUB printctrl(c) 'screen: steuerzeichen ($100 bis $1FF) auf bildschirm ausgeben {{printctrl(c) - screen: steuerzeichen von $100 bis $1FF wird an terminal gesendet}} bus_putchar2($0) 'kommandosequenz einleiten bus_putchar2($3) 'code 3 = sonderzeichen senden bus_putchar2(c & $0FF) 'unteres byte senden ' PUB printnl 'screen: $0D - CR ausgeben {{printnl - screen: $0D - CR ausgeben}} bus_putchar2(CHAR_NL) PUB printcls 'screen: screen löschen {{printcls - screen: screen löschen}} printctrl($00) PUB printlogo(x,y) 'screen: logo ausgeben bus_putchar2($0) 'kommandosequenz einleiten bus_putchar2(PRN_LOGO) 'logo ausgeben bus_putchar2(x) bus_putchar2(y) PUB curhome 'screen: cursorposition auf erste position setzen {{curhome - screen: cursorposition auf erste position setzen}} printctrl($01) PUB printtab 'screen: zur nächsten tabulatorposition {{printtab - screen: zur nächsten tabulatorposition}} printctrl($03) PUB curchar(char) 'screen: setzt cursorzeichen {{curchar - screen: setzt cursorzeichen}} printctrl($04) bus_putchar2(char) PUB curpos1 'screen: setzt cursor auf spalte 1 in zeile {{curpos1 - screen: setzt cursor auf spalte 1 in zeile}} printctrl($05) PUB cursetx(x) 'screen: setzt cursorposition auf x {{cursetx - screen: setzt cursorposition auf x}} printctrl($06) bus_putchar2(x) PUB cursety(y) 'screen: setzt cursorposition auf y {{cursety - screen: setzt cursorposition auf y}} printctrl($07) bus_putchar2(y) PUB curgetx: x 'screen: abfrage x-position cursor {{curgetx: x - 'screen: abfrage x-position cursor}} printctrl($08) return bus_getchar2 PUB curgety: y 'screen: abfrage y-position cursor {{curgetx: y - 'screen: abfrage y-position cursor}} printctrl($09) return bus_getchar2 PUB setcolor(color) 'screen: farbe setzen {{setcolor(color) - screen: setzt farbwert}} printctrl($10) bus_putchar2(color) PUB curon 'screen: schaltet cursor an {{curon - screen: schaltet cursor an}} printctrl($14) PUB curoff 'screen: schaltet cursor aus {{curon - screen: schaltet cursor aus}} printctrl($15) PUB sline(n) 'screen: startzeile scrollbereich setzen {{sline(n) - startzeile scrollbereich setzen}} printctrl($11) bus_putchar2(n) PUB eline(n) 'screen: endzeile scrollbereich setzen {{sline(n) - endzeile scrollbereich setzen}} printctrl($12) bus_putchar2(n) PUB scrollup 'screen: scrollt screen eine zeile hoch {{scrollup - screen: scrollt screen eine zeile hoch}} printctrl($16) PUB scrolldown 'screen: scrollt screen eine zeile runter {{scrolldown - screen: scrollt screen eine zeile runter}} printctrl($17) PUB settabs(tnr,tpos) 'screen: setzt eine tabulatorposition printctrl($18) bus_putchar2(tnr) bus_putchar2(tpos) PUB screeninit(stradr,n) 'screen: löschen, kopfzeile ausgeben und setzen {{screeninit(stradr,n) - screen löschen, kopfzeile ausgeben und setzen}} curoff printctrl($13) if stradr > 0 print(stradr) printnl else printnl printlogo(0,0) sline(n) 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 outa[31..25] := %0000100 outa[23..0] := %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 outa[31..25] := %0000110 outa[23..0] := %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 outa[31..25] := %0000011 outa[23..0] := %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 outa[31..25] := %0000010 outa[23..0] := %01111000_00000000_00000000 'prop1=1, busclk=0 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 outa[31..25] := %0000100 outa[23..0] := %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 outa[31..25] := %0000110 outa[23..0] := %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 outa[31..25] := %0000011 outa[23..0] := %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 outa[31..25] := 0000010 outa[23..0] := %01111000_00000000_00000000 'prop2=1, busclk=0 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 { memory-map: 0000 --> datei 1 datei 2 ... datei n rbas --> usermem start ... rend --> usermen ende sysvar --> systemvariablen aufbau datei ramdisk: 1 long zeiger auf nächste datei (oder 0 bei letzter datei) 1 long datenlänge 12 byte dateiname 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 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):adr | d,s,nx,len,blk 'ramdisk: datei löschen 'grösse berechnen if (adr := rd_searchadr(stradr)) > 0 len := ram_rdlong(sysmod, adr+4) + RDHLEN nx := ram_rdlong(sysmod,adr) blk := ram_getbas - nx 'block löschen d := adr s := adr + len repeat blk ram_wrbyte(sysmod,ram_rdbyte(sysmod,s++),d++) 'header neu setzen repeat nx := ram_rdlong(sysmod,adr) if nx nx := nx - len ram_wrlong(sysmod,nx,adr) adr := nx until nx == 0 'fbas neu setzen ram_setbas(ram_getbas - blk) return adr 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_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_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) 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. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}