109 lines
2.1 KiB
Z80 Assembly
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,'$'
|