1 // license:BSD-3-Clause 2 // copyright-holders:Curt Coder 3 /********************************************************************** 4 5 RCA CDP1869/1870/1876 Video Interface System (VIS) emulation 6 7 ********************************************************************** 8 _____ _____ 9 TPA 1 |* \_/ | 40 Vdd 10 TPB 2 | | 39 PMSEL 11 _MRD 3 | | 38 _PMWR 12 _MWR 4 | | 37 CMSEL 13 MA0/8 5 | | 36 _CMWR 14 MA1/9 6 | | 35 PMA0 15 MA2/10 7 | | 34 PMA1 16 MA3/11 8 | | 33 PMA2 17 MA4/12 9 | | 32 PMA3 18 MA5/13 10 | | 31 PMA4 19 MA6/14 11 | CDP1869 | 30 PMA5 20 MA7/15 12 | | 29 PMA6 21 N0 13 | | 28 PMA7 22 N1 14 | | 27 PMA8 23 N2 15 | | 26 PMA9 24 _H SYNC 16 | | 25 CMA3/PMA10 25 _DISPLAY 17 | | 24 CMA2 26 _ADDRSTB 18 | | 23 CMA1 27 SOUND 19 | | 22 CMA0 28 Vss 20 |_____________| 21 _N=3 29 30 _____ _____ 31 _PREDISPLAY 1 |* \_/ | 40 Vdd 32 _DISPLAY 2 | | 39 PAL/_NTSC 33 PCB 3 | | 38 CPUCLK 34 CCB1 4 | | 37 XTAL (DOT) 35 BUS7 5 | | 36 _XTAL (DOT) 36 CCB0 6 | | 35 _ADDRSTB 37 BUS6 7 | | 34 _MRD 38 CDB5 8 | | 33 TPB 39 BUS5 9 | | 32 CMSEL 40 CDB4 10 | | 31 BURST 41 BUS4 11 | CDP1870 | 30 _H SYNC 42 CDB3 12 | | 29 _COMPSYNC 43 BUS3 13 | | 28 LUM 44 CDB2 14 | | 27 PAL CHROM 45 BUS2 15 | | 26 NTSC CHROM 46 CDB1 16 | | 25 _XTAL (CHROM) 47 BUS1 17 | | 24 XTAL (CHROM) 48 CDB0 18 | | 23 _EMS 49 BUS0 19 | | 22 _EVS 50 Vss 20 |_____________| 21 _N=3 51 52 _____ _____ 53 _PREDISPLAY 1 |* \_/ | 40 Vdd 54 _DISPLAY 2 | | 39 PAL/_NTSC 55 PCB 3 | | 38 CPUCLK 56 CCB1 4 | | 37 XTAL (DOT) 57 BUS7 5 | | 36 _XTAL (DOT) 58 CCB0 6 | | 35 _ADDRSTB 59 BUS6 7 | | 34 _MRD 60 CDB5 8 | | 33 TPB 61 BUS5 9 | | 32 CMSEL 62 CDB4 10 | | 31 BURST 63 BUS4 11 | CDP1876 | 30 _H SYNC 64 CDB3 12 | | 29 _COMPSYNC 65 BUS3 13 | | 28 RED 66 CDB2 14 | | 27 BLUE 67 BUS2 15 | | 26 GREEN 68 CDB1 16 | | 25 _XTAL (CHROM) 69 BUS1 17 | | 24 XTAL (CHROM) 70 CDB0 18 | | 23 _EMS 71 BUS0 19 | | 22 _EVS 72 Vss 20 |_____________| 21 _N=3 73 74 **********************************************************************/ 75 76 #ifndef MAME_SOUND_CDP1869_H 77 #define MAME_SOUND_CDP1869_H 78 79 #pragma once 80 81 #include "emupal.h" 82 #include "screen.h" 83 84 //************************************************************************** 85 // TYPE DEFINITIONS 86 //************************************************************************** 87 88 #define CDP1869_CHAR_RAM_READ_MEMBER(name) uint8_t name(uint16_t pma, uint8_t cma, uint8_t pmd) 89 #define CDP1869_CHAR_RAM_WRITE_MEMBER(name) void name(uint16_t pma, uint8_t cma, uint8_t pmd, uint8_t data) 90 #define CDP1869_PCB_READ_MEMBER(name) int name(uint16_t pma, uint8_t cma, uint8_t pmd) 91 92 // ======================> cdp1869_device 93 94 class cdp1869_device : public device_t, 95 public device_sound_interface, 96 public device_video_interface, 97 public device_memory_interface 98 { 99 public: 100 static constexpr auto DOT_CLK_PAL = XTAL(5'626'000); 101 static constexpr auto DOT_CLK_NTSC = XTAL(5'670'000); 102 static constexpr auto COLOR_CLK_PAL = XTAL(8'867'236); 103 static constexpr auto COLOR_CLK_NTSC = XTAL(7'159'090); 104 105 static constexpr auto CPU_CLK_PAL = DOT_CLK_PAL / 2; 106 static constexpr auto CPU_CLK_NTSC = DOT_CLK_NTSC / 2; 107 108 static constexpr unsigned CH_WIDTH = 6; 109 110 static constexpr unsigned HSYNC_START = 56 * CH_WIDTH; 111 static constexpr unsigned HSYNC_END = 60 * CH_WIDTH; 112 static constexpr unsigned HBLANK_START = 54 * CH_WIDTH; 113 static constexpr unsigned HBLANK_END = 5 * CH_WIDTH; 114 static constexpr unsigned SCREEN_START_PAL = 9 * CH_WIDTH; 115 static constexpr unsigned SCREEN_START_NTSC = 10 * CH_WIDTH; 116 static constexpr unsigned SCREEN_START = 10 * CH_WIDTH; 117 static constexpr unsigned SCREEN_END = 50 * CH_WIDTH; 118 static constexpr unsigned SCREEN_WIDTH = 60 * CH_WIDTH; 119 120 static constexpr unsigned TOTAL_SCANLINES_PAL = 312; 121 static constexpr unsigned SCANLINE_VBLANK_START_PAL = 304; 122 static constexpr unsigned SCANLINE_VBLANK_END_PAL = 10; 123 static constexpr unsigned SCANLINE_VSYNC_START_PAL = 308; 124 static constexpr unsigned SCANLINE_VSYNC_END_PAL = 312; 125 static constexpr unsigned SCANLINE_DISPLAY_START_PAL = 44; 126 static constexpr unsigned SCANLINE_DISPLAY_END_PAL = 260; 127 static constexpr unsigned SCANLINE_PREDISPLAY_START_PAL = 43; 128 static constexpr unsigned SCANLINE_PREDISPLAY_END_PAL = 260; 129 static constexpr unsigned VISIBLE_SCANLINES_PAL = SCANLINE_DISPLAY_END_PAL - SCANLINE_DISPLAY_START_PAL; 130 131 static constexpr unsigned TOTAL_SCANLINES_NTSC = 262; 132 static constexpr unsigned SCANLINE_VBLANK_START_NTSC = 252; 133 static constexpr unsigned SCANLINE_VBLANK_END_NTSC = 10; 134 static constexpr unsigned SCANLINE_VSYNC_START_NTSC = 258; 135 static constexpr unsigned SCANLINE_VSYNC_END_NTSC = 262; 136 static constexpr unsigned SCANLINE_DISPLAY_START_NTSC = 36; 137 static constexpr unsigned SCANLINE_DISPLAY_END_NTSC = 228; 138 static constexpr unsigned SCANLINE_PREDISPLAY_START_NTSC = 35; 139 static constexpr unsigned SCANLINE_PREDISPLAY_END_NTSC = 228; 140 static constexpr unsigned VISIBLE_SCANLINES_NTSC = SCANLINE_DISPLAY_END_NTSC - SCANLINE_DISPLAY_START_NTSC; 141 142 static constexpr unsigned PALETTE_LENGTH = 8+64; 143 144 typedef device_delegate<uint8_t (uint16_t pma, uint8_t cma, uint8_t pmd)> char_ram_read_delegate; 145 typedef device_delegate<void (uint16_t pma, uint8_t cma, uint8_t pmd, uint8_t data)> char_ram_write_delegate; 146 typedef device_delegate<int (uint16_t pma, uint8_t cma, uint8_t pmd)> pcb_read_delegate; 147 148 // construction/destruction 149 template <typename T> cdp1869_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,T && addrmap)150 cdp1869_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&addrmap) 151 : cdp1869_device(mconfig, tag, owner, clock) 152 { 153 set_addrmap(0, std::forward<T>(addrmap)); 154 } 155 cdp1869_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 156 pal_ntsc_callback()157 auto pal_ntsc_callback() { return m_read_pal_ntsc.bind(); } prd_callback()158 auto prd_callback() { return m_write_prd.bind(); } set_color_clock(int color_clock)159 void set_color_clock(int color_clock) { m_color_clock = color_clock; } set_color_clock(const XTAL & xtal)160 void set_color_clock(const XTAL &xtal) { xtal.validate("selecting cdp1869 clock"); set_color_clock(xtal.value()); } 161 162 // delegate setters set_char_ram_read_callback(T &&...args)163 template <typename... T> void set_char_ram_read_callback(T &&... args) { m_in_char_ram_func.set(std::forward<T>(args)...); } set_char_ram_write_callback(T &&...args)164 template <typename... T> void set_char_ram_write_callback(T &&... args) { m_out_char_ram_func.set(std::forward<T>(args)...); } set_pcb_read_callback(T &&...args)165 template <typename... T> void set_pcb_read_callback(T &&... args) { m_in_pcb_func.set(std::forward<T>(args)...); } 166 167 // helper functions add_pal_screen(machine_config & config,T && screen_tag,U && clock)168 template <typename T, typename U> screen_device& add_pal_screen(machine_config &config, T &&screen_tag, U &&clock) 169 { 170 screen_device &screen(SCREEN(config, std::forward<T>(screen_tag), SCREEN_TYPE_RASTER)); 171 screen.set_screen_update(tag(), FUNC(cdp1869_device::screen_update)); 172 screen.set_raw(std::forward<U>(clock), cdp1869_device::SCREEN_WIDTH, cdp1869_device::HBLANK_END, cdp1869_device::HBLANK_START, 173 cdp1869_device::TOTAL_SCANLINES_PAL, cdp1869_device::SCANLINE_VBLANK_END_PAL, cdp1869_device::SCANLINE_VBLANK_START_PAL); 174 return screen; 175 } 176 add_ntsc_screen(machine_config & config,T && screen_tag,U && clock)177 template <typename T, typename U> screen_device& add_ntsc_screen(machine_config &config, T &&screen_tag, U &&clock) 178 { 179 screen_device &screen(SCREEN(config, std::forward<T>(screen_tag), SCREEN_TYPE_RASTER)); 180 screen.set_screen_update(tag(), FUNC(cdp1869_device::screen_update)); 181 screen.set_raw(std::forward<U>(clock), cdp1869_device::SCREEN_WIDTH, cdp1869_device::HBLANK_END, cdp1869_device::HBLANK_START, 182 cdp1869_device::TOTAL_SCANLINES_NTSC, cdp1869_device::SCANLINE_VBLANK_END_NTSC, cdp1869_device::SCANLINE_VBLANK_START_NTSC); 183 return screen; 184 } 185 186 virtual void io_map(address_map &map); 187 virtual void char_map(address_map &map); 188 virtual void page_map(address_map &map); 189 190 void out3_w(uint8_t data); 191 void out4_w(offs_t offset); 192 void out5_w(offs_t offset); 193 void out6_w(offs_t offset); 194 void out7_w(offs_t offset); 195 196 uint8_t char_ram_r(offs_t offset); 197 void char_ram_w(offs_t offset, uint8_t data); 198 199 uint8_t page_ram_r(offs_t offset); 200 void page_ram_w(offs_t offset, uint8_t data); 201 202 int predisplay_r(); 203 int pal_ntsc_r(); 204 205 uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); 206 207 void cdp1869(address_map &map); 208 protected: 209 // device-level overrides 210 virtual void device_add_mconfig(machine_config &config) override; 211 virtual void device_start() override; 212 virtual void device_post_load() override; 213 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; 214 215 // device_memory_interface overrides 216 virtual space_config_vector memory_space_config() const override; 217 218 // device_sound_interface callbacks 219 virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; 220 221 inline bool is_ntsc(); 222 inline uint8_t read_page_ram_byte(offs_t address); 223 inline void write_page_ram_byte(offs_t address, uint8_t data); 224 inline uint8_t read_char_ram_byte(offs_t pma, offs_t cma, uint8_t pmd); 225 inline void write_char_ram_byte(offs_t pma, offs_t cma, uint8_t pmd, uint8_t data); 226 inline int read_pcb(offs_t pma, offs_t cma, uint8_t pmd); 227 inline void update_prd_changed_timer(); 228 static rgb_t get_rgb(int i, int c, int l); 229 inline int get_lines(); 230 inline uint16_t get_pmemsize(int cols, int rows); 231 inline uint16_t get_pma(); 232 inline int get_pen(int ccb0, int ccb1, int pcb); 233 234 void draw_line(bitmap_rgb32 &bitmap, const rectangle &rect, int x, int y, uint8_t data, int color); 235 void draw_char(bitmap_rgb32 &bitmap, const rectangle &rect, int x, int y, uint16_t pma); 236 237 private: 238 devcb_read_line m_read_pal_ntsc; 239 devcb_write_line m_write_prd; 240 pcb_read_delegate m_in_pcb_func; 241 char_ram_read_delegate m_in_char_ram_func; 242 char_ram_write_delegate m_out_char_ram_func; 243 int m_color_clock; 244 245 //address_space *m_page_ram; 246 emu_timer *m_prd_timer; 247 sound_stream *m_stream; 248 required_device<palette_device> m_palette; 249 const address_space_config m_space_config; 250 251 // video state 252 int m_prd; // predisplay 253 int m_dispoff; // display off 254 int m_fresvert; // full resolution vertical 255 int m_freshorz; // full resolution horizontal 256 int m_cmem; // character memory access mode 257 int m_dblpage; // double page mode 258 int m_line16; // 16-line hi-res mode 259 int m_line9; // 9 line mode 260 int m_cfc; // color format control 261 uint8_t m_col; // character color control 262 uint8_t m_bkg; // background color 263 uint16_t m_pma; // page memory address 264 uint16_t m_hma; // home memory address 265 266 // sound state 267 stream_buffer::sample_t m_signal; // current signal 268 int m_incr; // initial wave state 269 int m_toneoff; // tone off 270 int m_wnoff; // white noise off 271 uint8_t m_tonediv; // tone divisor 272 uint8_t m_tonefreq; // tone range select 273 uint8_t m_toneamp; // tone output amplitude 274 uint8_t m_wnfreq; // white noise range select 275 uint8_t m_wnamp; // white noise output amplitude 276 277 void cdp1869_palette(palette_device &palette) const; 278 }; 279 280 281 // device type definition 282 DECLARE_DEVICE_TYPE(CDP1869, cdp1869_device) 283 284 #endif // MAME_SOUND_CDP1869_H 285