Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : MMBasic for Windows - betas
Page 9 of 30 | |||||
Author | Message | ||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4243 |
Peter, The option you give for text. Either in quotes when there is a space in the text, or, without quotes. Can that option als be applied to all commandline commands. So Run demo.bas (without quotes) Chdir wolf3d Edit test.bas Regards, Volhout PicomiteVGA PETSCII ROBOTS |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4042 |
Good morning Peter, You can run, but you can't hide from the power of unit-testing . 1. Here is a doozy: > list "tick-bug.bas" Dim t1%, t2%, t3%, t4% ' Comment this out and the ticks are accurate !!! Pause 1000 SetTick 100, inc_t1, 1 SetTick 50, inc_t2, 2 SetTick 10, inc_t3, 3 SetTick 2, inc_t4, 4 Pause 1000 SetTick 0, inc_t4, 4 SetTick 0, inc_t3, 3 SetTick 0, inc_t2, 2 SetTick 0, inc_t1, 1 Print Str$(t1%); " should be ~10" Print Str$(t2%); " should be ~20" Print Str$(t3%); " should be ~100" Print Str$(t4%); " should be ~500" Sub inc_t1() Inc t1% End Sub Sub inc_t2() Inc t2% End Sub Sub inc_t3() Inc t3% End Sub Sub inc_t4() Inc t4% End Sub > run "tick-bug.bas" 18 should be ~10 37 should be ~20 188 should be ~100 681 should be ~500 2. And here's a subtle one, that is probably also present on the CMM2 because I remember fixing it in MMB4L starting with the CMM2 error-handling code: list "error-bug.bas" Print " "; On Error Skip 1 Error "foo" Print "MSG: " Mm.ErrMsg$ > run "error-bug.bas" MSG: Error in line 5: foo Note how the Mm.ErrMsg$ has "incorrectly" got a leading CRLF. You need to output a CRLF when printing an uncaught error if the cursor is not at the start of the line, but you don't want that CRLF to be in Mm.ErrMsg$ itself, because that's just awkward. Best wishes, Tom Edited 2022-03-10 20:33 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
MMBasic.zip Fixes above issues |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4243 |
I know some of you already have exploited remote IO for MMB4W. This is my experiment. I connected a CMM1 through serial port to the laptop running MMB4W in Wine (linux). This is not different from attaching a picomite, but the CMM1 was lying on my desk. I configured COM2 to link to /dev/ttyACM0 in regedit. The CMM1 enumerates in linux as /dev/ttyACM0 Using the "AUTO" command (MMBasic 4.5 command for AUTOSAVE) and terminating with CTRL-C (CTRL-Z in modern MMBasic) I downloaded a program and run it. See attached code for MMB4W. The CMM1 does not need pre-programming. It is just a virgin machine with just MMBasic 4.5c 'test if we can remote program mites 'tested with maximite CMM1 'read ADC values from CMM1 in MMB4W 'open communication with the CMM1 open "com2:3800" as #1 'write a program to CMM1 from the data lines do read a$ if a$="" then a$=chr$(3) 'stop auto(save) mode with ctrl-C print #1,a$ pause 500 'estimated wait between commands loop until a$="run" 'gather the output of the CMM1 and print on screen c$="" do if loc(1)<>0 then b$=input$(1,#1) 'convert ascii data separated by <CR> to numeric value if b$=chr$(13) then print val(c$):c$="" else c$=c$+b$ end if end if loop while inkey$="" 'terminate the program print #1,chr$(3) 'stop running program pause 1000 close #1 end 'data statements containing the CMM1 program and commands data "new" 'clear program memory data "auto" 'enter autosave mode data "setpin 2,ain:settick 100,intr:do:loop:sub intr:print pin(2):end sub" 'the program data "" 'this symbolizes the chr$(3) data "run" 'start the program I did not know how to put chr$(3) in a data statement, so that is a kind of a "cludge". Edited 2022-03-11 07:50 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4042 |
Good morning Peter, thank you for your continued efforts. You've almost cleared all the errors reported by my unit-tests, though I will need to take another pass to ensure I haven't disabled any of them incorrectly. 1. LOF is not correctly implemented: > list "lof_bug.bas" Option Console Both Dim f$ = "hello_world.txt" Open f$ For Output As #1 Print #1, "Hello World"; Print Lof(#1) Close #1 Open f$ For Random As #1 Print Lof(#1) Close #1 On the CMM2: > run "lof_bug.bas" 11 11 On MMB4W: > run "lof_bug.bas" 0 0 2. EOF does not know that you've increased the maximum file number from 10 to 128: > list "eof_error.bas" Option Console Both Open "hello_world.txt" For Output As #11 Print #11, "Hello World" Print Eof(#11) Close #11 > run "eof_error.bas" Error in line 4: Invalid file number 3. Also there are some keywords not being highlighted in the editor: - CMM2: Console, Both & Random - MMB4W: Both & Random Edited 2022-03-11 20:32 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 830 |
When I try to start a program with the name "solarsys480x320.bas" with MMBASIC 0 "solarsys480x320.bas" , only follwing happens:That's all - nothing else happens... This program is in the same folder as MMBasic.exe "\Documents\MMBASIC" Frank |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
The output screen shows that MMBasic is looking in the root directory for the program and not finding it. To test this put a copy of it in "\" or include the path in the command. MMBASIC 0 "\Documents\MMBASIC\solarsys480x320.bas" If you want that to be the default path type:- OPTION DEFAULT PATH "\Documents\MMBASIC" or if you wish to keep the current default path:- OPTION SEARCH PATH "\Documents\MMBASIC" To see what the current default path is type:- OPTION LIST . Edited 2022-03-13 13:42 by phil99 |
||||
Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 830 |
@Phill99: THANKS! This helps a little bit... This is my business PC and there is a problem with the username - it is created there with a space in between. This has the consequence that the paths are often not recognized correctly... Let's see if I can't bend the path completely... Frank |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6099 |
A space in the default path is not a problem. Just start from "C:\" and enclose it in quotes when specifying. Seems to work for me... Jim Edit: If you have any Unicode characters in the path there could be problems. Edited 2022-03-14 07:02 by TassyJim VK7JH MMedit MMBasic Help |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
Tom I've fixed the two issues you found - both trivial. HOWEVER..... Option Console Both Open "hello_world.txt" For Output As #11 Print #11, "Hello World" Print Eof(#11) Close #11 On the CMM2 this gives 1 On MMB4W this give 0 If I change the code to fgetc 2 chars and ungetc them then I still don't see eof. It appears that feof is not useful when a file is open for write rather than read. What does MMB4L do? What is your implementation for MMfeof and or fun_eof ? |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4042 |
Hi Peter, I'd never tried calling Eof(#filedes) on a file I am writing before ;-) The answer is that MMB4L reports the system error "Bad file descriptor". The implementation looks like: int file_eof(int fnbr) { if (fnbr < 0 || fnbr > MAXOPENFILES) ERROR_INVALID_FILE_NUMBER; if (fnbr == 0) return 0; switch (file_table[fnbr].type) { case fet_closed: ERROR_NOT_OPEN; break; case fet_file: { FILE *f = file_table[fnbr].file_ptr; errno = 0; int ch = fgetc(f); // the Watcom compiler will only set eof after // it has tried to read beyond the end of file error_check(); int i = (feof(f) != 0) ? 1 : 0; error_check(); ungetc(ch, f); // undo the Watcom bug fix error_check(); return i; } case fet_serial: return serial_eof(fnbr); } ERROR_INTERNAL_FAULT; return 1; } But as you can see by the comment about the Watcom compiler this is just a rearranged version of Geoff's MMBasic for DOS/Windows code that I haven't dug into yet. The error is coming from trying to call fgetc() on a write-only stream, which I guess isn't that surprising. A straight call to the POSIX feof(f) function returns 0 which is what I would expect as no operation is being performed that sets that flag on the file-descriptor. Perhaps the CMM2 is wrong ? Or you should just hard-code Eof(#filedes) to return 1 when called on a write-only steam if that is what you think the behaviour should be ? I'm sorry that I don't have time for more investigation today, I slept poorly and need to go and do something about that. Best wishes, Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
More info FYI It works when the file is open for random IFF you fflush before the fgetc. It always returns 0 when the file is open for write |
||||
Plasmamac Guru Joined: 31/01/2019 Location: GermanyPosts: 554 |
Open "hello_world.txt" For Output As #11 Print #11, "Hello World" Print Eof(#11) Close #11 blitz3d shows 1,1 Blitzplus shows 1,0 Glbasic shows 1,1 qb64 shows 0,0 'Blitz3d and Blitzplus fileout = WriteFile("hello_dworld.txt") DebugLog Eof(fileout); eof WriteString( fileout, "MM4BW" ) DebugLog Eof(fileout); eof ? WaitKey() 'glbasic debug on OPENFILE(1, "EOF.txt", FALSE) DEBUG ENDOFFILE(1) WRITELONG 1, 1234 DEBUG ENDOFFILE(1) CLOSEFILE 1 SLEEP 2222 ' qb64 Open "EOFqb64.txt" For Output As #1 Print EOF(1) Print #1, x, y, z$ Print EOF(1) Close #1 Print "File created with data. Press a key!" K$ = Input$(1) 'press a key Plasma |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3802 |
Only one ungetc at a time is guaranteed to work so for portability don't do two or more. John |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6099 |
Just to add to the list PureBasic: If CreateFile(0, "hello_world.txt" ) Debug Lof(0) Debug Eof(0) Debug Loc(0) Debug "" WriteString(0,"Hello World",#PB_Ascii) Debug Lof(0) Debug Eof(0) Debug Loc(0) CloseFile(0) EndIf Eof() >> 1,1 Loc() And Lof() >> 0,11 Jim VK7JH MMedit MMBasic Help |
||||
Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 830 |
@TassyJim: It seems to be something different when the space is in the username... Anyway - I moved everything to D: and adjusted path - now it works! Frank |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4042 |
More on the EOF question: Consider this "C" code: #include <errno.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { errno = 0; FILE *f = fopen("hello-world.txt", "w"); if (!f) perror("fopen() error"); fprintf(f, "Hello World"); printf("feof before flush = %d\n", feof(f)); if (fflush(f) != 0) perror("fflush() error"); printf("feof after flush = %d\n", feof(f)); int ch = fgetc(f); if (ch == EOF) { printf("feof after fgetc = %d\n", feof(f)); printf("ferror() = %d\n", ferror(f)); printf("errno = %d\n", errno); if (ferror(f)) { perror("fgetc() error"); exit(0); } } else { printf("OK\n"); } if (fclose(f) != 0) perror("fclose() error"); } Compiled and run on Windows 10: thwill@PSEUK1383 MINGW64 /c/home-thwill $ cl c-file-io.c Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26433 for x64 Copyright (C) Microsoft Corporation. All rights reserved. c-file-io.c Microsoft (R) Incremental Linker Version 14.14.26433.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:c-file-io.exe c-file-io.obj thwill@PSEUK1383 MINGW64 /c/home-thwill $ ./c-file-io.exe fgetc() error: No error feof before flush = 0 feof after flush = 0 feof after fgetc = 0 ferror() = 1 errno = 0 Compiled and run on Linux: thwill@pseuk1383:~/home-thwill$ gcc --version gcc (Ubuntu 11.2.0-7ubuntu2) 11.2.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. thwill@pseuk1383:~/home-thwill$ gcc c-file-io.c thwill@pseuk1383:~/home-thwill$ ./a.out feof before flush = 0 feof after flush = 0 feof after fgetc = 0 ferror() = 1 errno = 9 fgetc() error: Bad file descriptor In my opinion the Microsoft compiler is a borked in that after calling fgetc() on a write only stream it sets the error flag but doesn't set errno - this is why MMB4W isn't reporting an error because its error handling code for stdio operations ONLY CHECKS errno - this is not C standard compliant; you are supposed to check the return value from the function before consulting the errno because a function that succeeds is according to the C standard still allowed to set errno. MMB4L (currently) has the same non-compliant error handling, but because Linux sets the errno in this case it works and reports "Bad file descriptor". Note that MMB4W and MMB4L are both basically using the same old code from MMBasic for DOS: int MMfeof(int fnbr) { int i, c; if(fnbr < 0 || fnbr > 10) error("Invalid file number"); if(fnbr == 0) return 0; fnbr--; if(MMComPtr[fnbr] != NULL) return SerialEOF(MMComPtr[fnbr]); if(MMFilePtr[fnbr] == NULL) error("File number is not open"); errno = 0; c = fgetc(MMFilePtr[fnbr]); // the Watcom compiler will only set eof after it has tried to read beyond the end of file if(ErrorCheck()) return 0; i = (feof(MMFilePtr[fnbr]) != 0) ? -1 : 0; if(ErrorCheck()) return 0; ungetc(c, MMFilePtr[fnbr]); // undo the Watcom bug fix ErrorCheck(); return i; } I think the comment in this code about the Watcom compiler having a bug is spurious. feof(f) does not check if you are at the end of stream 'f', it checks whether the EOF flag has been set on that stream, and in order for that flag to have been set you need to have performed an operation on the stream that generates that condition (e.g. read beyond the end of the stream). Hence the fgetc/ungetc are in general necessary and not something to do with the Watcom compiler. It *might* be possible for the code to provide a short-circuit check to see if feof(f) != 0 is already true before doing fgetc/ungetc ... however if something is writing the file whilst MMBasic is reading it then that will produce the wrong result. With resepct to MMBasic I think you just need to decide whether EOF called on a file opened FOR INPUT should return 0, 1 or throw an error and then hard-code that in rather than relying on calling feof(). Personally I'm in favour of reporting an error in this case. Best wishes, Tom Edited 2022-03-15 21:27 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
I'm going to leave it as it now is: eof on a file open for write reports 0 eof on a file open fro random reports correctly (but note only if you fflush before the fgetc) eof on a file open for read also works correctly of course. CMM2 will be different but this is irrelevant because you shouldn't be testing eof on a file open for write in the first place |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4042 |
OK, but note that is happening *accidentally* because the error handling for the call to fgetc() is not standards compliant (based on the MMB4W code currently visible on GitHub). Best wishes, Tom Edited 2022-03-15 21:31 by thwill Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
V5.07.03b7 MMBasic.zip Fixes the LOF and EOF issues identified above. Note the previous version of LOF returned the number of bytes from the current file pointer to the end of the file - actually probably more useful than the new version which matches the manual and just returns the filesize. Anyone think I should revert? |
||||
Page 9 of 30 |
Print this page |