Register arguments can be passed to v86 code
This commit is contained in:
parent
7937de6ef0
commit
750b1edc16
@ -11,19 +11,7 @@
|
|||||||
#include "dosfs.h"
|
#include "dosfs.h"
|
||||||
#include "tmpstring.c"
|
#include "tmpstring.c"
|
||||||
#include "../interrupt.h"
|
#include "../interrupt.h"
|
||||||
|
#include "../v86defs.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();
|
|
||||||
|
|
||||||
// all reading at 0x23000 - be careful!
|
// all reading at 0x23000 - be careful!
|
||||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
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 =
|
v86disk_addr_packet.transfer_buffer =
|
||||||
(uintptr_t)buffer & 0x000F |
|
(uintptr_t)buffer & 0x000F |
|
||||||
(((uintptr_t)buffer & 0xFFFF0) << 12);
|
(((uintptr_t)buffer & 0xFFFF0) << 12);
|
||||||
|
union V86Regs_t regs;
|
||||||
FARPTR v86_entry = i386LinearToFp(v86DiskRead);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
|
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 task_ptr
|
||||||
extern _enter_v86_internal_no_task
|
extern _enter_v86_internal_no_task
|
||||||
extern return_prev_task
|
extern return_prev_task
|
||||||
extern v86GfxMode
|
extern v86VideoInt
|
||||||
gpf_handler_32:
|
gpf_handler_32:
|
||||||
push eax
|
push eax
|
||||||
mov eax, dword [esp+8] ; EIP
|
mov eax, dword [esp+8] ; EIP
|
||||||
@ -56,19 +56,23 @@ cmp al, 0x00 ; get key
|
|||||||
jne .s1
|
jne .s1
|
||||||
call get_key
|
call get_key
|
||||||
jmp .return_to_offender
|
jmp .return_to_offender
|
||||||
.s1: cmp al, 0x10 ; set video mode
|
.s1: cmp al, 0x10 ; video interrupt
|
||||||
jne .return_to_offender
|
jne .return_to_offender
|
||||||
add esp, 4
|
add esp, 4
|
||||||
add dword [esp+0], 2
|
add dword [esp+0], 2
|
||||||
; add a new task
|
; add a new task
|
||||||
call _gpf_create_return_task
|
call _gpf_create_return_task
|
||||||
; now enter v86 mode
|
; now enter v86 mode
|
||||||
; push args
|
; get regs from return stack
|
||||||
mov eax, v86GfxMode
|
mov eax, [esp+12] ; return esp
|
||||||
|
mov eax, [eax] ; regs
|
||||||
|
push eax ; regs
|
||||||
|
mov eax, v86VideoInt
|
||||||
and eax, 0xffff
|
and eax, 0xffff
|
||||||
push eax ; ip
|
push eax ; ip
|
||||||
mov eax, v86GfxMode
|
mov eax, v86VideoInt
|
||||||
shr eax, 16
|
shr eax, 4
|
||||||
|
and eax, 0xf000
|
||||||
push eax ; cs
|
push eax ; cs
|
||||||
push 0xFF00 ; sp
|
push 0xFF00 ; sp
|
||||||
push 0x8000 ; ss
|
push 0x8000 ; ss
|
||||||
|
@ -51,7 +51,7 @@ FARPTR i386LinearToFp(void *ptr)
|
|||||||
{
|
{
|
||||||
unsigned seg, off;
|
unsigned seg, off;
|
||||||
off = (uintptr_t) ptr & 0xffff;
|
off = (uintptr_t) ptr & 0xffff;
|
||||||
seg = ((uintptr_t) ptr >> 16);
|
seg = ((uintptr_t) ptr >> 4) & 0xf000;
|
||||||
return MK_FP(seg, off);
|
return MK_FP(seg, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
kernel.c
43
kernel.c
@ -5,6 +5,7 @@
|
|||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "tss.h"
|
#include "tss.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
#include "v86defs.h"
|
||||||
|
|
||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
|
|
||||||
@ -53,22 +54,6 @@ uint32_t get_cr4() {
|
|||||||
return reg;
|
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 *jmp_usermode_test();
|
||||||
|
|
||||||
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
||||||
@ -119,8 +104,9 @@ void ensure_v86env() {
|
|||||||
|
|
||||||
void error_environment() {
|
void error_environment() {
|
||||||
ensure_v86env();
|
ensure_v86env();
|
||||||
|
union V86Regs_t regs;
|
||||||
FARPTR v86_entry = i386LinearToFp(v86TextMode);
|
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]);
|
printStr("Oh noes!!! System error! ;c Press E for a fun recovery :3", &error_screen[80]);
|
||||||
uint16_t *vga_text = ((uint16_t*)0xB8000);
|
uint16_t *vga_text = ((uint16_t*)0xB8000);
|
||||||
for (int i = 0; i < 80*50; i++)
|
for (int i = 0; i < 80*50; i++)
|
||||||
@ -128,7 +114,7 @@ void error_environment() {
|
|||||||
uint8_t key;
|
uint8_t key;
|
||||||
for (key = get_key(); key != 'e' && key != 'E'; key = get_key());
|
for (key = get_key(); key != 'e' && key != 'E'; key = get_key());
|
||||||
v86_entry = i386LinearToFp(v86TransFlag);
|
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)
|
00000 - 00400 IVT (1kB)
|
||||||
00400 - 01000 Unused (3kB)
|
00400 - 01000 Unused (3kB)
|
||||||
01000 - 04000 Free (12kB)
|
01000 - 04000 Free (12kB)
|
||||||
04000 - 07C00 Free (15kB)
|
04000 - 07C00 V86 Code (15kB)
|
||||||
07C00 - 08000 Boot (512B)
|
07C00 - 08000 Boot & V86 Code (512B)
|
||||||
08000 - 20000 V86 Code (96kB)
|
08000 - 20000 V86 Code (96kB)
|
||||||
20000 - 30000 Disk Buffer (64kB)
|
20000 - 30000 Disk Buffer (64kB)
|
||||||
30000 - 80000 Free (320kB)
|
30000 - 80000 Free (320kB)
|
||||||
@ -158,8 +144,15 @@ Protected Only (1MB+)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void TestV86() {
|
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);
|
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() {
|
void TestUser() {
|
||||||
char *vga = jmp_usermode_test();
|
char *vga = jmp_usermode_test();
|
||||||
@ -168,13 +161,15 @@ void TestUser() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TestDiskRead() {
|
void TestDiskRead() {
|
||||||
|
union V86Regs_t regs;
|
||||||
word *vga_text = (word *)0xb8000 + (80*5);
|
word *vga_text = (word *)0xb8000 + (80*5);
|
||||||
vga_text += printStr("Setting Text Mode... ", vga_text);
|
vga_text += printStr("Setting Text Mode... ", vga_text);
|
||||||
FARPTR v86_entry = i386LinearToFp(v86TextMode);
|
regs.w.ax = 3; // text mode
|
||||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
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);
|
vga_text += printStr("Done. Starting Disk Read... ", vga_text);
|
||||||
v86_entry = i386LinearToFp(v86DiskRead);
|
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;
|
vga_text = (word *)0xb8000;
|
||||||
char *diskReadBuf = (char *)0x23000;
|
char *diskReadBuf = (char *)0x23000;
|
||||||
for (int i = 0; i < (80*25)/2; i++) {
|
for (int i = 0; i < (80*25)/2; i++) {
|
||||||
|
2
link.ld
2
link.ld
@ -15,7 +15,7 @@ SECTIONS {
|
|||||||
_edata = .;
|
_edata = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
.realmode 0x8000 :
|
.realmode 0x4000 :
|
||||||
AT ( ADDR(.data) + SIZEOF(.data) )
|
AT ( ADDR(.data) + SIZEOF(.data) )
|
||||||
{ _v86code = .; *(.v86); _ev86code = .; }
|
{ _v86code = .; *(.v86); _ev86code = .; }
|
||||||
|
|
||||||
|
13
task.nasm
13
task.nasm
@ -89,7 +89,7 @@ mov ds, ax
|
|||||||
mov eax, ecx ; restore return value
|
mov eax, ecx ; restore return value
|
||||||
iret
|
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
|
||||||
global _enter_v86_internal_no_task
|
global _enter_v86_internal_no_task
|
||||||
enter_v86:
|
enter_v86:
|
||||||
@ -98,6 +98,17 @@ mov ecx, esp ; return stack
|
|||||||
call save_current_task
|
call save_current_task
|
||||||
_enter_v86_internal_no_task:
|
_enter_v86_internal_no_task:
|
||||||
mov ebp, esp ; save stack pointer
|
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+0] ; ss
|
||||||
push dword [ebp+4] ; esp
|
push dword [ebp+4] ; esp
|
||||||
pushfd ; eflags
|
pushfd ; eflags
|
||||||
|
@ -8,7 +8,14 @@ mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
|
|||||||
mov word [0xb8010], 0x0f00 | '!'
|
mov word [0xb8010], 0x0f00 | '!'
|
||||||
mov eax, 0 ; command = 00, get key
|
mov eax, 0 ; command = 00, get key
|
||||||
int 0x21 ; OS call
|
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
|
int 0x21 ; OS call
|
||||||
mov edi, 0xA0000
|
mov edi, 0xA0000
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
|
6
v86.nasm
6
v86.nasm
@ -84,6 +84,12 @@ int 0x10
|
|||||||
int 0x30
|
int 0x30
|
||||||
jmp $
|
jmp $
|
||||||
|
|
||||||
|
global v86VideoInt
|
||||||
|
v86VideoInt:
|
||||||
|
int 0x10
|
||||||
|
int 0x30
|
||||||
|
jmp $
|
||||||
|
|
||||||
global v86DiskRead
|
global v86DiskRead
|
||||||
v86DiskRead:
|
v86DiskRead:
|
||||||
xor ax, ax ; TODO fix assuming we're in first 64k
|
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;
|
Loading…
Reference in New Issue
Block a user