Include latest peanut_gb.h from deltabeard
This commit is contained in:
+39
-28
@@ -104,11 +104,6 @@
|
|||||||
# define PEANUT_GB_USE_INTRINSICS 1
|
# define PEANUT_GB_USE_INTRINSICS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Function definition for abort(). */
|
|
||||||
#ifndef PEANUT_GB_ABORT
|
|
||||||
# define PEANUT_GB_ABORT() abort()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Internal source code. **/
|
/** Internal source code. **/
|
||||||
/* Interrupt masks */
|
/* Interrupt masks */
|
||||||
#define VBLANK_INTR 0x01
|
#define VBLANK_INTR 0x01
|
||||||
@@ -226,11 +221,17 @@
|
|||||||
# define __has_builtin(x) 0
|
# define __has_builtin(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The PGB_UNREACHABLE() macro tells the compiler that the code path will never
|
||||||
|
* be reached, allowing for further optimisation. */
|
||||||
|
#if !defined(PGB_UNREACHABLE)
|
||||||
# if __has_builtin(__builtin_unreachable)
|
# if __has_builtin(__builtin_unreachable)
|
||||||
# define PGB_UNREACHABLE() __builtin_unreachable()
|
# define PGB_UNREACHABLE() __builtin_unreachable()
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
# define PGB_UNREACHABLE() __assume(0)
|
||||||
# else
|
# else
|
||||||
# define PGB_UNREACHABLE() PEANUT_GB_ABORT()
|
# define PGB_UNREACHABLE() abort()
|
||||||
# endif
|
# endif
|
||||||
|
#endif /* !defined(PGB_UNREACHABLE) */
|
||||||
|
|
||||||
#if PEANUT_GB_USE_INTRINSICS
|
#if PEANUT_GB_USE_INTRINSICS
|
||||||
/* If using MSVC, only enable intrinsics for x86 platforms*/
|
/* If using MSVC, only enable intrinsics for x86 platforms*/
|
||||||
@@ -342,10 +343,10 @@ struct cpu_registers_s
|
|||||||
/* Define specific bits of Flag register. */
|
/* Define specific bits of Flag register. */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned c : 1; /* Carry flag. */
|
uint8_t c : 1; /* Carry flag. */
|
||||||
unsigned h : 1; /* Half carry flag. */
|
uint8_t h : 1; /* Half carry flag. */
|
||||||
unsigned n : 1; /* Add/sub flag. */
|
uint8_t n : 1; /* Add/sub flag. */
|
||||||
unsigned z : 1; /* Zero flag. */
|
uint8_t z : 1; /* Zero flag. */
|
||||||
} f_bits;
|
} f_bits;
|
||||||
uint8_t a;
|
uint8_t a;
|
||||||
|
|
||||||
@@ -760,7 +761,7 @@ uint8_t __gb_read(struct gb_s *gb, const uint16_t addr)
|
|||||||
|
|
||||||
/* Return address that caused read error. */
|
/* Return address that caused read error. */
|
||||||
(gb->gb_error)(gb, GB_INVALID_READ, addr);
|
(gb->gb_error)(gb, GB_INVALID_READ, addr);
|
||||||
// PGB_UNREACHABLE();
|
PGB_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1065,9 +1066,8 @@ void __gb_write(struct gb_s *gb, const uint_fast16_t addr, const uint8_t val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return address that caused write error. */
|
/* Invalid writes are ignored. */
|
||||||
(gb->gb_error)(gb, GB_INVALID_WRITE, addr);
|
return;
|
||||||
// PGB_UNREACHABLE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t __gb_execute_cb(struct gb_s *gb)
|
uint8_t __gb_execute_cb(struct gb_s *gb)
|
||||||
@@ -1289,6 +1289,7 @@ static int compare_sprites(const void *in1, const void *in2)
|
|||||||
void __gb_draw_line(struct gb_s *gb)
|
void __gb_draw_line(struct gb_s *gb)
|
||||||
{
|
{
|
||||||
uint8_t pixels[160] = {0};
|
uint8_t pixels[160] = {0};
|
||||||
|
uint8_t bg_priority[20];
|
||||||
|
|
||||||
/* If LCD not initialised by front-end, don't render anything. */
|
/* If LCD not initialised by front-end, don't render anything. */
|
||||||
if(gb->display.lcd_draw_line == NULL)
|
if(gb->display.lcd_draw_line == NULL)
|
||||||
@@ -1349,6 +1350,8 @@ void __gb_draw_line(struct gb_s *gb)
|
|||||||
|
|
||||||
uint16_t tile;
|
uint16_t tile;
|
||||||
|
|
||||||
|
bg_priority[disp_x/8] = idx;
|
||||||
|
|
||||||
/* Select addressing mode. */
|
/* Select addressing mode. */
|
||||||
if(gb->hram_io[IO_LCDC] & LCDC_TILE_SELECT)
|
if(gb->hram_io[IO_LCDC] & LCDC_TILE_SELECT)
|
||||||
tile = VRAM_TILES_1 + idx * 0x10;
|
tile = VRAM_TILES_1 + idx * 0x10;
|
||||||
@@ -1378,6 +1381,8 @@ void __gb_draw_line(struct gb_s *gb)
|
|||||||
tile += 2 * py;
|
tile += 2 * py;
|
||||||
t1 = gb->vram[tile];
|
t1 = gb->vram[tile];
|
||||||
t2 = gb->vram[tile + 1];
|
t2 = gb->vram[tile + 1];
|
||||||
|
|
||||||
|
bg_priority[disp_x / 8] = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy background */
|
/* copy background */
|
||||||
@@ -1544,6 +1549,9 @@ void __gb_draw_line(struct gb_s *gb)
|
|||||||
// handle x flip
|
// handle x flip
|
||||||
uint8_t dir, start, end, shift;
|
uint8_t dir, start, end, shift;
|
||||||
|
|
||||||
|
uint8_t bg_priority_tile;
|
||||||
|
uint8_t tile_has_priority;
|
||||||
|
|
||||||
if(OF & OBJ_FLIP_X)
|
if(OF & OBJ_FLIP_X)
|
||||||
{
|
{
|
||||||
dir = 1;
|
dir = 1;
|
||||||
@@ -1559,25 +1567,30 @@ void __gb_draw_line(struct gb_s *gb)
|
|||||||
shift = OX - (start + 1);
|
shift = OX - (start + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bg_priority_tile = bg_priority[start / 8];
|
||||||
|
tile_has_priority = OT < bg_priority_tile;
|
||||||
|
|
||||||
// copy tile
|
// copy tile
|
||||||
t1 >>= shift;
|
t1 >>= shift;
|
||||||
t2 >>= shift;
|
t2 >>= shift;
|
||||||
|
|
||||||
|
/* TODO: Put for loop within the to if statements
|
||||||
|
* because the BG priority bit will be the same for
|
||||||
|
* all the pixels in the tile. */
|
||||||
for(uint8_t disp_x = start; disp_x != end; disp_x += dir)
|
for(uint8_t disp_x = start; disp_x != end; disp_x += dir)
|
||||||
{
|
{
|
||||||
uint8_t c = (t1 & 0x1) | ((t2 & 0x1) << 1);
|
uint8_t c = (t1 & 0x1) | ((t2 & 0x1) << 1);
|
||||||
// check transparency / sprite overlap / background overlap
|
// check transparency / sprite overlap / background overlap
|
||||||
#if 0
|
|
||||||
|
|
||||||
if(c
|
if(c && (OF & OBJ_PRIORITY) && tile_has_priority)
|
||||||
// && OX <= fx[disp_x]
|
{
|
||||||
&& !((OF & OBJ_PRIORITY)
|
/* Set pixel colour. */
|
||||||
&& ((pixels[disp_x] & 0x3)
|
pixels[disp_x] ^= (OF & OBJ_PALETTE)
|
||||||
&& fx[disp_x] == 0xFE)))
|
? gb->display.sp_palette[c + 4]
|
||||||
#else
|
: gb->display.sp_palette[c];
|
||||||
if(c && !(OF & OBJ_PRIORITY
|
pixels[disp_x] = ((~pixels[disp_x]) & 0x3);
|
||||||
&& pixels[disp_x] & 0x3))
|
}
|
||||||
#endif
|
else if(c && !(OF & OBJ_PRIORITY && (pixels[disp_x] & 0x3)))
|
||||||
{
|
{
|
||||||
/* Set pixel colour. */
|
/* Set pixel colour. */
|
||||||
pixels[disp_x] = (OF & OBJ_PALETTE)
|
pixels[disp_x] = (OF & OBJ_PALETTE)
|
||||||
@@ -1585,8 +1598,6 @@ void __gb_draw_line(struct gb_s *gb)
|
|||||||
: gb->display.sp_palette[c];
|
: gb->display.sp_palette[c];
|
||||||
/* Set pixel palette (OBJ0 or OBJ1). */
|
/* Set pixel palette (OBJ0 or OBJ1). */
|
||||||
pixels[disp_x] |= (OF & OBJ_PALETTE);
|
pixels[disp_x] |= (OF & OBJ_PALETTE);
|
||||||
/* Deselect BG palette. */
|
|
||||||
pixels[disp_x] &= ~LCD_PALETTE_BG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t1 = t1 >> 1;
|
t1 = t1 >> 1;
|
||||||
@@ -2329,7 +2340,7 @@ void __gb_step_cpu(struct gb_s *gb)
|
|||||||
/* This may be intentional, but this is required to stop an infinite
|
/* This may be intentional, but this is required to stop an infinite
|
||||||
* loop. */
|
* loop. */
|
||||||
(gb->gb_error)(gb, GB_HALT_FOREVER, gb->cpu_reg.pc.reg - 1);
|
(gb->gb_error)(gb, GB_HALT_FOREVER, gb->cpu_reg.pc.reg - 1);
|
||||||
// PGB_UNREACHABLE();
|
PGB_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gb->hram_io[IO_SC] & SERIAL_SC_TX_START)
|
if(gb->hram_io[IO_SC] & SERIAL_SC_TX_START)
|
||||||
@@ -3246,7 +3257,7 @@ void __gb_step_cpu(struct gb_s *gb)
|
|||||||
default:
|
default:
|
||||||
/* Return address where invlid opcode that was read. */
|
/* Return address where invlid opcode that was read. */
|
||||||
(gb->gb_error)(gb, GB_INVALID_OPCODE, gb->cpu_reg.pc.reg - 1);
|
(gb->gb_error)(gb, GB_INVALID_OPCODE, gb->cpu_reg.pc.reg - 1);
|
||||||
// PGB_UNREACHABLE();
|
PGB_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|||||||
Reference in New Issue
Block a user