v2prt0.as 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. /*
  2. $Id$
  3. */
  4. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  5. /*****************************************************************************\
  6. * Interface to 32-bit executable (from stub.asm)
  7. *
  8. * cs:eip according to COFF header
  9. * ds 32-bit data segment for COFF program
  10. * fs selector for our data segment (fs:0 is stubinfo)
  11. * ss:sp our stack (ss to be freed)
  12. * <others> All unspecified registers have unspecified values in them.
  13. \*****************************************************************************/
  14. /* modified by Pierre Muller to become the prt0.s for FPC Pascal */
  15. .file "v2prt0.as"
  16. /* #include "stubinfo.h" */
  17. STUBINFO = 0
  18. STUBINFO_MAGIC = 0
  19. STUBINFO_SIZE = 0x10
  20. STUBINFO_MINSTACK = 0x14
  21. STUBINFO_MEMORY_HANDLE = 0x18
  22. STUBINFO_INITIAL_SIZE = 0x1c
  23. STUBINFO_MINKEEP = 0x20
  24. STUBINFO_DS_SELECTOR = 0x22
  25. STUBINFO_DS_SEGMENT = 0x24
  26. STUBINFO_PSP_SELECTOR = 0x26
  27. STUBINFO_CS_SELECTOR = 0x28
  28. STUBINFO_ENV_SIZE = 0x2a
  29. STUBINFO_BASENAME = 0x2c
  30. STUBINFO_ARGV0 = 0x34
  31. STUBINFO_DPMI_SERVER = 0x44
  32. STUBINFO_END = 0x54
  33. /* .comm __stklen, 4
  34. this is added to the compiler so that we can specify
  35. the stack size */
  36. .comm __stkbottom,4
  37. .comm __stubinfo, 4
  38. .comm ___djgpp_base_address, 4
  39. .comm ___djgpp_selector_limit, 4
  40. .comm ___djgpp_stack_limit, 4
  41. .lcomm sel_buf, 8
  42. /* ___djgpp_ds_alias defined in go32/exceptn.s */
  43. /* inserted at the end of this file */
  44. /* we use a local copy that will be copied to exceptn.s */
  45. .globl ___v2prt0_ds_alias
  46. ___v2prt0_ds_alias:
  47. .long 0
  48. /* allocate 32*4 bytes for RMCB under the $ffff limit for Windows NT */
  49. .globl ___v2prt0_rmcb_regs
  50. ___v2prt0_rmcb_regs:
  51. .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  52. .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  53. .data
  54. ___djgpp_memory_handle_pointer:
  55. .long ___djgpp_memory_handle_list+8 /* Next free, first for stub */
  56. .comm ___djgpp_memory_handle_list, 2048 /* Enough for 256 handles */
  57. /* simply get current state */
  58. ___sbrk_interrupt_state:
  59. .long 0x902
  60. sbrk16_first_byte:
  61. .include "sbrk16.ah"
  62. sbrk16_last_byte:
  63. sbrk16_api_ofs:
  64. .long 0
  65. sbrk16_api_seg:
  66. .word 0
  67. zero:
  68. .long 0
  69. exit16_first_byte:
  70. .include "exit16.ah"
  71. exit16_last_byte:
  72. /* hook_387_emulator:
  73. .long ___emu387_load_hook */
  74. /* this is for when main comes from a library */
  75. .long _main
  76. .text
  77. .globl start
  78. start:
  79. pushl %ds /* set %es same as %ds */
  80. popl %es /* push/pop 4 bytes shorter than ax */
  81. /* Enable NULL pointer protection if DPMI supports it */
  82. testb $0x1, __crt0_startup_flags+1 /* include/crt0.h */
  83. jnz 1f
  84. movl $start, %eax
  85. cmpl $0x1000, %eax
  86. jl 1f
  87. movw $0x507, %ax
  88. .byte 0x64 /* fs: */
  89. movl STUBINFO_MEMORY_HANDLE, %esi
  90. xorl %ebx, %ebx /* Offset 0 in mem block */
  91. movl $1, %ecx /* Set one page */
  92. movl $zero, %edx
  93. int $0x31 /* Make null page uncommitted */
  94. jnc 1f
  95. call v2prt0_windows
  96. 1:
  97. /* Create an alias for DS to be used by real-mode callbacks (exception handler messes with DS itself) */
  98. movw %ds, %bx
  99. movw $0x000a, %ax
  100. int $0x31
  101. jnc ds_alias_ok
  102. movb $0x4c, %ah
  103. int $0x21
  104. ds_alias_ok:
  105. movw %ax, ___v2prt0_ds_alias
  106. movl %eax, %ebx
  107. movw $0x0009, %ax
  108. movw %cs, %cx /* get CPL from %cs */
  109. andl $3, %ecx
  110. shll $5, %ecx /* move it into place */
  111. orw $0xc093, %cx
  112. int $0x31 /* set access rights for alias */
  113. /* Maybe set our DS limit to 4Gb in size if flag set */
  114. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  115. jz 2f
  116. movw $0xffff, %cx
  117. movl %ecx, %edx
  118. movw $0x0008, %ax /* reset alias limit to -1 */
  119. int $0x31
  120. movw %cs, %bx
  121. movw $0x0008, %ax /* reset DS limit to -1 */
  122. int $0x31
  123. movw %ds, %bx
  124. movw $0x0008, %ax /* reset DS limit to -1 */
  125. int $0x31
  126. lsl %ebx, %ebx /* Should be -1 */
  127. incl %ebx
  128. jz 2f
  129. andb $0x7f, __crt0_startup_flags /* clear it if failure */
  130. 2:
  131. /* Allocate some DOS memory and copy our sbrk helper into it. */
  132. movl $sbrk16_first_byte, %esi
  133. movzwl 8(%esi), %ebx
  134. shrl $4, %ebx
  135. movw $0x0100, %ax
  136. int $0x31
  137. jnc dos_alloc_ok
  138. movb $0x4c, %ah
  139. int $0x21
  140. dos_alloc_ok:
  141. movw %cs, 2(%esi)
  142. /* store API information */
  143. movw %ds, 4(%esi)
  144. movw %dx, 6(%esi)
  145. /* selector for allocated block */
  146. movzwl (%esi), %eax /* calculate API address */
  147. movl %eax, sbrk16_api_ofs
  148. pushl %es /* move the data */
  149. movw %dx, %es
  150. movl $(sbrk16_last_byte - sbrk16_first_byte), %ecx
  151. shrl $2,%ecx
  152. xorl %edi, %edi
  153. cld
  154. rep
  155. movsl
  156. popl %es
  157. movl %edx, %ebx /* dos memory selector */
  158. movw $0x000b, %ax /* get descriptor */
  159. movl $sel_buf, %edi
  160. int $0x31
  161. andb $0xbf, sel_buf+6 /* make 16-bit */
  162. andb $0xf0, sel_buf+5 /* remove old type */
  163. orb $0x0a, sel_buf+5 /* set new type to code/read */
  164. xorl %eax, %eax /* allocate new selector */
  165. movw $0x0001, %cx
  166. int $0x31
  167. movw %ax, sbrk16_api_seg
  168. movl %eax, %ebx
  169. movw $0x000c, %ax /* set descriptor */
  170. movl $sel_buf, %edi
  171. int $0x31
  172. /* Initialize the brk/sbrk variables */
  173. /* movl $end, __what_size_app_thinks_it_is */
  174. .byte 0x64 /* fs: */
  175. movl STUBINFO_INITIAL_SIZE, %eax
  176. movl %eax, __what_size_dpmi_thinks_we_are
  177. /* Maybe lock the initial block, expects BX:CX */
  178. movl %ecx,%ebx
  179. movl %edx,%ecx
  180. addw $4096,%cx /* Skip null page */
  181. adcl $0,%ebx
  182. subl $4096,%eax
  183. pushl %eax
  184. call lock_memory
  185. .byte 0x64 /* fs: */
  186. movl STUBINFO_MEMORY_HANDLE, %eax
  187. movl %eax, ___djgpp_memory_handle_list
  188. .byte 0x64 /* fs: */ /* copy stubinfo into local memory */
  189. movl STUBINFO_SIZE, %eax
  190. pushl %eax
  191. call ___sbrk
  192. movl %eax, __stubinfo
  193. movl %eax,U_SYSTEM_STUB_INFO
  194. movl %eax, %edi
  195. .byte 0x64 /* fs: */
  196. movl STUBINFO_SIZE, %ecx
  197. shrl $2, %ecx
  198. xorl %esi, %esi /* Zero */
  199. pushl %ds
  200. pushl %fs
  201. popl %ds
  202. cld
  203. rep
  204. movsl
  205. popl %ds
  206. movl __stklen, %eax /* get program-requested stack size */
  207. .byte 0x64 /* fs: */
  208. movl STUBINFO_MINSTACK, %ecx /* get stub-requested stack size */
  209. cmpl %ecx, %eax
  210. jge use_stubinfo_stack_size /* use the larger of the two */
  211. movl %ecx, %eax
  212. movl %eax, __stklen /* store the actual stack length */
  213. use_stubinfo_stack_size:
  214. pushl %eax
  215. call ___sbrk /* allocate the memory */
  216. cmpl $-1, %eax
  217. je no_memory
  218. movl %eax, ___djgpp_stack_limit /* Bottom of stack */
  219. addl $256,%eax
  220. movl %eax,__stkbottom /* for stack checks */
  221. movl %eax,U_SYSTEM_STACKBOTTOM
  222. movl ___djgpp_stack_limit,%eax /* Bottom of stack */
  223. addl __stklen, %eax
  224. movw %ds, %dx /* set stack */
  225. movw %dx, %ss
  226. andl $0xfffffffc,%eax
  227. movl %eax, %esp
  228. xorl %ebp, %ebp
  229. call ___prt1_startup /* run program */
  230. jmp exit
  231. no_memory:
  232. movb $0xff, %al
  233. jmp exit
  234. /*-----------------------------------------------------------------------------*/
  235. /* #define FREESEL(x) movw x, %bx; movw $0x0001, %ax; int $0x31 */
  236. .macro FREESEL x
  237. movw \x,%bx
  238. movw $0x0001,%ax
  239. int $0x31
  240. .endm
  241. .global ___exit
  242. .align 2
  243. ___exit:
  244. /* special exit from dpmiexcp.c */
  245. .global __exit
  246. __exit:
  247. movl 4(%esp),%eax
  248. exit:
  249. movl %eax,%ecx
  250. xorl %eax,%eax
  251. movw %ax,%fs
  252. movw %ax,%gs
  253. cmpl $0,_exception_exit
  254. jz no_exception
  255. pushl %ecx
  256. call *_exception_exit
  257. popl %ecx
  258. no_exception:
  259. cli /* Just in case they didn't unhook ints */
  260. FREESEL U_SYSTEM_GO32_INFO_BLOCK+26 /* selector for linear memory */
  261. FREESEL ___v2prt0_ds_alias /* DS alias for rmcb exceptions */
  262. FREESEL sbrk16_api_seg /* sbrk cs */
  263. movw sbrk16_first_byte+6,%dx /* selector for allocated DOS mem */
  264. movw $0x101, %ax
  265. int $0x31 /* Free block and selector */
  266. 9:
  267. movl __stubinfo, %edx
  268. movl STUBINFO_CS_SELECTOR(%edx), %eax
  269. movw %ax, sbrk16_api_seg
  270. xorl %edi, %edi
  271. movl %edi, sbrk16_api_ofs /* Offset is zero */
  272. movw STUBINFO_DS_SELECTOR(%edx), %es
  273. movb %cl, %dl /* Exit status */
  274. movl $exit16_first_byte, %esi
  275. movl $(exit16_last_byte - exit16_first_byte), %ecx
  276. cld
  277. rep
  278. movsb
  279. movw %es,%ax /* We will free stack! */
  280. movw %ax,%ss
  281. movl $0x400,%esp /* Transfer buffer >= 1024 bytes */
  282. xorl %ebp, %ebp /* V1.10 bug fix */
  283. movl ___djgpp_memory_handle_list, %edi
  284. movl ___djgpp_memory_handle_list+2, %esi /* Skip word prefixes */
  285. FREESEL %ds
  286. movw %cs, %bx
  287. /* Call exit procedure with BX=32-bit CS; SI+DI=32-bit handle; DL=exit status */
  288. .byte 0x2e
  289. ljmp sbrk16_api_ofs
  290. /*-----------------------------------------------------------------------------*/
  291. /* .lcomm __what_size_app_thinks_it_is, 4 */
  292. __what_size_app_thinks_it_is:
  293. .long end
  294. .lcomm __what_we_return_to_app_as_old_size, 4
  295. .lcomm __what_size_dpmi_thinks_we_are, 4
  296. lock_memory:
  297. /* BX:CX should be linear address; size is pushed on stack */
  298. testb $0x10, __crt0_startup_flags+1 /* include/crt0.h */
  299. jz 13f
  300. pushl %esi
  301. pushl %edi
  302. pushl %eax
  303. movl 16(%esp),%edi
  304. movw 18(%esp),%si
  305. movw $0x600,%ax
  306. int $0x31
  307. popl %eax
  308. popl %edi
  309. popl %esi
  310. 13: ret $4 /* Pop the argument */
  311. .global ___sbrk
  312. .align 2
  313. ___sbrk:
  314. movl __what_size_app_thinks_it_is, %eax
  315. movl 4(%esp), %ecx /* Increment size */
  316. addl %ecx, %eax
  317. jnc brk_common
  318. /* Carry is only set if a negative increment or wrap happens. Negative
  319. increment is semi-OK, wrap (only for multiple zone sbrk) isn't. */
  320. test $0x80000000, %ecx /* Clears carry */
  321. jnz brk_common
  322. stc /* Put carry back */
  323. jmp brk_common
  324. .globl ___brk
  325. .align 2
  326. ___brk:
  327. movl 4(%esp), %eax
  328. clc
  329. brk_common:
  330. pushl %esi
  331. pushl %edi
  332. pushl %ebx
  333. movl __what_size_app_thinks_it_is, %edx /* save info */
  334. movl %edx, __what_we_return_to_app_as_old_size
  335. movl %eax, __what_size_app_thinks_it_is
  336. jc 10f /* Wrap for multi-zone */
  337. cmpl __what_size_dpmi_thinks_we_are, %eax /* don't bother shrinking */
  338. jbe brk_nochange
  339. addl $0x0000ffff, %eax /* round up to 64K block */
  340. andl $0xffff0000, %eax
  341. push %eax /* size - save for later */
  342. movl ___djgpp_memory_handle_list, %edi /* request new size */
  343. movw ___djgpp_memory_handle_list+2, %si
  344. movl %eax, %ecx /* size not limit */
  345. movl %eax, %ebx /* size not limit */
  346. shrl $16, %ebx /* BX:CX size */
  347. movw $0x0902, %ax /* disable interrupts */
  348. int $0x31
  349. movl %eax,___sbrk_interrupt_state
  350. testb %al,%al
  351. jz interrupts_already_disabled
  352. movw $0x0900,%eax
  353. int $0x31
  354. interrupts_already_disabled:
  355. lcall sbrk16_api_ofs
  356. setc %dl /* Save carry */
  357. /* popl %eax restore interrupts
  358. int $0x31 postponed after ds alias is set correctly */
  359. test %dl,%dl
  360. popl %edx
  361. jne brk_error
  362. movl %edi, ___djgpp_memory_handle_list /* store new handle */
  363. movw %si, ___djgpp_memory_handle_list+2
  364. movl %ecx, ___djgpp_base_address /* store new base address */
  365. movw %bx, ___djgpp_base_address+2
  366. movl %edx, %eax
  367. movl __what_size_dpmi_thinks_we_are, %ecx
  368. subl %ecx, %eax
  369. addl ___djgpp_base_address, %ecx
  370. movl %ecx, %ebx
  371. shrl $16, %ebx /* BX:CX addr */
  372. pushl %eax /* Size */
  373. call lock_memory
  374. decl %edx /* limit now, not size */
  375. 5: movl %edx, ___djgpp_selector_limit
  376. orw $0x0fff, %dx /* low bits set */
  377. movw $0x0008, %ax /* reset CS limit */
  378. movw %cs, %bx
  379. movl %edx, %ecx
  380. shrl $16, %ecx
  381. int $0x31 /* CX:DX is limit */
  382. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  383. jnz 3f
  384. movw $0x0008, %ax /* reset DS limit */
  385. movw %ds, %bx
  386. int $0x31
  387. movw $0x0008, %ax /* reset DS alias limit */
  388. movl ___v2prt0_ds_alias, %ebx
  389. int $0x31
  390. 3:
  391. movw $0x0007, %ax /* reset DS alias base */
  392. movl ___v2prt0_ds_alias, %ebx
  393. movl ___djgpp_base_address, %edx
  394. movw ___djgpp_base_address+2, %cx
  395. int $0x31
  396. movl %eax,___sbrk_interrupt_state /* restore interrupts */
  397. testb %al,%al
  398. je do_not_enable
  399. movw $0x0901,%eax
  400. int $0x31
  401. do_not_enable:
  402. movl ___djgpp_selector_limit, %edx
  403. 12: incl %edx /* Size not limit */
  404. testb $0x60, __crt0_startup_flags /* include/crt0.h */
  405. jz no_fill_sbrk_memory
  406. pushl %ds
  407. popl %es
  408. movl __what_size_dpmi_thinks_we_are, %edi /* set all newly resized bytes zero */
  409. movl %edx, %ecx /* Limit */
  410. subl %edi, %ecx /* Adjust count for base */
  411. xorl %eax, %eax
  412. testb $0x40, __crt0_startup_flags
  413. jz no_deadbeef
  414. movl $0xdeadbeef, %eax /* something really easy to spot */
  415. no_deadbeef:
  416. shrl $2, %ecx /* div 4 Longwords not bytes */
  417. cld
  418. rep
  419. stosl
  420. no_fill_sbrk_memory:
  421. movl %edx, __what_size_dpmi_thinks_we_are
  422. brk_nochange: /* successful return */
  423. movl __what_we_return_to_app_as_old_size, %eax
  424. jmp brk_return
  425. brk_error: /* error return */
  426. movl __what_we_return_to_app_as_old_size, %eax
  427. movl %eax, __what_size_app_thinks_it_is
  428. movl $-1, %eax
  429. brk_return:
  430. popl %ebx
  431. popl %edi
  432. popl %esi
  433. ret
  434. /* From here on this are parts of crt1.c converted to assembler
  435. and without any call to libc, so that it works without anything else
  436. additions made by Pierre Muller*/
  437. /* from dpmidefs.h * /
  438. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  439. /* from include <libc/asmdefs.h> */
  440. /* all macros removed here */
  441. /* #define FUNC(x) .globl x; x: */
  442. /* #define ENTER pushl %ebp; movl %esp,%ebp */
  443. /* #define LEAVE(x) movl %ebp,%esp; popl %ebp; ret $(x) */
  444. /* #define ARG1 8(%ebp)
  445. #define ARG1h 10(%ebp)
  446. #define ARG2 12(%ebp)
  447. #define ARG2h 14(%ebp)
  448. #define ARG3 16(%ebp)
  449. #define ARG4 20(%ebp)
  450. #define ARG5 24(%ebp)
  451. #define ARG6 28(%ebp)
  452. #define ARG7 32(%ebp)
  453. #define ARG8 36(%ebp) */
  454. .comm ___dpmi_error,2
  455. /* from dpmi0000.s */
  456. /* .globl ___dpmi_allocate_ldt_descriptors */
  457. /* using pascal convention => not usabel by C code */
  458. ___dpmi_allocate_ldt_descriptors:
  459. pushl %ebp; movl %esp,%ebp
  460. movl 8(%ebp), %ecx
  461. movl $0x0000, %eax
  462. int $0x31
  463. jnc .L_noerror0000
  464. movw %ax,___dpmi_error
  465. movl $-1,%eax
  466. jmp .L_leave0000
  467. .L_noerror0000:
  468. movzwl %ax,%eax
  469. .L_leave0000:
  470. movl %ebp,%esp
  471. popl %ebp
  472. ret $4
  473. /* from file dpmi0008.s */
  474. /* .globl ___dpmi_set_segment_limit */
  475. ___dpmi_set_segment_limit:
  476. pushl %ebp; movl %esp,%ebp
  477. movl 8(%ebp), %ebx
  478. movzwl 12(%ebp), %edx
  479. movzwl 14(%ebp),%ecx
  480. movl $0x0008,%eax
  481. int $0x31
  482. jnc .L_noerror0008
  483. movw %ax,___dpmi_error
  484. movl $-1,%eax
  485. jmp .L_leave0008
  486. .L_noerror0008:
  487. xorl %eax,%eax
  488. .L_leave0008:
  489. movl %ebp,%esp
  490. popl %ebp
  491. ret $8
  492. /* .globl ___dpmi_get_version */
  493. ___dpmi_get_version:
  494. pushl %ebp; movl %esp,%ebp
  495. movl $0x0400,%eax
  496. int $0x31
  497. jnc .L_noerror0400
  498. movw %ax,___dpmi_error
  499. movl $-1,%eax
  500. jmp .L_leave0400
  501. .L_noerror0400:
  502. movl 8(%ebp), %esi
  503. movb %ah, (%esi)
  504. movb %al, 1(%esi)
  505. movw %bx, 2(%esi)
  506. movb %cl, 4(%esi)
  507. movb %dh, 5(%esi)
  508. movb %dl, 6(%esi)
  509. xorl %eax,%eax
  510. .L_leave0400:
  511. movl %ebp,%esp
  512. popl %ebp
  513. ret $4
  514. /* .globl ___dpmi_get_segment_base_address*/
  515. ___dpmi_get_segment_base_address:
  516. pushl %ebp; movl %esp,%ebp
  517. movl 8(%ebp), %ebx
  518. movl $0x0006,%eax
  519. int $0x31
  520. jnc .L_noerror0006
  521. movw %ax,___dpmi_error
  522. movl $-1,%eax
  523. jmp .L_leave0006
  524. .L_noerror0006:
  525. movl 12(%ebp), %ebx
  526. movl %edx, (%ebx)
  527. movw %cx, 2(%ebx)
  528. xorl %eax,%eax
  529. .L_leave0006:
  530. movl %ebp,%esp
  531. popl %ebp
  532. ret $8
  533. .globl ___bss_count
  534. .data
  535. .align 2
  536. ___bss_count:
  537. .long 1
  538. .text
  539. .align 2
  540. .globl _setup_core_selector
  541. _setup_core_selector:
  542. pushl %ebp
  543. movl %esp,%ebp
  544. pushl $1
  545. call ___dpmi_allocate_ldt_descriptors
  546. /* addl $4,%esp */
  547. cmpl $-1,%eax
  548. jne .L24
  549. movw $0,U_SYSTEM_GO32_INFO_BLOCK+26
  550. leave
  551. ret
  552. .align 2,0x90
  553. .L24:
  554. movw %ax,U_SYSTEM_GO32_INFO_BLOCK+26
  555. movw %ax,_core_selector
  556. pushl $0x10ffff
  557. andl $0xffff,%eax
  558. pushl %eax
  559. call ___dpmi_set_segment_limit
  560. leave
  561. ret
  562. .align 2
  563. .globl _setup_screens
  564. _setup_screens:
  565. pushl %ebp
  566. movl %esp,%ebp
  567. movw U_SYSTEM_GO32_INFO_BLOCK+26,%dx
  568. movl $1048563,%ecx
  569. /APP
  570. movw %dx, %gs
  571. .byte 0x65
  572. movw (%ecx),%ax
  573. /NO_APP
  574. cmpw $64896,%ax
  575. jne .L26
  576. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+8
  577. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+4
  578. leave
  579. ret
  580. .align 2,0x90
  581. .L26:
  582. movl $1097,%ecx
  583. /APP
  584. movw %dx,%gs
  585. .byte 0x65
  586. movb (%ecx),%al
  587. /NO_APP
  588. cmpb $7,%al
  589. jne .L29
  590. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+4
  591. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+8
  592. leave
  593. ret
  594. .align 2,0x90
  595. .L29:
  596. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+4
  597. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+8
  598. leave
  599. ret
  600. .align 2
  601. .globl _setup_go32_info_block
  602. _setup_go32_info_block:
  603. pushl %ebp
  604. movl %esp,%ebp
  605. subl $8,%esp
  606. leal -8(%ebp),%eax
  607. pushl %eax
  608. call ___dpmi_get_version
  609. movl $40,U_SYSTEM_GO32_INFO_BLOCK
  610. movl __stubinfo,%edx
  611. movzwl 36(%edx),%eax
  612. sall $4,%eax
  613. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  614. movzwl 32(%edx),%ecx
  615. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+16
  616. movzwl 38(%edx),%ecx
  617. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+20
  618. movb -3(%ebp),%al
  619. movb %al,U_SYSTEM_GO32_INFO_BLOCK+24
  620. movb -2(%ebp),%al
  621. movb %al,U_SYSTEM_GO32_INFO_BLOCK+25
  622. movl $-1,U_SYSTEM_GO32_INFO_BLOCK+28
  623. pushl $U_SYSTEM_GO32_INFO_BLOCK+32
  624. movzwl 38(%edx),%eax
  625. pushl %eax
  626. call ___dpmi_get_segment_base_address
  627. movw $4,U_SYSTEM_GO32_INFO_BLOCK+36
  628. movb -8(%ebp),%dl
  629. salw $8,%dx
  630. movzbw -7(%ebp),%ax
  631. orw %ax,%dx
  632. movw %dx,U_SYSTEM_GO32_INFO_BLOCK+38
  633. call copy_to_c_go32_info_block
  634. leave
  635. ret
  636. copy_to_c_go32_info_block:
  637. leal U_SYSTEM_GO32_INFO_BLOCK,%esi
  638. leal __go32_info_block,%edi
  639. movl $10,%ecx
  640. rep
  641. movsl
  642. ret
  643. .data
  644. /* fpu codeword */
  645. ___fpucw:
  646. .long 0x1332
  647. /* __go32_info_block for C programs */
  648. .align 2
  649. .globl __go32_info_block
  650. .comm __go32_info_block,40
  651. /*
  652. -- prt1_startup --
  653. */
  654. .text
  655. .align 2
  656. .globl ___prt1_startup
  657. ___prt1_startup:
  658. pushl %ebp
  659. movl %esp,%ebp
  660. pushl %ebx
  661. incl ___bss_count
  662. movl $0,___crt0_argv
  663. call _setup_core_selector
  664. call _setup_screens
  665. call _setup_go32_info_block
  666. incl ___environ_changed
  667. fninit /* initialize fpu */
  668. /* fwait maybe this one is responsible of exceptions */
  669. fldcw ___fpucw
  670. pushl U_SYSTEM_ENVP
  671. pushl ___crt0_argv
  672. pushl ___crt0_argc
  673. call _pascal_start
  674. pushl %eax
  675. /* call _exit changed to */
  676. call exit
  677. .align 2,0x90
  678. /* .comm U_SYSTEM_DOS_ARGV0,4 */
  679. .comm ___dos_argv0,4
  680. .comm ___crt0_argc,4
  681. .comm ___crt0_argv,4
  682. .comm ___environ_changed,4
  683. /* ___environ_changed: not in data because it is defined in putenv.c */
  684. /* .long 0 */
  685. .globl _exception_exit
  686. _exception_exit:
  687. .long 0
  688. .globl _swap_in
  689. _swap_in:
  690. .long 0
  691. .globl _swap_out
  692. _swap_out:
  693. .long 0
  694. .global _v2prt0_exceptions_on
  695. _v2prt0_exceptions_on:
  696. .long 0
  697. // Fill null page with NOPs
  698. // and a jmp windows_error at the end
  699. .globl v2prt0_windows
  700. v2prt0_windows:
  701. movl $0x90909090,%eax
  702. xorl %edi,%edi
  703. movl $0x400,%ecx
  704. cld
  705. rep
  706. stosl
  707. movl $0xffB,%edi
  708. movb $0xe9,%al
  709. stosb
  710. movl $_fpc_windows_error-4,%eax
  711. subl %edi,%eax
  712. stosl
  713. ret
  714. // Raise SIGILL with UD2 opcode
  715. .globl _fpc_windows_error
  716. _fpc_windows_error:
  717. cmpl $0,_exception_exit
  718. je .L_error_216
  719. .byte 0x0f,0x0b
  720. .L_error_216:
  721. pushl $216
  722. call __exit
  723. jmp exit
  724. #enif
  725. /* this was the prt0.s from the go32v1 version */
  726. //
  727. // call as start(argc, argv, envp) (C-calling convention)
  728. //
  729. .globl _pascal_start
  730. _pascal_start:
  731. /* %ebx doesn't contain ScreenPrimary */
  732. movl U_SYSTEM_GO32_INFO_BLOCK+4,%ebx
  733. movl %ebx,_ScreenPrimary
  734. /* core selector in %fs */
  735. /* keep original fs for debuggers !!!!! (PM) */
  736. movw %fs,%ax
  737. movw %ax,___v2prt0_start_fs
  738. movw _core_selector,%ax
  739. movw %ax,%fs
  740. // Top of frame
  741. movl $0x0,%ebp
  742. movl %esp,%ebx
  743. movl 12(%ebx),%eax
  744. movl %eax,U_SYSTEM_ENVP
  745. movl %eax,_environ
  746. movl 8(%ebx),%eax
  747. movl %eax,_args
  748. movl 4(%ebx),%eax
  749. movl %eax,_argc
  750. call PASCALMAIN
  751. movl $0,%eax
  752. /* no error if passing here */
  753. /* movl $0x4c00,%eax
  754. int $0x21 */
  755. ret
  756. .data
  757. /* .comm U_SYSTEM_ENVP,4 */
  758. .globl _ScreenPrimary
  759. _ScreenPrimary:
  760. .long 0
  761. .globl _argc
  762. _argc:
  763. .long 0
  764. .globl _args
  765. _args:
  766. .long 0
  767. .globl _run_mode
  768. _run_mode:
  769. .word 4
  770. .globl _core_selector
  771. _core_selector:
  772. .word 0
  773. .globl ___v2prt0_start_fs
  774. ___v2prt0_start_fs:
  775. .word 0
  776. .globl _environ
  777. _environ:
  778. .long 0
  779. /* Here Pierre Muller added all what was in crt1.c */
  780. /* in assembler */
  781. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  782. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  783. /* adapted to assembler for FPC by Pierre Muller */
  784. /* Global variables */
  785. /* This gets incremented each time the program is started.
  786. Programs (such as Emacs) which dump their code to create
  787. a new executable, cause this to be larger than 2. Library
  788. functions that cache info in static variables should check
  789. the value of `__bss_count' if they need to reinitialize
  790. the static storage. */
  791. .data
  792. .globl ___bss_count
  793. ___bs_count:
  794. .long 1
  795. .globl __crt0_startup_flags
  796. __crt0_startup_flags:
  797. .long 0
  798. .globl __dos_ds
  799. __dos_ds:
  800. .long 0
  801. .globl ___PROXY
  802. ___PROXY:
  803. .ascii " !proxy"
  804. .byte 0
  805. .globl ___PROXY_LEN
  806. ___PROXY_LEN:
  807. .long 7
  808. /*
  809. $Log$
  810. Revision 1.10 2000-02-23 12:46:11 jonas
  811. * restored my fix (CVS screwed up the previous versinos because of wrong line
  812. breaks)
  813. Revision 1.7 2000/02/16 13:24:55 pierre
  814. * Mouse crash bug fixed !!!
  815. Revision 1.6 1999/07/10 23:17:15 pierre
  816. merged from fixes branch
  817. Revision 1.5.2.1 1999/07/10 23:15:02 pierre
  818. * fixes problem with putenv.c
  819. Revision 1.5 1999/03/01 15:40:53 peter
  820. * use external names
  821. * removed all direct assembler modes
  822. Revision 1.4 1999/02/19 12:25:37 pierre
  823. + ___v2prt0_rmcb_regs in text section for Windows NT
  824. + catch of calls into zero page for Windows 95
  825. (creates Run Time error 216 or SIGILL exception
  826. if dpmiexcp is loaded !)
  827. Revision 1.3 1999/01/05 10:44:59 pierre
  828. * suppressed fwaits to avoid FPU not present exceptions
  829. Revision 1.2 1998/12/21 14:14:21 pierre
  830. added some c vars needed to avoid loading od crt1.o
  831. Revision 1.1 1998/12/21 13:07:03 peter
  832. * use -FE
  833. Revision 1.4 1998/10/14 21:28:45 peter
  834. * initialize fpu so sigfpe is finally generated for fpu errors
  835. Revision 1.3 1998/08/19 10:56:35 pierre
  836. + added some special code for C interface
  837. to avoid loading of crt1.o or dpmiexcp.o from the libc.a
  838. Revision 1.2 1998/05/22 00:39:38 peter
  839. * go32v1, go32v2 recompiles with the new objects
  840. * remake3 works again with go32v2
  841. - removed some "optimizes" from daniel which were wrong
  842. */