The definitive "teach yourself machine code" text?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
AndyC
Dynamite Dan
Posts: 1405
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: 2041
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: 3266
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
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 »

Add LD B,0 before RET. Also, if you wish to see the result of your bitwise OR, then you need to load the value in A back into C: LD C,A. So, your code should look something like this:

Code: Select all

	LD A,(65025)
	LD C,A
	LD A,(65024)
	OR C
	ld c,a
	ld b,0
	RET
I strongly recommend you start using a debugger. Then you can step through your code instruction by instruction, and before you see the result of each, try to predict how the registers or memory contents will change. Then compare the actual results with your predictions.
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: 2041
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

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

Post by TMD2003 »

Looking through these responses, at least this confirms that it is doing a bitwise OR. That's useful to know.

And adjusting the program Peter sent me earlier wasn't too hard...

ld hl,22528
ld bc,352
ld (hl),87
inc hl
dec bc
ld a,b
or c
jr nz -8
ld hl,22880
ld bc,352
ld (hl),120
inc hl
dec bc
ld a,b
or c
jr nz -8
ret

...there's the program I needed, in 29 bytes. That'll do nicely. You may now all laugh derisively at the Softek compiler. See, I knew it could be given a pants-down thrashing.

Now on with the rest of it! And that includes understanding why the instructions ld a,b / or c do what they are needed to do here.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
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://www.google.co.uk/url?sa=t&rct=j ... PWnvolzweu

(PDF) for the Zilog Z80 manual.

LD r, n

Condition Bits Affected: None

(Page 86)

OR s

"The s operand is any of r, n, (HL), (IX+d), or (lY+d), as defined for the analogous ADD instructions."

Condition Bits Affected
S is set if result is negative; otherwise, it is reset.
Z is set if result is 0; otherwise, it is reset.
H is reset.
P/V is set if overflow; otherwise, it is reset.
N is reset.
C is reset.

(Page 173 and 174 (note PDF page nos by the way))

Here you see that the Z flag is set for an OR instruction, so then you can JR NZ/JR Z off the back of it.
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

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

Post by BenHanson »

Let me know if you want my z80 assembler source BTW and I can create a CodeProject article. Are you on Linux or Windows?

I now having the assembler loading a default .sna and then writing out a new one with the assembled code copied over. This hugely speeds up testing.
User avatar
TMD2003
Rick Dangerous
Posts: 2041
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 7:17 pm Let me know if you want my z80 assembler source BTW and I can create a CodeProject article. Are you on Linux or Windows?
Windows 7, although I have access to Lubuntu 15.10 on a USB stick.

Just don't assume I can run before I can walk...!
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: 3096
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 11:32 am 10 FOR n=22528 TO 22879: POKE n,15: POKE n+352,48: NEXT n
[...]
This could be done in 20 bytes, maybe even ten, but who needs this many?"
I know it was a rethoric question but since you mentioned my name...

I believe the minimum implementation is 17 bytes :)
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

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

Post by BenHanson »

For anyone that is interested you can find my Z80 assembler here: https://www.codeproject.com/Articles/52 ... -Assembler

Be sure to report any issues, this is all very new!

Thanks
User avatar
Morkin
Bugaboo
Posts: 3266
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

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

Post by Morkin »

Einar Saukas wrote: Sat Oct 03, 2020 7:41 pm I believe the minimum implementation is 17 bytes :)
* (Gets popcorn and waits for the optimization to begin) :lol:
My Speccy site: thirdharmoniser.com
User avatar
TMD2003
Rick Dangerous
Posts: 2041
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

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

Post by TMD2003 »

Is this also the right time to suggest a Machine Code sub-forum for threads like this one, the one cmal's just made, and others? It might well be useful.
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
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 »

Einar Saukas wrote: Sat Oct 03, 2020 7:41 pm I believe the minimum implementation is 17 bytes :)
It’s late and I’m tired, but I can’t for the life of me to get it below twenty:

Code: Select all

	ld bc,352
	ld de,$5800+352	
	ld hl,$5800
	ld a,48		

loop	ld (hl),15
	ld (de),a
	inc de
	cpi
	jp pe,loop	
:cry:
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
Einar Saukas
Bugaboo
Posts: 3096
Joined: Wed Nov 15, 2017 2:48 pm

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

Post by Einar Saukas »

There's a simpler solution in 20 bytes:

Code: Select all

ld hl, $5800
ld de, $5801
ld bc, 352
ld (hl), 15
ldir
ld bc, 351
ld (hl), 48
ldir
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 »

Okay, down to 19 bytes:

Code: Select all

	ld hl,$5800
	ld a,15
	call fill
	ld a,48

fill	ld bc,352
loop	ld (hl),a
	cpi
	ret po
	jr loop
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: 2041
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

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

Post by TMD2003 »

Two to go! Only two more to go!

Right now, I am hacking my way through the New Generation Software tutor. I've already improved the code for lesson 6, although I'm not supposed to know about INC and DEC yet. (ITV's new Geordie presentation team while Ant's drying out!) So far it's a bit like trying to write Python programs with functions I'm not supposed to know about, but I thought "what the hell, I'll look them up - how hard can it be?" And I wrote some iterative maths programs to calculate constants using Taylor series, just to see how easy it was.

I suppose that's something I could aim at with machine code - seeing as the Z80 has to work out functions like SIN and EXP using simple arithmetic until the result fills up all the available decimal places correctly, I'll see if I can (eventually) translate the BASIC programs for the Euler-Mascheroni constant and the (very slowly converging) Gregory-Leibniz formula for pi. It should also be relatively straightforward to calculate factorials, although the gamma function might be a bit more tricky...
Last edited by TMD2003 on Sun Oct 04, 2020 4:05 pm, edited 1 time in total.
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
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: Sun Oct 04, 2020 3:49 pm seeing as the Z80 has to work out functions like SIN and EXP using simple arithmetic until the result fills up all the available decimal places correctly, I'll see if I can (eventually) translate the BASIC programs for the Euler-Mascheroni constant and the (very slowly converging) Gregory-Leibniz formula for pi.
On smaller, underpowered systems like the Spectrum, coding is always a compromise between optimizing for speed or size. Sometimes, both can be achieved simultaneously, but only if the code is not very optimized to begin with. I am much more skilled at optimizing for speed, rather than size, so take my suggestion with a grain of salt, but for the most part, the trick with many complex math calculations is to resort to look-up tables of pre-calculated values.
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.
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

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

Post by Dr beep »

Everyone did it in his own way.

I would suggest a simple program that uses RST 16 to display a character and slowly expand that code into a moving character and finally a controlled moving character. This will give you ideas how to show progress and how input can be used in games.

First job is to get familiar with the input and output on a ZX Spectrum

Special effects like bitwise movement will come later.
User avatar
PeterJ
Site Admin
Posts: 6873
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

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

Post by PeterJ »

Dr beep wrote: Sun Oct 04, 2020 5:05 pm

I would suggest a simple program that uses RST 16 to display a character and slowly expand that code into a moving character and finally a controlled moving character. This will give you ideas how to show progress and how input can be used in games.

First job is to get familiar with the input and output on a ZX Spectrum
Agreed!
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

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

Post by BenHanson »

Also have a look at http://www.primrosebank.net/computers/z ... blyThe.pdf

You can reuse some of the ROM routines.
User avatar
TMD2003
Rick Dangerous
Posts: 2041
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

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

Post by TMD2003 »

After finishing the first of the four sides of the New Generation tutorial tapes, plus what I've picked up off this thread, would this be a reasonable summary of the registers?

Use A for doing any kind of calculations.
Use BC if you want the result to be returned to BASIC (i.e. via PRINT USR ..... or LET variable = USR .....).
Use DE if you'll need to keep on swapping with HL (because so far EX DE,HL is the only DE-specific instruction I've come across).
Use HL to store addresses that need to be easily referenced and retrieved.

As for the "BC loop" that occurred earlier in this thread (i.e. DEC BC | LD A,B | OR C | DJ NZ ...), is there any reason why that wouldn't work with DE instead of BC? I suppose I could modify that successful routine and try it, and see what happens...
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
BenHanson
Drutt
Posts: 9
Joined: Sat Oct 03, 2020 2:22 pm

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

Post by BenHanson »

DJNZ is decrement B and Jump relative Not Zero

Yes you can:

DEC DE
LD A, D
OR E
JR NZ, ...
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: Sun Oct 04, 2020 9:22 pm Use A for doing any kind of calculations.
Mostly, yes.
TMD2003 wrote: Sun Oct 04, 2020 9:22 pmUse BC if you want the result to be returned to BASIC (i.e. via PRINT USR ..... or LET variable = USR .....).
Well, this is a very specific case that has to do with the Spectrum’s operating system. BC (sometimes referred to as the Byte Counter) is used in block copy/compare/input/output operations and the B register itself is used by the DJNZ instruction.
TMD2003 wrote: Sun Oct 04, 2020 9:22 pmUse DE if you'll need to keep on swapping with HL (because so far EX DE,HL is the only DE-specific instruction I've come across).
DE (sometimes referred to as the DEstination) is also used in block copy operations and points to the destination address of a byte (or block of bytes) to be copied to.
TMD2003 wrote: Sun Oct 04, 2020 9:22 pmUse HL to store addresses that need to be easily referenced and retrieved.
HL is the most versatile of the register pairs. It is somewhat similar to the A register, as it is the place where the results of arithmetic operations will be stored (e.g. ADD HL,DE, SBC HL,BC). It is also the only register pair that can point to a byte in memory to be loaded directly with a value (e.g. LD (HL),n) or used in conjunction with the stack pointer SP.
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.
Post Reply