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:
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
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:
0E6C: .BYTE 00,00
0E6E: 4C 71 0E JMP $0E71
0E71: A0 00 LDY #$00
0E73: 8C 6D 0E STY $0E6D
0E76: A9 02 L
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:
Here is the resulting disassembly:
0E6A: .BYTE #$00,#$00
0E6C: 4C 6F 0E J
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
Next let’s look at some simple byte variable manipulation. Here is the first sample Action program:
And the assembly code
24B3: .byte $00
24B4: JMP $24B7
24B7: LDY #$01
24B9: STY $24B3
24BD: LDA $24B3
24C0: ADC #$02
24C2: STA $24B3
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 my favorite programming languages for the Atari 8-bit computers is OSS Action!. Action is a compiled, structured programming language similar to C or Pascal. One of the impressive features of Action is it’s very fast an efficient compiler. Not only does it compile programs quickly, it produced pretty tight machine code executables. I thought it would be interesting to take a look at some of the machine code that the compiler produces.
First lets look at the classic “Hello World” prog
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.
The display list for the demo consists of 24, 8 line high regions. Each region will display 41 chara
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
One of the games I remember from the good old days with my Atari 800 computer is the dungeon crawler Telengard by Avalon Hill. The game was written in Basic so I thought it would be interesting to take a look at the code for the game. One of the most interesting parts is the way the maze if generated. The dungeon in the game is very large, it has 50 level and each level is 200 by 200 rooms. The dungeon is also the same every time you play so you can map it out as you go along. I was really curio
I've been working on a Pong related project and I thought I would post a screen shot:
Yes, this may look like any one of 1000 different Pong simulation programs that people have written, but this one it a little bit different. The screen shot you see here was generated by doing a chip level simulation of the Pong circuit using a general purpose digital logic simulation engine. Here a little sample of the code used to define one of the score counters:
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
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
Here is the other proposal supercat made for the ball horizontal control circuit. This one actually appears to work exactly like the real circuit, providing 3 different ball speeds and saves at least 2 chips.
In the discussion of the ball horizontal control circuit, supercat proposed a simplified circuit that would perform the same function. This is the circuit I believe he is describing:
It actually comes pretty close to working, and it does use less chips, but instead of generating 3 speeds it generates 4.
The VSYNC input will make sure the circuit is only enabled for the first four lines on the screen. For each count on the hit counter the MOVE signal will be enabled for
As supercat observed in my last entry, I totally missed this part the first time around. Better late then never...
For anyone who has played Pong, you may remember that the more times you volley the ball back and forth, the faster the ball will move. This counter counts those volleys. Each time the ball is hit by either player the counter will increment until it reaches a count of 12, at which point it will be disabled by NAND gate E1. The counter is reset by the RST
It's been a while since I did an update to my Pong circuit analysis, but I just get distracted by other project far to easily!
The next section is the hit sound, the sound made when the ball is hit.
When the ball hits either paddle the /HIT signal will go low which will clear C2 and set the /Q output high. For /HIT to go low VPOS256 has to be high, so there won’t be another positive edge on VPOS256 to clock the counter until the next frame. On the
The next couple of circuits are used to generate the sounds for the game. The first sound circuit is for the score sound. This sound is played whenever either player misses the ball.
When a player misses the ball the /MISS signal will go low which will trigger the 555 timer G4. When triggered the output of G4 will go high and stay high for 242ms at which point the output will return low. When the output of the timer is high the 32V signal will be allowed to pass through NAND C3 to the
We have almost looked at the entire Pong circuit, just a few miscellaneous sections to go. This is the server timer circuit
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 reply to my last entry explaining the transistor portion of the game control circuit allowed me to work out the complete opertation of this section.
When the coin switch is activated it momentarily pulls /SRST low which resets the score counters. The two C9 inverters generating an active high reset signal which is also used to reset the score counters. When /SRST goes low it pulls the base of Q2 low which turns on Q2, which pulls the base of Q1 high turning Q1 on. With Q1 on the base of
I am hoping that I can get a little help figuring this section out. I am pretty good with digital analysis, but my transistor theory is a little (ok a lot) rusty. The purpose of this section is to control the game state. Here are the things that I do know about this circuit:
- When either /STOPG1 or /STOPG2 goes low, indicating that one of the score counters has reached the game ending score, the output of B3 (STOP G) will go high which stops the game. The high on STOP G will also set /ATRAC
The first step in counting the score is to determine when one player or the other has missed the ball. This turns out to be very easy to detect because the only graphic object that can move off the visible screen is the ball. The circuit shown below ANDs the horizontal component of the video with the HBLANK signal to create the /MISS signal. Whenever there are graphics being displayed during horizontal blank, /MISS will go low indicating that the ball went off the screen. /MISS next passes throu
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
The ball vertical motion is controlled by a slip counter just like the horizontal.
The counter is clocked by the /HSYNC signal so it will increment once per line. Since /VBLANK goes to the ENT input of B3 it will stop the count during VBLANK. When the two stages of the counter reach 255 the load signal will be triggered by B2. The upper stage of the counter is loaded with 0, and the lower portion is loaded with the output of the vertical control circuit. The values from the vertical c
Now that we have looked at the horizontal component of the ball we will look at the vertical portion. The vertical is based on a slip counter just like the horizontal so we will cover the slip counter control first. The vertical motion of the ball is influenced by two things, hitting the top or bottom of the screen, or hitting one of the paddles. When the ball hits the top or bottom of the screen, it will reverse direction, but keep the same speed. When the ball hits the paddle the effect on the