Do enough of the boot stub to produce an EXE header and enter DPMI protected
mode.
This commit is contained in:
parent
3716d49cd9
commit
1e0961c679
|
@ -12,6 +12,130 @@
|
|||
|
||||
.sect .text
|
||||
.use16
|
||||
exe_header:
|
||||
.data2 0x5a4d ! magic number
|
||||
.data2 0 ! number of bytes in last loadable page
|
||||
.data2 exe_text_paras ! size of .exe, in pages
|
||||
.data2 0 ! number of relocation entries
|
||||
.data2 0 ! start of loadable area, in 16-byte paragraphs
|
||||
.data2 exe_ram_paras ! required RAM size, in 16-byte paragraphs
|
||||
.data2 0 ! maximum RAM siz, in 16-byte paragraphse
|
||||
.data2 0 ! initial SS, relative to program
|
||||
.data2 exe_stack ! initial SP
|
||||
.data2 0 ! checksum (ignored)
|
||||
.data2 exe_start ! initial IP
|
||||
.data2 0 ! initial CS, relative to program
|
||||
.data2 0 ! offset of relocation table
|
||||
.data2 0 ! overlay number
|
||||
|
||||
dpmi_edi = 0x00
|
||||
dpmi_esi = 0x04
|
||||
dpmi_ebp = 0x08
|
||||
dpmi_ebx = 0x10
|
||||
dpmi_edx = 0x14
|
||||
dpmi_ecx = 0x18
|
||||
dpmi_eax = 0x1c
|
||||
dpmi_flags = 0x20
|
||||
dpmi_es = 0x22
|
||||
dpmi_ds = 0x24
|
||||
dpmi_fs = 0x26
|
||||
dpmi_gs = 0x28
|
||||
dpmi_ip = 0x2a
|
||||
dpmi_cs = 0x2c
|
||||
dpmi_sp = 0x2e
|
||||
dpmi_ss = 0x30
|
||||
|
||||
dpmi_ps = 0x32 ! WORD: protected register segment
|
||||
dpmi_rs = 0x34 ! WORD: real register segment
|
||||
dpmi_psp = 0x36 ! WORD: PSP segment
|
||||
dpmi_switch = 0x38 ! DWORD: far pointer of pmode switch routine
|
||||
|
||||
.seek 0x3c
|
||||
exe_start:
|
||||
! On entry, DS=ES=PSP. Make DS=CS, so we're running in tiny mode.
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov (dpmi_rs), ds
|
||||
mov (dpmi_psp), es
|
||||
|
||||
! Initialise DPMI.
|
||||
|
||||
mov ax, 0x1687
|
||||
int 0x2f
|
||||
or ax, ax
|
||||
jnz no_dpmi
|
||||
mov (dpmi_switch+0), di ! write back PMODE switch routine
|
||||
mov (dpmi_switch+2), es
|
||||
or si, si ! do we need a DPMI private area?
|
||||
jz 1f
|
||||
|
||||
mov bx, si
|
||||
movb ah, 0x48
|
||||
int 0x21 ! allocate memory from DOS
|
||||
mov es, ax ! data area segment -> es
|
||||
1:
|
||||
! Switch to protected mode.
|
||||
|
||||
mov ax, 1 ! 32-bit app
|
||||
callf (dpmi_switch)
|
||||
jc no_pmode
|
||||
|
||||
mov (dpmi_edx), go_msg
|
||||
mov ax, (dpmi_rs)
|
||||
mov (dpmi_ds), ax
|
||||
mov (dpmi_eax+1), 9
|
||||
call int21
|
||||
mov ax, 0x4c00
|
||||
int 0x21
|
||||
|
||||
! Simulate DOS interrupt bx.
|
||||
int21:
|
||||
mov bx, 0x21
|
||||
callint:
|
||||
xor ax, ax
|
||||
mov (dpmi_ss), ax ! zero stack: DPMI host allocates one.
|
||||
mov (dpmi_sp), ax
|
||||
push ds
|
||||
pop es
|
||||
mov di, ax
|
||||
mov ax, 0x300
|
||||
int 0x31 ! simulate DOS interrupt
|
||||
push cs
|
||||
pop ds
|
||||
ret
|
||||
|
||||
no_pmode: ! Could not switch to protected mode.
|
||||
mov dx, no_pmode_msg
|
||||
jmp exit_with_error
|
||||
|
||||
no_dpmi:
|
||||
mov dx, no_dpmi_msg
|
||||
! fall through
|
||||
|
||||
! Displays the message in dx and exits.
|
||||
exit_with_error:
|
||||
movb ah, 9
|
||||
int 0x21 ! print $-terminated string
|
||||
mov ax, 0x4cff
|
||||
int 0x21 ! terminate with error code al
|
||||
|
||||
.use32
|
||||
start_32bit:
|
||||
|
||||
go_msg:
|
||||
.ascii "Go!$"
|
||||
no_pmode_msg:
|
||||
.ascii "Couldn't switch to protected mode$"
|
||||
no_dpmi_msg:
|
||||
.ascii "No DPMI$"
|
||||
|
||||
exe_top:
|
||||
|
||||
exe_stack = exe_top + 512
|
||||
exe_text_paras = [exe_top - exe_header + 511] / 512
|
||||
exe_ram_paras = [exe_stack - exe_top + 15] / 16
|
||||
|
||||
|
||||
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
||||
|
||||
|
@ -30,8 +154,6 @@ begtext:
|
|||
|
||||
mov dx, bad_sys_msg
|
||||
dos_msg:
|
||||
movb ah, 9
|
||||
int 0x21
|
||||
ret
|
||||
|
||||
ok_sys:
|
||||
|
@ -168,3 +290,6 @@ no_room_msg: .ascii 'No room$'
|
|||
.comm .trppc, 4
|
||||
.comm .ignmask, 4
|
||||
.comm _errno, 4
|
||||
|
||||
! vim: ts=4 sw=4 et ft=asm
|
||||
|
||||
|
|
Loading…
Reference in a new issue