TriOS-alt/flash/regnatix/regflash.spin

315 lines
32 KiB
Plaintext

{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}