dpmiexcp.pp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by Pierre Muller,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { Translated to FPK pascal by Pierre Muller,
  13. without changing the exceptn.s file }
  14. Unit DPMIEXCP;
  15. {$I os.inc}
  16. { Real mode control-C check removed
  17. because I got problems with the RMCB
  18. can be used by setting this conditionnal (PM) }
  19. { works now correctly (PM) }
  20. {$define UseRMcbrk}
  21. interface
  22. uses go32;
  23. {$S- no stack check !!! }
  24. {$packrecords 2 }
  25. type tjmprec = record
  26. eax,ebx,ecx,edx,esi,edi,ebp,esp,eip,flags : longint;
  27. cs,ds,es,fs,gs,ss : word;
  28. { we should also save the FPU state, if we use this for excpections }
  29. { and the compiler supports FPU register variables }
  30. end;
  31. type pjmprec = ^tjmprec;
  32. type texception_state = record
  33. __eax, __ebx, __ecx, __edx, __esi : longint;
  34. __edi, __ebp, __esp, __eip, __eflags : longint;
  35. __cs, __ds, __es, __fs, __gs, __ss : word;
  36. __sigmask : longint; { for POSIX signals only }
  37. __signum : longint; { for expansion }
  38. __exception_ptr : longint; { pointer to previous exception }
  39. __fpu_state : array [0..108-1] of byte; { for future use }
  40. end;
  41. pexception_state = ^texception_state;
  42. { /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ }
  43. {#define __djgpp_exception_state (*__djgpp_exception_state_ptr) }
  44. const SIGABRT = 288;
  45. const SIGFPE = 289;
  46. const SIGILL = 290;
  47. const SIGSEGV = 291;
  48. const SIGTERM = 292;
  49. const SIGINT = 295;
  50. {const SIG_DFL = 0;}
  51. function SIG_DFL( x: longint) : longint;
  52. function SIG_ERR( x: longint) : longint;
  53. function SIG_IGN( x: longint) : longint;
  54. {const SIG_ERR = -1;
  55. const SIG_IGN = -1;}
  56. { __DJ_pid_t
  57. #undef __DJ_pid_t
  58. const __DJ_pid_t
  59. typedef int sig_atomic_t;
  60. int raise(int _sig);
  61. void (*signal(int _sig, void (*_func)(int)))(int); }
  62. { #ifndef __STRICT_ANSI__
  63. const SA_NOCLDSTOP 1
  64. const SIGALRM 293
  65. const SIGHUP 294
  66. /* SIGINT is ansi */}
  67. const SIGKILL = 296;
  68. const SIGPIPE = 297;
  69. const SIGQUIT = 298;
  70. const SIGUSR1 = 299;
  71. const SIGUSR2 = 300;
  72. {
  73. const SIG_BLOCK 1
  74. const SIG_SETMASK 2
  75. const SIG_UNBLOCK 3 }
  76. const SIGNOFP = 301;
  77. const SIGTRAP = 302;
  78. const SIGTIMR = 303; {/* Internal for setitimer (SIGALRM, SIGPROF) */ }
  79. const SIGPROF = 304;
  80. const SIGMAX = 320;
  81. { extern unsigned short __djgpp_our_DS;
  82. extern unsigned short __djgpp_app_DS; /* Data selector invalidated by HW ints */
  83. extern unsigned short __djgpp_ds_alias; /* Data selector always valid */
  84. extern unsigned short __djgpp_dos_sel; /* Linear mem selector copy in locked mem */
  85. extern unsigned short __djgpp_hwint_flags; /* 1 = Disable Ctrl-C; 2 = Count Ctrl-Break (don't kill) */
  86. extern unsigned __djgpp_cbrk_count; /* Count of CTRL-BREAK hits */
  87. extern int __djgpp_exception_inprog; /* Nested exception count */ }
  88. type SignalHandler = function (v : longint) : longint;
  89. function signal(sig : longint;func : SignalHandler) : SignalHandler;
  90. function _raise(sig : longint) : longint;
  91. procedure djgpp_exception_toggle;
  92. function djgpp_set_ctrl_c(enable : boolean) : boolean; { /* On by default */}
  93. procedure djgpp_exception_setup;
  94. function djgpp_exception_state : pexception_state;
  95. function do_faulting_finish_message : integer;
  96. function setjmp(var rec : tjmprec) : longint;
  97. function dpmi_set_coprocessor_emulation(flag : longint) : longint;
  98. procedure longjmp({const}var rec : tjmprec;return_value : longint);
  99. implementation
  100. {$ASMMODE DIRECT}
  101. {$L exceptn.o}
  102. const exceptions_on : boolean = false;
  103. var starttext, endtext : pointer;
  104. function SIG_ERR( x: longint) : longint;
  105. begin
  106. SIG_ERR:=-1;
  107. end;
  108. function SIG_IGN( x: longint) : longint;
  109. begin
  110. SIG_IGN:=-1;
  111. end;
  112. function SIG_DFL( x: longint) : longint;
  113. begin
  114. SIG_DFL:=0;
  115. end;
  116. { #include <libc/stubs.h>
  117. #include <stdio.h>
  118. #include <stdlib.h>
  119. #include <unistd.h>
  120. #include <io.h>
  121. #include <libc/farptrgs.h>
  122. #include <dpmi.h>
  123. #include <go32.h>
  124. #include <signal.h>
  125. #include <setjmp.h>
  126. #include <errno.h>
  127. #include <crt0.h>
  128. #include <pc.h>
  129. #include <sys/exceptn.h>
  130. #include <sys/nearptr.h> /* For DS base/limit info */
  131. #include <libc/internal.h> }
  132. { const newline = #13#10; }
  133. procedure err(x : string);
  134. begin
  135. write(stderr, x);
  136. flush(stderr);
  137. end;
  138. procedure errln(x : string);
  139. begin
  140. writeln(stderr, x);
  141. flush(stderr);
  142. end;
  143. { extern unsigned end __asm__ ('end'); }
  144. const cbrk_vect : byte = $1b;
  145. { /* May be $06 for PC98 */ }
  146. { /* These are all defined in exceptn.S and only used here */
  147. extern int __djgpp_exception_table;
  148. extern int __djgpp_npx_hdlr;
  149. extern int __djgpp_kbd_hdlr;
  150. extern int __djgpp_kbd_hdlr_pc98;
  151. extern int __djgpp_iret, __djgpp_i24;
  152. extern void __djgpp_cbrk_hdlr(void);
  153. extern int __djgpp_hw_lock_start, __djgpp_hw_lock_end;
  154. extern tseginfo __djgpp_old_kbd; }
  155. procedure itox(v,len : longint);
  156. var st : string;
  157. begin
  158. st:=hexstr(v,len);
  159. err(st);
  160. end;
  161. function except_to_sig(excep : longint) : longint;
  162. begin
  163. case excep of
  164. 5,8,9,11,12,13,14 : exit(SIGSEGV);
  165. 0,4,16 : exit(SIGFPE);
  166. 1,3 : exit(SIGTRAP);
  167. 7 : exit(SIGNOFP);
  168. else
  169. begin
  170. if(excep = $75) then {/* HW int to fake exception values hardcoded in exceptn.S */}
  171. exit(SIGFPE)
  172. else if (excep = $78) then
  173. exit(SIGTIMR)
  174. else if ((excep = $79) or (excep = $1b)) then
  175. exit(SIGINT)
  176. else
  177. exit(SIGILL);
  178. end;
  179. end;
  180. end;
  181. function djgpp_exception_state : pexception_state;
  182. begin
  183. asm
  184. movl ___djgpp_exception_state_ptr,%eax
  185. movl %eax,__RESULT
  186. end;
  187. end;
  188. procedure show_call_frame;
  189. begin
  190. errln('Call frame traceback EIPs:');
  191. errln(' 0x'+hexstr(djgpp_exception_state^.__eip, 8));
  192. dump_stack(djgpp_exception_state^.__ebp);
  193. end;
  194. const EXCEPTIONCOUNT = 18;
  195. const exception_names : array[0..EXCEPTIONCOUNT-1] of pchar = (
  196. 'Division by Zero',
  197. 'Debug',
  198. 'NMI',
  199. 'Breakpoint',
  200. 'Overflow',
  201. 'Bounds Check',
  202. 'Invalid Opcode',
  203. 'Coprocessor not available',
  204. 'Double Fault',
  205. 'Coprocessor overrun',
  206. 'Invalid TSS',
  207. 'Segment Not Present',
  208. 'Stack Fault',
  209. 'General Protection Fault',
  210. 'Page fault',
  211. ' ',
  212. 'Coprocessor Error',
  213. 'Alignment Check');
  214. const has_error : array [0..EXCEPTIONCOUNT-1] of byte =
  215. (0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1);
  216. const
  217. cbrk_hooked : boolean = false;
  218. procedure dump_selector(const name : string; sel : word);
  219. var base,limit : longint;
  220. begin
  221. err(name);
  222. err(': sel=');
  223. itox(sel, 4);
  224. if (sel<>0) then
  225. begin
  226. base:=get_segment_base_address(sel);
  227. {
  228. err(' invalid');
  229. }
  230. { else }
  231. err(' base='); itox(base, 8);
  232. limit:=get_segment_limit(sel);
  233. err(' limit='); itox(limit, 8);
  234. end;
  235. errln('');
  236. end;
  237. function farpeekb(sel : word;offset : longint) : byte;
  238. var b : byte;
  239. begin
  240. seg_move(sel,offset,get_ds,longint(@b),1);
  241. farpeekb:=b;
  242. end;
  243. const old_video_mode : byte = 3;
  244. function do_faulting_finish_message : integer;
  245. var en : pchar;
  246. signum,i : longint;
  247. old_vid : byte;
  248. begin
  249. do_faulting_finish_message:=0;
  250. signum:=djgpp_exception_state^.__signum;
  251. {/* check video mode for original here and reset (not if PC98) */ }
  252. if ((go32_info_block.linear_address_of_primary_screen <> $a0000) and
  253. (farpeekb(dosmemselector, $449) <> old_video_mode)) then
  254. begin
  255. old_vid:=old_video_mode;
  256. asm
  257. pusha
  258. movzbl old_vid,%eax
  259. int $0x10
  260. popa
  261. nop
  262. end;
  263. end;
  264. if (signum >= EXCEPTIONCOUNT) then
  265. en:=nil
  266. else
  267. en:=exception_names[signum];
  268. if (signum = $75) then
  269. en:='Floating Point exception';
  270. if (signum = $1b) then
  271. en:='Control-Break Pressed';
  272. if (signum = $79) then
  273. en:='Control-C Pressed';
  274. if (en = nil) then
  275. begin
  276. err('Exception ');
  277. itox(signum, 2);
  278. err(' at eip=');
  279. itox(djgpp_exception_state^.__eip, 8);
  280. end
  281. else
  282. begin
  283. write(stderr, 'FPK ',en);
  284. err(' at eip=');
  285. itox(djgpp_exception_state^.__eip, 8);
  286. end;
  287. { Control-C should stop the program also !}
  288. {if (signum = $79) then
  289. begin
  290. errln('');
  291. exit(-1);
  292. end;}
  293. if ((signum < EXCEPTIONCOUNT) and (has_error[signum]=1)) then
  294. begin
  295. errorcode := djgpp_exception_state^.__sigmask and $ffff;
  296. if(errorcode<>0) then
  297. begin
  298. err(', error=');
  299. itox(errorcode, 4);
  300. end;
  301. end;
  302. errln('');
  303. err('eax=');
  304. itox(djgpp_exception_state^.__eax, 8);
  305. err(' ebx='); itox(djgpp_exception_state^.__ebx, 8);
  306. err(' ecx='); itox(djgpp_exception_state^.__ecx, 8);
  307. err(' edx='); itox(djgpp_exception_state^.__edx, 8);
  308. err(' esi='); itox(djgpp_exception_state^.__esi, 8);
  309. err(' edi='); itox(djgpp_exception_state^.__edi, 8);
  310. errln('');
  311. err('ebp='); itox(djgpp_exception_state^.__ebp, 8);
  312. err(' esp='); itox(djgpp_exception_state^.__esp, 8);
  313. err(' program=');
  314. errln(paramstr(0));
  315. dump_selector('cs', djgpp_exception_state^.__cs);
  316. dump_selector('ds', djgpp_exception_state^.__ds);
  317. dump_selector('es', djgpp_exception_state^.__es);
  318. dump_selector('fs', djgpp_exception_state^.__fs);
  319. dump_selector('gs', djgpp_exception_state^.__gs);
  320. dump_selector('ss', djgpp_exception_state^.__ss);
  321. errln('');
  322. if (djgpp_exception_state^.__cs = get_cs) then
  323. show_call_frame;
  324. { must not return !! }
  325. if exceptions_on then
  326. djgpp_exception_toggle;
  327. asm
  328. pushw $1
  329. call ___exit
  330. end;
  331. end;
  332. var signal_list : Array[0..SIGMAX] of SignalHandler;
  333. { /* SIG_DFL = 0 */ }
  334. function signal(sig : longint;func : SignalHandler) : SignalHandler;
  335. var temp : SignalHandler;
  336. begin
  337. if ((sig <= 0) or (sig > SIGMAX) or (sig = SIGKILL)) then
  338. begin
  339. signal:=@SIG_ERR;
  340. runerror(201);
  341. end;
  342. temp := signal_list[sig - 1];
  343. signal_list[sig - 1] := func;
  344. signal:=temp;
  345. end;
  346. const signames : array [0..14] of string[4] = (
  347. 'ABRT',
  348. 'FPE ',
  349. 'ILL ',
  350. 'SEGV',
  351. 'TERM',
  352. 'ALRM',
  353. 'HUP ',
  354. 'INT ',
  355. 'KILL',
  356. 'PIPE',
  357. 'QUIT',
  358. 'USR1',
  359. 'USR2',
  360. 'NOFP',
  361. 'TRAP');
  362. function _raise(sig : longint) : longint;
  363. var temp : SignalHandler;
  364. label traceback_exit;
  365. begin
  366. if(sig <= 0) then
  367. exit(-1);
  368. if (sig > SIGMAX) then
  369. exit(-1);
  370. temp:=signal_list[sig - 1];
  371. if (temp = SignalHandler(@SIG_IGN)) then
  372. exit(0); { /* Ignore it */ }
  373. if (temp = SignalHandler(@SIG_DFL)) then
  374. begin
  375. traceback_exit:
  376. if ((sig >= SIGABRT) and (sig <= SIGTRAP)) then
  377. begin
  378. err('Exiting due to signal SIG');
  379. err(signames[sig-sigabrt]);
  380. end
  381. else
  382. begin
  383. err('Exiting due to signal $');
  384. itox(sig, 4);
  385. end;
  386. errln('');
  387. { if(djgpp_exception_state<>nil) then }
  388. do_faulting_finish_message(); {/* Exits, does not return */ }
  389. exit(-1);
  390. end;
  391. if ((longint(temp) < longint(starttext)) or (longint(temp) > longint(endtext))) then
  392. begin
  393. errln('Bad signal handler, ');
  394. goto traceback_exit;
  395. end;
  396. temp(sig);
  397. exit(0);
  398. end;
  399. { /* This routine must call exit() or jump changing stacks. This routine is
  400. the basis for traceback generation, core creation, signal handling. */ }
  401. { taken from sysutils.pas }
  402. function setjmp(var rec : tjmprec) : longint;
  403. begin
  404. asm
  405. pushl %edi
  406. movl rec,%edi
  407. movl %eax,(%edi)
  408. movl %ebx,4(%edi)
  409. movl %ecx,8(%edi)
  410. movl %edx,12(%edi)
  411. movl %esi,16(%edi)
  412. { load edi }
  413. movl -4(%ebp),%eax
  414. { ... and store it }
  415. movl %eax,20(%edi)
  416. { ebp ... }
  417. movl (%ebp),%eax
  418. movl %eax,24(%edi)
  419. { esp ... }
  420. movl %esp,%eax
  421. addl $12,%eax
  422. movl %eax,28(%edi)
  423. { the return address }
  424. movl 4(%ebp),%eax
  425. movl %eax,32(%edi)
  426. { flags ... }
  427. pushfl
  428. popl 36(%edi)
  429. { !!!!! the segment registers, not yet needed }
  430. { you need them if the exception comes from
  431. an interrupt or a seg_move }
  432. movw %cs,40(%edi)
  433. movw %ds,42(%edi)
  434. movw %es,44(%edi)
  435. movw %fs,46(%edi)
  436. movw %gs,48(%edi)
  437. movw %ss,50(%edi)
  438. movl ___djgpp_exception_state_ptr, %eax
  439. movl %eax, 60(%edi)
  440. { restore EDI }
  441. pop %edi
  442. { we come from the initial call }
  443. xorl %eax,%eax
  444. leave
  445. ret $4
  446. end;
  447. end;
  448. const exception_level : longint = 0;
  449. procedure longjmp({const}var rec : tjmprec;return_value : longint);
  450. begin
  451. if (@rec=pjmprec(djgpp_exception_state)) and
  452. (exception_level>0) then
  453. dec(exception_level);
  454. asm
  455. { restore compiler shit }
  456. popl %ebp
  457. {/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */}
  458. {/* This is file LONGJMP.S */}
  459. movl 4(%esp),%edi {/* get jmp_buf */}
  460. movl 8(%esp),%eax {/* store retval in j->eax */}
  461. movl %eax,0(%edi)
  462. movw 46(%edi),%fs
  463. movw 48(%edi),%gs
  464. movl 4(%edi),%ebx
  465. movl 8(%edi),%ecx
  466. movl 12(%edi),%edx
  467. movl 24(%edi),%ebp
  468. {/* Now for some uglyness. The jmp_buf structure may be ABOVE the
  469. point on the new SS:ESP we are moving to. We don't allow overlap,
  470. but do force that it always be valid. We will use ES:ESI for
  471. our new stack before swapping to it. */}
  472. movw 50(%edi),%es
  473. movl 28(%edi),%esi
  474. subl $28,%esi {/* We need 7 working longwords on stack */}
  475. movl 60(%edi),%eax
  476. es
  477. movl %eax,(%esi) {/* Exception pointer */}
  478. movzwl 42(%edi),%eax
  479. es
  480. movl %eax,4(%esi) {/* DS */}
  481. movl 20(%edi),%eax
  482. es
  483. movl %eax,8(%esi) {/* EDI */}
  484. movl 16(%edi),%eax
  485. es
  486. movl %eax,12(%esi) {/* ESI */}
  487. movl 32(%edi),%eax
  488. es
  489. movl %eax,16(%esi) {/* EIP - start of IRET frame */}
  490. movl 40(%edi),%eax
  491. es
  492. movl %eax,20(%esi) {/* CS */}
  493. movl 36(%edi),%eax
  494. es
  495. movl %eax,24(%esi) {/* EFLAGS */}
  496. movl 0(%edi),%eax
  497. movw 44(%edi),%es
  498. movw 50(%edi),%ss
  499. movl %esi,%esp
  500. popl ___djgpp_exception_state_ptr
  501. popl %ds
  502. popl %edi
  503. popl %esi
  504. iret {/* actually jump to new cs:eip loading flags */}
  505. end;
  506. end;
  507. procedure djgpp_exception_processor;[public,alias : '___djgpp_exception_processor'];
  508. var sig : longint;
  509. begin
  510. inc(exception_level);
  511. sig:=djgpp_exception_state^.__signum;
  512. if (exception_level=1) or (sig=$78) then
  513. begin
  514. sig := except_to_sig(sig);
  515. _raise(sig);
  516. if (djgpp_exception_state^.__signum >= EXCEPTIONCOUNT) then
  517. { /* Not exception so continue OK */ }
  518. longjmp(pjmprec(djgpp_exception_state)^, djgpp_exception_state^.__eax);
  519. {/* User handler did not exit or longjmp, we must exit */}
  520. err('FPK cannot continue from exception, exiting due to signal ');
  521. itox(sig, 4);
  522. errln('');
  523. end
  524. else
  525. begin
  526. if exception_level>2 then
  527. begin
  528. errln('FPK triple exception, exiting !!! ');
  529. if (exceptions_on) then
  530. djgpp_exception_toggle;
  531. asm
  532. pushw $1
  533. call ___exit
  534. end;
  535. end;
  536. err('FPK double exception, exiting due to signal ');
  537. itox(sig, 4);
  538. errln('');
  539. end;
  540. do_faulting_finish_message;
  541. end;
  542. type trealseginfo = tseginfo;
  543. pseginfo = ^tseginfo;
  544. var except_ori : array [0..EXCEPTIONCOUNT-1] of tseginfo;
  545. kbd_ori : tseginfo;
  546. npx_ori : tseginfo;
  547. cbrk_ori,cbrk_rmcb : trealseginfo;
  548. cbrk_regs : registers;
  549. {/* Routine toggles ALL the exceptions. Used around system calls, at exit. */}
  550. function djgpp_cbrk_hdlr : pointer;
  551. begin
  552. asm
  553. movl ___djgpp_cbrk_hdlr,%eax
  554. movl %eax,__RESULT
  555. end;
  556. end;
  557. function djgpp_old_kbd : pseginfo;
  558. begin
  559. asm
  560. movl ___djgpp_old_kbd,%eax
  561. movl %eax,__RESULT
  562. end;
  563. end;
  564. procedure djgpp_exception_toggle;
  565. var _except : tseginfo;
  566. i : longint;
  567. local_ex : boolean;
  568. begin
  569. {$ifdef SYSTEMDEBUG}
  570. if exceptions_on then
  571. begin
  572. errln('Disabling FPK exceptions');
  573. end
  574. else
  575. begin
  576. errln('Enabling FPK exceptions');
  577. end;
  578. {$endif SYSTEMDEBUG}
  579. { toggle here to avoid infinite recursion }
  580. { if a subfunction calls runerror !! }
  581. exceptions_on:= not exceptions_on;
  582. local_ex:=exceptions_on;
  583. asm
  584. movzbl local_ex,%eax
  585. movl %eax,_v2prt0_exceptions_on
  586. end;
  587. for i:=0 to EXCEPTIONCOUNT-1 do
  588. begin
  589. if get_pm_exception_handler(i,_except) then
  590. begin
  591. if (i <> 2) {or (_crt0_startup_flags & _CRT0_FLAG_NMI_SIGNAL))} then
  592. if not set_pm_exception_handler(i,except_ori[i]) then
  593. errln('error setting exception nø'+hexstr(i,2));
  594. except_ori[i] := _except;
  595. end
  596. else
  597. begin
  598. if get_exception_handler(i,_except) then
  599. begin
  600. if (i <> 2) {or (_crt0_startup_flags & _CRT0_FLAG_NMI_SIGNAL))} then
  601. if not set_exception_handler(i,except_ori[i]) then
  602. errln('error setting exception nø'+hexstr(i,2));
  603. except_ori[i] := _except;
  604. end
  605. end;
  606. end;
  607. get_pm_interrupt($75, _except);
  608. set_pm_interrupt($75, npx_ori);
  609. npx_ori:=_except;
  610. get_pm_interrupt(9, _except);
  611. set_pm_interrupt(9, kbd_ori);
  612. kbd_ori := _except;
  613. {$ifdef UseRMcbrk}
  614. if (cbrk_hooked) then
  615. begin
  616. set_rm_interrupt(cbrk_vect,cbrk_ori);
  617. free_rm_callback(cbrk_rmcb);
  618. cbrk_hooked := false;
  619. {$ifdef SYSTEMDEBUG}
  620. errln('back to ori rm cbrk '+hexstr(cbrk_ori.segment,4)+':'+hexstr(longint(cbrk_ori.offset),4));
  621. {$endif SYSTEMDEBUG}
  622. end
  623. else
  624. begin
  625. get_rm_interrupt(cbrk_vect, cbrk_ori);
  626. {$ifdef SYSTEMDEBUG}
  627. errln('ori rm cbrk '+hexstr(cbrk_ori.segment,4)+':'+hexstr(longint(cbrk_ori.offset),4));
  628. {$endif SYSTEMDEBUG}
  629. get_rm_callback(djgpp_cbrk_hdlr, cbrk_regs, cbrk_rmcb);
  630. set_rm_interrupt(cbrk_vect, cbrk_rmcb);
  631. {$ifdef SYSTEMDEBUG}
  632. errln('now rm cbrk '+hexstr(cbrk_rmcb.segment,4)+':'+hexstr(longint(cbrk_rmcb.offset),4));
  633. {$endif SYSTEMDEBUG}
  634. cbrk_hooked := true;
  635. end;
  636. {$endif UseRMcbrk}
  637. end;
  638. function dpmi_set_coprocessor_emulation(flag : longint) : longint;
  639. var
  640. res : longint;
  641. begin
  642. asm
  643. movl flag,%ebx
  644. movl $0xe01,%eax
  645. int $0x31
  646. jc .L_coproc_error
  647. xorl %eax,%eax
  648. .L_coproc_error:
  649. movl %eax,res
  650. end;
  651. dpmi_set_coprocessor_emulation:=res;
  652. end;
  653. procedure dpmiexcp_exit{(status : longint)};[alias : 'excep_exit'];
  654. {
  655. /* We need to restore hardware interrupt handlers even if somebody calls
  656. `_exit' directly, or else we crash the machine in nested programs.
  657. We only toggle the handlers if the original keyboard handler is intact
  658. (otherwise, they might have already toggled them). */ }
  659. begin
  660. if (exceptions_on) then
  661. djgpp_exception_toggle;
  662. asm
  663. xorl %eax,%eax
  664. movl %eax,_exception_exit
  665. movl %eax,_swap_in
  666. movl %eax,_swap_out
  667. end;
  668. { restore the FPU state }
  669. dpmi_set_coprocessor_emulation(1);
  670. end;
  671. { used by dos.pp for swap vectors }
  672. procedure dpmi_swap_in;[alias : 'swap_in'];
  673. begin
  674. if not (exceptions_on) then
  675. djgpp_exception_toggle;
  676. end;
  677. procedure dpmi_swap_out;[alias : 'swap_out'];
  678. begin
  679. if (exceptions_on) then
  680. djgpp_exception_toggle;
  681. end;
  682. procedure djgpp_exception_setup;
  683. var _except,old_kbd : tseginfo;
  684. locksize : longint;
  685. hw_lock_start, hw_lock_end : longint;
  686. i : longint;
  687. dossel :word;
  688. begin
  689. asm
  690. movl _exception_exit,%eax
  691. xorl %eax,%eax
  692. jne .L_already
  693. leal excep_exit,%eax
  694. movl %eax,_exception_exit
  695. leal swap_in,%eax
  696. movl %eax,_swap_in
  697. leal swap_out,%eax
  698. movl %eax,_swap_out
  699. end;
  700. for i := 0 to SIGMAX-1 do
  701. signal_list[i] := SignalHandler(@SIG_DFL);
  702. { /* app_DS only used when converting HW interrupts to exceptions */ }
  703. asm
  704. movw %ds,___djgpp_app_DS
  705. movw %ds,___djgpp_our_DS
  706. movl $___djgpp_hw_lock_start,%eax
  707. movl %eax,hw_lock_start
  708. movl $___djgpp_hw_lock_end,%eax
  709. movl %eax,hw_lock_end
  710. end;
  711. dossel := dosmemselector;
  712. asm
  713. movw dossel,%ax
  714. movw %ax,___djgpp_dos_sel
  715. end;
  716. {/* lock addresses which may see HW interrupts */}
  717. { lockmem.address = __djgpp_base_address + (unsigned) &__djgpp_hw_lock_start;}
  718. locksize := hw_lock_end - hw_lock_start;
  719. lock_code(pointer(hw_lock_start),locksize);
  720. _except.segment:=get_cs;
  721. { _except.offset:= (unsigned) &__djgpp_exception_table;}
  722. asm
  723. leal _except,%eax
  724. movl $___djgpp_exception_table,(%eax)
  725. end;
  726. for i:=0 to EXCEPTIONCOUNT-1 do
  727. begin
  728. except_ori[i] := _except; {/* New value to set */}
  729. _except.offset:=_except.offset + 4; {/* This is the size of push n, jmp */}
  730. end;
  731. kbd_ori.segment := _except.segment;
  732. npx_ori.segment := _except.segment;
  733. asm
  734. leal _NPX_ORI,%eax
  735. movl $___djgpp_npx_hdlr,(%eax)
  736. end;
  737. {npx_ori.offset32:= (unsigned) &__djgpp_npx_hdlr;}
  738. if (go32_info_block.linear_address_of_primary_screen <> $a0000) then
  739. begin
  740. asm
  741. leal _KBD_ORI,%eax
  742. movl $___djgpp_kbd_hdlr,(%eax)
  743. end;
  744. {kbd_ori.offset32 = (unsigned) &__djgpp_kbd_hdlr;}
  745. end
  746. else
  747. begin
  748. asm
  749. leal _KBD_ORI,%eax
  750. movl $___djgpp_kbd_hdlr_pc98,(%eax)
  751. end;
  752. {kbd_ori.offset32 = (unsigned) &__djgpp_kbd_hdlr_pc98;}
  753. cbrk_vect := $06;
  754. asm
  755. leal _except,%eax
  756. movl $___djgpp_iret,(%eax)
  757. end;
  758. {_except.offset32 = (unsigned) &__djgpp_iret; /* TDPMI98 bug */}
  759. set_pm_interrupt($23,_except);
  760. end;
  761. asm
  762. leal _except,%eax
  763. movl $___djgpp_i24,(%eax)
  764. end;
  765. {except.offset32 = (unsigned) &__djgpp_i24;}
  766. set_pm_interrupt($24, _except);
  767. get_pm_interrupt(9,old_kbd);
  768. asm
  769. movl $___djgpp_old_kbd,%edi
  770. leal old_kbd,%esi
  771. movl $6,%ecx { sier of tseginfo }
  772. rep
  773. movsb
  774. end;
  775. djgpp_exception_toggle; {/* Set new values & save old values */}
  776. {/* get original video mode and save */}
  777. old_video_mode := farpeekb(dosmemselector, $449);
  778. asm
  779. .L_already:
  780. end;
  781. end;
  782. function djgpp_set_ctrl_c(enable : boolean) : boolean;
  783. var oldenable : boolean;
  784. begin
  785. asm
  786. movb ___djgpp_hwint_flags,%al
  787. andb $1,%al
  788. movb %al,oldenable
  789. end;
  790. if (enable) then
  791. asm
  792. movl ___djgpp_hwint_flags,%eax
  793. andl $0xfffe,%eax
  794. movl %eax,___djgpp_hwint_flags
  795. end
  796. else
  797. asm
  798. movl ___djgpp_hwint_flags,%eax
  799. orl $1,%eax
  800. movl %eax,___djgpp_hwint_flags
  801. end;
  802. {__djgpp_hwint_flags |= 1;}
  803. djgpp_set_ctrl_c:=oldenable;
  804. end;
  805. begin
  806. asm
  807. movl $_etext,_ENDTEXT
  808. movl $start,_STARTTEXT
  809. movl ___v2prt0_ds_alias,%eax
  810. movl %eax,___djgpp_ds_alias
  811. end;
  812. djgpp_exception_setup;
  813. end.
  814. {
  815. $Log$
  816. Revision 1.4 1998-06-26 08:19:08 pierre
  817. + all debug in ifdef SYSTEMDEBUG
  818. + added local arrays :
  819. opennames names of opened files
  820. fileopen boolean array to know if still open
  821. usefull with gdb if you get problems about too
  822. many open files !!
  823. Revision 1.3 1998/05/31 14:18:23 peter
  824. * force att or direct assembling
  825. * cleanup of some files
  826. Revision 1.2 1998/04/21 14:46:33 pierre
  827. + debug info better output
  828. no normal code changed
  829. }