Run Machine Code in High Memory

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
Post Reply
RWAP
Posts: 1348
Joined: Thu May 08, 2008 8:42 am
Location: Stoke-on-Trent, UK
Contact:

Run Machine Code in High Memory

Post by RWAP »

I have now uploaded an article by John Oliger (originally published in the Syntax magazine - Summer 1983) which describes the modifications to enable you to use the 32K-48K RAM area for machine code. This is known as the NOT M1 decoding circuit.

This also includes further articles by Jeffrey D. Moore, on changes required enable the feature to be used with the Byte-Back M-64 or UM-64K memory).

Interestingly the latter article mentions two programs which make use of this feature - Hot Z-11 by Ray Kingsley and Memotext in RAM, Version 3, modified and marketed by Fred Nachbaur.

I am not sure what the advantage of this is in reality, or whatever happened to those original programs!

Although the article is based on the TS1000 - I presume it equally applies to the ZX81?

Download the articles
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Re: Run Machine Code in High Memory

Post by David G »

Yes, the Timex/Sinclair 1000 is a ZX81, using a ZX81 UK motherboard fitted with the optional 2K RAM chip and jumpered for 60hz television. The ROM is the same as a ZX81


The articles Rich uploaded are no longer available at that link, but from his description seem to be from SyncWare News Volume 2 no. 5 May-Jun, '85, which includes these two articles on pages 10-12: also an earlier John Oliger article on the same topic: MEMORY DECODING ABOVE 16K
Last edited by David G on Sat Nov 19, 2022 12:46 am, edited 1 time in total.
User avatar
mrtinb
Posts: 1906
Joined: Fri Nov 06, 2015 5:44 pm
Location: Denmark
Contact:

Re: Run Machine Code in High Memory

Post by mrtinb »

Andy Rea's ULA has a jumper to enable/disable M1NOT. I have used it primarily with Hot-Z II (called Hi-Z).

However my current setup only has 16k, so here I use a 16k version of Hot-Z II.
Martin
https://zx.rtin.be
ZX81, Lambda 8300, Commodore 64, Mac G4 Cube
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Run Machine Code in High Memory by John Oliger

Post by David G »

This circuit will allow you to use the 32-48K RAM area for machine code, with RAM packs such as the Memotech Memopak 64 or JLO 64K, but not the Byte-Back UM.


From SyncWare News Volume 2 no. 5 May-June 1985 page 10
HARDWARE PROJECTS

Run TS1000 Machine Code in High Memory

John Oliger

ZX81ers don't despair! This next trick was originally published in Syntax Quarterly, Summer 1983. It will allow you to use the 32-48K RAM area for machine code, if you have the Memotech or JLO 64K boards (and maybe some others, but not the Byte-Back UM).

It is necessary to add a little extra circuitry to separate out the video system from the dynamic RAM system, as Sinclair never dreamed of a ZX81 with more than 16K. Very simply, you cut the M1 not trace between the Z80 (pin 27) and the ULA (pin 10). Connect pin 2 to the Z80 side and the output on pin 8 to the ULA side. Again, use an ohm meter to chase down the A14, A15, Vcc (5 volts) and ground lines. They can all be picked up at or near the edge connector (except pin 8), but you may find some more convenient places. The diagrams show some very good places to pick up these traces. Be sure to remove all ICs (if possible) before doing any soldering.

Any relocatable programs will run here and not be affected by NEW or reset. ZXLR-8, Delphic toolkit, compiled programs with the Bob Berch Compiler, Hot Z and an assortment of other utilities will work up there and NOT interfere with any 16K program on the market.

TS1000 32 to 48K Machine Code Modification
TS1000 32 to 48K Machine Code Modification
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Re: Run Machine Code in High Memory

Post by David G »

mrtinb wrote: Wed Nov 16, 2022 7:30 pm Andy Rea's ULA has a jumper to enable/disable M1NOT.
So is "M1NOT" the same as the John Oliger machine code circuit modification? I think so as Jeffrey D. Moore calls it "Oliger's NOT Ml decoding circuit"
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

MEMORY DECODING ABOVE 16K by John Oliger

Post by David G »

I found this earlier article by John Oliger which outlined how to modify a ZX81 to use more memory than 16K. It uses a quad NAND gate IC chip (74LS00) to decode the chip select for an extra 16K (for example, when using two 16K RAM packs)

"M1NOT" is not explicitly stated, but for the 3rd 16K block it uses _M1_ (meaning the M1 pin signal inverted [NOT]) or as shown in the diagram:
__
M1


From SYNTAX ZX80 VOL. 3 NO. 5 MAY 1982 page 5
MEMORY DECODING ABOVE 16K

Sinclair made the ZX81 RAM easy to decode up to 16K, but you may want to add memory beyond this point. To add more than 16K memory to your ZX80/81, you must do more than just:

Code: Select all

_A13_ AND _A14_ AND _A15_ = _ROM_CS_
You’ll also need to account for the behavior of the display file.

If you decode your 1st 16K block with A14=1 and A15=0, the system crashes. ZX computers need the display file active for display, and the 8K ROM makes A15 high during display. You can use the relation:

Code: Select all

_____________________
A14 AND (Ml OR _A15_) = _RAM_CS_  0-16K
To get the second 16K block use:

Code: Select all

_______________
_A14_ AND _A15_ = _RAM_CS_  16-32K
Get the 3rd 16K block using:

Code: Select all

____________________
A14 AND A15 AND _M1_ = _RAM_CS_  32-48K
Sinclair RAMs lack this decoding; you must add it to stack 16K modules.

Use of high-memory sites is limited by the 8K ROM. You can’t run Z80 machine language routines here, nor extend the display file past 32768. Store variables and arrays in these high locations.

To find the end of the display file,

Code: Select all

PRINT PEEK 16400+256*PEEK 16401

With the extended memory, you must POKE 16388,255 & POKE 16389,255 & NEW, after you power up, but before you load any program. (The ZX8l only checks memory addresses up to 32768, and sets RAMTOP there when you power up.) If you poke RAMTOP too high, your computer will set it correctly after the NEW command.

John L. Oliger
Indianapolis, IN

Code: Select all

All Gates--74LS00 
                          ______       ______
       ______      A14 ---|     \      RAM CS
A15 ---|     \            |      |O-----------
 __    |      |O----------|_____/
 M1 ---|_____/                         0-16K

                          ______       ______
       _______     A15 ---|     \      RAM CS
     +-|      \           |      |O------------
     | |       |O- -------|_____/
A14 -+-|______/                        16-32K

       _____
A14 ---|    \     _____
       |     |O-+-|    \     _____     ______
A15 ---|____/   | |     |O-+-|    \    RAM CS
                +-|____/     |     |O----------
                           +-|____/
                         __|
                         M1            32-48K
All Gates--74LS00
All Gates--74LS00
User avatar
1024MAK
Posts: 5102
Joined: Mon Sep 26, 2011 10:56 am
Location: Looking forward to summer in Somerset, UK...

Re: Run Machine Code in High Memory

Post by 1024MAK »

Basically, the /M1 line from the Z80A has to be included in the address decoding. When /M1 is low, the area of RAM that normally contains the display file must be made available in the upper area (A14 and A15 high, 0xC000 to 0xFFFF). When /M1 is high, the address decoding can be done normally. Then the Z80A can store and read data in the upper area (0xC000 to 0xFFFF) but machine code cannot be run from this area.

For the area 0x8000 to 0xBFFF, there is no restriction on how the RAM is used, but the /ROMCS line needs to be taken high to prevent it from causing a data bus clash.

A standard ZX81 or TS1000 memory map can be summarised as:

Code: Select all

A15 A14
 0   0   0000 - 3FFF ROM
 0   1   4000 - 7FFF RAM
 1   0   8000 - BFFF ROM (same as 0000 - 3FFF)
 1   1   C000 - FFFF RAM (same as 4000 - 7FFF)
A14 selects between ROM or RAM, A15 selects between normal memory use and video memory use.

See also this post

Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp

:!: Standby alert :!:
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :!:
Looking forward to summer later in the year.
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Re: Run Machine Code in High Memory

Post by David G »

Thanks
David G
Posts: 387
Joined: Thu Jul 17, 2014 7:58 am
Location: 21 North, 156 West

Additional Byte-Back Memory Notes by Jeffrey D. Moore

Post by David G »

Second article


To use machine code (MC) in the above-32K RAM area requires two things:
  • Modify the BYTE-BACK M-64/UM-64 memory pack
  • Modify your ZX81 for M1 NOT Decoding per John Oliger's article
The UM-64 had an EEPROM socket and battery backup, in addition to the 64K dynamic RAM. Both M-64 and UM-64 have switches to de-select certain blocks of RAM (to allow ROMs in other devices to work?), so perhaps how that feature was implemented is what interfered with the M1 NOT circuit. In any case this article explains how to use it successfully


From SyncWare News Volume 2 no. 5 May-June 1985 page 10-12
HARDWARE PROJECTS

Additional Byte-Back Memory Pack Notes:

Jeffrey D. Moore
602 S. Mill Street
Louisville, Ohio 44641

Thanks to John Oliger's NOT Ml decoding circuit, many new and excellent pieces of software are coming into the market place that make use of machine language routines in the 32K-48K (8000-BFFF hex) region of memory. Some examples of these would include Hot Z-II by Ray Kingsley and Memotext in RAM, Version 3, modified and marketed by Fred Nachbaur.

However, there is one catch! It is best summed up by Ray Kingsley in his Hot Z-II User's Notes. "If you have a suitable memory...Oliger or Memotech or possibly another: Not a Byte-Back M-64 (or UM-64K memory-JM [Jeffrey Moore])...and you make the Oliger modification to your computer, you can run machine code in the 32K-48K block...".

I contacted Mr. Oliger, and he sadly confirmed that it was true, a Byte-Back M-64 or a UM-64K memory would not work with the NOT Ml decoding circuit. However, our conversation, and subsequent correspondence, led Mr. Oliger to develop the two chip buffer circuit shown in figure 1. I implemented and tested it in the Byte-Back M-64 Memory Pack, and found that it works great!

The buffer circuit itself should be constructed on a small universal circuit board (Radio Shack 276-150, or equiv., works well). Mount the buffer circuit on the heat sink side of the M-64/UM-64K memory circuit board with double-faced foam tape after all the wiring and inter-connections are complete. Care MUST be taken to fully electrically insulate the small board from the main board.


M-64 Hook-up

Modification of the M-64K memory board requires that two circuit traces be cut and seven wires installed to add the new circuit to the existing memory circuit. Find the 74LS08 (U12) chip on the M-64K memory board. Locate the circuit trace going from a feed-thru hole to pin 6 of this IC. Cut the trace between the feed-thru hole and pin 6 of U12. On the heat sink side of the M-64K memory board, locate the circuit trace going to pin 4 of the 74LS32 IC (Ull) and cut it at a convenient place. Using the plated feed-thru holes on the M-64K memory board where possible as solder points (not necessary, but it makes for a neater job), make the following connections:

1) Connect Vcc of the buffer board to the hole for pin 16 of the spare chip on the M-64K memory board.

2) Connect GND (ground) of the buffer board to the hole for pin 8 of the spare chip on the M-64K memory board.

3) Connect A15 of the buffer board (74LS08 pin 2 and 74LS86 pin 10) to pin 5 of the 74LS08 (U12) on the M-64K memory board.

4) Install a jumper on the M-64K memory board from pin 5 of the 74LS08 (U12) to pin 4 of the 74LS32 (Ull).

5) Connect A14 of the buffer board (74LS08 pin 1) to pin 5 of the 74LS32 (Ull) on the M-64K memory board.

6) Connect NOT Ml of the buffer board (74LS86 pin 12) to pin 4 of the 74LS08 (U12) on the M-64K memory board.

7) Finally, connect the output of the buffer board (74LS86 pin 8) to pin 2 of the 74LS244 IC chip (U16) closest to the 74LS08 chip (U12) on the M-64K memory
board.

BACKSIDE of UM 64
BACKSIDE of UM 64
UM-64 Connections

Figure 1. MODIFICATION for the BYTE BACK UM-64 RAM PACK
Figure 1. MODIFICATION for the BYTE BACK UM-64 RAM PACK

On the UM-64K memory board, one jumper needs to be removed, one trace needs to be cut, and seven wires must be connected, [Note: If you install the decoder board on the back of the UM-64 board, you may not have room for the backup battery. If this is important, consider mounting the decoding chips upside-down on one of the RAM IC's on the front side with crazy glue. Run "flying leads" to the appropriate circuit points, -ed.]

1) Remove the jumper (trace cut) going from "C" to "D".

2) Locate the circuit trace going to pin 2 of the 74LS244 IC (U16) closest to the EPROM socket and cut the trace in a convenient location, as close to pin 2 as possible.


Using feed-thru holes where available, make the following connections:

3) Connect +Vcc on the buffer board to +5 volts on the UM-64K memory board at a convenient location.

4) Connect GND of the buffer board to GND on the UM-64K memory board at a convenient location.

5) Connect A15 of the buffer board (74LS86 pin 10 and 74LS08 pin 2) to pin 5 of 74LS08 (U10) of the UM-64K memory board.

6) Install a jumper on the UM-64K memory board from pin 5 of the 74LS08 (U10) to "C" (A15 needs to be connected to pin 5 of U9, through "C" is the easiest way to get there).

7) Connect A14 of the buffer board (74LS08 pin 1) to pin 4 of the 74LS32 (U9) of the UM-64K memory board.

8) Connect NOT Ml of the buffer board (74LS86 pin 12) to pin 4 of the 74LS08 (U10) of the UM-64K memory board.

9) Finally, connect the output of the buffer board (74LS86 pin 8) to pin 2 of the 74LS244 chip (U16) closest to the PROM socket on the UM-64K memory board.

Be sure to double check all of your connections to insure that they are correct and that you have not created any solder bridges. Make sure the buffer board is secure to the M-64K memory board and that they are insulated from each other.

If you haven't already done so, make the modifications to your computer for NOT Ml Decoding per John O1iger*s article and test that circuit.

When all is well, power down your computer and connect the modified M-64K/UM-64K Memory Pack to it. Power back up. If that old familiar little "K" cursor shows up on the screen, you're over half way home. If not, immediately power down and re-check the buffer circuit and its connections for shorts and improper wiring. When everything checks out and powers up O.K. with the modified memory pack connected, enter the following commands: POKE 40000,201 followed by PRINT USR 40000. The screen should return 40000. This is a fair indication that everything is pretty much as it should be, but it is not foolproof. The "acid" test is to now load or write a program that runs MC in the 32K-48K region of memory and try it. It should now run correctly without any problems.
Post Reply