Skip to content

Instantly share code, notes, and snippets.

@mwadams
Created April 10, 2013 22:07
Show Gist options
  • Save mwadams/5358890 to your computer and use it in GitHub Desktop.
Save mwadams/5358890 to your computer and use it in GitHub Desktop.
Z80 Assembler example
; 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 ; [email protected] ; 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,'$'
@radeoliveira
Copy link

thank's

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment