Přečtení BMP - 938 sektorů – Assembler – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Přečtení BMP - 938 sektorů – Assembler – Fórum – Programujte.comPřečtení BMP - 938 sektorů – Assembler – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
Matěj Andrle+1
Grafoman
31. 12. 2013   #1
-
0
-

Dobrý den,
mám toto VBR: 

bits 16
org 0x7C00

Boot:

	mov ah, 0x42			; Extended Read Sectors From Drive
	mov dl, 0x80			; 80 - FF => HardDisk
	mov si, .imageStruct
	int 0x13

	mov ah, 0x42
	mov si, .kernelStruct
	int 0x13

	jnc InitializeVESA

	mov si, .error
	mov ah, 0xE
	mov cx, 29

.writeChar:

	lodsb
	int 0x10
	loop .writeChar

	mov ah, 0
	int 0x16				; Wait for keystroke
	mov ax, 0
	int 0x19				; Reboot the system

.kernelStruct:

	dw 16				; byte of structure length + empty byte
	dw segmentsForLoad		; sector count
	dd Kernel				; out address
	dq 1					; start

.imageStruct:

	dw 16
	dw 938
	dd BMP
	dq 26

.error db "Fatal Error! Press any key..."

InitializeVESA:

	in al, 0x92
	or al, 2
	out 0x92, al

	mov bx, 0x4118
	mov ax, 0x4F01
	mov di, ModeInfo
	mov cx, bx
	int 0x10

	mov ax, 0x4F02
	int 0x10

	cli
	lgdt [.GDTR]

	mov eax, cr0
	or al, 1
	mov cr0, eax

; CR0: PG|----RESERVED----|NE|ET|TS|EM|MP|PE
; PE Bit 0. The Protected Environment flag. This flag puts the system into protected mode when set.
; MP Bit 1. The Monitor Coprocessor flag. This flag controls the operation of the "WAIT" instruction.
; EM Bit 2. The Emulate flag. When this flag is set, coprocessor instructions will generate an exception.
; TS Bit 3. The Task Switched flag. This flag is set automatically when the processor switches to a new task.
; ET Bit 4. The Extension Type flag. ET (also called "R") tells us which type of coprocessor is installed. If ET = 0, an 80287 is installed. if ET = 1, an 80387 is installed.
; NE Bit 5. New exceptions. If this flag is clear, FPU exceptions arrive as interrupts. If set, as exceptions.
; PG Bit 31. The Paging flag. When this flag is set, memory paging is enabled. We will talk more about that in a second.

	mov ax, 0x8
	mov ds, ax
	mov es, ax
	mov ss, ax

	jmp 0x10:Kernel

.GDT dq 0, 0xCF92000000FFFF, 0xCF98000000FFFF

; Selector 0x00 cannot be used | 0x10 will be our code | 0x08 will be our data

.GDTR:

	dw 0x1F
	dd .GDT

times 510-($-$$) db 0
dw 0xAA55

%include "source/kernel/SMA.asm"
%include "source/kernel/features/Drawing.asm"
%include "source/kernel/features/Console.asm"
%include "source/kernel/features/Keyboard.asm"
%include "source/kernel/features/KeyMap.inc"
%include "source/kernel/features/Int.asm"
%include "source/kernel/features/String.asm"

segmentsForLoad equ ($-$$-512) / 16
times 512 - (($-$$) % 512) db 0

section .bss

ModeInfo:

	ModeAttributes resw 1
	WinAAttributes resb 1
	WinBAttributes resb 1
	WinGranularity resw 1
	WinSize resw 1
	WinASegment resw 1
	WinBSegment resw 1
	WinFuncPtr resd 1
	BytesPerScanLine resw 1
	ScreenWidth resw 1
	ScreenHeight resw 1
	XCharSize resb 1
	YCharSize resb 1
	NumberOfPlanes resb 1
	BitsPerPixel resb 1
	NumberOfBanks resb 1
	MemoryModel resb 1
	BankSize resb 1
	NumberOfImagePages resb 1
	ReservedPage resb 1
	RedMaskSize resb 1
	RedMaskPos resb 1
	GreenMaskSize resb 1
	GreenMaskPos resb 1
	BlueMaskSize resb 1
	BlueMaskPos resb 1
	ReservedMaskSize resb 1
	ReservedMaskPos resb 1
	DirectColorModeInfo resb 1
	; VBE 2.0 extensions
	PhysBasePtr resd 1
	OffScreenMemOffset resd 1
	OffScreenMemSize resw 1

BMP:

	ID1 resb 1
	ID2 resb 1
	FileSize resd 1
	Reserved1 resb 1
	Reserved2 resb 1
	Reserved3 resb 1
	Reserved4 resb 1
	Offset resd 1
	HeaderLength resd 1
	Width resd 1
	Height resd 1
	NumOfPlanes resw 1
	Depth resw 1
	Compression resd 1
	BytesCount resd 1
	Hresolution resd 1
	Xresolution resd 1
	NumOfUsedColors resd 1
	NumOfImportantColors resd 1

A tento kernel:
 

bits 32

Kernel:

	mov eax, BMP
	add eax, dword [Offset]
	mov [.pointer], eax
	mov esi, .params

.drawLine:

	mov eax, dword [.pointer]
	mov ebx, dword [eax]
	mov [.color], ebx

	call DrawPixel

	inc dword [.x]
	cmp dword [.x], Width
	jne .drawLine

	mov dword [.x], 0
	inc dword [.y]
	cmp dword [.y], Height
	je .done

	jmp short .drawLine

.done:

	mov dword [.y], 0
	hlt

.pointer dd 0

.params:

	.color dd 0
	.x dd 0
	.y dd 0

Chci tedy vykreslit BMP obrázek pixel po pixelu. Ale 938 byte se načíst nedá - to selže a když jsem zkusil 38 byte, tak neseděla ani hlavička souboru. (Ani první 2 byte.) Nevěděl by někdo proč? (Ano - několikrát jsem si ověřoval, že ten obrázek začíná na 26. sektoru - zkusil jsem i 25 a 36 - protože mi tam haprovala 10 a ještě mě napadlo, že to začíná od 0. sektoru - ale vše marné.)
Děkuji.

EDIT:

Rezervoval jsem trochu místa za ModeInfo a nyní se snad jak to vypadá načte těch 38 sektorů. 938 musím tedy rozkouskovat - proč to nejde naráz? (Když je vstupem dword...)

Nahlásit jako SPAM
IP: 78.136.161.–
Matěj Andrle+1
Grafoman
1. 1. 2014   #2
-
0
-

Tak už vím, že musím za ModeInfo nechat přesně 206 bytů - a hlavička mi sedí dokonale. Trochu si nejsem jist samotným vykreslením:
 

	mov eax, BMP
	add eax, dword [Offset]
	mov [.pointer], eax
	mov esi, .params

.drawLine:

	mov eax, dword [.pointer]
	mov ebx, dword [eax]
	mov [.color], ebx

	call DrawPixel
	add dword [.pointer], 4

	inc dword [.x]
	mov ebx, dword [Width]
	cmp dword [.x], ebx
	jne .drawLine

	mov dword [.x], 0
	inc dword [.y]
	mov ebx, dword [Height]
	cmp dword [.y], ebx
	je .done

	jmp short .drawLine

.done:

	mov dword [.y], 0
	hlt

.pointer dd 0

.params:

	.color dd 0
	.x dd 0
	.y dd 0

Ale tak jako tak je největším problémem načíst ceou bitmapu byť i po částech. Prostě to nejde načíst bez toho, aby pak načtení kernelu do RAM nezkončilo carry flagem. Nevíte někdo proč?
Děkuji.

Nahlásit jako SPAM
IP: 78.136.161.–
Matěj Andrle+1
Grafoman
1. 1. 2014   #3
-
0
-

Tak jsem na to přišel sám... :D

"Note: The limitation about not crossing cylinder boundaries is very annoying, especially when combined with the 127 sector limit -- because the arithmetic for the length and "start CHS" of the next consecutive read or write gets messy. The simplest workaround is to read or write only one sector at a time in CHS mode. Not all BIOSes have these two limitations, of course, but it is necessary to program for the "lowest common denominator"."

Bohužel to neřeší problém - proč to nefunguje ani při rozkouskování na části najednou načítatelné... Snad na to také přijdu... :D

Nahlásit jako SPAM
IP: 78.136.161.–
Matěj Andrle+1
Grafoman
2. 1. 2014   #4
-
0
-

S jistotou jsem omezil kód na:

	mov dl, 0x80			; 80 - FF => HardDisk
	mov si, .imageStruct
	mov cx, 14

.loadPart:

	mov ah, 0x42			; Extended Read Sectors From Drive
	int 0x13

	add dword [.imageStruct + 4], 34304
	add word [.imageStruct + 8], 67

loop .loadPart

Celý soubor má 938 sektorů - což je 14 * 67... Ale byť i jedna otočka způsobí, že to rozhodí kernel, což spolu nemá jak souviset. Mohu adresu cíle posunout maximálně v řádu stovek, přitom do přetečení FFFFFFFF to má zatraceně daleko - tak proč?

times 512 - (($-$$) % 512) db 0
sectorsForLoad equ ($-$$-512) / 512

section .bss

ModeInfo:

	ModeAttributes resw 1
	WinAAttributes resb 1
	WinBAttributes resb 1
	WinGranularity resw 1
	WinSize resw 1
	WinASegment resw 1
	WinBSegment resw 1
	WinFuncPtr resd 1
	BytesPerScanLine resw 1
	ScreenWidth resw 1
	ScreenHeight resw 1
	XCharSize resb 1
	YCharSize resb 1
	NumberOfPlanes resb 1
	BitsPerPixel resb 1
	NumberOfBanks resb 1
	MemoryModel resb 1
	BankSize resb 1
	NumberOfImagePages resb 1
	ReservedPage resb 1
	RedMaskSize resb 1
	RedMaskPos resb 1
	GreenMaskSize resb 1
	GreenMaskPos resb 1
	BlueMaskSize resb 1
	BlueMaskPos resb 1
	ReservedMaskSize resb 1
	ReservedMaskPos resb 1
	DirectColorModeInfo resb 1
	; VBE 2.0 extensions
	PhysBasePtr resd 1
	OffScreenMemOffset resd 1
	OffScreenMemSize resw 1

resb 206 ; Odsazení od ModeInfo

BMP:

	ID1 resb 1
	ID2 resb 1
	FileSize resd 1
	Reserved1 resb 1
	Reserved2 resb 1
	Reserved3 resb 1
	Reserved4 resb 1
	Offset resd 1
	HeaderLength resd 1
	Width resd 1
	Height resd 1
	NumOfPlanes resw 1
	Depth resw 1
	Compression resd 1
	BytesCount resd 1
	Hresolution resd 1
	Xresolution resd 1
	NumOfUsedColors resd 1
	NumOfImportantColors resd 1

Hlavička sedí - prvních 67 sektorů je tutově na správném místě, místo v RAM je - vše sedí - proč nemohu navršit dalších 67 sektorů? A to i když jsem udělal dvě jiné struktury - prostě opravdu nejde přilepit dalších 67 sektorů a jsem z toho na větvi - proč? (67 * 512 = 34304...)
Děkuji.

Nahlásit jako SPAM
IP: 78.136.161.–
Matěj Andrle+1
Grafoman
2. 1. 2014   #5
-
0
-

Nakonec jsem si uvědomil jak funguje adresace a napadlo mne použít segmenty - a vyšlo to... :D Teď už jen řeším jak správně BMP vykreslit ale základní tvar již odpovídá...

Nahlásit jako SPAM
IP: 78.136.161.–
Gregi
~ Anonymní uživatel
3 příspěvky
3. 1. 2014   #6
-
0
-

#5 Matěj Andrle
Toto je asi jediny funkcny sposob riesenia zlozitejsich problemov. Poradit si uplne, ale uplne sam ;-)

A pekne od Teba, za sa o nadobudnute znalosti i podelis pre ostatnych riesitelov.

Nahlásit jako SPAM
IP: 83.168.142.–
Řešení
Matěj Andrle+1
Grafoman
3. 1. 2014   #7
-
0
-
Vyřešeno Nejlepší odpověď

Tedy řešení:

bits 16
org 0x7C00

Boot:

	mov dl, 0x80			; 80 - FF => HardDisk
	mov si, .imageStruct
	mov cx, 14

.loadPart:

	mov ah, 0x42			; Extended Read Sectors From Drive
	int 0x13

	add dword [.imageStruct + 6], 2144
	add word [.imageStruct + 8], 67

loop .loadPart

...

.imageStruct:
    dw 16
    dw 67
    dd BMP                ; Offset : Segment
    dq 26

...

BMP:

	ID resw 1
	FileSize resd 1
	Reserved1 resb 1
	Reserved2 resb 1
	Reserved3 resb 1
	Reserved4 resb 1
	Offset resd 1
	HeaderLength resd 1
	Width resd 1
	Height resd 1
	NumOfPlanes resw 1
	Depth resw 1
	Compression resd 1
	BytesCount resd 1
	Hresolution resd 1
	Xresolution resd 1
	NumOfUsedColors resd 1
	NumOfImportantColors resd 1

Vykreslení, které funguje dokonale:

DrawImage:

	cmp word [ID], "BM"
	je DrawBMP

	ret

DrawBMP:

	pushad

	mov [.X], eax
	mov [.Y], ebx
	mov [.x], eax
	mov [.y], ebx

	mov esi, BMP
	add esi, [Offset]
	mov [.pointer], esi
	mov ebx, [Height]
	add [.y], ebx

.drawLine:

	mov esi, [.pointer]
	mov al, [esi]
	mov [.color], al
	mov al, [esi + 1]
	mov [.color + 1], al
	mov al, [esi + 2]
	mov [.color + 2], al
	add dword [.pointer], 3

	mov esi, .params
	call DrawPixel

	inc dword [.x]
	mov ebx, [Width]
	add ebx, [.X]
	cmp [.x], ebx
	jne .drawLine

	mov ebx, [.X]
	mov [.x], ebx
	dec dword [.y]
	mov ebx, [.Y]
	cmp [.y], ebx
	je .done

	jmp short .drawLine

.done:

	mov dword [.y], 0
	popad
	ret

.X dd 0
.Y dd 0

.pointer dd 0

.params:

	.color dd 0
	.x dd 0
	.y dd 0

Popíši problém - to čtení disku 42h nedokáže brát celou adresu - bere Segment:Offset - takže byla blbost psát tam plnou adresu - přidávám segment 2144, místo celé adresy... (16 * 2144)

Nahlásit jako SPAM
IP: 78.136.161.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 203 hostů

Podobná vlákna

Load BMP — založil bart

Změna štětce bmp — založil bird

Načítání BMP přes C++ — založil Lokutus7323

Načítání BMP - barvičky — založil Zelenáč

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý