v2prt0.as 28 KB

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