source: buchla-emu/emu/vid.c@ ac4e192

Last change on this file since ac4e192 was ac4e192, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Started VSDD emulation.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (C) 2017 The Contributors
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * A copy of the GNU General Public License can be found in the file
15 * "gpl.txt" in the top directory of this repository.
16 */
17
18#include <all.h>
19
20#define ver(...) _ver(vid_verbose, 0, __VA_ARGS__)
21#define ver2(...) _ver(vid_verbose, 1, __VA_ARGS__)
22#define ver3(...) _ver(vid_verbose, 2, __VA_ARGS__)
23
24int32_t vid_verbose = 0;
25
26#define SCR_W 512
27#define SCR_H 350
28#define VBL_H 50
29
30#define REG_VCR0 0
31#define REG_VCR1 1
32#define REG_RWBA 2
33#define REG_DSBA 5
34#define REG_ODTBA 7
35#define REG_ATBA 8
36#define REG_ATBAC 11
37
38#define VCR0_UCF 0x0001
39#define VCR0_DEN 0x0008
40
41#define DSBA_BS1 0x0080
42#define DSBA_BS0 0x0100
43
44#define REG_OFF 0x200
45#define PAL_OFF 0x40000
46
47#define OD0_BLA 0x0010
48
49#define WIN_SZ_W 0x10000
50#define MEM_SZ_W 0x20000
51
52#define N_BANKS 2
53
54static int32_t reg_off = REG_OFF;
55
56static uint16_t mem[MEM_SZ_W];
57static int32_t bank = 0;
58
59static int32_t pal[16];
60static int32_t i_pal = 0;
61
62void vid_init(void)
63{
64 ver("vid init");
65}
66
67void vid_quit(void)
68{
69 ver("vid quit");
70}
71
72bool vid_exec(void)
73{
74 ver3("vid exec");
75
76 static int32_t skip = 99999;
77 static int32_t line = 99999;
78
79 if (++skip < 10) {
80 ver3("vid skip %d", skip);
81 return false;
82 }
83
84 skip = 0;
85 int32_t vcr0 = mem[REG_VCR0];
86
87 if ((vcr0 & VCR0_DEN) == 0) {
88 ver3("vid dis");
89 return false;
90 }
91
92 if (++line < SCR_H + VBL_H) {
93 ver3("vid line %d", line);
94
95 if (line < SCR_H) {
96 ++mem[REG_ATBAC];
97 }
98
99 return line == SCR_H;
100 }
101
102 // We get here every 4,000 invocations -> 25 fps.
103
104 ver2("vid frame");
105 line = 0;
106
107 int32_t dsba = mem[REG_DSBA];
108 bank = ((dsba & DSBA_BS0) != 0 ? 1 : 0) + ((dsba & DSBA_BS1) != 0 ? 2 : 0);
109
110 int32_t rwba = mem[REG_RWBA];
111 reg_off = (rwba & 0xfff0) << 1;
112
113 int32_t atba = mem[REG_ATBA];
114 mem[REG_ATBAC] = (uint16_t)atba;
115
116 int32_t odtba = mem[REG_ODTBA] & 0xffc0;
117 int32_t y_beg[16], y_end[16];
118
119 for (int32_t i = 0; i < 16; ++i) {
120 y_beg[i] = -1;
121 y_end[i] = -1;
122
123 uint16_t *od = mem + odtba + 4 * i;
124
125 if ((od[0] & OD0_BLA) != 0) {
126 ver3("obj %d blanked", i);
127 continue;
128 }
129
130 int32_t w = (od[1] & 0xfc00) >> 6;
131
132 if (w == 0) {
133 ver3("obj %d empty", i);
134 continue;
135 }
136
137 int32_t mask = 1 << i;
138
139 for (int32_t k = 0; k < SCR_H; ++k) {
140 if ((mem[atba + k] & mask) == 0) {
141 if (y_beg[i] < 0) {
142 y_beg[i] = k;
143 }
144 else if (y_end[i] < 0) {
145 y_end[i] = k;
146 }
147 }
148 }
149
150 if (y_beg[i] < 0) {
151 ver3("obj %d unused", i);
152 continue;
153 }
154
155 int32_t x = od[1] & 0x03ff;
156 ver2("obj %d %d:%d %d+%d", i, y_beg[i], y_end[i], x, w);
157 }
158
159 int32_t vcr1 = mem[REG_VCR1];
160 int32_t fon_h = (vcr1 & 0xf000) >> 12;
161
162 return false;
163}
164
165uint32_t vid_read(uint32_t off, int32_t sz)
166{
167 ver2("vid rd %d 0x%05x:%d", bank, off, sz * 8);
168
169 int32_t off16 = (int32_t)(off / 2);
170
171 if (sz != 2 || bank >= N_BANKS || off % 2 != 0 || off16 >= WIN_SZ_W) {
172 fail("invalid vid rd %d %u:%d", bank, off, sz * 8);
173 }
174
175 if (off16 >= reg_off && off16 < reg_off + 16) {
176 return mem[off16 - reg_off];
177 }
178
179 return mem[bank * WIN_SZ_W + off16];
180}
181
182void vid_write(uint32_t off, int32_t sz, uint32_t val)
183{
184 ver2("vid wr %d 0x%05x:%d 0x%0*x", bank, off, sz * 8, sz * 2, val);
185
186 int32_t off16 = (int32_t)(off / 2);
187
188 if (sz != 2 || bank >= N_BANKS || off % 2 != 0 || (off16 >= WIN_SZ_W && off16 != PAL_OFF)) {
189 fail("invalid vid wr %d %u:%d", bank, off, sz * 8);
190 }
191
192 if (off16 == PAL_OFF) {
193 pal[i_pal] = (int32_t)val;
194 i_pal = (i_pal + 1) % 16;
195 return;
196 }
197
198 if (off16 >= reg_off && off16 < reg_off + 16) {
199 mem[off16 - reg_off] = (uint16_t)val;
200 return;
201 }
202
203 mem[bank * WIN_SZ_W + off16] = (uint16_t)val;
204}
Note: See TracBrowser for help on using the repository browser.