<?xml version="1.0" encoding="iso-8859-1" ?>
<rss version="2.0">
<channel>
	<title><![CDATA[DanBoris' Tech Blog]]></title>
	<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&module=showblog&blogid=52]]></link>
	<description><![CDATA[DanBoris' Tech Blog Syndication]]></description>
	<pubDate>Thu, 26 Nov 2009 17:09:27 +0000</pubDate>
	<webMaster>editor@atariage.com (AtariAge Forums)</webMaster>
	<generator>IP.Blog</generator>
	<ttl>60</ttl>
	<item>
		<title>Procedure Calls 1</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=6630]]></link>
		<category></category>
		<description><![CDATA[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:<br />
<br />
<pre class='prettyprint'>Proc test()
Return

Proc main()
   Test()
Return</pre><br />
<br />
<br />
<pre class='prettyprint'>0E61: 4C 64 0E    JMP  $0E64      

0E64: 60          RTS        

0E65: 4C 68 0E    JMP  $0E68      

0E68: 20 61 0E    JSR  $0E61      
0E6B: 60          RTS     </pre>   <br />
<br />
Our main procedure starts at 0E68 and it begins with a call to procedure Test using a JSR. The procedure Test starts at 0E61 which immediately jumps to the RTS since the procedure is empty. What I haven’t been able to figure out is why the JMP instruction is there since it doesn’t jump over anything. I have yet to find a case where it actually jumps over something.<br />
<br />
Next let’s look at how simple parameter passing is done:<br />
<br />
<pre class='prettyprint'>Proc test(byte I)
Return

Proc main()
Test(1)
Return</pre><br />
<br />
<br />
<pre class='prettyprint'>0E88: 	  .BYTE #$00
0E89: 4C 8C 0E    JMP  $0E8C      

0E8C: 8D 88 0E    STA  $0E88      
0E8F: 60          RTS        

0E90: 4C 93 0E    JMP  $0E93      

0E93: A9 01       LDA  #$01     
0E95: 20 89 0E    JSR  $0E89      
0E98: 60          RTS  </pre><br />
 <br />
This is the same as the first example, but now we pass a single BYTE parameter to the procedure. Here is an area where Action! does a good job at optimizing. Since there is only a single BYTE being passed it uses the most efficient way possible, it just passes it in the accumulator. At 0E93 the value 1 is loaded into the accumulator then the procedure is called.  At 0E8C that value passed is stored in the local variable I. You will notice that space for this variable is allocated before the start of the procedure code, so this doesn’t answer the mystery of the JMP instruction.]]></description>
		<pubDate>Thu, 26 Nov 2009 14:33:00 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=6630]]></guid>
	</item>
	<item>
		<title>CARD Math Part 2</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=6608]]></link>
		<category></category>
		<description><![CDATA[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. <br />
<br />
Here is the Action! program and it’s dis-assembly:<br />
<br />
<pre class='prettyprint'>
CARD I

PROC MAIN()
I=2
I=I+2
RETURN</pre><br />
<br />
<pre class='prettyprint'>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       LDA  #$02     
0E78: 8D 6C 0E    STA  $0E6C    

;I=I+2  
0E7B: 18          CLC        
0E7C: AD 6C 0E    LDA  $0E6C      
0E7F: 69 02       ADC  #$02     
0E81: 8D 6C 0E    STA  $0E6C      
0E84: AD 6D 0E    LDA  $0E6D      
0E87: 69 00       ADC  #$00     
0E89: 8D 6D 0E    STA  $0E6D      
0E8C: 60          RTS         </pre><br />
<br />
Most of what is here we have discussed before so I won’t go into great detail. As you can see since I is initialized to the value 2 the INY optimization can’t be used so two loads and stores are performed. It’s interesting to note that a different register is used for each byte. I am not sure why the compiler chooses to do this, although in the end it doesn’t affect program size or performance.<br />
<br />
The add part of the program is standard 6502 16-bit math, adding the lower byte, then adding the upper byte which also handles and carry from the lower byte.]]></description>
		<pubDate>Tue, 17 Nov 2009 21:15:00 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=6608]]></guid>
	</item>
	<item>
		<title>CARD Math Part 1</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=6599]]></link>
		<category></category>
		<description><![CDATA[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. <br />
<br />
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:<br />
<br />
<pre class='prettyprint'>CARD I

PROC MAIN()
I=1
I=I+1
RETURN</pre><br />
<br />
Here is the resulting disassembly:<br />
<br />
<pre class='prettyprint'>0E6A: .BYTE #$00,#$00

0E6C: 4C 6F 0E    JMP  $0E6F      

0E6F: A0 00       LDY  #$00     
0E71: 8C 6B 0E    STY  $0E6B      
0E74: C8          INY        
0E75: 8C 6A 0E    STY  $0E6A      
0E78: EE 6A 0E    INC  $0E6A      
0E7B: D0 03       BNE  $0E80      
0E7D: EE 6B 0E    INC  $0E6B   </pre>   <br />
<br />
We start at memory location $E6A where two bytes are set aside for variable I, and then as usual we have a JMP to that start of the code. <br />
<br />
The next four instructions assign the value 1 to I and you can see a nice little optimization here. First a 0 is put into the high byte of the variable. The low byte needs to have 1 in it and since the compiler knows that Y already contains 0 in can simply use the increment Y instruction to get a 1. This will save two bytes over using LDY #$01. <br />
<br />
The next three instructions handle the I=I+1. Just like in the BYTE math the compiler knows that +1 is just an increment so uses the INC instruction on the low byte of the variable instead of doing an ADC. The branch checks for an overflow and if there is one we then increment the high byte of the variable.]]></description>
		<pubDate>Sun, 15 Nov 2009 15:01:00 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=6599]]></guid>
	</item>
	<item>
		<title>7800 Sprites</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5463]]></link>
		<category></category>
		<description><![CDATA[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.<br />
<br />
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 sprite. If you want to see complete code on how to do this take a look at my 7800 Sprite Demo source code. For more details on the DLL and DL structure see the 7800 Software Guide. Both these files are available on my site <a href='http://www.atarihq.com/danb/a7800.shtml' class='bbc_url' title='External link' rel='nofollow'>http://www.atarihq.com/danb/a7800.shtml</a>.<br />
<br />
The first step is to setup the Display List List (DLL). Since we will be using 16 line high sprites the zones will also be 16 lines high, so this will give us 12 zones for a total of 192 lines. The first byte of each DLL entry will be $4F. This will enable 16 line holey DMA (I will explain this later) and an offset of 15 which corresponds to the 16 line height of the zone. The second and third bytes of the DLL are just a pointer to the Display List (DL) for this zone. For the purpose of this discussion we won’t worry about this address.<br />
<br />
Before we move onto how to setup the DL entries lets first have a refresher on how graphics data is setup in memory on the 7800. The graphics data for a sprite is NOT stored in sequential bytes in memory. Each line of graphics data for a sprite is stored on sequential pages (a page is 256 bytes) of memory, and it’s stored upside down. Let’s say we want to store our sprite data in the memory block between $A000 and $AFFF. For our first sprite the data for the first line of the sprite would be stored at location $AF00, the second line and $AE00, the third at $AD00, and so on until the last line is in location $A000. If we wanted to define a second sprite we would just move up one location in each page, so the first line would be in $AF01, the second in $AE01, and so on until the last line is in location $A001. <br />
<br />
Now let’s talk about how the DL entries would be setup. We will look at two scenarios, the first being where the sprite starts on the first line of a zone so it’s entirely in one zone, and the second scenario where it starts on the second line of a zone so it spans two zones. I am just going show how to use 5 byte DL entries, not the 4 byte entries. <br />
<br />
We start with the first scenario where the sprite in entirely in a single zone. The first thing we need to do it determine which zone the sprite is in. This is done simply by dividing the vertical position by 16 which is the same as taking the top 4 bits of the position. Once we know what zone the sprite is in we can start building the DL entry. <br />
<br />
The first byte of the DL entry is the low byte of the address of the sprite data. The data for the first sprite starts at location $A000 (even though it’s upside down we still say it starts at the lowest address), so this byte would be $00. The second byte will be $40. This just sets up the display mode and is not important for the purposes of this article. The third byte is the high byte of the sprite data, so it would be $A0 in this case. The fourth byte specifies the palette and the width, we will make this $1F and again the details are not important. Finally the fifth byte is the horizontal position of the sprite. <br />
<br />
The second scenario is a little more complicated. Since the sprite doesn’t fall entirely in one zone there will have to be a DL entry in two different zones. Both of these entries will be the same as the first scenario with the exception of the high byte of the graphics data (byte 3). <br />
<br />
To understand how these values will be determines you need to understand how the MARIA chip draws the screen. At the start of each DLL entry the offset value is loaded into a register in the chip. When MARIA goes to fetch graphics data it adds the offset value to the high byte of the graphics data. When it completes a line and moves to the next one it de-increments the offset value. So in the first scenario, on the first line the offset will be $0F which will get added to the high byte $A0, making an address of $AF00. This is why the graphics data is stored upside down. <br />
<br />
To have our sprite start on the second line of a zone instead of the first we would set the upper address to $A1. We are getting this by taking the lower 4 bits of the vertical position and adding it to $A0. When MARIA draws the first line it will add the offset of $0F to $A1 to get an address of $B000 for the first byte, when it draws the second line the offset of $0E will be added to $A1 so the second line of the zone would come from $AF00 which is the first line of the sprite data. But if we are taking the first line from $B000 wouldn’t this cause ‘garbage’ to be displayed at the top of the zone? No, because this is where holey DMA comes in to play. When 16 line holey DMA is enabled and MARIA fetches data from memory, if address bit 12 is high then zero is returned instead of data that is in memory. $B000 has bit 12 high so the graphics data will be zero for the first line of the zone. <br />
<br />
The first zone will contain the first 15 lines of the sprite, but the final line of the sprite will appear in the next zone. Again, the only difference from the first DL entry will be the high address of the graphics data. In this case we would set the high byte to $91. When the first line of this zone is drawn the offset will be $0F added to $91 = $A000 which is the last line of our sprite data. On the second line of the zone the offset will be $0E added to $91 = $9F00. Once again holey DMA will take effect since bit 12 is high so the graphics data will be zero. This will continue to the end of the zone. <br />
<br />
That is the basics of how to setup sprite data in the display lists. If we were doing more then one sprite we would iterate through each sprite repeating the process above and appending the DL entries to the end of each DL. Finally, once we have finished creating all the DL entires we would need to go back and terminate each DL. This is done by adding a final entry where the 2nd byte is zero.]]></description>
		<pubDate>Tue, 11 Nov 2008 23:28:30 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5463]]></guid>
	</item>
	<item>
		<title>Action!: Byte Math</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5444]]></link>
		<category></category>
		<description><![CDATA[Next let’s look at some simple byte variable manipulation. Here is the first sample Action program:<br />
<br />
<pre class='prettyprint'>BYTE I

PROC MAIN&#40;&#41;
I=1
I=I+2
RETURN</pre><br />
<br />
And the assembly code<br />
<br />
<pre class='prettyprint'>24B3&#58; .byte $00
24B4&#58; JMP  $24B7	  

24B7&#58; LDY  #$01	 
24B9&#58; STY  $24B3	  
24BC&#58; CLC		
24BD&#58; LDA  $24B3	  
24C0&#58; ADC  #$02	 
24C2&#58; STA  $24B3	  
24C5&#58; RTS</pre><br />
<br />
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 last time this is a little inefficient but not a big problem at the start of the program. <br />
<br />
Next we load the immediate value 1 into I. I assume they use the Y register for this so that A can be reserved for math operations which will allow for some optimizations under certain conditions. I have another example that I will post at some point that shows this. In this situation by using Y they actually miss out on the opportunity for an optimization. If A had been used the LDA would not have been necessary. Finally a normal 6502, 8-bit add sequence is executed and the result stored by in I. <br />
<br />
Now let’s look at almost the same program, but it will add one to I instead of two:<br />
<br />
<pre class='prettyprint'>BYTE I

PROC MAIN&#40;&#41;
I=1
I=I+1
RETURN</pre><br />
<br />
<br />
<pre class='prettyprint'>0E58&#58; .byte #$00
0E59&#58; JMP  $0E5C	  

0E5C&#58; LDY  #$01	 
0E5E&#58; STY  $0E58	  
0E61&#58; INC  $0E58	  
0E64&#58; RTS</pre><br />
<br />
As you can see the code is quite a bit smaller. The compiler recognized that I=I+1 is an increment so it uses the INC instruction on the memory location where I is stored resulting in a savings of three instructions.<br />
<br />
You may notice that this example is at a different memory location then the first one. I am not actually sure why this happened. I have been compiling these examples using an emulator and those two examples were compiled at different times so it’s possible that I had the emulator configured differently each time.]]></description>
		<pubDate>Fri, 07 Nov 2008 19:07:00 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5444]]></guid>
	</item>
	<item>
		<title>OSS Action!</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5430]]></link>
		<category></category>
		<description><![CDATA[One of my favorite programming languages for the Atari 8-bit computers is <a href='http://en.wikipedia.org/wiki/Action_programming_language' class='bbc_url' title='External link' rel='nofollow'>OSS Action!</a>. 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. <br />
<br />
First lets look at the classic “Hello World” program. This Action code simply prints HELLO WORLD:<br />
<br />
<pre class='prettyprint'>PROC MAIN&#40;&#41;
   PRINTE&#40;&#34;HELLO WORLD&#34;&#41;
RETURN</pre><br />
<br />
The resulting assembly code would look like this:<br />
<br />
<pre class='prettyprint'>246E&#58; JMP  $2471	  
2471&#58; JMP  $2480	  

2474&#58; .byte #$0B
2475&#58; .string	&#34;HELLO WORLD&#34;
2480&#58; LDX  #$24	 
2482&#58; LDA  #$74	 
2484&#58; JSR  $A46C	  
2487&#58; RTS</pre>    <br />
<br />
The program starts with two JMP instructions. Although this isn’t very efficient, it’s at the start of the program so isn’t a big problem. The first JMP jumps to the MAIN procedure which is the starting point for all Action programs. The second JMP is the start of the MAIN procedure and it needs to jump over the static text that stored before the procedure. <br />
<br />
Next we have the static text we will be printing. The first byte contains the length of the string and the rest the actual string data. After the string we have the actual code for the procedure. It simply loads the address of the string into the X and A registers and calls a library subroutine to do the printing.]]></description>
		<pubDate>Sun, 02 Nov 2008 15:10:07 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5430]]></guid>
	</item>
	<item>
		<title>7800 Fine Scrolling</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5198]]></link>
		<category></category>
		<description><![CDATA[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.<br />
<br />
<strong class='bbc'>Display List</strong><br />
<br />
The display list for the demo consists of 24, 8 line high regions. Each region will display 41 characters in the 320D mode using indirect graphics. Each region has two DL entries one to display the first 20 characters, the second to display the remaining 21. Two DLs are needed because you can’t display more the 32 characters with a single DL. <br />
<br />
<strong class='bbc'>Horizontal Scrolling</strong><br />
<br />
The horizontal scrolling turns out to be pretty easy because of the way the 7800 handles wrap around of the graphics. A horizontal position of 0 – 159 is visible on the screen but anything beyond 159 won’t be displayed. If you position a graphic with an hpos just below 255 the beginning of the graphic won’t be displayed but the rest will. So to do horizontal scrolling it’s simply a matter of changing the hpos of the two dl entries on each line. You will notice that the second DL entry has 21 characters instead of 20. This is necessary because even though the screen is 40 characters wide 41 different characters will be displayed during scrolling with partial characters at either end of the line. <br />
<br />
<strong class='bbc'>Vertical Scrolling</strong><br />
<br />
Vertical scrolling is a little trickier. Here we need to end up with partial characters at the top and bottom of the screen during scrolling. The cropping of the top row can easily be handled by varying the height of the top region between 1 and 8 lines. As the top region gets smaller the bottom region will needs to get bigger so its height is set to (8 – top region height). Simply changing the height of last region won’t actually give us the result we need, because as the region get smaller the top of the characters will be cropped off not the bottom. To compensate for this we need to adjust the character base pointer for just the last zone. For each line smaller we make the last region we need to move the character base pointer up one page. We can achieve this using a display list interrupt on the last zone to set the modified character base, then another one in the next zone to get it back to the default. <br />
<br />
<strong class='bbc'>Course Scrolling</strong><br />
<br />
Note that what I am demonstrating in this program is just fine scrolling. Once I have scrolled a full character width or height in a specific direction I reset the scrolling back to the start of the character. It gives the appearance of continuous scrolling but I am really just repeatedly scrolling over the same characters. You could layout the entire character map for a screen in RAM or ROM then scroll the screen over that map. When you reached the end of a fine scroll you would reset the scroll and then update all the memory pointers in the display list to course scroll to the next row of column of the map.]]></description>
		<pubDate>Sat, 23 Aug 2008 13:11:45 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5198]]></guid>
	</item>
	<item>
		<title>7800 Control Register</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5118]]></link>
		<category></category>
		<description><![CDATA[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!<br />
<br />
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) before you can use the TIA. <br />
<br />
There are 4 bits in the register and they work as follows:<br />
<br />
Bit 0 (lock mode) – When set to 1 this bit locks the control register so that no more writes will affect it. The only way to clear the lock is to power cycle the console. <br />
<br />
Bit 1 (MARIA Enable) - 1 = enable MARIA (also enables system RAM), 0 = disable MARIA (only RIOT RAM is available). 0 also disables the EXTRAM signal from the expansion connector.<br />
<br />
Bit 2 (EXT) - 0 = enable BIOS at $8000-$FFFF, 1 = disable BIOS / enable cartridge<br />
<br />
Bit 3 (TIA-EN) - 1 = enable TIA video pull-ups (video output is TIA instead of MARIA) and also disables 2 button joystick mode, 0 = disable TIA video pull-ups (video output is MARIA instead of TIA). <br />
<br />
Besides the functions controlled by the register bits, it also controls the HALT input to the 6502. When the 7800 is first powered up HALT is blocked from getting to the 6502, but after 2 writes to the control register (the data written doesn’t make a difference), the HALT input will be enabled. I am not sure why this function exists. I can only speculate that it’s to prevent the MARIA from spuriously halting the 6502 until it’s properly initialized.]]></description>
		<pubDate>Fri, 25 Jul 2008 23:54:29 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=5118]]></guid>
	</item>
	<item>
		<title>Telengard</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=4957]]></link>
		<category></category>
		<description><![CDATA[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 curious how the achieved this. <br />
<br />
The programmer did it by using a pseudo-random algorithm to generate the map. This results in a map that is complex enough to be interesting, but not so complex that it's unplayable.<br />
<br />
This is the formula that is used to determine the appearance of each room:<br />
<br />
<pre class='prettyprint'>XO = 1.6915
YO = 1.4278
ZO = 1.2462

q = x * XO + y * YO + z * ZO + x * YO + y * ZO + z * XO
hi = q And &HFF
q = x * y * ZO + y * z * XO + z * x * YO

If &#40;q And 3&#41; = 0 Then

	q = &#40;q / 4&#41; And &HF
	If q &#62; 9 Then q = q - 9
	hi = hi + q * 256

End If</pre><br />
<br />
XO, YO, and ZO are constants<br />
z = dungeon level<br />
x,y = room position in level<br />
<br />
This formula is run for each room that is displayed and the result, hi, is interpreted as follows:<br />
<br />
bits 0,1: Upper wall: 0,1 = nothing, 2 = door, 3 = wall<br />
bits 2,3: Left wall: 0,1 = nothing, 2 = door, 3 = wall<br />
bits 8-11: If not 0 then there is something special in the room<br />
<br />
    1 = Inn<br />
    2 = Pit<br />
    3 = Teleporter<br />
    4 = Stairway<br />
    5 = Alter<br />
    6 = Fountain<br />
    7 = Cube<br />
    8 = Throne<br />
    9 = Box<br />
<br />
The bottom wall and right wall of a room come from the left and top wall of adjacent rooms. There is also code that knows to  cap the right side and bottoms of the rooms at the edge of the maze.<br />
<br />
You can take a look at the full commented Basic code for Telengard on my web site along with a VB.NET program that allows you to browse the maze.<br />
<br />
<a href='http://www.atarihq.com/danb/Telengard.shtml' class='bbc_url' title='External link' rel='nofollow'>http://www.atarihq.com/danb/Telengard.shtml</a>]]></description>
		<pubDate>Sun, 08 Jun 2008 22:05:07 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=4957]]></guid>
	</item>
	<item>
		<title>Website Update</title>
		<link><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=3519]]></link>
		<category></category>
		<description><![CDATA[I've just added a Pong page to my website <a href='http://www.atarihq.com/danb' class='bbc_url' title='External link' rel='nofollow'>http://www.atarihq.com/danb/</a> that includes my Pong simulator as well as an updated set a schematics.]]></description>
		<pubDate>Sat, 30 Jun 2007 18:27:06 +0000</pubDate>
		<guid><![CDATA[http://www.atariage.com/forums/index.php?app=blog&blogid=52&showentry=3519]]></guid>
	</item>
</channel>
</rss>
