Sending Teletext over Serial
-
- Posts: 81
- Joined: Fri Mar 16, 2012 1:54 pm
- Location: Derby
- Contact:
Re: Sending Teletext over Serial
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.
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.
Re: Sending Teletext over Serial
No, I'm just a bit....erm....DIM.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.
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
-
- Posts: 81
- Joined: Fri Mar 16, 2012 1:54 pm
- Location: Derby
- Contact:
Re: Sending Teletext over Serial
The hang is a bit odd!
Is fle% definitely <=1024 ?
Typo at this line, I would've expected an error, but should be :
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%
Re: Sending Teletext over Serial
Sorry yes I change that after the post, as I wasn't sure and it started working for all the teletext pages: 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 $.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%
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
-
- Posts: 81
- Joined: Fri Mar 16, 2012 1:54 pm
- Location: Derby
- Contact:
Re: Sending Teletext over Serial
Another odd one !
Can you upload the .dsd file ?
Can you upload the .dsd file ?
- BeebMaster
- Posts: 7436
- Joined: Sun Aug 02, 2009 5:59 pm
- Location: Lost in the BeebVault!
- Contact:
Re: Sending Teletext over Serial
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).
(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).
Re: Sending Teletext over Serial
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.)
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
>_
Re: Sending Teletext over Serial
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.
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!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.
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
Re: Sending Teletext over Serial
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
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
>_
Re: Sending Teletext over Serial
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: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.
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
Thanks again!
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
Re: Sending Teletext over Serial
You could always use something likevela025 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
Code: Select all
LOCALA%,X%,Y%
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
Re: Sending Teletext over Serial
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
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)
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
And you could optimise it to just: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.
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
>_
Re: Sending Teletext over Serial
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.
Re: Sending Teletext over Serial
Hi Julie I'm always blown away by peoples knowledge on *. and you did not disappoint! . I had only included the lines that used the variables X and Y, here are the missing lines between 2790-2820: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.
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
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
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%
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
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!
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
Re: Sending Teletext over Serial
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: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.
(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
-
- Posts: 81
- Joined: Fri Mar 16, 2012 1:54 pm
- Location: Derby
- Contact:
Re: Sending Teletext over Serial
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
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)
Re: Sending Teletext over Serial
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:
After an Upload
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.
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.
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
Code: Select all
Channel on channel 138 at line 91
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
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