v2prt0.as 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206
  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. /* special exit from dpmiexcp.c */
  313. .global __exit
  314. __exit:
  315. movb 4(%esp), %al
  316. exit:
  317. movb %al, %cl
  318. xorl %eax,%eax
  319. movw %ax,%fs
  320. movw %ax,%gs
  321. cmpl $0,_exception_exit
  322. jz no_exception
  323. pushl %ecx
  324. call *_exception_exit
  325. popl %ecx
  326. no_exception:
  327. cli /* Just in case they didn't unhook ints */
  328. FREESEL U_SYSTEM_GO32_INFO_BLOCK+26 /* selector for linear memory */
  329. FREESEL ___v2prt0_ds_alias /* DS alias for rmcb exceptions */
  330. .ifdef MULTIBLOCK
  331. testb $0x8, __crt0_startup_flags+1 /* include/crt0.h */
  332. jz 9f
  333. .endif
  334. FREESEL sbrk16_api_seg /* sbrk cs */
  335. movw sbrk16_first_byte+6,%dx /* selector for allocated DOS mem */
  336. movw $0x101, %ax
  337. int $0x31 /* Free block and selector */
  338. 9:
  339. movl __stubinfo, %edx
  340. movl STUBINFO_CS_SELECTOR(%edx), %eax
  341. movw %ax, sbrk16_api_seg
  342. xorl %edi, %edi
  343. movl %edi, sbrk16_api_ofs /* Offset is zero */
  344. movw STUBINFO_DS_SELECTOR(%edx), %es
  345. movb %cl, %dl /* Exit status */
  346. movl $exit16_first_byte, %esi
  347. movl $(exit16_last_byte - exit16_first_byte), %ecx
  348. cld
  349. rep
  350. movsb
  351. movw %es,%ax /* We will free stack! */
  352. movw %ax,%ss
  353. movl $0x400,%esp /* Transfer buffer >= 1024 bytes */
  354. .ifdef MULTIBLOCK
  355. movl ___djgpp_memory_handle_pointer, %ebx
  356. jmp 7f
  357. 6: subl $8, %ebx
  358. movl (%ebx), %edi
  359. movw 2(%ebx), %si
  360. movw $0x502, %ax
  361. int $0x31
  362. 7: cmpl $___djgpp_memory_handle_list+8, %ebx
  363. jne 6b
  364. .endif /* MULTIBLOCK */
  365. xorl %ebp, %ebp /* V1.10 bug fix */
  366. movl ___djgpp_memory_handle_list, %edi
  367. movl ___djgpp_memory_handle_list+2, %esi /* Skip word prefixes */
  368. FREESEL %ds
  369. movw %cs, %bx
  370. /* Call exit procedure with BX=32-bit CS; SI+DI=32-bit handle; DL=exit status */
  371. .byte 0x2e
  372. ljmp sbrk16_api_ofs
  373. /*-----------------------------------------------------------------------------*/
  374. /* .lcomm __what_size_app_thinks_it_is, 4 */
  375. __what_size_app_thinks_it_is:
  376. .long end
  377. .lcomm __what_we_return_to_app_as_old_size, 4
  378. .lcomm __what_size_dpmi_thinks_we_are, 4
  379. lock_memory:
  380. /* BX:CX should be linear address; size is pushed on stack */
  381. testb $0x10, __crt0_startup_flags+1 /* include/crt0.h */
  382. jz 13f
  383. pushl %esi
  384. pushl %edi
  385. pushl %eax
  386. movl 16(%esp),%edi
  387. movw 18(%esp),%si
  388. movw $0x600,%ax
  389. int $0x31
  390. popl %eax
  391. popl %edi
  392. popl %esi
  393. 13: ret $4 /* Pop the argument */
  394. .if 0
  395. brk_hook_ret:
  396. ret
  397. .globl ___sbrk_brk_hook
  398. ___sbrk_brk_hook:
  399. .long brk_hook_ret
  400. .endif
  401. .global ___sbrk
  402. .align 2
  403. ___sbrk:
  404. movl __what_size_app_thinks_it_is, %eax
  405. movl 4(%esp), %ecx /* Increment size */
  406. addl %ecx, %eax
  407. jnc brk_common
  408. /* Carry is only set if a negative increment or wrap happens. Negative
  409. increment is semi-OK, wrap (only for multiple zone sbrk) isn't. */
  410. test $0x80000000, %ecx /* Clears carry */
  411. jnz brk_common
  412. stc /* Put carry back */
  413. jmp brk_common
  414. .globl ___brk
  415. .align 2
  416. ___brk:
  417. movl 4(%esp), %eax
  418. clc
  419. brk_common:
  420. pushl %esi
  421. pushl %edi
  422. pushl %ebx
  423. movl __what_size_app_thinks_it_is, %edx /* save info */
  424. movl %edx, __what_we_return_to_app_as_old_size
  425. movl %eax, __what_size_app_thinks_it_is
  426. jc 10f /* Wrap for multi-zone */
  427. cmpl __what_size_dpmi_thinks_we_are, %eax /* don't bother shrinking */
  428. jbe brk_nochange
  429. .ifdef MULTIBLOCK
  430. testb $0x8, __crt0_startup_flags+1 /* include/crt0.h */
  431. jz 10f
  432. .endif
  433. addl $0x0000ffff, %eax /* round up to 64K block */
  434. andl $0xffff0000, %eax
  435. push %eax /* size - save for later */
  436. movl ___djgpp_memory_handle_list, %edi /* request new size */
  437. movw ___djgpp_memory_handle_list+2, %si
  438. movl %eax, %ecx /* size not limit */
  439. movl %eax, %ebx /* size not limit */
  440. shrl $16, %ebx /* BX:CX size */
  441. movw $0x0900, %ax /* disable interrupts */
  442. int $0x31
  443. pushl %eax
  444. lcall sbrk16_api_ofs
  445. setc %dl /* Save carry */
  446. popl %eax /* restore interrupts */
  447. int $0x31
  448. test %dl,%dl
  449. popl %edx
  450. jne brk_error
  451. movl %edi, ___djgpp_memory_handle_list /* store new handle */
  452. movw %si, ___djgpp_memory_handle_list+2
  453. movl %ecx, ___djgpp_base_address /* store new base address */
  454. movw %bx, ___djgpp_base_address+2
  455. movl %edx, %eax
  456. movl __what_size_dpmi_thinks_we_are, %ecx
  457. subl %ecx, %eax
  458. addl ___djgpp_base_address, %ecx
  459. movl %ecx, %ebx
  460. shrl $16, %ebx /* BX:CX addr */
  461. pushl %eax /* Size */
  462. call lock_memory
  463. decl %edx /* limit now, not size */
  464. .ifdef MULTIBLOCK
  465. jmp 5f
  466. /* Current allocation not large enough, get another block */
  467. 10: movl %ecx, %eax /* Add amt */
  468. pushl %eax /* Save orig */
  469. addl $0x0000ffff, %eax /* round up to 64K block */
  470. andl $0xffff0000, %eax
  471. movl %eax, %edx /* Save size */
  472. movl %eax, %ecx
  473. movl %eax, %ebx
  474. shrl $16, %ebx /* BX:CX size */
  475. movw $0x501,%ax
  476. int $0x31
  477. popl %eax /* Orig size */
  478. jc brk_error
  479. pushl %edx /* Size */
  480. call lock_memory
  481. pushw %bx
  482. pushw %cx
  483. popl %ecx /* Linear address */
  484. /* What if the new base address is lower than __djgpp_base_address !!! */
  485. subl ___djgpp_base_address, %ecx /* New dpmi size */
  486. cmpl %ecx, __what_size_dpmi_thinks_we_are /* Back to back ? */
  487. je 4f
  488. movl %ecx, __what_size_dpmi_thinks_we_are
  489. movl %ecx, __what_we_return_to_app_as_old_size
  490. 4:
  491. movl __what_we_return_to_app_as_old_size, %ebx /* Base for new block */
  492. addl %ebx, %eax /* Final address */
  493. movl %eax, __what_size_app_thinks_it_is
  494. /* Note - save adjusted memory base and memory handle SI:DI here */
  495. movl ___djgpp_memory_handle_pointer, %ebx
  496. movl %edi, (%ebx)
  497. movw %si, 2(%ebx)
  498. movl %ecx, 4(%ebx)
  499. addl $8, %ebx
  500. cmpl $___djgpp_memory_handle_list+2040, %ebx /* At end? */
  501. je 11f
  502. movl %ebx, ___djgpp_memory_handle_pointer /* Only if not at end */
  503. 11:
  504. addl %ecx, %edx /* Final address */
  505. decl %edx /* Limit to end */
  506. /* If we get a block at a lower address we must skip the limit change */
  507. cmpl ___djgpp_selector_limit, %edx
  508. jbe 12f
  509. .endif
  510. 5: movl %edx, ___djgpp_selector_limit
  511. orw $0x0fff, %dx /* low bits set */
  512. movw $0x0008, %ax /* reset CS limit */
  513. movw %cs, %bx
  514. movl %edx, %ecx
  515. shrl $16, %ecx
  516. int $0x31 /* CX:DX is limit */
  517. testb $0x80, __crt0_startup_flags /* include/crt0.h */
  518. jnz 3f
  519. movw $0x0008, %ax /* reset DS limit */
  520. movw %ds, %bx
  521. int $0x31
  522. movw $0x0008, %ax /* reset DS alias limit */
  523. movl ___v2prt0_ds_alias, %ebx
  524. int $0x31
  525. 3:
  526. movw $0x0007, %ax /* reset DS alias base */
  527. movl ___v2prt0_ds_alias, %ebx
  528. movl ___djgpp_base_address, %edx
  529. movw ___djgpp_base_address+2, %cx
  530. int $0x31
  531. movl ___djgpp_selector_limit, %edx
  532. 12: incl %edx /* Size not limit */
  533. testb $0x60, __crt0_startup_flags /* include/crt0.h */
  534. jz no_fill_sbrk_memory
  535. pushl %ds
  536. popl %es
  537. movl __what_size_dpmi_thinks_we_are, %edi /* set all newly resized bytes zero */
  538. movl %edx, %ecx /* Limit */
  539. subl %edi, %ecx /* Adjust count for base */
  540. xorl %eax, %eax
  541. testb $0x40, __crt0_startup_flags
  542. jz no_deadbeef
  543. movl $0xdeadbeef, %eax /* something really easy to spot */
  544. no_deadbeef:
  545. shrl $2, %ecx /* div 4 Longwords not bytes */
  546. cld
  547. rep
  548. stosl
  549. no_fill_sbrk_memory:
  550. movl %edx, __what_size_dpmi_thinks_we_are
  551. .if 0 /* No purpose */
  552. pushl ___djgpp_memory_handle_list
  553. pushl ___djgpp_base_address
  554. movl ___sbrk_brk_hook, %eax
  555. call %eax
  556. addl $8, %esp
  557. .endif
  558. brk_nochange: /* successful return */
  559. movl __what_we_return_to_app_as_old_size, %eax
  560. jmp brk_return
  561. brk_error: /* error return */
  562. movl __what_we_return_to_app_as_old_size, %eax
  563. movl %eax, __what_size_app_thinks_it_is
  564. movl $-1, %eax
  565. brk_return:
  566. popl %ebx
  567. popl %edi
  568. popl %esi
  569. ret
  570. .globl __crt0_init_mcount
  571. __crt0_init_mcount:
  572. .ifdef IN_GCRT0
  573. jmp __mcount_init
  574. .else
  575. ret
  576. .endif
  577. /* From here on this are parts of crt1.c converted to assembler
  578. and without any call to libc, so that it works without anything else
  579. additions made by Pierre Muller*/
  580. /* from dpmidefs.h * /
  581. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  582. /* from include <libc/asmdefs.h> */
  583. /* all macros removed here */
  584. /* #define FUNC(x) .globl x; x: */
  585. /* #define ENTER pushl %ebp; movl %esp,%ebp */
  586. /* #define LEAVE(x) movl %ebp,%esp; popl %ebp; ret $(x) */
  587. /* #define ARG1 8(%ebp)
  588. #define ARG1h 10(%ebp)
  589. #define ARG2 12(%ebp)
  590. #define ARG2h 14(%ebp)
  591. #define ARG3 16(%ebp)
  592. #define ARG4 20(%ebp)
  593. #define ARG5 24(%ebp)
  594. #define ARG6 28(%ebp)
  595. #define ARG7 32(%ebp)
  596. #define ARG8 36(%ebp) */
  597. .comm ___dpmi_error,2
  598. /* from dpmi0000.s */
  599. /* .globl ___dpmi_allocate_ldt_descriptors */
  600. /* using pascal convention => not usabel by C code */
  601. ___dpmi_allocate_ldt_descriptors:
  602. pushl %ebp; movl %esp,%ebp
  603. movl 8(%ebp), %ecx
  604. movl $0x0000, %eax
  605. int $0x31
  606. jnc .L_noerror0000
  607. movw %ax,___dpmi_error
  608. movl $-1,%eax
  609. jmp .L_leave0000
  610. .L_noerror0000:
  611. movzwl %ax,%eax
  612. .L_leave0000:
  613. movl %ebp,%esp
  614. popl %ebp
  615. ret $4
  616. /* from file dpmi0008.s */
  617. /* .globl ___dpmi_set_segment_limit */
  618. ___dpmi_set_segment_limit:
  619. pushl %ebp; movl %esp,%ebp
  620. movl 8(%ebp), %ebx
  621. movzwl 12(%ebp), %edx
  622. movzwl 14(%ebp),%ecx
  623. movl $0x0008,%eax
  624. int $0x31
  625. jnc .L_noerror0008
  626. movw %ax,___dpmi_error
  627. movl $-1,%eax
  628. jmp .L_leave0008
  629. .L_noerror0008:
  630. xorl %eax,%eax
  631. .L_leave0008:
  632. movl %ebp,%esp
  633. popl %ebp
  634. ret $8
  635. /* .globl ___dpmi_get_version */
  636. ___dpmi_get_version:
  637. pushl %ebp; movl %esp,%ebp
  638. movl $0x0400,%eax
  639. int $0x31
  640. jnc .L_noerror0400
  641. movw %ax,___dpmi_error
  642. movl $-1,%eax
  643. jmp .L_leave0400
  644. .L_noerror0400:
  645. movl 8(%ebp), %esi
  646. movb %ah, (%esi)
  647. movb %al, 1(%esi)
  648. movw %bx, 2(%esi)
  649. movb %cl, 4(%esi)
  650. movb %dh, 5(%esi)
  651. movb %dl, 6(%esi)
  652. xorl %eax,%eax
  653. .L_leave0400:
  654. movl %ebp,%esp
  655. popl %ebp
  656. ret $4
  657. /* .globl ___dpmi_get_segment_base_address*/
  658. ___dpmi_get_segment_base_address:
  659. pushl %ebp; movl %esp,%ebp
  660. movl 8(%ebp), %ebx
  661. movl $0x0006,%eax
  662. int $0x31
  663. jnc .L_noerror0006
  664. movw %ax,___dpmi_error
  665. movl $-1,%eax
  666. jmp .L_leave0006
  667. .L_noerror0006:
  668. movl 12(%ebp), %ebx
  669. movl %edx, (%ebx)
  670. movw %cx, 2(%ebx)
  671. xorl %eax,%eax
  672. .L_leave0006:
  673. movl %ebp,%esp
  674. popl %ebp
  675. ret $8
  676. .globl ___bss_count
  677. .data
  678. .align 2
  679. ___bss_count:
  680. .long 1
  681. .text
  682. .align 2
  683. .globl _setup_core_selector
  684. _setup_core_selector:
  685. pushl %ebp
  686. movl %esp,%ebp
  687. pushl $1
  688. call ___dpmi_allocate_ldt_descriptors
  689. /* addl $4,%esp */
  690. cmpl $-1,%eax
  691. jne .L24
  692. movw $0,U_SYSTEM_GO32_INFO_BLOCK+26
  693. leave
  694. ret
  695. .align 2,0x90
  696. .L24:
  697. movw %ax,U_SYSTEM_GO32_INFO_BLOCK+26
  698. movw %ax,_core_selector
  699. pushl $0x10ffff
  700. andl $0xffff,%eax
  701. pushl %eax
  702. call ___dpmi_set_segment_limit
  703. leave
  704. ret
  705. .align 2
  706. .globl _setup_screens
  707. _setup_screens:
  708. pushl %ebp
  709. movl %esp,%ebp
  710. movw U_SYSTEM_GO32_INFO_BLOCK+26,%dx
  711. movl $1048563,%ecx
  712. /APP
  713. movw %dx, %gs
  714. .byte 0x65
  715. movw (%ecx),%ax
  716. /NO_APP
  717. cmpw $64896,%ax
  718. jne .L26
  719. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+8
  720. movl $655360,U_SYSTEM_GO32_INFO_BLOCK+4
  721. leave
  722. ret
  723. .align 2,0x90
  724. .L26:
  725. movl $1097,%ecx
  726. /APP
  727. movw %dx,%gs
  728. .byte 0x65
  729. movb (%ecx),%al
  730. /NO_APP
  731. cmpb $7,%al
  732. jne .L29
  733. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+4
  734. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+8
  735. leave
  736. ret
  737. .align 2,0x90
  738. .L29:
  739. movl $753664,U_SYSTEM_GO32_INFO_BLOCK+4
  740. movl $720896,U_SYSTEM_GO32_INFO_BLOCK+8
  741. leave
  742. ret
  743. .align 2
  744. .globl _setup_go32_info_block
  745. _setup_go32_info_block:
  746. pushl %ebp
  747. movl %esp,%ebp
  748. subl $8,%esp
  749. leal -8(%ebp),%eax
  750. pushl %eax
  751. call ___dpmi_get_version
  752. movl $40,U_SYSTEM_GO32_INFO_BLOCK
  753. movl __stubinfo,%edx
  754. movzwl 36(%edx),%eax
  755. sall $4,%eax
  756. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  757. movzwl 32(%edx),%ecx
  758. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+16
  759. movzwl 38(%edx),%ecx
  760. movl %ecx,U_SYSTEM_GO32_INFO_BLOCK+20
  761. movb -3(%ebp),%al
  762. movb %al,U_SYSTEM_GO32_INFO_BLOCK+24
  763. movb -2(%ebp),%al
  764. movb %al,U_SYSTEM_GO32_INFO_BLOCK+25
  765. movl $-1,U_SYSTEM_GO32_INFO_BLOCK+28
  766. pushl $U_SYSTEM_GO32_INFO_BLOCK+32
  767. movzwl 38(%edx),%eax
  768. pushl %eax
  769. call ___dpmi_get_segment_base_address
  770. movw $4,U_SYSTEM_GO32_INFO_BLOCK+36
  771. movb -8(%ebp),%dl
  772. salw $8,%dx
  773. movzbw -7(%ebp),%ax
  774. orw %ax,%dx
  775. movw %dx,U_SYSTEM_GO32_INFO_BLOCK+38
  776. call copy_to_c_go32_info_block
  777. leave
  778. ret
  779. copy_to_c_go32_info_block:
  780. leal U_SYSTEM_GO32_INFO_BLOCK,%esi
  781. leal __go32_info_block,%edi
  782. movl $10,%ecx
  783. rep
  784. movsl
  785. ret
  786. .data
  787. /* __go32_info_block for C programs */
  788. .align 2
  789. .globl __go32_info_block
  790. .comm __go32_info_block,40
  791. .globl ___PROXY
  792. ___PROXY:
  793. .ascii " !proxy\0"
  794. .globl ___PROXY_LEN
  795. .align 2
  796. ___PROXY_LEN:
  797. .long 7
  798. .text
  799. .align 2
  800. .globl ___prt1_startup
  801. ___prt1_startup:
  802. pushl %ebp
  803. movl %esp,%ebp
  804. pushl %ebx
  805. incl ___bss_count
  806. movl $0,___crt0_argv
  807. call _setup_core_selector
  808. call _setup_screens
  809. call _setup_go32_info_block
  810. /* call ___djgpp_exception_setup
  811. call _setup_ENVPment */
  812. incl ___environ_changed
  813. /* pushl $0
  814. call __use_lfn
  815. addl $4,%esp
  816. call ___crt0_setup_arguments
  817. movl ___crt0_argv,%eax
  818. testl %eax,%eax
  819. je .L55
  820. movl (%eax),%ebx
  821. jmp .L56
  822. .align 2,0x90
  823. .L55:
  824. movl U_SYSTEM_DOS_ARGV0,%ebx
  825. .L56:
  826. pushl %ebx
  827. call ___crt0_load_ENVPment_file
  828. pushl $0
  829. call __use_lfn
  830. pushl %ebx
  831. call __npxsetup
  832. call __crt0_init_mcount
  833. call ___main */
  834. pushl U_SYSTEM_ENVP
  835. pushl ___crt0_argv
  836. pushl ___crt0_argc
  837. call _pascal_start
  838. pushl %eax
  839. /* call _exit changed to */
  840. call exit
  841. .align 2,0x90
  842. /* .comm U_SYSTEM_DOS_ARGV0,4 */
  843. .comm ___dos_argv0,4
  844. .comm ___crt0_argc,4
  845. .comm ___crt0_argv,4
  846. .globl ___environ_changed
  847. ___environ_changed:
  848. .long 0
  849. .globl _exception_exit
  850. _exception_exit:
  851. .long 0
  852. .globl _swap_in
  853. _swap_in:
  854. .long 0
  855. .globl _swap_out
  856. _swap_out:
  857. .long 0
  858. .global _v2prt0_exceptions_on
  859. _v2prt0_exceptions_on:
  860. .long 0
  861. /*.comm __crt0_startup_flags,4
  862. .comm U_SYSTEM_ENVP,4 */
  863. .ifdef test_go32v1
  864. #
  865. # Called as start(argc, argv, envp)
  866. #
  867. # gs:edx points to prog_info structure. All other registers are OBSOLETE
  868. # but included for backwards compatibility
  869. #
  870. .text
  871. .globl old_start
  872. old_start:
  873. popl %ebx
  874. popl %eax
  875. movl %eax,__hard_master
  876. movl %esi,___pid
  877. movl %edi,___transfer_buffer
  878. movl %ebx,_ScreenPrimary
  879. movl %ebp,_ScreenSecondary
  880. cmpl $0, %edx
  881. je Lcopy_none
  882. movw %gs,%cx
  883. movw %ds,%ax
  884. cmpw %cx,%ax
  885. je Lcopy_none
  886. movl %gs:(%edx), %ecx
  887. cmpl U_SYSTEM_GO32_INFO_BLOCK, %ecx
  888. jbe Lcopy_less
  889. movl U_SYSTEM_GO32_INFO_BLOCK, %ecx
  890. Lcopy_less:
  891. movl $U_SYSTEM_GO32_INFO_BLOCK, %edi
  892. addl $3, %ecx
  893. andl $0xfffffffc, %ecx
  894. movl %ecx, (%edi)
  895. addl $4, %edi
  896. addl $4, %edx
  897. subl $4, %ecx
  898. Lcopy_more:
  899. movl %gs:(%edx), %eax
  900. movl %eax, (%edi)
  901. addl $4, %edx
  902. addl $4, %edi
  903. subl $4, %ecx
  904. jnz Lcopy_more
  905. movl U_SYSTEM_GO32_INFO_BLOCK+4, %eax
  906. movl %eax, _ScreenPrimary
  907. movl U_SYSTEM_GO32_INFO_BLOCK+8, %eax
  908. movl %eax, _ScreenSecondary
  909. movl U_SYSTEM_GO32_INFO_BLOCK+12, %eax
  910. movl %eax, ___transfer_buffer
  911. movl U_SYSTEM_GO32_INFO_BLOCK+20, %eax
  912. movl %eax, ___pid
  913. movl U_SYSTEM_GO32_INFO_BLOCK+24, %eax
  914. movl %eax, __hard_master
  915. jmp Lcopy_done
  916. Lcopy_none:
  917. movl %ebx,U_SYSTEM_GO32_INFO_BLOCK+4
  918. movl %ebp,U_SYSTEM_GO32_INFO_BLOCK+8
  919. movl %edi,U_SYSTEM_GO32_INFO_BLOCK+12
  920. movl $4096,U_SYSTEM_GO32_INFO_BLOCK+16
  921. movl %esi,U_SYSTEM_GO32_INFO_BLOCK+20
  922. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+24
  923. movl $28, U_SYSTEM_GO32_INFO_BLOCK
  924. Lcopy_done:
  925. movw U_SYSTEM_GO32_INFO_BLOCK+36,%ax
  926. movw %ax,_run_mode
  927. cmpw $4,%ax
  928. jne CanOnlyRunDPMI
  929. call Correct_tbaddress
  930. LtbaddressOK:
  931. movw U_SYSTEM_GO32_INFO_BLOCK+26,%ax
  932. movw %ax,_core_selector
  933. /* core selector in %fs */
  934. movw %ax,%fs
  935. xorl %esi,%esi
  936. xorl %edi,%edi
  937. xorl %ebp,%ebp
  938. xorl %ebx,%ebx
  939. movl %esp,%ebx
  940. movl $0x0,%ebp
  941. movl %esp,%ebx
  942. movl 8(%ebx),%eax
  943. movl %eax,U_SYSTEM_ENVP
  944. movl 4(%ebx),%eax
  945. movl %eax,_args
  946. movl (%ebx),%eax
  947. movl %eax,_argc
  948. call PASCALMAIN
  949. exit_again:
  950. movl $0x4c00,%eax
  951. int $0x21
  952. jmp exit_again
  953. ret
  954. Correct_tbaddress:
  955. movl ___transfer_buffer,%eax
  956. addl $1,%eax
  957. andl $0xFFFFF,%eax
  958. movl %eax,___transfer_buffer
  959. movl %eax,U_SYSTEM_GO32_INFO_BLOCK+12
  960. ret
  961. CanOnlyRunDPMI:
  962. movl $0x4c01,%eax
  963. int $0x21
  964. jmp exit_again
  965. .ascii "Can only run in DPMI "
  966. /* .data
  967. .globl _argc
  968. _argc:
  969. .long 0
  970. .globl _args
  971. _args:
  972. .long 0
  973. .globl _run_mode
  974. _run_mode:
  975. .word 0
  976. .globl _core_selector
  977. _core_selector:
  978. .word 0
  979. .globl _ENVP
  980. _ENVP:
  981. .long 0 */
  982. .globl ___pid
  983. ___pid:
  984. .long 42
  985. .globl ___transfer_buffer
  986. ___transfer_buffer:
  987. .long 0
  988. .globl _ScreenSecondary
  989. _ScreenSecondary:
  990. .long 0
  991. .globl __hard_master
  992. .globl __hard_slave
  993. .globl __core_select
  994. __hard_master:
  995. .byte 0
  996. __hard_slave:
  997. .byte 0
  998. .endif /* test_go32v1 */
  999. /* this was the prt0.s from the go32v1 version */
  1000. //
  1001. // call as start(argc, argv, envp) (C-calling convention)
  1002. //
  1003. .globl _pascal_start
  1004. _pascal_start:
  1005. /* %ebx doesn't contain ScreenPrimary */
  1006. movl U_SYSTEM_GO32_INFO_BLOCK+4,%ebx
  1007. movl %ebx,_ScreenPrimary
  1008. /* core selector in %fs */
  1009. movw _core_selector,%ax
  1010. movw %ax,%fs
  1011. // Top of frame
  1012. movl $0x0,%ebp
  1013. movl %esp,%ebx
  1014. movl 12(%ebx),%eax
  1015. movl %eax,U_SYSTEM_ENVP
  1016. movl %eax,_environ
  1017. movl 8(%ebx),%eax
  1018. movl %eax,_args
  1019. movl 4(%ebx),%eax
  1020. movl %eax,_argc
  1021. call PASCALMAIN
  1022. movl $0,%eax
  1023. /* no error if passing here */
  1024. /* movl $0x4c00,%eax
  1025. int $0x21 */
  1026. ret
  1027. .data
  1028. /* .comm U_SYSTEM_ENVP,4 */
  1029. .globl _ScreenPrimary
  1030. _ScreenPrimary:
  1031. .long 0
  1032. .globl _argc
  1033. _argc:
  1034. .long 0
  1035. .globl _args
  1036. _args:
  1037. .long 0
  1038. .globl _run_mode
  1039. _run_mode:
  1040. .word 4
  1041. .globl _core_selector
  1042. _core_selector:
  1043. .word 0
  1044. .globl _environ
  1045. _environ:
  1046. .long 0
  1047. /* Here Pierre Muller added all what was in crt1.c */
  1048. /* in assembler */
  1049. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  1050. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  1051. /* adapted to assembler for FPK by Pierre Muller */
  1052. /* Global variables */
  1053. /* This gets incremented each time the program is started.
  1054. Programs (such as Emacs) which dump their code to create
  1055. a new executable, cause this to be larger than 2. Library
  1056. functions that cache info in static variables should check
  1057. the value of `__bss_count' if they need to reinitialize
  1058. the static storage. */
  1059. .data
  1060. .globl ___bss_count
  1061. ___bs_count:
  1062. .long 1
  1063. .globl __crt0_startup_flags
  1064. __crt0_startup_flags:
  1065. .long 0
  1066. .globl __dos_ds
  1067. __dos_ds:
  1068. .long 0
  1069. /*
  1070. $Log$
  1071. Revision 1.3 1998-08-19 10:56:35 pierre
  1072. + added some special code for C interface
  1073. to avoid loading of crt1.o or dpmiexcp.o from the libc.a
  1074. Revision 1.2 1998/05/22 00:39:38 peter
  1075. * go32v1, go32v2 recompiles with the new objects
  1076. * remake3 works again with go32v2
  1077. - removed some "optimizes" from daniel which were wrong
  1078. */