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!