I have no idea how this works, could anyone help me?
here is the v86.asm ( my version ) code:
; includes:
%include 'intframe.inc' ; from john fine's code
GLOBAL call_BIOS
GLOBAL call_V86
%define args 12
;************************************************************************************************************
call_BIOS:
push ebx
push esi
push edi
push ebp
%assign args 20
mov ebp, esp
mov ebx, [ebp+args] ;Before frame
mov cl, [ebp+args+12] ;AH value
mov [fr.ah+ebx], cl ;Put it into before frame
mov eax, [ebp+args+8] ;Interrupt number
mov eax, [ZERO+eax*4] ;Get the vector
movzx edx, ax ;Extend IP part to EIP
shr eax, 16 ;Get CS part
mov [fr.eip+ebx], edx ;Put EIP in before frame
mov [fr.cs+ebx], eax ;Put CS in before frame
mov dword [fr.eflags+ebx], 0x23002
jmp short call_V86.1 ;Merge with main entry point
; void call_V86(INTFRAME *before, INTFRAME *after);
;
; Pushes three words (for iret or far ret) on the current v86 mode
; stack.
;
; Changes the p_ds, p_es, esp and ss fields in the before frame to
; allow that frame to be used to transfer control to V86 mode.
;
; When that v86 mode code exits with iret or far ret, the registers
; are put in the after frame, and the caller of call_V86 is resumed.
;
call_V86:
push ebx
push esi
push edi
push ebp
mov ebx, [esp+args] ;Before frame
.1: xor eax, eax ;Need NULL p_ds and p_es for
mov [fr.p_ds+ebx], eax ; standard INT_EXIT macro for V86
mov [fr.p_es+ebx], eax
pushf ;Save interrupt enable bit
mov esi, [v86k_esp] ;Get existing V86 frame limit
push dword [esp0] ;Save esp0
push esi ;Save V86 frame limit
%assign args args+12 ;Count 3 more dwords on stack
cli ;Can't allow interrupts between
;changing esp0 and IRETing
mov [esp0], esp ;Set new V86 frame limit
mov [v86k_esp], esp
movzx eax, word [fr.sp+esi-fr_size] ;Get V86 sp
movzx ecx, word [fr.ss+esi-fr_size] ;Get V86 ss
sub eax, byte 6 ;Make room on V86 stack
mov [fr.esp+ebx], eax ;Store in before frame
mov [fr.ss+ebx], ecx
shl ecx, 4 ;V86 stack segment base
mov dword [ZERO+eax+ecx+2], 0x3002FFFF ;Create a return point for the
mov word [ZERO+eax+ecx], unwind_sw ;V86 routine at FFFF:unwind_sw
mov esp, ebx ;Use before frame as a stack
INT_EXIT
unwind_sw: int 46h ;Get out of V86 mode
;************************************************************************************************************
tss: dd 0
esp0: dd stack0top
resb 0x66 - 0xC
dw 0x68
; I/O restrictions
resb 8192 ;0 - FFFF unrestricted
tss_size equ $-tss
v86k_esp dd stack0top
resd 4096
stack0top:
here is my kernel32.c:
/* kernel32.c : FritzOS C Kernel
Copyright (C) 2002 Tom Fritz
* This program is a part of the FritzOS kernel, and may be freely
* copied under the terms of the GNU General Public License (GPL),
* version 2, or at your option any later version.
For more info, look at the COPYING file.
*/
asm("jmp start"); // go to Start
#include "include/fstdio.h"
#include "include/graphics.h"
#include "include/intframe.h" ; from john fine's header file
extern void call_BIOS( INTFRAME* before, INTFRAME* after, int number, char ah );
void start()
{
/* k_printf( "FritzOS has loaded it\'s C kernel.", RED_GREEN, 1 );
k_printf( "FritzOS Prekernel0.5, Copyright (C) 2002 Tom Fritz", RED_GREEN, 3 );
k_printf( "FritzOS comes with ABSOLUTELY NO WARRANTY; for details look at COPYING.", WHITE_BLACK,
4 );
k_printf( "This is free software, and you are welcome to redistribute it under certain",
WHITE_BLACK, 5 );
k_printf( "conditions; look at COPYING for details.", WHITE_BLACK, 6 ); */
INTFRAME* hm1, * hm2;
call_BIOS( hm1, hm2, 10, 3 );
Freeze();
}
// End of kernel32.c
