Memory questions
Memory questions
I'm new to the spectrum, and I've been trying to find a detailed memory map of the 48k so I know what I'm allowed to use. These are the best resources I could find, but some areas are still unclear:
http://www.worldofspectrum.org/ZXBasicM ... hap25.html
http://www.breakintoprogram.co.uk/compu ... memory-map
The 0x0000-0x5BFF range is clear enough (ROM + screen memory + printer buffer), but after that I'm not sure. Is there a document/manual I'm missing that explains all the special memory areas? These are the questions I'm trying to answer:
1) What is 0x5CC0-0x5CCA reserved for?
2) What is 0xFF58-0xFFFF reserved for?
3) The blog says system variables are from 0x5C00-0x5CBF, but the manual stops at 0x5CB5. What are those undocumented 10 bytes for? I at least know to poke 111 into 0x5CBB to disable the "bytes: ___" messages (so said the loading screen tutorial), but I don't know why that works.
http://www.worldofspectrum.org/ZXBasicM ... hap25.html
http://www.breakintoprogram.co.uk/compu ... memory-map
The 0x0000-0x5BFF range is clear enough (ROM + screen memory + printer buffer), but after that I'm not sure. Is there a document/manual I'm missing that explains all the special memory areas? These are the questions I'm trying to answer:
1) What is 0x5CC0-0x5CCA reserved for?
2) What is 0xFF58-0xFFFF reserved for?
3) The blog says system variables are from 0x5C00-0x5CBF, but the manual stops at 0x5CB5. What are those undocumented 10 bytes for? I at least know to poke 111 into 0x5CBB to disable the "bytes: ___" messages (so said the loading screen tutorial), but I don't know why that works.
Re: Memory questions
The Devil is in the detail.
Like when you buy a car from a dealer, you got a whole bunch of different configurations depending on what options you selected. The same goes for the spectrum. Depending on what widgets you have connected to it alters in very subtle ways how the memory map works.
Do you have Interface I or II connected? how about the printer? That can change how the map looks.
In general terms, from a high level then sure it all looks kinda the same but its when you get down to levels of greater detail that these differences come into play.
Even assuming you are using Interface I, its not so simple - what device is connected and how many can alter the map.
Like when you buy a car from a dealer, you got a whole bunch of different configurations depending on what options you selected. The same goes for the spectrum. Depending on what widgets you have connected to it alters in very subtle ways how the memory map works.
Do you have Interface I or II connected? how about the printer? That can change how the map looks.
In general terms, from a high level then sure it all looks kinda the same but its when you get down to levels of greater detail that these differences come into play.
Even assuming you are using Interface I, its not so simple - what device is connected and how many can alter the map.
Re: Memory questions
Let's say I've only got a tape recorder connected. Without a printer I assume that means the printer buffer area is free for me to use. Are the other reserved areas meant for device I/O?
Re: Memory questions
The printer buffer is replaced by additional system variables on 128K machines, so it's best avoided unless you're disabling the system routines entirely. The memory directly after the system variables is the channel information. There is a more comprehensive memory map in Chapter 24 of the Speccy manual (I'd recommend the +2A/+3 version which is similar in detail to the original 48K manual, but highlights the variances on the 128K machines).
http://www.worldofspectrum.org/ZXSpectr ... 8pt24.html
http://www.worldofspectrum.org/ZXSpectr ... 8pt24.html
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Memory questions
What Andy said above, plus the following. The idea of a memory map becomes mostly moot once your code abandons the BASIC interpreter. System variables is the only area of any interest, provided you make extensive use of ROM routines. Note, however, that some system variables will differ on different Spectrum models. There are several, however, that are universal and helpful for, say, creating custom loaders with a small footprint.
Other than that—especially if you’re redirecting the stack pointer and use a custom font—the only aspect of the “memory map” concept that is of any import is the screen file (well, duh) and keeping track of which bank you page in on 128K machines (noting that contention patterns differ between the original 128K/+2 Spectrums and the +2A/+3).
Other than that—especially if you’re redirecting the stack pointer and use a custom font—the only aspect of the “memory map” concept that is of any import is the screen file (well, duh) and keeping track of which bank you page in on 128K machines (noting that contention patterns differ between the original 128K/+2 Spectrums and the +2A/+3).
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Memory questions
One comment - all these things like printer buffer, system variables,UGD and so on are important when you work in Basic. It's the Basic interpreter running in ROM which uses parts of memory this way.
If you run your own program In assembler you can ignore it all if you wish and use memory for your own goals. In such case everything above attribute area will be just free memory to use. You need to setup some things first but it it possible.
If you run your own program In assembler you can ignore it all if you wish and use memory for your own goals. In such case everything above attribute area will be just free memory to use. You need to setup some things first but it it possible.
Re: Memory questions
As a footnote to this, there will probably be a little bit of BASIC you load in to load and kick off your machine code routine. While that BASIC is running, it'll need the system variables and some memory to run in. But once it calls your machine code routine, so long as you have no intention of returning to BASIC, you can then use the whole memory for whatever you want. The screen is always drawn from the memory starting at 16384 and you can't change that.
One way to exploit it might be to use it as a buffer or calculation scratchpad. Another method might be to copy some data that you loaded into upper memory to free up some upper memory to use as a buffer. And why would you do that?
Well, there's another issue. The first 16K of memory needs to be read by the ULA to generate the screen (even though the screen only occupies 6.75K); this can slow down access to it (called 'contention') so anything you want to operate at the fastest possible speed (be that program code or graphics buffering) should be placed in the top 32K of memory. It's a bad idea to run game code anywhere below 32768.
So once your game's loaded, you can copy non-critical data down to lower memory, and free up some upper memory for faster graphics buffering, etc.
One way to exploit it might be to use it as a buffer or calculation scratchpad. Another method might be to copy some data that you loaded into upper memory to free up some upper memory to use as a buffer. And why would you do that?
Well, there's another issue. The first 16K of memory needs to be read by the ULA to generate the screen (even though the screen only occupies 6.75K); this can slow down access to it (called 'contention') so anything you want to operate at the fastest possible speed (be that program code or graphics buffering) should be placed in the top 32K of memory. It's a bad idea to run game code anywhere below 32768.
So once your game's loaded, you can copy non-critical data down to lower memory, and free up some upper memory for faster graphics buffering, etc.
Re: Memory questions
Don't forget that unless you change interrupt mode and provide your own interrupt service routine that will be using the ROM and accessing some of the variables
Re: Memory questions
Lots of useful info, thanks everyone!
I don't want to break compatibility with the 128k so I'll avoid touching the printer buffer.
I don't plan to use BASIC outside of the loader, but I have noticed I need to leave some room after 0x5CCB to allow BASIC to load my code. Good to know that it's free to use it after my program starts.
It looks like the 0xFF58-0xFFFF area is for the GO SUB stack and UDG, so that answers #2.
Knowing that the area after system variables is for channels answers #3 and explains why poking 0x5CBB disables the loading messages (redirects a stream). If the channel info area is exactly 21 bytes long then that also answers #1. However, I don't know how to read this bar from the +3 manual:
Does this mean the size of "Channel information" is variable? What are the "80h" blocks for? I might use the built-in print function in my code so I think I should avoid overwriting this area.
I don't want to break compatibility with the 128k so I'll avoid touching the printer buffer.
I don't plan to use BASIC outside of the loader, but I have noticed I need to leave some room after 0x5CCB to allow BASIC to load my code. Good to know that it's free to use it after my program starts.
It looks like the 0xFF58-0xFFFF area is for the GO SUB stack and UDG, so that answers #2.
Knowing that the area after system variables is for channels answers #3 and explains why poking 0x5CBB disables the loading messages (redirects a stream). If the channel info area is exactly 21 bytes long then that also answers #1. However, I don't know how to read this bar from the +3 manual:
Code: Select all
--+-------------+-----+-------+------+-----+-------------------+----+-----+--
| Channel | 80h | BASIC | Vars | 80h | Command or prog. | NL | 80h |
| information | | prog | | | line being edited | | |
--+-------------+-----+-------+------+-----+-------------------+----+-----+--
^ ^
| |
5CB6h WORKSP
(23734)
CHANS
Re: Memory questions
Yes, the channel area can expand to accommodate additional channel definitions (if you have an interface 1 attached for example). The 80h bytes, I believe, are just end markers so the ROM knows when to stop iterating (without having to do a compare of the address with another system variable)
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Memory questions
Well, it’s not 0x5CCB per se, but rather whatever’s held in the PROG system variable. The value will change depending on which peripherals are attached to the Spectrum (and initialized), so don’t just assume it’s 23755.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Memory questions
If you don't need ALL existing memory you can safely do for example in standard Spectrum 48kB
This leaves area above 24000 for machine code. Your tiny Basic loader starts at 23755 and will fit below 24000
And if your machine code program is short just place it above 32768 so it runs in memory not slowed down by ULA.
Code: Select all
1 CLEAR 24000
2 LOAD "" SCREEN$
3 LOAD "" CODE
4 RANDOMIZE USR 24000
And if your machine code program is short just place it above 32768 so it runs in memory not slowed down by ULA.
Re: Memory questions
IIRC, for Balachor's Revenge I started the program at 24500 and pointed the stack pointer just below it. The stack isn't particularly big during the game, <100 bytes.
I figured that'd be pretty safe for most models, peripherals etc. as I didn't need to return to BASIC for anything. Though it was more a rough guess than anything else.
I figured that'd be pretty safe for most models, peripherals etc. as I didn't need to return to BASIC for anything. Though it was more a rough guess than anything else.
My Speccy site: thirdharmoniser.com
- Einar Saukas
- Bugaboo
- Posts: 3144
- Joined: Wed Nov 15, 2017 2:48 pm
Re: Memory questions
It should be CLEAR 23999Ralf wrote: ↑Wed Apr 04, 2018 1:33 pm If you don't need ALL existing memory you can safely do for example in standard Spectrum 48kB
This leaves area above 24000 for machine code. Your tiny Basic loader starts at 23755 and will fit below 24000Code: Select all
1 CLEAR 24000 2 LOAD "" SCREEN$ 3 LOAD "" CODE 4 RANDOMIZE USR 24000
And if your machine code program is short just place it above 32768 so it runs in memory not slowed down by ULA.
Re: Memory questions
Eagle eyes Einar
Re: Memory questions
Alright, I think I've got a handle on the "memory map" now. I do plan to use ALL available memory (and then some) since I'll be trying to write my project in C for the most part.
Perfect, that's just what I need. At the moment this reads 0x5CCB for me, but I should check that var in my loader or program code so I know exactly where to place my code/data or wtv ends up in that area.Ast A. Moore wrote: ↑Wed Apr 04, 2018 9:42 am Well, it’s not 0x5CCB per se, but rather whatever’s held in the PROG system variable.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Memory questions
For releases, I personally use a machine-code loader placed inside the BASIC file. To run it, I make use of the PROG variable (but there’s an even better way to do it). As for the value that PROG contains, try this experiment (that is, if your emulator can also emulate the Interface 1):
1. “Attach” the Interface 1 and reset the machine
2. Read the PROG system variable: PRINT PEEK 23635+256*PEEK 23636
3. Do CAT 1 (you’ll get an error, but that’s irrelevant)
4. Now read the PROG sys. variable again. The value will change.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
- 1024MAK
- Bugaboo
- Posts: 3123
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Memory questions
In case you have not worked it out, the names in the table in the Spectrum manual that define the location in memory where the boundaries are, are system variables. So to find the current location of said boundary, read the appropriate system variable.w00tguy wrote: ↑Wed Apr 04, 2018 2:17 amCode: Select all
--+-------------+-----+-------+------+-----+-------------------+----+-----+-- | Channel | 80h | BASIC | Vars | 80h | Command or prog. | NL | 80h | | information | | prog | | | line being edited | | | --+-------------+-----+-------+------+-----+-------------------+----+-----+-- ^ ^ | | 5CB6h WORKSP (23734) CHANS
Mark
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.
“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.