Skip to content

Commit

Permalink
Added an example of calculating Fibonacci numbers.
Browse files Browse the repository at this point in the history
The maximum possible number of a number in the sequence is 47.
It is limited to the 32-bit value of numbers.
The result is displayed in hexadecimal value, since it is very
difficult to implement the conversion of such large numbers to
decimal representation (ASCII) without hardware division.
  • Loading branch information
baskiton committed Apr 2, 2021
1 parent 31db99e commit 2c091f1
Show file tree
Hide file tree
Showing 2 changed files with 309 additions and 0 deletions.
2 changes: 2 additions & 0 deletions rom/fibo.rom
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
v2.0 raw
38 2F 0C 0A 53 74 61 72 74 69 6E 67 20 6C 6F 61 64 69 6E 67 20 74 68 65 20 46 69 62 6F 6E 61 63 63 69 20 70 72 6F 67 72 61 6D 2E 2E 2E 0A 24 4C 06 03 0E 01 2E 0C 36 03 2A 04 A8 2A 07 06 02 4E 16 02 1E 00 26 01 2E 0D 36 00 2A 07 38 E7 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 AB 0A 45 6E 74 65 72 20 74 68 65 20 64 65 73 69 72 65 64 20 46 69 62 6F 20 6E 75 6D 62 65 72 20 28 32 20 74 6F 20 34 37 29 3A 20 24 16 20 A8 2E 0C 36 80 F8 30 11 48 32 0D 36 84 3E 01 36 88 3E 10 22 3C 0A 40 4B 0D 04 30 38 4F 0D 14 0A 04 41 22 C7 1E 00 0E 0A 16 00 14 10 60 60 0D 10 38 57 0D 04 10 39 41 0D 44 18 C2 3C 10 40 55 0D 39 41 0D 44 18 21 68 7F 0D 30 48 7B 0D 28 C7 38 55 0D 4E 06 01 16 01 2A 04 19 48 7F 0D 22 44 4C 54 5C 64 05 16 04 2E 0C 1E 80 26 84 F4 C7 CF F3 8F F9 F4 F8 18 20 11 48 99 0D 66 5E 56 4E 46 22 44 54 06 01 16 01 2A 04 56 46 22 0E 0A 39 AD 0D 22 4C 54 5C 64 26 00 30 48 C9 0D 28 D7 30 48 CF 0D 28 C7 14 30 C8 A8 1E 0A 84 19 48 D6 0D 81 E0 11 48 CA 0D C4 66 5E 56 4E 22 39 2B 0D 06 03 0E 01 2E 0D 36 00 2A 04 06 0C 0E 04 2E 0C 36 88 2A 05 2E 0C 36 88 39 BE 0D D0 11 39 8B 0D 0E 2E 39 AD 0D 11 48 07 0E 39 B8 0D 2E 0C 36 84 0E 30 39 AD 0D 0E 78 39 AD 0D 26 04 39 50 0D 39 B8 0D 38 E7 0D FF
307 changes: 307 additions & 0 deletions src/fibo.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
org 0C00h
jmp loader

loader_msg:
db 0Ah, "Starting loading the Fibonacci program...", 0Ah, "$"

loader:
push b

mov a, 3
mov b, 1
mov h, (loader_msg >> 8)
mov l, (loader_msg & 255)
int 4h

xor a, a
int 7h ; reset storage system to copy

mov a, 2 ; read the second sector to RAM
pop b ; storage number
mov c, 2 ; count of sectors to read
mov d, 0
mov e, 1
mov h, 0Dh
mov l, 00h
int 7h

jmp start

padding:
; db 176 dup 0 ; pad
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
signature:
db 0ABh ; boot signature

intro:
db 0Ah, "Enter the desired Fibo number (2 to 47): ", "$"

num_a equ 0C80h
num_b equ 0C84h
kb_buf equ 0C88h
KB_BUF_SIZE equ 16

SETUP proc
mov c, (16 + KB_BUF_SIZE)
xor a, a ; (A)=0

mov h, (num_a >> 8)
mov l, (num_a & 255)
set_loop:
mov mem, a
inc l
dec c
jnz set_loop

mov l, (num_b & 255)
mov mem, 01h ; num_b = 1
mov l, (kb_buf & 255)
mov mem, KB_BUF_SIZE ; set buffer max size

ret
SETUP endp

DIG_TO_HEX proc
; (A) - digit to convert from num to HEX ASCII
cmp a, 10
jnc hex_conv_alpha ; a >= 10
hex_conv_dig:
add a, '0' ; a < 10
jmp hex_conv
hex_conv_alpha: ; a >= 10
sub a, 10
add a, 'A'
hex_conv:
ret
DIG_TO_HEX endp

PRINT_HEX proc
; (H)(L) - address of number
; (E) - number of bytes

mov a, mem
mov d, 0 ; cnt of digits
mov b, 10

hex_prep:
mov c, 0 ; remainder

hex_loop:
sub a, 16 ; eq div by 16
jc hex_save_ord
inc c
jmp hex_loop

hex_save_ord:
add a, 16 ; return digit to positive

call DIG_TO_HEX
push a ; save digit
inc d

mov a, c
cmp a, 16
jnc hex_prep ; jmp if remainder >= 16

call DIG_TO_HEX
push a ; save digit
inc d

dec e
jz hex_print_loop
inc l
jnz hex1
inc h
hex1:
mov a, mem
jmp hex_prep

hex_print_loop:
pop b
mov a, 1
mov c, 1
int 4h
dec d
jnz hex_print_loop

ret
PRINT_HEX endp

ADD_UI32 proc
; Realization the next sequence:
; t = a + b
; a = b
; b = t
; or short:
; a, b = b, a + b
add_start:
push a
push b
push c
push d
push e

clc ; clear carry flag
mov c, 04h ; counter for 32bit numbers
mov h, (num_a >> 8) ; constant value

mov d, (num_a & 255)
mov e, (num_b & 255)

add_loop:
mov l, e
mov a, mem ; t = b
mov b, mem ; tb = b
mov l, d
adc a, mem ; t = t(b) + a
mov mem, b ; a = tb(b)
mov l, e
mov mem, a ; b = t

inc d
inc e
dec c
jnz add_loop

add_end:
pop e
pop d
pop c
pop b
pop a

ret
ADD_UI32 endp

putc proc
; (B) Char to write
push a
push c

mov a, 1
mov c, 1
int 4h

pop c
pop a

ret
putc endp

put_nl proc
mov b, 0Ah
call putc ; new line
ret
put_nl endp

atoi proc
; (H)(L) - address of string buffer by INT5
; The string must contain only ASCII digits!
; (A) - result return
push b
push c
push d
push e

atoi0:
mov e, 0 ; result
inc l
jnz atoi1
inc h

atoi1:
mov c, mem ; string length
atoi1_loop:
inc l
jnz atoi2
inc h

atoi2:
mov a, mem
sub a, '0'
mov b, a

xor a, a
mov d, 10
atoi3_mult:
add a, e
dec d
jnz atoi3_mult ; multiple by 10

add a, b
mov e, a ; save result

atoi4:
dec c
jnz atoi1_loop

atoi_end:
mov a, e
pop e
pop d
pop c
pop b

ret
atoi endp

start:
call SETUP

mov a, 3
mov b, 1
mov h, (intro >> 8)
mov l, (intro & 255)
int 4h ; print intro string

; get desired fibo number (2 to 47) (int5 A=4, clear buffer before (A=12))
mov a, 0Ch
mov b, 4
mov h, (kb_buf >> 8)
mov l, (kb_buf & 255)
int 5h

mov h, (kb_buf >> 8)
mov l, (kb_buf & 255)
call atoi
mov c, a
dec c

fibo:
call ADD_UI32

mov b, '.'
call putc ; put dot for each set

dec c
jnz fibo

call put_nl ; new line

result:
mov h, (num_b >> 8)
mov l, (num_b & 255)

mov b, "0"
call putc
mov b, "x"
call putc

mov e, 4
call PRINT_HEX

call put_nl ; new line

jmp start

hlt

1 comment on commit 2c091f1

@baskiton
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1 Done

Please sign in to comment.