2
0

dpmiexcp.pp 27 KB

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