summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xanalyze_olp.py53
-rw-r--r--vdp.c392
-rw-r--r--vdp.h2
3 files changed, 215 insertions, 232 deletions
diff --git a/analyze_olp.py b/analyze_olp.py
index 652edc4..4d7b935 100755
--- a/analyze_olp.py
+++ b/analyze_olp.py
@@ -20,9 +20,16 @@ def detect_low(sample, bit):
return not sample & mask
def analyze_delays(chanmap, datafile):
- m68k_clk = chanmap['M68K CLK']
+ if 'M68K_CLK' in chanmap:
+ m68k_clk = chanmap['M68K CLK']
+ elif 'CLK' in chanmap:
+ m68k_clk = chanmap['CLK']
m_as = chanmap['!AS']
+ ram_oe = chanmap['RAM !LOE/!RFSH']
+ ram_ce = chanmap['RAM !CE']
last = False
+ prev = False
+ prevRefresh = False
clks = 0
as_start = 0
for line in datafile.readlines():
@@ -36,10 +43,47 @@ def analyze_delays(chanmap, datafile):
if detect_rise(last, sample, m_as):
as_clks = clks - as_start
if as_clks > 2:
- print '!AS held for', as_clks, 'cycles starting (delay of ' + str(as_clks - 2) + ') at', as_start, 'and ending at', clks
+ if not (prev is False):
+ print '!AS held for', as_clks, 'cycles starting (delay of ' + str(as_clks - 2) + ') at', as_start, 'and ending at', clks, 'delta since last delay:', as_start - prev
+ else:
+ print '!AS held for', as_clks, 'cycles starting (delay of ' + str(as_clks - 2) + ') at', as_start, 'and ending at', clks
+ prev = as_start
elif detect_fall(last, sample, m_as):
as_start = clks
+ if detect_fall(last, sample, ram_oe) and detect_high( sample, ram_ce):
+ if prevRefresh is False:
+ print 'RAM refresh at ', clks
+ else:
+ print 'RAM refresh at', clks, 'delta since last:', clks-prevRefresh
+ prevRefresh = clks
last = sample
+
+def analyze_refresh(chanmap, datafile):
+ if 'M68K_CLK' in chanmap:
+ m68k_clk = chanmap['M68K CLK']
+ elif 'CLK' in chanmap:
+ m68k_clk = chanmap['CLK']
+ ram_oe = chanmap['RAM !LOE/!RFSH']
+ ram_ce = chanmap['RAM !CE']
+ clks = 0
+ last = False
+ prevRefresh = False
+ for line in datafile.readlines():
+ line = line.strip()
+ if line and not line.startswith(';'):
+ sample,_,num = line.partition('@')
+ sample = int(sample, 16)
+ if not (last is False):
+ if detect_rise(last, sample, m68k_clk):
+ clks = clks + 1
+ if detect_fall(last, sample, ram_oe) and detect_high( sample, ram_ce):
+ if prevRefresh is False:
+ print 'RAM refresh at ', clks
+ else:
+ print 'RAM refresh at', clks, 'delta since last:', clks-prevRefresh
+ prevRefresh = clks
+ last = sample
+
def main(args):
if len(args) < 2:
@@ -49,12 +93,15 @@ def main(args):
channelfile = olpfile.open('channel.labels')
channels = [line.strip() for line in channelfile.readlines()]
channelfile.close()
+ print channels
chanmap = {}
for i in xrange(0, len(channels)):
chanmap[channels[i]] = i
datafile = olpfile.open('data.ols')
analyze_delays(chanmap, datafile)
-
+ datafile.close()
+ #datafile = olpfile.open('data.ols')
+ #analyze_refresh(chanmap, datafile)
if __name__ == '__main__':
main(argv)
diff --git a/vdp.c b/vdp.c
index b5a5713..c76f099 100644
--- a/vdp.c
+++ b/vdp.c
@@ -24,7 +24,7 @@
#define MCLKS_SLOT_H32 20
#define VINT_SLOT_H40 4 //21 slots before HSYNC, 16 during, 10 after
#define VINT_SLOT_H32 4 //old value was 23, but recent tests suggest the actual value is close to the H40 one
-#define HSYNC_SLOT_H40 234
+#define HSYNC_SLOT_H40 228
#define HSYNC_END_H40 (HSYNC_SLOT_H40+17)
#define HSYNC_END_H32 (33 * MCLKS_SLOT_H32)
#define HBLANK_START_H40 178 //should be 179 according to Nemesis, but 178 seems to fit slightly better with my test ROM results
@@ -514,7 +514,7 @@ void external_slot(vdp_context * context)
}
}
-void run_dma_src(vdp_context * context, uint32_t slot)
+void run_dma_src(vdp_context * context, int32_t slot)
{
//TODO: Figure out what happens if CD bit 4 is not set in DMA copy mode
//TODO: Figure out what happens when CD:0-3 is not set to a write mode in DMA operations
@@ -528,7 +528,7 @@ void run_dma_src(vdp_context * context, uint32_t slot)
//68K -> VDP
case 0:
case 0x40:
- if (!slot || !is_refresh(context, slot-1)) {
+ if (slot == -1 || !is_refresh(context, slot-1)) {
cur = context->fifo + context->fifo_write;
cur->cycle = context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
cur->address = context->address;
@@ -975,31 +975,31 @@ void vdp_advance_line(vdp_context *context)
}
#define CHECK_ONLY if (context->cycles >= target_cycles) { return; }
-#define CHECK_LIMIT if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } context->hslot++; context->cycles += slot_cycles; CHECK_ONLY
+#define CHECK_LIMIT if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } context->hslot++; context->cycles += slot_cycles; CHECK_ONLY
#define COLUMN_RENDER_BLOCK(column, startcyc) \
case startcyc:\
read_map_scroll_a(column, context->vcounter, context);\
CHECK_LIMIT\
- case (startcyc+1):\
+ case ((startcyc+1)&0xFF):\
external_slot(context);\
CHECK_LIMIT\
- case (startcyc+2):\
+ case ((startcyc+2)&0xFF):\
render_map_1(context);\
CHECK_LIMIT\
- case (startcyc+3):\
+ case ((startcyc+3)&0xFF):\
render_map_2(context);\
CHECK_LIMIT\
- case (startcyc+4):\
+ case ((startcyc+4)&0xFF):\
read_map_scroll_b(column, context->vcounter, context);\
CHECK_LIMIT\
- case (startcyc+5):\
+ case ((startcyc+5)&0xFF):\
read_sprite_x(context->vcounter, context);\
CHECK_LIMIT\
- case (startcyc+6):\
+ case ((startcyc+6)&0xFF):\
render_map_3(context);\
CHECK_LIMIT\
- case (startcyc+7):\
+ case ((startcyc+7)&0xFF):\
render_map_output(context->vcounter, column, context);\
CHECK_LIMIT
@@ -1029,19 +1029,16 @@ void vdp_advance_line(vdp_context *context)
CHECK_LIMIT\
case (startcyc+7):\
render_map_output(context->vcounter, column, context);\
- if (column == 40 || (column == 32 && startcyc == 124)) {\
- vdp_advance_line(context);\
- }\
CHECK_LIMIT
#define SPRITE_RENDER_H40(slot) \
case slot:\
render_sprite_cells( context);\
scan_sprite_table(context->vcounter, context);\
- if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } \
+ if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \
if (slot == 182) {\
context->hslot = 229;\
- context->cycles += slot_cycles;\
+ context->cycles += h40_hsync_cycles[0];\
} else {\
context->hslot++;\
if (slot >= HSYNC_SLOT_H40 && slot < HSYNC_END_H40) {\
@@ -1056,7 +1053,7 @@ void vdp_advance_line(vdp_context *context)
case slot:\
render_sprite_cells( context);\
scan_sprite_table(context->vcounter, context);\
- if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } \
+ if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \
if (slot == 147) {\
context->hslot = 233;\
} else {\
@@ -1075,55 +1072,21 @@ void vdp_h40(vdp_context * context, uint32_t target_cycles)
{
for (;;)
{
- case 165:
- external_slot(context);
- CHECK_LIMIT
- case 166:
- external_slot(context);
- CHECK_LIMIT
- //sprite render to line buffer starts
- case 167:
- context->cur_slot = MAX_DRAWS-1;
- memset(context->linebuf, 0, LINEBUF_SIZE);
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- }
- CHECK_LIMIT
- case 168:
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- }
- CHECK_LIMIT
- case 169:
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- }
- CHECK_LIMIT
- case 170:
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) {
- context->hslot++;
- context->cycles += slot_cycles;
- return;
- }
- }
- CHECK_LIMIT
//sprite attribute table scan starts
- case 171:
+ case 165:
context->sprite_index = 0x80;
context->slot_counter = MAX_SPRITES_LINE;
render_sprite_cells( context);
scan_sprite_table(context->vcounter, context);
CHECK_LIMIT
+ SPRITE_RENDER_H40(166)
+ SPRITE_RENDER_H40(167)
+ case 168:
+ external_slot(context);
+ CHECK_LIMIT
+ SPRITE_RENDER_H40(169)
+ SPRITE_RENDER_H40(170)
+ SPRITE_RENDER_H40(171)
SPRITE_RENDER_H40(172)
SPRITE_RENDER_H40(173)
SPRITE_RENDER_H40(174)
@@ -1134,13 +1097,13 @@ void vdp_h40(vdp_context * context, uint32_t target_cycles)
SPRITE_RENDER_H40(179)
SPRITE_RENDER_H40(180)
SPRITE_RENDER_H40(181)
+ //!HSYNC asserted
SPRITE_RENDER_H40(182)
SPRITE_RENDER_H40(229)
SPRITE_RENDER_H40(230)
SPRITE_RENDER_H40(231)
SPRITE_RENDER_H40(232)
SPRITE_RENDER_H40(233)
- //!HSYNC asserted
SPRITE_RENDER_H40(234)
SPRITE_RENDER_H40(235)
SPRITE_RENDER_H40(236)
@@ -1149,13 +1112,7 @@ void vdp_h40(vdp_context * context, uint32_t target_cycles)
SPRITE_RENDER_H40(239)
SPRITE_RENDER_H40(240)
SPRITE_RENDER_H40(241)
- SPRITE_RENDER_H40(242)
- SPRITE_RENDER_H40(243)
- SPRITE_RENDER_H40(244)
- SPRITE_RENDER_H40(245)
- SPRITE_RENDER_H40(246)
- SPRITE_RENDER_H40(247)
- case 248:
+ case 242:
address = (context->regs[REG_HSCROLL] & 0x3F) << 10;
mask = 0;
if (context->regs[REG_MODE_3] & 0x2) {
@@ -1168,39 +1125,36 @@ void vdp_h40(vdp_context * context, uint32_t target_cycles)
context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1];
context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3];
//printf("%d: HScroll A: %d, HScroll B: %d\n", context->vcounter, context->hscroll_a, context->hscroll_b);
- if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); }
+ if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); }
context->hslot++;
context->cycles += h40_hsync_cycles[14];
CHECK_ONLY
//!HSYNC high
- SPRITE_RENDER_H40(249)
- SPRITE_RENDER_H40(250)
- SPRITE_RENDER_H40(251)
- SPRITE_RENDER_H40(252)
- case 253:
+ SPRITE_RENDER_H40(243)
+ SPRITE_RENDER_H40(244)
+ SPRITE_RENDER_H40(245)
+ SPRITE_RENDER_H40(246)
+ case 247:
read_map_scroll_a(0, context->vcounter, context);
CHECK_LIMIT
- SPRITE_RENDER_H40(254)
- case 255:
+ SPRITE_RENDER_H40(248)
+ case 249:
render_map_1(context);
scan_sprite_table(context->vcounter, context);//Just a guess
- if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); }
- context->hslot = 0;
- context->cycles += slot_cycles;
- CHECK_ONLY
- case 0:
+ CHECK_LIMIT
+ case 250:
render_map_2(context);
scan_sprite_table(context->vcounter, context);//Just a guess
CHECK_LIMIT
- case 1:
+ case 251:
read_map_scroll_b(0, context->vcounter, context);
CHECK_LIMIT
- SPRITE_RENDER_H40(2)
- case 3:
+ SPRITE_RENDER_H40(252)
+ case 253:
render_map_3(context);
scan_sprite_table(context->vcounter, context);//Just a guess
CHECK_LIMIT
- case 4:
+ case 254:
if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) {
context->flags2 |= FLAG2_VINT_PENDING;
context->pending_vint_start = context->cycles;
@@ -1214,26 +1168,53 @@ void vdp_h40(vdp_context * context, uint32_t target_cycles)
context->sprite_draws = MAX_DRAWS;
context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED);
CHECK_LIMIT
- COLUMN_RENDER_BLOCK(2, 5)
- COLUMN_RENDER_BLOCK(4, 13)
- COLUMN_RENDER_BLOCK(6, 21)
- COLUMN_RENDER_BLOCK_REFRESH(8, 29)
- COLUMN_RENDER_BLOCK(10, 37)
- COLUMN_RENDER_BLOCK(12, 45)
- COLUMN_RENDER_BLOCK(14, 53)
- COLUMN_RENDER_BLOCK_REFRESH(16, 61)
- COLUMN_RENDER_BLOCK(18, 69)
- COLUMN_RENDER_BLOCK(20, 77)
- COLUMN_RENDER_BLOCK(22, 85)
- COLUMN_RENDER_BLOCK_REFRESH(24, 93)
- COLUMN_RENDER_BLOCK(26, 101)
- COLUMN_RENDER_BLOCK(28, 109)
- COLUMN_RENDER_BLOCK(30, 117)
- COLUMN_RENDER_BLOCK_REFRESH(32, 125)
- COLUMN_RENDER_BLOCK(34, 133)
- COLUMN_RENDER_BLOCK(36, 141)
- COLUMN_RENDER_BLOCK(38, 149)
- COLUMN_RENDER_BLOCK_REFRESH(40, 157)
+ COLUMN_RENDER_BLOCK(2, 255)
+ COLUMN_RENDER_BLOCK(4, 7)
+ COLUMN_RENDER_BLOCK(6, 15)
+ COLUMN_RENDER_BLOCK_REFRESH(8, 23)
+ COLUMN_RENDER_BLOCK(10, 31)
+ COLUMN_RENDER_BLOCK(12, 39)
+ COLUMN_RENDER_BLOCK(14, 47)
+ COLUMN_RENDER_BLOCK_REFRESH(16, 55)
+ COLUMN_RENDER_BLOCK(18, 63)
+ COLUMN_RENDER_BLOCK(20, 71)
+ COLUMN_RENDER_BLOCK(22, 79)
+ COLUMN_RENDER_BLOCK_REFRESH(24, 87)
+ COLUMN_RENDER_BLOCK(26, 95)
+ COLUMN_RENDER_BLOCK(28, 103)
+ COLUMN_RENDER_BLOCK(30, 111)
+ COLUMN_RENDER_BLOCK_REFRESH(32, 119)
+ COLUMN_RENDER_BLOCK(34, 127)
+ COLUMN_RENDER_BLOCK(36, 135)
+ COLUMN_RENDER_BLOCK(38, 143)
+ COLUMN_RENDER_BLOCK_REFRESH(40, 151)
+ case 159:
+ external_slot(context);
+ CHECK_LIMIT
+ case 160:
+ external_slot(context);
+ CHECK_LIMIT
+ //sprite render to line buffer starts
+ case 161:
+ context->cur_slot = MAX_DRAWS-1;
+ memset(context->linebuf, 0, LINEBUF_SIZE);
+ render_sprite_cells(context);
+ CHECK_LIMIT
+ case 162:
+ render_sprite_cells(context);
+ CHECK_LIMIT
+ case 163:
+ render_sprite_cells(context);
+ CHECK_LIMIT
+ case 164:
+ render_sprite_cells(context);
+ vdp_advance_line(context);
+ if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) {
+ context->hslot++;
+ context->cycles += slot_cycles;
+ return;
+ }
+ CHECK_LIMIT
}
default:
context->hslot++;
@@ -1251,84 +1232,42 @@ void vdp_h32(vdp_context * context, uint32_t target_cycles)
{
for (;;)
{
- case 132:
- external_slot(context);
- CHECK_LIMIT
- case 133:
- external_slot(context);
- CHECK_LIMIT
- //sprite render to line buffer starts
- case 134:
- context->cur_slot = MAX_DRAWS_H32-1;
- memset(context->linebuf, 0, LINEBUF_SIZE);
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- }
- CHECK_LIMIT
- case 135:
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- }
- CHECK_LIMIT
- case 136:
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- }
- CHECK_LIMIT
- case 137:
- if (context->vcounter == 0x1FF) {
- external_slot(context);
- } else {
- render_sprite_cells(context);
- if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) {
- context->hslot++;
- context->cycles += slot_cycles;
- return;
- }
- }
- CHECK_LIMIT
//sprite attribute table scan starts
- case 138:
+ case 132:
context->sprite_index = 0x80;
context->slot_counter = MAX_SPRITES_LINE_H32;
render_sprite_cells( context);
scan_sprite_table(context->vcounter, context);
CHECK_LIMIT
+ SPRITE_RENDER_H32(133)
+ SPRITE_RENDER_H32(134)
+ SPRITE_RENDER_H32(135)
+ SPRITE_RENDER_H32(136)
+ SPRITE_RENDER_H32(137)
+ SPRITE_RENDER_H32(138)
SPRITE_RENDER_H32(139)
SPRITE_RENDER_H32(140)
SPRITE_RENDER_H32(141)
- SPRITE_RENDER_H32(142)
+ case 142:
+ external_slot(context);
+ CHECK_LIMIT
SPRITE_RENDER_H32(143)
SPRITE_RENDER_H32(144)
SPRITE_RENDER_H32(145)
SPRITE_RENDER_H32(146)
SPRITE_RENDER_H32(147)
- case 233:
- external_slot(context);
- CHECK_LIMIT
+ //HSYNC start
+ SPRITE_RENDER_H32(233)
SPRITE_RENDER_H32(234)
SPRITE_RENDER_H32(235)
SPRITE_RENDER_H32(236)
SPRITE_RENDER_H32(237)
SPRITE_RENDER_H32(238)
- //HSYNC start
SPRITE_RENDER_H32(239)
- SPRITE_RENDER_H32(240)
- SPRITE_RENDER_H32(241)
- SPRITE_RENDER_H32(242)
- SPRITE_RENDER_H32(243)
- SPRITE_RENDER_H32(244)
- SPRITE_RENDER_H32(245)
- case 246:
+ case 240:
external_slot(context);
CHECK_LIMIT
- case 247:
+ case 241:
address = (context->regs[REG_HSCROLL] & 0x3F) << 10;
mask = 0;
if (context->regs[REG_MODE_3] & 0x2) {
@@ -1342,38 +1281,35 @@ void vdp_h32(vdp_context * context, uint32_t target_cycles)
context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3];
//printf("%d: HScroll A: %d, HScroll B: %d\n", context->vcounter, context->hscroll_a, context->hscroll_b);
CHECK_LIMIT
- SPRITE_RENDER_H32(248)
- SPRITE_RENDER_H32(249)
- SPRITE_RENDER_H32(250)
- SPRITE_RENDER_H32(251)
+ SPRITE_RENDER_H32(242)
+ SPRITE_RENDER_H32(243)
+ SPRITE_RENDER_H32(244)
+ SPRITE_RENDER_H32(245)
//!HSYNC high
- case 252:
+ case 246:
read_map_scroll_a(0, context->vcounter, context);
CHECK_LIMIT
- SPRITE_RENDER_H32(253)
- case 254:
+ SPRITE_RENDER_H32(247)
+ case 248:
render_map_1(context);
scan_sprite_table(context->vcounter, context);//Just a guess
CHECK_LIMIT
- case 255:
+ case 249:
render_map_2(context);
scan_sprite_table(context->vcounter, context);//Just a guess
- if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); }
- context->cycles += slot_cycles;
- context->hslot = 0;
- CHECK_ONLY
- case 0:
+ CHECK_LIMIT
+ case 250:
read_map_scroll_b(0, context->vcounter, context);
CHECK_LIMIT
- case 1:
+ case 251:
render_sprite_cells(context);
scan_sprite_table(context->vcounter, context);
CHECK_LIMIT
- case 2:
+ case 252:
render_map_3(context);
scan_sprite_table(context->vcounter, context);//Just a guess
CHECK_LIMIT
- case 3:
+ case 253:
render_map_output(context->vcounter, 0, context);
scan_sprite_table(context->vcounter, context);//Just a guess
//reverse context slot counter so it counts the number of sprite slots
@@ -1383,22 +1319,49 @@ void vdp_h32(vdp_context * context, uint32_t target_cycles)
context->sprite_draws = MAX_DRAWS_H32;
context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED);
CHECK_LIMIT
- COLUMN_RENDER_BLOCK(2, 4)
- COLUMN_RENDER_BLOCK(4, 12)
- COLUMN_RENDER_BLOCK(6, 20)
- COLUMN_RENDER_BLOCK_REFRESH(8, 28)
- COLUMN_RENDER_BLOCK(10, 36)
- COLUMN_RENDER_BLOCK(12, 44)
- COLUMN_RENDER_BLOCK(14, 52)
- COLUMN_RENDER_BLOCK_REFRESH(16, 60)
- COLUMN_RENDER_BLOCK(18, 68)
- COLUMN_RENDER_BLOCK(20, 76)
- COLUMN_RENDER_BLOCK(22, 84)
- COLUMN_RENDER_BLOCK_REFRESH(24, 92)
- COLUMN_RENDER_BLOCK(26, 100)
- COLUMN_RENDER_BLOCK(28, 108)
- COLUMN_RENDER_BLOCK(30, 116)
- COLUMN_RENDER_BLOCK_REFRESH(32, 124)
+ COLUMN_RENDER_BLOCK(2, 254)
+ COLUMN_RENDER_BLOCK(4, 6)
+ COLUMN_RENDER_BLOCK(6, 14)
+ COLUMN_RENDER_BLOCK_REFRESH(8, 22)
+ COLUMN_RENDER_BLOCK(10, 30)
+ COLUMN_RENDER_BLOCK(12, 38)
+ COLUMN_RENDER_BLOCK(14, 46)
+ COLUMN_RENDER_BLOCK_REFRESH(16, 54)
+ COLUMN_RENDER_BLOCK(18, 62)
+ COLUMN_RENDER_BLOCK(20, 70)
+ COLUMN_RENDER_BLOCK(22, 78)
+ COLUMN_RENDER_BLOCK_REFRESH(24, 86)
+ COLUMN_RENDER_BLOCK(26, 94)
+ COLUMN_RENDER_BLOCK(28, 102)
+ COLUMN_RENDER_BLOCK(30, 110)
+ COLUMN_RENDER_BLOCK_REFRESH(32, 118)
+ case 126:
+ external_slot(context);
+ CHECK_LIMIT
+ case 127:
+ external_slot(context);
+ CHECK_LIMIT
+ //sprite render to line buffer starts
+ case 128:
+ context->cur_slot = MAX_DRAWS_H32-1;
+ memset(context->linebuf, 0, LINEBUF_SIZE);
+ render_sprite_cells(context);
+ CHECK_LIMIT
+ case 129:
+ render_sprite_cells(context);
+ CHECK_LIMIT
+ case 130:
+ render_sprite_cells(context);
+ CHECK_LIMIT
+ case 131:
+ render_sprite_cells(context);
+ vdp_advance_line(context);
+ if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) {
+ context->hslot++;
+ context->cycles += slot_cycles;
+ return;
+ }
+ CHECK_LIMIT
}
default:
context->hslot++;
@@ -1444,19 +1407,6 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
//line 0x1FF is basically active even though it's not displayed
uint8_t active_slot = context->vcounter < inactive_start || context->vcounter == 0x1FF;
uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40;
- if (context->vcounter == inactive_start) {
- if (is_h40) {
- //the first inactive line behaves as an active one for the first 4 slots
- if (context->hslot > LINE_CHANGE_H40 && context->hslot < 171) {
- active_slot = 1;
- }
- } else {
- //the first inactive line behaves as an active one for the first few slots
- if (context->hslot > LINE_CHANGE_H32 && context->hslot < 138) {
- active_slot = 1;
- }
- }
- }
if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) {
if (is_h40) {
vdp_h40(context, target_cycles);
@@ -1465,18 +1415,18 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
}
} else {
if (is_h40) {
- if (context->hslot == 167) {
+ if (context->hslot == 161) {
context->cur_slot = MAX_DRAWS-1;
memset(context->linebuf, 0, LINEBUF_SIZE);
- } else if (context->hslot == 171) {
+ } else if (context->hslot == 165) {
context->sprite_index = 0x80;
context->slot_counter = MAX_SPRITES_LINE;
}
} else {
- if (context->hslot == 134) {
+ if (context->hslot == 128) {
context->cur_slot = MAX_DRAWS_H32-1;
memset(context->linebuf, 0, LINEBUF_SIZE);
- } else if (context->hslot == 138) {
+ } else if (context->hslot == 132) {
context->sprite_index = 0x80;
context->slot_counter = MAX_SPRITES_LINE_H32;
}
@@ -1490,7 +1440,9 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
}
uint32_t inccycles;
if (is_h40) {
- if (context->hslot < HSYNC_SLOT_H40 || context->hslot >= HSYNC_END_H40) {
+ if (context->hslot == 182) {
+ inccycles = h40_hsync_cycles[0];
+ } else if (context->hslot < HSYNC_SLOT_H40 || context->hslot >= HSYNC_END_H40) {
inccycles = MCLKS_SLOT_H40;
} else {
inccycles = h40_hsync_cycles[context->hslot-HSYNC_SLOT_H40];
@@ -1509,7 +1461,6 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
}
context->cycles += inccycles;
context->hslot++;
- context->hslot &= 0xFF;
if (is_h40) {
if (context->hslot == LINE_CHANGE_H40) {
vdp_advance_line(context);
@@ -1692,22 +1643,7 @@ uint16_t vdp_control_port_read(vdp_context * context)
uint32_t line= context->vcounter;
uint32_t slot = context->hslot;
uint32_t inactive_start = (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START);
- if (
- (
- line > inactive_start
- && line < 0x1FF
- )
- || (line == inactive_start
- && (
- slot >= (context->regs[REG_MODE_4] & BIT_H40 ? VBLANK_START_H40 : VBLANK_START_H32)
- || slot < (context->regs[REG_MODE_4] & BIT_H40 ? LINE_CHANGE_H40 : LINE_CHANGE_H32)
- )
- )
- || (line == 0x1FF
- && slot < (context->regs[REG_MODE_4] & BIT_H40 ? VBLANK_START_H40 : VBLANK_START_H32))
- && slot >= (context->regs[REG_MODE_4] & BIT_H40 ? LINE_CHANGE_H40 : LINE_CHANGE_H32)
- || !(context->regs[REG_MODE_2] & BIT_DISP_EN)
- ) {
+ if ((line >= inactive_start && line < 0x1FF) || !(context->regs[REG_MODE_2] & BIT_DISP_EN)) {
value |= 0x8;
}
if (context->regs[REG_MODE_4] & BIT_H40) {
diff --git a/vdp.h b/vdp.h
index 5b9288c..1e0de91 100644
--- a/vdp.h
+++ b/vdp.h
@@ -148,9 +148,9 @@ typedef struct {
uint16_t vscroll_latch[2];
uint32_t frame;
uint16_t vcounter;
- uint16_t hslot; //hcounter/2
uint16_t hscroll_a;
uint16_t hscroll_b;
+ uint8_t hslot; //hcounter/2
uint8_t latched_mode;
uint8_t sprite_index;
uint8_t sprite_draws;