New VGA mode? [someone please lock this or something]

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.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

New VGA mode? [someone please lock this or something]

Post by NunoLava1998 »

I tried this code on my hardware and this mode came up... somehow. Either my BIOS/UEFI is drunk or VGA is 10/10.

Anyway, using this code:

Code: Select all

BITS 32
ORG 0x0000
init:
; Set DS = CS
mov ax, cs
mov ds, ax

; Set to graphics mode 0x13 (320x200x256)
mov ax, 13h
int 10h

; Set ES to the VGA video segment at 0xA000
mov ax, 0xa000
mov es, ax
jmp KMAIN
KMAIN:
mov ax, 30
mov bx, 20
mov cx, 320
mul cx
add ax, bx
mov di, ax
mov dl, 0x0C
mov [es:di],dl
mov ax, 1
mov bx, 1
mov cx, 320
mul cx
add ax, bx
mov di, ax
mov dl, 0x08
mov [es:di],dl
hlt
jmp KMAIN
My hardware displayed the blinking cursor, while displaying the VGA pixels in VESA mode, VESA-type in size and VGA-type in location.
So basically my hardware is allowing for text mode, VGA and VESA to run at the same time, when it should only be VGA.

edit: lmao i put 16bit code into 32bit code.
Last edited by NunoLava1998 on Mon Oct 17, 2016 12:49 am, edited 2 times in total.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: New VGA mode?

Post by Brendan »

Hi,

Code: Select all

BITS 32

Code: Select all

mov ax, 13h
int 10h
When you tell the assembler to generate 32-bit code it generates 32-bit code. If the CPU is actually executing 16-bit code then it decodes/interprets the instruction very differently and you end up executing trash.

Executing trash leads to unexpected results.

For reference, this is what the CPU sees when it executes your code:

Code: Select all

00000000  668CC8            mov eax,cs
00000003  8ED8              mov ds,ax
00000005  66B81300CD10      mov eax,0x10cd0013
0000000B  66B800A08EC0      mov eax,0xc08ea000
00000011  EB00              jmp short 0x13
00000013  66B81E0066BB      mov eax,0xbb66001e
00000019  1400              adc al,0x0
0000001B  66B9400166F7      mov ecx,0xf7660140
00000021  E166              loope 0x89
00000023  01D8              add ax,bx
00000025  6689C7            mov edi,eax
00000028  B20C              mov dl,0xc
0000002A  2667881566B80100  mov [dword es:0x1b866],dl
00000032  66BB010066B9      mov ebx,0xb9660001
00000038  40                inc ax
00000039  0166F7            add [bp-0x9],sp
0000003C  E166              loope 0xa4
0000003E  01D8              add ax,bx
00000040  6689C7            mov edi,eax                                                                                                           
00000043  B208              mov dl,0x8
00000045  26                es
00000046  67                a32
00000047  8815              mov [di],dl
00000049  F4                hlt
0000004A  EBC7              jmp short 0x13

Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

Brendan wrote:Hi,

Code: Select all

BITS 32

Code: Select all

mov ax, 13h
int 10h
When you tell the assembler to generate 32-bit code it generates 32-bit code. If the CPU is actually executing 16-bit code then it decodes/interprets the instruction very differently and you end up executing trash.

Executing trash leads to unexpected results.


Cheers,

Brendan
So i thought 32bit code was backwards compatible with 16bit and it generated trash that my forced my hardware to literally combine text, VGA and VESA in one.




That is just the best result of a misunderstanding ever.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: New VGA mode?

Post by Brendan »

Hi,
NunoLava1998 wrote:So i thought 32bit code was backwards compatible with 16bit and it generated trash that my forced my hardware to literally combine text, VGA and VESA in one.
It's not backward compatible - things like the sizes of immediates change, etc.

I added a disassembly to show what the CPU would see. You can tell from this that you don't even change video mode (the bytes that were the "int 0x10" instruction end up becoming part of a "mov eax,0x10cd0013" instruction).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

Brendan wrote:Hi,

Code: Select all

BITS 32

Code: Select all

mov ax, 13h
int 10h
For reference, this is what the CPU sees when it executes your code:

Code: Select all

00000000  668CC8            mov eax,cs
00000003  8ED8              mov ds,ax
00000005  66B81300CD10      mov eax,0x10cd0013
0000000B  66B800A08EC0      mov eax,0xc08ea000
00000011  EB00              jmp short 0x13
00000013  66B81E0066BB      mov eax,0xbb66001e
00000019  1400              adc al,0x0
0000001B  66B9400166F7      mov ecx,0xf7660140
00000021  E166              loope 0x89
00000023  01D8              add ax,bx
00000025  6689C7            mov edi,eax
00000028  B20C              mov dl,0xc
0000002A  2667881566B80100  mov [dword es:0x1b866],dl
00000032  66BB010066B9      mov ebx,0xb9660001
00000038  40                inc ax
00000039  0166F7            add [bp-0x9],sp
0000003C  E166              loope 0xa4
0000003E  01D8              add ax,bx
00000040  6689C7            mov edi,eax                                                                                                           
00000043  B208              mov dl,0x8
00000045  26                es
00000046  67                a32
00000047  8815              mov [di],dl
00000049  F4                hlt
0000004A  EBC7              jmp short 0x13
"move random registers around and change eax to 0xb9660001"
the code i provided is very similar to what NASM produced (sarcasm)
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: New VGA mode?

Post by Schol-R-LEA »

Brendan wrote:Hi,

Code: Select all

BITS 32

Code: Select all

mov ax, 13h
int 10h
When you tell the assembler to generate 32-bit code it generates 32-bit code. If the CPU is actually executing 16-bit code then it decodes/interprets the instruction very differently and you end up executing trash.

Executing trash leads to unexpected results.
In case it isn't clear, the problem Brendan is pointing out is that you are invoking an interrupt vector which isn't going to be present in protected mode - or if it is, it is one which you set up, not the standard BIOS interrupt vector which would have been in the IVT if this were real mode - in p-mode, the IVT isn't there at all, and it would be using the IDT you created instead.

Or, conversely, you are running code assembled for 32-bit p-mode while running in real-mode. I doubt I need to elaborate on why this isn't going to work. If you are using 16-bit instructions under 32-bit code generation, then most of the generated code will be the same, but not all of it, which means some of it will work and some won't.

So, unless you are in p-mode and have set up an interrupt vector in your IDT that mimics the BIOS interrupts (or redirects to a virtualized BIOS call), then... well, frankly I am surprised it didn't triple-fault outright. This is far less dramatic than it probably could have been.

Can you explain a bit more about what you were trying to do?

EDIT: I just notice the ORG 0000 part. Just how are you running this? In real mode, this would put the code at the start of the current segment; the same holds in p-mode, of course, but it isn't typical to use multiple segments in p-mode (the usual practice is to give each process a flat virtual memory space and using paging hardware to control RWX access).
Last edited by Schol-R-LEA on Sun Oct 16, 2016 10:43 am, edited 2 times in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

Schol-R-LEA wrote:
Brendan wrote:Hi,

Code: Select all

BITS 32

Code: Select all

mov ax, 13h
int 10h
When you tell the assembler to generate 32-bit code it generates 32-bit code. If the CPU is actually executing 16-bit code then it decodes/interprets the instruction very differently and you end up executing trash.

Executing trash leads to unexpected results.
In case it isn't clear, the problem Brendan is pointing out is that you are invoking an interrupt vector which isn't going to be present in protected mode - or if it is, it is one which you set up, not the standard BIOS interrupt vector which would have been in the IVT if this were real mode - in p-mode, the IVT isn't there at all, and it would be using the IDT you created instead.

Or, conversely, you are running code assembled for 32-bit p-mode while running in real-mode. I doubt I need to elaborate on why this isn't going to work. If you are using 16-bit instructions, then most of the generated code will be the same, but not all of it, which means some of it will work and some won't.

So, unless you are in p-mode and have set up an interrupt vector in your IDT that mimics the BIOS interrupts (or redirects to a virtualized BIOS call), then... well, frankly I am surprised it didn't triple-fault outright. This is far less dramatic than it probably could have been.

Can you explain a bit more about what you were trying to do?
I run the code on my computer and it worked. But it was in a mode where text, VESA and VGA were fused... wat, and it could hold to, well, whatever the BIOS wants (if your BIOS supports 1,324,768 by 2,880,529, it will probably resize to that in this code.)
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

Schol-R-LEA wrote:
Brendan wrote:Hi,

Code: Select all

BITS 32

Code: Select all

mov ax, 13h
int 10h
EDIT: I just notice the ORG 0000 part. Just how are you running this? In real mode, this would put the code at the start of the current segment; the same holds in p-mode, of course, but it isn't typical to use multiple segments in p-mode (the usual practice is to give each process a flat virtual memory space and using paging hardware to control RWX access).
does the code look like it's in p-mo.. but here's why i put the ORG.

Code: Select all

bits 16
ORG 0x7c00      ; Bootloader starts at physical address 0x07c00

    ; At start bootloader sets DL to boot drive

    ; Since we specified an ORG(offset) of 0x7c00 we should make sure that
    ; Data Segment (DS) is set accordingly. The DS:Offset that would work
    ; in this case is DS=0 . That would map to segment:offset 0x0000:0x7c00
    ; which is physical memory address (0x0000<<4)+0x7c00 . We can't rely on
    ; DS being set to what we expect upon jumping to our code so we set it
    ; explicitly
    xor ax, ax
    mov ds, ax        ; DS=0

    cli               ; Turn off interrupts for SS:SP update
                      ; to avoid a problem with buggy 8088 CPUs
    mov ss, ax        ; SS = 0x0000
    mov sp, 0x7c00    ; SP = 0x7c00
                      ; We'll set the stack starting just below
                      ; where the bootloader is at 0x0:0x7c00. The
                      ; stack can be placed anywhere in usable and
                      ; unused RAM.
    sti               ; Turn interrupts back on

reset:                ; Resets floppy drive

    xor ax,ax         ; AH = 0 = Reset floppy disk
    int 0x13
    jc reset          ; If carry flag was set, try again

    mov ax,0x07e0     ; When we read the sector, we are going to read to
                      ;    address 0x07e0:0x0000 (phys address 0x07e00)
                      ;    right after the bootloader in memory
    mov es,ax         ; Set ES with 0x07e0
    xor bx,bx         ; Offset to read sector to
floppy:
    mov ah,0x2        ; 2 = Read floppy
    mov al,0x1        ; Reading one sector
    mov ch,0x0        ; Track(Cylinder) 1
    mov cl,0x2        ; Sector 2
    mov dh,0x0        ; Head 1
    int 0x13
    jc floppy         ; If carry flag was set, try again

    jmp 0x07e0:0x0000 ; Jump to 0x7e0:0x0000 setting CS to 0x07e0
                      ;    IP to 0 which is code in second stage
                      ;    (0x07e0<<4)+0x0000 = 0x07e00 physical address

times 510 - ($ - $$) db 0   ; Fill the rest of sector with 0
dw 0xAA55                   ; This is the boot signature
" jmp 0x07e0:0x0000 ; Jump to 0x7e0:0x0000 setting CS to 0x07e0"
"0x0000"
I have tested it. Always. Works.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: New VGA mode?

Post by Schol-R-LEA »

BTW, was this the source of your code, Dr. Frankenstein? Unless that was your post - and your command of English suggests otherwise - you really need to take code like this as a guide to writing your own code, not copypasta it without understanding what it is doing.

Also, what is this part for?

Code: Select all

jmp KMAIN
KMAIN:
While there once was a reason why you might do a JMP FAR at the start of the first-stage boot sector (to regularize the origin, something that used to be a problem with non-compliant BIOS loaders but has long since ceased to be an issue), there is no justification I can think of for doing this, certainly not after the first few instructions of the first stage. Can you give any reason for this beyond "it is what the code I copied it from did"?
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: New VGA mode?

Post by Schol-R-LEA »

Pop quiz: in the original code (show below), what does the line mul cx do, and why are you doing it?

Code: Select all

vga:
    ; Draw pixel in middle of screen
    mov ax, [ycoord]
    mov bx, [xcoord]
    mov cx, 320
    mul cx
    add ax, bx
    mov di, ax
    mov dl, [color]
    mov [es:di],dl
Given that you repeat this code (sans the indirections; by making your loads immediates, without giving them equates to name the constants, you have made the whole less readable) in a way that makes the multiply pointless (as you are multiplying by one in the second repetition), I am not convinced you know. I am not even convinced you know what the original code was meant to do, for that matter (hint - one of the comments says it explicitly).

Similarly, can you tell me why you are using mode 0x13, rather than some other mode? There is a reason in the original, I am wondering if you can tell me what that reason is.

Can you tell me what you expected it to display? I would love to hear it.

EDIT: I want you to understand that I am not doing this to pick on you, but to make a point about how you are coming across to us, and how many problems you will have if you keep trying to Frankenstein together other people's code into a system without really understanding what the code does. The Sewage Overflow copypasta approach does not work in OS dev. There is no substitute for understanding here, and, to paraphrase Euclid, no royal road to OS dev.
Last edited by Schol-R-LEA on Sun Oct 16, 2016 3:13 pm, edited 2 times in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
MichaelFarthing
Member
Member
Posts: 167
Joined: Thu Mar 10, 2016 7:35 am
Location: Lancaster, England, Disunited Kingdom

Re: New VGA mode?

Post by MichaelFarthing »

I'm prepared to PM the answer in return for a SOLEMN PROMISE that no more images will be displayed in posts by the OP.
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

Re: New VGA mode?

Post by azblue »

NunoLava1998 wrote: "move random registers around and change eax to 0xb9660001"
the code i provided is very similar to what NASM produced (sarcasm)
It sounds like you think the assembler didn't do what you told it to do. It did; you just didn't know what you were doing. When you tell it to output 32bit code and then do something like:

Code: Select all

mov ax, 1234h
It precedes the command with 0x66 so the CPU knows that this command is using a data size inconsistent with the mode chosen. In other words, with the CPU running in 32 bit mode, it will interpret the command as a 16 bit one -- exactly as you intended.

But you're running this as a bootloader, which means you're in 16 bit real mode -- not what you told the assembler. So when the CPU, in 16 bit mode, sees the operand size override, it treats the command as 32 bit, rather than the 16 bit command that you wanted. So it moves into eax 0x1234 + (next 16 bits of code) <<16

Tell your assembler what you actually mean, and be sure you understand how to use the assembler and how the CPU works.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

Schol-R-LEA wrote:Pop quiz: in the original code (show below), what does the line mul cx do, and why are you doing it?

Code: Select all

vga:
    ; Draw pixel in middle of screen
    mov ax, [ycoord]
    mov bx, [xcoord]
    mov cx, 320
    mul cx
    add ax, bx
    mov di, ax
    mov dl, [color]
    mov [es:di],dl
Given that you repeat this code (sans the indirections; by making your loads immediates, without giving them equates to name the constants, you have made the whole less readable) in a way that makes the multiply pointless (as you are multiplying by one in the second repetition), I am not convinced you know. I am not even convinced you know what the original code was meant to do, for that matter (hint - one of the comments says it explicitly).

Similarly, can you tell me why you are using mode 0x13, rather than some other mode? There is a reason in the original, I am wondering if you can tell me what that reason is.

Can you tell me what you expected it to display? I would love to hear it.

EDIT: I want you to understand that I am not doing this to pick on you, but to make a point about how you are coming across to us, and how many problems you will have if you keep trying to Frankenstein together other people's code into a system without really understanding what the code does. The Sewage Overflow copypasta approach does not work in OS dev. There is no substitute for understanding here, and, to paraphrase Euclid, no royal road to OS dev.
1: I want to output 2 pixels, and at the end the initial (ax, bx, cx) variables don't matter. It's just part of the way of finding the video address i need to put a pixel in so it is displayed correctly. The code works, and if you set cx to 320 and did "mov cx, 48", cx would be 48, not 368 or something else.
2: GUI
3: 2 pixels, i'm just testing on real hardware.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

Schol-R-LEA wrote:BTW, was this the source of your code, Dr. Frankenstein? Unless that was your post - and your command of English suggests otherwise - you really need to take code like this as a guide to writing your own code, not copypasta it without understanding what it is doing.

Also, what is this part for?

Code: Select all

jmp KMAIN
KMAIN:
While there once was a reason why you might do a JMP FAR at the start of the first-stage boot sector (to regularize the origin, something that used to be a problem with non-compliant BIOS loaders but has long since ceased to be an issue), there is no justification I can think of for doing this, certainly not after the first few instructions of the first stage. Can you give any reason for this beyond "it is what the code I copied it from did"?
I do not want to set 0x13 every single time the CPU executes KMAIN, so i set it at the start, THEN jump to KMAIN and start the loop.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: New VGA mode?

Post by NunoLava1998 »

someone please lock this
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
Post Reply