v2prt0.as 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  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 $-1, %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. /* .globl ___dpmi_get_segment_base_address*/
  507. ___dpmi_get_segment_base_address:
  508. pushl %ebp; movl %esp,%ebp
  509. movl 8(%ebp), %ebx
  510. movl $0x0006,%eax
  511. int $0x31
  512. jnc .L_noerror0006
  513. movw %ax,___dpmi_error
  514. movl $-1,%eax
  515. jmp .L_leave0006
  516. .L_noerror0006:
  517. movl 12(%ebp), %ebx
  518. movl %edx, (%ebx)
  519. movw %cx, 2(%ebx)
  520. xorl %eax,%eax
  521. .L_leave0006:
  522. movl %ebp,%esp
  523. popl %ebp
  524. ret $8
  525. .globl ___bss_count
  526. .data
  527. .align 2
  528. ___bss_count:
  529. .long 1
  530. .text
  531. .align 2
  532. .globl _setup_core_selector
  533. _setup_core_selector:
  534. pushl %ebp
  535. movl %esp,%ebp
  536. pushl $1
  537. call ___dpmi_allocate_ldt_descriptors
  538. /* addl $4,%esp */
  539. cmpl $-1,%eax
  540. jne .L24
  541. movw $0,U_SYSTEM_GO32_INFO_BLOCK+26
  542. leave
  543. ret
  544. .align 2,0x90
  545. .L24:
  546. movw %ax,U_SYSTEM_GO32_INFO_BLOCK+26
  547. movw %ax,_core_selector
  548. pushl $0x10ffff
  549. andl $0xffff,%eax
  550. pushl %eax
  551. call ___dpmi_set_segment_limit
  552. leave
  553. ret
  554. .align 2
  555. .globl _setup_screens
  556. _setup_screens:
  557. pushl %ebp
  558. movl %esp,%ebp
  559. movw U_SYSTEM_GO32_INFO_BLOCK+26,%dx
  560. movl $1048563,%ecx
  561. /APP
  562. movw %dx, %gs
  563. .byte 0x65
  564. movw (%ecx),%ax
  565. /NO_APP
  566. cmpw $64896,%ax
  567. jne .L26
  568. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+8
  569. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+4
  570. leave
  571. ret
  572. .align 2,0x90
  573. .L26:
  574. movl $1097,%ecx
  575. /APP
  576. movw %dx,%gs
  577. .byte 0x65
  578. movb (%ecx),%al
  579. /NO_APP
  580. cmpb $7,%al
  581. jne .L29
  582. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+4
  583. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+8
  584. leave
  585. ret
  586. .align 2,0x90
  587. .L29:
  588. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+4
  589. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+8
  590. leave
  591. ret
  592. .align 2
  593. .globl _setup_go32_info_block
  594. _setup_go32_info_block:
  595. pushl %ebp
  596. movl %esp,%ebp
  597. subl $8,%esp
  598. leal -8(%ebp),%eax
  599. pushl %eax
  600. call ___dpmi_get_version
  601. movl $40,U_SYSTEM_GO32_INFO_BLOCK
  602. movl __stubinfo,%edx
  603. movzwl 36(%edx),%eax
  604. sall $4,%eax
  605. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  606. movzwl 32(%edx),%ecx
  607. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+16
  608. movzwl 38(%edx),%ecx
  609. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+20
  610. movb -3(%ebp),%al
  611. movb %al,U_SYSTEM_GO32_INFO_BLOCK+24
  612. movb -2(%ebp),%al
  613. movb %al,U_SYSTEM_GO32_INFO_BLOCK+25
  614. movl $-1,U_SYSTEM_GO32_INFO_BLOCK+28
  615. pushl $U_SYSTEM_GO32_INFO_BLOCK+32
  616. movzwl 38(%edx),%eax
  617. pushl %eax
  618. call ___dpmi_get_segment_base_address
  619. movw $4,U_SYSTEM_GO32_INFO_BLOCK+36
  620. movb -8(%ebp),%dl
  621. salw $8,%dx
  622. movzbw -7(%ebp),%ax
  623. orw %ax,%dx
  624. movw %dx,U_SYSTEM_GO32_INFO_BLOCK+38
  625. call copy_to_c_go32_info_block
  626. leave
  627. ret
  628. copy_to_c_go32_info_block:
  629. leal U_SYSTEM_GO32_INFO_BLOCK,%esi
  630. leal __go32_info_block,%edi
  631. movl $10,%ecx
  632. rep
  633. movsl
  634. ret
  635. .data
  636. /* fpu codeword */
  637. ___fpucw:
  638. .long 0x1332
  639. /* __go32_info_block for C programs */
  640. .align 2
  641. .globl __go32_info_block
  642. .comm __go32_info_block,40
  643. /*
  644. -- prt1_startup --
  645. */
  646. .text
  647. .align 2
  648. .globl ___prt1_startup
  649. ___prt1_startup:
  650. pushl %ebp
  651. movl %esp,%ebp
  652. pushl %ebx
  653. incl ___bss_count
  654. movl $0,___crt0_argv
  655. call _setup_core_selector
  656. call _setup_screens
  657. call _setup_go32_info_block
  658. incl ___environ_changed
  659. /* call set_processor emulation */
  660. /* neede to avoid FPU exception if calling from anothe DPMI program */
  661. movl $0xe01,%eax
  662. movl $1,%ebx
  663. int $0x31
  664. fninit /* initialize fpu */
  665. push %eax /* Dummy for status store check */
  666. movl %esp,%esi
  667. movw $0x5a5a,(%esi)
  668. /* fwait maybe this one is responsible of exceptions */
  669. fnstsw (%esi)
  670. cmpb $0,(%esi)
  671. jne .Lno_387
  672. fldcw ___fpucw
  673. .Lno_387:
  674. popl %eax
  675. pushl U_SYSTEM_ENVP
  676. pushl ___crt0_argv
  677. pushl ___crt0_argc
  678. call _pascal_start
  679. pushl %eax
  680. /* call _exit changed to */
  681. call exit
  682. .align 2,0x90
  683. /* .comm U_SYSTEM_DOS_ARGV0,4 */
  684. .comm ___dos_argv0,4
  685. .comm ___crt0_argc,4
  686. .comm ___crt0_argv,4
  687. .comm ___environ_changed,4
  688. /* ___environ_changed: not in data because it is defined in putenv.c */
  689. /* .long 0 */
  690. .globl _exception_exit
  691. _exception_exit:
  692. .long 0
  693. .globl _swap_in
  694. _swap_in:
  695. .long 0
  696. .globl _swap_out
  697. _swap_out:
  698. .long 0
  699. .global _v2prt0_exceptions_on
  700. _v2prt0_exceptions_on:
  701. .long 0
  702. // Fill null page with NOPs
  703. // and a jmp windows_error at the end
  704. .globl v2prt0_windows
  705. v2prt0_windows:
  706. movl $0x90909090,%eax
  707. xorl %edi,%edi
  708. movl $0x400,%ecx
  709. cld
  710. rep
  711. stosl
  712. movl $0xffB,%edi
  713. movb $0xe9,%al
  714. stosb
  715. movl $_fpc_windows_error-4,%eax
  716. subl %edi,%eax
  717. stosl
  718. ret
  719. // Raise SIGILL with UD2 opcode
  720. .globl _fpc_windows_error
  721. _fpc_windows_error:
  722. cmpl $0,_exception_exit
  723. je .L_error_216
  724. .byte 0x0f,0x0b
  725. .L_error_216:
  726. pushl $216
  727. call __exit
  728. jmp exit
  729. #enif
  730. /* this was the prt0.s from the go32v1 version */
  731. //
  732. // call as start(argc, argv, envp) (C-calling convention)
  733. //
  734. .globl _pascal_start
  735. _pascal_start:
  736. /* %ebx doesn't contain ScreenPrimary */
  737. movl U_SYSTEM_GO32_INFO_BLOCK+4,%ebx
  738. movl %ebx,_ScreenPrimary
  739. /* core selector in %fs */
  740. /* keep original fs for debuggers !!!!! (PM) */
  741. movw %fs,%ax
  742. movw %ax,___v2prt0_start_fs
  743. movw _core_selector,%ax
  744. movw %ax,%fs
  745. // Top of frame
  746. movl $0x0,%ebp
  747. movl %esp,%ebx
  748. movl 12(%ebx),%eax
  749. movl %eax,U_SYSTEM_ENVP
  750. movl %eax,_environ
  751. movl 8(%ebx),%eax
  752. movl %eax,_args
  753. movl 4(%ebx),%eax
  754. movl %eax,_argc
  755. call PASCALMAIN
  756. movl $0,%eax
  757. /* no error if passing here */
  758. /* movl $0x4c00,%eax
  759. int $0x21 */
  760. ret
  761. .data
  762. /* .comm U_SYSTEM_ENVP,4 */
  763. .globl _ScreenPrimary
  764. _ScreenPrimary:
  765. .long 0
  766. .globl _argc
  767. _argc:
  768. .long 0
  769. .globl _args
  770. _args:
  771. .long 0
  772. .globl _run_mode
  773. _run_mode:
  774. .word 4
  775. .globl _core_selector
  776. _core_selector:
  777. .word 0
  778. .globl ___v2prt0_start_fs
  779. ___v2prt0_start_fs:
  780. .word 0
  781. .globl _environ
  782. _environ:
  783. .long 0
  784. /* Here Pierre Muller added all what was in crt1.c */
  785. /* in assembler */
  786. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  787. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  788. /* adapted to assembler for FPC by Pierre Muller */
  789. /* Global variables */
  790. /* This gets incremented each time the program is started.
  791. Programs (such as Emacs) which dump their code to create
  792. a new executable, cause this to be larger than 2. Library
  793. functions that cache info in static variables should check
  794. the value of `__bss_count' if they need to reinitialize
  795. the static storage. */
  796. .data
  797. .globl ___bss_count
  798. ___bs_count:
  799. .long 1
  800. .globl __crt0_startup_flags
  801. __crt0_startup_flags:
  802. .long 0
  803. .globl __dos_ds
  804. __dos_ds:
  805. .long 0
  806. .globl ___PROXY
  807. ___PROXY:
  808. .ascii " !proxy"
  809. .byte 0
  810. .globl ___PROXY_LEN
  811. ___PROXY_LEN:
  812. .long 7
  813. /*
  814. $Log$
  815. Revision 1.3 2001-08-21 13:12:22 florian
  816. * reverted to previous version
  817. Revision 1.1 2000/07/13 06:30:40 michael
  818. + Initial import
  819. Revision 1.15 2000/07/11 09:37:55 pierre
  820. * get it to compile with AS v 2.10
  821. Revision 1.14 2000/05/18 06:40:52 pierre
  822. * avoid FPU exception on startup if no coprocessor and loaded from another DPMI program
  823. Revision 1.13 2000/04/06 13:05:15 pierre
  824. * bug fix for 915, hopefully
  825. Revision 1.12 2000/02/28 11:17:48 pierre
  826. * remove Jonas unnecessary (but correct) code
  827. Revision 1.11 2000/02/27 11:21:17 pierre
  828. * Enormous bug in mouse fix fixed
  829. Revision 1.10 2000/02/23 12:46:11 jonas
  830. * restored my fix (CVS screwed up the previous versinos because of wrong line
  831. breaks)
  832. Revision 1.7 2000/02/16 13:24:55 pierre
  833. * Mouse crash bug fixed !!!
  834. Revision 1.6 1999/07/10 23:17:15 pierre
  835. merged from fixes branch
  836. Revision 1.5.2.1 1999/07/10 23:15:02 pierre
  837. * fixes problem with putenv.c
  838. Revision 1.5 1999/03/01 15:40:53 peter
  839. * use external names
  840. * removed all direct assembler modes
  841. Revision 1.4 1999/02/19 12:25:37 pierre
  842. + ___v2prt0_rmcb_regs in text section for Windows NT
  843. + catch of calls into zero page for Windows 95
  844. (creates Run Time error 216 or SIGILL exception
  845. if dpmiexcp is loaded !)
  846. Revision 1.3 1999/01/05 10:44:59 pierre
  847. * suppressed fwaits to avoid FPU not present exceptions
  848. Revision 1.2 1998/12/21 14:14:21 pierre
  849. added some c vars needed to avoid loading od crt1.o
  850. Revision 1.1 1998/12/21 13:07:03 peter
  851. * use -FE
  852. Revision 1.4 1998/10/14 21:28:45 peter
  853. * initialize fpu so sigfpe is finally generated for fpu errors
  854. Revision 1.3 1998/08/19 10:56:35 pierre
  855. + added some special code for C interface
  856. to avoid loading of crt1.o or dpmiexcp.o from the libc.a
  857. Revision 1.2 1998/05/22 00:39:38 peter
  858. * go32v1, go32v2 recompiles with the new objects
  859. * remake3 works again with go32v2
  860. - removed some "optimizes" from daniel which were wrong
  861. */