2016-01-27 11:31:39 +00:00
|
|
|
#include "video.hpp"
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
struct PPU : Thread, IO {
|
2016-01-27 11:31:39 +00:00
|
|
|
static auto Enter() -> void;
|
|
|
|
auto main() -> void;
|
2016-02-04 21:18:06 +00:00
|
|
|
auto scanline() -> void;
|
|
|
|
auto frame() -> void;
|
2016-01-27 11:31:39 +00:00
|
|
|
auto step(uint clocks) -> void;
|
|
|
|
auto power() -> void;
|
|
|
|
|
2016-03-01 12:23:18 +00:00
|
|
|
//io.cpp
|
2016-02-04 10:29:08 +00:00
|
|
|
auto portRead(uint16 addr) -> uint8 override;
|
|
|
|
auto portWrite(uint16 addr, uint8 data) -> void override;
|
|
|
|
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
//render-sprite.cpp
|
|
|
|
auto renderSpriteDecode() -> void;
|
|
|
|
|
2016-03-08 11:34:00 +00:00
|
|
|
//render-mono.cpp
|
|
|
|
auto renderMonoFetch(uint14 offset, uint3 y, uint3 x) -> uint2;
|
|
|
|
auto renderMonoBack() -> void;
|
|
|
|
auto renderMonoScreenOne() -> void;
|
|
|
|
auto renderMonoScreenTwo() -> void;
|
|
|
|
auto renderMonoSprite() -> void;
|
|
|
|
|
|
|
|
//render-color.cpp
|
|
|
|
auto renderColorFetch(uint16 offset, uint3 y, uint3 x) -> uint4;
|
|
|
|
auto renderColorBack() -> void;
|
|
|
|
auto renderColorScreenOne() -> void;
|
|
|
|
auto renderColorScreenTwo() -> void;
|
|
|
|
auto renderColorSprite() -> void;
|
2016-03-01 12:23:18 +00:00
|
|
|
|
|
|
|
//state
|
|
|
|
uint12 output[224 * 144];
|
2016-01-27 11:31:39 +00:00
|
|
|
|
|
|
|
struct Status {
|
|
|
|
uint vclk;
|
|
|
|
uint hclk;
|
|
|
|
} status;
|
2016-02-04 10:29:08 +00:00
|
|
|
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
struct Sprite {
|
|
|
|
uint8 x;
|
|
|
|
uint8 y;
|
|
|
|
uint1 vflip;
|
|
|
|
uint1 hflip;
|
|
|
|
uint1 priority;
|
|
|
|
uint1 window;
|
|
|
|
uint4 palette; //renderSpriteDecode() always sets bit3
|
|
|
|
uint9 tile;
|
|
|
|
};
|
|
|
|
vector<Sprite> sprites;
|
|
|
|
|
2016-03-01 12:23:18 +00:00
|
|
|
struct Pixel {
|
2016-03-02 11:19:33 +00:00
|
|
|
enum class Source : uint { Back, ScreenOne, ScreenTwo, Sprite };
|
2016-03-01 12:23:18 +00:00
|
|
|
Source source;
|
|
|
|
uint12 color;
|
|
|
|
} pixel;
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
struct Registers {
|
|
|
|
//$0000 DISP_CTRL
|
2016-03-08 11:34:00 +00:00
|
|
|
uint1 screenTwoWindowEnable;
|
|
|
|
uint1 screenTwoWindowInvert;
|
|
|
|
uint1 spriteWindowEnable;
|
|
|
|
uint1 spriteEnable;
|
|
|
|
uint1 screenTwoEnable;
|
|
|
|
uint1 screenOneEnable;
|
2016-02-04 10:29:08 +00:00
|
|
|
|
|
|
|
//$0001 BACK_COLOR
|
2016-03-08 11:34:00 +00:00
|
|
|
uint8 backColor;
|
2016-02-04 10:29:08 +00:00
|
|
|
|
2016-02-18 10:32:22 +00:00
|
|
|
//$0003 LINE_CMP
|
|
|
|
uint8 lineCompare;
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
//$0004 SPR_BASE
|
|
|
|
uint6 spriteBase;
|
|
|
|
|
|
|
|
//$0005 SPR_FIRST
|
|
|
|
uint7 spriteFirst;
|
|
|
|
|
|
|
|
//$0006 SPR_COUNT
|
|
|
|
uint8 spriteCount; //0 - 128
|
|
|
|
|
|
|
|
//$0007 MAP_BASE
|
|
|
|
uint4 screenTwoMapBase;
|
|
|
|
uint4 screenOneMapBase;
|
|
|
|
|
2016-02-18 10:32:22 +00:00
|
|
|
//$0008 SCR2_WIN_X0
|
|
|
|
uint8 screenTwoWindowX0;
|
|
|
|
|
|
|
|
//$0009 SCR2_WIN_Y0
|
|
|
|
uint8 screenTwoWindowY0;
|
|
|
|
|
|
|
|
//$000a SCR2_WIN_X1
|
|
|
|
uint8 screenTwoWindowX1;
|
|
|
|
|
|
|
|
//$000b SCR2_WIN_Y1
|
|
|
|
uint8 screenTwoWindowY1;
|
|
|
|
|
|
|
|
//$000c SPR_WIN_X0
|
|
|
|
uint8 spriteWindowX0;
|
|
|
|
|
|
|
|
//$000d SPR_WIN_Y0
|
|
|
|
uint8 spriteWindowY0;
|
|
|
|
|
|
|
|
//$000e SPR_WIN_X1
|
|
|
|
uint8 spriteWindowX1;
|
|
|
|
|
|
|
|
//$000f SPR_WIN_Y1
|
|
|
|
uint8 spriteWindowY1;
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
//$0010 SCR1_X
|
|
|
|
uint8 scrollOneX;
|
|
|
|
|
|
|
|
//$0011 SCR1_Y
|
|
|
|
uint8 scrollOneY;
|
|
|
|
|
|
|
|
//$0012 SCR2_X
|
|
|
|
uint8 scrollTwoX;
|
|
|
|
|
|
|
|
//$0013 SCR2_Y
|
|
|
|
uint8 scrollTwoY;
|
|
|
|
|
|
|
|
//$0014 LCD_CTRL
|
|
|
|
uint8 control;
|
|
|
|
|
|
|
|
//$0015 LCD_ICON
|
2016-03-08 11:34:00 +00:00
|
|
|
uint1 iconAux3;
|
|
|
|
uint1 iconAux2;
|
|
|
|
uint1 iconAux1;
|
|
|
|
uint1 iconHorizontal;
|
|
|
|
uint1 iconVertical;
|
|
|
|
uint1 iconSleep;
|
2016-02-04 10:29:08 +00:00
|
|
|
|
2016-02-18 10:32:22 +00:00
|
|
|
//$0016 LCD_VTOTAL
|
|
|
|
uint8 vtotal;
|
|
|
|
|
|
|
|
//$0017 LCD_VBLANK
|
|
|
|
uint8 vblank;
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
//$001c-001f PALMONO_POOL
|
2016-02-18 10:32:22 +00:00
|
|
|
uint4 pool[8];
|
|
|
|
|
|
|
|
//$0020-003f PALMONO
|
|
|
|
struct Palette {
|
|
|
|
uint3 color[4];
|
|
|
|
} palette[16];
|
2016-02-04 10:29:08 +00:00
|
|
|
} r;
|
2016-01-27 11:31:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern PPU ppu;
|