mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
alto2: refactor display and CROM/RAM config (nw)
Refactor the display to use a buffer of the size of the total margins. Remove the deprecated MCFG_SCREEN_REFRESH_RATE(). Try to synchronize the CPU on the vertical sync generated by mame calling the screen_update() function. Instead of a fixed CROM/CRAM configuration defined through macros, make this a machine configuration parameter. You can now choose between the 3 setups: 1 = 1K CROM, 1K CRAM, 1 S register bank 2 = 2K CROM, 1K CRAM, 1 S register bank 3 = 1K CROM, 3K CRAM, 8 S register banks TODO: Some games which used to work in Salto do no longer work with this driver, e.g. pacman7 from the allgames.chd
This commit is contained in:
parent
32acbb190b
commit
de6745296b
@ -37,31 +37,11 @@ void alto2_cpu_device::f2_late_load_csr()
|
||||
|
||||
/**
|
||||
* @brief curt_activate: called by the CPU when the cursor task becomes active
|
||||
*
|
||||
* Shift CSR to xpreg % 16 position to make it easier to
|
||||
* to handle the word xor in unload_word().
|
||||
* <PRE>
|
||||
* xpreg % 16 cursor bits
|
||||
* [ first word ][ second word ]
|
||||
* ----------------------------------------------
|
||||
* 0 xxxxxxxxxxxxxxxx0000000000000000
|
||||
* 1 0xxxxxxxxxxxxxxxx000000000000000
|
||||
* 2 00xxxxxxxxxxxxxxxx00000000000000
|
||||
* ...
|
||||
* 14 00000000000000xxxxxxxxxxxxxxxx00
|
||||
* 15 000000000000000xxxxxxxxxxxxxxxx0
|
||||
* </PRE>
|
||||
*/
|
||||
void alto2_cpu_device::activate_curt()
|
||||
{
|
||||
m_task_wakeup &= ~(1 << m_task);
|
||||
m_dsp.curt_wakeup = false;
|
||||
|
||||
int x = 01777 - m_dsp.xpreg;
|
||||
UINT32 bits = m_dsp.csr << (16 - (x & 15));
|
||||
m_dsp.cursor0 = static_cast<UINT16>(bits >> 16);
|
||||
m_dsp.cursor1 = static_cast<UINT16>(bits);
|
||||
m_dsp.curxpos = x / 16;
|
||||
}
|
||||
|
||||
/** @brief initialize the cursor task F1 and F2 functions */
|
||||
@ -79,6 +59,4 @@ void alto2_cpu_device::reset_curt()
|
||||
m_dsp.curt_blocks = false;
|
||||
m_dsp.xpreg = 0;
|
||||
m_dsp.csr = 0;
|
||||
m_dsp.curxpos = 0;
|
||||
m_dsp.cursor0 = m_dsp.cursor1 = 0;
|
||||
}
|
||||
|
@ -245,11 +245,12 @@ static const UINT16 double_bits[256] = {
|
||||
//! update the internal frame buffer and draw the scanline segment if changed
|
||||
void alto2_cpu_device::update_framebuf_word(UINT16* framebuf, int x, int y, UINT16 word)
|
||||
{
|
||||
int xpword = (m_dsp.xpreg ^ 01777) / 16;
|
||||
// mixing with the cursor
|
||||
if (x == m_dsp.curxpos + 0)
|
||||
word ^= m_dsp.cursor0;
|
||||
if (x == m_dsp.curxpos + 1)
|
||||
word ^= m_dsp.cursor1;
|
||||
if (x == xpword++)
|
||||
word ^= (m_dsp.csr << (m_dsp.xpreg % 16)) >> 16;
|
||||
if (x == xpword)
|
||||
word ^= (m_dsp.csr << (m_dsp.xpreg % 16)) & 0xffff;
|
||||
// no change?
|
||||
if (word == framebuf[x])
|
||||
return;
|
||||
@ -263,14 +264,14 @@ void alto2_cpu_device::update_framebuf_word(UINT16* framebuf, int x, int y, UINT
|
||||
void alto2_cpu_device::unload_word()
|
||||
{
|
||||
int x = m_unload_word;
|
||||
int y = ((m_dsp.hlc - m_dsp.vblank) & ~02001) ^ HLC1024;
|
||||
int y = m_dsp.scanline;
|
||||
|
||||
if (y < 0 || y >= ALTO2_DISPLAY_HEIGHT || x >= ALTO2_DISPLAY_VISIBLE_WORDS)
|
||||
if (y < 0 || y >= ALTO2_DISPLAY_TOTAL_HEIGHT || x >= ALTO2_DISPLAY_VISIBLE_WORDS)
|
||||
{
|
||||
m_unload_time = -1;
|
||||
return;
|
||||
}
|
||||
UINT16* framebuf = m_dsp.framebuf.get() + y * ALTO2_DISPLAY_SCANLINE_WORDS;
|
||||
UINT16* framebuf = m_dsp.framebuf.get() + y * ALTO2_DISPLAY_SCANLINE_WORDS;
|
||||
UINT16 word = m_dsp.inverse;
|
||||
UINT8 a38 = m_disp_a38[m_dsp.ra * 16 + m_dsp.wa];
|
||||
if (FIFO_MBEMPTY(a38))
|
||||
@ -329,8 +330,14 @@ void alto2_cpu_device::display_state_machine()
|
||||
{
|
||||
// count horizontal line counters and wrap
|
||||
m_dsp.hlc += 1;
|
||||
if (m_dsp.hlc > ALTO2_DISPLAY_HLC_END)
|
||||
if (m_dsp.hlc > ALTO2_DISPLAY_HLC_END) {
|
||||
m_dsp.hlc = ALTO2_DISPLAY_HLC_START;
|
||||
m_dsp.scanline = 30;
|
||||
m_dsp.vsync = true;
|
||||
} else if (m_dsp.hlc == 1024) {
|
||||
m_dsp.vsync = true;
|
||||
m_dsp.scanline = 31;
|
||||
}
|
||||
// wake up the memory refresh task _twice_ on each scanline
|
||||
m_task_wakeup |= 1 << task_mrt;
|
||||
}
|
||||
@ -342,9 +349,6 @@ void alto2_cpu_device::display_state_machine()
|
||||
|
||||
if (A66_VBLANK(a66))
|
||||
{
|
||||
// Rising edge of VBLANK: remember HLC[1-10] where the VBLANK starts
|
||||
m_dsp.vblank = m_dsp.hlc & ~(1 << 10);
|
||||
|
||||
LOG((this,LOG_DISPL,1, " VBLANK"));
|
||||
|
||||
// VSYNC is always within VBLANK, thus we handle it only here
|
||||
@ -357,6 +361,7 @@ void alto2_cpu_device::display_state_machine()
|
||||
*/
|
||||
m_task_wakeup |= 1 << task_dvt;
|
||||
}
|
||||
m_dsp.inverse = 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -385,9 +390,10 @@ void alto2_cpu_device::display_state_machine()
|
||||
}
|
||||
if (!A63_HBLANK(a63) && A63_HBLANK(m_dsp.a63))
|
||||
{
|
||||
m_dsp.scanline += 2;
|
||||
// Falling edge of a63 HBLANK starts unloading of FIFO words
|
||||
LOG((this,LOG_DISPL,1, " HBLANK\\ UNLOAD"));
|
||||
m_unload_time = ALTO2_DISPLAY_BITTIME(m_dsp.halfclock ? 32 : 16);
|
||||
m_unload_time = ALTO2_DISPLAY_BITTIME(m_dsp.halfclock ? 40+32 : 40+16);
|
||||
m_unload_word = 0;
|
||||
}
|
||||
}
|
||||
@ -470,7 +476,7 @@ void alto2_cpu_device::display_state_machine()
|
||||
*/
|
||||
void alto2_cpu_device::f2_late_evenfield()
|
||||
{
|
||||
UINT16 r = HLC1024 ^ 1;
|
||||
UINT16 r = m_dsp.odd ? 0 : 1;
|
||||
LOG((this,LOG_DISPL,2," EVENFIELD branch (%#o | %#o)\n", m_next2, r));
|
||||
m_next2 |= r;
|
||||
}
|
||||
@ -499,12 +505,8 @@ void alto2_cpu_device::init_disp()
|
||||
save_item(NAME(m_dsp.dwt_blocks));
|
||||
save_item(NAME(m_dsp.curt_blocks));
|
||||
save_item(NAME(m_dsp.curt_wakeup));
|
||||
save_item(NAME(m_dsp.vblank));
|
||||
save_item(NAME(m_dsp.xpreg));
|
||||
save_item(NAME(m_dsp.csr));
|
||||
save_item(NAME(m_dsp.curxpos));
|
||||
save_item(NAME(m_dsp.cursor0));
|
||||
save_item(NAME(m_dsp.cursor1));
|
||||
|
||||
m_disp_a38 = prom_load(machine(), &pl_displ_a38, memregion("displ_a38")->base());
|
||||
m_disp_a63 = prom_load(machine(), &pl_displ_a63, memregion("displ_a63")->base());
|
||||
@ -512,7 +514,7 @@ void alto2_cpu_device::init_disp()
|
||||
|
||||
m_dsp.hlc = ALTO2_DISPLAY_HLC_START;
|
||||
|
||||
m_dsp.framebuf = std::make_unique<UINT16[]>(ALTO2_DISPLAY_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS);
|
||||
m_dsp.framebuf = std::make_unique<UINT16[]>(ALTO2_DISPLAY_TOTAL_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS);
|
||||
m_dsp.patterns = auto_alloc_array(machine(), UINT8, 65536 * 16);
|
||||
for (int y = 0; y < 65536; y++) {
|
||||
UINT8* dst = m_dsp.patterns + y * 16;
|
||||
@ -520,7 +522,8 @@ void alto2_cpu_device::init_disp()
|
||||
*dst++ = (~y >> (15 - x)) & 1;
|
||||
}
|
||||
|
||||
m_dsp.bitmap = std::make_unique<bitmap_ind16>(ALTO2_DISPLAY_WIDTH, ALTO2_DISPLAY_HEIGHT);
|
||||
// Allocate a bitmap including the V/H blank areas
|
||||
m_dsp.bitmap = std::make_unique<bitmap_ind16>(ALTO2_DISPLAY_TOTAL_WIDTH, ALTO2_DISPLAY_TOTAL_HEIGHT);
|
||||
m_dsp.state = 0;
|
||||
}
|
||||
|
||||
@ -537,6 +540,7 @@ void alto2_cpu_device::reset_disp()
|
||||
m_dsp.a66 = 0;
|
||||
m_dsp.setmode = 0;
|
||||
m_dsp.inverse = 0;
|
||||
m_dsp.scanline = 30;
|
||||
m_dsp.halfclock = false;
|
||||
m_dsp.wa = 0;
|
||||
m_dsp.ra = 0;
|
||||
@ -544,12 +548,10 @@ void alto2_cpu_device::reset_disp()
|
||||
m_dsp.dwt_blocks = false;
|
||||
m_dsp.curt_blocks = false;
|
||||
m_dsp.curt_wakeup = false;
|
||||
m_dsp.vblank = 0;
|
||||
m_dsp.vsync = false;
|
||||
m_dsp.odd = false;
|
||||
m_dsp.xpreg = 0;
|
||||
m_dsp.csr = 0;
|
||||
m_dsp.curxpos = 0;
|
||||
m_dsp.cursor0 = 0;
|
||||
m_dsp.cursor1 = 0;
|
||||
memset(m_dsp.framebuf.get(), 1, sizeof(UINT16) * ALTO2_DISPLAY_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS);
|
||||
}
|
||||
|
||||
@ -557,10 +559,7 @@ void alto2_cpu_device::reset_disp()
|
||||
UINT32 alto2_cpu_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap(bitmap, *m_dsp.bitmap, 0, 0, 0, 0, cliprect);
|
||||
m_dsp.vsync = false;
|
||||
m_dsp.odd = !m_dsp.odd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void alto2_cpu_device::screen_eof(screen_device &screen, bool state)
|
||||
{
|
||||
// FIXME: do we need this in some way?
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
* scanlines to the monitor. The frame rate is 60Hz, which is actually the rate
|
||||
* of the half-frames. The rate for full frames is thus 30Hz.
|
||||
*/
|
||||
#define ALTO2_DISPLAY_TOTAL_HEIGHT ((ALTO2_DISPLAY_HLC_END - ALTO2_DISPLAY_HLC_START) / 2)
|
||||
#define ALTO2_DISPLAY_TOTAL_HEIGHT ((ALTO2_DISPLAY_HLC_END + 1 - ALTO2_DISPLAY_HLC_START) / 2)
|
||||
|
||||
/**
|
||||
* @brief display total width, including horizontal blanking
|
||||
@ -80,7 +80,8 @@
|
||||
#define ALTO2_DISPLAY_HEIGHT 808
|
||||
|
||||
//! Visible width of the display; 38 x 16 bit words - 2 pixels.
|
||||
#define ALTO2_DISPLAY_WIDTH 606
|
||||
//#define ALTO2_DISPLAY_WIDTH 606
|
||||
#define ALTO2_DISPLAY_WIDTH 608
|
||||
|
||||
//! Visible words per scanline.
|
||||
#define ALTO2_DISPLAY_VISIBLE_WORDS ((ALTO2_DISPLAY_WIDTH+15)/16)
|
||||
@ -197,7 +198,10 @@ struct {
|
||||
UINT32 hlc; //!< horizontal line counter
|
||||
UINT32 setmode; //!< value written by last SETMODE<-
|
||||
UINT32 inverse; //!< set to 0xffff if line is inverse, 0x0000 otherwise
|
||||
UINT32 scanline; //!< current scanline
|
||||
bool halfclock; //!< false for normal pixel clock, true for half pixel clock
|
||||
bool vsync; //!< true after vsync, false when end_of_frame was called
|
||||
bool odd; //!< true if odd field
|
||||
UINT16 fifo[ALTO2_DISPLAY_FIFO]; //!< display word fifo
|
||||
UINT32 wa; //!< fifo input pointer (write address; 4-bit)
|
||||
UINT32 ra; //!< fifo output pointer (read address; 4-bit)
|
||||
@ -207,12 +211,8 @@ struct {
|
||||
bool dwt_blocks; //!< set true, if the DWT executed BLOCK
|
||||
bool curt_blocks; //!< set true, if the CURT executed BLOCK
|
||||
bool curt_wakeup; //!< set true, if CURT wakeups are generated
|
||||
UINT32 vblank; //!< most recent HLC with VBLANK still high (11-bit)
|
||||
UINT32 xpreg; //!< cursor cursor x position register (10-bit)
|
||||
UINT32 csr; //!< cursor shift register (16-bit)
|
||||
UINT32 curxpos; //!< helper: first cursor word in scanline
|
||||
UINT32 cursor0; //!< helper: shifted cursor data for left word
|
||||
UINT32 cursor1; //!< helper: shifted cursor data for right word
|
||||
std::unique_ptr<UINT16[]> framebuf; //!< array of words of the raw bitmap that is displayed
|
||||
UINT8 *patterns; //!< array of 65536 patterns (16 bytes) with 1 byte per pixel
|
||||
std::unique_ptr<bitmap_ind16> bitmap; //!< MAME bitmap with 16 bit indices
|
||||
|
@ -42,25 +42,27 @@
|
||||
#define FIFO_STOPWAKE(a38) (0 == (a38 & disp_a38_STOPWAKE) ? true : false)
|
||||
|
||||
/**
|
||||
* @brief block the display word task
|
||||
* @brief Block the display word task.
|
||||
*/
|
||||
void alto2_cpu_device::f1_early_dwt_block()
|
||||
{
|
||||
m_dsp.dwt_blocks = true;
|
||||
|
||||
/* clear the wakeup for the display word task */
|
||||
// Clear the wakeup for the display word task
|
||||
m_task_wakeup &= ~(1 << m_task);
|
||||
LOG((this,LOG_DWT,2," BLOCK %s\n", task_name(m_task)));
|
||||
|
||||
/* wakeup the display horizontal task, if it didn't block itself */
|
||||
// Wakeup the display horizontal task, if it didn't block itself
|
||||
if (!m_dsp.dht_blocks)
|
||||
m_task_wakeup |= 1 << task_dht;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the display data register
|
||||
* @brief Load the display data register
|
||||
* Pushes the word on the bus to the display FIFO.
|
||||
* If the FIFO becomes full, the wakeup flag for task_dwt is reset.
|
||||
*/
|
||||
void alto2_cpu_device::f2_late_dwt_load_ddr()
|
||||
void alto2_cpu_device::f2_late_load_ddr()
|
||||
{
|
||||
LOG((this,LOG_DWT,2," DDR<- BUS (%#o)\n", m_bus));
|
||||
m_dsp.fifo[m_dsp.wa] = m_bus;
|
||||
|
@ -17,7 +17,7 @@ enum {
|
||||
};
|
||||
|
||||
void f1_early_dwt_block(); //!< F1 func: block the display word task
|
||||
void f2_late_dwt_load_ddr(); //!< F2 func: load the display data register
|
||||
void f2_late_load_ddr(); //!< F2 func: load the display data register
|
||||
void init_dwt(int task = task_dwt); //!< initialize the display word task
|
||||
void exit_dwt(); //!< deinitialize the display word task
|
||||
void reset_dwt(); //!< reset the display word task
|
||||
|
@ -230,7 +230,7 @@ WRITE16_MEMBER( alto2_cpu_device::mouse_buttons_w ) { X_WRBITS(m_hw.utilin,16,13
|
||||
/**
|
||||
* @brief read the UTILIN port
|
||||
*
|
||||
* @param addr memory mapped I/O address to be read
|
||||
* @param offset memory mapped I/O address to be read
|
||||
* @return current value on the UTILIN port
|
||||
*/
|
||||
READ16_MEMBER( alto2_cpu_device::utilin_r )
|
||||
@ -250,7 +250,7 @@ READ16_MEMBER( alto2_cpu_device::utilin_r )
|
||||
/**
|
||||
* @brief read the XBUS port
|
||||
*
|
||||
* @param addr memory mapped I/O address to be read
|
||||
* @param offset memory mapped I/O address to be read
|
||||
* @return current value on the XBUS port latch
|
||||
*/
|
||||
READ16_MEMBER( alto2_cpu_device::xbus_r )
|
||||
|
@ -7,16 +7,13 @@
|
||||
*****************************************************************************/
|
||||
#include "alto2cpu.h"
|
||||
|
||||
#define DEBUG_WRTRAM 0 //!< define to 1 to printf disassembled CRAM writes
|
||||
#define DEBUG_WRTRAM 1 //!< define to 1 to print CRAM writes
|
||||
#define DEBUG_RDRAM 1 //!< define to 1 to print CRAM reads
|
||||
#define DEBUG_BRANCH 1 //!< define to 1 to print branching to ROM/RAM
|
||||
|
||||
//! direct read access to the microcode CRAM
|
||||
#define RD_CRAM(addr) (*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + addr * 4))
|
||||
|
||||
//! direct write access to the microcode CRAM
|
||||
#define WR_CRAM(addr,data) do { \
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + addr * 4) = data; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief read the microcode ROM/RAM halfword
|
||||
*
|
||||
@ -88,17 +85,30 @@ void alto2_cpu_device::rdram()
|
||||
}
|
||||
|
||||
m_rdram_flag = false;
|
||||
if (ALTO2_UCODE_RAM_BASE + addr >= ALTO2_UCODE_SIZE) {
|
||||
if (m_ucode_ram_base + addr >= m_ucode_size) {
|
||||
value = 0177777; /* ??? */
|
||||
LOG((this,LOG_CPU,0,"invalid address (%06o)\n", addr));
|
||||
#if DEBUG_RDRAM
|
||||
printf("RD CRAM_BANKSEL=%d RAM%d [%04o] invalid address!\n",
|
||||
GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
value = RD_CRAM(addr) ^ ALTO2_UCODE_INVERTED;
|
||||
value = *reinterpret_cast<UINT32 *>(m_ucode_cram.get() + addr * 4) ^ ALTO2_UCODE_INVERTED;
|
||||
#if DEBUG_RDRAM
|
||||
char buffer[256];
|
||||
UINT8* oprom = m_ucode_cram.get() + 4 * wordaddr;
|
||||
disasm_disassemble(buffer, wordaddr, oprom, oprom, 0);
|
||||
printf("RD CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o value:%011o '%s'\n",
|
||||
GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu,
|
||||
value, buffer);
|
||||
#endif
|
||||
if (GET_CRAM_HALFSEL(m_cram_addr)) {
|
||||
value = value >> 16;
|
||||
LOG((this,LOG_CPU,0,"upper:%06o\n", value & 0177777));
|
||||
value >>= 16;
|
||||
LOG((this,LOG_CPU,0,"upper:%06o\n", value));
|
||||
} else {
|
||||
LOG((this,LOG_CPU,0,"lower:%06o\n", value & 0177777));
|
||||
value &= 0177777;
|
||||
LOG((this,LOG_CPU,0,"lower:%06o\n", value));
|
||||
}
|
||||
m_bus &= value;
|
||||
}
|
||||
@ -115,25 +125,29 @@ void alto2_cpu_device::rdram()
|
||||
*/
|
||||
void alto2_cpu_device::wrtram()
|
||||
{
|
||||
UINT32 bank = GET_CRAM_BANKSEL(m_cram_addr);
|
||||
UINT32 wordaddr = GET_CRAM_WORDADDR(m_cram_addr);
|
||||
UINT32 value = ((m_myl << 16) | m_alu) ^ ALTO2_UCODE_INVERTED;
|
||||
const UINT32 bank = GET_CRAM_BANKSEL(m_cram_addr);
|
||||
const UINT32 wordaddr = GET_CRAM_WORDADDR(m_cram_addr);
|
||||
const UINT32 addr = bank * ALTO2_UCODE_PAGE_SIZE + wordaddr; // write RAM 0,1,2
|
||||
const UINT32 value = (m_myl << 16) | m_alu;
|
||||
|
||||
UINT32 addr = bank * ALTO2_UCODE_PAGE_SIZE + wordaddr; // write RAM 0,1,2
|
||||
LOG((this,LOG_CPU,0," wrtram: RAM%d [%04o] upper:%06o lower:%06o", bank, wordaddr, m_myl, m_alu));
|
||||
|
||||
#if DEBUG_WRTRAM
|
||||
printf("WR CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o\n",
|
||||
GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu);
|
||||
#endif
|
||||
|
||||
m_wrtram_flag = false;
|
||||
if (ALTO2_UCODE_RAM_BASE + addr >= ALTO2_UCODE_SIZE) {
|
||||
if (m_ucode_ram_base + addr >= m_ucode_size) {
|
||||
LOG((this,LOG_CPU,0," invalid address %06o\n", addr));
|
||||
return;
|
||||
}
|
||||
LOG((this,LOG_CPU,0,"\n"));
|
||||
WR_CRAM(addr, value);
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + addr * 4) = value ^ ALTO2_UCODE_INVERTED;
|
||||
|
||||
#if DEBUG_WRTRAM
|
||||
char buffer[256];
|
||||
UINT8* oprom = m_ucode_cram.get() + 4 * wordaddr;
|
||||
disasm_disassemble(buffer, wordaddr, oprom, oprom, 0);
|
||||
printf("WR CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o value:%011o '%s'\n",
|
||||
GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu,
|
||||
value, buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,6 +197,9 @@ void alto2_cpu_device::bs_late_load_sreg()
|
||||
void alto2_cpu_device::branch_ROM(const char *from, int page)
|
||||
{
|
||||
(void)from;
|
||||
#if DEBUG_BRANCH
|
||||
printf("SWMODE: branch from %s to ROM%d (%#o)\n", from, page, m_next2);
|
||||
#endif
|
||||
m_next2 = (m_next2 & ALTO2_UCODE_PAGE_MASK) + page * ALTO2_UCODE_PAGE_SIZE;
|
||||
LOG((this,LOG_RAM,2," SWMODE: branch from %s to ROM%d (%#o)\n", from, page, m_next2));
|
||||
}
|
||||
@ -193,7 +210,10 @@ void alto2_cpu_device::branch_ROM(const char *from, int page)
|
||||
void alto2_cpu_device::branch_RAM(const char *from, int page)
|
||||
{
|
||||
(void)from;
|
||||
m_next2 = (m_next2 & ALTO2_UCODE_PAGE_MASK) + ALTO2_UCODE_RAM_BASE + page * ALTO2_UCODE_PAGE_SIZE;
|
||||
#if DEBUG_BRANCH
|
||||
printf("SWMODE: branch from %s to RAM%d (%#o)\n", from, page, m_next2);
|
||||
#endif
|
||||
m_next2 = (m_next2 & ALTO2_UCODE_PAGE_MASK) + m_ucode_ram_base + page * ALTO2_UCODE_PAGE_SIZE;
|
||||
LOG((this,LOG_RAM,2," SWMODE: branch from %s to RAM%d\n", from, page, m_next2));
|
||||
}
|
||||
|
||||
@ -211,147 +231,152 @@ void alto2_cpu_device::branch_RAM(const char *from, int page)
|
||||
*/
|
||||
void alto2_cpu_device::f1_late_swmode()
|
||||
{
|
||||
/* currently executing in what page? */
|
||||
UINT16 current = m_mpc / ALTO2_UCODE_PAGE_SIZE;
|
||||
// Currently executing in what CROM/CRAM page?
|
||||
UINT16 page = m_mpc / ALTO2_UCODE_PAGE_SIZE;
|
||||
UINT16 next;
|
||||
|
||||
#if (ALTO2_UCODE_ROM_PAGES == 1 && ALTO2_UCODE_RAM_PAGES == 1)
|
||||
switch (current) {
|
||||
case 0:
|
||||
branch_RAM("ROM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_ROM("RAM0", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible current mpc %d\n", current);
|
||||
}
|
||||
#endif
|
||||
#if (ALTO2_UCODE_ROM_PAGES == 2 && ALTO2_UCODE_RAM_PAGES == 1)
|
||||
UINT16 next = X_RDBITS(m_next2,10,1,1);
|
||||
|
||||
switch (current) {
|
||||
case 0: /* ROM0 to RAM0 or ROM1 */
|
||||
switch (next) {
|
||||
switch (m_cram_config) {
|
||||
case 1: // 1K CROM, 1K CRAM
|
||||
switch (page) {
|
||||
case 0:
|
||||
branch_RAM("ROM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_ROM("ROM0", 1);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
}
|
||||
break;
|
||||
case 1: /* ROM1 to ROM0 or RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("ROM1", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("ROM1", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
}
|
||||
break;
|
||||
case 2: /* RAM0 to ROM0 or ROM1 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_ROM("RAM0", 1);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
fatal(1, "Impossible current mpc %u\n", page);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible current mpc %d\n", current);
|
||||
}
|
||||
#endif
|
||||
#if (ALTO2_UCODE_ROM_PAGES == 1 && ALTO2_UCODE_RAM_PAGES == 3)
|
||||
UINT16 next = X_RDBITS(m_next2,10,1,2);
|
||||
|
||||
switch (current) {
|
||||
case 0: /* ROM0 to RAM0, RAM2, RAM1, RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_RAM("ROM0", 0);
|
||||
case 2: // 2K CROM, 1K CRAM
|
||||
next = X_RDBITS(m_next2,10,1,1);
|
||||
switch (page) {
|
||||
case 0: /* ROM0 to RAM0 or ROM1 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_RAM("ROM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_ROM("ROM0", 1);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("ROM0", 2);
|
||||
case 1: /* ROM1 to ROM0 or RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("ROM1", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("ROM1", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("ROM0", 1);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("ROM0", 0);
|
||||
case 2: /* RAM0 to ROM0 or ROM1 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_ROM("RAM0", 1);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
fatal(1, "Impossible current mpc %u\n", page);
|
||||
}
|
||||
break;
|
||||
case 1: /* RAM0 to ROM0, RAM2, RAM1, RAM1 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM0", 0);
|
||||
|
||||
case 3: // 1K CROM, 3K CRAM
|
||||
next = X_RDBITS(m_next2,10,1,2);
|
||||
|
||||
switch (page) {
|
||||
case 0: /* ROM0 to RAM0, RAM2, RAM1, RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_RAM("ROM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("ROM0", 2);
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("ROM0", 1);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("ROM0", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("RAM0", 2);
|
||||
case 1: /* RAM0 to ROM0, RAM2, RAM1, RAM1 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM0", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("RAM0", 2);
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("RAM0", 1);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("RAM0", 1);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("RAM0", 1);
|
||||
case 2: /* RAM1 to ROM0, RAM2, RAM0, RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM1", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("RAM1", 2);
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("RAM1", 0);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("RAM1", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("RAM0", 1);
|
||||
case 3: /* RAM2 to ROM0, RAM1, RAM0, RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM2", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("RAM2", 1);
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("RAM2", 0);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("RAM2", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %u\n", next);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
}
|
||||
break;
|
||||
case 2: /* RAM1 to ROM0, RAM2, RAM0, RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM1", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("RAM1", 2);
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("RAM1", 0);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("RAM1", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
}
|
||||
break;
|
||||
case 3: /* RAM2 to ROM0, RAM1, RAM0, RAM0 */
|
||||
switch (next) {
|
||||
case 0:
|
||||
branch_ROM("RAM2", 0);
|
||||
break;
|
||||
case 1:
|
||||
branch_RAM("RAM2", 1);
|
||||
break;
|
||||
case 2:
|
||||
branch_RAM("RAM2", 0);
|
||||
break;
|
||||
case 3:
|
||||
branch_RAM("RAM2", 0);
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible next %d\n", next);
|
||||
fatal(1, "Impossible current mpc %u\n", page);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal(1, "Impossible current mpc %d\n", current);
|
||||
fatal(1, "Impossible control ROM/RAM config %u (%u CROM pages, %u CRAM pages)\n",
|
||||
m_cram_config, m_ucode_rom_pages, m_ucode_ram_pages);
|
||||
}
|
||||
#else
|
||||
fatal(1, "Impossible control ROM/RAM combination %d/%d\n", ALTO2_UCODE_ROM_PAGES, ALTO2_UCODE_RAM_PAGES);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -372,8 +397,6 @@ void alto2_cpu_device::f1_late_rdram()
|
||||
LOG((this,LOG_RAM,2," RDRAM\n"));
|
||||
}
|
||||
|
||||
#if (ALTO2_UCODE_RAM_PAGES == 3)
|
||||
|
||||
/**
|
||||
* @brief f1_load_rmr late: load the reset mode register
|
||||
*
|
||||
@ -386,16 +409,17 @@ void alto2_cpu_device::f1_late_load_rmr()
|
||||
LOG((this,LOG_RAM,2," RMR<-; BUS (%#o)\n", m_bus));
|
||||
m_reset_mode = m_bus;
|
||||
}
|
||||
#else // ALTO2_UCODE_RAM_PAGES != 3
|
||||
|
||||
/**
|
||||
* @brief f1_load_srb late: load the S register bank from BUS[12-14]
|
||||
* F1=013 corresponds to SRB<- in the emulator, if the RAM size is
|
||||
* just 1K. It sets the S register bank for the current task.
|
||||
*/
|
||||
void alto2_cpu_device::f1_late_load_srb()
|
||||
{
|
||||
m_s_reg_bank[m_task] = X_RDBITS(m_bus,16,12,14) % ALTO2_SREG_BANKS;
|
||||
m_s_reg_bank[m_task] = X_RDBITS(m_bus,16,12,14) % m_sreg_banks;
|
||||
LOG((this,LOG_RAM,2," SRB<-; srb[%d] := %#o\n", m_task, m_s_reg_bank[m_task]));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RAM related task slots initialization
|
||||
|
@ -7,35 +7,8 @@
|
||||
*****************************************************************************/
|
||||
#ifdef ALTO2_DEFINE_CONSTANTS
|
||||
|
||||
#if (ALTO2_CRAM_CONFIG==1)
|
||||
#define ALTO2_UCODE_ROM_PAGES 1 //!< number of microcode ROM pages
|
||||
#define ALTO2_UCODE_RAM_PAGES 1 //!< number of microcode RAM pages
|
||||
#elif (ALTO2_CRAM_CONFIG==2)
|
||||
#define ALTO2_UCODE_ROM_PAGES 2 //!< number of microcode ROM pages
|
||||
#define ALTO2_UCODE_RAM_PAGES 1 //!< number of microcode RAM pages
|
||||
#elif (ALTO2_CRAM_CONFIG==3)
|
||||
#define ALTO2_UCODE_ROM_PAGES 1 //!< number of microcode ROM pages
|
||||
#define ALTO2_UCODE_RAM_PAGES 3 //!< number of microcode RAM pages
|
||||
#else
|
||||
#error "Undefined CROM/CRAM configuration"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief number of S register banks
|
||||
* This depends on the number of RAM pages
|
||||
* 8 pages in 3K CRAM configuration
|
||||
* 1 page in 1K CRAM configurations
|
||||
*/
|
||||
#if (ALTO2_UCODE_RAM_PAGES == 3)
|
||||
#define ALTO2_SREG_BANKS 8
|
||||
#else
|
||||
#define ALTO2_SREG_BANKS 1
|
||||
#endif
|
||||
|
||||
#define ALTO2_UCODE_PAGE_SIZE 02000 //!< number of words of microcode
|
||||
#define ALTO2_UCODE_PAGE_MASK (ALTO2_UCODE_PAGE_SIZE-1) //!< mask for microcode ROM/RAM address
|
||||
#define ALTO2_UCODE_SIZE ((ALTO2_UCODE_ROM_PAGES + ALTO2_UCODE_RAM_PAGES) * ALTO2_UCODE_PAGE_SIZE) //!< total number of words of microcode
|
||||
#define ALTO2_UCODE_RAM_BASE (ALTO2_UCODE_ROM_PAGES * ALTO2_UCODE_PAGE_SIZE) //!< base offset for the RAM page(s)
|
||||
|
||||
#else // ALTO2_DEFINE_CONSTANTS
|
||||
#ifndef _A2RAM_H_
|
||||
@ -51,11 +24,8 @@ enum {
|
||||
f1_ram_swmode = f1_task_10, //!< f1 10: switch mode to CROM/CRAM in same page
|
||||
f1_ram_wrtram = f1_task_11, //!< f1 11: start WRTRAM cycle
|
||||
f1_ram_rdram = f1_task_12, //!< f1 12: start RDRAM cycle
|
||||
#if (ALTO2_UCODE_RAM_PAGES == 3)
|
||||
f1_ram_load_rmr = f1_task_13, //!< f1 13: load the reset mode register
|
||||
#else // ALTO2_UCODE_RAM_PAGES != 3
|
||||
f1_ram_load_srb = f1_task_13 //!< f1 14: load the S register bank from BUS[12-14]
|
||||
#endif
|
||||
f1_ram_load_srb = f1_task_13 //!< f1 13: load the S register bank from BUS[12-14]
|
||||
};
|
||||
|
||||
void bs_early_read_sreg(); //!< bus source: drive bus by S register or M (MYL), if rsel is = 0
|
||||
@ -66,11 +36,8 @@ void branch_RAM(const char *from, int page); //!< branch to RAM page
|
||||
void f1_late_swmode(); //!< F1 func: switch to micro program counter BUS[6-15] in other bank
|
||||
void f1_late_wrtram(); //!< F1 func: start WRTRAM cycle
|
||||
void f1_late_rdram(); //!< F1 func: start RDRAM cycle
|
||||
#if (ALTO2_UCODE_RAM_PAGES == 3)
|
||||
void f1_late_load_rmr(); //!< F1 func: load the reset mode register
|
||||
#else // ALTO2_UCODE_RAM_PAGES != 3
|
||||
void f1_late_load_srb(); //!< F1 func: load the S register bank from BUS[12-14]
|
||||
#endif
|
||||
void init_ram(int task); //!< called by RAM related tasks
|
||||
void exit_ram(); //!< deinitialize the RAM related tasks
|
||||
void reset_ram(); //!< reset the RAM related tasks
|
||||
|
@ -60,8 +60,7 @@ alto2_log_t logprintf;
|
||||
//**************************************************************************
|
||||
|
||||
DEVICE_ADDRESS_MAP_START( ucode_map, 32, alto2_cpu_device )
|
||||
AM_RANGE(0, ALTO2_UCODE_RAM_BASE - 1) AM_READ ( crom_r )
|
||||
AM_RANGE(ALTO2_UCODE_RAM_BASE, ALTO2_UCODE_SIZE - 1) AM_READWRITE( cram_r, cram_w )
|
||||
AM_RANGE(0, 4*ALTO2_UCODE_PAGE_SIZE - 1) AM_READWRITE( crom_cram_r, crom_cram_w )
|
||||
ADDRESS_MAP_END
|
||||
|
||||
DEVICE_ADDRESS_MAP_START( const_map, 16, alto2_cpu_device )
|
||||
@ -126,6 +125,12 @@ alto2_cpu_device::alto2_cpu_device(const machine_config& mconfig, const char* ta
|
||||
m_ucode_config("ucode", ENDIANNESS_BIG, 32, 12, -2 ),
|
||||
m_const_config("const", ENDIANNESS_BIG, 16, 8, -1 ),
|
||||
m_iomem_config("iomem", ENDIANNESS_BIG, 16, 17, -1 ),
|
||||
m_cram_config(2),
|
||||
m_ucode_rom_pages(1),
|
||||
m_ucode_ram_pages(2),
|
||||
m_ucode_ram_base(ALTO2_UCODE_PAGE_SIZE),
|
||||
m_ucode_size(3*ALTO2_UCODE_PAGE_SIZE),
|
||||
m_sreg_banks(1),
|
||||
m_ucode_crom(nullptr),
|
||||
m_const_data(nullptr),
|
||||
m_icount(0),
|
||||
@ -471,10 +476,8 @@ static const prom_load_t pl_ucode[] = {
|
||||
/* dmap */ DMAP_DEFAULT,
|
||||
/* dand */ KEEP,
|
||||
/* type */ sizeof(UINT32)
|
||||
}
|
||||
|
||||
#if (ALTO2_UCODE_ROM_PAGES > 1)
|
||||
,
|
||||
},
|
||||
// NOTE: the Mesa 5.1 ucode PROM may be used as RAM, if m_cram_config == 3
|
||||
{ // 02000-03777 RSEL(0)',RSEL(1)',RSEL(2)',RSEL(3)'
|
||||
"xm51.u54",
|
||||
nullptr,
|
||||
@ -595,7 +598,6 @@ static const prom_load_t pl_ucode[] = {
|
||||
/* dand */ KEEP,
|
||||
/* type */ sizeof(UINT32)
|
||||
}
|
||||
#endif // (UCODE_ROM_PAGES > 1)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -811,13 +813,14 @@ void alto2_cpu_device::device_start()
|
||||
// get a pointer to the IO address space
|
||||
m_iomem = &space(AS_2);
|
||||
|
||||
// decode ALTO2_UCODE_PAGES = 1 or 2 pages of micro code PROMs to CROM
|
||||
m_ucode_crom = prom_load(machine(), pl_ucode, memregion("ucode_proms")->base(), ALTO2_UCODE_ROM_PAGES, 8);
|
||||
// Decode 2 pages of micro code PROMs to CROM
|
||||
// If m_cram_config == 1 or 3, only the first page will be used
|
||||
m_ucode_crom = prom_load(machine(), pl_ucode, memregion("ucode_proms")->base(), 2, 8);
|
||||
|
||||
// allocate micro code CRAM
|
||||
m_ucode_cram = std::make_unique<UINT8[]>(sizeof(UINT32) * ALTO2_UCODE_RAM_PAGES * ALTO2_UCODE_PAGE_SIZE);
|
||||
// allocate micro code CRAM for max 3 pages
|
||||
m_ucode_cram = std::make_unique<UINT8[]>(sizeof(UINT32) * 3 * ALTO2_UCODE_PAGE_SIZE);
|
||||
// fill with the micro code inverted bits value
|
||||
for (offs_t offset = 0; offset < ALTO2_UCODE_RAM_PAGES * ALTO2_UCODE_PAGE_SIZE; offset++)
|
||||
for (offs_t offset = 0; offset < 3 * ALTO2_UCODE_PAGE_SIZE; offset++)
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + offset * 4) = ALTO2_UCODE_INVERTED;
|
||||
|
||||
// decode constant PROMs to m_const_data
|
||||
@ -1015,22 +1018,20 @@ void alto2_cpu_device::state_string_export(const device_state_entry &entry, std:
|
||||
}
|
||||
}
|
||||
|
||||
//! read microcode CROM
|
||||
READ32_MEMBER ( alto2_cpu_device::crom_r )
|
||||
//! read microcode CROM or CRAM
|
||||
READ32_MEMBER ( alto2_cpu_device::crom_cram_r )
|
||||
{
|
||||
return *reinterpret_cast<UINT32 *>(m_ucode_crom + offset * 4);
|
||||
if (offset < m_ucode_ram_base)
|
||||
return *reinterpret_cast<UINT32 *>(m_ucode_crom + offset * 4);
|
||||
return *reinterpret_cast<UINT32 *>(m_ucode_cram.get() + (offset - m_ucode_ram_base) * 4);
|
||||
}
|
||||
|
||||
//! read microcode CRAM
|
||||
READ32_MEMBER ( alto2_cpu_device::cram_r )
|
||||
//! write microcode CROM or CRAM (CROM of course can't be written)
|
||||
WRITE32_MEMBER( alto2_cpu_device::crom_cram_w )
|
||||
{
|
||||
return *reinterpret_cast<UINT32 *>(m_ucode_cram.get() + offset * 4);
|
||||
}
|
||||
|
||||
//! write microcode CRAM
|
||||
WRITE32_MEMBER( alto2_cpu_device::cram_w )
|
||||
{
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + offset * 4) = data;
|
||||
if (offset < m_ucode_ram_base)
|
||||
return;
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + (offset - m_ucode_ram_base) * 4) = data;
|
||||
}
|
||||
|
||||
//! read constants PROM
|
||||
@ -1040,9 +1041,9 @@ READ16_MEMBER ( alto2_cpu_device::const_r )
|
||||
}
|
||||
|
||||
//! direct read access to the microcode CROM or CRAM
|
||||
#define RD_UCODE(addr) (addr < ALTO2_UCODE_RAM_BASE ? \
|
||||
#define RD_UCODE(addr) (addr < m_ucode_ram_base ? \
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_crom + addr * 4) : \
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + (addr - ALTO2_UCODE_RAM_BASE) * 4))
|
||||
*reinterpret_cast<UINT32 *>(m_ucode_cram.get() + (addr - m_ucode_ram_base) * 4))
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
@ -1055,6 +1056,7 @@ void alto2_cpu_device::device_reset()
|
||||
ioport_port* etherid = ioport(":ETHERID");
|
||||
if (etherid)
|
||||
m_ether_id = etherid->read() & 0377;
|
||||
|
||||
// call all sub-devices' reset_...
|
||||
reset_memory();
|
||||
reset_disp();
|
||||
@ -2268,13 +2270,18 @@ UINT32 alto2_cpu_device::alu_74181(UINT32 a, UINT32 b, UINT8 smc)
|
||||
/** @brief flag that tells wheter operation was 0: arithmetic (M=0) or 1: logic (M=1) */
|
||||
#define ALUM A10_ALUM
|
||||
|
||||
/** @brief execute the CPU for at most nsecs nano seconds */
|
||||
/** @brief execute the CPU for the number of cycles in m_icount */
|
||||
void alto2_cpu_device::execute_run()
|
||||
{
|
||||
m_next = m_task_mpc[m_task]; // get current task's next mpc and address modifier
|
||||
m_next2 = m_task_next2[m_task];
|
||||
|
||||
do {
|
||||
if (m_dsp.vsync) {
|
||||
// synchronizing to the vsync signal
|
||||
continue;
|
||||
}
|
||||
|
||||
m_mpc = m_next; // next instruction's micro program counter
|
||||
m_mir = RD_UCODE(m_mpc); // fetch the micro code
|
||||
|
||||
@ -2283,15 +2290,16 @@ void alto2_cpu_device::execute_run()
|
||||
debugger_instruction_hook(this, m_mpc);
|
||||
m_cycle++;
|
||||
|
||||
|
||||
if (f1() == f1_load_mar && check_mem_load_mar_stall(m_rsel)) {
|
||||
LOG((this,LOG_CPU,3, " MAR<- stall\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f2() == f2_load_md && check_mem_write_stall()) {
|
||||
LOG((this,LOG_CPU,3, " MD<- stall\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bus source decoding is not performed if f1 == f1_const
|
||||
* or f2 == f2_const. These functions use the MIR BS field to
|
||||
@ -2320,33 +2328,32 @@ void alto2_cpu_device::execute_run()
|
||||
// The constant memory is gated to the bus by F1 == f1_const, F2 == f2_const, or BS >= 4
|
||||
if (!do_bs || bs() >= bs_task_4) {
|
||||
const UINT32 addr = 8 * m_rsel + bs();
|
||||
// FIXME: is the format of m_const_data endian safe?
|
||||
const UINT16 data = m_const_data[2*addr] | (m_const_data[2*addr+1] << 8);
|
||||
m_bus &= data;
|
||||
LOG((this,LOG_CPU,2," %#o; BUS &= %#o CONST[%03o]\n", m_bus, data, addr));
|
||||
}
|
||||
|
||||
/*
|
||||
* early F2 function has to be called before early BS,
|
||||
* Early F2 function has to be called before early BS,
|
||||
* because the emulator task F2 acsource or acdest may
|
||||
* change the m_rsel
|
||||
* change the value of m_rsel
|
||||
*/
|
||||
switch (f2()) {
|
||||
case f2_task_12: // f2 12 task specific
|
||||
case f2_task_12: // f2 12 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_early_load_dns();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_13: // f2 13 task specific
|
||||
case f2_task_13: // f2 13 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_early_acdest();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_16: // f2 16 task specific
|
||||
case f2_task_16: // f2 16 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_early_acsource();
|
||||
@ -2366,22 +2373,22 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
case bs_task_3: // BUS source is task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
case task_emu: // emulator task
|
||||
bs_early_read_sreg();
|
||||
break;
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
bs_early_read_kstat();
|
||||
break;
|
||||
case task_ether: // ethernet task
|
||||
case task_ether: // ethernet task
|
||||
bs_early_eidfct();
|
||||
break;
|
||||
case task_mrt: // memory refresh task
|
||||
case task_dwt: // display word task
|
||||
case task_curt: // cursor task
|
||||
case task_dht: // display horizontal task
|
||||
case task_dvt: // display vertical task
|
||||
case task_part: // parity task
|
||||
case task_mrt: // memory refresh task
|
||||
case task_dwt: // display word task
|
||||
case task_curt: // cursor task
|
||||
case task_dht: // display horizontal task
|
||||
case task_dvt: // display vertical task
|
||||
case task_part: // parity task
|
||||
break;
|
||||
default:
|
||||
bs_early_bad();
|
||||
@ -2389,20 +2396,20 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
case bs_task_4: // BUS source is task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
case task_emu: // emulator task
|
||||
bs_early_load_sreg();
|
||||
break;
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
bs_early_read_kdata();
|
||||
break;
|
||||
case task_ether: // ethernet task
|
||||
case task_mrt: // memory refresh task
|
||||
case task_dwt: // display word task
|
||||
case task_curt: // cursor task
|
||||
case task_dht: // display horizontal task
|
||||
case task_dvt: // display vertical task
|
||||
case task_part: // parity task
|
||||
case task_ether: // ethernet task
|
||||
case task_mrt: // memory refresh task
|
||||
case task_dwt: // display word task
|
||||
case task_curt: // cursor task
|
||||
case task_dht: // display horizontal task
|
||||
case task_dvt: // display vertical task
|
||||
case task_part: // parity task
|
||||
break;
|
||||
default:
|
||||
bs_early_bad();
|
||||
@ -2414,9 +2421,9 @@ void alto2_cpu_device::execute_run()
|
||||
case bs_mouse: // BUS source is mouse data
|
||||
bs_early_mouse();
|
||||
break;
|
||||
case bs_disp: // BUS source displacement (emulator task)
|
||||
case bs_disp: // BUS source displacement (emulator task)
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
case task_emu: // emulator task
|
||||
bs_early_emu_disp();
|
||||
break;
|
||||
default:
|
||||
@ -2428,10 +2435,10 @@ void alto2_cpu_device::execute_run()
|
||||
|
||||
// early F1 function
|
||||
switch (f1()) {
|
||||
case f1_task: // f1 02 task switch
|
||||
case f1_task: // f1 02 task switch
|
||||
f1_early_task();
|
||||
break;
|
||||
case f1_block: // f1 03 task block
|
||||
case f1_block: // f1 03 task block
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_early_emu_block();
|
||||
@ -2466,28 +2473,28 @@ void alto2_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case f1_task_13: // f1 13 task specific
|
||||
case f1_task_13: // f1 13 task specific
|
||||
switch (m_task) {
|
||||
case task_ether: // ethernet task
|
||||
f1_early_eilfct();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_14: // f1 14 task specific
|
||||
case f1_task_14: // f1 14 task specific
|
||||
switch (m_task) {
|
||||
case task_ether: // ethernet task
|
||||
f1_early_epfct();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_16: // f1 16 task specific
|
||||
case f1_task_16: // f1 16 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_early_rsnf();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_17: // f1 17 task specific
|
||||
case f1_task_17: // f1 17 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_early_startf();
|
||||
@ -2520,27 +2527,27 @@ void alto2_cpu_device::execute_run()
|
||||
|
||||
// late F1 function call now
|
||||
switch (f1()) {
|
||||
case f1_load_mar: // f1 01 load memory address register
|
||||
case f1_load_mar: // f1 01 load memory address register
|
||||
f1_late_load_mar();
|
||||
break;
|
||||
case f1_l_lsh_1: // f1 04 left shift L once
|
||||
case f1_l_lsh_1: // f1 04 left shift L once
|
||||
f1_late_l_lsh_1();
|
||||
break;
|
||||
case f1_l_rsh_1: // f1 05 right shift L once
|
||||
case f1_l_rsh_1: // f1 05 right shift L once
|
||||
f1_late_l_rsh_1();
|
||||
break;
|
||||
case f1_l_lcy_8: // f1 06 cycle L 8 times
|
||||
case f1_l_lcy_8: // f1 06 cycle L 8 times
|
||||
f1_late_l_lcy_8();
|
||||
break;
|
||||
|
||||
case f1_task_10: // f1 10 task specific
|
||||
case f1_task_10: // f1 10 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_late_swmode();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_11: // f1 11 task specific
|
||||
case f1_task_11: // f1 11 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_late_wrtram();
|
||||
@ -2551,7 +2558,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_12: // f1 12 task specific
|
||||
case f1_task_12: // f1 12 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_late_rdram();
|
||||
@ -2562,14 +2569,13 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_13: // f1 13 task specific
|
||||
case f1_task_13: // f1 13 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
#if (ALTO2_UCODE_RAM_PAGES == 3)
|
||||
f1_late_load_rmr();
|
||||
#else
|
||||
f1_late_load_srb();
|
||||
#endif
|
||||
if (m_cram_config == 3) // 3K CRAM available?
|
||||
f1_late_load_rmr();
|
||||
else
|
||||
f1_late_load_srb();
|
||||
break;
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
@ -2577,7 +2583,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_14: // f1 14 task specific
|
||||
case f1_task_14: // f1 14 task specific
|
||||
switch (m_task) {
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
@ -2585,7 +2591,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_15: // f1 15 task specific
|
||||
case f1_task_15: // f1 15 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f1_late_emu_load_esrb();
|
||||
@ -2599,7 +2605,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_16: // f1 16 task specific
|
||||
case f1_task_16: // f1 16 task specific
|
||||
switch (m_task) {
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
@ -2607,7 +2613,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f1_task_17: // f1 17 task specific
|
||||
case f1_task_17: // f1 17 task specific
|
||||
switch (m_task) {
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
@ -2619,26 +2625,26 @@ void alto2_cpu_device::execute_run()
|
||||
|
||||
// late F2 function call now
|
||||
switch (f2()) {
|
||||
case f2_bus_eq_zero: // f2 01 branch on bus equals 0
|
||||
case f2_bus_eq_zero: // f2 01 branch on bus equals 0
|
||||
f2_late_bus_eq_zero();
|
||||
break;
|
||||
case f2_shifter_lt_zero: // f2 02 branch on shifter less than 0
|
||||
case f2_shifter_lt_zero: // f2 02 branch on shifter less than 0
|
||||
f2_late_shifter_lt_zero();
|
||||
break;
|
||||
case f2_shifter_eq_zero: // f2 03 branch on shifter equals 0
|
||||
case f2_shifter_eq_zero: // f2 03 branch on shifter equals 0
|
||||
f2_late_shifter_eq_zero();
|
||||
break;
|
||||
case f2_bus: // f2 04 branch on BUS[6-15]
|
||||
case f2_bus: // f2 04 branch on BUS[6-15]
|
||||
f2_late_bus();
|
||||
break;
|
||||
case f2_alucy: // f2 05 branch on (latched) ALU carry
|
||||
case f2_alucy: // f2 05 branch on (latched) ALU carry
|
||||
f2_late_alucy();
|
||||
break;
|
||||
case f2_load_md: // f2 06 load memory data
|
||||
case f2_load_md: // f2 06 load memory data
|
||||
f2_late_load_md();
|
||||
break;
|
||||
|
||||
case f2_task_10: // f2 10 task specific
|
||||
case f2_task_10: // f2 10 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_late_busodd();
|
||||
@ -2651,7 +2657,7 @@ void alto2_cpu_device::execute_run()
|
||||
f2_late_eodfct();
|
||||
break;
|
||||
case task_dwt: // display word task
|
||||
f2_late_dwt_load_ddr();
|
||||
f2_late_load_ddr();
|
||||
break;
|
||||
case task_curt: // cursor task
|
||||
f2_late_load_xpreg();
|
||||
@ -2664,7 +2670,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_11: // f2 11 task specific
|
||||
case f2_task_11: // f2 11 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_late_magic();
|
||||
@ -2684,7 +2690,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_12: // f2 12 task specific
|
||||
case f2_task_12: // f2 12 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_late_load_dns();
|
||||
@ -2698,7 +2704,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_13: // f2 13 task specific
|
||||
case f2_task_13: // f2 13 task specific
|
||||
switch (m_task) {
|
||||
case task_ksec: // disk sector task
|
||||
case task_kwd: // disk word task
|
||||
@ -2709,7 +2715,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_14: // f2 14 task specific
|
||||
case f2_task_14: // f2 14 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_late_load_ir();
|
||||
@ -2723,7 +2729,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_15: // f2 15 task specific
|
||||
case f2_task_15: // f2 15 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_late_idisp();
|
||||
@ -2737,7 +2743,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case f2_task_16: // f2 16 task specific
|
||||
case f2_task_16: // f2 16 task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
f2_late_acsource();
|
||||
@ -2761,7 +2767,7 @@ void alto2_cpu_device::execute_run()
|
||||
break;
|
||||
case bs_task_4: // BUS source is task specific
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
case task_emu: // emulator task
|
||||
bs_late_load_sreg();
|
||||
break;
|
||||
}
|
||||
@ -2771,7 +2777,7 @@ void alto2_cpu_device::execute_run()
|
||||
|
||||
// update T register, if LOADT is set
|
||||
if (loadt()) {
|
||||
m_cram_addr = m_alu; // latch CRAM address
|
||||
m_cram_addr = m_alu; // latch CRAM address
|
||||
if (flags & TSELECT) {
|
||||
m_t = m_alu; // T source is ALU
|
||||
LOG((this,LOG_CPU,2, " T<- ALU (%#o)\n", m_alu));
|
||||
@ -2783,7 +2789,7 @@ void alto2_cpu_device::execute_run()
|
||||
|
||||
// update L register and LALUC0 if LOADL is set
|
||||
if (loadl()) {
|
||||
m_l = m_alu; // load L from ALU
|
||||
m_l = m_alu; // load L from ALU
|
||||
if (flags & ALUM) {
|
||||
m_laluc0 = 0; // logic operation - put 0 into latched carry
|
||||
LOG((this,LOG_CPU,2, " L<- ALU (%#o); LALUC0<- %o\n", m_alu, 0));
|
||||
@ -2794,7 +2800,8 @@ void alto2_cpu_device::execute_run()
|
||||
// update M (MYL) register, if a RAM related task is active
|
||||
if (m_ram_related[m_task]) {
|
||||
m_myl = m_alu; // load M from ALU, if 'GOODTASK'
|
||||
m_s[m_s_reg_bank[m_task]][0] = m_alu; // also writes to S[bank][0], which can't be read
|
||||
// also writes to S[_task][0], which can't be read
|
||||
m_s[m_s_reg_bank[m_task]][0] = m_alu;
|
||||
LOG((this,LOG_CPU,2, " M<- ALU (%#o)\n", m_alu));
|
||||
}
|
||||
}
|
||||
@ -2811,14 +2818,19 @@ void alto2_cpu_device::execute_run()
|
||||
m_task_next2[m_task] = m_next2;
|
||||
m_task = m_next_task;
|
||||
LOG((this,LOG_CPU,1, "task switch to %02o:%s (cycle %lld)\n", m_task, task_name(m_task), cycle()));
|
||||
m_next = m_task_mpc[m_task]; // get new task's mpc
|
||||
m_next2 = m_task_next2[m_task]; // get address modifier after task switch (needed?)
|
||||
// Get the new task's mpc
|
||||
m_next = m_task_mpc[m_task];
|
||||
// Get address modifier after task switch.
|
||||
m_next2 = m_task_next2[m_task];
|
||||
|
||||
// let the task know it becomes active now and (most probably) reset the wakeup
|
||||
// Let the task know it becomes active now and
|
||||
// (most probably) reset the wakeup
|
||||
switch (m_task) {
|
||||
case task_emu: // emulator task
|
||||
// No activate_emu();
|
||||
break;
|
||||
case task_ksec: // disk sector task
|
||||
// No activate_ksec();
|
||||
break;
|
||||
case task_ether: // ethernet task
|
||||
activate_eth();
|
||||
@ -2827,6 +2839,7 @@ void alto2_cpu_device::execute_run()
|
||||
activate_mrt();
|
||||
break;
|
||||
case task_dwt: // display word task
|
||||
// No activate_dwt();
|
||||
break;
|
||||
case task_curt: // cursor task
|
||||
activate_curt();
|
||||
@ -2841,6 +2854,7 @@ void alto2_cpu_device::execute_run()
|
||||
activate_part();
|
||||
break;
|
||||
case task_kwd: // disk word task
|
||||
// No activate_kwd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2849,8 +2863,8 @@ void alto2_cpu_device::execute_run()
|
||||
if (m_dsp_time >= 0) {
|
||||
/**
|
||||
* Subtract the microcycle time from the display time accu.
|
||||
* If it underflows, call the display state machine and add
|
||||
* the time for 32(!) pixel clocks to the accu.
|
||||
* If it underflows, call the display state machine which
|
||||
* adds the time for 32 pixel clocks to the accu.
|
||||
* This is very close to every seventh CPU cycle
|
||||
*/
|
||||
m_dsp_time -= ALTO2_UCYCLE;
|
||||
@ -2863,7 +2877,7 @@ void alto2_cpu_device::execute_run()
|
||||
* Subtract the microcycle time from the unload time accu.
|
||||
* If it underflows, call the unload word function which adds
|
||||
* the time for 16 or 32 pixel clocks to the accu, or ends
|
||||
* the unloading by leaving m_unload_time at -1.
|
||||
* the FIFO unloading by leaving m_unload_time at -1.
|
||||
*/
|
||||
m_unload_time -= ALTO2_UCYCLE;
|
||||
if (m_unload_time < 0)
|
||||
@ -2874,7 +2888,7 @@ void alto2_cpu_device::execute_run()
|
||||
/**
|
||||
* Subtract the microcycle time from the bitclk time accu.
|
||||
* If it underflows, call the disk bitclk function which adds
|
||||
* the time for one bit as clocks to the accu, or ends
|
||||
* the time for one bit as clock cycles to the accu, or ends
|
||||
* the bitclk sequence by leaving m_bitclk_time at -1.
|
||||
*/
|
||||
m_bitclk_time -= ALTO2_UCYCLE;
|
||||
@ -2882,7 +2896,7 @@ void alto2_cpu_device::execute_run()
|
||||
}
|
||||
} while (m_icount-- > 0);
|
||||
|
||||
/* save this task's mpc and address modifier */
|
||||
// Save this task's mpc and address modifier
|
||||
m_task_mpc[m_task] = m_next;
|
||||
m_task_next2[m_task] = m_next2;
|
||||
}
|
||||
@ -2900,7 +2914,7 @@ void alto2_cpu_device::hard_reset()
|
||||
// every task starts at mpc = task number, in either ROM0 or RAM0
|
||||
m_task_mpc[task] = (m_ctl2k_u38[task] >> 4) ^ 017;
|
||||
if (0 == (m_reset_mode & (1 << task)))
|
||||
m_task_mpc[task] |= ALTO2_UCODE_RAM_BASE;
|
||||
m_task_mpc[task] |= m_ucode_ram_base;
|
||||
}
|
||||
|
||||
init_memory();
|
||||
@ -2931,11 +2945,36 @@ void alto2_cpu_device::hard_reset()
|
||||
/** @brief software initiated reset (STARTF) */
|
||||
void alto2_cpu_device::soft_reset()
|
||||
{
|
||||
// Setup the CROM and CRAM configuration
|
||||
ioport_port* config = ioport(":CONFIG");
|
||||
if (config)
|
||||
m_cram_config = (config->read() >> 1) & 3;
|
||||
switch (m_cram_config) {
|
||||
case 0: // invalid, default to 1
|
||||
case 1: // 1K CROM, 1K CRAM, 1 S register bank
|
||||
m_ucode_rom_pages = 1;
|
||||
m_ucode_ram_pages = 1;
|
||||
m_sreg_banks = 1;
|
||||
break;
|
||||
case 2: // 2K CROM, 1K CRAM, 1 S register bank
|
||||
m_ucode_rom_pages = 2;
|
||||
m_ucode_ram_pages = 1;
|
||||
m_sreg_banks = 1;
|
||||
break;
|
||||
case 3: // 1K CROM, 3K CRAM, 8 S register banks
|
||||
m_ucode_rom_pages = 1;
|
||||
m_ucode_ram_pages = 3;
|
||||
m_sreg_banks = 8;
|
||||
break;
|
||||
}
|
||||
m_ucode_ram_base = m_ucode_rom_pages * ALTO2_UCODE_PAGE_SIZE;
|
||||
m_ucode_size = (m_ucode_rom_pages + m_ucode_ram_pages) * ALTO2_UCODE_PAGE_SIZE;
|
||||
|
||||
for (int task = 0; task < ALTO2_TASKS; task++) {
|
||||
// every task starts at mpc = task number, in either ROM0 or RAM0
|
||||
m_task_mpc[task] = (m_ctl2k_u38[task] >> 4) ^ 017;
|
||||
if (0 == (m_reset_mode & (1 << task)))
|
||||
m_task_mpc[task] |= ALTO2_UCODE_RAM_BASE;
|
||||
m_task_mpc[task] |= m_ucode_ram_base;
|
||||
}
|
||||
m_next2_task = task_emu; // switch to task 0 (emulator)
|
||||
m_reset_mode = 0xffff; // all tasks start in ROM0 again
|
||||
|
@ -46,11 +46,6 @@ enum {
|
||||
#define ALTO2_DEBUG 1
|
||||
#endif
|
||||
|
||||
#ifndef ALTO2_CRAM_CONFIG
|
||||
//! Use default CROM/CRAM configuration 2.
|
||||
#define ALTO2_CRAM_CONFIG 2
|
||||
#endif
|
||||
|
||||
//!< Define to 1 to use the F9318 priority encoder code (broken).
|
||||
#define USE_PRIO_F9318 0
|
||||
|
||||
@ -200,9 +195,6 @@ public:
|
||||
//! update the screen bitmap
|
||||
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
//! screen VBLANK handler
|
||||
void screen_eof(screen_device &screen, bool state);
|
||||
|
||||
DECLARE_ADDRESS_MAP( ucode_map, 32 );
|
||||
DECLARE_ADDRESS_MAP( const_map, 16 );
|
||||
DECLARE_ADDRESS_MAP( iomem_map, 16 );
|
||||
@ -255,18 +247,22 @@ private:
|
||||
|
||||
address_space* m_iomem;
|
||||
|
||||
UINT32 m_cram_config; //!< CROM/CRAM configuration (1 .. 3)
|
||||
UINT32 m_ucode_rom_pages; //!< Number of CROM pages; derived from m_cram_config
|
||||
UINT32 m_ucode_ram_pages; //!< Number of CRAM pages; derived from m_cram_config
|
||||
UINT32 m_ucode_ram_base; //!< Base offset of the CRAM addresses
|
||||
UINT32 m_ucode_size; //!< Size of both, CROM and CRAM together
|
||||
UINT32 m_sreg_banks; //!< Number of S register banks; derived from m_cram_config
|
||||
|
||||
UINT8* m_ucode_crom;
|
||||
std::unique_ptr<UINT8[]> m_ucode_cram;
|
||||
UINT8* m_const_data;
|
||||
|
||||
//! read microcode CROM
|
||||
DECLARE_READ32_MEMBER ( crom_r );
|
||||
//! read microcode CROM or CRAM, depending on m_ucode_ram_base
|
||||
DECLARE_READ32_MEMBER ( crom_cram_r );
|
||||
|
||||
//! read microcode CRAM
|
||||
DECLARE_READ32_MEMBER ( cram_r );
|
||||
|
||||
//! write microcode CRAM
|
||||
DECLARE_WRITE32_MEMBER( cram_w );
|
||||
//! write microcode CRAM, depending on m_ucode_ram_base (ignore writes to CROM)
|
||||
DECLARE_WRITE32_MEMBER( crom_cram_w );
|
||||
|
||||
//! read constants PROM
|
||||
DECLARE_READ16_MEMBER ( const_r );
|
||||
@ -568,7 +564,7 @@ private:
|
||||
UINT16 m_next; //!< current micro instruction's next
|
||||
UINT16 m_next2; //!< next micro instruction's next
|
||||
UINT16 m_r[ALTO2_REGS]; //!< R register file
|
||||
UINT16 m_s[ALTO2_SREG_BANKS][ALTO2_REGS]; //!< S register file(s)
|
||||
UINT16 m_s[8][ALTO2_REGS]; //!< S register file(s) (1 or 8 are used)
|
||||
UINT16 m_bus; //!< wired-AND bus
|
||||
UINT16 m_t; //!< T register
|
||||
UINT16 m_alu; //!< the current ALU
|
||||
|
@ -344,7 +344,7 @@ offs_t alto2_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8
|
||||
break;
|
||||
case 7: // put the constant from PROM (RSELECT,BS) on the bus
|
||||
pa = (rsel << 3) | bs;
|
||||
dst += snprintf(dst, len - (size_t)(dst - buffer), "BUS<-%05o", const_prom[pa]);
|
||||
dst += snprintf(dst, len - (size_t)(dst - buffer), "BUS<-%05o ", const_prom[pa]);
|
||||
break;
|
||||
default:
|
||||
dst += snprintf(dst, len - (size_t)(dst - buffer), "F1_%02o ", f1);
|
||||
@ -386,6 +386,8 @@ offs_t alto2_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8
|
||||
dst += snprintf(dst, len - (size_t)(dst - buffer), "BUS<-F2_%02o ", f2);
|
||||
break;
|
||||
}
|
||||
if (dst > buffer && dst[-1] == ' ')
|
||||
*--dst = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -162,6 +162,11 @@ static INPUT_PORTS_START( alto2 )
|
||||
PORT_CONFNAME( 0x01, 0x01, "Memory switch")
|
||||
PORT_CONFSETTING( 0x00, "on")
|
||||
PORT_CONFSETTING( 0x01, "off")
|
||||
PORT_CONFNAME( 0x06, 0x02, "CROM/CRAM configuration")
|
||||
PORT_CONFSETTING( 0x00, "Invalid (no CROM/CRAM)")
|
||||
PORT_CONFSETTING( 0x02, "1K CROM, 1K CRAM")
|
||||
PORT_CONFSETTING( 0x04, "2K CROM, 1K CRAM")
|
||||
PORT_CONFSETTING( 0x06, "1K CROM, 3K CRAM")
|
||||
PORT_CONFNAME( 0x70, 0x00, "Ethernet breath-of-life")
|
||||
PORT_CONFSETTING( 0x00, "off")
|
||||
PORT_CONFSETTING( 0x10, "5 seconds")
|
||||
@ -252,7 +257,7 @@ ROM_END
|
||||
//**************************************************************************
|
||||
|
||||
ADDRESS_MAP_START( alto2_ucode_map, AS_0, 32, alto2_state )
|
||||
AM_RANGE(0, ALTO2_UCODE_SIZE-1) AM_DEVICE32( "maincpu", alto2_cpu_device, ucode_map, 0xffffffffUL )
|
||||
AM_RANGE(0, 4*ALTO2_UCODE_PAGE_SIZE-1) AM_DEVICE32( "maincpu", alto2_cpu_device, ucode_map, 0xffffffffUL )
|
||||
ADDRESS_MAP_END
|
||||
|
||||
ADDRESS_MAP_START( alto2_const_map, AS_1, 16, alto2_state )
|
||||
@ -275,12 +280,14 @@ static MACHINE_CONFIG_START( alto2, alto2_state )
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::white)
|
||||
MCFG_SCREEN_RAW_PARAMS(XTAL_20_16MHz,
|
||||
ALTO2_DISPLAY_TOTAL_WIDTH, 0, ALTO2_DISPLAY_WIDTH,
|
||||
ALTO2_DISPLAY_TOTAL_HEIGHT, 0, ALTO2_DISPLAY_HEIGHT)
|
||||
MCFG_SCREEN_REFRESH_RATE(30) // two interlaced fields
|
||||
MCFG_SCREEN_VBLANK_TIME(ALTO2_DISPLAY_VBLANK_TIME)
|
||||
ALTO2_DISPLAY_TOTAL_WIDTH,
|
||||
0,
|
||||
ALTO2_DISPLAY_WIDTH,
|
||||
ALTO2_DISPLAY_TOTAL_HEIGHT,
|
||||
16, // some scalines of vblank period before
|
||||
16+ALTO2_DISPLAY_HEIGHT+8) // and after the usual range
|
||||
MCFG_SCREEN_REFRESH_RATE(30) // two interlaced fields at 60Hz
|
||||
MCFG_SCREEN_UPDATE_DEVICE("maincpu", alto2_cpu_device, screen_update)
|
||||
MCFG_SCREEN_VBLANK_DEVICE("maincpu", alto2_cpu_device, screen_eof)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
|
||||
MCFG_DEFAULT_LAYOUT( layout_vertical )
|
||||
|
Loading…
Reference in New Issue
Block a user