Language Assembler (Z80)
(Sinclair/Timex variant)
Date: | 07/28/05 |
Author: | Damien Guard |
URL: | http://www.damieng.com |
Comments: | 7 |
Info: | n/a |
Score: | (3.27 in 742 votes) |
; 99 Bottles of Beer program in Zilgo Z80 assembly language. ; Assembles for ZX Spectrum/Timex - change Spectrum: lines ; if porting. Help from Marko! Compiled and tested with SPIN ; ; Adapted from the Alan deLespinasse's Intel 8086 version ; ; Author: Damien Guard ; damien@envytech.co.uk ; www.damieng.com org 32768 start: ld a, 2 ; Spectrum: channel 2 = "S" for screen call $1601 ; Spectrum: Select print channel using ROM ld c,99 ; Number of bottles to start with loopstart: call printc ; Print the number of bottles ld hl,line1 ; Print the rest of the first line call printline call printc ; Print the number of bottles ld hl,line2_3 ; Print rest of the 2nd and 3rd lines call printline dec c ; Take one bottle away call printc ; Print the number of bottles ld hl,line4 ; Print the rest of the fourth line call printline ld a,c cp 0 ; Out of beer bottles? jp nz,loopstart ; If not, loop round again ret ; Return to BASIC printc: ; Routine to print C register as ASCII decimal ld a,c call dtoa2d ; Split A register into D and E ld a,d ; Print first digit in D cp '0' ; Don't bother printing leading 0 jr z,printc2 rst 16 ; Spectrum: Print the character in 'A' printc2: ld a,e ; Print second digit in E rst 16 ; Spectrum: Print the character in 'A' ret printline: ; Routine to print out a line ld a,(hl) ; Get character to print cp '$' ; See if it '$' terminator jp z,printend ; We're done if it is rst 16 ; Spectrum: Print the character in 'A' inc hl ; Move onto the next character jp printline ; Loop round printend: ret dtoa2d: ; Decimal to ASCII (2 digits only), in: A, out: DE ld d,'0' ; Starting from ASCII '0' dec d ; Because we are inc'ing in the loop ld e,10 ; Want base 10 please and a ; Clear carry flag dtoa2dloop: inc d ; Increase the number of tens sub e ; Take away one unit of ten from A jr nc,dtoa2dloop ; If A still hasn't gone negative, do another add a,e ; Decreased it too much, put it back add a,'0' ; Convert to ASCII ld e,a ; Stick remainder in E ret ; Data line1: defb ' bottles of beer on the wall,',13,'$' line2_3: defb ' bottles of beer,',13,'Take one down, pass it around,',13,'$' line4: defb ' bottles of beer on the wall.',13,13,'$'
Download Source | Write Comment
Alternative Versions
Version | Author | Date | Comments | Rate |
---|---|---|---|---|
Amstrad CPC Version | Duncan Bayne | 08/20/05 | 2 | |
2004 submission | Elroy Sullivan & Barry Goode | 08/13/09 | 0 |
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments
Oleg Kosenkov said on 04/23/06 05:27:56
Zilgo -> Zilog
bau de jogos said on 11/23/06 23:46:07
It is very good to see the old Z80 beating many modern languages in clarity and correctness
sergio said on 10/05/07 11:58:10
Hello! You have a Very good site! I like it! I just wanted to pass on a note to let you know
banana said on 05/21/08 08:07:47
This line could be optimized:
cp 0 ;Out of beer bottles?
Instead of comparing to zero, just do 'and a', which should update the flags and is a byte shorter.
Mark G said on 04/27/09 10:43:01
Looks like 8080 code written with Zilog mnemonic surely if this was Z80 we we have used a DJNZ to control the loop
Jean-Charles Meyrignac said on 05/31/09 17:53:30
The base 10 routine is overkill !
This could be improved by using a BCD counter instead.
Start with ld c,99h
Instead of dec c use:
ld a,c
sub a,1
daa
ld c,a
Printing an hexadecimal number is done as:
ld d,a
srl a
srl a
srl a
srl a
add a,'0'
printchar
ld a,d
and a,0Fh
printchar
(sorry, my Z80 is a little bit rusty)
barrym said on 08/18/10 04:22:30
@bau: Clarity? Sure. Correctness? Not so much. (Duncan Baynes' version produces a
much more correct output).