Jump to content

SeaGtGruff

Members
  • Content Count

    5,587
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by SeaGtGruff

  1. If the score jitters, the problem must be somewhere between the end of the game screen and the beginning of the score. The only difference I see in that section of code between the 2009 version and the December 2007 version is that the "beginscore" label was moved down a line: December 2007 version: ; cycle 0 lda (scorepointers+$,y ;+5 5 15 beginscore sta GRP1 ;+3 8 24 D1 D1 D2 -- lda (scorepointers+$6),y ;+5 13 39 2009 version: ; cycle 0 beginscore lda (scorepointers+$,y ;+5 5 15 sta GRP1 ;+3 8 24 D1 D1 D2 -- lda (scorepointers+$6),y ;+5 13 39 Assuming the December 2007 version was jitter-free and the 2009 version is giving you the jitters, I would try cutting out the line with "beginscore" and paste it one more line further down, then recompile your program with the modified file and see if that fixes the jitter.
  2. There's not really anything to install, just put the dasm.exe file in whatever directory you want to keep it in. You can't just "run" dasm by itself per se. What I mean is, you must give it command line parameters to tell it what you want it to assemble. For example, suppose you have a text file named "mygame.asm" containing assembly code for a game you've written. To keep this simple, let's assume you've put dasm.exe and your mygame.asm file in the same folder. To assemble it with dasm you could open a command prompt window, change directories so you're in the folder where you've got dasm.exe and mygame.asm, then enter a command something like the following: dasm mygame.asm -f3 -omygame.bin The first command line parameter after "dasm" is the name of the file you want to assemble. The remaining command line parameters can be in any order, as the letter after the dash tells dasm what the parameter is. The -o parameter tells dasm what you want the output file (resulting object file) to be named. The -f parameter tells dasm what format to use for the output file. For an Atari 2600 or Atari 7800 game you'll want to use -f3, which is the "raw" format-- no file header, and the object file will be a single chunk of contiguous code. You can include full file paths with the file names if you need to (if everything isn't going to be in the same folder as the dasm.exe program), but if there are any spaces in the file paths or file names then you'll need to enclose them in quotes, as in the following example: "c:\dasm folder\dasm.exe" "c:\my programming stuff\my game.asm" -f3 -o"c:\my programming stuff\my game.bin" Since dasm can assemble different types of assembly code, your assembly program will need to start with a "processor" instruction to tell it which processor (type of assembly language) you're assembling for, such as processor 6502 This should be the first line of your program, before any other code. Since dasm is just an assembler, not an editor, and since you have to use a command line with parameters to "run" dasm (i.e., to assemble something with it), you may want to get an IDE to do your programming in, then set up a user-defined tool in the IDE that will call dasm with the appropriate parameters. I like to use Crimson Editor because it's free and is fairly full-featured as free IDEs go, but other people like to use other IDEs or editors. You can set up one tool for calling dasm to assemble your programs, and another tool for calling an emulator to run your assembled programs. All you really need is a text editor-- for instance, Notepad in Windows would work fine. Then you can either open a command prompt and type a suitable command line to assemble your code, or make a batch file to help simplify it for you. Before anyone tries to give you more specific guidance, you might want to decide on what sort of environment or setup you want to use-- for example, a particular IDE, or Notepad and some batch files, or whatever.
  3. I guess I messed up when I said "if the final result is positive." Here's a slightly modified set of steps that are more accurate: (1) Take the number of the cycle that comes right after the RESxx completes. (2) Multiply by 3 to get the equivalent color clock number. (3) Add 4 to get the adjusted color clock number. (4) Subtract 68 to convert the adjusted color clock number into a pixel position. (5) If the result is negative, keep adding 3 to it until you get a positive value. (6) If you're repositioning a player, add 1 more pixel. The thing is, even though you have to add 5 instead of 4 to get the player's position, the TIA behaves as though the player starts 1 pixel earlier and is 9 pixels wide, but the leftmost pixel is always blank. You can read about the technical reasons for this in a document called "Atari 2600 TIA Hardware Notes" by Andrew Tower. So in the example you gave, it's actually ((21 * 3) + 4) - 68 = -1, which is negative, so you have to keep adding 3 until you get a positive number, or -1 + 3 = 2. Then you have to add 1 more because you're repositioning a player, so you end up with 2 + 1 = 3. But there's an exception at the right edge of the screen. If you strobe RESxx such that the next cycle after the instruction ends is cycle 75, you get ((75 * 3) + 4) - 68 = (225 + 4) - 68 = 229 - 68 = 161. The color clocks go up to only 227 (i.e., color clock 228 = color clock 0), so that's actually 229 - 68 = (229 - 228) - 68 = 1 - 68 = -67, which is negative. However, the next cycle after the RESxx instruction ends is still within the active portion of the scan line, so the TIA is still clocking the sprite position counters, and the sprite's new position ends up at pixel 1, or at pixel 2 if it's a player. That's because the sprite position counters stop during the horizontal blank, which is why a sprite wraps around the screen if its left edge is near the right edge of the screen (i.e., the left side of the player is at the right side of the screen and the rest of the player gets drawn at the left side of the screen). So essentially the new position is 161 as computed the first time. Subtract 160 for the wraparound behavior, giving 161 - 160 = 1 for the ball or a missile. Then add 1 if you're repositioning a player. As I mentioned before, it appears that repositioning a sprite while HMOVE is doing its thing causes the sprite to end up 1 pixel further to the right than expected, but I'm not sure of the specifics of that behavior.
  4. It's easy enough to figure out. (1) Take the number of the cycle that comes right after the RESxx completes. (2) Multiply by 3 to get the equivalent color clock number. (3) Add 4 if you're repositioning the ball or a missile, else add 5 if you're repositioning a player. (4) Subtract 68 to convert the resulting (adjusted) color clock number into a screen (pixel) position. If the final result is positive, that's the new position. If the final result is negative (i.e., inside the horizontal blanking area), the new position will generally be 2 for the missiles or ball, or 3 for the players-- those being the first values that fall within the active (visible) area. However, if you strobe RESxx right after doing a standard HMOVE it seems to throw the repositioning off by 1, making the new positions 3 for the missiles or ball, or 4 for the players. But I'm not sure of the details-- i.e., whether it's anytime while HMOVE is feeding extra clocks to the position counters, or if there's some specific time frame involved-- so it's probably best to use trial and error to find the exact position if HMOVE is also involved. Here's an example: Suppose you do a 3-cycle STA RESP0 that begins at cycle 25 and therefore spans cycles 25, 26, and 27. The next cycle is 28, so multiply by 3 (28*3=84), add 5 since a player is involved (84+5=89), and subtract 68 (89-68=21). So the new position will be at pixel 21.
  5. I think Random Terrain's bB reference page *may* have a link to the newest versions of the compiler and include files, under the "Getting Started" section-- but I haven't checked the zip file it links to yet to see if it contains the latest versions.
  6. I had thought there might be as many as three rings, so that's what I started with in a screen mockup using Paint. You can use the player size register to increase the size of the heart. There are up to 3 player sizes-- normal width, double with, and quadruple width. I think quad might be too big as is, but you could decrease the number of pixels slightly while making the player bigger to make the size increase look more natural (less dramatic). For instance, if the smallest heart is 8 pixels wide, then a double-size player would be 16 color clocks wide (2 color clocks per pixel). So for the third size you could decrease the heart to 6 pixels wide, which would be 24 color clocks wide for a quad-size player (4 color clocks per pixel), or only 3 times the size of the smallest heart as opposed to 4 times the size. That might make the heart look a little too blocky at the largest size, but another option is to draw the largest heart using two double-size players-- the left half with player 0 and the right half with player 1. Yet another option would be to draw the double-size heart using two players so you can still get the same pixel size (16 pixels total, 8 for each half), then draw the triple-size heart with one player sandwiched between two copies of the other player with the second copy being reflected (24 pixels total, 8 for the left side, 8 for the center, and 8 for the right side). I'm tinkering around with some ideas for a custom kernel, and will post more if I can come up with something feasible.
  7. Yes, Visual bB is just an IDE, although Visual bB is specifically for use with bB and has a lot of nice built-in tools to help with designing bB games. As the bB language gets updated, Visual bB often has to be updated accordingly. I don't use Visual bB myself, because I've been using Crimson Editor for several years as my free IDE of choice for batari Basic, 6502 assembly, Free BASIC, etc. I keep telling myself that one of these days I'm going to switch to Visual bB, but today keeps becoming yesterday, and I still haven't made the switch yet-- too lazy, I guess! You should be able to use any decent IDE for your bB programming, as long as you set up a user-defined tool for calling the bB compiler batch to compile your program, and another tool for calling Stella or other emulator to run your program.
  8. I watched the video of the original game and of the Atari 2600 WIP. How many rows (concentric circles) are you going for? The video of the original game started with 1 circle and went up to 2 circles, but I got the impression it would have added more as the game progresses?
  9. If you do a STA RESP0 at cycle 0 through cycle 22, you should get player 0 at screen position 3. If you do a STA RESP0 at cycle 23, you should get player 0 at screen position 6. Note that the cycle numbers mentioned actually refer to the cycle that comes immediately *after* the instruction, due to the way cycles are counted. That is, suppose you do a STA WSYNC and then a STA RESP0. The cycles would typically be counted as follows: STA WSYNC ; +3 ; 0 STA RESP0 ; +3 ; 3 Of course, different programmers may use different notation, but I do it as shown above. The first number shows how many cycles the instruction takes, and the second number shows how many cycles have elapsed on the current scan line. In this example we can't tell which cycle the STA WSYNC instruction begins on, but we know that STA WSYNC will pause the CPU and it won't start processing again until cycle 0. That means the STA RESP0 instruction will begin at cycle 0 and end at cycle 2-- i.e., since it takes 3 cycles to execute, it will span cycles 0, 1, and 2. Thus, the next cycle *after* the STA RESP0 instruction will be cycle 3, which is also equal to the total number of cycles that have elapsed on the current scan line. Following the naming convention used when referring to HMOVE-- e.g., a "cycle 73 HMOVE" or a "cycle 74 HMOVE"-- this would be called a "cycle 3 RESP0" because the instruction takes effect at cycle 3. Actually, there's a lag between the end of the STA RESP0 instruction and player 0's new position, due to the way the TIA works, but the repositioning process starts as soon as the instruction ends. The amount of the lag depends on a few things, but the shortest lag for the two players is 5 color clocks. I haven't seen your code or the code you're using from vdub bobby, but the only thing that comes to mind is that you might be referring to the color clock where the instruction *starts* rather than the color clock that comes after the instruction has completed. And it's possible you're using either absolute addressing or zero-page,X addressing or zero-page,Y addressing (which take 4 cycles) rather than zero-page addressing (which takes 3 cycles). Most positioning routines do use zero-page,X or zero-page,Y addressing, where the X or Y register is used to offest the target address so the same routine can be used for positioning any of the five sprites. So if that's what you're doing, the STA RESP0,X instruction takes 4 cycles or 12 color clocks. Hence if it starts at color clock 57 (or pixel -11), that would be cycle 19. But it spans cycles 19, 20, 21, and 22, therefore it doesn't take effect until cycle 23, which would produce a new player 0 position at pixel 6: STA RESP0,X ; +4 ; -11 ; 057 ; 19-22 ; 23 ; 069 ; 001 ; 006 The numbers given above are an expansion of the way I normally count cycles-- they show the number of cycles used by the instruction, the screen position the instruction starts on, the corresponding color clock, the cycles that the instruction spans, the cycle immediately following the instruction, the corresponding color clock, the corresponding screen position, and the new position of the sprite. Normally I would notate this as shown below (omitting the starting values and the cycles spanned by the instruction), but I gave the additional numbers above to help illustrate what I think may be going on. STA RESP0,X ; +4 ; 23 ; 069 ; 001 ; 006 If you did STA RESP0,X a cycle earlier, you would get the results you expected: STA RESP0,X ; +4 ; 22 ; 066 ; -02 ; 003
  10. I doubt the changes I made to RevEng's kernel would be of much use to you-- these sorts of kernels are really just demos rather than useful general-purpose kernels, because they're too specific in what they do. But the same concept (changing one or more color registers mid-line) would be useful. I haven't read the thread about your game idea yet. After I do, I'll see if I can suggest anything that might be useful.
  11. This is just a rough first attempt. The timing's a bit off (the colors on the first visible line are lined up differently than on the rest of the lines), but other than that it works. Interesting effect is that there appear to be 15 or 16 shades of each color due to the way the colors overlap from one frame to the next. rainbowkernel2.asm rainbowbasic2.bas rainbowbasic2.bas.bin
  12. That is great news! (As you can tell, I'm not up to speed on DPC+ yet.)
  13. Can a DPC+ queue be pointed to RAM so the data can be modified from screen to screen, or do the queues have to point to ROM?
  14. The only Wizardry game I have is Wizardry 8, which I really like-- except the hard drive I'd installed it on crashed years ago, and I can't find the installation CD. I'm sure I still have it stuck away somewhere, but I wish they'd release a compendium of all the Wizardry games.
  15. I thought there was an old demo of a 48-bit "sprite" moving around the screen? I'm sure the code to that demo should be available somewhere-- I can't find it right now but IIRC it's called "Big Move" or something like that, by Eckhard Stolberg. Studying that code might give you some direction.
  16. As Ian Primus says, one of the address lines (A12) is used as a chip select-- it's wired so it always reads 1. That's why the cartridge address space is $1000-$1FFF. And on a 2K cartridge, A11 isn't used, giving addresses of either $1000-$17FF or $1800-$1FFF (i.e., the 2K is effectively "mirrored").
  17. I have a TIA spreadsheet I've been working on (off and on)-- simulating the logic gates, latches, etc., with a spreadsheet-- and I'll see if I can simulate strobing the RESxx registers immediately after strobing HMOVE on cycle 3 (i.e., right after strobing WSYNC). It may take a little while, though, so don't hold your breath!
  18. I don't know the specifics of why there's a 1-pixel difference, without examining the schematics to see if I can work that part out. But the general advice in the programming guide is not to change the HMxx registers within 24 cycles after strobing HMOVE. However, this isn't changing the HMxx registers, it's strobing a RESxx register after HMOVE, so it isn't exactly the same thing-- but the reason may be related in some way. I suspect that David Crane may have initially used an HMM1 value to move it 2 pixels to the left, then changed it to 3 pixels to the left after seeing that missile 1 was ending up 1 pixel to the right of where he wanted it-- unless he already knew that missile 1 would end up 1 pixel "off" due to the exact sequence in which he was strobing WSYNC, HMOVE, and RESM1 (which is possible, since he undoubtedly knew quite a bit about the TIA at the technical level).
  19. Strobing RESxx during HBLANK doesn't set a sprite's position to pixel 0, it sets it to pixel 2 for the missiles and the ball, and to pixel 3 for the players. The "Stella Programmer's Guide" does say that However, that is erroneous. If you want a technical explanation, remember that 1 machine cycle equals 3 color clocks, so depending on which machine cycle you strobe a RESxx register on, the best you can do is position a sprite at some interval of 3 color clocks-- that is, if you strobe it at cycle X and the sprite is positioned at clock Y, then strobing it at cycle X+1 will position the sprite at clock Y+3. Furthermore, the horizontal events (for lack of a better term) are timed by the "horizontal clocks," which run at 4 times the color clock rate; and due to the way the latches of the LFSR counters are driven by the horizontal clock 1 and horizontal clock 2 signals, triggering some event doesn't cause that event to occur until 4 clocks later. So if you strobe a RESxx register at machine cycle X-- which corresponds to color clock 3X-- the sprite's new position becomes 3X+4. For the players, the new position will actually be 3X+5, because they require an extra color clock before the TIA starts to draw them. So suppose you strobe RESM1 at machine cycle 23, which corresponds to color clock 69 (23 times 3). Missile 1 will be positioned at color clock 73 (69 plus 4), or pixel 5 (73 minus 68). If you strobe RESM1 a cycle earlier than that-- i.e., at cycle 22-- missile 1 will be at pixel 2 (5 minus 3). Strobing RESM1 at any other time during HBLANK has the same effect as strobing it at cycle 22-- missile 1 will be at pixel 2. The players will be 1 pixel to the right, or at pixel 3. Edit: I checked the Pitfall II code, and it strobes RESM1 right after strobing HMOVE: STA WSYNC STA HMOVE STA RESM1 When I tried that, it did position missile 1 at pixel 3 rather than at pixel 2. If I don't strobe HMOVE (i.e., STA WSYNC then STA RESM1), missile 1 is positioned at pixel 2 as expected. So strobing RESM1 right after HMOVE changes the positioning slightly.
  20. Silly rabbit, there's no such thing as a hot tub time machine, only video arcade time machines!
  21. This article says Since the legends claim that Jeffrey Dailey died before Peter Bukowski, this article implies that the legends about Jeffrey Dailey are just stories with no truth to them. It does seem interesting that Peter Bukowski's death seems to be fairly well substantiated, yet no such reports can be found about Jeffrey Dailey's death.
  22. I think you have the upper/lower descriptions reversed-- bank 0 is the lower bank and bank 1 is the upper bank, in that bank 0 has a lower address range than bank 1 in the ROM image. Of course, they both occupy the same memory space when they're swapped in, but for an 8K ROM bank 0 is assigned an ORG address of $1000 and a RORG address of $D000, whereas bank 1 is assigned an ORG address of $2000 and a RORG address of $F000. The ORG addresses are for compiling purposes, to keep the banks in separate but contiguous space within the ROM image (i.e., so the ROM image is 8K in size), and the RORG addresses determine the logical addresses that will be used within each bank. Thus, the ORG addresses could be $0000 for bank 0 and $1000 for bank 1, or $1000 and $2000, or $2000 and $3000, etc.-- any two 4K blocks of addresses that are contiguous to each other (the second one begins immediately after the first one ends). But for the standard bankswitching the RORG addresses for the banks must begin at $1000 or one of its "mirrors"-- $1000, $3000, $5000, $7000, $9000, $B000, $D000, or $F000-- since those are the addresses that will coincide with the 4K cartridge area in the memory space. As far as the graphics data, it depends on what type of graphics data you're talking about. Either the graphics data must be in the same bank as the display kernel (so the kernel can load the graphics as it's drawing the screen), or the graphics must be stored in RAM that's always accessible regardless of which bank is switched in (usually meaning in the zero-page RIOT RAM, or in the Superchip RAM if the Superchip option is being used). If the graphics data were not in the same bank as the kernel, the kernel would have to switch banks as the screen is being drawn so the data could be loaded, then switch back to the kernel's bank so the next instruction can be executed. Normally only the playfield data gets stored in RAM, so you should be able to put playfield data statements in either bank, and the data will be moved to RAM when a particular playfield statement is executed. But the player graphics data normally gets loaded directly from ROM, hence the player0 and player1 statements get their data compiled into the same bank as the kernel. If you want, you can create data tables for the players in the other bank, but then you'd need to copy the data to RAM and modify the player graphics pointers to point to the RAM so the kernel will read the data from there. As far as what happens when the banks are switched, anything that's been written to RAM, or to the TIA or RIOT registers, will stay put, but the 4K ROM area will be completely swapped-- so as you say, "all previous rom data is lost." This doesn't cause the display to crash because the "user code" is executed during the vertical blanking, so it doesn't matter whether the graphics data is still in the currently-selected bank or not. Then bank 1 gets switched in when it's time for the kernel to do its thing, and stays switched in until the kernel is done and turns control back over to the "user code." And batari Basic also handles the bank switching process for you, so your code can do a "goto" from one bank to the other, or "gosub" to the other bank and then "return" back to the first bank, without you having to worry about it much-- aside from the need to be aware that switching banks in a "goto" or "gosub" or "return" does eat up more machine cycles than doing a "goto" or "gosub" or "return" within the same bank.
  23. It was only mentioned briefly in passing in that thread. I don't know what they changed in IE10 to break this, but I hope they eventually post a fix for it.
  24. Yes, it happens in IE10 in Win8. It was mentioned in the Windows 8 thread.
  25. According to the sources I found, Jeff Dailey was 19, not 18. Peter Burkowski was 18. According to an article in Video Games magazine (October 1982, pp. 14-15), deputy coroner Mark Allen reported that scar tissue was found on Peter Burkowski's heart, and it was at least two weeks old. (http://home.hiwaay.n.../cvg/death.html) I take it the excitement and stress of playing Berzerk was too much for his already-weakened heart, leading to his heart attack. It could have happened doing almost anything-- for example, if he were reading a book and someone snuck up behind him and popped a paper bag to startle him as a joke. Another page (http://www.arcade-hi...e=detail&id=236) says that Alan McNeil-- the creator of Berzerk-- addressed these legends in Retro Gamer (Issue 47). I happen to have that issue, so I looked up the article ("The Making of... Berzerk," pp. 48-53). In a sidebar on page 53 captioned "Kill the Humanoid!" it says "But one player did die while playing the game. (Alan refutes reports that claim two died.) 'The unfortunate fellow was obese and had run upstairs to play the game,' Alan explains. 'The legend is he set a high score and died, but the owner of the arcade said he didn't finish the game-- he was out of breath from the moment he arrived until he dropped....'" It doesn't mention the name of the player, but I'm going to guess he was talking about Jeff Dailey, for the following reasons: (1) Peter Burkowski was said to be in good physical shape (that is, aside from having two-week-old scar tissue on his heart), which certainly doesn't fit the description of the player being "obese"; (2) Peter Burkowski reportedly died after playing Berzerk, not while playing it; and (3) the story about Jeff Dailey seems to imply he'd just gotten the high score, whereas the reports about Peter Burkowski say he put his initials on the high score screen twice but don't claim they were the two highest scores. Maybe you could get more information from Alan McNeil? Edit: I can't seem to find any solid information about Jeff Dailey, whereas the articles about Peter Burkowski seem more solid (because they mention the names of the arcade, arcade owner, deputy coroner, and a doctor)-- so maybe Alan McNeil was talking about Peter Burkowski? Except the article about him says he had just put a quarter into another game when he collapsed, plus he was said to be in good shape, not "obese," so...?
×
×
  • Create New...