Page 1 of 2
New to Machine code, help required
Posted: Thu Dec 06, 2018 5:26 pm
by Panther
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 !
Re: New to Machine code, help required
Posted: Thu Dec 06, 2018 7:38 pm
by rune
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
Re: New to Machine code, help required
Posted: Thu Dec 06, 2018 8:11 pm
by XavSnap
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)
Re: New to Machine code, help required
Posted: Thu Dec 06, 2018 8:45 pm
by rune
@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?
Re: New to Machine code, help required
Posted: Thu Dec 06, 2018 11:16 pm
by siggi
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
Re: New to Machine code, help required
Posted: Fri Dec 07, 2018 1:06 am
by Panther
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) ?
Re: New to Machine code, help required
Posted: Fri Dec 07, 2018 2:07 am
by XavSnap
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
Re: New to Machine code, help required
Posted: Fri Dec 07, 2018 2:47 am
by 1024MAK
@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
Re: New to Machine code, help required
Posted: Fri Dec 07, 2018 3:06 am
by XavSnap
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 !

Re: New to Machine code, help required
Posted: Fri Dec 07, 2018 9:28 am
by rune
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