The definitive "teach yourself machine code" text?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

The definitive "teach yourself machine code" text?

Post by TMD2003 »

I really need to know this, and I am going to throw it open to those in the know.

I HAVE: William H. Tang's "Spectrum Machine Language for the Absolute Beginner", the book.
I ALSO HAVE: "The Complete Machine Code Tutor" published by New Generation Software, the four-tape teach-yourself-on-the-Spectrum-itself package. I assume Malcolm Evans was in charge of this one.
I KNOW OF: Toni Baker's "Mastering Machine Code on your ZX Spectrum". I know t'other forum has a copy in the archive.

Should I press ahead with one of these three, or is there an alternative definitively brilliant book that is recommended by pretty much everyone?

I have a miminal understanding of machine code, so far, that is best described along these lines: "there are registers, there is a stack, numbers are shunted around on the registers and up and down the stack, witchcraft happens, and Manic Miner appears on the screen." Essentially, I do understand that there are these registers, but absolutely zero concept of how and why moving the numbers around does anything, or can do anything, other than mathematics.

So what I really need is the equivalent of, say, "how to explain electricity to a medieval alchemist", i.e. someone who's obviously not a complete brainlet, but who also has absolutely no concept that such a thing could even exist, let alone how it can be used in everyday life, and to whom it could be taken as proof of the existence of magic.

It's not that I want to be the next world-renowned programmer in the scene - far from it, that's nothing more than a pipe dream. It's more that I'd like to be able to make short routines to do simple tasks in a near-instant that BASIC would otherwise take a minute or two. If I was going to make a machine code game of any description, it would probably be something along the lines of what appeared in the pages of Sinclair Programs in 1982.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
Einar Saukas
Bugaboo
Posts: 3120
Joined: Wed Nov 15, 2017 2:48 pm

Re: The definitive "teach yourself machine code" text?

Post by Einar Saukas »

TMD2003 wrote: Sat Oct 03, 2020 12:04 am I KNOW OF: Toni Baker's "Mastering Machine Code on your ZX Spectrum". I know t'other forum has a copy in the archive.
Do you mean this archive?

https://spectrumcomputing.co.uk/entry/2 ... X_Spectrum
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: The definitive "teach yourself machine code" text?

Post by Ast A. Moore »

At the risk of sounding like a broken record, I’m going to say that the biggest mistake many people who want to start coding in assembly/machine code make, is thinking that they need to learn assembly or machine code. In reality, assembly is very, very simple; there isn’t much to learn. The books you have are more than enough to give you a head start.

What you really need to learn and understand is how the Spectrum works. Learn and understand its architecture (it’s fairly basic), what each component (you can access as a programmer) does, and how to interpret its state or change it. Then figuring out how to program becomes the easy part.

I cannot stress this enough—there is absolutely no point in trying to “teach yourself machine code,” if you don’t have a good handle on how computers work. So, start with that. Here are some of the topics you should become familiar with (in no particular order):

1. What is a CPU?
2. What is data? What is code? The concept of duality of data and code.
3. The binary system; why it’s relevant for programming
4. Input and output
5. Data/code storage and retrieval
6. Data and address buses
7. How the video signal is formed by the ULA.
8. Where the ULA gets data to display on the screen.

Perhaps you’ll even want to do some light computing history reading. This will explain what a register is and how the CPU (especially a simple one, such as the Z80) is similar to mechanical adders, why we use the binary system, and many other aspects.

There’s really no other way of going about it. Learning to “code” without knowing how computers work is an exercise in futility.
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.
User avatar
cmal
Manic Miner
Posts: 630
Joined: Fri Jun 05, 2020 1:05 am
Location: California

Re: The definitive "teach yourself machine code" text?

Post by cmal »

Agree with Ast. Each machine code instruction in itself does a very simple defined thing. But learning it without learning the architecture of the computer will seem pointless.
That's how my first attempt at learning MC went. I tried reading a book that explained too much of the theory (registers, stack, loops e.t.c.) and eventually I lost interest because I didn't know how to apply it.
Then I used the Machine Code Tutor from New Generation Software and that's when the light bulb went on. It gives you the theory but it also has example code that you can step through to see how the registers change. It also uses the display and attributes in their example code so that you actually see stuff happening on the screen.
User avatar
evilpaul
Manic Miner
Posts: 244
Joined: Tue Jul 28, 2020 8:04 am
Location: Espoo, Finland
Contact:

Re: The definitive "teach yourself machine code" text?

Post by evilpaul »

Another vote for “don’t try to learn z80 in isolation” here. I think Jonathan Cauldwell’s tutorials are good - they teach you a small bit at a time and they are completely focused on the ZX. You can find these tutorials in a few places, just google for “How to write ZX Spectrum Games by Jonathan Cauldwell”

Another thing I’d say is to just get on and do it. I don’t remember ever reading one magic book that taught me z80. I read lots of books and articles and wrote lots of code and did experiments. It depends on your learning style though - some people read books, some people just dive in and experiment and some, like me, do a bit of both.
User avatar
PeterJ
Site Admin
Posts: 6877
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: The definitive "teach yourself machine code" text?

Post by PeterJ »

Assembly language instructions are relatively easy, the problem is putting them in the right order!

I'm nowhere near level of many of the other programmers here, but I agree with much of what has been said.

Start with understanding the Spectrum, it's memory layout and the way the screen is organised. If you haven't used BASIC for a while get familiar with that again (that doesn't apply to you [mention]TMD2003[/mention]).

Have a clear understanding of binary and to a lesser extent hexadecimal.

Learn the basic commands such as loading, addition and subtraction, and jumps. Take time to understand how instructions impact the flag register. Also the handing of 16 bit and negative numbers.

My route then was the Jonathan Cauldwell book as well. If you don't understand one of the examples go back to a z80 book and understand before moving on.

https://spectrumcomputing.co.uk/index.p ... id=2001501

You also need to pick your development tools. I use Pasmo because I find it easy, but there are many other options. ZXSpin is very old but has a built in assembled which is useful.

My favourite general guide to get you started is Cracking The Code by John Wilson. Read the first few chapters then jump into Johnathans book.

https://spectrumcomputing.co.uk/index.p ... id=2000640
User avatar
PeterJ
Site Admin
Posts: 6877
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: The definitive "teach yourself machine code" text?

Post by PeterJ »

The Machine Code Tutor that [mention]cmal[/mention] mentioned is available here:

https://spectrumcomputing.co.uk/entry/8 ... Code_Tutor
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: The definitive "teach yourself machine code" text?

Post by TMD2003 »

Ooooh, crikey, as Lawnmower Deth would say. I suspected I might regret asking this question...

First of all, let's make an example in BASIC of something I might want to be able to do - such as, clear the screen in two different colours. I can do that in one line.
10 FOR n=0 TO 10: PRINT AT n,0; PAPER 1;"[32 spaces]"; AT n+11,0; PAPER 6;"[32 spaces]": NEXT n
We have something that resembles the Ukrainian flag, and it takes around 0.7-0.8 seconds (timed less-than-accurately with a stopwatch, rather than a screen recorder and analysis frame-by-frame). However, if I had some existing text and wanted to overlay this flag on top of it, then I know I can do that by poking all the attributes in turn...
10 FOR n=22528 TO 22879: POKE n,15: POKE n+352,48: NEXT n
And now all my text is white on blue in the top half, black on yellow in the bottom half, with the BRIGHT and FLASH channels off. It takes 4.2 seconds.

I know that machine code could do this in an instant, and I know that it could fill the screen with random text in an instant that the flag design could then be imposed upon, and I know that any programmer worthy of the name could do it. I know how to POKE the display file in BASIC as you see above, and last night while writing another CSSCGC entry I needed my own display file converter that I left on the BASIC Dumping Ground.

This is a mere 76 bytes of BASIC, and I thought it was so simple that it wouldn't be any harm if just took it and ran it through a compiler. I know of the Softek Compiler, so I tried that. The resultant code works, in an instant, as I expected. But what I did not expect is how long it is - 97 bytes (and variables, which I didn't need to save, took it up to 103 bytes). Instinct, at least, tells me that there is no way that the machine code should be longer than the BASIC original, and the compiler has made it work effectively with brute force. Think of the equivalent of a book that's been written in English, translated into Japanese by a native Japanese speaker, and then the Japanese version has been re-translated into English by a native English speaker who has never seen the original. The two English books will be markedly different.

I could run the compiled code through a disassembler and print it out. Einar, Ast, Joefish and anyone else who's achieved all sorts of wizardry on the Spectrum will point at it and laugh, and not without good reason. "97 bytes? NINETY-SEVEN BYTES? What is this, code written by Fletcherisers? This could be done in 20 bytes, maybe even ten, but who needs this many?"
(Look up Fletcherisers and you'll get the joke.)

Clearly, this will not do, and so begins my quest.
Einar Saukas wrote: Sat Oct 03, 2020 12:30 am Do you mean this archive?
https://spectrumcomputing.co.uk/entry/2 ... X_Spectrum
I knew you'd say that - and the other lot have made it much harder to get hold of offline copies, in favour of that online page-turner-type setup. I should probably not say how I actually got hold of this text, suffice to say I have it and several others to look through.

And one day I'm going to take my Spectrum-themed-Minecraft site and turn all the links to SC so that I know they actually work!
Ast A. Moore wrote: Sat Oct 03, 2020 12:43 am What you really need to learn and understand is how the Spectrum works. Learn and understand its architecture (it’s fairly basic), what each component (you can access as a programmer) does, and how to interpret its state or change it. Then figuring out how to program becomes the easy part.
See, this is what I was dreading. Something is already telling me that I have to have an extensive knowledge of electronics, right down to its most fundamental level. What is a transistor, why does a transistor do what it does, how and why does layering thin sheets of silicon and punching them in various places form a network of transistors, and why does this one particular network of thousands upon thousands of miniaturised transistors encased in resin form what we know as "the Zilog Z80 microprocessor", which will do what we want it to do? I don't have 20 years to learn that... but then again, neither did Matthew Smith, Adrian Sherwin and all the other teenagers who made Spectrum games in machine code in 1983-84 or there abouts, because they hadn't even been on the planet that long.

The only equivalent I can think of that I do understand is NMR, and I only know about that because I spent so long studying chemistry - it's touched upon as briefly as possible right at the end of A-level and only really explored on undergrad university courses. I know that I can prepare a sample of the same substance in the same solvent, and the spectrum will always be the same - the chemical shifts will be the same when recorded in PPM, and the coupling constants will be the same in Hz, even if they'll look wider apart on the spectrum itself on a lower-field spectrometer. I know I could insert the sample, ask the computer controlling it for proton, carbon, COSY, HMQC and HMBC spectra and they'd appear, and confirm exactly what had been in the sample. I did not have to know what the RF pulse sequences were that generated all those experiments, or why and how they did it, just that they did, and the results of those experiments would be what I was expecting them to be.

Is understanding the internal workings of the Spectrum more like that? In other words, "this is the Z80, this is the ULA, this is the bus, they do this", but I don't need to know the internal structure, i.e. why an extensive network of thousands upon thousands of transistors laid out in this very specific way produces the result that it does.

For the list of eight things to understand, I've got one of those down - i.e. what binary is and why computers need it. I can't always translate instantly between binary and hex - it requires at least some pause for thought unless it's 0000 or 1111 - but to get binary to decimal or vice versa I'd go straight to the calculator. The rest... may take some time.
cmal wrote: Sat Oct 03, 2020 3:59 am Then I used the Machine Code Tutor from New Generation Software and that's when the light bulb went on. It gives you the theory but it also has example code that you can step through to see how the registers change. It also uses the display and attributes in their example code so that you actually see stuff happening on the screen.
This is definitely a big bonus. If there's one thing I can understand, it's the display file, because it has specific values attributed to it. It's working out how to POKE to it without access to the POKE command that is going to be the major hurdle, but I suspect this will tell me.

Cheers for everything so far - I'll see what I can do. Expect more walls of text like this, the further I get into it.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
PeterJ
Site Admin
Posts: 6877
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: The definitive "teach yourself machine code" text?

Post by PeterJ »

If you are happy to use the ROM routines [mention]TMD2003[/mention] then that example is straightforward. I know the purists will chastise me hugely for using the ROM routines, but its personal choice.

RST 10h is the ROM printing routine and you can print the character set from 16 to 22 on page 135 of v3 of the 48K BASIC manual, so a simple example would be:

Code: Select all

ld a,2 ;open channel 2
call1601h
ld a,22 ; Print At
rst 10h
ld a,10 ; print at 10
rst 10h
ld a,10 ; print at 10,10
ld a,16 ; ink
rst 10h
ld a,1 ;load a with colour for blue
rst 10h
ld a,17 ; paper
rst 10h
ld a,6 ;yellow paper
ld a,'A'
rst 10 ; print character
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: The definitive "teach yourself machine code" text?

Post by TMD2003 »

Hmmm. RST 10h is something I've come across, when I've been typing in programs for the Type Fantastic - anything in those involving machine code involved me also typing the assembler listing into the accompanying text file. Likewise, I've seen various CALL instructions, though the only one I might recognise as doing something I know is "send this to a ROM routine that controls the beeper", which was involved in a program to make various sound effects, pretty much all of which I recognise from very early games (look for anything written by Martyn C. Davies or Kevin J. Bezant and they're bound to be in there).

I've taken a quick initial look at the New Generation tutor, and in lesson two there's an example of how to POKE to the attributes. Even at this stage it's a good chunk of what I'd need to machinecodify that BASIC routine. It is no more than LD instructions mostly using A, but they're sent to the attributes and hence I can see what's going on. It says:
LD (STORE),A - STORE is the next byte above the final RET, and it contains the value 7
LD (22528),A
LD E,25
LD A,E
LD (22529),A
LD A,(22530)
LD (22529),A
LD (22528),A
LD A,E
LD (STORE),A
RET

Very simple, even I can see that. And even at this stage I can see that it forms the basis of what I'd want to do - I don't need E involved with a different value, just some way to INC the display file address so that successive squares are LDed with the same value. I suspect that what lies in wait is that I will find that only A can be INCed or DECed, so the two-byte address will have to be held in BC, DE, HL (any specific one of those, and if so, why...?) and the single byte that needs to be increased will have to be shunted into A, increased and then shunted back again. All that is already building up towards making a long pile of bytes that would explain why the Softek compiled version of my BASIC routine was longer than the BASIC itself...

Hence:
Project 1: Write some code that will work, however messy, just to prove I can do it.
Project 2: Condense it until it runs in as few bytes as possible.

Still, it's an adventure, isn't it? One that I should have made 20 years ago at least, probably 30...
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
dfzx
Manic Miner
Posts: 682
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Re: The definitive "teach yourself machine code" text?

Post by dfzx »

Just to clear up a couple of your misunderstandings...

First, absolutely no one is going to point and laugh at anything you produce. We all started right at the beginning, just like you are.

Second, your BASIC program might well occupy 76 bytes, but don't forget it needs 16,384 bytes of BASIC interpretter code to make it work. Those 76 bytes aren't really a program by themselves, they need the 16K of code in ROM to make them do something.

Third, you don't need to know anything about transistors, or buses, or the workings of the ULA to write ZX Spectrum Z80 code. You don't need to be able to do hex calculations in your head. The fact you already understand how the display file works, and how you can change what the user sees by changing values in that area of memory, shows you probably already know enough to write a little game.

It actually seems like you've done the hard bit, but it hasn't quite gelled in your head yet.

Why don't you try writing:

10 FOR n=22528 TO 22879: POKE n,15: POKE n+352,48: NEXT n

in assembly language? There's a useful lesson in just that little line.
Derek Fountain, author of the ZX Spectrum C Programmer's Getting Started Guide and various open source games, hardware and other projects, including an IF1 and ZX Microdrive emulator.
User avatar
Morkin
Bugaboo
Posts: 3274
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: The definitive "teach yourself machine code" text?

Post by Morkin »

Ast A. Moore wrote: Sat Oct 03, 2020 12:43 am What you really need to learn and understand is how the Spectrum works. Learn and understand its architecture (it’s fairly basic), what each component (you can access as a programmer) does, and how to interpret its state or change it. Then figuring out how to program becomes the easy part.

I cannot stress this enough—there is absolutely no point in trying to “teach yourself machine code,” if you don’t have a good handle on how computers work. So, start with that. Here are some of the topics you should become familiar with (in no particular order):

1. What is a CPU?
2. What is data? What is code? The concept of duality of data and code.
3. The binary system; why it’s relevant for programming
4. Input and output
5. Data/code storage and retrieval
6. Data and address buses
7. How the video signal is formed by the ULA.
8. Where the ULA gets data to display on the screen.
...I'd probably slightly disagree with this - I don't really know much (if anything) about computer and Speccy architecture, or how the hardware works at all at an electronic level, how the computer actually deals with your code etc.

I'd say when I was learning assembly I only really learned (3) and (5) in this list and that was enough to learn enough to write two Speccy games. I think the other elements may be more important at a more advanced level - e.g. super-smooth movement and syncing with the display beam (which you can tell [mention]Ast A. Moore[/mention] is a wizard at if you look at his Yankee game). I'd argue that they can come (much) later.

On the book front, I personally dipped in and out of books, and used most of them for reference - I'm not sure if there was a single one that taught me everything (and I clearly still don't know everything!).

I totally agree with Project 1 - just starting out with just trying out your own code doing bits and bobs, however messy it is - if it works, it works!

Personally I'd suggest not worrying about Project 2 (optimization) unless you're running out of memory. But if you're at that point it's likely that you probably know enough as you'll have written a fairly hefty program - you'll find even messy and convoluted assembly code takes up infinitely less space than a BASIC program. But if you want to do it, then go for it, I'm sure it's all good for learning. :)
My Speccy site: thirdharmoniser.com
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: The definitive "teach yourself machine code" text?

Post by Ast A. Moore »

TMD2003 wrote: Sat Oct 03, 2020 11:32 am Is understanding the internal workings of the Spectrum more like that? In other words, "this is the Z80, this is the ULA, this is the bus, they do this", but I don't need to know the internal structure, i.e. why an extensive network of thousands upon thousands of transistors laid out in this very specific way produces the result that it does.
You got it. I mean, knowing a little bit of electronics will always come in handy, but strictly speaking, it’s not necessary for programming (at least for the Spectrum). But you do need to know the underlying logic of computer operation. In other words, it’s not necessary to study the photographs of the die of the Z80 to understand what a register or ALU looks like at a physical level. You do, however, need to learn what a CPU is, what it can and, most importantly, what it can’t do, how to feed it the numbers to crunch, and how to retrieve them for use later.

As for your other question about program size vs. speed, comparing higher-level programming languages such as BASIC with low-level ones, such as assembly, is never straightforward. In many ways, higher-level languages are a compromise between efficiency and legibility. For example, the Z80 cannot multiply or divide two arbitrary numbers. (It can, however, multiply and divide by two.) So, when you issue a simple instruction in BASIC such as LET a=x*y, a whole lot of code of the BASIC interpreter residing in ROM will be executed. Some of it will be the BASIC parser itself, and some will be a special routine that will multiply the two numbers by using several iterations of additions. So, your (roughly) six bytes of BASIC will actually translate to a few dozen bytes of machine code.
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.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: The definitive "teach yourself machine code" text?

Post by Ast A. Moore »

Morkin wrote: Sat Oct 03, 2020 1:12 pm I don't really know much (if anything) about computer and Speccy architecture, or how the hardware works at all at an electronic level, how the computer actually deals with your code etc.

I'd say when I was learning assembly I only really learned (3) and (5) in this list and that was enough to learn enough to write two Speccy games. I think the other elements may be more important at a more advanced level - e.g. super-smooth movement and syncing with the display beam (which you can tell @Ast A. Moore is a wizard at if you look at his Yankee game). I'd argue that they can come (much) later.
Thank you!

Of course it depends on how one’s particular mind works. Mine can be a little thick, so I need to have a deeper understanding of how computers work in order to use and program them efficiently. Otherwise, the problem becomes too abstract for my poor brain to understand it.
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.
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: The definitive "teach yourself machine code" text?

Post by TMD2003 »

dfzx wrote: Sat Oct 03, 2020 12:39 pm Just to clear up a couple of your misunderstandings...
First, absolutely no one is going to point and laugh at anything you produce. We all started right at the beginning, just like you are.
But to clear up your misunderstanding (and that of anyone else who might have made it), I wasn't implying anyone would laugh at my code, it was that you probably would (and should) laugh at the code produced by the Softek Compiler. Which leads us to...
dfzx wrote: Sat Oct 03, 2020 12:39 pm Why don't you try writing:
10 FOR n=22528 TO 22879: POKE n,15: POKE n+352,48: NEXT n
in assembly language? There's a useful lesson in just that little line.
I've already got an idea of how I'd do it, but so far all I know about is LD, INC and JP to get it to loop back. I'm almost certainly going to need a CP in there somewhere so that the computer knows when to stop looping, but I haven't got that far yet. Once I've written the routine that does the same as this BASIC line, I'll send the Softek compiled version through a disassembler, see if it actually does dissasemble into a readable listing (everything I've tried so far hasn't...) and see how it compares with what I wrote from scratch.

Right now I am reading the Usborne Introduction To Machine Code For Beginners. As it's intended for kids in single digits (which, at the time of its publication, I was... just not now), it's incredibly simple and should be understandable even for a complete dunce. There is probably no shame in doing so if James May's revelation about Ladybird books is anything to go by (which I think was in one of his Toy Stories) - grown men in their 40s working for engineering firms kept covert copies of Ladybird's "how things work" books, without their illustrated covers, that they could use as quick and easy reference guides that stated the facts that they needed to know. I just don't need all the cartoonish drawings illustrating everything.
Morkin wrote: Sat Oct 03, 2020 1:12 pm I'd say when I was learning assembly I only really learned (3) and (5) in this list and that was enough to learn enough to write two Speccy games. I think the other elements may be more important at a more advanced level - e.g. super-smooth movement and syncing with the display beam (which you can tell [mention]Ast A. Moore[/mention] is a wizard at if you look at his Yankee game). I'd argue that they can come (much) later.
Ast is clearly a level 99 wizard with intrinsically high magic stats, whereas I'm a level 1 wizard at the moment with whatever stats the random number generator gave me. When I first heard "floating bus", I thought of a lost storyline for if there'd ever been a Chitty Chitty Bang Bang Part II: What Caractacus Potts Did In His Shed After Truly Divorced Him For Spending Too Much Time In His Shed. Maybe, one day, I'll understand it, but that day is still a long way off!
Morkin wrote: Sat Oct 03, 2020 1:12 pm Personally I'd suggest not worrying about Project 2 (optimization) unless you're running out of memory. But if you're at that point it's likely that you probably know enough as you'll have written a fairly hefty program - you'll find even messy and convoluted assembly code takes up infinitely less space than a BASIC program. But if you want to do it, then go for it, I'm sure it's all good for learning. :)
There is a good reason why I'd want to optimise. Look at some of the things I've shoved on the BASIC Dumping Ground, such as the Mighty Musical Character Sets. They're effectively the culmination of my fascination with user-defined character sets, and in this project I discovered what happens if the set is POKEd too high. What I do is load the character set starting at an address that divides by 256, so that I will never need to POKE 23606 with any other value than its default 0.
i.e.: character set loaded at 64000, POKE 23607,249; character set loaded at 64512, POKE 23607,251.

It is possible to load the character set at 64768 and POKE 23607,252 but the characters from lower-case "k" onwards clash with the UDGs. Even so I thought I'd try it anyway because the musical character set didn't need UDGs (though they might be useful if there were any single-square characters, which there weren't). What I found was, while I was defining characters in the top two rows (i.e. space to _), the characters in the third row that weren't UDGs (i.e. £ and a to j) were becoming corrupted. I was using my own program that defines both character sets and UDGs - it uses no machine code but it also doesn't set RAMTOP to the byte before the character set.

But if I did stick to defining the character set at 64512 so that I can get a full 96 characters in as well as a full set of UDGs and load the whole lot in one go - and if I rememebered to CLEAR 64511 beforehand, then...
LOAD "bytes" CODE 64512,1024 - breaks down as 64512-652769 for the character set, 65368-65535 for the UDGs, and... 65280-65368 unused. That's 88 measly bytes which, if they are left untouched, would be useful for the kind of short machine code routines I might want to include.

So there's my first target for Project 2. The Softek compiler took 97 bytes to do what I want to do; I have to get it down to 88 or less.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
Rorthron
Dynamite Dan
Posts: 1644
Joined: Sun Nov 12, 2017 10:35 pm

Re: The definitive "teach yourself machine code" text?

Post by Rorthron »

For what little it's worth, I personally I didn't much like William Tang, Spectrum Machine Language for the Absolute Beginner. I found it spent too much time on vague analogies and too little on the specifics. I preferred Ian Sinclair, Introducing Spectrum Machine Code - How To Get More Speed and Power, and the ultimate Z80 bible, Rodney Zaks, Programming the Z80 (though it's not Spectrum specific). But I am about as far as it's possible to get from a Spectrum assembly expert!

(That's two programming threads I've commented on. I'm not quite sure what's come over me!)
User avatar
Morkin
Bugaboo
Posts: 3274
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: The definitive "teach yourself machine code" text?

Post by Morkin »

...I'd almost forgotten what it was like to keep track of UDGs and alternate character sets in BASIC - the beauty of assembly is that you can just use text labels instead, and store pretty much as many graphics as you want to design.

...It would be interesting to see what the compiled BASIC code looks like.
Ast A. Moore wrote: Sat Oct 03, 2020 2:16 pm Of course it depends on how one’s particular mind works. Mine can be a little thick, so I need to have a deeper understanding of how computers work in order to use and program them efficiently. Otherwise, the problem becomes too abstract for my poor brain to understand it.
Of course - the fact that most tutorials start off with that stuff indicates that some people like to start from the ground up in a structured way.
My Speccy site: thirdharmoniser.com
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

Re: The definitive "teach yourself machine code" text?

Post by BenHanson »

Hello,

You obviously are nearly there. Here is the complete code:

ORG 23296
LD BC, 352 ; Counter
LD HL, 22528
LD IX, 22880
LOOP:
LD (HL), 15
LD (IX+0), 48
INC HL
INC IX
DEC BC
LD A, B
OR C
JR NZ, LOOP
RET

I have been working on my own Z80 assembler in C++ and poking around I came across your question. From what you've said already you should be able to follow the code OK. The complication is that DEC BC does not set the zero flag, so you have to involve the A register.

Hope that helps!

Regards,

Ben
AndyC
Dynamite Dan
Posts: 1406
Joined: Mon Nov 13, 2017 5:12 am

Re: The definitive "teach yourself machine code" text?

Post by AndyC »

Firstly forget worrying about transistors or low level electronics or any of that nonsense. What you need is a reasonable (but by no means perfect) logical model of how the spectrum operates. Knowing things like the fact that instructions are fetched from memory one at a time, change values held in "register" depending on the commands and that manipulating certain memory addresses or IO ports make things happen on screen etc.

And don't worry about size of code etc right now, certainly don't worry about comparing it with BASIC. A single PRINT command may only take a byte, but the implementation details of it along with the interpreter itself is enormous, so it's comparing apples and oranges.

Finally start with really, really small examples. Play around with trivial tasks like clearing the screen or adding a few numbers together. You can learn a lot more by experimenting with changing simple short programs than by diving head in and trying to write complex sprite routines. Allow yourself small victories and in no time you'll be ready for bigger ones.
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: The definitive "teach yourself machine code" text?

Post by TMD2003 »

BenHanson wrote: Sat Oct 03, 2020 2:57 pm Hello,
You obviously are nearly there. Here is the complete code:
ORG 23296
LD BC, 352 ; Counter
LD HL, 22528
LD IX, 22880
LOOP:
LD (HL), 15
LD (IX+0), 48
INC HL
INC IX
DEC BC
LD A, B
OR C
JR NZ, LOOP
RET

I have been working on my own Z80 assembler in C++ and poking around I came across your question. From what you've said already you should be able to follow the code OK. The complication is that DEC BC does not set the zero flag, so you have to involve the A register.

Hope that helps!
Strangely, at around the same time PeterJ just sent me an email with a list of codes to disassemble, to see if I could work out what it was doing - and it fills the screen in inked-in pixels, a row of eight at a time, and does it so quickly I barely have time to notice. His listing doesn't involve IX at all - but it does involve that LD A,B and then OR C so this must be the magic part of the code that tells the computer when to stop looping.

That's a fine introduction to the forum, and then some.
AndyC wrote: Sat Oct 03, 2020 2:59 pm Finally start with really, really small examples. Play around with trivial tasks like clearing the screen or adding a few numbers together. You can learn a lot more by experimenting with changing simple short programs than by diving head in and trying to write complex sprite routines. Allow yourself small victories and in no time you'll be ready for bigger ones.
I've thought of something I might want to do which could be useful - convert a decimal number (0-255) to binary, and fish out individual bits from the byte. I'm starting by converting the ZX81 "Hex Bin Converter" from Sinclair Programs in April/May 1983 to the Spectrum so I can see how it works, and being a ZX81 listing it's strictly one statement per line.

Why I might want to do this: I can see why I might need the ATTR function broken down into smaller chunks, and thought I could do it via some DEF FNs, i.e.
DEF FN f(r,c) = ... returns 1 if the square is flashing, otherwise 0.
DEF FN b(r,c) = ... returns 1 if the square is bright, otherwise 0.
DEF FN p(r,c) = ... returns the paper colour of that square.
DEF FN i(r,c) = ... returns the ink colour of that square.

The first is easy enough... test ATTR(r,c) and see if it's 128 or more. FN b involves a hit more manipulation (i.e. ATTR(r,c) is >=64 and <=127), but FN p and FN i will involve a string of three bits that then have to be re-converted to decimal. Something tells me this would be (a) slow and (b) actually easier in machine code, with its shift-the-bits-left-and-right opcodes.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
AndyC
Dynamite Dan
Posts: 1406
Joined: Mon Nov 13, 2017 5:12 am

Re: The definitive "teach yourself machine code" text?

Post by AndyC »

It's not a bad place to start. You'll want to look at how AND works in a bitwise fashion, along with the shift and rotate operations. And possibly BIT for testing things like Bright and Flash.
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

Re: The definitive "teach yourself machine code" text?

Post by BenHanson »

- LD A with your byte
- Use BIT 7, A to test whether the top bit is set
- Use SLA A to shift the bits in A left
- Loop back to the BIT 7, A check

LD B, 8 ; Counter
LD A, %00110100
Loop:
BIT 7, A
JR NZ, set
; print 0 here
JR next
set:
; print 1 here
next:
DJNZ Loop
RET
User avatar
TMD2003
Rick Dangerous
Posts: 2043
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: The definitive "teach yourself machine code" text?

Post by TMD2003 »

Right, everyone, what's going on here? I'm testing the routine that's supposed to return a zero so the computer will jump out of a loop, so I wrote a short program to see if OR C does what I think it's doing.

I can't LD C,(address), I can only LD A,(address). Hence, if I do this:
POKE 65024,177 - 0xFE00, if you didn't notice, to make the code slightly easier
POKE 65025,162

And then run this routine:
LD A,(65025)
LD C,A
LD A,(65024)
OR C
RET

There should be the values 177 in A, and 162 in C. I'm expecting a bitwise 177 OR 162 (10110001 OR 10100010) which is 179 (10110011).

I get... 60066, the second byte of which is 162, i.e. C.

What is C being ORed with, if it isn't A?

EDIT: I should probably include the BASIC listing in case I've made an error I was unaware was an error:
10 CLEAR 59999
20 FOR n=60000 TO 60008
30 READ bt: POKE n,bt: NEXT n
40 DATA 58,1,254: REM ld a,(65025)
50 DATA 79: REM ld c,a
60 DATA 58,0,254: REM ld a,(65024)
70 DATA 177,201: REM or c | ret
80 INPUT "A? ";a,"C? ";c
90 POKE 65024,a: POKE 65025,c
100 LET d=a: GO SUB 1000: PRINT "A = ";a;" ";h$;" ";b$
110 LET d=c: GO SUB 1000: PRINT "C = ";c;" ";h$;" ";b$
120 LET d=USR 60000: GO SUB 1000: PRINT "AorC= ";d;" ";h$;" ";b$
130 PRINT : GO TO 80
(1000 is a subroutine that takes the variable d and outputs b$ and h$, strings containing 8-bit binary and two-digit hex versions of the value d)
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
Morkin
Bugaboo
Posts: 3274
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: The definitive "teach yourself machine code" text?

Post by Morkin »

OR C changes the A register, but it doesn't affect the C register.

C will still contain its original value LD'd earlier. Unless you do a LD C,A before the RET.
My Speccy site: thirdharmoniser.com
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

Re: The definitive "teach yourself machine code" text?

Post by BenHanson »

See https://worldofspectrum.org/ZXBasicManu ... hap26.html

You need a value in BC if you want to return it to basic.

10 LET a=32500
20 READ n: POKE a,n
30 LETa=a+1:GOTO20
40 DATA 1,99,0,201

then

PRINT USR 32500
Post Reply