Page 1 of 1

video memory

Posted: Fri Jan 02, 2009 7:04 pm
by mobruan
hi, i want to write at screen an ascii, i try the following but didnt work....

mov ax, 0x10 ;ds seletor - base 0x0000
mov ds, ax

mov [0xb8000], byte 0x41
mov [0xb8001], byte 0x7

obs: im in pe mode

Re: video memory

Posted: Fri Jan 02, 2009 7:54 pm
by JohnnyTheDon
AFAIK, it should be

Code: Select all

mov byte [0xb8000], 0x41
mov byte [0xb8001], 0x7

Re: video memory

Posted: Sat Jan 03, 2009 3:56 am
by Combuster
If the first one would be the problem it also wouldn't assemble (missing operand size). If it assembles then doesn't work, then I don't know what the exact problem would be as it should work (unless some other context is wrong) - does it crash or anything?

Re: video memory

Posted: Sat Jan 03, 2009 7:38 am
by mobruan
No, the code assembles...

Re: video memory

Posted: Sat Jan 03, 2009 7:49 am
by kmtdk
well
first of all 0x07 is not a good char to display.
try this instead:

Code: Select all

mov esi,0xb8000
mov ax,0x0f61 
mov [esi],ax ; prints an "a" 
but if it dont work, we will need to know a few things more:
Have you entered paging ??
have you changed videomode ??
and sutch things.

KMT dk

Re: video memory

Posted: Sat Jan 03, 2009 10:43 am
by mobruan
Hi, the code is this:

Code: Select all

org 0x07c00

start:

bits 16

cli

lgdt [gdt_addr]
mov eax, cr0
or eax, 0x01
mov cr0, eax
jmp 0x08:codigo
sti


bits 32
codigo:


mov ax, word 0x10    
mov ds, word ax

mov [0xb8000], byte 0x61
mov [0xb8001], byte 0x0f

spin: jmp spin

isr:


bits 16

gdt_addr:
lim dw 23
base dd gdt

idt_addr:
limite dw 263
bas dd idt

idt:
times 32 dd 0
off1 dw 0
sel dw 0x10
res  db 0
misc db 0x8e
off2 dw 0
end_idt:

gdt:

null dd 0
null2 dd 0

c_limite dw 0xffff
c_base dw 0x0000
c_base2 db 0x00
c_type db 0x98
c_limite2 db 0xcf
c_base3 db 0x00

d_limite dw 0xffff
d_base dw 0x0000
d_base2 db 0x00
d_type db 0x92
d_limite2 db 0xcf
d_base3 db 0x00

end_gdt:


Re: video memory

Posted: Sat Jan 03, 2009 10:59 am
by 01000101
I'd set all of your segment registers to AX instead of just DS.
try something like this...

Code: Select all

codigo:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

mov ebx, 0xB8000
mov byte [es:ebx], 'P'    ; char 'P'
inc ebx
mov byte [es:ebx], 0x0A    ; attribute 'bright green foreground'
I have a feeling that your code is using ES as it's segment register for video memory references and since it is uninitialized, it could be pointing just about anywhere.

Re: video memory

Posted: Sat Jan 03, 2009 11:07 am
by mobruan
it didnt work...i copied this code from somewhere, it´s working, and i think its exact the same as mine. i dont know whats going wrong...

Code: Select all

org 0x07c00             ; Start address 0000:7c00 
jmp short begin_boot   ; Jump to start of boot routine & skip other data

bootmesg db "Our OS boot sector loading ......"
pm_mesg  db "Switching to protected mode ...."

dw 512                   ; Bytes per sector
db 1		    ; Sectors per cluster
dw 1		    ; Number of reserved sectors
db 2		    ; Number of FATs
dw 0x00e0	    ; Number of dirs in root
dw 0x0b40 	    ; Number of sectors in volume
db 0x0f0	               ; Media descriptor
dw 9		    ; Number of sectors per FAT
dw 18		    ; Number of sectors per track
dw 2		    ; Number of read/write sectors
dw 0		    ; Number of hidden sectors

print_mesg :
   mov ah,0x13	    ; Fn 13h of int 10h writes a whole string on screen
   mov al,0x00	    ; bit 0 determines cursor pos,0->point to start after			               ; function call,1->point to last position written
   mov bx,0x0007	    ; bh -> screen page ie 0,bl = 07 ie white on black
   mov cx,0x20	    ; Length of string here 32 
   mov dx,0x0000	    ; dh->start cursor row,dl->start cursor column
   int 0x10	    ; call bios interrupt 10h
   ret		    ; Return to calling routine

get_key :
   mov ah,0x00	  
   int 0x16              ; Get_key Fn 00h of 16h,read next character
   ret

clrscr :
   mov ax,0x0600      ; Fn 06 of int 10h,scroll window up,if al = 0 clrscr
   mov cx,0x0000      ; Clear window from 0,0 
   mov dx,0x174f      ; to 23,79
   mov bh,0	   ; fill with colour 0
   int 0x10	   ; call bios interrupt 10h
   ret

begin_boot :
   call clrscr             ; Clear the screen first
   mov bp,bootmesg     ; Set the string ptr to message location
   call print_mesg       ; Print the message
   call get_key	    ; Wait till a key is pressed
bits 16
   call clrscr	    ; Clear the screen
   mov ax,0xb800	    ; Load gs to point to video memory
   mov gs,ax	    ; We intend to display a brown A in real mode
   mov word [gs:0],0x641   ; display
   call get_key          ; Get_key again,ie display till key is pressed	
   mov bp,pm_mesg	    ; Set string pointer   	
   call print_mesg	    ; Call print_mesg subroutine   
   call get_key          ; Wait till key is pressed
   call clrscr             ; Clear the screen
   cli		    ; Clear or disable interrupts
   lgdt[gdtr]	    ; Load GDT	
   mov eax,cr0	    ; The lsb of cr0 is the protected mode bit
   or al,0x01	    ; Set protected mode bit
   mov cr0,eax	    ; Mov modified word to the control register
   jmp codesel:go_pm

bits 32
go_pm : 
   mov ax,datasel   
   mov ds,ax	       ; Initialise ds & es to data segment
   mov es,ax	
   mov ax,videosel	       ; Initialise gs to video memory
   mov gs,ax	
   mov word [gs:0],0x741 ; Display white A in protected mode
spin : jmp spin             ; Loop

bits 16
gdtr :
   dw gdt_end-gdt-1      ; Length of the gdt
   dd gdt		       ; physical address of gdt
gdt
nullsel equ $-gdt           ; $->current location,so nullsel = 0h
gdt0 		       ; Null descriptor,as per convention gdt0 is 0
   dd 0		       ; Each gdt entry is 8 bytes, so at 08h it is CS
   dd 0                      ; In all the segment descriptor is 64 bits
codesel equ $-gdt	       ; This is 8h,ie 2nd descriptor in gdt
code_gdt		       ; Code descriptor 4Gb flat segment at 0000:0000h
   dw 0x0ffff	       ; Limit 4Gb  bits 0-15 of segment descriptor
   dw 0x0000	       ; Base 0h bits 16-31 of segment descriptor (sd)
   db 0x00                  ; Base addr of seg 16-23 of 32bit addr,32-39 of sd	
   db 0x09a	       ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor				       ; privilege level 0-3,Segment descriptor 1 ie code	    		                  ; or data seg descriptor,Type of seg,Accessed bit
   db 0x0cf	       ; Upper 4 bits G,D,0,AVL ->1 segment len is page		                                     ; granular, 1 default operation size is 32bit seg		                              ; AVL : Available field for user or OS
                              ; Lower nibble bits 16-19 of segment limit
   db 0x00	       ; Base addr of seg 24-31 of 32bit addr,56-63 of sd
datasel equ $-gdt	       ; ie 10h, beginning of next 8 bytes for data sd
data_gdt		       ; Data descriptor 4Gb flat seg at 0000:0000h
   dw 0x0ffff	       ; Limit 4Gb
   dw 0x0000	       ; Base 0000:0000h
   db 0x00	       ; Descriptor format same as above
   db 0x092
   db 0x0cf
   db 0x00
videosel equ $-gdt	       ; ie 18h,next gdt entry
   dw 3999	       ; Limit 80*25*2-1
   dw 0x8000	       ; Base 0xb8000
   db 0x0b
   db 0x92	       ; present,ring 0,data,expand-up,writable
   db 0x00	       ; byte granularity 16 bit
   db 0x00
gdt_end

times 510-($-$$)  db 0  ; Fill bytes from present loc to 510 with 0s
              dw 0x0aa55  ; Write aa55 in bytes 511,512 to indicate that			                  ; it is a bootable sector. 

Re: video memory

Posted: Sat Jan 03, 2009 11:58 am
by mobruan
any ideias...?
obs: my code is the first one showed.

Re: video memory

Posted: Sat Jan 03, 2009 1:03 pm
by thooot
You're not setting up your segments in 16-bit mode so I'm not sure what the "lgdt [gdt_addr]" line will actually end up loading. I would try changing the first bit to the following:

Code: Select all

org 0x07c00
bits 16

jmp short start             ; load cs
start:

mov ax, cs
mov ds, ax                   ; load ds
mov es, ax                   ; load es


cli

lgdt [gdt_addr]

Re: video memory

Posted: Sat Jan 03, 2009 2:22 pm
by kmtdk
well
the LGDT use DS to point into memory
so if DS is not set propperly, you will not load the rigt value
DS has to 0x0000; since you told the compiler that it is working at 0x7c00
just in case you want an example, i will just give one:

Code: Select all

org 0x7c00

mov ax,0x0000
mov ds,ax ; this is just for testing !!

LGDT  [GDT_address] ; still points to the GDT
Mov eax,CR0
or eax,0x80000000
mov CR0,eax ; 32 bit mode entered
jmp 0x08:pmode

pmode:
use32
mov ax,0x10
mov ds,ax
mov es,ax
mov gs,ax
mov fs,ax

mov ax,0x0f61 ; white "a"
mov [0xb8000],ax ; print to the screen
mov [0xb8000+2],ax ; just print once more :P
hlt ; so we dont take 100 % cpu power ...
jmp $ ; loop for ever


; here you can have the GDT code, please inseart yourself

To show what i mean about the LGDT command:

Code: Select all

LGDT [GDT_address]
looks like this: (if wee assume that "GDT_address" is 0x7d20, and DS is 0x0100)
LGDT [DS:0x7d20]
and some fast calculation, tells me that the real addres is then:
(0x100*10)+0x7d20 = 0x8d20

hope this is enought .....

KMT dk



EDIT:
it was an example, and i know you will have to do some changes to make it work, it was just to give view on how to do it.

Re: video memory

Posted: Sat Jan 03, 2009 3:49 pm
by Dex
Min Pmode boot code =

Code: Select all

;************************************
; By Dex
; Assemble with fasm 
; c:\fasm Pmode.asm Pmode.bin
;
;************************************
org 0x7C00 
use16
;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00 
;*****************************
; Setting up, to enter pmode.
;*****************************
        cli 
        lgdt  [gdtr]
        mov   eax, cr0
        or    al,0x1 
        mov   cr0,eax
        jmp   0x10: protected
;*****************************
; Pmode. ;-)
;*****************************
use32
protected:
        mov   ax,0x8 
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   esp,0x7C00
;*****************************
; Turn floppy off (if space).
;*****************************
        mov   dx,3F2h
        mov   al,0
        out   dx,al
;*********************************
; Print T in the right hand corner
;*********************************
        mov   byte [es:0xB809E], "T"
;*********************************
; Just loop for now
;*********************************
        jmp   $
;*************************************
; GDT. 
;*************************************
gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF
gdt_end:

gdtr:       dw gdt_end - gdt - 1
            dd gdt
;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-start)  db 0
dw 0xaa55
Compare your to it (NOTE: fasm code)

Re: video memory

Posted: Sat Jan 03, 2009 6:04 pm
by mobruan
IT WORKED!!!!
thanks!