SMSQ SBASIC EX and break

Anything QL Software or Programming Related.
olifink
Chuggy Microdrive
Posts: 69
Joined: Tue Oct 30, 2018 7:35 pm

SMSQ SBASIC EX and break

Post by olifink »

I finally found a bit of dedicated time during the hols for SMSQ on the Q68 (sweet thing it is) and QPC. EX'ing a _bas file makes me smile every time I think about it, very nicely done indeed - almost no reason to do _asm anymore... :) especially for filters!

Does anybody know a way to disable or capture break/ctrl-spc in SBASIC yet? WHEN ERR ERR_NC doesn't work (unless I'm doing it wrong) but it could - and perhaps should be the way to do it, right?

This would make it even more consistent with what one gets from compiled basic

O


User avatar
janbredenbeek
Super Gold Card
Posts: 632
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: SMSQ SBASIC EX and break

Post by janbredenbeek »

olifink wrote: Does anybody know a way to disable or capture break/ctrl-spc in SBASIC yet? WHEN ERR ERR_NC doesn't work (unless I'm doing it wrong) but it could - and perhaps should be the way to do it, right?
I've done it back in the '80s when I wrote procedures and functions for Basicode. This included a command BREAK_OFF to disable the Break key combination.
The code is on GitHub (from lines 713 onwards), but the essential part is to set up a scheduler task which reads out a flag set by BREAK_ON/BREAK_OFF and resets the BV.BRK flag set by another scheduler task (in JS and earlier versions this was a polled task but in Minerva it was moved out there to avoid being called when SuperBasic was being moved in memory).

Code: Select all

SCHDTASK  TST.B     BREAKDIS+$10(A3)    A3 = start of storage area -$10
          BEQ.S     RTS1                leave BREAK alone
          MOVE.L    SV.JBBAS(A6),A0     get pointer to start of job table
          MOVE.L    (A0),A0             get start of job 0's header
          MOVE.L    JB.A6(A0),A1        ... and value for A6
          TAS       BV.BRK(A1)          reset any BREAK flag
          TST.W     JB.STAT(A0)         job suspended?
          BGE.S     RTS1                yes, exit      
          MOVE.W    #-2,JB.STAT(A0)     ensure interrupt code can't break I/O
RTS1      RTS
One flaw of this code is that it only disables BREAK on job 0 (the SBASIC parent), it has to be reworked in order to disable BREAK on all SBASICs. Under Minerva or SMSQ/E there might perhaps be a more efficient way to do this...

Jan.


olifink
Chuggy Microdrive
Posts: 69
Joined: Tue Oct 30, 2018 7:35 pm

Re: SMSQ SBASIC EX and break

Post by olifink »

oh, interesting - thanks for the pointer :)


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

Re: SMSQ SBASIC EX and break

Post by pjw »

In SMSQ/E just: poke !!$e4,%10000
Theres a similar poke for Qdos, IIRC.
Of course, it applies system wide, not to any particular SBASIC, which is what I thought you were asking.
Check out the systems variables. There are some more keys there concerning break.


Per
dont be happy. worry
- ?
User avatar
janbredenbeek
Super Gold Card
Posts: 632
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: SMSQ SBASIC EX and break

Post by janbredenbeek »

pjw wrote:In SMSQ/E just: poke !!$e4,%10000
Theres a similar poke for Qdos, IIRC.
Of course, it applies system wide, not to any particular SBASIC, which is what I thought you were asking.
Check out the systems variables. There are some more keys there concerning break.
Thanks for mentioning SMSQ/E. Should be fairly easy compared to QDOS.
Under QDOS, this variable is unused and the BREAK code is part of the keyboard interrupt code which is not easily replacable, hence the hack via a scheduler task.
Under Minerva, the keyboard interrupt code sets a flag in the sx.event system variable which is read by a scheduler task which performs the BREAK. There should be a way to disable this mechanism but I have yet to find out how.

Jan.


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

Re: SMSQ SBASIC EX and break

Post by pjw »

janbredenbeek wrote:
pjw wrote:In SMSQ/E just: poke !!$e4,%10000
Theres a similar poke for Qdos, IIRC.
Of course, it applies system wide, not to any particular SBASIC, which is what I thought you were asking.
Check out the systems variables. There are some more keys there concerning break.
Thanks for mentioning SMSQ/E. Should be fairly easy compared to QDOS.
Under QDOS, this variable is unused and the BREAK code is part of the keyboard interrupt code which is not easily replacable, hence the hack via a scheduler task.
Under Minerva, the keyboard interrupt code sets a flag in the sx.event system variable which is read by a scheduler task which performs the BREAK. There should be a way to disable this mechanism but I have yet to find out how.

Jan.
Are you quite sure? Some commercial programs that used Fastload, ie an early version of QLOAD, to load tokenised SuperBASIC programs, managed to disable break, so punters couldnt break into the program and nick their code (or see their horrid spaghetti ;)) I seem to recall cracking a few of those by dis-disabling that feature, but I no longer remember how they, or I, did it.
That being said, it seems an odd thing to want to do nowadays, on a multitasking machine..


Per
dont be happy. worry
- ?
User avatar
pjw
QL Wafer Drive
Posts: 1299
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: SMSQ SBASIC EX and break

Post by pjw »

Ah, yes: The poke to disable break under Qdos is poke_l 163900, 0. Unfortunately this also disables all other scheduler tasks :evil:
(And that still doesnt remind me how I managed to switch break on again. There was a break_on/break_off toolkit out there once.
Perhaps that was it?)


Per
dont be happy. worry
- ?
User avatar
janbredenbeek
Super Gold Card
Posts: 632
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: SMSQ SBASIC EX and break

Post by janbredenbeek »

pjw wrote:Ah, yes: The poke to disable break under Qdos is poke_l 163900, 0. Unfortunately this also disables all other scheduler tasks :evil:
(And that still doesnt remind me how I managed to switch break on again. There was a break_on/break_off toolkit out there once.
Perhaps that was it?)
Actually it disables the polled tasks so the keyboard and serial ports won't work anymore (unless you read them out using your own code). The only way to restore this is to poke back the old value (which is a link in ROM on JS and earlier).

Jan.


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

Re: SMSQ SBASIC EX and break

Post by pjw »

janbredenbeek wrote:
pjw wrote:Ah, yes: The poke to disable break under Qdos is poke_l 163900, 0. Unfortunately this also disables all other scheduler tasks :evil:
(And that still doesnt remind me how I managed to switch break on again. There was a break_on/break_off toolkit out there once.
Perhaps that was it?)
Actually it disables the polled tasks so the keyboard and serial ports won't work anymore (unless you read them out using your own code). The only way to restore this is to poke back the old value (which is a link in ROM on JS and earlier).

Jan.
Yes, its probably better just to remove the CTRL keys from the keyboard.


Per
dont be happy. worry
- ?
olifink
Chuggy Microdrive
Posts: 69
Joined: Tue Oct 30, 2018 7:35 pm

Re: SMSQ SBASIC EX and break

Post by olifink »

pjw wrote:In SMSQ/E just: poke !!$e4,%10000
Theres a similar poke for Qdos, IIRC.
Of course, it applies system wide, not to any particular SBASIC, which is what I thought you were asking.
Check out the systems variables. There are some more keys there concerning break.
sys_klock would be an interesting copy protection scheme, but not really what I was looking for: a way to not accidentally break into only an EX'd SBASIC so that it behaves like a compiled program running as any other job. The ideal situation is to have break passed as ERR_NC into then WHEN ERRor handling only when it's being EXecuted and not run interactively. From looking at the mention of ERR_NC in the WHEN ERRor documentation one should think that was always the intent.

Looking at the implementation however that situation never happens, as sb_break(a6) checks are preceding any other handlers and always give up processing without any further consideration:

from in dev8_smsq_sbas_execute.asm(57):

Code: Select all

	tst.b	sb_break(a6)		 ; break?
	bpl.s	sbx_rtd0		 ; ... yes, give up

	move.w	sb_wherr(a6),sb_nline(a6) ; when?
	ble.s	sbx_rtd0		  ; ... no

	move.b	#1,sb_nstmt(a6)
	st	sb_wheiu(a6)		 ; when now in use
	bra	sb_execute		 ; ... use it

sbx_rtd0
	tst.l	d0
sbx_rts
	rts
However, it appears that a small change there can remedy this situation without any runtime penalty: An additional check to hand over the break condition to sbx_wherr only if the job is running without it own command channel 0 seems a sensible approach as EX'd _bas files only get #0 opened under error conditions (and closed again if needed). This gives an WHEN ERRor handler the chance to check for ERR_NC and handle or ignore and continue as needed. That way, it also doesn't get in the way of interactive work in the interpreter:

Proposed change:

Code: Select all

	tst.b	sb_break(a6)		 ; break?
	bpl.s	sbx_brk0		 ; ... yes, handle break
sbx_wherr
	move.w	sb_wherr(a6),sb_nline(a6) ; when?
	ble.s	sbx_rtd0		  ; ... no

	move.b	#1,sb_nstmt(a6)
	st	sb_wheiu(a6)		 ; when now in use
	bra	sb_execute		 ; ... use it

sbx_rtd0
	tst.l	d0
sbx_rts
	rts

sbx_brk0
	move.l	d0,d3			 ; remember error code
	jsr	sb_chan0		 ; check if channel 0 exists
	beq.s	sbc_brkcnt		 ; ...yes, normal break handling
	move.l	d3,d0			 ; restore error code
	bra.s	sbx_wherr		 ; hand off to when error

sbc_brkcnt
	move.l	d3,d0			 ; restore error code
	bra.s	sbx_rtd0		 ; and give up
Not perhaps the most elegant code but I now have a local SMSQ build that behaves as I would expect it.

Incidentally: what is the protocol for contributing back into SMSQ/E mainline development? I would like to avoid having to maintain my private fork for this if others perhaps find it useful as well and would want to contribute upstream. Is there any way of doing this?

O


Post Reply