RosettaCodeData/Task/Ackermann-function/Z80-Assembly/ackermann-function.z80

109 lines
2.1 KiB
Z80 Assembly

OPT --syntax=abf : OUTPUT "ackerman.com"
ORG $100
jr demo_start
;--------------------------------------------------------------------------------------------------------------------
; entry: ackermann_fn
; input: bc = m, hl = n
; output: hl = A(m,n) (16bit only)
ackermann_fn.inc_n:
inc hl
ackermann_fn:
inc hl
ld a,c
or b
ret z ; m == 0 -> return n+1
; m > 0 case ; bc = m, hl = n+1
dec bc
dec hl ; m-1, n restored
ld a,l
or h
jr z,.inc_n ; n == 0 -> return A(m-1, 1)
; m > 0, n > 0 ; bc = m-1, hl = n
push bc
inc bc
dec hl
call ackermann_fn ; n = A(m, n-1)
pop bc
jp ackermann_fn ; return A(m-1,A(m, n-1))
;--------------------------------------------------------------------------------------------------------------------
; helper functions for demo printing 4x9 table
print_str:
push bc
push hl
ld c,9
.call_cpm:
call 5
pop hl
pop bc
ret
print_hl:
ld b,' '
ld e,b
call print_char
ld de,-10000
call extract_digit
ld de,-1000
call extract_digit
ld de,-100
call extract_digit
ld de,-10
call extract_digit
ld a,l
print_digit:
ld b,'0'
add a,b
ld e,a
print_char:
push bc
push hl
ld c,2
jr print_str.call_cpm
extract_digit:
ld a,-1
.digit_loop:
inc a
add hl,de
jr c,.digit_loop
sbc hl,de
or a
jr nz,print_digit
ld e,b
jr print_char
;--------------------------------------------------------------------------------------------------------------------
demo_start: ; do m: [0,4) cross n: [0,9) table
ld bc,0
.loop_m:
ld hl,0 ; bc = m, hl = n = 0
ld de,txt_m_is
call print_str
ld a,c
or '0'
ld e,a
call print_char
ld e,':'
call print_char
.loop_n:
push bc
push hl
call ackermann_fn
call print_hl
pop hl
pop bc
inc hl
ld a,l
cp 9
jr c,.loop_n
ld de,crlf
call print_str
inc bc
ld a,c
cp 4
jr c,.loop_m
rst 0 ; return to CP/M
txt_m_is: db "m=$"
crlf: db 10,13,'$'