Jump to content
IGNORED

Finished XB Compiler


senior_falcon

Recommended Posts

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:post-8393-0-73966700-1356550282_thumb.pngpost-8393-0-78683700-1356550212_thumb.png (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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

 

:)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by Kurt_Woloch
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by Kurt_Woloch
  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...