/* Hey EMACS -*- linux-c -*- */ /* $Id: mem.c 2601 2007-07-14 08:49:30Z roms $ */ /* TiEmu - Tiemu Is an EMUlator * * Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin * Copyright (c) 2001-2003, Romain Lievin * Copyright (c) 2003, Julien Blache * Copyright (c) 2004, Romain Li�vin * Copyright (c) 2005, Romain Li�vin, Kevin Kofler * Copyright (c) 2007, Romain Li�vin * * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Memory management: RAM, PROM/FLASH, I/O ports and bkpts */ #include #include #include #include #include "../dbg/bkpts.h" #include "../images.h" #include "../ti68k_def.h" #include "../ti68k_int.h" #include "../uae/libuae.h" #include "hw.h" #include "hwprot.h" #include "m68k.h" #include "mem.h" #include "mem89.h" #include "mem89tm.h" #include "mem92.h" #include "mem92p.h" #include "memv2.h" #include "ports.h" static IMG_INFO *img = &img_infos; // 000000-0fffff : RAM (128 or 256 KB) // 100000-1fffff : // 200000-2fffff : internal ROM (TI92, TI89, V200) or unused // 300000-3fffff : idem // 400000-4fffff : external ROM (TI92, TI92-II, TI92+) or unused // 500000-5fffff : idem // 600000-6fffff : memory mapped I/O (all HW) // 700000-7fffff : memory mapped I/O (HW2, HW3) // 800000-8fffff : ROM (TI89 Titanium) or unused // 900000-9fffff : idem // a00000-afffff : idem // b00000-bfffff : idem // c00000-cfffff : unused // d00000-dfffff : ... // e00000-efffff : ... // d00000-ffffff : unused static GETBYTE_FUNC get_byte_ptr; // set on memXX.c or hwprot.c static GETWORD_FUNC get_word_ptr; static GETLONG_FUNC get_long_ptr; static PUTBYTE_FUNC put_byte_ptr; static PUTWORD_FUNC put_word_ptr; static PUTLONG_FUNC put_long_ptr; GETBYTE_FUNC mem_get_byte_ptr; // set by memXX.c:tiXX_mem_init GETWORD_FUNC mem_get_word_ptr; GETLONG_FUNC mem_get_long_ptr; PUTBYTE_FUNC mem_put_byte_ptr; PUTWORD_FUNC mem_put_word_ptr; PUTLONG_FUNC mem_put_long_ptr; REALADR_FUNC mem_get_real_addr_ptr; /* Mem init/exit */ int hw_mem_init(void) { // get memory sizes if(tihw.ti92v2) { // TI92 II is same as TI92+ in memory size tihw.rom_size = ti68k_get_rom_size(TI92p); tihw.ram_size = ti68k_get_ram_size(TI92p); tihw.io_size = ti68k_get_io_size(TI92p); } else { tihw.rom_size = ti68k_get_rom_size(tihw.calc_type); tihw.ram_size = ti68k_get_ram_size(tihw.calc_type); tihw.io_size = ti68k_get_io_size(tihw.calc_type); tihw.io2_size = ti68k_get_io2_size(tihw.calc_type); tihw.io3_size = ti68k_get_io3_size(tihw.calc_type); } // allocate mem tihw.ram = malloc(tihw.ram_size); tihw.rom = malloc(tihw.rom_size); tihw.io = malloc(tihw.io_size); tihw.io2 = malloc(tihw.io2_size); tihw.io3 = malloc(tihw.io3_size); tihw.unused = malloc(16); // clear RAM/ROM/IO memset(tihw.ram, 0x00, tihw.ram_size); memset(tihw.io, 0x00, tihw.io_size); memset(tihw.io2, 0x00, tihw.io2_size); memset(tihw.io2, 0x00, tihw.io3_size); memset(tihw.rom, 0xff, tihw.rom_size); memset(tihw.unused, 0x14, 16); // set banks and mappers on per calc basis switch(tihw.calc_type) { case TI92: ti92_mem_init(); break; case TI92p: ti92p_mem_init(); break; case TI89: ti89_mem_init(); break; case V200: v200_mem_init(); break; case TI89t: ti89t_mem_init(); break; default: break; } // blit ROM memcpy(tihw.rom, img->data, img->size); free(img->data); if(!tihw.ram || !tihw.rom || !tihw.io || !tihw.io2) return -1; // set memory mappers for hw protection if(params.hw_protect && (tihw.calc_type != TI92)) { get_byte_ptr = hwp_get_byte; get_word_ptr = hwp_get_word; get_long_ptr = hwp_get_long; put_byte_ptr = hwp_put_byte; put_word_ptr = hwp_put_word; put_long_ptr = hwp_put_long; } else { get_byte_ptr = mem_get_byte_ptr; get_word_ptr = mem_get_word_ptr; get_long_ptr = mem_get_long_ptr; put_byte_ptr = mem_put_byte_ptr; put_word_ptr = mem_put_word_ptr; put_long_ptr = mem_put_long_ptr; } return 0; } int hw_mem_reset(void) { return 0; } int hw_mem_exit(void) { // free memory if(tihw.ram) free(tihw.ram); tihw.ram = NULL; if(tihw.rom) free(tihw.rom); tihw.rom = NULL; if(tihw.io) free(tihw.io); tihw.io = NULL; if(tihw.io2) free(tihw.io2); tihw.io2 = NULL; if(tihw.io3) free(tihw.io3); tihw.io3 = NULL; // clear breakpoints ti68k_bkpt_clear_access(); ti68k_bkpt_clear_range(); return 0; } uint8_t *hw_get_real_address(uint32_t adr) { return mem_get_real_addr_ptr(adr); } uint32_t hw_get_long(uint32_t adr) { adr &= 0xFFFFFF; // Odd address: exception ! if(adr & 1) { regs.spcflags |= SPCFLAG_ADRERR; return 0; } return get_long_ptr(adr); } uint16_t hw_get_word(uint32_t adr) { adr &= 0xFFFFFF; // Odd address: exception ! if(adr & 1) { regs.spcflags |= SPCFLAG_ADRERR; return 0; } return get_word_ptr(adr); } uint8_t hw_get_byte(uint32_t adr) { adr &= 0xFFFFFF; return get_byte_ptr(adr); } uint8_t hw_get_byte_noexcept(uint32_t adr) { adr &= 0xFFFFFF; return get_byte_ptr(adr); } void hw_put_long(uint32_t adr, uint32_t arg) { adr &= 0xFFFFFF; // Odd address: exception ! if(adr & 1) { regs.spcflags |= SPCFLAG_ADRERR; return; } // Protected memory violation. Triggered when memory below [$000120] is // written while bit 2 of [$600001] is set if((adr < 0x120) && io_bit_tst(0x01, 2)) hw_m68k_irq(7); else put_long_ptr(adr, arg); } void hw_put_word(uint32_t adr, uint16_t arg) { adr &= 0xFFFFFF; // Odd address: exception ! if(adr & 1) { regs.spcflags |= SPCFLAG_ADRERR; return; } // Protected memory violation. Triggered when memory below [$000120] is // written while bit 2 of [$600001] is set if((adr < 0x120) && io_bit_tst(0x01, 2)) hw_m68k_irq(7); else put_word_ptr(adr, arg); } void hw_put_byte(uint32_t adr, uint8_t arg) { adr &= 0xFFFFFF; // Protected memory violation. Triggered when memory below [$000120] is // written while bit 2 of [$600001] is set if((adr < 0x120) && io_bit_tst(0x01, 2)) hw_m68k_irq(7); else put_byte_ptr(adr, arg); } void hw_put_byte_noexcept(uint32_t adr, uint8_t arg) { adr &= 0xFFFFFF; put_byte_ptr(adr, arg); }