123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809 |
- {****************************************************************************
- FPK-Pascal -- OS/2 runtime library
- Copyright (c) 1993,95 by Florian Kl„mpfl
- Copyright (c) 1997 by Dani‰l Mantione
- FPK-Pascal is distributed under the GNU Public License v2. So is this unit.
- The GNU Public License requires you to distribute the source code of this
- unit with any product that uses it. We grant you an exception to this, and
- that is, when you compile a program with the FPK Pascal compiler, you do not
- need to ship source code with that program, AS LONG AS YOU ARE USING
- UNMODIFIED CODE! If you modify this code, you MUST change the next line:
- <This an official, unmodified FPK Pascal source code file.>
- Send us your modified files, we can work together if you want!
- ****************************************************************************}
- unit sysos2;
- {$I os.inc}
- interface
- { die betriebssystemunabhangigen Deklarationen einfuegen: }
- {$I SYSTEMH.INC}
- {$I heaph.inc}
- type Tos=(osDOS,osOS2,osDPMI);
- var os_mode:Tos;
- first_meg:pointer;
- type Psysthreadib=^Tsysthreadib;
- Pthreadinfoblock=^Tthreadinfoblock;
- Pprocessinfoblock=^Tprocessinfoblock;
- Tbytearray=array[0..$ffff] of byte;
- Pbytearray=^Tbytearray;
- Tsysthreadib=record
- tid,
- priority,
- version:longint;
- MCcount,
- MCforceflag:word;
- end;
- Tthreadinfoblock=record
- pexchain,
- stack,
- stacklimit:pointer;
- tib2:Psysthreadib;
- version,
- ordinal:longint;
- end;
- Tprocessinfoblock=record
- pid,
- parentpid,
- hmte:longint;
- cmd,
- env:Pbytearray;
- flstatus,
- ttype:longint;
- end;
- procedure _DosGetInfoBlocks(var Atib:Pthreadinfoblock;
- var Apib:Pprocessinfoblock);
- implementation
- { die betriebssystemunabhangigen Implementationen einfuegen: }
- {$I SYSTEM.INC}
- procedure _DosGetInfoBlocks(var Atib:Pthreadinfoblock;
- var Apib:Pprocessinfoblock);[C];
- {****************************************************************************
- Miscelleanious related routines.
- ****************************************************************************}
- procedure halt;
- begin
- asm
- movw $0x4c00,%ax
- call ___syscall
- end;
- end;
- procedure halt(errnum : byte);
- begin
- asm
- movb $0x4c,%ah
- movb errnum,%al
- call ___syscall
- end;
- end;
- function paramcount : longint;
- begin
- asm
- movl _argc,%eax
- decl %eax
- leave
- ret
- end ['EAX'];
- end;
- function paramstr(l : longint):string;
- function args : pointer;
- begin
- asm
- movl _argv,%eax
- leave
- ret
- end ['EAX'];
- end;
- var p:^Pchar;
- begin
- if (l>=0) and (l<=paramcount) then
- begin
- p:=args;
- paramstr:=strpas(p[l]);
- end
- else paramstr:='';
- end;
- procedure randomize;
- var hl:longint;
- begin
- asm
- movb $0x2c,%ah
- call ___syscall
- movw %cx,-4(%ebp)
- movw %dx,-2(%ebp)
- end;
- randseed:=hl;
- end;
- {****************************************************************************
- Text-file I/O related routines.
- ****************************************************************************}
- function open(f:Pchar;flags:longint):longint;
- begin
- asm
- movb $0x3d,%ah
- movl 8(%ebp),%edx
- movb 12(%ebp),%al
- call ___syscall
- jnc LOPEN1
- movw %ax,U_SYSOS2_INOUTRES;
- xorl %eax,%eax
- LOPEN1:
- ; Returnwert ist in EAX
- leave
- ret $8
- end;
- end;
- function create(f : pchar):longint;
- begin
- asm
- movb $0x3c,%ah
- movl 8(%ebp),%edx
- xor %ecx,%ecx
- call ___syscall
- jnc Lcreate1
- movw %ax,U_SYSOS2_INOUTRES;
- xorl %eax,%eax
- Lcreate1:
- ; Returnwert ist in EAX
- leave
- ret $8
- end;
- end;
- procedure do_close(h:longint);
- begin
- asm
- movb $0x3e,%ah
- mov h,%ebx
- call ___syscall
- end;
- end;
- function dosfilepos(handle:longint) : longint;
- begin
- asm
- movb $0x42,%ah
- movb $0x1,%al
- movl 8(%ebp),%ebx
- xorl %edx,%edx
- call ___syscall
- jnc LDOSFILEPOS
- movw %ax,U_SYSOS2_INOUTRES;
- xorl %eax,%eax
- LDOSFILEPOS:
- leave
- ret $4
- end;
- end;
- procedure dosseek(handle:longint;pos:longint);
- begin
- asm
- movb $0x42,%ah
- xorb %al,%al
- movl 8(%ebp),%ebx
- movl 12(%ebp),%edx
- call ___syscall
- jnc LDOSSEEK1
- movw %ax,U_SYSOS2_INOUTRES;
- LDOSSEEK1:
- end;
- end;
- function dosfilesize(handle : longint):longint;
- function set_at_end(handle:longint) : longint;
- begin
- asm
- movb $0x42,%ah
- movb $0x2,%al
- ; Vorsicht Stack: 0 %ebp; 4 retaddr;
- ; 8 nextstackframe; 12 handle
- movl 12(%ebp),%ebx
- xorl %edx,%edx
- call ___syscall
- jnc Lset_at_end
- movw %ax,U_SYSOS2_INOUTRES;
- xorl %eax,%eax
- Lset_at_end:
- leave
- ret $8
- end;
- end;
- var tempfilesize,aktfilepos:longint;
- begin
- aktfilepos:=dosfilepos(handle);
- tempfilesize:=set_at_end(handle);
- dosseek(handle,aktfilepos);
- dosfilesize:=tempfilesize;
- end;
- procedure fileclosefunc(var t : textrec);
- begin
- do_close(t.handle);
- t.mode:=fmclosed;
- end;
- procedure fileopenfunc(var f:textrec);
- var b:array[0..255] of char;
- size:longint;
- begin
- move(f.name[1],b,length(f.name));
- b[length(f.name)]:=#0;
- f.inoutfunc:=@fileinoutfunc;
- f.flushfunc:=@fileinoutfunc;
- f.closefunc:=@fileclosefunc;
- case f.mode of
- fminput:
- f.handle:=open(b,0);
- fmoutput:
- f.handle:=create(b);
- fmappend:
- begin
- f.handle:=open(b,1);
- f.mode:=fmoutput;
- size:=dosfilesize(f.handle);
- if size>0 then
- begin
- {Set filepointer to eof character if present,
- or to end of file if not. Any change to the
- file causes the eof character to be overwritten,
- so we get a correct text file.}
- dosseek(f.handle,size-1);
- dosread(f.handle,longint(@b),1);
- if b[0]<>#26 then
- dosseek(f.handle,size);
- end;
- end;
- end;
- end;
- function eof(var t:text):boolean;[iocheck];
- var zoekpos:byte;
- begin
- { maybe we need new data }
- if textrec(t).bufpos+3>=textrec(t).bufend then
- dateifunc(textrec(t).inoutfunc)(textrec(t));
- eof:=dosfilesize(textrec(t).handle)<=dosfilepos(textrec(t).handle);
- if eof then
- eof:=textrec(t).bufend<=textrec(t).bufpos;
- if not eof then
- begin
- {If the next character is an end-of-file character,
- or if we are at eoln and first character on next line
- is eof then we should also return true.}
- zoekpos:=textrec(t).bufpos;
- while textrec(t).buffer[zoekpos] in [#13,#10] do
- inc(zoekpos);
- if zoekpos>textrec(t).bufpos+2 then
- eof:=false
- else
- eof:=textrec(t).buffer[zoekpos]=#26;
- end;
- end;
- {****************************************************************************
- File I/O related routines.
- ****************************************************************************}
- procedure doserase(p:Pchar);
- begin
- asm
- movl 8(%ebp),%edx
- movb $0x41,%ah
- call ___syscall
- jnc LERASE1
- movw %ax,U_SYSOS2_INOUTRES;
- LERASE1:
- end;
- end;
- procedure dosrename(p1,p2:Pchar);
- begin
- asm
- movl 8(%ebp),%edx
- movl 12(%ebp),%edi
- movb $0x56,%ah
- call ___syscall
- jnc LRENAME1
- movw %ax,U_SYSOS2_INOUTRES;
- LRENAME1:
- end;
- end;
- function dosread(h,addr,len:longint):longint;
- begin
- asm
- movl 16(%ebp),%ecx
- movl 12(%ebp),%edx
- movl 8(%ebp),%ebx
- movb $0x3f,%ah
- call ___syscall
- jnc LDOSREAD1
- movw %ax,U_SYSOS2_INOUTRES;
- xorl %eax,%eax
- LDOSREAD1:
- leave
- ret $12
- end;
- end;
- function doswrite(h,addr,len:longint) : longint;
- begin
- asm
- movl 16(%ebp),%ecx
- movl 12(%ebp),%edx
- movl 8(%ebp),%ebx
- movb $0x40,%ah
- call ___syscall
- jnc LDOSWRITE1
- movw %ax,U_SYSOS2_INOUTRES;
- LDOSWRITE1:
- movl %eax,-4(%ebp)
- end;
- end;
- procedure rewrite(var f:file;l:word);
- var b:array[0..255] of char;
- begin
- {According to Turbo Pascal helpfile, a file is automatically closed
- if it's open.}
- if filerec(f).mode<>fmclosed then
- close(f);
- filerec(f).mode:=fmoutput;
- move(filerec(f).name[1],b,length(filerec(f).name));
- b[length(filerec(f).name)]:=#0;
- filerec(f).handle:=create(b);
- filerec(f).recsize:=l;
- end;
- procedure rewrite(var f:file);
- begin
- rewrite(f,128);
- end;
- procedure reset(var f:file;l:word);
- var b:array[0..255] of char;
- begin
- {According to Turbo Pascal helpfile, a file is automatically closed
- if it's open.}
- if filerec(f).mode<>fmclosed then
- close(f);
- move(filerec(f).name[1],b,length(filerec(f).name));
- b[length(filerec(f).name)]:=#0;
- case filemode of
- 0:
- begin
- filerec(f).mode:=fminput;
- filerec(f).handle:=open(b,0);
- end;
- 1:
- begin
- filerec(f).mode:=fmoutput;
- filerec(f).handle:=open(b,1);
- end;
- 2:
- begin
- filerec(f).mode:=fminout;
- filerec(f).handle:=open(b,2);
- end;
- end;
- filerec(f).recsize:=l;
- end;
- procedure reset(var f:file);
- begin
- reset(f,128);
- end;
- procedure blockwrite(var f:file;var buf;count:longint);
- var p:pointer;
- size:longint;
- begin
- p:=@buf;
- doswrite(filerec(f).handle,longint(p),count*filerec(f).recsize);
- end;
- procedure blockread(var f:file;var buf;count:longint;var result:longint);
- begin
- result:=dosread(filerec(f).handle,longint(@buf),
- count*filerec(f).recsize) div filerec(f).recsize;
- end;
- procedure blockread(var f:file;var buf;count:longint);
- var result:longint;
- begin
- blockread(f,buf,count,result);
- end;
- procedure truncate (var f : file);[iocheck];
- var p : pointer;
- begin
- doswrite(filerec(f).handle,longint(p),0);
- end;
- procedure close(var f:file);
- begin
- if (filerec(f).mode<>fmclosed) then
- begin
- filerec(f).mode:=fmclosed;
- do_close(filerec(f).handle);
- end;
- end;
- function filepos(var f:file):longint;
- var l:longint;
- begin
- filepos:=dosfilepos(filerec(f).handle) div filerec(f).recsize;
- end;
- function filesize(var f:file) : longint;
- begin
- filesize:=dosfilesize(filerec(f).handle) div filerec(f).recsize;
- end;
- function eof(var f:file):boolean;[iocheck];
- begin
- eof:=filesize(f)<=filepos(f);
- end;
- procedure seek(var f:file;pos : longint);
- begin
- dosseek(filerec(f).handle,pos*filerec(f).recsize);
- end;
- {****************************************************************************
- Directory related routines.
- ****************************************************************************}
- procedure dos_dirs(func:byte;name:Pchar);
- begin
- asm
- movl 10(%ebp),%edx
- movb 8(%ebp),%ah
- call ___syscall
- jnc LDOS_DIRS1
- movw %ax,U_SYSOS2_INOUTRES;
- LDOS_DIRS1:
- leave
- ret $6
- end;
- end;
- procedure _dir(func:byte;const s:string);
- var buffer:array[0..255] of char;
- begin
- move(s[1],buffer,length(s));
- buffer[length(s)]:=#0;
- dos_dirs(func,buffer);
- end;
- procedure mkdir(const s:string);
- begin
- _dir($39,s);
- end;
- procedure rmdir(const s:string);
- begin
- _dir($3a,s);
- end;
- procedure chdir(const s:string);
- begin
- _dir($3b,s);
- end;
- { thanks to Michael Van Canneyt <[email protected]>, }
- { who wrote this code }
- procedure getdir(drivenr:byte;var dir:string);
- var temp:string;
- sof:pointer;
- i:byte;
- begin
- sof:=@dir[4];
- { dir[1..3] will contain '[drivenr]:\', but is not }
- { supplied by DOS, so we let dos string start at }
- { dir[4] }
- asm
- { Get dir from drivenr:0=default, 1=A etc... }
- movb drivenr,%dl
- { put (previously saved) offset in si }
- movl sof,%esi
- { call msdos function 47H : Get dir }
- mov $0x47,%ah
- { make the call }
- call ___syscall
- { Rem: if call unsuccesfull, carry is set, and AX has }
- { error code }
- end;
- { Now Dir should be filled with directory in ASCIIZ, }
- { starting from dir[4] }
- dir[0]:=#3;
- dir[2]:=':';
- dir[3]:='\';
- i:=4;
- { conversation to Pascal string }
- while (dir[i]<>#0) do
- begin
- { convert path name to DOS }
- if dir[i]='/' then
- dir[i]:='\';
- dir[0]:=chr(i);
- inc(i);
- end;
- { upcase the string (FPKPascal function) }
- dir:=upcase(dir);
- if drivenr<>0 then { Drive was supplied. We know it }
- dir[1]:=chr(65+drivenr-1)
- else
- begin
- { We need to get the current drive from DOS function 19H }
- { because the drive was the default, which can be unknown }
- asm
- movb $0x19,%ah
- call ___syscall
- addb $65,%al
- movb %al,i
- end;
- dir[1]:=chr(i)
- end;
- end;
- {****************************************************************************
- Heap management releated routines.
- ****************************************************************************}
- { this function allows to extend the heap by calling
- syscall $7f00 resizes the brk area}
- function sbrk(size:longint):longint;
- begin
- asm
- movl size,%edx
- movl $0x7f00,%ax
- int $0x21
- movl %eax,__RESULT
- end;
- end;
- function getheapstart:pointer;
- begin
- asm
- movl __heap_base,%eax
- leave
- ret
- end ['EAX'];
- end;
- {$i heap.inc}
- {***************************************************************************
- Runtime error checking related routines.
- ***************************************************************************}
- {$S-}
- procedure st1(stack_size:longint);[public,alias: 'STACKCHECK'];
- begin
- { called when trying to get local stack }
- { if the compiler directive $S is set }
- asm
- movl stack_size,%ebx
- movl %esp,%eax
- subl %ebx,%eax
- {$ifdef SYSTEMDEBUG}
- movl U_SYSOS2_LOWESTSTACK,%ebx
- cmpl %eax,%ebx
- jb _is_not_lowest
- movl %eax,U_SYSOS2_LOWESTSTACK
- _is_not_lowest:
- {$endif SYSTEMDEBUG}
- cmpb $2,U_SYSOS2_OS_MODE
- jne _running_in_dos
- movl U_SYSOS2_STACKBOTTOM,%ebx
- jmp _running_in_os2
- _running_in_dos:
- movl __heap_brk,%ebx
- _running_in_os2:
- cmpl %eax,%ebx
- jae __short_on_stack
- leave
- ret $4
- __short_on_stack:
- end ['EAX','EBX'];
- { this needs a local variable }
- { so the function called itself !! }
- { Writeln('low in stack ');}
- RunError(202);
- end;
- {no stack check in system }
- {****************************************************************************
- System unit initialization.
- ****************************************************************************}
- var
- pib:Pprocessinfoblock;
- tib:Pthreadinfoblock;
- begin
- {Determine the operating system we are running on.}
- asm
- movw $0x7f0a,%ax
- call ___syscall
- test $512,%bx ; Bit 9 is OS/2 flag.
- setnzb U_SYSOS2_OS_MODE
- test $4096,%bx
- jz _noRSX
- movb $2,U_SYSOS2_OS_MODE
- _noRSX:
- end;
- {Now request, if we are running under DOS,
- read-access to the first meg. of memory.}
- if os_mode in [osDOS,osDPMI] then
- asm
- mov $0x7f13,%ax
- xor %ebx,%ebx
- mov $0xfff,%ecx
- xor %edx,%edx
- call ___syscall
- mov %eax,U_SYSOS2_FIRST_MEG
- end
- else
- first_meg:=nil;
- {At 0.9.2, case for enumeration does not work.}
- case os_mode of
- osDOS:
- stackbottom:=0;
- osOS2:
- begin
- _DosGetInfoBlocks(tib,pib);
- stackbottom:=longint(tib^.stack);
- end;
- osDPMI:
- stackbottom:=0; {Not sure how to get it, but seems to be
- always zero.}
- end;
- exitproc:=nil;
- {Initialize the heap.}
- InitHeap;
-
- { to test stack depth }
- loweststack:=maxlongint;
- {Enable the brk area by initializing it with the initial heap size.}
- asm
- mov $0x7f01,%ax
- movl HEAPSIZE,%edx
- call ___syscall
- end;
- { Ein- und Ausgabe initialisieren }
- assign(input,'');
- textrec(input).handle:=0;
- textrec(input).mode:=fminput;
- textrec(input).inoutfunc:=@fileinoutfunc;
- textrec(input).flushfunc:=@fileinoutfunc;
- assign(output,'');
- textrec(output).handle:=1;
- textrec(output).mode:=fmoutput;
- textrec(output).inoutfunc:=@fileinoutfunc;
- textrec(output).flushfunc:=@fileinoutfunc;
- textrec(input).mode:=fminput;
- { kein Ein- Ausgabefehler }
- inoutres:=0;
- end.
|