Page 1 of 1

io port access in protected mode

Posted: Wed Dec 17, 2003 12:00 am
by madmatt
I'm writing an OS and trying to set vga mode13h witout the bios.  The direct access works with the dpmi program that I'm using, but with the OS that I am writing, the selectors work fine, the io ports don't seem to be working correctly.  I am using an amd 2300+(2.0 ghz) for development.  Anybody have any advice?
MATT

RE:io port access in protected mode

Posted: Wed Dec 17, 2003 12:00 am
by carbonBased
Well, your development platform is irrelevant... VGA is VGA, no matter what processor you're using.

How is it not working, though?  Simply nothing happens, or you get an exception, or something else?

What's you code look like?

I don't have any ideas offhand, but if you can give us some more information, we might be able to spot something.

Cheers,
Jeff

RE:io port access in protected mode

Posted: Wed Dec 17, 2003 12:00 am
by madmatt
I'll try to explain, I'm using a dpmi (similar to DOS4GW) for assembly development until I can use the kernel itself for development.  In the dpmi, I use code to set vga mode 13h directly without the bios, and the mode gets set correctly, until I use it in my kernel code, then it still seems to be in text mode.  the selectors for code and data are setup pretty much the way they are in the dpmi, except for using ring 0 for the decriptors.  I was looking over the intel documentation and seems to me the problem is MTRR related.  I let everyone know if I figure it out.  I guess I should tell you what I have setup, and what i don't! ;^}.
I have selectors for cs (4mb),ds (4mb),ss (64kb) gs (4gb),real memory (64kb), no call gates, or system,task, or mtrr registers setup yet.
all selectors work, and have not had any problems with them so far
Anyways, here is the descriptor info and source to my vga routine below:

[SELECTOR INFO]
LDRD.GDT:
     ;format of descritor:  
     ;segment limit (word)
     ;lower word 32bit-base (word)
     ;mid byte of 32bit-base (byte)
     ;access (byte)
     ;gdo (byte)
     ;hi byte of 32bit base (byte)              
     gdt.blank descriptor       $0000,$0000,$00,$00,$00,$00
     gdt.code descriptor        $03ff,$0000,$11,$9b,$c0,$00
     gdt.data descriptor        $03ff,$0000,$11,$93,$c0,$00
     gdt.stack descriptor       LDRC.STACKSIZE,$0000,$00,$97,$40,$00
     gdt.global4gb descriptor   $ffff,$0000,$00,$93,$cf,$00
     gdt.realmem descriptor     LDRC.REALMEMSIZE,$ffff,$00,$cf,$90,$00

[VGA SETMODE ROUTINE]
VGAC.SCREENADDR equ $a0000
VGAC.NUMSEQUENCER equ 5
VGAC.NUMCRTC equ 25
VGAC.NUMGRAPHICS equ 9
VGAC.NUMATTRIB equ 21
VGAC.MISC equ $3c2
VGAC.SEQUENCER equ $3c4
VGAC.CRTC equ $3d4
VGAC.GRAPHICS equ $3ce
VGAC.FEATURE equ $3da
VGAC.ATTRIB equ $3c0
VGAC.STATUS equ $3da
VGAC.VREND equ $11
VGAC.NOPROT equ $7F
VGAC.ENABLEATTRIB equ $20

align 16

vgad.mode13h:
     db 063h,000h
     db 003h,001h,00fh,000h,00eh
     db 05fh,04fh,050h,082h,054h,080h,0bfh,01fh,000h,041h,000h,000h,000h,000h
     db 000h,000h,09ch,00eh,08fh,028h,040h,096h,0b9h,0a3h,0ffh
     db 000h,000h,000h,000h,000h,050h,007h,00fh,0ffh
     db 000h,001h,002h,003h,004h,005h,006h,007h,008h,009h,00ah,00bh,00ch,00dh
     db 00eh,00fh
     db 041h,000h,00fh,000h,000h
align 16

proc vga.outregs                        ;Output CL registers to port DX
     xor al,al                          ;start at reg 0
vga.outregs_l1:
     mov ah,[esi]                       ;load data
     inc esi                            ;update source
     out dx,ax                          ;output data
     inc al                                     ;increase register number
     dec cl                                     ;decrease count
     jnz vga.outregs_l1         ;loop whilst still OK
     ret                                        ;and exit
endp                                            ;

proc vga.setmoderegs        ;set VGA registers for mode data
     mov dx,VGAC.STATUS     ;get retrace reg
vga.setmoderegs_l1:             ;
     in al,dx                   ;get value
     test al,8                  ;check for vertical retrace bit
     jnz vga.setmoderegs_l1 ;loop until clear
vga.setmoderegs_l2:             ;
     in al,dx                   ;get value
     test al,8                  ;check for retrace again
     jz vga.setmoderegs_l2  ;loop until it's set this time
                                                ;so we get start of ret. to set mode
     mov esi,vgad.mode13h   ;pointed to by ESI
     mov dx,VGAC.MISC       ;get VGA MISC reg num
     mov al,[esi]               ;load AL
     inc esi                    ;update source
     out dx,al                  ;output to port
     mov dx,VGAC.FEATURE    ;get Feature controller number
     mov al,[esi]               ;load data
     inc esi                    ;update source
     out dx,al                  ;output register data
     mov dx,VGAC.SEQUENCER    ;get sequencer port number
     mov cl,VGAC.NUMSEQUENCER ;get number of regs to set
     call vga.outregs         ;do them
     mov ah,[esi+VGAC.VREND]  ;load CRTC VREND byte
     mov al,VGAC.VREND        ;load reg number
     and ah,VGAC.NOPROT       ;clear protection bit
     mov dx,VGAC.CRTC         ;CRTC port number
     out dx,ax                    ;no protection
     mov cl,VGAC.NUMCRTC      ;number of CRTC regs
     call vga.outregs         ;output to port
     mov dx,VGAC.GRAPHICS     ;get graphics port number
     mov cl,VGAC.NUMGRAPHICS  ;get number of regs
     call vga.outregs         ;do it
     mov dx,VGAC.FEATURE      ;load feature controller port
     in al,dx                     ;reset attrib flip flop by reading
     mov dx,VGAC.ATTRIB       ;attribute controller port
     mov cl,VGAC.NUMATTRIB    ;number of regs
     xor al,al                    ;clear AL
vga.setmoderegs_l3:               ;
     mov ah,[esi]                 ;load AH
     out dx,al                    ;output to port
     xchg al,ah                   ;swap data/reg num
     out dx,al                    ;output to port
     xchg ah,al                   ;swap back
     inc al                               ;next reg
     inc esi                      ;increase source
     cmp al,cl                    ;done yet?
     jb vga.setmoderegs_l3    ;loop until done
     mov al,VGAC.ENABLEATTRIB ;enable attribute register reads
     out dx,al                    ;do it
     ret                              ;and exit
endp                                  ;