cbd68598a3
which fixes some potential memory leaks
305 lines
8.1 KiB
C++
305 lines
8.1 KiB
C++
/////////////////////////////////////////////////////////////////////////
|
|
// $Id: unmapped.cc,v 1.14 2001-12-21 19:33:18 bdenney Exp $
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2001 MandrakeSoft S.A.
|
|
//
|
|
// MandrakeSoft S.A.
|
|
// 43, rue d'Aboukir
|
|
// 75002 Paris - France
|
|
// http://www.linux-mandrake.com/
|
|
// http://www.mandrakesoft.com/
|
|
//
|
|
// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
#include "bochs.h"
|
|
#define LOG_THIS bx_unmapped.
|
|
|
|
|
|
bx_unmapped_c bx_unmapped;
|
|
#if BX_USE_UM_SMF
|
|
#define this (&bx_unmapped)
|
|
#endif
|
|
|
|
logfunctions *bioslog;
|
|
|
|
bx_unmapped_c::bx_unmapped_c(void)
|
|
{
|
|
put("UNMP");
|
|
settype(UNMAPLOG);
|
|
bioslog = new logfunctions ();
|
|
bioslog->put("BIOS");
|
|
bioslog->settype (BIOSLOG);
|
|
s.port80 = 0x00;
|
|
s.port8e = 0x00;
|
|
|
|
s.bios_message_i = 0;
|
|
}
|
|
|
|
bx_unmapped_c::~bx_unmapped_c(void)
|
|
{
|
|
if ( bioslog != NULL ) /* DT 17.12.2001 21:32 */
|
|
{
|
|
delete bioslog;
|
|
bioslog = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
bx_unmapped_c::init(bx_devices_c *d)
|
|
{
|
|
BX_UM_THIS devices = d;
|
|
|
|
for (Bit32u addr=0; addr<0x10000; addr++) {
|
|
BX_UM_THIS devices->register_io_read_handler(this, read_handler,
|
|
addr, "Unmapped");
|
|
BX_UM_THIS devices->register_io_write_handler(this, write_handler,
|
|
addr, "Unmapped");
|
|
}
|
|
}
|
|
|
|
|
|
// static IO port read callback handler
|
|
// redirects to non-static class handler to avoid virtual functions
|
|
|
|
Bit32u
|
|
bx_unmapped_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
|
|
{
|
|
#if !BX_USE_UM_SMF
|
|
bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;
|
|
|
|
return( class_ptr->read(address, io_len) );
|
|
}
|
|
|
|
Bit32u
|
|
bx_unmapped_c::read(Bit32u address, unsigned io_len)
|
|
{
|
|
#else
|
|
UNUSED(this_ptr);
|
|
#endif // !BX_USE_UM_SMF
|
|
UNUSED(io_len);
|
|
|
|
Bit32u retval;
|
|
|
|
// This function gets called for access to any IO ports which
|
|
// are not mapped to any device handler. Reads return 0
|
|
|
|
if (address >= 0x02e0 && address <= 0x02ef) {
|
|
retval = 0;
|
|
goto return_from_read;
|
|
}
|
|
|
|
switch (address) {
|
|
case 0x80:
|
|
retval = BX_UM_THIS s.port80;
|
|
break;
|
|
case 0x8e:
|
|
retval = BX_UM_THIS s.port8e;
|
|
break;
|
|
#if BX_PORT_E9_HACK
|
|
// Unused port on ISA - this can be used by the emulated code
|
|
// to detect it is running inside Bochs and that the debugging
|
|
// features are available (write 0xFF or something on unused
|
|
// port 0x80, then read from 0xe9, if value is 0xe9, debug
|
|
// output is available) (see write() for that) -- Andreas and Emmanuel
|
|
case 0xe9:
|
|
retval = 0xe9;
|
|
break;
|
|
#endif
|
|
case 0x03df:
|
|
retval = 0xffffffff;
|
|
BX_DEBUG(("unsupported IO read from port %04x (CGA)", address));
|
|
break;
|
|
case 0x023a:
|
|
case 0x02f8: /* UART */
|
|
case 0x02f9: /* UART */
|
|
case 0x02fb: /* UART */
|
|
case 0x02fc: /* UART */
|
|
case 0x02fd: /* UART */
|
|
case 0x02ea:
|
|
case 0x02eb:
|
|
case 0x03e8:
|
|
case 0x03e9:
|
|
case 0x03ea:
|
|
case 0x03eb:
|
|
case 0x03ec:
|
|
case 0x03ed:
|
|
case 0x03f8: /* UART */
|
|
case 0x03f9: /* UART */
|
|
case 0x03fb: /* UART */
|
|
case 0x03fc: /* UART */
|
|
case 0x03fd: /* UART */
|
|
case 0x17c6:
|
|
retval = 0xffffffff;
|
|
BX_DEBUG(("unsupported IO read from port %04x", address));
|
|
break;
|
|
default:
|
|
retval = 0xffffffff;
|
|
}
|
|
|
|
return_from_read:
|
|
if (bx_dbg.unsupported_io)
|
|
switch (io_len) {
|
|
case 1:
|
|
retval = (Bit8u)retval;
|
|
BX_DEBUG(("unmapped: 8-bit read from %04x = %02x", address, retval));
|
|
break;
|
|
case 2:
|
|
retval = (Bit16u)retval;
|
|
BX_DEBUG(("unmapped: 16-bit read from %04x = %04x", address, retval));
|
|
break;
|
|
case 4:
|
|
BX_DEBUG(("unmapped: 32-bit read from %04x = %08x", address, retval));
|
|
break;
|
|
default:
|
|
BX_DEBUG(("unmapped: ??-bit read from %04x = %x", address, retval));
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
// static IO port write callback handler
|
|
// redirects to non-static class handler to avoid virtual functions
|
|
|
|
void
|
|
bx_unmapped_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
|
|
{
|
|
#if !BX_USE_UM_SMF
|
|
bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;
|
|
|
|
class_ptr->write(address, value, io_len);
|
|
}
|
|
|
|
void
|
|
bx_unmapped_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|
{
|
|
#else
|
|
UNUSED(this_ptr);
|
|
#endif // !BX_USE_UM_SMF
|
|
UNUSED(io_len);
|
|
|
|
|
|
// This function gets called for access to any IO ports which
|
|
// are not mapped to any device handler. Writes to an unmapped
|
|
// IO port are ignored.
|
|
|
|
// ???
|
|
|
|
|
|
if (address >= 0x02e0 && address <= 0x02ef)
|
|
goto return_from_write;
|
|
|
|
switch (address) {
|
|
case 0x80: // diagnostic test port to display progress of POST
|
|
//BX_DEBUG(("Diagnostic port 80h: write = %02xh", (unsigned) value));
|
|
BX_UM_THIS s.port80 = value;
|
|
break;
|
|
|
|
case 0x8e: // ???
|
|
BX_UM_THIS s.port8e = value;
|
|
break;
|
|
|
|
#if BX_PORT_E9_HACK
|
|
// This port doesn't exist on normal ISA architecture. However,
|
|
// we define a convention here, to display on the console of the
|
|
// system running Bochs, anything that is written to it. The
|
|
// idea is to provide debug output very early when writing
|
|
// BIOS or OS code for example, without having to bother with
|
|
// properly setting up a serial port or anything.
|
|
//
|
|
// Idea by Andreas Beck (andreas.beck@ggi-project.org)
|
|
|
|
case 0xe9:
|
|
putchar(value);
|
|
fflush(stdout);
|
|
break;
|
|
#endif
|
|
case 0xed: // Dummy port used as I/O delay
|
|
break;
|
|
case 0xee: // ???
|
|
break;
|
|
|
|
case 0x2f2:
|
|
case 0x2f3:
|
|
case 0x2f4:
|
|
case 0x2f5:
|
|
case 0x2f6:
|
|
case 0x2f7:
|
|
case 0x3e8:
|
|
case 0x3e9:
|
|
case 0x3eb:
|
|
case 0x3ec:
|
|
case 0x3ed:
|
|
// BX_DEBUG(("unsupported IO write to port %04x of %02x",
|
|
// address, value));
|
|
break;
|
|
case 0x0401:
|
|
if (BX_UM_THIS s.bios_message_i > 0) {
|
|
// if there are bits of message in the buffer, print them as the
|
|
// panic message. Otherwise fall into the next case.
|
|
if (BX_UM_THIS s.bios_message_i >= BX_BIOS_MESSAGE_SIZE)
|
|
BX_UM_THIS s.bios_message_i = BX_BIOS_MESSAGE_SIZE-1;
|
|
BX_UM_THIS s.bios_message[ BX_UM_THIS s.bios_message_i] = 0;
|
|
BX_UM_THIS s.bios_message_i = 0;
|
|
bioslog->panic((BX_UM_THIS s.bios_message));
|
|
break;
|
|
}
|
|
case 0x0400:
|
|
bioslog->panic("BIOS panic at rombios.c, line %d", value);
|
|
break;
|
|
case 0xfedc:
|
|
bx_dbg.debugger = (value > 0);
|
|
BX_DEBUG(( "DEBUGGER = %u", (unsigned) bx_dbg.debugger));
|
|
break;
|
|
|
|
case 0xfff0:
|
|
BX_UM_THIS s.bios_message[BX_UM_THIS s.bios_message_i] =
|
|
(Bit8u) value;
|
|
BX_UM_THIS s.bios_message_i ++;
|
|
if ( BX_UM_THIS s.bios_message_i >= BX_BIOS_MESSAGE_SIZE ) {
|
|
BX_UM_THIS s.bios_message[ BX_BIOS_MESSAGE_SIZE - 1] = 0;
|
|
BX_UM_THIS s.bios_message_i = 0;
|
|
bioslog->info("%s", BX_UM_THIS s.bios_message);
|
|
}
|
|
else if ((value & 0xff) == '\n') {
|
|
BX_UM_THIS s.bios_message[ BX_UM_THIS s.bios_message_i - 1 ] = 0;
|
|
BX_UM_THIS s.bios_message_i = 0;
|
|
bioslog->info("%s", BX_UM_THIS s.bios_message);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return_from_write:
|
|
if (bx_dbg.unsupported_io)
|
|
switch (io_len) {
|
|
case 1:
|
|
BX_INFO(("unmapped: 8-bit write to %04x = %02x", address, value));
|
|
break;
|
|
case 2:
|
|
BX_INFO(("unmapped: 16-bit write to %04x = %04x", address, value));
|
|
break;
|
|
case 4:
|
|
BX_INFO(("unmapped: 32-bit write to %04x = %08x", address, value));
|
|
break;
|
|
default:
|
|
BX_INFO(("unmapped: ??-bit write to %04x = %x", address, value));
|
|
break;
|
|
}
|
|
}
|