prt0comn.asm 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. ; common startup code for all the memory models
  2. %ifdef __TINY__
  3. %fatal "The tiny memory model is not supported by Windows."
  4. %elifdef __SMALL__
  5. %define __NEAR_CODE__
  6. %define __NEAR_DATA__
  7. %elifdef __MEDIUM__
  8. %define __FAR_CODE__
  9. %define __NEAR_DATA__
  10. %elifdef __COMPACT__
  11. %define __NEAR_CODE__
  12. %define __FAR_DATA__
  13. %elifdef __LARGE__
  14. %define __FAR_CODE__
  15. %define __FAR_DATA__
  16. %elifdef __HUGE__
  17. %define __FAR_CODE__
  18. %define __FAR_DATA__
  19. %else
  20. %fatal "Memory model not defined."
  21. %endif
  22. %ifdef __FAR_CODE__
  23. extra_param_offset equ 2
  24. %else
  25. extra_param_offset equ 0
  26. %endif
  27. %ifdef __FAR_DATA__
  28. extra_data_offset equ 2
  29. %else
  30. extra_data_offset equ 0
  31. %endif
  32. cpu 8086
  33. segment _TEXT use16 class=CODE align=1
  34. extern PASCALMAIN
  35. extern __fpc_PrefixSeg
  36. extern __fpc_CmdLine
  37. extern __fpc_CmdShow
  38. extern __fpc_HInstance
  39. extern __fpc_HPrevInst
  40. extern __fpc_SelectorInc
  41. extern ___stack
  42. extern InitTask
  43. import InitTask KERNEL
  44. extern WaitEvent
  45. import WaitEvent KERNEL
  46. extern InitApp
  47. import InitApp USER
  48. extern __AHIncr
  49. import __AHIncr KERNEL
  50. ..start: ; Win16 applications start with the following
  51. ; values in registers:
  52. ;
  53. ; AX = zero
  54. ; BX = the size, in bytes, of the stack
  55. ; CX = the size, in bytes, of the heap
  56. ; DI = handle, identifying the new application instance
  57. ; SI = handle, identifying the previous application instance
  58. ; BP = zero
  59. ; ES = segment of the Program Segment Prefix (PSP)
  60. ; DS = segment of the automatic data segment for the application
  61. ; SS = DS
  62. ; SP = offset of the first byte of the application stack
  63. ; call InitTask to initialize the task. Windows expects this to
  64. ; be the first function, called by the application code. On entry,
  65. ; it expects all the startup parameters in registers described above.
  66. call far InitTask
  67. ; InitTask result:
  68. ; AX = 1-success; 0-error
  69. test ax, ax
  70. jz error
  71. ; InitTask result:
  72. ; CX = stack limit, in bytes
  73. ; DI = instance handle for the new task
  74. ; DX = the nCmdShow parameter
  75. ; ES = segment of the Program Segment Prefix (PSP) for the new task
  76. ; ES:BX = the command line
  77. ; SI = instance handle for the previous application instance (if any)
  78. mov ax, es
  79. mov [__fpc_PrefixSeg], ax
  80. mov [__fpc_CmdLine+2], ax
  81. mov [__fpc_CmdLine], bx
  82. mov [__fpc_CmdShow], dx
  83. mov [__fpc_HInstance], di
  84. mov [__fpc_HPrevInst], si
  85. ; the offset of the Win16 kernel function __AHIncr (by definition)
  86. ; gives us the value of SelectorInc. The function __AHIncr is
  87. ; otherwise useless (when called, it increments AH by one :) )
  88. ; The value of SelectorInc is usually 8 in most (all?) win16
  89. ; implementations, but it's good practice not to hardcode it.
  90. mov word [__fpc_SelectorInc], __AHIncr
  91. ; call WaitEvent(0) to clear the event that started this task
  92. ; Windows expects this call immediately after InitTask
  93. xor ax, ax
  94. push ax
  95. call far WaitEvent
  96. ; call InitApp(hInstance) to initialize the queue and support
  97. ; routines for the app. Windows expects this to be the third
  98. ; call in the Win16 startup sequence.
  99. push word [__fpc_HInstance]
  100. call far InitApp
  101. test ax, ax
  102. jz error
  103. %ifdef __FAR_CODE__
  104. call far PASCALMAIN
  105. %else
  106. call PASCALMAIN
  107. %endif
  108. error:
  109. mov ax, 4cffh
  110. int 21h
  111. global FPC_MSDOS_CARRY
  112. FPC_MSDOS_CARRY:
  113. stc
  114. global FPC_MSDOS
  115. FPC_MSDOS:
  116. mov al, 21h ; not ax, because only the low byte is used
  117. pop dx
  118. %ifdef __FAR_CODE__
  119. pop bx
  120. %endif
  121. pop cx
  122. %ifdef __FAR_DATA__
  123. pop si
  124. %endif
  125. push ax
  126. %ifdef __FAR_DATA__
  127. push si
  128. %endif
  129. push cx
  130. %ifdef __FAR_CODE__
  131. push bx
  132. %endif
  133. push dx
  134. ; global FPC_INTR
  135. ;FPC_INTR:
  136. %ifdef __FAR_CODE__
  137. inc bp
  138. %endif
  139. push bp
  140. mov bp, sp
  141. mov al, byte [bp + 6 + extra_param_offset + extra_data_offset]
  142. ; mov byte [cs:int_number], al
  143. mov si, [bp + 4 + extra_param_offset]
  144. push ds
  145. %ifdef __FAR_DATA__
  146. mov ax, [bp + 6 + extra_param_offset]
  147. mov ds, ax
  148. %endif
  149. mov ax, word [si + 16]
  150. mov es, ax
  151. mov ax, word [si + 14] ; ds
  152. push ax
  153. mov ax, word [si]
  154. mov bx, word [si + 2]
  155. mov cx, word [si + 4]
  156. mov dx, word [si + 6]
  157. mov bp, word [si + 8]
  158. mov di, word [si + 12]
  159. mov si, word [si + 10]
  160. pop ds
  161. ; db 0CDh ; opcode of INT xx
  162. ;int_number:
  163. ; db 255
  164. int 21h
  165. pushf
  166. push ds
  167. push si
  168. push bp
  169. mov bp, sp
  170. %ifdef __FAR_DATA__
  171. mov si, [bp + 16 + extra_param_offset]
  172. %else
  173. mov si, word [bp + 8]
  174. %endif
  175. mov ds, si
  176. mov si, word [bp + 14 + extra_param_offset]
  177. mov word [si], ax
  178. mov word [si + 2], bx
  179. mov word [si + 4], cx
  180. mov word [si + 6], dx
  181. mov word [si + 12], di
  182. mov ax, es
  183. mov word [si + 16], ax
  184. pop ax
  185. mov word [si + 8], ax
  186. pop ax
  187. mov word [si + 10], ax
  188. pop ax
  189. mov word [si + 14], ax
  190. pop ax
  191. mov word [si + 18], ax
  192. pop ds
  193. pop bp
  194. %ifdef __FAR_CODE__
  195. dec bp
  196. retf 4 + extra_data_offset
  197. %else
  198. ret 4 + extra_data_offset
  199. %endif
  200. segment _DATA use16 class=DATA align=2
  201. ; the first 16 bytes of the automatic data segment are reserved.
  202. ; they are filled by the InitTask function with these values
  203. dw 0
  204. oOldSP: dw 0
  205. hOldSS: dw 5
  206. pLocalHeap: dw 0
  207. pAtomTable: dw 0
  208. pStackTop: dw 0
  209. pStackMin: dw 0
  210. pStackBot: dw 0
  211. ; end of reserved area, filled by InitTask
  212. segment stack stack class=STACK align=16
  213. group DGROUP _DATA stack