prt0comn.asm 7.3 KB

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