;Simpel miniräknare
;C++arl Mar. 2007
format MZ	;exe format
org 0x100	;standard startpunkt (256)

jmp start
   ;Funktioner

   ;Användar IO:--

   ;Läser in två tal och skriver lite emellan, kräver inga variabler
   Readinp:
	;skriv
	mov ah, 09h
	lea dx, [endline]
	int 21h

	lea dx, [firstnum]
	int 21h

	;Läs första talet
	mov ah, 01h
	mov bx, num1
	@@:
	   int 21h
	   cmp al, 13 ; 13 = enter
	   je @f
	   mov byte [bx], al
	   inc bx
	jmp @B

	;Skriv igen
	@@:
	   mov ah, 09h
	   lea dx, [endline]
	   int 21h

	   lea dx, [secnum]
	   int 21h

	   mov ah, 01h
	   mov bx, num2

	;Läs andra gången
	@@:
	    int 21h
	    cmp al, 13 ; 13 = enter
	    je @f
	    mov byte [bx], al
	    inc bx
	jmp @B

	@@:
	    ret

   ;Konverteringsalgoritmer:--

   ;Konvertera num1 från ascii till äkta int
   Konvertera_till_int_num1:
	mov bx, num1
	mov cx, bx    ;cx innehåller nu antal digits inlästa
	.conv:
		sub byte [bx], 48
		inc bx
		loop .conv ; jmp if cx > 0
   ret

   ;Konvertera num2 från ascii till äkta int
   Konvertera_till_int_num2:
	mov bx, num2
	mov cx, bx    ;cx innehåller nu antal digits inlästa
	.conv:
		sub byte [bx], 48
		inc bx
		loop .conv ; jmp if cx > 0
   ret

   ;Konvertera num3 till ascii
   Konvertera_till_ascii:
	mov di, res
	mov ax, [num3]
	.conv:
		mov	cx, 0x0A  ; flytta Ah till cx
		xor	dx, dx	  ;nolla dx
		div	cx	  ;dela ax med cx, svaret i AL, resten i AH
		add	dl, 0x30   ;öka dl med 30h
		mov	byte [di], dl ;flyttar värdet av dl till byten som addressen di's address pekar på
		inc	di	;öka di med ett
		or	ax, ax	;är ax = 0?
		jnz	.conv

	mov byte [di], "$"
   ret

   ;Matematiska funktioner:--

   Addera:
	call Konvertera_till_int_num1
	call Konvertera_till_int_num2
	mov bx, [num2]
	add bx, [num1]
	mov [num3], bx

	lea dx, [endline]
	mov ah, 9h
	int 21h

	lea dx, [summa]
	int 21h

	call Konvertera_till_ascii
	mov ah, 09h
	mov dx, res
	int 21h
   ret

   ;Övrigt:--

   Unimplemented:
	mov dx, endline
	mov ah, 09h
	int 21h
	mov dx, unim
	int 21h
   ret

   Avsluta:
       mov ax, 4C00h
       int 21h
   ret

;da code
start:
	mov ah, 09h ; skriva
	lea dx, [endline]
	int 21h

	lea dx, [startup]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [lines]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [menu1]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [menu2]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [menu3]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [menu4]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [endline]
	int 21h

	lea dx, [prompt]
	int 21h

	mov ah, 01h ; nu ska vi läsa
	int 21h
	;spara svaret
	mov [choice], al

	cmp [choice], 2Bh ; 2Bh = +
	jnz @F

		call Readinp
		call Addera

	@@:
	call Unimplemented
	call Avsluta
ret

;Variabler:--

endline DB 10, "$"
startup DB "Welcome to C++arl's FASM calculator", "$"
lines DB "-----------------------------------", "$"
menu1 DB "+ : Addition", "$"
menu2 DB "- : Subtraction", "$"
menu3 DB "/ : Division", "$"
menu4 DB "* : Multiplication", "$"
prompt DB "Enter your choice: ", "$"
firstnum DB "Enter the first number: ", "$"
secnum DB "Enter the second number: ", "$"
summa DB "Summan blir: ", "$"
unim DB "That feature is not available yet. . .", "$"
num1 DW 16 dup 24h
num2 DW 16 dup 24h
num3 DW 0
choice DB 8 dup (0x24) ; fill with \0
res DB 0
