The horizontal and vertical counters are used to drive the rest of the digital logic in the circuit, but these counters cannot directly drive the synchronization of the CRT, for this horizontal and vertical sync signals are needed. Here is the circuit that generates the horizontal sync:
wishes.zip
The two H5 NAND gates form an RS flip-flip. When pin 4 goes low, pin 6 will go high and stay high, until pin 10 goes low. At the end of a scan line /H RESET will go low which will set HBLANKING
The vertical sync circuit works similar to the horizontal sync circuit. Again we have an RS flip-flop composed of two logic gates (F5), but this one is triggered by a high instead of a low. At the end of the vertical count, V RESET will go high, which will set VBLANK high which indicates the start of the vertical blank period. When the vertical counter reaches 4, the output of G5 will go low which is the vertical sync signal. When the count reaches 8, 8V goes high, the output of H5 goes low whic
While studying the score counters I was having a hard time figuring out how the score was credited to the correct player, it seemed that misses on the left side where scoring on the left side instead of the right. Turns out that I had a mistake in an earlier section, Ball Horizontal Control (Part 1). Turns out that I had the /HIT1 and /HIT2 counters reversed, the circuit should look like this:
This is the proper description of how this circuit should work.
The flip/flop H3 is used
We have almost looked at the entire Pong circuit, just a few miscellaneous sections to go. This is the server timer circuit
2puck.zip
During normal play the output of F4, /RUN and STOP G will all be low which will make the output of E5 high, which will keep the SERVE output of B5 low. When the ball is missed, /MISS will go low, pin 6 of E6 will go high which resets the ball speed counter. Pin 3 of E6 will then go low which triggers the 555 timer and sets the output high, and sets the o
The next thing I want to talk about is the attract mode, which is the mode the game is in when it’s not being played, designed to “attract” new players. Most of the schematics for this section I have posted already, so I will just describe how attract effects each section. The attract signal is generated by the game control circuit and is fed as both an active high and active low signal to various other circuits in the game.
In the paddle circuit, /ATTRACT holds the preset pin of flip-flop
Looks like we have finally come to the last Pong circuit we need to cover. I just looked back at the archive for this blog and was shocked when I realized that I have been doing this Pong circuit description for almost 2 years! I know I was going through this pretty slowly but never realized I had taken that long. On to the final circuit...
This circuit is used to generate a sound whenever the ball hits the top or bottom of the screen. During normal play /SERVER is high so the flip/flo
Occasionally questions come up about the special “hidden” control register in the 7800, and I usually end up searching back through the forum archive for the answer, so I thought I’d finally document it somewhere I can find it!
The purpose of this control register is to switch the 7800 from 7800 mode to 2600 mode. The register can be written to using any address between $0000 and $001F. This address range overlaps the TIA so once the register is set you need to set the lock bit (see below) b
I’ve recently been doing some research into how scrolling games work on the 7800. I have created a demo program that shows a method for doing horizontal and vertical fine scrolling controlled with the player one joystick. I’ve tested this program on an emulator but on the actual hardware. The attached ZIP files contains the source and binary that can be used with an emulator.
Display List
The display list for the demo consists of 24, 8 line high regions. Each region will display 41 chara
Next let’s look at some simple byte variable manipulation. Here is the first sample Action program:
BYTE I
PROC MAIN()
I=1
I=I+2
RETURN
And the assembly code
24B3: .byte $00
24B4: JMP $24B7
24B7: LDY #$01
24B9: STY $24B3
24BC: CLC
24BD: LDA $24B3
24C0: ADC #$02
24C2: STA $24B3
24C5: RTS
This code starts at memory location $24B3 which is where the global variable I is stored. Next we have a jump instruction that gets us to the MAIN procedure. Like
One of the trickier parts of the 7800’s MARIA graphics chip is understanding how to setup the display lists and display list list (DL and DLL). Even trying to put a single sprite on the screen can be tricky. In this article I will explain how to setup these data structures to get a simple sprite on the screen.
In this example we will take a very narrow scenario just to explain the basics of how to get a sprite on the screen. I will show how to display a single 16 line high by 1 byte wide spr
I can’t believe it’s been over a year since my last blog post, time sure does fly! I thought it was about time to get back to some posts and continue my Action! language topic.
Last time I talked about BYTE math, this time we will start looking at CARDinal math. In Action the CARD data type is a two byte unsigned value. Here is the first piece of Action! code:
CARD I
PROC MAIN()
I=1
I=I+1
RETURN
Here is the resulting disassembly:
0E6A: .BYTE #$00,#$00
0E6C: 4C 6F 0E J
In my last post I showed how the Action! compiler produces some pretty optimized code for CARD math under certain circumstances. This time I will show the more general case which should be pretty familiar to anyone who has done 6502 programming.
Here is the Action! program and it’s dis-assembly:
CARD I
PROC MAIN()
I=2
I=I+2
RETURN
0E6C: .BYTE 00,00
0E6E: 4C 71 0E JMP $0E71
;I=2
0E71: A0 00 LDY #$00
0E73: 8C 6D 0E STY $0E6D
0E76: A9 02 L
Let's take a break from looking at Action! math and take a look at procedure calls. We will start up with something that is trivially simple:
Proc test()
Return
Proc main()
Test()
Return
0E61: 4C 64 0E JMP $0E64
0E64: 60 RTS
0E65: 4C 68 0E JMP $0E68
0E68: 20 61 0E JSR $0E61
0E6B: 60 RTS
Our main procedure starts at 0E68 and it begins with a call to procedure Test using a JSR. The procedure Test starts at