Skip to content

Commit cad6bd9

Browse files
avivaceISSOtmBella
authored
Converted GB Camera sections 2.2.6 - 3.1.2 (#478)
Co-authored-by: Eldred Habert <[email protected]> Co-authored-by: Bella <bella@debian-BULLSEYE-live-builder-AMD64>
1 parent 3ee8144 commit cad6bd9

File tree

1 file changed

+147
-16
lines changed

1 file changed

+147
-16
lines changed

src/Gameboy_Camera.md

Lines changed: 147 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ The Game Boy Camera cartridge contains 4 ICs: the usual ROM and RAM ICs, a big c
1212

1313
The main board contains all ICs except from the sensor.
1414

15-
Component# | Part#/inscription | Description |
16-
-----------|--------------------------------------|----------------------|
17-
U1 | MAC-GBD Nintendo 9807 SA | I/O, memory control. |
18-
U2 | GBD-PCAX-0 F M538011-E - 08 8145507 | 1MB ROM |
19-
U3 | 52CV1000SF85LL SHARP JAPAN 9805 5 0A | 128KB RAM |
15+
| Component# | Part#/inscription | Description |
16+
| ---------- | ------------------------------------ | -------------------- |
17+
| U1 | MAC-GBD Nintendo 9807 SA | I/O, memory control. |
18+
| U2 | GBD-PCAX-0 F M538011-E - 08 8145507 | 1MB ROM |
19+
| U3 | 52CV1000SF85LL SHARP JAPAN 9805 5 0A | 128KB RAM |
2020

2121
The U1 is the only one connected to the GB cartridge pins (besides some address pins of the ROM IC). The U2 and U3 (ROM and RAM) are connected to U1. The M64282FP "retina" chip is in a separate PCB, and is connected to the U1.
2222
The M64282FP handles most of the configuration of the capturing process. The U1 transforms the commands from the Game Boy CPU into the correct signals needed for the M64282FP. The detailed timings are described below.
@@ -63,6 +63,7 @@ Unlike most games, the GB Camera RAM can only be written when PHI pin = '1'. It'
6363
The Game Boy Camera I/O registers are mapped to all banks with bit 4 set to '1'. The GB Camera ROM usually changes to bank 16 ($10) to use the registers.
6464

6565
There are 3 groups of registers:
66+
6667
- The first group is composed by the trigger register A000. This register starts the capture process and returns the current status (working/capture finished).
6768
- The second group is composed by registers A001-A005, used to configure most parameters of the M64282FP sensor.
6869
- The third group is composed by 48 registers that form a 4×4 matrix. Each element of the matrix is formed by 3 bytes. This matrix is used by the controller for contrast and dithering.
@@ -139,54 +140,184 @@ Those registers form a 4×4 matrix with 3 bytes per element. They handle ditheri
139140
<figure>
140141
<img src="imgs/gbcamera/fig1.png" alt="Horizontal edge processing modes.">
141142
<figcaption>Horizontal edge processing modes</figcaption>
142-
</figure>
143+
</figure>
143144

144145
<figure>
145146
<img src="imgs/gbcamera/fig2.png" alt="Vertical edge processing modes.">
146147
<figcaption>Vertical edge processing modes.</figcaption>
147-
</figure>
148+
</figure>
148149

149150
<figure>
150151
<img src="imgs/gbcamera/fig3.png" alt="2D edge processing modes.">
151152
<figcaption>2D edge processing modes.</figcaption>
152-
</figure>
153+
</figure>
153154

154155
<figure>
155156
<img src="imgs/gbcamera/fig4.png" alt="1-D filtering hardware.">
156157
<figcaption>1-D filtering hardware.</figcaption>
157-
</figure>
158+
</figure>
158159

159160
<figure>
160161
<img src="imgs/gbcamera/fig5.png" alt="Positive image.">
161162
<figcaption>Positive image.</figcaption>
162-
</figure>
163+
</figure>
163164

164165
<figure>
165166
<img src="imgs/gbcamera/fig6.png" alt="Negative image.">
166167
<figcaption>Negative image.</figcaption>
167-
</figure>
168+
</figure>
168169

169170
<figure>
170171
<img src="imgs/gbcamera/fig7.png" alt="Edge extraction.">
171172
<figcaption>Edge extraction.</figcaption>
172-
</figure>
173+
</figure>
174+
175+
## Game Boy Camera Timings
176+
177+
The capture process is started when the A000 register of the Game Boy Camera cartridge is written with any value with bit 0 set to "1".
178+
The Game Boy Camera cartridge is one of the few cartridges that use the PHI signal (clock from the GB).
179+
That signal is a 1 MiHz clock (1047567 Hz).
180+
The M6438FP chip needs a clock input too, which is half the frequency of the PHI pin (0.5 Mihz, 524288Hz).
181+
The reason for that is that the sensor chip sometimes handles the signals on the rising edge of the clock, but other times on the falling edge.
182+
183+
::: tip NOTE
184+
185+
This means that the GB Camera shouldn't be used in GBC double speed mode!
186+
187+
:::
188+
189+
The time needed to capture and process an image depends on the exposure time and the value of N bit of the register 1 of the M64282FP chip.
190+
In GAME BOY CYCLES (1 MiHz):
191+
192+
```
193+
N_bit = ([A001] & BIT(7)) ? 0 : 512
194+
exposure = ([A002]<<8) | [A003]
195+
CYCLES = 32446 + N_bit + 16 * exposure
196+
```
197+
198+
Divide those values by 2 to get the sensor clocks.
199+
200+
### Capture process timings
173201

202+
The next values are in sensor clocks.
203+
Multiply by 2 to get Game Boy cycles:
204+
205+
```
206+
- Reset pulse.
207+
- Configure sensor registers. (11 x 8 CLKs)
208+
- Wait (1 CLK)
209+
- Start pulse (1 CLK)
210+
- Exposure time (exposure_steps x 8 CLKs)
211+
- Wait (2 CLKs)
212+
- Read start
213+
- Read period (N=1 ? 16128 : 16384 CLKs)
214+
- Read end
215+
- Wait (3 CLKs)
216+
- Reset pulse to stop the sensor
217+
218+
(88 + 1 + 1 + 2 + 16128 + 3 = 16223)
219+
220+
CLKs = 16223 + ( N_bit ? 0 : 256 ) + 8 * exposure
221+
```
222+
223+
Above is the previous result divided by 2.
224+
During the read process, every pixel is written when it is read from the sensor.
225+
If the read process is stopped, (by shutting the GB off, for example) the RAM will have contents of the current picture until the read was stopped.
226+
From there, it will have the data from the image captured before that one.
227+
The sensor transfers are 128x128 pixels, but the upper and lower rows are corrupted.
228+
The Game Boy Camera controller uses the medium rows of the sensor image.
229+
This means that it ignores the first 8 rows and the last 8 rows.
230+
231+
The clock signal during read period must be the same as the one used during the exposure time, but if the clock during the read period is too slow, the sensor will continue increasing the charge values of each pixel so the image will appear to be taken with a higher exposure time.
232+
The brightness doesn't always seem to increase, however.
233+
There appears to be some kind of limit.
234+
235+
## The Game Boy Camera sensor (M64282FP)
236+
237+
The M64282FP does some processing to the captured image.
238+
First, it performs an edge control, then it does gain control, and lastly, it does level control.
239+
The resulting analog value is the one that can be read in the V<sub>out</sub> pin.
240+
The sensor can capture infrared radiation, so the images can be a bit strange compared to others captured by better sensors.
241+
242+
## The M64282FP registers
243+
244+
### Register 1
245+
246+
This corresponds to the register A001 of the Game Boy Camera.
247+
248+
When shooting, the values change based on how much light there is.
249+
250+
| Symbol | Bits | Operation |
251+
| ------ | ---- | ------------------------------------------------- |
252+
| N | 7 | Exclusively set vertical edge enhancement mode. |
253+
| VH | 5-6 | Select vertical/horizontal edge enhancement mode. |
254+
| G | 0-4 | Analog output gain. |
255+
256+
<break><break>
257+
<break><break>
258+
259+
| G3 | G2 | G1 | G0 | Gain |
260+
| --- | --- | --- | --- | ---- |
261+
| 0 | 0 | 0 | 1 | 14.0 |
262+
| 0 | 0 | 0 | 1 | 15.5 |
263+
| 0 | 0 | 1 | 0 | 17.0 |
264+
| 0 | 0 | 1 | 1 | 18.5 |
265+
| 0 | 1 | 0 | 0 | 20.0 |
266+
| 0 | 1 | 0 | 1 | 21.5 |
267+
| 0 | 1 | 1 | 0 | 23.0 |
268+
| 0 | 1 | 1 | 1 | 24.5 |
269+
| 1 | 0 | 0 | 0 | 26.0 |
270+
| 1 | 0 | 0 | 1 | 29.0 |
271+
| 1 | 0 | 1 | 0 | 32.0 |
272+
| 1 | 0 | 1 | 1 | 35.0 |
273+
| 1 | 1 | 0 | 0 | 38.0 |
274+
| 1 | 1 | 0 | 1 | 41.0 |
275+
| 1 | 1 | 1 | 0 | 45.5 |
276+
| 1 | 1 | 1 | 1 | 51.5 |
277+
278+
If G4 = "1", the total gain is the previous one plus 6 dB.
279+
The Game Boy Camera uses $00, $04, $08, and $0A at 14 dB, 20 dB, 26 dB, and 32 dB respectively, which translate to a gain of 5.01, 10.00, 19.95, and 39.81.
280+
The Game Boy Camera seems to like to duplicate the game in each step.
281+
282+
## Registers 2 and 3
283+
284+
Registers 2 and 3 contain the exposure time (a 16 bit unsigned value).
285+
According to the M64282FP datasheet, each step is 16 µs.
286+
The GB needs 16 PHI clocks for every step.
287+
However, if N = "1", `exposure_steps` should be greater than or equal to $0030.
288+
289+
```
290+
u16 exposure_steps ((Reg2)<<8) | [Reg3]
291+
Step time = 1 / 1048576 Hz * 16 = 0,954 µs* 16 = 15,259 µs
292+
```
293+
294+
It's a bit less than the 16 µs the datasheet says, but it's close enough.
295+
296+
Below are some example values to get acceptable pictures under various light conditions:
297+
298+
| Value | Conditions |
299+
| ----- | -------------------------------------------------- |
300+
| $0030 | Objects under direct sunlight. |
301+
| $0300 | Objects not under direct sunlight. |
302+
| $0800 | Room during the day with good light. |
303+
| $2C00 | Room at night with no light. |
304+
| $5000 | Room at night with no light, only a reading lamp . |
305+
| $F000 | Room at night with only a TV on in the background. |
174306

175307
## Sample code for emulators
176308

177309
The following code is used to convert a greyscale image to the Game Boy Camera format. `GB_CameraTakePicture()` should be called when bit 0 of A000 register is st to '1'. The emulator should wait CAM_CLOCKS_LEFT until the bit 0 is cleared. The gain and level control are not needed to emulate the Game Boy Camera because webcams do that automatically. In fact, trying to emulate that will probably break the image. The code is not very clean because it has been extracted from [GiiBiiAdvance](https://github.com/AntonioND/giibiiadvance), but it seems to handle all used configurations of edge handling.
178310

179311
Note that the actual Game Boy Camera sensor is affected by infrared so the emulation can't be perfect anyway. A good way of converting a RGB image into grayscale is to do:
180312

181-
182313
```c
183314

184315
//--------------------------------------------------------------------
185316

186317
// The actual sensor image is 128x126 or so.
187318
#define GBCAM_SENSOR_EXTRA_LINES (8)
188319
#define GBCAM_SENSOR_W (128)
189-
#define GBCAM_SENSOR_H (112+GBCAM_SENSOR_EXTRA_LINES)
320+
#define GBCAM_SENSOR_H (112+GBCAM_SENSOR_EXTRA_LINES)
190321

191322
#define GBCAM_W (128)
192323
#define GBCAM_H (112)
@@ -396,13 +527,13 @@ static void GB_CameraTakePicture(void)
396527
break;
397528
}
398529
}
399-
530+
400531
// Make unsigned
401532
for(i = 0; i < GBCAM_SENSOR_W; i++) for(j = 0; j < GBCAM_SENSOR_H; j++)
402533
{
403534
gb_cam_retina_output_buf[i][j] = gb_cam_retina_output_buf[i][j]+128;
404535
}
405-
536+
406537
//------------------------------------------------
407538

408539
// Controller handling

0 commit comments

Comments
 (0)