Trying out other people's programs that rely on channels #0, #1, #2 and end up messing up my display is not something I enjoy. Of course, I normally sandpit suspect programs in an SBASIC daughter job, so that saves a bit of annoyance.
But if you program in SBASIC, why not use something like this simple startup code:
Code: Select all
100 wsx% = 512: wsy% = 256: REMark My program's (fixed) window size
110 wox% = 0: woy% = 0: REMark Window origin
120 :
130 wc = FOPEN('con'): REMark Open a fresh output window
140 scrx% = SCR_XLIM(#wc): scry% = SCR_YLIM(#wc)
150 IF scrx% > wsx%: wox% = (scrx% - wsx%) / 2: REMark Center on screen
160 IF scry% > (wsy% + 20): woy% = 20: REMark Leave room for button bar
179 WINDOW#wc; wsx%, wsy%, wox%, woy%
etc..
If your program doesn't have to have a fixed size you could for example let wsx% = scrx% and wsy% = scry% or any other size you choose. Display code would then have to be scaled accordingly. Take the Mandelbrot routines published by Steve recently:
Code: Select all
100 REMark MandelQdos_bas
110 WINDOW 512,256,0,0: PAPER 0: CLS
130 FOR d=0 TO 255
140 y0=(d-128)/128
150 FOR a=0 TO 511
160 x0=(a-256)/128: x=0: y=0
170 FOR i=1 TO 32
180 xt=x*x-y*y+x0: y=(2*x*y)+y0: x=xt
190 IF ((x*x+y*y)>4): EXIT i
200 END FOR i: BLOCK 1,1,a,d,(i MOD 8)
210 END FOR a: IF KEYROW(1)=8: EXIT d
220 END FOR d: PAUSE: PAUSE
Code: Select all
100 REMark MandelQdos_bas
102 ch=FOPEN("con")
104 scrx%=SCR_XLIM(#ch): scry%=SCR_YLIM(#ch)
106 x2%=scrx% DIV 2: y2%=scry% DIV 2
108 WINDOW#ch; scrx%,scry%,0,0: CLS#ch
112 FOR d=0 TO scry%-1
114 y0=(d-y2%)/y2%
116 FOR a=0 TO scrx%-1
118 x0=(a-x2%)/y2%: x=0: y=0
120 FOR i=1 TO 32
122 xt=x*x-y*y+x0: y=(2*x*y)+y0: x=xt
124 IF ((x*x+y*y)>4): EXIT i
126 END FOR i
128 BLOCK#ch;1,1,a,d,(i MOD 8)
130 END FOR a
132 IF KEYROW(1)=8: EXIT d
134 END FOR d
138 PAUSE#ch
If you have a larger screen but get an Out of Range error it is probably because the window it is being run in has already had its OUTLine set. Try it again in an SBASIC daughter job, ie type SBASIC<ENTER> in the main console and LRUN it from the daughter. Or use QD, one of the best programming text editors, and dispatch it directly from there with F10.
SBASIC programs can also be EXecuted like compiled or assembled jobs. (LRUN is for wimps!

When you EXecute an SBASIC program you can make it so that it will accept parameters. Like a file name or something. No need for the user to fiddle the code or answer repeated INPUT questions each time. The program above has been modified below to take its parameters from the command line:
Code: Select all
100 REMark MandelQdos_bas
102 ch% = FOPEN("con")
104 if len(CMD$) < 7 then
106 scrx% = SCR_XLIM(#ch%): scry% = SCR_YLIM(#ch%)
108 scox% = 0: scoy% = 0
110 else
112 Parse CMD$
114 endif
116 x2% = scrx% DIV 2: y2% = scry% DIV 2
118 WINDOW#ch%; scrx%, scry%, scox%, scoy%: CLS#ch%
120 :
122 t = date
124 FOR d% = 0 TO scry% - 1
126 y0 = (d% - y2%) / y2%
128 FOR a% = 0 TO scrx% - 1
130 x0 = (a% - x2%) / y2%
132 x = 0: y = 0
134 FOR i% = 1 TO 32
136 xx2 = x * x: yx2 = y * y
138 y = (2 * x * y) + y0
140 x = xx2 - yx2 + x0
142 IF ((xx2 + yx2) > 4): EXIT i%
144 END FOR i%
146 BLOCK#ch%; 1,1, a%, d%, (i% MOD 8)
148 END FOR a%
150 IF KEYROW(1) = 8: EXIT d%: REMark ESC
152 END FOR d%
154 at#ch%; 2, scrx% div 6 - 5: print#ch%; date - t
156 BEEP 2000, 2
158 PAUSE#ch%; (date - t) * 25
160 QUIT
162 :
164 :
166 DEFine PROCedure Parse(cl$)
168 LOCal l%, p%, n%
170 l% = LEN(cl$)
172 scrx% = cl$
174 p% = ',' INSTR cl$
176 n% = p% + 1
178 scry% = cl$(n% TO l%)
180 p% = ',' INSTR cl$(n% TO l%)
182 n% = n% + p%
184 scox% = cl$(n% TO l%)
186 p% = ',' INSTR cl$(n% TO l%)
188 n% = n% + p%
190 scoy% = cl$(n% TO l%)
192 END DEFine Parse
194 :
196 :
The program accepts four parameters: window size and origin, as in:
EX ram1_QMandel_bas;'300,200,50,20'
Values separated by comma with no spaces between. The parser, Parse, is very simple, so does not do any error checking for this example. If NO parameters are supplied the program takes up the whole screen.
To test it, I wrote this little dispatcher. I could have added some parameter parsing there too, but to keep it simple, youll have to make whatever changes in the code itself. It too is meant to be EXecuted, but you could just LRUN it or dispatch it directly from QD:
Code: Select all
100 REMark Tile multiple QMandles. Set nx, ny and fnm$
102 :
104 nx% = 2: ny% = 2
106 fnm$ = 'ram1_QMandel_bas'
108 :
110 sys_clnk = $C4: pt_xscrs = $F2: pt_yscrs = $F4
112 scrx% = PEEK_W(!sys_clnk! pt_xscrs): REMark Get screen size without
114 scry% = PEEK_W(!sys_clnk! pt_yscrs): REMark a channel (PE only!)
116 :
118 FOR x% = 0 TO nx% - 1
120 FOR y% = 0 TO ny% - 1
122 xs% = scrx% DIV nx%
124 ys% = scry% DIV ny%
126 ox% = x% * xs%
128 oy% = y% * ys%
130 EX fnm$; xs% & ',' & ys% & ',' & ox% & ',' & oy%
132 END FOR y%
134 END FOR x%
136 IF JOBID: QUIT
138 :
140 :
Lines 110 - 114 get the screen size directly from the driver, since no display channel is needed or wanted. This "trick" only works in SMSQ/E, without extra toolkits.
A couple of other things I like to see in the sort of programs we publish here, is an option to ESCape. Having to BREAK into a program to stop it can be a nuisance, especially if it leaves things dangling or in a mess. ESCape should lead to some form of clean termination that leaves the system much as it was. So, open channels should be closed, memory released, windows restored. BREAK is fine for debugging, but not for ordinary use. Like crashing your car into a tree every time you wanted to stop, before they invented breaks..
Another thing is programs that may take a long time to complete something. Sometimes it can be hard to know whether they are just in deep thought, or have crashed. A BEEP or a message would be useful here!
(I once uptated the OS on a Mac I had, via the internet. The machine appeared totally dead and unresponsive for 12 hours or so. Black screen, no messages, nothing to say what was going on. A wonder I didnt just pull the plug and complain! The next day, suddenly it sprang to life, updated! What utter idiots multi-trillion dollar companies can be! NOT an example to follow!)
Im not an expert programmer, but I try out a lot of programs to see whats going on, so I am, perhaps, a bit of an expert in what feels like "good paractice" to me.
I know there are many different setups, many different ways of doing things, many different ideas of do's and dont's. But things change, and so should we.