mirror of
https://github.com/holub/mame
synced 2025-04-16 13:34:55 +03:00
Merge pull request #478 from jfdelnero/master
EF9365 video controller skeleton added and connected to Squale [Jean-Francois DEL NERO]
This commit is contained in:
commit
60083f5094
@ -154,6 +154,18 @@ if (VIDEOS["EF9345"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/ef9365.h,VIDEOS["EF9365"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (VIDEOS["EF9365"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/video/ef9365.cpp",
|
||||
MAME_DIR .. "src/devices/video/ef9365.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--@src/devices/video/epic12.h,VIDEOS["EPIC12"] = true
|
||||
--------------------------------------------------
|
||||
|
@ -275,6 +275,7 @@ VIDEOS["BUFSPRITE"] = true
|
||||
VIDEOS["DM9368"] = true
|
||||
--VIDEOS["EF9340_1"] = true
|
||||
--VIDEOS["EF9345"] = true
|
||||
--VIDEOS["EF9365"] = true
|
||||
--VIDEOS["GF4500"] = true
|
||||
VIDEOS["GF7600GS"] = true
|
||||
VIDEOS["EPIC12"] = true
|
||||
|
@ -272,6 +272,7 @@ VIDEOS["DL1416"] = true
|
||||
VIDEOS["DM9368"] = true
|
||||
VIDEOS["EF9340_1"] = true
|
||||
VIDEOS["EF9345"] = true
|
||||
VIDEOS["EF9365"] = true
|
||||
VIDEOS["GF4500"] = true
|
||||
--VIDEOS+= EPIC12"] = true
|
||||
--VIDEOS+= FIXFREQ"] = true
|
||||
|
455
src/devices/video/ef9365.cpp
Normal file
455
src/devices/video/ef9365.cpp
Normal file
@ -0,0 +1,455 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Jean-François DEL NERO
|
||||
/*********************************************************************
|
||||
|
||||
ef9365.c
|
||||
|
||||
Thomson EF9365 video controller emulator code
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ef9365.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// devices
|
||||
const device_type EF9365 = &device_creator<ef9365_device>;
|
||||
|
||||
// default address map
|
||||
static ADDRESS_MAP_START( ef9365, AS_0, 8, ef9365_device )
|
||||
AM_RANGE(0x0000, 0x1fff) AM_RAM // BLUE
|
||||
AM_RANGE(0x2000, 0x3fff) AM_RAM // GREEN
|
||||
AM_RANGE(0x4000, 0x5fff) AM_RAM // RED
|
||||
AM_RANGE(0x6000, 0x7fff) AM_RAM // INTENSITY
|
||||
ADDRESS_MAP_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// memory_space_config - return a description of
|
||||
// any address spaces owned by this device
|
||||
//-------------------------------------------------
|
||||
|
||||
const address_space_config *ef9365_device::memory_space_config(address_spacenum spacenum) const
|
||||
{
|
||||
return (spacenum == AS_0) ? &m_space_config : NULL;
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// INLINE HELPERS
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// live device
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// ef9365_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ef9365_device::ef9365_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, EF9365, "EF9365", tag, owner, clock, "ef9365", __FILE__),
|
||||
device_memory_interface(mconfig, *this),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, NULL, *ADDRESS_MAP_NAME(ef9365)),
|
||||
m_palette(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// static_set_palette_tag: Set the tag of the
|
||||
// palette device
|
||||
//-------------------------------------------------
|
||||
|
||||
void ef9365_device::static_set_palette_tag(device_t &device, const char *tag)
|
||||
{
|
||||
downcast<ef9365_device &>(device).m_palette.set_tag(tag);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// static_set_color_filler: Set the color value
|
||||
// used by the chip to draw/fill the memory
|
||||
//-------------------------------------------------
|
||||
|
||||
void ef9365_device::static_set_color_filler( UINT8 color )
|
||||
{
|
||||
m_current_color = color;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void ef9365_device::device_start()
|
||||
{
|
||||
m_busy_timer = timer_alloc(BUSY_TIMER);
|
||||
|
||||
m_videoram = &space(0);
|
||||
m_charset = region();
|
||||
m_current_color = 0x0F;
|
||||
|
||||
m_screen_out.allocate(496, m_screen->height());
|
||||
|
||||
save_item(NAME(m_border));
|
||||
save_item(NAME(m_registers));
|
||||
save_item(NAME(m_bf));
|
||||
save_item(NAME(m_state));
|
||||
|
||||
save_item(NAME(m_screen_out));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
void ef9365_device::device_reset()
|
||||
{
|
||||
m_state = 0;
|
||||
m_bf = 0;
|
||||
|
||||
memset(m_registers, 0, sizeof(m_registers));
|
||||
memset(m_border, 0, sizeof(m_border));
|
||||
|
||||
m_screen_out.fill(0);
|
||||
|
||||
set_video_mode();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
void ef9365_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case BUSY_TIMER:
|
||||
m_bf = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set busy flag and timer to clear it
|
||||
void ef9365_device::set_busy_flag(int period)
|
||||
{
|
||||
m_bf = 1;
|
||||
m_busy_timer->adjust(attotime::from_usec(period));
|
||||
}
|
||||
|
||||
// set then ef9365 mode
|
||||
void ef9365_device::set_video_mode(void)
|
||||
{
|
||||
UINT16 new_width = 256;
|
||||
|
||||
if (m_screen->width() != new_width)
|
||||
{
|
||||
rectangle visarea = m_screen->visible_area();
|
||||
visarea.max_x = new_width - 1;
|
||||
|
||||
m_screen->configure(new_width, m_screen->height(), visarea, m_screen->frame_period().attoseconds());
|
||||
}
|
||||
|
||||
//border color
|
||||
memset(m_border, 0, sizeof(m_border));
|
||||
}
|
||||
|
||||
void ef9365_device::draw_border(UINT16 line)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ef9365_device::draw_character( unsigned char c )
|
||||
{
|
||||
int x_char,y_char;
|
||||
int char_base,char_pix;
|
||||
unsigned int x, y;
|
||||
|
||||
x = ( (m_registers[EF9365_REG_X_MSB]<<8) | m_registers[EF9365_REG_X_LSB]);
|
||||
y = ( (m_registers[EF9365_REG_Y_MSB]<<8) | m_registers[EF9365_REG_Y_LSB]);
|
||||
|
||||
if(c<96)
|
||||
{
|
||||
y = ( 256 - y ) - 8;
|
||||
|
||||
if( ( x < ( 256 - 5 ) ) && ( y < ( 256 - 8 ) ) )
|
||||
{
|
||||
char_base = c * 5; // 5 bytes per char.
|
||||
char_pix = 0;
|
||||
|
||||
for(y_char=0;y_char<8;y_char++)
|
||||
{
|
||||
for(x_char=0;x_char<5;x_char++)
|
||||
{
|
||||
if ( m_charset->u8(char_base + (char_pix>>3) ) & ( 0x80 >> (char_pix&7)))
|
||||
{
|
||||
if( m_current_color & 0x01)
|
||||
m_videoram->write_byte ( 0x0000 + ((((y_char+y)*256) + (x_char+x))>>3), m_videoram->read_byte( 0x0000 + ((((y_char+y)*256) + (x_char+x))>>3)) | (0x80 >> ((((y_char+y)*256) + (x_char+x))&7) ) );
|
||||
|
||||
if( m_current_color & 0x02)
|
||||
m_videoram->write_byte ( 0x2000 + ((((y_char+y)*256) + (x_char+x))>>3), m_videoram->read_byte( 0x2000 + ((((y_char+y)*256) + (x_char+x))>>3)) | (0x80 >> ((((y_char+y)*256) + (x_char+x))&7) ) );
|
||||
|
||||
if( m_current_color & 0x04)
|
||||
m_videoram->write_byte ( 0x4000 + ((((y_char+y)*256) + (x_char+x))>>3), m_videoram->read_byte( 0x4000 + ((((y_char+y)*256) + (x_char+x))>>3)) | (0x80 >> ((((y_char+y)*256) + (x_char+x))&7) ) );
|
||||
|
||||
if( m_current_color & 0x08)
|
||||
m_videoram->write_byte ( 0x6000 + ((((y_char+y)*256) + (x_char+x))>>3), m_videoram->read_byte( 0x6000 + ((((y_char+y)*256) + (x_char+x))>>3)) | (0x80 >> ((((y_char+y)*256) + (x_char+x))&7) ) );
|
||||
}
|
||||
|
||||
char_pix++;
|
||||
}
|
||||
}
|
||||
|
||||
x = x + 6;
|
||||
|
||||
m_registers[EF9365_REG_X_MSB] = x >> 8;
|
||||
m_registers[EF9365_REG_X_LSB] = x & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute EF9365 command
|
||||
void ef9365_device::ef9365_exec(UINT8 cmd)
|
||||
{
|
||||
m_state = 0;
|
||||
|
||||
set_busy_flag(4);
|
||||
|
||||
if( ( cmd>>4 ) == 0 )
|
||||
{
|
||||
switch(cmd & 0xF)
|
||||
{
|
||||
case 0x0: // Set bit 1 of CTRL1 : Pen Selection
|
||||
#ifdef DBGMODE
|
||||
printf("Set bit 1 of CTRL1 : Pen Selection\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_CTRL1] |= 0x02;
|
||||
break;
|
||||
case 0x1: // Clear bit 1 of CTRL1 : Eraser Selection
|
||||
#ifdef DBGMODE
|
||||
printf("Clear bit 1 of CTRL1 : Eraser Selection\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_CTRL1] &= (~0x02);
|
||||
break;
|
||||
case 0x2: // Set bit 0 of CTRL1 : Pen/Eraser down selection
|
||||
#ifdef DBGMODE
|
||||
printf("Set bit 0 of CTRL1 : Pen/Eraser down selection\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_CTRL1] |= 0x01;
|
||||
break;
|
||||
case 0x3: // Clear bit 0 of CTRL1 : Pen/Eraser up selection
|
||||
#ifdef DBGMODE
|
||||
printf("Clear bit 0 of CTRL1 : Pen/Eraser up selection\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_CTRL1] &= (~0x01);
|
||||
break;
|
||||
case 0x4: // Clear screen
|
||||
#ifdef DBGMODE
|
||||
printf("Clear screen\n");
|
||||
#endif
|
||||
break;
|
||||
case 0x5: // X and Y registers reset to 0
|
||||
#ifdef DBGMODE
|
||||
printf("X and Y registers reset to 0\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_X_MSB] = 0;
|
||||
m_registers[EF9365_REG_X_LSB] = 0;
|
||||
|
||||
m_registers[EF9365_REG_Y_MSB] = 0;
|
||||
m_registers[EF9365_REG_Y_LSB] = 0;
|
||||
break;
|
||||
case 0x6: // X and Y registers reset to 0 and clear screen
|
||||
#ifdef DBGMODE
|
||||
printf("X and Y registers reset to 0 and clear screen\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_X_MSB] = 0;
|
||||
m_registers[EF9365_REG_X_LSB] = 0;
|
||||
|
||||
m_registers[EF9365_REG_Y_MSB] = 0;
|
||||
m_registers[EF9365_REG_Y_LSB] = 0;
|
||||
break;
|
||||
case 0x7: // Clear screen, set CSIZE to code "minsize". All other registers reset to 0
|
||||
#ifdef DBGMODE
|
||||
printf("Clear screen, set CSIZE to code \"minsize\". All other registers reset to 0\n");
|
||||
#endif
|
||||
break;
|
||||
case 0x8: // Light-pen initialization (/White forced low)
|
||||
#ifdef DBGMODE
|
||||
printf("Light-pen initialization (/White forced low)\n");
|
||||
#endif
|
||||
break;
|
||||
case 0x9: // Light-pen initialization
|
||||
#ifdef DBGMODE
|
||||
printf("Light-pen initialization\n");
|
||||
#endif
|
||||
break;
|
||||
case 0xA: // 5x8 block drawing (size according to CSIZE)
|
||||
#ifdef DBGMODE
|
||||
printf("5x8 block drawing (size according to CSIZE)\n");
|
||||
#endif
|
||||
break;
|
||||
case 0xB: // 4x4 block drawing (size according to CSIZE)
|
||||
#ifdef DBGMODE
|
||||
printf("4x4 block drawing (size according to CSIZE)\n");
|
||||
#endif
|
||||
break;
|
||||
case 0xC: // Screen scanning : pen or Eraser as defined by CTRL1
|
||||
#ifdef DBGMODE
|
||||
printf("Screen scanning : pen or Eraser as defined by CTRL1\n");
|
||||
#endif
|
||||
break;
|
||||
case 0xD: // X reset to 0
|
||||
#ifdef DBGMODE
|
||||
printf("X reset to 0\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_X_MSB] = 0;
|
||||
m_registers[EF9365_REG_X_LSB] = 0;
|
||||
break;
|
||||
case 0xE: // Y reset to 0
|
||||
#ifdef DBGMODE
|
||||
printf("Y reset to 0\n");
|
||||
#endif
|
||||
m_registers[EF9365_REG_Y_MSB] = 0;
|
||||
m_registers[EF9365_REG_Y_LSB] = 0;
|
||||
break;
|
||||
case 0xF: // Direct image memory access request for the next free cycle.
|
||||
#ifdef DBGMODE
|
||||
printf("Direct image memory access request for the next free cycle.\n");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
logerror("Unemulated EF9365 cmd: %02x\n", cmd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( cmd>>4 ) == 1 )
|
||||
{
|
||||
if( ( cmd & 0xF ) < 0x8 )
|
||||
{
|
||||
// Vector generation ( for b2,b1,0 see small vector definition)
|
||||
#ifdef DBGMODE
|
||||
printf("Vector generation ( for b2,b1,0 see small vector definition)\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special direction vectors generation ( for b2,b1,0 see small vector definition)
|
||||
#ifdef DBGMODE
|
||||
printf("Special direction vectors generation ( for b2,b1,0 see small vector definition)\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( cmd>>4 ) >= 0x8 )
|
||||
{
|
||||
// Small vector definition.
|
||||
#ifdef DBGMODE
|
||||
printf("Small vector definition.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw character
|
||||
#ifdef DBGMODE
|
||||
printf("Draw character\n");
|
||||
#endif
|
||||
draw_character( cmd - 0x20 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
EF9365 interface
|
||||
**************************************************************/
|
||||
|
||||
UINT32 ef9365_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int i,j,k;
|
||||
unsigned long r,v,b;
|
||||
k = 0;
|
||||
for(i=0;i<256;i++)
|
||||
{
|
||||
for(j=0;j<256;j++)
|
||||
{
|
||||
r = v = b = 0;
|
||||
|
||||
if( m_videoram->read_byte(0x0000 + (k>>3)) & (0x80>>(k&7)))
|
||||
{
|
||||
b = 0xFF;
|
||||
}
|
||||
|
||||
if( m_videoram->read_byte(0x2000 + (k>>3)) & (0x80>>(k&7)))
|
||||
{
|
||||
v = 0xFF;
|
||||
}
|
||||
|
||||
if( m_videoram->read_byte(0x4000 + (k>>3)) & (0x80>>(k&7)))
|
||||
{
|
||||
r = 0xFF;
|
||||
}
|
||||
|
||||
if( m_videoram->read_byte(0x6000 + (k>>3)) & (0x80>>(k&7)))
|
||||
{
|
||||
r = r / 2;
|
||||
v = v / 2;
|
||||
b = b / 2;
|
||||
}
|
||||
|
||||
m_screen_out.pix32(i, j) = ( r<<16 ) | ( v<<8 ) | b;
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
copybitmap(bitmap, m_screen_out, 0, 0, 0, 0, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ef9365_device::update_scanline(UINT16 scanline)
|
||||
{
|
||||
if (scanline == 250)
|
||||
m_state |= (0x02); // vsync
|
||||
|
||||
if (scanline == 0)
|
||||
{
|
||||
m_state &= (~0x02);
|
||||
draw_border(0);
|
||||
}
|
||||
|
||||
else if (scanline < 120)
|
||||
{
|
||||
}
|
||||
else if (scanline < 250)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER( ef9365_device::data_r )
|
||||
{
|
||||
if (offset & 0xF)
|
||||
return m_registers[offset & 0xF];
|
||||
|
||||
if (m_bf)
|
||||
m_state &= (~0x04);
|
||||
else
|
||||
m_state |= 0x04;
|
||||
|
||||
#ifdef DBGMODE
|
||||
printf("rd ef9365 [0x%2x] = [0x%2x]\n", offset&0xF,m_state );
|
||||
#endif
|
||||
return m_state;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( ef9365_device::data_w )
|
||||
{
|
||||
m_registers[offset & 0xF] = data;
|
||||
#ifdef DBGMODE
|
||||
printf("wr ef9365 [0x%2x] = [0x%2x]\n", offset&0xF,data );
|
||||
#endif
|
||||
|
||||
if (!offset)
|
||||
ef9365_exec(m_registers[0] & 0xff);
|
||||
}
|
106
src/devices/video/ef9365.h
Normal file
106
src/devices/video/ef9365.h
Normal file
@ -0,0 +1,106 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Jean-François DEL NERO
|
||||
/*********************************************************************
|
||||
|
||||
ef9365.h
|
||||
|
||||
Thomson EF9365 video controller
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EF9365_H__
|
||||
#define __EF9365_H__
|
||||
|
||||
|
||||
#define MCFG_EF9365_PALETTE(_palette_tag) \
|
||||
ef9365_device::static_set_palette_tag(*device, "^" _palette_tag);
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> ef9365_device
|
||||
|
||||
class ef9365_device : public device_t,
|
||||
public device_memory_interface,
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
ef9365_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration
|
||||
static void static_set_palette_tag(device_t &device, const char *tag);
|
||||
|
||||
// device interface
|
||||
DECLARE_READ8_MEMBER( data_r );
|
||||
DECLARE_WRITE8_MEMBER( data_w );
|
||||
|
||||
void update_scanline(UINT16 scanline);
|
||||
void static_set_color_filler( UINT8 color );
|
||||
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
// device_config_memory_interface overrides
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
|
||||
|
||||
// address space configurations
|
||||
const address_space_config m_space_config;
|
||||
|
||||
// inline helper
|
||||
|
||||
private:
|
||||
void draw_character( unsigned char c );
|
||||
void set_busy_flag(int period);
|
||||
void set_video_mode(void);
|
||||
void draw_border(UINT16 line);
|
||||
void ef9365_exec(UINT8 cmd);
|
||||
|
||||
// internal state
|
||||
static const device_timer_id BUSY_TIMER = 0;
|
||||
|
||||
memory_region *m_charset;
|
||||
address_space *m_videoram;
|
||||
|
||||
UINT8 m_current_color;
|
||||
UINT8 m_bf; //busy flag
|
||||
UINT8 m_registers[0x10]; //registers
|
||||
UINT8 m_state; //status register
|
||||
UINT8 m_border[80]; //border color
|
||||
|
||||
bitmap_rgb32 m_screen_out;
|
||||
|
||||
// timers
|
||||
emu_timer *m_busy_timer;
|
||||
|
||||
required_device<palette_device> m_palette;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type EF9365;
|
||||
|
||||
#define EF9365_REG_STATUS 0x00
|
||||
#define EF9365_REG_CMD 0x00
|
||||
#define EF9365_REG_CTRL1 0x01
|
||||
#define EF9365_REG_CTRL2 0x02
|
||||
#define EF9365_REG_CSIZE 0x03
|
||||
#define EF9365_REG_DELTAX 0x05
|
||||
#define EF9365_REG_DELTAY 0x07
|
||||
#define EF9365_REG_X_MSB 0x08
|
||||
#define EF9365_REG_X_LSB 0x09
|
||||
#define EF9365_REG_Y_MSB 0x0A
|
||||
#define EF9365_REG_Y_LSB 0x0B
|
||||
#define EF9365_REG_XLP 0x0C
|
||||
#define EF9365_REG_YLP 0x0D
|
||||
|
||||
#define EF9365_REG_CTRL1 0x01
|
||||
#define EF9365_REG_CTRL1 0x01
|
||||
|
||||
#endif
|
@ -1,9 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Miodrag Milanovic
|
||||
// copyright-holders:Miodrag Milanovic, Jean-François DEL NERO
|
||||
/***************************************************************************
|
||||
|
||||
Apollo 7 Squale
|
||||
|
||||
The following hardware description is an extract of the Squale hardware analysis
|
||||
presented on this page : http://hxc2001.free.fr/Squale.
|
||||
This is a work in progress and is subject to changes
|
||||
|
||||
PCB Ref Qty Manufacturer Ref Description / Datasheet
|
||||
============================================================================================
|
||||
U1 1 EF6809P 8-BIT MICROPROCESSOR UNIT (MPU)
|
||||
@ -24,7 +28,7 @@
|
||||
Memory map
|
||||
==========
|
||||
|
||||
Periphiriques Adresses
|
||||
Devices Adresses
|
||||
=========================================================
|
||||
EPROM 0xF100-0xFFFF
|
||||
Extension Port 0xF080-0xF0FF
|
||||
@ -43,32 +47,83 @@
|
||||
|
||||
|
||||
Notes:
|
||||
1) For 8KB versions of the monitor, the bank switching is done via bit 7 of REG1.
|
||||
1) For 8KB versions of the monitor, the bank switching is done with the bit 7 of REG1.
|
||||
2) VID_RD1 : [7..0] = I0,R0,G0,B0,I1,R1,G1,B1 (I=Intensity,R=Red,G=Green,B=Blue)
|
||||
3) VID_RD2 : [7..0] = I2,R2,G2,B2,I3,R3,G3,B3 (I=Intensity,R=Red,G=Green,B=Blue)
|
||||
3) REG1 : [7..0] = EPROM Bank,-,Modem,K7,I,R,G,B (I=Intensity,R=Red,V=Green,B=Blue)
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "video/ef9365.h"
|
||||
#include "machine/6821pia.h"
|
||||
#include "machine/6850acia.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
#define MAIN_CLOCK XTAL_14MHz
|
||||
#define AY_CLOCK MAIN_CLOCK / 8 /* 1.75 Mhz */
|
||||
#define CPU_CLOCK MAIN_CLOCK / 4 /* 3.50 Mhz */
|
||||
|
||||
class squale_state : public driver_device
|
||||
{
|
||||
public:
|
||||
squale_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_acia(*this, "ef6850")
|
||||
, m_ay8910(*this, "ay8910")
|
||||
, m_pia_u72(*this, "pia_u72")
|
||||
, m_pia_u75(*this, "pia_u75")
|
||||
, m_ef9365(*this, "ef9365")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
{ }
|
||||
|
||||
DECLARE_WRITE8_MEMBER(ctrl_w);
|
||||
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(squale_scanline);
|
||||
|
||||
private:
|
||||
required_device<acia6850_device> m_acia;
|
||||
required_device<ay8910_device> m_ay8910;
|
||||
required_device<pia6821_device> m_pia_u72;
|
||||
required_device<pia6821_device> m_pia_u75;
|
||||
required_device<ef9365_device> m_ef9365;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
};
|
||||
|
||||
/*************************
|
||||
* Misc Handlers *
|
||||
*************************/
|
||||
|
||||
WRITE8_MEMBER( squale_state::ctrl_w )
|
||||
{
|
||||
#ifdef DBGMODE
|
||||
printf("write ctrl reg : 0x%X\n",data);
|
||||
#endif
|
||||
|
||||
membank("rom_bank")->set_entry(data >> 7);
|
||||
|
||||
m_ef9365->static_set_color_filler(data & 0xF);
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER( squale_state::squale_scanline )
|
||||
{
|
||||
m_ef9365->update_scanline((UINT16)param);
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START(squale_mem, AS_PROGRAM, 8, squale_state)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
AM_RANGE(0x0000,0xefff) AM_RAM
|
||||
AM_RANGE(0xf100,0xffff) AM_ROM AM_REGION("maincpu", 0x100)
|
||||
AM_RANGE(0xf000,0xf00f) AM_DEVREADWRITE("ef9365", ef9365_device, data_r, data_w)
|
||||
AM_RANGE(0xf010,0xf01f) AM_WRITE( ctrl_w )
|
||||
AM_RANGE(0xf044,0xf047) AM_DEVREADWRITE("pia_u75", pia6821_device, read_alt, write_alt)
|
||||
AM_RANGE(0xf048,0xf04b) AM_DEVREADWRITE("pia_u72", pia6821_device, read_alt, write_alt)
|
||||
AM_RANGE(0xf050,0xf05f) AM_DEVREADWRITE("ef6850", acia6850_device, data_r, data_w)
|
||||
AM_RANGE(0xf060,0xf06f) AM_DEVREADWRITE("ay8910", ay8910_device, data_r, address_data_w)
|
||||
AM_RANGE(0xf100,0xffff) AM_ROMBANK("rom_bank");
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( squale_io, AS_IO, 8, squale_state)
|
||||
@ -79,18 +134,66 @@ ADDRESS_MAP_END
|
||||
static INPUT_PORTS_START( squale )
|
||||
INPUT_PORTS_END
|
||||
|
||||
void squale_state::machine_start()
|
||||
{
|
||||
membank("rom_bank")->configure_entry(0, memregion("maincpu")->base() + 0x100);
|
||||
membank("rom_bank")->configure_entry(1, memregion("maincpu")->base() + 0x1100);
|
||||
membank("rom_bank")->set_entry( 0 );
|
||||
}
|
||||
|
||||
void squale_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( squale, squale_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu",M6809, XTAL_1MHz)
|
||||
MCFG_CPU_ADD("maincpu",M6809, CPU_CLOCK)
|
||||
MCFG_CPU_PROGRAM_MAP(squale_mem)
|
||||
MCFG_CPU_IO_MAP(squale_io)
|
||||
|
||||
/* Cartridge pia */
|
||||
MCFG_DEVICE_ADD("pia_u72", PIA6821, 0)
|
||||
// TODO : Add port I/O handler
|
||||
|
||||
/* Keyboard pia */
|
||||
MCFG_DEVICE_ADD("pia_u75", PIA6821, 0)
|
||||
// TODO : Add port I/O handler
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("ay8910", AY8910, AY_CLOCK)
|
||||
// TODO : Add port I/O handler
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
|
||||
|
||||
MCFG_DEVICE_ADD ("ef6850", ACIA6850, 0)
|
||||
|
||||
/* screen */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_UPDATE_DEVICE("ef9365", ef9365_device, screen_update)
|
||||
|
||||
MCFG_SCREEN_SIZE(336, 270)
|
||||
MCFG_SCREEN_VISIBLE_AREA(00, 336-1, 00, 270-1)
|
||||
MCFG_PALETTE_ADD("palette", 8)
|
||||
|
||||
MCFG_DEVICE_ADD("ef9365", EF9365, 0)
|
||||
MCFG_EF9365_PALETTE("palette")
|
||||
MCFG_TIMER_DRIVER_ADD_SCANLINE("squale_sl", squale_state, squale_scanline, "screen", 0, 10)
|
||||
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/* ROM definition */
|
||||
ROM_START( squale )
|
||||
ROM_REGION( 0x2000, "maincpu", 0 )
|
||||
ROM_LOAD( "sqm2r1.bin", 0x0000, 0x2000, CRC(ed57c707) SHA1(c8bd33a6fb07fe7f881f2605ad867b7e82366bfc) )
|
||||
ROM_DEFAULT_BIOS("v201")
|
||||
|
||||
ROM_SYSTEM_BIOS(0, "v201", "Version 2.1")
|
||||
ROMX_LOAD( "sqmon_2r1.bin", 0x0000, 0x2000, CRC(ed57c707) SHA1(c8bd33a6fb07fe7f881f2605ad867b7e82366bfc), ROM_BIOS(1) )
|
||||
|
||||
// place ROM v1.2 signature here.
|
||||
|
||||
ROM_REGION( 0x1E0, "ef9365", 0 )
|
||||
ROM_LOAD( "charset_ef9365.rom", 0x0000, 0x01E0, CRC(22BE2908) SHA1(3920ee887b8ca2887b3e0471bea7c1045a87fc10) )
|
||||
ROM_END
|
||||
|
||||
/* Driver */
|
||||
|
Loading…
Reference in New Issue
Block a user