#include "vgabios.h"
|
#include "vgabios.h"
|
|
|
/* Declares */
|
/* Declares */
|
static Bit8u read_byte();
|
static Bit8u read_byte();
|
static Bit16u read_word();
|
static Bit16u read_word();
|
static void write_byte();
|
static void write_byte();
|
static void write_word();
|
static void write_word();
|
static Bit8u inb();
|
static Bit8u inb();
|
static Bit16u inw();
|
static Bit16u inw();
|
static void outb();
|
static void outb();
|
static void outw();
|
static void outw();
|
|
|
static Bit16u get_SS();
|
static Bit16u get_SS();
|
|
|
// Output
|
// Output
|
static void printf();
|
static void printf();
|
|
|
static Bit8u find_vga_entry();
|
static Bit8u find_vga_entry();
|
|
|
static void memsetb();
|
static void memsetb();
|
static void memsetw();
|
static void memsetw();
|
static void memcpyb();
|
static void memcpyb();
|
static void memcpyw();
|
static void memcpyw();
|
|
|
static void biosfn_set_video_mode();
|
static void biosfn_set_video_mode();
|
static void biosfn_set_cursor_shape();
|
static void biosfn_set_cursor_shape();
|
static void biosfn_set_cursor_pos();
|
static void biosfn_set_cursor_pos();
|
static void biosfn_get_cursor_pos();
|
static void biosfn_get_cursor_pos();
|
static void biosfn_scroll();
|
static void biosfn_scroll();
|
static void biosfn_read_char_attr();
|
static void biosfn_read_char_attr();
|
static void biosfn_write_char_attr();
|
static void biosfn_write_char_attr();
|
static void biosfn_write_char_only();
|
static void biosfn_write_char_only();
|
static void biosfn_write_teletype();
|
static void biosfn_write_teletype();
|
static void biosfn_load_text_8_16_pat();
|
static void biosfn_load_text_8_16_pat();
|
static void biosfn_write_string();
|
static void biosfn_write_string();
|
extern Bit8u video_save_pointer_table[];
|
extern Bit8u video_save_pointer_table[];
|
|
|
// This is for compiling with gcc2 and gcc3
|
// This is for compiling with gcc2 and gcc3
|
#define ASM_START #asm
|
#define ASM_START #asm
|
#define ASM_END #endasm
|
#define ASM_END #endasm
|
|
|
ASM_START
|
ASM_START
|
|
|
MACRO SET_INT_VECTOR
|
MACRO SET_INT_VECTOR
|
push ds
|
push ds
|
xor ax, ax
|
xor ax, ax
|
mov ds, ax
|
mov ds, ax
|
mov ax, ?3
|
mov ax, ?3
|
mov ?1*4, ax
|
mov ?1*4, ax
|
mov ax, ?2
|
mov ax, ?2
|
mov ?1*4+2, ax
|
mov ?1*4+2, ax
|
pop ds
|
pop ds
|
MEND
|
MEND
|
|
|
ASM_END
|
ASM_END
|
|
|
ASM_START
|
ASM_START
|
.text
|
.text
|
.rom
|
.rom
|
.org 0
|
.org 0
|
|
|
use16 8086
|
use16 8086
|
|
|
vgabios_start:
|
vgabios_start:
|
.byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */
|
.byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */
|
|
|
.byte 0x40 /* BIOS extension length in units of 512 bytes */
|
.byte 0x40 /* BIOS extension length in units of 512 bytes */
|
|
|
|
|
vgabios_entry_point:
|
vgabios_entry_point:
|
|
|
jmp vgabios_init_func
|
jmp vgabios_init_func
|
|
|
vgabios_name:
|
vgabios_name:
|
.ascii "Zet/Bochs VGABios"
|
.ascii "Zet/Bochs VGABios"
|
.ascii " "
|
.ascii " "
|
.byte 0x00
|
.byte 0x00
|
|
|
// Info from Bart Oldeman
|
// Info from Bart Oldeman
|
.org 0x1e
|
.org 0x1e
|
.ascii "IBM"
|
.ascii "IBM"
|
.byte 0x00
|
.byte 0x00
|
|
|
vgabios_version:
|
vgabios_version:
|
#ifndef VGABIOS_VERS
|
#ifndef VGABIOS_VERS
|
.ascii "current-cvs"
|
.ascii "current-cvs"
|
#else
|
#else
|
.ascii VGABIOS_VERS
|
.ascii VGABIOS_VERS
|
#endif
|
#endif
|
.ascii " "
|
.ascii " "
|
|
|
vgabios_date:
|
vgabios_date:
|
.ascii VGABIOS_DATE
|
.ascii VGABIOS_DATE
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x00
|
.byte 0x00
|
|
|
vgabios_copyright:
|
vgabios_copyright:
|
.ascii "(C) 2003 the LGPL VGABios developers Team"
|
.ascii "(C) 2003 the LGPL VGABios developers Team"
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x00
|
.byte 0x00
|
|
|
vgabios_license:
|
vgabios_license:
|
.ascii "This VGA/VBE Bios is released under the GNU LGPL"
|
.ascii "This VGA/VBE Bios is released under the GNU LGPL"
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x00
|
.byte 0x00
|
|
|
vgabios_website:
|
vgabios_website:
|
.ascii "Please visit :"
|
.ascii "Please visit :"
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
;;.ascii " . http://www.plex86.org"
|
;;.ascii " . http://www.plex86.org"
|
;;.byte 0x0a,0x0d
|
;;.byte 0x0a,0x0d
|
.ascii " . http://zet.aluzina.org"
|
.ascii " . http://zet.aluzina.org"
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.ascii " . http://bochs.sourceforge.net"
|
.ascii " . http://bochs.sourceforge.net"
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.ascii " . http://www.nongnu.org/vgabios"
|
.ascii " . http://www.nongnu.org/vgabios"
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x0a,0x0d
|
.byte 0x00
|
.byte 0x00
|
|
|
|
|
;; ========================================================
|
;; ========================================================
|
;;
|
;;
|
;; Init Entry point
|
;; Init Entry point
|
;;
|
;;
|
;; ========================================================
|
;; ========================================================
|
vgabios_init_func:
|
vgabios_init_func:
|
|
|
;; init vga card
|
;; init vga card
|
call init_vga_card
|
call init_vga_card
|
|
|
;; init basic bios vars
|
;; init basic bios vars
|
call init_bios_area
|
call init_bios_area
|
|
|
;; set int10 vect
|
;; set int10 vect
|
SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
|
SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
|
|
|
;; display splash screen
|
;; display splash screen
|
call _display_splash_screen
|
call _display_splash_screen
|
|
|
;; init video mode and clear the screen
|
;; init video mode and clear the screen
|
mov ax,#0x0003
|
mov ax,#0x0003
|
int #0x10
|
int #0x10
|
|
|
;; show info
|
;; show info
|
call _display_info
|
call _display_info
|
|
|
retf
|
retf
|
ASM_END
|
ASM_END
|
|
|
/*
|
/*
|
* int10 handled here
|
* int10 handled here
|
*/
|
*/
|
ASM_START
|
ASM_START
|
vgabios_int10_handler:
|
vgabios_int10_handler:
|
pushf
|
pushf
|
cmp ah, #0x0f
|
cmp ah, #0x0f
|
jne int10_test_1A
|
jne int10_test_1A
|
call biosfn_get_video_mode
|
call biosfn_get_video_mode
|
jmp int10_end
|
jmp int10_end
|
int10_test_1A:
|
int10_test_1A:
|
int10_test_1103:
|
int10_test_1103:
|
cmp ax, #0x1103
|
cmp ax, #0x1103
|
jne int10_normal
|
jne int10_normal
|
call biosfn_set_text_block_specifier
|
call biosfn_set_text_block_specifier
|
jmp int10_end
|
jmp int10_end
|
|
|
int10_normal:
|
int10_normal:
|
push es
|
push es
|
push ds
|
push ds
|
;pusha ; we do this instead:
|
;pusha ; we do this instead:
|
|
|
push ax
|
push ax
|
push cx
|
push cx
|
push dx
|
push dx
|
push bx
|
push bx
|
push sp
|
push sp
|
mov bx, sp
|
mov bx, sp
|
sseg
|
sseg
|
add [bx], #10
|
add [bx], #10
|
sseg
|
sseg
|
mov bx, [bx+2]
|
mov bx, [bx+2]
|
push bp
|
push bp
|
push si
|
push si
|
push di
|
push di
|
|
|
;; We have to set ds to access the right data segment
|
;; We have to set ds to access the right data segment
|
mov bx, #0xc000
|
mov bx, #0xc000
|
mov ds, bx
|
mov ds, bx
|
|
|
call _int10_func
|
call _int10_func
|
|
|
; popa ; we do this instead:
|
; popa ; we do this instead:
|
pop di
|
pop di
|
pop si
|
pop si
|
pop bp
|
pop bp
|
add sp, #2
|
add sp, #2
|
pop bx
|
pop bx
|
pop dx
|
pop dx
|
pop cx
|
pop cx
|
pop ax
|
pop ax
|
|
|
pop ds
|
pop ds
|
pop es
|
pop es
|
int10_end:
|
int10_end:
|
popf
|
popf
|
iret
|
iret
|
ASM_END
|
ASM_END
|
|
|
#include "vgatables.h"
|
#include "vgatables.h"
|
#include "vgafonts.h"
|
#include "vgafonts.h"
|
|
|
/*
|
/*
|
* Boot time harware inits
|
* Boot time harware inits
|
*/
|
*/
|
ASM_START
|
ASM_START
|
init_vga_card:
|
init_vga_card:
|
;; switch to color mode and enable CPU access 480 lines
|
;; switch to color mode and enable CPU access 480 lines
|
mov dx, #0x3C2
|
mov dx, #0x3C2
|
mov al, #0xC3
|
mov al, #0xC3
|
outb dx,al
|
outb dx,al
|
|
|
;; more than 64k 3C4/04
|
;; more than 64k 3C4/04
|
mov dx, #0x3C4
|
mov dx, #0x3C4
|
mov al, #0x04
|
mov al, #0x04
|
outb dx,al
|
outb dx,al
|
mov dx, #0x3C5
|
mov dx, #0x3C5
|
mov al, #0x02
|
mov al, #0x02
|
outb dx,al
|
outb dx,al
|
|
|
#if defined(USE_BX_INFO) || defined(DEBUG)
|
#if defined(USE_BX_INFO) || defined(DEBUG)
|
mov bx, #msg_vga_init
|
mov bx, #msg_vga_init
|
push bx
|
push bx
|
call _printf
|
call _printf
|
#endif
|
#endif
|
; inc sp
|
; inc sp
|
; inc sp
|
; inc sp
|
ret
|
ret
|
|
|
#if defined(USE_BX_INFO) || defined(DEBUG)
|
#if defined(USE_BX_INFO) || defined(DEBUG)
|
msg_vga_init:
|
msg_vga_init:
|
.ascii "VGABios $Id: vgabios.c,v 1.9 2009-03-05 19:58:40 zeus Exp $"
|
.ascii "VGABios $Id: vgabios.c,v 1.66 2006/07/10 07:47:51 vruppert Exp $"
|
.byte 0x0d,0x0a,0x00
|
.byte 0x0d,0x0a,0x00
|
#endif
|
#endif
|
ASM_END
|
ASM_END
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
/*
|
/*
|
* Boot time bios area inits
|
* Boot time bios area inits
|
*/
|
*/
|
ASM_START
|
ASM_START
|
init_bios_area:
|
init_bios_area:
|
push ds
|
push ds
|
mov ax, # BIOSMEM_SEG
|
mov ax, # BIOSMEM_SEG
|
mov ds, ax
|
mov ds, ax
|
|
|
;; init detected hardware BIOS Area
|
;; init detected hardware BIOS Area
|
mov bx, # BIOSMEM_INITIAL_MODE
|
mov bx, # BIOSMEM_INITIAL_MODE
|
mov ax, [bx]
|
mov ax, [bx]
|
and ax, #0xffcf
|
and ax, #0xffcf
|
;; set 80x25 color (not clear from RBIL but usual)
|
;; set 80x25 color (not clear from RBIL but usual)
|
or ax, #0x0020
|
or ax, #0x0020
|
mov [bx], ax
|
mov [bx], ax
|
|
|
;; Just for the first int10 find its children
|
;; Just for the first int10 find its children
|
|
|
;; the default char height
|
;; the default char height
|
mov bx, # BIOSMEM_CHAR_HEIGHT
|
mov bx, # BIOSMEM_CHAR_HEIGHT
|
mov al, #0x10
|
mov al, #0x10
|
mov [bx], al
|
mov [bx], al
|
|
|
;; Clear the screen
|
;; Clear the screen
|
mov bx, # BIOSMEM_VIDEO_CTL
|
mov bx, # BIOSMEM_VIDEO_CTL
|
mov al, #0x60
|
mov al, #0x60
|
mov [bx], al
|
mov [bx], al
|
|
|
;; Set the basic screen we have
|
;; Set the basic screen we have
|
mov bx, # BIOSMEM_SWITCHES
|
mov bx, # BIOSMEM_SWITCHES
|
mov al, #0xf9
|
mov al, #0xf9
|
mov [bx], al
|
mov [bx], al
|
|
|
;; Set the basic modeset options
|
;; Set the basic modeset options
|
mov bx, # BIOSMEM_MODESET_CTL
|
mov bx, # BIOSMEM_MODESET_CTL
|
mov al, #0x51
|
mov al, #0x51
|
mov [bx], al
|
mov [bx], al
|
|
|
;; Set the default MSR
|
;; Set the default MSR
|
mov bx, # BIOSMEM_CURRENT_MSR
|
mov bx, # BIOSMEM_CURRENT_MSR
|
mov al, #0x09
|
mov al, #0x09
|
mov [bx], al
|
mov [bx], al
|
|
|
pop ds
|
pop ds
|
ret
|
ret
|
|
|
_video_save_pointer_table:
|
_video_save_pointer_table:
|
.word _video_param_table
|
.word _video_param_table
|
.word 0xc000
|
.word 0xc000
|
|
|
.word 0 /* XXX: fill it */
|
.word 0 /* XXX: fill it */
|
.word 0
|
.word 0
|
|
|
.word 0 /* XXX: fill it */
|
.word 0 /* XXX: fill it */
|
.word 0
|
.word 0
|
|
|
.word 0 /* XXX: fill it */
|
.word 0 /* XXX: fill it */
|
.word 0
|
.word 0
|
|
|
.word 0 /* XXX: fill it */
|
.word 0 /* XXX: fill it */
|
.word 0
|
.word 0
|
|
|
.word 0 /* XXX: fill it */
|
.word 0 /* XXX: fill it */
|
.word 0
|
.word 0
|
|
|
.word 0 /* XXX: fill it */
|
.word 0 /* XXX: fill it */
|
.word 0
|
.word 0
|
|
|
ASM_END
|
ASM_END
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
/*
|
/*
|
* Boot time Splash screen
|
* Boot time Splash screen
|
*/
|
*/
|
static void display_splash_screen()
|
static void display_splash_screen()
|
{
|
{
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
/*
|
/*
|
* Tell who we are
|
* Tell who we are
|
*/
|
*/
|
|
|
static void display_info()
|
static void display_info()
|
{
|
{
|
ASM_START
|
ASM_START
|
mov ax,#0xc000
|
mov ax,#0xc000
|
mov ds,ax
|
mov ds,ax
|
mov si,#vgabios_name
|
mov si,#vgabios_name
|
call _display_string
|
call _display_string
|
mov si,#vgabios_version
|
mov si,#vgabios_version
|
call _display_string
|
call _display_string
|
|
|
;;mov si,#vgabios_copyright
|
;;mov si,#vgabios_copyright
|
;;call _display_string
|
;;call _display_string
|
;;mov si,#crlf
|
;;mov si,#crlf
|
;;call _display_string
|
;;call _display_string
|
|
|
mov si,#vgabios_license
|
mov si,#vgabios_license
|
call _display_string
|
call _display_string
|
mov si,#vgabios_website
|
mov si,#vgabios_website
|
call _display_string
|
call _display_string
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
static void display_string()
|
static void display_string()
|
{
|
{
|
// Get length of string
|
// Get length of string
|
ASM_START
|
ASM_START
|
mov ax,ds
|
mov ax,ds
|
mov es,ax
|
mov es,ax
|
mov di,si
|
mov di,si
|
xor cx,cx
|
xor cx,cx
|
not cx
|
not cx
|
xor al,al
|
xor al,al
|
cld
|
cld
|
repne
|
repne
|
scasb
|
scasb
|
not cx
|
not cx
|
dec cx
|
dec cx
|
push cx
|
push cx
|
|
|
mov ax,#0x0300
|
mov ax,#0x0300
|
mov bx,#0x0000
|
mov bx,#0x0000
|
int #0x10
|
int #0x10
|
|
|
pop cx
|
pop cx
|
mov ax,#0x1301
|
mov ax,#0x1301
|
mov bx,#0x000b
|
mov bx,#0x000b
|
mov bp,si
|
mov bp,si
|
int #0x10
|
int #0x10
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------
|
// --------------------------------------------------------
|
/*
|
/*
|
* int10 main dispatcher
|
* int10 main dispatcher
|
*/
|
*/
|
static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
|
static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
|
Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
|
Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
|
{
|
{
|
// BIOS functions
|
// BIOS functions
|
switch(GET_AH())
|
switch(GET_AH())
|
{
|
{
|
case 0x00:
|
case 0x00:
|
biosfn_set_video_mode(GET_AL());
|
biosfn_set_video_mode(GET_AL());
|
switch(GET_AL()&0x7F)
|
switch(GET_AL()&0x7F)
|
{case 6:
|
{case 6:
|
SET_AL(0x3F);
|
SET_AL(0x3F);
|
break;
|
break;
|
case 0:
|
case 0:
|
case 1:
|
case 1:
|
case 2:
|
case 2:
|
case 3:
|
case 3:
|
case 4:
|
case 4:
|
case 5:
|
case 5:
|
case 7:
|
case 7:
|
SET_AL(0x30);
|
SET_AL(0x30);
|
break;
|
break;
|
default:
|
default:
|
SET_AL(0x20);
|
SET_AL(0x20);
|
}
|
}
|
break;
|
break;
|
case 0x01:
|
case 0x01:
|
biosfn_set_cursor_shape(GET_CH(),GET_CL());
|
biosfn_set_cursor_shape(GET_CH(),GET_CL());
|
break;
|
break;
|
case 0x02:
|
case 0x02:
|
biosfn_set_cursor_pos(GET_BH(),DX);
|
biosfn_set_cursor_pos(GET_BH(),DX);
|
break;
|
break;
|
case 0x03:
|
case 0x03:
|
biosfn_get_cursor_pos(GET_BH(),&CX,&DX);
|
biosfn_get_cursor_pos(GET_BH(),&CX,&DX);
|
break;
|
break;
|
case 0x06:
|
case 0x06:
|
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP);
|
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP);
|
break;
|
break;
|
case 0x07:
|
case 0x07:
|
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN);
|
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN);
|
break;
|
break;
|
case 0x08:
|
case 0x08:
|
biosfn_read_char_attr(GET_BH(),&AX);
|
biosfn_read_char_attr(GET_BH(),&AX);
|
break;
|
break;
|
case 0x09:
|
case 0x09:
|
biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX);
|
biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX);
|
break;
|
break;
|
case 0x0A:
|
case 0x0A:
|
biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX);
|
biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX);
|
break;
|
break;
|
case 0x0E:
|
case 0x0E:
|
// Ralf Brown Interrupt list is WRONG on bh(page)
|
// Ralf Brown Interrupt list is WRONG on bh(page)
|
// We do output only on the current page !
|
// We do output only on the current page !
|
biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);
|
biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);
|
break;
|
break;
|
case 0x11:
|
case 0x11:
|
switch(GET_AL())
|
switch(GET_AL())
|
{
|
{
|
case 0x04:
|
case 0x04:
|
case 0x14:
|
case 0x14:
|
biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
|
biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
|
break;
|
break;
|
}
|
}
|
break;
|
break;
|
case 0x13:
|
case 0x13:
|
biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
|
biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
// ============================================================================================
|
// ============================================================================================
|
//
|
//
|
// BIOS functions
|
// BIOS functions
|
//
|
//
|
// ============================================================================================
|
// ============================================================================================
|
|
|
static void biosfn_set_video_mode(mode) Bit8u mode;
|
static void biosfn_set_video_mode(mode) Bit8u mode;
|
{// mode: Bit 7 is 1 if no clear screen
|
{// mode: Bit 7 is 1 if no clear screen
|
|
|
// Should we clear the screen ?
|
// Should we clear the screen ?
|
Bit8u noclearmem=mode&0x80;
|
Bit8u noclearmem=mode&0x80;
|
Bit8u line,mmask,*palette,vpti;
|
Bit8u line,mmask,*palette,vpti;
|
Bit16u i,twidth,theightm1,cheight;
|
Bit16u i,twidth,theightm1,cheight;
|
Bit8u modeset_ctl,video_ctl,vga_switches;
|
Bit8u modeset_ctl,video_ctl,vga_switches;
|
Bit16u crtc_addr;
|
Bit16u crtc_addr;
|
|
|
// The real mode
|
// The real mode
|
mode=mode&0x7f;
|
mode=mode&0x7f;
|
|
|
// find the entry in the video modes
|
// find the entry in the video modes
|
line=find_vga_entry(mode);
|
line=find_vga_entry(mode);
|
|
|
if(line==0xFF)
|
if(line==0xFF)
|
return;
|
return;
|
|
|
vpti=line_to_vpti[line];
|
vpti=line_to_vpti[line];
|
twidth=video_param_table[vpti].twidth;
|
twidth=video_param_table[vpti].twidth;
|
theightm1=video_param_table[vpti].theightm1;
|
theightm1=video_param_table[vpti].theightm1;
|
cheight=video_param_table[vpti].cheight;
|
cheight=video_param_table[vpti].cheight;
|
|
|
// Read the bios vga control
|
// Read the bios vga control
|
video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
|
video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
|
|
|
// Read the bios vga switches
|
// Read the bios vga switches
|
vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES);
|
vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES);
|
|
|
// Read the bios mode set control
|
// Read the bios mode set control
|
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
|
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
|
|
|
// Then we know the number of lines
|
// Then we know the number of lines
|
// FIXME
|
// FIXME
|
|
|
// if palette loading (bit 3 of modeset ctl = 0)
|
// if palette loading (bit 3 of modeset ctl = 0)
|
if((modeset_ctl&0x08)==0)
|
if((modeset_ctl&0x08)==0)
|
{// Set the PEL mask
|
{// Set the PEL mask
|
outb(VGAREG_PEL_MASK,vga_modes[line].pelmask);
|
outb(VGAREG_PEL_MASK,vga_modes[line].pelmask);
|
|
|
// Set the whole dac always, from 0
|
// Set the whole dac always, from 0
|
outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
|
outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
|
|
|
// From which palette
|
// From which palette
|
switch(vga_modes[line].dacmodel)
|
switch(vga_modes[line].dacmodel)
|
{case 0:
|
{case 0:
|
palette=&palette0;
|
palette=&palette0;
|
break;
|
break;
|
case 1:
|
case 1:
|
palette=&palette1;
|
palette=&palette1;
|
break;
|
break;
|
case 2:
|
case 2:
|
palette=&palette2;
|
palette=&palette2;
|
break;
|
break;
|
case 3:
|
case 3:
|
palette=&palette3;
|
palette=&palette3;
|
break;
|
break;
|
}
|
}
|
// Always 256*3 values
|
// Always 256*3 values
|
for(i=0;i<0x0100;i++)
|
for(i=0;i<0x0100;i++)
|
{if(i<=dac_regs[vga_modes[line].dacmodel])
|
{if(i<=dac_regs[vga_modes[line].dacmodel])
|
{outb(VGAREG_DAC_DATA,palette[(i*3)+0]);
|
{outb(VGAREG_DAC_DATA,palette[(i*3)+0]);
|
outb(VGAREG_DAC_DATA,palette[(i*3)+1]);
|
outb(VGAREG_DAC_DATA,palette[(i*3)+1]);
|
outb(VGAREG_DAC_DATA,palette[(i*3)+2]);
|
outb(VGAREG_DAC_DATA,palette[(i*3)+2]);
|
}
|
}
|
else
|
else
|
{outb(VGAREG_DAC_DATA,0);
|
{outb(VGAREG_DAC_DATA,0);
|
outb(VGAREG_DAC_DATA,0);
|
outb(VGAREG_DAC_DATA,0);
|
outb(VGAREG_DAC_DATA,0);
|
outb(VGAREG_DAC_DATA,0);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// Reset Attribute Ctl flip-flop
|
// Reset Attribute Ctl flip-flop
|
inb(VGAREG_ACTL_RESET);
|
inb(VGAREG_ACTL_RESET);
|
|
|
// Set Attribute Ctl
|
// Set Attribute Ctl
|
for(i=0;i<=0x13;i++)
|
for(i=0;i<=0x13;i++)
|
{outb(VGAREG_ACTL_ADDRESS,i);
|
{outb(VGAREG_ACTL_ADDRESS,i);
|
outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);
|
outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);
|
}
|
}
|
outb(VGAREG_ACTL_ADDRESS,0x14);
|
outb(VGAREG_ACTL_ADDRESS,0x14);
|
outb(VGAREG_ACTL_WRITE_DATA,0x00);
|
outb(VGAREG_ACTL_WRITE_DATA,0x00);
|
|
|
// Set Sequencer Ctl
|
// Set Sequencer Ctl
|
outb(VGAREG_SEQU_ADDRESS,0);
|
outb(VGAREG_SEQU_ADDRESS,0);
|
outb(VGAREG_SEQU_DATA,0x03);
|
outb(VGAREG_SEQU_DATA,0x03);
|
for(i=1;i<=4;i++)
|
for(i=1;i<=4;i++)
|
{outb(VGAREG_SEQU_ADDRESS,i);
|
{outb(VGAREG_SEQU_ADDRESS,i);
|
outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);
|
outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);
|
}
|
}
|
|
|
// Set Grafx Ctl
|
// Set Grafx Ctl
|
for(i=0;i<=8;i++)
|
for(i=0;i<=8;i++)
|
{outb(VGAREG_GRDC_ADDRESS,i);
|
{outb(VGAREG_GRDC_ADDRESS,i);
|
outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);
|
outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);
|
}
|
}
|
|
|
// Set CRTC address VGA or MDA
|
// Set CRTC address VGA or MDA
|
crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
|
crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
|
|
|
// Disable CRTC write protection
|
// Disable CRTC write protection
|
outw(crtc_addr,0x0011);
|
outw(crtc_addr,0x0011);
|
// Set CRTC regs
|
// Set CRTC regs
|
for(i=0;i<=0x18;i++)
|
for(i=0;i<=0x18;i++)
|
{outb(crtc_addr,i);
|
{outb(crtc_addr,i);
|
outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);
|
outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);
|
}
|
}
|
|
|
// Set the misc register
|
// Set the misc register
|
outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg);
|
outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg);
|
|
|
// Enable video
|
// Enable video
|
outb(VGAREG_ACTL_ADDRESS,0x20);
|
outb(VGAREG_ACTL_ADDRESS,0x20);
|
inb(VGAREG_ACTL_RESET);
|
inb(VGAREG_ACTL_RESET);
|
|
|
if(noclearmem==0x00)
|
if(noclearmem==0x00)
|
{
|
{
|
if(vga_modes[line].class==TEXT)
|
if(vga_modes[line].class==TEXT)
|
{
|
{
|
memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k
|
memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k
|
}
|
}
|
else
|
else
|
{
|
{
|
if(mode<0x0d)
|
if(mode<0x0d)
|
{
|
{
|
memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k
|
memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k
|
}
|
}
|
else
|
else
|
{
|
{
|
outb( VGAREG_SEQU_ADDRESS, 0x02 );
|
outb( VGAREG_SEQU_ADDRESS, 0x02 );
|
mmask = inb( VGAREG_SEQU_DATA );
|
mmask = inb( VGAREG_SEQU_DATA );
|
outb( VGAREG_SEQU_DATA, 0x0f ); // all planes
|
outb( VGAREG_SEQU_DATA, 0x0f ); // all planes
|
memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k
|
memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k
|
outb( VGAREG_SEQU_DATA, mmask );
|
outb( VGAREG_SEQU_DATA, mmask );
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// Set the BIOS mem
|
// Set the BIOS mem
|
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
|
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
|
write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth);
|
write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth);
|
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l);
|
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l);
|
write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
|
write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
|
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
|
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
|
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
|
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
|
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
|
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
|
write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
|
write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
|
write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
|
write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
|
|
|
// FIXME We nearly have the good tables. to be reworked
|
// FIXME We nearly have the good tables. to be reworked
|
write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now
|
write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now
|
write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table);
|
write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table);
|
write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000);
|
write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000);
|
|
|
// FIXME
|
// FIXME
|
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but...
|
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but...
|
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...
|
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...
|
|
|
if(vga_modes[line].class==TEXT)
|
if(vga_modes[line].class==TEXT)
|
{
|
{
|
biosfn_set_cursor_shape(0x06,0x07);
|
biosfn_set_cursor_shape(0x06,0x07);
|
}
|
}
|
|
|
// Set cursor pos for page 0..7
|
// Set cursor pos for page 0..7
|
for(i=0;i<8;i++)
|
for(i=0;i<8;i++)
|
biosfn_set_cursor_pos(i,0x0000);
|
biosfn_set_cursor_pos(i,0x0000);
|
|
|
// Write the fonts in memory
|
// Write the fonts in memory
|
if(vga_modes[line].class==TEXT)
|
if(vga_modes[line].class==TEXT)
|
{
|
{
|
ASM_START
|
ASM_START
|
;; copy and activate 8x16 font
|
;; copy and activate 8x16 font
|
mov ax, #0x1104
|
mov ax, #0x1104
|
mov bl, #0x00
|
mov bl, #0x00
|
int #0x10
|
int #0x10
|
mov ax, #0x1103
|
mov ax, #0x1103
|
mov bl, #0x00
|
mov bl, #0x00
|
int #0x10
|
int #0x10
|
ASM_END
|
ASM_END
|
}
|
}
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_set_cursor_shape (CH,CL)
|
static void biosfn_set_cursor_shape (CH,CL)
|
Bit8u CH;Bit8u CL;
|
Bit8u CH;Bit8u CL;
|
{Bit16u cheight,curs,crtc_addr;
|
{Bit16u cheight,curs,crtc_addr;
|
Bit8u modeset_ctl;
|
Bit8u modeset_ctl;
|
|
|
CH&=0x3f;
|
CH&=0x3f;
|
CL&=0x1f;
|
CL&=0x1f;
|
|
|
curs=(CH<<8)+CL;
|
curs=(CH<<8)+CL;
|
write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs);
|
write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs);
|
|
|
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
|
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
|
cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))
|
if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))
|
{
|
{
|
if(CL!=(CH+1))
|
if(CL!=(CH+1))
|
{
|
{
|
CH = ((CH+1) * cheight / 8) -1;
|
CH = ((CH+1) * cheight / 8) -1;
|
}
|
}
|
else
|
else
|
{
|
{
|
CH = ((CL+1) * cheight / 8) - 2;
|
CH = ((CL+1) * cheight / 8) - 2;
|
}
|
}
|
CL = ((CL+1) * cheight / 8) - 1;
|
CL = ((CL+1) * cheight / 8) - 1;
|
}
|
}
|
|
|
// CTRC regs 0x0a and 0x0b
|
// CTRC regs 0x0a and 0x0b
|
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
outb(crtc_addr,0x0a);
|
outb(crtc_addr,0x0a);
|
outb(crtc_addr+1,CH);
|
outb(crtc_addr+1,CH);
|
outb(crtc_addr,0x0b);
|
outb(crtc_addr,0x0b);
|
outb(crtc_addr+1,CL);
|
outb(crtc_addr+1,CL);
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_set_cursor_pos (page, cursor)
|
static void biosfn_set_cursor_pos (page, cursor)
|
Bit8u page;Bit16u cursor;
|
Bit8u page;Bit16u cursor;
|
{
|
{
|
Bit8u current;
|
Bit8u current;
|
Bit16u crtc_addr;
|
Bit16u crtc_addr;
|
|
|
// Should not happen...
|
// Should not happen...
|
if(page>7)return;
|
if(page>7)return;
|
|
|
// Bios cursor pos
|
// Bios cursor pos
|
write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor);
|
write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor);
|
|
|
// Set the hardware cursor
|
// Set the hardware cursor
|
current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
|
current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
|
if(page==current)
|
if(page==current)
|
{
|
{
|
// CRTC regs 0x0e and 0x0f
|
// CRTC regs 0x0e and 0x0f
|
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
outb(crtc_addr,0x0e);
|
outb(crtc_addr,0x0e);
|
outb(crtc_addr+1,(cursor&0xff00)>>8);
|
outb(crtc_addr+1,(cursor&0xff00)>>8);
|
outb(crtc_addr,0x0f);
|
outb(crtc_addr,0x0f);
|
outb(crtc_addr+1,cursor&0x00ff);
|
outb(crtc_addr+1,cursor&0x00ff);
|
}
|
}
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_get_cursor_pos (page,shape, pos)
|
static void biosfn_get_cursor_pos (page,shape, pos)
|
Bit8u page;Bit16u *shape;Bit16u *pos;
|
Bit8u page;Bit16u *shape;Bit16u *pos;
|
{
|
{
|
Bit16u ss=get_SS();
|
Bit16u ss=get_SS();
|
|
|
// Default
|
// Default
|
write_word(ss, shape, 0);
|
write_word(ss, shape, 0);
|
write_word(ss, pos, 0);
|
write_word(ss, pos, 0);
|
|
|
if(page>7)return;
|
if(page>7)return;
|
// FIXME should handle VGA 14/16 lines
|
// FIXME should handle VGA 14/16 lines
|
write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE));
|
write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE));
|
write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2));
|
write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2));
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)
|
static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)
|
Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;
|
Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;
|
{
|
{
|
// page == 0xFF if current
|
// page == 0xFF if current
|
|
|
Bit8u mode,line,cheight,bpp,cols;
|
Bit8u mode,line,cheight,bpp,cols;
|
Bit16u nbcols,nbrows,i;
|
Bit16u nbcols,nbrows,i;
|
Bit16u address;
|
Bit16u address;
|
|
|
if(rul>rlr)return;
|
if(rul>rlr)return;
|
if(cul>clr)return;
|
if(cul>clr)return;
|
|
|
// Get the mode
|
// Get the mode
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
line=find_vga_entry(mode);
|
line=find_vga_entry(mode);
|
if(line==0xFF)return;
|
if(line==0xFF)return;
|
|
|
// Get the dimensions
|
// Get the dimensions
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
|
|
// Get the current page
|
// Get the current page
|
if(page==0xFF)
|
if(page==0xFF)
|
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
|
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
|
|
|
if(rlr>=nbrows)rlr=nbrows-1;
|
if(rlr>=nbrows)rlr=nbrows-1;
|
if(clr>=nbcols)clr=nbcols-1;
|
if(clr>=nbcols)clr=nbcols-1;
|
if(nblines>nbrows)nblines=0;
|
if(nblines>nbrows)nblines=0;
|
cols=clr-cul+1;
|
cols=clr-cul+1;
|
|
|
if(vga_modes[line].class==TEXT)
|
if(vga_modes[line].class==TEXT)
|
{
|
{
|
// Compute the address
|
// Compute the address
|
address=SCREEN_MEM_START(nbcols,nbrows,page);
|
address=SCREEN_MEM_START(nbcols,nbrows,page);
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);
|
printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);
|
#endif
|
#endif
|
|
|
if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
|
if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
|
{
|
{
|
memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);
|
memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);
|
}
|
}
|
else
|
else
|
{// if Scroll up
|
{// if Scroll up
|
if(dir==SCROLL_UP)
|
if(dir==SCROLL_UP)
|
{for(i=rul;i<=rlr;i++)
|
{for(i=rul;i<=rlr;i++)
|
{
|
{
|
if((i+nblines>rlr)||(nblines==0))
|
if((i+nblines>rlr)||(nblines==0))
|
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
|
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
|
else
|
else
|
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);
|
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);
|
}
|
}
|
}
|
}
|
else
|
else
|
{for(i=rlr;i>=rul;i--)
|
{for(i=rlr;i>=rul;i--)
|
{
|
{
|
if((i<rul+nblines)||(nblines==0))
|
if((i<rul+nblines)||(nblines==0))
|
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
|
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
|
else
|
else
|
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);
|
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);
|
if (i>rlr) break;
|
if (i>rlr) break;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_read_char_attr (page,car)
|
static void biosfn_read_char_attr (page,car)
|
Bit8u page;Bit16u *car;
|
Bit8u page;Bit16u *car;
|
{Bit16u ss=get_SS();
|
{Bit16u ss=get_SS();
|
Bit8u xcurs,ycurs,mode,line;
|
Bit8u xcurs,ycurs,mode,line;
|
Bit16u nbcols,nbrows,address;
|
Bit16u nbcols,nbrows,address;
|
Bit16u cursor,dummy;
|
Bit16u cursor,dummy;
|
|
|
// Get the mode
|
// Get the mode
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
line=find_vga_entry(mode);
|
line=find_vga_entry(mode);
|
if(line==0xFF)return;
|
if(line==0xFF)return;
|
|
|
// Get the cursor pos for the page
|
// Get the cursor pos for the page
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
|
|
// Get the dimensions
|
// Get the dimensions
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
|
|
// Compute the address
|
// Compute the address
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
|
|
write_word(ss,car,read_word(vga_modes[line].sstart,address));
|
write_word(ss,car,read_word(vga_modes[line].sstart,address));
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_write_char_attr (car,page,attr,count)
|
static void biosfn_write_char_attr (car,page,attr,count)
|
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
|
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
|
{
|
{
|
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
|
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
|
Bit16u nbcols,nbrows,address;
|
Bit16u nbcols,nbrows,address;
|
Bit16u cursor,dummy;
|
Bit16u cursor,dummy;
|
|
|
// Get the mode
|
// Get the mode
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
line=find_vga_entry(mode);
|
line=find_vga_entry(mode);
|
if(line==0xFF)return;
|
if(line==0xFF)return;
|
|
|
// Get the cursor pos for the page
|
// Get the cursor pos for the page
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
|
|
// Get the dimensions
|
// Get the dimensions
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
|
|
// Compute the address
|
// Compute the address
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
|
|
dummy=((Bit16u)attr<<8)+car;
|
dummy=((Bit16u)attr<<8)+car;
|
memsetw(vga_modes[line].sstart,address,dummy,count);
|
memsetw(vga_modes[line].sstart,address,dummy,count);
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_write_char_only (car,page,attr,count)
|
static void biosfn_write_char_only (car,page,attr,count)
|
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
|
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
|
{
|
{
|
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
|
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
|
Bit16u nbcols,nbrows,address;
|
Bit16u nbcols,nbrows,address;
|
Bit16u cursor,dummy;
|
Bit16u cursor,dummy;
|
|
|
// Get the mode
|
// Get the mode
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
line=find_vga_entry(mode);
|
line=find_vga_entry(mode);
|
if(line==0xFF)return;
|
if(line==0xFF)return;
|
|
|
// Get the cursor pos for the page
|
// Get the cursor pos for the page
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
|
|
// Get the dimensions
|
// Get the dimensions
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
|
|
// Compute the address
|
// Compute the address
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
|
|
while(count-->0)
|
while(count-->0)
|
{write_byte(vga_modes[line].sstart,address,car);
|
{write_byte(vga_modes[line].sstart,address,car);
|
address+=2;
|
address+=2;
|
}
|
}
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_write_teletype (car, page, attr, flag)
|
static void biosfn_write_teletype (car, page, attr, flag)
|
Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
|
Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
|
{// flag = WITH_ATTR / NO_ATTR
|
{// flag = WITH_ATTR / NO_ATTR
|
|
|
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
|
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
|
Bit16u nbcols,nbrows,address;
|
Bit16u nbcols,nbrows,address;
|
Bit16u cursor,dummy;
|
Bit16u cursor,dummy;
|
|
|
// special case if page is 0xff, use current page
|
// special case if page is 0xff, use current page
|
if(page==0xff)
|
if(page==0xff)
|
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
|
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
|
|
|
// Get the mode
|
// Get the mode
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
|
line=find_vga_entry(mode);
|
line=find_vga_entry(mode);
|
if(line==0xFF)return;
|
if(line==0xFF)return;
|
|
|
// Get the cursor pos for the page
|
// Get the cursor pos for the page
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
|
|
// Get the dimensions
|
// Get the dimensions
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
|
|
switch(car)
|
switch(car)
|
{
|
{
|
case 7:
|
case 7:
|
//FIXME should beep
|
//FIXME should beep
|
break;
|
break;
|
|
|
case 8:
|
case 8:
|
if(xcurs>0)xcurs--;
|
if(xcurs>0)xcurs--;
|
break;
|
break;
|
|
|
case '\r':
|
case '\r':
|
xcurs=0;
|
xcurs=0;
|
break;
|
break;
|
|
|
case '\n':
|
case '\n':
|
ycurs++;
|
ycurs++;
|
break;
|
break;
|
|
|
case '\t':
|
case '\t':
|
do
|
do
|
{
|
{
|
biosfn_write_teletype(' ',page,attr,flag);
|
biosfn_write_teletype(' ',page,attr,flag);
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
biosfn_get_cursor_pos(page,&dummy,&cursor);
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
|
}while(xcurs%8==0);
|
}while(xcurs%8==0);
|
break;
|
break;
|
|
|
default:
|
default:
|
|
|
if(vga_modes[line].class==TEXT)
|
if(vga_modes[line].class==TEXT)
|
{
|
{
|
// Compute the address
|
// Compute the address
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
|
|
|
// Write the char
|
// Write the char
|
write_byte(vga_modes[line].sstart,address,car);
|
write_byte(vga_modes[line].sstart,address,car);
|
|
|
if(flag==WITH_ATTR)
|
if(flag==WITH_ATTR)
|
write_byte(vga_modes[line].sstart,address+1,attr);
|
write_byte(vga_modes[line].sstart,address+1,attr);
|
}
|
}
|
xcurs++;
|
xcurs++;
|
}
|
}
|
|
|
// Do we need to wrap ?
|
// Do we need to wrap ?
|
if(xcurs==nbcols)
|
if(xcurs==nbcols)
|
{xcurs=0;
|
{xcurs=0;
|
ycurs++;
|
ycurs++;
|
}
|
}
|
|
|
// Do we need to scroll ?
|
// Do we need to scroll ?
|
if(ycurs==nbrows)
|
if(ycurs==nbrows)
|
{
|
{
|
if(vga_modes[line].class==TEXT)
|
if(vga_modes[line].class==TEXT)
|
{
|
{
|
biosfn_scroll(0x01,0x07,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
|
biosfn_scroll(0x01,0x07,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
|
}
|
}
|
ycurs-=1;
|
ycurs-=1;
|
}
|
}
|
|
|
// Set the cursor for the page
|
// Set the cursor for the page
|
cursor=ycurs; cursor<<=8; cursor+=xcurs;
|
cursor=ycurs; cursor<<=8; cursor+=xcurs;
|
biosfn_set_cursor_pos(page,cursor);
|
biosfn_set_cursor_pos(page,cursor);
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
ASM_START
|
ASM_START
|
biosfn_get_video_mode:
|
biosfn_get_video_mode:
|
push ds
|
push ds
|
mov ax, # BIOSMEM_SEG
|
mov ax, # BIOSMEM_SEG
|
mov ds, ax
|
mov ds, ax
|
push bx
|
push bx
|
mov bx, # BIOSMEM_CURRENT_PAGE
|
mov bx, # BIOSMEM_CURRENT_PAGE
|
mov al, [bx]
|
mov al, [bx]
|
pop bx
|
pop bx
|
mov bh, al
|
mov bh, al
|
push bx
|
push bx
|
mov bx, # BIOSMEM_VIDEO_CTL
|
mov bx, # BIOSMEM_VIDEO_CTL
|
mov ah, [bx]
|
mov ah, [bx]
|
and ah, #0x80
|
and ah, #0x80
|
mov bx, # BIOSMEM_CURRENT_MODE
|
mov bx, # BIOSMEM_CURRENT_MODE
|
mov al, [bx]
|
mov al, [bx]
|
or al, ah
|
or al, ah
|
mov bx, # BIOSMEM_NB_COLS
|
mov bx, # BIOSMEM_NB_COLS
|
mov ah, [bx]
|
mov ah, [bx]
|
pop bx
|
pop bx
|
pop ds
|
pop ds
|
ret
|
ret
|
ASM_END
|
ASM_END
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void get_font_access()
|
static void get_font_access()
|
{
|
{
|
ASM_START
|
ASM_START
|
mov dx, # VGAREG_SEQU_ADDRESS
|
mov dx, # VGAREG_SEQU_ADDRESS
|
mov ax, #0x0100
|
mov ax, #0x0100
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0402
|
mov ax, #0x0402
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0704
|
mov ax, #0x0704
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0300
|
mov ax, #0x0300
|
out dx, ax
|
out dx, ax
|
mov dx, # VGAREG_GRDC_ADDRESS
|
mov dx, # VGAREG_GRDC_ADDRESS
|
mov ax, #0x0204
|
mov ax, #0x0204
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0005
|
mov ax, #0x0005
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0406
|
mov ax, #0x0406
|
out dx, ax
|
out dx, ax
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
static void release_font_access()
|
static void release_font_access()
|
{
|
{
|
ASM_START
|
ASM_START
|
mov dx, # VGAREG_SEQU_ADDRESS
|
mov dx, # VGAREG_SEQU_ADDRESS
|
mov ax, #0x0100
|
mov ax, #0x0100
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0302
|
mov ax, #0x0302
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0304
|
mov ax, #0x0304
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0300
|
mov ax, #0x0300
|
out dx, ax
|
out dx, ax
|
mov dx, # VGAREG_READ_MISC_OUTPUT
|
mov dx, # VGAREG_READ_MISC_OUTPUT
|
in al, dx
|
in al, dx
|
and al, #0x01
|
and al, #0x01
|
push cx
|
push cx
|
mov cl,*2
|
mov cl,*2
|
shl al,cl
|
shl al,cl
|
pop cx
|
pop cx
|
or al, #0x0a
|
or al, #0x0a
|
mov ah, al
|
mov ah, al
|
mov al, #0x06
|
mov al, #0x06
|
mov dx, # VGAREG_GRDC_ADDRESS
|
mov dx, # VGAREG_GRDC_ADDRESS
|
out dx, ax
|
out dx, ax
|
mov ax, #0x0004
|
mov ax, #0x0004
|
out dx, ax
|
out dx, ax
|
mov ax, #0x1005
|
mov ax, #0x1005
|
out dx, ax
|
out dx, ax
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
ASM_START
|
ASM_START
|
idiv_u:
|
idiv_u:
|
xor dx,dx
|
xor dx,dx
|
div bx
|
div bx
|
ret
|
ret
|
ASM_END
|
ASM_END
|
|
|
static void set_scan_lines(lines) Bit8u lines;
|
static void set_scan_lines(lines) Bit8u lines;
|
{
|
{
|
Bit16u crtc_addr,cols,page,vde;
|
Bit16u crtc_addr,cols,page,vde;
|
Bit8u crtc_r9,ovl,rows;
|
Bit8u crtc_r9,ovl,rows;
|
|
|
crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
outb(crtc_addr, 0x09);
|
outb(crtc_addr, 0x09);
|
crtc_r9 = inb(crtc_addr+1);
|
crtc_r9 = inb(crtc_addr+1);
|
crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
|
crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
|
outb(crtc_addr+1, crtc_r9);
|
outb(crtc_addr+1, crtc_r9);
|
/*
|
/*
|
if(lines==8)
|
if(lines==8)
|
{
|
{
|
biosfn_set_cursor_shape(0x06,0x07);
|
biosfn_set_cursor_shape(0x06,0x07);
|
}
|
}
|
else
|
else
|
{
|
{
|
biosfn_set_cursor_shape(lines-4,lines-3);
|
biosfn_set_cursor_shape(lines-4,lines-3);
|
}
|
}
|
*/
|
*/
|
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines);
|
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines);
|
outb(crtc_addr, 0x12);
|
outb(crtc_addr, 0x12);
|
vde = inb(crtc_addr+1);
|
vde = inb(crtc_addr+1);
|
outb(crtc_addr, 0x07);
|
outb(crtc_addr, 0x07);
|
ovl = inb(crtc_addr+1);
|
ovl = inb(crtc_addr+1);
|
vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
|
vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
|
rows = vde / lines;
|
rows = vde / lines;
|
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1);
|
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1);
|
cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2);
|
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2);
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
ASM_START
|
ASM_START
|
biosfn_set_text_block_specifier:
|
biosfn_set_text_block_specifier:
|
push ax
|
push ax
|
push dx
|
push dx
|
mov dx, # VGAREG_SEQU_ADDRESS
|
mov dx, # VGAREG_SEQU_ADDRESS
|
mov ah, bl
|
mov ah, bl
|
mov al, #0x03
|
mov al, #0x03
|
out dx, ax
|
out dx, ax
|
pop dx
|
pop dx
|
pop ax
|
pop ax
|
ret
|
ret
|
ASM_END
|
ASM_END
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL;
|
static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL;
|
{
|
{
|
Bit16u blockaddr,dest,i,src;
|
Bit16u blockaddr,dest,i,src;
|
|
|
get_font_access();
|
get_font_access();
|
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
|
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
|
for(i=0;i<0x100;i++)
|
for(i=0;i<0x100;i++)
|
{
|
{
|
src = i * 16;
|
src = i * 16;
|
dest = blockaddr + i * 32;
|
dest = blockaddr + i * 32;
|
memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16);
|
memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16);
|
}
|
}
|
release_font_access();
|
release_font_access();
|
if(AL>=0x10)
|
if(AL>=0x10)
|
{
|
{
|
set_scan_lines(16);
|
set_scan_lines(16);
|
}
|
}
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset)
|
static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset)
|
Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset;
|
Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset;
|
{
|
{
|
Bit16u newcurs,oldcurs,dummy;
|
Bit16u newcurs,oldcurs,dummy;
|
Bit8u car,carattr;
|
Bit8u car,carattr;
|
|
|
// Read curs info for the page
|
// Read curs info for the page
|
biosfn_get_cursor_pos(page,&dummy,&oldcurs);
|
biosfn_get_cursor_pos(page,&dummy,&oldcurs);
|
|
|
// if row=0xff special case : use current cursor position
|
// if row=0xff special case : use current cursor position
|
if(row==0xff)
|
if(row==0xff)
|
{col=oldcurs&0x00ff;
|
{col=oldcurs&0x00ff;
|
row=(oldcurs&0xff00)>>8;
|
row=(oldcurs&0xff00)>>8;
|
}
|
}
|
|
|
newcurs=row; newcurs<<=8; newcurs+=col;
|
newcurs=row; newcurs<<=8; newcurs+=col;
|
biosfn_set_cursor_pos(page,newcurs);
|
biosfn_set_cursor_pos(page,newcurs);
|
|
|
while(count--!=0)
|
while(count--!=0)
|
{
|
{
|
car=read_byte(seg,offset++);
|
car=read_byte(seg,offset++);
|
if((flag&0x02)!=0)
|
if((flag&0x02)!=0)
|
attr=read_byte(seg,offset++);
|
attr=read_byte(seg,offset++);
|
|
|
biosfn_write_teletype(car,page,attr,WITH_ATTR);
|
biosfn_write_teletype(car,page,attr,WITH_ATTR);
|
}
|
}
|
|
|
// Set back curs pos
|
// Set back curs pos
|
if((flag&0x01)==0)
|
if((flag&0x01)==0)
|
biosfn_set_cursor_pos(page,oldcurs);
|
biosfn_set_cursor_pos(page,oldcurs);
|
}
|
}
|
|
|
// ============================================================================================
|
// ============================================================================================
|
//
|
//
|
// Video Utils
|
// Video Utils
|
//
|
//
|
// ============================================================================================
|
// ============================================================================================
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static Bit8u find_vga_entry(mode)
|
static Bit8u find_vga_entry(mode)
|
Bit8u mode;
|
Bit8u mode;
|
{
|
{
|
Bit8u i,line=0xFF;
|
Bit8u i,line=0xFF;
|
for(i=0;i<=MODE_MAX;i++)
|
for(i=0;i<=MODE_MAX;i++)
|
if(vga_modes[i].svgamode==mode)
|
if(vga_modes[i].svgamode==mode)
|
{line=i;
|
{line=i;
|
break;
|
break;
|
}
|
}
|
return line;
|
return line;
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void memsetw(seg,offset,value,count)
|
static void memsetw(seg,offset,value,count)
|
Bit16u seg;
|
Bit16u seg;
|
Bit16u offset;
|
Bit16u offset;
|
Bit16u value;
|
Bit16u value;
|
Bit16u count;
|
Bit16u count;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push cx
|
push cx
|
push es
|
push es
|
push di
|
push di
|
|
|
mov cx, 10[bp] ; count
|
mov cx, 10[bp] ; count
|
cmp cx, #0x00
|
cmp cx, #0x00
|
je memsetw_end
|
je memsetw_end
|
mov ax, 4[bp] ; segment
|
mov ax, 4[bp] ; segment
|
mov es, ax
|
mov es, ax
|
mov ax, 6[bp] ; offset
|
mov ax, 6[bp] ; offset
|
mov di, ax
|
mov di, ax
|
mov ax, 8[bp] ; value
|
mov ax, 8[bp] ; value
|
cld
|
cld
|
rep
|
rep
|
stosw
|
stosw
|
|
|
memsetw_end:
|
memsetw_end:
|
pop di
|
pop di
|
pop es
|
pop es
|
pop cx
|
pop cx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void memcpyb(dseg,doffset,sseg,soffset,count)
|
static void memcpyb(dseg,doffset,sseg,soffset,count)
|
Bit16u dseg;
|
Bit16u dseg;
|
Bit16u doffset;
|
Bit16u doffset;
|
Bit16u sseg;
|
Bit16u sseg;
|
Bit16u soffset;
|
Bit16u soffset;
|
Bit16u count;
|
Bit16u count;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push cx
|
push cx
|
push es
|
push es
|
push di
|
push di
|
push ds
|
push ds
|
push si
|
push si
|
|
|
mov cx, 12[bp] ; count
|
mov cx, 12[bp] ; count
|
cmp cx, #0x0000
|
cmp cx, #0x0000
|
je memcpyb_end
|
je memcpyb_end
|
mov ax, 4[bp] ; dsegment
|
mov ax, 4[bp] ; dsegment
|
mov es, ax
|
mov es, ax
|
mov ax, 6[bp] ; doffset
|
mov ax, 6[bp] ; doffset
|
mov di, ax
|
mov di, ax
|
mov ax, 8[bp] ; ssegment
|
mov ax, 8[bp] ; ssegment
|
mov ds, ax
|
mov ds, ax
|
mov ax, 10[bp] ; soffset
|
mov ax, 10[bp] ; soffset
|
mov si, ax
|
mov si, ax
|
cld
|
cld
|
rep
|
rep
|
movsb
|
movsb
|
|
|
memcpyb_end:
|
memcpyb_end:
|
pop si
|
pop si
|
pop ds
|
pop ds
|
pop di
|
pop di
|
pop es
|
pop es
|
pop cx
|
pop cx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void memcpyw(dseg,doffset,sseg,soffset,count)
|
static void memcpyw(dseg,doffset,sseg,soffset,count)
|
Bit16u dseg;
|
Bit16u dseg;
|
Bit16u doffset;
|
Bit16u doffset;
|
Bit16u sseg;
|
Bit16u sseg;
|
Bit16u soffset;
|
Bit16u soffset;
|
Bit16u count;
|
Bit16u count;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push cx
|
push cx
|
push es
|
push es
|
push di
|
push di
|
push ds
|
push ds
|
push si
|
push si
|
|
|
mov cx, 12[bp] ; count
|
mov cx, 12[bp] ; count
|
cmp cx, #0x0000
|
cmp cx, #0x0000
|
je memcpyw_end
|
je memcpyw_end
|
mov ax, 4[bp] ; dsegment
|
mov ax, 4[bp] ; dsegment
|
mov es, ax
|
mov es, ax
|
mov ax, 6[bp] ; doffset
|
mov ax, 6[bp] ; doffset
|
mov di, ax
|
mov di, ax
|
mov ax, 8[bp] ; ssegment
|
mov ax, 8[bp] ; ssegment
|
mov ds, ax
|
mov ds, ax
|
mov ax, 10[bp] ; soffset
|
mov ax, 10[bp] ; soffset
|
mov si, ax
|
mov si, ax
|
cld
|
cld
|
rep
|
rep
|
movsw
|
movsw
|
|
|
memcpyw_end:
|
memcpyw_end:
|
pop si
|
pop si
|
pop ds
|
pop ds
|
pop di
|
pop di
|
pop es
|
pop es
|
pop cx
|
pop cx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static Bit8u
|
static Bit8u
|
read_byte(seg, offset)
|
read_byte(seg, offset)
|
Bit16u seg;
|
Bit16u seg;
|
Bit16u offset;
|
Bit16u offset;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push bx
|
push bx
|
push ds
|
push ds
|
mov ax, 4[bp] ; segment
|
mov ax, 4[bp] ; segment
|
mov ds, ax
|
mov ds, ax
|
mov bx, 6[bp] ; offset
|
mov bx, 6[bp] ; offset
|
mov al, [bx]
|
mov al, [bx]
|
;; al = return value (byte)
|
;; al = return value (byte)
|
pop ds
|
pop ds
|
pop bx
|
pop bx
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static Bit16u
|
static Bit16u
|
read_word(seg, offset)
|
read_word(seg, offset)
|
Bit16u seg;
|
Bit16u seg;
|
Bit16u offset;
|
Bit16u offset;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push bx
|
push bx
|
push ds
|
push ds
|
mov ax, 4[bp] ; segment
|
mov ax, 4[bp] ; segment
|
mov ds, ax
|
mov ds, ax
|
mov bx, 6[bp] ; offset
|
mov bx, 6[bp] ; offset
|
mov ax, [bx]
|
mov ax, [bx]
|
;; ax = return value (word)
|
;; ax = return value (word)
|
pop ds
|
pop ds
|
pop bx
|
pop bx
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void
|
static void
|
write_byte(seg, offset, data)
|
write_byte(seg, offset, data)
|
Bit16u seg;
|
Bit16u seg;
|
Bit16u offset;
|
Bit16u offset;
|
Bit8u data;
|
Bit8u data;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push bx
|
push bx
|
push ds
|
push ds
|
mov ax, 4[bp] ; segment
|
mov ax, 4[bp] ; segment
|
mov ds, ax
|
mov ds, ax
|
mov bx, 6[bp] ; offset
|
mov bx, 6[bp] ; offset
|
mov al, 8[bp] ; data byte
|
mov al, 8[bp] ; data byte
|
mov [bx], al ; write data byte
|
mov [bx], al ; write data byte
|
pop ds
|
pop ds
|
pop bx
|
pop bx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
static void
|
static void
|
write_word(seg, offset, data)
|
write_word(seg, offset, data)
|
Bit16u seg;
|
Bit16u seg;
|
Bit16u offset;
|
Bit16u offset;
|
Bit16u data;
|
Bit16u data;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push bx
|
push bx
|
push ds
|
push ds
|
mov ax, 4[bp] ; segment
|
mov ax, 4[bp] ; segment
|
mov ds, ax
|
mov ds, ax
|
mov bx, 6[bp] ; offset
|
mov bx, 6[bp] ; offset
|
mov ax, 8[bp] ; data word
|
mov ax, 8[bp] ; data word
|
mov [bx], ax ; write data word
|
mov [bx], ax ; write data word
|
pop ds
|
pop ds
|
pop bx
|
pop bx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
Bit8u
|
Bit8u
|
inb(port)
|
inb(port)
|
Bit16u port;
|
Bit16u port;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push dx
|
push dx
|
mov dx, 4[bp]
|
mov dx, 4[bp]
|
in al, dx
|
in al, dx
|
pop dx
|
pop dx
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
Bit16u
|
Bit16u
|
inw(port)
|
inw(port)
|
Bit16u port;
|
Bit16u port;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push dx
|
push dx
|
mov dx, 4[bp]
|
mov dx, 4[bp]
|
in ax, dx
|
in ax, dx
|
pop dx
|
pop dx
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
void
|
void
|
outb(port, val)
|
outb(port, val)
|
Bit16u port;
|
Bit16u port;
|
Bit8u val;
|
Bit8u val;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push dx
|
push dx
|
mov dx, 4[bp]
|
mov dx, 4[bp]
|
mov al, 6[bp]
|
mov al, 6[bp]
|
out dx, al
|
out dx, al
|
pop dx
|
pop dx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
void
|
void
|
outw(port, val)
|
outw(port, val)
|
Bit16u port;
|
Bit16u port;
|
Bit16u val;
|
Bit16u val;
|
{
|
{
|
ASM_START
|
ASM_START
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
|
|
push ax
|
push ax
|
push dx
|
push dx
|
mov dx, 4[bp]
|
mov dx, 4[bp]
|
mov ax, 6[bp]
|
mov ax, 6[bp]
|
out dx, ax
|
out dx, ax
|
pop dx
|
pop dx
|
pop ax
|
pop ax
|
|
|
pop bp
|
pop bp
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
Bit16u get_SS()
|
Bit16u get_SS()
|
{
|
{
|
ASM_START
|
ASM_START
|
mov ax, ss
|
mov ax, ss
|
ASM_END
|
ASM_END
|
}
|
}
|
|
|
void printf(s)
|
void printf(s)
|
Bit8u *s;
|
Bit8u *s;
|
{
|
{
|
Bit8u c, format_char;
|
Bit8u c, format_char;
|
Boolean in_format;
|
Boolean in_format;
|
unsigned format_width, i;
|
unsigned format_width, i;
|
Bit16u *arg_ptr;
|
Bit16u *arg_ptr;
|
Bit16u arg_seg, arg, digit, nibble, shift_count;
|
Bit16u arg_seg, arg, digit, nibble, shift_count;
|
|
|
arg_ptr = &s;
|
arg_ptr = &s;
|
arg_seg = get_SS();
|
arg_seg = get_SS();
|
|
|
in_format = 0;
|
in_format = 0;
|
format_width = 0;
|
format_width = 0;
|
|
|
while (c = read_byte(0xc000, s)) {
|
while (c = read_byte(0xc000, s)) {
|
if ( c == '%' ) {
|
if ( c == '%' ) {
|
in_format = 1;
|
in_format = 1;
|
format_width = 0;
|
format_width = 0;
|
}
|
}
|
else if (in_format) {
|
else if (in_format) {
|
if ( (c>='0') && (c<='9') ) {
|
if ( (c>='0') && (c<='9') ) {
|
format_width = (format_width * 10) + (c - '0');
|
format_width = (format_width * 10) + (c - '0');
|
}
|
}
|
else if (c == 'x') {
|
else if (c == 'x') {
|
arg_ptr++; // increment to next arg
|
arg_ptr++; // increment to next arg
|
arg = read_word(arg_seg, arg_ptr);
|
arg = read_word(arg_seg, arg_ptr);
|
if (format_width == 0)
|
if (format_width == 0)
|
format_width = 4;
|
format_width = 4;
|
i = 0;
|
i = 0;
|
digit = format_width - 1;
|
digit = format_width - 1;
|
for (i=0; i<format_width; i++) {
|
for (i=0; i<format_width; i++) {
|
nibble = (arg >> (4 * digit)) & 0x000f;
|
nibble = (arg >> (4 * digit)) & 0x000f;
|
if (nibble <= 9)
|
if (nibble <= 9)
|
outb(0x0500, nibble + '0');
|
outb(0x0500, nibble + '0');
|
else
|
else
|
outb(0x0500, (nibble - 10) + 'A');
|
outb(0x0500, (nibble - 10) + 'A');
|
digit--;
|
digit--;
|
}
|
}
|
in_format = 0;
|
in_format = 0;
|
}
|
}
|
//else if (c == 'd') {
|
//else if (c == 'd') {
|
// in_format = 0;
|
// in_format = 0;
|
// }
|
// }
|
}
|
}
|
else {
|
else {
|
outb(0x0500, c);
|
outb(0x0500, c);
|
}
|
}
|
s ++;
|
s ++;
|
}
|
}
|
}
|
}
|
|
|
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
|
|
ASM_START
|
ASM_START
|
;; DATA_SEG_DEFS_HERE
|
;; DATA_SEG_DEFS_HERE
|
ASM_END
|
ASM_END
|
|
|
ASM_START
|
ASM_START
|
.ascii "vgabios ends here"
|
.ascii "vgabios ends here"
|
.byte 0x00
|
.byte 0x00
|
vgabios_end:
|
vgabios_end:
|
.byte 0xCB
|
.byte 0xCB
|
;; BLOCK_STRINGS_BEGIN
|
;; BLOCK_STRINGS_BEGIN
|
ASM_END
|
ASM_END
|
|
|