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)