v2prt0.as 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  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 ds_alias_ok
  99. movb $0x4c, %ah
  100. int $0x21
  101. ds_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 dos_alloc_ok
  135. movb $0x4c, %ah
  136. int $0x21
  137. dos_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,U_SYSTEM_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 use_stubinfo_stack_size /* use the larger of the two */
  208. movl %ecx, %eax
  209. movl %eax, __stklen /* store the actual stack length */
  210. use_stubinfo_stack_size:
  211. pushl %eax
  212. call ___sbrk /* allocate the memory */
  213. cmpl $-1, %eax
  214. je no_memory
  215. movl %eax, ___djgpp_stack_limit /* Bottom of stack */
  216. addl $256,%eax
  217. movl %eax,__stkbottom /* for stack checks */
  218. movl %eax,U_SYSTEM_STACKBOTTOM
  219. movl ___djgpp_stack_limit,%eax /* Bottom of stack */
  220. addl __stklen, %eax
  221. movw %ds, %dx /* set stack */
  222. movw %dx, %ss
  223. andl $0xfffffffc,%eax
  224. movl %eax, %esp
  225. xorl %ebp, %ebp
  226. call ___prt1_startup /* run program */
  227. jmp exit
  228. no_memory:
  229. movb $0xff, %al
  230. jmp exit
  231. /*-----------------------------------------------------------------------------*/
  232. /* #define FREESEL(x) movw x, %bx; movw $0x0001, %ax; int $0x31 */
  233. .macro FREESEL x
  234. movw \x,%bx
  235. movw $0x0001,%ax
  236. int $0x31
  237. .endm
  238. .global ___exit
  239. .align 2
  240. ___exit:
  241. /* special exit from dpmiexcp.c */
  242. .global __exit
  243. __exit:
  244. movl 4(%esp),%eax
  245. exit:
  246. movl %eax,%ecx
  247. xorl %eax,%eax
  248. movw %ax,%fs
  249. movw %ax,%gs
  250. cmpl $0,_exception_exit
  251. jz no_exception
  252. pushl %ecx
  253. call *_exception_exit
  254. popl %ecx
  255. no_exception:
  256. cli /* Just in case they didn't unhook ints */
  257. FREESEL U_SYSTEM_GO32_INFO_BLOCK+26 /* selector for linear memory */
  258. FREESEL ___v2prt0_ds_alias /* DS alias for rmcb exceptions */
  259. FREESEL sbrk16_api_seg /* sbrk cs */
  260. movw sbrk16_first_byte+6,%dx /* selector for allocated DOS mem */
  261. movw $0x101, %ax
  262. int $0x31 /* Free block and selector */
  263. 9:
  264. movl __stubinfo, %edx
  265. movl STUBINFO_CS_SELECTOR(%edx), %eax
  266. movw %ax, sbrk16_api_seg
  267. xorl %edi, %edi
  268. movl %edi, sbrk16_api_ofs /* Offset is zero */
  269. movw STUBINFO_DS_SELECTOR(%edx), %es
  270. movb %cl, %dl /* Exit status */
  271. movl $exit16_first_byte, %esi
  272. movl $(exit16_last_byte - exit16_first_byte), %ecx
  273. cld
  274. rep
  275. movsb
  276. movw %es,%ax /* We will free stack! */
  277. movw %ax,%ss
  278. movl $0x400,%esp /* Transfer buffer >= 1024 bytes */
  279. xorl %ebp, %ebp /* V1.10 bug fix */
  280. movl ___djgpp_memory_handle_list, %edi
  281. movl ___djgpp_memory_handle_list+2, %esi /* Skip word prefixes */
  282. FREESEL %ds
  283. movw %cs, %bx
  284. /* Call exit procedure with BX=32-bit CS; SI+DI=32-bit handle; DL=exit status */
  285. .byte 0x2e
  286. ljmp sbrk16_api_ofs
  287. /*-----------------------------------------------------------------------------*/
  288. /* .lcomm __what_size_app_thinks_it_is, 4 */
  289. __what_size_app_thinks_it_is:
  290. .long end
  291. .lcomm __what_we_return_to_app_as_old_size, 4
  292. .lcomm __what_size_dpmi_thinks_we_are, 4
  293. lock_memory:
  294. /* BX:CX should be linear address; size is pushed on stack */
  295. testb $0x10, __crt0_startup_flags+1 /* include/crt0.h */
  296. jz 13f
  297. pushl %esi
  298. pushl %edi
  299. pushl %eax
  300. movl 16(%esp),%edi
  301. movw 18(%esp),%si
  302. movw $0x600,%ax
  303. int $0x31
  304. popl %eax
  305. popl %edi
  306. popl %esi
  307. 13: ret $4 /* Pop the argument */
  308. .global ___sbrk
  309. .align 2
  310. ___sbrk:
  311. movl __what_size_app_thinks_it_is, %eax
  312. movl 4(%esp), %ecx /* Increment size */
  313. addl %ecx, %eax
  314. jnc brk_common
  315. /* Carry is only set if a negative increment or wrap happens. Negative
  316. increment is semi-OK, wrap (only for multiple zone sbrk) isn't. */
  317. test $0x80000000, %ecx /* Clears carry */
  318. jnz brk_common
  319. stc /* Put carry back */
  320. jmp brk_common
  321. .globl ___brk
  322. .align 2
  323. ___brk:
  324. movl 4(%esp), %eax
  325. clc
  326. brk_common:
  327. pushl %esi
  328. pushl %edi
  329. pushl %ebx
  330. movl __what_size_app_thinks_it_is, %edx /* save info */
  331. movl %edx, __what_we_return_to_app_as_old_size
  332. movl %eax, __what_size_app_thinks_it_is
  333. /* multi code is not present */
  334. /* jc 10f Wrap for multi-zone */
  335. cmpl __what_size_dpmi_thinks_we_are, %eax /* don't bother shrinking */
  336. jbe brk_nochange
  337. addl $0x0000ffff, %eax /* round up to 64K block */
  338. andl $0xffff0000, %eax
  339. push %eax /* size - save for later */
  340. movl ___djgpp_memory_handle_list, %edi /* request new size */
  341. movw ___djgpp_memory_handle_list+2, %si
  342. movl %eax, %ecx /* size not limit */
  343. movl %eax, %ebx /* size not limit */
  344. shrl $16, %ebx /* BX:CX size */
  345. movw $0x0900, %ax /* disable interrupts */
  346. int $0x31
  347. movl %eax,___sbrk_interrupt_state
  348. lcall sbrk16_api_ofs
  349. setc %dl /* Save carry */
  350. /* popl %eax restore interrupts
  351. int $0x31 postponed after ds alias is set correctly */
  352. test %dl,%dl
  353. popl %edx
  354. jne brk_error
  355. movl %edi, ___djgpp_memory_handle_list /* store new handle */
  356. movw %si, ___djgpp_memory_handle_list+2
  357. movl %ecx, ___djgpp_base_address /* store new base address */
  358. movw %bx, ___djgpp_base_address+2
  359. movl %edx, %eax
  360. movl __what_size_dpmi_thinks_we_are, %ecx
  361. subl %ecx, %eax
  362. addl ___djgpp_base_address, %ecx
  363. movl %ecx, %ebx
  364. shrl $16, %ebx /* BX:CX addr */
  365. pushl %eax /* Size */
  366. call lock_memory
  367. decl %edx /* limit now, not size */
  368. 5: movl %edx, ___djgpp_selector_limit
  369. orw $0x0fff, %dx /* low bits set */
  370. movw $0x0008, %ax /* reset CS limit */
  371. movw %cs, %bx
  372. movl %edx, %ecx
  373. shrl $16, %ecx
  374. int $0x31 /* CX:DX is limit */
  375. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  376. jnz 3f
  377. movw $0x0008, %ax /* reset DS limit */
  378. movw %ds, %bx
  379. int $0x31
  380. movw $0x0008, %ax /* reset DS alias limit */
  381. movl ___v2prt0_ds_alias, %ebx
  382. int $0x31
  383. 3:
  384. movw $0x0007, %ax /* reset DS alias base */
  385. movl ___v2prt0_ds_alias, %ebx
  386. movl ___djgpp_base_address, %edx
  387. movw ___djgpp_base_address+2, %cx
  388. int $0x31
  389. movl ___sbrk_interrupt_state,%eax /* restore interrupts */
  390. int $0x31
  391. movl ___djgpp_selector_limit, %edx
  392. 12: incl %edx /* Size not limit */
  393. testb $0x60, __crt0_startup_flags /* include/crt0.h */
  394. jz no_fill_sbrk_memory
  395. pushl %ds
  396. popl %es
  397. movl __what_size_dpmi_thinks_we_are, %edi /* set all newly resized bytes zero */
  398. movl %edx, %ecx /* Limit */
  399. subl %edi, %ecx /* Adjust count for base */
  400. xorl %eax, %eax
  401. testb $0x40, __crt0_startup_flags
  402. jz no_deadbeef
  403. movl $0xdeadbeef, %eax /* something really easy to spot */
  404. no_deadbeef:
  405. shrl $2, %ecx /* div 4 Longwords not bytes */
  406. cld
  407. rep
  408. stosl
  409. no_fill_sbrk_memory:
  410. movl %edx, __what_size_dpmi_thinks_we_are
  411. brk_nochange: /* successful return */
  412. movl __what_we_return_to_app_as_old_size, %eax
  413. jmp brk_return
  414. brk_error: /* error return */
  415. movl __what_we_return_to_app_as_old_size, %eax
  416. movl %eax, __what_size_app_thinks_it_is
  417. movl $0, %eax
  418. brk_return:
  419. popl %ebx
  420. popl %edi
  421. popl %esi
  422. ret
  423. /* From here on this are parts of crt1.c converted to assembler
  424. and without any call to libc, so that it works without anything else
  425. additions made by Pierre Muller*/
  426. /* from dpmidefs.h * /
  427. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  428. /* from include <libc/asmdefs.h> */
  429. /* all macros removed here */
  430. /* #define FUNC(x) .globl x; x: */
  431. /* #define ENTER pushl %ebp; movl %esp,%ebp */
  432. /* #define LEAVE(x) movl %ebp,%esp; popl %ebp; ret $(x) */
  433. /* #define ARG1 8(%ebp)
  434. #define ARG1h 10(%ebp)
  435. #define ARG2 12(%ebp)
  436. #define ARG2h 14(%ebp)
  437. #define ARG3 16(%ebp)
  438. #define ARG4 20(%ebp)
  439. #define ARG5 24(%ebp)
  440. #define ARG6 28(%ebp)
  441. #define ARG7 32(%ebp)
  442. #define ARG8 36(%ebp) */
  443. .comm ___dpmi_error,2
  444. /* from dpmi0000.s */
  445. /* .globl ___dpmi_allocate_ldt_descriptors */
  446. /* using pascal convention => not usabel by C code */
  447. ___dpmi_allocate_ldt_descriptors:
  448. pushl %ebp; movl %esp,%ebp
  449. movl 8(%ebp), %ecx
  450. movl $0x0000, %eax
  451. int $0x31
  452. jnc .L_noerror0000
  453. movw %ax,___dpmi_error
  454. movl $-1,%eax
  455. jmp .L_leave0000
  456. .L_noerror0000:
  457. movzwl %ax,%eax
  458. .L_leave0000:
  459. movl %ebp,%esp
  460. popl %ebp
  461. ret $4
  462. /* from file dpmi0008.s */
  463. /* .globl ___dpmi_set_segment_limit */
  464. ___dpmi_set_segment_limit:
  465. pushl %ebp; movl %esp,%ebp
  466. movl 8(%ebp), %ebx
  467. movzwl 12(%ebp), %edx
  468. movzwl 14(%ebp),%ecx
  469. movl $0x0008,%eax
  470. int $0x31
  471. jnc .L_noerror0008
  472. movw %ax,___dpmi_error
  473. movl $-1,%eax
  474. jmp .L_leave0008
  475. .L_noerror0008:
  476. xorl %eax,%eax
  477. .L_leave0008:
  478. movl %ebp,%esp
  479. popl %ebp
  480. ret $8
  481. /* .globl ___dpmi_get_version */
  482. ___dpmi_get_version:
  483. pushl %ebp; movl %esp,%ebp
  484. movl $0x0400,%eax
  485. int $0x31
  486. jnc .L_noerror0400
  487. movw %ax,___dpmi_error
  488. movl $-1,%eax
  489. jmp .L_leave0400
  490. .L_noerror0400:
  491. movl 8(%ebp), %esi
  492. movb %ah, (%esi)
  493. movb %al, 1(%esi)
  494. movw %bx, 2(%esi)
  495. movb %cl, 4(%esi)
  496. movb %dh, 5(%esi)
  497. movb %dl, 6(%esi)
  498. xorl %eax,%eax
  499. .L_leave0400:
  500. movl %ebp,%esp
  501. popl %ebp
  502. ret $4
  503. _set_os_trueversion:
  504. pushl %ebp
  505. movl %esp,%ebp
  506. movl $0x3306,%eax
  507. xorl %ebx,%ebx
  508. int $0x21
  509. movzbl %bl,%eax
  510. shll $8,%eax
  511. shrl $8,%ebx
  512. andl $0xff,%ebx
  513. addl %ebx,%eax
  514. movw %ax,__os_trueversion
  515. popl %ebp
  516. ret
  517. /* .globl ___dpmi_get_segment_base_address*/
  518. ___dpmi_get_segment_base_address:
  519. pushl %ebp; movl %esp,%ebp
  520. movl 8(%ebp), %ebx
  521. movl $0x0006,%eax
  522. int $0x31
  523. jnc .L_noerror0006
  524. movw %ax,___dpmi_error
  525. movl $-1,%eax
  526. jmp .L_leave0006
  527. .L_noerror0006:
  528. movl 12(%ebp), %ebx
  529. movl %edx, (%ebx)
  530. movw %cx, 2(%ebx)
  531. xorl %eax,%eax
  532. .L_leave0006:
  533. movl %ebp,%esp
  534. popl %ebp
  535. ret $8
  536. .globl ___bss_count
  537. .data
  538. .align 2
  539. ___bss_count:
  540. .long 1
  541. .text
  542. .align 2
  543. .globl _setup_core_selector
  544. _setup_core_selector:
  545. pushl %ebp
  546. movl %esp,%ebp
  547. pushl $1
  548. call ___dpmi_allocate_ldt_descriptors
  549. /* addl $4,%esp */
  550. cmpl $-1,%eax
  551. jne .L24
  552. movw $0,U_SYSTEM_GO32_INFO_BLOCK+26
  553. leave
  554. ret
  555. .align 2,0x90
  556. .L24:
  557. movw %ax,U_SYSTEM_GO32_INFO_BLOCK+26
  558. movw %ax,_core_selector
  559. pushl $0x10ffff
  560. andl $0xffff,%eax
  561. pushl %eax
  562. call ___dpmi_set_segment_limit
  563. leave
  564. ret
  565. .align 2
  566. .globl _setup_screens
  567. _setup_screens:
  568. pushl %ebp
  569. movl %esp,%ebp
  570. movw U_SYSTEM_GO32_INFO_BLOCK+26,%dx
  571. movl $1048563,%ecx
  572. /APP
  573. movw %dx, %gs
  574. .byte 0x65
  575. movw (%ecx),%ax
  576. /NO_APP
  577. cmpw $64896,%ax
  578. jne .L26
  579. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+8
  580. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+4
  581. leave
  582. ret
  583. .align 2,0x90
  584. .L26:
  585. movl $1097,%ecx
  586. /APP
  587. movw %dx,%gs
  588. .byte 0x65
  589. movb (%ecx),%al
  590. /NO_APP
  591. cmpb $7,%al
  592. jne .L29
  593. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+4
  594. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+8
  595. leave
  596. ret
  597. .align 2,0x90
  598. .L29:
  599. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+4
  600. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+8
  601. leave
  602. ret
  603. .align 2
  604. .globl _setup_go32_info_block
  605. _setup_go32_info_block:
  606. pushl %ebp
  607. movl %esp,%ebp
  608. subl $8,%esp
  609. leal -8(%ebp),%eax
  610. pushl %eax
  611. call ___dpmi_get_version
  612. movl $40,U_SYSTEM_GO32_INFO_BLOCK
  613. movl __stubinfo,%edx
  614. movzwl 36(%edx),%eax
  615. sall $4,%eax
  616. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  617. movzwl 32(%edx),%ecx
  618. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+16
  619. movzwl 38(%edx),%ecx
  620. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+20
  621. movb -3(%ebp),%al
  622. movb %al,U_SYSTEM_GO32_INFO_BLOCK+24
  623. movb -2(%ebp),%al
  624. movb %al,U_SYSTEM_GO32_INFO_BLOCK+25
  625. movl $-1,U_SYSTEM_GO32_INFO_BLOCK+28
  626. pushl $U_SYSTEM_GO32_INFO_BLOCK+32
  627. movzwl 38(%edx),%eax
  628. pushl %eax
  629. call ___dpmi_get_segment_base_address
  630. movw $4,U_SYSTEM_GO32_INFO_BLOCK+36
  631. movb -8(%ebp),%dl
  632. salw $8,%dx
  633. movzbw -7(%ebp),%ax
  634. orw %ax,%dx
  635. movw %dx,U_SYSTEM_GO32_INFO_BLOCK+38
  636. call copy_to_c_go32_info_block
  637. leave
  638. ret
  639. copy_to_c_go32_info_block:
  640. leal U_SYSTEM_GO32_INFO_BLOCK,%esi
  641. leal __go32_info_block,%edi
  642. movl $10,%ecx
  643. rep
  644. movsl
  645. ret
  646. .data
  647. /* fpu codeword */
  648. ___fpucw:
  649. .long 0x1332
  650. /* __go32_info_block for C programs */
  651. .align 2
  652. .globl __go32_info_block
  653. .comm __go32_info_block,40
  654. /*
  655. -- prt1_startup --
  656. */
  657. .text
  658. .align 2
  659. .globl ___prt1_startup
  660. ___prt1_startup:
  661. pushl %ebp
  662. movl %esp,%ebp
  663. pushl %ebx
  664. incl ___bss_count
  665. movl $0,___crt0_argv
  666. call _set_os_trueversion
  667. call _setup_core_selector
  668. call _setup_screens
  669. call _setup_go32_info_block
  670. incl ___environ_changed
  671. /* call set_processor emulation */
  672. /* neede to avoid FPU exception if calling from anothe DPMI program */
  673. movl $0xe01,%eax
  674. movl $1,%ebx
  675. int $0x31
  676. fninit /* initialize fpu */
  677. push %eax /* Dummy for status store check */
  678. movl %esp,%esi
  679. movw $0x5a5a,(%esi)
  680. /* fwait maybe this one is responsible of exceptions */
  681. fnstsw (%esi)
  682. cmpb $0,(%esi)
  683. jne .Lno_387
  684. fldcw ___fpucw
  685. .Lno_387:
  686. popl %eax
  687. pushl U_SYSTEM_ENVP
  688. pushl ___crt0_argv
  689. pushl ___crt0_argc
  690. call _pascal_start
  691. pushl %eax
  692. /* call _exit changed to */
  693. call exit
  694. .align 2,0x90
  695. /* .comm U_SYSTEM_DOS_ARGV0,4 */
  696. .comm ___dos_argv0,4
  697. .comm ___crt0_argc,4
  698. .comm ___crt0_argv,4
  699. .comm ___environ_changed,4
  700. /* ___environ_changed: not in data because it is defined in putenv.c */
  701. /* .long 0 */
  702. .globl _exception_exit
  703. _exception_exit:
  704. .long 0
  705. .globl _swap_in
  706. _swap_in:
  707. .long 0
  708. .globl _swap_out
  709. _swap_out:
  710. .long 0
  711. .global _v2prt0_exceptions_on
  712. _v2prt0_exceptions_on:
  713. .long 0
  714. // Fill null page with NOPs
  715. // and a jmp windows_error at the end
  716. .globl v2prt0_windows
  717. v2prt0_windows:
  718. movl $0x90909090,%eax
  719. xorl %edi,%edi
  720. movl $0x400,%ecx
  721. cld
  722. rep
  723. stosl
  724. movl $0xffB,%edi
  725. movb $0xe9,%al
  726. stosb
  727. movl $_fpc_windows_error-4,%eax
  728. subl %edi,%eax
  729. stosl
  730. ret
  731. // Raise SIGILL with UD2 opcode
  732. .globl _fpc_windows_error
  733. _fpc_windows_error:
  734. cmpl $0,_exception_exit
  735. je .L_error_216
  736. .byte 0x0f,0x0b
  737. .L_error_216:
  738. pushl $216
  739. call __exit
  740. jmp exit
  741. #enif
  742. /* this was the prt0.s from the go32v1 version */
  743. //
  744. // call as start(argc, argv, envp) (C-calling convention)
  745. //
  746. .globl _pascal_start
  747. _pascal_start:
  748. /* %ebx doesn't contain ScreenPrimary */
  749. movl U_SYSTEM_GO32_INFO_BLOCK+4,%ebx
  750. movl %ebx,_ScreenPrimary
  751. /* core selector in %fs */
  752. /* keep original fs for debuggers !!!!! (PM) */
  753. movw %fs,%ax
  754. movw %ax,___v2prt0_start_fs
  755. movw _core_selector,%ax
  756. movw %ax,%fs
  757. // Top of frame
  758. movl $0x0,%ebp
  759. movl %esp,%ebx
  760. movl 12(%ebx),%eax
  761. movl %eax,U_SYSTEM_ENVP
  762. movl %eax,_environ
  763. movl 8(%ebx),%eax
  764. movl %eax,_args
  765. movl 4(%ebx),%eax
  766. movl %eax,_argc
  767. call PASCALMAIN
  768. movl $0,%eax
  769. /* no error if passing here */
  770. /* movl $0x4c00,%eax
  771. int $0x21 */
  772. ret
  773. .data
  774. /* .comm U_SYSTEM_ENVP,4 */
  775. .globl _ScreenPrimary
  776. _ScreenPrimary:
  777. .long 0
  778. .globl _argc
  779. _argc:
  780. .long 0
  781. .globl _args
  782. _args:
  783. .long 0
  784. .globl _run_mode
  785. _run_mode:
  786. .word 4
  787. .globl _core_selector
  788. _core_selector:
  789. .word 0
  790. .globl ___v2prt0_start_fs
  791. ___v2prt0_start_fs:
  792. .word 0
  793. .globl _environ
  794. _environ:
  795. .long 0
  796. /* Here Pierre Muller added all what was in crt1.c */
  797. /* in assembler */
  798. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  799. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  800. /* adapted to assembler for FPC by Pierre Muller */
  801. /* Global variables */
  802. /* This gets incremented each time the program is started.
  803. Programs (such as Emacs) which dump their code to create
  804. a new executable, cause this to be larger than 2. Library
  805. functions that cache info in static variables should check
  806. the value of `__bss_count' if they need to reinitialize
  807. the static storage. */
  808. .data
  809. .globl ___bss_count
  810. ___bs_count:
  811. .long 1
  812. .globl __crt0_startup_flags
  813. __crt0_startup_flags:
  814. .long 0
  815. .globl __dos_ds
  816. __dos_ds:
  817. .long 0
  818. .globl ___PROXY
  819. ___PROXY:
  820. .ascii " !proxy"
  821. .byte 0
  822. .globl ___PROXY_LEN
  823. ___PROXY_LEN:
  824. .long 7
  825. .comm __os_trueversion,2