Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2018-2020, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE HOST;
  9.  
  10. IMPORT SYSTEM, K := KOSAPI, API, RTL;
  11.  
  12.  
  13. CONST
  14.  
  15.     slash* = "/";
  16.     OS* = "KOS";
  17.  
  18.     bit_depth* = RTL.bit_depth;
  19.     maxint* = RTL.maxint;
  20.     minint* = RTL.minint;
  21.  
  22.     MAX_PARAM = 1024;
  23.  
  24.  
  25. TYPE
  26.  
  27.     FNAME = ARRAY 520 OF CHAR;
  28.  
  29.     FS = POINTER TO rFS;
  30.  
  31.     rFS = RECORD
  32.         subfunc, pos, hpos, bytes, buffer: INTEGER;
  33.         name: FNAME
  34.     END;
  35.  
  36.     FD = POINTER TO rFD;
  37.  
  38.     rFD = RECORD
  39.         attr: INTEGER;
  40.         ntyp: CHAR;
  41.         reserved: ARRAY 3 OF CHAR;
  42.         time_create, date_create,
  43.         time_access, date_access,
  44.         time_modif,  date_modif,
  45.         size, hsize: INTEGER;
  46.         name: FNAME
  47.     END;
  48.  
  49.  
  50. VAR
  51.  
  52.  
  53.     Console: BOOLEAN;
  54.  
  55.     Params: ARRAY MAX_PARAM, 2 OF INTEGER;
  56.     argc*: INTEGER;
  57.  
  58.     eol*: ARRAY 3 OF CHAR;
  59.  
  60.     maxreal*: REAL;
  61.  
  62.  
  63. PROCEDURE [stdcall, "Console.obj", "con_init"] con_init (wnd_width, wnd_height, scr_width, scr_height, title: INTEGER);
  64.  
  65. PROCEDURE [stdcall, "Console.obj", "con_exit"] con_exit (bCloseWindow: BOOLEAN);
  66.  
  67. PROCEDURE [stdcall, "Console.obj", "con_write_string"] con_write_string (string, length: INTEGER);
  68.  
  69.  
  70. PROCEDURE ExitProcess* (p1: INTEGER);
  71. BEGIN
  72.     IF Console THEN
  73.         con_exit(FALSE)
  74.     END;
  75.     K.sysfunc1(-1)
  76. END ExitProcess;
  77.  
  78.  
  79. PROCEDURE OutChar* (c: CHAR);
  80. BEGIN
  81.     IF Console THEN
  82.         con_write_string(SYSTEM.ADR(c), 1)
  83.     ELSE
  84.         K.sysfunc3(63, 1, ORD(c))
  85.     END
  86. END OutChar;
  87.  
  88.  
  89. PROCEDURE GetFileInfo (FName: ARRAY OF CHAR; VAR Info: rFD): BOOLEAN;
  90. VAR
  91.     res2: INTEGER;
  92.     fs:   rFS;
  93.  
  94. BEGIN
  95.     fs.subfunc := 5;
  96.     fs.pos := 0;
  97.     fs.hpos := 0;
  98.     fs.bytes := 0;
  99.     fs.buffer := SYSTEM.ADR(Info);
  100.     COPY(FName, fs.name)
  101.     RETURN K.sysfunc22(70, SYSTEM.ADR(fs), res2) = 0
  102. END GetFileInfo;
  103.  
  104.  
  105. PROCEDURE Exists (FName: ARRAY OF CHAR): BOOLEAN;
  106. VAR
  107.     fd: rFD;
  108.  
  109. BEGIN
  110.     RETURN GetFileInfo(FName, fd) & ~(4 IN BITS(fd.attr))
  111. END Exists;
  112.  
  113.  
  114. PROCEDURE Close (VAR F: FS);
  115. BEGIN
  116.     IF F # NIL THEN
  117.         DISPOSE(F)
  118.     END
  119. END Close;
  120.  
  121.  
  122. PROCEDURE Open (FName: ARRAY OF CHAR): FS;
  123. VAR
  124.     F: FS;
  125.  
  126. BEGIN
  127.     IF Exists(FName) THEN
  128.         NEW(F);
  129.         IF F # NIL THEN
  130.             F.subfunc := 0;
  131.             F.pos := 0;
  132.             F.hpos := 0;
  133.             F.bytes := 0;
  134.             F.buffer := 0;
  135.             COPY(FName, F.name)
  136.         END
  137.     ELSE
  138.         F := NIL
  139.     END
  140.  
  141.     RETURN F
  142. END Open;
  143.  
  144.  
  145. PROCEDURE Read (F: FS; Buffer, Count: INTEGER): INTEGER;
  146. VAR
  147.     res, res2: INTEGER;
  148.  
  149. BEGIN
  150.     IF F # NIL THEN
  151.         F.subfunc := 0;
  152.         F.bytes := Count;
  153.         F.buffer := Buffer;
  154.         res := K.sysfunc22(70, SYSTEM.ADR(F^), res2);
  155.         IF res2 > 0 THEN
  156.             F.pos := F.pos + res2
  157.         END
  158.     ELSE
  159.         res2 := 0
  160.     END
  161.  
  162.     RETURN res2
  163. END Read;
  164.  
  165.  
  166. PROCEDURE Write (F: FS; Buffer, Count: INTEGER): INTEGER;
  167. VAR
  168.     res, res2: INTEGER;
  169.  
  170. BEGIN
  171.     IF F # NIL THEN
  172.         F.subfunc := 3;
  173.         F.bytes := Count;
  174.         F.buffer := Buffer;
  175.         res := K.sysfunc22(70, SYSTEM.ADR(F^), res2);
  176.         IF res2 > 0 THEN
  177.             F.pos := F.pos + res2
  178.         END
  179.     ELSE
  180.         res2 := 0
  181.     END
  182.  
  183.     RETURN res2
  184. END Write;
  185.  
  186.  
  187. PROCEDURE Create (FName: ARRAY OF CHAR): FS;
  188. VAR
  189.     F:    FS;
  190.     res2: INTEGER;
  191.  
  192. BEGIN
  193.     NEW(F);
  194.     IF F # NIL THEN
  195.         F.subfunc := 2;
  196.         F.pos := 0;
  197.         F.hpos := 0;
  198.         F.bytes := 0;
  199.         F.buffer := 0;
  200.         COPY(FName, F.name);
  201.         IF K.sysfunc22(70, SYSTEM.ADR(F^), res2) # 0 THEN
  202.             DISPOSE(F)
  203.         END
  204.     END
  205.  
  206.     RETURN F
  207. END Create;
  208.  
  209.  
  210. PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER;
  211. VAR
  212.     n: INTEGER;
  213.     fs: FS;
  214.  
  215. BEGIN
  216.     SYSTEM.GET(SYSTEM.ADR(F), fs);
  217.     n := Read(fs, SYSTEM.ADR(Buffer[0]), bytes);
  218.     IF n = 0 THEN
  219.         n := -1
  220.     END
  221.  
  222.     RETURN n
  223. END FileRead;
  224.  
  225.  
  226. PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER;
  227. VAR
  228.     n: INTEGER;
  229.     fs: FS;
  230.  
  231. BEGIN
  232.     SYSTEM.GET(SYSTEM.ADR(F), fs);
  233.     n := Write(fs, SYSTEM.ADR(Buffer[0]), bytes);
  234.     IF n = 0 THEN
  235.         n := -1
  236.     END
  237.  
  238.     RETURN n
  239. END FileWrite;
  240.  
  241.  
  242. PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER;
  243. VAR
  244.     fs: FS;
  245.     res: INTEGER;
  246.  
  247. BEGIN
  248.     fs := Create(FName);
  249.     SYSTEM.GET(SYSTEM.ADR(fs), res)
  250.     RETURN res
  251. END FileCreate;
  252.  
  253.  
  254. PROCEDURE FileClose* (F: INTEGER);
  255. VAR
  256.     fs: FS;
  257.  
  258. BEGIN
  259.     SYSTEM.GET(SYSTEM.ADR(F), fs);
  260.     Close(fs)
  261. END FileClose;
  262.  
  263.  
  264. PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER;
  265. VAR
  266.     fs: FS;
  267.     res: INTEGER;
  268.  
  269. BEGIN
  270.     fs := Open(FName);
  271.     SYSTEM.GET(SYSTEM.ADR(fs), res)
  272.     RETURN res
  273. END FileOpen;
  274.  
  275.  
  276. PROCEDURE GetTickCount* (): INTEGER;
  277.     RETURN K.sysfunc2(26, 9)
  278. END GetTickCount;
  279.  
  280.  
  281. PROCEDURE AppAdr (): INTEGER;
  282. VAR
  283.     buf: ARRAY 1024 OF CHAR;
  284.     a: INTEGER;
  285.  
  286. BEGIN
  287.     a := K.sysfunc3(9, SYSTEM.ADR(buf), -1);
  288.     SYSTEM.GET(SYSTEM.ADR(buf) + 22, a)
  289.     RETURN a
  290. END AppAdr;
  291.  
  292.  
  293. PROCEDURE GetCommandLine (): INTEGER;
  294. VAR
  295.     param: INTEGER;
  296.  
  297. BEGIN
  298.     SYSTEM.GET(28 + AppAdr(), param)
  299.     RETURN param
  300. END GetCommandLine;
  301.  
  302.  
  303. PROCEDURE GetName (): INTEGER;
  304. VAR
  305.     name: INTEGER;
  306.  
  307. BEGIN
  308.     SYSTEM.GET(32 + AppAdr(), name)
  309.     RETURN name
  310. END GetName;
  311.  
  312.  
  313. PROCEDURE GetChar (adr: INTEGER): CHAR;
  314. VAR
  315.     res: CHAR;
  316.  
  317. BEGIN
  318.     SYSTEM.GET(adr, res)
  319.     RETURN res
  320. END GetChar;
  321.  
  322.  
  323. PROCEDURE ParamParse;
  324. VAR
  325.     p, count, name, cond: INTEGER;
  326.     c: CHAR;
  327.  
  328.  
  329.     PROCEDURE ChangeCond (A, B, C: INTEGER; c: CHAR; VAR cond: INTEGER);
  330.     BEGIN
  331.         IF (c <= 20X) & (c # 0X) THEN
  332.             cond := A
  333.         ELSIF c = 22X THEN
  334.             cond := B
  335.         ELSIF c = 0X THEN
  336.             cond := 6
  337.         ELSE
  338.             cond := C
  339.         END
  340.     END ChangeCond;
  341.  
  342.  
  343. BEGIN
  344.     p := GetCommandLine();
  345.     name := GetName();
  346.     Params[0, 0] := name;
  347.     WHILE GetChar(name) # 0X DO
  348.         INC(name)
  349.     END;
  350.     Params[0, 1] := name - 1;
  351.     cond := 0;
  352.     count := 1;
  353.     WHILE (argc < MAX_PARAM) & (cond # 6) DO
  354.         c := GetChar(p);
  355.         CASE cond OF
  356.         |0: ChangeCond(0, 4, 1, c, cond); IF cond = 1 THEN Params[count, 0] := p END
  357.         |1: ChangeCond(0, 3, 1, c, cond); IF cond IN {0, 6} THEN Params[count, 1] := p - 1; INC(count) END
  358.         |3: ChangeCond(3, 1, 3, c, cond); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
  359.         |4: ChangeCond(5, 0, 5, c, cond); IF cond = 5 THEN Params[count, 0] := p END
  360.         |5: ChangeCond(5, 1, 5, c, cond); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
  361.         |6:
  362.         END;
  363.         INC(p)
  364.     END;
  365.     argc := count
  366. END ParamParse;
  367.  
  368.  
  369. PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR);
  370. VAR
  371.     i, j, len: INTEGER;
  372.     c: CHAR;
  373.  
  374. BEGIN
  375.     j := 0;
  376.     IF n < argc THEN
  377.         len := LEN(s) - 1;
  378.         i := Params[n, 0];
  379.         WHILE (j < len) & (i <= Params[n, 1]) DO
  380.             c := GetChar(i);
  381.             IF c # 22X THEN
  382.                 s[j] := c;
  383.                 INC(j)
  384.             END;
  385.             INC(i);
  386.         END;
  387.     END;
  388.     s[j] := 0X
  389. END GetArg;
  390.  
  391.  
  392. PROCEDURE GetCurrentDirectory* (VAR path: ARRAY OF CHAR);
  393. VAR
  394.     n: INTEGER;
  395.  
  396. BEGIN
  397.     GetArg(0, path);
  398.     n := LENGTH(path) - 1;
  399.     WHILE path[n] # slash DO
  400.         DEC(n)
  401.     END;
  402.     path[n + 1] := 0X
  403. END GetCurrentDirectory;
  404.  
  405.  
  406. PROCEDURE isRelative* (path: ARRAY OF CHAR): BOOLEAN;
  407.     RETURN path[0] # slash
  408. END isRelative;
  409.  
  410.  
  411. PROCEDURE now* (VAR year, month, day, hour, min, sec: INTEGER);
  412. VAR
  413.     date, time: INTEGER;
  414.  
  415. BEGIN
  416.     date  := K.sysfunc1(29);
  417.     time  := K.sysfunc1(3);
  418.  
  419.     year  := date MOD 16;
  420.     date  := date DIV 16;
  421.     year  := (date MOD 16) * 10 + year;
  422.     date  := date DIV 16;
  423.  
  424.     month := date MOD 16;
  425.     date  := date DIV 16;
  426.     month := (date MOD 16) * 10 + month;
  427.     date  := date DIV 16;
  428.  
  429.     day   := date MOD 16;
  430.     date  := date DIV 16;
  431.     day   := (date MOD 16) * 10 + day;
  432.     date  := date DIV 16;
  433.  
  434.     hour  := time MOD 16;
  435.     time  := time DIV 16;
  436.     hour  := (time MOD 16) * 10 + hour;
  437.     time  := time DIV 16;
  438.  
  439.     min   := time MOD 16;
  440.     time  := time DIV 16;
  441.     min   := (time MOD 16) * 10 + min;
  442.     time  := time DIV 16;
  443.  
  444.     sec   := time MOD 16;
  445.     time  := time DIV 16;
  446.     sec   := (time MOD 16) * 10 + sec;
  447.     time  := time DIV 16;
  448.  
  449.     year := year + 2000
  450. END now;
  451.  
  452.  
  453. PROCEDURE UnixTime* (): INTEGER;
  454.     RETURN 0
  455. END UnixTime;
  456.  
  457.  
  458. PROCEDURE d2s* (x: REAL): INTEGER;
  459. VAR
  460.     h, l, s, e: INTEGER;
  461.  
  462. BEGIN
  463.     SYSTEM.GET(SYSTEM.ADR(x), l);
  464.     SYSTEM.GET(SYSTEM.ADR(x) + 4, h);
  465.  
  466.     s := ASR(h, 31) MOD 2;
  467.     e := (h DIV 100000H) MOD 2048;
  468.     IF e <= 896 THEN
  469.         h := (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8 + 800000H;
  470.         REPEAT
  471.             h := h DIV 2;
  472.             INC(e)
  473.         UNTIL e = 897;
  474.         e := 896;
  475.         l := (h MOD 8) * 20000000H;
  476.         h := h DIV 8
  477.     ELSIF (1151 <= e) & (e < 2047) THEN
  478.         e := 1151;
  479.         h := 0;
  480.         l := 0
  481.     ELSIF e = 2047 THEN
  482.         e := 1151;
  483.         IF (h MOD 100000H # 0) OR (l # 0) THEN
  484.             h := 80000H;
  485.             l := 0
  486.         END
  487.     END;
  488.     DEC(e, 896)
  489.  
  490.     RETURN LSL(s, 31) + LSL(e, 23) + (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8
  491. END d2s;
  492.  
  493.  
  494. PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER;
  495. BEGIN
  496.     SYSTEM.GET(SYSTEM.ADR(x),     a);
  497.     SYSTEM.GET(SYSTEM.ADR(x) + 4, b)
  498.     RETURN a
  499. END splitf;
  500.  
  501.  
  502. BEGIN
  503.     eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X;
  504.     maxreal := 1.9;
  505.     PACK(maxreal, 1023);
  506.     Console := API.import;
  507.     IF Console THEN
  508.         con_init(-1, -1, -1, -1, SYSTEM.SADR("Oberon-07 for KolibriOS"))
  509.     END;
  510.     ParamParse
  511. END HOST.