+MrFish #1 Posted December 27, 2011 I'm doing some coding in PL65 using the 2nd cracked version (where compiling actually produces run-able code). I'm having a problem getting several related library procedures to execute properly when being called from a procedure that has a STRING passed as one of it's parameters. The following code example produces an executable in which the PROC WRTSTR (from 'Terminal.lib') in the PROC PrintText does not print the string A$. At this point during execution the program continuously prints to the screen what looks like the contents of memory. INCLUDE D:Terminal.lib !-------------------------------------- PROC PrintText (STRING A$[20]) INT I BEGIN FOR I=1 TO 50000 DO NEXT WRTSTR (A$) REPEAT FOREVER END !-------------------------------------- MAIN () STRING A$[20] BEGIN A$ = "Main Proc " WRTSTR (A$) A$ = "PrintText Proc " PrintText (A$) END If I code the PROC PrintText without a STRING as a parameter I can then execute a WRTSTR without any problems. This example will work whether I have no parameters or if any parameters that are passed are not STRINGs. INCLUDE D:Terminal.lib !-------------------------------------- PROC PrintText () INT I STRING A$[20] DATA "PrintText Proc "; BEGIN FOR I=1 TO 50000 DO NEXT WRTSTR (A$) REPEAT FOREVER END !-------------------------------------- MAIN () STRING A$[20] BEGIN A$ = "Main Proc " WRTSTR (A$) PrintText () END Also, WRTSTR will fail in PROC PrintText if I pass a STRING parameter even if I don't use the passed parameter in the WRTSTR statement. This problem persists with the WRTLN function as well, which is just a variant that sends an EOL at the end of the string being printed to the screen. Using PCHAR (and altering the code accordingly) instead of WRTSTR cures the problem, but I'm still wondering why WRTSTR and WRTLN will not function properly in this particular case? I'm running the compiler off a DOS 2.5 disk rather than the uploaded SpartaDOS disk. I've tried compiling and running it under SpartaDOS X using the original disk and the DOS 2.5 disk as well and it doesn't change the outcome. I've run the executables under emulation and with real hardware and I've compiled it using real hardware. There are no examples of using WRTSTR or WRTLN in the sample game program that Noahsoft included on the PL65 disk. It uses PCHAR for it's title screen. Normally I would post this in the programming forum, but since the cracked disk was posted on the main forum and since this may be a problem with the cracked compiler or an associated library file, I'm posting it here. Here are the files for the above example, including a copy of PL65 on a DOS 2.5 disk: PL65 Example.zip Any help is appreciated. Thanks, MF Quote Share this post Link to post Share on other sites
flashjazzcat #2 Posted December 27, 2011 Interesting. In either case, surely WRTSTR is passed a pointer value. Only difference I can see is in use the parameter stack between the two calls. I've had a play around with it but am not making any progress. It's an interesting language, this. Pascal-like with assembler thrown in. I have to say it's given me an appetite for coding on the A8 again - which I have sorely missed since going cross-development. I wish we had the sources for PL65 since I think the compiler's I/O could probably be speeded up (assuming it uses single byte put / get). Anyway - getting away from the point here. I'll keep playing with this. Quote Share this post Link to post Share on other sites
DearHorse #3 Posted May 8, 2014 (edited) Hi Mr Fish, I just stumble over your text now and I don't know if my quote may be usefull for you by now in 2014 ... I see you used the same A$ declaration for your procedure and for global variable. perhaps if compiler is single pass, reservation for A$ as var either as global and local can make a problem. trying to change to B$ in proc declaration, just to see ? perhaps also map A$ to see how strings are implemented (pascal as PL65 seems to get its inspiration use the first byte of data string to define the lenght of the string (quicker process) while C (azt) check each char/byte to see if zero (slower). perhaps another method here, I don't know. I stumble on your post because PL65 interest me as he can mix ASM & high level language (as we could do in turbo-pascal at his time) (and it remember me a bit the PLM I used 20 years ago on 8031/ 8051 microcontrollers). best regards Rudy Edited May 8, 2014 by DearHorse Quote Share this post Link to post Share on other sites
576XE #4 Posted May 9, 2014 Hello,Friends, Resently I've tried to write simplest TSR in pl65. ! VBI Procedure for changing colors ! It Stays TSR after loading BYTE HELPFG=$02DC,COLBAK=$02C8 CONST HELP=$11,BLUE=$80,RED=$32 BYTE OLDHLP INT DOSINI=$0C,MEMLO=$2E7,FINISH PROC VBI*() CONST SYSVBV=$E45F BEGIN LDA HELPFG CMP OLDHLP BEQ Exit CMP #HELP BNE Exit ! LDA COLBAK CMP #RED BNE ToRED ! LDA #BLUE STA COLBAK GOTO Exit :ToRED LDA #RED STA COLBAK :Exit LDA HELPFG STA OLDHLP LDA #$07 STA HELPFG JMP SYSVBV END PROC SetVBI*() CONST SETVBV=$E45C BEGIN STX XSAVE LDA #$06 LDX #VBI/$100 LDY #VBI AND $FF JSR SETVBV LDX XSAVE END PROC NoRESET*() BEGIN GOTO INIT ! This part is Resident. :TROJAN RTS :BUMPUP LDA #FINISH AND $FF STA MEMLO LDA #FINISH/$100 STA MEMLO+1 RTS :TSR JSR TROJAN JSR BUMPUP JSR SetVBI LDA #BLUE STA COLBAK RTS ! This part is executed at power up only. :INIT LDA DOSINI STA TSR+1 LDA DOSINI+1 STA TSR+2 ! LDA #TSR AND $FF STA DOSINI LDA #TSR/$100 STA DOSINI+1 ! JSR BUMPUP END CONST [email protected] MAIN() BEGIN COLBAK=BLUE SetVBI*() FINISH=LoMem NoRESET*() END You can see that it's really assembler, but I know that it can be written in clear PL65, as it's no more then moving data between variables, or filling data with the help of pointers. The only thing I can't solve lays in single-pass nature of pl65 and it's assembler. All things must be declared before compilation. I can't find a way to properly fill address field of JSR TROJAN statement. I'm not a programmer at all, sorry. Quote Share this post Link to post Share on other sites
576XE #5 Posted May 13, 2014 (edited) Dear Mr Fish, This is CITE from PL65 manual: Parameter variables are treated within the procedure exactly the same as local variables, ... Thus this strange behavior may be caused by the absense of proper initialisation for PROC PrintText (STRING A$[20]) I mean that as parameter is LOCAL, then A$ in PrintText is different then A$ in MAIN ANYWAY! Parameter declaration in PrintTest only says compiler about the quantity of bytes needed on stack for transmitting to PROC and no more. Really A$ in PrintText never was declared as no address and no length can't be accessed by compiler. This may help IMHO: INCLUDE TERMINAL.LIB STRING A$[20] ! Declaration and memory allocation for string ... PROC PrintText (STRING A$[20]) ! Here compiler knows A$ INT I BEGIN FOR I=1 TO 50000 DO NEXT WRTSTR (A$) REPEAT FOREVER END ... MAIN() ! Here compiler knows the same A$ as PrintText thus we can make ! proper initialization of string in MAIN() BEGIN ... END In this case A$ is seeing for both PrintText and MAIN. Another way may be using POINTERS to beginning of string. Another note is that real dimension of any string MUST be LEN+4. 2 bytes is string address and two bytes is it's lenght. That's all Folks. Edited May 13, 2014 by 130XE Quote Share this post Link to post Share on other sites
576XE #6 Posted April 19, 2016 I recently found that the meaning of real declaration of string in PL65 is like this: Adr (2 bytes), Len (2 bytes), String (len-1 bytes), EOL(1 byte) PL65 works with ASM values anyway, thus it can't exclude $9B FROM string, because another program may use $9B as terminator. I recently replaced EOL with SPACE. It works! It was NOT string-dedicated function! (It was some kind of byte oriented function.) String-dedicated functions - all pays attention to EOL after string. Some of them using it but some not. Quote Share this post Link to post Share on other sites
576XE #7 Posted December 17, 2016 Hi there, FRIENDS!Recently I found very convenient russified font editing program... It takes all my mind and I decided to write some PL65 code for autorun fontloader for programming in russified BASIC F.E...The PL65 is really the product of ingenious master who placed all it's ideas in lang and never tried to exhaustively testing it.The code: INCLUDE TERMINAL.LIB MAIN() STRING S$[2] BEGIN PUT(0,125) WRTLN("ENTER STRING, PLEASE ...") S$=INPUT$() WRTSTR("LEN OF INPUT$ = ") WRITE(LEN(S$)) END Being tested and working it gives this picture while entered "Return" only: Thus you know the beast side of beauty!This problem may be simply recognized.Manual says that the string in PL65 is defined as addr/len(it means that TERMINAL.LIB based on pointers)but ATARI's SIO is defined in other way: addr/EOLI mean that PL65 never recognizes EOL, because it's internal control symbol for PL65.I want to say that when some of our procedures or functiones calls SIO,SIO evidently returns EOL with it's output!And PL65 adds 1 to LEN(string$) Quote Share this post Link to post Share on other sites
576XE #8 Posted December 17, 2016 Here i'll add some workable code: INCLUDE TERMINAL.LIB STRING FName$[20] ! Procedures and Functions !------------------------- PROC Cls() BEGIN PUT(0,125) END !------------------------- FUNC Prompt$() STRING Out$[20] BEGIN Cls() WRTLN("INPUT:") WRTLN("ENTER FILENAME TO LOAD, PLEASE...") Out$=INPUT$() END Out$ !------------------------- PROC Adopt() STRING D$[20] DATA "D:"; BEGIN IF LEN(FName$)=1 THEN ERROR(7) ENDIF IF (FName$[1,1]=":" OR FName$[2,2]=":") THEN ! If FName$ contain ':' then we need not concatenation! RETURN ELSE ! In contrary we need it! D$[LEN(D$)]=FName$ FName$=D$ ENDIF END ! Main program !------------------------- MAIN() BEGIN TRAP retry :again FName$=Prompt$() Adopt() WRTLN(FName$) GOTO exit :retry TRAP retry GOTO again :exit END It's filename normalization. Here I must say that simple code: (FName$[1]=":" OR FName$[2]=":") is absolutely NOT Working!!! Because of PL65 manner of string nature of compared values. As them represents both addresses and lengthes they do NOT compares identical values at all! Addr or Len will be different anyway! WRTSTR("FILE") will never give us addr/len such as WRTSTR("F") Quote Share this post Link to post Share on other sites
Tickled_Pink #9 Posted December 17, 2016 I used PL65 almost exclusively for years and never realised there was a problem with WRTSTR. I'm wondering whether or not it's poor documentation that's the problem, although BITD I considered the documentation to be pretty good. However, I suspect that WRTSTR was one function that I didn't use that often. I tended to roll my own code, especially for game and demo projects. However, there is one project that I might still have lying around that may have used extensive use of WRTSTR. But then again IIRC use of the library functions caused a noticeable slowdown in writing text to the screen, so I may even have written my own code for that. Quote Share this post Link to post Share on other sites
576XE #10 Posted December 18, 2016 Hello Tickled_Pink! I must say that documentation of PL65 is very detailed and explicit. Particularly it means that to find something we need to read all book. My personal problem was that I could not realize for a long time that There Is NOT string PROCs in PL65 but only string FUNCs. Any PROC works with strings by default. Another thing is that we need not $-sign in FUNCs only in 2 cases - while writing compile-time expression and while using dot operator. For fast screen-out I often used line based output with precalculated array of 24 POINTER addresses of screen lines. Quote Share this post Link to post Share on other sites
Tickled_Pink #11 Posted December 21, 2016 I was just thinking about it now. Doesn't WRTSTR use the SIO functions in another library file - is it TERMINAL.LIB? That would account for the slowness of the text draw. So thinking about it now I probably did write my own for the project I was working on. I did a writeup on this and a version of the game Loopz that I had been working on for MyAtari magazine years ago. Both being written in PL65. I intend to finish them at some point if I still have the original disks. Life kind of got in the way. Loopz was around 75% complete. The other was a disk cataloguer which had a GUI-like interface insofar as the way that I displayed unavailable menu options greyed out using DLIs. Quote Share this post Link to post Share on other sites
576XE #12 Posted May 18, 2017 I really love PL65. It's the artifact of langs. Only thinking in it's way we can understand how the langs growth. Even ACTION! is premAtive because of lack of typedef syntax in PL65. YES! It's possible to wright something like Dynamic Memory Allocation in PL65 but ... Its POINTERS are too ancient at all!!! Anyway I love your interest in PL65. Quote Share this post Link to post Share on other sites