Note to self. Never watch these tutorials after consuming too much beer. Thanks Daryl for these. I think there are sad people who just dislike any video regardless.
Thanks Darryl Sloan for these tutorials, its jogging my 51 year old brain, to understand Z80 again, it's been over 25 years since i coded Z80, great memories are flooding back.
After teaching myself 6502 machine language by writing out instructions on paper and poking them to memory directly, eventually using an assembler was like using BASIC! It made things so much easier. I really wish kids these days were taught something at least as low level as assembly language; they might even enjoy designing graphics on paper and converting the binary to decimal and poking it in, or maybe I'm just easily entertained.
That’s a neat tutorial. I’m glad people still express interest in Z80 assembly. One small clarification (perhaps not hugely important, but useful to know, nevertheless). RST (which stands for “restart,” by the way) is essentially a subroutine call. It’s advantage over the CALL instruction is that it takes less memory-just one byte, as opposed to three-and it executes faster. The disadvantages are that it is limited to eight fixed addresses (0, 8, 16, 24, 32, 40, 48, and 56) and that it cannot be used with conditionals. Anyway, keep up the good work!
Found these very good Darryl. Hope you decide to continue the series. I'm new to assembly language with some general programming knowledge. I've currently followed parts 1 and 2 and processing them in my thoughts for a bit before moving to part 3. Im just messing about with the code from parts 1 and 2 to get familiar with it. Understanding it so far with a bit of thinking now and then. Found your tips on binary VERY good and the scheme for converting to decimal and from decimal has taught me more than my previous 43 years about binary. It clicked as you described the process. Thanks.
If I remember correctly, the $ sign outside of quotes in assembly code means "the current memory location" so what you're saying in the last line is "eostr EQUals the current memory location" which lets eostr-string calculate the length of the string to print, which is the value loaded into the BC register pair. This reminds me of when I created a machine code routine for the TRS-80 color computer to allow me to print the whole of the IBM extended ASCII character set on the high-res graphics screen via a USR call from BASIC. The data for the character set took up more space than the machine code, in spite of me adding heaps of fancy commands to do such things as redefining characters under control of the BASIC program (good for games).
I think what is actually happening is that the compiler is being made to know the memory address immediately following the last letter of the word "Hello" in order for that to be used to be able to work out how many letters there are. I don't think the contents of the memory location labelled "eostr" matters as the calculation "eostr - string" uses the memory locations and not their contents as the operands. I think he has just happened to load it with its own location in order to set up a memory location that can be referenced as the one immediately after the last letter's location.
Great stuff. Well needed. Not done assembler since uni. I really want to make use of this to make some useful little utilities using a serial port. I really hope I'll get into this. Can't wait :)
ASCII only goes up to 127 as it's a 7bit set. The Spectrum's character set above that is non standard. (The Spectrum doesn't actually use ASCII, but a very close version -- there's no £ sign in ASCII for example).
Trying to figure what the routines are that you "call" 5633 and 8252, eventually led me to this book which seems to be a decent reference guide (not all understandable by me yet!) - wos.meulie.net/pub/sinclair/books/s/SpectrumOperatingSystemThe.pdf and Paul Land's SpeccyVirgins site of links. What resources do you use for reference (or is it mostly rememebered)?
If you want to know in detail what the ROM routines do in a Spectrum, I highly recommend _The Complete Spectrum ROM Disassembly_ by Ian Logan and Frank O’Hara. There’s a fully searchable online version as well: skoolkid.github.io/rom/index.html
Really enjoying this series, Darryl; the pace is spot on. Also, it's a great idea to do a Connect 4 game - looking forward to seeing how this develops. Cheers.
defb = define bytes. They are normal memory locations, starting wherever you put them in your code. It is perfectly possible to run them as a programme - just jump or call to one of those bytes.
The easier way to deal with the binary is to convert it to hex, every 4 bits is one hex digit, so that graphic at 18:26 woud be 00, 18, 3C, 7E, 7E, 3C, 18, 00. Split right down the middle.
Hi Darryl. Many thanks for your great tutorials that I've just belatedly stumbled upon. I have a question if you wouldn't mind helping. How do you save the basic program in ZX Spin as so far I've been unable to do this? (I can save the assembler code). Best regards, Bob
There is a way, but I forget. It involves loading a virtual tape into the emulator, setting it to record, then using SAVE from BASIC. You can, of course, just use the snapshot feature to save the entire virtual Spectrum's memory as a .sna file that can be loaded back in.
17:09 If the program uses data to keep track of items and you make a mistake somewhere else in it, the data can be run. This is called arbitrary code execution or ACE for short. Examples include the 8F item (8th floor, its ID isn't 8F) in Pokemon Red and the coin case in US and european versions of Pokemon Gold
Hello, thank you for the great job you're doing with this. I have a question, is there a way to print out a memory's value ? I mean if i poke 32000,144 how can i print out the value (144) ? TX
Thanks. Tricky problem. Here's how I would tackle it (but there might be an easier way, as my Z80 knowledge isn't comprehensive). You'd have to do a number of checks, such as: Is the number greater than 199? Then print "2", else is the number greater than 99? Then print "1". That takes care of the hundred's column. Then do a similar piece of logic for the tens, then the units. I'm summarising, but you get the idea.
@@darrylsloan thank's. i thought, better, i was hoping there was some callable routin somewhere in the z80 to do so but writing it. I already wrote it for the 8 bit number, working on 16 bit now. Greetings
The sequence ld a,2 call 5633 is equivalent to print #2; This selects the channel for the upper screen as the current output stream. calling with a having 3 selects the printer. Using Open #3,"b" would send data through an interface 1's rs232 port, if LPrint.... or Print #3 is used, like wise if ld a,3; call 5633....
finally got my board working correctly. Its not the most elegant code but it works. Looking forward to the next tutorial. drive.google.com/file/d/0B-clecJ31PPVeEhQRzdXVDJYUnM/view?usp=sharing
Another question I have is: Is there a way to redefine a string I defined with db? For example I set the string to "TEST" then print it then set it to "HELLO" and print it? I can't seem to find the way, since I've tried loading the address of str into HL then loading "HELLO" into the address currently held in HL but it won't work.
"Is there a way to redefine a string I defined with db?" Yes, but it's not really the right approach. You'd end up using more lines of code to do that than to simply create a new string with a new label (say string2), then replicate the code for the routine that prints a string and tweak it to point at string2. I do think I cover multiple strings in this lesson somewhere.
@@darrylsloan But replicating this code for every string I have to print looks very cluttered. I asked if there's a way to assign a string to another string.
@@darrylsloan Completely understand that. Just another thing. Won't just defining more and more strings take up memory? Is there a memoryfree command of sorts?
@@365tito3 You're not quite grasping what's happening yet. "call 8252" doesn't create a string. It's a ROM routine that prints data to the screen, depending on what values are preloaded into DE and BC. It's says, "Fetch the data starting at address DE and print it to the screen for next BC number of bytes." If I put 30000 into DE and 00005 into BC, then the data that is stored in 30000, 30001, 30002, 30003, 30004 will be printed to the screen, one byte/char at a time.
Ast A more (comments below) Peeked (excuse joke) my interest in the rest of the Restart Calls for my own Assembly notes. Here you go... RST ROM ‘Calls’ aka Restart Calls ------------------------------------------------------ DEC HEX DESCRIPTION 00 00 Reset/Start the Speccy 08 08 Error restart. Also used to Invoke the ZX Interface 1 16 10 Print a character held in the ‘A’ register to the current channel 24 18 Collect a character 32 20 Collect next character 40 28 Floating Point Calculator 48 30 Make 'BC' spaces - creates free locations in the workspace 56 38 Maskable interrupt. Read the keyboard and update Real time clock (RTC) Keep for future reference! P.S. Your doing a great job Darryl.
My intention is to print an exclamation point to the screen. In the ASCII lookup table, "!" is character 33. So LD A, "!" is the same as typing LD A, 33. The assembler will translate anything in quotes for you. I chose "!" merely because it is the first printable character after a space (32).
@@ImperatorGrausam The accumulator, "A", is one of several registers. The others are B, C, D, E, H, L. They are a bit like variables that you can use in the short-term purposes, such as addition, subtraction, moving data around. In my purpose, I'm moving the data "!" to the screen. The instruction RST 16 moves whatever it finds in the accumulator to the screen. Ultimately, you'll need a book to gain a proper understanding of all this.
Strictly speaking, it does not. The RST x (RST comes from Restart) instruction behaves like a CALL x, but the x (if expressed in decimal) can only be from 0 to 56 and only a multiple of 8. It is a shorter and quicker instruction for calling one of eight locations (0,8,16,...,56) at the beginning of the memory space. It is then the ROM that is in the Spectrum where the address 16 has a jump to a routine (further in the ROM) that prints one character (defined by the A register) to where ever is the current position.
Basically what pev said. The RST (restart) instruction was intended to be used by interrupt controller chips so that they could send a single-byte instruction to the CPU to tell it how to handle the interrupt. Programmers quickly realised that the instruction could also be used as a single-byte CALL instruction (the CALL instruction requires 3 bytes) and so make your program smaller (an important consideration in the days when computer memory was small and expensive) and slightly faster (only having to load one byte instead of three to CALL a subroutine).
Thanks Darryl but unfortunately Norton wont allow me to keep Spin it flags the file as unsafe and removes the dll's immediately doesnt even offer me the option to run it
Thankyou for being so helpful and quick to reply. I'll go ask at World of Spectrum they'll sort me out then I can get back to the tutorial which is the best I've yet encountered. I have written everything down in a notebook with the coding annotated explaining what it does from your narrative. This PC is a 64 bit one running Vista and perhaps thats why it doesnt like Spin?
I'm using pasmo (assembler) and Visual Studio Code on Linux to edit the assembly code and generate the binary. To get the assembled binary into fuse, just use the menu command: File>Load Binary Data and locate the assembly.
Actually, there is still some compiling going on from assembly language, which the CPU doesn't directly understand to machine code, 0s and 1s, that the CPU does directly understand....... Assembly language is the lowest level language that humans can practically work with....