In Volume 1, I ran a series on getting the most out of your ZX/TS with full-size printer and Memotech Centronics interface. Since then, this CIF has become unavailable. Fortunately, several other printer interfaces (both parallel and serial) are available. These include Centronics Parallel IF’s by Aerco, Byte-Back, John Oliger, and Tasman, and serial IF’s from Byte-Back and possibly others.
Most of these come with “printer driver” software that allow you to LLIST, COPY and LPRINT. At least one (the Aerco) includes an EPROM card that overlays the ROM and allows direct use of the Sinclair commands. The Tasman is the exception (to my knowledge), since it is being imported for the TS2068. (It WILL work with the ZX81/TS1000, however.) Similarly, the Aerco CIF for the TS2068 is identical to the TS1000 version except that it lacks the ROM overlay card. With the appropriate driver software, it too will work with the ZX81 family (and at less cost than the one intended for it).
JLO’s driver software (per SQ 1:1) is short and sweet, but lacks LLIST and LPRINT options. Byte-Back’s software has LLIST and a sort of LPRINT, but it doesn’t allow lower-case and is over 600 bytes long. Wouldn’t it be nice if we had a “universal” printer driver that was compact, flexible, and would work with the ZX81 and ANY interface? Well, here it is.
What It Does
The routine described here just fits into 1/2K. This is handy if you’re adapting software that was designed for the Memotech CIF which uses the 1/2K region from 2800-29FFh (10240-10751). The first 128 bytes is a Sinclair-ASCII conversion table. The code itself is therefore only 384 bytes long. It was written in a way to make it easily re-locatable to other areas of memory, and uses only one variable (system variable “VERS”). The last routine is a small section of code that customizes the software to your interface. Routines for the Aerco, Byte-Back Centronics, Byte-Back RS232 and/or MD-2 modem, JLO Centronics, and TASMAN Centronics are presented here. Others are easily implemented as long as you know the requirements to send an ASCII character.
This software includes LLIST, COPY, COPN (copy N lines of the screen), and three different ways of LPRINTing any string. All are accessed with RAND USR.
* COPY – RAND USR 10368 from within a program dumps all 24 lines to the printer.
* COPN – This is similar to COPY, except that you specify how many lines to copy with RAND (number), and then RAND USR 10391. The COPY routines are easily patched into Hot-Z or other software.
* LLIST – LIST the desired starting line, and RAND USR 10402 to get a hard-copy program listing. Unlike some other LLIST routines, this one won’t balk at “illegal” characters. It will print a tilde ( ° ) instead. It won’t stop prematurely due to an ENTER character (CHR$ 118) in the middle of a line, so even lines that mess up your screen will LPRINT properly. Like COPY and COPN, LLIST will print “normal” characters as capitals, and inverse video characters as lower-case. (Keeps the tokens looking normal).
* LPRINT – This allows you to print out the contents of any string, simple or arrayed. CHR$ 118 (ENTER) within the string will force a “newline.” To print a string, simply RAND CODE “(string name)”, then RAND USR (number). The argument of the USR can be one of three numbers:
10650 (LPRINT 1). This prints inverse video as capitals, and normal video as lower-case. This is what you’d normally use for text, since the inverse characters are more naturally viewed as upper-case (in the style of WSII, Memotext, etc.)
10655 (LPRINT 2). This routine is just like LPRINT 1, except that it prints normal characters as capitals (like COPY and LLIST).
10660 (LPRINT 3). This send the contents of the selected string in ASCII code, without translation. This is handy for sending printer control codes and custom characters. The only code that can’t be sent in this fashion is 118 (76h, or lower case “v”) since it is still used to force a line-feed.
Examples
LET A$="THIS WILL PRINT"+CHR$118+"AS THREE LINES"+CHR$118+"IN LOWER CASE."
RAND CODE "A"
RAND USR 10650
LET B$="THIS PRINTS AS ALL CAPITALS"
RAND CODE "B"
RAND USR 10655
To put printer into expanded mode,
LET C$=":" or LET C$=CHR$ 14
RAND CODE "C"
RAND USR 10660
Entering the Program
Start with the usual 1 REM, 540 bytes long. Following the system described in an earlier “Translations” article, you could enter 1 PRINT 0+0+…. with 68 repetitions of “+0”.
Use Hot Z or Hot Z II to enter the data and code from 2800h-29FF, and transfer into the REM. Alternately, use the hex loader shown in Listing 1. However you do it, you’ll first enter the conversion table of Table 1, then the machine-code of Listing 2, then the 12 bytes of the down-loader routine of Listing 3. When you’re done, LIST 10, and POKE 16420,10. This prevents the automatic listing from getting stuck because of the illegal codes.
Listing 2 is for the TASMAN interface. If you have one of the others, use the appropriate ASCII routine for your unit to replace the code starting at 29D8h. If yours isn’t listed, find out from the manufacturer what it takes to print an ASCII character, and use the routines presented here as guidelines to writing your own ASCII print routine.
Add the BASIC driver of Listing 4 (replacing the hex loader if you used it), and RUN the program to save it to tape. After saving (or subsequently re-loading) the whole business is quickly transferred into its operating region in low memory by the little routine (Listing 3) at 4286h (17030d).
Listing 1. Hex Loader
1 PRINT 0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0
10 REM HEX LOADER
15 POKE 16513,234
20 FOR I=16514 TO 17041
22 LET AD=I-6274
23 LET H=INT (AD/256)
24 LET L=AD-256*H
25 LET HH=INT (H/16)
26 LET HL=H-16*HH
27 LET LH=INT (L/16)
28 LET LL=L-16*LH
29 LET A$=CHR$ (HH+28)+CHR$ (HL+28)+CHR$ (LH+28)+CHR$ (LL+28)
30 SCROLL
35 PRINT A$,
40 INPUT B$
50 LET A=16*(CODE B$(1)-28)+CODE B$(2)-28
60 PRINT B$
70 POKE I,A
80 NEXT I
Table 1. ASCII Conversion Table Hex Values from 2800 to 287F
20: 20: 20: 20: 20: 20: 20: 20: 20: 20: 20: 22: 23: 24: 3A: 3F: 28: 29: 3E: 3C: 3D: 2B: 2D: 2A: 2F: 3B: 2C: 2E: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 61: 62: 63: 64: 65: 66: 67: 68: 69: 6A: 6B: 6C: 6D: 6E: 6F: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 7A: 20: 20: 20: 20: 20: 20: 20: 20: 20: 20: 20: 7C: 25: 26: 60: 21: 7B: 7D: 7E: 5F: 5B: 40: 5D: 7F: 5C: 5E: 27: 20: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 41: 42: 43: 44: 45: 46: 47: 48: 49: 4A: 4B: 4C: 4D: 4E: 4F: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 5A:
NOTE: Enter values shown ACROSS from left to right, top to bottom.
Driver Machine Code
Listing 2.
2880~1618 COPY LD D,18 / >COPY FULL SCREEN
2882 2A0C40 COPD LD HL,(DFIL) :Copy D lines
2885 23 INC HL :Next address
2886 7E LD A,(HL) :Get character in A
2887 FE76 CP 76 :End of line?
2889 2805 JR Z 2890 :Yes.
288B CDBD29 CALL NRML :No. Ship it out,
288E 18F5 JR 2885 and loop back.
2890 CDCD29 CALL LFED :Send line feed
2893 15 DEC D :Decrement Line counter,
2894 20EF JR NZ 2885 and do next line
2896 C9 RET unless done.
2897 ED4B3240 COPN LD BC,(SEED) >COPY N LINES
289B 79 LD A,C :No. of lines in A.
289C FE19 CP 19 ; :Over-range?
289E D0 RET NC :Yes, so return.
289F 57 LD D,A :No, put it in D,
28A0 18E0 JR COPD and go to COPD.
28A2 2A0A40 LIST LD HL,(EPPC) >LLIST PROGRAM
28A5 CDD809 CALL LIAD :Get line start addr.
28A8 7E NEXL LD A,(HL) :First char. in A.
28A9 FE76 CP 76 :End of program?
28AB C8 RET Z :Yes, so return.
28AC 46 LD B,(HL) :No. Get line
28AD 23 INC HL number
28AE 4E LD C,(HL) in BC
28AF 23 INC HL and increment.
28B0 E5 PUSH HL :Save the address.
28B1 C5 LNBR PUSH BC :Get line no. from BC
28B2 E1 POP HL into HL.
28B3 11E803 THOU LD DE,03E8 :Thousands digit
28B6 CDD428 CALL DCML gets printed,
28B9 116400 HUND LD DE,0064 then hundreds,
28BC CDD428 CALL DCML
28BF 110A00 TENS LD DE,000A tens,
28C2 CDD428 CALL DCML
28C5 110100 ONES LD DE,0001 and finally units
28C8 CDD428 CALL DCML get shipped out.
28CB AF XOR A :Set "space NOT"
28CC 320940 LD (VERS),A flag, and
28CF CDBD29 CALL NRML print space.
28D2 180F JR LLEN :Continue to LLEN.
28D4 AF DCML XOR A :DECIMAL CONVERSION
28D5 ED52 SUBT SBC HL,DE :Subtract modulus.
28D7~3803 JR C BORO :"Borrow?"
28D9 3C INC A :No. Incr. counter,
28DA 18F9 JR SUBT and subtract again.
28DC 19 BORO ADD HL,DE :Yes. Add it back,
28DD C630 ADD A,30 K convert to ASCII,
28DF CDD829 CALL ASCI and print it.
28E2 C9 RET :Return for next digit.
28E3 E1 LLEN POP HL :Retrieve addr.,
28E4 5E LD E,(HL) and get line
28E5 23 INC HL length in DE,
28E6 56 LD D,(HL) point to
28E7 23 NXCH INC HL next character, and
28E8 1B DEC DE decr. length counter.
28E9 7A ELN? LD A,D :Have we reached
28EA B3 OR E end of line?
28EB 200A JR NZ TEXT :No. It's text of line.
28ED CDCD29 CALL LFED :Yes. send LF,
28F0 CD460F BRK? CALL BRAK check for BREAK,
28F3 D0 RET NC and quit if so.
28F4 23 INC HL :Else incr. add.
28F5 18B1 JR NEXL and do next line.
28F7 7E TEXT LD A,(HL) :Text char. in A.
28F8 FE7E CP 7E :Is is number slug?
28FA 200C JR NZ NOTN :No. Go on.
28FC 23 INC HL :Yes,
28FD 23 INC HL
28FE 23 INC HL so
28FF 23 INC HL
2900 23 INC HL skip
2901 1B DEC DE
2902 1B DEC DE it,
2903 1B DEC DE
2904 1B DEC DE and get
2905 1B DEC DE
2906 18DF JR NXCH next character.
2908 F5 NOTN PUSH AF :Save character, and
2909 E67F AND 7F reduce modulus 80h.
290B FE40 TKN? CP 40 :Is it a token?
290D 300B JR NC TOKN :Yes. Go to TOKN.
290F F1 POP AF :No. Get character,
2910 CDBD29 CALL NRML and print it.
2913 3E01 LD A,01 :Now reset "Space
2915 320940 LD (VERS),A NOT" flag,
2918 18CD JR NXCH next character.
291A~3A0940 TOKN LD A,(VERS) :It's a token; space
291D A7 AND A already printed?
291E 2809 JR Z NLSP :Yes- don't print again.
2920 AF LSPC XOR A :No.
2921 320940 LD (VERS),A Set "Space NOT,"
2924 CDBD29 CALL NRML print the space,
2927 1804 JR PRTK and go on.
2929 3C NLSP INC A :Reset
292A 320940 LD (VERS),A "space NOT."
292D F1 PRTK POP AF :Get token code,
292E CD7509 CALL TOKA find ROM address.
2931 0A NTCH LD A,(BC) :Next char. in token.
2932 F5 PUSH AF :Save it, then
2933 E67F AND 7F modulus 80h.
2935 FE0F CP 0F ? :Illegal "token?"
2937 2002 JR NZ OKTK :No. Valid token.
2939 3E92 ILGL LD A,92 :Yes. Repl. with a " ~ "
293B CDBD29 OKTK CALL NRML Print character.
293E 03 INC BC :Incr. address
293F F1 POP AF and retrieve char.
2940 FE80 CP 80 :Was it inverse (last)?
2942 38ED JR C NTCH :No. Loop back.
2944 AF TSPC XOR A :Set "space Not",
2945 320940 LD (VERS),A and print
2948 CDBD29 CALL NRML trailing space.
294B 189A JR NXCH :Next character.
294D ED4B3240 LPRT LD BC,(SEED) : >LPRINT ROUTINE
2951 79 LD A,C :Var. char. code in A,
2952 C6A0 ADD A,A0 :add 160 (for array
2954 47 LD B,A var. check). Move to B.
2955 ED5B1040 LD DE,(VARS) :Get VARS start add.
2959 EB NXVR EX DE,HL :Next variable.
295A 7E LD A,(HL) :Get var. name.
295B B8 CKAR CP B :Check for string array.
295C 2816 JR Z ARAY :Yes. Handle as such.
295E C680 ADD A,80 :No. Add 128 for
2960 2002 JR NZ CKSP simple string check.
2962 CF NFND RST 08H :Var. not found,
2963 01 ERROR 2 error back out.
2964 B8 CKSP CP B :Simple string var.?
2965 2807 JR Z SMPL :Yes. Handle as such.
2967 C5 PUSH BC :No. Save search code,
2968 CDF209 CALL NXBV get next var. addr.,
296B C1 POP BC get search code,
296C~18EB JR NXVR and start over.
296E 23 SMPL INC HL :It's a simple
296F 5E LD E,(HL) string variable
2970 23 INC HL so get start
2971 56 LD D,(HL) address in DE,
2972 180D JR PVAR then print it.
2974 23 ARAY INC HL :It's a string
2975 5E LD E,(HL)
2976 23 INC HL array variable,
2977 56 LD D,(HL)
2978 23 INC HL so find out
2979 1B DEC DE
297A 46 LD B,(HL) how many dims.,
297B 23 GTST INC HL /
297C 23 INC HL then step addr.
297D 1B DEC DE
297E 1B DEC DE and counter
297F 10FA DJNZ GTST till start found.
2981 23 PVAR INC HL :Next character addr
2982 7A LD A,D :Check if counter
2983 B3 OR E down to zero.
2984 2004 JR NZ GCHR :No, so go on.
2986 CDCD29 CALL LFED :Yes, send a LF
2989 C9 RET and return.
298A 7E GCHR LD A,(HL) :Get the character.
298B FE76 CP 76 :Is it an "Enter?"
298D 2005 JR NZ PCHR :No. Print it as-is.
298F CDCD29 CALL LFED :Yes. Send a LF
2992 1803 JR NCHR and get next char.
2994 CDAD29 PCHR CALL RVRS :Send it out.
2997 1B NCHR DEC DE :Decrement counter,
2998 18E7 JR PVAR and loop back.
299A 21AD29 LPR1 LD HL,RVRS : >LPRINT 1
299D 1808 JR 29A7 :Inverse = CAPITALS
299F 21BD29 LPR2 LD HL,NRML : >LPRINT 2
29A2 1803 JR 29A7 :Inverse = LOWERCASE
29A4 21D829 LPR3 LD HL,ASCI : >LPRINT 3 - ASCII code.
29A7 229529 LD (2995),HL :Set LPRINT CALL,
29AA 18A1 JR LPRT go to main routine.
29AC 00 NOP :INV.=CAPS SUBROUTINE
29AD E5 RVRS PUSH HL :Save address
29AE 2628 XLAT LD H,28 C :Hi byte of conv. table
29B0 CB7F BIT 7,A :Inverse?
29B2 2802 JR Z 29B6
29B4~D640 SUB 40 :Yes, subtract 64.
29B6 6F LD L,A :Low byte of conv. table.
29B7 7E LD A,(HL) :Look it up,
29B8 E1 POP HL get address back,
29B9 CDD829 CALL ASCI send it out,
29BC C9 RET and return.
29BD E5 NRML PUSH HL :INV.=L.C. SUBROUTINE
29BE F5 PUSH AF :Save Sinc. character.
29BF E67F AND 7F :Modulus 128d.
29C1 FE1C CP 1C 0 :Is it a symbol?
29C3 3805 JR C 29CA :Yes. Leave unchanged.
29C5 F1 POP AF :No. Change cases.
29C6 C680 ADD A,80
29C8 18E4 JR XLAT
29CA F1 POP AF
29CB 18E1 JR XLAT
29CD 3E0D LFED LD A,0D $ :LINE-FEED SUBROUTINE
29CF CDD829 CALL ASCI :Send a CR,
29D2 3E0A LD A,0A
29D4 CDD829 CALL ASCI and an LF.
29D7 C9 RET
29D8 E5 ASCI PUSH HL :PRINT ASCII SUBROUT.
29D9 D5 PUSH DE for TASMAN interface.
29DA C5 PUSH BC Save registers,
29DB F5 PUSH AF and ASCII char.
29DC CDE702 CALL TFAS :Temp. FAST mode.
29DF DBBF STAT IN A,(BF) :Printer ready?
29E1 CB47 BIT 0,A Loop back
29E3 20FA JR NZ STAT if not.
29E5 AF STUP XOR A :Else set up
29E6 D3FB OUT (FB),A PIO chip
29E8 3D DEC A parameters
29E9 D37B OUT (7B),A for "transmit."
29EB D3FB OUT (FB),A
29ED F1 SEND POP AF Then get char.
29EE D37B OUT (7B),A and ship it out.
29F0 3EF7 RSTR LD A,F7 :Now restore
29F2 D3FB OUT (FB),A PIO chip
29F4 3EFF LD A,FF for next time.
29F6 D3FB OUT (FB),A
29F8 CD0702 CALL MDCK :Mode check.
29FB C1 POP BC
29FC D1 POP DE :Restore registers.
29FD E1 POP HL
29FE~C9 RET
29FF 00 NOP
ASCII Print Routines For Various Interfaces
BYTE-BACK RS232 INTERFACE AND MD-2
29D8~E5 ASCI PUSH HL
29D9 D5 PUSH DE
29DA C5 PUSH BC
29DB F5 PUSH AF
29DC CDE702 CALL TFAS
29DF 3AFF3F STAT LD A,(3FFF)
29E2 E601 AND 01
29E4 28F9 JR Z STAT
29E6 F1 SEND POP AF
29E7 32FE3F LD (3FFE),A
29EA CD0702 CALL MDCK
29ED CDF429 CALL DLAY
29F0 C1 POP BC
29F1 D1 POP DE
29F2 E1 POP HL
29F3 C9 RET
29F4 0610 DLAY LD B,10 (
29F6 3EFF LD A,FF
29F8 3D DEC A
29F9 20FD JR NZ 29F8
29FB 10F9 DJNZ 29F6
29FD C9 RET
DLAY routine may not be necessary with your printer; experiment with different values in 29F5. 120 units=about 1 sec. in SLOW mode. Min. delay is when 29F7=01 an 29F5=01.
J.L.O. CENT. INTERFACE
29D8~E5 ASCI PUSH HL
29D9 D5 PUSH DE
29DA C5 PUSH BC
29DB F5 PUSH AF
29DC CDE702 CALL TFAS
29DF 3AFFFF STAT LD A,(FFFF)
29E2 FE18 CP 18 /
29E4 20F9 JR NZ STAT
29E6 F1 SEND POP AF
29E7 32FFFF LD (FFFF),A
29EA CD0702 CALL MDCK
29ED C1 POP BC
29EE D1 POP DE
29EF E1 POP HL
29F0 C9 RET
BYTE-BACK CENT. INTERFACE
29D8~E5 ASCI PUSH HL
29D9 D5 PUSH DE
29DA C5 PUSH BC
29DB F5 PUSH AF
29DC CDE702 CALL TFAS
29DF DB1F STAT IN A,(1F 3)
29E1 CB7F BIT 7,A
29E3 28FA JR Z STAT
29E5 F1 SEND POP AF
29E6 D31F OUT (1F 3),A
29E8 CD0702 CALL MDCK
29EB C1 POP BC
29EC D1 POP DE
29ED E1 POP HL
29EE C9 RET
AERCO CENT. INTERFACE
29D8~E5 ASCI PUSH HL
29D9 D5 PUSH DE
29DA C5 PUSH BC
29DB F5 PUSH AF
29DC CDE702 CALL TFAS
29DF DB7F STAT IN A,(7F)
29E1 CB67 BIT 4,A
29E3 20FA JR NZ STAT
29E5 F1 SEND POP AF
29E6 D37F OUT (7F),A
29E8 00 NOP
29E9 00 NOP
29EA DB7F RSTR IN A,(7F)
29EC CD0702 CALL MDCK
29EF C1 POP BC
29F0 D1 POP DE
29F1 E1 POP HL
29F2 C9 RET
Customizing Graphics
You may customize your version to allow LPRINT, COPY and LLIST of graphics characters. As listed, the conversion table sends spaces for these, since not all printers support the block graphics. If yours does, answer “Y” and enter the ASCII codes for each graphic symbol in turn. (Consult SWN Vol. 1 for Gemini 10X, or your printer manual.)
You may want to define the graphics characters to print control codes. (Example: make the graphic on “A” the ESC code 27d, and the graphics on S, D, F, G and H your most-used ESC commands like 10/12 CPI, underline on/off, etc. Be warned though; this may cause strange effects with LLIST/COPY.) SAVE the finished result to tape for future use by answering “Y” on “SAVE?” If you made a mistake, answer “N” and do it over with GOTO 50.
Patching Hot Z
The COPY routines use the D register as a line counter for compatability with Hot-Z II and other programs that patch into the Sinclair COPY command. To patch the Hot Z II “COPY” command, change the command at 63F9 to CALL 2882. Patching the “COPY cursor to END” is only slightly more involved:
5D1D E5 PUSH HL
5D1E CD8628 CALL 2886
5D21 E1 POP HL
5D22 00 NOP
If you have 32K or more, you can then use Hot Z II to load itself into high memory starting at 8009h (END at B4E5). Then set cursor to 5D1D, END to 63FB, and transfer to 92E1. Save it back to a new tape for future use.
If you have only 16K, then merge HOT Z II with BIGREM, Quit and Save the whole enchilada to your new tape. After re-loading, go back into Hot Z with RAND USR 22528 (cold start) or RAND USR 27273 (warm start; must be from SLOW mode).
Eprom Notes
If you have one of the I/F’s that have an EPROM that overlays the ROM and contains its own printer driver, and you wish to use “UPD” instead, you can disable the EPROM. On most devices you can simply disable the EPROM by disconnecting its CHIP SELECT NOT and CHIP ENABLE NOT and tying them to +5V.
To disable the AERCO ROM card, the recommended modification is to cut the trace to pin 11 of the 74LS27 and tie it to +5V instead. (It is presently connected to ground.) Better yet, install a SPDT switch so you can turn the EPROM on and off at will.
The Memotech CIF is the one unit that I know of on which this won’t work; it has a PAL chip that does the overlay decoding, and I haven’t figured out a way to turn it off and still have the I/O port work.
The Byte-Back Modem and RS232 IF might present a problem with some RAMs since the IF and modem are memory-mapped at 3FFE-3FFF. If you can’t get it to work with RAM enabled in the 8-16K range, there is a one-chip mod to handle it. (If this doesn’t appear in this issue, contact me for details.)
Basic Driver Listing 4.
1 REM 530 SPACES FOR TABLE, CODE, AND DOWN-LOADER.
10 SAVE "UPD-TAS"
20 PRINT "UPD IS LOADED.",,,,"USR 10368 = COPY 24 LINES",,," RAND N, THEN USR 10391"," = COPY N LINES ",,," LIST N, THEN USR 10402 "," = LLIST STARTING AT LINE N",,," RAND CODE ""(VAR. NAME)"", THEN "," USR 10650: INVERSE=CAPITALS"," USR 10655: INVERSE=LOWERCASE"," USR 10660: SEND AS ASCII CODE"
40 RAND USR 17030
45 PAUSE 4E4
50 CLS
60 PRINT ,," INPUT CUSTOM GRAPHIC CHARACTERS?"
65 PAUSE 4E4
70 IF INKEY$="N" THEN STOP
80 IF INKEY$<>"Y" THEN GOTO 65
90 PRINT AT 10,0;"CODE CHR$ ","PRESENT NEW ",," VAL VAL "
95 SCROLL
100 LET C=0
105 FOR A=1 TO 74
110 IF A=11 THEN LET C=64
115 IF A=11 THEN LET A=64
125 PRINT A+C;TAB 6;CHR$ (A+C)," ";PEEK (A+16514);TAB 24;"?"
130 INPUT B
140 POKE A+16514,B
150 PRINT AT 21,24;B
155 SCROLL
157 SCROLL
160 NEXT A
165 PAUSE 4E4
167 CLS
170 PRINT "SAVE? Y/N"
175 PAUSE 4E4
180 IF INKEY$="N" THEN STOP
190 IF INKEY$="Y" THEN RUN
200 GOTO 170
Relocating UPD
Relocating UPD is simple. Start by changing all CALLs to the new addresses. There are no absolute JPs. The only other commands that need to be changed are at 299A, 299F, 29A4, & 29A7. These load the argument of the CALL at 2994 with the selected routine for LPRINT. Hot Z II’s “relocate” command will do this all for you.
The conversion table must start at an address with the low byte = zero (e.g. 2000h, 4100h, etc.) If you relocate the table, then change the command at 29AE to LD H,(new high byte value). This is the only change you’ll have to make if you use Hot Z II’s “Relocate” command.
DOWN-LOAD TRANSFER ROUTINE
4286~010002 LD BC,0200
4289 110028 LD DE,2800
428C 218240 LD HL,4082
428F EDB0 LDIR
4291 C9 RET
4292 00 NOP
If you are using the hex loader, enter the hex values (01, 00, 02, etc.) starting at prompt address 2A04
You also have to change the transfer address in the down-load routine, and modify all BASIC USR call addresses accordingly.
Open Invitation
This printer driver is the result of considerable effort by myself and others to get the most flexible and compact software possible. In the interest of standardization, I cordially invite present and future interface manufacturers to supply this routine with their units, PROVIDED THERE IS NO ADDITIONAL CHARGE TO THE CUSTOMER, aside from a maximum $5 handling charge. These routines are therefore not copyrighted, though I would appreciate mention of the source.
My thanks go out to Donald Thompson, Bill Fisher, Thomas B. Woods, Aerco, Byte-Back and Memotech for their help and contributions.
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.