Setting VGA 640*480 mode without interrupts or V8086
Setting VGA 640*480 mode without interrupts or V8086
I need to switch to VGA 640*480 graphics mode, but i can't use interrupts and V8086. How to change graphics mode without interrupts and V8086 (e.g. out* and in*)?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Setting VGA 640*480 mode without interrupts or V8086
Hi,
If you like potentially dodgy hacks; you can cross your fingers and hope the previous video mode wasn't an "SVGA or better" mode and assume the video card is using ancient "VGA compatibility", and assume that this compatibility is "good enough" (e.g. closer to 99% compatible at the hardware level rather than just 80% compatible); then you can put a Michael Jackson cassette tape in your walkman (to get that authentic 1980s vibe happening) and diddle with the "VGA" hardware directly.
Cheers,
Brendan
For which specific video card when it's using which specific video mode beforehand?catnikita255 wrote:I need to switch to VGA 640*480 graphics mode, but i can't use interrupts and V8086. How to change graphics mode without interrupts and V8086 (e.g. out* and in*)?
If you like potentially dodgy hacks; you can cross your fingers and hope the previous video mode wasn't an "SVGA or better" mode and assume the video card is using ancient "VGA compatibility", and assume that this compatibility is "good enough" (e.g. closer to 99% compatible at the hardware level rather than just 80% compatible); then you can put a Michael Jackson cassette tape in your walkman (to get that authentic 1980s vibe happening) and diddle with the "VGA" hardware directly.
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.
Re: Setting VGA 640*480 mode without interrupts or V8086
I'm read it, but how do i write the values to the registers? I'm found the tutorial, but it's not opening =(. This is the tutorial: http://www.osdever.net/index.php/tutori ... UI_tut.pdf. Is anybody has a copy of it?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Setting VGA 640*480 mode without interrupts or V8086
The correct way is really to use the BIOS.
with in/out ?catnikita255 wrote:I'm read it, but how do i write the values to the registers? I'm found the tutorial, but it's not opening =(. This is the tutorial: http://www.osdever.net/index.php/tutori ... UI_tut.pdf. Is anybody has a copy of it?
Re: Setting VGA 640*480 mode without interrupts or V8086
Use the code below:
the functions are documented with comments, showing the registers for the parameters.
Use set_mode_0x13 to switch to 640 * 480 VGA mode, and put_0x13_pixel for pixel plotting.
Hope this helps!
btw, this is what i use in my C code for calling the putpixel routine
the functions are documented with comments, showing the registers for the parameters.
Use set_mode_0x13 to switch to 640 * 480 VGA mode, and put_0x13_pixel for pixel plotting.
Hope this helps!
Code: Select all
[BITS 32]
; symbol exports
[GLOBAL set_mode_0x03]
[GLOBAL set_mode_0x13]
[GLOBAL put_0x13_pixel]
;-------------------;
; VGA palettes ;
;-------------------;
palette256 db 00, 00, 00, 00, 10, 41, 12, 28, 18, 02, 43, 22, 35
db 19, 09, 58, 00, 00, 57, 35, 12, 43, 43, 47, 24, 24
db 28, 20, 24, 60, 10, 60, 15, 31, 47, 63, 62, 56, 20
db 60, 56, 22, 63, 61, 36, 63, 63, 63, 00, 00, 00, 05
db 05, 05, 08, 08, 08, 11, 11, 11, 14, 14, 14, 17, 17
db 17, 20, 20, 20, 24, 24, 24, 28, 28, 28, 32, 32, 32
db 36, 36, 36, 40, 40, 40, 45, 45, 45, 50, 50, 50, 56
db 56, 56, 63, 63, 63, 13, 12, 15, 15, 16, 22, 17, 20
db 29, 19, 24, 36, 21, 28, 43, 23, 31, 50, 25, 34, 57
db 26, 42, 63, 00, 15, 02, 01, 22, 04, 02, 29, 06, 03
db 36, 08, 04, 43, 10, 05, 50, 12, 06, 57, 14, 20, 63
db 40, 18, 06, 07, 25, 12, 11, 33, 17, 14, 40, 23, 18
db 48, 28, 21, 55, 34, 25, 62, 39, 27, 63, 48, 36, 15
db 03, 02, 22, 06, 04, 29, 09, 06, 36, 12, 08, 43, 15
db 10, 50, 18, 12, 57, 21, 14, 63, 28, 20, 15, 00, 00
db 22, 07, 00, 29, 15, 00, 36, 23, 00, 43, 31, 00, 50
db 39, 00, 57, 47, 00, 63, 55, 00, 15, 05, 03, 22, 11
db 07, 29, 17, 11, 36, 23, 15, 43, 29, 19, 50, 35, 23
db 57, 41, 27, 63, 53, 34, 28, 14, 12, 33, 20, 14, 38
db 26, 16, 43, 32, 18, 48, 38, 20, 53, 44, 22, 58, 50
db 24, 63, 56, 30, 05, 05, 06, 10, 10, 13, 15, 15, 20
db 20, 20, 27, 25, 25, 34, 30, 30, 41, 35, 35, 48, 44
db 44, 63, 03, 06, 05, 05, 11, 09, 07, 16, 13, 09, 21
db 17, 11, 26, 21, 13, 31, 25, 15, 36, 29, 20, 48, 38
db 06, 06, 07, 13, 13, 15, 20, 20, 23, 27, 27, 31, 34
db 34, 39, 41, 41, 47, 48, 48, 55, 57, 57, 63, 06, 15
db 04, 12, 22, 08, 18, 29, 12, 24, 36, 16, 30, 43, 20
db 36, 50, 24, 42, 57, 28, 54, 63, 35, 15, 10, 10, 22
db 16, 16, 29, 21, 21, 36, 27, 27, 43, 32, 32, 50, 38
db 38, 57, 43, 43, 63, 54, 54, 15, 15, 06, 22, 22, 12
db 29, 29, 18, 36, 36, 24, 43, 43, 30, 50, 50, 36, 57
db 57, 42, 63, 63, 54, 02, 04, 14, 06, 12, 21, 10, 20
db 28, 14, 28, 35, 18, 36, 42, 22, 44, 49, 26, 52, 56
db 36, 63, 63, 18, 04, 14, 24, 08, 21, 31, 12, 28, 37
db 16, 35, 44, 20, 42, 50, 24, 49, 57, 28, 56, 63, 38
db 63, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 53, 44, 22, 09
db 08, 12, 16, 14, 16, 22, 21, 20, 29, 27, 24, 35, 34
db 28, 42, 40, 32, 48, 47, 36, 57, 56, 43, 08, 12, 16
db 14, 16, 22, 21, 20, 29, 27, 24, 35, 34, 28, 42, 40
db 32, 48, 47, 36, 57, 56, 43, 63, 13, 09, 11, 21, 16
db 15, 27, 22, 18, 36, 29, 22, 42, 35, 25, 51, 42, 29
db 57, 48, 32, 63, 56, 39, 06, 14, 09, 12, 21, 14, 18
db 27, 22, 24, 33, 28, 30, 39, 36, 36, 46, 42, 42, 52
db 47, 50, 59, 53, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
db 00
palette16 db 00, 00, 00, 00, 00, 42, 00, 42, 00, 00, 42, 42, 42
db 00, 00, 42, 00, 42, 42, 21, 00, 42, 42, 42, 21, 21
db 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 63, 21, 21
db 63, 21, 63, 63, 63, 21, 63, 63, 63
;---------------------;
; VGA mode values. ;
;---------------------;
mode0x03 db 0x67, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x5F, 0x4F
db 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0E
db 0x0F, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0E, 0x8F, 0x28
db 0x01, 0x96, 0xB9, 0xA3, 0xFF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x10, 0x0E, 0x00, 0xFF, 0x00, 0x01, 0x02, 0x03
db 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 0x3C
db 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00
mode0x13 db 0x63, 0x00, 0x03, 0x01, 0x0F, 0x00, 0x0E, 0x5F, 0x4F
db 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0E, 0x8F, 0x28
db 0x40, 0x96, 0xB9, 0xA3, 0xFF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x00, 0x01, 0x02, 0x03
db 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C
db 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00
vga_buff dd 0
;---------------------------------;
; sets the screen to mode 0x03 ;
;---------------------------------;
set_mode_0x03:
pushad
push ax
mov esi, mode0x03
call set_regs
;call load_font ; IT WORKS!! FINALLY!
mov esi, palette16
call set_palette16
pop ax
cmp ax, 1
jne .cont
;call cls ; in text.inc
.cont:
popad
ret
;---------------------------------;
; sets the screen to mode 0x13 ;
;---------------------------------;
set_mode_0x13:
pushad
push ax
mov esi, mode0x13
call set_regs
mov esi, palette256
call set_palette256
pop ax
cmp ax, 1
jne .cont
mov edi, 0xa0000 ; write directly to mem
mov ax, 0x0000 ; clear all 256kb with color 0
mov ecx, 0x20000 ; 256kb, 0x20000 = (256*1024)/2
rep stosw ; by wordwrites
.cont:
popad
ret
;------------------------------------;
; put a pixel at x, y with color ;
; used only in mode 0x13 ;
; ;
; input: bx = x ;
; cx = y ;
; al = color ;
; ;
; output: none. ;
;------------------------------------;
put_0x13_pixel:
push ax
push bx
push cx
push edi
mov edi, 0xa0000 ; directly to mem
add di, bx
mov bx, cx
shl cx, 8
shl bx, 6
add cx, bx
add di, cx
stosb
pop edi
pop cx
pop bx
pop ax
ret
;-----------------------------------------------------;
; put a sprite at x, y. only for mode 0x13 ;
; ;
; input: ax = x, bx = y, cx = width, dx = height ;
; esi = pointer to sprite ;
; ;
; output: none. ;
;-----------------------------------------------------;
put_0x13_sprite:
pushad ; this was a
.row_loop: ; nightmare to write.
dec dx ; guess how many times
push cx ; i got lost in the push
push ax ; and pops here.. ;)
.col_loop: ; not to mention what
dec cx ; time it was when i wrote
push ax ; it.. :P
push bx
push cx
mov cx, bx
mov bx, ax
lodsb
call put_0x13_pixel
pop cx
pop bx
pop ax
inc ax
cmp cx, 0
jne .col_loop
pop ax
pop cx
inc bx
cmp dx, 0
jne .row_loop
popad
ret
;---------------------------------------------;
; sets the palette (256 colors) ;
; ;
; input: esi = palette. ;
; output: none. ;
;---------------------------------------------;
set_palette256:
push ax
push cx
push dx
xor cx, cx
.l1:
mov dx, 0x03C8
mov al, cl ; color no. = loop no.
out dx, al
inc dx ; port 0x3C9
mov al, byte [esi] ; red
out dx, al
inc esi
mov al, byte [esi] ; green
out dx, al
inc esi
mov al, byte [esi] ; blue
out dx, al
inc esi
inc cx
cmp cx, 256
jl .l1
pop dx
pop cx
pop ax
ret
;---------------------------------------------;
; sets the palette (16 colors) ;
; ;
; input: esi = pointer to palette. ;
; output: none. ;
;---------------------------------------------;
set_palette16:
push ax
push cx
push dx
xor cx, cx
.l1:
mov dx, 0x3DA
in al, dx
mov al, cl ; color no.
mov dx, 0x3C0
out dx, al
inc dx ; port 0x3C1
in al, dx
mov dx, 0x3C8
out dx, al
inc dx ; port 0x3C9
mov al, byte [esi] ; red
out dx, al
inc esi
mov al, byte [esi] ; green
out dx, al
inc esi
mov al, byte [esi] ; blue
out dx, al
inc esi
inc cx
cmp cx, 16
jl .l1
mov dx, 0x3DA
in al, dx
mov al, 0x20
mov dx, 0x3C0
out dx, al
pop dx
pop cx
pop ax
ret
;---------------------------------;
; Set VGA regs to choosen mode ;
; internal use. ;
;---------------------------------;
set_regs:
cli
mov dx, 0x3C2
lodsb
out dx, al
mov dx, 0x3DA
lodsb
out dx, al
xor ecx, ecx
mov dx, 0x3C4
.l1:
lodsb
xchg al, ah
mov al, cl
out dx, ax
inc ecx
cmp cl, 4
jbe .l1
mov dx, 0x3D4
mov ax, 0x0E11
out dx, ax
xor ecx, ecx
mov dx, 0x3D4
.l2:
lodsb
xchg al, ah
mov al, cl
out dx, ax
inc ecx
cmp cl, 0x18
jbe .l2
xor ecx, ecx
mov dx, 0x3CE
.l3:
lodsb
xchg al, ah
mov al, cl
out dx, ax
inc ecx
cmp cl, 8
jbe .l3
mov dx, 0x3DA
in al, dx
xor ecx, ecx
mov dx, 0x3C0
.l4:
in ax, dx
mov al, cl
out dx, al
lodsb
out dx, al
inc ecx
cmp cl, 0x14
jbe .l4
mov al, 0x20
out dx, al
sti
ret
Code: Select all
extern void put_0x13_pixel();
void putpixel (uint16_t x, uint16_t y, uint8_t c) {
__asm__ __volatile__ ("mov %0, %%bx\n\t"
"mov %1, %%cx\n\t"
"mov %2, %%al"
: /* NULL */
: "X"(x), "X"(y), "X"(c));
put_0x13_pixel();
}
Joonyoung Lee
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
Re: Setting VGA 640*480 mode without interrupts or V8086
Hi,
Cheers,
Brendan
That code only sets mode 0x13 (320*200 with 256 colours) and doesn't set mode 0x12 (640*480 with 16 colours).0fb1d8 wrote:Use the code below:
the functions are documented with comments, showing the registers for the parameters.
Use set_mode_0x13 to switch to 640 * 480 VGA mode, and put_0x13_pixel for pixel plotting.
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.
Re: Setting VGA 640*480 mode without interrupts or V8086
Refer to the IBM VGA register specification to know the meaning of each register so that you can set up any video mode you want. That's what I did to be able to make my routine to set VGA-compatible text and graphic modes. Here is my code:
You would use it like this:
Hope this helps.
Code: Select all
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
typedef unsigned long long int qword;
inline byte inb(word port)
{
byte r;
asm volatile(
".intel_syntax noprefix\n\t"
"in al,dx\n\t"
".att_syntax"
:"=a"(r)
:"d"(port)
);
return(r);
}
inline void outb(word port,byte val)
{
asm volatile(
".intel_syntax noprefix\n\t"
"out dx,al\n\t"
".att_syntax"
:
:"d"(port),"a"(val)
);
}
//constants
#define VGA_CRT 0 //CRT set
#define VGA_ACT 1 //attribute controller set
#define VGA_GEN 2 //general registers set
#define VGA_SEQ 3 //sequencer set
#define VGA_GCT 4 //graphics controller set
#define VGA_OLD 5 //old pallete enable
#define VGA__GEN__MIS 0 //miscellaneous in the generals set
#define VGA__GEN__ST1 1 //status 1 in the generals set, readonly
#define VGA__OLD__ENA 0 //old pallete enable index
#define VGA__GEN_MISC_R 0x3cc //general miscellaneous, read
#define VGA__GEN_MISC_W 0x3c2 //general miscellaneous, write
#define VGA__GEN_STATUS1 0x3da //general status 1
#define VGA__SEQ_ADDR 0x3c4 //sequencer, address
#define VGA__SEQ_DATA 0x3c5 //sequencer, data
#define VGA__SEQ__RST 0 //sequencer, reset
#define VGA__SEQ__CLK 1 //sequencer, clock mode
#define VGA__SEQ__MAP 2 //sequencer, map selection
#define VGA__SEQ__FNT 3 //sequencer, font selection
#define VGA__SEQ__MEM 4 //sequencer, memory mode
#define VGA__CRT_ADDR 0x3d4 //CRT, address
#define VGA__CRT_DATA 0x3d5 //CRT, data
#define VGA__CRT__HTO 0 //CRT, horizontal total
#define VGA__CRT__HDE 1 //CRT, horizontal display-enable end
#define VGA__CRT__HBS 2 //CRT, horizontal blanking start
#define VGA__CRT__HBE 3 //CRT, horizontal blanking end
#define VGA__CRT__HRS 4 //CRT, horizontal retrace start
#define VGA__CRT__HRE 5 //CRT, horizontal retrace end
#define VGA__CRT__VTO 6 //CRT, vertical total
#define VGA__CRT__MSB 7 //CRT, most significant bits
#define VGA__CRT__PRS 8 //CRT, preset scanline
#define VGA__CRT__MSL 9 //CRT, maximum scanline
#define VGA__CRT__CSL 10 //CRT, cursor start
#define VGA__CRT__CEL 11 //CRT, cursor end
#define VGA__CRT__SAH 12 //CRT, start address (high)
#define VGA__CRT__SAL 13 //CRT, start address (low)
#define VGA__CRT__CLH 14 //CRT, cursor location (high)
#define VGA__CRT__CLL 15 //CRT, cursor location (low)
#define VGA__CRT__VRS 16 //CRT, vertical retrace start
#define VGA__CRT__VRE 17 //CRT, vertical retrace end
#define VGA__CRT__VDE 18 //CRT, vertical display-enable end
#define VGA__CRT__OFF 19 //CRT, offset (logical line width)
#define VGA__CRT__ULL 20 //CRT, underline location
#define VGA__CRT__VBS 21 //CRT, vertical blanking start
#define VGA__CRT__VBE 22 //CRT, vertical blanking end
#define VGA__CRT__MOD 23 //CRT, mode
#define VGA__CRT__SSL 24 //CRT, line compare (split screen line)
#define VGA__GCT_ADDR 0x3ce //graphics controller, address
#define VGA__GCT_DATA 0x3cf //graphics controller, data
#define VGA__GCT__WRV 0 //graphics controller, write value
#define VGA__GCT__WRS 1 //graphics controller, write selection
#define VGA__GCT__COC 2 //graphics controller, color compare
#define VGA__GCT__DRO 3 //graphics controller, data rotate
#define VGA__GCT__RDM 4 //graphics controller, read map
#define VGA__GCT__GMO 5 //graphics controller, graphics mode
#define VGA__GCT__MIS 6 //graphics controller, miscelaneous
#define VGA__GCT__CSE 7 //graphics controller, color selection
#define VGA__GCT__BIT 8 //graphics controller, bit mask
#define VGA__ACT_ADDA 0x3c0 //attribute controller, address and data
#define VGA__ACT_READ 0x3c1 //attribute controller, read
#define VGA__ACT__ATB 16 //attribute controller, attributes
#define VGA__ACT__BOR 17 //attribute controller, border color
#define VGA__ACT__PEN 18 //attribute controller, plane enable
#define VGA__ACT__OFF 19 //attribute controller, offset
#define VGA__ACT__CSE 20 //attribute controller, color selection
#define VGA__DAC_ADDR_R 0x3c7 //pallete, read address
#define VGA__DAC_ADDR_W 0x3c8 //pallete, write address
#define VGA__DAC_DATA 0x3c9 //pallete, data
#define VGA__DAC_MASK 0x3c6 //pallete, bit mask
//VGA register structure
typedef struct
{
byte
gen_mis,
seq[5],
crt[25],
gct[9],
act[5];
}vgaregs_t;
//tables for horizontal configurations
//SEQ_CLK,SEQ_MEM,CRT_HTO,CRT_HDE,CRT_HBS,CRT_HBE,CRT_HRS,CRT_HRE,CRT_OFF,GCT_GMO,GCT_MIS,ACT_ATB
byte tbl_hor_txt40[12]={0x08,0x00,0x2d,0x27,0x28,0x10,0x2b,0xa0,0x14,0x10,0x0e,0x00};
byte tbl_hor_txt80[12]={0x00,0x00,0x5f,0x4f,0x50,0x02,0x55,0x81,0x28,0x10,0x0e,0x00};
byte tbl_hor_txt90[12]={0x00,0x00,0x6b,0x59,0x5a,0x0e,0x5f,0xac,0x2d,0x10,0x0e,0x00};
//0x5e,0xaa
byte tbl_hor_gra640[12]={0x01,0x04,0x5f,0x4f,0x50,0x02,0x54,0x80,0x28,0x00,0x05,0x01};
//0x55,0x81
byte tbl_hor_gra720[12]={0x01,0x04,0x6b,0x59,0x5a,0x0e,0x5e,0xaa,0x2d,0x00,0x05,0x01};
//0x5f,0xac
byte tbl_hor_gra320[12]={0x01,0x04,0x5f,0x4f,0x50,0x02,0x54,0x80,0x28,0x40,0x05,0x41};
//0x55,0x81
byte tbl_hor_gra360[12]={0x01,0x04,0x6b,0x59,0x5a,0x0e,0x5e,0xaa,0x2d,0x40,0x05,0x41};
//0x5f,0xac
//tables for vertical configurations
//GEN_MIS,CRT_VTO,CRT_MSB,CRT_MSL,CRT_VRS,CRT_VRE,CRT_VDE,CRT_VBS,CRT_VBE
byte tbl_ver_txt20_12[9]={0xc0,0x0b,0x3e,0xcb,0xea,0x0c,0xdf,0xe7,0x04};
byte tbl_ver_txt25_8[9]={0x40,0xbf,0x1f,0xc7,0x9c,0x2e,0x8f,0x96,0xb9};
byte tbl_ver_txt25_14[9]={0x80,0xbf,0x1f,0x4d,0x83,0x35,0x5d,0x63,0xba};
byte tbl_ver_txt25_16[9]={0x40,0xbf,0x1f,0x4f,0x9c,0x2e,0x8f,0x96,0xb9};
byte tbl_ver_txt30_8[9]={0xc0,0x0b,0x3e,0xc7,0xea,0x0c,0xdf,0xe7,0x04};
byte tbl_ver_txt30_16[9]={0xc0,0x0b,0x3e,0x4f,0xea,0x0c,0xdf,0xe7,0x04};
byte tbl_ver_txt40_12[9]={0xc0,0x0b,0x3e,0x4b,0xea,0x0c,0xdf,0xe7,0x04};
byte tbl_ver_txt50_8[9]={0x40,0xbf,0x1f,0x47,0x9c,0x2e,0x8f,0x96,0xb9};
byte tbl_ver_txt60_8[9]={0xc0,0x0b,0x3e,0x47,0xea,0x0c,0xdf,0xe7,0x04};
byte tbl_ver_gra200[9]={0x40,0xbf,0x1f,0x41,0x9c,0x2e,0x8f,0x96,0xb9};
byte tbl_ver_gra240[9]={0xc0,0x0b,0x3e,0x41,0xea,0x0c,0xdf,0xe7,0x04};
byte tbl_ver_gra350[9]={0x80,0xbf,0x1f,0x40,0x83,0x35,0x5d,0x63,0xba};
byte tbl_ver_gra400[9]={0x40,0xbf,0x1f,0x40,0x9c,0x2e,0x8f,0x96,0xb9};
byte tbl_ver_gra480[9]={0xc0,0x0b,0x3e,0x40,0xea,0x0c,0xdf,0xe7,0x04};
//tables for video modes
//SEQ_CLK,ACT_OFF,CRT_MOD
byte tbl_mod_txt8p[]={0x01,0x00,0x00};
byte tbl_mod_txt9p[]={0x00,0x08,0x00};
byte tbl_mod_gra16c[]={0x01,0x00,0x40};
byte tbl_mod_gra256c[]={0x01,0x00,0x40};
//functions
//writes a value in a VGA register
//set is 0 for CRT controller, 1 for attribute controller, 2 for
//generals, 3 for sequencer, 4 for graphics controller, 5 for
//old pallete enable
void VGAWriteReg(byte set, byte index, byte value)
{
switch(set)
{
case VGA_CRT:
if(index<=24)
{
outb(VGA__CRT_ADDR,index);
outb(VGA__CRT_DATA,value);
}
break;
case VGA_ACT:
if(index<=20)
{
inb(VGA__GEN_STATUS1);
index=(inb(VGA__ACT_ADDA)&0x20)|index;
inb(VGA__GEN_STATUS1);
outb(VGA__ACT_ADDA,index);
outb(VGA__ACT_ADDA,value);
}
break;
case VGA_GEN:
if(index==0)
{
outb(VGA__GEN_MISC_W,value);
}
break;
case VGA_SEQ:
if(index<=4)
{
outb(VGA__SEQ_ADDR,index);
outb(VGA__SEQ_DATA,value);
}
break;
case VGA_GCT:
if(index<=8)
{
outb(VGA__GCT_ADDR,index);
outb(VGA__GCT_DATA,value);
}
break;
case VGA_OLD:
if(index==0)
{
value=value?0x20:0;
inb(VGA__GEN_STATUS1);
outb(VGA__ACT_ADDA,value);
}
break;
}
}
//reads a value from a VGA register
//set is 0 for CRT controller, 1 for attribute controller, 2 for
//generals, 3 for sequencer, 4 for graphics controller, 5 for
//old pallete enable
byte VGAReadReg(byte set, byte index)
{
byte r=0;
switch(set)
{
case VGA_CRT:
if(index<=24)
{
outb(VGA__CRT_ADDR,index);
r=inb(VGA__CRT_DATA);
}
break;
case VGA_ACT:
if(index<=20)
{
inb(VGA__GEN_STATUS1);
index=(inb(VGA__ACT_ADDA)&0x20)|index;
inb(VGA__GEN_STATUS1);
outb(VGA__ACT_ADDA,index);
r=inb(VGA__ACT_READ);
}
break;
case VGA_GEN:
if(index==VGA__GEN__MIS)
{
r=inb(VGA__GEN_MISC_R);
}
if(index==VGA__GEN__ST1)
{
r=inb(VGA__GEN_STATUS1);
}
break;
case VGA_SEQ:
if(index<=4)
{
outb(VGA__SEQ_ADDR,index);
r=inb(VGA__SEQ_DATA);
}
break;
case VGA_GCT:
if(index<=8)
{
outb(VGA__GCT_ADDR,index);
r=inb(VGA__GCT_DATA);
}
break;
case VGA_OLD:
if(index==0)
{
inb(VGA__GEN_STATUS1);
r=(inb(VGA__ACT_ADDA)>>5)&1;
}
break;
}
return(r);
}
//resets the registers in a VGA register structure
void resetregs(vgaregs_t*regs)
{
dword i;
byte*p=(byte*)regs;
for(i=0;i<sizeof(vgaregs_t);i++)
{
*p++=0;
}
regs->gen_mis=0x23;//enable video memory, normal mode, upper 64KB page
regs->seq[VGA__SEQ__CLK]=0x02;//set bit to 1
regs->seq[VGA__SEQ__MAP]=0x0f;//select the 4 planes
regs->seq[VGA__SEQ__MEM]=0x02;//enable 256KB
regs->crt[VGA__CRT__HBE]=0x80;//set bit to 1
regs->crt[VGA__CRT__VRE]=0x30;//disable IRQs
regs->crt[VGA__CRT__ULL]=31;//underline location
regs->crt[VGA__CRT__MSB]=0x10;//split screen
regs->crt[VGA__CRT__MSL]=0x40;
regs->crt[VGA__CRT__SSL]=0xff;
regs->crt[VGA__CRT__MOD]=0xa3;//normal mode
regs->gct[VGA__GCT__BIT]=0xff;//bit mask
regs->act[VGA__ACT__ATB-16]=0x04;//enable line characters
regs->act[VGA__ACT__PEN-16]=0x0f;//enable the 4 planes
}
//changes the video mode by writing in all the VGA registers
void vgachangemode(vgaregs_t*regs)
{
word i;
//unlock some CRTC registrrs
VGAWriteReg(VGA_CRT,VGA__CRT__VRE,VGAReadReg(VGA_CRT,VGA__CRT__VRE)&0x7f);
//enable pallete
outb(VGA__DAC_MASK,0xff);
//wait until display-enable start
//while(!(VGAReadReg(VGA_GEN,VGA__GEN__ST1)&0x08));
//while(VGAReadReg(VGA_GEN,VGA__GEN__ST1)&0x08);
//stop sequencer
VGAWriteReg(VGA_SEQ,VGA__SEQ__RST,0x01);
//write in the registers
VGAWriteReg(VGA_GEN,VGA__GEN__MIS,regs->gen_mis);
for(i=1;i<5;i++)
VGAWriteReg(VGA_SEQ,i,regs->seq[i]);
for(i=0;i<25;i++)
VGAWriteReg(VGA_CRT,i,regs->crt[i]);
for(i=0;i<9;i++)
VGAWriteReg(VGA_GCT,i,regs->gct[i]);
for(i=0;i<5;i++)
VGAWriteReg(VGA_ACT,i+16,regs->act[i]);
//reset old pallete
VGAWriteReg(VGA_OLD,VGA__OLD__ENA,0);
for(i=0;i<16;i++)
VGAWriteReg(VGA_ACT,i,i);
VGAWriteReg(VGA_OLD,VGA__OLD__ENA,1);
//resume sequencer
VGAWriteReg(VGA_SEQ,VGA__SEQ__RST,0x03);
}
//selects the text plane
void settextplane(void)
{
VGAWriteReg(VGA_GCT,VGA__GCT__GMO,0x10);
VGAWriteReg(VGA_GCT,VGA__GCT__MIS,(VGAReadReg(VGA_GCT,VGA__GCT__MIS)&0x0c)|2);
VGAWriteReg(VGA_SEQ,VGA__SEQ__MAP,0x03);
VGAWriteReg(VGA_GCT,VGA__GCT__RDM,1);
VGAWriteReg(VGA_SEQ,VGA__SEQ__MEM,0x02);
}
//selects the font plane
void setfontplane(void)
{
VGAWriteReg(VGA_GCT,VGA__GCT__GMO,0x00);
VGAWriteReg(VGA_GCT,VGA__GCT__MIS,VGAReadReg(VGA_GCT,VGA__GCT__MIS)&0x0c);
VGAWriteReg(VGA_SEQ,VGA__SEQ__MAP,0x04);
VGAWriteReg(VGA_GCT,VGA__GCT__RDM,2);
VGAWriteReg(VGA_SEQ,VGA__SEQ__MEM,0x06);
}
//modifies the VGA pallete
//pal=pointer to the first pallete color to be used
//first=first color to modify
//num=number of colors to modify
void VGASetPal(byte*pal,byte first,word num)
{
if((num+first)>256)num=256-first;
if(!num)return;
num*=3;
outb(VGA__DAC_ADDR_W,first);
while(num--)
{
outb(VGA__DAC_DATA,(*pal)>>2);
pal++;
}
}
//obtains the VGA pallete
//pal=pointer to the first pallete color to be overwritten
//first=first color to read
//num=number of colors to read
void VGAGetPal(byte*pal,byte first,word num)
{
if((num+first)>256)num=256-first;
if(!num)return;
num*=3;
outb(VGA__DAC_ADDR_R,first);
while(num--)
{
*pal=inb(VGA__DAC_DATA)<<2;
pal++;
}
}
//puts the text cursor in the x,y coordinates
//w is the visual screen width in characters
void VGAGotoXY(byte x,byte y,byte w)
{
word c;
c=y;c*=w;
c+=x;
VGAWriteReg(VGA_CRT,VGA__CRT__CLH,c>>8);
VGAWriteReg(VGA_CRT,VGA__CRT__CLL,c);
}
//gets the cursor coordinates and returns them in x,y
//w is the visual screen width in characters
void VGAWhereXY(byte*x,byte*y,byte w)
{
word c;
c=VGAReadReg(VGA_CRT,VGA__CRT__CLH);
c<<=8;
c|=VGAReadReg(VGA_CRT,VGA__CRT__CLL);
*x=c%w;
*y=c/w;
}
//changes the text cursor appearence
//y=first line
//h=block height
void VGASetCursor(byte y,byte h)
{
VGAWriteReg(VGA_CRT,VGA__CRT__CSL,y&31);
VGAWriteReg(VGA_CRT,VGA__CRT__CEL,(y+h-1)&31);
}
//gets the text cursor appearence
//y=first line
//h=block height
void VGAGetCursor(byte*y,byte*h)
{
*y=VGAReadReg(VGA_CRT,VGA__CRT__CSL)&31;
*h=VGAReadReg(VGA_CRT,VGA__CRT__CEL)&31;
*h-=*y;
(*h)++;
}
//enables or disables the text cursor
void VGACursor(byte e)
{
e=e?0:0x20;
VGAWriteReg(VGA_CRT,VGA__CRT__CSL,(VGAReadReg(VGA_CRT,VGA__CRT__CSL)&31)|e);
}/*end function*/
//modifies the text font
//fnt=pointer to the first font character to be used
//ch=character height in the font
//first=first character in the VGA font to modify
//num=number of characters to modify
void VGASetFont(byte*fnt,byte ch,word first,word num)
{
byte*v=(byte*)0xb8000;
word i,j;
if((num+first)>512)num=512-first;
if(!num)return;
v+=first*32;
setfontplane();
for(i=0;i<num;i++)
{
for(j=0;j<ch;j++)
{
v[j]=fnt[j];
}
for(j=ch;j<32;j++)
{
v[j]=0;
}
fnt+=ch;
v+=32;
}
settextplane();
}
//obtains the text font
//fnt=pointer to the first font character to be overwritten
//ch=character height in the font
//first=first character in the VGA font to read
//num=number of characters to read
void VGAGetFont(byte*fnt,byte ch,word first,word num)
{
byte*v=(byte*)0xb8000;
word i,j;
if((num+first)>512)num=512-first;
if(!num)return;
v+=first*32;
setfontplane();
for(i=0;i<num;i++)
{
for(j=0;j<ch;j++)
{
fnt[j]=v[j];
}
fnt+=ch;
v+=32;
}
settextplane();
}
//waits until a vertical retrace period starts
void VGAWaitVBL(void)
{
while(VGAReadReg(VGA_GEN,VGA__GEN__ST1)&8);
while(!(VGAReadReg(VGA_GEN,VGA__GEN__ST1)&8));
}/*end function*/
//sets a VGA video mode
//returns 1 if the mode is valid, 0 if not
//m=mode
// 0=text (8-pixels-wide characters)
// 1=text (9-pixels-wide characters)
// 2=graphics 16 colors
// 3=graphics 256 colors
//w=width (in characters or in pixels)
//h=height (in characters or in pixels)
//o=option
// text modes:
// 8=8-pixels-high characters
// 12=12-pixels-high characters
// 14=14-pixels-high characters
// 16=16-pixels-high characters
// graphic modes:
// 0=normal
// 1=chained mode
//----------------------------------------------------------------
//text mode widths (8p): 40, 80, 90
//text mode widths (9p): 40, 80
//text mode heights (8-pix-h): 25, 30, 50, 60
//text mode heights (12-pix-h): 20, 40
//text mode heights (14-pix-h): 25
//text mode heights (16-pix-h): 25, 30
//graphic mode widths (16c): 640, 720
//graphic mode widths (256c): 320, 360
//graphic mode heights: 200, 240, 350, 400, 480
//chained mode only allows 320*200 at 256 colors
byte VGAMode(byte m,word w,word h,byte o)
{
byte*tbl_hor,*tbl_ver,*tbl_mod;
byte*v;
dword i;
vgaregs_t regs;
byte chained=0;
byte curstart=0,curheight=0;
resetregs(®s);
switch(m)
{
case 0://txt 8p
case 1://txt 9p
if(m)
{
tbl_mod=tbl_mod_txt9p;
regs.gen_mis|=0x04;
}
else
{
tbl_mod=tbl_mod_txt8p;
}
switch(w)
{
case 40:
tbl_hor=tbl_hor_txt40;
break;
case 80:
tbl_hor=tbl_hor_txt80;
break;
case 90:
if(m==1)return(0);
tbl_hor=tbl_hor_txt90;
regs.gen_mis|=0x04;
break;
default:
return(0);
}
switch(h)
{
case 20:
switch(o)
{
case 12:
tbl_ver=tbl_ver_txt20_12;
break;
default:
return(0);
}
break;
case 25:
switch(o)
{
case 8:
tbl_ver=tbl_ver_txt25_8;
break;
case 14:
tbl_ver=tbl_ver_txt25_14;
break;
case 16:
tbl_ver=tbl_ver_txt25_16;
break;
default:
return(0);
}
break;
case 30:
switch(o)
{
case 8:
tbl_ver=tbl_ver_txt30_8;
break;
case 16:
tbl_ver=tbl_ver_txt30_16;
break;
default:
return(0);
}
break;
case 40:
switch(o)
{
case 12:
tbl_ver=tbl_ver_txt40_12;
break;
default:
return(0);
}
break;
case 50:
switch(o)
{
case 8:
tbl_ver=tbl_ver_txt50_8;
break;
default:
return(0);
}
break;
case 60:
switch(o)
{
case 8:
tbl_ver=tbl_ver_txt60_8;
break;
default:
return(0);
}
break;
default:
return(0);
}
break;
case 2://gra 16c
if(o)return(0);
tbl_mod=tbl_mod_gra16c;
switch(w)
{
case 640:
tbl_hor=tbl_hor_gra640;
break;
case 720:
regs.gen_mis|=0x04;
tbl_hor=tbl_hor_gra720;
break;
default:
return(0);
}
switch(h)
{
case 200:
tbl_ver=tbl_ver_gra200;
break;
case 240:
tbl_ver=tbl_ver_gra240;
break;
case 350:
tbl_ver=tbl_ver_gra350;
break;
case 400:
tbl_ver=tbl_ver_gra400;
break;
case 480:
tbl_ver=tbl_ver_gra480;
break;
default:
return(0);
}
break;
case 3://gra 256c
tbl_mod=tbl_mod_gra256c;
switch(w)
{
case 320:
tbl_hor=tbl_hor_gra320;
break;
case 360:
regs.gen_mis|=0x04;
tbl_hor=tbl_hor_gra360;
break;
default:
return(0);
}
switch(h)
{
case 200:
tbl_ver=tbl_ver_gra200;
break;
case 240:
tbl_ver=tbl_ver_gra240;
break;
case 350:
tbl_ver=tbl_ver_gra350;
break;
case 400:
tbl_ver=tbl_ver_gra400;
break;
case 480:
tbl_ver=tbl_ver_gra480;
break;
default:
return(0);
}
switch(o)
{
case 0:
break;
case 1:
chained=1;
if((w!=320)||(h!=200))
return(0);
break;
default:
return(0);
}
break;
default:
return(0);
}
regs.seq[VGA__SEQ__CLK]|=tbl_hor[0];
regs.seq[VGA__SEQ__MEM]|=tbl_hor[1];
regs.crt[VGA__CRT__HTO]|=tbl_hor[2];
regs.crt[VGA__CRT__HDE]|=tbl_hor[3];
regs.crt[VGA__CRT__HBS]|=tbl_hor[4];
regs.crt[VGA__CRT__HBE]|=tbl_hor[5];
regs.crt[VGA__CRT__HRS]|=tbl_hor[6];
regs.crt[VGA__CRT__HRE]|=tbl_hor[7];
regs.crt[VGA__CRT__OFF]|=tbl_hor[8];
regs.gct[VGA__GCT__GMO]|=tbl_hor[9];
regs.gct[VGA__GCT__MIS]|=tbl_hor[10];
regs.act[VGA__ACT__ATB-16]|=tbl_hor[11];
regs.gen_mis|=tbl_ver[0];
regs.crt[VGA__CRT__VTO]|=tbl_ver[1];
regs.crt[VGA__CRT__MSB]|=tbl_ver[2];
regs.crt[VGA__CRT__MSL]|=tbl_ver[3];
regs.crt[VGA__CRT__VRS]|=tbl_ver[4];
regs.crt[VGA__CRT__VRE]|=tbl_ver[5];
regs.crt[VGA__CRT__VDE]|=tbl_ver[6];
regs.crt[VGA__CRT__VBS]|=tbl_ver[7];
regs.crt[VGA__CRT__VBE]|=tbl_ver[8];
regs.seq[VGA__SEQ__CLK]|=tbl_mod[0];
regs.act[VGA__ACT__OFF-16]|=tbl_mod[1];
regs.crt[VGA__CRT__MOD]|=tbl_mod[2];
if(chained)
{
regs.seq[VGA__SEQ__MEM]|=0x08;
regs.crt[VGA__CRT__ULL]|=0x40;
regs.crt[VGA__CRT__MOD]&=0xbf;
}
vgachangemode(®s);
switch(m)
{
case 0:
case 1:
setfontplane();
v=(byte*)0xb8000;
for(i=0;i<32768;i++)*v++=0;
settextplane();
v=(byte*)0xb8000;
for(i=0;i<32768;i++)*v++=0;
switch(o)
{
case 8:
curstart=o-2;
curheight=2;
break;
case 12:
curstart=o-4;
curheight=2;
break;
case 14:
curstart=o-4;
curheight=2;
break;
case 16:
curstart=o-6;
curheight=2;
}
VGASetCursor(curstart,curheight);
break;
case 2:
case 3:
v=(byte*)0xa0000;
VGAWriteReg(VGA_SEQ,VGA__SEQ__MAP,15);
for(i=0;i<65536;i++)*v++=0;
}
return(1);
}
Code: Select all
VGAMode(2,640,480,0);//set 640*480 at 16 colors
//VGASetFont(FONT,fontheight,0,256);//this only in text mode to set the font
//VGACursor(0);//this only in text mode in case you want to disable the cursor
VGASetPal(PAL16,0,16);//set the pallete
Re: Setting VGA 640*480 mode without interrupts or V8086
Thank you very much, but what is PAL16? Anything except this seems working for me.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Setting VGA 640*480 mode without interrupts or V8086
You should know that. It is a 16 color pallete. It would be defined as:catnikita255 wrote:Thank you very much, but what is PAL16? Anything except this seems working for me.
Code: Select all
byte PAL16[48]=
{
0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x00,
0x80,0x00,0x80,0x80,0x80,0x00,0xc0,0xc0,0xc0,0x80,0x80,0x80,0x00,0x00,0xff,
0x00,0xff,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0xff,0xff,0x00,
0xff,0xff,0xff
};
Re: Setting VGA 640*480 mode without interrupts or V8086
Ok, now the last thing. How to write putpixel()?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Setting VGA 640*480 mode without interrupts or V8086
You first need to understand how the memory is accessed in this bit-planar mode. The putpixel function would work OK, but drawing images with it would be extremly slow, so more functions are needed for other things like drawing rectangles or images.catnikita255 wrote:Ok, now the last thing. How to write putpixel()?
The VGA has 4 planes, and you can choose which planes to write to, and which plane to read from. There's only a 64KB memory window to access the 256KB video memory. With four planes, you can access the entire VGA memory. The memory is organized as follows: imagine you're in a monocrome mode with 1 bit per pixel, accessing a byte in video memory allows you to access 8 pixels at a time, the VGA added 3 more planes and instead of having 1bpp there are 4bpp, where each different bit in a pixel comes from a different plane, so all the 4 planes are read by the VGA each time a pixel has to be got from memory and drawn to the screen. It's not easy at the beginning, but it's just a matter of reordering the bits when converting from a normal image (in packed-pixel format) to a VGA-like image (in bit planar format). Well, this is how it works for 16 color modes, for 256 color unchained modes it's different, but the planes are used in a similar way.
The putpixel funcion would be like this, remember this is only for 16 color modes, you can't use this function for 256 color modes, wether chained or unchained.
Code: Select all
//puts a pixel in 16 color mode
//x,y=pixel coordinates
//color=pixel color
//w,h=screen dimensions
void VGAPix16(word x,word y,byte color,word w,word h)
{
byte*v=(byte*)0xa0000;
dword off;
int plane;
byte mask;
if((x>=w)||(y>=h))return;
off=(y*w+x)>>3;
v+=off;
mask=1<<(7-(x&7));
for(plane=0;plane<4;plane++)
{
VGAWriteReg(VGA_SEQ,VGA__SEQ__MAP,1<<plane);
VGAWriteReg(VGA_GCT,VGA__GCT__RDM,plane);
if(color&(1<<plane))
*v|=mask;
else
*v&=~mask;
}
}