video memory

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
mobruan
Member
Member
Posts: 71
Joined: Thu Oct 09, 2008 8:25 am
Location: Rio de Janeiro - Brazil

video memory

Post 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
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: video memory

Post by JohnnyTheDon »

AFAIK, it should be

Code: Select all

mov byte [0xb8000], 0x41
mov byte [0xb8001], 0x7
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: video memory

Post 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?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
mobruan
Member
Member
Posts: 71
Joined: Thu Oct 09, 2008 8:25 am
Location: Rio de Janeiro - Brazil

Re: video memory

Post by mobruan »

No, the code assembles...
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: video memory

Post 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
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
mobruan
Member
Member
Posts: 71
Joined: Thu Oct 09, 2008 8:25 am
Location: Rio de Janeiro - Brazil

Re: video memory

Post 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:

User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: video memory

Post 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.
mobruan
Member
Member
Posts: 71
Joined: Thu Oct 09, 2008 8:25 am
Location: Rio de Janeiro - Brazil

Re: video memory

Post 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. 
mobruan
Member
Member
Posts: 71
Joined: Thu Oct 09, 2008 8:25 am
Location: Rio de Janeiro - Brazil

Re: video memory

Post by mobruan »

any ideias...?
obs: my code is the first one showed.
thooot
Member
Member
Posts: 30
Joined: Sun Jun 01, 2008 11:20 am

Re: video memory

Post 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]
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: video memory

Post 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.
Last edited by kmtdk on Sat Jan 03, 2009 4:03 pm, edited 1 time in total.
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Re: video memory

Post 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)
mobruan
Member
Member
Posts: 71
Joined: Thu Oct 09, 2008 8:25 am
Location: Rio de Janeiro - Brazil

Re: video memory

Post by mobruan »

IT WORKED!!!!
thanks!
Post Reply