Hy to all, I need a help about mode switching. Excuse me if I use a lot of words but I want to expose my problem in all its details. Those are my skills :
In real mode I use NASM, i know how to chain interrupts like system timer, how to use BIOS, how to write in video memory by Int 10h (320X200 256 colors and 640X480 16 colors), how to create a bootstrap loader, how to write to I/O ports and so on. I have made a lot of small .com files that demonstrate ( to me ) what can be done; I have never built a large .exe program or accessed databases or used VGA Mode X.
In protected mode, under Win98, I use MASM32 to write GUI applications ( simple screensavers, simple forms ) or DLL containing functions that I can call from VB. I have to learn how to write VxDs, applications that use ODBC, DirectX, OpenGL and a lot more.
What is my goal ? To write in NASM a program that enable protected mode. I have found a lot of examples, but they are often incomplete, use TASM sintax, are too complex to verify. I have all Intel's documentation but the main difficulty is, in my opinion, to find a simple example where structures like IDT are well defined.
I hate protection !!! I want to implement a flat system where you have a single segment of 4 Gb readable and writable, a sort of super 8086 without paging. In this environment I would load from disk all my data and keep them in memory once and forever.
I think that interrupt handling would be the main problem but one could return back to real mode with interrupt number to process it and then switch again to p. mode like DOS extenders do.
Are you interested in ?
I would like to know your opinion about difficulty, or your ideas.
Thanks to all !!

fooCoder
Posted on 2001-08-29 08:17:04 by fooCoder
fooCoder,

I'm precisely working on that. I've downloaded lots of tutorials and
source codes about protected mode and relatives.

About NASM I found:

http://www.venezuelacultural.com.ve/files/PM-NASM.ZIP (82KB)

I don't know if this is what you search, but it seems me
a well work.

Do you hate pm? I believe that you want try with Flat Real Mode. I've
worked with a example for NASM, but did not run:

http://www.venezuelacultural.com.ve/files/FLAT100.ZIP (43KB)

I got best results with these tasm source codes:

http://www.venezuelacultural.com.ve/files/FLAU.ZIP (12KB)

I was very surprised with this posibility, but is not so easy.
A found useful info about this in:

http://www.venezuelacultural.com.ve/files/GEM0022.ZIP (6KB)

The author says that flat real mode was a dream with the i486 and
windows 3.x, but with the new DOS extenders and the PENTIUN
processors, this mode became less attractive since it is still
16-bit.

The author recomends use it only in 486 plataforms. The flat real
mode implementation of of this author is based on the use of
HIMEM.SYS. But is not stable. Posibly, the best is study the
HIMEM.SYS. Here is a disasembly:

http://www.venezuelacultural.com.ve/files/HIMEM.ZIP (11KB)

(great work of Renegade!)

You will need a mechanism to know the used memory and the
address of the used chunks.

My opinion is that could be a way and posibly, with the new
hardware posibilities, this could be --the way. Seems me that
by this way you don't have to use paging or swap files. So, this
could be a very fast plataform. But we need a minimal protection
mechanism if we work on a multiprogramming system with
multiple users.

Anyway, I'm not better than you about these themes, I continue
studing and working... Seems me a extensive subject.

nmt
Posted on 2001-08-29 14:12:15 by n u M I T_o r
here it is my one of my first OS tests ...

Its NASM specific because NASM was able to make a raw output bin file, this was placed in the first sectors of a floppy with Linux rawwrite.exe tool

it goes tp PM flat mode but without INTS, there is a bug in the INT routines so the LGIDT routine is comented

I guess i posted this before on the old messageboard



; bootsector system loader
; version 0.0.3
;
; build with:
; ===============
; nasm -f bin os4.asm -o os4.bin -l os4.lst
;
; Credits go to:
; =========================
; Linus Torvalds and Linux
; GazOS
; and may other anonymous heroes
;

BITS 16

ORG 0x0000

boot01:
jmp boot02
nop

; data zone , variables we may need
;========================================
boot_drv db 0 ; drive number we where loaded from
cs_segment dw 0
Track db 0
Sector db 0
Head db 0
Length dw 1
x1 dd boot01
x2 dd boot02

; back to code
; ===============================================
; BIOS loads this first 512bytes sector at linear 0000:7C00h
; so we set DS to 0x07C0
; in order to correctly access data references
; ===============================================
align 16

boot02:
cli ; please no interupts
mov ax,0x07C0
mov ds,ax
mov es,ax ; es same as ds

mov [boot_drv],dl ; save drive #

; here we make our own stack
; at 0x9000:0xFFF0 linear 0x0009:FFF0

mov ax,0x9000 ; segment for stack
mov ss,ax
mov sp,0xFFF0 ; offset for stack

sti ; enable ints again

; clear direction flag
; repetitive string operations
; will increment SI/DI from now on

cld

; print a short wellcome message

mov si,msg_001
call Print_Msg

; test our hex printing routine

mov dx,0xface ; arbitrary hex constant to print
call Print_Hex16
call Print_CRLF


mov ax,0x07C0 ; base memory for loading
mov es,ax
; ========================================================
; Load the Setup Code Sectors at linear 0x0000:7e00
; Note that ES is already set up above at ES=0x07C0
; buffer is at es:bx ie 0x7c00:0200 and 0x7C00+0x0200=0x7E00
; =========================================================

load_setup:
xor cx,cx
xor ah,ah ; func.no.0 = reset FDC
xor dl,dl ; drive.no=0 ie disk a:
int 0x13 ; use bios call

xor dx,dx ; drive 0, head 0
mov cl,2 ; sector 2, track 0
mov bx,0x0200 ; offset of loading
; address ES:BX = 07C00:0200, linear 0x0000:7E00
mov ah,2 ; func.no.2=read sectors
mov al,16 ; 8 sectors 8*512=4096=4k=0x1000h
; setup is loaded at 0x7E00-0x8E00
int 0x13 ; read it via bios call
jnc ok_load_setup ; if ok - continue

; Ouch...here we have an error.... :(

push ax ; save error code
call Print_CRLF ; newline
pop ax ; retrive error code
mov dx,ax
call Print_Hex16 ; print error code

; if error ... lets try it again ....

jmp load_setup

ok_load_setup:
mov si,msg_002 ; print happy message...
call Print_Msg


; nothig more to do here ...eh..
; bye-bye First Sector .... for now


; jmp far dword Sector_002

; QUICK HACK FOR A -FAR- JMP INSTRUCTION
DB 0xEA ; jump to sector 02
DW 0x7E00 ; offset
DW 0x0000 ; segment


; ************************************
; utility routines for the bootsector
; ************************************
;
; First a message printing routine
; using bios call to output ASCII letters to Screen
; until the last char=0 when it stops and returns
; ===================================================
Print_Msg:
lodsb ; al=[ds:si], si=si+1
or al,al
jz ok_msg1

; BIOS int 0x10 function 0x0E = write char to console
mov ah,0x0E ; ah=0x0e al=ascii code of char to output
int 10h
jmp Print_Msg
ok_msg1:
ret
;
; Print newline to Screen
; CR and LF are actually a newline
; ===================================================
Print_CRLF:
mov ax,0x0E0D ; al=CR=0x0D, ah=0x0E=print char fn
int 10h
mov ax,0x0E0A ; al=LF=0x0A
int 10h
ret
;
; print 16 bit value from DX in hexa format on Screen
; DX register has the value to print
; ======================================================
Print_Hex16:
mov cx, 4 ; 4 hex digits

PrintDigit:
rol dx, 4 ; rotate so that lowest 4 bits are used
mov ax, 0E0Fh ; ah = request, al = mask for nybble
and al, dl

add al, 90h ; convert al to ascii hex (four instructions)
daa ; somebody spent 1 hour
adc al, 40h ; to understand how this code works..
daa ; WOW!

int 10h ; call BIOS to print char
loop PrintDigit
ret

; ========================================================
; some messages i use in boot sector
; ========================================================
msg_001: db ">Loading SOL OS Ver. 0.0.3",10,13,0
msg_002: db ">Setup Code Loaded Ok! :) ",10,13,0

; ===============================================================
; NASM knows:
; $ =begining of curent line at assembly time
; $$=begining of current section at assembly time
; so expression $-$$ equals curent position in curent section
; or offset from the begining of current section
; ================================================================

times 510-($-$$) db 0 ; go to end of sector, ie 512-2=510

; ========================================
; boot disk signature is required
; at end of sector 1 Track 0
; or else BIOS will not execute this
; as a valid boot sector
; ========================================
BootSignature:
db 0x55,0xAA


; ==================================
; HERE sector 01 Physically ends
; ==================================

; ==============================================================
; HERE sector 02 Physically starts
; ==============================================================
; this sector will be loaded by previous code
; at addr linear 0x0000:7d00 ie segment:offset= 0x7c00:0200
;

Sector_002:

mov si,msg_003 ; message to show we are in the second
call Print_Msg ; sector now
;
jmp Setup_Start
;
; Some more messages we use in second sector
;
msg_003: db "Setup Code Started ",10,13,0,0
msg_A20_line: db "Enableing A20 line ",10,13,0
msg_005: db "Going to PM Mode...bye bye... ",10,13,0
msg_8259 db "Seting up 8259 Interupt Controller...",10,13,0

; ============================================
; this routine enables the infamouse A20 Line
; ============================================
Enable_A20:
call empty_8042
mov al,0xD1 ; command write
out 0x64,al
call empty_8042
mov al,0xDF ; A20 line is going to be on from now on
out 0x60,al
call empty_8042
ret

; =============================================================
; This routine checks that the keyboard command queue is empty
; (after emptying the output buffers)
; for A20 Line enableing commands
; it deals with the 8042 chip whitch is used
; as a keyboard controller in PCs
; =============================================================
empty_8042:
call Delay
in al,0x64 ; 8042 status port
test al,1 ; output buffer?
jz no_output
;
call Delay
in al,0x60 ; yes, then read it
jmp empty_8042 ; and of course we ignore it

no_output:
test al,2 ; is input buffer full?
jnz empty_8042 ; yes - loop
ret

; here is a short delay for input/output operations
;==================================================
Delay:
jmp delay_01
delay_01:
jmp delay_02
delay_02:
ret

; =====================================
; 8259 PIC initialization
; =====================================
Init_8259:
cli

mov si,msg_8259 ; tell the user
call Print_Msg ; what we do next

mov al, 11h ; ICW1 to both controllers
out 20h, al ; bit 0=1: ICW4 provided
call Delay ; bit 1=0: cascaded PICs
out 0A0h, al ; bit 2=0: call address interval 8
call Delay ; bit 4=1: at 1 (?)

mov al, 20h ; ICW2 PIC1 - offset of vectors
out 21h, al
call Delay

mov al, 28h ; ICW2 PIC2 - offset of vectors
out 0A1h, al
call Delay

mov al, 4h ; ICW3 PIC1 (master)
out 21h, al ; bit 2=1: irq2 is the slave
call Delay

mov al, 2h ; ICW3 PIC2
out 0A1h, al ; bit 1=1: slave id is 2
call Delay

mov al, 1h ; ICW4 to both controllers
out 21h, al ; bit 0=1: 8086 mode
call Delay
out 0A1h, al
call Delay

mov al, 0h ; OCW1 interrupt mask to both
out 20h, al ; no irq masked
call Delay
out 0A0h, al
call Delay

ret

; ==========================================================================
; Hope this will stop the FDC motor...
; this motor is also stopped by
; int 0x08=realtime clock but after 2 seconds
; and only if interupts are enabled....
; ==========================================================================
Kill_motor:
push dx
mov dx,0x3f2
xor al, al
out dx,al
pop dx
ret

; ==========================================
; This is our actual Setup 16bits Code
; hopefully it will:
; 1.setup as necesarry
; 2.go to protected mode
; 3.load the kernel
; 4.and fire up the kernel!
; ==========================================

Setup_Start:

; call Init_8259

;==================================
; Going to Protected Mode
; in 4 little steps:
;===================================
; STEP.0.
; ========
; Enable A20 line
; strange hadrware in PCs
; forces us to do this :)
;
mov si,msg_A20_line ; tell the user what we are
call Print_Msg ; going to do
;
call Enable_A20

;

;
; STEP.1.
; =========
; We disable Ints...lol.... once again?
; but it looks like some BIOS-es enable ints
; on int_13 and then forget to disable them again
; on exit

CLI
;
; STEP.2.
; ==========
; Set the GDT System Table
;
; db 0x66
; lidt [idt_48] ; load idt with 16:32 pointer to IDT

db 0x66 ; 32 bit instruction override
lgdt [gdt_48] ; load gdt with 16:32 pointer to GDT


; our last message from REAL MODE...
; strange but we cant print messages if ints are disabled?

; mov si,msg_005
; call Print_Msg


;
; STEP.3.
; Go To PROTECTED MODE!

;
MOV EAX, CR0
OR AL, 1
MOV CR0, EAX

; MicroP is now in "Protected (safe sex?) mode" :)

; pmode1: jmp pmode1
;
; jump far to selector1:pmode_next to clear pipeline ,etc
; and to load CS segment with the correct selector
; we also have to add 0x7C00 to any absolute address
; as we use no linker ;)
;
jmp dword 0x0008:0x7c00+pmode_next
;

;


pmode_next:
;===============================================================
; from now on we are in 32 bit protected mode
; and we hope never have to leave again :)
; but also never forget that here we have no help from bios :(
; so we have to know our way with ALL hardware i/o ports and stuff
;===============================================================
[BITS 32]

nop ; just padding
nop ; also

;================================================
; kill the floppy disk motor
; eh...allready having hardware problems :)
;
; at early testing stages
; this also told me...for the first time
; that I am in protected mode...at last
; without looseing control..:)
;=================================================

mov edx,0x03f2
xor eax,eax
out dx,al

;=================================================
; prepare segment registers
; all of them now hold segment descriptors
; SS is still a problem
; because i dont yet have a valid stack descriptor
; we now have:
; #1.selector 008h -code 32bits nonconforming base=0 size=4Giga
; #2.selector 010h -data 32bits read/write base=0 size=4Giga
; #3.selector 018h -data 32bits read/write base=0 size=4Giga
;=================================================================================
mov ax,0x0010 ; #2 segment descriptor=data r/w 4G
nop
nop
nop
;
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
;======================================================
; treat the StackSegment separately
; ... gently with that axe :)
; we will use the general data descriptor for now
; and setup a new stack starting at 2M boundry
; and expanding down of course
; this makes 2megabytes our minimum memory req
; and i hope our kernel will fit in just 1M
; also hope stack will never go too much down
; because we are not safe :(
;=======================================================
mov ss,ax
mov esp,(2*1024*1024) ; 2megabytes for stack :)
;
mov eax,0 ;for safety
push eax
push eax

mov ecx,80*5
mov edx,0xB8000
;
mic_loop:
mov al,"A"
mov bl,0x07
mov byte [edx],al
inc edx
mov byte [edx],bl
inc edx
;
dec ecx
or ecx,ecx
jnz mic_loop
;



test_loop:
in al,0x64
and al,0x01
jz test_loop ; no key then loop back

; we have a key

in al,0x60 ;get scan_code
and al,0x7f ;only one scan_code for both key_up and key_down
;
xor ecx,ecx
mov cl,al
shl ecx,2 ; *4
;
add ecx,kb_ascii_table+0x7C00 ; no linker so i have to do it :)
mov eax,[ecx]

mov edx,0xB8000+80*4*2+40*2 ;hmmm lots of absolute address here
mov byte [edx],al
;
cmp al,13 ; Enter Key
jz setup_ints

jmp test_loop


setup_ints:
;===============================

; first prepare the 8259 PIC

; call Init_8259_32



call Delay32


; now the infamouse LIDT instruction
;=================================================
; db 0x66 ; 32 bit instruction overide
lidt [idt_48] ; load idt with 16:32 pointer to IDT


int 5

;
; sti ; enable ints
jmp test_loop

big_loop:
nop
nop
cli
hlt

jmp big_loop



; here is a short delay for input/output operations
;==================================================
Delay32:
jmp delay_01_32
delay_01_32:
jmp delay_02_32
delay_02_32:
ret

; =====================================
; 8259 PIC initialization
; =====================================
Init_8259_32:
cli

; mov si,msg_8259 ; tell the user
; call Print_Msg ; what we do next

mov al, 11h ; ICW1 to both controllers
out 20h, al ; bit 0=1: ICW4 provided
call Delay ; bit 1=0: cascaded PICs
out 0A0h, al ; bit 2=0: call address interval 8
call Delay32 ; bit 4=1: at 1 (?)

mov al, 20h ; ICW2 PIC1 - offset of vectors
out 21h, al ; irq00 mapped to int020h
call Delay32

mov al, 28h ; ICW2 PIC2 - offset of vectors
out 0A1h, al ; irq08 mapped to int028h
call Delay32

mov al, 4h ; ICW3 PIC1 (master)
out 21h, al ; bit 2=1: irq2 is the slave
call Delay32

mov al, 2h ; ICW3 PIC2
out 0A1h, al ; bit 1=1: slave id is 2
call Delay32

mov al, 1h ; ICW4 to both controllers
out 21h, al ; bit 0=1: 8086 mode
call Delay
out 0A1h, al
call Delay32

mov al, 0h ; OCW1 interrupt mask to both
out 20h, al ; no irq masked
call Delay ; all irq's will trigger int's
out 0A0h, al
call Delay32

ret




; ======================
; interupt handlers
; ======================
align 32
;
int00_hand:
mov al,"0"
mov edx,0xB8000+2*0
mov byte [edx],al
jmp $
;
align 32
int01_hand:
mov al,"1"
mov edx,0xB8000+2*1
mov byte [edx],al
jmp $
;
align 32
int02_hand:
mov al,"2"
mov edx,0xB8000+2*2
mov byte [edx],al
jmp $
;
align 32
int03_hand:
mov al,"3"
mov edx,0xB8000+2*3
mov byte [edx],al
jmp $
;
align 32
int04_hand:
mov al,"4"
mov edx,0xB8000+2*4
mov byte [edx],al
jmp $
;
align 32
int05_hand:
mov al,"5"
mov edx,0xB8000+2*5
mov byte [edx],al
jmp $
;
align 32
int06_hand:
mov al,"6"
mov edx,0xB8000+2*6
mov byte [edx],al
jmp $
;
align 32
int07_hand:
mov al,"7"
mov edx,0xB8000+2*7
mov byte [edx],al
jmp $
;
align 32
int08_hand:
mov al,"8"
mov edx,0xB8000+2*8
mov byte [edx],al
jmp $
;
align 32
int09_hand:
mov al,"9"
mov edx,0xB8000+2*9
mov byte [edx],al
jmp $
;
align 32
int0A_hand:
mov al,"A"
mov edx,0xB8000+2*0x0A
mov byte [edx],al
jmp $
;
align 32
int0B_hand:
mov al,"B"
mov edx,0xB8000+2*0x0B
mov byte [edx],al
jmp $
;
align 32
int0C_hand:
mov al,"C"
mov edx,0xB8000+2*0x0C
mov byte [edx],al
jmp $
;
align 32
int0D_hand:
mov al,"D"
mov edx,0xB8000+2*0x0D
mov byte [edx],al
jmp $
;
align 32
int0E_hand:
mov al,"E"
mov edx,0xB8000+2*0x0E
mov byte [edx],al
jmp $
;
align 32
int0F_hand:
mov al,"F"
mov edx,0xB8000+2*0x0F
mov byte [edx],al
jmp $
;
align 32
int10_hand:
mov al,"0"
mov edx,0xB8000+2*0x10
mov byte [edx],al
jmp $
;
align 32
int11_hand:
mov al,"1"
mov edx,0xB8000+2*0x11
mov byte [edx],al
jmp $
;
align 32
int12_hand:
mov al,"2"
mov edx,0xB8000+2*0x12
mov byte [edx],al
jmp $
;
align 32
int13_hand:
mov al,"3"
mov edx,0xB8000+2*0x13
mov byte [edx],al
jmp $
;
align 32
int14_hand:
mov al,"4"
mov edx,0xB8000+2*0x14
mov byte [edx],al
jmp $
;
align 32
int15_hand:
mov al,"5"
mov edx,0xB8000+2*0x15
mov byte [edx],al
jmp $
;
align 32
int16_hand:
mov al,"6"
mov edx,0xB8000+2*0x16
mov byte [edx],al
jmp $
;
align 32
int17_hand:
mov al,"7"
mov edx,0xB8000+2*0x17
mov byte [edx],al
jmp $
;
align 32
int18_hand:
mov al,"8"
mov edx,0xB8000+2*0x18
mov byte [edx],al
jmp $
;
align 32
int19_hand:
mov al,"9"
mov edx,0xB8000+2*0x09
mov byte [edx],al
jmp $
;
align 32
int1A_hand:
mov al,"A"
mov edx,0xB8000+2*0x1A
mov byte [edx],al
jmp $
;
align 32
int1B_hand:
mov al,"B"
mov edx,0xB8000+2*0x1B
mov byte [edx],al
jmp $
;
align 32
int1C_hand:
mov al,"C"
mov edx,0xB8000+2*0x1C
mov byte [edx],al
jmp $
;
align 32
int1D_hand:
mov al,"D"
mov edx,0xB8000+2*0x1D
mov byte [edx],al
jmp $
;
align 32
int1E_hand:
mov al,"E"
mov edx,0xB8000+2*0x1E
mov byte [edx],al
jmp $
;
align 32
int1F_hand:
mov al,"F"
mov edx,0xB8000+2*0x1F
mov byte [edx],al
jmp $
;
align 4
int20_hand:
mov eax,0020h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int21_hand:
mov eax,0021h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int22_hand:
mov eax,0022h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int23_hand:
mov eax,0023h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int24_hand:
mov eax,0024h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int25_hand:
mov eax,0025h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int26_hand:
mov eax,0026h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int27_hand:
mov eax,0027h
jmp 0x0008:main_int_hand+0x7c00
;
align 4
int28_hand:
mov eax,0028h
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int29_hand:
mov eax,0029h
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int2A_hand:
mov eax,002Ah
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int2B_hand:
mov eax,002Bh
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int2C_hand:
mov eax,002Ch
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int2D_hand:
mov eax,002Dh
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int2E_hand:
mov eax,002Eh
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int2F_hand:
mov eax,002Fh
jmp 0x0008:main_int_hand+0x7c00;
;
align 4
int30_hand:
mov eax,0030h
jmp 0x0008:main_int_hand+0x7c00;
;
align 4





; ========================================
; Main interupt handler routine
; ========================================
align 32
main_int_hand:
iretd




; *********************************************
; ************* Descriptor tables *************
; *********************************************


; =============================================
; First the GLOBAL DESCRIPTOR TABLE
; witch can have a maximum of (8192 x 8bytes) entrys
; each 8 byte entry is an segment descriptor
; made of 3 fields:
; 1=BASE ADRESS of the SEGMENT
; 2=LIMIT of the SEGMENT
; 3=ACCESS RIGHTS/TYPE of the SEGMENT
;
; those 3 fields are (stupidely?) bit mixed and merged
; or encoded in a strange way....
;
;

align 32

BIG_GDT:
;===========================
; #0 segment descriptor
; dummy
; Intel(c)(r) specifications
;============================
db 0,0,0,0 ; the first selector is dummy
db 0,0,0,0 ; and unused even by the microP
;
; so loading a segment register with a "zero" selector
; will show that you dont use that segment
; it is ok with the exception of the CS and SS segment registers
; witch will generate a protection fault if loaded with zero selector
;


; ===========================
; #1 segment descriptor
; index=0x08
; code
; read is ok
; nonconforming
; ring 0
; base=0
; limit=4Giga
; ===========================
;
; THIS IS/WAS my first "real" segment descriptor
; I am so proud of it....cause i thought i will never make it
; by hand...
; ========================================================================
dw 0xFFFF ; limit00 to limit15=0xFFFF=4GigaByte
dw 0x0000 ; base00 to base15=0x0000
;
db 0x00 ; base16 to base23=0x00
db 0x9A ; 0x9=1001=P/DPL/S
; 0xA=1010=Type=code/nonconforming/read
;
; P=1=Present
; DPL=00=Maximum privilege level ...requ? or applied?
; S=1=Code or Data Segment (ie not a system segment)
;
; Type=1010=b11:b10:b09:b08
; b11=1=Code
; b10=0=nonconforming
; b09=1=Read from code segment is acceptable
; please note that writeing to a code segment in never
; acceptable from Intel's point of view...
; b08=0=Accessed is zero...until actually loaded?


db 0xCF ; limit16 to limit19=0xF
; 0xC=1100=G:D/B:0:AVL
;
; G=1=Granularity=4Kbyte increments to the limit
; D/B=1=32 bits segment
; AVL=0=this bit is available for use by system software..
; they are generouse 1bit for free...wow! :)
;

db 0x00 ; base24 to base31=0x00
;==========================================================================

; ===========================
; #2 segment descriptor
; index=0x10
; data
; read / write
; ring 0
; base=0
; limit=4Giga
; ===========================
dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
dw 0x0000 ; base address=0
dw 0x9200 ; data read/write
dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit)

; ===========================
; #3 segment descriptor
; index=0x18
; read / write
; base=0
; limit=4Giga
; ===========================
dw 0xFFFF ; 4Gb - (0x100000*0x1000 = 4Gb)
dw 0x0000 ; base address=0
dw 0x9200 ; data read/write
dw 0x00CF ; granularity=4096, 386 (+5th nibble of limit)



align 32

BIG_IDT:
; ======================================================================
; interupt gate 00
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int00_hand+0x7c00 ; offset 0...15

; interupt gate 01
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int01_hand+0x7c00 ; offset 0...15

; interupt gate 02
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int02_hand+0x7c00 ; offset 0...15

; interupt gate 03
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int03_hand+0x7c00 ; offset 0...15

; interupt gate 04
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int04_hand+0x7c00 ; offset 0...15

; interupt gate 05
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int05_hand+0x7c00 ; offset 0...15

; interupt gate 06
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int06_hand+0x7c00 ; offset 0...15

; interupt gate 07
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int07_hand+0x7c00 ; offset 0...15

; interupt gate 08
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int08_hand+0x7c00 ; offset 0...15

; interupt gate 09
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int09_hand+0x7c00 ; offset 0...15

; interupt gate 0A
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int0A_hand+0x7c00 ; offset 0...15

; interupt gate 0B
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int0B_hand+0x7c00 ; offset 0...15

; interupt gate 0C
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int0C_hand+0x7c00 ; offset 0...15

; interupt gate 0D
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int0D_hand+0x7c00 ; offset 0...15

; interupt gate 0E
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int0E_hand+0x7c00 ; offset 0...15

; interupt gate 0F
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int0F_hand+0x7c00 ; offset 0...15

; interupt gate 10
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int10_hand+0x7c00 ; offset 0...15

; interupt gate 11
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int11_hand+0x7c00 ; offset 0...15

; interupt gate 12
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int12_hand+0x7c00 ; offset 0...15

; interupt gate 13
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int13_hand+0x7c00 ; offset 0...15

; interupt gate 14
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int14_hand+0x7c00 ; offset 0...15

; interupt gate 15
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int15_hand+0x7c00 ; offset 0...15

; interupt gate 16
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int16_hand+0x7c00 ; offset 0...15

; interupt gate 17
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int17_hand+0x7c00 ; offset 0...15

; interupt gate 18
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int18_hand+0x7c00 ; offset 0...15

; interupt gate 19
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int19_hand+0x7c00 ; offset 0...15

; interupt gate 1A
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int1A_hand+0x7c00 ; offset 0...15

; interupt gate 1B
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int1B_hand+0x7c00 ; offset 0...15

; interupt gate 1C
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int1C_hand+0x7c00 ; offset 0...15

; interupt gate 1D
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int1D_hand+0x7c00 ; offset 0...15

; interupt gate 1E
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int1E_hand+0x7c00 ; offset 0...15

; interupt gate 1F
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int1F_hand+0x7c00 ; offset 0...15

; interupt gate 20
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int20_hand+0x7c00 ; offset 0...15

; interupt gate 21
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int21_hand+0x7c00 ; offset 0...15

; interupt gate 22
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int22_hand+0x7c00 ; offset 0...15

; interupt gate 23
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int23_hand+0x7c00 ; offset 0...15

; interupt gate 24
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int24_hand+0x7c00 ; offset 0...15

; interupt gate 25
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int25_hand+0x7c00 ; offset 0...15

; interupt gate 26
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int26_hand+0x7c00 ; offset 0...15

; interupt gate 27
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int27_hand+0x7c00 ; offset 0...15

; interupt gate 28
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int28_hand+0x7c00 ; offset 0...15

; interupt gate 29
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int29_hand+0x7c00 ; offset 0...15

; interupt gate 2A
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int2A_hand+0x7c00 ; offset 0...15

; interupt gate 2B
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int2B_hand+0x7c00 ; offset 0...15

; interupt gate 2C
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int2C_hand+0x7c00 ; offset 0...15

; interupt gate 2D
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int2D_hand+0x7c00 ; offset 0...15

; interupt gate 2E
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int2E_hand+0x7c00 ; offset 0...15

; interupt gate 2F
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int2F_hand+0x7c00 ; offset 0...15

; interupt gate 30
dw 0x0000 ; offset 31...16
db 10001110b ; P=1,dpl=00,0,d=1=32bit,xxx
db 00000000b ; rezerved
dw 0x0008 ; our only code segment selector
dw int30_hand+0x7c00 ; offset 0...15


;
times 8*255 db 0

; data structures req. for LGIT and LGDT instructions
; ===================================================
idt_48:
dw 0x017f ; idt limit=30h*8-1=180-1=17f entries
dd BIG_IDT+0x7c00 ; idt base

gdt_48:
dw 0x0004*0x08 ; gdt limit=4 max GDT entries
dd BIG_GDT+0x7c00 ; gdt base






kb_ascii_table:
dd 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 9
dd 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13, 0, 'a', 's'
dd 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`', 0, 92, 'z', 'x', 'c', 'v'
dd 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 3, 3, 3, 3, 8
dd 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0
dd 0, 0, 0, 127, 0, 0, 92, 3, 3, 0, 0, 0, 0, 0, 0, 0
dd 13, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0

kb_capslock_table:
dd 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 9
dd 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 13, 0, 'A', 'S'
dd 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', 39, '`', 0, 92, 'Z', 'X', 'C', 'V'
dd 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 3, 3, 3, 3, 8
dd 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0
dd 0, 0, 0, 127, 0, 0, 92, 3, 3, 0, 0, 0, 0, 0, 0, 0
dd 13, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0

kb_shift_table:
dd 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 126, 126
dd 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 126, 0, 'A', 'S'
dd 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', 34, '~', 0, '|', 'Z', 'X', 'C', 'V'
dd 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, 1, 0, 1, 1, 1, 1, 1
dd 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0
dd 0, 0, 1, 127, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0
dd 13, 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', 0, 0, 0, 0, 0

kb_control_table:
dd 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 127, 127
dd 17, 23, 5, 18, 20, 25, 21, 9, 15, 16, 2, 2, 10, 0, 1, 19
dd 4, 6, 7, 8, 10, 11, 12, 0, 0, 0, 0, 0, 26, 24, 3, 22
dd 2, 14, 13, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2
dd 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
dd 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0


Posted on 2001-08-29 21:26:37 by BogdanOntanu
Thank you boys !!!!!!
n u M I T_o r your links are good, I think we should exchange our experiences and progresses in system programming.
BogdanOntanu, your source code is great, I will carefully study it
because it seems to me a good base to developing a protected mode system.
Anyway, I think I have been successful in Flat Real Mode !!!
I have modified, in NASM syntax, the source code of gem0022.txt,
making little modifications; I don't fully understand the bitfields of
Global Descriptor Table yet , but it is a matter of concentration and time.So I left unaltered those values and the operation made by the code here and switched to pmode. If you load segment register with 0 the system crash, so I left the original value of 24.
Then we are back in real mode, but our segment should be 4Gb.
My part of program performs stupid and non optimized operation such as printing a message by using DOS ( I saved the ds early in the code at an arbitrary location ), displaying the Vga ROM BIOS using a flat addressing mode, and finally, writing and reading a character at a location in extended memory. I use different registers, so, if you see this char in the lower right corner of your screen, this means that this should came from extended memory.

The file is a simple .com called a.asm
The command line :

nasmw a.asm -o a.com
I restart win98 in DOS mode and launch the program; I haven't noticed any problem to restart windows yet ( but they could happen).
So, thanks a lot.

;============================================







Mem32_GDT dw 0,0,0,0

dw 0ffffh,0ffh,9a00h,0
dw 0ffffh,0ffh,9200h,0
dw 0ffffh,0ffh,9200h,8fh

GDTptr dw GDTptr-1-Mem32_GDT
dd Mem32_GDT ; Absolute adress GDTtable
dw 0

mes db 'Hello World$'




START:

;Save ds at an arbitrary location to
;display message with DOS later

mov di, 0x0000
mov ax, 0x5000
mov es, ax;
mov ax, ds
mov ,ax;

;=[0x5000:0x0000]


mov ax,cs ; set up GDT for this code segment
mov ds,ax
movzx eax,ax
shl eax,4
add ,eax
lgdt

mov ax,cs
and eax,65535
shl eax,4
mov ,ax;
mov ,ax
ror eax,16
mov ,al
mov ,al
mov ,ah
mov ,ah

cli ; no interrupts

mov eax,cr0; set protected mode
or al,1
mov cr0,eax

pmode:

mov ax,24; now we are in protected mode;
mov ds,ax; set all selector limits to 4 GB
mov es,ax;
mov fs,ax ;
mov gs,ax;

mov eax,cr0; restore real mode
and al,0feh
mov cr0,eax

;db 0eah; far jump to rmode label (unnecessary with Pentium)
;dw rmode
;dw .text ; (.text is not correct)

rmode:

clc ; now we are back in real mode, zero carry
sti ; to indicate ok and enable interrupts

;Restore old cs for DOS print string message

mov di, 0
mov ax, 0x5000
mov es, ax;=[0x5000:0x0000]
mov ax, ; get old ds
mov ds, ax

;Print string

mov dx, mes;
mov ah, 9;
int 21h;

;OK, I want to read VGA BIOS at ADDRESS 0xC000:0x0000
;In a flat model it should be byte number 786432
;I will use register ds = 0 (16 bit) and esi (32 bit offset)

mov ax, 0
mov ds, ax
mov esi, 786432;

;Now a non optimized, primitive routine to access Video Page
;starting at address 0xB800:0x0000
;I will use es di, both are 16 bit registers

mov ax, 0xB800
mov es, ax
mov di, 0

;=[0xB800:0x0000]

mov cx, 1200

ShowChar

;read char in bh
mov bh,

;write char in video memory
mov ,bh

;point to next char
inc esi;

;2 increments to skip char attributes
inc di;
inc di;

loop ShowChar

;OK, now I want to write my own char at an
;arbitrary address >16 Mb in RAM
;After writing, I want to read it
;If all is ok, I should be displayed in
;the down right corner of the screen

;put a face at 24? Mb

mov esi, 25165824; 24? Mb
mov bh, 0x01;
mov , bh;

;read face from location 25165824 using another register

mov al,

;point to corner
mov di, 3998;
;Display my char
mov ,al

End
mov ah, 0x4c;
int 21h
Posted on 2001-08-30 03:58:13 by fooCoder
> n u M I T_o r your links are good, I think we should
> exchange our experiences and progresses in system programming.

Of course. Here is my email:

numit_or@iname.com

Please, write me, I've finded more info in the Intel Manual.

> I don't fully understand the bitfields of
> Global Descriptor Table yet

The GDT structure is an array of 8 byte (64 bits).
But there are some types of Segment Descriptor we
can define. Intel explains the general descriptor
format for all types of segment descriptors:

bits 0-15: Segment Limit (15:00) - Size of the segment
bits 15-31: Segment base (15:00) - location of byte 0 of the segment.
bits 32-39: Segment base (23:16)
bits 40-43: Type. Indicates the segment or gate type and specifies the
possible kinds of access.
bit 44: Descriptor type (0=system, 1=code or data)
bits 45-46: P - Segment present.
bits 48-51: Segment Limit (19:16)
bit 52: AVL - Available for use by system software (programmer use)
bit 53: 0
bit 54: D/B: Default operation size (0=16-bit segment, 1=32-bit seg)
bit 55: granularity
bit 56: base (31:24)

About the base: the processor puts together the to segment limit fields
to form a 20-bit value. Ther granularyty field says to the processor
how interpret the segment limit.

fooCoder, I will test your code...


BogdanOntanu:
Great source code! It will be very useful for me. Like fooCoder,
I will carefully study it. Thanks!

nmt
Posted on 2001-08-30 13:25:07 by n u M I T_o r
Thank you n u M I T_o r, I will write you soon (my email address is blueeyestwo@hotmail.com).
Following the waves of enthusiasm, I have quickly written
a ram dumper that allow you to navigate the memory.
It is brutal but it works.
You start viewing 4000 bytes from address 1048576 ( the first byte is in the upper left corner of the screen, the last in the lower right corner ).
Press '4' to advance 1 byte, press '3' to go back.
Press any key ( es. SPACEBAR ) to advance to the next 4000 bytes or press 'b' to go back 4000 bytes.
Press '2' to advance 1 Megabyte or '1' to do the opposite.
Press 'q' to quit.
You should carefully consider how much RAM you have because, if you attempt to read a non existing address, the system hangs.
So adjust the correct value in CheckLimit.
If you go above the limit or below 0, you return to address 0 ( an interesting address, you can see the Keyboard Buffer and Timer Ticks Counter to modify their values, just keep up pressing '1' ).

If you use Win98 restart the PC in DOS mode and launch the program ( and browse . . . .).
If you start from DOS, the Extended Memory should be free ( who knows ?)

I repeat, it is only a prototype but I have seen interesting things with it!

Bye,

fooCoder

;;
;; a1.asm brutal ram dumper ( ALL YOUR RAM !!)
;; nasmw a1.asm -o a1.com







Mem32_GDT dw 0,0,0,0

dw 0ffffh,0ffh,9a00h,0
dw 0ffffh,0ffh,9200h,0
dw 0ffffh,0ffh,9200h,8fh

GDTptr dw GDTptr-1-Mem32_GDT
dd Mem32_GDT ; Absolute adress GDTtable
dw 0



START:

mov ax,cs ; set up GDT for this code segment
mov ds,ax
movzx eax,ax
shl eax,4
add ,eax
lgdt

mov ax,cs
and eax,65535
shl eax,4
mov ,ax;
mov ,ax
ror eax,16
mov ,al
mov ,al
mov ,ah
mov ,ah

cli ; no interrupts

mov eax,cr0 ; set protected mode
or al,1
mov cr0,eax

pmode:
mov ax,24 ; now we are in protected mode;
mov ds,ax ; set all selector limits to 4 GB
mov es,ax ;
mov fs,ax ;
mov gs,ax ;

mov eax,cr0 ; restore real mode
and al,0feh
mov cr0,eax

rmode:
clc ; now we are back in real mode, zero carry
sti ; to indicate ok and enable interrupts

mov ax, 0
mov ds, ax
mov ax, 0xB800;
mov es, ax;

;;;;;;;;Start at 1 Mb

mov esi, 1048576;

MEMEDIT

;es = 0xB800
;ds = 0
;esi = 1048576
;di = 0;

mov cx, 4000
mov di, 0x0000;

Leggi
;read char in bh
mov bh,

;write char in video memory
mov ,bh

;point to next char
inc esi;

;2 increments to skip char attributes
inc di;
inc di;
loop Leggi

mov ah, 0x00
int 0x16;
quit
cmp al, 'q'
je End
MegaAdd
cmp al, '2'
jnz MegaTog
add esi, 1048576
call CheckLimit
MegaTog
cmp al, '1'
jnz back
sub esi, 1048576+8000
call CheckLimit
back
cmp al, 'b'
jnz forw1
sub esi, 8000
call CheckLimit

forw1
cmp al, '4'
jnz back1
sub esi, 3999
call CheckLimit
back1
cmp al, '3'
jnz NextPage
sub esi, 4001
call CheckLimit
NextPage
jmp MEMEDIT

End
mov ah, 0x4c;
int 21h

CheckLimit

;Excursion 0-128 Mb is 0 to 0x8000000 - 8000 byte
;On this PC 0 - 64 Mb is 0 to 0x4000000 - 8000 byte
;Put here the value of your RAM

cmp esi,0
ja Maggiore; if > 0
mov esi, 0
Maggiore
cmp esi, 0x4000000 - 8000
jna Torna; if not above Torna
mov esi, 0
Torna
ret
Posted on 2001-08-31 08:38:25 by fooCoder
flat real mode is baaad carma. First of all, it's not compatible with
any "real" operating system, and it can't use emm386 either.
Next, your code is still stuck in 16bit. You get no 32bit instructions,
unless you use those dreaded 66h and 67h prefixes. Memory management
is only really possible with XMS, and you also constantly have to
check whether A20 is enabled or not (think there's an XMS function
call to handle this). flat realmode / voodo / unreal mode tends to
be pretty buggy as well. So I'd advise you to only study it as a
curiosity, never ever use it for anything.

As for os-development in general, there's a lot of good resources
around. Sabre's OS stuff (can't remember URL, but it should be easy
to find) is a good starting point with links and stuff.

Btw, if you should bump into the V2OS project, don't take the stuff
they say too seriously. They simply don't know what they're talking about.

Protection is a good thing. It might be a bit difficult to program, but
it gives so many wonderful benefits. And doesn't really affect your
program speed. Anybody thinking user apps should run ring0 oughta
be bitchslapped. Paging and ring0<>ring3 splitting are your friends.
Don't bother about segmented "protection", it's no use really. Stay
with 32bit flat protected mode, like windows, linux, bsd, and anything
else that's worth more than a penny. If you ever come anywhere,
be sure to use paging to separate processes in memory. Paging
is REALLY your friend, you can do lots of neat stuff with it.
Posted on 2001-08-31 10:51:57 by f0dder