Kurt_Woloch Posted December 26, 2012 Share Posted December 26, 2012 I've now created a version of my SSGC Racer that does compile OK, taking out the unsupported instructions. I've adjusted the game speed to the higher speed of the compiled program, and it now looks much smoother than before. However, I'm getting some screen corruption at the start of the actual game. I don't know exactly at which point it occurs, but apparently the compiled and assembled version of the program overwrites some of the character set and color table at this point. Here's a screenshot of how it is and how it should be: (the first picture shows the game ending of the compiled version, and the second one shows the game start of the non-compiled version) I've attached a ZIP file with the files for the new version to this post. You can drop them into a DSK folder of Classic99 to play with. Sorry that I can't bring better news, and I'm not in a hurry. :-) SSGC_Compiled.zip Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 26, 2012 Author Share Posted December 26, 2012 Hi Kurt: In your program you have used DISPLAY USING. USING is not supported by the compiler at present. Quote Link to comment Share on other sites More sharing options...
Kurt_Woloch Posted December 26, 2012 Share Posted December 26, 2012 Hi Kurt: In your program you have used DISPLAY USING. USING is not supported by the compiler at present. Um... you're right. But I don't think this causes the graphics distortion. The only thing this causes are the "##:##" strings visible on the screen where there should actually be lap times. But it's a bit tricky to replace this because at that point I was displaying and formatting a number variable with 1/100 seconds, and this would have to be rewritten for integer arithmetics. Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted December 26, 2012 Share Posted December 26, 2012 Nope - no disk access. If this a future possibility? Not a request and I have no idea of the challenge that implementing something like this would take, but wow - it would rock big time with file access. BTW - I am loving really this compiler! Thanks for the effort. Quote Link to comment Share on other sites More sharing options...
Kurt_Woloch Posted December 27, 2012 Share Posted December 27, 2012 OK... I've now completed another version of my SSGCC racer. This should fix some glitches that turned up in the previous version. First I took out the unsupported "USING" clause. Then there was a glitch in the curve calculation which, due to the integer arithmetics, made it bend much less than it should have in slight curves. And then, to make it a bit more interesting, I changed the way the street behaves... now the car no longer moves left and right, instead the street scrolls left and right like in the arcade version of "Pole Position". Unfortunately, the compiled version now crashes before the race even starts... probably right after the display has been corrupted. Why it crashes is a mystery to me... anyway, after the crash, the program sits in a tight loop, which goes: > 0C28 020C li R12,>1b00 1B00 0C2C 1D00 sbo >0000 0C2E 045B b *R11 Unfortunately, R11 is filled with address 0C28, which makes it jump right to the beginning of the loop again. I've attached the new version to this post. SSGC-Compiled.zip Quote Link to comment Share on other sites More sharing options...
1980gamer Posted December 27, 2012 Share Posted December 27, 2012 I am really trying to test this out. I have always liked putting little programs together in XB but never liked the speed and poor collision detection. I put a simple SNAKESSSS game together, but every program I ever write MUST use random values. How can I add randomness to a program, if RND doesn't really work? 10 py=int(rnd*21)+2 20 px=int(rnd*29)+2 these lines are to place a prize in the random x,y position on the screen. Please help! Thanks, Gene Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted December 27, 2012 Share Posted December 27, 2012 I am really trying to test this out. I have always liked putting little programs together in XB but never liked the speed and poor collision detection. I put a simple SNAKESSSS game together, but every program I ever write MUST use random values. How can I add randomness to a program, if RND doesn't really work? 10 py=int(rnd*21)+2 20 px=int(rnd*29)+2 these lines are to place a prize in the random x,y position on the screen. Please help! Thanks, Gene What you're doing should be absolutely fine. From the documentation/manual: Because RND returns a number between 0 and 1, the INT of RND is always 0. Because of this, the following line of code won't work properly in the compiled code:.10 IF RND>.5 THEN 100 ELSE 200 There is a work around built into the compiler that deals with this problem. You have to multiply the RND by some number and then INT the result. Instead of the example above you should use: 10 IF INT(RND*2)=1 THEN 100 ELSE 200 This gives either a 0 or a 1 in both Extended BASIC and the compiled code. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 27, 2012 Author Share Posted December 27, 2012 I won't be able to do much more than glance at Kurt's program in the next couple of days. Because it was originally written for floating point math and arrays are used, it could be that something like this is happening: Original XB: X=ARRAY((.1*200)-10) In the XB program this would be element 10 in ARRAY Because the INT of .1 is 0 this would be element -10 in the compiled program. That will crash the compiled program. I didn't notice any nested arrays which is another way to crash the program. Take a look and see if anything like that might be happening. Also do a RES 1,3 to get around the line number bug. (That is fixed and an updated compiler will be posted shortly) You could try putting CALL KEY and DISPLAY AT between each line to let you execute one line at a time and see which line number was just executed. We'll get it sorted out somehow. Quote Link to comment Share on other sites More sharing options...
Kurt_Woloch Posted December 28, 2012 Share Posted December 28, 2012 (edited) OK... I investigated the error now for a good two hours, and this is what I found out... It seems like both the error and the "hang" are caused by the interrupt routine which gets "freed" after each executed call in the compiled code (should I call them "call"? How do you call each line of the compiled code which represents a call?). The interrupt routine at some point copies the value from address $837A into R12 and then does as many loop iterations as given in this address. Apparently, in that loop something gets written to the VDP because the workspace pointer is placed such that some register accesses increase the VDP pointer. Which statement in the compiled code actually causes this isn't quite clear. It probably happens somewhere in line 168 which is the sequence HCHAR, VCHAR, VCHAR, DELSPRITE, where the DELSPRITE is supposed to clear sprites 3, 4, 5 and 6 (the starting lights). After that comes the JOYST command which starts line 170. In my last test, an interrupt occured after the DELSPRITE, and that interrupt corrupts the VDP memory as seen on the screenshot. After that, the program continues to run for a while, but then eventually another interrupt sends the program counter into nirvana over some strange hoops. It jumps to $0078, then to $0270, then to $0c0c, then to $4020 where there are only zeroes which get "executed" until $6000, then the tight loop at $0c28 gets entered. However, I still don't know what error in my program would cause such a glitch to happen. I only know that it must be hidden somewhere in line 165 (from the HCHAR command on) or in line 168, in the following secuence: DATA HCHAR,NC6,NC6,NC16,NC58 DATA LET,NV17,NC59 L168 DATA HCHAR,NC26,NC6,NC39,NC40 DATA VCHAR,NC37,NC17,NC15,NC10 DATA VCHAR,NC37,NC32,NC15,NC10 DATA DELSPR,NBR,NC46,NBR,NC3,NBR,NC17,NBR,NC49$ which in the original code says: CALL HCHAR(1,1,112,352)::TTB3=7424 168 CALL HCHAR(12,1,120,32)::CALL VCHAR(13,5,96,9)::CALL VCHAR(13,28,96,9)::CALL DELSPRITE(#3,#4,#5,#6) 170 CALL JOYST(1,X,Y) Come to think about it, I think the DELSPRITE routine itself could be at fault. From what I saw in the interrupt routine, $837A actually seems to contain the number of the highest sprite that should be treated with auto-motion. At the fatal interrupt, this address is set to a ridiculously high value (I think $F7 or $FC or something like that). The routine then tries to process auto-motion for that many sprites and thus writes to an area which exceeds the sprite attribute table. In this case, the pattern descriptor table would be affected, but it seems like some bytes in the sprite motion table also get updated, causing the color table and whatever comes after it to be compromised as well. If what comes after it is a currently playing sound list, the sound routine gets confused as well. Now the delsprite routine, according to the source code of Runtime2, does write to $837A, updating it. Could it be that it's updating the number of sprites the wrong way so that it turns out incredibly high? Edited December 28, 2012 by Kurt_Woloch Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted December 28, 2012 Share Posted December 28, 2012 Still playing with this to get some ideas of speed etc. I threw together a small routine which runs fine in XB and does what it is supposed to, and it also assembles without errors - but when running the XB compiled program the dots don't move. Also when I try to BREAK the program it locks up with a buzz. Any ideas what the issue is? 100 DIM X(28),XD(28),XS(28),Y(28),YD(28),YS(28) 110 CALL CLEAR :: CALL SCREEN(2):: CALL CHAR(128,"000001"):: CALL COLOR(13,14,2) 120 CALL CHAR(129,"00000000000000FF"):: CALL CHAR(130,"FF"):: CALL CHAR(131,"0101010101010101"):: CALL CHAR(132,"8080808080808080") 130 CALL HCHAR(5,5,129,23):: CALL HCHAR(20,5,130,23):: CALL VCHAR(6,4,131,14):: CALL VCHAR(6,28,132,14) 140 FOR I=1 TO 28 150 X(I)=95 :: Y(I)=117 160 XD(I)=INT(RND*2)+1 :: YD(I)=INT(RND*2)+1 170 XS(I)=INT(RND*4)+1 :: YS(I)=INT(RND*4)+1 180 CALL SPRITE(#I,128,(RND*13)+3,X(I),Y(I)) 190 NEXT I 200 FOR I=1 TO 28 210 IF XD(I)=1 THEN 220 :: X(I)=X(I)-XS(I):: GOTO 230 220 X(I)=X(I)+XS(I) 230 IF YD(I)=1 THEN 240 :: Y(I)=Y(I)-YS(I):: GOTO 250 240 Y(I)=Y(I)+YS(I) 250 IF X(I)<40 THEN 260 :: GOTO 270 260 X(I)=41 :: XD(I)=1 :: GOTO 290 270 IF X(I)>150 THEN 280 :: GOTO 290 280 X(I)=149 :: XD(I)=2 290 IF Y(I)<26 THEN 300 :: GOTO 310 300 Y(I)=27 :: YD(I)=1 :: GOTO 330 310 IF Y(I)>208 THEN 320 :: GOTO 330 320 Y(I)=207 :: YD(I)=2 330 CALL LOCATE(#I,X(I),Y(I)):: CALL COLOR(#I,(RND*13)+3):: NEXT I :: GOTO 200 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 28, 2012 Author Share Posted December 28, 2012 You are running up against the line number bug that Rich G. discovered. Line numbers 235,238,239,240,254 cause problems, also those numbers with 256,512,768, etc added to them. This is fixed and will be posted in the next couple days once I thoroughly test the print and display routines. For now an easy fix for you to do is to RES 10,5 or other numbers that ensure that the largest line number is less than 235. This is caused by some of the additions for XB. There was no problem in the earlier BX compiler and it fell through the cracks because none of my test programs were more than 10 lines long! Your program should work fine after the RES. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 28, 2012 Author Share Posted December 28, 2012 OK... I investigated the error now for a good two hours, and this is what I found out... It seems like both the error and the "hang" are caused by the interrupt routine which gets "freed" after each executed call in the compiled code (should I call them "call"? How do you call each line of the compiled code which represents a call?). The interrupt routine at some point copies the value from address $837A into R12 and then does as many loop iterations as given in this address. Kurt, I will get out the E/A manual tonight to see if there's something I overlooked. The compiler uses two different interrupt routines. One is to scan for "CLEAR". That is a console routine located at >0020 which points to >04b2. The other is used for the VALIDATE option for ACCEPT. I don't think that either should cause any trouble. The sprite motion is controlled by an interrupt routine which must be where the trouble lies. There is a line of code in DELSPR that writes to >837A: AB @HXFF00,@>837A which decrements the byte at 837A. If HXFF00 is getting changed somehow then that would account for the trouble. Quote Link to comment Share on other sites More sharing options...
Bones-69 Posted December 28, 2012 Share Posted December 28, 2012 You are running up against the line number bug that Rich G. discovered. Thanks for your help. A res certainly solved the problem. XB compiled then run with Classic CPU throttling is certainly going to make for some fun times. Quote Link to comment Share on other sites More sharing options...
Kurt_Woloch Posted December 28, 2012 Share Posted December 28, 2012 (edited) OK... some more debugging... When the DELSPRITE routine gets entered to clear the starting lights as described above, $837A is already 00. Then the line cb R8,@>837a compares R8, which is #$0300, to this value, then the JLT command doesn't branch, and the instruction after that now reads "ab @>ecac,@>837a". Seems like HXFF00 got changed to @>ecac. Anyway, $837A does get decremented and is now $FF00 which causes the next interrupt to attempt auto-motion for 255 sprites. I've also investigated how $837A arrives at the value of 0 when DELSPRITE gets entered. It gets accessed a few times, but it always remains 0. I think the only code that accesses $837A before the offending DELSPRITE call is at SPINIT where $837A gets set to 0 from R1 which gets set to 112. Now... it isn't necessary for $837A to contain any other value than 0 as long as you don't need auto-motion, and my program doesn't need it until the actual game loop starts, which is after the offending DELSPRITE routine. Therefore it would be perfectly normal for $837A to be 0 at this point, yet DELSPRITE decrements it. In fact, I think just decrementing it doesn't really cut it. Let's assume you have 5 sprites on screen, and sprite #5 is moving. Now you call DELSPRITE to delete sprite #2 and #3. $837A should be set to 5 in order for the motion of sprite 5 to work. In your code, DELSPRITE would now decrement $837A to 4, so sprite #5 stops moving although it's still there and actually should still be moving. What I'm trying to say is that there should be a different solution to how $837A is handled on DELSPRITE. It actually should contain the number of the highest still moving sprite after execution of DELSPRITE. Decrementing it only works if the number in $837A corresponds to the highest sprite on screen, and the highest sprite has been deleted, but both is not the case here. Edited December 28, 2012 by Kurt_Woloch 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 28, 2012 Author Share Posted December 28, 2012 Kurt, thanks so much for tracking down this bug. It makes my job a whole lot easier when someone else can troubleshoot the code to find out where the problem lies. As so often happens, now that it is obvious, it is obvious that my DELSPR routine won't work properly if no sprites are in motion. I will rewrite this today, run tests and hopefully get these updates posted this weekend. Harry 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 28, 2012 Author Share Posted December 28, 2012 Kurt: Here is a quick fix that should get this working right away: Find the DELSPR routine in RUNTIME2. Two lines before DELSP2 is: JLT DELSP2 Change this line to be JNE DELSP2 I've written a better (and bulkier) handler for updating the maximum sprites in motion which will go into the update, but the above should at least work for you. Quote Link to comment Share on other sites More sharing options...
1980gamer Posted December 30, 2012 Share Posted December 30, 2012 WOW, this is so fast! I cannot believe how fast the TI can be! Great tip on using sound to delay game play! I am ready to put a few demos together now. Thanks, this is awesome! Quote Link to comment Share on other sites More sharing options...
unhuman Posted December 30, 2012 Share Posted December 30, 2012 Make sure you get the new version from this thread: http://www.atariage.com/forums/topic/206961-xb-compiler-v21/ Quote Link to comment Share on other sites More sharing options...
Kurt_Woloch Posted December 30, 2012 Share Posted December 30, 2012 Thank you for that proposal. I didn't get to include in into my program because when I saw it this morning, you had already released version 2.1, so I decided to skip this correction and use version 2.1 instead. Kurt: Here is a quick fix that should get this working right away: Find the DELSPR routine in RUNTIME2. Two lines before DELSP2 is: JLT DELSP2 Change this line to be JNE DELSP2 I've written a better (and bulkier) handler for updating the maximum sprites in motion which will go into the update, but the above should at least work for you. 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.