Yet Another Software Question

Anything QL Software or Programming Related.
User avatar
Mr_Navigator
QL Fanatic
Posts: 782
Joined: Mon Dec 13, 2010 11:17 pm
Location: UK, Essex
Contact:

Yet Another Software Question

Post by Mr_Navigator »

I may be running out of titles on this type of query soon ( :lol: )

I have gone back at least 3 years as I think I have asked something similar to this before but cannot find it in my posts.

So I am using an emulator with SMSQ/e loaded and have the ability to have a daughter SBASIC running.


So lets call them MAIN in which the program is running and SUB in which it is not.

What I would like to do is code in MAIN to retrieve a line of SuperBASIC code from SUB, change it (I can already do this part), and then place it back in SUB, replacing the line that was there.

Any ideas people?


-----------------------------------------------------------------------------------
QLick here for the Back 2 the QL Blog http://backtotheql.blogspot.co.uk/
User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Yet Another Software Question

Post by tofro »

Yep. Do something weird. Use named pipes :)

On the sending end:

Code: Select all

10 open#3,PIPE_test
20 print#3;"1000 PRINT 'We are using pipes' "&CHR$(10)
30 close #3
on the receiving end, inside your program there:

Code: Select all

998 DLINE 1000 to
999 MERGE PIPE_test : RUN 1000
Note the line number alignment in the two programs. We're expecting line 1000 to end up at the receiving end, so DLINE needs to delete line 1000 there.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
Mr_Navigator
QL Fanatic
Posts: 782
Joined: Mon Dec 13, 2010 11:17 pm
Location: UK, Essex
Contact:

Re: Yet Another Software Question

Post by Mr_Navigator »

Thanks Tobias, this works a treat. However I would like to fully control the receiving end from the sending end. At the moment I have to switch jobs and type in merge/load 'pipe_test' in the daughter BASIC in order for it to be executed.

Is there anyway I can control this from the sending end?


-----------------------------------------------------------------------------------
QLick here for the Back 2 the QL Blog http://backtotheql.blogspot.co.uk/
User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Yet Another Software Question

Post by tofro »

Lee,
if you look in my second (receiving) example, you will actually see I have built that into a program - This receiving Program is executing the merged line 1000 (can be more lines, if needed) on the fly.

Let me show you a bit more elaborate example:

Sending end:

Code: Select all

10 REPeat outer
20 OPEN #3,pipe_bastest
30 lineNo = 10000
110 INPUT "Line to execute (without line #) ";line$
130 PRINT#3;lineNo & " " & line$ & CHR$(10)
145 PRINT #3;CHR$(26) :REMark EOF
150 CLOSE #3
160 END REPeat outer
And the receiving (executing) end:

Code: Select all

10 it =0
20 REPeat lp
30   PRINT "Iteration ";it
40   it = it + 1
50   DLINE 10000 TO 20000
60   MERGE pipe_bastest
70   GO SUB 10000
80 END REPeat
30000 RETurn
Try those two short programs in 2 separate SBASIC windows and see that you can enter S*BASIC lines on the sending end that are merged and executed on the receiving end, on the fly, in that running program.

Hope this helps,
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
Mr_Navigator
QL Fanatic
Posts: 782
Joined: Mon Dec 13, 2010 11:17 pm
Location: UK, Essex
Contact:

Re: Yet Another Software Question

Post by Mr_Navigator »

Thanks again Tofro, it works quite well but only one way and not exactly what I am after. The commands in the daughter BASIC, all default to scr #2 which is ok for adding a line or more to the daughter BASIC. However I want to be able to get line back and forth in to the MAIN(send) SBASIC.

I've tried using History and Pipes in various forms but keep get errors. So let me stated exactly what I would like to do.

MAIN SBASIC - Send lines of BASIC to Daughter SBASIC
MAIN SBASIC - Retrieve lines of BASIC from Daughter SBASIC
MAIN SBASIC - Send commands to Daughter SBASIC to run a SBASIC Command or written PROCedure

Daughter SBASIC - Automatically receive lines of BASIC from MAIN SBASIC
Daughter SBASIC - Automatically send lines of BASIC to MAIN SBASIC when requested
Daughter SBASIC - Automatically run a SBASIC Command or written PROCedure when requested from MAIN SBASIC


This works in Daughter SBASIC and shows passing the line from MAIN SBASIC

Code: Select all

110 REPeat loop
120    MERGE Pipe_test
130    LIST 1000 TO
140    PAUSE 75
150 END REPeat
I've tried this in Daughter BASIC but it is difficult to get it to work remotely from MAIN

Code: Select all

220 DEFine PROCedure SendBack (LineNo)
230  OPEN  #4, PIPE_ReturnLine
240  LIST  #4, LineNo TO LineNo
250  CLOSE #4
260 END DEFine
I've tried using
PIPE and
PRINT #3,a$ & CHR$ {10) in MAIN

and

INPUT #4,b$

as a way to pass a command, but then using TURBO TOOLKIT's COMMAND_LINE and TYPE_IN in Daughter BASIC to act on any command trips up as they revert to MAIN SBASIC scr#0 and this screws everything up.

Frustrating, as there should be a way to do this.


-----------------------------------------------------------------------------------
QLick here for the Back 2 the QL Blog http://backtotheql.blogspot.co.uk/
Martin_Head
Aurora
Posts: 852
Joined: Tue Dec 17, 2013 1:17 pm

Re: Yet Another Software Question

Post by Martin_Head »

I don't know if this would work, or is what you want to do. And it's just off the top of my head.

If you searched the channel tables to find the channel ID's of #0 for the daughter and main SBASIC's and the start of the channel definition blocks for #0 in the daughter and main SBASIC's.

Could you then POKE text into the keyboard queue for whichever SBASIC you wanted to control.

For example you could send text to the daughter SBASIC, form the main SBASIC as if it was typed in the daughter SBASIC.

I don't know if I've thought this through right, or if daughter channel definition blocks are stored in the SMSQ/E side, or inside the SBASIC daughter job.

Martin


User avatar
Mr_Navigator
QL Fanatic
Posts: 782
Joined: Mon Dec 13, 2010 11:17 pm
Location: UK, Essex
Contact:

Re: Yet Another Software Question

Post by Mr_Navigator »

Martin_Head wrote:I don't know if this would work, or is what you want to do. And it's just off the top of my head.

If you searched the channel tables to find the channel ID's of #0 for the daughter and main SBASIC's and the start of the channel definition blocks for #0 in the daughter and main SBASIC's.

Could you then POKE text into the keyboard queue for whichever SBASIC you wanted to control.

For example you could send text to the daughter SBASIC, form the main SBASIC as if it was typed in the daughter SBASIC.

I don't know if I've thought this through right, or if daughter channel definition blocks are stored in the SMSQ/E side, or inside the SBASIC daughter job.

Martin
I don't know enough about channel definition blocks, however it got me thinking.

I tried this

Code: Select all

100 INPUT #0,"Type Something";a$
110 INPUT #1,"Type Something";a$
120 INPUT #2,"Type Something";a$
130 TYPE_IN "Hello "&CHR$(10)
and as expected 'Type Something' appeared in all three windows in Daughter SBASIC

Cursor flashed in window #0, typing ED and Hello appeared in #2 which had to be deleted of course.

I then changed it to

Code: Select all

100 INPUT #0,"Type Something";a$
110 INPUT #1,"Type Something";a$
120 INPUT #2,"Type Something";a$
125 INPUT #0,"Type Something";a$
130 TYPE_IN "Hello "&CHR$(10)
Lo and behold Hello appeared in #0 as it was the last window to use the cursor which TYPE_IN seems to follow. Now unfortunately I don't want to switch from MAIN to Daughter each time, however I had an idea. So I tried this

Code: Select all

100 INPUT #0,"Type Something";a$
110 INPUT #1,"Type Something";a$
120 INPUT #2,"Type Something";a$
126 CURSOR_ON #0
130 TYPE_IN "Hello "&CHR$(10)
This worked as Hello appeared in #0 with an error "Unknown Procedure" as expected. So now more testing to see if I can do this remotely without interference from Daughter, I think there is also a way to blank SBASIC while it is still running in the background, but I don't know yet if CURSOR_ON will affect that situation. I'll update when done.


-----------------------------------------------------------------------------------
QLick here for the Back 2 the QL Blog http://backtotheql.blogspot.co.uk/
User avatar
pjw
QL Wafer Drive
Posts: 1297
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Yet Another Software Question

Post by pjw »

I have experimented with using SBASIC daughter jobs to do useful stuff, and was going to publish an article on it in a recent Quanta. But Ive held back as I dont like the way listings are rendered in the mag at present. Below is a much earlier attempt to explore the concept. Things have moved on since then, but it may provide some ideas:

100 REMark Get an SBASIC job to work as
110 REMark a slave of another SBASIC.
120 REMark Full programmable interpreter
130 REMark via PRINT statements!
140 REMark By pjwitte January 23rd 2001
150 :
160 REMark Init
170 ch = 1: cu = 0: CLS#ch: CLS#cu
180 pip$ = 'pipe_p' & HEX$(DATE,32)
190 :
200 JOB_NAME 'Master'
210 :
220 REMark Plumb in SBAS slave
230 co = FOPEN(pip$ & 'o_2048')
240 ERT co
250 REMark lrun our command stream
260 cm$ = 'lrun "' & pip$ & 'o"'
270 REMark Start SBAS with command
280 EXEP 'SBASIC'; cm$
290 REMark We control command channel
300 PRINT#co; 'ch = fopen(#0;"' & pip$ & 'i_64")'
310 PRINT#co; 'JOB_NAME "Slave"'
320 REMark Messages come out here
330 ci = FOP_IN(pip$ & 'i'): IF ci < 0: CLOSE
340 ERT ci
350 :
360 REMark Give slave some tools
370 LIST#co; 1000 TO
380 :
390 REMark Test
400 PRINT#co; 'echo "Hello": beep 2000, 2'
410 IF Answer < 0: CLOSE: STOP
420 :
430 REMark Torment!
440 CLS#cu: PRINT#cu; 'Type in your commands'
450 REPeat sb
460 INPUT#cu; '>'! cm$
470 IF cm$ = '' OR cm$ == 'quit': EXIT sb
480 PRINT#co; cm$
490 IF Answer < 0: EXIT sb
500 END REPeat sb
510 PRINT#co; 'beep 2000, 2: quit'
520 CLOSE
530 :
540 DEFine FuNction Answer
550 ans% = 0
560 REPeat il
570 k$ = INKEY$(#ci; 20)
580 IF LEN(k$) = 0: EXIT il
590 INPUT#ci; l$: echo k$ & l$
600 ans% = 1
610 END REPeat il
620 IF EOF(#ci): ans% = -10
630 IF ans% = 0: echo 'no answer'
640 IF ans% < 0: echo 'Slave died'
650 RETurn ans%
660 END DEFine
670 :
1000 DEFine PROCedure echo(t$)
1010 PRINT#ch; t$
1020 END DEFine
1030 :

Per


Per
dont be happy. worry
- ?
stevepoole
Super Gold Card
Posts: 714
Joined: Mon Nov 24, 2014 2:03 pm

Re: Yet Another Software Question

Post by stevepoole »

Hi All,
The SMSQ/E manual page 29 mentions the possibility of using the keyword PIPE to communicate between EXed programs.

There are no details of how to implement this, and working it out by trial and error seems daunting.

I need four multitasking daughter jobs, each with its own CON_ to communicate instantaneous keyboard presses between them. So I have devised my own method of doing this, which works but is unconventional. (The keypresses determine output on four interacting screens).

If I understand correctly, PIPE is only recognised when programs are run using EX. This would make prototyping particularly arduous.

The person I am writing the program for does not use Turbo. Are there any other standard ways of doing this which makes prototyping easier ?

Regards,
Steve.


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

Re: Yet Another Software Question

Post by janbredenbeek »

stevepoole wrote:Hi All,
The SMSQ/E manual page 29 mentions the possibility of using the keyword PIPE to communicate between EXed programs.
PIPE is not a keyword but a device. Basically, it's a queue which you can write data ('PRINT') to by one job and input data from by another job.
It's a bit tricky to use from Basic; you have to OPEN a channel for output first to PIPE_nnnnn (where nnnnn is the queue size) and then open an input channel to 'PIPE' (without size) and specify the corresponding output channel as parameter in D3 so the system knows how to link them (SMSQ/E seems to support named pipes which is easier to use from Basic).
If I understand correctly, PIPE is only recognised when programs are run using EX. This would make prototyping particularly arduous.
EX can execute a chain of programs linked via pipes. E.g. EX unzip;'-c test.zip' TO grep 'fred' pipes the output of unzip to grep. This way it builds a pipe where unzip writes data to and grep gets its input from.

Jan


Post Reply