format binary as 'ima'
org 7c00h
use16
start:
mov ax, cs ; for GDT -> DS:GDTR
mov ds, ax
mov es,ax
; ????????? ? ?????? (?????? ???? ?????? LFB)
mov ax,4f01h
mov cx,4112h
mov edi,VBETABLE2
int 10h
mov ax,4f02h
mov bx,4112h
int 10h
; ????? ?20:
in al,92h
or al,2
out 92h,al
cli
in al,70h
or al,80h
out 70h,al
lgdt fword [GDTR]
lidt fword [IDTR]
; Set the protected mode
mov eax,cr0
or eax,1
mov cr0,eax
jmp CODE_SELECTOR : CODE_32BIT
NULL_SELECTOR = 0 ; ??????? ????????
CODE_SELECTOR = 1 shl 3 ; ???????? ????
DATA_SELECTOR = 2 shl 3 ; ???????? ??????
;VIDEO_SELECTOR = 3 shl 3 ; ???????? ?????? ???????????
GDTR: ; Global Descriptors Table Register
dw 4*8-1 ; ?????? GDT
dd GDT ; ???????? GDT
GDT:
; ??????? ??????????
NULL_descr db 8 dup (0)
; ?????????? 32-?????????? ???????? ????: ???? = 00000000h, ?????? = FFFFFFFFh
CODE_descr db 0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b , 00h
; ?????????? 32-?????????? ???????? ??????: ???? = 00000000h, ?????? = FFFFFFFFh
DATA_descr db 0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b , 00h
; ?????????? ???????? ???????????: ???? = 000B8000h, ?????? = 0000FFFFh (? ?????? ?????? ?? ????????????)
;VIDEO_descr db 0FFh, 0FFh, 00h, 80h, 0Bh, 10010010b, 01000000b , 00h
USE32
CODE_32BIT:
; ??????? ??????????
sti
in al, 70h
and al, 7Fh
out 70h, al
mov ax,DATA_SELECTOR
mov ds,ax ; ds ? es - ????????? ?? ??????
mov es,ax
mov ecx,230400
mov edi, dword ptr VBETABLE2+028h ; Adress of video memory (LFB)
mov esi, dword ptr texture
cld
lodsb
cmp al,0xff
je ok
jmp notok
ok:
rep movsb
notok :
mov ecx,100
n_ok:
mov edi, dword ptr VBETABLE2+028h
mov al,0xff ; BLUE
stosb
mov al,0x00 ; GREEN
stosb
mov al,0x00 ; RED
stosb
loop n_ok
ex:
jmp $
include 'interrupts.asm'
include 'idt_lite.inc'
GP_FAULT db '** GENERAL PROTECTION FAULT **' ,0
cursor dd 0x00
error db 'error!' ,0
VBETABLE2 db 512 dup (0)
end_code:
texture:
db 368640*4 - ($-start) dup (0xFF)
; texture
Защищенный режим. Считывание переменной из секции кода
Есть код перехода в защищенный режим
Все нормально работает, за исключением одного момента.
Как использовать команды lodsb и stosb ?
Структура такая:
-----------
----Код------
Получение данных из data_seg
---Код----
---Данные (dataseg)----
------
Т.е. в самом коде подключен файл (incbin - алиас file в FASM) и с него нужно читать данные, записывать в видеопамять.
Делаю так:
cs=ds=0
mov ax,DATA_SELECTOR
mov ds,ax ; данные
mov es,ax ; видео
; Разрешение экрана 640х480х24 (VESA) (640х480х3 = 921600)
mov ecx,230400 (так как мы пишем по 4 байта то 230400 * 4 = 921600)
mov edi, dword ptr VBETABLE2+028h ; здесь линейный адрес из VESA (с ним все ок)
mov esi, dword ptr texture
rep movsd
...........
texture: dd 230400 dup 0xFFFFFFFF ;(белый)
Экран должен полностью заполнятся белым цветом, но вместо белого экрана выводится какой-то шум. Т.е. явно читает оттуда откуда не надо
Я думаю дело или в сегменте или в неправильной адресации... Но где же тут ошибка?
P.S. Для наглядности: в коде вот тут:
mov edi, dword ptr VBETABLE2+028h ; Adress of video memory (LFB)
mov esi, dword ptr texture
cld
lodsb
cmp al,0xff
je ok
Загружается байт который находится по адресу "texture" он заполнен значениями 0xFF
texture: db 368640*4 - ($-start) dup (0xFF)
И если значение равно 0xff то дальше должна выполнятся программа с метки ok, но загруженное значение != 0xFF. Почему?
Код:
Эмм... у меня тут при компиляции программы получается бинарный файлик около 200 Kb, который я записываю на дискетку hex редактором...
В коде нету подгрузки кода который находится за пределом 512 байт
Меня тут мысль посетила)))
А проблема ли не в том что bios грузит только первых 512 байт, а остальные просто отметает? )))
Чтобы что-то подгружать в защищенном режиме, нужно иметь для этого собственные дрова. Чтобы загружать большие объемы данных в расширенную память посредством BIOS, нужно использовать буфер, расположенный в базовой памяти, и переносить данные порциями, многократно переключаясь между RM/PM или используя т.н. нереальный режим.
Если еще проще, сразу после перехода в защищенный режим:
С маленькими значениями (1-128 dec)
texture db 128 dup (0xff)
Работает нормально.
Если поставить большие (2048 например у меня) то просто черный экран.
texture db 2048 dup (0xff)
Используя такой код:
Код:
CODE_32BIT:
sti
in al, 70h
and al, 7Fh
out 70h, al
mov ax,DATA_SELECTOR
mov ds,ax
mov es,ax
mov ecx,32
mov edi, dword ptr VBETABLE2+028h ; Adress of video memory (LFB)
mov esi, texture
rep movsd
jmp $
texture db 128 dup (0xff)
sti
in al, 70h
and al, 7Fh
out 70h, al
mov ax,DATA_SELECTOR
mov ds,ax
mov es,ax
mov ecx,32
mov edi, dword ptr VBETABLE2+028h ; Adress of video memory (LFB)
mov esi, texture
rep movsd
jmp $
texture db 128 dup (0xff)
Еще раз повторюсь, как правильно считать данные из подключенного файла (incbin в коде) если он (в данном случае) больше чем 192 Kb, используя movsd, lodsd ?
У меня же только сегмент данных, и сегмент кода, с базой 0 и размером в 4Gb.
cs = ds = 0
Нет разницы, больше 192 кб или меньше. Попробуйте заполнить экран одним цветом посредством stosd.
mov edi,dword ptr VBETABLE2 + 028h
mov al,0xFF
mov ecx, 640 * 480 * 3
rep stosb
jmp $
А вот когда так:
mov edi, dword ptr VBETABLE2 + 028h
mov esi, dword ptr texture
mov ecx,640*480*3
foo:
lodsb
stosb
loop foo
jmp $
texture db 640 * 480 * 3 dup (0xFF)
То выводится непойми что...
Я это сразу заметил, увидев стартовое смещение 7C00h, но подумал, что вы адекватный человек и загружаете этот образ какой-то другой программой. Кстати образ с картинкой 640x480x3 не поместится в базовую память.
Т.е. получается что после перехода в защищенный режим и открытия линии А20 мне все еще недоступно 4Гб ?
Если допустим подгружать текстуру после перехода в защищенный режим