Sending Teletext over Serial

bbc micro/electron/atom/risc os coding queries and routines
WrightStuff
Posts: 81
Joined: Fri Mar 16, 2012 1:54 pm
Location: Derby
Contact:

Re: Sending Teletext over Serial

Post by WrightStuff »

I'm missing something obvious here!
If you've managed to scrape a bit of free memory using MODE 135, why not just grab a block of memory for your page using DIM ?
No point manually trying to identify free memory blocks, let BASIC do it for you.

If you're really still strapped for memory (e.g. getting 'No room' errors with the above), could declare a smaller DIM and as you've got a Master128, *SRLOAD the page into SWRAM and then read chunks of it back using *SRREAD.
vela025
Posts: 198
Joined: Tue Jun 16, 2020 4:48 pm
Contact:

Re: Sending Teletext over Serial

Post by vela025 »

WrightStuff wrote: Wed Feb 21, 2024 7:07 pm I'm missing something obvious here!
If you've managed to scrape a bit of free memory using MODE 135, why not just grab a block of memory for your page using DIM ?
No point manually trying to identify free memory blocks, let BASIC do it for you.
No, I'm just a bit....erm....DIM.

I've done the following but it hangs just after loading the file in to memory

Code: Select all

DIM mnu% 1024
q=OPENINn$
fle%=EXT#q
CLOSE#q
OSCLI("LOAD "+n$+" "+STR$~mnu%)
FOR r%=0to(fle%-1):VDU (STR$~mnu%)?r%:NEXT r%
BBC Master 128, PiTubeDirect, RGB2HDMI, Twin 5 1/4" & GoTek, BeebSCSI, Retroclinic Datacentre (E), Oki Microline 280, Sony TCM-737, Miracle WS2000 Modem, WE Mouse. BeeBS BBS - http://beebs.ddns.net
WrightStuff
Posts: 81
Joined: Fri Mar 16, 2012 1:54 pm
Location: Derby
Contact:

Re: Sending Teletext over Serial

Post by WrightStuff »

The hang is a bit odd!
Is fle% definitely <=1024 ?

Typo at this line, I would've expected an error, but should be :

Code: Select all

FOR r%=0to(fle%-1):VDU mnu%?r%:NEXT r%
vela025
Posts: 198
Joined: Tue Jun 16, 2020 4:48 pm
Contact:

Re: Sending Teletext over Serial

Post by vela025 »

WrightStuff wrote: Wed Feb 21, 2024 9:25 pm The hang is a bit odd!
Is fle% definitely <1024 ?

Typo at this line, I would've expected an error, but should be :

Code: Select all

FOR r%=0to(fle%-1):VDU mnu%?r%:NEXT r%
Sorry yes I change that after the post, as I wasn't sure and it started working for all the teletext pages:
teletext working.png
but for ANSI files it is telling me no such variable at line 60, and after checking the ones in use at the line fle% is empty for some reason...which I don't really understand as this is a bit of code I user currently and works.*dir $.
ansi not working.png
BBC Master 128, PiTubeDirect, RGB2HDMI, Twin 5 1/4" & GoTek, BeebSCSI, Retroclinic Datacentre (E), Oki Microline 280, Sony TCM-737, Miracle WS2000 Modem, WE Mouse. BeeBS BBS - http://beebs.ddns.net
WrightStuff
Posts: 81
Joined: Fri Mar 16, 2012 1:54 pm
Location: Derby
Contact:

Re: Sending Teletext over Serial

Post by WrightStuff »

Another odd one !
Can you upload the .dsd file ?
User avatar
BeebMaster
Posts: 7380
Joined: Sun Aug 02, 2009 5:59 pm
Location: Lost in the BeebVault!
Contact:

Re: Sending Teletext over Serial

Post by BeebMaster »

It's possible that if the file is longer than the amount DIMmed (ie. 1500 bytes here) then it will overwrite variables declared after the DIM - including fle% so it no longer exists as a variable when it gets to line 60. A way round this is either to declare fle% and other variables as dummy values before the DIM, so they survive an overflow of the memory block reserved, or test that the file length doesn't exceed the amount reserved before loading it.

(Or get the file length and then use that for the DIM, which would work in this example, but fixing the memory block to the length of the first file loaded is unlikely to be useful if more files are to be loaded later on.)

Another idea is to use the integer variables if they aren't being used already - A% to Z% - which are available in BBC BASIC as standard, so can be used without taking up any more memory, and because of that, they don't get overwritten if data overruns corrupt the rest of the variable space.

CLEAR isn't needed at the beginning by the way, as all variables - except the A% to Z% integer variables - are cleared on RUN (or LOAD or CHAIN) unlike some other vintage BASICs which don't do that (and which also can "save" variables with the program I think).
Image
User avatar
jgharston
Posts: 5321
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Sending Teletext over Serial

Post by jgharston »

Yes, if the data you're sending is different length, then again from the Wiki:

max%=80 (say)
DIM data% max%-1
in%=OPENIN(infile$)
num%=EXT#in%
REPEAT
len%=max%
IF num%<len% THEN len%=num%
PROCgbpb(4,in%, data%,len%,0)
FOR n%=0 TO len%-1:PROCserial_send(data%?n%):NEXT n%
(or, eg: FOR n%=0 TO len%-1:VDU data%?n%:NEXT n%)
num%=num%-len%
UNTIL num%=0

etc.

I think, as pointed out, your files are longer than 1024 bytes, so you're overwriting whatever is in memory after the buffer, which will be the variables you are using to access the data. What does *INFO *.* give you?

(It's surprising how small a GBPB buffer you need to speed up data transfer, I've seen a buffer of 4 bytes being faster than a 4-byte BGET loop.)

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
vela025
Posts: 198
Joined: Tue Jun 16, 2020 4:48 pm
Contact:

Re: Sending Teletext over Serial

Post by vela025 »

WrightStuff wrote: Wed Feb 21, 2024 9:25 pm The hang is a bit odd!
Is fle% definitely <=1024 ?
:oops: Just realized that the image I was using in BeebEm was way older than I thought and contained corrupt menu files...which were indeed over 1024. Just tried it on the real thing and it has cut the ANSI menu loading time down from 9.7 seconds to 4 second! Unfortunately whilst working great it is causing no room errors in Mode 7. I would need to change more of the program to get it to work properly in Mode 135 which is always an option.
BeebMaster wrote: Wed Feb 21, 2024 10:33 pm Another idea is to use the integer variables if they aren't being used already - A% to Z% - which are available in BBC BASIC as standard, so can be used without taking up any more memory, and because of that, they don't get overwritten if data overruns corrupt the rest of the variable space.
A great idea, they are already all in use, thanks for the info on CLEAR, I wasn't sure so wanted to cover all bases! :lol:
jgharston wrote: Wed Feb 21, 2024 10:52 pm Yes, if the data you're sending is different length
Yes, to get around this I was using EXT to store the length of the file in fle% and then using this with max=fle% DIV 4, was this why it didn't speed things up?

Code: Select all

 3820DEFPROCVA(mn$):LOCALq:q=OPENINmn$:fle%=EXT#q:IF q=0 THEN TERM%=TRUE:CLOSE#q:ENDPROC
 3830CLOSE#q
 
 3850max%=fle% DIV4
 3860DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256
 3870DIM data% max%-1
 3890in%=OPENIN(mn$)
 3900FOR pass%=1TO4
 3910PROCgbpb(4,in%,data%,max%,0)
 3920FOR n%=0 TO max%-1:PROCserial_send(data%?n%):NEXT n%
 3930NEXT pass%
 3940CLOSE#in%

 3960ENDPROC
 3980DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
 3990?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:CALL &FFD1:ENDPROC
 4010DEFPROCserial_send(byte%)
 4020VDUbyte%
 4030ENDPROC
 
BBC Master 128, PiTubeDirect, RGB2HDMI, Twin 5 1/4" & GoTek, BeebSCSI, Retroclinic Datacentre (E), Oki Microline 280, Sony TCM-737, Miracle WS2000 Modem, WE Mouse. BeeBS BBS - http://beebs.ddns.net
User avatar
jgharston
Posts: 5321
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Sending Teletext over Serial

Post by jgharston »

If you use the
len%=max%
IF num%<len% THEN len%=num%

version just before your post, then it's irrelevent what size the files are (and if they are a multiple of 4), and it's irrelevent how long the buffer is, so if running out of memory you can make it smaller right down to about 10 bytes or so.

Edit, eg:
xxxx REM when program initialises
xxxx max%=80
xxxx DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256
xxxx DIM data% max%-1

3820 DEFPROCVA(mn$)
3830 in%=OPENIN(mn$):IF in%=0 THEN ENDPFOC
3840 num%=EXT#in%
3850 REPEAT
3860 len%=max%:IF num%<len% THEN len%=num%
3870 PROCgbpb(4,in%, data%,len%,0)
3880 FOR n%=0 TO len%-1:PROCserial_send(data%?n%):NEXT n%
3890 num%=num%-len%
3900 UNTIL num%=0
3910 CLOSE#in%:in%=0
3920 ENDPROC
3980 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
3990 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:CALL &FFD1:ENDPROC
4010 DEFPROCserial_send(byte%)
4020 VDUbyte%
4030 ENDPROC

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
vela025
Posts: 198
Joined: Tue Jun 16, 2020 4:48 pm
Contact:

Re: Sending Teletext over Serial

Post by vela025 »

jgharston wrote: Thu Feb 22, 2024 12:05 pm If you use the
len%=max%
IF num%<len% THEN len%=num%

version just before your post, then it's irrelevent what size the files are (and if they are a multiple of 4), and it's irrelevent how long the buffer is, so if running out of memory you can make it smaller right down to about 10 bytes or so.
Thanks again for this, it has sped things up considerably. Will it matter that X% and Y% are used elsewhere in the program, it doesn't seem to have caused a problem...but might it after a bit more testing? They are used in the following locations:

Code: Select all

2790DEFFNba:A%=145:X%=1:B%=(USR(&FFF4)AND&1FF0000)DIV&10000:IFB%AND&100:=-1
2820DEFPROCbc(Y%):A%=138:X%=2:CALLOSB%:ENDPROC
3550DEFPROCPP(X%,Y%,A$):LOCALI%,J%:I%=&7BFF+40*Y%+X%:FORJ%=I%+1TO&7C27+40*Y%:?J%=0:NEXT:FORJ%=1TOLENA$:I%?J%=ASCMID$(A$,J%):NEXT:ENDPROC
I'm getting the occasional no room error, so I'll hunt through the code and try find some space from somewhere and reduce max%

Thanks again! :D
BBC Master 128, PiTubeDirect, RGB2HDMI, Twin 5 1/4" & GoTek, BeebSCSI, Retroclinic Datacentre (E), Oki Microline 280, Sony TCM-737, Miracle WS2000 Modem, WE Mouse. BeeBS BBS - http://beebs.ddns.net
julie_m
Posts: 587
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Sending Teletext over Serial

Post by julie_m »

vela025 wrote: Thu Feb 22, 2024 2:34 pmWill it matter that X% and Y% are used elsewhere in the program, it doesn't seem to have caused a problem...but might it after a bit more testing? They are used in the following locations:

Code: Select all

2790DEFFNba:A%=145:X%=1:B%=(USR(&FFF4)AND&1FF0000)DIV&10000:IFB%AND&100:=-1
2820DEFPROCbc(Y%):A%=138:X%=2:CALLOSB%:ENDPROC
3550DEFPROCPP(X%,Y%,A$):LOCALI%,J%:I%=&7BFF+40*Y%+X%:FORJ%=I%+1TO&7C27+40*Y%:?J%=0:NEXT:FORJ%=1TOLENA$:I%?J%=ASCMID$(A$,J%):NEXT:ENDPROC
You could always use something like

Code: Select all

LOCALA%,X%,Y%
inside your FN / PROC definitions. Just like variables whose names match the parameters in the DEFinition (and, indeed, using the same code in the BASIC interpreter .....), the original values of any variables declared LOCAL inside a function or procedure are saved temporarily, so the names can safely be reused within the function / procedure; then the original values are restored on encountering an = or ENDPROC.

So try

Code: Select all

2790DEFFNba:LOCALA%,X%,B%:A%=145:X%=1:B%=(USR(&FFF4)AND&1FF0000)DIV&10000:IFB%AND&100:=-1
2820DEFPROCbc(Y%):LOCALA%,X%:A%=138:X%=2:CALLOSB%:ENDPROC
3550DEFPROCPP(X%,Y%,A$):LOCALI%,J%:I%=&7BFF+40*Y%+X%:FORJ%=I%+1TO&7C27+40*Y%:?J%=0:NEXT:FORJ%=1TOLENA$:I%?J%=ASCMID$(A$,J%):NEXT:ENDPROC
I can see some stuff missing between lines 2790 and 2820 -- line 2790 is trying to read a character from the RS423 input buffer using OSBYTE &91 and does a conditional =-1 if the carry flag was set (meaning the buffer is empty); so my money is on the next line returning the value that was in the Y register (which is the character successfully read) and will be in B% AND &FF.
User avatar
jgharston
Posts: 5321
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Sending Teletext over Serial

Post by jgharston »

It's common to use a global control block and have X%/Y% always pointing to it, setting them at the start of the main program loop and after any errors (which is often the same place).

If you don't want to do that, you could use this sort of code:

3980 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
3985 LOCAL X%,Y%:X%=ctrl%:Y%=X%DIV256
3990 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:CALL &FFD1:ENDPROC
I can see some stuff missing between lines 2790 and 2820 -- line 2790 is trying to read a character from the RS423 input buffer using OSBYTE &91 and does a conditional =-1 if the carry flag was set (meaning the buffer is empty); so my money is on the next line returning the value that was in the Y register (which is the character successfully read) and will be in B% AND &FF.
And you could optimise it to just:

2790DEFFNba:LOCAL A%,X%:A%=145:X%=1:A%=USR &FFF4:IF (A% AND &1000000):=-1
...then the rest of code, it looks like it's missing returning the byte read, so:
2790DEFFNba:LOCAL A%,X%:A%=145:X%=1:A%=USR &FFF4:IF (A% AND &1000000):=-1 ELSE =(A% AND &FF0000) DIV 65536
which can be optimised to:
2790DEFFNba:LOCAL A%,X%:A%=145:X%=1:A%=((USR &FFF4) AND &1FF0000) DIV 65536:IF A%>255:=-1 ELSE =A%
or even:
2790DEFFNba:LOCAL A%,X%:A%=145:X%=1:A%=((USR &FFF4) AND &1FF0000) DIV 65536:=A% OR (A%>255)

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
julie_m
Posts: 587
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Sending Teletext over Serial

Post by julie_m »

Also, in case it's not obvious, a file with ANSI control sequences in it will be longer than 1024 bytes; for instance, the ANSI sequence for "red text" is &1B &5B &33 &31 &6D (or maybe &9B &33 &31 &6D), as opposed to just &81 on the BBC micro.
vela025
Posts: 198
Joined: Tue Jun 16, 2020 4:48 pm
Contact:

Re: Sending Teletext over Serial

Post by vela025 »

julie_m wrote: Thu Feb 22, 2024 5:53 pm I can see some stuff missing between lines 2790 and 2820 -- line 2790 is trying to read a character from the RS423 input buffer using OSBYTE &91 and does a conditional =-1 if the carry flag was set (meaning the buffer is empty); so my money is on the next line returning the value that was in the Y register (which is the character successfully read) and will be in B% AND &FF.
Hi Julie I'm always blown away by peoples knowledge on *. and you did not disappoint! :D. I had only included the lines that used the variables X and Y, here are the missing lines between 2790-2820:

Code: Select all

2790DEFFNba:A%=145:X%=1:B%=(USR(&FFF4)AND&1FF0000)DIV&10000:IFB%AND&100:=-1
2800:=B%
2810DEFFNbb:S%=TIME:REPEAT:B%=FNba:UNTILB%>-1ORTIME-S%>100:=B%
2820DEFPROCbc(Y%):A%=138:X%=2:CALLOSB%:ENDPROC
jgharston wrote: Thu Feb 22, 2024 10:19 pm If you don't want to do that, you could use this sort of code:

3980 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
3985 LOCAL X%,Y%:X%=ctrl%:Y%=X%DIV256
3990 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:CALL &FFD1:ENDPROC
Ok thanks I think this will be the method I go for, after a bit more testing it seems to only be effected with returning to the Main menu from downloading or uploading a file. Will that mean that I no longer need to define X and Y at the outset with:

Code: Select all

DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256
or would LOCAL X and Y still make use of this same space? Apologies if this is a really obvious question.

I'm running PROCgbpb with a 20 byte buffer which does make a big difference, I upped it to 25 but the curse of "no room" returned. I have started to play with the idea of splitting the program in to modules as very few people use the downloads/uploads area, I thought I could separate this out in to a different program that's only loaded if needed. I've successfully (I think) split the downloads and uploads code from the main program, so that everything other than download and uploads works fine (this allows for a 128byte buffer...possibly more but I haven't tried any higher) which takes a mode 7 page down to just under 2 seconds and an ANSI page to 5.

One example I found of another program doing this used something similar to the following:

Code: Select all

DIM over%=(TOP-2)
...
OSCLI "LOAD PROG2 "+STR$~over%
I've tried the same, but it causes OBBS to get stuck in a loop at the DIM over%=(TOP-2) part. Without this it doesn't get stuck in a loop but I think loads PROG2 over the top of the program currently in memory causing no such variable errors. I assume reserving space for PROG2 with DIM would be the same as having the PROG2 listings within PROG1 and end up not saving any space. PROG2 would still need some of the variables and strings from PROG1 so I presume I can't use CHAIN. Likewise PROG2 would need to make use of Functions and Procedures defined in PROG1...(or would it be best to duplicate these in PROG2?). I've set PROG1 to have listing from 10-3990 and PROG2 picks up at 4000-5500.

You're supposed to be able to chain an external program from within OBBS(although the feature seems missing from both archived versions) as log as the program you're chaining contains the following:

Code: Select all

...at the start
7 BBC%=OPENIN":2.O.LAST":INPUT#BBC%,user$,last$:CLOSE#BBC%:IFlast$<>""THENuser$=user$+" "+last$
...at the end
10045 IF ERR=88 THEN Z%=TRUE:L%=TRUE:CHAIN"RETURN"
10050 PRINT''''''"Sorry, System error ";:REPORT:PRINT" at line ";ERL;" file name of file"
10055 IF ERR=88 THEN REM Z%=TRUE:PA.=&7000:CH."RETURN"
10060 PRINT''
10070 PRINT"Do you wish to return to the BBS ? ";:A$=GET$:IFA$="Y"THEN Z%=FALSE:PAGE=&7000:CHAIN"RETURN":ELSE RUN
Maybe I could use something similar to open the Downloads/Uploads part of the program (but then I think I'd still have the problem of it referring back to PROCs and FNs from the main program.
julie_m wrote: Fri Feb 23, 2024 4:12 pm Also, in case it's not obvious, a file with ANSI control sequences in it will be longer than 1024 bytes; for instance, the ANSI sequence for "red text" is &1B &5B &33 &31 &6D (or maybe &9B &33 &31 &6D), as opposed to just &81 on the BBC micro.
Yes they would be if I were using full screens, so I'm cheating a bit and making them shorter than usual (around 15-20) rows and between 40-60 columns, so they vary in size, but the largest is 1.6kb but with the speed improvements I might venture to having a full 80 x 24 to give it a good test.

And again thank you all for your help! :D
BBC Master 128, PiTubeDirect, RGB2HDMI, Twin 5 1/4" & GoTek, BeebSCSI, Retroclinic Datacentre (E), Oki Microline 280, Sony TCM-737, Miracle WS2000 Modem, WE Mouse. BeeBS BBS - http://beebs.ddns.net
julie_m
Posts: 587
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Sending Teletext over Serial

Post by julie_m »

Variables used as function / procedure parameters in the DEF statement, or declared LOCAL within the body, get their initial values copied to the procedure stack (which grows downwards from just below HIMEM; which in turn is normally just below the bottom of screen memory, unless you deliberately changed it). New values assigned to those variables are stored in their existing slots in the BASIC variable database for the duration of the function / procedure, and then overwritten from the proc stack when it exits.

(Apropos of nothing, this is the opposite way to how PHP does it .....)

This allows a PROC or FN to call itself recursively, as long as due care is taken, without having to worry about stomping on variable values. (You might have to worry about running out of stack space, if the depth builds up too much .....)

There is a slight issue with defining X% and Y% "up front" to point to a common parameter block to use for all OSWORD and similar calls with something like DIMX%32:Y%=X%DIV256; and that is, once you have created new, temporary versions of X% and Y%, as parameters or LOCAL variables, those temporary values will be passed downstream to all FNs and PROCs called from within the current one! You cannot get them back, until you exit fully to the main program. So it's probably worth dedicating a variable (maybe even a static int, for speed) to hold the base address of the parameter block.


Note also that, very occasionally, where a MOS call returns one or more 32-bit addresses, it's worth putting the parameter block somewhere between &0404 and &46B; since this is where A% to Z% are stored (A% is at &404, B% is at &408 and so forth), just so you can pick up any returned values directly from the static integer variables. If you declared these variables LOCAL, then their old values will even be restored on exit.


Here's a program that demonstrates visually how the procedure stack grows:

Code: Select all

   10HIMEM=&8000
   20VDU22,4,28,0,15,39,0
   30INPUT"Enter a number :"A%
   40PRINT;A%;"!=";FNfac(A%)
   50END
   60DEFFNfac(A%)
   70IFA%>1THEN=FNfac(A%-1)*A%ELSE=1
This sets HIMEM to the end of screen memory, does a sneaky MODE change without telling BASIC about it (so HIMEM doesn't get updated) and defines a text window in just the upper half of the screen, so as not to encroach onto the growing stack. It then calculates a factorial recursively, and the stack grows across the bottom part of the screen each time the function calls itself. (This won't run out of stack space in this form, because 34! won't fit into a signed 4-byte value, and the program crashes with a "Too big" error.) You can try adding more parameters and creating some local variables to get an idea how much stack space is being used by this.
WrightStuff
Posts: 81
Joined: Fri Mar 16, 2012 1:54 pm
Location: Derby
Contact:

Re: Sending Teletext over Serial

Post by WrightStuff »

On the subject of 'No room'. You can use this to output your current byte totals for PROG,VARS usage and FREE.
I grabbed this from somewhere else so apologies if its slightly innacurate!, I've always found it useful anyway.
With the caveat it doesn't know anything about any machine code segments.
You should see FREE at 0 when your prog runs out of space

Code: Select all

a=TOP-PAGE:b=!2 AND &FFFF:P."PROG: "+STR$(a)+" VARS: "+STR$(b-a)+" FREE: "+STR$(HIMEM-b)
vela025
Posts: 198
Joined: Tue Jun 16, 2020 4:48 pm
Contact:

Re: Sending Teletext over Serial

Post by vela025 »

Hi,

I've now split the download section of obbs from the main program by storing the required strings and variables in a file before chaining the transfer program, and then it loads them back in on chaining the main obbs program. It all works well, apart from if you use the CP/M download or Upload option when in the transfer section of the program (128byte Xmodem)... it will download and upload the files as normal but upon returning to the main OBBS program I get the following error when trying to open the file that stores the saved strings and variables from the previous session:

After a Download:

Code: Select all

Channel on channel 145 at line 91
After an Upload

Code: Select all

Channel on channel 138 at line 91
I've used TRACEON (and also used old school paper and pencil) to following the procedures to see what's happeneing. The file being transfered (F%) is being closed before returning to the main obbs program, however it's unable to open the file needed within the main obbs program to restore the previous session. But this is only following cp/m transfer, it is fine if either the user selects ascii, ascii with control codes or abort. Selecting any of these options (once the action is complete) returns the user back to the main program where they left off.

I've placed in CLOSE#0 and at the start of OBBS and just prior to the Download program returning to the main program, but the error is the same.

This is the section of the downloads program that is dealing with CP/M transfers.

Code: Select all


   50 Lm=TIME:nul%=0:soh%=&01:eot%=&04:ack%=&06:nak%=&15:can%=&18:eof%=&1A:OSB%=&FFF4:day=?&80:month=?&81:year=?&82
   60 IF cmd$="DNLD" THEN PROCao(prm$)


  150 DEFPROCao(file$)
  160 CLS:PRINT"The following protocols are"'"available:":PRINT"1ASCII only"'"2ASCII with buffer control codes."'"3CP/M protocol"'"orAbort download":PRINT'"Which? ";:CM=FNy:VDUCM:IFCM=51PROCam(file$):ENDPROC

  110 DEFPROCam(file$):PRINT'"CP/M Transfer - Are you sure? ";:REPEATCM=FNy:UNTILCM=110ORCM=121:VDUCM,13,10:IFCM=110ENDPROC
  120 F%=OPENINfile$:JJ%=F%:IFF%=0PRINT"Sorry, File not Fd%":ENDPROC
  130 PRINT'"File open, awaiting initial NAK"'':CALLD%:T%=EXT#F%:W%=0:PROCbe:JJ%=0:CLOSE#F%:CALLC%:ENDPROC
  
   500 DEFFNba:A%=145:X%=1:B%=(USR(&FFF4)AND&1FF0000)DIV&10000:IFB%AND&100:=-1
  510 :=B%
  520 DEFFNbb:S%=TIME:REPEAT:B%=FNba:UNTILB%>-1ORTIME-S%>100:=B%
  530 DEFPROCbc(Y%):A%=138:X%=2:CALLOSB%:ENDPROC
  540 DEFPROCbd:REPEATUNTILFNbb=-1:ENDPROC
  550 DEFPROCbe:PRINT'"[Transmit]":IFT%=W%E%=13:PROCax:ENDPROC
  560 p%=W%:bl%=1:try%=0:E%=0:REPEAT:S%=TIME:REPEAT:B%=FNba:UNTILB%=ack%ORB%=nak%ORTIME-S%>2000:IFB%=ack%PROCbgELSEIFB%<>nak%E%=9
  570 try%=try%+1:PROCay:IFE%=0PRINT"[BLOCK]":PROCbfELSEIFE%=1PROCbc(eot%):PRINT"[EOT]"ELSEIFE%=9PROCbh
  580 UNTILE%=9ORE%=11:PROCax:ENDPROC
  590 DEFPROCbf:cks%=0:PROCbc(soh%):PROCbc(bl%):PROCbc((NOTbl%)AND&FF):FORcc%=0TO127:IFp%+cc%>=T%B%=nul%ELSEPTR#F%=(p%+cc%):B%=BGET#F%
  600 PROCbc(B%):cks%=(cks%+B%)AND&FF:NEXTcc%:PROCbc(cks%):ENDPROC
  610 DEFPROCbg:try%=0:IFE%=1THENE%=11:ENDPROC
  620 p%=p%+128:bl%=(bl%+1)AND&FF:IFp%>=T%E%=1
  630 ENDPROC
For both Uploads and Downloads E% returns 11 before returning to the main program.

Any ideas?

Edit:

It might be worth mentioning the main program is chained from a Machine Code starter (below), I'm guessing that something above is having some effect on a memory location mentioned in the MC which is then having a knock on effect when returning back to the main program.

Code: Select all

  
  150 *FX2 2
  151 MODE 135
  160 ?&FE6E=0
  170 SPACE=&B30
  180 lowercase=&70:?lowercase=FALSE
  190 linefeeds=&71:?linefeeds=FALSE
  200 colours=&72:?colours=0
  210 oswrchv=&74
  220 CTRL_Kenable=&77:?&77=FALSE
  225  xflg=&F8:?&F8=0
  230 temp=&76
  240 FLAG=&92
  250 OSWRCH=&FFEE
  260 WRCHV=&20E
  270 NVWRCH=&FFCB
  280 DIMPP% 256:FORpass=0 TO 2 STEP 2
  290 P%=PP%:[OPT pass:.check
  300 LDA#0:STA&423
  310 LDA#&23:STA&420
  320 LDA#234:LDX#0:LDY#&FF:JSR&FFF4
  330 CPX#0:BNE tube
  340 LDA#&80:STA&421:RTS
  350 .tube
  360 LDA#&84:JSR&FFF4
  370 STY&421
  380 RTS
  390 ]:NEXT:CALL check
  400 FOR pass=0 TO 2 STEP 2
  410 P%=SPACE
  420 [OPT pass
  430 .C% LDX#2:\*** CHANGE OSWRCH VECTOR
  440 LDAWRCHV:CMP#newoswrch MOD256:BEQ dontdoitagain
  450 SEI
  460 LDA WRCHV:STA oswrchv
  470 LDA WRCHV+1:STA oswrchv+1
  480 LDA #newoswrch MOD256:STA WRCHV
  490 LDA #newoswrch DIV256:STA WRCHV+1
  500 CLI
  510 .dontdoitagain
  520 STX&422:RTS
  530 .D% \*** RESTORE OSWRCH VECTOR
  540 SEI
  550 LDAoswrchv:STAWRCHV:LDAoswrchv+1:STAWRCHV+1:CLI:RTS
  560 .newoswrch \ *** NEW OSWRCH ROUTINE
  570  STA&73:PHP:PHA:TXA:PHA:TYA:PHA
  580 LDA#3:LDX#3:LDY#0:JSR&FFF4
  582  .ckempty LDA #152:LDX #2:JSR &FFF4:BCC ckempty
  585  .ckloop LDA xflg:BNE ckloop
  590 LDA &73
  600 CMP #10
  610 BNE notlinefeed
  620 LDA linefeeds
  630 BEQ return
  640 LDA#10
  650 JSR NVWRCH:JMP return
  660 .notlinefeed
  670 LDA lowercase
  680 BNE lcaseok
  690 LDA &73
  700 CMP #95
  710 BCC lcaseok
  720 AND#223
  730 CMP#128:BCC ptrit:LDA#32:.ptrit
  740 JSRNVWRCH:JMPreturn
  750 .lcaseok
  760 LDA&72:BNE colsok
  770 LDA&73:CMP#128:BCC colsok
  780 LDA#32:JSRNVWRCH:JMPreturn
  790 .colsok
  800 LDA&73:JSRNVWRCH
  810 .return
  820 LDA#3:LDX#0:LDY#0:JSR&FFF4
  830 PLA:TAY:PLA:TAX:PLA:PLP
  840 LDA&73:JSRNVWRCH:RTS
  940  .event \ **** EVENT HANDLER
  950  PHP:PHA:TXA:PHA:TYA:PHA
  960 LDA#&7A:JSR&FFF4:INX:BEQ out:PLA:PHA:TAY:LDA#138:LDX#1:JSR&FFF4:LDA#21:DEX:JSR&FFF4:.out PLA:PHA
  970 AND#127
  980 CMP#&13:BEQ stop
  990 CMP#&11:BEQ start
 1000 CMP#9:BEQ escape
 1010 CMP#&B:BEQ quit
 1020 CMP#13:BNE return2:LDA&FE60:ORA#128:STA&FE60
 1030  .return2
 1040 .return3
 1050 PLA:TAY:PLA:TAX:PLA:PLP
 1060 RTS
 1070 .stop
 1080 LDA&FE60:AND#127:STA&FE60:LDA #1:STA xflg
 1090 .rtn
 1100 PLA:LDA#0:PHA
 1110  JMPreturn2
 1120 .start
 1130 LDA&FE60:ORA#128:STA&FE60:LDA #0:sta xflg
 1140 JMPrtn
 1150 .escape
 1160 LDA#&79:LDX#0:LDY#0:JSR&FFF4
 1170  CPX#&60:BNE return2
 1180 LDA#125:LDX#0:LDY#0:JSR&FFF4
 1190  LDA#0:STAFLAG:JMPreturn2
 1200  .quit LDA&77:BEQreturn2:LDA#2:STAFLAG:LDA#125:LDX#0:LDY#0:JSR&FFF4:JMPreturn2
 1210 .G% SEI:LDA#event MOD256:STA&220
 1220 LDA#event DIV256:STA&221
 1230 LDA#HH% MOD256:STA&202
 1240 LDA#HH% DIV256:STA&203
 1250 CLI
 1260 RTS
 1360 .HH%  \ *** NEW ERROR HANDLER
 1370  PHP:PHA:TXA:PHA:TYA:PHA
 1380 LDY#0:LDA(&FD),Y
 1390 CMP#0
 1400 BEQ noroom
 1410 PLA:TAY:PLA:TAX:PLA:PLP
 1420 JMP !&202 AND&FFFF
 1430 .noroom
 1440 PLA:TAY:PLA:TAX:PLA:PLP
 1450 BRK
 1460 EQUB 89
 1470 EQUS "No Room"
 1480 EQUB 0
 1490 ]:NEXT
 2350 *FX4,2
 2360 *FX225,1
 2370 *FX226,16
 2380 *FX227,32
 2390 *FX228,48
 2400 *FX221,64
 2410 *FX222,80
 2420 *FX223,96
 2430 *FX224,112
 2600 *FX229,1
 2610 *FX14,2
 2620 *FX181,0
 2630 *FX7,7
 2640 *FX8,7
 2650 ?&FE62=128:*FX15
 2651 *FX2,2
 2652 *FX3,7
 2653 OSCLI"FX21,1"
 2654 PRINT"AT":WAIT$=INKEY$(75)
 2655 PRINT"ATS0=1":WAIT$=INKEY$(75)
 2656 OSCLI"FX15"
 2660 CHAIN"OBSMOD"
 2670 A$="*FX234,255"+CHR$13+"CHAIN""OBSMOD"""
 2671 CHAIN"OBSMOD"
 2680 A%=138:X%=0
 2690 FORI%=1 TO LEN A$
 2700 Y%=ASCMID$(A$,I%,1):CALL&FFF4
 2710 NEXT
 2720 END
BBC Master 128, PiTubeDirect, RGB2HDMI, Twin 5 1/4" & GoTek, BeebSCSI, Retroclinic Datacentre (E), Oki Microline 280, Sony TCM-737, Miracle WS2000 Modem, WE Mouse. BeeBS BBS - http://beebs.ddns.net
Post Reply

Return to “programming”