prt0.asm 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. ; nasm -f obj -o prt0.o prt0.asm
  2. cpu 8086
  3. segment text use16
  4. extern PASCALMAIN
  5. extern dos_psp
  6. extern _edata ; defined by WLINK, indicates start of BSS
  7. extern _end ; defined by WLINK, indicates end of BSS
  8. extern __stklen
  9. extern __stkbottom
  10. extern __nearheap_start
  11. extern __nearheap_end
  12. ..start:
  13. ; init the stack
  14. mov bx, dgroup
  15. mov ss, bx
  16. mov sp, stacktop
  17. ; zero fill the BSS section
  18. mov es, bx
  19. mov di, _edata wrt dgroup
  20. mov cx, _end wrt dgroup
  21. sub cx, di
  22. jz no_bss
  23. xor al, al
  24. rep stosb
  25. no_bss:
  26. ; save the Program Segment Prefix
  27. push ds
  28. ; init DS
  29. mov ds, bx
  30. ; pop the PSP from stack and store it in the pascal variable dos_psp
  31. pop ax
  32. mov word [dos_psp], ax
  33. ; allocate max heap
  34. ; TODO: also support user specified heap size
  35. ; try to resize our main DOS memory block until the end of the data segment
  36. mov bx, word [dos_psp]
  37. mov es, bx
  38. sub bx, dgroup
  39. neg bx ; bx = (ds - psp) in paragraphs
  40. add bx, 1000h ; 64kb in paragraphs
  41. mov ah, 4Ah
  42. int 21h
  43. jc mem_realloc_err
  44. ; bx = the new size in paragraphs
  45. add bx, word [dos_psp]
  46. sub bx, dgroup
  47. mov cl, 4
  48. shl bx, cl
  49. sub bx, 2
  50. mov sp, bx
  51. add bx, 2
  52. sub bx, word [__stklen]
  53. and bl, 0FEh
  54. mov word [__stkbottom], bx
  55. cmp bx, _end wrt dgroup
  56. jb not_enough_mem
  57. ; heap is between [ds:_end wrt dgroup] and [ds:__stkbottom - 1]
  58. mov word [__nearheap_start], _end wrt dgroup
  59. mov bx, word [__stkbottom]
  60. dec bx
  61. mov word [__nearheap_end], bx
  62. jmp PASCALMAIN
  63. not_enough_mem:
  64. mov dx, not_enough_mem_msg
  65. jmp error_msg
  66. mem_realloc_err:
  67. mov dx, mem_realloc_err_msg
  68. error_msg:
  69. mov ah, 9
  70. int 21h
  71. mov ax, 4CFFh
  72. int 21h
  73. global FPC_MSDOS_CARRY
  74. FPC_MSDOS_CARRY:
  75. stc
  76. global FPC_MSDOS
  77. FPC_MSDOS:
  78. mov al, 21h ; not ax, because only the low byte is used
  79. pop dx
  80. pop cx
  81. push ax
  82. push cx
  83. push dx
  84. global FPC_INTR
  85. FPC_INTR:
  86. push bp
  87. mov bp, sp
  88. mov al, byte [ss:bp + 6]
  89. mov byte [cs:int_number], al
  90. mov si, [ss:bp + 4]
  91. push ds
  92. mov ax, word [si + 16]
  93. mov es, ax
  94. mov ax, word [si + 14] ; ds
  95. push ax
  96. mov ax, word [si]
  97. mov bx, word [si + 2]
  98. mov cx, word [si + 4]
  99. mov dx, word [si + 6]
  100. mov bp, word [si + 8]
  101. mov di, word [si + 12]
  102. mov si, word [si + 10]
  103. pop ds
  104. db 0CDh ; opcode of INT xx
  105. int_number:
  106. db 255
  107. pushf
  108. push ds
  109. push si
  110. push bp
  111. mov bp, sp
  112. mov si, word [ss:bp + 8]
  113. mov ds, si
  114. mov si, word [ss:bp + 14]
  115. mov word [si], ax
  116. mov word [si + 2], bx
  117. mov word [si + 4], cx
  118. mov word [si + 6], dx
  119. mov word [si + 12], di
  120. mov ax, es
  121. mov word [si + 16], ax
  122. pop ax
  123. mov word [si + 8], ax
  124. pop ax
  125. mov word [si + 10], ax
  126. pop ax
  127. mov word [si + 14], ax
  128. pop ax
  129. mov word [si + 18], ax
  130. pop ds
  131. pop bp
  132. ret 4
  133. segment data
  134. mem_realloc_err_msg:
  135. db 'Memory allocation error', 13, 10, '$'
  136. not_enough_mem_msg:
  137. db 'Not enough memory', 13, 10, '$'
  138. segment bss class=bss
  139. segment stack stack class=stack
  140. resb 256
  141. stacktop:
  142. group dgroup data bss stack