|
|
|
|
/*
|
|
|
|
|
* (C) Copyright 2002
|
|
|
|
|
* Daniel Engstr<EFBFBD>m, Omicron Ceti AB, daniel@omicron.se
|
|
|
|
|
*
|
|
|
|
|
* See file CREDITS for list of people who contributed to this
|
|
|
|
|
* project.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
|
* published by the Free Software Foundation; either version 2 of
|
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Based on msbios.c from rolo 1.6:
|
|
|
|
|
*----------------------------------------------------------------------
|
|
|
|
|
* (C) Copyright 2000
|
|
|
|
|
* Sysgo Real-Time Solutions GmbH
|
|
|
|
|
* Klein-Winternheim, Germany
|
|
|
|
|
*----------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* During it's initialization phase, before switching to protected
|
|
|
|
|
* mode, the Linux Kernel makes a few BIOS calls. This won't work
|
|
|
|
|
* if the board does not have a BIOS.
|
|
|
|
|
*
|
|
|
|
|
* This is a very minimalisic BIOS that supplies just enough
|
|
|
|
|
* functionality to keep the Linux Kernel happy. It is NOT
|
|
|
|
|
* a general purpose replacement for a real BIOS !!
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define OFFS_ES 0
|
|
|
|
|
#define OFFS_GS 2
|
|
|
|
|
#define OFFS_DS 4
|
|
|
|
|
#define OFFS_DI 6
|
|
|
|
|
#define OFFS_SI 8
|
|
|
|
|
#define OFFS_BP 10
|
|
|
|
|
#define OFFS_SP 12
|
|
|
|
|
#define OFFS_BX 14
|
|
|
|
|
#define OFFS_DX 16
|
|
|
|
|
#define OFFS_CX 18
|
|
|
|
|
#define OFFS_AX 20
|
|
|
|
|
#define OFFS_VECTOR 22
|
|
|
|
|
#define OFFS_IP 24
|
|
|
|
|
#define OFFS_CS 26
|
|
|
|
|
#define OFFS_FLAGS 28
|
|
|
|
|
|
|
|
|
|
#define SEGMENT 0x40
|
|
|
|
|
#define STACK 0x800 /* stack at 0x40:0x800 -> 0x800 */
|
|
|
|
|
|
|
|
|
|
.section .bios, "ax"
|
|
|
|
|
.code16
|
|
|
|
|
.org 0
|
|
|
|
|
|
|
|
|
|
.globl rm_int00
|
|
|
|
|
rm_int00:
|
|
|
|
|
pushw $0
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int01
|
|
|
|
|
rm_int01:
|
|
|
|
|
pushw $1
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int02
|
|
|
|
|
rm_int02:
|
|
|
|
|
pushw $2
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int03
|
|
|
|
|
rm_int03:
|
|
|
|
|
pushw $3
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int04
|
|
|
|
|
rm_int04:
|
|
|
|
|
pushw $4
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int05
|
|
|
|
|
rm_int05:
|
|
|
|
|
pushw $5
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int06
|
|
|
|
|
rm_int06:
|
|
|
|
|
pushw $6
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int07
|
|
|
|
|
rm_int07:
|
|
|
|
|
pushw $7
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int08
|
|
|
|
|
rm_int08:
|
|
|
|
|
pushw $8
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int09
|
|
|
|
|
rm_int09:
|
|
|
|
|
pushw $9
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int0a
|
|
|
|
|
rm_int0a:
|
|
|
|
|
pushw $10
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int0b
|
|
|
|
|
rm_int0b:
|
|
|
|
|
pushw $11
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int0c
|
|
|
|
|
rm_int0c:
|
|
|
|
|
pushw $12
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int0d
|
|
|
|
|
rm_int0d:
|
|
|
|
|
pushw $13
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int0e
|
|
|
|
|
rm_int0e:
|
|
|
|
|
pushw $14
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int0f
|
|
|
|
|
rm_int0f:
|
|
|
|
|
pushw $15
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int10
|
|
|
|
|
rm_int10:
|
|
|
|
|
pushw $16
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int11
|
|
|
|
|
rm_int11:
|
|
|
|
|
pushw $17
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int12
|
|
|
|
|
rm_int12:
|
|
|
|
|
pushw $18
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int13
|
|
|
|
|
rm_int13:
|
|
|
|
|
pushw $19
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int14
|
|
|
|
|
rm_int14:
|
|
|
|
|
pushw $20
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int15
|
|
|
|
|
rm_int15:
|
|
|
|
|
pushw $21
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int16
|
|
|
|
|
rm_int16:
|
|
|
|
|
pushw $22
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int17
|
|
|
|
|
rm_int17:
|
|
|
|
|
pushw $23
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int18
|
|
|
|
|
rm_int18:
|
|
|
|
|
pushw $24
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int19
|
|
|
|
|
rm_int19:
|
|
|
|
|
pushw $25
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int1a
|
|
|
|
|
rm_int1a:
|
|
|
|
|
pushw $26
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int1b
|
|
|
|
|
rm_int1b:
|
|
|
|
|
pushw $27
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int1c
|
|
|
|
|
rm_int1c:
|
|
|
|
|
pushw $28
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int1d
|
|
|
|
|
rm_int1d:
|
|
|
|
|
pushw $29
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int1e
|
|
|
|
|
rm_int1e:
|
|
|
|
|
pushw $30
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_int1f
|
|
|
|
|
rm_int1f:
|
|
|
|
|
pushw $31
|
|
|
|
|
jmp any_interrupt16
|
|
|
|
|
.globl rm_def_int
|
|
|
|
|
rm_def_int:
|
|
|
|
|
iret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* All interrupt jumptable entries jump to here
|
|
|
|
|
* after pushing the interrupt vector number onto the
|
|
|
|
|
* stack.
|
|
|
|
|
*/
|
|
|
|
|
any_interrupt16:
|
|
|
|
|
pusha /* save general registers */
|
|
|
|
|
pushw %ds /* save some segments */
|
|
|
|
|
pushw %gs
|
|
|
|
|
pushw %es
|
|
|
|
|
pushw %ss /* save callers stack segment .. */
|
|
|
|
|
popw %gs /* ... in gs */
|
|
|
|
|
movw $SEGMENT,%ax /* setup my segments */
|
|
|
|
|
movw %ax,%ds
|
|
|
|
|
movw %ax,%es
|
|
|
|
|
movw %ax,%ss
|
|
|
|
|
movw %sp,%bp
|
|
|
|
|
movw $STACK,%sp /* setup BIOS stackpointer */
|
|
|
|
|
|
|
|
|
|
gs movw OFFS_VECTOR(%bp), %ax
|
|
|
|
|
cmpw $0x10, %ax
|
|
|
|
|
je Lint_10h
|
|
|
|
|
cmpw $0x11, %ax
|
|
|
|
|
je Lint_11h
|
|
|
|
|
cmpw $0x13, %ax
|
|
|
|
|
je Lint_13h
|
|
|
|
|
cmpw $0x15, %ax
|
|
|
|
|
je Lint_15h
|
|
|
|
|
cmpw $0x16, %ax
|
|
|
|
|
je Lint_16h
|
|
|
|
|
movw $0xffff, %ax
|
|
|
|
|
jmp Lout
|
|
|
|
|
Lint_10h: /* VGA BIOS services */
|
|
|
|
|
call bios_10h
|
|
|
|
|
jmp Lout
|
|
|
|
|
Lint_11h:
|
|
|
|
|
call bios_11h
|
|
|
|
|
jmp Lout
|
|
|
|
|
Lint_13h: /* BIOS disk services */
|
|
|
|
|
call bios_13h
|
|
|
|
|
jmp Lout
|
|
|
|
|
Lint_15h: /* Misc. BIOS services */
|
|
|
|
|
call bios_15h
|
|
|
|
|
jmp Lout
|
|
|
|
|
Lint_16h: /* keyboard services */
|
|
|
|
|
call bios_16h
|
|
|
|
|
jmp Lout
|
|
|
|
|
Lout:
|
|
|
|
|
cmpw $0, %ax
|
|
|
|
|
je Lhandeled
|
|
|
|
|
|
|
|
|
|
/* Insert code for unhandeled INTs here.
|
|
|
|
|
*
|
|
|
|
|
* ROLO prints a message to the console
|
|
|
|
|
* (we could do that but then we're in 16bit mode
|
|
|
|
|
* so we'll have to get back into 32bit mode
|
|
|
|
|
* to use the console I/O routines (if we do this
|
|
|
|
|
* we shuls make int 0x10 and int 0x16 work as well))
|
|
|
|
|
*/
|
|
|
|
|
Lhandeled:
|
|
|
|
|
|
|
|
|
|
pushw %gs /* restore callers stack segment */
|
|
|
|
|
popw %ss
|
|
|
|
|
movw %bp,%sp /* restore stackpointer */
|
|
|
|
|
|
|
|
|
|
popw %es /* restore segment selectors */
|
|
|
|
|
popw %gs
|
|
|
|
|
popw %ds
|
|
|
|
|
|
|
|
|
|
popa /* restore GP registers */
|
|
|
|
|
addw $2,%sp /* dump vector number */
|
|
|
|
|
iret /* return from interrupt */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
************************************************************
|
|
|
|
|
* BIOS interrupt 10h -- VGA services
|
|
|
|
|
************************************************************
|
|
|
|
|
*/
|
|
|
|
|
bios_10h:
|
|
|
|
|
gs movw OFFS_AX(%bp), %ax
|
|
|
|
|
shrw $8, %ax
|
|
|
|
|
cmpw $0x3, %ax
|
|
|
|
|
je Lcur_pos
|
|
|
|
|
cmpw $0xf, %ax
|
|
|
|
|
je Lvid_state
|
|
|
|
|
cmpw $0x12, %ax
|
|
|
|
|
je Lvid_cfg
|
|
|
|
|
movw $0xffff, %ax
|
|
|
|
|
ret
|
|
|
|
|
Lcur_pos: /* Read Cursor Position and Size */
|
|
|
|
|
gs movw $0, OFFS_CX(%bp)
|
|
|
|
|
gs movw $0, OFFS_DX(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
Lvid_state: /* Get Video State */
|
|
|
|
|
gs movw $(80 << 8|0x03), OFFS_AX(%bp) /* 80 columns, 80x25, 16 colors */
|
|
|
|
|
gs movw $0, OFFS_BX(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
Lvid_cfg: /* Video Subsystem Configuration (EGA/VGA) */
|
|
|
|
|
gs movw $0x10, OFFS_BX(%bp) /* indicate CGA/MDA/HGA */
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
************************************************************
|
|
|
|
|
* BIOS interrupt 11h -- Equipment determination
|
|
|
|
|
************************************************************
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
bios_11h:
|
|
|
|
|
movw bios_equipment, %ax
|
|
|
|
|
gs movw %ax, OFFS_AX(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
************************************************************
|
|
|
|
|
* BIOS interrupt 13h -- Disk services
|
|
|
|
|
************************************************************
|
|
|
|
|
*/
|
|
|
|
|
bios_13h:
|
|
|
|
|
gs movw OFFS_AX(%bp), %ax
|
|
|
|
|
shrw $8, %ax
|
|
|
|
|
cmpw $0x15, %ax
|
|
|
|
|
je Lfunc_15h
|
|
|
|
|
movw $0xffff, %ax
|
|
|
|
|
ret
|
|
|
|
|
Lfunc_15h:
|
|
|
|
|
gs movw OFFS_AX(%bp), %ax
|
|
|
|
|
andw $0xff, %ax /* return AH=0->drive not present */
|
|
|
|
|
gs movw %ax, OFFS_AX(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
***********************************************************
|
|
|
|
|
* BIOS interrupt 15h -- Miscellaneous services
|
|
|
|
|
***********************************************************
|
|
|
|
|
*/
|
|
|
|
|
bios_15h:
|
|
|
|
|
gs movw OFFS_AX(%bp), %ax
|
|
|
|
|
shrw $8, %ax
|
|
|
|
|
cmpw $0xc0, %ax
|
|
|
|
|
je Lfunc_c0h
|
|
|
|
|
cmpw $0xe8, %ax
|
|
|
|
|
je Lfunc_e8h
|
|
|
|
|
cmpw $0x88, %ax
|
|
|
|
|
je Lfunc_88h
|
|
|
|
|
movw $0xffff, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
Lfunc_c0h: /* Return System Configuration Parameters (PS2 only) */
|
|
|
|
|
gs movw OFFS_FLAGS(%bp), %ax
|
|
|
|
|
orw $1, %ax /* return carry -- function not supported */
|
|
|
|
|
gs movw %ax, OFFS_FLAGS(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
Lfunc_e8h:
|
|
|
|
|
gs movw OFFS_AX(%bp), %ax
|
|
|
|
|
andw $0xff, %ax
|
|
|
|
|
cmpw $1, %ax
|
|
|
|
|
je Lfunc_e801h
|
|
|
|
|
gs movw OFFS_FLAGS(%bp), %ax
|
|
|
|
|
orw $1, %ax /* return carry -- function not supported */
|
|
|
|
|
gs movw %ax, OFFS_FLAGS(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
Lfunc_e801h: /* Get memory size for >64M Configurations */
|
|
|
|
|
movw $ram_in_64kb_chunks, %ax
|
|
|
|
|
cmpw $256, %ax
|
|
|
|
|
ja Lmore_than_16mb
|
|
|
|
|
shlw $6, %ax /* multiply by 64 */
|
|
|
|
|
gs movw %ax, OFFS_AX(%bp) /* return memory size in 1kb chunks in AX and CX */
|
|
|
|
|
gs movw %ax, OFFS_CX(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
gs movw %ax, OFFS_BX(%bp) /* set BX and DX to 0*/
|
|
|
|
|
gs movw %ax, OFFS_DX(%bp)
|
|
|
|
|
gs movw OFFS_FLAGS(%bp), %ax
|
|
|
|
|
andw $0xfffe, %ax /* clear carry -- function succeeded */
|
|
|
|
|
gs movw %ax, OFFS_FLAGS(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
Lmore_than_16mb:
|
|
|
|
|
subw $0x100, %ax /* subtract 16MB */
|
|
|
|
|
|
|
|
|
|
gs movw $0x3c00, OFFS_AX(%bp) /* return 0x3c00 (16MB-384k) in AX and CX */
|
|
|
|
|
gs movw $0x3c00, OFFS_CX(%bp)
|
|
|
|
|
gs movw %ax, OFFS_BX(%bp) /* set BX and DX to number of 64kb chunks - 256 */
|
|
|
|
|
gs movw %ax, OFFS_DX(%bp)
|
|
|
|
|
|
|
|
|
|
gs movw OFFS_FLAGS(%bp), %ax
|
|
|
|
|
andw $0xfffe, %ax /* clear carry -- function succeeded */
|
|
|
|
|
gs movw %ax, OFFS_FLAGS(%bp)
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
Lfunc_88h:
|
|
|
|
|
movw ram_in_64kb_chunks, %ax
|
|
|
|
|
subw $16, %ax
|
|
|
|
|
shlw $6, %ax
|
|
|
|
|
|
|
|
|
|
gs movw %ax, OFFS_AX(%bp) /* return number of kilobytes in ax */
|
|
|
|
|
|
|
|
|
|
gs movw OFFS_FLAGS(%bp), %ax
|
|
|
|
|
andw $0xfffe, %ax /* clear carry -- function succeeded */
|
|
|
|
|
gs movw %ax, OFFS_FLAGS(%bp)
|
|
|
|
|
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
************************************************************
|
|
|
|
|
* BIOS interrupt 16h -- keyboard services
|
|
|
|
|
************************************************************
|
|
|
|
|
*/
|
|
|
|
|
bios_16h:
|
|
|
|
|
gs movw OFFS_AX(%bp), %ax
|
|
|
|
|
shrw $8, %ax
|
|
|
|
|
cmpw $0x03, %ax
|
|
|
|
|
je Lfunc_03h
|
|
|
|
|
movw $0xffff, %ax
|
|
|
|
|
ret
|
|
|
|
|
Lfunc_03h:
|
|
|
|
|
xorw %ax, %ax /* do nothing -- function not supported */
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.globl ram_in_64kb_chunks
|
|
|
|
|
ram_in_64kb_chunks:
|
|
|
|
|
.word 0
|
|
|
|
|
|
|
|
|
|
.globl bios_equipment
|
|
|
|
|
bios_equipment:
|
|
|
|
|
.word 0
|
|
|
|
|
|