LPRINT on ZX81?

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

LPRINT on ZX81?

Post by siggi »

Hi
is there any high level support of the printer (Sinclair printer routines in ROM) of a ZX81 in z88dk?
I am thinking of writing a network printer, running on a ZX81+printer (using ZeddyNet) :)

Siggi

PS: e. g. the BASIC program line interface???
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

The original zx printer could be driven in a particular way, permitting high resolution (iirc). I suppose that most of the third party parallel interfaces were not featuring a ROM extension, which printer configuration are you thinking at?
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hi Stefano
I want to use the original Sinclair printer or compatible (Alphacom 32, Seikosha GP50S).
Text mode (zeddy character set incl. graphics!) would be OK. Hires would be nice to have ;-)

Maybe putting the text into a BASIC string variable (A$) and then call the BASIC line "LPRINT A$" would be possible, but is a special ZX81 solution (not portable). Perhaps there is a better solution?

Siggi
User avatar
dom
Well known member
Posts: 1314
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I think that?s probably the most portable way to do it - well portable across the ZX machines.

Any bit bashing would be just restricted to the ZX printer.

I guess any other printer interface could trap the LPRINT ROM address so doing it that way would cover those as well.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

The disadvantage of that solution is, that a "real" Basic program is needed (to hold the code line e. g. "100 PRINT A$" and the BASIC variable A$). Thus it would not be possible to run the compiled program above 32K without having its special "help" BASIC program at 16K.

MEMOTECH also uses BASIC-commands within MEMOCALC to "LOAD" and "SAVE" the spreadsheet data as program/variables using the BASIC commands. But they have this Basic-commands stored in EPROM@12K. They call a ROM routine, to which the address of the BASIC line in EPROM is passed and which interprets the BASIC command (starting with the command token and terminated by <CR>) there . Thus they don't need a BASIC line number to find that line in BASIC ram.
AFAIK that is not possible with the Z88DK implementation to run a BASIC line. Correct?

Currently I think calling the LPRINT-CH-routine in ZX81 (passing the ZX81-character to be LPRINTED in A) dircecty would be be best solution (also running above 32K without own BASIC program). Rom disassembly:

Code: Select all

;THE 'LPRINT-CH' SUBROUTINE
;Characters are added one by one to the printer buffer. Once the buffer is full, or a N/L character is entered the buffer is emptied.

0851 LPRINT-CH        
                CP        +76
                JR        Z,0871,COPY-BUFF
                LD        C,A
                LD        A,(PR-CC)
                AND        +7F
                CP        +5C
                LD        L,A
                LD        H,+40
                CALL        Z,0871,COPY-BUFF
                LD        (HL),C
                INC        L
                LD        (PR-CC),L
                RET
Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Correction: instead "AFAIK that is not possible with the Z88DK implementation to run a BASIC line. Correct?" it should be
"AFAIK that is not possible with the Z88DK implementation to run such a BASIC line. Correct?"
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Ok, the ZX PRINTER is well emulated on EO, the task is intriguing, so I'll experiment a bit around it.
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I prepared a very basic support for the zx81 and ZX Spectrum, zx_lprintc(chr) will, basing on the ROM routine output a single character to the printer buffer, NEWLINE will finalize the line printing.
I chose to avoid FASTCALL to be as close as possible to fputc_cons, in case someone would like to replace the stdout.
On the ZX81 the zx_ascimode() call can alter the character output behavior as it already happens for the console, by default the ASCII conversion is enabled (as usual).
The ZX128 works only in 48Kmode, probably because of the lack of a clean printer buffer area, so ATM I'm avoiding to insert the ROM3 interposer. The TS2068 seems in working order, while the Lambda printer does not seem to be properly emulated (I suppose it works on the real HW, if it ever existed) and the ZX80 does not support a printer at all.
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

fior the record, I was able to call the basic from within a c program:
https://github.com/z88dk/z88dk/blob/mas ... x_line.asm

more detail on zx_lprintc: the zx81 rom is designed to support text only output on the zx printer, so its default small 32 bytes space suffices.. the spectrum will use its 256 byte buffer .
the ringo zx81 clone does not seem to understand the printer redirection, other clones do.
it is definitely possible to provide a low level driver, eg. to support graphics hardcopy, I'll give it a try.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Indeed!
Matthias wrote "Power BASIC", an extension to ZX81 Basic. It contains also HIRES and supports also printing an Sinclar printer. Docu and source is there:
http://www.swatosch.de/zx81/
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

thanks for the link, this sounds promising!
I noticed it should also be possible to provide a text driver for the zx80 by adapting the zx81 rom code.. in theory.
sadly I am missing something somewhere and the printer is not reacting :( It is a pity, the work was already at an average status.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Did you test on a real ZX80 or using EO (which maybe does not expect a printer at ZX80)?
IMHO the ZX80 hardware (which can be upgraded to a (FAST) ZX81) should be able to work with a printer ...
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

If it would help: I don't have a "real" ZX80, but a ZxMore, running 6 ZX81 instances and a ZX80 instance and a real printer attached to it ....
Siggi
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

changing the zx80 rom with the zx81 one works, so I wouldn't blame eighty one
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Siggi, could you test zx_lprintc ? Does it suffice ?

I'm afraid I lost the Swatosch' HRG-MS sources ! I'm sure I had them, because my initial WRX driver was based on it.. where can I get a copy ?
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hi Stefano
I have been on holidays, so I could not check yet (coming soon ;-) )

I don't have the source of HRG-MS. But you could send an e-mail to Matthias (his address is on his page, link is given above).

And about HIRES printing: Wilf published this some years ago:

Code: Select all

I have attached the source code for a simple printer driver which
uses the same protocol as the built ZX LPRINT commands.
I wrote it as part of the WRX16 hires package to print HIRES screens
to the 2040 and similar printers.
It is easier to understand than the ZX ROM code and may shed some
light on the way that the ZX81 sends print data and tests printer
status. Unlike the the ROM code it sends the bitmapped HIRES display
file directly to the printer without converting character codes to
graphics bits. Hope this helps.
Best regards.

PWRX16 - HIRES GRAPHICS ROUTINE FOR THE ZX81 PRINTER
                    by W.RIGTER

A 52 BYTE PRINTER DRIVER FOR PRINTING A WRX16
BITMAPPED HIRES SCREEN THE ZX AND 2050 PRINTERS.
ILLUSTRATION OF THE ZX81 CORE PRINTER I/O PROTOCOL.
COMPARE THIS ROUTINE TO THE ZX81 ROM ROUTINE WHICH FIRST
CONVERTS CHARACTER CODES TO 64 GRAPHICS BITS BEFORE PRINTING

PWRX16  CALL 0F23         ;SET FAST MODE
        LD E,CO           ;REGISTER E = 192 LINES (192 X LOOP1)
        LD HL,(ARRAY)     ;REGISTER HL POINTS TO 256X192 BIT ARRAY
        XOR A             ;SET REGISTER BITS 0-7 TO ZERO
        OUT FB,A          ;START PRINTER (BIT 2=0)
LOOP1     IN A,FB         ;GET PRINTER STATUS BYTE
          RLA             ;ROTATE BIT 7 (LF BUSY) TO C FLAG
          JR NC,LOOP1     ;LOOP IF LINEFEED IS BUSY (C=0)
          LD D,20         ;32 BYTES (256 BITS) PER LINE
LOOP2       LD B,08       ;REGISTER B = 8 X LOOP2 COUNTER
            LD C,(HL)     ;REGISTER C = 8 BITS TO BE PRINTED
LOOP3         IN A,FE     ;GET PRINTER STATUS
              RRA         ;ROTATE BIT 0 (DATA READY) INTO C FLAG
              JR NC LOOP3 ;LOOP IF DATA
              LD A,C      ;COPY C TO A
              AND 80      ;REGISTER A BIT 7 IS PRINTER DATA BIT
              OUT FB,A    ;SEND DATA BIT TO PRINTER
              RL C        ;ROTATE NEXT DATA BIT TO BIT 7
              DJNZ LOOP3  ;REPEAT 8 TIMES (BYTE = 8 BITS)
            INC HL        ;INCREMENT ARRAY POINTER TO NEXT BYTE
            DEC D         ;DECREMENT LOOP2 COUNTER
            JR NZ LOOP2   ;REPEAT 32 TIMES
          DEC E           ;DECREMENT LOOP1 COUNTER
          JR NZ LOOP1     ;REPEAT 192 TIMES
        LD A,04           ;BIT 2 IS PRINTER ON/OFF BIT
        OUT FB,A          ;TURN OFF PRINTER
        CALL 0F2B         ;RESTORE SLOW MODE
        RET               ;BACK TO THE CALLING PROGRAM
Regards
Siggi
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Very good, thankyou, I'll surely play with it !
In this moment I'm sorting out the TS2068 stuff and I can't interrupt it at this stage, so the ZX81 must wait.
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I did some experiment, this routine is heavily simplified and lacks the horizontal synchronization which, in my opinion, makes it useless.
On the other side it is very handy to learn how the ZX printer works, because the extra biasing would mess up the program loops: the missing parts are the pixel strobe sync and the speed control biasing (the stylus speed must be reduced in the last 2 of 8 pixel lines), both present in the ZX81 and Spectrum ROMs.
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I MADE IT !!
https://raw.githubusercontent.com/z88dk ... rdcopy.asm


It combines the ZX Spectrum driver and a hint by Wilf on how to wait for the line sync.
It should be easy to adapt it to all the HRG drivers (at the moment it runs on WRX only)
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

stefano wrote:I MADE IT !!
Great :)

Is it already part of nightly build? How do I call the hardcopy routine on ZX81?

Siggi
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

zx_hardcopy(). Dom fixed a commit error I made so the WRX version is already available.
I can't test it on a real ZX Printer, so feedbacks are welcome.
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

progress is here:
https://github.com/z88dk/z88dk/issues/853
I my opinion the results are interesting, the ts2068 hrg screen is printed by rotating it and the zx81 udg graphics mode includes a printer driver able to print redefined fonts
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

ZX80 version is ready for the next nightly build :)
In the link above you can see a screenshot of the zx80 font as it appears on the EO "printer" tool.
Luckily the text driver can work on the D-FILE directly, no need for extra buffers and probably it is also able to deal with a collapsed D-FILE.
The zx_lprintc(chr) is still missing, it would require the a 32 bytes buffer and the code to wrap up the line.
stefano
Well known member
Posts: 1635
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Jupiter ace. this one is still at an experimental level, the current driver skips the rightmost column and uses a wrong font but works on the eightyone emulator ... I'd really like to find a tester for it
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hi Stefano
I did some tests, using DSTAR.C of the examples\zy81 directory.
I added some code to LPRINT a line of text and to do a hardcopy. But I got unexpected results.

1) The text line "Hardcopy\n" is not printed at all
2) The hardcopy of the hires DSTAR screen shows ZX81 graphic and text characters, not the graphic as seen on screen
The size seems to be correct. And the printed text/graphic character blocks change, when the screen content is changed.

This are the changes I made to the example file:
DSTAR.H

Code: Select all

#define K_SWITCH   'm'  /* [SPACE]      */
#define K_EXIT     'g' /* [Esc]/[Quit] */
#define K_CLEAR    'h'
// added by SE 21-07-2018
#define K_HARDCOPY 'z' /* COPY */
DSTAR.C

Code: Select all

#include <sound.h>

// added by SE 21-07-2018
#include <zx81.h>
#include <string.h>

Code: Select all

                case K_CLEAR:
                  #ifdef SOUND
                    bit_fx4 (3);
                  #endif
                  SetupLevel();
                  break;
                // added by SE 21-07-2018
                case K_HARDCOPY:
                  zx_lprints("Hardcopy\r\n");
                  zx_hardcopy();
                  break;

Code: Select all

void zx_lprints(char *s)
{
        int i;
        for (i=0; i < strlen(s); i++)
                zx_lprintc(i);
        zx_lprintc(10);
        zx_lprintc(13);
}
Any ideas, what could be wrong?
I tested using a ZxMore running a ZX81 ROM and a Timex 2040 printer.

My question: does zx_hardcopy() only a hires screen copy or does it also a lowres copy (depending on current display mode)

Siggi

PS: Should is send some pictures by e-mail?
Post Reply