2024-02-09 08:45:34 +00:00
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright ( C ) 2018 - 24 divingkatae and maximum
( theweirdo ) spatium
( Contact divingkatae # 1017 or powermax # 2286 on Discord for more info )
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 3 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 , see < https : //www.gnu.org/licenses/>.
*/
/** Definitions for the Apple RAMDAC ASICs (RaDACal & DACula). */
# ifndef APPLE_RAMDAC_H
# define APPLE_RAMDAC_H
# include <devices/common/hwcomponent.h>
# include <devices/ioctrl/macio.h>
# include <cinttypes>
# include <functional>
enum DacFlavour {
RADACAL ,
DACULA ,
} ;
2024-02-18 13:00:47 +00:00
# define DACULA_VENDOR_SIERRA 0x3C // 14.3 MHz
# define DACULA_VENDOR_OTHER 0x84 // 15 MHz
2024-02-09 08:45:34 +00:00
constexpr auto VIDEO_XTAL = 14318180.0f ; // external crystal oscillator frequency
namespace RamdacRegs {
enum RamdacRegs : uint8_t {
ADDRESS = 0 , // address register
CURSOR_CLUT = 1 , // cursor palette data
MULTI = 2 , // multipurpose section
CLUT_DATA = 3 , // color palette data
// multipurpose section registers (both RaDACal & DACula)
CURSOR_POS_HI = 0x10 , // cursor position, high-order byte
CURSOR_POS_LO = 0x11 , // cursor position, low-order byte
2024-02-18 12:16:50 +00:00
MISC_CTRL = 0x20 , // miscellaneus control bits ; Dacula: read ; when 1MB VRAM then write (mode&15) else write (mode)
DBL_BUF_CTRL = 0x21 , // double buffer control bits ; Dacula: write 4; Radical: set to 0 if using optional bank (bankb) in Open Firmware or for 2nd page in ndrv
TEST_CTRL = 0x22 , // enable/disable DAC tests ; Dacula: write 0
2024-02-09 08:45:34 +00:00
// multipurpose section registers (DACula only)
2024-02-18 12:16:50 +00:00
PLL_CTRL = 0x23 , // phase locked loop control ; Dacula: if read 2 then write 3 else write 2 <-
VIDCLK_M_SET_A = 0x24 , // M parameter for the set A ; Dacula: N2 for 2
VIDCLK_PN_SET_A = 0x25 , // P & N parameters for the set A ; Dacula: D2 for 2
// = 0x26, // Dacula: write 0xc6 before changing the clock
VIDCLK_M_SET_B = 0x27 , // M parameter for the set B ; Dacula: N2 for 3 <-
VIDCLK_PN_SET_B = 0x28 , // P & N parameters for the set B ; Dacula: D2 for 3 <-
DAC_29 = 0x29 , // Dacula: linux writes 0xa6 after changing the clock ; macrom writes 0xc6
VENDOR_ID = 0x40 , // Dacula: DAC_TYPE 0x3c or 0x84
2024-02-09 08:45:34 +00:00
} ;
} ; // namespace RamdacRegs
2024-02-18 12:25:04 +00:00
typedef std : : function < void ( uint8_t index , uint8_t * colors ) > GetClutEntryCallback ;
2024-02-09 08:45:34 +00:00
typedef std : : function < void ( uint8_t index , uint8_t * colors ) > SetClutEntryCallback ;
typedef std : : function < void ( bool cursor_on ) > CursorCtrlCallback ;
class AppleRamdac : public HWComponent , public IobusDevice {
public :
AppleRamdac ( DacFlavour flavour ) ;
~ AppleRamdac ( ) = default ;
uint16_t iodev_read ( uint32_t address ) ;
void iodev_write ( uint32_t address , uint16_t value ) ;
int get_clock_div ( ) ;
int get_pix_width ( ) ;
int get_dot_freq ( ) ;
2024-01-31 01:26:37 +00:00
uint8_t get_dbl_buf_cr ( ) { return dbl_buf_cr ; }
2024-02-09 08:45:34 +00:00
void set_fb_parameters ( int width , int height , uint32_t pitch ) {
this - > video_width = width ;
this - > video_height = height ;
this - > fb_pitch = pitch ;
} ;
void measure_hw_cursor ( uint8_t * fb_ptr ) ;
void draw_hw_cursor ( uint8_t * src_buf , uint8_t * dst_buf , int dst_pitch ) ;
2024-02-18 12:25:04 +00:00
GetClutEntryCallback get_clut_entry_cb = nullptr ;
2024-02-09 08:45:34 +00:00
SetClutEntryCallback set_clut_entry_cb = nullptr ;
CursorCtrlCallback cursor_ctrl_cb = nullptr ;
protected :
DacFlavour flavour ;
uint8_t dac_addr = 0 ;
uint8_t dac_cr = 0 ;
uint8_t dbl_buf_cr = 0 ;
uint8_t tst_cr = 0 ;
uint16_t cursor_xpos = 0 ; // horizontal position of the cursor region
uint16_t cursor_ypos = 0 ;
uint16_t cursor_height = 0 ;
uint8_t cursor_pos_lo = 0 ;
uint8_t clk_m [ 2 ] = { } ;
uint8_t clk_pn [ 2 ] = { } ;
uint8_t pll_cr = 0 ;
2024-02-18 13:00:47 +00:00
uint8_t dac_vendor = DACULA_VENDOR_SIERRA ;
2024-02-09 08:45:34 +00:00
uint8_t comp_index = 0 ;
uint8_t clut_color [ 3 ] = { } ;
uint32_t cursor_clut [ 8 ] = { } ;
int video_width = 0 ;
int video_height = 0 ;
uint32_t fb_pitch = 0 ;
} ;
# endif // APPLE_RAMDAC_H