v2prt0.as 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  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. /* multi code is not present */
  337. /* jc 10f Wrap for multi-zone */
  338. cmpl __what_size_dpmi_thinks_we_are, %eax /* don't bother shrinking */
  339. jbe brk_nochange
  340. addl $0x0000ffff, %eax /* round up to 64K block */
  341. andl $0xffff0000, %eax
  342. push %eax /* size - save for later */
  343. movl ___djgpp_memory_handle_list, %edi /* request new size */
  344. movw ___djgpp_memory_handle_list+2, %si
  345. movl %eax, %ecx /* size not limit */
  346. movl %eax, %ebx /* size not limit */
  347. shrl $16, %ebx /* BX:CX size */
  348. movw $0x0900, %ax /* disable interrupts */
  349. int $0x31
  350. movl %eax,___sbrk_interrupt_state
  351. lcall sbrk16_api_ofs
  352. setc %dl /* Save carry */
  353. /* popl %eax restore interrupts
  354. int $0x31 postponed after ds alias is set correctly */
  355. test %dl,%dl
  356. popl %edx
  357. jne brk_error
  358. movl %edi, ___djgpp_memory_handle_list /* store new handle */
  359. movw %si, ___djgpp_memory_handle_list+2
  360. movl %ecx, ___djgpp_base_address /* store new base address */
  361. movw %bx, ___djgpp_base_address+2
  362. movl %edx, %eax
  363. movl __what_size_dpmi_thinks_we_are, %ecx
  364. subl %ecx, %eax
  365. addl ___djgpp_base_address, %ecx
  366. movl %ecx, %ebx
  367. shrl $16, %ebx /* BX:CX addr */
  368. pushl %eax /* Size */
  369. call lock_memory
  370. decl %edx /* limit now, not size */
  371. 5: movl %edx, ___djgpp_selector_limit
  372. orw $0x0fff, %dx /* low bits set */
  373. movw $0x0008, %ax /* reset CS limit */
  374. movw %cs, %bx
  375. movl %edx, %ecx
  376. shrl $16, %ecx
  377. int $0x31 /* CX:DX is limit */
  378. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  379. jnz 3f
  380. movw $0x0008, %ax /* reset DS limit */
  381. movw %ds, %bx
  382. int $0x31
  383. movw $0x0008, %ax /* reset DS alias limit */
  384. movl ___v2prt0_ds_alias, %ebx
  385. int $0x31
  386. 3:
  387. movw $0x0007, %ax /* reset DS alias base */
  388. movl ___v2prt0_ds_alias, %ebx
  389. movl ___djgpp_base_address, %edx
  390. movw ___djgpp_base_address+2, %cx
  391. int $0x31
  392. movl ___sbrk_interrupt_state,%eax /* restore interrupts */
  393. int $0x31
  394. movl ___djgpp_selector_limit, %edx
  395. 12: incl %edx /* Size not limit */
  396. testb $0x60, __crt0_startup_flags /* include/crt0.h */
  397. jz no_fill_sbrk_memory
  398. pushl %ds
  399. popl %es
  400. movl __what_size_dpmi_thinks_we_are, %edi /* set all newly resized bytes zero */
  401. movl %edx, %ecx /* Limit */
  402. subl %edi, %ecx /* Adjust count for base */
  403. xorl %eax, %eax
  404. testb $0x40, __crt0_startup_flags
  405. jz no_deadbeef
  406. movl $0xdeadbeef, %eax /* something really easy to spot */
  407. no_deadbeef:
  408. shrl $2, %ecx /* div 4 Longwords not bytes */
  409. cld
  410. rep
  411. stosl
  412. no_fill_sbrk_memory:
  413. movl %edx, __what_size_dpmi_thinks_we_are
  414. brk_nochange: /* successful return */
  415. movl __what_we_return_to_app_as_old_size, %eax
  416. jmp brk_return
  417. brk_error: /* error return */
  418. movl __what_we_return_to_app_as_old_size, %eax
  419. movl %eax, __what_size_app_thinks_it_is
  420. movl $0, %eax
  421. brk_return:
  422. popl %ebx
  423. popl %edi
  424. popl %esi
  425. ret
  426. /* From here on this are parts of crt1.c converted to assembler
  427. and without any call to libc, so that it works without anything else
  428. additions made by Pierre Muller*/
  429. /* from dpmidefs.h * /
  430. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  431. /* from include <libc/asmdefs.h> */
  432. /* all macros removed here */
  433. /* #define FUNC(x) .globl x; x: */
  434. /* #define ENTER pushl %ebp; movl %esp,%ebp */
  435. /* #define LEAVE(x) movl %ebp,%esp; popl %ebp; ret $(x) */
  436. /* #define ARG1 8(%ebp)
  437. #define ARG1h 10(%ebp)
  438. #define ARG2 12(%ebp)
  439. #define ARG2h 14(%ebp)
  440. #define ARG3 16(%ebp)
  441. #define ARG4 20(%ebp)
  442. #define ARG5 24(%ebp)
  443. #define ARG6 28(%ebp)
  444. #define ARG7 32(%ebp)
  445. #define ARG8 36(%ebp) */
  446. .comm ___dpmi_error,2
  447. /* from dpmi0000.s */
  448. /* .globl ___dpmi_allocate_ldt_descriptors */
  449. /* using pascal convention => not usabel by C code */
  450. ___dpmi_allocate_ldt_descriptors:
  451. pushl %ebp; movl %esp,%ebp
  452. movl 8(%ebp), %ecx
  453. movl $0x0000, %eax
  454. int $0x31
  455. jnc .L_noerror0000
  456. movw %ax,___dpmi_error
  457. movl $-1,%eax
  458. jmp .L_leave0000
  459. .L_noerror0000:
  460. movzwl %ax,%eax
  461. .L_leave0000:
  462. movl %ebp,%esp
  463. popl %ebp
  464. ret $4
  465. /* from file dpmi0008.s */
  466. /* .globl ___dpmi_set_segment_limit */
  467. ___dpmi_set_segment_limit:
  468. pushl %ebp; movl %esp,%ebp
  469. movl 8(%ebp), %ebx
  470. movzwl 12(%ebp), %edx
  471. movzwl 14(%ebp),%ecx
  472. movl $0x0008,%eax
  473. int $0x31
  474. jnc .L_noerror0008
  475. movw %ax,___dpmi_error
  476. movl $-1,%eax
  477. jmp .L_leave0008
  478. .L_noerror0008:
  479. xorl %eax,%eax
  480. .L_leave0008:
  481. movl %ebp,%esp
  482. popl %ebp
  483. ret $8
  484. /* .globl ___dpmi_get_version */
  485. ___dpmi_get_version:
  486. pushl %ebp; movl %esp,%ebp
  487. movl $0x0400,%eax
  488. int $0x31
  489. jnc .L_noerror0400
  490. movw %ax,___dpmi_error
  491. movl $-1,%eax
  492. jmp .L_leave0400
  493. .L_noerror0400:
  494. movl 8(%ebp), %esi
  495. movb %ah, (%esi)
  496. movb %al, 1(%esi)
  497. movw %bx, 2(%esi)
  498. movb %cl, 4(%esi)
  499. movb %dh, 5(%esi)
  500. movb %dl, 6(%esi)
  501. xorl %eax,%eax
  502. .L_leave0400:
  503. movl %ebp,%esp
  504. popl %ebp
  505. ret $4
  506. _set_os_trueversion:
  507. pushl %ebp
  508. movl %esp,%ebp
  509. movl $0x3306,%eax
  510. xorl %ebx,%ebx
  511. int $0x21
  512. movzbl %bl,%eax
  513. shll $8,%eax
  514. shrl $8,%ebx
  515. andl $0xff,%ebx
  516. addl %ebx,%eax
  517. movw %ax,__os_trueversion
  518. popl %ebp
  519. ret
  520. /* .globl ___dpmi_get_segment_base_address*/
  521. ___dpmi_get_segment_base_address:
  522. pushl %ebp; movl %esp,%ebp
  523. movl 8(%ebp), %ebx
  524. movl $0x0006,%eax
  525. int $0x31
  526. jnc .L_noerror0006
  527. movw %ax,___dpmi_error
  528. movl $-1,%eax
  529. jmp .L_leave0006
  530. .L_noerror0006:
  531. movl 12(%ebp), %ebx
  532. movl %edx, (%ebx)
  533. movw %cx, 2(%ebx)
  534. xorl %eax,%eax
  535. .L_leave0006:
  536. movl %ebp,%esp
  537. popl %ebp
  538. ret $8
  539. .globl ___bss_count
  540. .data
  541. .align 2
  542. ___bss_count:
  543. .long 1
  544. .text
  545. .align 2
  546. .globl _setup_core_selector
  547. _setup_core_selector:
  548. pushl %ebp
  549. movl %esp,%ebp
  550. pushl $1
  551. call ___dpmi_allocate_ldt_descriptors
  552. /* addl $4,%esp */
  553. cmpl $-1,%eax
  554. jne .L24
  555. movw $0,U_SYSTEM_GO32_INFO_BLOCK+26
  556. leave
  557. ret
  558. .align 2,0x90
  559. .L24:
  560. movw %ax,U_SYSTEM_GO32_INFO_BLOCK+26
  561. movw %ax,_core_selector
  562. pushl $0x10ffff
  563. andl $0xffff,%eax
  564. pushl %eax
  565. call ___dpmi_set_segment_limit
  566. leave
  567. ret
  568. .align 2
  569. .globl _setup_screens
  570. _setup_screens:
  571. pushl %ebp
  572. movl %esp,%ebp
  573. movw U_SYSTEM_GO32_INFO_BLOCK+26,%dx
  574. movl $1048563,%ecx
  575. /APP
  576. movw %dx, %gs
  577. .byte 0x65
  578. movw (%ecx),%ax
  579. /NO_APP
  580. cmpw $64896,%ax
  581. jne .L26
  582. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+8
  583. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+4
  584. leave
  585. ret
  586. .align 2,0x90
  587. .L26:
  588. movl $1097,%ecx
  589. /APP
  590. movw %dx,%gs
  591. .byte 0x65
  592. movb (%ecx),%al
  593. /NO_APP
  594. cmpb $7,%al
  595. jne .L29
  596. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+4
  597. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+8
  598. leave
  599. ret
  600. .align 2,0x90
  601. .L29:
  602. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+4
  603. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+8
  604. leave
  605. ret
  606. .align 2
  607. .globl _setup_go32_info_block
  608. _setup_go32_info_block:
  609. pushl %ebp
  610. movl %esp,%ebp
  611. subl $8,%esp
  612. leal -8(%ebp),%eax
  613. pushl %eax
  614. call ___dpmi_get_version
  615. movl $40,U_SYSTEM_GO32_INFO_BLOCK
  616. movl __stubinfo,%edx
  617. movzwl 36(%edx),%eax
  618. sall $4,%eax
  619. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  620. movzwl 32(%edx),%ecx
  621. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+16
  622. movzwl 38(%edx),%ecx
  623. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+20
  624. movb -3(%ebp),%al
  625. movb %al,U_SYSTEM_GO32_INFO_BLOCK+24
  626. movb -2(%ebp),%al
  627. movb %al,U_SYSTEM_GO32_INFO_BLOCK+25
  628. movl $-1,U_SYSTEM_GO32_INFO_BLOCK+28
  629. pushl $U_SYSTEM_GO32_INFO_BLOCK+32
  630. movzwl 38(%edx),%eax
  631. pushl %eax
  632. call ___dpmi_get_segment_base_address
  633. movw $4,U_SYSTEM_GO32_INFO_BLOCK+36
  634. movb -8(%ebp),%dl
  635. salw $8,%dx
  636. movzbw -7(%ebp),%ax
  637. orw %ax,%dx
  638. movw %dx,U_SYSTEM_GO32_INFO_BLOCK+38
  639. call copy_to_c_go32_info_block
  640. leave
  641. ret
  642. copy_to_c_go32_info_block:
  643. leal U_SYSTEM_GO32_INFO_BLOCK,%esi
  644. leal __go32_info_block,%edi
  645. movl $10,%ecx
  646. rep
  647. movsl
  648. ret
  649. .data
  650. /* fpu codeword */
  651. ___fpucw:
  652. .long 0x1332
  653. /* __go32_info_block for C programs */
  654. .align 2
  655. .globl __go32_info_block
  656. .comm __go32_info_block,40
  657. /*
  658. -- prt1_startup --
  659. */
  660. .text
  661. .align 2
  662. .globl ___prt1_startup
  663. ___prt1_startup:
  664. pushl %ebp
  665. movl %esp,%ebp
  666. pushl %ebx
  667. incl ___bss_count
  668. movl $0,___crt0_argv
  669. call _set_os_trueversion
  670. call _setup_core_selector
  671. call _setup_screens
  672. call _setup_go32_info_block
  673. incl ___environ_changed
  674. /* call set_processor emulation */
  675. /* neede to avoid FPU exception if calling from anothe DPMI program */
  676. movl $0xe01,%eax
  677. movl $1,%ebx
  678. int $0x31
  679. fninit /* initialize fpu */
  680. push %eax /* Dummy for status store check */
  681. movl %esp,%esi
  682. movw $0x5a5a,(%esi)
  683. /* fwait maybe this one is responsible of exceptions */
  684. fnstsw (%esi)
  685. cmpb $0,(%esi)
  686. jne .Lno_387
  687. fldcw ___fpucw
  688. .Lno_387:
  689. popl %eax
  690. pushl U_SYSTEM_ENVP
  691. pushl ___crt0_argv
  692. pushl ___crt0_argc
  693. call _pascal_start
  694. pushl %eax
  695. /* call _exit changed to */
  696. call exit
  697. .align 2,0x90
  698. /* .comm U_SYSTEM_DOS_ARGV0,4 */
  699. .comm ___dos_argv0,4
  700. .comm ___crt0_argc,4
  701. .comm ___crt0_argv,4
  702. .comm ___environ_changed,4
  703. /* ___environ_changed: not in data because it is defined in putenv.c */
  704. /* .long 0 */
  705. .globl _exception_exit
  706. _exception_exit:
  707. .long 0
  708. .globl _swap_in
  709. _swap_in:
  710. .long 0
  711. .globl _swap_out
  712. _swap_out:
  713. .long 0
  714. .global _v2prt0_exceptions_on
  715. _v2prt0_exceptions_on:
  716. .long 0
  717. // Fill null page with NOPs
  718. // and a jmp windows_error at the end
  719. .globl v2prt0_windows
  720. v2prt0_windows:
  721. movl $0x90909090,%eax
  722. xorl %edi,%edi
  723. movl $0x400,%ecx
  724. cld
  725. rep
  726. stosl
  727. movl $0xffB,%edi
  728. movb $0xe9,%al
  729. stosb
  730. movl $_fpc_windows_error-4,%eax
  731. subl %edi,%eax
  732. stosl
  733. ret
  734. // Raise SIGILL with UD2 opcode
  735. .globl _fpc_windows_error
  736. _fpc_windows_error:
  737. cmpl $0,_exception_exit
  738. je .L_error_216
  739. .byte 0x0f,0x0b
  740. .L_error_216:
  741. pushl $216
  742. call __exit
  743. jmp exit
  744. #enif
  745. /* this was the prt0.s from the go32v1 version */
  746. //
  747. // call as start(argc, argv, envp) (C-calling convention)
  748. //
  749. .globl _pascal_start
  750. _pascal_start:
  751. /* %ebx doesn't contain ScreenPrimary */
  752. movl U_SYSTEM_GO32_INFO_BLOCK+4,%ebx
  753. movl %ebx,_ScreenPrimary
  754. /* core selector in %fs */
  755. /* keep original fs for debuggers !!!!! (PM) */
  756. movw %fs,%ax
  757. movw %ax,___v2prt0_start_fs
  758. movw _core_selector,%ax
  759. movw %ax,%fs
  760. // Top of frame
  761. movl $0x0,%ebp
  762. movl %esp,%ebx
  763. movl 12(%ebx),%eax
  764. movl %eax,U_SYSTEM_ENVP
  765. movl %eax,_environ
  766. movl 8(%ebx),%eax
  767. movl %eax,_args
  768. movl 4(%ebx),%eax
  769. movl %eax,_argc
  770. call PASCALMAIN
  771. movl $0,%eax
  772. /* no error if passing here */
  773. /* movl $0x4c00,%eax
  774. int $0x21 */
  775. ret
  776. .data
  777. /* .comm U_SYSTEM_ENVP,4 */
  778. .globl _ScreenPrimary
  779. _ScreenPrimary:
  780. .long 0
  781. .globl _argc
  782. _argc:
  783. .long 0
  784. .globl _args
  785. _args:
  786. .long 0
  787. .globl _run_mode
  788. _run_mode:
  789. .word 4
  790. .globl _core_selector
  791. _core_selector:
  792. .word 0
  793. .globl ___v2prt0_start_fs
  794. ___v2prt0_start_fs:
  795. .word 0
  796. .globl _environ
  797. _environ:
  798. .long 0
  799. /* Here Pierre Muller added all what was in crt1.c */
  800. /* in assembler */
  801. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  802. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  803. /* adapted to assembler for FPC by Pierre Muller */
  804. /* Global variables */
  805. /* This gets incremented each time the program is started.
  806. Programs (such as Emacs) which dump their code to create
  807. a new executable, cause this to be larger than 2. Library
  808. functions that cache info in static variables should check
  809. the value of `__bss_count' if they need to reinitialize
  810. the static storage. */
  811. .data
  812. .globl ___bss_count
  813. ___bs_count:
  814. .long 1
  815. .globl __crt0_startup_flags
  816. __crt0_startup_flags:
  817. .long 0
  818. .globl __dos_ds
  819. __dos_ds:
  820. .long 0
  821. .globl ___PROXY
  822. ___PROXY:
  823. .ascii " !proxy"
  824. .byte 0
  825. .globl ___PROXY_LEN
  826. ___PROXY_LEN:
  827. .long 7
  828. .comm __os_trueversion,2
  829. /*
  830. $Log$
  831. Revision 1.7 2003-09-27 11:52:35 peter
  832. * sbrk returns pointer
  833. Revision 1.6 2002/09/08 09:16:15 jonas
  834. * added closing of comment for logs to avoid warning
  835. Revision 1.5 2002/09/07 16:01:19 peter
  836. * old logs removed and tabs fixed
  837. Revision 1.4 2002/02/03 09:51:41 peter
  838. * merged winxp fixes
  839. */