v2prt0.as 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  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 FPK Pascal */
  15. .file "v2prt0.s"
  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. /* .comm ___djgpp_ds_alias, 4 must be in locked code */
  49. /* undef MULTIBLOCK */
  50. /* MULTIBLOCK = 0 does not work */
  51. /* Win95 sometimes gives a block at an address lower than the base
  52. address of _djgpp => big troubles
  53. That is why I removed the multiblocks
  54. Pierre Muller */
  55. .data
  56. /* .ifdef MULTIBLOCK needed anyhow */
  57. ___djgpp_memory_handle_pointer:
  58. .long ___djgpp_memory_handle_list+8 /* Next free, first for stub */
  59. .comm ___djgpp_memory_handle_list, 2048 /* Enough for 256 handles */
  60. /* .endif */
  61. sbrk16_first_byte:
  62. .include "sbrk16.ah"
  63. sbrk16_last_byte:
  64. sbrk16_api_ofs:
  65. .long 0
  66. sbrk16_api_seg:
  67. .word 0
  68. zero:
  69. .long 0
  70. exit16_first_byte:
  71. .include "exit16.ah"
  72. exit16_last_byte:
  73. /* hook_387_emulator:
  74. .long ___emu387_load_hook */
  75. /* this pulls in the ident string, generated in .. */
  76. /* .long ___libc_ident_string */
  77. /* this is for when main comes from a library */
  78. .long _main
  79. .text
  80. .globl start
  81. start:
  82. pushl %ds /* set %es same as %ds */
  83. popl %es /* push/pop 4 bytes shorter than ax */
  84. .if 0 /* we do this in the stub now */
  85. movl $edata, %edi /* set all BSS bytes to zero */
  86. movl $end, %ecx
  87. subl %edi, %ecx
  88. xorl %eax, %eax /* Zero fill value */
  89. shrl $2, %ecx /* div 4 Longwords not bytes */
  90. cld
  91. rep
  92. stosl
  93. .endif
  94. /* Enable NULL pointer protection if DPMI supports it */
  95. testb $0x1, __crt0_startup_flags+1 /* include/crt0.h */
  96. jnz 1f
  97. movl $start, %eax
  98. cmpl $0x1000, %eax
  99. jl 1f
  100. movw $0x507, %ax
  101. .byte 0x64 /* fs: */
  102. movl STUBINFO_MEMORY_HANDLE, %esi
  103. xorl %ebx, %ebx /* Offset 0 in mem block */
  104. movl $1, %ecx /* Set one page */
  105. movl $zero, %edx
  106. int $0x31 /* Make null page uncommitted */
  107. 1:
  108. /* Create an alias for DS to be used by real-mode callbacks (exception handler messes with DS itself) */
  109. movw %ds, %bx
  110. movw $0x000a, %ax
  111. int $0x31
  112. jnc ds_alias_ok
  113. movb $0x4c, %ah
  114. int $0x21
  115. ds_alias_ok:
  116. movw %ax, ___v2prt0_ds_alias
  117. movl %eax, %ebx
  118. movw $0x0009, %ax
  119. movw %cs, %cx /* get CPL from %cs */
  120. andl $3, %ecx
  121. shll $5, %ecx /* move it into place */
  122. orw $0xc093, %cx
  123. int $0x31 /* set access rights for alias */
  124. /* Maybe set our DS limit to 4Gb in size if flag set */
  125. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  126. jz 2f
  127. movw $0xffff, %cx
  128. movl %ecx, %edx
  129. movw $0x0008, %ax /* reset alias limit to -1 */
  130. int $0x31
  131. movw %cs, %bx
  132. movw $0x0008, %ax /* reset DS limit to -1 */
  133. int $0x31
  134. movw %ds, %bx
  135. movw $0x0008, %ax /* reset DS limit to -1 */
  136. int $0x31
  137. lsl %ebx, %ebx /* Should be -1 */
  138. incl %ebx
  139. jz 2f
  140. andb $0x7f, __crt0_startup_flags /* clear it if failure */
  141. 2:
  142. .ifdef MULTIBLOCK
  143. testb $0x8, __crt0_startup_flags+1 /* include/crt0.h */
  144. jz 8f
  145. .endif
  146. /* Allocate some DOS memory and copy our sbrk helper into it. */
  147. movl $sbrk16_first_byte, %esi
  148. movzwl 8(%esi), %ebx
  149. shrl $4, %ebx
  150. movw $0x0100, %ax
  151. int $0x31
  152. jnc dos_alloc_ok
  153. movb $0x4c, %ah
  154. int $0x21
  155. dos_alloc_ok:
  156. movw %cs, 2(%esi)
  157. /* store API information */
  158. movw %ds, 4(%esi)
  159. movw %dx, 6(%esi)
  160. /* selector for allocated block */
  161. movzwl (%esi), %eax /* calculate API address */
  162. movl %eax, sbrk16_api_ofs
  163. pushl %es /* move the data */
  164. movw %dx, %es
  165. movl $(sbrk16_last_byte - sbrk16_first_byte), %ecx
  166. shrl $2,%ecx
  167. xorl %edi, %edi
  168. cld
  169. rep
  170. movsl
  171. popl %es
  172. movl %edx, %ebx /* dos memory selector */
  173. movw $0x000b, %ax /* get descriptor */
  174. movl $sel_buf, %edi
  175. int $0x31
  176. andb $0xbf, sel_buf+6 /* make 16-bit */
  177. andb $0xf0, sel_buf+5 /* remove old type */
  178. orb $0x0a, sel_buf+5 /* set new type to code/read */
  179. xorl %eax, %eax /* allocate new selector */
  180. movw $0x0001, %cx
  181. int $0x31
  182. movw %ax, sbrk16_api_seg
  183. movl %eax, %ebx
  184. movw $0x000c, %ax /* set descriptor */
  185. movl $sel_buf, %edi
  186. int $0x31
  187. .ifdef MULTIBLOCK
  188. 8: movl $___djgpp_memory_handle_list+8, %edi
  189. movl %edi, ___djgpp_memory_handle_pointer
  190. xorl %eax, %eax
  191. 9: cmpl %eax, (%edi)
  192. je 10f
  193. mov %eax, (%edi)
  194. addl $4, %edi
  195. jmp 9b
  196. 10: movw %cs, %bx
  197. movw $0x0006,%ax
  198. int $0x31
  199. movl %edx,___djgpp_base_address
  200. movw %cx,___djgpp_base_address+2
  201. .endif /* MULTIBLOCK */
  202. /* Initialize the brk/sbrk variables */
  203. /* movl $end, __what_size_app_thinks_it_is */
  204. .byte 0x64 /* fs: */
  205. movl STUBINFO_INITIAL_SIZE, %eax
  206. movl %eax, __what_size_dpmi_thinks_we_are
  207. /* Maybe lock the initial block, expects BX:CX */
  208. movl %ecx,%ebx
  209. movl %edx,%ecx
  210. addw $4096,%cx /* Skip null page */
  211. adcl $0,%ebx
  212. subl $4096,%eax
  213. pushl %eax
  214. call lock_memory
  215. .byte 0x64 /* fs: */
  216. movl STUBINFO_MEMORY_HANDLE, %eax
  217. movl %eax, ___djgpp_memory_handle_list
  218. .byte 0x64 /* fs: */ /* copy stubinfo into local memory */
  219. movl STUBINFO_SIZE, %eax
  220. pushl %eax
  221. call ___sbrk
  222. movl %eax, __stubinfo
  223. movl %eax,U_SYSTEM_STUB_INFO
  224. movl %eax, %edi
  225. .byte 0x64 /* fs: */
  226. movl STUBINFO_SIZE, %ecx
  227. shrl $2, %ecx
  228. xorl %esi, %esi /* Zero */
  229. pushl %ds
  230. pushl %fs
  231. popl %ds
  232. cld
  233. rep
  234. movsl
  235. popl %ds
  236. movl __stklen, %eax /* get program-requested stack size */
  237. .byte 0x64 /* fs: */
  238. movl STUBINFO_MINSTACK, %ecx /* get stub-requested stack size */
  239. cmpl %ecx, %eax
  240. jge use_stubinfo_stack_size /* use the larger of the two */
  241. movl %ecx, %eax
  242. movl %eax, __stklen /* store the actual stack length */
  243. use_stubinfo_stack_size:
  244. pushl %eax
  245. call ___sbrk /* allocate the memory */
  246. cmpl $-1, %eax
  247. je no_memory
  248. movl %eax, ___djgpp_stack_limit /* Bottom of stack */
  249. addl $256,%eax
  250. movl %eax,__stkbottom /* for stack checks */
  251. movl %eax,U_SYSTEM_STACKBOTTOM
  252. .ifdef LOCK_BOTTOM_STACK
  253. /* test lock one page at bottom of stack to be sure that there is */
  254. /* not stack overflow, as the minimal size is 128 ko 4ko less is not much !! */
  255. testb $0x1, __crt0_startup_flags+1 /* include/crt0.h */
  256. jnz 101f /* just to be sure it is not used */
  257. movl %eax, %ebx /* Offset __djgpp_stack_limit in mem block */
  258. addl $0xfff,%ebx
  259. andl $0xfffff000,%ebx /* page align it */
  260. movw $0x507, %ax
  261. .ifdef MULTIBLOCK
  262. movl ___djgpp_memory_handle_pointer-8, %esi /* last memory block */
  263. .else /* not MULTIBLOCK */
  264. movl ___djgpp_memory_handle_list, %esi /* last memory block */
  265. .endif
  266. movl $1, %ecx /* Set one page */
  267. movl $zero, %edx
  268. int $0x31 /* Make first stack page page uncommitted */
  269. 101:
  270. .endif /* LOCK_BOTTOM_STACK */
  271. movl ___djgpp_stack_limit,%eax /* Bottom of stack */
  272. addl __stklen, %eax
  273. movw %ds, %dx /* set stack */
  274. movw %dx, %ss
  275. movl %eax, %esp
  276. xorl %ebp, %ebp
  277. .if 0 /* done in crt1.c */
  278. .byte 0x64 /* fs: */ /* set up _go32_info_block structure */
  279. movzwl STUBINFO_MINKEEP, %eax
  280. movl %eax, U_SYSTEM_GO32_INFO_BLOCK+16 /* .size_of_transfer_buffer */
  281. .byte 0x64 /* fs: */
  282. movzwl STUBINFO_DS_SEGMENT, %eax
  283. shll $4, %eax
  284. movl %eax, U_SYSTEM_GO32_INFO_BLOCK+12 /* .linear_address_of_transfer_buffer */
  285. xorl %eax, %eax
  286. movl $1, %ecx
  287. int $0x31
  288. jc no_selector
  289. movw %ax, U_SYSTEM_GO32_INFO_BLOCK+26 /* .selector_for_linear_memory */
  290. movl %eax, %ebx
  291. movl $8, %eax
  292. movl $0x0f, %ecx
  293. movw $0xffff, %dx
  294. int $0x31 /* Set limit 1Mb */
  295. no_selector:
  296. .endif
  297. call ___prt1_startup /* run program */
  298. jmp exit
  299. no_memory:
  300. movb $0xff, %al
  301. jmp exit
  302. /*-----------------------------------------------------------------------------*/
  303. /* #define FREESEL(x) movw x, %bx; movw $0x0001, %ax; int $0x31 */
  304. .macro FREESEL x
  305. movw \x,%bx
  306. movw $0x0001,%ax
  307. int $0x31
  308. .endm
  309. .global ___exit
  310. .align 2
  311. ___exit:
  312. movb 4(%esp), %al
  313. exit:
  314. movb %al, %cl
  315. xorl %eax,%eax
  316. movw %ax,%fs
  317. movw %ax,%gs
  318. cmpl $0,_exception_exit
  319. jz no_exception
  320. pushl %ecx
  321. call *_exception_exit
  322. popl %ecx
  323. no_exception:
  324. cli /* Just in case they didn't unhook ints */
  325. FREESEL U_SYSTEM_GO32_INFO_BLOCK+26 /* selector for linear memory */
  326. FREESEL ___v2prt0_ds_alias /* DS alias for rmcb exceptions */
  327. .ifdef MULTIBLOCK
  328. testb $0x8, __crt0_startup_flags+1 /* include/crt0.h */
  329. jz 9f
  330. .endif
  331. FREESEL sbrk16_api_seg /* sbrk cs */
  332. movw sbrk16_first_byte+6,%dx /* selector for allocated DOS mem */
  333. movw $0x101, %ax
  334. int $0x31 /* Free block and selector */
  335. 9:
  336. movl __stubinfo, %edx
  337. movl STUBINFO_CS_SELECTOR(%edx), %eax
  338. movw %ax, sbrk16_api_seg
  339. xorl %edi, %edi
  340. movl %edi, sbrk16_api_ofs /* Offset is zero */
  341. movw STUBINFO_DS_SELECTOR(%edx), %es
  342. movb %cl, %dl /* Exit status */
  343. movl $exit16_first_byte, %esi
  344. movl $(exit16_last_byte - exit16_first_byte), %ecx
  345. cld
  346. rep
  347. movsb
  348. movw %es,%ax /* We will free stack! */
  349. movw %ax,%ss
  350. movl $0x400,%esp /* Transfer buffer >= 1024 bytes */
  351. .ifdef MULTIBLOCK
  352. movl ___djgpp_memory_handle_pointer, %ebx
  353. jmp 7f
  354. 6: subl $8, %ebx
  355. movl (%ebx), %edi
  356. movw 2(%ebx), %si
  357. movw $0x502, %ax
  358. int $0x31
  359. 7: cmpl $___djgpp_memory_handle_list+8, %ebx
  360. jne 6b
  361. .endif /* MULTIBLOCK */
  362. xorl %ebp, %ebp /* V1.10 bug fix */
  363. movl ___djgpp_memory_handle_list, %edi
  364. movl ___djgpp_memory_handle_list+2, %esi /* Skip word prefixes */
  365. FREESEL %ds
  366. movw %cs, %bx
  367. /* Call exit procedure with BX=32-bit CS; SI+DI=32-bit handle; DL=exit status */
  368. .byte 0x2e
  369. ljmp sbrk16_api_ofs
  370. /*-----------------------------------------------------------------------------*/
  371. /* .lcomm __what_size_app_thinks_it_is, 4 */
  372. __what_size_app_thinks_it_is:
  373. .long end
  374. .lcomm __what_we_return_to_app_as_old_size, 4
  375. .lcomm __what_size_dpmi_thinks_we_are, 4
  376. lock_memory:
  377. /* BX:CX should be linear address; size is pushed on stack */
  378. testb $0x10, __crt0_startup_flags+1 /* include/crt0.h */
  379. jz 13f
  380. pushl %esi
  381. pushl %edi
  382. pushl %eax
  383. movl 16(%esp),%edi
  384. movw 18(%esp),%si
  385. movw $0x600,%ax
  386. int $0x31
  387. popl %eax
  388. popl %edi
  389. popl %esi
  390. 13: ret $4 /* Pop the argument */
  391. .if 0
  392. brk_hook_ret:
  393. ret
  394. .globl ___sbrk_brk_hook
  395. ___sbrk_brk_hook:
  396. .long brk_hook_ret
  397. .endif
  398. .global ___sbrk
  399. .align 2
  400. ___sbrk:
  401. movl __what_size_app_thinks_it_is, %eax
  402. movl 4(%esp), %ecx /* Increment size */
  403. addl %ecx, %eax
  404. jnc brk_common
  405. /* Carry is only set if a negative increment or wrap happens. Negative
  406. increment is semi-OK, wrap (only for multiple zone sbrk) isn't. */
  407. test $0x80000000, %ecx /* Clears carry */
  408. jnz brk_common
  409. stc /* Put carry back */
  410. jmp brk_common
  411. .globl ___brk
  412. .align 2
  413. ___brk:
  414. movl 4(%esp), %eax
  415. clc
  416. brk_common:
  417. pushl %esi
  418. pushl %edi
  419. pushl %ebx
  420. movl __what_size_app_thinks_it_is, %edx /* save info */
  421. movl %edx, __what_we_return_to_app_as_old_size
  422. movl %eax, __what_size_app_thinks_it_is
  423. jc 10f /* Wrap for multi-zone */
  424. cmpl __what_size_dpmi_thinks_we_are, %eax /* don't bother shrinking */
  425. jbe brk_nochange
  426. .ifdef MULTIBLOCK
  427. testb $0x8, __crt0_startup_flags+1 /* include/crt0.h */
  428. jz 10f
  429. .endif
  430. addl $0x0000ffff, %eax /* round up to 64K block */
  431. andl $0xffff0000, %eax
  432. push %eax /* size - save for later */
  433. movl ___djgpp_memory_handle_list, %edi /* request new size */
  434. movw ___djgpp_memory_handle_list+2, %si
  435. movl %eax, %ecx /* size not limit */
  436. movl %eax, %ebx /* size not limit */
  437. shrl $16, %ebx /* BX:CX size */
  438. movw $0x0900, %ax /* disable interrupts */
  439. int $0x31
  440. pushl %eax
  441. lcall sbrk16_api_ofs
  442. setc %dl /* Save carry */
  443. popl %eax /* restore interrupts */
  444. int $0x31
  445. test %dl,%dl
  446. popl %edx
  447. jne brk_error
  448. movl %edi, ___djgpp_memory_handle_list /* store new handle */
  449. movw %si, ___djgpp_memory_handle_list+2
  450. movl %ecx, ___djgpp_base_address /* store new base address */
  451. movw %bx, ___djgpp_base_address+2
  452. movl %edx, %eax
  453. movl __what_size_dpmi_thinks_we_are, %ecx
  454. subl %ecx, %eax
  455. addl ___djgpp_base_address, %ecx
  456. movl %ecx, %ebx
  457. shrl $16, %ebx /* BX:CX addr */
  458. pushl %eax /* Size */
  459. call lock_memory
  460. decl %edx /* limit now, not size */
  461. .ifdef MULTIBLOCK
  462. jmp 5f
  463. /* Current allocation not large enough, get another block */
  464. 10: movl %ecx, %eax /* Add amt */
  465. pushl %eax /* Save orig */
  466. addl $0x0000ffff, %eax /* round up to 64K block */
  467. andl $0xffff0000, %eax
  468. movl %eax, %edx /* Save size */
  469. movl %eax, %ecx
  470. movl %eax, %ebx
  471. shrl $16, %ebx /* BX:CX size */
  472. movw $0x501,%ax
  473. int $0x31
  474. popl %eax /* Orig size */
  475. jc brk_error
  476. pushl %edx /* Size */
  477. call lock_memory
  478. pushw %bx
  479. pushw %cx
  480. popl %ecx /* Linear address */
  481. /* What if the new base address is lower than __djgpp_base_address !!! */
  482. subl ___djgpp_base_address, %ecx /* New dpmi size */
  483. cmpl %ecx, __what_size_dpmi_thinks_we_are /* Back to back ? */
  484. je 4f
  485. movl %ecx, __what_size_dpmi_thinks_we_are
  486. movl %ecx, __what_we_return_to_app_as_old_size
  487. 4:
  488. movl __what_we_return_to_app_as_old_size, %ebx /* Base for new block */
  489. addl %ebx, %eax /* Final address */
  490. movl %eax, __what_size_app_thinks_it_is
  491. /* Note - save adjusted memory base and memory handle SI:DI here */
  492. movl ___djgpp_memory_handle_pointer, %ebx
  493. movl %edi, (%ebx)
  494. movw %si, 2(%ebx)
  495. movl %ecx, 4(%ebx)
  496. addl $8, %ebx
  497. cmpl $___djgpp_memory_handle_list+2040, %ebx /* At end? */
  498. je 11f
  499. movl %ebx, ___djgpp_memory_handle_pointer /* Only if not at end */
  500. 11:
  501. addl %ecx, %edx /* Final address */
  502. decl %edx /* Limit to end */
  503. /* If we get a block at a lower address we must skip the limit change */
  504. cmpl ___djgpp_selector_limit, %edx
  505. jbe 12f
  506. .endif
  507. 5: movl %edx, ___djgpp_selector_limit
  508. orw $0x0fff, %dx /* low bits set */
  509. movw $0x0008, %ax /* reset CS limit */
  510. movw %cs, %bx
  511. movl %edx, %ecx
  512. shrl $16, %ecx
  513. int $0x31 /* CX:DX is limit */
  514. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  515. jnz 3f
  516. movw $0x0008, %ax /* reset DS limit */
  517. movw %ds, %bx
  518. int $0x31
  519. movw $0x0008, %ax /* reset DS alias limit */
  520. movl ___v2prt0_ds_alias, %ebx
  521. int $0x31
  522. 3:
  523. movw $0x0007, %ax /* reset DS alias base */
  524. movl ___v2prt0_ds_alias, %ebx
  525. movl ___djgpp_base_address, %edx
  526. movw ___djgpp_base_address+2, %cx
  527. int $0x31
  528. movl ___djgpp_selector_limit, %edx
  529. 12: incl %edx /* Size not limit */
  530. testb $0x60, __crt0_startup_flags /* include/crt0.h */
  531. jz no_fill_sbrk_memory
  532. pushl %ds
  533. popl %es
  534. movl __what_size_dpmi_thinks_we_are, %edi /* set all newly resized bytes zero */
  535. movl %edx, %ecx /* Limit */
  536. subl %edi, %ecx /* Adjust count for base */
  537. xorl %eax, %eax
  538. testb $0x40, __crt0_startup_flags
  539. jz no_deadbeef
  540. movl $0xdeadbeef, %eax /* something really easy to spot */
  541. no_deadbeef:
  542. shrl $2, %ecx /* div 4 Longwords not bytes */
  543. cld
  544. rep
  545. stosl
  546. no_fill_sbrk_memory:
  547. movl %edx, __what_size_dpmi_thinks_we_are
  548. .if 0 /* No purpose */
  549. pushl ___djgpp_memory_handle_list
  550. pushl ___djgpp_base_address
  551. movl ___sbrk_brk_hook, %eax
  552. call %eax
  553. addl $8, %esp
  554. .endif
  555. brk_nochange: /* successful return */
  556. movl __what_we_return_to_app_as_old_size, %eax
  557. jmp brk_return
  558. brk_error: /* error return */
  559. movl __what_we_return_to_app_as_old_size, %eax
  560. movl %eax, __what_size_app_thinks_it_is
  561. movl $-1, %eax
  562. brk_return:
  563. popl %ebx
  564. popl %edi
  565. popl %esi
  566. ret
  567. .globl __crt0_init_mcount
  568. __crt0_init_mcount:
  569. .ifdef IN_GCRT0
  570. jmp __mcount_init
  571. .else
  572. ret
  573. .endif
  574. /* From here on this are parts of crt1.c converted to assembler
  575. and without any call to libc, so that it works without anything else
  576. additions made by Pierre Muller*/
  577. /* from dpmidefs.h * /
  578. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  579. /* from include <libc/asmdefs.h> */
  580. /* all macros removed here */
  581. /* #define FUNC(x) .globl x; x: */
  582. /* #define ENTER pushl %ebp; movl %esp,%ebp */
  583. /* #define LEAVE(x) movl %ebp,%esp; popl %ebp; ret $(x) */
  584. /* #define ARG1 8(%ebp)
  585. #define ARG1h 10(%ebp)
  586. #define ARG2 12(%ebp)
  587. #define ARG2h 14(%ebp)
  588. #define ARG3 16(%ebp)
  589. #define ARG4 20(%ebp)
  590. #define ARG5 24(%ebp)
  591. #define ARG6 28(%ebp)
  592. #define ARG7 32(%ebp)
  593. #define ARG8 36(%ebp) */
  594. .comm ___dpmi_error,2
  595. /* from dpmi0000.s */
  596. .globl ___dpmi_allocate_ldt_descriptors
  597. ___dpmi_allocate_ldt_descriptors:
  598. pushl %ebp; movl %esp,%ebp
  599. movl 8(%ebp), %ecx
  600. movl $0x0000, %eax
  601. int $0x31
  602. jnc .L_noerror0000
  603. movw %ax,___dpmi_error
  604. movl $-1,%eax
  605. jmp .L_leave0000
  606. .L_noerror0000:
  607. movzwl %ax,%eax
  608. .L_leave0000:
  609. movl %ebp,%esp
  610. popl %ebp
  611. ret $4
  612. /* from file dpmi0008.s */
  613. .globl ___dpmi_set_segment_limit
  614. ___dpmi_set_segment_limit:
  615. pushl %ebp; movl %esp,%ebp
  616. movl 8(%ebp), %ebx
  617. movzwl 12(%ebp), %edx
  618. movzwl 14(%ebp),%ecx
  619. movl $0x0008,%eax
  620. int $0x31
  621. jnc .L_noerror0008
  622. movw %ax,___dpmi_error
  623. movl $-1,%eax
  624. jmp .L_leave0008
  625. .L_noerror0008:
  626. xorl %eax,%eax
  627. .L_leave0008:
  628. movl %ebp,%esp
  629. popl %ebp
  630. ret $8
  631. .globl ___dpmi_get_version
  632. ___dpmi_get_version:
  633. pushl %ebp; movl %esp,%ebp
  634. movl $0x0400,%eax
  635. int $0x31
  636. jnc .L_noerror0400
  637. movw %ax,___dpmi_error
  638. movl $-1,%eax
  639. jmp .L_leave0400
  640. .L_noerror0400:
  641. movl 8(%ebp), %esi
  642. movb %ah, (%esi)
  643. movb %al, 1(%esi)
  644. movw %bx, 2(%esi)
  645. movb %cl, 4(%esi)
  646. movb %dh, 5(%esi)
  647. movb %dl, 6(%esi)
  648. xorl %eax,%eax
  649. .L_leave0400:
  650. movl %ebp,%esp
  651. popl %ebp
  652. ret $4
  653. .globl ___dpmi_get_segment_base_address
  654. ___dpmi_get_segment_base_address:
  655. pushl %ebp; movl %esp,%ebp
  656. movl 8(%ebp), %ebx
  657. movl $0x0006,%eax
  658. int $0x31
  659. jnc .L_noerror0006
  660. movw %ax,___dpmi_error
  661. movl $-1,%eax
  662. jmp .L_leave0006
  663. .L_noerror0006:
  664. movl 12(%ebp), %ebx
  665. movl %edx, (%ebx)
  666. movw %cx, 2(%ebx)
  667. xorl %eax,%eax
  668. .L_leave0006:
  669. movl %ebp,%esp
  670. popl %ebp
  671. ret $8
  672. .globl ___bss_count
  673. .data
  674. .align 2
  675. ___bss_count:
  676. .long 1
  677. .text
  678. .align 2
  679. .globl _setup_core_selector
  680. _setup_core_selector:
  681. pushl %ebp
  682. movl %esp,%ebp
  683. pushl $1
  684. call ___dpmi_allocate_ldt_descriptors
  685. /* addl $4,%esp */
  686. cmpl $-1,%eax
  687. jne .L24
  688. movw $0,U_SYSTEM_GO32_INFO_BLOCK+26
  689. leave
  690. ret
  691. .align 2,0x90
  692. .L24:
  693. movw %ax,U_SYSTEM_GO32_INFO_BLOCK+26
  694. movw %ax,_core_selector
  695. pushl $0x10ffff
  696. andl $0xffff,%eax
  697. pushl %eax
  698. call ___dpmi_set_segment_limit
  699. leave
  700. ret
  701. .align 2
  702. .globl _setup_screens
  703. _setup_screens:
  704. pushl %ebp
  705. movl %esp,%ebp
  706. movw U_SYSTEM_GO32_INFO_BLOCK+26,%dx
  707. movl $1048563,%ecx
  708. /APP
  709. movw %dx, %gs
  710. .byte 0x65
  711. movw (%ecx),%ax
  712. /NO_APP
  713. cmpw $64896,%ax
  714. jne .L26
  715. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+8
  716. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+4
  717. leave
  718. ret
  719. .align 2,0x90
  720. .L26:
  721. movl $1097,%ecx
  722. /APP
  723. movw %dx,%gs
  724. .byte 0x65
  725. movb (%ecx),%al
  726. /NO_APP
  727. cmpb $7,%al
  728. jne .L29
  729. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+4
  730. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+8
  731. leave
  732. ret
  733. .align 2,0x90
  734. .L29:
  735. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+4
  736. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+8
  737. leave
  738. ret
  739. .align 2
  740. .globl _setup_go32_info_block
  741. _setup_go32_info_block:
  742. pushl %ebp
  743. movl %esp,%ebp
  744. subl $8,%esp
  745. leal -8(%ebp),%eax
  746. pushl %eax
  747. call ___dpmi_get_version
  748. movl $40,U_SYSTEM_GO32_INFO_BLOCK
  749. movl __stubinfo,%edx
  750. movzwl 36(%edx),%eax
  751. sall $4,%eax
  752. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  753. movzwl 32(%edx),%ecx
  754. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+16
  755. movzwl 38(%edx),%ecx
  756. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+20
  757. movb -3(%ebp),%al
  758. movb %al,U_SYSTEM_GO32_INFO_BLOCK+24
  759. movb -2(%ebp),%al
  760. movb %al,U_SYSTEM_GO32_INFO_BLOCK+25
  761. movl $-1,U_SYSTEM_GO32_INFO_BLOCK+28
  762. pushl $U_SYSTEM_GO32_INFO_BLOCK+32
  763. movzwl 38(%edx),%eax
  764. pushl %eax
  765. call ___dpmi_get_segment_base_address
  766. movw $4,U_SYSTEM_GO32_INFO_BLOCK+36
  767. movb -8(%ebp),%dl
  768. salw $8,%dx
  769. movzbw -7(%ebp),%ax
  770. orw %ax,%dx
  771. movw %dx,U_SYSTEM_GO32_INFO_BLOCK+38
  772. leave
  773. ret
  774. .globl ___PROXY
  775. .data
  776. ___PROXY:
  777. .ascii " !proxy\0"
  778. .globl ___PROXY_LEN
  779. .align 2
  780. ___PROXY_LEN:
  781. .long 7
  782. .text
  783. .align 2
  784. .globl ___prt1_startup
  785. ___prt1_startup:
  786. pushl %ebp
  787. movl %esp,%ebp
  788. pushl %ebx
  789. incl ___bss_count
  790. movl $0,___crt0_argv
  791. call _setup_core_selector
  792. call _setup_screens
  793. call _setup_go32_info_block
  794. /* call ___djgpp_exception_setup
  795. call _setup_ENVPment */
  796. incl ___environ_changed
  797. /* pushl $0
  798. call __use_lfn
  799. addl $4,%esp
  800. call ___crt0_setup_arguments
  801. movl ___crt0_argv,%eax
  802. testl %eax,%eax
  803. je .L55
  804. movl (%eax),%ebx
  805. jmp .L56
  806. .align 2,0x90
  807. .L55:
  808. movl U_SYSTEM_DOS_ARGV0,%ebx
  809. .L56:
  810. pushl %ebx
  811. call ___crt0_load_ENVPment_file
  812. pushl $0
  813. call __use_lfn
  814. pushl %ebx
  815. call __npxsetup
  816. call __crt0_init_mcount
  817. call ___main */
  818. pushl U_SYSTEM_ENVP
  819. pushl ___crt0_argv
  820. pushl ___crt0_argc
  821. call _pascal_start
  822. pushl %eax
  823. /* call _exit changed to */
  824. call exit
  825. .align 2,0x90
  826. /* .comm U_SYSTEM_DOS_ARGV0,4 */
  827. .comm ___crt0_argc,4
  828. .comm ___crt0_argv,4
  829. .globl ___environ_changed
  830. ___environ_changed:
  831. .long 0
  832. .globl _exception_exit
  833. _exception_exit:
  834. .long 0
  835. .globl _swap_in
  836. _swap_in:
  837. .long 0
  838. .globl _swap_out
  839. _swap_out:
  840. .long 0
  841. .global _v2prt0_exceptions_on
  842. _v2prt0_exceptions_on:
  843. .long 0
  844. /*.comm __crt0_startup_flags,4
  845. .comm U_SYSTEM_ENVP,4 */
  846. .ifdef test_go32v1
  847. #
  848. # Called as start(argc, argv, envp)
  849. #
  850. # gs:edx points to prog_info structure. All other registers are OBSOLETE
  851. # but included for backwards compatibility
  852. #
  853. .text
  854. .globl old_start
  855. old_start:
  856. popl %ebx
  857. popl %eax
  858. movl %eax,__hard_master
  859. movl %esi,___pid
  860. movl %edi,___transfer_buffer
  861. movl %ebx,_ScreenPrimary
  862. movl %ebp,_ScreenSecondary
  863. cmpl $0, %edx
  864. je Lcopy_none
  865. movw %gs,%cx
  866. movw %ds,%ax
  867. cmpw %cx,%ax
  868. je Lcopy_none
  869. movl %gs:(%edx), %ecx
  870. cmpl U_SYSTEM_GO32_INFO_BLOCK, %ecx
  871. jbe Lcopy_less
  872. movl U_SYSTEM_GO32_INFO_BLOCK, %ecx
  873. Lcopy_less:
  874. movl $U_SYSTEM_GO32_INFO_BLOCK, %edi
  875. addl $3, %ecx
  876. andl $0xfffffffc, %ecx
  877. movl %ecx, (%edi)
  878. addl $4, %edi
  879. addl $4, %edx
  880. subl $4, %ecx
  881. Lcopy_more:
  882. movl %gs:(%edx), %eax
  883. movl %eax, (%edi)
  884. addl $4, %edx
  885. addl $4, %edi
  886. subl $4, %ecx
  887. jnz Lcopy_more
  888. movl U_SYSTEM_GO32_INFO_BLOCK+4, %eax
  889. movl %eax, _ScreenPrimary
  890. movl U_SYSTEM_GO32_INFO_BLOCK+8, %eax
  891. movl %eax, _ScreenSecondary
  892. movl U_SYSTEM_GO32_INFO_BLOCK+12, %eax
  893. movl %eax, ___transfer_buffer
  894. movl U_SYSTEM_GO32_INFO_BLOCK+20, %eax
  895. movl %eax, ___pid
  896. movl U_SYSTEM_GO32_INFO_BLOCK+24, %eax
  897. movl %eax, __hard_master
  898. jmp Lcopy_done
  899. Lcopy_none:
  900. movl %ebx,U_SYSTEM_GO32_INFO_BLOCK+4
  901. movl %ebp,U_SYSTEM_GO32_INFO_BLOCK+8
  902. movl %edi,U_SYSTEM_GO32_INFO_BLOCK+12
  903. movl $4096,U_SYSTEM_GO32_INFO_BLOCK+16
  904. movl %esi,U_SYSTEM_GO32_INFO_BLOCK+20
  905. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+24
  906. movl $28, U_SYSTEM_GO32_INFO_BLOCK
  907. Lcopy_done:
  908. movw U_SYSTEM_GO32_INFO_BLOCK+36,%ax
  909. movw %ax,_run_mode
  910. cmpw $4,%ax
  911. jne CanOnlyRunDPMI
  912. call Correct_tbaddress
  913. LtbaddressOK:
  914. movw U_SYSTEM_GO32_INFO_BLOCK+26,%ax
  915. movw %ax,_core_selector
  916. /* core selector in %fs */
  917. movw %ax,%fs
  918. xorl %esi,%esi
  919. xorl %edi,%edi
  920. xorl %ebp,%ebp
  921. xorl %ebx,%ebx
  922. movl %esp,%ebx
  923. movl $0x0,%ebp
  924. movl %esp,%ebx
  925. movl 8(%ebx),%eax
  926. movl %eax,U_SYSTEM_ENVP
  927. movl 4(%ebx),%eax
  928. movl %eax,_args
  929. movl (%ebx),%eax
  930. movl %eax,_argc
  931. call PASCALMAIN
  932. exit_again:
  933. movl $0x4c00,%eax
  934. int $0x21
  935. jmp exit_again
  936. ret
  937. Correct_tbaddress:
  938. movl ___transfer_buffer,%eax
  939. addl $1,%eax
  940. andl $0xFFFFF,%eax
  941. movl %eax,___transfer_buffer
  942. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  943. ret
  944. CanOnlyRunDPMI:
  945. movl $0x4c01,%eax
  946. int $0x21
  947. jmp exit_again
  948. .ascii "Can only run in DPMI "
  949. /* .data
  950. .globl _argc
  951. _argc:
  952. .long 0
  953. .globl _args
  954. _args:
  955. .long 0
  956. .globl _run_mode
  957. _run_mode:
  958. .word 0
  959. .globl _core_selector
  960. _core_selector:
  961. .word 0
  962. .globl _ENVP
  963. _ENVP:
  964. .long 0 */
  965. .globl ___pid
  966. ___pid:
  967. .long 42
  968. .globl ___transfer_buffer
  969. ___transfer_buffer:
  970. .long 0
  971. .globl _ScreenSecondary
  972. _ScreenSecondary:
  973. .long 0
  974. .globl __hard_master
  975. .globl __hard_slave
  976. .globl __core_select
  977. __hard_master:
  978. .byte 0
  979. __hard_slave:
  980. .byte 0
  981. .endif /* test_go32v1 */
  982. /* this was the prt0.s from the go32v1 version */
  983. //
  984. // call as start(argc, argv, envp) (C-calling convention)
  985. //
  986. .globl _pascal_start
  987. _pascal_start:
  988. /* %ebx doesn't contain ScreenPrimary */
  989. movl U_SYSTEM_GO32_INFO_BLOCK+4,%ebx
  990. movl %ebx,_ScreenPrimary
  991. /* core selector in %fs */
  992. movw _core_selector,%ax
  993. movw %ax,%fs
  994. // Top of frame
  995. movl $0x0,%ebp
  996. movl %esp,%ebx
  997. movl 12(%ebx),%eax
  998. movl %eax,U_SYSTEM_ENVP
  999. movl 8(%ebx),%eax
  1000. movl %eax,_args
  1001. movl 4(%ebx),%eax
  1002. movl %eax,_argc
  1003. call PASCALMAIN
  1004. movl $0,%eax
  1005. /* no error if passing here */
  1006. /* movl $0x4c00,%eax
  1007. int $0x21 */
  1008. ret
  1009. .data
  1010. /* .comm U_SYSTEM_ENVP,4 */
  1011. .globl _ScreenPrimary
  1012. _ScreenPrimary:
  1013. .long 0
  1014. .globl _argc
  1015. _argc:
  1016. .long 0
  1017. .globl _args
  1018. _args:
  1019. .long 0
  1020. .globl _run_mode
  1021. _run_mode:
  1022. .word 4
  1023. .globl _core_selector
  1024. _core_selector:
  1025. .word 0
  1026. /* Here Pierre Muller added all what was in crt1.c */
  1027. /* in assembler */
  1028. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  1029. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  1030. /* adapted to assembler for FPK by Pierre Muller */
  1031. /* Global variables */
  1032. /* This gets incremented each time the program is started.
  1033. Programs (such as Emacs) which dump their code to create
  1034. a new executable, cause this to be larger than 2. Library
  1035. functions that cache info in static variables should check
  1036. the value of `__bss_count' if they need to reinitialize
  1037. the static storage. */
  1038. .data
  1039. .globl ___bss_count
  1040. ___bs_count:
  1041. .long 1
  1042. .globl __crt0_startup_flags
  1043. __crt0_startup_flags:
  1044. .long 0
  1045. .globl __dos_ds
  1046. __dos_ds:
  1047. .long 0
  1048. /*
  1049. $Log$
  1050. Revision 1.2 1998-05-22 00:39:38 peter
  1051. * go32v1, go32v2 recompiles with the new objects
  1052. * remake3 works again with go32v2
  1053. - removed some "optimizes" from daniel which were wrong
  1054. */