Ich bin mal so frei und poste meinen Code. Der ist zwar zu 90 % zusammengeklaut, aber er funktioniert.
Im Prinzip muss man nur jede menge VGA-Register mit den richtigen Werten füttern. Um das ganze so einfach wie möglich zu machen, speichert man die Registerwerte für einen Modus in einem Block.
Zum Moduswechsel wird eine Funktion benutzt, die diesen Block ausliest und in die richtigen Register schreibt.
Ein Wechsel in den mode13h sehe dann so aus:
mov edi, vga.mode.graphic_320x200x256
call vga.set_registers
;IN: edi=@register_set
vga.set_registers:
push eax
push ecx
push edx
push edi
;MISC
mov dx, vga.reg.misc_write
mov al, [edi]
out dx, al
inc edi
;sequencer
xor ecx, ecx
.loop_seq:
mov dx, vga.reg.seq_index
mov eax, ecx
out dx, al
mov dx, vga.reg.seq_data
mov al, [edi]
out dx, al
inc edi
inc ecx
cmp ecx, 5
jne .loop_seq
;unlock crtc registers
mov dx, vga.reg.crtc_index
mov al, 3
out dx, al
mov dx, vga.reg.crtc_data
in al, dx
or al, 0x80 ;set ? bit
out dx, al
mov dx, vga.reg.crtc_index
mov al, 11
out dx, al
mov dx, vga.reg.crtc_data
in al, dx
and al, 0x7F ;del ? bit
out dx, al
;???make sure they remain unlocked???
or byte[edi+ 3],0x80
and byte[edi+11],0x7F
;write crtc registers
xor ecx, ecx
.loop_crtc:
mov dx, vga.reg.crtc_index
mov eax, ecx
out dx, al
mov dx, vga.reg.crtc_data
mov al, [edi]
out dx, al
inc edi
inc ecx
cmp ecx, 25
jne .loop_crtc
;write gc (graphic controller) registers
xor ecx, ecx
.loop_gc:
mov dx, vga.reg.gc_index
mov eax, ecx
out dx, al
mov dx, vga.reg.gc_data
mov al, [edi]
out dx, al
inc edi
inc ecx
cmp ecx, 9
jne .loop_gc
;write ac (attribute controller) registers
xor ecx, ecx
.loop_ac:
;?
mov dx, vga.reg.instat_read
in al, dx
;?
mov dx, vga.reg.ac_index
mov eax, ecx
out dx, al
mov dx, vga.reg.ac_data_write
mov al, [edi]
out dx, al
inc edi
inc ecx
cmp ecx, 21
jne .loop_ac
;/* lock 16-color palette and unblank display */
; (void)inportb(VGA_INSTAT_READ);
; outportb(VGA_AC_INDEX, 0x20);
;???lock 16 color palette???
mov dx, vga.reg.instat_read
in al, dx
mov dx, vga.reg.ac_index
mov al, 0x20
out dx, al
pop edi
pop edx
pop ecx
pop eax
ret
;register sets for different modi
;MISC
;SEQ
;CRTC
;GC
;AC
;text modes
;()=to do
; 40x25 (40x30) 40x50 (40x60)
; (45x25) (45x30) (45x50) (45x60)
; 80x25 (80x30) 80x50 (80x60)
; (90x25) 90x30 (90x50) 90x60
;vga.mode.text_40x25:
;MISC
; db 0x67
;SEQ
; db 0x03, 0x08, 0x03, 0x00, 0x02
;CRTC
; db 0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F
; db 0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0xA0
; db 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3
; db 0xFF
;GC
; db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00
; db 0xFF
;AC
; db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
; db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
; db 0x0C, 0x00, 0x0F, 0x08, 0x00
;vga.mode.text_40x50:
;MISC
; db 0x67
;SEQ
; db 0x03, 0x08, 0x03, 0x00, 0x02
;CRTC
; db 0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F
; db 0x00, 0x47, 0x06, 0x07, 0x00, 0x00, 0x04, 0x60
; db 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3
; db 0xFF
;GC
; db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00
; db 0xFF
;AC
; db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
; db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
; db 0x0C, 0x00, 0x0F, 0x08, 0x00
vga.mode.text_80x25: ;this is the standard mode!
;MISC
db 0x67
;SEQ
db 0x03, 0x00, 0x03, 0x00, 0x02
;CRTC
db 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F
db 0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x50
db 0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3
db 0xFF
;GC
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00
db 0xFF
;AC
db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
db 0x0C, 0x00, 0x0F, 0x08, 0x00
vga.mode.text_80x50:
;MISC
db 0x67
;SEQ
db 0x03, 0x00, 0x03, 0x00, 0x02
;CRTC
db 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F
db 0x00, 0x47, 0x06, 0x07, 0x00, 0x00, 0x01, 0x40
db 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3
db 0xFF
;GC
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00
db 0xFF
;AC
db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
db 0x0C, 0x00, 0x0F, 0x08, 0x00
vga.mode.text_90x30:
;MISC
db 0xE7
;SEQ
db 0x03, 0x01, 0x03, 0x00, 0x02
;CRTC
db 0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E
db 0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x00
db 0xEA, 0x0C, 0xDF, 0x2D, 0x10, 0xE8, 0x05, 0xA3
db 0xFF
;GC
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00
db 0xFF
;AC
db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
db 0x0C, 0x00, 0x0F, 0x08, 0x00
vga.mode.text_90x60:
;MISC
db 0xE7
;SEQ
db 0x03, 0x01, 0x03, 0x00, 0x02
;CRTC
db 0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E
db 0x00, 0x47, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00
db 0xEA, 0x0C, 0xDF, 0x2D, 0x08, 0xE8, 0x05, 0xA3
db 0xFF
;GC
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00
db 0xFF
;AC
db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
db 0x0C, 0x00, 0x0F, 0x08, 0x00
;graphic modes *****************************************************************
vga.mode.graphic_320x200x256:
;MISC
db 0x63
;SEQ
db 0x03, 0x01, 0x0F, 0x00, 0x0E
;CRTC
db 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F
db 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3
db 0xFF
;GC
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F
db 0xFF
;AC
db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
db 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
db 0x41, 0x00, 0x0F, 0x00, 0x00
vga.mode.graphic_640x480x16:
;MISC
db 0xE3
;SEQ
db 0x03, 0x01, 0x08, 0x00, 0x06
;CRTC
db 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E
db 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3
db 0xFF
;GC
db 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F
db 0xFF
;AC
db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07
db 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
db 0x01, 0x00, 0x0F, 0x00, 0x00
;vga.mode.graphic_640x480x2
;vga.mode.graphic_320x200x4
;vga.mode.graphic_720x480x16
;vga.mode.graphic_320x200x256_modex
;unsigned char g_640x480x2[] =
;{
;/* MISC */
; 0xE3,
;/* SEQ */
; 0x03, 0x01, 0x0F, 0x00, 0x06,
;/* CRTC */
; 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E,
; 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
; 0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
; 0xFF,
;/* GC */
; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F,
; 0xFF,
;/* AC */
; 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
; 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
; 0x01, 0x00, 0x0F, 0x00, 0x00
;};
;/*****************************************************************************
;*** NOTE: the mode described by g_320x200x4[]
;is different from BIOS mode 05h in two ways:
;- Framebuffer is at A000:0000 instead of B800:0000
;- Framebuffer is linear (no screwy line-by-line CGA addressing)
;*****************************************************************************/
;unsigned char g_320x200x4[] =
;{
;/* MISC */
; 0x63,
;/* SEQ */
; 0x03, 0x09, 0x03, 0x00, 0x02,
;/* CRTC */
; 0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F,
; 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
; 0x9C, 0x0E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA3,
; 0xFF,
;/* GC */
; 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00,
; 0xFF,
;/* AC */
; 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
; 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
; 0x01, 0x00, 0x03, 0x00, 0x00
;};
;unsigned char g_720x480x16[] =
;{
;/* MISC */
; 0xE7,
;/* SEQ */
; 0x03, 0x01, 0x08, 0x00, 0x06,
;/* CRTC */
; 0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E,
; 0x00, 0x40, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
; 0xEA, 0x0C, 0xDF, 0x2D, 0x08, 0xE8, 0x05, 0xE3,
; 0xFF,
;/* GC */
; 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F,
; 0xFF,
;/* AC */
; 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
; 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
; 0x01, 0x00, 0x0F, 0x00, 0x00,
;};
;unsigned char g_320x200x256_modex[] =
;{
;/* MISC */
; 0x63,
;/* SEQ */
; 0x03, 0x01, 0x0F, 0x00, 0x06,
;/* CRTC */
; 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
; 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
; 0x9C, 0x0E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
; 0xFF,
;/* GC */
; 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
; 0xFF,
;/* AC */
; 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
; 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
; 0x41, 0x00, 0x0F, 0x00, 0x00
;};
;/* g_360x480x256_modex - to do */