sysamiga.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team.
  5. Some parts taken from
  6. Marcel Timmermans - Modula 2 Compiler
  7. Nils Sjoholm - Amiga porter
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. unit sysamiga;
  15. { Things left to do : }
  16. { - Fix randomize }
  17. { - Fix DOSError result variable to conform to IOResult of }
  18. { Turbo Pascal }
  19. {$I os.inc}
  20. interface
  21. { used for single computations }
  22. const BIAS4 = $7f-1;
  23. {$I systemh.inc}
  24. {$I heaph.inc}
  25. const
  26. UnusedHandle : longint = -1;
  27. StdInputHandle : longint = 0;
  28. StdOutputHandle : longint = 0;
  29. StdErrorHandle : longint = 0;
  30. _ExecBase:longint = $4;
  31. _WorkbenchMsg : longint = 0;
  32. intuitionname : pchar = 'intuition.library';
  33. dosname : pchar = 'dos.library';
  34. utilityname : pchar = 'utility.library';
  35. _IntuitionBase : pointer = nil; { intuition library pointer }
  36. _DosBase : pointer = nil; { DOS library pointer }
  37. _UtilityBase : pointer = nil; { utiity library pointer }
  38. _LVOFindTask = -294;
  39. _LVOWaitPort = -384;
  40. _LVOGetMsg = -372;
  41. _LVOOpenLibrary = -552;
  42. _LVOCloseLibrary = -414;
  43. _LVOClose = -36;
  44. _LVOOpen = -30;
  45. _LVOIoErr = -132;
  46. _LVOSeek = -66;
  47. _LVODeleteFile = -72;
  48. _LVORename = -78;
  49. _LVOWrite = -48;
  50. _LVORead = -42;
  51. _LVOCreateDir = -120;
  52. _LVOSetCurrentDirName = -558;
  53. _LVOGetCurrentDirName = -564;
  54. _LVOInput = -54;
  55. _LVOOutput = -60;
  56. implementation
  57. {$I system.inc}
  58. {$I lowmath.inc}
  59. type
  60. plongint = ^longint;
  61. {$S-}
  62. PROCEDURE St1(stack_size: longint);[public,alias: 'STACKCHECK'];
  63. begin
  64. asm
  65. { called when trying to get local stack }
  66. { if the compiler directive $S is set }
  67. { it must preserve all registers !! }
  68. ADD.L A7,D0 { stacksize + actual stackpointer }
  69. MOVE.L _ExecBase,A0
  70. MOVE.L 276(A0),A0 { ExecBase.thisTask }
  71. CMP.L 58(A0),D0 { Task.SpLower }
  72. BGT @Ok
  73. move.l #202,d0
  74. jsr HALT_ERROR { stack overflow }
  75. @Ok:
  76. end;
  77. end;
  78. procedure CloseLibrary(lib : pointer); Assembler;
  79. { Close the library pointed to in lib }
  80. asm
  81. MOVE.L A6,-(A7)
  82. MOVE.L _ExecBase,A6
  83. MOVE.L lib,a1
  84. JSR _LVOCloseLibrary(A6)
  85. MOVE.L (A7)+,A6
  86. end;
  87. Function KickVersion: word; assembler;
  88. asm
  89. move.l _ExecBase, a0 { Get Exec Base }
  90. move.l 20(a0), d0 { Return version - version at this offset }
  91. end;
  92. procedure halt(errnum : byte);
  93. begin
  94. do_exit;
  95. flush(stderr);
  96. { close the libraries }
  97. If _UtilityBase <> nil then
  98. Begin
  99. CloseLibrary(_UtilityBase);
  100. end;
  101. If _DosBase <> nil then
  102. Begin
  103. CloseLibrary(_DosBase);
  104. end;
  105. If _IntuitionBase <> nil then
  106. Begin
  107. CloseLibrary(_IntuitionBase);
  108. end;
  109. asm
  110. clr.l d0
  111. move.b errnum,d0
  112. move.l STKPTR,sp
  113. rts
  114. end;
  115. end;
  116. function paramcount : longint; assembler;
  117. asm
  118. clr.l d0
  119. move.w __ARGC,d0
  120. sub.w #1,d0
  121. end;
  122. function paramstr(l : longint) : string;
  123. function args : pointer; assembler;
  124. asm
  125. move.l __ARGS,d0
  126. end;
  127. var
  128. p : ^pchar;
  129. begin
  130. if (l>=0) and (l<=paramcount) then
  131. begin
  132. p:=args;
  133. paramstr:=strpas(p[l]);
  134. end
  135. else paramstr:='';
  136. end;
  137. procedure randomize;
  138. var
  139. hl : longint;
  140. begin
  141. asm
  142. { !!!!!!! }
  143. end;
  144. randseed:=hl;
  145. end;
  146. { This routine is used to grow the heap. }
  147. { But here we do a trick, we say that the }
  148. { heap cannot be regrown! }
  149. function sbrk( size: longint): longint;
  150. { on exit -1 = if fails. }
  151. Begin
  152. sbrk:=-1;
  153. end;
  154. {$I heap.inc}
  155. {****************************************************************************
  156. Low Level File Routines
  157. ****************************************************************************}
  158. procedure do_close(h : longint);
  159. begin
  160. asm
  161. move.l h,d1
  162. move.l a6,d6 { save a6 }
  163. move.l _DOSBase,a6
  164. jsr _LVOClose(a6)
  165. move.l d6,a6 { restore a6 }
  166. end;
  167. end;
  168. procedure do_erase(p : pchar);
  169. begin
  170. asm
  171. move.l a6,d6 { save a6 }
  172. move.l _DOSBase,a6
  173. move.l p,d1
  174. jsr _LVODeleteFile(a6)
  175. tst.l d0 { zero = failure }
  176. bne @noerror
  177. jsr _LVOIoErr(a6)
  178. move.l d0,InOutRes
  179. @noerror:
  180. move.l d6,a6 { restore a6 }
  181. end;
  182. end;
  183. procedure do_rename(p1,p2 : pchar);
  184. begin
  185. asm
  186. move.l a6,d6 { save a6 }
  187. move.l d2,-(sp) { save d2 }
  188. move.l p1,d1
  189. move.l p2,d2
  190. move.l _DOSBase,a6
  191. jsr _LVORename(a6)
  192. move.l (sp)+,d2 { restore d2 }
  193. tst.l d0
  194. bne @dosreend { if zero = error }
  195. jsr _LVOIoErr(a6)
  196. move.l d0,InOutRes
  197. @dosreend:
  198. move.l d6,a6 { restore a6 }
  199. end;
  200. end;
  201. function do_write(h,addr,len : longint) : longint;
  202. begin
  203. asm
  204. move.l a6,d6
  205. movem.l d2/d3,-(sp)
  206. move.l _DOSBase,a6
  207. move.l h,d1
  208. move.l addr,d2
  209. move.l len,d3
  210. jsr _LVOWrite(a6)
  211. movem.l (sp)+,d2/d3
  212. tst.l d0
  213. bne @doswrend { if zero = error }
  214. jsr _LVOIoErr(a6)
  215. move.l d0,InOutRes
  216. bra @doswrend2
  217. @doswrend:
  218. move.l d0,@RESULT
  219. @doswrend2:
  220. move.l d6,a6
  221. end;
  222. end;
  223. function do_read(h,addr,len : longint) : longint;
  224. begin
  225. asm
  226. move.l a6,d6
  227. movem.l d2/d3,-(sp)
  228. move.l _DOSBase,a6
  229. move.l h,d1
  230. move.l addr,d2
  231. move.l len,d3
  232. jsr _LVORead(a6)
  233. movem.l (sp)+,d2/d3
  234. tst.l d0
  235. bne @doswrend { if zero = error }
  236. jsr _LVOIoErr(a6)
  237. move.l d0,InOutRes
  238. bra @doswrend2
  239. @doswrend:
  240. move.l d0,@RESULT
  241. @doswrend2:
  242. move.l d6,a6
  243. end;
  244. end;
  245. function do_filepos(handle : longint) : longint;
  246. begin
  247. asm
  248. move.l a6,d6
  249. move.l handle,d1
  250. move.l d2,-(sp)
  251. move.l d3,-(sp) { save registers }
  252. clr.l d2 { offset 0 }
  253. move.l #0,d3 { OFFSET_CURRENT }
  254. jsr _LVOSeek(a6)
  255. move.l (sp)+,d3 { restore registers }
  256. move.l (sp)+,d2
  257. cmp.l #-1,d0 { is there a file access error? }
  258. bne @noerr
  259. jsr _LVOIoErr(a6)
  260. move.l d0,InOutRes
  261. bra @fposend
  262. @noerr:
  263. move.l d0,@Result
  264. @fposend:
  265. move.l d6,a6 { restore a6 }
  266. end;
  267. end;
  268. procedure do_seek(handle,pos : longint);
  269. begin
  270. asm
  271. move.l a6,d6
  272. move.l handle,d1
  273. move.l d2,-(sp)
  274. move.l d3,-(sp) { save registers }
  275. move.l pos,d2
  276. move.l #-1,d3 { OFFSET_BEGINNING }
  277. jsr _LVOSeek(a6)
  278. move.l (sp)+,d3 { restore registers }
  279. move.l (sp)+,d2
  280. cmp.l #-1,d0 { is there a file access error? }
  281. bne @noerr
  282. jsr _LVOIoErr(a6)
  283. move.l d0,InOutRes
  284. bra @seekend
  285. @noerr:
  286. @seekend:
  287. move.l d6,a6 { restore a6 }
  288. end;
  289. end;
  290. function do_seekend(handle:longint):longint;
  291. begin
  292. asm
  293. { seek from end of file }
  294. move.l a6,d6
  295. move.l handle,d1
  296. move.l d2,-(sp)
  297. move.l d3,-(sp) { save registers }
  298. clr.l d2
  299. move.l #1,d3 { OFFSET_END }
  300. jsr _LVOSeek(a6)
  301. move.l (sp)+,d3 { restore registers }
  302. move.l (sp)+,d2
  303. cmp.l #-1,d0 { is there a file access error? }
  304. bne @noerr
  305. jsr _LVOIoErr(a6)
  306. move.l d0,InOutRes
  307. bra @seekend
  308. @noerr:
  309. move.l d0,@Result
  310. @seekend:
  311. move.l d6,a6 { restore a6 }
  312. end;
  313. end;
  314. function do_filesize(handle : longint) : longint;
  315. var
  316. aktfilepos : longint;
  317. begin
  318. aktfilepos:=do_filepos(handle);
  319. do_filesize:=do_seekend(handle);
  320. do_seek(handle,aktfilepos);
  321. end;
  322. procedure do_truncate (handle,pos:longint);
  323. begin
  324. {!!!!!!!!!!!!}
  325. end;
  326. procedure do_open(var f;p:pchar;flags:longint);
  327. {
  328. filerec and textrec have both handle and mode as the first items so
  329. they could use the same routine for opening/creating.
  330. when (flags and $10) the file will be append
  331. when (flags and $100) the file will be truncate/rewritten
  332. when (flags and $1000) there is no check for close (needed for textfiles)
  333. }
  334. var
  335. i : longint;
  336. oflags: longint;
  337. begin
  338. { close first if opened }
  339. if ((flags and $1000)=0) then
  340. begin
  341. case filerec(f).mode of
  342. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  343. fmclosed : ;
  344. else
  345. begin
  346. inoutres:=102; {not assigned}
  347. exit;
  348. end;
  349. end;
  350. end;
  351. { reset file handle }
  352. filerec(f).handle:=UnusedHandle;
  353. oflags:=$04;
  354. { convert filemode to filerec modes }
  355. case (flags and 3) of
  356. 0 : begin
  357. filerec(f).mode:=fminput;
  358. oflags:=$01;
  359. end;
  360. 1 : filerec(f).mode:=fmoutput;
  361. 2 : filerec(f).mode:=fminout;
  362. end;
  363. if (flags and $100)<>0 then
  364. begin
  365. filerec(f).mode:=fmoutput;
  366. oflags:=$02;
  367. end
  368. else
  369. if (flags and $10)<>0 then
  370. begin
  371. filerec(f).mode:=fmoutput;
  372. oflags:=$04;
  373. end;
  374. { empty name is special }
  375. if p[0]=#0 then
  376. begin
  377. case filerec(f).mode of
  378. fminput : filerec(f).handle:=StdInputHandle;
  379. fmappend,
  380. fmoutput : begin
  381. filerec(f).handle:=StdOutputHandle;
  382. filerec(f).mode:=fmoutput; {fool fmappend}
  383. end;
  384. end;
  385. exit;
  386. end;
  387. { THE AMIGA AUTOMATICALLY OPENS IN READ-WRITE MODE }
  388. { FOR ALL CASES. }
  389. asm
  390. move.l a6,d6 { save a6 }
  391. move.l f,d1
  392. move.l #1004,d0 { MODE_READWRITE }
  393. move.l _DOSBase,a6
  394. jsr _LVOOpen(a6)
  395. tst.l d0
  396. bne @noopenerror { on zero an error occured }
  397. jsr _LVOIoErr(a6)
  398. move.l d0,InOutRes
  399. bra @openend
  400. @noopenerror:
  401. move.l d0,i
  402. @openend:
  403. move.l d6,a6 { restore a6 }
  404. end;
  405. filerec(f).handle:=i;
  406. if (flags and $10)<>0 then
  407. do_seekend(filerec(f).handle);
  408. end;
  409. {*****************************************************************************
  410. UnTyped File Handling
  411. *****************************************************************************}
  412. {$i file.inc}
  413. {*****************************************************************************
  414. Typed File Handling
  415. *****************************************************************************}
  416. {$i typefile.inc}
  417. {*****************************************************************************
  418. Text File Handling
  419. *****************************************************************************}
  420. {$i text.inc}
  421. {*****************************************************************************
  422. Directory Handling
  423. *****************************************************************************}
  424. procedure mkdir(const s : string);
  425. var
  426. buffer : array[0..255] of char;
  427. begin
  428. move(s[1],buffer,length(s));
  429. buffer[length(s)]:=#0;
  430. asm
  431. move.l a6,d6
  432. move.l _DosBase,a6
  433. lea buffer,a0
  434. move.l a0,d1
  435. jsr _LVOCreateDir(a6)
  436. tst.l d0
  437. bne @noerror
  438. move.l #1,InOutRes
  439. @noerror:
  440. move.l d6,a6
  441. end;
  442. end;
  443. procedure rmdir(const s : string);
  444. var
  445. buffer : array[0..255] of char;
  446. begin
  447. move(s[1],buffer,length(s));
  448. buffer[length(s)]:=#0;
  449. do_erase(buffer);
  450. end;
  451. procedure chdir(const s : string);
  452. var
  453. buffer : array[0..255] of char;
  454. begin
  455. move(s[1],buffer,length(s));
  456. buffer[length(s)]:=#0;
  457. asm
  458. move.l a6,d6
  459. move.l _DosBase,a6
  460. lea buffer,a1
  461. move.l a1,d1
  462. jsr _LVOSetCurrentDirName(a6)
  463. bne @noerror
  464. move.l #1,InOutRes
  465. @noerror:
  466. move.l d6,a6
  467. end;
  468. end;
  469. procedure getdir(drivenr : byte;var dir : string);
  470. var
  471. l : longint;
  472. p : pointer;
  473. begin
  474. l:=length(dir);
  475. if drivenr <> 0 then
  476. begin
  477. dir:='';
  478. exit;
  479. end;
  480. p:=@dir[1];
  481. if l <> 0 then { workaround for v36 bug }
  482. Begin
  483. asm
  484. move.l a6,d6
  485. move.l _DosBase,a6
  486. move.l p,d1
  487. move.l l,d2
  488. jsr _LVOGetCurrentDirName(a6)
  489. bne @noerror
  490. move.l #1,InOutRes
  491. @noerror:
  492. move.l d6,a6
  493. end;
  494. end
  495. else
  496. dir:='';
  497. { upcase the string (FPKPascal function) }
  498. dir:=upcase(dir);
  499. end;
  500. {*****************************************************************************
  501. SystemUnit Initialization
  502. *****************************************************************************}
  503. Procedure Startup; Assembler;
  504. asm
  505. move.l a6,d6 { save a6 }
  506. move.l (4),a6 { get ExecBase pointer }
  507. move.l a6,_ExecBase
  508. suba.l a1,a1
  509. jsr _LVOFindTask(a6)
  510. move.l d0,a0
  511. { Check the stack value }
  512. { are we running from a CLI? }
  513. tst.l 172(a0) { 172 = pr_CLI }
  514. bne @fromCLI
  515. { we do not support Workbench yet .. }
  516. move.l d6,a6 { restore a6 }
  517. move.l #1,d0
  518. jsr HALT_ERROR
  519. @fromCLI:
  520. { Open the following libraries: }
  521. { Intuition.library }
  522. { dos.library }
  523. moveq.l #0,d0
  524. lea intuitionname,a1
  525. jsr _LVOOpenLibrary(a6)
  526. move.l d0,_IntuitionBase
  527. beq @exitprg
  528. moveq.l #0,d0
  529. lea utilityname,a1
  530. jsr _LVOOpenLibrary(a6)
  531. move.l d0,_UtilityBase
  532. beq @exitprg
  533. moveq.l #0,d0
  534. lea dosname,a1
  535. jsr _LVOOpenLibrary(a6)
  536. move.l d0,_DOSBase
  537. beq @exitprg
  538. { Find standard input and output }
  539. { for CLI }
  540. @OpenFiles:
  541. move.l _DOSBase,a6
  542. jsr _LVOInput(a6) { get standard in }
  543. move.l d0, StdInputHandle { save standard Input handle }
  544. { move.l d0,d1 }{ set up for next call }
  545. { jsr _LVOIsInteractive(a6)}{ is it interactive? }
  546. { move.l #_Input,a0 }{ get file record again }
  547. { move.b d0,INTERACTIVE(a0) }{ set flag }
  548. { beq StdInNotInteractive }{ skip this if not interactive }
  549. { move.l BUFFER(a0),a1 }{ get buffer address }
  550. { add.l #1,a1 }{ make end one byte further on }
  551. { move.l a1,MAX(a0) }{ set buffer size }
  552. { move.l a1,CURRENT(a0) }{ will need a read }
  553. bra @OpenStdOutput
  554. @StdInNotInteractive
  555. { jsr _p%FillBuffer } { fill the buffer }
  556. @OpenStdOutput
  557. jsr _LVOOutput(a6) { get ouput file handle }
  558. move.l d0,StdOutputHandle { get file record }
  559. bra @startupend
  560. { move.l d0,d1 } { set up for call }
  561. { jsr _LVOIsInteractive(a6) } { is it interactive? }
  562. { move.l #_Output,a0 } { get file record }
  563. { move.b d0,INTERACTIVE(a0)} { set flag }
  564. @exitprg:
  565. move.l d6,a6 { restore a6 }
  566. move.l #219,d0
  567. jsr HALT_ERROR
  568. @startupend:
  569. move.l d6,a6 { restore a6 }
  570. end;
  571. procedure OpenStdIO(var f:text;mode:word;hdl:longint);
  572. begin
  573. Assign(f,'');
  574. TextRec(f).Handle:=hdl;
  575. TextRec(f).Mode:=mode;
  576. TextRec(f).InOutFunc:=@FileInOutFunc;
  577. TextRec(f).FlushFunc:=@FileInOutFunc;
  578. TextRec(f).Closefunc:=@fileclosefunc;
  579. end;
  580. begin
  581. { Startup }
  582. Startup;
  583. { Only AmigaOS v2.04 or greater is supported }
  584. If KickVersion < 36 then
  585. Begin
  586. WriteLn('v36 or greater of Kickstart required.');
  587. Halt(1);
  588. end;
  589. { Initialize ExitProc }
  590. ExitProc:=Nil;
  591. { to test stack depth }
  592. loweststack:=maxlongint;
  593. { Setup heap }
  594. InitHeap;
  595. { Setup stdin, stdout and stderr }
  596. OpenStdIO(Input,fmInput,StdInputHandle);
  597. OpenStdIO(Output,fmOutput,StdOutputHandle);
  598. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  599. { Reset IO Error }
  600. InOutRes:=0;
  601. end.
  602. {
  603. $Log$
  604. Revision 1.1 1998-03-25 11:18:47 root
  605. Initial revision
  606. Revision 1.14 1998/03/21 04:20:09 carl
  607. * correct ExecBase pointer (from Nils Sjoholm)
  608. * correct OpenLibrary vector (from Nils Sjoholm)
  609. Revision 1.13 1998/03/14 21:34:32 carl
  610. * forgot to save a6 in Startup routine
  611. Revision 1.12 1998/02/24 21:19:42 carl
  612. *** empty log message ***
  613. Revision 1.11 1998/02/23 02:22:49 carl
  614. * bugfix if linking problems
  615. Revision 1.9 1998/02/06 16:34:32 carl
  616. + do_open is now standard with other platforms
  617. Revision 1.8 1998/02/02 15:01:45 carl
  618. * fixed bug with opening library versions (from Nils Sjoholm)
  619. Revision 1.7 1998/01/31 19:35:19 carl
  620. + added opening of utility.library
  621. Revision 1.6 1998/01/29 23:20:54 peter
  622. - Removed Backslash convert
  623. Revision 1.5 1998/01/27 10:55:04 peter
  624. * Amiga uses / not \, so change AllowSlash -> AllowBackSlash
  625. Revision 1.4 1998/01/25 21:53:20 peter
  626. + Universal Handles support for StdIn/StdOut/StdErr
  627. * Updated layout of sysamiga.pas
  628. Revision 1.3 1998/01/24 21:09:53 carl
  629. + added missing input/output function pointers
  630. Revision 1.2 1998/01/24 14:08:25 carl
  631. * RunError 217 --> RunError 219 (cannot open lib)
  632. + Standard Handle names implemented
  633. Revision 1.1 1998/01/24 05:12:15 carl
  634. + initial revision, some stuff still missing though.
  635. (and as you might imagine ... untested :))
  636. }