Register arguments can be passed to v86 code
This commit is contained in:
		@@ -11,19 +11,7 @@
 | 
			
		||||
#include "dosfs.h"
 | 
			
		||||
#include "tmpstring.c"
 | 
			
		||||
#include "../interrupt.h"
 | 
			
		||||
 | 
			
		||||
struct __attribute((__packed__)) Int13DiskPacket_t {
 | 
			
		||||
    uint8_t size; // 0x10
 | 
			
		||||
    uint8_t reserved; // 0x00
 | 
			
		||||
    uint16_t blocks;
 | 
			
		||||
    uint32_t transfer_buffer; // 0x2300:0000
 | 
			
		||||
    uint64_t start_block;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct Int13DiskPacket_t v86disk_addr_packet;
 | 
			
		||||
 | 
			
		||||
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
 | 
			
		||||
extern void v86DiskRead();
 | 
			
		||||
#include "../v86defs.h"
 | 
			
		||||
 | 
			
		||||
// all reading at 0x23000 - be careful!
 | 
			
		||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
@@ -32,8 +20,9 @@ uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t
 | 
			
		||||
	v86disk_addr_packet.transfer_buffer =
 | 
			
		||||
		(uintptr_t)buffer & 0x000F |
 | 
			
		||||
		(((uintptr_t)buffer & 0xFFFF0) << 12);
 | 
			
		||||
	union V86Regs_t regs;
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								fault.nasm
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								fault.nasm
									
									
									
									
									
								
							@@ -40,7 +40,7 @@ extern get_key
 | 
			
		||||
extern task_ptr
 | 
			
		||||
extern _enter_v86_internal_no_task
 | 
			
		||||
extern return_prev_task
 | 
			
		||||
extern v86GfxMode
 | 
			
		||||
extern v86VideoInt
 | 
			
		||||
gpf_handler_32:
 | 
			
		||||
push eax
 | 
			
		||||
mov eax, dword [esp+8] ; EIP
 | 
			
		||||
@@ -56,19 +56,23 @@ cmp al, 0x00 ; get key
 | 
			
		||||
jne .s1
 | 
			
		||||
call get_key
 | 
			
		||||
jmp .return_to_offender
 | 
			
		||||
.s1: cmp al, 0x10 ; set video mode
 | 
			
		||||
.s1: cmp al, 0x10 ; video interrupt
 | 
			
		||||
jne .return_to_offender
 | 
			
		||||
add esp, 4
 | 
			
		||||
add dword [esp+0], 2
 | 
			
		||||
; add a new task
 | 
			
		||||
call _gpf_create_return_task
 | 
			
		||||
; now enter v86 mode
 | 
			
		||||
; push args
 | 
			
		||||
mov eax, v86GfxMode
 | 
			
		||||
; get regs from return stack
 | 
			
		||||
mov eax, [esp+12] ; return esp
 | 
			
		||||
mov eax, [eax] ; regs
 | 
			
		||||
push eax ; regs
 | 
			
		||||
mov eax, v86VideoInt
 | 
			
		||||
and eax, 0xffff
 | 
			
		||||
push eax ; ip
 | 
			
		||||
mov eax, v86GfxMode
 | 
			
		||||
shr eax, 16
 | 
			
		||||
mov eax, v86VideoInt
 | 
			
		||||
shr eax, 4
 | 
			
		||||
and eax, 0xf000
 | 
			
		||||
push eax ; cs
 | 
			
		||||
push 0xFF00 ; sp
 | 
			
		||||
push 0x8000 ; ss
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ FARPTR i386LinearToFp(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    unsigned seg, off;
 | 
			
		||||
    off = (uintptr_t) ptr & 0xffff;
 | 
			
		||||
    seg = ((uintptr_t) ptr >> 16);
 | 
			
		||||
    seg = ((uintptr_t) ptr >> 4) & 0xf000;
 | 
			
		||||
    return MK_FP(seg, off);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								kernel.c
									
									
									
									
									
								
							@@ -5,6 +5,7 @@
 | 
			
		||||
#include "interrupt.h"
 | 
			
		||||
#include "tss.h"
 | 
			
		||||
#include "paging.h"
 | 
			
		||||
#include "v86defs.h"
 | 
			
		||||
 | 
			
		||||
typedef unsigned short word;
 | 
			
		||||
 | 
			
		||||
@@ -53,22 +54,6 @@ uint32_t get_cr4() {
 | 
			
		||||
    return reg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct __attribute((__packed__)) Int13DiskPacket_t {
 | 
			
		||||
    uint8_t size; // 0x10
 | 
			
		||||
    uint8_t reserved; // 0x00
 | 
			
		||||
    uint16_t blocks;
 | 
			
		||||
    uint32_t transfer_buffer; // 0x2300:0000
 | 
			
		||||
    uint64_t start_block;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct Int13DiskPacket_t v86disk_addr_packet;
 | 
			
		||||
 | 
			
		||||
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
 | 
			
		||||
extern void v86Test();
 | 
			
		||||
extern void v86TransFlag();
 | 
			
		||||
extern void v86GfxMode();
 | 
			
		||||
extern void v86TextMode();
 | 
			
		||||
extern void v86DiskRead();
 | 
			
		||||
extern char *jmp_usermode_test();
 | 
			
		||||
 | 
			
		||||
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
 | 
			
		||||
@@ -119,8 +104,9 @@ void ensure_v86env() {
 | 
			
		||||
 | 
			
		||||
void error_environment() {
 | 
			
		||||
    ensure_v86env();
 | 
			
		||||
    union V86Regs_t regs;
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86TextMode);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
    printStr("Oh noes!!! System error! ;c    Press E for a fun recovery :3", &error_screen[80]);
 | 
			
		||||
    uint16_t *vga_text = ((uint16_t*)0xB8000);
 | 
			
		||||
    for (int i = 0; i < 80*50; i++)
 | 
			
		||||
@@ -128,7 +114,7 @@ void error_environment() {
 | 
			
		||||
    uint8_t key;
 | 
			
		||||
    for (key = get_key(); key != 'e' && key != 'E'; key = get_key());
 | 
			
		||||
    v86_entry = i386LinearToFp(v86TransFlag);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -136,8 +122,8 @@ Real Mode Accessible (First MB)
 | 
			
		||||
 00000 -  00400 IVT (1kB)
 | 
			
		||||
 00400 -  01000 Unused (3kB)
 | 
			
		||||
 01000 -  04000 Free (12kB)
 | 
			
		||||
 04000 -  07C00 Free (15kB)
 | 
			
		||||
 07C00 -  08000 Boot (512B)
 | 
			
		||||
 04000 -  07C00 V86 Code (15kB)
 | 
			
		||||
 07C00 -  08000 Boot & V86 Code (512B)
 | 
			
		||||
 08000 -  20000 V86 Code (96kB)
 | 
			
		||||
 20000 -  30000 Disk Buffer (64kB)
 | 
			
		||||
 30000 -  80000 Free (320kB)
 | 
			
		||||
@@ -158,8 +144,15 @@ Protected Only (1MB+)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void TestV86() {
 | 
			
		||||
    union V86Regs_t regs;
 | 
			
		||||
    regs.d.edi = 0x11111111;
 | 
			
		||||
    regs.d.esi = 0x22222222;
 | 
			
		||||
    regs.d.ebx = 0x33333333;
 | 
			
		||||
    regs.d.edx = 0x44444444;
 | 
			
		||||
    regs.d.ecx = 0x55555555;
 | 
			
		||||
    regs.d.eax = 0x66666666;
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86Test);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
}
 | 
			
		||||
void TestUser() {
 | 
			
		||||
    char *vga = jmp_usermode_test();
 | 
			
		||||
@@ -168,13 +161,15 @@ void TestUser() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void TestDiskRead() {
 | 
			
		||||
    union V86Regs_t regs;
 | 
			
		||||
    word *vga_text = (word *)0xb8000 + (80*5);
 | 
			
		||||
    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86TextMode);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
 | 
			
		||||
    regs.w.ax = 3; // text mode
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86VideoInt);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
    vga_text += printStr("Done. Starting Disk Read... ", vga_text);
 | 
			
		||||
    v86_entry = i386LinearToFp(v86DiskRead);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
    vga_text = (word *)0xb8000;
 | 
			
		||||
    char *diskReadBuf = (char *)0x23000;
 | 
			
		||||
    for (int i = 0; i < (80*25)/2; i++) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								link.ld
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								link.ld
									
									
									
									
									
								
							@@ -15,7 +15,7 @@ SECTIONS {
 | 
			
		||||
        _edata = .;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .realmode 0x8000 :
 | 
			
		||||
    .realmode 0x4000 :
 | 
			
		||||
        AT ( ADDR(.data) + SIZEOF(.data) )
 | 
			
		||||
        { _v86code = .; *(.v86); _ev86code = .; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								task.nasm
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								task.nasm
									
									
									
									
									
								
							@@ -89,7 +89,7 @@ mov ds, ax
 | 
			
		||||
mov eax, ecx ; restore return value
 | 
			
		||||
iret
 | 
			
		||||
 | 
			
		||||
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
 | 
			
		||||
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs);
 | 
			
		||||
global enter_v86
 | 
			
		||||
global _enter_v86_internal_no_task
 | 
			
		||||
enter_v86:
 | 
			
		||||
@@ -98,6 +98,17 @@ mov ecx, esp ; return stack
 | 
			
		||||
call save_current_task
 | 
			
		||||
_enter_v86_internal_no_task:
 | 
			
		||||
mov ebp, esp               ; save stack pointer
 | 
			
		||||
mov eax, dword [ebp+16] ; regs
 | 
			
		||||
test eax, eax
 | 
			
		||||
jz .no_regs
 | 
			
		||||
; load regs: edi, esi, ebx, edx, ecx, eax
 | 
			
		||||
mov edi, dword [eax+0]
 | 
			
		||||
mov esi, dword [eax+4]
 | 
			
		||||
mov ebx, dword [eax+8]
 | 
			
		||||
mov edx, dword [eax+12]
 | 
			
		||||
mov ecx, dword [eax+16]
 | 
			
		||||
mov eax, dword [eax+20]
 | 
			
		||||
.no_regs:
 | 
			
		||||
push dword  [ebp+0]        ; ss
 | 
			
		||||
push dword  [ebp+4]        ; esp
 | 
			
		||||
pushfd                     ; eflags
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,14 @@ mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
 | 
			
		||||
mov word [0xb8010], 0x0f00 | '!'
 | 
			
		||||
mov eax, 0 ; command = 00, get key
 | 
			
		||||
int 0x21 ; OS call
 | 
			
		||||
mov eax, 0x00030010 ; command = 10, set video mode 3
 | 
			
		||||
push 0x00000013 ; eax  AH=0,AL=3 set video mode 3
 | 
			
		||||
push 0x00000000 ; ecx
 | 
			
		||||
push 0x00000000 ; edx
 | 
			
		||||
push 0x00000000 ; ebx
 | 
			
		||||
push 0x00000000 ; esi
 | 
			
		||||
push 0x00000000 ; edi
 | 
			
		||||
push esp ; regs
 | 
			
		||||
mov eax, 0x10 ; command = 10
 | 
			
		||||
int 0x21 ; OS call
 | 
			
		||||
mov edi, 0xA0000
 | 
			
		||||
xor eax, eax
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								v86.nasm
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								v86.nasm
									
									
									
									
									
								
							@@ -84,6 +84,12 @@ int 0x10
 | 
			
		||||
int 0x30
 | 
			
		||||
jmp $
 | 
			
		||||
 | 
			
		||||
global v86VideoInt
 | 
			
		||||
v86VideoInt:
 | 
			
		||||
int 0x10
 | 
			
		||||
int 0x30
 | 
			
		||||
jmp $
 | 
			
		||||
 | 
			
		||||
global v86DiskRead
 | 
			
		||||
v86DiskRead:
 | 
			
		||||
xor ax, ax ; TODO fix assuming we're in first 64k
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								v86defs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								v86defs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
extern void v86Test();
 | 
			
		||||
extern void v86TransFlag();
 | 
			
		||||
extern void v86GfxMode();
 | 
			
		||||
extern void v86TextMode();
 | 
			
		||||
extern void v86DiskRead();
 | 
			
		||||
extern void v86VideoInt();
 | 
			
		||||
 | 
			
		||||
union __attribute((__packed__)) V86Regs_t {
 | 
			
		||||
    struct dword_regs { 
 | 
			
		||||
        uint32_t edi;
 | 
			
		||||
        uint32_t esi;
 | 
			
		||||
        uint32_t ebx;
 | 
			
		||||
        uint32_t edx;
 | 
			
		||||
        uint32_t ecx;
 | 
			
		||||
        uint32_t eax;
 | 
			
		||||
    } d;
 | 
			
		||||
    struct word_regs { 
 | 
			
		||||
        uint16_t di, _upper_di;
 | 
			
		||||
        uint16_t si, _upper_si;
 | 
			
		||||
        uint16_t bx, _upper_bx;
 | 
			
		||||
        uint16_t dx, _upper_dx;
 | 
			
		||||
        uint16_t cx, _upper_cx;
 | 
			
		||||
        uint16_t ax, _upper_ax;
 | 
			
		||||
    } w;
 | 
			
		||||
    struct byte_regs { 
 | 
			
		||||
        uint16_t di, _upper_di;
 | 
			
		||||
        uint16_t si, _upper_si;
 | 
			
		||||
        uint8_t bl, bh;
 | 
			
		||||
        uint16_t _upper_bx;
 | 
			
		||||
        uint8_t dl, dh;
 | 
			
		||||
        uint16_t _upper_dx;
 | 
			
		||||
        uint8_t cl, ch;
 | 
			
		||||
        uint16_t _upper_cx;
 | 
			
		||||
        uint8_t al, ah;
 | 
			
		||||
        uint16_t _upper_ax;
 | 
			
		||||
    } h;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs);
 | 
			
		||||
 | 
			
		||||
struct __attribute((__packed__)) Int13DiskPacket_t {
 | 
			
		||||
    uint8_t size; // 0x10
 | 
			
		||||
    uint8_t reserved; // 0x00
 | 
			
		||||
    uint16_t blocks;
 | 
			
		||||
    uint32_t transfer_buffer; // 0x2300:0000
 | 
			
		||||
    uint64_t start_block;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct Int13DiskPacket_t v86disk_addr_packet;
 | 
			
		||||
		Reference in New Issue
	
	Block a user