DanBoris
Members-
Content Count
1,086 -
Joined
-
Last visited
Content Type
Profiles
Member Map
Forums
Blogs
Gallery
Calendar
Store
Everything posted by DanBoris
-
You can find the roller controller and driving controller schematics here: http://xi6.com/hacks/ The roller controller schematics are pretty good but unfortunately for me they don't trace all the way out to the cables that connect to the system. Dan
-
Thanks! It would even be helpful if someone could open one up and just take a closeup picture of the area where the cables connect. Dan
-
I was wonder if someone could help me out with a Colecovision Roller Controller problem. I had been tracing the circuit for the roller controller PCB (before someone pointed out existing schematics online) and I noticed too late that a bunch of the wires going to the cables that connect to the system had broken off. Now I don't know which wires went where and the schematics don't show this. What I need to know is which color wires go to each position on the J5 and J6 locations on the PCB. Thanks Dan
-
What was the first "color" coin op game?
DanBoris replied to Cassidy Nolen's topic in Arcade and Pinball
Actually this might not be as difficult as you might initially think. I recently did some work on no-cpu arcade game simulator called DICE http://adamulation.blogspot.com/. It currently does circuit level simulation of Atari's Pong, Rebound and Gotcha all running at playable speeds. Now, I admit Indy 800 is quite a bit more complicated, but until I saw Dice I didn't think even Pong could be simulated at a playable speed. Dan -
If you have one of the Pokey cartridges, Ballblazer or Commando, you could narrow the problem down a bit. If they work then the problem is most likely with the TIA chip, if not it's in the analog section where the sound gets mixed into the composite video.
-
You can read a sample chapter from the book here: http://mitpress.mit.edu/catalog/item/defau...96&mode=toc
-
OT: Frequency Scanner/Sweeper, anybody know anything about them?
DanBoris replied to Cassidy Nolen's topic in Hardware
Take a look at this, it might help: http://ww1.microchip.com/downloads/en/AppNotes/00238C.pdf -
The resistor on pin 28 is not unusual in 7800 carts, you can see an example of another cart on my 7800 Cart Page that has the resistor. I am really surprised at the way the one on your cart is installed, much more labor intensive then inserting the chip fully and just raising the pin. Still don't know what the purpose of the resistor is.
-
You can also see another picture of the inside on my site along with the schematics: http://www.atarihq.com/danb/52trakball.htm
-
Around 0:52 in the video they show a screen shot of a game, does anyone have any idea what game that is? Dan
-
Are you referring to the 5200 trackball? The 5200 trackball does use pulse encoding internally, but the output of the trackball to the controller port is strictly analog. The speed of the balls rotation is converted into a voltage level that goes to the 5200 stick input so moving the ball faster is equivallent to push the stick further in one direction. Dan
-
Here a quick explanation of branch instructions, hope this helps. I guess branch instructions can be a little tricky because there are other things you need to understand before you can utilize them effectively. First you need to understand the processor status registers. The flags in this register are set or cleared based on the result of a lot of the other instructions. You can look at a 6502 instruction reference to see exactly which instructions set which flags. The flags that the branches can use are: Z – Zero Flag – This is set whenever an instruction results in a zero. So if you do a LDA #$00, the flag will be set, or if the X register contain 1 and you do a DEX, the zero flag will be set. Any other result will clear the zero flag. This is the flag you will probably use most often. C – Carry Flag – This is set whenever the A register rolls over from $FF to $00. So if A contains #$F0 and you do ADC #$20 then the carry flag will be set. This is a really important flag when you are doing 16-bit addition. N – Negative Flag – This is set equal to bit 7 of the result. When doing signed arithmetic bit 7 indicates a negative number thus the name Negative Flag. V – Overflow Flag – This is used when doing BCD arithmetic. It can be pretty confusing so I won’t get into it here. One important thing to remember about these flags, once they are set or cleared they remain in this state until another instruction that affects the flag is executed. Since not every instruction affects every flag it’s possible for a flag to carry over numerous instructions. Once you understand the flags the branch instructions are pretty simple. Each one checks the state of a flag and either branches execution to another memory location, or continues with the next instruction after the branch. The one tricky thing about this is that branches are “relative”. Branch instruction only takes up two bytes, the first byte is the opcode and the second is how far from the current memory location to jump. So if the second byte of a branch is $08 then the 8 will be added to the program counter and that’s where execution will continue. Since only one byte is used for this offset you can only branch 128 bytes forward, or 127 bytes backward. When working in assembler you don’t have to worry much about this offset, you just specify the address (usually a label) you want to branch to and the assembler will calculate the offset. The assembler will also tell you if you try to branch too far. So here are a few examples of the branch instructions: BNE – Branch if not equal (to zero). This will branch if the zero flag is not set. For example: Ldx #$00 loop inx bne loop This piece of code the loop until X rolls over to zero. BEQ is the opposite of BNE, it branches when the zero flag is cleared. If you go through the instruction reference you will find branch instruction that test each flag for being set or being cleared. One more important instruction to understand is the CMP, Compare, instruction. The instruction takes the operand data, subtracts it from the accumulator, set the N, Z, C flags and then discards the result, the accumulator is not modified. Here is an example: Lda $50 CMP #$22 BEQ endgame In this code if memory location $50 contains #$22 the branch will jump to the code at “endgame”. The compare instruction will subtract $22 from the accumulator, so if it contains $22 the result will be zero and the Z flag will be set. BEQ will test for the Z flag being set and take the branch.
-
Do you mean the instructions like BNE, BEQ, etc? What about them is giving you trouble? Dan
-
Not easily. The joystick inputs on the 5200 are analog, but the Colecovision steering controller is completely digital. Instead of a potentiometer it uses a digital encoder disk to sense the rotation. Dan
-
Sources for back in the day critical reviews
DanBoris replied to Great Hierophant's topic in Atari 2600
You can find some issues of Creative Computing Video & Arcade Magazine here: http://www.atarimagazines.com/cva/ There are some 2600 reviews in there. -
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 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 http://www.atarihq.com/danb/a7800.shtml. 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. 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. 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. 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. 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. 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). 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. 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. 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. 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.
-
Actually the technical document on it is available, you can find it here: http://www.retromicro.com/files/atari/8bit/cgia.pdf It was not much more then an ANTIC and GTIA on the same piece of silicon. It moved a few other support components on to the chip, but was software compatible, including addressing, to the separate ANTIC and GTIA. Dan
-
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 last time this is a little inefficient but not a big problem at the start of the program. 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. Now let’s look at almost the same program, but it will add one to I instead of two: BYTE I PROC MAIN() I=1 I=I+1 RETURN 0E58: .byte #$00 0E59: JMP $0E5C 0E5C: LDY #$01 0E5E: STY $0E58 0E61: INC $0E58 0E64: RTS 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. 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.
-
Gorf, First, let me appologize if I say some things that are obvious, I am not sure which parts of the Maria you understnad and which you don't. Once of the things you might be missing is that the DL is a list of entires, not a single entry. So if you have 4 sprites in the same zone you will have a list of 4 entries in the DL, one right after the other. You mention that you are going to do a character mapped background. In this case you would probably want to put your character DL entries in the list first since they won't change, then put the sprite DL entries after them. Memory management can be a little tricky, you will need to have enough memory for each DL entry to hold the largest number of sprites that can appear in each zone. Another thing to remember is that each sprite will probably have entries in two different DLs. If the DL falls on a even increment of 16 it will appear in only one zone, but in all other cases it will overlap two zones so you will have have a DL entry in the first zone to display the top of the sprite, then a second entry in the next zone to display the bottom. Dan
-
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” program. This Action code simply prints HELLO WORLD: PROC MAIN() PRINTE("HELLO WORLD") RETURN The resulting assembly code would look like this: 246E: JMP $2471 2471: JMP $2480 2474: .byte #$0B 2475: .string "HELLO WORLD" 2480: LDX #$24 2482: LDA #$74 2484: JSR $A46C 2487: RTS 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. 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.
-
Thanks! The Colecovision controller ports are completely digital so the only way to interface a resistive paddle would be to do some sort of analog to digital conversion. I haven't dug into the Colecovision driving controller yet, but I am assuming this is some sort of digital encoder like the driving controllers on the 2600. Dan
-
The biggest limiting factor is how many clock cycles the Maria graphics chip has to work with on each line. Doing some quick calculations it appear that if you did 4 pixel wide, 4 color sprites you would have enough time to display 27 sprites on each line. If you did 2 bytes of graphics data to get an 8 pixel wide sprite you could get 21 sprites per line. Of course it's a little trickier then this since the 7800 display is usually broken up into 8 or 16 line high zones, so these limits would actually be per zone not per region. So if you did 8 line high regions, you could actually get up to 252 8x8x4 color sprites on one screen. For a more realistic example you can look at Robotron which on some screens has over 50, 8 pixel wide by 4 color sprites on the screen at once. Dan
-
Wikipedia is your friend: http://en.wikipedia.org/wiki/Texas_Instruments_TMS9918 Ah, thanks! I actually read the Wikipedia article, guess I read it two fast. Dan
-
Since both the Colecovsion and the SMS use TMS9918 for video, how can the SMS do more more colors per sprite then the Colecovision? Dan
-
I am curious what people who know the CV think it could do with Robotron. Robotron demonstrates the 7800's strongest feature, the ability to do a lot of colorful moving objects. Some screens in Robotron have up to 50 moving objects, each with 4 colors and different sprites using a different color pallette. Dan
