Sunday, April 28, 2024

Odyssey 2 X/Y Position Registers

Update: After first publishing this article I read the notes in the O2 MAME driver and it indicated that there was some other unexpected behavior with these registers. I did some testing and have updated the article with the new findings.    

    I recently set up a development system for the Odyssey 2 so I could dig into some of the capabilities of the system. I am looking to improve the documentation I wrote back in the 90's to support the home-brew community and maybe improve the O2EM emulator. The first thing I took a look at is the X/Y position registers which seem to work differently then any of the current documentation describes.

    The purpose of these registers is to get the current X and Y position of the electron beam that is drawing the graphics on the CRT. Knowing the position could be useful to do mid-screen graphics changes. The registers are read from the VDC chip at location $A5 for the X position and $A4 for the Y position. 

   There seems to be two ways to read these registers. First you can bring bit one of the VDC Control Register ($A0) to 1 (&H02) and then back to 0. This will latch in the current beam position and they can then be read and will not change until this bit is strobed again. Second you can bring bit one of the VDC Control Register (&HA0) to 1 at which point the registers will follow the beam position, but you cannot read the Y position until you have first read the X position. The game Blockout read the Y position like this, it reads the X registers, throws away the value and then reads the Y. 

. Bit one in the VDC Status Register (&HA1) is supposed to indicate that the beam has been latched, but it seems to just follow the state of the latch bit in the control register, so wouldn't seem to have a purpose, but I will explain later what I think it is for. 

    I did same tests on the X register and could not get reliable results from reading it. Even if it was reliable the CPU just wouldn't be fast enough to read the registers for any meaningful purpose. 

    The Y register starts at 0 at the end of VBlank and increments to $F7 before the start of the next VBlank. It remains $F7 for the duration of VBlank before resetting back to 0. 

    According to the Intel datasheet on the 8244 VDC chip, there is a pin called STB that can also be used to latch the beam position. This pin is not used on the Odyssey 2, but I assume the intention of this pin was to support a light gun. This would also explain the need for bit one in the status register which indicates that the position has been latched, I assume this bit would also be set by the external pin. 

    A test program can be found here that demonstrates the relationship between the scanline counter and the Y Position Register.

https://github.com/danlb2000/Odyssey-2/tree/main/PositionRegiserTest

    The program resets the counter to a specified value and then records the value of Y Position register when the timer IRQ happens. It also changes the screen color at that time to demonstrate how mid screen color changes work. During the vertical blank it displays the value of the Y Position on screen. Adjusting the value of  TIMER_START will show different values on the screen. The program can also be re-configured to show the value of Y Position during VBlank. 

As of this writing neither MAME nor O2EM give the same results for this test as the real hardware.




Sunday, April 14, 2024

Magnavox Odyssey 2

 

Image is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license.



The Odyssey 2, known as the Philips Videopac G7000 in Europe, was a cartridge based videogame console developed by Magnavox and released in 1978. My first exposure to this machine was back in the late 70's when one of my friends had one. In 1996 I wrote the first emulator of the system, O2EM. At the time there was no publicly available information on the system so I ended up having to reverse engineer it. Eventually the project was taken over by Andre de la Rocha who continued to update it. 

Processor: Intel 8048

Speed: .36 MHz clock speed

RAM: 128 Bytes + 64 Bytes in processor

ROM: BIOS: 1K (Internal to processor)
            Cartridges: 2K address space, 2 bank select inputs for up to 8K bank switched carts

Sound: Intel 8244 custom Audio/Video IC
             24-bit shift register, clockable at 2 frequencies; noise generator

Graphics: Intel 8244 custom Audio/Video IC

Graphics RAM: 256 bytes of video control registers
Colors: 16
Sprites: 4, 8x8 pixel, 1 color
Background Graphics: 9x8 grid of lines or blocks. Each segment individually controllable
          28 Character objects from predefined internal character set

I/O: 2, 8 direction digital joysticks with one fire button

        48 key QWERT membrane keyboard with reset button        

Ports: Cartridge ports doubles as a system expansion port

           Early versions of the system had joystick ports, but later systems hardwired the joysticks

The system was a big leap forward compared to the dedicated "pong" console Magnavox had been producing up to that point, but was not as flexible as the Atari 2600. The graphics system is quite limited with the four 8x8 sprites being the only objects where the programmer had complete control of the shape which made if difficult to port existing games to the system. The 8048, which was designed to be an embedded controller, is also a little tricky to use for game programming. It has a very lean instruction set, for example it has no subtraction instructions, and no comparison instruction. 

I have recently setup a development system that will allow me to run software directly on the hardware so I can study the operation of the system in more detail. This will allow me to update the technical documentation I wrote back in the 90s and possibly make some improvements to O2EM.

If you are interested in more information about the system I recommend this Facebook group which has a good collection of available O2 documentation and example code.

Odyssey 2 and Videopac Homebrew Games