New to Machine code, help required

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
Panther
Posts: 2
Joined: Wed Dec 05, 2018 4:46 pm

New to Machine code, help required

Post by Panther » Thu Dec 06, 2018 5:26 pm

Hi peeps,

New to the forum and looking for guidance as I take my first steps into ZX81 machine code !!
I’ve been reading through ‘Mastering Machine Code on your ZX81’ and I’m understanding it so far but I’m a little confused with one of the most basic things;

Printing to the screen !!

One of the examples is;
3E97 LD A,inverse-*
CD0808 CALL PRINT
18F9 JR START

Which from what I understand loads the code for an inverse asterix into register A, call a print routine to print the contents of A in the next available print position and finally jumps back 7 bytes to repeat until the screen is full and you get an error 5 out of screen error.

Now I’ve tried a couple of things to fill the screen without the error and I’m failing miserably but I can’t see where I am going wrong, I know it’s probably really simple but any pointers would help.

So far I’ve tried;

3E08 LD A, Character 8
01D602 LD BC, 726
CD0808 CALL PRINT
0B DEC BC
20FA JR NZ, CALL PRINT
C9 RET

And

01D602 LD BC,726
3E08 LD A, Inverse space
CD0808 CALL PRINT
EBD0 LDIR
C9 RET

The first fills the screen with an out of screen error, the second just prints one character and stops.

I thought the JR NZ would jump back until the last calculation was zero (BC), likewise I thought the LDIR would repeat again until BC has decremented to zero

Plenty more questions to come I think !

rune
Posts: 158
Joined: Thu Sep 04, 2014 8:35 am

Re: New to Machine code, help required

Post by rune » Thu Dec 06, 2018 7:38 pm

Hi Panther, where does the 726 value come from? The standard screen is 22 lines x 32 columns so 704 positions.

Also, if you press the CONT key, your first routine will print another screen of characters... Thats because the JR NZ tests the value of the A Register, you are decrementing BC.

So, the routine prints the character for ever with breaks when the screen is filled.

The second example you print the first value thats held in A

But LDIR uses the HE and DE registers - Specifically the contents of memory address pointed to by HL is loaded into the memory address pointed to by DE, BC is decremented - HL and DE incremented and the cycle repeated until BC = 0.
A is ignored.

Here is my take on the first example. The code will stop with 0/10 which means the program has completed. Formatting is lost, so I have used "."s to get the code indented.

............. LD BC, 704
PRNT....... LD A, 44
............. CALL PRINT
............. DEC BC
............. LD A, B
............. OR C
............. JR NZ, PRNT
............. RET

User avatar
XavSnap
Posts: 520
Joined: Sat May 10, 2008 4:23 pm

Re: New to Machine code, help required

Post by XavSnap » Thu Dec 06, 2018 8:11 pm

Use the RST10 function, to avoid to destroyed the n/l character...

Code: Select all

Lb40A4:
	LD HL,$03BF 
Lb40A7:
	LD A,151 ; '*'
	RST 10H ; Display= A reg.
	LD A,$00 
	DEC HL 
	CP H 
	JR NZ, Lb40A7 ; [$40A7:16551]
	RET ; ==========================
@rune : (22 lines x 32 )+23 (new/line=$76)

rune
Posts: 158
Joined: Thu Sep 04, 2014 8:35 am

Re: New to Machine code, help required

Post by rune » Thu Dec 06, 2018 8:45 pm

@XavSnap, yes, but to be pedantic, 704 + 23 N/L is 727, not 726. Also using Call Print or RST#10 would only print in printable locations, so the count has to be 704.

Why did you use $03BF as the counter? Isnt that more than a standard screen?

User avatar
siggi
Posts: 875
Joined: Thu May 08, 2008 9:30 am
Location: Dauernheim, Germany
Contact:

Re: New to Machine code, help required

Post by siggi » Thu Dec 06, 2018 11:16 pm

rune wrote:
Thu Dec 06, 2018 7:38 pm
Also, if you press the CONT key, your first routine will print another screen of characters... Thats because the JR NZ tests the value of the A Register, you are decrementing BC.
No, JR NZ tests the Z-flag, which is part of the F register. It could be set by a lot of instructions (like "DEC C" or "AND A"), but not by 16 bit operations like "DEC BC".

Siggi
My ZX81 web-server: online since 2007
http://zx81-siggi.endoftheinternet.org/index.html

Panther
Posts: 2
Joined: Wed Dec 05, 2018 4:46 pm

Re: New to Machine code, help required

Post by Panther » Fri Dec 07, 2018 1:06 am

rune wrote:
Thu Dec 06, 2018 7:38 pm
Hi Panther, where does the 726 value come from? The standard screen is 22 lines x 32 columns so 704 positions.

Also, if you press the CONT key, your first routine will print another screen of characters... Thats because the JR NZ tests the value of the A Register, you are decrementing BC.

So, the routine prints the character for ever with breaks when the screen is filled.

The second example you print the first value thats held in A

But LDIR uses the HE and DE registers - Specifically the contents of memory address pointed to by HL is loaded into the memory address pointed to by DE, BC is decremented - HL and DE incremented and the cycle repeated until BC = 0.
A is ignored.

Here is my take on the first example. The code will stop with 0/10 which means the program has completed. Formatting is lost, so I have used "."s to get the code indented.

............. LD BC, 704
PRNT....... LD A, 44
............. CALL PRINT
............. DEC BC
............. LD A, B
............. OR C
............. JR NZ, PRNT
............. RET
Hi rune,

The 726 comes from 32 + the new line = 33 x 22 = 726 (only what I've read in the book)

So from this "But LDIR uses the HE and DE registers - Specifically the contents of memory address pointed to by HL is loaded into the memory address pointed to by DE, BC is decremented - HL and DE incremented and the cycle repeated until BC = 0.
A is ignored.
"

Are you saying it's printing the contents of A (first character) and then continuing until BC=0 but just printing blank spaces (ignoring A) ?

User avatar
XavSnap
Posts: 520
Joined: Sat May 10, 2008 4:23 pm

Re: New to Machine code, help required

Post by XavSnap » Fri Dec 07, 2018 2:07 am

5 examples to fill a screen.

Code: Select all

#include ZX81.sym

#define ORG  .org       ; TASM cross-assembler definitions
#define equ  .equ
;-----------------------------------

;------- Rom and Ram Symbols -------
RAM_D_FILE equ $400C ; D_file address.
EXTERR equ $005B ; Basic Break function ! Ignore line instructions.
CURSEUR equ $8F5 ; Point to PRINT AT DEST.(BC=X,Y)
CHAINE equ $B6B ; PRINT A CHAINE (BC=LEN;DE=TEXT LOC)
	
ORG 16514
;--------------------------------1
	LD BC,0000
	CALL CURSEUR
	LD BC,22*32
LOOP1:
	LD A,157 ; '1'
	RST 10H
	DEC BC
	LD A,B
	OR C
	JR NZ,LOOP1
	RET
;--------------------------------2

	LD HL,(RAM_D_FILE)
	LD B,158 ; '2'
	LD DE,32*24+23
LOOP2:
	LD A,$76
	INC HL
	CP (HL)
	DEC DE
	JR Z,LOOP2
	LD (HL),B
	LD A,D
	OR E
	RET Z
	JR LOOP2

;--------------------------------3

	LD HL,(RAM_D_FILE)
LOOP3:
	INC HL
	LD D,H
	LD E,L
	INC DE
	LD A,159 ; '3'
	LD (HL),A
	LD BC,31
	LDIR
	LD A,$80
	EX DE,HL
	INC HL
	CP (HL)
	EX DE,HL
	RET Z
	INC HL
	JR LOOP3

;--------------------------------4

	LD HL,(RAM_D_FILE)
	INC HL
	LD D,H
	LD E,L
	INC DE
	LD A,160 ; '4'
	LD (HL),A
	LD BC,31
	LDIR
	LD BC,$0100
	CALL CURSEUR
	LD L,21

LOOP4:

	LD DE,(RAM_D_FILE)
	INC DE
	LD BC,32
	CALL CHAINE
	DEC L
	RET Z
	RET Z
	JR LOOP4

;--------------------------------5

Lb40A4:
	LD BC,0000
	CALL CURSEUR
		LD HL,$03BF 
Lb40A7:
		LD A,161 ; '5'
		RST 10H ; Display= A reg.
		LD A,$00 
		DEC HL 
		CP H 
		JR NZ, Lb40A7 ; [$40A7:16551]
		RET ; ==========================
	
.end
fill_test.zip
(54.07 KiB) Downloaded 3 times

User avatar
1024MAK
Posts: 2154
Joined: Mon Sep 26, 2011 10:56 am
Location: Looking forward to summer in Somerset, UK...

Re: New to Machine code, help required

Post by 1024MAK » Fri Dec 07, 2018 2:47 am

@Panther

A few things to keep in mind.

Some of the Z80 instructions are designed to be compatible with the Intel 8080. Hence the slightly different way that 8 bit and 16 bit operations are handled with respect to the effect on the flag (F) register. The conditional jumps are based on the relevant bit in the flag register. Check each op-code to see if and what affect it has (if any) on the flags.

Some calls to the ROM code will affect some registers, as the routine may use some of the registers for it’s own purposes.

Mark

User avatar
XavSnap
Posts: 520
Joined: Sat May 10, 2008 4:23 pm

Re: New to Machine code, help required

Post by XavSnap » Fri Dec 07, 2018 3:06 am

:mrgreen:

Yes,

Code: Select all

	INC DE
	LD BC,32
	CALL CHAINE
	DEC L
	RET Z
	RET Z
	JR LOOP4
The first RET Z don't work.
I tryed using the A register with a "OR A" to clean the F register, CCF for the carry...
But, the ROM seem to add a new jump to the PC accumulator...
Two RET seem working !
:lol:

rune
Posts: 158
Joined: Thu Sep 04, 2014 8:35 am

Re: New to Machine code, help required

Post by rune » Fri Dec 07, 2018 9:28 am

Hi Xavsnap
Are you saying it's printing the contents of A (first character) and then continuing until BC=0 but just printing blank spaces (ignoring A) ?
Yes, the LDIR command only operates on HL, DE, BC registers. We dont know what addresses HL or BC are pointing to, just that they pass the contents from HL to DE and increase as BC decreases. (Probably) nothing is being printed to the screen, not even blank characters during the LDIR

Post Reply