; Programma per il calcolo del fattoriale

	org 400h

	baseadd equ 1000h		;conterrā risultato longword parte meno significativa


	code		;inizia programma
	movl #6,R0
	jsr FATT
    	HALT	       ; risultato in R2


MULTIPLY:
	;subroutine per la moltiplicazione 
	;richiede moltiplicando e moltiplicatore codificati come longwords unsigned in R0 e R1
	;indirizzo di memoria per risultato in R2
	;in caso di overflow ritorna con il flag di carry settato e non aggiorna la memoria
	
	push r1
	push r3

	xorl r3,r3

loop:	cmpl #0,r1
	jz update
        addl r0,r3
	jc overflow
	subl #1,r1
	jmp loop
		
update:	movl r3,(r2)

overflow: 
	pop r3
	pop r1
	ret


FATT:
;subroutine per il calcolo del fattoriale
;richiede intero non segnato (longword) di cui calcolare il fattoriale in R0
;restituisce il fattoriale in R1. In caso di overflow: R1=0 e Carry flag settato
	push R3		; salvo R2
	push R2		; salvo R2
	cmpl #0,R0
	jnz cont;
	movl #1, R1
	clrc
	jmp exit;
cont:
	cmpl #1,R0
	jnz cont1
	clrc
	movl R0, R1
	jmp exit;
cont1:
	subl #1,R0   ; R0=i-1
	jsr fatt  
	jnc cont2
	jmp exit;
cont2:
	addl #1,R0  ; carico in R0 il moltiplicando (ovvero i), il moltiplicatore fatt(i-1) č giā in R1 
	movl #baseadd,R2			
	JSR MULTIPLY;
	jc overfl2;
	movl baseadd,R1
	jmp exit
overfl2:
	xorl r1,r1
exit:	pop r2;
	pop r3;
	ret;

	end
