Here is how to make a copy of the “Memotext” word-processor, which you can save to tape and re-load later into RAM or NVM (non-volatile memory) in the 8-16K range. This will be useful if you, as I, have a second machine with Memotech CIF (Centronics printer interface) and wish to run Memotext without “tearing down” your main machine (or buying a second module, even if you can find one; Memotech no longer supplies them.) Or, the Memotext module may increase your ZX81/TS1000’s power demand to the point where you get crashes after extended operation on a hot day; if you could substitute an NVM board such as the Hunter board with its lower power consumption, you wouldn’t have to build or buy a larger power supply to accomodate Memotext. Lastly, TS1500 users will find this very useful, as the module runs into the cassette plugs, whereas the Hunter board should just barely fit.
Before we get into the step-by-step instructions for making a RAM-based version of Memotext, I should mention that this will require NO hardware modifications to your machine, and no additional software is needed to do the job. Although a “REM generator” is useful for the first step, it is not vital as I’ll describe a (relatively) quick and easy way of doing this “by hand.” The hardware required is a ZX81/TS1000 with at least 16K user RAM. Also you’ll need the CIF and (of course) Memotext modules. If you have the SIF (RS232 serial interface) the procedure should work equally well, though we haven’t actually tried it. The machine on which you run the final result should have, again, 16K RAM or higher, CIF (or SIF,) and RAM or NVM in the full 8-16K range (such as is afforded by a 64K pack or a Hunter board.)
Lest you’re worried about “conflicts” due to having the CIF module and RAM in the same area, fear not. We’ll duplicate the CIF (or SIF) program in the RAM, so that when this area (10-10.5K for CIF, possibly more for SIF) is addressed, both units return the same output on the data lines; result – both units “give the same answer” and no conflict can occur.
An additional bonus is that the unused area from 10.5-12K will be available for other routines, such as fast load/save programs, transfer routines, or other utilities. While we’re at it, we’ll also patch in a “QIT” function to allow return to BASIC from Memotext without having to power down or hit a reset switch. We’ll also add an alternate initialization step to preserve your current RAMTOP setting. Memotext, as supplied, uses up all available memory regardless of the initial RAMTOP setting, which can be a pain if you’re keeping other programs in “protected memory.” In an earlier issue I reported that you could keep protected programs in high memory, which remain there until you hit your RESET button to escape Memotext. This is true only if you’re careful not to go beyond 16K of text or data files; with the modified entry point, you can type away to your heart’s content until you get an “out of space” message. On entering QIT, you leave Memotext with your RAMTOP setting intact.
But enough introductory ramblings, already. Here’s how you go about performing this feat of magic.
1. Generate a REM …
Power up your ZX81/TS1000 with Memotext, CIF, and at least 16K RAM. Disable the 8-16K region if you’re using a 64K pack. Now generate a line 1 REM statement at least 8204 bytes long (8192 bytes for Memotext and CIF, 12 bytes for the transfer routine that will upload then later download the program.) If you have a REM generator utility, use it and proceed to step 2. Otherwise, go on to step 1A.
1a. …the Easy Way
If you had to type in an 8K REM statement a character at a time, it would probably be enough to make you give up computing for good. Fortunately, you can use a couple tricks to help matters immeasurably. First, go into FAST mode and type in a line 1 statement like this:
1 PRINT 0+0+0+0+0....+0
You will need a 1 PRINT 0 followed by 113 repetitions of “+0” – for a total of 114 zeroes and 113 pluses. Each “0” actually takes up seven bytes, so you’ve actually entered a statement 911 bytes long. (See “VDAQ” in SWN 1:5 for an explanation why this works.) Note that the keyword must be a PRINT, not a REM. Check that you have the right length; PRINT PEEK 18342 should return 118 (end of line “enter” character.) Now make eight more identical lines, using the edit function (shift 1) to bring down the line, change the line number to 2, and enter; keep doing this until you have nine lines, numbered consecutively 1-9. Now bring line 9 back down, and delete five repetitions of “+0” – and re-enter this slightly shorter version. At this point, check your work with with PRINT PEEK 24721; you should again get 118.
Now enter the following “immediate” commands (no line number:)
POKE 16511,17
POKE 16512,32
POKE 16513,234
The first two POKEs tell the computer that the line 1 is actually 8209 bytes long (including the PRINT and the “enter” at the end)- i.e. all the way to the end of line 9. The third POKE changes the first PRINT into a REM – you now have an 8207 byte REM statement. When you LIST 1, everything still looks the same, but you can verify that all nine lines have indeed been “swallowed up” by trying to LIST (or delete) lines 2, 3, etc. and you’ll see that these lines no longer exist, as such.
2. Put Memotext Into the REM
Now enter the BASIC lines of Listing 1. When you’ve checked them over for accuracy, hook up your tape recorder, put it in RECORD, and RUN the program. It will save to tape (in case you make a boo-boo later) and then prompt you to input the 12-byte transfer routine to load Memotext and CIF into the REM statement. Enter the values from Table 1; when all 12 have been entered, check that they’re all correct (if not, answer “N” on “ALL OK?” prompt, and do it over.)
LISTING 1.
10 SLOW
20 SAVE "MEMOTEX▒"
30 CLS
40 PRINT "INPUT TRANSFER ROUTINE",,
50 FOR A=24706 TO 24717
60 INPUT B
70 POKE A,B
80 PRINT A,PEEK A
90 NEXT A
100 PRINT ,,"ALL OK?"
110 IF INKEY$="Y" THEN GOTO 140
120 IF INKEY$="N" THEN GOTO 30
130 GOTO 110
140 CLS
150 PRINT "TURN MEMOTEXT ON"
160 PAUSE 300
170 RAND USR 24706
180 PRINT AT 0,15;"FF","THEN BREAK"
190 PAUSE 4E4
Assuming that you did it right, press “Y.” You now have five seconds during which to flip up the switch on Memotext. Don’t touch the keyboard while the Memotext module is on, or you might unwillingly enter the Memotext program. At the end of the five-second PAUSE, the transfer routine you laid in will almost instantly transfer the entire 8-16K region of memory (Memotext and CIF) into your line 1 REM. When prompted, flip Memotext OFF and then hit the BREAK key. If you LIST line 1, you will see that typical “machine-code-ese” has replaced all those PRINT 0+0+0’s.
At this point, once again SAVE to tape, this time from the immediate mode.
3. Making a few Changes
After SAVEing to help protect against Murphy’s Law, make the following POKEs:
POKE 24710,0
POKE 24711,32
POKE 24713,130
POKE 24714,64
These POKEs reverse the direction of the transfer routine, so you can later boot the whole works back down into the 8-16K RAM from the REM statement.
POKE 20951,54
POKE 20952,46
POKE 20953,57
POKE 20954,195
POKE 20955,3
These POKEs install the “QIT” function in the program’s function table. You can install your own additional functions starting at 20956 (later to be located at 12634,) e.g. to call other utilities from within Memotext. Five bytes are required for each function; the first three are the character codes of the function (Q, I, T in our case) and the last two are the address which is called by that function (low-high order – the BASIC “NEW” command in the case of the QIT command above.) There is room for up to three more commands after the QIT.
POKE 17245,42
POKE 17246,4
POKE 17247,64
POKE 17248,195
POKE 17249,90
POKE 17250,54
These POKEs set up a alternate entry point to the program. This entry point makes the program use the existing RAMTOP setting in initializing its stack, leaving the rest of “protected” memory alone.
Now delete BASIC lines 30 through 190, (leave in lines 10 and 20, and of course the line 1 REM) and again SAVE to tape using RUN (just in case of a screw-up.)
TABLE 1 ADDRESS VALUE ADDRESS VALUE 24706 1 24712 33 24707 0 24713 0 24708 32 24714 32 24709 17 24715 237 24710 130 24716 176 24711 64 24717 201
4. Enter the Basic ‘Loader’
Now enter lines 30 through 130 of Listing 2. Use tokens for words like AND, TO, RETURN, etc. in the PRINT statements if you wish to save a few seconds loading time. When you’ve checked for errors and corrected any you find, the RAM-based Memotext program is complete. SAVE to tape by entering RUN.
LISTING 2.
10 SLOW
20 SAVE "MEMOTEX▒"
30 POKE 8192,0
35 POKE 16383,0
40 POKE 8192,201
45 POKE 16383,201
50 IF PEEK 8192<>201 OR PEEK 16383<>201 THEN GOTO 100
60 RAND USR 24706
70 PRINT TAB 3;"*****MEMOTEXT STORED*****",,,"FLIP WRITE-PROTECT IF AVAILABLE.",,"ANY KEY TO "" NEW "" LOADER, THEN RAND USR 13824 TO ENTER MEMOTEXT(MUST BE IN ""SLOW"" MODE.)",,," TO EXIT MEMOTEXT AND RETURN TO BASIC, ENTER ""QIT"" IN RESPONSE TO ""FUNCTION?"" PROMPT."
75 PRINT ,,"TO RESTART MEMOTEXT:",," RAND USR 13824 OR 13890 TO USE ALL AVAILABLE RAM",,"OR",," RAND USR 8923 TO PRESERVE RAMTOP"
80 IF INKEY$="" THEN GOTO 80
90 NEW
100 PRINT "*****NO RAM IN 8-16K REGION*****",,"ENABLE NVM OR 8-16K RAM, THEN PRESS ANY KEY TO CONTINUE."
110 IF INKEY$="" THEN GOTO 110
120 CLS
130 GOTO 30
5. Testing the Program
After SAVEing, power down your computer and remove the Memotext module and install your NVM board or engage the 8-16K region of your 64K pack. Leave the CIF (and your printer) on-line, and power back up again. LOAD the final version of the program using LOAD “MEMOTEXT” – when loaded, the program checks the first and last bytes of the 8-16K range to verify that it’s there and can be written to; if you get the “No RAM in 8-16K region” message, you’ve probably just forgotten to enable it; do so now, and press any key. You should get the “Memotext Stored” report, indicating that the program has been successfully booted into low memory. You’re now ready to run Memotext.
Note that you have two (or rather three) options for entering the Memotext program itself. The first, accessed by RAND USR 13824 or RAND USR 13890 (use whichever you find easier to remember) causes the program to initialize as before; it checks to see if you have 16, 32, or 48K of user RAM, automatically sets RAMTOP and its stack accordingly, and proceeds into the program. The other entry point, accessed with RAND USR 8923, leaves RAMTOP alone and initializes to this point only. To escape Memotext after saving your files to tape, simply enter “QIT” from the “Main Program Loop” (“FUNCTION?” prompt.) Whichever entry you use, the program should operate exactly as detailed in the manual.
To make back-up copies of the tape, simple LOAD it, then press BREAK when the screen report appears; put in a blank tape, start the machine in RECORD, and enter RUN.
Final Comments
In case you’ve wondered how the Memotext module jumps into the program simply by pressing a key after flipping it ON, here’s how it works. The module’s hardware actually changes four ROM locations in the “warm boot” portion of the operating system. It changes the command at 0416h from CALL 0F23 (FAST) to CALL 0207 (“Mode check,”) and changes the command at 0419h from CALL 0A2A (CLS) to CALL 3600 (Memotext entry.) This part of the ROM is executed when you enter a command in the immediate mode – hence, the “auto-start” feature. In the RAM-based version, of course, this doesn’t happen, since we haven’t added the hardware to “jimmy” the ROM.
As indicated in the “title screen,” your USR call to Memotext must be made from SLOW mode. As near as I can tell, the program still works in FAST mode, though it doesn’t do you any good since you can’t see the screen display.
It is quite probable that a similar procedure will work to make RAM-based versions of the other Memotech program modules (Memocalc and Memotext assembler) as well as the Timex “Command Cartridges.” I’d be interested in hearing from anyone experimenting with this, and the results. Quite probably, in the case of the Memotech stuff, the same ROM changes are made; you can check this out by using HotZ (or a BASIC loop) to make a copy of the ROM in high memory with the module on, then quitting HotZ, and writing a simple BASIC loop to compare the actual ROM with the copy in hi-mem.
I would also be interested in hearing from anyone experimenting with the RAM-based Memotext using the JLO video upgrade. I haven’t finished building up my “Super ZX” with the JLO TMS 9918 upgrade, so haven’t been able to mess with it myself. It could be that the increased speed would make the auto-repeating key feature too fast; another challenge would be to find and change the timing loop that controls this.
This entire article was, of course, written using the the RAM-based version of Memotext. So if it doesn’t work for you, chances are something went wrong along the way – go back to the beginning and try again.
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.