{{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 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 stopt, 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) header einer bin-datei 00 b400 ' clkfreq low 02 04c4 ' clkfreq hi 04 ca6f ' sum byte, clkmode byte 06 0010 ' (obj) object start addr 08 005c ' (vars) variables start 0A 0088 ' (stk) stack start 0C 002c ' (PUB) obchain first PUB method start 0E 008c ' (isp) initial stack pointer value --------------------------------------------------------------------------------------------------------- }} CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 COGMAX = 8 INTERPRETER = $f004 'interpreteradresse (rom) PROGLEN = 31900 'größe des verfügbaren programmspeichers '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 = %00001000_01011000_00000000_00000000 '/prop2=0, /wr=0, busclk=0 'M2 = %00000110_01011000_00000000_00000000 '/prop2=0, /wr=1, busclk=1 'M3 = %00001100_01111000_00000000_00000000 '/prop2=1, /wr=1, busclk=0 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, SD_LED 'administra-sd-card-befehlscodes SD_MOUNT SD_DIROPEN SD_NEXTFILE SD_OPEN SD_CLOSE SD_GETC SD_PUTC SD_READ SD_WRITE VAR byte heap[PROGLEN] 'programmspeicher 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 DAT sysname byte "reg.sys", 0 'name der systemdatei PUB main | spinbin,i 'loader: hauptroutine {{main - loader: hauptroutine}} bus_init 'bus initialisieren wr_long(@lflag,LOADERPTR) 'zeiger auf loader-register setzen ram_write(0,MAGIC) 'kaltstartflag rücksetzen repeat while sdmount 'sd-karte einbinden 'waitcnt(clkfreq + cnt) 'frida spinbin := load(@sysname) 'sys.bin laden bus_off 'bus deaktivieren run(spinbin) 'sys-objekt ausführen 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 sdled waitcnt(10_000_000 * 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 > PROGLEN '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 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 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 sdmount: err 'sd-card: mounten {{sdmount: err - sd-card: mounten}} bus_putchar1(SD_MOUNT) err := bus_getchar1 PUB sdled 'sd-card: schaltet led am cardreader um {{sdled - sd-card: schaltet led am cardreader um}} bus_putchar1(SD_LED) 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[23] := 1 'obere adresse in adresslatch übernehmen ' outa[23] := 0 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 }} ' dira := db_in ' datenbus auf eingabe schalten frida outa[18..8] := 0 ' adresse a0..a10 auf 0 setzen ' outa[23] := 1 ' obere adresse in adresslatch übernehmen frida ' outa[23] := 0 'frida 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 ' outa[reg_al] := 0 ' strobe aus 'frida dira := db_in ' datenbus auf eingabe schalten frida outa[reg_al] := 1 ' obere adresse in adresslatch übernehmen frida outa[reg_al] := 0 'frida 'waitcnt(100_000_000 + cnt) ' warte bis alle systeme bereit 'frida 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. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}