Improved fault handling
This commit is contained in:
		@@ -94,8 +94,8 @@ mov gs, ax
 | 
				
			|||||||
mov ss, ax
 | 
					mov ss, ax
 | 
				
			||||||
; check A20
 | 
					; check A20
 | 
				
			||||||
.a20:
 | 
					.a20:
 | 
				
			||||||
mov edi, 0x101337
 | 
					mov edi, 0x107C00
 | 
				
			||||||
mov esi, 0x001337
 | 
					mov esi, 0x007C00
 | 
				
			||||||
mov [esi], esi
 | 
					mov [esi], esi
 | 
				
			||||||
mov [edi], edi
 | 
					mov [edi], edi
 | 
				
			||||||
cmpsd
 | 
					cmpsd
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,14 @@ mov ax, 0x10
 | 
				
			|||||||
mov es, ax
 | 
					mov es, ax
 | 
				
			||||||
; move to 'safe' location
 | 
					; move to 'safe' location
 | 
				
			||||||
mov ebp, 0x318000
 | 
					mov ebp, 0x318000
 | 
				
			||||||
 | 
					; copy stack a bit
 | 
				
			||||||
 | 
					mov ecx, 0
 | 
				
			||||||
 | 
					.copy:
 | 
				
			||||||
 | 
					mov eax, [esp+ecx*4]
 | 
				
			||||||
 | 
					mov [ebp+ecx*4], eax
 | 
				
			||||||
 | 
					inc ecx
 | 
				
			||||||
 | 
					cmp ecx, 6
 | 
				
			||||||
 | 
					jl .copy
 | 
				
			||||||
mov esp, ebp
 | 
					mov esp, ebp
 | 
				
			||||||
call error_environment
 | 
					call error_environment
 | 
				
			||||||
.hlt:
 | 
					.hlt:
 | 
				
			||||||
@@ -47,6 +55,7 @@ mov eax, dword [esp+16] ; EFLAGS
 | 
				
			|||||||
and eax, 1 << 17 ; VM flag
 | 
					and eax, 1 << 17 ; VM flag
 | 
				
			||||||
test eax, eax
 | 
					test eax, eax
 | 
				
			||||||
pop eax
 | 
					pop eax
 | 
				
			||||||
 | 
					mov dword [_gpf_eax_save], eax
 | 
				
			||||||
jnz gpf_handler_v86
 | 
					jnz gpf_handler_v86
 | 
				
			||||||
jmp gpf_handler_32
 | 
					jmp gpf_handler_32
 | 
				
			||||||
gpf_unhandled:
 | 
					gpf_unhandled:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								interrupt.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								interrupt.c
									
									
									
									
									
								
							@@ -99,6 +99,7 @@ __attribute((__no_caller_saved_registers__))
 | 
				
			|||||||
extern void return_prev_task();
 | 
					extern void return_prev_task();
 | 
				
			||||||
__attribute((__no_caller_saved_registers__))
 | 
					__attribute((__no_caller_saved_registers__))
 | 
				
			||||||
extern void error_environment(); // defined in kernel.c
 | 
					extern void error_environment(); // defined in kernel.c
 | 
				
			||||||
 | 
					extern uint32_t _gpf_eax_save;
 | 
				
			||||||
#define VALID_FLAGS 0xDFF
 | 
					#define VALID_FLAGS 0xDFF
 | 
				
			||||||
__attribute__ ((interrupt))
 | 
					__attribute__ ((interrupt))
 | 
				
			||||||
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
 | 
					void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
 | 
				
			||||||
@@ -233,8 +234,11 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
 | 
				
			|||||||
                    uint16_t *e = error_screen;
 | 
					                    uint16_t *e = error_screen;
 | 
				
			||||||
                    for (int i = 0; i < 80; i++)
 | 
					                    for (int i = 0; i < 80; i++)
 | 
				
			||||||
                        e[i] = 0x0f00;
 | 
					                        e[i] = 0x0f00;
 | 
				
			||||||
                    e += int_printStr("Unknown instruction caused V86 GPF: ", e);
 | 
					                    e += int_printStr("Unknown instruction caused V86 GPF(", e);
 | 
				
			||||||
                    *(uint32_t*)e = 0x1f001f00;
 | 
					                    int_printWord(error_code, e);
 | 
				
			||||||
 | 
					                    e += 4;
 | 
				
			||||||
 | 
					                    e += int_printStr("):", e);
 | 
				
			||||||
 | 
					                    *(uint32_t*)e = 0x7f007f00;
 | 
				
			||||||
                    int_printDword(*(uint32_t*)ip, e);
 | 
					                    int_printDword(*(uint32_t*)ip, e);
 | 
				
			||||||
                    e += 9;
 | 
					                    e += 9;
 | 
				
			||||||
                    *(uint8_t*)e = '@';
 | 
					                    *(uint8_t*)e = '@';
 | 
				
			||||||
@@ -293,19 +297,14 @@ void set_trap_gate(uint8_t gate, void (*handler)()) {
 | 
				
			|||||||
    IDT[gate].type_attributes = 0x8F;
 | 
					    IDT[gate].type_attributes = 0x8F;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void setup_interrupts() {
 | 
					void setup_interrupts() {
 | 
				
			||||||
 | 
					    asm volatile("cli");
 | 
				
			||||||
    IDTR.size = 256*8 - 1;
 | 
					    IDTR.size = 256*8 - 1;
 | 
				
			||||||
    IDTR.offset = (uint32_t)(size_t)IDT;
 | 
					    IDTR.offset = (uint32_t)(size_t)IDT;
 | 
				
			||||||
    for (int i = 0; i < 256; i++) {
 | 
					    for (int i = 0; i < 256; i++) {
 | 
				
			||||||
        *(uint64_t*)&IDT[i] = 0;
 | 
					        *(uint64_t*)&IDT[i] = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < 9; i++) {
 | 
					    for (int i = 0; i < 256; i++) {
 | 
				
			||||||
        set_trap_gate(i, unhandled_handler);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (int i = 10; i < 15; i++) {
 | 
					 | 
				
			||||||
        set_trap_gate(i, unhandled_handler);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (int i = 16; i < 22; i++) {
 | 
					 | 
				
			||||||
        set_trap_gate(i, unhandled_handler);
 | 
					        set_trap_gate(i, unhandled_handler);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								kernel.c
									
									
									
									
									
								
							@@ -109,18 +109,31 @@ void ensure_v86env() {
 | 
				
			|||||||
__attribute((__no_caller_saved_registers__))
 | 
					__attribute((__no_caller_saved_registers__))
 | 
				
			||||||
extern void return_prev_task();
 | 
					extern void return_prev_task();
 | 
				
			||||||
__attribute((__no_caller_saved_registers__))
 | 
					__attribute((__no_caller_saved_registers__))
 | 
				
			||||||
void error_environment() {
 | 
					void error_environment(uint32_t stack0, uint32_t stack1, uint32_t stack2, uint32_t stack3, uint32_t stack4, uint32_t stack5) {
 | 
				
			||||||
    ensure_v86env();
 | 
					    ensure_v86env();
 | 
				
			||||||
 | 
					    setup_interrupts(); // just in case
 | 
				
			||||||
    for (int i = 0; i < 80*50; i++)
 | 
					    for (int i = 0; i < 80*50; i++)
 | 
				
			||||||
        if (!(error_screen[i] & 0xFF00))
 | 
					        if (!(error_screen[i] & 0xFF00))
 | 
				
			||||||
            error_screen[i] = 0x0f00 | (error_screen[i] & 0x00FF);
 | 
					            error_screen[i] = 0x0f00 | (error_screen[i] & 0x00FF);
 | 
				
			||||||
    union V86Regs_t regs;
 | 
					    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), ®s);
 | 
					    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
				
			||||||
    char str0[] = "Oh noes!!! System error! ;c    ";
 | 
					    char str0[] = "Oh noes!!! System error! ;c     STKDMP:";
 | 
				
			||||||
    printStr(str0, &error_screen[80]);
 | 
					    printStr(str0, &error_screen[80]);
 | 
				
			||||||
    printStr("Press E for a fun recovery :3", &error_screen[80+sizeof(str0)]);
 | 
					    uint16_t *tmp = &error_screen[80+sizeof(str0)-1];
 | 
				
			||||||
    printStr("Press R to return to previous task", &error_screen[160+sizeof(str0)]);
 | 
					    tmp += printDword(stack0, tmp);
 | 
				
			||||||
 | 
					    tmp++;
 | 
				
			||||||
 | 
					    tmp += printDword(stack1, tmp);
 | 
				
			||||||
 | 
					    tmp++;
 | 
				
			||||||
 | 
					    tmp += printDword(stack2, tmp);
 | 
				
			||||||
 | 
					    tmp = &error_screen[80*2+sizeof(str0)-1];
 | 
				
			||||||
 | 
					    tmp += printDword(stack3, tmp);
 | 
				
			||||||
 | 
					    tmp++;
 | 
				
			||||||
 | 
					    tmp += printDword(stack4, tmp);
 | 
				
			||||||
 | 
					    tmp++;
 | 
				
			||||||
 | 
					    tmp += printDword(stack5, tmp);
 | 
				
			||||||
 | 
					    printStr("Press E for a fun recovery :3", &error_screen[80*2]);
 | 
				
			||||||
 | 
					    printStr("Press R to return to previous task", &error_screen[80*3]);
 | 
				
			||||||
    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++)
 | 
				
			||||||
        vga_text[i] = error_screen[i];
 | 
					        vga_text[i] = error_screen[i];
 | 
				
			||||||
@@ -225,6 +238,7 @@ void FileSelect() {
 | 
				
			|||||||
    int32_t fileHovered = 0, lastFileHovered = 0;
 | 
					    int32_t fileHovered = 0, lastFileHovered = 0;
 | 
				
			||||||
    for (char reload = 1;;) {
 | 
					    for (char reload = 1;;) {
 | 
				
			||||||
        // Info line (4)
 | 
					        // Info line (4)
 | 
				
			||||||
 | 
					        DrawScreen();
 | 
				
			||||||
        printStr("T to run tests - X to view in hex - V to view as text - P to load as program", &vga_text[80*4+2]);
 | 
					        printStr("T to run tests - X to view in hex - V to view as text - P to load as program", &vga_text[80*4+2]);
 | 
				
			||||||
        VOLINFO vi; DIRINFO di;
 | 
					        VOLINFO vi; DIRINFO di;
 | 
				
			||||||
        if (reload) {
 | 
					        if (reload) {
 | 
				
			||||||
@@ -253,7 +267,6 @@ void FileSelect() {
 | 
				
			|||||||
            case 0x14: // t
 | 
					            case 0x14: // t
 | 
				
			||||||
                create_child(0x380000, (uintptr_t)RunTests, 0);
 | 
					                create_child(0x380000, (uintptr_t)RunTests, 0);
 | 
				
			||||||
                SetCursorDisabled();
 | 
					                SetCursorDisabled();
 | 
				
			||||||
                DrawScreen();
 | 
					 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KEY_P:
 | 
					            case KEY_P:
 | 
				
			||||||
@@ -261,7 +274,6 @@ void FileSelect() {
 | 
				
			|||||||
                create_child(0x380000, (uintptr_t)ProgramLoadTest, 2, path, &vi);
 | 
					                create_child(0x380000, (uintptr_t)ProgramLoadTest, 2, path, &vi);
 | 
				
			||||||
                SetVideo25Lines();
 | 
					                SetVideo25Lines();
 | 
				
			||||||
                SetCursorDisabled();
 | 
					                SetCursorDisabled();
 | 
				
			||||||
                DrawScreen();
 | 
					 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KEY_X:
 | 
					            case KEY_X:
 | 
				
			||||||
@@ -270,7 +282,6 @@ void FileSelect() {
 | 
				
			|||||||
                create_child(0x380000, (uintptr_t)HexViewTest, 2, path, &vi);
 | 
					                create_child(0x380000, (uintptr_t)HexViewTest, 2, path, &vi);
 | 
				
			||||||
                SetVideo25Lines();
 | 
					                SetVideo25Lines();
 | 
				
			||||||
                SetCursorDisabled();
 | 
					                SetCursorDisabled();
 | 
				
			||||||
                DrawScreen();
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KEY_V:
 | 
					            case KEY_V:
 | 
				
			||||||
                File83ToPath((char*)entries[fileHovered].name, (char*)path);
 | 
					                File83ToPath((char*)entries[fileHovered].name, (char*)path);
 | 
				
			||||||
@@ -278,7 +289,6 @@ void FileSelect() {
 | 
				
			|||||||
                create_child(0x380000, (uintptr_t)TextViewTest, 2, path, &vi);
 | 
					                create_child(0x380000, (uintptr_t)TextViewTest, 2, path, &vi);
 | 
				
			||||||
                SetVideo25Lines();
 | 
					                SetVideo25Lines();
 | 
				
			||||||
                SetCursorDisabled();
 | 
					                SetCursorDisabled();
 | 
				
			||||||
                DrawScreen();
 | 
					 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
@@ -346,6 +356,21 @@ void start() {
 | 
				
			|||||||
    SetVideo25Lines();
 | 
					    SetVideo25Lines();
 | 
				
			||||||
    SetCursorDisabled();
 | 
					    SetCursorDisabled();
 | 
				
			||||||
    DrawScreen();
 | 
					    DrawScreen();
 | 
				
			||||||
    FileSelect();
 | 
					    uint32_t stack;
 | 
				
			||||||
 | 
					    asm volatile("mov %%esp,%%eax":"=a"(stack));
 | 
				
			||||||
 | 
					    stack = ((stack - 0x4000) / 0x1000) * 0x1000;
 | 
				
			||||||
 | 
					    for (;;) {
 | 
				
			||||||
 | 
					        create_child(stack, (uintptr_t)FileSelect, 0);
 | 
				
			||||||
 | 
					        // should never return, so if it does,
 | 
				
			||||||
 | 
					        // we have an error
 | 
				
			||||||
 | 
					        SetVideo25Lines();
 | 
				
			||||||
 | 
					        SetCursorDisabled();
 | 
				
			||||||
 | 
					        DrawScreen();
 | 
				
			||||||
 | 
					        vga_text = &((word*)0xb8000)[80*4 + 2];
 | 
				
			||||||
 | 
					        vga_text += printStr("Error loading file select. Ensure the disk has a valid MBR and FAT partition.", vga_text);
 | 
				
			||||||
 | 
					        vga_text = &((word*)0xb8000)[80*5 + 2];
 | 
				
			||||||
 | 
					        vga_text += printStr("Press R to retry.", vga_text);
 | 
				
			||||||
 | 
					        for (;(get_scancode() & 0xff) != KEY_R;);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tests.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tests.c
									
									
									
									
									
								
							@@ -39,13 +39,13 @@ void TestDiskRead() {
 | 
				
			|||||||
    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
					    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
				
			||||||
    regs.w.ax = 3; // text mode
 | 
					    regs.w.ax = 3; // text mode
 | 
				
			||||||
    V8086Int(0x10, ®s); 
 | 
					    V8086Int(0x10, ®s); 
 | 
				
			||||||
    vga_text += printStr("Done. Starting Disk Read... ", vga_text);
 | 
					    //vga_text += printStr("Done. Starting Disk Read... ", vga_text);
 | 
				
			||||||
    char *diskReadBuf = (char *)0x8000;
 | 
					    char *diskReadBuf = (char *)0x20000;
 | 
				
			||||||
	v86disk_addr_packet.transfer_buffer =
 | 
						v86disk_addr_packet.transfer_buffer =
 | 
				
			||||||
		(uintptr_t)diskReadBuf & 0x000F |
 | 
							(uintptr_t)diskReadBuf & 0x000F |
 | 
				
			||||||
		(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
 | 
							(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
 | 
				
			||||||
    FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
					    FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
				
			||||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
					    enter_v86(0x0000, 0x8000, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
				
			||||||
    vga_text = (uint16_t *)0xb8000;
 | 
					    vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    for (int i = 0; i < (80*25)/2; i++) {
 | 
					    for (int i = 0; i < (80*25)/2; i++) {
 | 
				
			||||||
        printByte(diskReadBuf[i], &vga_text[i*2]);
 | 
					        printByte(diskReadBuf[i], &vga_text[i*2]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ mov dword [0xb8000], 0x0f000f00 | 'U' | 's' << 16
 | 
				
			|||||||
mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
 | 
					mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
 | 
				
			||||||
mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
 | 
					mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
 | 
				
			||||||
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
 | 
					mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
 | 
				
			||||||
mov word [0xb8010], 0x0f00 | '!'
 | 
					mov dword [0xb8010], 0x0f000f00 | '!'
 | 
				
			||||||
mov dword [0xb8000+160], 0x0f000f00 | 'F' | 'a' << 16
 | 
					mov dword [0xb8000+160], 0x0f000f00 | 'F' | 'a' << 16
 | 
				
			||||||
mov dword [0xb8004+160], 0x0f000f00 | 'u' | 'l' << 16
 | 
					mov dword [0xb8004+160], 0x0f000f00 | 'u' | 'l' << 16
 | 
				
			||||||
mov dword [0xb8008+160], 0x0f000f00 | 't' | 's' << 16
 | 
					mov dword [0xb8008+160], 0x0f000f00 | 't' | 's' << 16
 | 
				
			||||||
@@ -18,12 +18,24 @@ mov dword [0xb8000+480], 0x0f000f00 | 'p' | ':' << 16
 | 
				
			|||||||
mov dword [0xb8004+480], 0x0f000f00 | ' ' | 'P' << 16
 | 
					mov dword [0xb8004+480], 0x0f000f00 | ' ' | 'P' << 16
 | 
				
			||||||
mov dword [0xb8008+480], 0x0f000f00 | 'G' | 'F' << 16
 | 
					mov dword [0xb8008+480], 0x0f000f00 | 'G' | 'F' << 16
 | 
				
			||||||
mov dword [0xb800C+480], 0x0f000f00 | 'L' | 'T' << 16
 | 
					mov dword [0xb800C+480], 0x0f000f00 | 'L' | 'T' << 16
 | 
				
			||||||
 | 
					mov dword [0xb8000+640], 0x0f000f00 | 'u' | ':' << 16
 | 
				
			||||||
 | 
					mov dword [0xb8004+640], 0x0f000f00 | ' ' | '#' << 16
 | 
				
			||||||
 | 
					mov dword [0xb8008+640], 0x0f000f00 | 'U' | 'D' << 16
 | 
				
			||||||
 | 
					mov dword [0xb800C+640], 0x0f000f00 | '2' | ' ' << 16
 | 
				
			||||||
 | 
					mov dword [0xb8000+800], 0x0f000f00 | 'g' | ':' << 16
 | 
				
			||||||
 | 
					mov dword [0xb8004+800], 0x0f000f00 | ' ' | '#' << 16
 | 
				
			||||||
 | 
					mov dword [0xb8008+800], 0x0f000f00 | 'G' | 'P' << 16
 | 
				
			||||||
 | 
					mov dword [0xb800C+800], 0x0f000f00 | 'F' | ' ' << 16
 | 
				
			||||||
mov eax, 0 ; command = 00h, get key
 | 
					mov eax, 0 ; command = 00h, get key
 | 
				
			||||||
int 0x21 ; OS call
 | 
					int 0x21 ; OS call
 | 
				
			||||||
cmp al, 'd'
 | 
					cmp al, 'd'
 | 
				
			||||||
je .div_err
 | 
					je .div_err
 | 
				
			||||||
cmp al, 'p'
 | 
					cmp al, 'p'
 | 
				
			||||||
je .page_err
 | 
					je .page_err
 | 
				
			||||||
 | 
					cmp al, 'u'
 | 
				
			||||||
 | 
					je .undefined_err
 | 
				
			||||||
 | 
					cmp al, 'g'
 | 
				
			||||||
 | 
					je .gpf_err
 | 
				
			||||||
push 0x00000013 ; eax  AH=0,AL=3 set video mode 3
 | 
					push 0x00000013 ; eax  AH=0,AL=3 set video mode 3
 | 
				
			||||||
push 0x00000000 ; ecx
 | 
					push 0x00000000 ; ecx
 | 
				
			||||||
push 0x00000000 ; edx
 | 
					push 0x00000000 ; edx
 | 
				
			||||||
@@ -43,9 +55,6 @@ inc al
 | 
				
			|||||||
cmp eax, 200
 | 
					cmp eax, 200
 | 
				
			||||||
jl .loop
 | 
					jl .loop
 | 
				
			||||||
mov eax, 0xA0000
 | 
					mov eax, 0xA0000
 | 
				
			||||||
;mov ecx, 1000000000
 | 
					 | 
				
			||||||
;.dbg:
 | 
					 | 
				
			||||||
;loop .dbg
 | 
					 | 
				
			||||||
int 0x30 ; Exit
 | 
					int 0x30 ; Exit
 | 
				
			||||||
.page_err:
 | 
					.page_err:
 | 
				
			||||||
mov edx, 0x105000 ; somewhere in kernel mem
 | 
					mov edx, 0x105000 ; somewhere in kernel mem
 | 
				
			||||||
@@ -53,3 +62,8 @@ mov edx, [edx] ; should page fault
 | 
				
			|||||||
.div_err:
 | 
					.div_err:
 | 
				
			||||||
xor ebx, ebx
 | 
					xor ebx, ebx
 | 
				
			||||||
div bl ; Unhandled DIV0 exception
 | 
					div bl ; Unhandled DIV0 exception
 | 
				
			||||||
 | 
					.undefined_err:
 | 
				
			||||||
 | 
					ud2 ; undefined instruction
 | 
				
			||||||
 | 
					.gpf_err:
 | 
				
			||||||
 | 
					mov ax, 0x10
 | 
				
			||||||
 | 
					mov ds, ax   ; load ds with bad value
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								v86.nasm
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								v86.nasm
									
									
									
									
									
								
							@@ -97,7 +97,10 @@ mov ah, 0x42
 | 
				
			|||||||
mov dl, 0x80 ; TODO get this from BIOS or something
 | 
					mov dl, 0x80 ; TODO get this from BIOS or something
 | 
				
			||||||
mov si, v86disk_addr_packet ; ds:si
 | 
					mov si, v86disk_addr_packet ; ds:si
 | 
				
			||||||
int 0x13
 | 
					int 0x13
 | 
				
			||||||
 | 
					jc .err
 | 
				
			||||||
int 0x30
 | 
					int 0x30
 | 
				
			||||||
 | 
					.err:
 | 
				
			||||||
 | 
					ud2
 | 
				
			||||||
jmp $
 | 
					jmp $
 | 
				
			||||||
global v86disk_addr_packet
 | 
					global v86disk_addr_packet
 | 
				
			||||||
v86disk_addr_packet:
 | 
					v86disk_addr_packet:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user