v2prt0.as 28 KB

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