ZX81: C console print position does not match BASIC print position
ZX81: C console print position does not match BASIC print position
My current problem is: I have an USB driver, which writes to screen using RST 10 (and using the print position stored in BASIC system variables.
But the simple console driver (LOWRES) of Z88DK holds its own print position, so printing of the driver and printing of my C program (printf in LOWRES, not ANSI) may overwrite the other text, making screen handling not easy :-(
The C-console driver should use the BASIC system variables to hold its cursor position. Then I could use the ROM call PRINT_AT for cursor positioning (like in BASIC), which is not supported by the simple C-console driver.
Siggi
But the simple console driver (LOWRES) of Z88DK holds its own print position, so printing of the driver and printing of my C program (printf in LOWRES, not ANSI) may overwrite the other text, making screen handling not easy :-(
The C-console driver should use the BASIC system variables to hold its cursor position. Then I could use the ROM call PRINT_AT for cursor positioning (like in BASIC), which is not supported by the simple C-console driver.
Siggi
Hi Stefano,
the bugfix does not work as (I) expected
I wrote a BASIC and C program: the C program writes a 'C' to screen, the BASIC writes 'B' next to the C. The expected output should be
"BCB"
But the 'C' is always overwritten by the 'B'. So the output is
"BB"
Maybe the C-program does not set the system variable
"16398 DF_CC Address of PRINT position in display file."
correctly?
Here my test programs
and
Siggi
Addendum:
Perhaps you could put these 2 functions into the ZX81 lib?
the bugfix does not work as (I) expected
I wrote a BASIC and C program: the C program writes a 'C' to screen, the BASIC writes 'B' next to the C. The expected output should be
"BCB"
But the 'C' is always overwritten by the 'B'. So the output is
"BB"
Maybe the C-program does not set the system variable
"16398 DF_CC Address of PRINT position in display file."
correctly?
Here my test programs
Code: Select all
//zcc +zx81 -startup=2 -create-app -vn -o test.bin test.c
#include <stdio.h>
void main(void)
{
putchar('C');
}
Code: Select all
10 PRINT "B";
20 RAND USR 16514
25 PAUSE 100
30 PRINT "B"
Addendum:
Perhaps you could put these 2 functions into the ZX81 lib?
Code: Select all
void zx_cls(void)
{
putchar(12);
}
void zx_print_at(unsigned char line, unsigned char column)
{
#asm
XREF restore81
call restore81
pop hl; address
pop bc; column into C
pop de; line
push de
push bc
push hl
ld b,e; line into B
jp 0x8F5
#endasm
}
Last edited by siggi on Thu Nov 17, 2011 3:34 pm, edited 1 time in total.
I thought I replied already, but I can't see my post, so I'm writing it again.
I slightly improved fputc_cons to make the BASIC cursor follow me when I print a character *only*.
CR and LF could not behave as expected, and there is a known bug when a character is being printed in the last column (BASIC won't be able to insert the needed <CR>).
On the other side it costs three bytes only
zx_cls() now is implemented, I definitely prefer my fast screen fill code to the ROM CLS.
I slightly improved fputc_cons to make the BASIC cursor follow me when I print a character *only*.
CR and LF could not behave as expected, and there is a known bug when a character is being printed in the last column (BASIC won't be able to insert the needed <CR>).
On the other side it costs three bytes only
zx_cls() now is implemented, I definitely prefer my fast screen fill code to the ROM CLS.
I just had a crash, when I loaded Bodo's "25thanni.p" with my USB FILE MANAGER written in C from the USB stick.stefano wrote:zx_cls() now is implemented, I definitely prefer my fast screen fill code to the ROM CLS.
The problem is, that my UFM expects an expanded display file (line length 32 + HALT), but Bodos P-file was not saved by a ZX81, but generated directly from assembler, having a collapsed display file (consists only of HALTs).
The ROM CLS routine can handle a collapsed display file, so I could call it to expand a collapsed display file to an expanded, which then would be fit to my UFM. But the (faster) "screen fill code" does not support that.
So the ROM CLS routine is slower, but safer to use ..
Siggi
Edit:
Perhaps you could change the CLS routine in such a way:
if the DFILE has its expected size
then
call fast fill routine
else
call ROM CLS (to expand the DFILE)
Last edited by siggi on Sat Nov 26, 2011 11:25 am, edited 1 time in total.
Siggi, we are supporting the collapsed D-file too as an option for the packager so I know what you do mean.
I never thought at this situation because the packager does not insert the auto-run option in the filename... as soon as the user RUNs the program the screen is expanded automatically.
Ok, I'll have a look..
I never thought at this situation because the packager does not insert the auto-run option in the filename... as soon as the user RUNs the program the screen is expanded automatically.
Ok, I'll have a look..
Hi Stefano,
there is still a problem when mixing C and BASIC printing:
I used the latest build of Z88DK to compile my UFM, which uses the C print routines. But the USB driver, that is called by UFM, uses the BASIC print environment (RST 10).
I used zx_cls() before calling the driver. After return form the driver the behaviour of UFM was wrong: the screen got out of sync, when I pressed a key.
The problem was solved, after I added a "putchar (12)" after the zx_cls() call. So putchar(12) seems to affect other variables compared to zx_cls(). IMHO both routines should set the print position to upper left corner and the difference should only be in speed and expansion of a collapsed D-FILE.
Siggi
Edit: no, the D-FILE was still expanded after the driver call.
there is still a problem when mixing C and BASIC printing:
I used the latest build of Z88DK to compile my UFM, which uses the C print routines. But the USB driver, that is called by UFM, uses the BASIC print environment (RST 10).
I used zx_cls() before calling the driver. After return form the driver the behaviour of UFM was wrong: the screen got out of sync, when I pressed a key.
The problem was solved, after I added a "putchar (12)" after the zx_cls() call. So putchar(12) seems to affect other variables compared to zx_cls(). IMHO both routines should set the print position to upper left corner and the difference should only be in speed and expansion of a collapsed D-FILE.
Siggi
Edit: no, the D-FILE was still expanded after the driver call.
Last edited by siggi on Wed Nov 30, 2011 7:50 pm, edited 1 time in total.
The current entry to ROM (jp $a2a) is ok: I used also this call with elder Z88DK versions.stefano wrote:Ok ok, it could depend on the location entry I'm using with zx_cls.
You should NOT add additional code to zx_cls() to solve that problem, because anybody can still call the ROM directly without using zx_cls (e. g. when I compile older C-programs, which do not know about zx_cls()).I'll try by forcing the env. variables.
Please do changes only in the "putchar(12)" routines. No one would call them directly ...
Siggi
Siggi, I'm sorry but I got your message after putting the latest changes online.
Please have at least a look at zx_setcursorpos(x,y), it is meant for (0;0) at top-left.
At the moment that fix is in place, it was useful for other functions (i.e. to place the cursor at top-left after scrolling down the text).
Please have at least a look at zx_setcursorpos(x,y), it is meant for (0;0) at top-left.
At the moment that fix is in place, it was useful for other functions (i.e. to place the cursor at top-left after scrolling down the text).
Hmm, the linker says: "Error in expression _ZX_SETCURSORPOS" ...
In which lib is it included?
Should it work also in ANSI mode?
Siggi
Edit:
Upps: it was not the linker. The error message is:
In which lib is it included?
Should it work also in ANSI mode?
Siggi
Edit:
Upps: it was not the linker. The error message is:
Code: Select all
2 errors occurred during assembly
Key to filenames:
C:\DOKUME~1\Engel\LOKALE~1\Temp\s5a8_.o = ufm-driver.c
File 'C:\DOKUME~1\Engel\LOKALE~1\Temp\s5a8_.asm', Module 'UFM', Symbol not defin
ed
Error in expression _ZX_SETCURSORPOS
File 'C:\DOKUME~1\Engel\LOKALE~1\Temp\s5a8_.asm', Module 'UFM', Symbol not defin
ed
Error in expression _ZX_SETCURSORPOS
Last edited by siggi on Tue Dec 20, 2011 10:28 am, edited 1 time in total.
Hmm, UFM and that test program both crash with the latest build :-(
Siggi
Code: Select all
#include <stdio.h>
main(void)
{
zx_setcursorpos(0,0); printf("1");
zx_setcursorpos(21,0); printf("2");
zx_setcursorpos(0,30); printf("3");
zx_setcursorpos(21,29); printf("4");
}
I still have major problems when mixing BASIC and C "screens":
I currently write an NFM (Network Filemanager) to load/save programs via Ethernet.
I am using routines to do that, which I used already in older programs (to load programs from USB sticks or FAT32 MMC cards) and they worked (with older z88dk versions). Now, when I am loading a file, I often have crashes or corrupted screens :-(
The problem is: when I load a new program (my NFM is running above 32K) , the current DFLILE is overwritten by the new program, thus the DFILE and is located on a new position and the print positions (absolute positons) do not match any more.
I tried to clear the new screen (using first the ROM routine to expand a possibly collapsed DFILE) and also do a putchar(12) to clear the "C screen" (and to reset the print position maybe used in C libs).
But that did not help ...
LOAD is done in FAST mode and the C slow routine is called after loading. But then the display is corrupted ..
Here is my code to load a P-file:
Any hints what I could do better?
Siggi
I currently write an NFM (Network Filemanager) to load/save programs via Ethernet.
I am using routines to do that, which I used already in older programs (to load programs from USB sticks or FAT32 MMC cards) and they worked (with older z88dk versions). Now, when I am loading a file, I often have crashes or corrupted screens :-(
The problem is: when I load a new program (my NFM is running above 32K) , the current DFLILE is overwritten by the new program, thus the DFILE and is located on a new position and the print positions (absolute positons) do not match any more.
I tried to clear the new screen (using first the ROM routine to expand a possibly collapsed DFILE) and also do a putchar(12) to clear the "C screen" (and to reset the print position maybe used in C libs).
But that did not help ...
LOAD is done in FAST mode and the C slow routine is called after loading. But then the display is corrupted ..
Here is my code to load a P-file:
Code: Select all
int RunProgram(char * fname, int execute, char * address)
{
char save_cd; // usewd to save my CDFLAGS
char retry = 0; /* hope that no retry is necessary */
char is_prog = 0;
unsigned int addr;
int err;
if (*address)
{
addr = atoi(address);
execute = 0;
}
else
{
addr = PROG;
is_prog = 1;
if (!strchr(fname,'.'))
strcat(fname,".P");
}
#ifdef DEBUG
printf("loading %s to %u\n", fname, addr);
#endif
/* load during fast mode only! */
ZX81Fast();
save_cd = CDFLAGS;
#ifdef TEST_UI
#asm
; on EO: copy P file from 50000 to 16393
ld HL, 50000
ld DE, 16393
ld BC, 14000 ; leave space for stack
ldir
#endasm
#else
do
{
err = load_file_tnfs(mount_point, fname, addr);
if (err >= 0)
{
if (is_prog)
{
/* plausi check for file end */
if (*(unsigned char *)(E_LINE-1) == 0x80) /* file end is as expected */
{
/* a new BASIC program is loaded */
CDFLAGS = save_cd; // restore my CDFLAGS
if(execute == '+')
{
C_exit(); /* abort C program, cleanup stack, goto BASIC */
}
else if (execute == '-')
{
NXTLIN = 0; /* destroy autorun info */
}
ZX81Cls(); /* expand possibly collapsed D-File */
zx_cls(); /* clear C screen */
if (retry)
printf("Retries: %d\n", retry);
retry = 0;
}
else
{
retry++; /* retry */
}
}
}
else
return(err);
}
while (retry);
#endif
return(EOK);
}
Siggi
It seems, that now Z88DK does not keep the BASIC print position (stored in ZX81 system variables) in sync with the C print position (at least in text mode). I am using that code to prevent scrolling a big e-mail from screen before the user could read it:
That worked well in 2014 but no more today.
This little BASIC program shows the behavior of BASIC:
Value a=20 gives result 4.
Siggi
Code: Select all
char lines @ 16442;
// Pause when screen gets full
int check_full(void)
{
int ret_val = 0;
if (lines < 4)
{
printf("\n<cr>");
in_WaitForNoKey();
if (getchar() != 13)
{
ret_val = -1;
}
zx_cls();
}
return ret_val;
}
This little BASIC program shows the behavior of BASIC:
Code: Select all
10 input a
20 print at 1,0;peek 16442
Siggi