summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/wswan.h
blob: 8a6b550b3ca0afb6012c6fd222abe12f027f87f7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// license:BSD-3-Clause
// copyright-holders:Anthony Kruize, Wilbert Pol
/**********************************************************************

 wswan.h

 File to handle video emulation of the Bandai WonderSwan.

 Anthony Kruize
 Wilbert Pol

**********************************************************************/

#ifndef __WSWAN_VIDEO__
#define __WSWAN_VIDEO__


enum
{
	VDP_TYPE_WSWAN = 0,
	VDP_TYPE_WSC
};

#define WSWAN_X_PIXELS  (28*8)
#define WSWAN_Y_PIXELS  (18*8)



typedef device_delegate<void (int irq)> wswan_video_irq_cb_delegate;
#define WSWAN_VIDEO_IRQ_CB_MEMBER(_name)   void _name(int irq)

typedef device_delegate<void (void)> wswan_video_dmasnd_cb_delegate;
#define WSWAN_VIDEO_DMASND_CB_MEMBER(_name)   void _name(void)

#define MCFG_WSWAN_VIDEO_IRQ_CB(_class, _method) \
	wswan_video_device::set_irq_callback(*device, wswan_video_irq_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));

#define MCFG_WSWAN_VIDEO_DMASND_CB(_class, _method) \
	wswan_video_device::set_dmasnd_callback(*device, wswan_video_dmasnd_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));

#define MCFG_WSWAN_VIDEO_TYPE( _type) \
	wswan_video_device::set_vdp_type(*device, _type);


class wswan_video_device : public device_t
{
public:
	wswan_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	~wswan_video_device() {}

	// static configuration
	static void set_irq_callback(device_t &device, wswan_video_irq_cb_delegate callback) { downcast<wswan_video_device &>(device).m_set_irq_cb = callback; }
	static void set_dmasnd_callback(device_t &device, wswan_video_dmasnd_cb_delegate callback) { downcast<wswan_video_device &>(device).m_snd_dma_cb = callback; }
	static void set_vdp_type(device_t &device, int type) { downcast<wswan_video_device &>(device).m_vdp_type = type; }

	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);

	virtual DECLARE_READ8_MEMBER(vram_r);
	virtual DECLARE_WRITE8_MEMBER(vram_w);
	virtual DECLARE_READ8_MEMBER(reg_r);
	virtual DECLARE_WRITE8_MEMBER(reg_w);

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	void setup_palettes();
	void draw_background();
	void draw_foreground_0();
	void draw_foreground_2();
	void draw_foreground_3();
	void handle_sprites(int mask);
	void refresh_scanline();
	void scanline_interrupt();
	void common_save();

	bitmap_ind16 m_bitmap;
	uint8_t m_layer_bg_enable;          /* Background layer on/off */
	uint8_t m_layer_fg_enable;          /* Foreground layer on/off */
	uint8_t m_sprites_enable;           /* Sprites on/off */
	uint8_t m_window_sprites_enable;        /* Sprite window on/off */
	uint8_t m_window_fg_mode;           /* 0:inside/outside, 1:??, 2:inside, 3:outside */
	uint8_t m_bg_control;
	uint8_t m_current_line;         /* Current scanline : 0-158 (159?) */
	uint8_t m_line_compare;         /* Line to trigger line interrupt on */
	uint32_t m_sprite_table_address;        /* Address of the sprite table */
	uint8_t m_sprite_table_buffer[512];
	uint8_t m_sprite_first;         /* First sprite to draw */
	uint8_t m_sprite_count;         /* Number of sprites to draw */
	uint8_t m_sprite_first_latch;
	uint8_t m_sprite_count_latch;
	uint16_t m_layer_bg_address;        /* Address of the background screen map */
	uint16_t m_layer_fg_address;        /* Address of the foreground screen map */
	uint8_t m_window_fg_left;           /* Left coordinate of foreground window */
	uint8_t m_window_fg_top;            /* Top coordinate of foreground window */
	uint8_t m_window_fg_right;          /* Right coordinate of foreground window */
	uint8_t m_window_fg_bottom;         /* Bottom coordinate of foreground window */
	uint8_t m_window_sprites_left;      /* Left coordinate of sprites window */
	uint8_t m_window_sprites_top;       /* Top coordinate of sprites window */
	uint8_t m_window_sprites_right;     /* Right coordinate of sprites window */
	uint8_t m_window_sprites_bottom;        /* Bottom coordinate of sprites window */
	uint8_t m_layer_bg_scroll_x;        /* Background layer X scroll */
	uint8_t m_layer_bg_scroll_y;        /* Background layer Y scroll */
	uint8_t m_layer_fg_scroll_x;        /* Foreground layer X scroll */
	uint8_t m_layer_fg_scroll_y;        /* Foreground layer Y scroll */
	uint8_t m_lcd_control;           /* LCD on/off */
	uint8_t m_icons;                /* FIXME: What do we do with these? Maybe artwork? */
	uint8_t m_color_mode;           /* monochrome/color mode */
	uint8_t m_colors_16;            /* 4/16 colors mode */
	uint8_t m_tile_packed;          /* layered/packed tile mode switch */
	uint8_t m_timer_hblank_enable;      /* Horizontal blank interrupt on/off */
	uint8_t m_timer_hblank_mode;        /* Horizontal blank timer mode */
	uint16_t m_timer_hblank_reload;     /* Horizontal blank timer reload value */
	uint16_t m_timer_hblank_count;      /* Horizontal blank timer counter value */
	uint8_t m_timer_vblank_enable;      /* Vertical blank interrupt on/off */
	uint8_t m_timer_vblank_mode;        /* Vertical blank timer mode */
	uint16_t m_timer_vblank_reload;     /* Vertical blank timer reload value */
	uint16_t m_timer_vblank_count;      /* Vertical blank timer counter value */
	int m_main_palette[8];
	emu_timer *m_timer;

	std::vector<uint8_t> m_vram;
	uint8_t *m_palette_vram;
	uint8_t m_palette_port[0x20];
	int m_pal[16][16];
	uint8_t m_regs[256];

	wswan_video_irq_cb_delegate m_set_irq_cb;
	wswan_video_dmasnd_cb_delegate m_snd_dma_cb;
	int m_vdp_type;

	// timer IDs
	static const device_timer_id TIMER_SCANLINE = 0;

	// interrupt flags
	// these are the same as the wswan.h ones
	static const uint8_t WSWAN_VIDEO_IFLAG_LCMP   = 0x10;
	static const uint8_t WSWAN_VIDEO_IFLAG_VBLTMR = 0x20;
	static const uint8_t WSWAN_VIDEO_IFLAG_VBL    = 0x40;
	static const uint8_t WSWAN_VIDEO_IFLAG_HBLTMR = 0x80;
};

extern const device_type WSWAN_VIDEO;


#endif