Dr. Jim's QL Dumping Ground

Anything QL Software or Programming Related.
martyn_hill
Aurora
Posts: 909
Joined: Sat Oct 25, 2014 9:53 am

Re: Dr. Jim's QL Dumping Ground

Post by martyn_hill »

Interesting observation...

I always thought that the terminating REMark should not be taken as a formal statement and thus trigger the interpretation of the FOR structure as a one-liner in any or our S*Basic variants.

However, I also see that JS ROM (under Qem) does treat the REM as a statement to close the FOR construct and thus treats it as a the one-liner...


Derek_Stewart
Font of All Knowledge
Posts: 3928
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Dr. Jim's QL Dumping Ground

Post by Derek_Stewart »

Hi,

Sorry I forgot about last week...

I did not put a REM statement in the FOR loop with JS,JM it seemsed to give 1,2,3,4,5,8 as SMSQ/E

No matter back to sleep....


Regards,

Derek
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by pjw »

Sorry (again!) I just couldnt resist this:

Code: Select all

100 x = 1
110 IF x = 0 THEN REMark test
120  PRINT 'SuperBASIC'
130 ELSE
140  PRINT 'SBASIC'
150 END IF
Really, SuperBASIC ought to barf at the ELSE..


Per
dont be happy. worry
- ?
User avatar
BSJR
Trump Card
Posts: 182
Joined: Sun Oct 18, 2015 12:53 pm
Location: Amsterdam
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by BSJR »

pjw wrote:Sorry (again!) I just couldnt resist this:

Code: Select all

100 x = 1
110 IF x = 0 THEN REMark test
120  PRINT 'SuperBASIC'
130 ELSE
140  PRINT 'SBASIC'
150 END IF
Really, SuperBASIC ought to barf at the ELSE..
This may be accepted by SBasic but does not work when compiled by Qlib 3.36. Then the IF /FOR /REPeat line is seen as inline loop as in QDOS.

BSJR


User avatar
TMD2003
Trump Card
Posts: 168
Joined: Sat Oct 10, 2020 12:18 pm

Re: Dr. Jim's QL Dumping Ground

Post by TMD2003 »

I am going to have to test the suggestions made to the previous listing myself... but for now, a noob question that's relevant to what I've just decided to do a few minutes ago.

Is there a QL equivalent to the Spectrum's SAVE "filename" SCREEN$ (which is in itself a shorthand for SAVE "filename" CODE 16384,6912) that will save a screen dump pixel-for-pixel? All I know is, it will start with SBYTES, if it exists...


Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
M68008
Trump Card
Posts: 223
Joined: Sat Jan 29, 2011 1:55 am
Contact:

Re: Dr. Jim's QL Dumping Ground

Post by M68008 »

TMD2003 wrote:Is there a QL equivalent to the Spectrum's SAVE "filename" SCREEN$ (which is in itself a shorthand for SAVE "filename" CODE 16384,6912) that will save a screen dump pixel-for-pixel? All I know is, it will start with SBYTES, if it exists...
To save the screen:

Code: Select all

SBYTES filename,131072,32768
Then you can reload it with:

Code: Select all

LBYTES filename,131072


stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Dr. Jim's QL Dumping Ground

Post by stevepoole »

Hi TMD,

On some more recent QL systems, replace 131072 with SCR_BASE, as this keeps any shifts in the memory area located....

Also replace 32768 (bytes), with SCR_XLIM * SCR_YLIM

Eg: 100 SBYTES flp1_filename, SCR_BASE, SCR_XLIM * SCR_YLIM

On emulators, you may need to modify again to allow for resolution : eg: bytes = ( SCR_XLIM * SCR_YLIM ) * 2 : (where '2' doubles to a bigger screen resolution).

If in doubt, experiment to adapt to your system.... starting with the smaller values so as not to load in non_screen addresses, which may cause crashes !

Steve.


User avatar
TMD2003
Trump Card
Posts: 168
Joined: Sat Oct 10, 2020 12:18 pm

Re: Dr. Jim's QL Dumping Ground

Post by TMD2003 »

Hmmm. It seems I may have to make a separate SMSQ/E edition if I'm going to do that - to adjust the proportions of the screen, and also use more than four colours. However, I'll stick to the original QL version first and get that exactly how I want it, so this:
M68008 wrote:To save the screen:

Code: Select all

SBYTES filename,131072,32768
Then you can reload it with:

Code: Select all

LBYTES filename,131072
...will do nicely!

Steve: I note what you said as well, so I'll probably attempt that SCR_BASE when I get to the SMSQ/E version.

I'm sure I read somewhere that QPC2 is permanently stuck with the 1:1 pixel resolution rather than the 1.36:1 of the original QL, so it'll need a fair bit of recalculation and won't be an overnight job.


Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
dilwyn
Mr QL
Posts: 2753
Joined: Wed Dec 01, 2010 10:39 pm

Re: Dr. Jim's QL Dumping Ground

Post by dilwyn »

stevepoole wrote:Hi TMD,

On some more recent QL systems, replace 131072 with SCR_BASE, as this keeps any shifts in the memory area located....

Also replace 32768 (bytes), with SCR_XLIM * SCR_YLIM

Eg: 100 SBYTES flp1_filename, SCR_BASE, SCR_XLIM * SCR_YLIM

On emulators, you may need to modify again to allow for resolution : eg: bytes = ( SCR_XLIM * SCR_YLIM ) * 2 : (where '2' doubles to a bigger screen resolution).

If in doubt, experiment to adapt to your system.... starting with the smaller values so as not to load in non_screen addresses, which may cause crashes !

Steve.
Even better, instead of trying to adjust the SCR_XLIM part and having to test for the different colour depths, use SCR_LLEN, which tells you the number of bytes per line of the screen display in SBASIC. You can hide the absence of these SBASIC functions from SuperBASIC when running on a QL by using a VER$ function call to examine the version of BASIC that the program is running on:

Code: Select all

1000 DEFine PROCedure Save_Screen (filename$)
1010   LOCal v$
1020   v$ = VER$
1030   IF v$ = 'HBA' THEN
1040     REMark SBASIC
1050     SBYTES filename$,SCR_BASE,SCR_LLEN*SCR_YLIM
1060   ELSE
1070     REMark other systems
1080     SBYTES filename$,131072,32768
1090   END IF
1100 END DEFine Save_Screen
Line 120 makes a note of the BASIC version on this machine. A little peculiarity is that you should really copy VER$ to a variable rather than use it in an expression on some systems - it's a documented bug that upsets the stack on some versions of BASIC, can't remember the full details, probably covered in Simon Goodwin and Mark Knight's articles on S*BASIC bugs.

Line 1030 tests if we are running on SBASIC (version code is HBA) and if it is, work out the screen size by multiplying the screen line length by the number of lines down the screen. The function SCR_BASE tells you where in memory the screen starts.

If we are not running on SBASIC, line 1080 then saves the screen as it would on a standard QL.

A saved screen will then load with LBYTES filename$,SCR_BASE as long as the screen is the same size as the current display. Sadly, an SBYTES screen does not save the screen dimensions within the file, so the only check you can do when reloading is that the length matches the current display. At best with a mismatch, you'll get a scarmbled display or a picture which only covers part of the display. At worst, screen files larger than the screen will overwrite what is beyong the screen in memory (e.g. system variables) and a crash will follow.

This copes with all screen variations with two notable exceptions.

1. Aurora. The video display has a fixed line width, which may be larger than the visible part in certain modes. To work around this, you would need to test for an Aurora then do different variants of Steve's method depending on the display mode, for mode 4 or 8 it would be pixel width DIV 4, while for the 256 colour mode it would be screen width * screen height.

2. uQLx-derived emulators. Some, such as SQLUX, have the facility to use fixed higher resolution displays in mode 4. Meaning that the line width may not be 512 pixels/128 bytes. Again, you'd need to find a way to test for uQLx then use functions defined in its BASIC to get the size of screen to save.

Once you have the code needed to check for those systems, you can add extra IF statements to handle those cases - afraid I don't know how to test for Aurora and uQLx from BASIC, although their manuals probably explain.

So, sadly, when it comes to QL graphics, nothing is simple, largely because the original QL design never really foresaw the need for handling high resolution or high colour displays, so the extensions to handle it are only present in later versions of BASIC. So it can be hard to make the necessary tests to allow routines to adapt to also work on the older systems.

In fairness, not that many people regularly use the high colour, high resolution modes, so just using SBYTES filename$,131072,32768 will probably work 90% of the time, as long as you document that your program will only work on systems with QL-style display.


EmmBee
Trump Card
Posts: 240
Joined: Fri Jan 13, 2012 5:29 pm
Location: Kent

Re: Dr. Jim's QL Dumping Ground

Post by EmmBee »

pjw wrote: So Ive learnt two new things about FOR loops quite recently, summed up here:

Code: Select all

FOR i = 1 to 5 STEP 2, 8:		REMark Note the REMark! (SMSQ/E only!)
	PRINT i
END FOR i
Thanks for letting me know, Per. I’ll make some corrections to QLiberator and release a new version, soon.

Coming back on topic, about the REMarks In TMD2003’s factorising program: they are being used to highlight the start of definitions. Back in the day, many years ago, I also used to do this. Nowadays, however, the modern trend seems to be to have a single line with just one colon “:” to separate the definitions.

Code: Select all

100 CLS
110 initial_input
120 factor_array (f0)
130 factors_found
140 STOP
150 :
160 DEFine PROCedure initial_input
180   PRINT "INPUT INTEGER TO FACTORISE"\"(min.2, max.999999)"\\"-> ";
190   REPeat loop1
200     INPUT f0
210     IF f0 >= 2 AND f0 <= 999999 AND f0 = INT(f0) THEN EXIT loop1
220   END REPeat loop1
230 END DEFine initial_input
240 :
250 DEFine PROCedure factor_array(f1)
270 LOCal n, cf
280   DIM f(19) : f1 = f0
290   FOR n = 1 TO SQRT(f1) STEP 2, f1
300     cf = n : IF n = 1 THEN cf = 2
310     AT 5,0 : PRINT "Dividing by "; cf
320     REPeat loop2
330       IF cf*((f1/cf)-INT(f1/cf)) <> 0 THEN EXIT loop2
340       f1 = f1/cf : f(f(0)+1) = cf : f(0) = f(0)+1
350       IF f1 = 1 THEN RETurn
360     END REPeat loop2
370   END FOR n
380   IF f1 = f0 THEN f(0) = 1 : f(1) = f1
390 END DEFine factor_array
400 :
410 DEFine PROCedure factors_found
430 LOCal n
440   AT 5,0 : PRINT "NUMBER OF FACTORS = ";f(0)\\"FACTORS:"
450   FOR n = 1 TO f(0)-1 : PRINT f(n)!"x "; : END FOR n : PRINT f(f(0));
460   IF f(0) = 1 THEN PRINT "is a PRIME NUMBER"
470 END DEFine factors_found
EmmBee


Post Reply