We can now load and run 32-bit protected-mode executables. We have not,
however, set up the data segment.
This commit is contained in:
		
							parent
							
								
									b48b5b13ce
								
							
						
					
					
						commit
						d464606dd6
					
				
					 6 changed files with 60 additions and 145 deletions
				
			
		| 
						 | 
					@ -11,144 +11,12 @@
 | 
				
			||||||
.sect .bss
 | 
					.sect .bss
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.sect .text
 | 
					.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_rs     = 0x32 ! WORD: real segment
 | 
					 | 
				
			||||||
dpmi_psp    = 0x34 ! 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)
 | 
					 | 
				
			||||||
    jnc pmode                   ! Success!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ! 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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pmode:
 | 
					 | 
				
			||||||
    ! We're now in protected mode! Switch our code segment to 32-bit mode.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mov cx, cs
 | 
					 | 
				
			||||||
    lar cx, cx
 | 
					 | 
				
			||||||
    movb cl, ch
 | 
					 | 
				
			||||||
    movb ch, 0xc0
 | 
					 | 
				
			||||||
    mov bx, cs
 | 
					 | 
				
			||||||
    mov ax, 0x0009
 | 
					 | 
				
			||||||
    int 0x31                    ! Make selector 32 bit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .use32
 | 
					 | 
				
			||||||
    o16 mov (dpmi_edx), go_msg
 | 
					 | 
				
			||||||
    o16 mov ax, (dpmi_rs)
 | 
					 | 
				
			||||||
    o16 mov (dpmi_ds), ax
 | 
					 | 
				
			||||||
    movb (dpmi_eax+1), 9
 | 
					 | 
				
			||||||
    call int21
 | 
					 | 
				
			||||||
    o16 mov ax, 0x4c00
 | 
					 | 
				
			||||||
    int 0x21
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ! Simulate DOS interrupt bx.
 | 
					 | 
				
			||||||
int21:
 | 
					 | 
				
			||||||
    o16 mov bx, 0x21
 | 
					 | 
				
			||||||
callint:
 | 
					 | 
				
			||||||
    o16 xor ax, ax
 | 
					 | 
				
			||||||
    o16 mov (dpmi_ss), ax           ! zero stack: DPMI host allocates one.
 | 
					 | 
				
			||||||
    o16 mov (dpmi_sp), ax
 | 
					 | 
				
			||||||
    push ds
 | 
					 | 
				
			||||||
    pop es
 | 
					 | 
				
			||||||
    mov di, ax
 | 
					 | 
				
			||||||
    o16 mov ax, 0x300
 | 
					 | 
				
			||||||
    int 0x31                    ! simulate DOS interrupt
 | 
					 | 
				
			||||||
    push cs
 | 
					 | 
				
			||||||
    pop ds
 | 
					 | 
				
			||||||
    ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 */
 | 
					#define STACK_BUFFER 128 /* number of bytes to leave for stack */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
begtext:
 | 
					begtext:
 | 
				
			||||||
 | 
					    mov eax, 0x4c00
 | 
				
			||||||
 | 
					    int 0x21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ! Make sure we are running under MS-DOS 2 or above.
 | 
					    ! Make sure we are running under MS-DOS 2 or above.
 | 
				
			||||||
    !
 | 
					    !
 | 
				
			||||||
    ! While at it, also remember the actual DOS version, so that we know
 | 
					    ! While at it, also remember the actual DOS version, so that we know
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,32 @@ ackfile {
 | 
				
			||||||
	vars = { plat = "msdos386" }
 | 
						vars = { plat = "msdos386" }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ackfile {
 | 
				
			||||||
 | 
						name = "stub",
 | 
				
			||||||
 | 
						srcs = { "./stub.s" },
 | 
				
			||||||
 | 
						vars = { plat = "msdos386" }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					normalrule {
 | 
				
			||||||
 | 
						name = "stub_aout",
 | 
				
			||||||
 | 
						ins = {
 | 
				
			||||||
 | 
							"util/led+led",
 | 
				
			||||||
 | 
							"+stub"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						outleaves = { "stub.aout" },
 | 
				
			||||||
 | 
						commands = { "%{ins[1]} %{ins[2]} -o %{outs[1]}" }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					normalrule {
 | 
				
			||||||
 | 
						name = "stub_exe",
 | 
				
			||||||
 | 
						ins = {
 | 
				
			||||||
 | 
							"util/amisc+aslod",
 | 
				
			||||||
 | 
							"+stub_aout"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						outleaves = { "stub.exe" },
 | 
				
			||||||
 | 
						commands = { "%{ins[1]} %{ins[2]} %{outs[1]}" }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build_plat_libs {
 | 
					build_plat_libs {
 | 
				
			||||||
	name = "libs",
 | 
						name = "libs",
 | 
				
			||||||
	arch = "i386",
 | 
						arch = "i386",
 | 
				
			||||||
| 
						 | 
					@ -19,6 +45,7 @@ installable {
 | 
				
			||||||
		"+libs",
 | 
							"+libs",
 | 
				
			||||||
        "./include+pkg",
 | 
					        "./include+pkg",
 | 
				
			||||||
		["$(PLATIND)/msdos386/boot.o"] = "+boot",
 | 
							["$(PLATIND)/msdos386/boot.o"] = "+boot",
 | 
				
			||||||
 | 
							["$(PLATIND)/msdos386/stub.exe"] = "+stub_exe",
 | 
				
			||||||
        ["$(PLATIND)/msdos386/libsys.a"] = "./libsys+lib",
 | 
					        ["$(PLATIND)/msdos386/libsys.a"] = "./libsys+lib",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,6 @@ name cv
 | 
				
			||||||
	from .out
 | 
						from .out
 | 
				
			||||||
	to .exe
 | 
						to .exe
 | 
				
			||||||
	program {EM}/bin/aslod
 | 
						program {EM}/bin/aslod
 | 
				
			||||||
	args < >
 | 
						args -p {PLATFORMDIR}/stub.exe < >
 | 
				
			||||||
	outfile msdos386.exe
 | 
						outfile msdos386.exe
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,7 @@ exe_start:
 | 
				
			||||||
    mov bx, (fh)
 | 
					    mov bx, (fh)
 | 
				
			||||||
    mov ax, 0x4200
 | 
					    mov ax, 0x4200
 | 
				
			||||||
    xor cx, cx                  ! high offset
 | 
					    xor cx, cx                  ! high offset
 | 
				
			||||||
    xor dx, dx                  ! low offset
 | 
					    mov dx, text_top            ! low offset
 | 
				
			||||||
    int 0x21                    ! lseek
 | 
					    int 0x21                    ! lseek
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    o32 xor edi, edi            ! destination 32-bit register
 | 
					    o32 xor edi, edi            ! destination 32-bit register
 | 
				
			||||||
| 
						 | 
					@ -194,7 +194,7 @@ exe_start:
 | 
				
			||||||
    o32 mov eax, (pmemhandle)
 | 
					    o32 mov eax, (pmemhandle)
 | 
				
			||||||
    o32 movzx ebx, (rseg)
 | 
					    o32 movzx ebx, (rseg)
 | 
				
			||||||
    push es
 | 
					    push es
 | 
				
			||||||
    push text_top
 | 
					    push 0
 | 
				
			||||||
    retf
 | 
					    retf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bad_dpmi:
 | 
					bad_dpmi:
 | 
				
			||||||
| 
						 | 
					@ -225,12 +225,6 @@ exit_with_error:
 | 
				
			||||||
    mov ax, 0x4cff
 | 
					    mov ax, 0x4cff
 | 
				
			||||||
    int 0x21                    ! terminate with error code al
 | 
					    int 0x21                    ! terminate with error code al
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pmode:
 | 
					 | 
				
			||||||
    .use32
 | 
					 | 
				
			||||||
    mov ax, 0x4c00
 | 
					 | 
				
			||||||
    int 0x21
 | 
					 | 
				
			||||||
    .use16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ! Simulate DOS interrupt.
 | 
					    ! Simulate DOS interrupt.
 | 
				
			||||||
int21:
 | 
					int21:
 | 
				
			||||||
    mov (dpmi_eax), ax
 | 
					    mov (dpmi_eax), ax
 | 
				
			||||||
| 
						 | 
					@ -266,6 +260,7 @@ no_file_msg:
 | 
				
			||||||
    .asciz "Couldn't open .exe"
 | 
					    .asciz "Couldn't open .exe"
 | 
				
			||||||
no_dpmi_msg:
 | 
					no_dpmi_msg:
 | 
				
			||||||
    .asciz "No DPMI host installed"
 | 
					    .asciz "No DPMI host installed"
 | 
				
			||||||
 | 
					.align 2
 | 
				
			||||||
text_top:
 | 
					text_top:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exe_text_pages = [text_top - exe_header + 511] / 512
 | 
					exe_text_pages = [text_top - exe_header + 511] / 512
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
aslod \- ACK simple loader
 | 
					aslod \- ACK simple loader
 | 
				
			||||||
.SH SYNOPSIS
 | 
					.SH SYNOPSIS
 | 
				
			||||||
.B aslod
 | 
					.B aslod
 | 
				
			||||||
[\-h] [\-v] inputfile outputfile
 | 
					[\-h] [\-v] [\-p prefixfile] inputfile outputfile
 | 
				
			||||||
.SH DESCRIPTION
 | 
					.SH DESCRIPTION
 | 
				
			||||||
.I aslod
 | 
					.I aslod
 | 
				
			||||||
converts an absolute ack.out file into a simple binary memory dump.
 | 
					converts an absolute ack.out file into a simple binary memory dump.
 | 
				
			||||||
| 
						 | 
					@ -16,5 +16,8 @@ The file must have all references resolved and be linked to a
 | 
				
			||||||
fixed address. aslod will dump the segments, in order, such
 | 
					fixed address. aslod will dump the segments, in order, such
 | 
				
			||||||
that the first byte of TEXT is at offset 0 in the file
 | 
					that the first byte of TEXT is at offset 0 in the file
 | 
				
			||||||
(regardless of where it is in memory).
 | 
					(regardless of where it is in memory).
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					If a prefix file is specified, this is prepended to the output before writing.
 | 
				
			||||||
 | 
					No changes to the output itself are made.
 | 
				
			||||||
.SH "SEE ALSO"
 | 
					.SH "SEE ALSO"
 | 
				
			||||||
ack.out(5)
 | 
					ack.out(5)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@ struct outsect outsect[S_MAX];
 | 
				
			||||||
char* stringarea;
 | 
					char* stringarea;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char* outputfile = NULL;                /* Name of output file, or NULL */
 | 
					char* outputfile = NULL;                /* Name of output file, or NULL */
 | 
				
			||||||
 | 
					char* prefixfile = NULL;				/* Name of prefix file, or NULL */
 | 
				
			||||||
char* program;                          /* Name of current program: argv[0] */
 | 
					char* program;                          /* Name of current program: argv[0] */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FILE* input;                            /* Input stream */
 | 
					FILE* input;                            /* Input stream */
 | 
				
			||||||
| 
						 | 
					@ -136,6 +137,19 @@ void emits(struct outsect* section, struct outsect* nextsect)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void emitprefixfile(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE* fp = fopen(prefixfile, "rb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!feof(fp))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char buffer[BUFSIZ];
 | 
				
			||||||
 | 
							size_t blocksize = fread(buffer, 1, BUFSIZ, fp);
 | 
				
			||||||
 | 
							writef(buffer, 1, blocksize);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fclose(fp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Macros from modules/src/object/obj.h */
 | 
					/* Macros from modules/src/object/obj.h */
 | 
				
			||||||
#define Xchar(ch)	((ch) & 0377)
 | 
					#define Xchar(ch)	((ch) & 0377)
 | 
				
			||||||
| 
						 | 
					@ -204,6 +218,12 @@ int main(int argc, char* argv[])
 | 
				
			||||||
				verbose = true;
 | 
									verbose = true;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case 'p':
 | 
				
			||||||
 | 
									argv++;
 | 
				
			||||||
 | 
									argc--;
 | 
				
			||||||
 | 
									prefixfile = argv[1];
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
			syntaxerror:
 | 
								syntaxerror:
 | 
				
			||||||
				fatal("syntax error --- try -h for help");
 | 
									fatal("syntax error --- try -h for help");
 | 
				
			||||||
| 
						 | 
					@ -288,6 +308,8 @@ int main(int argc, char* argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* And go! */
 | 
						/* And go! */
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						if (prefixfile)
 | 
				
			||||||
 | 
							emitprefixfile();
 | 
				
			||||||
	emits(&outsect[TEXT], &outsect[ROM]);
 | 
						emits(&outsect[TEXT], &outsect[ROM]);
 | 
				
			||||||
	emits(&outsect[ROM], &outsect[DATA]);
 | 
						emits(&outsect[ROM], &outsect[DATA]);
 | 
				
			||||||
	emits(&outsect[DATA], NULL);
 | 
						emits(&outsect[DATA], NULL);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue