OpenCores
URL https://opencores.org/ocsvn/zet86/zet86/trunk

Subversion Repositories zet86

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /zet86/trunk/soc/bios
    from Rev 48 to Rev 49
    Reverse comparison

Rev 48 → Rev 49

/vgabios.c
0,0 → 1,1553
#include "vgabios.h"
 
/* Declares */
static Bit8u read_byte();
static Bit16u read_word();
static void write_byte();
static void write_word();
static Bit8u inb();
static Bit16u inw();
static void outb();
static void outw();
 
static Bit16u get_SS();
 
// Output
static void printf();
 
static Bit8u find_vga_entry();
 
static void memsetb();
static void memsetw();
static void memcpyb();
static void memcpyw();
 
static void biosfn_set_video_mode();
static void biosfn_set_cursor_shape();
static void biosfn_set_cursor_pos();
static void biosfn_get_cursor_pos();
static void biosfn_scroll();
static void biosfn_read_char_attr();
static void biosfn_write_char_attr();
static void biosfn_write_char_only();
static void biosfn_write_teletype();
static void biosfn_load_text_8_16_pat();
static void biosfn_write_string();
extern Bit8u video_save_pointer_table[];
 
// This is for compiling with gcc2 and gcc3
#define ASM_START #asm
#define ASM_END #endasm
 
ASM_START
 
MACRO SET_INT_VECTOR
push ds
xor ax, ax
mov ds, ax
mov ax, ?3
mov ?1*4, ax
mov ax, ?2
mov ?1*4+2, ax
pop ds
MEND
 
ASM_END
 
ASM_START
.text
.rom
.org 0
 
use16 8086
 
vgabios_start:
.byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */
 
.byte 0x40 /* BIOS extension length in units of 512 bytes */
 
 
vgabios_entry_point:
 
jmp vgabios_init_func
 
vgabios_name:
.ascii "Zet/Bochs VGABios"
.ascii " "
.byte 0x00
 
// Info from Bart Oldeman
.org 0x1e
.ascii "IBM"
.byte 0x00
 
vgabios_version:
#ifndef VGABIOS_VERS
.ascii "current-cvs"
#else
.ascii VGABIOS_VERS
#endif
.ascii " "
 
vgabios_date:
.ascii VGABIOS_DATE
.byte 0x0a,0x0d
.byte 0x00
 
vgabios_copyright:
.ascii "(C) 2003 the LGPL VGABios developers Team"
.byte 0x0a,0x0d
.byte 0x00
 
vgabios_license:
.ascii "This VGA/VBE Bios is released under the GNU LGPL"
.byte 0x0a,0x0d
.byte 0x0a,0x0d
.byte 0x00
 
vgabios_website:
.ascii "Please visit :"
.byte 0x0a,0x0d
;;.ascii " . http://www.plex86.org"
;;.byte 0x0a,0x0d
.ascii " . http://zet.aluzina.org"
.byte 0x0a,0x0d
.ascii " . http://bochs.sourceforge.net"
.byte 0x0a,0x0d
.ascii " . http://www.nongnu.org/vgabios"
.byte 0x0a,0x0d
.byte 0x0a,0x0d
.byte 0x00
 
 
;; ========================================================
;;
;; Init Entry point
;;
;; ========================================================
vgabios_init_func:
 
;; init vga card
call init_vga_card
 
;; init basic bios vars
call init_bios_area
 
;; set int10 vect
SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
 
;; display splash screen
call _display_splash_screen
 
;; init video mode and clear the screen
mov ax,#0x0003
int #0x10
 
;; show info
call _display_info
 
retf
ASM_END
 
/*
* int10 handled here
*/
ASM_START
vgabios_int10_handler:
pushf
cmp ah, #0x0f
jne int10_test_1A
call biosfn_get_video_mode
jmp int10_end
int10_test_1A:
int10_test_1103:
cmp ax, #0x1103
jne int10_normal
call biosfn_set_text_block_specifier
jmp int10_end
 
int10_normal:
push es
push ds
;pusha ; we do this instead:
 
push ax
push cx
push dx
push bx
push sp
mov bx, sp
sseg
add [bx], #10
sseg
mov bx, [bx+2]
push bp
push si
push di
 
;; We have to set ds to access the right data segment
mov bx, #0xc000
mov ds, bx
 
call _int10_func
 
; popa ; we do this instead:
pop di
pop si
pop bp
add sp, #2
pop bx
pop dx
pop cx
pop ax
 
pop ds
pop es
int10_end:
popf
iret
ASM_END
 
#include "vgatables.h"
#include "vgafonts.h"
 
/*
* Boot time harware inits
*/
ASM_START
init_vga_card:
;; switch to color mode and enable CPU access 480 lines
mov dx, #0x3C2
mov al, #0xC3
outb dx,al
 
;; more than 64k 3C4/04
mov dx, #0x3C4
mov al, #0x04
outb dx,al
mov dx, #0x3C5
mov al, #0x02
outb dx,al
 
#if defined(USE_BX_INFO) || defined(DEBUG)
mov bx, #msg_vga_init
push bx
call _printf
#endif
; inc sp
; inc sp
ret
 
#if defined(USE_BX_INFO) || defined(DEBUG)
msg_vga_init:
.ascii "VGABios $Id: vgabios.c,v 1.9 2009-03-05 19:58:40 zeus Exp $"
.byte 0x0d,0x0a,0x00
#endif
ASM_END
 
// --------------------------------------------------------------------------------------------
/*
* Boot time bios area inits
*/
ASM_START
init_bios_area:
push ds
mov ax, # BIOSMEM_SEG
mov ds, ax
 
;; init detected hardware BIOS Area
mov bx, # BIOSMEM_INITIAL_MODE
mov ax, [bx]
and ax, #0xffcf
;; set 80x25 color (not clear from RBIL but usual)
or ax, #0x0020
mov [bx], ax
 
;; Just for the first int10 find its children
 
;; the default char height
mov bx, # BIOSMEM_CHAR_HEIGHT
mov al, #0x10
mov [bx], al
 
;; Clear the screen
mov bx, # BIOSMEM_VIDEO_CTL
mov al, #0x60
mov [bx], al
 
;; Set the basic screen we have
mov bx, # BIOSMEM_SWITCHES
mov al, #0xf9
mov [bx], al
 
;; Set the basic modeset options
mov bx, # BIOSMEM_MODESET_CTL
mov al, #0x51
mov [bx], al
 
;; Set the default MSR
mov bx, # BIOSMEM_CURRENT_MSR
mov al, #0x09
mov [bx], al
 
pop ds
ret
 
_video_save_pointer_table:
.word _video_param_table
.word 0xc000
 
.word 0 /* XXX: fill it */
.word 0
 
.word 0 /* XXX: fill it */
.word 0
 
.word 0 /* XXX: fill it */
.word 0
 
.word 0 /* XXX: fill it */
.word 0
 
.word 0 /* XXX: fill it */
.word 0
 
.word 0 /* XXX: fill it */
.word 0
 
ASM_END
 
// --------------------------------------------------------------------------------------------
/*
* Boot time Splash screen
*/
static void display_splash_screen()
{
}
 
// --------------------------------------------------------------------------------------------
/*
* Tell who we are
*/
 
static void display_info()
{
ASM_START
mov ax,#0xc000
mov ds,ax
mov si,#vgabios_name
call _display_string
mov si,#vgabios_version
call _display_string
 
;;mov si,#vgabios_copyright
;;call _display_string
;;mov si,#crlf
;;call _display_string
 
mov si,#vgabios_license
call _display_string
mov si,#vgabios_website
call _display_string
ASM_END
}
 
static void display_string()
{
// Get length of string
ASM_START
mov ax,ds
mov es,ax
mov di,si
xor cx,cx
not cx
xor al,al
cld
repne
scasb
not cx
dec cx
push cx
 
mov ax,#0x0300
mov bx,#0x0000
int #0x10
 
pop cx
mov ax,#0x1301
mov bx,#0x000b
mov bp,si
int #0x10
ASM_END
}
 
// --------------------------------------------------------
/*
* int10 main dispatcher
*/
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;
{
// BIOS functions
switch(GET_AH())
{
case 0x00:
biosfn_set_video_mode(GET_AL());
switch(GET_AL()&0x7F)
{case 6:
SET_AL(0x3F);
break;
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 7:
SET_AL(0x30);
break;
default:
SET_AL(0x20);
}
break;
case 0x01:
biosfn_set_cursor_shape(GET_CH(),GET_CL());
break;
case 0x02:
biosfn_set_cursor_pos(GET_BH(),DX);
break;
case 0x03:
biosfn_get_cursor_pos(GET_BH(),&CX,&DX);
break;
case 0x06:
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP);
break;
case 0x07:
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN);
break;
case 0x08:
biosfn_read_char_attr(GET_BH(),&AX);
break;
case 0x09:
biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX);
break;
case 0x0A:
biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX);
break;
case 0x0E:
// Ralf Brown Interrupt list is WRONG on bh(page)
// We do output only on the current page !
biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);
break;
case 0x11:
switch(GET_AL())
{
case 0x04:
case 0x14:
biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
break;
}
break;
case 0x13:
biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
break;
}
}
 
// ============================================================================================
//
// BIOS functions
//
// ============================================================================================
 
static void biosfn_set_video_mode(mode) Bit8u mode;
{// mode: Bit 7 is 1 if no clear screen
 
// Should we clear the screen ?
Bit8u noclearmem=mode&0x80;
Bit8u line,mmask,*palette,vpti;
Bit16u i,twidth,theightm1,cheight;
Bit8u modeset_ctl,video_ctl,vga_switches;
Bit16u crtc_addr;
 
// The real mode
mode=mode&0x7f;
 
// find the entry in the video modes
line=find_vga_entry(mode);
 
if(line==0xFF)
return;
 
vpti=line_to_vpti[line];
twidth=video_param_table[vpti].twidth;
theightm1=video_param_table[vpti].theightm1;
cheight=video_param_table[vpti].cheight;
 
// Read the bios vga control
video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
 
// Read the bios vga switches
vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES);
 
// Read the bios mode set control
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
 
// Then we know the number of lines
// FIXME
 
// if palette loading (bit 3 of modeset ctl = 0)
if((modeset_ctl&0x08)==0)
{// Set the PEL mask
outb(VGAREG_PEL_MASK,vga_modes[line].pelmask);
 
// Set the whole dac always, from 0
outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
 
// From which palette
switch(vga_modes[line].dacmodel)
{case 0:
palette=&palette0;
break;
case 1:
palette=&palette1;
break;
case 2:
palette=&palette2;
break;
case 3:
palette=&palette3;
break;
}
// Always 256*3 values
for(i=0;i<0x0100;i++)
{if(i<=dac_regs[vga_modes[line].dacmodel])
{outb(VGAREG_DAC_DATA,palette[(i*3)+0]);
outb(VGAREG_DAC_DATA,palette[(i*3)+1]);
outb(VGAREG_DAC_DATA,palette[(i*3)+2]);
}
else
{outb(VGAREG_DAC_DATA,0);
outb(VGAREG_DAC_DATA,0);
outb(VGAREG_DAC_DATA,0);
}
}
}
 
// Reset Attribute Ctl flip-flop
inb(VGAREG_ACTL_RESET);
 
// Set Attribute Ctl
for(i=0;i<=0x13;i++)
{outb(VGAREG_ACTL_ADDRESS,i);
outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);
}
outb(VGAREG_ACTL_ADDRESS,0x14);
outb(VGAREG_ACTL_WRITE_DATA,0x00);
 
// Set Sequencer Ctl
outb(VGAREG_SEQU_ADDRESS,0);
outb(VGAREG_SEQU_DATA,0x03);
for(i=1;i<=4;i++)
{outb(VGAREG_SEQU_ADDRESS,i);
outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);
}
 
// Set Grafx Ctl
for(i=0;i<=8;i++)
{outb(VGAREG_GRDC_ADDRESS,i);
outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);
}
 
// Set CRTC address VGA or MDA
crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
 
// Disable CRTC write protection
outw(crtc_addr,0x0011);
// Set CRTC regs
for(i=0;i<=0x18;i++)
{outb(crtc_addr,i);
outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);
}
 
// Set the misc register
outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg);
 
// Enable video
outb(VGAREG_ACTL_ADDRESS,0x20);
inb(VGAREG_ACTL_RESET);
 
if(noclearmem==0x00)
{
if(vga_modes[line].class==TEXT)
{
memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k
}
else
{
if(mode<0x0d)
{
memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k
}
else
{
outb( VGAREG_SEQU_ADDRESS, 0x02 );
mmask = inb( VGAREG_SEQU_DATA );
outb( VGAREG_SEQU_DATA, 0x0f ); // all planes
memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k
outb( VGAREG_SEQU_DATA, mmask );
}
}
}
 
// Set the BIOS mem
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
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_CRTC_ADDRESS,crtc_addr);
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
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
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+2, 0xc000);
 
// FIXME
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...
 
if(vga_modes[line].class==TEXT)
{
biosfn_set_cursor_shape(0x06,0x07);
}
 
// Set cursor pos for page 0..7
for(i=0;i<8;i++)
biosfn_set_cursor_pos(i,0x0000);
 
// Write the fonts in memory
if(vga_modes[line].class==TEXT)
{
ASM_START
;; copy and activate 8x16 font
mov ax, #0x1104
mov bl, #0x00
int #0x10
mov ax, #0x1103
mov bl, #0x00
int #0x10
ASM_END
}
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_set_cursor_shape (CH,CL)
Bit8u CH;Bit8u CL;
{Bit16u cheight,curs,crtc_addr;
Bit8u modeset_ctl;
 
CH&=0x3f;
CL&=0x1f;
 
curs=(CH<<8)+CL;
write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs);
 
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))
{
if(CL!=(CH+1))
{
CH = ((CH+1) * cheight / 8) -1;
}
else
{
CH = ((CL+1) * cheight / 8) - 2;
}
CL = ((CL+1) * cheight / 8) - 1;
}
 
// CTRC regs 0x0a and 0x0b
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
outb(crtc_addr,0x0a);
outb(crtc_addr+1,CH);
outb(crtc_addr,0x0b);
outb(crtc_addr+1,CL);
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_set_cursor_pos (page, cursor)
Bit8u page;Bit16u cursor;
{
Bit8u current;
Bit16u crtc_addr;
 
// Should not happen...
if(page>7)return;
 
// Bios cursor pos
write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor);
 
// Set the hardware cursor
current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
if(page==current)
{
// CRTC regs 0x0e and 0x0f
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
outb(crtc_addr,0x0e);
outb(crtc_addr+1,(cursor&0xff00)>>8);
outb(crtc_addr,0x0f);
outb(crtc_addr+1,cursor&0x00ff);
}
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_get_cursor_pos (page,shape, pos)
Bit8u page;Bit16u *shape;Bit16u *pos;
{
Bit16u ss=get_SS();
 
// Default
write_word(ss, shape, 0);
write_word(ss, pos, 0);
 
if(page>7)return;
// FIXME should handle VGA 14/16 lines
write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE));
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)
Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;
{
// page == 0xFF if current
 
Bit8u mode,line,cheight,bpp,cols;
Bit16u nbcols,nbrows,i;
Bit16u address;
 
if(rul>rlr)return;
if(cul>clr)return;
 
// Get the mode
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
line=find_vga_entry(mode);
if(line==0xFF)return;
 
// Get the dimensions
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
 
// Get the current page
if(page==0xFF)
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
 
if(rlr>=nbrows)rlr=nbrows-1;
if(clr>=nbcols)clr=nbcols-1;
if(nblines>nbrows)nblines=0;
cols=clr-cul+1;
 
if(vga_modes[line].class==TEXT)
{
// Compute the address
address=SCREEN_MEM_START(nbcols,nbrows,page);
#ifdef DEBUG
printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);
#endif
 
if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
{
memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);
}
else
{// if Scroll up
if(dir==SCROLL_UP)
{for(i=rul;i<=rlr;i++)
{
if((i+nblines>rlr)||(nblines==0))
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
else
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);
}
}
else
{for(i=rlr;i>=rul;i--)
{
if((i<rul+nblines)||(nblines==0))
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
else
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);
if (i>rlr) break;
}
}
}
}
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_read_char_attr (page,car)
Bit8u page;Bit16u *car;
{Bit16u ss=get_SS();
Bit8u xcurs,ycurs,mode,line;
Bit16u nbcols,nbrows,address;
Bit16u cursor,dummy;
 
// Get the mode
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
line=find_vga_entry(mode);
if(line==0xFF)return;
 
// Get the cursor pos for the page
biosfn_get_cursor_pos(page,&dummy,&cursor);
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
 
// Get the dimensions
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
 
// Compute the address
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
 
write_word(ss,car,read_word(vga_modes[line].sstart,address));
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_write_char_attr (car,page,attr,count)
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
{
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
Bit16u nbcols,nbrows,address;
Bit16u cursor,dummy;
 
// Get the mode
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
line=find_vga_entry(mode);
if(line==0xFF)return;
 
// Get the cursor pos for the page
biosfn_get_cursor_pos(page,&dummy,&cursor);
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
 
// Get the dimensions
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
 
// Compute the address
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
 
dummy=((Bit16u)attr<<8)+car;
memsetw(vga_modes[line].sstart,address,dummy,count);
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_write_char_only (car,page,attr,count)
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
{
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
Bit16u nbcols,nbrows,address;
Bit16u cursor,dummy;
 
// Get the mode
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
line=find_vga_entry(mode);
if(line==0xFF)return;
 
// Get the cursor pos for the page
biosfn_get_cursor_pos(page,&dummy,&cursor);
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
 
// Get the dimensions
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
 
// Compute the address
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
 
while(count-->0)
{write_byte(vga_modes[line].sstart,address,car);
address+=2;
}
}
 
// --------------------------------------------------------------------------------------------
static void biosfn_write_teletype (car, page, attr, flag)
Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
{// flag = WITH_ATTR / NO_ATTR
 
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
Bit16u nbcols,nbrows,address;
Bit16u cursor,dummy;
 
// special case if page is 0xff, use current page
if(page==0xff)
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
 
// Get the mode
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
line=find_vga_entry(mode);
if(line==0xFF)return;
 
// Get the cursor pos for the page
biosfn_get_cursor_pos(page,&dummy,&cursor);
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
 
// Get the dimensions
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
 
switch(car)
{
case 7:
//FIXME should beep
break;
 
case 8:
if(xcurs>0)xcurs--;
break;
 
case '\r':
xcurs=0;
break;
 
case '\n':
ycurs++;
break;
 
case '\t':
do
{
biosfn_write_teletype(' ',page,attr,flag);
biosfn_get_cursor_pos(page,&dummy,&cursor);
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
}while(xcurs%8==0);
break;
 
default:
 
if(vga_modes[line].class==TEXT)
{
// Compute the address
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
 
// Write the char
write_byte(vga_modes[line].sstart,address,car);
 
if(flag==WITH_ATTR)
write_byte(vga_modes[line].sstart,address+1,attr);
}
xcurs++;
}
 
// Do we need to wrap ?
if(xcurs==nbcols)
{xcurs=0;
ycurs++;
}
 
// Do we need to scroll ?
if(ycurs==nbrows)
{
if(vga_modes[line].class==TEXT)
{
biosfn_scroll(0x01,0x07,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
}
ycurs-=1;
}
 
// Set the cursor for the page
cursor=ycurs; cursor<<=8; cursor+=xcurs;
biosfn_set_cursor_pos(page,cursor);
}
 
// --------------------------------------------------------------------------------------------
ASM_START
biosfn_get_video_mode:
push ds
mov ax, # BIOSMEM_SEG
mov ds, ax
push bx
mov bx, # BIOSMEM_CURRENT_PAGE
mov al, [bx]
pop bx
mov bh, al
push bx
mov bx, # BIOSMEM_VIDEO_CTL
mov ah, [bx]
and ah, #0x80
mov bx, # BIOSMEM_CURRENT_MODE
mov al, [bx]
or al, ah
mov bx, # BIOSMEM_NB_COLS
mov ah, [bx]
pop bx
pop ds
ret
ASM_END
 
// --------------------------------------------------------------------------------------------
static void get_font_access()
{
ASM_START
mov dx, # VGAREG_SEQU_ADDRESS
mov ax, #0x0100
out dx, ax
mov ax, #0x0402
out dx, ax
mov ax, #0x0704
out dx, ax
mov ax, #0x0300
out dx, ax
mov dx, # VGAREG_GRDC_ADDRESS
mov ax, #0x0204
out dx, ax
mov ax, #0x0005
out dx, ax
mov ax, #0x0406
out dx, ax
ASM_END
}
 
static void release_font_access()
{
ASM_START
mov dx, # VGAREG_SEQU_ADDRESS
mov ax, #0x0100
out dx, ax
mov ax, #0x0302
out dx, ax
mov ax, #0x0304
out dx, ax
mov ax, #0x0300
out dx, ax
mov dx, # VGAREG_READ_MISC_OUTPUT
in al, dx
and al, #0x01
push cx
mov cl,*2
shl al,cl
pop cx
or al, #0x0a
mov ah, al
mov al, #0x06
mov dx, # VGAREG_GRDC_ADDRESS
out dx, ax
mov ax, #0x0004
out dx, ax
mov ax, #0x1005
out dx, ax
ASM_END
}
 
ASM_START
idiv_u:
xor dx,dx
div bx
ret
ASM_END
 
static void set_scan_lines(lines) Bit8u lines;
{
Bit16u crtc_addr,cols,page,vde;
Bit8u crtc_r9,ovl,rows;
 
crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
outb(crtc_addr, 0x09);
crtc_r9 = inb(crtc_addr+1);
crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
outb(crtc_addr+1, crtc_r9);
/*
if(lines==8)
{
biosfn_set_cursor_shape(0x06,0x07);
}
else
{
biosfn_set_cursor_shape(lines-4,lines-3);
}
*/
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines);
outb(crtc_addr, 0x12);
vde = inb(crtc_addr+1);
outb(crtc_addr, 0x07);
ovl = inb(crtc_addr+1);
vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
rows = vde / lines;
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1);
cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2);
}
 
// --------------------------------------------------------------------------------------------
ASM_START
biosfn_set_text_block_specifier:
push ax
push dx
mov dx, # VGAREG_SEQU_ADDRESS
mov ah, bl
mov al, #0x03
out dx, ax
pop dx
pop ax
ret
ASM_END
 
// --------------------------------------------------------------------------------------------
static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL;
{
Bit16u blockaddr,dest,i,src;
 
get_font_access();
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
for(i=0;i<0x100;i++)
{
src = i * 16;
dest = blockaddr + i * 32;
memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16);
}
release_font_access();
if(AL>=0x10)
{
set_scan_lines(16);
}
}
 
// --------------------------------------------------------------------------------------------
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;
{
Bit16u newcurs,oldcurs,dummy;
Bit8u car,carattr;
 
// Read curs info for the page
biosfn_get_cursor_pos(page,&dummy,&oldcurs);
 
// if row=0xff special case : use current cursor position
if(row==0xff)
{col=oldcurs&0x00ff;
row=(oldcurs&0xff00)>>8;
}
 
newcurs=row; newcurs<<=8; newcurs+=col;
biosfn_set_cursor_pos(page,newcurs);
 
while(count--!=0)
{
car=read_byte(seg,offset++);
if((flag&0x02)!=0)
attr=read_byte(seg,offset++);
 
biosfn_write_teletype(car,page,attr,WITH_ATTR);
}
 
// Set back curs pos
if((flag&0x01)==0)
biosfn_set_cursor_pos(page,oldcurs);
}
 
// ============================================================================================
//
// Video Utils
//
// ============================================================================================
 
// --------------------------------------------------------------------------------------------
static Bit8u find_vga_entry(mode)
Bit8u mode;
{
Bit8u i,line=0xFF;
for(i=0;i<=MODE_MAX;i++)
if(vga_modes[i].svgamode==mode)
{line=i;
break;
}
return line;
}
 
// --------------------------------------------------------------------------------------------
static void memsetw(seg,offset,value,count)
Bit16u seg;
Bit16u offset;
Bit16u value;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
 
push ax
push cx
push es
push di
 
mov cx, 10[bp] ; count
cmp cx, #0x00
je memsetw_end
mov ax, 4[bp] ; segment
mov es, ax
mov ax, 6[bp] ; offset
mov di, ax
mov ax, 8[bp] ; value
cld
rep
stosw
 
memsetw_end:
pop di
pop es
pop cx
pop ax
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
static void memcpyb(dseg,doffset,sseg,soffset,count)
Bit16u dseg;
Bit16u doffset;
Bit16u sseg;
Bit16u soffset;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
 
push ax
push cx
push es
push di
push ds
push si
 
mov cx, 12[bp] ; count
cmp cx, #0x0000
je memcpyb_end
mov ax, 4[bp] ; dsegment
mov es, ax
mov ax, 6[bp] ; doffset
mov di, ax
mov ax, 8[bp] ; ssegment
mov ds, ax
mov ax, 10[bp] ; soffset
mov si, ax
cld
rep
movsb
 
memcpyb_end:
pop si
pop ds
pop di
pop es
pop cx
pop ax
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
static void memcpyw(dseg,doffset,sseg,soffset,count)
Bit16u dseg;
Bit16u doffset;
Bit16u sseg;
Bit16u soffset;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
 
push ax
push cx
push es
push di
push ds
push si
 
mov cx, 12[bp] ; count
cmp cx, #0x0000
je memcpyw_end
mov ax, 4[bp] ; dsegment
mov es, ax
mov ax, 6[bp] ; doffset
mov di, ax
mov ax, 8[bp] ; ssegment
mov ds, ax
mov ax, 10[bp] ; soffset
mov si, ax
cld
rep
movsw
 
memcpyw_end:
pop si
pop ds
pop di
pop es
pop cx
pop ax
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
static Bit8u
read_byte(seg, offset)
Bit16u seg;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
 
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov al, [bx]
;; al = return value (byte)
pop ds
pop bx
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
static Bit16u
read_word(seg, offset)
Bit16u seg;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
 
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov ax, [bx]
;; ax = return value (word)
pop ds
pop bx
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
static void
write_byte(seg, offset, data)
Bit16u seg;
Bit16u offset;
Bit8u data;
{
ASM_START
push bp
mov bp, sp
 
push ax
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov al, 8[bp] ; data byte
mov [bx], al ; write data byte
pop ds
pop bx
pop ax
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
static void
write_word(seg, offset, data)
Bit16u seg;
Bit16u offset;
Bit16u data;
{
ASM_START
push bp
mov bp, sp
 
push ax
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov ax, 8[bp] ; data word
mov [bx], ax ; write data word
pop ds
pop bx
pop ax
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
Bit8u
inb(port)
Bit16u port;
{
ASM_START
push bp
mov bp, sp
 
push dx
mov dx, 4[bp]
in al, dx
pop dx
 
pop bp
ASM_END
}
 
Bit16u
inw(port)
Bit16u port;
{
ASM_START
push bp
mov bp, sp
 
push dx
mov dx, 4[bp]
in ax, dx
pop dx
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
void
outb(port, val)
Bit16u port;
Bit8u val;
{
ASM_START
push bp
mov bp, sp
 
push ax
push dx
mov dx, 4[bp]
mov al, 6[bp]
out dx, al
pop dx
pop ax
 
pop bp
ASM_END
}
 
// --------------------------------------------------------------------------------------------
void
outw(port, val)
Bit16u port;
Bit16u val;
{
ASM_START
push bp
mov bp, sp
 
push ax
push dx
mov dx, 4[bp]
mov ax, 6[bp]
out dx, ax
pop dx
pop ax
 
pop bp
ASM_END
}
 
Bit16u get_SS()
{
ASM_START
mov ax, ss
ASM_END
}
 
void printf(s)
Bit8u *s;
{
Bit8u c, format_char;
Boolean in_format;
unsigned format_width, i;
Bit16u *arg_ptr;
Bit16u arg_seg, arg, digit, nibble, shift_count;
 
arg_ptr = &s;
arg_seg = get_SS();
 
in_format = 0;
format_width = 0;
 
while (c = read_byte(0xc000, s)) {
if ( c == '%' ) {
in_format = 1;
format_width = 0;
}
else if (in_format) {
if ( (c>='0') && (c<='9') ) {
format_width = (format_width * 10) + (c - '0');
}
else if (c == 'x') {
arg_ptr++; // increment to next arg
arg = read_word(arg_seg, arg_ptr);
if (format_width == 0)
format_width = 4;
i = 0;
digit = format_width - 1;
for (i=0; i<format_width; i++) {
nibble = (arg >> (4 * digit)) & 0x000f;
if (nibble <= 9)
outb(0x0500, nibble + '0');
else
outb(0x0500, (nibble - 10) + 'A');
digit--;
}
in_format = 0;
}
//else if (c == 'd') {
// in_format = 0;
// }
}
else {
outb(0x0500, c);
}
s ++;
}
}
 
// --------------------------------------------------------------------------------------------
 
ASM_START
;; DATA_SEG_DEFS_HERE
ASM_END
 
ASM_START
.ascii "vgabios ends here"
.byte 0x00
vgabios_end:
.byte 0xCB
;; BLOCK_STRINGS_BEGIN
ASM_END
/rombios.c
0,0 → 1,2574
// ROM BIOS compatability entry points:
// ===================================
// $e05b ; POST Entry Point
// $e6f2 ; INT 19h Boot Load Service Entry Point
// $f045 ; INT 10 Functions 0-Fh Entry Point
// $f065 ; INT 10h Video Support Service Entry Point
// $f0a4 ; MDA/CGA Video Parameter Table (INT 1Dh)
// $fff0 ; Power-up Entry Point
// $fff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
// $fffe ; System Model ID
 
#include "rombios.h"
 
#define BX_CPU 0
 
/* model byte 0xFC = AT */
#define SYS_MODEL_ID 0xFC
 
#ifndef BIOS_BUILD_DATE
# define BIOS_BUILD_DATE "06/23/99"
#endif
 
// 1K of base memory used for Extended Bios Data Area (EBDA)
// EBDA is used for PS/2 mouse support, and IDE BIOS, etc.
#define EBDA_SEG 0x9FC0
#define EBDA_SIZE 1 // In KiB
#define BASE_MEM_IN_K (640 - EBDA_SIZE)
 
/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
#define IPL_SEG 0x9ff0
#define IPL_TABLE_OFFSET 0x0000
#define IPL_TABLE_ENTRIES 8
#define IPL_COUNT_OFFSET 0x0080 /* u16: number of valid table entries */
#define IPL_SEQUENCE_OFFSET 0x0082 /* u16: next boot device */
#define IPL_BOOTFIRST_OFFSET 0x0084 /* u16: user selected device */
#define IPL_SIZE 0xff
#define IPL_TYPE_FLOPPY 0x01
#define IPL_TYPE_HARDDISK 0x02
#define IPL_TYPE_CDROM 0x03
#define IPL_TYPE_BEV 0x80
 
// This is for compiling with gcc2 and gcc3
#define ASM_START #asm
#define ASM_END #endasm
 
ASM_START
.rom
 
.org 0x0000
 
use16 8086
 
MACRO SET_INT_VECTOR
mov ax, ?3
mov ?1*4, ax
mov ax, ?2
mov ?1*4+2, ax
MEND
 
ASM_END
 
typedef unsigned char Bit8u;
typedef unsigned short Bit16u;
typedef unsigned short bx_bool;
typedef unsigned long Bit32u;
 
 
void memsetb(seg,offset,value,count);
void memcpyb(dseg,doffset,sseg,soffset,count);
void memcpyd(dseg,doffset,sseg,soffset,count);
 
// memset of count bytes
void
memsetb(seg,offset,value,count)
Bit16u seg;
Bit16u offset;
Bit16u value;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
 
push ax
push cx
push es
push di
 
mov cx, 10[bp] ; count
test cx, cx
je memsetb_end
mov ax, 4[bp] ; segment
mov es, ax
mov ax, 6[bp] ; offset
mov di, ax
mov al, 8[bp] ; value
cld
rep
stosb
 
memsetb_end:
pop di
pop es
pop cx
pop ax
 
pop bp
ASM_END
}
 
// memcpy of count bytes
void
memcpyb(dseg,doffset,sseg,soffset,count)
Bit16u dseg;
Bit16u doffset;
Bit16u sseg;
Bit16u soffset;
Bit16u count;
{
ASM_START
push bp
mov bp, sp
 
push ax
push cx
push es
push di
push ds
push si
 
mov cx, 12[bp] ; count
test cx, cx
je memcpyb_end
mov ax, 4[bp] ; dsegment
mov es, ax
mov ax, 6[bp] ; doffset
mov di, ax
mov ax, 8[bp] ; ssegment
mov ds, ax
mov ax, 10[bp] ; soffset
mov si, ax
cld
rep
movsb
 
memcpyb_end:
pop si
pop ds
pop di
pop es
pop cx
pop ax
 
pop bp
ASM_END
}
 
// Bit32u (unsigned long) and long helper functions
ASM_START
 
idiv_u:
xor dx,dx
div bx
ret
 
ldivul:
mov cx,[di]
mov di,2[di]
call ludivmod
xchg ax,cx
xchg bx,di
ret
 
.align 2
ldivmod:
mov dx,di ; sign byte of b in dh
mov dl,bh ; sign byte of a in dl
test di,di
jns set_asign
neg di
neg cx
sbb di,*0
set_asign:
test bx,bx
jns got_signs ; leave r = a positive
neg bx
neg ax
sbb bx,*0
j got_signs
 
.align 2
ludivmod:
xor dx,dx ; both sign bytes 0
got_signs:
push bp
push si
mov bp,sp
push di ; remember b
push cx
b0 = -4
b16 = -2
 
test di,di
jne divlarge
test cx,cx
je divzero
cmp bx,cx
jae divlarge ; would overflow
xchg dx,bx ; a in dx:ax, signs in bx
div cx
xchg cx,ax ; q in di:cx, junk in ax
xchg ax,bx ; signs in ax, junk in bx
xchg ax,dx ; r in ax, signs back in dx
mov bx,di ; r in bx:ax
j zdivu1
 
divzero: ; return q = 0 and r = a
test dl,dl
jns return
j negr ; a initially minus, restore it
 
divlarge:
push dx ; remember sign bytes
mov si,di ; w in si:dx, initially b from di:cx
mov dx,cx
xor cx,cx ; q in di:cx, initially 0
mov di,cx
; r in bx:ax, initially a
; use di:cx rather than dx:cx in order
; to have dx free for a byte pair later
cmp si,bx
jb loop1
ja zdivu ; finished if b > r
cmp dx,ax
ja zdivu
 
; rotate w (= b) to greatest dyadic multiple of b <= r
 
loop1:
shl dx,*1 ; w = 2*w
rcl si,*1
jc loop1_exit ; w was > r counting overflow (unsigned)
cmp si,bx ; while w <= r (unsigned)
jb loop1
ja loop1_exit
cmp dx,ax
jbe loop1 ; else exit with carry clear for rcr
loop1_exit:
rcr si,*1
rcr dx,*1
loop2:
shl cx,*1 ; q = 2*q
rcl di,*1
cmp si,bx ; if w <= r
jb loop2_over
ja loop2_test
cmp dx,ax
ja loop2_test
loop2_over:
add cx,*1 ; q++
adc di,*0
sub ax,dx ; r = r-w
sbb bx,si
loop2_test:
shr si,*1 ; w = w/2
rcr dx,*1
cmp si,b16[bp] ; while w >= b
ja loop2
jb zdivu
cmp dx,b0[bp]
jae loop2
 
zdivu:
pop dx ; sign bytes
zdivu1:
test dh,dh
js zbminus
test dl,dl
jns return ; else a initially minus, b plus
mov dx,ax ; -a = b * q + r ==> a = b * (-q) + (-r)
or dx,bx
je negq ; use if r = 0
sub ax,b0[bp] ; use a = b * (-1 - q) + (b - r)
sbb bx,b16[bp]
not cx ; q = -1 - q (same as complement)
not di
negr:
neg bx
neg ax
sbb bx,*0
return:
mov sp,bp
pop si
pop bp
ret
 
.align 2
zbminus:
test dl,dl ; (-a) = (-b) * q + r ==> a = b * q + (-r)
js negr ; use if initial a was minus
mov dx,ax ; a = (-b) * q + r ==> a = b * (-q) + r
or dx,bx
je negq ; use if r = 0
sub ax,b0[bp] ; use a = b * (-1 - q) + (b + r)
; (b is now -b)
sbb bx,b16[bp]
not cx
not di
mov sp,bp
pop si
pop bp
ret
 
.align 2
negq:
neg di
neg cx
sbb di,*0
mov sp,bp
pop si
pop bp
ret
 
.align 2
ltstl:
ltstul:
test bx,bx
je ltst_not_sure
ret
 
.align 2
ltst_not_sure:
test ax,ax
js ltst_fix_sign
ret
 
.align 2
ltst_fix_sign:
inc bx
ret
 
.align 2
lmull:
lmulul:
mov cx,ax
mul word ptr 2[di]
xchg ax,bx
mul word ptr [di]
add bx,ax
mov ax,ptr [di]
mul cx
add bx,dx
ret
 
.align 2
lsubl:
lsubul:
sub ax,[di]
sbb bx,2[di]
ret
 
.align 2
laddl:
laddul:
add ax,[di]
adc bx,2[di]
ret
 
.align 2
lorl:
lorul:
or ax,[di]
or bx,2[di]
ret
 
.align 2
lsrul:
mov cx,di
jcxz lsru_exit
cmp cx,*32
jae lsru_zero
lsru_loop:
shr bx,*1
rcr ax,*1
loop lsru_loop
lsru_exit:
ret
 
.align 2
lsru_zero:
xor ax,ax
mov bx,ax
ret
 
.align 2
landl:
landul:
and ax,[di]
and bx,2[di]
ret
 
.align 2
lcmpl:
lcmpul:
sub bx,2[di]
je lcmp_not_sure
ret
 
.align 2
lcmp_not_sure:
cmp ax,[di]
jb lcmp_b_and_lt
jge lcmp_exit
 
inc bx
lcmp_exit:
ret
 
.align 2
lcmp_b_and_lt:
dec bx
ret
 
ASM_END
 
// for access to RAM area which is used by interrupt vectors
// and BIOS Data Area
 
typedef struct {
unsigned char filler1[0x400];
unsigned char filler2[0x6c];
Bit16u ticks_low;
Bit16u ticks_high;
Bit8u midnight_flag;
} bios_data_t;
 
#define BiosData ((bios_data_t *) 0)
 
typedef struct {
union {
struct {
Bit16u di, si, bp, sp;
Bit16u bx, dx, cx, ax;
} r16;
struct {
Bit16u filler[4];
Bit8u bl, bh, dl, dh, cl, ch, al, ah;
} r8;
} u;
} pusha_regs_t;
 
typedef struct {
union {
struct {
Bit16u flags;
} r16;
struct {
Bit8u flagsl;
Bit8u flagsh;
} r8;
} u;
} flags_t;
 
#define SetCF(x) x.u.r8.flagsl |= 0x01
#define SetZF(x) x.u.r8.flagsl |= 0x40
#define ClearCF(x) x.u.r8.flagsl &= 0xfe
#define ClearZF(x) x.u.r8.flagsl &= 0xbf
#define GetCF(x) (x.u.r8.flagsl & 0x01)
 
typedef struct {
Bit16u ip;
Bit16u cs;
flags_t flags;
} iret_addr_t;
 
typedef struct {
Bit16u type;
Bit16u flags;
Bit32u vector;
Bit32u description;
Bit32u reserved;
} ipl_entry_t;
 
static Bit16u inw();
static void outw();
 
static Bit8u read_byte();
static Bit16u read_word();
static void write_byte();
static void write_word();
static void bios_printf();
 
static void int09_function();
static void int13_harddisk();
static void transf_sect();
static void int13_diskette_function();
static void int16_function();
static void int19_function();
static void int1a_function();
static Bit16u get_CS();
static Bit16u get_SS();
static unsigned int enqueue_key();
static unsigned int dequeue_key();
static void set_diskette_ret_status();
static void set_diskette_current_cyl();
 
static void print_bios_banner();
static void print_boot_device();
static void print_boot_failure();
 
#if DEBUG_INT16
# define BX_DEBUG_INT16(a...) BX_DEBUG(a)
#else
# define BX_DEBUG_INT16(a...)
#endif
 
#define SET_AL(val8) AX = ((AX & 0xff00) | (val8))
#define SET_BL(val8) BX = ((BX & 0xff00) | (val8))
#define SET_CL(val8) CX = ((CX & 0xff00) | (val8))
#define SET_DL(val8) DX = ((DX & 0xff00) | (val8))
#define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8))
#define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8))
#define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8))
#define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8))
 
#define GET_AL() ( AX & 0x00ff )
#define GET_BL() ( BX & 0x00ff )
#define GET_CL() ( CX & 0x00ff )
#define GET_DL() ( DX & 0x00ff )
#define GET_AH() ( AX >> 8 )
#define GET_BH() ( BX >> 8 )
#define GET_CH() ( CX >> 8 )
#define GET_DH() ( DX >> 8 )
 
#define GET_ELDL() ( ELDX & 0x00ff )
#define GET_ELDH() ( ELDX >> 8 )
 
#define SET_CF() FLAGS |= 0x0001
#define CLEAR_CF() FLAGS &= 0xfffe
#define GET_CF() (FLAGS & 0x0001)
 
#define SET_ZF() FLAGS |= 0x0040
#define CLEAR_ZF() FLAGS &= 0xffbf
#define GET_ZF() (FLAGS & 0x0040)
 
#define UNSUPPORTED_FUNCTION 0x86
 
#define none 0
#define MAX_SCAN_CODE 0x58
 
static struct {
Bit16u normal;
Bit16u shift;
Bit16u control;
Bit16u alt;
Bit8u lock_flags;
} scan_to_scanascii[MAX_SCAN_CODE + 1] = {
{ none, none, none, none, none },
{ 0x011b, 0x011b, 0x011b, 0x0100, none }, /* escape */
{ 0x0231, 0x0221, none, 0x7800, none }, /* 1! */
{ 0x0332, 0x0340, 0x0300, 0x7900, none }, /* 2@ */
{ 0x0433, 0x0423, none, 0x7a00, none }, /* 3# */
{ 0x0534, 0x0524, none, 0x7b00, none }, /* 4$ */
{ 0x0635, 0x0625, none, 0x7c00, none }, /* 5% */
{ 0x0736, 0x075e, 0x071e, 0x7d00, none }, /* 6^ */
{ 0x0837, 0x0826, none, 0x7e00, none }, /* 7& */
{ 0x0938, 0x092a, none, 0x7f00, none }, /* 8* */
{ 0x0a39, 0x0a28, none, 0x8000, none }, /* 9( */
{ 0x0b30, 0x0b29, none, 0x8100, none }, /* 0) */
{ 0x0c2d, 0x0c5f, 0x0c1f, 0x8200, none }, /* -_ */
{ 0x0d3d, 0x0d2b, none, 0x8300, none }, /* =+ */
{ 0x0e08, 0x0e08, 0x0e7f, none, none }, /* backspace */
{ 0x0f09, 0x0f00, none, none, none }, /* tab */
{ 0x1071, 0x1051, 0x1011, 0x1000, 0x40 }, /* Q */
{ 0x1177, 0x1157, 0x1117, 0x1100, 0x40 }, /* W */
{ 0x1265, 0x1245, 0x1205, 0x1200, 0x40 }, /* E */
{ 0x1372, 0x1352, 0x1312, 0x1300, 0x40 }, /* R */
{ 0x1474, 0x1454, 0x1414, 0x1400, 0x40 }, /* T */
{ 0x1579, 0x1559, 0x1519, 0x1500, 0x40 }, /* Y */
{ 0x1675, 0x1655, 0x1615, 0x1600, 0x40 }, /* U */
{ 0x1769, 0x1749, 0x1709, 0x1700, 0x40 }, /* I */
{ 0x186f, 0x184f, 0x180f, 0x1800, 0x40 }, /* O */
{ 0x1970, 0x1950, 0x1910, 0x1900, 0x40 }, /* P */
{ 0x1a5b, 0x1a7b, 0x1a1b, none, none }, /* [{ */
{ 0x1b5d, 0x1b7d, 0x1b1d, none, none }, /* ]} */
{ 0x1c0d, 0x1c0d, 0x1c0a, none, none }, /* Enter */
{ none, none, none, none, none }, /* L Ctrl */
{ 0x1e61, 0x1e41, 0x1e01, 0x1e00, 0x40 }, /* A */
{ 0x1f73, 0x1f53, 0x1f13, 0x1f00, 0x40 }, /* S */
{ 0x2064, 0x2044, 0x2004, 0x2000, 0x40 }, /* D */
{ 0x2166, 0x2146, 0x2106, 0x2100, 0x40 }, /* F */
{ 0x2267, 0x2247, 0x2207, 0x2200, 0x40 }, /* G */
{ 0x2368, 0x2348, 0x2308, 0x2300, 0x40 }, /* H */
{ 0x246a, 0x244a, 0x240a, 0x2400, 0x40 }, /* J */
{ 0x256b, 0x254b, 0x250b, 0x2500, 0x40 }, /* K */
{ 0x266c, 0x264c, 0x260c, 0x2600, 0x40 }, /* L */
{ 0x273b, 0x273a, none, none, none }, /* ;: */
{ 0x2827, 0x2822, none, none, none }, /* '" */
{ 0x2960, 0x297e, none, none, none }, /* `~ */
{ none, none, none, none, none }, /* L shift */
{ 0x2b5c, 0x2b7c, 0x2b1c, none, none }, /* |\ */
{ 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00, 0x40 }, /* Z */
{ 0x2d78, 0x2d58, 0x2d18, 0x2d00, 0x40 }, /* X */
{ 0x2e63, 0x2e43, 0x2e03, 0x2e00, 0x40 }, /* C */
{ 0x2f76, 0x2f56, 0x2f16, 0x2f00, 0x40 }, /* V */
{ 0x3062, 0x3042, 0x3002, 0x3000, 0x40 }, /* B */
{ 0x316e, 0x314e, 0x310e, 0x3100, 0x40 }, /* N */
{ 0x326d, 0x324d, 0x320d, 0x3200, 0x40 }, /* M */
{ 0x332c, 0x333c, none, none, none }, /* ,< */
{ 0x342e, 0x343e, none, none, none }, /* .> */
{ 0x352f, 0x353f, none, none, none }, /* /? */
{ none, none, none, none, none }, /* R Shift */
{ 0x372a, 0x372a, none, none, none }, /* * */
{ none, none, none, none, none }, /* L Alt */
{ 0x3920, 0x3920, 0x3920, 0x3920, none }, /* space */
{ none, none, none, none, none }, /* caps lock */
{ 0x3b00, 0x5400, 0x5e00, 0x6800, none }, /* F1 */
{ 0x3c00, 0x5500, 0x5f00, 0x6900, none }, /* F2 */
{ 0x3d00, 0x5600, 0x6000, 0x6a00, none }, /* F3 */
{ 0x3e00, 0x5700, 0x6100, 0x6b00, none }, /* F4 */
{ 0x3f00, 0x5800, 0x6200, 0x6c00, none }, /* F5 */
{ 0x4000, 0x5900, 0x6300, 0x6d00, none }, /* F6 */
{ 0x4100, 0x5a00, 0x6400, 0x6e00, none }, /* F7 */
{ 0x4200, 0x5b00, 0x6500, 0x6f00, none }, /* F8 */
{ 0x4300, 0x5c00, 0x6600, 0x7000, none }, /* F9 */
{ 0x4400, 0x5d00, 0x6700, 0x7100, none }, /* F10 */
{ none, none, none, none, none }, /* Num Lock */
{ none, none, none, none, none }, /* Scroll Lock */
{ 0x4700, 0x4737, 0x7700, none, 0x20 }, /* 7 Home */
{ 0x4800, 0x4838, none, none, 0x20 }, /* 8 UP */
{ 0x4900, 0x4939, 0x8400, none, 0x20 }, /* 9 PgUp */
{ 0x4a2d, 0x4a2d, none, none, none }, /* - */
{ 0x4b00, 0x4b34, 0x7300, none, 0x20 }, /* 4 Left */
{ 0x4c00, 0x4c35, none, none, 0x20 }, /* 5 */
{ 0x4d00, 0x4d36, 0x7400, none, 0x20 }, /* 6 Right */
{ 0x4e2b, 0x4e2b, none, none, none }, /* + */
{ 0x4f00, 0x4f31, 0x7500, none, 0x20 }, /* 1 End */
{ 0x5000, 0x5032, none, none, 0x20 }, /* 2 Down */
{ 0x5100, 0x5133, 0x7600, none, 0x20 }, /* 3 PgDn */
{ 0x5200, 0x5230, none, none, 0x20 }, /* 0 Ins */
{ 0x5300, 0x532e, none, none, 0x20 }, /* Del */
{ none, none, none, none, none },
{ none, none, none, none, none },
{ 0x565c, 0x567c, none, none, none }, /* \| */
{ 0x5700, 0x5700, none, none, none }, /* F11 */
{ 0x5800, 0x5800, none, none, none } /* F12 */
};
 
Bit16u
inw(port)
Bit16u port;
{
ASM_START
push bp
mov bp, sp
 
push dx
mov dx, 4[bp]
in ax, dx
pop dx
 
pop bp
ASM_END
}
 
void
outw(port, val)
Bit16u port;
Bit16u val;
{
ASM_START
push bp
mov bp, sp
 
push ax
push dx
mov dx, 4[bp]
mov ax, 6[bp]
out dx, ax
pop dx
pop ax
 
pop bp
ASM_END
}
 
Bit8u
read_byte(seg, offset)
Bit16u seg;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
 
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov al, [bx]
;; al = return value (byte)
pop ds
pop bx
 
pop bp
ASM_END
}
 
Bit16u
read_word(seg, offset)
Bit16u seg;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
 
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov ax, [bx]
;; ax = return value (word)
pop ds
pop bx
 
pop bp
ASM_END
}
 
void
write_byte(seg, offset, data)
Bit16u seg;
Bit16u offset;
Bit8u data;
{
ASM_START
push bp
mov bp, sp
 
push ax
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov al, 8[bp] ; data byte
mov [bx], al ; write data byte
pop ds
pop bx
pop ax
 
pop bp
ASM_END
}
 
void
write_word(seg, offset, data)
Bit16u seg;
Bit16u offset;
Bit16u data;
{
ASM_START
push bp
mov bp, sp
 
push ax
push bx
push ds
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov ax, 8[bp] ; data word
mov [bx], ax ; write data word
pop ds
pop bx
pop ax
 
pop bp
ASM_END
}
 
Bit16u
get_CS()
{
ASM_START
mov ax, cs
ASM_END
}
 
Bit16u
get_SS()
{
ASM_START
mov ax, ss
ASM_END
}
 
void
wrch(c)
Bit8u c;
{
ASM_START
push bp
mov bp, sp
 
push bx
mov ah, #0x0e
mov al, 4[bp]
xor bx,bx
int #0x10
pop bx
 
pop bp
ASM_END
}
 
void
send(action, c)
Bit16u action;
Bit8u c;
{
if (action & BIOS_PRINTF_SCREEN) {
if (c == '\n') wrch('\r');
wrch(c);
}
}
 
void
put_int(action, val, width, neg)
Bit16u action;
short val, width;
bx_bool neg;
{
short nval = val / 10;
if (nval)
put_int(action, nval, width - 1, neg);
else {
while (--width > 0) send(action, ' ');
if (neg) send(action, '-');
}
send(action, val - (nval * 10) + '0');
}
 
void
put_uint(action, val, width, neg)
Bit16u action;
unsigned short val;
short width;
bx_bool neg;
{
unsigned short nval = val / 10;
if (nval)
put_uint(action, nval, width - 1, neg);
else {
while (--width > 0) send(action, ' ');
if (neg) send(action, '-');
}
send(action, val - (nval * 10) + '0');
}
 
void
put_luint(action, val, width, neg)
Bit16u action;
unsigned long val;
short width;
bx_bool neg;
{
unsigned long nval = val / 10;
if (nval)
put_luint(action, nval, width - 1, neg);
else {
while (--width > 0) send(action, ' ');
if (neg) send(action, '-');
}
send(action, val - (nval * 10) + '0');
}
 
void put_str(action, segment, offset)
Bit16u action;
Bit16u segment;
Bit16u offset;
{
Bit8u c;
 
while (c = read_byte(segment, offset)) {
send(action, c);
offset++;
}
}
 
//--------------------------------------------------------------------------
// bios_printf()
// A compact variable argument printf function.
//
// Supports %[format_width][length]format
// where format can be x,X,u,d,s,S,c
// and the optional length modifier is l (ell)
//--------------------------------------------------------------------------
void
bios_printf(action, s)
Bit16u action;
Bit8u *s;
{
Bit8u c, format_char;
bx_bool in_format;
short i;
Bit16u *arg_ptr;
Bit16u arg_seg, arg, nibble, hibyte, shift_count, format_width, hexadd;
 
arg_ptr = &s;
arg_seg = get_SS();
 
in_format = 0;
format_width = 0;
 
if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT)
bios_printf (BIOS_PRINTF_SCREEN, "FATAL: ");
 
while (c = read_byte(get_CS(), s)) {
if ( c == '%' ) {
in_format = 1;
format_width = 0;
}
else if (in_format) {
if ( (c>='0') && (c<='9') ) {
format_width = (format_width * 10) + (c - '0');
}
else {
arg_ptr++; // increment to next arg
arg = read_word(arg_seg, arg_ptr);
if (c == 'x' || c == 'X') {
if (format_width == 0)
format_width = 4;
if (c == 'x')
hexadd = 'a';
else
hexadd = 'A';
for (i=format_width-1; i>=0; i--) {
nibble = (arg >> (4 * i)) & 0x000f;
send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
}
}
else if (c == 'u') {
put_uint(action, arg, format_width, 0);
}
else if (c == 'l') {
s++;
c = read_byte(get_CS(), s); /* is it ld,lx,lu? */
arg_ptr++; /* increment to next arg */
hibyte = read_word(arg_seg, arg_ptr);
if (c == 'd') {
if (hibyte & 0x8000)
put_luint(action, 0L-(((Bit32u) hibyte << 16) | arg), format_width-1, 1);
else
put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
}
else if (c == 'u') {
put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
}
else if (c == 'x' || c == 'X')
{
if (format_width == 0)
format_width = 8;
if (c == 'x')
hexadd = 'a';
else
hexadd = 'A';
for (i=format_width-1; i>=0; i--) {
nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f;
send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
}
}
}
else if (c == 'd') {
if (arg & 0x8000)
put_int(action, -arg, format_width - 1, 1);
else
put_int(action, arg, format_width, 0);
}
else if (c == 's') {
put_str(action, get_CS(), arg);
}
else if (c == 'S') {
hibyte = arg;
arg_ptr++;
arg = read_word(arg_seg, arg_ptr);
put_str(action, hibyte, arg);
}
else if (c == 'c') {
send(action, arg);
}
else
BX_PANIC("bios_printf: unknown format\n");
in_format = 0;
}
}
else {
send(action, c);
}
s ++;
}
 
if (action & BIOS_PRINTF_HALT) {
// freeze in a busy loop.
ASM_START
cli
halt2_loop:
hlt
jmp halt2_loop
ASM_END
}
}
 
static char bios_svn_version_string[] = "$Revision: 1.13 $ $Date: 2009-03-05 00:26:53 $";
 
//--------------------------------------------------------------------------
// print_bios_banner
// displays a the bios version
//--------------------------------------------------------------------------
void
print_bios_banner()
{
printf("Zet ROMBIOS - build: %s\n%s\n\n",
BIOS_BUILD_DATE, bios_svn_version_string);
}
 
//--------------------------------------------------------------------------
// BIOS Boot Specification 1.0.1 compatibility
//
// Very basic support for the BIOS Boot Specification, which allows expansion
// ROMs to register themselves as boot devices, instead of just stealing the
// INT 19h boot vector.
//
// This is a hack: to do it properly requires a proper PnP BIOS and we aren't
// one; we just lie to the option ROMs to make them behave correctly.
// We also don't support letting option ROMs register as bootable disk
// drives (BCVs), only as bootable devices (BEVs).
//
// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm
//--------------------------------------------------------------------------
 
static char drivetypes[][20]={"", "Floppy flash image" };
 
static void
init_boot_vectors()
{
ipl_entry_t e;
Bit16u count = 0;
Bit16u ss = get_SS();
 
/* Clear out the IPL table. */
memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE);
 
/* User selected device not set */
write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF);
 
/* Floppy drive */
e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
count++;
 
/* Remember how many devices we have */
write_word(IPL_SEG, IPL_COUNT_OFFSET, count);
/* Not tried booting anything yet */
write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff);
}
 
static Bit8u
get_boot_vector(i, e)
Bit16u i; ipl_entry_t *e;
{
Bit16u count;
Bit16u ss = get_SS();
/* Get the count of boot devices, and refuse to overrun the array */
count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
if (i >= count) return 0;
/* OK to read this device */
memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
return 1;
}
 
//--------------------------------------------------------------------------
// print_boot_device
// displays the boot device
//--------------------------------------------------------------------------
 
void
print_boot_device(e)
ipl_entry_t *e;
{
Bit16u type;
char description[33];
Bit16u ss = get_SS();
type = e->type;
/* NIC appears as type 0x80 */
if (type == IPL_TYPE_BEV) type = 0x4;
if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");
printf("Booting from %s", drivetypes[type]);
/* print product string if BEV */
if (type == 4 && e->description != 0) {
/* first 32 bytes are significant */
memcpyb(ss, &description, (Bit16u)(e->description >> 16), (Bit16u)(e->description & 0xffff), 32);
/* terminate string */
description[32] = 0;
printf(" [%S]", ss, description);
}
printf("...\n\n");
}
 
//--------------------------------------------------------------------------
// print_boot_failure
// displays the reason why boot failed
//--------------------------------------------------------------------------
void
print_boot_failure(type, reason)
Bit16u type; Bit8u reason;
{
if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n");
 
printf("Boot failed");
if (type < 4) {
/* Report the reason too */
if (reason==0)
printf(": not a bootable disk");
else
printf(": could not read the boot disk");
}
printf("\n\n");
}
 
 
void
int16_function(DI, SI, BP, SP, BX, DX, CX, AX, FLAGS)
Bit16u DI, SI, BP, SP, BX, DX, CX, AX, FLAGS;
{
Bit8u scan_code, ascii_code, shift_flags, led_flags, count;
Bit16u kbd_code, max;
 
shift_flags = read_byte(0x0040, 0x17);
led_flags = read_byte(0x0040, 0x97);
 
switch (GET_AH()) {
case 0x00: /* read keyboard input */
 
if ( !dequeue_key(&scan_code, &ascii_code, 1) ) {
BX_PANIC("KBD: int16h: out of keyboard input\n");
}
if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
else if (ascii_code == 0xE0) ascii_code = 0;
AX = (scan_code << 8) | ascii_code;
break;
 
case 0x01: /* check keyboard status */
if ( !dequeue_key(&scan_code, &ascii_code, 0) ) {
SET_ZF();
return;
}
if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
else if (ascii_code == 0xE0) ascii_code = 0;
AX = (scan_code << 8) | ascii_code;
CLEAR_ZF();
break;
 
case 0x02: /* get shift flag status */
shift_flags = read_byte(0x0040, 0x17);
SET_AL(shift_flags);
break;
 
case 0x05: /* store key-stroke into buffer */
if ( !enqueue_key(GET_CH(), GET_CL()) ) {
SET_AL(1);
}
else {
SET_AL(0);
}
break;
 
case 0x09: /* GET KEYBOARD FUNCTIONALITY */
// bit Bochs Description
// 7 0 reserved
// 6 0 INT 16/AH=20h-22h supported (122-key keyboard support)
// 5 1 INT 16/AH=10h-12h supported (enhanced keyboard support)
// 4 1 INT 16/AH=0Ah supported
// 3 0 INT 16/AX=0306h supported
// 2 0 INT 16/AX=0305h supported
// 1 0 INT 16/AX=0304h supported
// 0 0 INT 16/AX=0300h supported
//
SET_AL(0x30);
break;
 
case 0x10: /* read MF-II keyboard input */
 
if ( !dequeue_key(&scan_code, &ascii_code, 1) ) {
BX_PANIC("KBD: int16h: out of keyboard input\n");
}
if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
AX = (scan_code << 8) | ascii_code;
break;
 
case 0x11: /* check MF-II keyboard status */
if ( !dequeue_key(&scan_code, &ascii_code, 0) ) {
SET_ZF();
return;
}
if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0;
AX = (scan_code << 8) | ascii_code;
CLEAR_ZF();
break;
 
case 0x12: /* get extended keyboard status */
shift_flags = read_byte(0x0040, 0x17);
SET_AL(shift_flags);
shift_flags = read_byte(0x0040, 0x18) & 0x73;
shift_flags |= read_byte(0x0040, 0x96) & 0x0c;
SET_AH(shift_flags);
BX_DEBUG_INT16("int16: func 12 sending %04x\n",AX);
break;
 
case 0x92: /* keyboard capability check called by DOS 5.0+ keyb */
SET_AH(0x80); // function int16 ah=0x10-0x12 supported
break;
 
case 0xA2: /* 122 keys capability check called by DOS 5.0+ keyb */
// don't change AH : function int16 ah=0x20-0x22 NOT supported
break;
 
case 0x6F:
if (GET_AL() == 0x08)
SET_AH(0x02); // unsupported, aka normal keyboard
 
default:
BX_INFO("KBD: unsupported int 16h function %02x\n", GET_AH());
}
}
 
unsigned int
dequeue_key(scan_code, ascii_code, incr)
Bit8u *scan_code;
Bit8u *ascii_code;
unsigned int incr;
{
Bit16u buffer_start, buffer_end, buffer_head, buffer_tail;
Bit16u ss;
Bit8u acode, scode;
 
#if BX_CPU < 2
buffer_start = 0x001E;
buffer_end = 0x003E;
#else
buffer_start = read_word(0x0040, 0x0080);
buffer_end = read_word(0x0040, 0x0082);
#endif
 
buffer_head = read_word(0x0040, 0x001a);
buffer_tail = read_word(0x0040, 0x001c);
 
if (buffer_head != buffer_tail) {
ss = get_SS();
acode = read_byte(0x0040, buffer_head);
scode = read_byte(0x0040, buffer_head+1);
write_byte(ss, ascii_code, acode);
write_byte(ss, scan_code, scode);
 
if (incr) {
buffer_head += 2;
if (buffer_head >= buffer_end)
buffer_head = buffer_start;
write_word(0x0040, 0x001a, buffer_head);
}
return(1);
}
else {
return(0);
}
}
 
void
int09_function(DI, SI, BP, SP, BX, DX, CX, AX)
Bit16u DI, SI, BP, SP, BX, DX, CX, AX;
{
Bit8u scancode, asciicode, shift_flags;
Bit8u mf2_flags, mf2_state;
 
//
// DS has been set to F000 before call
//
 
 
scancode = GET_AL();
 
if (scancode == 0) {
BX_INFO("KBD: int09 handler: AL=0\n");
return;
}
 
 
shift_flags = read_byte(0x0040, 0x17);
mf2_flags = read_byte(0x0040, 0x18);
mf2_state = read_byte(0x0040, 0x96);
asciicode = 0;
 
switch (scancode) {
case 0x3a: /* Caps Lock press */
shift_flags ^= 0x40;
write_byte(0x0040, 0x17, shift_flags);
mf2_flags |= 0x40;
write_byte(0x0040, 0x18, mf2_flags);
break;
case 0xba: /* Caps Lock release */
mf2_flags &= ~0x40;
write_byte(0x0040, 0x18, mf2_flags);
break;
 
case 0x2a: /* L Shift press */
shift_flags |= 0x02;
write_byte(0x0040, 0x17, shift_flags);
break;
case 0xaa: /* L Shift release */
shift_flags &= ~0x02;
write_byte(0x0040, 0x17, shift_flags);
break;
 
case 0x36: /* R Shift press */
shift_flags |= 0x01;
write_byte(0x0040, 0x17, shift_flags);
break;
case 0xb6: /* R Shift release */
shift_flags &= ~0x01;
write_byte(0x0040, 0x17, shift_flags);
break;
 
case 0x1d: /* Ctrl press */
if ((mf2_state & 0x01) == 0) {
shift_flags |= 0x04;
write_byte(0x0040, 0x17, shift_flags);
if (mf2_state & 0x02) {
mf2_state |= 0x04;
write_byte(0x0040, 0x96, mf2_state);
} else {
mf2_flags |= 0x01;
write_byte(0x0040, 0x18, mf2_flags);
}
}
break;
case 0x9d: /* Ctrl release */
if ((mf2_state & 0x01) == 0) {
shift_flags &= ~0x04;
write_byte(0x0040, 0x17, shift_flags);
if (mf2_state & 0x02) {
mf2_state &= ~0x04;
write_byte(0x0040, 0x96, mf2_state);
} else {
mf2_flags &= ~0x01;
write_byte(0x0040, 0x18, mf2_flags);
}
}
break;
 
case 0x38: /* Alt press */
shift_flags |= 0x08;
write_byte(0x0040, 0x17, shift_flags);
if (mf2_state & 0x02) {
mf2_state |= 0x08;
write_byte(0x0040, 0x96, mf2_state);
} else {
mf2_flags |= 0x02;
write_byte(0x0040, 0x18, mf2_flags);
}
break;
case 0xb8: /* Alt release */
shift_flags &= ~0x08;
write_byte(0x0040, 0x17, shift_flags);
if (mf2_state & 0x02) {
mf2_state &= ~0x08;
write_byte(0x0040, 0x96, mf2_state);
} else {
mf2_flags &= ~0x02;
write_byte(0x0040, 0x18, mf2_flags);
}
break;
 
case 0x45: /* Num Lock press */
if ((mf2_state & 0x03) == 0) {
mf2_flags |= 0x20;
write_byte(0x0040, 0x18, mf2_flags);
shift_flags ^= 0x20;
write_byte(0x0040, 0x17, shift_flags);
}
break;
case 0xc5: /* Num Lock release */
if ((mf2_state & 0x03) == 0) {
mf2_flags &= ~0x20;
write_byte(0x0040, 0x18, mf2_flags);
}
break;
 
case 0x46: /* Scroll Lock press */
mf2_flags |= 0x10;
write_byte(0x0040, 0x18, mf2_flags);
shift_flags ^= 0x10;
write_byte(0x0040, 0x17, shift_flags);
break;
 
case 0xc6: /* Scroll Lock release */
mf2_flags &= ~0x10;
write_byte(0x0040, 0x18, mf2_flags);
break;
 
default:
if (scancode & 0x80) {
break; /* toss key releases ... */
}
if (scancode > MAX_SCAN_CODE) {
BX_INFO("KBD: int09h_handler(): unknown scancode read: 0x%02x!\n", scancode);
return;
}
if (shift_flags & 0x08) { /* ALT */
asciicode = scan_to_scanascii[scancode].alt;
scancode = scan_to_scanascii[scancode].alt >> 8;
} else if (shift_flags & 0x04) { /* CONTROL */
asciicode = scan_to_scanascii[scancode].control;
scancode = scan_to_scanascii[scancode].control >> 8;
} else if (((mf2_state & 0x02) > 0) && ((scancode >= 0x47) && (scancode <= 0x53))) {
/* extended keys handling */
asciicode = 0xe0;
scancode = scan_to_scanascii[scancode].normal >> 8;
} else if (shift_flags & 0x03) { /* LSHIFT + RSHIFT */
/* check if lock state should be ignored
* because a SHIFT key are pressed */
 
if (shift_flags & scan_to_scanascii[scancode].lock_flags) {
asciicode = scan_to_scanascii[scancode].normal;
scancode = scan_to_scanascii[scancode].normal >> 8;
} else {
asciicode = scan_to_scanascii[scancode].shift;
scancode = scan_to_scanascii[scancode].shift >> 8;
}
} else {
/* check if lock is on */
if (shift_flags & scan_to_scanascii[scancode].lock_flags) {
asciicode = scan_to_scanascii[scancode].shift;
scancode = scan_to_scanascii[scancode].shift >> 8;
} else {
asciicode = scan_to_scanascii[scancode].normal;
scancode = scan_to_scanascii[scancode].normal >> 8;
}
}
if (scancode==0 && asciicode==0) {
BX_INFO("KBD: int09h_handler(): scancode & asciicode are zero?\n");
}
enqueue_key(scancode, asciicode);
break;
}
if ((scancode & 0x7f) != 0x1d) {
mf2_state &= ~0x01;
}
mf2_state &= ~0x02;
write_byte(0x0040, 0x96, mf2_state);
}
 
unsigned int
enqueue_key(scan_code, ascii_code)
Bit8u scan_code, ascii_code;
{
Bit16u buffer_start, buffer_end, buffer_head, buffer_tail, temp_tail;
 
#if BX_CPU < 2
buffer_start = 0x001E;
buffer_end = 0x003E;
#else
buffer_start = read_word(0x0040, 0x0080);
buffer_end = read_word(0x0040, 0x0082);
#endif
 
buffer_head = read_word(0x0040, 0x001A);
buffer_tail = read_word(0x0040, 0x001C);
 
temp_tail = buffer_tail;
buffer_tail += 2;
if (buffer_tail >= buffer_end)
buffer_tail = buffer_start;
 
if (buffer_tail == buffer_head) {
return(0);
}
 
write_byte(0x0040, temp_tail, ascii_code);
write_byte(0x0040, temp_tail+1, scan_code);
write_word(0x0040, 0x001C, buffer_tail);
return(1);
}
 
 
#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
 
void
int13_harddisk(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
{
write_byte(0x0040, 0x008e, 0); // clear completion flag
 
switch (GET_AH()) {
case 0x08:
SET_AL(0);
SET_CH(0);
SET_CL(0);
SET_DH(0);
SET_DL(0); /* FIXME returns 0, 1, or n hard drives */
 
// FIXME should set ES & DI
 
goto int13_fail;
break;
 
default:
BX_INFO("int13_harddisk: function %02xh unsupported, returns fail\n", GET_AH());
goto int13_fail;
break;
}
 
int13_fail:
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
int13_fail_noah:
SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
SET_CF(); // error occurred
return;
 
int13_success:
SET_AH(0x00); // no error
int13_success_noah:
SET_DISK_RET_STATUS(0x00);
CLEAR_CF(); // no error
return;
}
 
void
transf_sect(seg, offset)
Bit16u seg;
Bit16u offset;
{
ASM_START
push bp
mov bp, sp
 
push ax
push bx
push cx
push dx
push di
push ds
 
mov ax, 4[bp] ; segment
mov ds, ax
mov bx, 6[bp] ; offset
mov dx, #0xe000
mov cx, #256
xor di, di
 
one_sect:
in ax, dx ; read word from flash
mov [bx+di], ax ; write word
inc dx
inc dx
inc di
inc di
loop one_sect
 
pop ds
pop di
pop dx
pop cx
pop bx
pop ax
 
pop bp
ASM_END
}
 
void
int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
{
Bit8u drive, num_sectors, track, sector, head, status;
Bit16u base_address, base_count, base_es;
Bit8u page, mode_register, val8, dor;
Bit8u return_status[7];
Bit8u drive_type, num_floppies, ah;
Bit16u es, last_addr;
Bit16u log_sector, tmp, i, j;
 
ah = GET_AH();
 
switch ( ah ) {
case 0x00: // diskette controller reset
SET_AH(0);
set_diskette_ret_status(0);
CLEAR_CF(); // successful
set_diskette_current_cyl(drive, 0); // current cylinder
return;
 
case 0x02: // Read Diskette Sectors
num_sectors = GET_AL();
track = GET_CH();
sector = GET_CL();
head = GET_DH();
drive = GET_ELDL();
 
if ((drive > 1) || (head > 1) || (sector == 0) ||
(num_sectors == 0) || (num_sectors > 72)) {
BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
SET_AH(1);
set_diskette_ret_status(1);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
return;
}
 
page = (ES >> 12); // upper 4 bits
base_es = (ES << 4); // lower 16bits contributed by ES
base_address = base_es + BX; // lower 16 bits of address
// contributed by ES:BX
if ( base_address < base_es ) {
// in case of carry, adjust page by 1
page++;
}
base_count = (num_sectors * 512) - 1;
 
// check for 64K boundary overrun
last_addr = base_address + base_count;
if (last_addr < base_address) {
SET_AH(0x09);
set_diskette_ret_status(0x09);
SET_AL(0); // no sectors read
SET_CF(); // error occurred
return;
}
 
log_sector = track * 36 + head * 18 + sector - 1;
last_addr = page << 12;
 
// Configure the sector address
for (j=0; j<num_sectors; j++)
{
outw(0xe000, log_sector+j);
base_count = base_address + (j << 9);
transf_sect (last_addr, base_count);
}
 
// ??? should track be new val from return_status[3] ?
set_diskette_current_cyl(drive, track);
// AL = number of sectors read (same value as passed)
SET_AH(0x00); // success
CLEAR_CF(); // success
return;
default:
BX_INFO("int13_diskette: unsupported AH=%02x\n", GET_AH());
 
// if ( (ah==0x20) || ((ah>=0x41) && (ah<=0x49)) || (ah==0x4e) ) {
SET_AH(0x01); // ???
set_diskette_ret_status(1);
SET_CF();
return;
// }
}
}
 
void
set_diskette_ret_status(value)
Bit8u value;
{
write_byte(0x0040, 0x0041, value);
}
 
void
set_diskette_current_cyl(drive, cyl)
Bit8u drive;
Bit8u cyl;
{
/* TEMP HACK: FOR MSDOS */
if (drive > 1)
drive = 1;
/* BX_PANIC("set_diskette_current_cyl(): drive > 1\n"); */
write_byte(0x0040, 0x0094+drive, cyl);
}
 
void
int19_function(seq_nr)
Bit16u seq_nr;
{
Bit16u ebda_seg=read_word(0x0040,0x000E);
Bit16u bootdev;
Bit8u bootdrv;
Bit8u bootchk;
Bit16u bootseg;
Bit16u bootip;
Bit16u status;
Bit16u bootfirst;
 
ipl_entry_t e;
 
// Here we assume that BX_ELTORITO_BOOT is defined, so
// CMOS regs 0x3D and 0x38 contain the boot sequence:
// CMOS reg 0x3D & 0x0f : 1st boot device
// CMOS reg 0x3D & 0xf0 : 2nd boot device
// CMOS reg 0x38 & 0xf0 : 3rd boot device
// boot device codes:
// 0x00 : not defined
// 0x01 : first floppy
// 0x02 : first harddrive
// 0x03 : first cdrom
// 0x04 - 0x0f : PnP expansion ROMs (e.g. Etherboot)
// else : boot failure
 
// Get the boot sequence
/*
* Zet: we don't have a CMOS device
*
bootdev = inb_cmos(0x3d);
bootdev |= ((inb_cmos(0x38) & 0xf0) << 4);
bootdev >>= 4 * seq_nr;
bootdev &= 0xf;
*/
bootdev = 0x1;
 
/* Read user selected device */
bootfirst = read_word(IPL_SEG, IPL_BOOTFIRST_OFFSET);
if (bootfirst != 0xFFFF) {
bootdev = bootfirst;
/* User selected device not set */
write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF);
/* Reset boot sequence */
write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xFFFF);
} else if (bootdev == 0) BX_PANIC("No bootable device.\n");
 
/* Translate from CMOS runes to an IPL table offset by subtracting 1 */
bootdev -= 1;
 
/* Read the boot device from the IPL table */
if (get_boot_vector(bootdev, &e) == 0) {
BX_INFO("Invalid boot device (0x%x)\n", bootdev);
return;
}
 
/* Do the loading, and set up vector as a far pointer to the boot
* address, and bootdrv as the boot drive */
print_boot_device(&e);
 
switch(e.type) {
case IPL_TYPE_FLOPPY: /* FDD */
case IPL_TYPE_HARDDISK: /* HDD */
 
bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
bootseg = 0x07c0;
status = 0;
 
ASM_START
push bp
mov bp, sp
push ax
push bx
push cx
push dx
 
mov dl, _int19_function.bootdrv + 2[bp]
mov ax, _int19_function.bootseg + 2[bp]
mov es, ax ;; segment
xor bx, bx ;; offset
mov ah, #0x02 ;; function 2, read diskette sector
mov al, #0x01 ;; read 1 sector
mov ch, #0x00 ;; track 0
mov cl, #0x01 ;; sector 1
mov dh, #0x00 ;; head 0
int #0x13 ;; read sector
jnc int19_load_done
mov ax, #0x0001
mov _int19_function.status + 2[bp], ax
 
int19_load_done:
pop dx
pop cx
pop bx
pop ax
pop bp
ASM_END
 
if (status != 0) {
print_boot_failure(e.type, 1);
return;
}
 
/* Canonicalize bootseg:bootip */
bootip = (bootseg & 0x0fff) << 4;
bootseg &= 0xf000;
break;
 
default: return;
}
 
/* Debugging info */
BX_INFO("Booting from %x:%x\n", bootseg, bootip);
 
/* Jump to the boot vector */
ASM_START
mov bp, sp
;; Build an iret stack frame that will take us to the boot vector.
;; iret pops ip, then cs, then flags, so push them in the opposite order.
pushf
mov ax, _int19_function.bootseg + 0[bp]
push ax
mov ax, _int19_function.bootip + 0[bp]
push ax
;; Set the magic number in ax and the boot drive in dl.
mov ax, #0xaa55
mov dl, _int19_function.bootdrv + 0[bp]
;; Zero some of the other registers.
xor bx, bx
mov ds, bx
mov es, bx
mov bp, bx
;; Go!
iret
ASM_END
}
 
void
int1a_function(regs, ds, iret_addr)
pusha_regs_t regs; // regs pushed from PUSHA instruction
Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call
{
Bit8u val8;
 
ASM_START
sti
ASM_END
 
switch (regs.u.r8.ah) {
case 0: // get current clock count
ASM_START
cli
ASM_END
regs.u.r16.cx = BiosData->ticks_high;
regs.u.r16.dx = BiosData->ticks_low;
regs.u.r8.al = BiosData->midnight_flag;
BiosData->midnight_flag = 0; // reset flag
ASM_START
sti
ASM_END
// AH already 0
ClearCF(iret_addr.flags); // OK
break;
 
default:
SetCF(iret_addr.flags); // Unsupported
}
}
 
ASM_START
;----------------------
;- INT13h (relocated) -
;----------------------
;
; int13_relocated is a little bit messed up since I played with it
; I have to rewrite it:
; - call a function that detect which function to call
; - make all called C function get the same parameters list
;
int13_relocated:
push ax
push cx
push dx
push bx
 
int13_legacy:
 
push dx ;; push eltorito value of dx instead of sp
 
push bp
push si
push di
 
push es
push ds
push ss
pop ds
 
;; now the 16-bit registers can be restored with:
;; pop ds; pop es; popa; iret
;; arguments passed to functions should be
;; DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS
 
test dl, #0x80
jnz int13_notfloppy
 
mov ax, #int13_out
push ax
jmp _int13_diskette_function
 
int13_notfloppy:
 
int13_disk:
;; int13_harddisk modifies high word of EAX
; shr eax, #16
; push ax
call _int13_harddisk
; pop ax
; shl eax, #16
 
int13_out:
pop ds
pop es
; popa ; we do this instead:
pop di
pop si
pop bp
add sp, #2
pop bx
pop dx
pop cx
pop ax
 
iret
 
;----------
;- INT18h -
;----------
int18_handler: ;; Boot Failure recovery: try the next device.
 
;; Reset SP and SS
mov ax, #0xfffe
mov sp, ax
xor ax, ax
mov ss, ax
 
;; Get the boot sequence number out of the IPL memory
mov bx, #IPL_SEG
mov ds, bx ;; Set segment
mov bx, IPL_SEQUENCE_OFFSET ;; BX is now the sequence number
inc bx ;; ++
mov IPL_SEQUENCE_OFFSET, bx ;; Write it back
mov ds, ax ;; and reset the segment to zero.
 
;; Carry on in the INT 19h handler, using the new sequence number
push bx
 
jmp int19_next_boot
 
;----------
;- INT19h -
;----------
int19_relocated: ;; Boot function, relocated
 
;; int19 was beginning to be really complex, so now it
;; just calls a C function that does the work
 
push bp
mov bp, sp
 
;; Reset SS and SP
mov ax, #0xfffe
mov sp, ax
xor ax, ax
mov ss, ax
 
;; Start from the first boot device (0, in AX)
mov bx, #IPL_SEG
mov ds, bx ;; Set segment to write to the IPL memory
mov IPL_SEQUENCE_OFFSET, ax ;; Save the sequence number
mov ds, ax ;; and reset the segment.
 
push ax
 
int19_next_boot:
 
;; Call the C code for the next boot device
call _int19_function
 
;; Boot failed: invoke the boot recovery function
int #0x18
 
;----------
;- INT1Ch -
;----------
int1c_handler: ;; User Timer Tick
iret
 
 
;--------------------
;- POST: EBDA segment
;--------------------
; relocated here because the primary POST area isnt big enough.
ebda_post:
xor ax, ax ; mov EBDA seg into 40E
mov ds, ax
mov word ptr [0x40E], #EBDA_SEG
ret;;
 
rom_checksum:
push ax
push bx
push cx
xor ax, ax
xor bx, bx
xor cx, cx
mov ch, [2]
shl cx, #1
checksum_loop:
add al, [bx]
inc bx
loop checksum_loop
and al, #0xff
pop cx
pop bx
pop ax
ret
 
 
;; We need a copy of this string, but we are not actually a PnP BIOS,
;; so make sure it is *not* aligned, so OSes will not see it if they scan.
.align 16
db 0
pnp_string:
.ascii "$PnP"
 
 
rom_scan:
;; Scan for existence of valid expansion ROMS.
;; Video ROM: from 0xC0000..0xC7FFF in 2k increments
;; General ROM: from 0xC8000..0xDFFFF in 2k increments
;; System ROM: only 0xE0000
;;
;; Header:
;; Offset Value
;; 0 0x55
;; 1 0xAA
;; 2 ROM length in 512-byte blocks
;; 3 ROM initialization entry point (FAR CALL)
 
rom_scan_loop:
push ax ;; Save AX
mov ds, cx
mov ax, #0x0004 ;; start with increment of 4 (512-byte) blocks = 2k
cmp [0], #0xAA55 ;; look for signature
jne rom_scan_increment
call rom_checksum
jnz rom_scan_increment
mov al, [2] ;; change increment to ROM length in 512-byte blocks
 
;; We want our increment in 512-byte quantities, rounded to
;; the nearest 2k quantity, since we only scan at 2k intervals.
test al, #0x03
jz block_count_rounded
and al, #0xfc ;; needs rounding up
add al, #0x04
block_count_rounded:
 
xor bx, bx ;; Restore DS back to 0000:
mov ds, bx
push ax ;; Save AX
push di ;; Save DI
;; Push addr of ROM entry point
push cx ;; Push seg
;; push #0x0003 ;; Push offset - not an 8086 valid operand
mov ax, #0x0003
push ax
 
;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
;; That should stop it grabbing INT 19h; we will use its BEV instead.
mov ax, #0xf000
mov es, ax
lea di, pnp_string
 
mov bp, sp ;; Call ROM init routine using seg:off on stack
db 0xff ;; call_far ss:[bp+0]
db 0x5e
db 0
cli ;; In case expansion ROM BIOS turns IF on
add sp, #2 ;; Pop offset value
pop cx ;; Pop seg value (restore CX)
 
;; Look at the ROM's PnP Expansion header. Properly, we're supposed
;; to init all the ROMs and then go back and build an IPL table of
;; all the bootable devices, but we can get away with one pass.
mov ds, cx ;; ROM base
mov bx, 0x001a ;; 0x1A is the offset into ROM header that contains...
mov ax, [bx] ;; the offset of PnP expansion header, where...
cmp ax, #0x5024 ;; we look for signature "$PnP"
jne no_bev
mov ax, 2[bx]
cmp ax, #0x506e
jne no_bev
mov ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
cmp ax, #0x0000 ;; the Bootstrap Entry Vector, or zero if there is none.
je no_bev
 
;; Found a device that thinks it can boot the system. Record its BEV and product name string.
mov di, 0x10[bx] ;; Pointer to the product name string or zero if none
mov bx, #IPL_SEG ;; Go to the segment where the IPL table lives
mov ds, bx
mov bx, IPL_COUNT_OFFSET ;; Read the number of entries so far
cmp bx, #IPL_TABLE_ENTRIES
je no_bev ;; Get out if the table is full
push cx
mov cx, #0x4 ;; Zet: Needed to be compatible with 8086
shl bx, cl ;; Turn count into offset (entries are 16 bytes)
pop cx
mov 0[bx], #IPL_TYPE_BEV ;; This entry is a BEV device
mov 6[bx], cx ;; Build a far pointer from the segment...
mov 4[bx], ax ;; and the offset
cmp di, #0x0000
je no_prod_str
mov 0xA[bx], cx ;; Build a far pointer from the segment...
mov 8[bx], di ;; and the offset
no_prod_str:
push cx
mov cx, #0x4
shr bx, cl ;; Turn the offset back into a count
pop cx
inc bx ;; We have one more entry now
mov IPL_COUNT_OFFSET, bx ;; Remember that.
 
no_bev:
pop di ;; Restore DI
pop ax ;; Restore AX
rom_scan_increment:
push cx
mov cx, #5
shl ax, cl ;; convert 512-bytes blocks to 16-byte increments
;; because the segment selector is shifted left 4 bits.
pop cx
add cx, ax
pop ax ;; Restore AX
cmp cx, ax
jbe rom_scan_loop
 
xor ax, ax ;; Restore DS back to 0000:
mov ds, ax
ret
 
;; for 'C' strings and other data, insert them here with
;; a the following hack:
;; DATA_SEG_DEFS_HERE
 
 
;; the following area can be used to write dynamically generated tables
.align 16
bios_table_area_start:
dd 0xaafb4442
dd bios_table_area_end - bios_table_area_start - 8;
 
;--------
;- POST -
;--------
.org 0xe05b ; POST Entry Point
post:
xor ax, ax
 
normal_post:
; case 0: normal startup
 
cli
mov ax, #0xfffe
mov sp, ax
xor ax, ax
mov ds, ax
mov ss, ax
 
;; zero out BIOS data area (40:00..40:ff)
mov es, ax
mov cx, #0x0080 ;; 128 words
mov di, #0x0400
cld
rep
stosw
 
;; set all interrupts to default handler
xor bx, bx ;; offset index
mov cx, #0x0100 ;; counter (256 interrupts)
mov ax, #dummy_iret_handler
mov dx, #0xF000
 
post_default_ints:
mov [bx], ax
add bx, #2
mov [bx], dx
add bx, #2
loop post_default_ints
 
;; set vector 0x79 to zero
;; this is used by 'gardian angel' protection system
SET_INT_VECTOR(0x79, #0, #0)
 
;; base memory in K 40:13 (word)
mov ax, #BASE_MEM_IN_K
mov 0x0413, ax
 
 
;; Manufacturing Test 40:12
;; zerod out above
 
;; Warm Boot Flag 0040:0072
;; value of 1234h = skip memory checks
;; zerod out above
 
;; Bootstrap failure vector
SET_INT_VECTOR(0x18, #0xF000, #int18_handler)
 
;; Bootstrap Loader vector
SET_INT_VECTOR(0x19, #0xF000, #int19_handler)
 
;; User Timer Tick vector
SET_INT_VECTOR(0x1c, #0xF000, #int1c_handler)
 
;; Memory Size Check vector
SET_INT_VECTOR(0x12, #0xF000, #int12_handler)
 
;; Equipment Configuration Check vector
SET_INT_VECTOR(0x11, #0xF000, #int11_handler)
 
;; EBDA setup
call ebda_post
 
;; Keyboard
SET_INT_VECTOR(0x09, #0xF000, #int09_handler)
SET_INT_VECTOR(0x16, #0xF000, #int16_handler)
 
xor ax, ax
mov ds, ax
mov 0x0417, al /* keyboard shift flags, set 1 */
mov 0x0418, al /* keyboard shift flags, set 2 */
mov 0x0419, al /* keyboard alt-numpad work area */
mov 0x0471, al /* keyboard ctrl-break flag */
mov 0x0497, al /* keyboard status flags 4 */
mov al, #0x10
mov 0x0496, al /* keyboard status flags 3 */
 
/* keyboard head of buffer pointer */
mov bx, #0x001E
mov 0x041A, bx
 
/* keyboard end of buffer pointer */
mov 0x041C, bx
 
/* keyboard pointer to start of buffer */
mov bx, #0x001E
mov 0x0480, bx
 
/* keyboard pointer to end of buffer */
mov bx, #0x003E
mov 0x0482, bx
 
;; CMOS RTC
SET_INT_VECTOR(0x1A, #0xF000, #int1a_handler)
 
;; Video setup
SET_INT_VECTOR(0x10, #0xF000, #int10_handler)
 
mov cx, #0xc000 ;; init vga bios
mov ax, #0xc780
 
call rom_scan
 
call _print_bios_banner
 
;; Floppy setup
SET_INT_VECTOR(0x13, #0xF000, #int13_handler)
 
call _init_boot_vectors
 
mov cx, #0xc800 ;; init option roms
mov ax, #0xe000
call rom_scan
 
sti ;; enable interrupts
int #0x19
 
;-------------------------------------------
;- INT 13h Fixed Disk Services Entry Point -
;-------------------------------------------
.org 0xe3fe ; INT 13h Fixed Disk Services Entry Point
int13_handler:
//JMPL(int13_relocated)
jmp int13_relocated
 
.org 0xe401 ; Fixed Disk Parameter Table
 
;----------
;- INT19h -
;----------
.org 0xe6f2 ; INT 19h Boot Load Service Entry Point
int19_handler:
 
jmp int19_relocated
 
 
;----------------------------------------
;- INT 16h Keyboard Service Entry Point -
;----------------------------------------
.org 0xe82e
int16_handler:
 
sti
push ds
pushf
;pusha ; we do this instead:
push ax
push cx
push dx
push bx
push sp
mov bx, sp
sseg
add [bx], #10
sseg
mov bx, [bx+2]
push bp
push si
push di
 
cmp ah, #0x00
je int16_F00
cmp ah, #0x10
je int16_F00
 
mov bx, #0xf000
mov ds, bx
call _int16_function
; popa ; we do this instead:
pop di
pop si
pop bp
add sp, #2
pop bx
pop dx
pop cx
pop ax
popf
pop ds
jz int16_zero_set
 
int16_zero_clear:
push bp
mov bp, sp
//SEG SS
and BYTE [bp + 0x06], #0xbf
pop bp
iret
 
int16_zero_set:
push bp
mov bp, sp
//SEG SS
or BYTE [bp + 0x06], #0x40
pop bp
iret
 
int16_F00:
mov bx, #0x0040
mov ds, bx
 
int16_wait_for_key:
cli
mov bx, 0x001a
cmp bx, 0x001c
jne int16_key_found
sti
nop
#if 0
/* no key yet, call int 15h, function AX=9002 */
0x50, /* push AX */
0xb8, 0x02, 0x90, /* mov AX, #0x9002 */
0xcd, 0x15, /* int 15h */
0x58, /* pop AX */
0xeb, 0xea, /* jmp WAIT_FOR_KEY */
#endif
jmp int16_wait_for_key
 
int16_key_found:
mov bx, #0xf000
mov ds, bx
call _int16_function
; popa ; we do this instead:
pop di
pop si
pop bp
add sp, #2
pop bx
pop dx
pop cx
pop ax
popf
pop ds
#if 0
/* notify int16 complete w/ int 15h, function AX=9102 */
0x50, /* push AX */
0xb8, 0x02, 0x91, /* mov AX, #0x9102 */
0xcd, 0x15, /* int 15h */
0x58, /* pop AX */
#endif
iret
 
 
 
;-------------------------------------------------
;- INT09h : Keyboard Hardware Service Entry Point -
;-------------------------------------------------
.org 0xe987
int09_handler:
cli
push ax
in al, #0x60 ;;read key from keyboard controller
sti
 
push ds
;pusha ; we do this instead:
 
push ax
push cx
push dx
push bx
push sp
mov bx, sp
sseg
add [bx], #10
sseg
mov bx, [bx+2]
push bp
push si
push di
 
;; check for extended key
cmp al, #0xe0
jne int09_check_pause
xor ax, ax
mov ds, ax
mov al, BYTE [0x496] ;; mf2_state |= 0x02
or al, #0x02
mov BYTE [0x496], al
jmp int09_done
 
int09_check_pause: ;; check for pause key
cmp al, #0xe1
jne int09_process_key
xor ax, ax
mov ds, ax
mov al, BYTE [0x496] ;; mf2_state |= 0x01
or al, #0x01
mov BYTE [0x496], al
jmp int09_done
 
int09_process_key:
mov bx, #0xf000
mov ds, bx
call _int09_function
int09_done:
; popa ; we do this instead:
pop di
pop si
pop bp
add sp, #2
pop bx
pop dx
pop cx
pop ax
 
pop ds
 
cli
pop ax
iret
 
 
;----------
;- INT10h -
;----------
.org 0xf065 ; INT 10h Video Support Service Entry Point
int10_handler:
;; dont do anything, since the VGA BIOS handles int10h requests
iret
 
.org 0xf0a4 ; MDA/CGA Video Parameter Table (INT 1Dh)
 
;----------
;- INT12h -
;----------
.org 0xf841 ; INT 12h Memory Size Service Entry Point
; ??? different for Pentium (machine check)?
int12_handler:
push ds
mov ax, #0x0040
mov ds, ax
mov ax, 0x0013
pop ds
iret
 
;----------
;- INT11h -
;----------
.org 0xf84d ; INT 11h Equipment List Service Entry Point
int11_handler:
push ds
mov ax, #0x0040
mov ds, ax
mov ax, 0x0010
pop ds
iret
 
;----------
;- INT1Ah -
;----------
.org 0xfe6e ; INT 1Ah Time-of-day Service Entry Point
int1a_handler:
push ds
;pusha ; we do this instead:
push ax
push cx
push dx
push bx
push sp
mov bx, sp
sseg
add [bx], #10
sseg
mov bx, [bx+2]
push bp
push si
push di
 
xor ax, ax
mov ds, ax
int1a_callfunction:
call _int1a_function
; popa ; we do this instead:
pop di
pop si
pop bp
add sp, #2
pop bx
pop dx
pop cx
pop ax
 
pop ds
iret
 
;------------------------------------------------
;- IRET Instruction for Dummy Interrupt Handler -
;------------------------------------------------
.org 0xff53 ; IRET Instruction for Dummy Interrupt Handler
dummy_iret_handler:
iret
 
.org 0xfff0 ; Power-up Entry Point
; hlt
jmp 0xf000:post
 
.org 0xfff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
.ascii BIOS_BUILD_DATE
 
.org 0xfffe ; System Model ID
db SYS_MODEL_ID
db 0x00 ; filler
ASM_END
 
ASM_START
.org 0xcc00
bios_table_area_end:
// bcc-generated data will be placed here
ASM_END
/biossums.c
0,0 → 1,504
/*
* $Id: biossums.c,v 1.7 2009-02-06 03:48:27 zeus Exp $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
 
/* biossums.c --- written by Eike W. for the Bochs BIOS */
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
typedef unsigned char byte;
 
void check( int value, char* message );
 
#define LEN_BIOS_DATA 0x10000
#define MAX_OFFSET (LEN_BIOS_DATA - 1)
 
 
#define BIOS_OFFSET 0xFFFF
 
long chksum_bios_get_offset( byte* data, long offset );
byte chksum_bios_calc_value( byte* data, long offset );
byte chksum_bios_get_value( byte* data, long offset );
void chksum_bios_set_value( byte* data, long offset, byte value );
 
 
#define _32__LEN 9
#define _32__CHKSUM 10
 
#define _32__MINHDR 16
 
long chksum__32__get_offset( byte* data, long offset );
byte chksum__32__calc_value( byte* data, long offset );
byte chksum__32__get_value( byte* data, long offset );
void chksum__32__set_value( byte* data, long offset, byte value );
 
 
#define _MP__LEN 8
#define _MP__CHKSUM 10
 
#define _MP__MINHDR 16
 
long chksum__mp__get_offset( byte* data, long offset );
byte chksum__mp__calc_value( byte* data, long offset );
byte chksum__mp__get_value( byte* data, long offset );
void chksum__mp__set_value( byte* data, long offset, byte value );
 
 
#define PCMP_BASELEN 4
#define PCMP_CHKSUM 7
#define PCMP_EXT_LEN 40
#define PCMP_EXT_CHKSUM 42
 
#define PCMP_MINHDR 42
 
long chksum_pcmp_get_offset( byte* data, long offset );
byte chksum_pcmp_calc_value( byte* data, long offset );
byte chksum_pcmp_get_value( byte* data, long offset );
void chksum_pcmp_set_value( byte* data, long offset, byte value );
 
 
#define _PIR_LEN 6
#define _PIR_CHKSUM 31
 
#define _PIR_MINHDR 32
 
long chksum__pir_get_offset( byte *data, long offset );
byte chksum__pir_calc_value( byte* data, long offset );
byte chksum__pir_get_value( byte* data, long offset );
void chksum__pir_set_value( byte* data, long offset, byte value );
 
 
byte bios_data[LEN_BIOS_DATA];
long bios_len;
 
 
int main(int argc, char* argv[]) {
 
FILE* stream;
long offset, tmp_offset;
byte cur_val = 0, new_val = 0;
int arg = 1, hits, pad = 0;
 
 
if ((argc == 3) && (!strcmp(argv[1], "-pad"))) {
pad = 1;
arg = 2;
} else if (argc != 2) {
printf("Error. Need a file-name as an argument.\n");
exit(EXIT_FAILURE);
}
memset(bios_data, 0xff, LEN_BIOS_DATA);
 
if ((stream = fopen(argv[arg], "rb")) == NULL) {
printf("Error opening %s for reading.\n", argv[arg]);
exit(EXIT_FAILURE);
}
bios_len = fread(bios_data, 1, LEN_BIOS_DATA, stream);
if ((bios_len < LEN_BIOS_DATA) && (pad == 0)) {
printf("Error reading 64KBytes from %s.\n", argv[arg]);
fclose(stream);
exit(EXIT_FAILURE);
}
fclose(stream);
if (pad == 1) goto write_bios;
 
hits = 0;
offset = 0L;
while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) {
offset = tmp_offset;
cur_val = chksum__32__get_value( bios_data, offset );
new_val = chksum__32__calc_value( bios_data, offset );
printf( "\n\nPCI-Bios header at: 0x%4lX\n", offset );
printf( "Current checksum: 0x%02X\n", cur_val );
printf( "Calculated checksum: 0x%02X ", new_val );
hits++;
}
if( hits == 1 && cur_val != new_val ) {
printf( "Setting checksum." );
chksum__32__set_value( bios_data, offset, new_val );
}
if( hits >= 2 ) {
printf( "Multiple PCI headers! No checksum set." );
}
if( hits ) {
printf( "\n" );
}
 
 
hits = 0;
offset = 0L;
while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) {
offset = tmp_offset;
cur_val = chksum__mp__get_value( bios_data, offset );
new_val = chksum__mp__calc_value( bios_data, offset );
printf( "\n\nMP header at: 0x%4lX\n", offset );
printf( "Current checksum: 0x%02X\n", cur_val );
printf( "Calculated checksum: 0x%02X ", new_val );
hits++;
}
if( hits == 1 && cur_val != new_val ) {
printf( "Setting checksum." );
chksum__mp__set_value( bios_data, offset, new_val );
}
if( hits >= 2 ) {
printf( "Warning! Multiple MP headers. No checksum set." );
}
if( hits ) {
printf( "\n" );
}
 
 
hits = 0;
offset = 0L;
while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) {
offset = tmp_offset;
cur_val = chksum_pcmp_get_value( bios_data, offset );
new_val = chksum_pcmp_calc_value( bios_data, offset );
printf( "\n\nPCMP header at: 0x%4lX\n", offset );
printf( "Current checksum: 0x%02X\n", cur_val );
printf( "Calculated checksum: 0x%02X ", new_val );
hits++;
}
if( hits == 1 && cur_val != new_val ) {
printf( "Setting checksum." );
chksum_pcmp_set_value( bios_data, offset, new_val );
}
if( hits >= 2 ) {
printf( "Warning! Multiple PCMP headers. No checksum set." );
}
if( hits ) {
printf( "\n" );
}
 
 
hits = 0;
offset = 0L;
while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) {
offset = tmp_offset;
cur_val = chksum__pir_get_value( bios_data, offset );
new_val = chksum__pir_calc_value( bios_data, offset );
printf( "\n\n$PIR header at: 0x%4lX\n", offset );
printf( "Current checksum: 0x%02X\n", cur_val );
printf( "Calculated checksum: 0x%02X\n ", new_val );
hits++;
}
if( hits == 1 && cur_val != new_val ) {
printf( "Setting checksum." );
chksum__pir_set_value( bios_data, offset, new_val );
}
if( hits >= 2 ) {
printf( "Warning! Multiple $PIR headers. No checksum set." );
}
if( hits ) {
printf( "\n" );
}
 
 
offset = 0L;
offset = chksum_bios_get_offset( bios_data, offset );
cur_val = chksum_bios_get_value( bios_data, offset );
new_val = chksum_bios_calc_value( bios_data, offset );
printf( "\n\nBios checksum at: 0x%4lX\n", offset );
printf( "Current checksum: 0x%02X\n", cur_val );
printf( "Calculated checksum: 0x%02X ", new_val );
if( cur_val != new_val ) {
printf( "Setting checksum." );
chksum_bios_set_value( bios_data, offset, new_val );
}
printf( "\n" );
 
write_bios:
if ((stream = fopen(argv[arg], "wb")) == NULL) {
printf("Error opening %s for writing.\n", argv[arg]);
exit(EXIT_FAILURE);
}
if (fwrite(bios_data, 1, LEN_BIOS_DATA, stream) < LEN_BIOS_DATA) {
printf("Error writing 64KBytes to %s.\n", argv[arg]);
fclose(stream);
exit(EXIT_FAILURE);
}
fclose(stream);
 
return(EXIT_SUCCESS);
}
 
 
void check(int okay, char* message) {
 
if (!okay) {
printf("\n\nError. %s.\n", message);
exit(EXIT_FAILURE);
}
}
 
 
long chksum_bios_get_offset( byte* data, long offset ) {
 
return( BIOS_OFFSET );
}
 
 
byte chksum_bios_calc_value( byte* data, long offset ) {
 
int i;
byte sum;
 
sum = 0;
for( i = 0; i < MAX_OFFSET; i++ ) {
sum = sum + *( data + i );
}
sum = -sum; /* iso ensures -s + s == 0 on unsigned types */
return( sum );
}
 
 
byte chksum_bios_get_value( byte* data, long offset ) {
 
return( *( data + BIOS_OFFSET ) );
}
 
 
void chksum_bios_set_value( byte* data, long offset, byte value ) {
 
*( data + BIOS_OFFSET ) = value;
}
 
 
byte chksum__32__calc_value( byte* data, long offset ) {
 
int i;
int len;
byte sum;
 
check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" );
len = *( data + offset + _32__LEN ) << 4;
check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" );
sum = 0;
for( i = 0; i < len; i++ ) {
if( i != _32__CHKSUM ) {
sum = sum + *( data + offset + i );
}
}
sum = -sum;
return( sum );
}
 
 
long chksum__32__get_offset( byte* data, long offset ) {
 
long result = -1L;
 
offset = offset + 0x0F;
offset = offset & ~( 0x0F );
while( offset + 16 < MAX_OFFSET ) {
offset = offset + 16;
if( *( data + offset + 0 ) == '_' && \
*( data + offset + 1 ) == '3' && \
*( data + offset + 2 ) == '2' && \
*( data + offset + 3 ) == '_' ) {
result = offset;
break;
}
}
return( result );
}
 
 
byte chksum__32__get_value( byte* data, long offset ) {
 
check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
return( *( data + offset + _32__CHKSUM ) );
}
 
 
void chksum__32__set_value( byte* data, long offset, byte value ) {
 
check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
*( data + offset + _32__CHKSUM ) = value;
}
 
 
byte chksum__mp__calc_value( byte* data, long offset ) {
 
int i;
int len;
byte sum;
 
check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" );
len = *( data + offset + _MP__LEN ) << 4;
check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" );
sum = 0;
for( i = 0; i < len; i++ ) {
if( i != _MP__CHKSUM ) {
sum = sum + *( data + offset + i );
}
}
sum = -sum;
return( sum );
}
 
 
long chksum__mp__get_offset( byte* data, long offset ) {
 
long result = -1L;
 
offset = offset + 0x0F;
offset = offset & ~( 0x0F );
while( offset + 16 < MAX_OFFSET ) {
offset = offset + 16;
if( *( data + offset + 0 ) == '_' && \
*( data + offset + 1 ) == 'M' && \
*( data + offset + 2 ) == 'P' && \
*( data + offset + 3 ) == '_' ) {
result = offset;
break;
}
}
return( result );
}
 
 
byte chksum__mp__get_value( byte* data, long offset ) {
 
check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
return( *( data + offset + _MP__CHKSUM ) );
}
 
 
void chksum__mp__set_value( byte* data, long offset, byte value ) {
 
check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
*( data + offset + _MP__CHKSUM ) = value;
}
 
 
byte chksum_pcmp_calc_value( byte* data, long offset ) {
 
int i;
int len;
byte sum;
 
check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" );
len = *( data + offset + PCMP_BASELEN ) + \
( *( data + offset + PCMP_BASELEN + 1 ) << 8 );
check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" );
if( *( data + offset + PCMP_EXT_LEN ) | \
*( data + offset + PCMP_EXT_LEN + 1 ) | \
*( data + offset + PCMP_EXT_CHKSUM ) ) {
check( 0, "PCMP header indicates extended tables (unsupported)" );
}
sum = 0;
for( i = 0; i < len; i++ ) {
if( i != PCMP_CHKSUM ) {
sum = sum + *( data + offset + i );
}
}
sum = -sum;
return( sum );
}
 
 
long chksum_pcmp_get_offset( byte* data, long offset ) {
 
long result = -1L;
 
offset = offset + 0x0F;
offset = offset & ~( 0x0F );
while( offset + 16 < MAX_OFFSET ) {
offset = offset + 16;
if( *( data + offset + 0 ) == 'P' && \
*( data + offset + 1 ) == 'C' && \
*( data + offset + 2 ) == 'M' && \
*( data + offset + 3 ) == 'P' ) {
result = offset;
break;
}
}
return( result );
}
 
 
byte chksum_pcmp_get_value( byte* data, long offset ) {
 
check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
return( *( data + offset + PCMP_CHKSUM ) );
}
 
 
void chksum_pcmp_set_value( byte* data, long offset, byte value ) {
 
check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
*( data + offset + PCMP_CHKSUM ) = value;
}
 
 
byte chksum__pir_calc_value( byte* data, long offset ) {
 
int i;
int len;
byte sum;
 
check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" );
len = *( data + offset + _PIR_LEN ) + \
( *( data + offset + _PIR_LEN + 1 ) << 8 );
check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" );
sum = 0;
for( i = 0; i < len; i++ ) {
if( i != _PIR_CHKSUM ) {
sum = sum + *( data + offset + i );
}
}
sum = -sum;
return( sum );
}
 
 
long chksum__pir_get_offset( byte* data, long offset ) {
 
long result = -1L;
 
offset = offset + 0x0F;
offset = offset & ~( 0x0F );
while( offset + 16 < MAX_OFFSET ) {
offset = offset + 16;
if( *( data + offset + 0 ) == '$' && \
*( data + offset + 1 ) == 'P' && \
*( data + offset + 2 ) == 'I' && \
*( data + offset + 3 ) == 'R' ) {
result = offset;
break;
}
}
return( result );
}
 
 
byte chksum__pir_get_value( byte* data, long offset ) {
 
check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
return( *( data + offset + _PIR_CHKSUM ) );
}
 
 
void chksum__pir_set_value( byte* data, long offset, byte value ) {
 
check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
*( data + offset + _PIR_CHKSUM ) = value;
}
 
/makesym.perl
0,0 → 1,31
#!/usr/bin/perl
#
# $Id: makesym.perl,v 1.7 2009-02-06 03:48:27 zeus Exp $
#
# Read output file from as86 (e.g. rombios.txt) and write out a symbol
# table suitable for the Bochs debugger.
#
 
$WHERE_BEFORE_SYM_TABLE = 0;
$WHERE_IN_SYM_TABLE = 1;
$WHERE_AFTER_SYM_TABLE = 2;
 
$where = $WHERE_BEFORE_SYM_TABLE;
while (<STDIN>) {
chop;
if ($where == WHERE_BEFORE_SYM_TABLE && /^Symbols:/) {
$where = $WHERE_IN_SYM_TABLE;
} elsif ($where == $WHERE_IN_SYM_TABLE && /^$/) {
$where = $WHERE_AFTER_SYM_TABLE;
}
if ($where == $WHERE_IN_SYM_TABLE) {
@F = split (/\s+/);
($name[0], $junk, $addr[0], $junk, $name[1], $junk, $addr[1]) = @F;
foreach $col (0,1) {
next if length $addr[$col] < 1;
$addr[$col] =~ tr/A-Z/a-z/;
$addr[$col] = "000f" . $addr[$col];
print "$addr[$col] $name[$col]\n";
}
}
}
makesym.perl Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: .bochsrc =================================================================== --- .bochsrc (nonexistent) +++ .bochsrc (revision 49) @@ -0,0 +1,6 @@ +romimage: file=zet-bios.out +vgaromimage: file=/usr/share/vgabios/vgabios.bin +#boot: floppy +#loppya: 1_44="a-1.44.img", status=inserted +debug: action=report +log: bochs.log Index: Makefile =================================================================== --- Makefile (nonexistent) +++ Makefile (revision 49) @@ -0,0 +1,101 @@ +.SUFFIXES: .cc + +srcdir = . + + +SHELL = /bin/sh + + + +CXX = g++ +CXXFLAGS = -g3 -O0 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES +CC = gcc +CFLAGS = -g -O2 -Wall -Wstrict-prototypes + +LDFLAGS = +LIBS = -lm +RANLIB = ranlib + +BCC = bcc +GCC = gcc +GCC32 = gcc -m32 +AS86 = as86 + +BX_INCDIRS = -I.. -I$(srcdir)/.. -I../iodev -I$(srcdir)/../iodev +LOCAL_CXXFLAGS = + +BUILDDATE = `date '+%m/%d/%y'` +BIOS_BUILD_DATE = "-DBIOS_BUILD_DATE=\"$(BUILDDATE)\"" +# +# -------- end configurable options -------------------------- +# + +RELEASE = `pwd | sed "s-.*/--"` +RELDATE = `date '+%d %b %Y'` +RELVERS = `pwd | sed "s-.*/--" | sed "s/vgabios//" | sed "s/-//"` + +VGABIOS_DATE = "-DVGABIOS_DATE=\"$(RELDATE)\"" + + +all: bios.rom + +ff.out: ../../bin/ff + ../../bin/ff 8192 >$@ + +%.ml403: %.rom + hexdump -v -e '4/1 "%02X"' -e '"\n"' $< > ../../impl/virtex4-ml403ep/sim/$@ + +%.rom: %.out + ../../bin/out2rom-ml403 ff.out $< >$@ + +#vgabios.rom: vgabios.out +# out2rom-ml403 ff.out $< >$@ + +#hd.rom: hd.out +# out2rom-ml403 ff.out $< >$@ + +bios.out: vgabios.out ff.out zet-bios.out + cat vgabios.out ff.out zet-bios.out > $@ + +run: flash.rom + prf + +clean: + rm -f *.o *.a *.s _rombios*_.c rombios*.txt rombios*.sym *.out *.rom + rm -f usage biossums vgasums + rm -f *.ld86 \ + temp.awk.* vgabios*.orig _vgabios_* vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak + +bios-clean: + rm -f zet-bios.out + +.cc.o: + $(CXX) -c $(BX_INCDIRS) $(CXXFLAGS) $(LOCAL_CXXFLAGS) $< -o $@ + +zet-bios.out: rombios.c biossums rombios.h + $(GCC32) $(BIOS_BUILD_DATE) -DLEGACY -E -P $< > _rombiosl_.c + $(BCC) -o rombiosl.s -C-c -D__i86__ -0 -S _rombiosl_.c + sed -e 's/^\.text//' -e 's/^\.data//' rombiosl.s > _rombiosl_.s + $(AS86) _rombiosl_.s -b tmpl.bin -u- -w- -g -0 -j -O -l rombiosl.txt + -perl ${srcdir}/makesym.perl < rombiosl.txt > rombiosl.sym + mv tmpl.bin $@ + ./biossums $@ + rm -f _rombiosl_.s + +vgabios.out: vgabios.c vgabios.h vgatables.h vgasums + $(GCC) -E vgabios.c $(VGABIOS_VERS) -P $(VGABIOS_DATE) > _vgabios_.c + $(BCC) -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios.s > _vgabios_.s + $(AS86) _vgabios_.s -b vgabios.bin -u -w- -g -0 -j -O -l vgabios.txt +# rm -f _vgabios_.s _vgabios_.c vgabios.s + mv vgabios.bin $@ + ./vgasums $@ + +%.rtlrom: %.out + hexdump -v -e '1/1 "%02X"' -e '"\n"' $< > ../../sim/$@ + +vgasums: vgasums.c + $(CC) -o vgasums vgasums.c + +biossums: biossums.c + $(GCC) -o biossums biossums.c Index: vgafonts.h =================================================================== --- vgafonts.h (nonexistent) +++ vgafonts.h (revision 49) @@ -0,0 +1,784 @@ +/* + * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip + * The package is (c) by Joseph Gil + * The individual fonts are public domain + */ +static Bit8u vgafont8[256*8]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, + 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, + 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, + 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, + 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, + 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, + 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, + 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, + 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, + 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, + 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, + 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, + 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, + 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, + 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, + 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, + 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, + 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, + 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, + 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, + 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, + 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, + 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, + 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, + 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, + 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, + 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, + 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, + 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, + 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, + 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, + 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, + 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, + 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, + 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, + 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, + 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, + 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, + 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, + 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, + 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, + 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, + 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, + 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, + 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, + 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, + 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static Bit8u vgafont14[256*14]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, + 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static Bit8u vgafont16[256*16]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static Bit8u vgafont14alt[1]={0x00}; +static Bit8u vgafont16alt[1]={0x00}; Index: vgabios.h =================================================================== --- vgabios.h (nonexistent) +++ vgabios.h (revision 49) @@ -0,0 +1,47 @@ +#ifndef vgabios_h_included +#define vgabios_h_included + +/* Types */ +typedef unsigned char Bit8u; +typedef unsigned short Bit16u; +typedef unsigned long Bit32u; +typedef unsigned short Boolean; + +/* Defines */ + +#define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) +#define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) +#define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) +#define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) +#define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) +#define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) +#define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) +#define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) + +#define GET_AL() ( AX & 0x00ff ) +#define GET_BL() ( BX & 0x00ff ) +#define GET_CL() ( CX & 0x00ff ) +#define GET_DL() ( DX & 0x00ff ) +#define GET_AH() ( AX >> 8 ) +#define GET_BH() ( BX >> 8 ) +#define GET_CH() ( CX >> 8 ) +#define GET_DH() ( DX >> 8 ) + +#define SET_CF() FLAGS |= 0x0001 +#define CLEAR_CF() FLAGS &= 0xfffe +#define GET_CF() (FLAGS & 0x0001) + +#define SET_ZF() FLAGS |= 0x0040 +#define CLEAR_ZF() FLAGS &= 0xffbf +#define GET_ZF() (FLAGS & 0x0040) + +#define SCROLL_DOWN 0 +#define SCROLL_UP 1 +#define NO_ATTR 2 +#define WITH_ATTR 3 + +#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) +#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) +#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) + +#endif Index: vgasums.c =================================================================== --- vgasums.c (nonexistent) +++ vgasums.c (revision 49) @@ -0,0 +1,220 @@ +/* biossums.c --- written by Eike W. for the Bochs BIOS */ +/* adapted for the LGPL'd VGABIOS by vruppert */ + +/* This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include + +typedef unsigned char byte; + +void check( int value, char* message ); + +#define MAX_BIOS_DATA 0x10000 + +long chksum_bios_get_offset( byte* data, long offset ); +byte chksum_bios_calc_value( byte* data, long offset ); +byte chksum_bios_get_value( byte* data, long offset ); +void chksum_bios_set_value( byte* data, long offset, byte value ); + + +#define PMID_LEN 20 +#define PMID_CHKSUM 19 + +long chksum_pmid_get_offset( byte* data, long offset ); +byte chksum_pmid_calc_value( byte* data, long offset ); +byte chksum_pmid_get_value( byte* data, long offset ); +void chksum_pmid_set_value( byte* data, long offset, byte value ); + + +byte bios_data[MAX_BIOS_DATA]; +long bios_len; + + +int main( int argc, char* argv[] ) { + + FILE* stream; + long offset, tmp_offset; + byte cur_val = 0, new_val = 0; + int hits; + + + if (argc != 2) { + printf( "Error. Need a file-name as an argument.\n" ); + exit( EXIT_FAILURE ); + } + + if ((stream = fopen(argv[1], "rb")) == NULL) { + printf("Error opening %s for reading.\n", argv[1]); + exit(EXIT_FAILURE); + } + memset(bios_data, 0, MAX_BIOS_DATA); + bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream); + if (bios_len >= MAX_BIOS_DATA) { + printf("Error reading max. 65535 Bytes from %s.\n", argv[1]); + fclose(stream); + exit(EXIT_FAILURE); + } + fclose(stream); + if (bios_len < 0x7FFF) { + bios_len = 0x8000; + } else { + bios_len = (bios_len + 0x201) & ~0x1FF; + } + bios_data[2] = (byte)(bios_len / 512); + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum_pmid_get_value( bios_data, offset ); + new_val = chksum_pmid_calc_value( bios_data, offset ); + printf( "\nPMID entry at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum_pmid_set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Multiple PMID entries! No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + offset = 0L; + offset = chksum_bios_get_offset( bios_data, offset ); + cur_val = chksum_bios_get_value( bios_data, offset ); + new_val = chksum_bios_calc_value( bios_data, offset ); + printf( "\nBios checksum at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + if( cur_val != new_val ) { + printf( "Setting checksum." ); + chksum_bios_set_value( bios_data, offset, new_val ); + } + printf( "\n" ); + + + if(( stream = fopen( argv[1], "wb" )) == NULL ) { + printf( "Error opening %s for writing.\n", argv[1] ); + exit( EXIT_FAILURE ); + } + if( fwrite( bios_data, 1, bios_len, stream ) < bios_len ) { + printf( "Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1] ); + fclose( stream ); + exit( EXIT_FAILURE ); + } + fclose( stream ); + + return( EXIT_SUCCESS ); +} + + +void check( int okay, char* message ) { + + if( !okay ) { + printf( "\n\nError. %s.\n", message ); + exit( EXIT_FAILURE ); + } +} + + +long chksum_bios_get_offset( byte* data, long offset ) { + + return (bios_len - 1); +} + + +byte chksum_bios_calc_value( byte* data, long offset ) { + + int i; + byte sum; + + sum = 0; + for( i = 0; i < offset; i++ ) { + sum = sum + *( data + i ); + } + sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ + return( sum ); +} + + +byte chksum_bios_get_value( byte* data, long offset ) { + + return( *( data + offset ) ); +} + + +void chksum_bios_set_value( byte* data, long offset, byte value ) { + + *( data + offset ) = value; +} + + +byte chksum_pmid_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + len = PMID_LEN; + check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != PMID_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum_pmid_get_offset( byte* data, long offset ) { + + long result = -1L; + + while ((offset + PMID_LEN) < (bios_len - 1)) { + offset = offset + 1; + if( *( data + offset + 0 ) == 'P' && \ + *( data + offset + 1 ) == 'M' && \ + *( data + offset + 2 ) == 'I' && \ + *( data + offset + 3 ) == 'D' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum_pmid_get_value( byte* data, long offset ) { + + check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); + return( *( data + offset + PMID_CHKSUM ) ); +} + + +void chksum_pmid_set_value( byte* data, long offset, byte value ) { + + check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); + *( data + offset + PMID_CHKSUM ) = value; +} Index: vgatables.h =================================================================== --- vgatables.h (nonexistent) +++ vgatables.h (revision 49) @@ -0,0 +1,622 @@ +/* + * + * BIOS Memory + * + */ +#define BIOSMEM_SEG 0x40 + +#define BIOSMEM_INITIAL_MODE 0x10 +#define BIOSMEM_CURRENT_MODE 0x49 +#define BIOSMEM_NB_COLS 0x4A +#define BIOSMEM_PAGE_SIZE 0x4C +#define BIOSMEM_CURRENT_START 0x4E +#define BIOSMEM_CURSOR_POS 0x50 +#define BIOSMEM_CURSOR_TYPE 0x60 +#define BIOSMEM_CURRENT_PAGE 0x62 +#define BIOSMEM_CRTC_ADDRESS 0x63 +#define BIOSMEM_CURRENT_MSR 0x65 +#define BIOSMEM_CURRENT_PAL 0x66 +#define BIOSMEM_NB_ROWS 0x84 +#define BIOSMEM_CHAR_HEIGHT 0x85 +#define BIOSMEM_VIDEO_CTL 0x87 +#define BIOSMEM_SWITCHES 0x88 +#define BIOSMEM_MODESET_CTL 0x89 +#define BIOSMEM_DCC_INDEX 0x8A +#define BIOSMEM_VS_POINTER 0xA8 +#define BIOSMEM_VBE_FLAG 0xB9 +#define BIOSMEM_VBE_MODE 0xBA + + +/* + * + * VGA registers + * + */ +#define VGAREG_ACTL_ADDRESS 0x3c0 +#define VGAREG_ACTL_WRITE_DATA 0x3c0 +#define VGAREG_ACTL_READ_DATA 0x3c1 + +#define VGAREG_INPUT_STATUS 0x3c2 +#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 +#define VGAREG_VIDEO_ENABLE 0x3c3 +#define VGAREG_SEQU_ADDRESS 0x3c4 +#define VGAREG_SEQU_DATA 0x3c5 + +#define VGAREG_PEL_MASK 0x3c6 +#define VGAREG_DAC_STATE 0x3c7 +#define VGAREG_DAC_READ_ADDRESS 0x3c7 +#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 +#define VGAREG_DAC_DATA 0x3c9 + +#define VGAREG_READ_FEATURE_CTL 0x3ca +#define VGAREG_READ_MISC_OUTPUT 0x3cc + +#define VGAREG_GRDC_ADDRESS 0x3ce +#define VGAREG_GRDC_DATA 0x3cf + +#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 +#define VGAREG_MDA_CRTC_DATA 0x3b5 +#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 +#define VGAREG_VGA_CRTC_DATA 0x3d5 + +#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba +#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da +#define VGAREG_ACTL_RESET 0x3da + +#define VGAREG_MDA_MODECTL 0x3b8 +#define VGAREG_CGA_MODECTL 0x3d8 +#define VGAREG_CGA_PALETTE 0x3d9 + +/* Video memory */ +#define VGAMEM_GRAPH 0xA000 +#define VGAMEM_CTEXT 0xB800 +#define VGAMEM_MTEXT 0xB000 + +/* + * + * Tables of default values for each mode + * + */ +#define MODE_MAX 15 +#define TEXT 0x00 +#define GRAPH 0x01 + +#define CTEXT 0x00 +#define MTEXT 0x01 +#define CGA 0x02 +#define PLANAR1 0x03 +#define PLANAR4 0x04 +#define LINEAR8 0x05 + +// for SVGA +#define LINEAR15 0x10 +#define LINEAR16 0x11 +#define LINEAR24 0x12 +#define LINEAR32 0x13 + +typedef struct +{Bit8u svgamode; + Bit8u class; /* TEXT, GRAPH */ + Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ + Bit8u pixbits; + Bit16u sstart; + Bit8u pelmask; + Bit8u dacmodel; /* 0 1 2 3 */ +} VGAMODES; + +static VGAMODES vga_modes[MODE_MAX+1]= +{//mode class model bits sstart pelm dac + {0x00, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x01, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x02, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x03, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x04, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, + {0x05, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, + {0x06, GRAPH, CGA, 1, 0xB800, 0xFF, 0x01}, + {0x07, TEXT, MTEXT, 4, 0xB000, 0xFF, 0x00}, + {0x0D, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, + {0x0E, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, + {0x0F, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x00}, + {0x10, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, + {0x11, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x02}, + {0x12, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, + {0x13, GRAPH, LINEAR8, 8, 0xA000, 0xFF, 0x03}, + {0x6A, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02} +}; + +/* convert index in vga_modes[] to index in video_param_table[] */ +static Bit8u line_to_vpti[MODE_MAX+1]={ + 0x17, 0x17, 0x18, 0x18, 0x04, 0x05, 0x06, 0x07, + 0x0d, 0x0e, 0x11, 0x12, 0x1a, 0x1b, 0x1c, 0x1d, +}; + +/* Default Palette */ +#define DAC_MAX_MODEL 3 + +static Bit8u dac_regs[DAC_MAX_MODEL+1]= +{0x3f,0x3f,0x3f,0xff}; + +/* standard BIOS Video Parameter Table */ +typedef struct { + Bit8u twidth; + Bit8u theightm1; + Bit8u cheight; + Bit8u slength_l; + Bit8u slength_h; + Bit8u sequ_regs[4]; + Bit8u miscreg; + Bit8u crtc_regs[25]; + Bit8u actl_regs[20]; + Bit8u grdc_regs[9]; +} VideoParamTableEntry; + +static VideoParamTableEntry video_param_table[30] = { +{ + /* index=0x00 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x01 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x02 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x03 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x04 vga mode 0x04 */ + 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ + 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x63, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, + 0xff, /* crtc_regs */ + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x03, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x05 vga mode 0x05 */ + 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ + 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x63, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, + 0xff, /* crtc_regs */ + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x03, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x06 vga mode 0x06 */ + 80, 24, 8, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x01, 0x01, 0x00, 0x06, /* sequ_regs */ + 0x63, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, + 0xff, /* crtc_regs */ + 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x01, 0x00, 0x01, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x07 vga mode 0x07 */ + 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x66, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x08 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x09 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0a no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0b no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0c no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0d vga mode 0x0d */ + 40, 24, 8, 0x00, 0x20, /* tw, th-1, ch, slength */ + 0x09, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0x63, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x0e vga mode 0x0e */ + 80, 24, 8, 0x00, 0x40, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0x63, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x0f no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x10 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x11 vga mode 0x0f */ + 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xa3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x12 vga mode 0x10 */ + 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xa3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x13 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x14 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x15 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x16 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x17 vga mode 0x01 */ + 40, 24, 16, 0x00, 0x08, /* tw, th-1, ch, slength */ + 0x08, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x67, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x18 vga mode 0x03 */ + 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x67, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x19 vga mode 0x07 */ + 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x66, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1a vga mode 0x11 */ + 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xe3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1b vga mode 0x12 */ + 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xe3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1c vga mode 0x13 */ + 40, 24, 8, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x0e, /* sequ_regs */ + 0x63, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x41, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1d vga mode 0x6a */ + 100, 36, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xe3, /* miscreg */ + 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +}; + +/* Mono */ +static Bit8u palette0[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f +}; + +static Bit8u palette1[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f +}; + +static Bit8u palette2[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, + 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, + 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, + 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, + 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, + 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f +}; + +static Bit8u palette3[256][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, + 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, + 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, + 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, + 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, + 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, + + 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, + 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, + 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, + 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, + 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, + 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, + 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, + 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, + + 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, + 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, + 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, + 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, + 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, + 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, + 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, + 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, + + 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, + 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, + 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, + 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, + 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, + 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, + 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 +}; + +static Bit8u static_functionality[0x10]= +{ + /* 0 */ 0xff, // All modes supported #1 + /* 1 */ 0xe0, // All modes supported #2 + /* 2 */ 0x0f, // All modes supported #3 + /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved + /* 7 */ 0x07, // 200, 350, 400 scan lines + /* 8 */ 0x02, // mamimum number of visible charsets in text mode + /* 9 */ 0x08, // total number of charset blocks in text mode + /* a */ 0xe7, // Change to add new functions + /* b */ 0x0c, // Change to add new functions + /* c */ 0x00, // reserved + /* d */ 0x00, // reserved + /* e */ 0x00, // Change to add new functions + /* f */ 0x00 // reserved +}; Index: rombios.h =================================================================== --- rombios.h (nonexistent) +++ rombios.h (revision 49) @@ -0,0 +1,10 @@ +#define BIOS_PRINTF_HALT 1 +#define BIOS_PRINTF_SCREEN 2 +#define BIOS_PRINTF_INFO 4 +#define BIOS_PRINTF_DEBUG 8 +#define BIOS_PRINTF_ALL (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO) +#define BIOS_PRINTF_DEBHALT (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT) + +#define printf(format, p...) bios_printf(BIOS_PRINTF_SCREEN, format, ##p) +#define BX_INFO(format, p...) bios_printf(BIOS_PRINTF_INFO, format, ##p) +#define BX_PANIC(format, p...) bios_printf(BIOS_PRINTF_DEBHALT, format, ##p)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.