Jump to content
IGNORED

ABASIC for Geneve 9640 - MDOS Development Thread


9640News

Recommended Posts

Pulled over from another thread:

I believe that either ABASIC or the OS is incorrectly calculating the sprite number or VRAM address of the sprite table. I can get the distance of sprite #1 by checking sprite #2.

 

100 CALL SPRITE(#1,65,2,50,50,0,5) !create sprite #1 at 50,50 with motion along one axis

110 CALL DISTANCE(#1,50,50,R) !R will not change

120 CALL DISTANCE(#2,50,50,F) !F will change even though there is no sprite #2 defined or in motion

130 DISPLAY AT(24,1):R;F

140 GOTO 110

When F reaches 32,400 the interpreter pauses twice, most likely a vram and/or calculation overflow. 

 

@mizapf I suspect the issue is in one or more video XOP routines. If you are able to isolate via a TIC test program, that would be most helpful.  Also, the pause that I reference in the above test stops all auto-motion, which leads me to believe there is a second error in the OS video XOP support.  The ABASIC routines pass values to and from the video XOPs.

  • Like 1
Link to comment
Share on other sites

OK, here is the TIC program. I implemented both, the first BASIC program and this one here (DIST1, DIST2).

 

DIST1_C:
#include <stdio_h>
#include <video_h>

int f;
int g;

main() {
   vidmode(3);
   putchar(12);
   sprite(1,65,2,50,50);
   sprite(2,67,7,30,30);
   spmotn(1,5,0);
   spmotn(2,5,0);
   while (1) {
      f = spdist(1,2);
      g = spdrc(2,1,1);
      locate(24,5);
      printf("%d %d    ", f, g);
   }
}

 

DIST2_C:

#include <stdio_h>
#include <video_h>

int r;
int f;

main() {
   vidmode(3);
   putchar(12);
   sprite(1,65,2,50,50);
   spmotn(1,0,5);
   while (1) {
      r = spdrc(1,50,50);
      f = spdrc(1,50,50);
      locate(24,1);
      printf("%d %d    ", r, f);
   }
}

 

sprdist.dsk

  • Like 2
Link to comment
Share on other sites

This "second" error shows up as a delay or lockup during the distance computation. The distance calculation code from the Geneve OS is in the spoiler.

 

At the very end of the routine, the larger of the differences between the two rows(R1,R2) and two columns(C1,C2) is squared until it reaches a value that approximates a^2 + b^2. 

 

R5 is the counter for the "square root" value of c, i.e, the hypotenuse.  In the second comparison, I am thinking the JLT should be JL?  I'm not sure if I am reading the logic and math correctly...  Nearly all of the comments are mine.

Spoiler

[spoiler]

===============================
;
; compute distance. 
;
; INPUT: 
; R0=sprite #1 row
; R1=sprite #1 col
; R2=fixed Row or Sprite#2 row
; R3=fixed Col or Sprite#2 col
;
; OUTPUTS: 
;       MOV     @X900ST,@4(R13)           actual distance, caller R2
;       MOV     @X900ST+8,@6(R13)         squared distance (XB), caller R3
;

X922D1  S       R0,R2
        ABS     R2
        MOV     R2,R6                   * R6 ROW DIFF.

        S       R1,R3
        ABS     R3
        MOV     R3,R7                   * R7 COL DIFF.

;r2=row dif; r3=col dif

;if it works for dot, then it should work for sprite. Which seems
;to point to sprite#2 attribute problem.


; a=r2
; b=r3
; therefore, r2*r2 yields a^2 in R3
; r1*r1 yields b^2 in R2
;
; (MPY is 32-bit output RxRy)

        MOV     R2,R1
        MOV     R3,R2
        MPY     R2,R2    r3=a^2
        MPY     R1,R1    r2=b^2

;---
; Set R5 to either the row or col difference, whichever is higher
; But why...
;
        MOV     R6,R5    R5=row diff
        C       R6,R7    compare row diff to col diff 
        JGT     X922D2    row diff higher, skip
        MOV     R7,R5   row diff lower, so R5=col diff

;
X922D2  A       R3,R2    R2= c^2 = a^2+b^2        * R2 BASE
        JNC     X922D3   carry?
        LI      R8,1     yes            * MSB
        JMP     X922D4

X922D3  CLR     R8       ;no carry

X922D4  MOV     R2,R6        ;R6= c^2
;
; is value above 32767? If not, skip. Otherwise, set to 32767.
;
; why are we forcing the value to 32767? Is this simply a limit for the interpreter and XB compat?
;
        CI      R6,32767    ;check c^2 
        JLE     X922D6

        LI      R6,32767    ;c^2 max

X922D6  MOV     R6,@X900ST+8    ;save value. This is returned via XOP as squared distance.
        MOV     R5,@X900ST+2    ;either the row or col diff (whichever was higher)
;
;this routine is comparing the square of each R5 value until
;it is reached. Alternative to a square root. This is probably where the
;1-2 second pause and/or lockup occurs during the CALL DISTANCE.

X922D5  MOV     @X900ST+2,R5
        MOV     R5,@X900ST    ;actual distance returned to caller
        INC     R5
        MOV     R5,@X900ST+2    ;
        MPY     R5,R5        

; If R8=0 and R5=0...
        C       R5,R8        ;checks previous carry bit (R8)
        JLT     X922D5        ; this is probably OK

        C       R6,R2        ;calculated value < R2 (a^2 + b^2)=c^2 ?
        JLT     X922D5        ;yes, do another iteration. But should this really be JL since we expect the value could exceed 32767? 

        RT

[/spoiler]

 

Link to comment
Share on other sites

37 minutes ago, mizapf said:

OK, here is the TIC program. I implemented both, the first BASIC program and this one here (DIST1, DIST2).

Ah, those DIST1 numbers look good. 20^2 + 20^2 = 800.  In DIST2, I am not seeing the 1-2 second pause exhibited by the ABASIC version. Interesting.  I would expect TIC to use the XOPs but who knows, Clint may have written his own code before he fixed many of the video routines, or the bug is in ABASIC. 

  • Like 1
Link to comment
Share on other sites

Well, if the BASIC interpreter trips over the error, the program in TIC won't be affected anyway, as it is running on the bare metal. I would not expect the XOP routine doing something like "pausing". Machine language routines that seemingly "pause" do something vicious instead.

  • Like 2
Link to comment
Share on other sites

1 hour ago, mizapf said:

Well, if the BASIC interpreter trips over the error, the program in TIC won't be affected anyway, as it is running on the bare metal. I would not expect the XOP routine doing something like "pausing". Machine language routines that seemingly "pause" do something vicious instead.

My assumption (see the hidden contents in my earlier post) was (is) that the distance calculation that calculates the "square root" is getting stuck due to the use of JLT.  I'll try to test my assumption tonight.      

  • Like 1
Link to comment
Share on other sites

Changing the test from JLT to JL resolved the calculation issue.  The problem is that the square root "substitute" was checking a signed number when it should have been testing for an unsigned number.  The delays and lockups are gone, and the numbers now seem to match the TIC versions.  File: L6.VX1D23S, label X922D5, final two lines before the RT. 

 

        C       R6,R2        ;calculated value < R2 (a^2 + b^2)=c^2 ?
        JL     X922D5        ;yes, do another iteration

  • Like 4
Link to comment
Share on other sites

The CALL DISTANCE routine modifies the parsed sprite #number from base 1 to base 0.  I removed the two "DEC" statements from the DISTANCE parse, and together with the above fix, DISTANCE is now identifying the correct sprites for both sprite-to-sprite and sprite-to-point calculations.  A quick review of other sprite-related routines did not uncover any others that changed the sprite base to 0.  ABASIC file 165.SPRITES  labels DST01 and DST05 contain the offending statements.

 

I think there may be some incorrect auto-motion code and/or reporting for when sprites leave the visible space.  CALL POSITION reports the row value jumping from 192 to 230'ish, then increments to 255 before re-appearing on the top row; XB seems to do the same thing, so this might be OK.  The sprite-to-sprite (or point) calculations seem slightly different (XB vs. ABASIC) when the sprite is off the screen.  Someone with better knowledge of sprites would need to right a better test program. 

  • Like 4
  • Haha 1
Link to comment
Share on other sites

This morning I remembered where I had stashed a letter Jim Uzzell sent me long ago (1996!) concerning bugs in ABASIC and/or MDOS.  It seems both DISTANCE and COINC had bugs back then. I seem to recall a disk with some test programs, maybe even a copy of what he sent Clint. I'll look through my files later this week.  

 

@hloberg thank you for testing the fixes.  If you run into issues with COINC, try the test version I sent you. Maybe we got a 2-for-1 deal this time around.

 

image.thumb.png.e1635c3542e48af732d617794efa04c9.png

  • Like 3
Link to comment
Share on other sites

As for me, I did not notice the bugs because I never wrote an ABASIC program, apart from some few lines for testing. At the time that I got the Geneve, I already had 6 years of assembly language, and then went on with c99 and then TIC, and never really returned to BASIC (despite all these nice developments that we have until today).

  • Like 2
Link to comment
Share on other sites

34 minutes ago, InsaneMultitasker said:

This morning I remembered where I had stashed a letter Jim Uzzell sent me long ago (1996!) concerning bugs in ABASIC and/or MDOS.  It seems both DISTANCE and COINC had bugs back then. I seem to recall a disk with some test programs, maybe even a copy of what he sent Clint. I'll look through my files later this week.  

 

@hloberg thank you for testing the fixes.  If you run into issues with COINC, try the test version I sent you. Maybe we got a 2-for-1 deal this time around.

 

image.thumb.png.e1635c3542e48af732d617794efa04c9.png

i'll check COINC too and compare with XB.

  • Like 4
Link to comment
Share on other sites

On 3/6/2023 at 10:02 AM, hloberg said:

i'll check COINC too and compare with XB.

Thanks. When you test the routines, try using both the minimum and maximum sprite numbers to confirm the limits are working properly.  I was able to use sprite #0 which suggests a sprite number boundary condition that could be corrected.  And since @mizapf's test was successful with TIC - which also uses the XOPS - I am fairly confident the issue does not involve the OS. 

 

Update: ABASIC's CALL SPRITE requires a sprite value of #0 to #31.  (File: 165.SPRITES routine GETSP1).  The ABASIC manual states this should be 1-32.   Recommend we document this inconsistency and update the manual. I checked the following commands: sprite, pattern, motion, delsprite, distance, coinc, position, locate, color.  They all seem to use GETSP1 and act on sprite #0-31.

image.thumb.png.a5f798819130e6937ca5ccec0c66b9d8.png

 

There is code that refers to mousemode using sprite #0; in the manual, the MOUSE section states that sprite #0 should not be used when the mousemode is active.  It may be a good idea to call this out in the SPRITE command when the manual is updated.  Some commands, like DELSPRITE, do not touch sprite #0 if the mouse is ON. 

 

  • Like 2
Link to comment
Share on other sites

I found a couple typos in the manual anyway so i'll add this to the list of changes. also change the tome version to 4.08b from 4.09. listing it as 4.09 like I did was confusing.

and final CFA.

btw, this formula [DIST=((ABS(X1-X2)^2)+(ABS(Y1-Y2)^2))] matches CALL DISTANCE exactly.

here's a program from the TI99 that test the formula and compares with CALL DISTANCE.

90 CALL CLEAR
100 CALL SPRITE(#1,65,2,50,50,1,1)
105 CALL SPRITE(#2,75,2,60,60,_1,-1)
110 CALL DISTANCE(#1,#2,R)
120 CALL POSITION(#1,Y1,X1)
122 CALL POSITION(#2,Y2,X2)
127 D=((ABS(X1-X2)^2)+(ABS(Y1-Y2)^2))
130 DISPLAY AT(24,1):R
135 DISPLAY AT(23,1):D
140 GOTO 110

 

  • Like 2
Link to comment
Share on other sites

This simple program in XB moves a sprite down to the bottom of the screen.  XB doesn't complain when the dot row exceeds 192 and the sprite seems to re-appear and 'blink' with a dot row between 193 to 230'ish. And, POSITION reports varying values as the LOCATE dot row increases. 

 

ABASIC simply reports a dot row range error beyond 192.  For compatibility, I wonder if we need to ease up on the dot row. 

 

I am not sure what to make of the sprite row oddities between rows 193-255.


50 CALL CLEAR
60 R=150
100 CALL SPRITE(#1,65,2,50,50,0,0)
110 C=50
115 R=R+1 :: CALL LOCATE(#1,R,C)
116 IF R=256 THEN R=150
117 CALL POSITION(#1,R1,C1)
120 DISPLAY AT(22,1):R;C;R1;C1
130 GOTO 110

 

Here's a slightly different version. I printed the values for LOCATE and POSITION to "CLIP" via Classic99. 


 

Spoiler


10 OPEN #1:"CLIP",OUTPUT
50 CALL CLEAR
60 R=150
100 CALL SPRITE(#1,65,2,50,50,0,0)
110 C=50
112 C=50
115 R=R+1 :: CALL LOCATE(#1,R,C)
116 IF R=256 THEN CLOSE #1 :: END
117 CALL POSITION(#1,R1,C1)
119 PRINT #1:R;R1
120 DISPLAY AT(22,1):R;C;R1;C1
130 GOTO 110


---------------------------------
 LOC  POS
 190  190
 191  191
 192  192
 193  193
 194  194
 
 195  227
 196  228
 197  229
 198  230
 199  231
 200  232
 201  233
 202  170
 203  235
 204  172
 205  237
 206  238
 207  239
 208  240
 209  241
 210  242
 211  243
 212  244

 213  181
 214  246
 215  183
 216  248
 217  185
 218  250
 219  187
 220  252
 221  253
 222  190
 223  255
 224  256

 225  1
 226  194
-----------
 227  227
 228  228
 229  229
 230  230
 231  231
 232  232
 233  233
 234  234
 235  235
 236  236
 237  237
 238  238
 239  239
 240  240
 241  241
 242  242
 243  243
 244  244
 245  245
 246  246
 247  247
 248  248
 249  249
 250  250
 251  251
 252  252
 253  253
 254  254
 255  255
------------

 

  • Like 2
Link to comment
Share on other sites

The hidden content lists the values for position and locate between rows 192 and 255.  I thought about pausing (versus up/down) and then decided it would be easier to just review the values after capturing them once.  (I preferred the old spoiler tag and visibility - it is too easy to overlook the new barely-visible tag for the hidden content)

  • Like 2
Link to comment
Share on other sites

I tracked down a 1985-era bug.  For statements with a line number argument (GOTO, GOSUB, USING, etc), if the line number was a multiple of 173 or 227, the crunch routine would append an unrelated token immediately after the line number.  For example, GOSUB 173 would become "GOSUB 173RETURN"

 

@9640News I will pass the source for this and the sprite fixes to you this weekend. 

  • Like 2
Link to comment
Share on other sites

3 minutes ago, mizapf said:

Interestingly, it does not fully parse the line, so a

100 GOTO 100 ASDFGHJKL

 

does not raise an error.

 

BTW, when I press CTRL-C, I get a character (â) on the command line.

May I ask you to confirm the version number of the ABASIC that you are using?  Version 4.08 included a few fixes for CTRL-C handling in both run-time and immediate modes.  

 

V4.08  1 February 2022
       - Updated reference manual, very nice work by @hloberg!
       - Corrected RUN command to execute from within a program, without
         requiring the optional line number
       - Corrected RUN command, able to load programs from the current
         working directory e.g., RUN "FILE" and with MDOS device
         identification e.g., RUN "H:\GAMES\LOADER" in immediate and
         program modes.
       - CTRL-C now works when a program is loaded and auto-started
       - CTRL-C artifact is no longer printed when key is pressed

       - RANDOMIZE now generates different sequences at startup, when no
         seed is specified. System clock is used to set RAND16. A big
         thank you to Lee Stewart for reviewing the ABASIC random code!
       - Noted issues and potential gotchas based on testing

  • Like 3
Link to comment
Share on other sites

14 hours ago, mizapf said:

Interestingly, it does not fully parse the line, so a

100 GOTO 100 ASDFGHJKL

 

does not raise an error.

I tried a similar line in Extended BASIC and it too ran without an error.  Below is what "100 GOTO 100 ASDFGHIJKL" looks like in a saved program file. I don't see a token between the GOTO's line number and the string of characters so I guess the interpreter never gets past the GOTO 100 and therefore doesn't care what you typed.  Prescan might have trouble if you typed a recognized keyword instead of random characters.

 

00000000 00 03 37 C7 37 C4 37 D7 00 64 37 C9 0F 86 C9 00 ..7.7.7..d7.....
00000010 64 41 53 44 46 47 48 4A 49 4B 4C 00 00 00 00 00 dASDFGHJIKL.....

  • Like 1
Link to comment
Share on other sites

On 3/13/2023 at 12:29 AM, InsaneMultitasker said:

I tried a similar line in Extended BASIC and it too ran without an error.  Below is what "100 GOTO 100 ASDFGHIJKL" looks like in a saved program file. I don't see a token between the GOTO's line number and the string of characters so I guess the interpreter never gets past the GOTO 100 and therefore doesn't care what you typed.  Prescan might have trouble if you typed a recognized keyword instead of random characters.

 

00000000 00 03 37 C7 37 C4 37 D7 00 64 37 C9 0F 86 C9 00 ..7.7.7..d7.....
00000010 64 41 53 44 46 47 48 4A 49 4B 4C 00 00 00 00 00 dASDFGHJIKL.....

This sent me down a rabbit hole this morning.  TI BASIC doesn't care what you have past the GOTO 100 either.  Using a keyword (NEXT) - I was able to make a line that was far longer than any other line I've made in TI BASIC without getting the LINE TOO LONG error.  


This line is longer than the screen is, but runs without error.

image.png

image.png

  • Haha 3
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...