[Oberon] Standalone BootLoader format
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Thu May 14 17:54:22 CEST 2020
> Your first word of the bootfile should be the length of the first
> section, the second word should be the address, and then the subsequent
> words should be the data you want to put at that address. Any subsequent
> section must also be like this. You need to finish with a section with
> a word len of zero.
>
> From section 14.1 of the book:
>
> BootFile = {block}.
> block = size address {byte}. (size and address are words)
>
> and size = 0 indicates the end of the file. {} means possibly repeated.
Maybe the procedure MakeStream and the command WriteStream below
is useful. MakeStream generates just that format.
-ap
--------------------------------
VAR W: Texts.Writer;
PROCEDURE MakeStream(VAR Rf, Rg: Files.Rider; blksize, destadr: INTEGER);
VAR i, a: INTEGER; b: BYTE;
BEGIN Files.ReadByte(Rf, b); i := 0; a := destadr;
WHILE ~Rf.eof DO
IF i MOD blksize = 0 THEN Files.WriteInt(Rg, blksize); Files.WriteInt(Rg, a); INC(a, blksize); i := 0 END ;
Files.WriteByte(Rg, b); INC(i); Files.ReadByte(Rf, b)
END ;
WHILE i < blksize DO Files.WriteByte(Rg, 0); INC(i) END ;
Files.WriteInt(Rg, 0) (*size of last block*)
END MakeStream;
PROCEDURE WriteStream*; (*convert file to stream format with specified block size and dest adr*)
VAR f, g: Files.File; Rf, Rg: Files.Rider;
filelen, blksize, res: INTEGER;
name, name1: ARRAY 32 OF CHAR;
S: Texts.Scanner;
BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); res := -1;
IF S.class = Texts.Name THEN name := S.s; Texts.Scan(S);
IF S.class = Texts.Name THEN name1 := S.s; Texts.Scan(S);
IF S.class = Texts.Int THEN blksize := S.i; Texts.Scan(S);
IF S.class = Texts.Int THEN res := 0; Texts.WriteString(W, " WriteStream ");
Texts.WriteString(W, name); Texts.Write(W, " "); Texts.WriteString(W, name1);
Texts.WriteInt(W, blksize, 5); Texts.WriteInt(W, S.i, 5);
IF blksize >= 0 THEN
IF S.i >= 0 THEN f := Files.Old(name);
IF f # NIL THEN filelen := Files.Length(f);
IF filelen > 0 THEN g := Files.New(name1);
IF blksize = 0 THEN blksize := filelen END ;
Files.Set(Rf, f, 0); Files.Set(Rg, g, 0); MakeStream(Rf, Rg, blksize, S.i);
Files.Register(g); Texts.WriteString(W, " done")
ELSE Texts.WriteString(W, " input file empty")
END
ELSE Texts.WriteString(W, " input file not found")
END
ELSE Texts.WriteString(W, " destaddr must be >= 0")
END
ELSE Texts.WriteString(W, " blocksize must be >= 0")
END
END
END
END
END ;
IF res = -1 THEN Texts.WriteString(W, "Usage: ORX.WriteStream inputfile M.stream blocksize destadr") END ;
Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
END WriteStream;
More information about the Oberon
mailing list