Comments (24)
Is it stock CP/M 3?
from hi-tech-z80-c.
While I build things using an emulator on my mac mini or Raspberry Pi (zxcc, RunCPM and under SIMH AltairZ80), I verify and test on real hardware too.
Mainly I use a Z280 running banked-memory CP/M 3 with Simeon Cran's ZPM3 enhanced BDOS replacement (The hardware is Bill Shen's Z280RC in RC2014 format). This is where I noticed this issue with submit file input.
I'll switch to Digital Research's CP/M 3's stock standard BNKBDOS3 and RESBDOS3 (Y2K versions) and report back.
from hi-tech-z80-c.
So the problem I have is with zxcc. SIMH works perfectly ...
I have no real hardware with CP/M-3 though. (SC-131 and RC2014 with CP/M 2.2 only).
Are you using this?
https://www.retrobrewcomputers.org/doku.php?id=builderpages:plasmo:z280rc
from hi-tech-z80-c.
I confirm same problem on simh cp/m-3 ...
from hi-tech-z80-c.
Yes that's the Z280RC. I wrote the banked memory CP/M 3 BIOS for it.
Swapping to DRI's BDOS show's the same symptoms.
I'll now install a copy of HI-TECH C on my Z80 MBC2 (which will be slow) and test it there. If needs be I can also fire up my almost 40 year old S-100 bus system - but it only has 8-inch floppies which may not be working (last fired up about 14 years ago to make disk images of all my old floppies!).
from hi-tech-z80-c.
It works properly under CP/M 2.2 on a real Z80
A>type test.sub
; CP/M 2.2 uses XSUB for program input
xsub
c309-6
-o -v test.c
A>submit test.sub
A>XSUB
A>C309-6
Hi-Tech C Compiler (CP/M-80) V3.09-6
Copyright (C) 1984-87 HI-TECH SOFTWARE
c> -O -V TEST.C
0:A:CPP -DCPM -DHI_TECH_C -Dz80 -I0:A: TEST.C $CTMP1.$$$
0:A:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:A:CGEN $CTMP2.$$$ $CTMP1.$$$
0:A:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:A:ZAS -J -N -oTEST.OBJ $CTMP2.$$$
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
0:A:LINQ -Z -Ptext=0,data,bss -C100H -OTEST.COM 0:A:CRTCPM.OBJ TEST.OBJ 0:AB
ERA TEST.OBJ
ERA $$EXEC.$$$
(xsub active)
A>
(sorry iI posted this to the wrong issue before)
from hi-tech-z80-c.
So quick look at it is the gets call in getargs after the prompt does not get anything ... it looks like the initialisation of the input being the console does not take into account input set by submit... (function nextch line 206).
FYI I also tried to GENCOM C.COM with PIPEMGR. To no avail. It does not work either ...
Will carry on investigating this week end if you want.
I also validated that a normal program generated with the same libc as c.com works properly ...
#include <stdio.h>
int main() {
char buf[246];
gets(buf);
printf("(%s)\n",buf);
return 0;
}
J>type test.sub
rc
< -v hello.c
<
J>test
J>rc
-v hello.c
( -v hello.c)
J>
So the scope of the issue is the front end of getargs ...
from hi-tech-z80-c.
The fact that the sign-on banner (written to stderr) loses the same number of characters that should be input to the c> prompt is suspicious. I've confirmed that increasing the command line reduces the banner by the same number of characters.
I'm going to have lunch then look deeper...
from hi-tech-z80-c.
this is happening with all programs compiled with c.com contrary to what I thought. the more is written to stderr, the more is not taken into account in the input.
from hi-tech-z80-c.
Ok progress...
Reversed write.c (plus U_RSX in case) and it works.
what creates the issue is at line 90:
if (fc->fsize < fc->rwp)
fc->fsize = fc->rwp;
Removing this fsize adjustment resolves the problem
Looking at the history and reason for the fix is part of the pipemgr fix ...
Further digging needs to be I suspect ... I think further testing needs to be done . Interesting though is the fact that I did not have these two line in my pipemgr integration.
I will also check whether it resolve my problem with the size adjustment...
Interestingly ... the last problem I had (Issue #6) that was preventing c to work under cc is also gone. Everything works (i.e. the changes to stat, open, close I could not take ...). It is what I perceived as a bug in the cpm3 emulation of xxcc ....
the following changes were causing grief and removing the lines above makes it work. The changes were
in open.c commenting section around line 30:
/* if (d) // Byte count represents UNUSED bytes in last
d = 0x80 - d; // sector ... Changed 9 Apr 2014 jrs */
in stat.c commenting section around line 57:
/*
Changed to interpret last record byte count as the number of
UNUSED bytes. Slightly simpler, historically correct and
consistent with other tools that I use. [jrs 2014-04-08]
if (d)
d=0x80-d;
*/
in close.c around line 16 changing
fc->nr = (fc->fsize & 0x7f); /* Set exact file size */
by
fc->nr = (-fc->fsize & 0x7f); /* Set exact file size */
So if I remove those 2 lines in write.c, I am now able to run with exactly the same version as you, i.e. zxcc-htc and your project at 100% in line and only differ by cosmetics...
Can you double check that on your you zxcc env?
2 birds with one stone I hope.
from hi-tech-z80-c.
Sorry, I had to attend to family commitments yesterday - so I didn't get to look into this further until now.
The changes for the exact file sizes under CP/M 3 were done by Jon Saxton (jrs) and are explained in my README.md - simplifying file size calculations with backwards compatibility to CP/M 2.2. These then needed to be back-ported into John Elliot's original PIPEMGR (and the Van Nuys utilities).
The code you found in the write() routine is suspicious - over-writing the read-write pointer. I began by looking for a missing call to fflush() which should be used when mixing reads and writes to the same stream.
from hi-tech-z80-c.
Yes, Actually now the changes of Jon Saxton are working in zxcc perfectly once I remove those 2 lines in write.c. did not before which is the problem I was experiencing with the c front end.
It also fixes our submit input problem.
I tried extra flushes to no avail before reverting write and finding the suspicious two lines.
from hi-tech-z80-c.
I'm just confirming the change to write() works on CP/M 3 before pushing it. Thanks for spotting this before I did!
from hi-tech-z80-c.
Super cool!!! I am finally fully aligned with your code base 😉
I just need to do clean up to be verbatim the same.
PS: I created two small issues 🙁 sorry for not PR'ing but I am struggling with the text attributes in .gitattributes. cloning modifying everything.
from hi-tech-z80-c.
I saw your .gitattributes issue. I use a mac and found it easier to just keep the sources with CR-LF line endings (which also is the way SIMH AltairZ80 exports files with the W command - and the reason I kept the ugly upper-case file names). Judicious use of dos2unix/unix2dos and the file commands fixes things - and I think there's a git setting to do this too.
from hi-tech-z80-c.
I'm just confirming the change to write() works on CP/M 3 before pushing it. Thanks for spotting this before I did!
Sorry I was called away.
This change does not fix this issue.
Looking more closely at the code, there's two long words in the file control block for keeping the read write pointer (fc->rwp) and the file length (fc->fsize) in bytes. All this code in the write() routine is doing is updating the length of the file in bytes when the file is expanded.
from hi-tech-z80-c.
so I can confirm that the 2 extra lines compared to the HTC original
- make submit input work in my test
- fix the usage of Saxton changes in a zxcc environment.
Do you have any idea/suggestion to pursue the testing and see side effects of removing them? I am a bit blind on this one as all my tests work.
from hi-tech-z80-c.
I only see this issue under CP/M 3 on my Z280RC and under SIMH AltairZ80. I'll go back and look at diffs and try doing a paper walk-through the I/O in getargs().
from hi-tech-z80-c.
Ok the problem reappeared for me too on SIMH. So I unfortunately lost the fix that was working at some stage.
The 2 lines removed from write are fixing for. sure the compatibility problem with zxcc but I am like you back to square one on submit input.
the symptom is for each character (including the banner) output to CON, we loose one submit input character I wonder if my success was just a red hairing as a result of using TED which has weird behaviour with spaces.
In any case, it is not fixed.
from hi-tech-z80-c.
I am so frustrated to having succeeded in making it work yesterday, I went through the same motion again but with a couple of tests I kept ...
Added here a little litmus test.
A simple submit:
t.com
<-v hello.c
<
t.com l
<a b c
and a simple program
The output on sim with CP/M-3
J>t.sub
J>t.com
epvr e f i xh
ltleos.tc>
0; (test)
exiting ...
J>t.com l
p rbe fci xd
e f
(e f
)
exiting ...
J>
So
- both tests fail: the problem is not in getargs specifically, using fgets to get the input from submit broken too. that removes the main guilt of getargs probably
- notice the prefix that 'gobbles up' the number of inputs from submit
For summary, the variant with fgets is a simple as that:
char * b;
b=fgets(buf,256,stdin);
b[256]=0;
fprintf(stderr, "(%s)\n",buf);
The problem seems to be in the management of the inputs/outputs (read, write, fcb) ...
I don't know enough about the sharing of FCBs and Context, but it looks like the context/FCB of stdin and stdout are shared which does not make sense to me ...
Follow up:
- The underlying action is completely implemented by fgetc in fgetc.as, looking at that to get clued in further. the only interaction it has with the channel is through filebuf.c which has not changed. in term calls read. the two functions manipulate only the stdin structure as expected so work on different FILE descriptors.
- I again as I did yesterday reverse the write.c and read.c to their originals and here is the results:
J>t.sub
J>t.com
-v hello.c
J>WARNING: PROGRAM INPUT IGNORED
t.com l
a b c d e f
It work perfectly....
- I tried the two independently. write.c is the one making the difference.
- I align the style to get the minimum diff:
3,4d2
< extern char _piped; /* PIPEMGR loaded? */
<
14d11
< char RSXPB[4];
21,23d17
< RSXPB[0]=0x7D;
< RSXPB[1]=0;
< RSXPB[3]=0;
43,54d36
< case U_ERR:
< RSXPB[0]=0x7A;
< case U_RSX:
< while(nbytes--) {
< _sigchk();
< RSXPB[2]= *buf++;
< if (_piped)
< bdos(CPMRSX,RSXPB);
< else
< bdos(CPMWCON,RSXPB[2]);
< }
< return count;
84,85d65
< /* if (fc->fsize < fc->rwp)
< fc->fsize = fc->rwp;*/
(ignore the 2 last lines, they are an issue with zxcc working or not)
- The only big difference between the two is U_ERR but in the previous release, U_ERR was not used, U_CON was instead ... so it works because it goes simply cuts away the U_ERR content .... 🙁
- I redo the test with stdout instead of stderr ... failure. So write.c is not the guilty guy ... or not alone at lease ..., searching for other readers of CON: .... so here is the list:
getch.c: return bdos(CPMRCON) & 0xFF;
read.c: bdos(CPMRCOB, buffer);
signal.c: c = bdos(CPMRCON);
- getch.c is out of the loop
- read.c has no surprise
- signal.c ..... _sigchk is called everywhere in read and ... in write ....
- so I changed quickly a sigchk into a nop function and it works !!!!!!!
- let's check where _sigchk is called:
grep sigchk *.c *.as
read.c: _sigchk();
signal.c:_sigchk()
write.c: _sigchk();
write.c: _sigchk();
write.c: _sigchk();
write.c: _sigchk();
in particular, when we do console write, creating a competition between CP/M Functions 10 and Function 1, which in a normal case never happens, the buffered console read being expected to be exclusive but in the case of the submit input, this is exactly happening.
case U_ERR:
RSXPB[0]=0x7A;
case U_RSX:
while(nbytes--) {
_sigchk();
RSXPB[2]= *buf++;
if (_piped)
bdos(CPMRSX,RSXPB);
else
bdos(CPMWCON,RSXPB[2]);
}
return count;
- A proposed solution is to document it and to surround input interactions with proper signal handling around writes to the console when a buffered read is acquired.
signal(SIGINT,SIG_IGN);
signal(SIGINT,SIG_DFL);
in getargs.c for the prompt:
static char nxtch()
{
if (interactive && *str == '\\' && str[1] == 0)
{
if (!bp)
bp = alloc(256);
if (isatty(fileno(stdin))) {
signal(SIGINT,SIG_IGN);
fprintf(stderr, "%s> ", name);
signal(SIGINT,SIG_DFL);
}
gets(bp);
str = bp;
}
if (*str)
return *str++;
return 0;
}
and c.c for the banner
if (isatty(fileno(stdin))) {
signal(SIGINT,SIG_IGN);
fprintf(stderr, "HI-TECH C COMPILER (CP/M-80) V@@TAG@@\n");
fprintf(stderr, "Copyright (C) 1984-2021 HI-TECH SOFTWARE\n");
#if EDUC
fprintf(stderr, "Licensed for Educational purposes only\n");
#endif EDUC
signal(SIGINT,SIG_DFL);
}
if(argc == 1) {
argv = _getargs((char *)0, PROMPT);
}
- trying it now. it works. but I found another bug on the way with the compiler this time, not being able to properly convert integers as function pointers (signal_t).
PS: I found an unrelated small bug on getargs I am also chasing. After getargs is executed there is a missing carriage return or the EOL is displayed as a LF, hence my fprintf(stderr,"\n") after getargs ....
from hi-tech-z80-c.
Working solution description:
- First of all a change to the small test:
- a small alteration of signal.h and signal.c to define signal_t as a void* instead of a function type. P1 does not like that.
in signal.h:
typedef void* signal_t;
in signal.c:
if(where == SIG_DFL)
exit(0);
((int(*)())where)(0);
- a protection of the printf in getargs.c
if (isatty(fileno(stdin))) {
signal_t prev=signal(SIGINT,SIG_IGN);
fprintf(stderr, "%s> ", name);
signal(SIGINT,prev);
}
- a change to the c.c drive (careful this is mine but the change is only on the banner)
if (isatty(fileno(stdin))) {
signal_t prev=signal(SIGINT,SIG_IGN);
fprintf(stderr, "HI-TECH C COMPILER (CP/M-80) V@@TAG@@\n");
fprintf(stderr, "Copyright (C) 1984-2021 HI-TECH SOFTWARE\n");
#if EDUC
fprintf(stderr, "Licensed for Educational purposes only\n");
#endif EDUC
signal(SIGINT,prev);
}
Working really well now.
last small test with the c front end ... success 😀
J>type tt.sub
c
<-v hello.c
J>tt
J>c
HI-TECH C COMPILER (CP/M-80) V3.09-P009.1-dev
Copyright (C) 1984-2021 HI-TECH SOFTWARE
c> -v hello.c
0:CPP -DCPM -DHI_TECH_C -D_HTC_C -Dz80 -I HELLO.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:ZAS -N -oHELLO.OBJ $CTMP1.$$$
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $CTMP5.$$$
0:LINK -Z -Ptext=0,data,bss -C100h -OHELLO.COM CRT0.OBJ HELLO.OBJ LIBC.LIB
ERA HELLO.OBJ
ERA $$EXEC.$$$
J>
from hi-tech-z80-c.
And last, I think we could explore the usage of
(BDOS function 109 (C_MODE) - Set or get console mode)
for CP/M 3 an PCP/M at lease
But I suppose it is another story. The number of case where the sigchk can interfere with a submit like scenario are legions: Examples of that any I/Os happening before or during console interactions, functions like getenv for example (reading files so calling _sigchk)
from hi-tech-z80-c.
You have been busy while I was sleeping.
I also narrowed down some issues with gets() too and the problems of mixing of input and output to a stream.
The manual warns about such mixing and suggests (page 120 of the doc/HTCZ80.TXT file)
When using one of the read/write modes (with a '+'
character in the string), although they permits reading and
writing on the same stream, it is not possible to arbi-
trarily mix input and output calls to the same stream. At
any given time a stream opened with a "+" mode will be in
either an input or output state. The state may only be
changed when the associated buffer is empty, which is only
guaranteed immediately after a call to fflush() or one of
the file positioning functions fseek() or rewind(). The
buffer will also be empty after encountering EOF while read-
ing a binary stream, but it is recommended that an explicit
call to fflush() be used to ensure this situation. Thus
after reading from a stream you should call fflush() or
fseek() before attempting to write on that stream, and vice
versa.
Your solution seems fine - but there may be other traps lurking in other areas of the code.
Also regarding the sensitivity to message lengths in the start-up code I noticed the x86 detection code in the start-up modules is broken (doesn't work when a compiler produced .COM file runs under MS-DOS as it should). I'll fix this as a separate issue and review/merge your recent pull request shortly after I have my breakfast!
Tony
from hi-tech-z80-c.
Finally fixed this issue (fingers crossed)!
from hi-tech-z80-c.
Related Issues (20)
- new C.C frontend not running on ZXCC HOT 9
- Extraction aborting - overlay.h isn't working HOT 4
- bios() calls to invoke XMOVE and MOVE fail under DRI banked BDOS HOT 2
- Wrong prototypes for ctime, gmtime and localtime HOT 1
- Work related to Hi-tech C HOT 1
- Hi-Tech C MSDOS v7.80 HOT 5
- LIBC library object modules need re-ordering HOT 1
- Undefined symbols with build 13 ( _open, _fseek, _creat, __filbuf) HOT 5
- Can't execute $EXEC HOT 4
- Cannot sseem to include libraries on different drive HOT 1
- It doesn't run on the Agon Light yet and it's not 24 bit to suit the eZ80 CPUs HOT 1
- Cannot find user library on D0: HOT 11
- Resulting com files bigger than original compiler HOT 7
- Linking question HOT 2
- I'm getting a "can't create testprg.obj" HOT 3
- Passing struct as argument to function pointer inside struct HOT 1
- Can you detect if include defined? HOT 3
- Running out of memory HOT 2
- Better way to pass args from C to ASM HOT 5
- module has code below file base of 0100h HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hi-tech-z80-c.