CPCWiki forum

General Category => Programming => Topic started by: jonesypeter on 20:01, 27 January 16

Title: Assembly Language Newbie - Treat me gently!
Post by: jonesypeter on 20:01, 27 January 16
Hi,


I have tried many times in the past to grasp the basics of Machine Code, and although normally I'm a ZX Spectrum user I wanted to do more with the Amsttrad CPC Range (and feel this is a better managed forum than a certain other one, especially at the moment), and found the Amstrad PrintOut fanzine Machine Code tutorials which I found the best tutorial I had read for ages.


Anyway I'm just printing characters to the screen.  I have got the grasp of writing 255 characters, but if I want more I'm copying the code as you will see below.  Is there a more elegant (not too complex) way of achieving this? I know I need to use Loops, but I don't know any way of jumping out of an outer loop without using the A Register (which I'm already using)


Thanks in advance.



ORG &4000
LD a,255
.main
ld b,a
ld a,65
CALL &BB5A
ld a,b
DEC A
CP 0
JP Z, two
JP main

.two

LD a,255
.main2
ld b,a
ld a,66
CALL &BB5A
ld a,b
DEC A
CP 0
JP Z, three
JP main2

.three

LD a,255
.main3
ld b,a
ld a,67
CALL &BB5A
ld a,b
DEC A
CP 0
JP Z, four
JP main3

.four

LD a,255
.main4
ld b,a
ld a,68
CALL &BB5A
ld a,b
DEC A
CP 0
RET Z
JP main4





Title: Re: Assembly Language Newbie - Treat me gently!
Post by: TFM on 20:25, 27 January 16
Quote from: jonesypeter on 20:01, 27 January 16

ORG &4000

.write
ld hl,text

loop
ld a,(hl)
or a,a
ret z
push hl
CALL &BB5A
pop hl
inc hl
JP loop

text DB "This is the text you like to print.... as long as you want.",0


If you have questions, let me know.

Title: Re: Assembly Language Newbie - Treat me gently!
Post by: Grim on 20:38, 27 January 16
This will repeatedly print a null terminated string for a given number of char, as your example does.
ORG &4000

; set pointer on a null terminated char string in HL
ld hl,nt_string
; set how many char to output in B
ld b,200

; save string pointer into DE
ld d,h
ld e,l

; main loop
loop ld a,(hl) ; read one char
inc hl ; move string pointer to next char
call &BB5A ; print char (if it is null, nothing gets out)
or a ; test if char is null
jr nz,continue
ld h,d ; if it is, restore the string pointer in HL
ld l,e ; to its initial value
continue
djnz loop ; loop until B=0
; exit
ret

; A null terminated string of any length
nt_string
DB "CPC-WIKI ",0


The DJNZ instruction performs something like DEC B:JR NZ,<offset>, which is handy to handle 8-bit loop using B as loop counter.
Also, a null char (zero) has no effect when output to screen with &BB5A, which is why the example above does not bother and print all char read before testing if it is a null or not.

About your code, this snippet:
DEC A
CP 0
JR Z,<something>

The DEC A instruction will automatically set the Zero flag if A equal zero, thus the following CP 0 is not necessary.

ps: Nice avatar! His records might help a lot to remain zen when learning assembly :)
Title: Re: Assembly Language Newbie - Treat me gently!
Post by: jonesypeter on 21:11, 27 January 16
Thanks Grim,


Really useful.  Will take a read through and give it a go. Thanks also for the info about the DEC instruction.


RE: Bob Marley.  I wish I had been able to see him live, but sadly not.
Title: Re: Assembly Language Newbie - Treat me gently!
Post by: jonpaule on 12:05, 15 March 16
Opcode 'OR A' to test for zero. Now that brings back some good and some painful memories!
Powered by SMFPacks Menu Editor Mod