dpmiexcp.pp 27 KB

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