Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
vic4_palette.c
Go to the documentation of this file.
1 /* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2016-2021 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5  MEGA65 palette handling for VIC-IV with compatibility for C65 style
6  VIC-III palette.
7 
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21 
22 
23 #include "xemu/emutools.h"
24 #include "vic4_palette.h"
25 #include "vic4.h"
26 
27 
28 // C65/M65 compatible layout of the palette registers, the SDL centric one is the same, but in SDL pixel format: vic_palettes
32 Uint32 vic_palettes[NO_OF_PALETTE_REGS]; // SDL texture format compatible entries of all the four palettes of the MEGA65
33 Uint32 *palette = vic_palettes; // the current used palette for video/text (points into vic_palettes)
34 Uint32 *spritepalette = vic_palettes; // the current used palette for sprites (points into vic_palettes)
36 static struct {
41 } sdlpalinfo;
42 unsigned int palregaccofs;
43 
44 
45 static XEMU_INLINE Uint8 swap_nibbles ( Uint8 i )
46 {
47  return ((i & 0x0F) << 4) | ((i & 0xF0) >> 4);
48 }
49 
50 
52 {
53  for (int i = 0; i < NO_OF_PALETTE_REGS; i++)
54  vic_palettes[i] =
55  sdlpalinfo.alpha_mask |
56  ((swap_nibbles(vic_palette_bytes_red [i] & 0xEF)) << sdlpalinfo.red_shift ) |
57  ( swap_nibbles(vic_palette_bytes_green[i]) << sdlpalinfo.green_shift) |
58  ( swap_nibbles(vic_palette_bytes_blue [i]) << sdlpalinfo.blue_shift ) ;
59 }
60 
61 
62 void vic4_init_palette ( void )
63 {
64  sdlpalinfo.red_shift = sdl_pix_fmt->Rshift;
65  sdlpalinfo.red_mask = 0xFFU << sdlpalinfo.red_shift;
66  sdlpalinfo.red_revmask = ~sdlpalinfo.red_mask;
67  sdlpalinfo.green_shift = sdl_pix_fmt->Gshift;
68  sdlpalinfo.green_mask = 0xFFU << sdlpalinfo.green_shift;
69  sdlpalinfo.green_revmask = ~sdlpalinfo.green_mask;
70  sdlpalinfo.blue_shift = sdl_pix_fmt->Bshift;
71  sdlpalinfo.blue_mask = 0xFFU << sdlpalinfo.blue_shift;
72  sdlpalinfo.blue_revmask = ~sdlpalinfo.blue_mask;
73  sdlpalinfo.alpha_shift = sdl_pix_fmt->Ashift;
74  sdlpalinfo.alpha_mask = 0xFFU << sdlpalinfo.alpha_shift;
75  sdlpalinfo.alpha_revmask = ~sdlpalinfo.alpha_mask;
76  // Only for checking, this should never happen:
77  if (
78  sdlpalinfo.red_mask != sdl_pix_fmt->Rmask ||
79  sdlpalinfo.green_mask != sdl_pix_fmt->Gmask ||
80  sdlpalinfo.blue_mask != sdl_pix_fmt->Bmask ||
81  sdlpalinfo.alpha_mask != sdl_pix_fmt->Amask
82  )
83  FATAL("SDL palette problem!");
84 #ifdef DO_INIT_PALETTE
85  // DO_INIT_PALETTE: I would say, we don't need to initialize palette,
86  // since Hyppo will do it. So DO_INIT_PALETTE is currently not defined.
87  static const Uint8 def_pal[] = {
88  0, 0, 0, // black
89  15, 15, 15, // white
90  15, 0, 0, // red
91  0, 15, 15, // cyan
92  15, 0, 15, // magenta
93  0, 15, 0, // green
94  0, 0, 15, // blue
95  15, 15, 0, // yellow
96  15, 6, 0, // orange
97  10, 4, 0, // brown
98  15, 7, 7, // pink
99  5, 5, 5, // dark grey
100  8, 8, 8, // medium grey
101  9, 15, 9, // light green
102  9, 9, 15, // light blue
103  11, 11, 11 // light grey
104  };
105  for (int i = 0; i < NO_OF_PALETTE_REGS; i++) {
106  vic_palette_bytes_red[i] = (def_pal[(i & 0xF) * 3 + 0] * 16) & 0xEF;
107  vic_palette_bytes_green[i] = def_pal[(i & 0xF) * 3 + 1] * 16;
108  vic_palette_bytes_blue[i] = def_pal[(i & 0xF) * 3 + 2] * 16;
109  }
110 #else
111  for (int i = 0; i < NO_OF_PALETTE_REGS; i++) {
112  vic_palette_bytes_red [i] = 0;
114  vic_palette_bytes_blue [i] = 0;
115  }
116 #endif
118  palette = vic_palettes; // the current used palette for video/text (points into vic_palettes)
119  spritepalette = vic_palettes; // the current used palette for sprites (points into vic_palettes)
121  palregaccofs = 0;
122 }
123 
124 
125 
126 void vic4_write_palette_reg_red ( unsigned int num, Uint8 data )
127 {
128  num = (num & 0xFF) + palregaccofs;
130  vic_palettes[num] = (vic_palettes[num] & sdlpalinfo.red_revmask) | ((swap_nibbles(data & 0xEF)) << sdlpalinfo.red_shift);
131  if (num >= 0x300 && num <= 0x30F) // first 16 entries of bank #3 forms the "ROM palette" of C65
132  vic_palettes[num + 0x100] = vic_palettes[num];
133  if (num >= 0x10 && num <= 0xFF) // rest of the entires of bank #0, also the "ROM palette" emulation stuff
134  vic_palettes[num + 0x400] = vic_palettes[num];
135 }
136 
137 void vic4_write_palette_reg_green ( unsigned int num, Uint8 data )
138 {
139  num = (num & 0xFF) + palregaccofs;
141  vic_palettes[num] = (vic_palettes[num] & sdlpalinfo.green_revmask) | (swap_nibbles(data) << sdlpalinfo.green_shift);
142  if (num >= 0x300 && num <= 0x30F)
143  vic_palettes[num + 0x100] = vic_palettes[num];
144  if (num >= 0x10 && num <= 0xFF)
145  vic_palettes[num + 0x400] = vic_palettes[num];
146 }
147 
148 void vic4_write_palette_reg_blue ( unsigned int num, Uint8 data )
149 {
150  num = (num & 0xFF) + palregaccofs;
152  vic_palettes[num] = (vic_palettes[num] & sdlpalinfo.blue_revmask) | (swap_nibbles(data) << sdlpalinfo.blue_shift);
153  if (num >= 0x300 && num <= 0x30F)
154  vic_palettes[num + 0x100] = vic_palettes[num];
155  if (num >= 0x10 && num <= 0xFF)
156  vic_palettes[num + 0x400] = vic_palettes[num];
157 }
158 
159 void vic3_write_palette_reg_red ( unsigned int num, Uint8 data )
160 {
161  //vic4_write_palette_reg_red (num, (((data & 0xF) * 17) & 0xEF) | (data & 0x10));
162  vic4_write_palette_reg_red(num, data & 0x1F);
163 }
164 
165 void vic3_write_palette_reg_green ( unsigned int num, Uint8 data )
166 {
167  //vic4_write_palette_reg_green(num, (data & 0xF) * 17);
169 }
170 
171 void vic3_write_palette_reg_blue ( unsigned int num, Uint8 data )
172 {
173  //vic4_write_palette_reg_blue (num, (data & 0xF) * 17);
174  vic4_write_palette_reg_blue (num, data & 0xF);
175 }
176 
177 Uint8 vic4_read_palette_reg_red ( unsigned int num )
178 {
179  return vic_palette_bytes_red[(num & 0xFF) + palregaccofs];
180 }
181 
182 Uint8 vic4_read_palette_reg_green ( unsigned int num )
183 {
184  return vic_palette_bytes_green[(num & 0xFF) + palregaccofs];
185 }
186 
187 Uint8 vic4_read_palette_reg_blue ( unsigned int num )
188 {
189  return vic_palette_bytes_blue[(num & 0xFF) + palregaccofs];
190 }
191 
192 void check_if_rom_palette ( int rom_pal )
193 {
194  if (rom_pal) { // ROM palette turned on ...
195  // ... but some pointers points to bank#0: then set to our emulated rom bank
196  if (palette == vic_palettes)
197  palette = vic_palettes + 0x400;
199  spritepalette = vic_palettes + 0x400;
200  if (altpalette == vic_palettes)
201  altpalette = vic_palettes + 0x400;
202  } else { // ROM palette turned off
203  // the opposite as the previous things ...
204  if (palette == vic_palettes + 0x400)
206  if (spritepalette == vic_palettes + 0x400)
208  if (altpalette == vic_palettes + 0x400)
210  }
211 }
vic4.h
NO_OF_PALETTE_REGS
#define NO_OF_PALETTE_REGS
Definition: vic4_palette.h:23
emutools.h
vic4_revalidate_all_palette
void vic4_revalidate_all_palette(void)
Definition: vic4_palette.c:51
vic4_write_palette_reg_green
void vic4_write_palette_reg_green(unsigned int num, Uint8 data)
Definition: vic4_palette.c:137
green_mask
Uint32 green_mask
Definition: vic4_palette.c:38
vic_palettes
Uint32 vic_palettes[NO_OF_PALETTE_REGS]
Definition: vic4_palette.c:32
vic3_write_palette_reg_blue
void vic3_write_palette_reg_blue(unsigned int num, Uint8 data)
Definition: vic4_palette.c:171
vic3_write_palette_reg_green
void vic3_write_palette_reg_green(unsigned int num, Uint8 data)
Definition: vic4_palette.c:165
blue_mask
Uint32 blue_mask
Definition: vic4_palette.c:39
sdl_pix_fmt
SDL_PixelFormat * sdl_pix_fmt
Definition: emutools.c:80
check_if_rom_palette
void check_if_rom_palette(int rom_pal)
Definition: vic4_palette.c:192
spritepalette
Uint32 * spritepalette
Definition: vic4_palette.c:34
vic_palette_bytes_green
Uint8 vic_palette_bytes_green[NO_OF_PALETTE_REGS]
Definition: vic4_palette.c:30
vic4_read_palette_reg_green
Uint8 vic4_read_palette_reg_green(unsigned int num)
Definition: vic4_palette.c:182
blue_shift
Uint32 blue_shift
Definition: vic4_palette.c:39
red_mask
Uint32 red_mask
Definition: vic4_palette.c:37
XEMU_INLINE
#define XEMU_INLINE
Definition: emutools_basicdefs.h:126
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
Uint32
uint32_t Uint32
Definition: fat32.c:49
Uint8
uint8_t Uint8
Definition: fat32.c:51
vic4_init_palette
void vic4_init_palette(void)
Definition: vic4_palette.c:62
palette
Uint32 * palette
Definition: vic4_palette.c:33
green_revmask
Uint32 green_revmask
Definition: vic4_palette.c:38
vic4_read_palette_reg_red
Uint8 vic4_read_palette_reg_red(unsigned int num)
Definition: vic4_palette.c:177
vic_palette_bytes_blue
Uint8 vic_palette_bytes_blue[NO_OF_PALETTE_REGS]
Definition: vic4_palette.c:31
palregaccofs
unsigned int palregaccofs
Definition: vic4_palette.c:42
altpalette
Uint32 * altpalette
Definition: vic4_palette.c:35
blue_revmask
Uint32 blue_revmask
Definition: vic4_palette.c:39
alpha_mask
Uint32 alpha_mask
Definition: vic4_palette.c:40
green_shift
Uint32 green_shift
Definition: vic4_palette.c:38
vic4_write_palette_reg_blue
void vic4_write_palette_reg_blue(unsigned int num, Uint8 data)
Definition: vic4_palette.c:148
alpha_revmask
Uint32 alpha_revmask
Definition: vic4_palette.c:40
vic4_write_palette_reg_red
void vic4_write_palette_reg_red(unsigned int num, Uint8 data)
Definition: vic4_palette.c:126
vic_palette_bytes_red
Uint8 vic_palette_bytes_red[NO_OF_PALETTE_REGS]
Definition: vic4_palette.c:29
vic4_palette.h
vic4_read_palette_reg_blue
Uint8 vic4_read_palette_reg_blue(unsigned int num)
Definition: vic4_palette.c:187
vic3_write_palette_reg_red
void vic3_write_palette_reg_red(unsigned int num, Uint8 data)
Definition: vic4_palette.c:159
FATAL
#define FATAL(...)
Definition: xep128.h:117
red_shift
Uint32 red_shift
Definition: vic4_palette.c:37
red_revmask
Uint32 red_revmask
Definition: vic4_palette.c:37
alpha_shift
Uint32 alpha_shift
Definition: vic4_palette.c:40