flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > How to move cursor in 32 bit protected mode? Goto page 1, 2 Next |
Author |
|
ManOfSteel 31 Aug 2012, 07:24
newport wrote: I have read the tutorial at [...] osdev.org on vga programming of the cursor, but I cannot make heads or tails of it Is this what you're talking about? I see lots of details and comments. What exactly are you not understanding? newport wrote: I can't seem to wrap my head around how to translate my current location in video ram to the cursor position. Read the C code in the OSDev article above or the code and comments in this article. The 0x0E (14 in decimal) and 0x0F (15 in decimal) are VGA registers. When you write those in VGA port 0x3D4, you're telling the hardware you want to write the location of the cursor (in port 0x3D5). 14 is for the hi-byte, 15 for the lo-byte. The rest of the code is just mathematical operations to convert the desired cursor location into data readable by the hardware. Make sure you understand how bit shifting instructions (e.g. shl/shr) work. newport wrote:
If you've seen a 2*... formula somewhere, it probably has to do with printing text on the screen, in which case the 2 represents the word (2 bytes) for the character itself and its color. The VGA hardware ports simply don't care about all that: they're setting the location of the cursor in a 80*25 array. newport wrote: also, the OUT Instruction is very confusing..... Do you have the Intel manuals or any serious reference? They explain everything in great detail. |
|||
31 Aug 2012, 07:24 |
|
newport 31 Aug 2012, 11:24
yes...that is what I am talking about. I do have the intel manuals. I think I'll re-read the section on IN and OUT again and the link you provided. And afterwards try to clarify my question to greater detail. Thanks.
|
|||
31 Aug 2012, 11:24 |
|
newport 31 Aug 2012, 15:13
OK...Here is what I come up with based on several examples floating around the internet and it works...But my main question is how would I translate for example...
VRAM location 0xB80A0 ( ES:EDI ) to it's corresponding X and Y positions? Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get Cursor Pos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; curPosX db 0 curPosY db 0 columns equ 80 posCursor: pusha ;position = (row*80) + col; ;AX will contain 'position' mov al, [curPosY] ;set AX to 'row' mov cl, columns mul cl ;multiplies cl * al and stores value in ax mov bx, ax movzx ax, [curPosX] ;copy and zero-extend pos 'X' to AX add bx, ax mov cx, bx ;store 'position' in CX ;cursor LOW port to vga INDEX register mov al, 0fh ;Cursor Location Low Register -- mov dx, 3d4h ;VGA port 3D4h out dx, al mov ax, cx ;restore 'postion' back to AX mov dx, 3d5h ;VGA port 3D5h out dx, al ;send to VGA hardware ;cursor HIGH port to vga INDEX register mov al, 0eh mov dx, 3d4h ;VGA port 3D4h out dx, al mov ax, cx ;restore 'position' back to AX shr ax, 8 ;get high byte in 'position' mov dx, 3d5h ;VGA port 3D5h out dx, al ;send to VGA hardware popa retd ;-------------------------------------------------------------------------------- |
|||
31 Aug 2012, 15:13 |
|
ManOfSteel 31 Aug 2012, 19:15
Well it's just the opposite. 0xb8000 being the base, the VGA cursor is at 0xa0 (or 160 in decimal).
Provided you're in 80x25 text-mode, you should be at the very beginning of row 2, since every character you see is encoded with 2 bytes and there are 80 characters (i.e. 160 bytes) per row. You should get the result with a simple division. Say you're at 0xb80d8. 216 / (80*2) = 1 remainder 56. So y=1 and x=56/2=28 (or row 2, col 29). In a division, the quotient is in *ax and the remainder in *dx. Check your instructions reference for more information on div. Also note that easy multiplication (and division) can be done using bit-shifting instructions, e.g. M*2 is obtained with shl M,1 (shr for division). Simple binary notation logic. |
|||
31 Aug 2012, 19:15 |
|
BAiC 01 Sep 2012, 00:41
newport: in and out are not toys, nor are they "c" concepts. when you issue an "out" you are sending electrical charges over specific bus lines. if unprofessional hardware is connected you can do some serious damage. for modern and professional hardware; bad i/o ends up doing little more than issuing the wrong command (such as a disk write instead of a disk read for legacy disk drives).
it is extraordinarily easy to forget these facts when working inside an emulator/vm. Stefan |
|||
01 Sep 2012, 00:41 |
|
sinsi 01 Sep 2012, 10:51
Pmode code
Code: setcurspos: mov [cursx],ecx mov [cursy],edx sethwcurs: push eax ecx edx mov eax,80 mov ecx,[cursx] mul [cursy] add ecx,eax mov ah,ch mov edx,3d4h mov al,0eh out edx,ax mov ah,cl inc al out edx,ax pop edx ecx eax ret If you use VESA modes, they might not be VGA compatible (haven't seen that, but the option is there). |
|||
01 Sep 2012, 10:51 |
|
newport 01 Sep 2012, 14:58
Thanks everybody for the help! Great Info.....
|
|||
01 Sep 2012, 14:58 |
|
newport 01 Sep 2012, 15:08
BAiC wrote: newport: in and out are not toys, nor are they "c" concepts. when you issue an "out" you are sending electrical charges over specific bus lines. if unprofessional hardware is connected you can do some serious damage. for modern and professional hardware; bad i/o ends up doing little more than issuing the wrong command (such as a disk write instead of a disk read for legacy disk drives). BAiC...are there any other ways of manipulating the cursor without IN/OUT that doesn't incur such a high risk factor? Just asking cause I haven't seen any and now I'm a little weary about trying my OS on actual hardware....(considering my limited experience in assembly of course)... |
|||
01 Sep 2012, 15:08 |
|
ManOfSteel 01 Sep 2012, 20:24
Not really. The only other way is to use the BIOS interrupts. But you'd need to switch to real-mode and then back to protected-mode for every cursor movement. Definitely not recommended.
Or maybe you could ignore the VGA cursor altogether, use some character (e.g. an underscore) to show the pseudo-cursor location and do some character substitutions every time it's moved. Anyway, you'll have to get used to the in/out instructions because under protected-mode they're pretty much the only way you can do something with the hardware. So get detailed and trustworthy data sheets and make sure you're not doing something you're not supposed to do. |
|||
01 Sep 2012, 20:24 |
|
revolution 01 Sep 2012, 21:54
BAiC wrote: newport: in and out are not toys, nor are they "c" concepts. when you issue an "out" you are sending electrical charges over specific bus lines. if unprofessional hardware is connected you can do some serious damage. for modern and professional hardware; bad i/o ends up doing little more than issuing the wrong command (such as a disk write instead of a disk read for legacy disk drives). Indeed with regard to damage caused by software it is usually the opposite. It is in fact very difficult to cause physical damage to hardware with only software commands. There have been cases in the past where systems were vulnerable to particular I/O sequences but these cases were not the result of errant programming; they were the result of detailed and deliberate attempts to find a vulnerability and exploit it. It is inconceivable that this could happen by accident. Unless someone has taken the time to make a detailed study of the hardware and found a weakness then it is fair to say that there is no chance that I/O commands can cause damage. And if a weakness did exist then I would have expected some malware to have attempted to exploit it long before now. So in summary: Don't worry about it. Nothing bad will happen. |
|||
01 Sep 2012, 21:54 |
|
newport 02 Sep 2012, 04:05
thanks revolution! that eases my worries. I did however think the "using the underscore as a pseudo-cursor" was an interesting idea by Man of Steel...but on the other hand; this might be something for future endeavors.. as for now, I think if I want to become a serious Assembly Programmer it is necessary for me to actually be able to utilize architecture code rather than trying to find ways to manipulate it.
Great info guys! I appreciate all your help! |
|||
02 Sep 2012, 04:05 |
|
freecrac 02 Sep 2012, 07:36
ManOfSteel wrote: Or maybe you could ignore the VGA cursor altogether, use some character (e.g. an underscore) to show the pseudo-cursor location and do some character substitutions every time it's moved. If we want to use a higher resolution, maybe in a graphic mode with 32 Bit per pixel, then we can not be shure if we can use a vga cursor, or it is limited only for textmode, so we have to use our own pseudo-cursor. Here is a litlle piece of code(not really functional only a part of it) using an own pseudo-cursor. But i have written this code for the 16 Bit unrealmode. (Using the 32 bit protected mode we have to use some other instruction.) To show the ASCII character in a higher resotution i get every character from the character table that comes within our video bios and writing the character pixel by pixel to the linear framebuffer (or writing a quadrouple of pixels of each dot, for to enlarge both dimensions for to become taller characters on the screen, if we think it would be to small for reading.) For the cursor i like to use inverted characters. Code: IrqVec = 8h * 4 ; Interrupt-Vector Coun_Port = 40h ; Timer-Counter low/high Cont_Port = 43h ; Timer-Controller Cursor_Speed = 7 ; 1 = fast Home_PosX = 9 ; Text-Cursor col Home_PosY = 23 ; Text-Cursor row cli xor ax, ax mov es, ax mov ebx, DWORD PTR es:[IrqVec] ; Vector (Offset/Segment) mov DWORD PTR[ALTVEC], ebx mov cs:DWORD PTR[OLDVEC], ebx mov es:[IrqVec], OFFSET NEUVEC ; IRQ-Vector mov es:[IrqVec+2], cs ; set to new Routine mov al, 36h ; set to 18,2 Hertz (standard) out Cont_Port, al xor al, al out Coun_Port, al ; low out Coun_Port, al ; high sti mov BYTE PTR[TEXY], Home_PosY mov BYTE PTR[TEXX], Home_PosX ; Cursor Start-Position ; ; SET C U R S O R ; TACUR: cmp BYTE PTR[RETY], 0 ; Blinking Cursor jz short NOBEW mov eax, DWORD PTR[RETY] ; on moving restore old Pos mov edi, DWORD PTR[VIDADR] mov ebx, 16*MaxX * 4 mul ebx xor ecx, ecx mov ebx, eax mov eax, 16 * 4 mul DWORD PTR[RETX] lea eax, [eax+ebx] mov bx, OFFSET BUFFER lea edi, [edi+eax] mov ax, Text_MaxX+2 mul WORD PTR[RETY] add bx, ax add bx, WORD PTR[RETX] mov cl, [bx] ; GET Ascii call GETCHAR ; Paint char on screen mov BYTE PTR[RETY], 0 mov BYTE PTR[RETX], 0 NOBEW: mov edi, DWORD PTR[VIDADR] ; set Cursor on new poition mov eax, DWORD PTR[TEXY] mov ebx, 16*MaxX * 4 mul ebx xor ecx, ecx mov ebx, eax mov eax, 16 * 4 mul DWORD PTR[TEXX] lea eax, [eax+ebx] mov bx, OFFSET BUFFER lea edi, [edi+eax] mov ax, Text_MaxX+2 mul WORD PTR[TEXY] add bx, ax add bx, WORD PTR[TEXX] mov cl, [bx] ; get Ascii cmp BYTE PTR[CURFLAG], 0 jz short SWAP call SKIPCHA ; Invert-Char to screen jmp short SKIP ; XRAUS: cli mov ebx, DWORD PTR[ALTVEC] ; restore IRQ 1Ch mov DWORD PTR es:[IrqVec], ebx sti ;----------------------------- NEUVEC: inc BYTE PTR[CURFLAG+1] cmp BYTE PTR[CURFLAG+1], Cursor_Speed jb short NOHIT mov BYTE PTR[CURFLAG+1], 0 xor BYTE PTR[CURFLAG], 1 ; invert Aktiv-Flag NOHIT: DB 0EAh ; jmp far OLDVEC DD 0 ; to the old Interrupt ;----------------------------- CURFLAG DB 0, 0, 0, 0 ALTVEC DD 0 ; Offset/Segment of IRQ 1Ch TEXY DB 0, 0, 0, 0 TEXX DB 0, 0, 0, 0 |
|||
02 Sep 2012, 07:36 |
|
newport 02 Sep 2012, 08:02
this is very interesting...Im gonna bookmark this page because I will eventually want to move to graphics mode and this will definitely serve as a good reference for my studies. cool freecrac!
|
|||
02 Sep 2012, 08:02 |
|
BAiC 03 Sep 2012, 22:09
revolution wrote:
revolution: if you had read my entire post you would have noticed the blatant disclaimers: if unprofessional hardware is connected and for modern and professional hardware. |
|||
03 Sep 2012, 22:09 |
|
BAiC 03 Sep 2012, 22:16
newport: my OS, Mathis, uses a simple XOR algorithm to invert the color of the current text cursor (the Mouses' position actually). it's very effective for text mode and its' implementation only uses memory writes. I never bothered learning the cursor since I only use Text Mode for debugging.
if you want to eventually use an RGB(A)-style display the VGA cursor won't help much. modern graphics cards support dedicated logic for cursors but their implementation has no relation to the legacy VGA cursor so learning it has questionable benefits. Stefan |
|||
03 Sep 2012, 22:16 |
|
revolution 03 Sep 2012, 23:44
BAiC wrote: if you had read my entire post you would have noticed the blatant disclaimers: if unprofessional hardware is connected and for modern and professional hardware. |
|||
03 Sep 2012, 23:44 |
|
freecrac 04 Sep 2012, 18:33
revolution wrote:
Maybe some rare video adapter exist and they are not VGA compatible? With some onboard grafik and older externe cards with a vesa bios version before VBE 2 it is not possible to use the VESA-LFB, it is only possible to use paged modes. Dirk |
|||
04 Sep 2012, 18:33 |
|
edfed 04 Sep 2012, 19:18
video adapters are suposed to be all VGA compatible since at least a decade.
older hardware is supposed to don't currently be used because the PC where it was connected is dead, or just because it is so obsolete that it would be a cure to code anything for it. if you see some video adapters like that, just keep them for collection, but don't waste time trying to make it work, especially if you don't find the documentation about it. the cursor can be moved using IO ports in any text mode for any VGA compatible card. some VGA ports are also used to tell the screen dimentions. using all them, you can write a function able to put the cursor anywhere on the screen. personnaly, i've pointed that the acer aspire one (netbook) don't have the standard 80*25 resolution, and it makes the creation of the putchar function a necessity to work the same on any machine. this putchar function should use the same getXres and getYres as movecursor function, but will multiply by 2 the position to spot the correct character cell. |
|||
04 Sep 2012, 19:18 |
|
BAiC 04 Sep 2012, 21:15
revolution wrote:
it's hardware that is made without bothering to perform such things as quality control and is otherwise amateurish. it includes, but is not limited to, any production by you. your software is unprofessional. if you applied your "skills" to hardware then your hardware would be unprofessional. how is that for a definition? |
|||
04 Sep 2012, 21:15 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.