123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- ; nasm -f obj -o prt0.o prt0.asm
- cpu 8086
- segment text use16
- extern PASCALMAIN
- extern dos_psp
- extern dos_version
- extern _edata ; defined by WLINK, indicates start of BSS
- extern _end ; defined by WLINK, indicates end of BSS
- extern __stklen
- extern __stkbottom
- extern __nearheap_start
- extern __nearheap_end
- ..start:
- ; init the stack
- mov bx, dgroup
- mov ss, bx
- mov sp, stacktop
- ; zero fill the BSS section
- mov es, bx
- mov di, _edata wrt dgroup
- mov cx, _end wrt dgroup
- sub cx, di
- jz no_bss
- xor al, al
- rep stosb
- no_bss:
- ; save the Program Segment Prefix
- push ds
- ; init DS
- mov ds, bx
- ; pop the PSP from stack and store it in the pascal variable dos_psp
- pop ax
- mov word [dos_psp], ax
- ; get DOS version and save it in the pascal variable dos_version
- mov ax, 3000h
- int 21h
- xchg al, ah
- mov word [dos_version], ax
- ; allocate max heap
- ; TODO: also support user specified heap size
- ; try to resize our main DOS memory block until the end of the data segment
- mov bx, word [dos_psp]
- mov es, bx
- sub bx, dgroup
- neg bx ; bx = (ds - psp) in paragraphs
- add bx, 1000h ; 64kb in paragraphs
- mov ah, 4Ah
- int 21h
- jc mem_realloc_err
- ; bx = the new size in paragraphs
- add bx, word [dos_psp]
- sub bx, dgroup
- mov cl, 4
- shl bx, cl
- sub bx, 2
- mov sp, bx
- add bx, 2
- sub bx, word [__stklen]
- and bl, 0FEh
- mov word [__stkbottom], bx
- cmp bx, _end wrt dgroup
- jb not_enough_mem
- ; heap is between [ds:_end wrt dgroup] and [ds:__stkbottom - 1]
- mov word [__nearheap_start], _end wrt dgroup
- mov bx, word [__stkbottom]
- dec bx
- mov word [__nearheap_end], bx
- jmp PASCALMAIN
- not_enough_mem:
- mov dx, not_enough_mem_msg
- jmp error_msg
- mem_realloc_err:
- mov dx, mem_realloc_err_msg
- error_msg:
- mov ah, 9
- int 21h
- mov ax, 4CFFh
- int 21h
- global FPC_MSDOS_CARRY
- FPC_MSDOS_CARRY:
- stc
- global FPC_MSDOS
- FPC_MSDOS:
- mov al, 21h ; not ax, because only the low byte is used
- pop dx
- pop cx
- push ax
- push cx
- push dx
- global FPC_INTR
- FPC_INTR:
- push bp
- mov bp, sp
- mov al, byte [ss:bp + 6]
- mov byte [cs:int_number], al
- mov si, [ss:bp + 4]
- push ds
- mov ax, word [si + 16]
- mov es, ax
- mov ax, word [si + 14] ; ds
- push ax
- mov ax, word [si]
- mov bx, word [si + 2]
- mov cx, word [si + 4]
- mov dx, word [si + 6]
- mov bp, word [si + 8]
- mov di, word [si + 12]
- mov si, word [si + 10]
-
- pop ds
- db 0CDh ; opcode of INT xx
- int_number:
- db 255
-
- pushf
- push ds
- push si
- push bp
- mov bp, sp
- mov si, word [ss:bp + 8]
- mov ds, si
- mov si, word [ss:bp + 14]
- mov word [si], ax
- mov word [si + 2], bx
- mov word [si + 4], cx
- mov word [si + 6], dx
- mov word [si + 12], di
- mov ax, es
- mov word [si + 16], ax
- pop ax
- mov word [si + 8], ax
- pop ax
- mov word [si + 10], ax
- pop ax
- mov word [si + 14], ax
- pop ax
- mov word [si + 18], ax
-
- pop ds
- pop bp
- ret 4
- segment data
- mem_realloc_err_msg:
- db 'Memory allocation error', 13, 10, '$'
- not_enough_mem_msg:
- db 'Not enough memory', 13, 10, '$'
- segment bss class=bss
- segment stack stack class=stack
- resb 256
- stacktop:
- group dgroup data bss stack
|