accousticguitar Posted October 11, 2008 Share Posted October 11, 2008 I've been working on a new Adventure hack, and I've run into a problem. The portals for the white and black castles won't allow the square to enter. Strangely enough, they will allow a dragon to enter. It will disappear into the castle if it hits the portal. What could I be doing wrong? I changed the EntryRoomOffsets to the new room number for the entry room inside the castle, but it just doesn't work. It doesn't seem to matter what number I put there, it won't let me in. Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 11, 2008 Share Posted October 11, 2008 What happens when you try to enter? Does it attempt to switch to the new screen? Does the new screen have an opening on the bottom to allow the player to pass through? Dragons are exempt from playfield collision, so that would explain why they could pass through if the playfield is what's obstructing the path. Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 11, 2008 Author Share Posted October 11, 2008 It does not attempt to switch to the new screen. The square just bounces off the portal like it is running into a wall. I did make sure that the new screen had an opening in the bottom, just in case, but it didn't make a difference. Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 11, 2008 Share Posted October 11, 2008 (edited) Hmm. It sounds like a problem with the portcullis collision routines. Can you drop items into the portcullis? Check various ones. If you added objects, like more portcullis' or keys, that could have thrown off your numbers or something. Try looking at the Portals_2 through Portals_4 routines and see what they pull references from. From what can see, it might think the player is on another screen, or maybe your portcullis states are messed up. Also, are there any other problems that have surfaced at the same time as this bug? Heh, watch Nukey Shay pop out of nowhere and know exactly what's wrong. Edited October 11, 2008 by EarthQuake Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 11, 2008 Author Share Posted October 11, 2008 I am now getting an "origins reverse indexed" error when I try to assemble it, but I don't think it's related. I've been adding rooms and I always have trouble when I try to do that. I have not added any portals or objects to the game. Items do drop into the portcullis when I drop them and they are touching it. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 11, 2008 Share Posted October 11, 2008 (edited) Question: Are you using the missile as the player? If so, you need to update the collision registers used in the PBCollision routine. A hit MUST register before the player can enter. Other objects use a different routine. CXM0P ($30) = collisions between missile0 and the players (bit7=player1, bit6=player0). Bit on = hit. CXM1P ($31) = collisions between missile1 and the players (bit7=player0, bit6=player1). Bit on = hit. Note the reversed order between them. ;if you are using missile0... PBCollision_2: LDA CXM0P;3 Get player00-m0 collision AND #$40;2 RTS;6 PBCollision_3: LDA CXM0P;3 Get player01-m0 collision AND #$80;2 RTS;6 ;if you are using missile1... PBCollision_2: LDA CXM1P;3 Get player00-m1 collision AND #$80;2 RTS;6 PBCollision_3: LDA CXM1P;3 Get player01-m1 collision AND #$40;2 RTS;6 Edited October 11, 2008 by Nukey Shay Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 11, 2008 Author Share Posted October 11, 2008 Nope, nothing that fancy. The weird thing is I can go into the yellow castle just fine, but not the black or white ones. I started out this hack by taking the Adventure Country hack that I posted here but I switched over to a fresh 8k Adventure format so I could get rid of the room data crossing over page boundaries (I'm still having trouble getting it to assemble when I put in ORGs and RORGs). Since it won't assemble now anyway I might as well go back to the original hack I was doing. At least I could get into the castles. I thought I had that ORG RORG stuff figured out, but I guess not. Oh well, pages crossing boundaries isn't that big of a deal. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 11, 2008 Share Posted October 11, 2008 The only other thing that I can think of (without seeing actual code) is that the values provided in CastleRoomOffsets doesn't match the first byte in PortInfo1, 2, and 3. These must be the same (watch out for missing "$" on hex values). Not EntryRoomOffsets...these are the rooms you get sent to). Also, keys and gates must run consecutively in memory. And managing ORG $xx00's is not so difficult...just only put a maximum of 256 bytes between them. If you go over that, Dasm will report it (so grab a full bitmap and move it someplace else). Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 11, 2008 Share Posted October 11, 2008 (edited) A good habit to start doing is to change very little at a time between revisions of your code. Playtest after each couple of lines you add/change so you know exactly what causes a problem if one should arise. In fact, keep a copy of each major revision so if a problem crops up, you can revert back to your last known working state. It has saved me A LOT of time. Right now I have a folder with my last 14 major revisions, and fortunately they saved me around revision #13 when I couldn't figure out why I was starting to get a black screen.) Oh, and ORG and RORG tags make data tables so much easier to organize without crossing page boundaries. You can place 12 screen bitmaps on a page with 4 bytes left over. Making sure you don't cross these boundaries is what prevents the playfield from having skewed pixels in-game (something I saw a few times in your Adventure Country hack). Edited October 11, 2008 by EarthQuake Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 11, 2008 Author Share Posted October 11, 2008 A good habit to start doing is to change very little at a time between revisions of your code. Playtest after each couple of lines you add/change so you know exactly what causes a problem if one should arise. I am definitely going to start doing that. Oh, and ORG and RORG tags make data tables so much easier to organize without crossing page boundaries. You can place 12 screen bitmaps on a page with 4 bytes left over. Making sure you don't cross these boundaries is what prevents the playfield from having skewed pixels in-game (something I saw a few times in your Adventure Country hack). I was able to make them work in the Dragon's Lair hack of Missadventure Revised, but I can't seem to get them to work in the Adventure Country hack. When I put the ORGs and RORGs in it comes up with the "origins reverse indexed" error. I'm going to have to ignore it for now I guess. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 11, 2008 Share Posted October 11, 2008 (edited) That error is usually attributed to a specified address that is lower than the address that the previous ORG had (i.e. trying to go in reverse). Search for ORG from top-to-bottom and make sure that they are sequential. Dasm will tell you what ORG did it right above the error Example: I stuck an ORG of $1B00 below a byte that had an ORG of $1BFF in Raiders. Here's what Dasm told me: DASM V2.20.10, Macro Assembler ©1988-2004segment: INITIAL CODE SEGMENT 1b00 eqm vs current org: 1c00 Raiders.asm (1895): error: Origin Reverse-indexed. Aborting assembly You can also avoid that problem by using ALIGN 256 instead. I use ORG's, but you don't have to follow my methods. The goal is just to keep bitmap info off page breaks so that no glitching occurs. Either method gets you there. Edited October 11, 2008 by Nukey Shay Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 12, 2008 Author Share Posted October 12, 2008 Does that mean I would delete the ORGs and RORGs and replace them all with ALIGN 256? Or do I perhaps use ALIGN 256 just once with no ORGs and RORGs? At any rate, I'm ready to try it since I'm not having much luck with ORGs and RORGs. Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 12, 2008 Share Posted October 12, 2008 (edited) What Nukey was trying to say was that the error you got is because one or more of your ORG/RORG tags has a value that is higher than the ORG/RORG tags that follow it. ORG tags are much better because you can see exactly how it's organized and how many bytes each page has. Here are how the tags are in my code: 2600 constants here... Game variables here... ORG $1000 RORG $D000 Code for first bank here... ORG $10E4 <- These might change depending on RORG $D0E4 <- how much space your code takes up. 28 bytes of data tables can go here... Again, this amount of free space might change. ORG $1100 RORG $D100 256 bytes of data tables can go here... ORG $1200 RORG $D200 You can put more data tables... ORG $1300 RORG $D300 ...between each of these tags. ORG $1400 RORG $D400 You can put 256 bytes of data on each page. ORG $1500 RORG $D500 ORG $1600 RORG $D600 ORG $1700 RORG $D700 ORG $1800 RORG $D800 ORG $1900 RORG $D900 ORG $1A00 RORG $DA00 ORG $1B00 RORG $DB00 ORG $1C00 RORG $DC00 ORG $1D00 RORG $DD00 ORG $1E00 RORG $DE00 ORG $1F00 RORG $DF00 248 bytes of data tables can go here... ORG $1FF8 RORG $DFF8 6502 vectors are here... ORG $2000 RORG $F000 Code for second bank here... ORG $27FB <- Again, the values used here depend RORG $F7FB <- on how much space the code takes up. And because my code almost ends up taking an additional page, I'm left with 5 bytes here. ($2800 minus $27FB equals 5) ORG $2800 RORG $F800 And use tags here just like I did in the first bank. ORG $2FF8 <- Leave unchanged. RORG $FFF8 Remember, if you try to squeeze too much data between org tags, it will complain about it. That is it's purpose, to tell you if your data crosses pages. Always count up the bytes in your data and separate your tables so they fit between the tags. Sometimes it's like a puzzle, but if you're using the 8K source, it will be easy to find places for your table. One note about the tags, the Room Data Table is larger than 256 bytes. This means you have to leave out an ORG/RORG tag so you have a "page" of 512 bytes. I would suggest putting the Room Data Table at the very end of your source file. Remember that you don't need ORG/RORG tags in every section. They just help you keep track of how much ROM space you're using. I didn't miss anything, did I Nukey? Edited October 12, 2008 by EarthQuake Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 12, 2008 Share Posted October 12, 2008 (edited) You got it right, but that's not what he asked Replace -almost- all occurances of ORG/RORG with ALIGN 256 (keep at least 1 space in front of the word so Dasm won't mistake it for a label)...you could just comment them out or delete them... ex: ; ORG $1F00 ; RORG $DF00 ALIGN 256 Keep the ORG/RORG at the start of each bank (so Dasm is given an intro address to assemble to), and the end of each bank (so that the reset/interrupt vectors stay at $xFFC-$xFFF). $xFF8-$xFFB remain unusable in an F8 binary. You still need to be careful about adding more than 256 bytes between them. If a section contains more than that, Dasm won't report an error. If/when the next ALIGN 256 command is reached, Dasm will just skip over uneven addresses until it reaches the next page break at $xx00 (potentially wasting up to 255 bytes of ROM). That is why I prefer using ORG's You don't need to worry so much about Adventure, because you can just count the number of screen bitmaps you place between them. 256 divided by 21 bytes per screen = 12 screens with 4 bytes left over. Edited October 12, 2008 by Nukey Shay Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 12, 2008 Author Share Posted October 12, 2008 (edited) Thanks for the help guys. I think I've narrowed the problem down. I commented out some of the ORGs and RORGs then tried assembling it and found that the problem lies with 3 different ones. 1C00, 1D00, and 2CDE. I changed some of the sprite graphics that lie between 1C00 and 1D00 so that may be part of the problem. The 2CDE tag is the one before the room data tables which are larger than they used to be (which may be another part of the problem). I always assumed the tags went something like this with an ORG RORG before the data: ORG RORG 256 bytes of data But it seems like you are saying you need an ORG RORG before and after the 256 bytes of data which would look more like this: ORG RORG 256 bytes of data ORG RORG I haven't tried the ALIGN 256 yet. I'd hate to waste all that extra space if there's a chance I can figure out this ORG RORG stuff. Edit: Oh yeah, one more dumb question. How do you count bytes so that you know whether or not you are over the 256 bytes (like with the sprite graphics)? Edited October 12, 2008 by accousticguitar Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 12, 2008 Share Posted October 12, 2008 You don't have to if you are using ORG to seperate pages. That's why I like it. If you try placing 257 bytes between (for example) an ORG $1D00 and ORG $1E00, Dasm will complain...printing this right on the screen: DASM V2.20.10, Macro Assembler ©1988-2004segment: INITIAL CODE SEGMENT 1E00 vs current org: 1E01 filename.asm (xxxx): error: Origin Reverse-indexed. Aborting assembly "Initial code segment" is where it tried to ORG. "Vs. current org" is the current address that it's at (it spilled over 1 byte because I tried putting 257 bytes between them). "filename.asm" is the name of the assembly, and "(xxxx)" would print a number...the line number in the assembly file that the error occurs on (useful if you are using a text editor that shows your current line #). I dunno an efficient way of counting bytes between ALIGN's (other than manually looking at them). Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 12, 2008 Share Posted October 12, 2008 BTW an ending ORG/RORG (by itself) means nothing unless it's followed by at least one byte, value, opcode, or whatever. It's just a setting for Dasm to use when placing data in a file. So if you had more than 256 bytes between pages in one area, Dasm might not complain at all. Like this: Ex... ORG $1E00 ;257 or more bytes follow... ORG $1F00 ;nothing here ;vector stuff at the end ORG $1FF8 .word 0,0,START,0 The ORG at $1F00 didn't catch the problem because Dasm didn't try placing anything there. It wouldn't notice there's a problem until it spills over $1FF8 (because that's where the next set of data actually exists in this example). Also, you can use ORG to fill a block of memory if you want. Unreferenced areas will automatically get filled with the byte $FF, but you can change it to whatever you want. This fills leftover memory before $1F00 to zero... Ex... ORG $1F00,0 About RORG... You might be wondering why these are required. The is due to the 6507's limitations. All ROM must be assembled to odd-numbered 4k blocks of memory. If you tried just using ORG $1000 for the first block and ORG $3000 for the second, Dasm would assume that another 4k block exists at $2000 (and it will happily fill 4k of $FF's between them)...generating a 12k binary. That's where RORG comes in and corrects things. You can ORG to $1000 and $2000 (avoiding the "assumed" block problem), and RORG to odd-numbered blocks to keep the 2600 happy. Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 12, 2008 Share Posted October 12, 2008 (edited) Counting bytes... Although Nukey is correct in that you don't have to count bytes, because DASM tells you which ORG tag is being "overflowed" and by how many bytes, it's always helpful to know anyways. Tables are series of bytes that routines in your code can easily sift through. Here are some examples: Simple 3-byte table... .byte $00, $00, $00 Dragon difficulty table at 6 bytes... DragonDiff: .byte $D0,$E8 ; Level 1 (Position B, Position A) .byte $F0,$F6 ; Level 2 (Position B, Position A) .byte $F0,$F6 ; Level 3 (Position B, Position A) Part of the object data table at 24 bytes... YellowPortcullisData: .word PortcullisInfo1, YellowPortcullisR, PortcullisStates .byte $00,$00 WhitePortcullisData: .word PortcullisInfo2, WhitePortcullisR, PortcullisStates .byte $00,$00 BlackPortcullisData: .word PortcullisInfo3, BlackPortcullisR, PortcullisStates .byte $00,$00 Each value after a .byte is one byte, and each value after a .word is two bytes. It helps to add a little comment at the end of each table telling how many bytes it uses (although you gotta remember to change this if you modify the table). And also, this is totally unrelated, but it's a cool addition when your hack is finished and you have some extra bytes left. You can create a table where each value corresponds to an ascii character, so when your hack is viewed in a hex editor with text viewing, you can have a secret message or author information! .byte $45,$41,$52,$54,$48,$51,$55,$41,$4B,$45 Edited October 12, 2008 by EarthQuake Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 12, 2008 Author Share Posted October 12, 2008 Yay, I got it to work by counting bytes! (Where is the emoticon for clapping hands in childish glee?) I was way over in a couple places. Thanks for all the help! I do have one more question. How many bytes are the room data tables? I'm guessing 8 bytes per room. Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 12, 2008 Share Posted October 12, 2008 In RoomDataTable? 8 per room in the 8k assembly, 9 per room in the original game (because it included an alternate color value for the B&W switch). This table most likely spill over (and it's nothing serious to the console when it does). The only way to avoid it would be to never have more than 32 total screens. Most of Adventure's tables are not time-critical...just the bitmaps of screens and objects. Of course, it's always good practice to save cycles wherever possible (so that future additions have extra time). Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 12, 2008 Author Share Posted October 12, 2008 I guess I won't worry about it then. Thanks again for all the help! Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted October 20, 2008 Share Posted October 20, 2008 Something that would save a lot of space in the game is to edit that huge RoomDataTable into seperate tables. One for the LSB of the first variable, one for the MSB, one for the color, etc. Then it's no longer necessary to do a subroutine to fetch a base address and dink around with Y offsets/indirect loads (the room number itself becomes the offset for each specific table). The same could be done with the Objects table (the object number itself becomes the offset for reading). I might make an updated version of the 4k and 8k optimized code, as this simple change could lead to a lot of spare time before a screen call is needed (maybe even get it down to 2 frames - improving performance). Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 21, 2008 Share Posted October 21, 2008 So in essence you break up the room data table into 8 or 9 smaller tables that should give a boost in performance? While it may be nice having faster execution, it would really make things harder to modify. What sort of speed improvements are we talking about? Quote Link to comment Share on other sites More sharing options...
accousticguitar Posted October 21, 2008 Author Share Posted October 21, 2008 While it may be nice having faster execution, it would really make things harder to modify. I have trouble as it is. Quote Link to comment Share on other sites More sharing options...
EarthQuake Posted October 21, 2008 Share Posted October 21, 2008 (edited) By the way I figured out one cause for the portcullis' not to work. If you rearranged things in the main game loop to optimize it, calling the portcullis routine too late in the loop will recreate the exact problem you had. In my case, I placed it right before the main game loop returns to the beginning, right after the last PrintDisplay. Atwwong! I see you buddy! Edited October 21, 2008 by EarthQuake Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.