| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- (*
- BSD 2-Clause License
- Copyright (c) 2018-2022, Anton Krotov
- All rights reserved.
- *)
- MODULE HOST;
- IMPORT SYSTEM, K := KOSAPI, API;
- CONST
- slash* = "/";
- eol* = 0DX + 0AX;
- bit_depth* = API.BIT_DEPTH;
- maxint* = ROR(-2, 1);
- minint* = ROR(1, 1);
- MAX_PARAM = 1024;
- TYPE
- DAYS = ARRAY 12, 31, 2 OF INTEGER;
- FNAME = ARRAY 520 OF CHAR;
- FS = POINTER TO rFS;
- rFS = RECORD
- subfunc, pos, hpos, bytes, buffer: INTEGER;
- name: FNAME
- END;
- FD = POINTER TO rFD;
- rFD = RECORD
- attr: INTEGER;
- ntyp: CHAR;
- reserved: ARRAY 3 OF CHAR;
- time_create, date_create,
- time_access, date_access,
- time_modif, date_modif,
- size, hsize: INTEGER;
- name: FNAME
- END;
- VAR
- Console: BOOLEAN;
- days: DAYS;
- Params: ARRAY MAX_PARAM, 2 OF INTEGER;
- argc*: INTEGER;
- maxreal*, inf*: REAL;
- PROCEDURE [stdcall, "Console.obj", "con_init"] con_init (wnd_width, wnd_height, scr_width, scr_height, title: INTEGER);
- PROCEDURE [stdcall, "Console.obj", "con_exit"] con_exit (bCloseWindow: BOOLEAN);
- PROCEDURE [stdcall, "Console.obj", "con_write_string"] con_write_string (string, length: INTEGER);
- PROCEDURE ExitProcess* (p1: INTEGER);
- BEGIN
- IF Console THEN
- con_exit(FALSE)
- END;
- K.sysfunc1(-1)
- END ExitProcess;
- PROCEDURE OutChar* (c: CHAR);
- BEGIN
- IF Console THEN
- con_write_string(SYSTEM.ADR(c), 1)
- ELSE
- K.sysfunc3(63, 1, ORD(c))
- END
- END OutChar;
- PROCEDURE GetFileInfo (FName: ARRAY OF CHAR; VAR Info: rFD): BOOLEAN;
- VAR
- res2: INTEGER;
- fs: rFS;
- BEGIN
- fs.subfunc := 5;
- fs.pos := 0;
- fs.hpos := 0;
- fs.bytes := 0;
- fs.buffer := SYSTEM.ADR(Info);
- COPY(FName, fs.name)
- RETURN K.sysfunc22(70, SYSTEM.ADR(fs), res2) = 0
- END GetFileInfo;
- PROCEDURE Exists (FName: ARRAY OF CHAR): BOOLEAN;
- VAR
- fd: rFD;
- BEGIN
- RETURN GetFileInfo(FName, fd) & ~(4 IN BITS(fd.attr))
- END Exists;
- PROCEDURE Close (VAR F: FS);
- BEGIN
- IF F # NIL THEN
- DISPOSE(F)
- END
- END Close;
- PROCEDURE Open (FName: ARRAY OF CHAR): FS;
- VAR
- F: FS;
- BEGIN
- IF Exists(FName) THEN
- NEW(F);
- IF F # NIL THEN
- F.subfunc := 0;
- F.pos := 0;
- F.hpos := 0;
- F.bytes := 0;
- F.buffer := 0;
- COPY(FName, F.name)
- END
- ELSE
- F := NIL
- END
- RETURN F
- END Open;
- PROCEDURE Read (F: FS; Buffer, Count: INTEGER): INTEGER;
- VAR
- res, res2: INTEGER;
- BEGIN
- IF F # NIL THEN
- F.subfunc := 0;
- F.bytes := Count;
- F.buffer := Buffer;
- res := K.sysfunc22(70, SYSTEM.ADR(F^), res2);
- IF res2 > 0 THEN
- F.pos := F.pos + res2
- END
- ELSE
- res2 := 0
- END
- RETURN res2
- END Read;
- PROCEDURE Write (F: FS; Buffer, Count: INTEGER): INTEGER;
- VAR
- res, res2: INTEGER;
- BEGIN
- IF F # NIL THEN
- F.subfunc := 3;
- F.bytes := Count;
- F.buffer := Buffer;
- res := K.sysfunc22(70, SYSTEM.ADR(F^), res2);
- IF res2 > 0 THEN
- F.pos := F.pos + res2
- END
- ELSE
- res2 := 0
- END
- RETURN res2
- END Write;
- PROCEDURE Create (FName: ARRAY OF CHAR): FS;
- VAR
- F: FS;
- res2: INTEGER;
- BEGIN
- NEW(F);
- IF F # NIL THEN
- F.subfunc := 2;
- F.pos := 0;
- F.hpos := 0;
- F.bytes := 0;
- F.buffer := 0;
- COPY(FName, F.name);
- IF K.sysfunc22(70, SYSTEM.ADR(F^), res2) # 0 THEN
- DISPOSE(F)
- END
- END
- RETURN F
- END Create;
- PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER;
- VAR
- n: INTEGER;
- fs: FS;
- BEGIN
- SYSTEM.GET(SYSTEM.ADR(F), fs);
- n := Read(fs, SYSTEM.ADR(Buffer[0]), bytes);
- IF n = 0 THEN
- n := -1
- END
- RETURN n
- END FileRead;
- PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER;
- VAR
- n: INTEGER;
- fs: FS;
- BEGIN
- SYSTEM.GET(SYSTEM.ADR(F), fs);
- n := Write(fs, SYSTEM.ADR(Buffer[0]), bytes);
- IF n = 0 THEN
- n := -1
- END
- RETURN n
- END FileWrite;
- PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER;
- VAR
- fs: FS;
- res: INTEGER;
- BEGIN
- fs := Create(FName);
- SYSTEM.GET(SYSTEM.ADR(fs), res)
- RETURN res
- END FileCreate;
- PROCEDURE FileClose* (F: INTEGER);
- VAR
- fs: FS;
- BEGIN
- SYSTEM.GET(SYSTEM.ADR(F), fs);
- Close(fs)
- END FileClose;
- PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER;
- VAR
- fs: FS;
- res: INTEGER;
- BEGIN
- fs := Open(FName);
- SYSTEM.GET(SYSTEM.ADR(fs), res)
- RETURN res
- END FileOpen;
- PROCEDURE chmod* (FName: ARRAY OF CHAR);
- END chmod;
- PROCEDURE GetTickCount* (): INTEGER;
- RETURN K.sysfunc2(26, 9)
- END GetTickCount;
- PROCEDURE AppAdr (): INTEGER;
- VAR
- buf: ARRAY 1024 OF CHAR;
- a: INTEGER;
- BEGIN
- a := K.sysfunc3(9, SYSTEM.ADR(buf), -1);
- SYSTEM.GET(SYSTEM.ADR(buf) + 22, a)
- RETURN a
- END AppAdr;
- PROCEDURE GetCommandLine (): INTEGER;
- VAR
- param: INTEGER;
- BEGIN
- SYSTEM.GET(28 + AppAdr(), param)
- RETURN param
- END GetCommandLine;
- PROCEDURE GetName (): INTEGER;
- VAR
- name: INTEGER;
- BEGIN
- SYSTEM.GET(32 + AppAdr(), name)
- RETURN name
- END GetName;
- PROCEDURE GetChar (adr: INTEGER): CHAR;
- VAR
- res: CHAR;
- BEGIN
- SYSTEM.GET(adr, res)
- RETURN res
- END GetChar;
- PROCEDURE ParamParse;
- VAR
- p, count, name, cond: INTEGER;
- c: CHAR;
- PROCEDURE ChangeCond (A, B, C: INTEGER; c: CHAR; VAR cond: INTEGER);
- BEGIN
- IF (c <= 20X) & (c # 0X) THEN
- cond := A
- ELSIF c = 22X THEN
- cond := B
- ELSIF c = 0X THEN
- cond := 6
- ELSE
- cond := C
- END
- END ChangeCond;
- BEGIN
- p := GetCommandLine();
- name := GetName();
- Params[0, 0] := name;
- WHILE GetChar(name) # 0X DO
- INC(name)
- END;
- Params[0, 1] := name - 1;
- cond := 0;
- count := 1;
- WHILE (argc < MAX_PARAM) & (cond # 6) DO
- c := GetChar(p);
- CASE cond OF
- |0: ChangeCond(0, 4, 1, c, cond); IF cond = 1 THEN Params[count, 0] := p END
- |1: ChangeCond(0, 3, 1, c, cond); IF cond IN {0, 6} THEN Params[count, 1] := p - 1; INC(count) END
- |3: ChangeCond(3, 1, 3, c, cond); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
- |4: ChangeCond(5, 0, 5, c, cond); IF cond = 5 THEN Params[count, 0] := p END
- |5: ChangeCond(5, 1, 5, c, cond); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
- |6:
- END;
- INC(p)
- END;
- argc := count
- END ParamParse;
- PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR);
- VAR
- i, j, len: INTEGER;
- c: CHAR;
- BEGIN
- j := 0;
- IF n < argc THEN
- len := LEN(s) - 1;
- i := Params[n, 0];
- WHILE (j < len) & (i <= Params[n, 1]) DO
- c := GetChar(i);
- IF c # 22X THEN
- s[j] := c;
- INC(j)
- END;
- INC(i)
- END
- END;
- s[j] := 0X
- END GetArg;
- PROCEDURE GetCurrentDirectory* (VAR path: ARRAY OF CHAR);
- VAR
- n: INTEGER;
- BEGIN
- n := K.sysfunc4(30, 2, SYSTEM.ADR(path[0]), LEN(path) - 2);
- path[n - 1] := slash;
- path[n] := 0X
- END GetCurrentDirectory;
- PROCEDURE isRelative* (path: ARRAY OF CHAR): BOOLEAN;
- RETURN path[0] # slash
- END isRelative;
- PROCEDURE UnixTime* (): INTEGER;
- VAR
- date, time, year, month, day, hour, min, sec: INTEGER;
- BEGIN
- date := K.sysfunc1(29);
- time := K.sysfunc1(3);
- year := date MOD 16;
- date := date DIV 16;
- year := (date MOD 16) * 10 + year;
- date := date DIV 16;
- month := date MOD 16;
- date := date DIV 16;
- month := (date MOD 16) * 10 + month;
- date := date DIV 16;
- day := date MOD 16;
- date := date DIV 16;
- day := (date MOD 16) * 10 + day;
- date := date DIV 16;
- hour := time MOD 16;
- time := time DIV 16;
- hour := (time MOD 16) * 10 + hour;
- time := time DIV 16;
- min := time MOD 16;
- time := time DIV 16;
- min := (time MOD 16) * 10 + min;
- time := time DIV 16;
- sec := time MOD 16;
- time := time DIV 16;
- sec := (time MOD 16) * 10 + sec;
- time := time DIV 16;
- INC(year, 2000)
- RETURN ((year - 1970) * 365 + days[month - 1, day - 1, ORD(year DIV 4 = 0)] + (year - 1969) DIV 4) * 86400 + hour * 3600 + min * 60 + sec
- END UnixTime;
- PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER;
- BEGIN
- SYSTEM.GET32(SYSTEM.ADR(x), a);
- SYSTEM.GET32(SYSTEM.ADR(x) + 4, b)
- RETURN a
- END splitf;
- PROCEDURE d2s* (x: REAL): INTEGER;
- VAR
- h, l, s, e: INTEGER;
- BEGIN
- e := splitf(x, l, h);
- s := ASR(h, 31) MOD 2;
- e := (h DIV 100000H) MOD 2048;
- IF e <= 896 THEN
- h := (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8 + 800000H;
- REPEAT
- h := h DIV 2;
- INC(e)
- UNTIL e = 897;
- e := 896;
- l := (h MOD 8) * 20000000H;
- h := h DIV 8
- ELSIF (1151 <= e) & (e < 2047) THEN
- e := 1151;
- h := 0;
- l := 0
- ELSIF e = 2047 THEN
- e := 1151;
- IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN
- h := 80000H;
- l := 0
- END
- END;
- DEC(e, 896)
- RETURN LSL(s, 31) + LSL(e, 23) + (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8
- END d2s;
- PROCEDURE init (VAR days: DAYS);
- VAR
- i, j, n0, n1: INTEGER;
- BEGIN
- FOR i := 0 TO 11 DO
- FOR j := 0 TO 30 DO
- days[i, j, 0] := 0;
- days[i, j, 1] := 0;
- END
- END;
- days[ 1, 28, 0] := -1;
- FOR i := 0 TO 1 DO
- days[ 1, 29, i] := -1;
- days[ 1, 30, i] := -1;
- days[ 3, 30, i] := -1;
- days[ 5, 30, i] := -1;
- days[ 8, 30, i] := -1;
- days[10, 30, i] := -1;
- END;
- n0 := 0;
- n1 := 0;
- FOR i := 0 TO 11 DO
- FOR j := 0 TO 30 DO
- IF days[i, j, 0] = 0 THEN
- days[i, j, 0] := n0;
- INC(n0)
- END;
- IF days[i, j, 1] = 0 THEN
- days[i, j, 1] := n1;
- INC(n1)
- END
- END
- END;
- inf := SYSTEM.INF();
- maxreal := 1.9;
- PACK(maxreal, 1023);
- Console := TRUE;
- IF Console THEN
- con_init(-1, -1, -1, -1, SYSTEM.SADR("Oberon-07 for KolibriOS"))
- END;
- ParamParse
- END init;
- BEGIN
- init(days)
- END HOST.
|