KOSAPI.ob07 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2018-2019, 2022 Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE KOSAPI;
  7. IMPORT SYSTEM;
  8. TYPE
  9. STRING = ARRAY 1024 OF CHAR;
  10. VAR
  11. DLL_INIT: PROCEDURE [stdcall] (entry: INTEGER);
  12. PROCEDURE [stdcall-] sysfunc1* (arg1: INTEGER): INTEGER;
  13. BEGIN
  14. SYSTEM.CODE(
  15. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  16. 0CDH, 040H, (* int 64 *)
  17. 0C9H, (* leave *)
  18. 0C2H, 004H, 000H (* ret 4 *)
  19. )
  20. RETURN 0
  21. END sysfunc1;
  22. PROCEDURE [stdcall-] sysfunc2* (arg1, arg2: INTEGER): INTEGER;
  23. BEGIN
  24. SYSTEM.CODE(
  25. 053H, (* push ebx *)
  26. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  27. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  28. 0CDH, 040H, (* int 64 *)
  29. 05BH, (* pop ebx *)
  30. 0C9H, (* leave *)
  31. 0C2H, 008H, 000H (* ret 8 *)
  32. )
  33. RETURN 0
  34. END sysfunc2;
  35. PROCEDURE [stdcall-] sysfunc3* (arg1, arg2, arg3: INTEGER): INTEGER;
  36. BEGIN
  37. SYSTEM.CODE(
  38. 053H, (* push ebx *)
  39. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  40. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  41. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  42. 0CDH, 040H, (* int 64 *)
  43. 05BH, (* pop ebx *)
  44. 0C9H, (* leave *)
  45. 0C2H, 00CH, 000H (* ret 12 *)
  46. )
  47. RETURN 0
  48. END sysfunc3;
  49. PROCEDURE [stdcall-] sysfunc4* (arg1, arg2, arg3, arg4: INTEGER): INTEGER;
  50. BEGIN
  51. SYSTEM.CODE(
  52. 053H, (* push ebx *)
  53. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  54. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  55. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  56. 08BH, 055H, 014H, (* mov edx, dword [ebp + 20] *)
  57. 0CDH, 040H, (* int 64 *)
  58. 05BH, (* pop ebx *)
  59. 0C9H, (* leave *)
  60. 0C2H, 010H, 000H (* ret 16 *)
  61. )
  62. RETURN 0
  63. END sysfunc4;
  64. PROCEDURE [stdcall-] sysfunc5* (arg1, arg2, arg3, arg4, arg5: INTEGER): INTEGER;
  65. BEGIN
  66. SYSTEM.CODE(
  67. 053H, (* push ebx *)
  68. 056H, (* push esi *)
  69. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  70. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  71. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  72. 08BH, 055H, 014H, (* mov edx, dword [ebp + 20] *)
  73. 08BH, 075H, 018H, (* mov esi, dword [ebp + 24] *)
  74. 0CDH, 040H, (* int 64 *)
  75. 05EH, (* pop esi *)
  76. 05BH, (* pop ebx *)
  77. 0C9H, (* leave *)
  78. 0C2H, 014H, 000H (* ret 20 *)
  79. )
  80. RETURN 0
  81. END sysfunc5;
  82. PROCEDURE [stdcall-] sysfunc6* (arg1, arg2, arg3, arg4, arg5, arg6: INTEGER): INTEGER;
  83. BEGIN
  84. SYSTEM.CODE(
  85. 053H, (* push ebx *)
  86. 056H, (* push esi *)
  87. 057H, (* push edi *)
  88. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  89. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  90. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  91. 08BH, 055H, 014H, (* mov edx, dword [ebp + 20] *)
  92. 08BH, 075H, 018H, (* mov esi, dword [ebp + 24] *)
  93. 08BH, 07DH, 01CH, (* mov edi, dword [ebp + 28] *)
  94. 0CDH, 040H, (* int 64 *)
  95. 05FH, (* pop edi *)
  96. 05EH, (* pop esi *)
  97. 05BH, (* pop ebx *)
  98. 0C9H, (* leave *)
  99. 0C2H, 018H, 000H (* ret 24 *)
  100. )
  101. RETURN 0
  102. END sysfunc6;
  103. PROCEDURE [stdcall-] sysfunc7* (arg1, arg2, arg3, arg4, arg5, arg6, arg7: INTEGER): INTEGER;
  104. BEGIN
  105. SYSTEM.CODE(
  106. 053H, (* push ebx *)
  107. 056H, (* push esi *)
  108. 057H, (* push edi *)
  109. 055H, (* push ebp *)
  110. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  111. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  112. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  113. 08BH, 055H, 014H, (* mov edx, dword [ebp + 20] *)
  114. 08BH, 075H, 018H, (* mov esi, dword [ebp + 24] *)
  115. 08BH, 07DH, 01CH, (* mov edi, dword [ebp + 28] *)
  116. 08BH, 06DH, 020H, (* mov ebp, dword [ebp + 32] *)
  117. 0CDH, 040H, (* int 64 *)
  118. 05DH, (* pop ebp *)
  119. 05FH, (* pop edi *)
  120. 05EH, (* pop esi *)
  121. 05BH, (* pop ebx *)
  122. 0C9H, (* leave *)
  123. 0C2H, 01CH, 000H (* ret 28 *)
  124. )
  125. RETURN 0
  126. END sysfunc7;
  127. PROCEDURE [stdcall-] sysfunc22* (arg1, arg2: INTEGER; VAR res2: INTEGER): INTEGER;
  128. BEGIN
  129. SYSTEM.CODE(
  130. 053H, (* push ebx *)
  131. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  132. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  133. 0CDH, 040H, (* int 64 *)
  134. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  135. 089H, 019H, (* mov dword [ecx], ebx *)
  136. 05BH, (* pop ebx *)
  137. 0C9H, (* leave *)
  138. 0C2H, 00CH, 000H (* ret 12 *)
  139. )
  140. RETURN 0
  141. END sysfunc22;
  142. PROCEDURE mem_commit (adr, size: INTEGER);
  143. VAR
  144. tmp: INTEGER;
  145. BEGIN
  146. FOR tmp := adr TO adr + size - 1 BY 4096 DO
  147. SYSTEM.PUT(tmp, 0)
  148. END
  149. END mem_commit;
  150. PROCEDURE [stdcall] malloc* (size: INTEGER): INTEGER;
  151. VAR
  152. ptr: INTEGER;
  153. BEGIN
  154. SYSTEM.CODE(060H); (* pusha *)
  155. IF sysfunc2(18, 16) > ASR(size, 10) THEN
  156. ptr := sysfunc3(68, 12, size);
  157. IF ptr # 0 THEN
  158. mem_commit(ptr, size)
  159. END
  160. ELSE
  161. ptr := 0
  162. END;
  163. SYSTEM.CODE(061H) (* popa *)
  164. RETURN ptr
  165. END malloc;
  166. PROCEDURE [stdcall] free* (ptr: INTEGER): INTEGER;
  167. BEGIN
  168. SYSTEM.CODE(060H); (* pusha *)
  169. IF ptr # 0 THEN
  170. ptr := sysfunc3(68, 13, ptr)
  171. END;
  172. SYSTEM.CODE(061H) (* popa *)
  173. RETURN 0
  174. END free;
  175. PROCEDURE [stdcall] realloc* (ptr, size: INTEGER): INTEGER;
  176. BEGIN
  177. SYSTEM.CODE(060H); (* pusha *)
  178. ptr := sysfunc4(68, 20, size, ptr);
  179. SYSTEM.CODE(061H) (* popa *)
  180. RETURN ptr
  181. END realloc;
  182. PROCEDURE AppAdr (): INTEGER;
  183. VAR
  184. buf: ARRAY 1024 OF CHAR;
  185. a: INTEGER;
  186. BEGIN
  187. a := sysfunc3(9, SYSTEM.ADR(buf), -1);
  188. SYSTEM.GET(SYSTEM.ADR(buf) + 22, a)
  189. RETURN a
  190. END AppAdr;
  191. PROCEDURE GetCommandLine* (): INTEGER;
  192. VAR
  193. param: INTEGER;
  194. BEGIN
  195. SYSTEM.GET(28 + AppAdr(), param)
  196. RETURN param
  197. END GetCommandLine;
  198. PROCEDURE GetName* (): INTEGER;
  199. VAR
  200. name: INTEGER;
  201. BEGIN
  202. SYSTEM.GET(32 + AppAdr(), name)
  203. RETURN name
  204. END GetName;
  205. PROCEDURE [stdcall] dll_init2 (arg1, arg2, arg3, arg4, arg5: INTEGER);
  206. BEGIN
  207. SYSTEM.CODE(
  208. 060H, (* pusha *)
  209. 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *)
  210. 08BH, 05DH, 00CH, (* mov ebx, dword [ebp + 12] *)
  211. 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *)
  212. 08BH, 055H, 014H, (* mov edx, dword [ebp + 20] *)
  213. 08BH, 075H, 018H, (* mov esi, dword [ebp + 24] *)
  214. 0FFH, 0D6H, (* call esi *)
  215. 061H, (* popa *)
  216. 0C9H, (* leave *)
  217. 0C2H, 014H, 000H (* ret 20 *)
  218. )
  219. END dll_init2;
  220. PROCEDURE GetProcAdr* (name: ARRAY OF CHAR; lib: INTEGER): INTEGER;
  221. VAR
  222. cur, procname, adr: INTEGER;
  223. PROCEDURE streq (str1, str2: INTEGER): BOOLEAN;
  224. VAR
  225. c1, c2: CHAR;
  226. BEGIN
  227. REPEAT
  228. SYSTEM.GET(str1, c1);
  229. SYSTEM.GET(str2, c2);
  230. INC(str1);
  231. INC(str2)
  232. UNTIL (c1 # c2) OR (c1 = 0X)
  233. RETURN c1 = c2
  234. END streq;
  235. BEGIN
  236. adr := 0;
  237. IF (lib # 0) & (name # "") THEN
  238. cur := lib;
  239. REPEAT
  240. SYSTEM.GET(cur, procname);
  241. INC(cur, 8)
  242. UNTIL (procname = 0) OR streq(procname, SYSTEM.ADR(name[0]));
  243. IF procname # 0 THEN
  244. SYSTEM.GET(cur - 4, adr)
  245. END
  246. END
  247. RETURN adr
  248. END GetProcAdr;
  249. PROCEDURE init (dll: INTEGER);
  250. VAR
  251. lib_init: INTEGER;
  252. BEGIN
  253. lib_init := GetProcAdr("lib_init", dll);
  254. IF lib_init # 0 THEN
  255. DLL_INIT(lib_init)
  256. END;
  257. lib_init := GetProcAdr("START", dll);
  258. IF lib_init # 0 THEN
  259. DLL_INIT(lib_init)
  260. END
  261. END init;
  262. PROCEDURE OutChar* (c: CHAR);
  263. BEGIN
  264. sysfunc3(63, 1, ORD(c))
  265. END OutChar;
  266. PROCEDURE OutLn*;
  267. BEGIN
  268. OutChar(0DX);
  269. OutChar(0AX)
  270. END OutLn;
  271. PROCEDURE OutString (s: ARRAY OF CHAR);
  272. VAR
  273. i: INTEGER;
  274. BEGIN
  275. i := 0;
  276. WHILE (i < LEN(s)) & (s[i] # 0X) DO
  277. OutChar(s[i]);
  278. INC(i)
  279. END
  280. END OutString;
  281. PROCEDURE imp_error (lib, proc: STRING);
  282. BEGIN
  283. OutString("import error: ");
  284. IF proc = "" THEN
  285. OutString("can't load '")
  286. ELSE
  287. OutString("not found '"); OutString(proc); OutString("' in '")
  288. END;
  289. OutString(lib);
  290. OutString("'" + 0DX + 0AX)
  291. END imp_error;
  292. PROCEDURE GetStr (adr, i: INTEGER; VAR str: STRING);
  293. VAR
  294. c: CHAR;
  295. BEGIN
  296. REPEAT
  297. SYSTEM.GET(adr, c); INC(adr);
  298. str[i] := c; INC(i)
  299. UNTIL c = 0X
  300. END GetStr;
  301. PROCEDURE [stdcall-] dll_Load* (import_table: INTEGER): INTEGER;
  302. CONST
  303. path = "/sys/lib/";
  304. VAR
  305. imp, lib, exp, proc, pathLen: INTEGER;
  306. procname, libname: STRING;
  307. BEGIN
  308. SYSTEM.CODE(060H); (* pusha *)
  309. libname := path;
  310. pathLen := LENGTH(libname);
  311. SYSTEM.GET(import_table, imp);
  312. WHILE imp # 0 DO
  313. SYSTEM.GET(import_table + 4, lib);
  314. GetStr(lib, pathLen, libname);
  315. exp := sysfunc3(68, 19, SYSTEM.ADR(libname[0]));
  316. IF exp = 0 THEN
  317. imp_error(libname, "")
  318. ELSE
  319. REPEAT
  320. SYSTEM.GET(imp, proc);
  321. IF proc # 0 THEN
  322. GetStr(proc, 0, procname);
  323. proc := GetProcAdr(procname, exp);
  324. IF proc # 0 THEN
  325. SYSTEM.PUT(imp, proc)
  326. ELSE
  327. proc := 1;
  328. imp_error(libname, procname)
  329. END;
  330. INC(imp, 4)
  331. END
  332. UNTIL proc = 0;
  333. init(exp)
  334. END;
  335. INC(import_table, 8);
  336. SYSTEM.GET(import_table, imp);
  337. END;
  338. SYSTEM.CODE(061H) (* popa *)
  339. RETURN 0
  340. END dll_Load;
  341. PROCEDURE [stdcall] dll_Init (entry: INTEGER);
  342. BEGIN
  343. SYSTEM.CODE(060H); (* pusha *)
  344. IF entry # 0 THEN
  345. dll_init2(SYSTEM.ADR(malloc), SYSTEM.ADR(free), SYSTEM.ADR(realloc), SYSTEM.ADR(dll_Load), entry)
  346. END;
  347. SYSTEM.CODE(061H); (* popa *)
  348. END dll_Init;
  349. PROCEDURE LoadLib* (name: ARRAY OF CHAR): INTEGER;
  350. VAR
  351. Lib: INTEGER;
  352. BEGIN
  353. DLL_INIT := dll_Init;
  354. Lib := sysfunc3(68, 19, SYSTEM.ADR(name[0]));
  355. IF Lib # 0 THEN
  356. init(Lib)
  357. END
  358. RETURN Lib
  359. END LoadLib;
  360. PROCEDURE _init* (import_table: INTEGER);
  361. BEGIN
  362. DLL_INIT := dll_Init;
  363. dll_Load(import_table)
  364. END _init;
  365. END KOSAPI.