
STACKADDR: word 0F000           ; beginning of stack area
STR1:      word 0E000
STR2:      word 0E100

;****************************************************************************

; LIBRARY FUNCTIONS


; GETS function: reads a line and stores the string
;                at memory address passed in R1

GETS:      LDBI R0 0A           ; void gets (char *str)
L_GETS:    INB R2 0001
           TSTI 0001     
           JMPNZ L_GETS
           STBR R2 R1    
           SUB R0 R2
           JMPZ END_GETS   
           INC R1
           JMP L_GETS
END_GETS:  LDBI R2 0
           STBR R2 R1    
           RET

; PUTS function: sends to the output device the string 
;                whose address is passed in R1

PUTS:      LDBR R2 R1           ; void puts (char *str)
           JMPZ END_PUTS
L_PUTS:    OUTB R2 0000
           TSTO 0000     
           JMPNZ L_PUTS
           INC R1
           JMP PUTS
END_PUTS:  LDBI R2 0A
LEND_PUTS: OUTB R2 0000
           TSTO 0000     
           JMPNZ LEND_PUTS
           RET

; DIV function: R0 <- R1 / R2 and  R15 <- R1 % R2 
; NOTE: only non-negative numbers are supported

DIV:       LDWI R0 0            ; int div (int a, int b)
           MV R1 R15
L_DIV:     MV R15 R3
           SUB R2 R3
           JMPN END_DIV
           SUB R2 R15
           INC R0
           JMP L_DIV
END_DIV:   RET

; WRITENUM function: writes on the output device the number 
;                    whose value is passed in R1
; NOTE: only non-negative numbers are supported

WRITENUM:  LDWI R10 1           ; void writenum (int n)
L1_WRNUM:  LDWI R11 09
           SUB R1 R11
           JMPNN L2_WRNUM
           LDWI R2 0A
           PUSH R10
           CALL DIV
           POP R10
           MV R0 R1
           PUSH R15
           INC R10
           JMP L1_WRNUM
L2_WRNUM:  LDWI R11 30
           ADD R1 R11
L3_WRNUM:  OUTB R11 0000
           TSTO 0000
           DEC R10
           JMPZ E_WRNUM
           POP R1               ; was R15, stored in the stack
           JMP L2_WRNUM
E_WRNUM:   RET

;****************************************************************************

; MAIN PROGRAM

START:     LDWA R15 STACKADDR   ; stack initialization
           SPWR R15             ; NOTE: every function receives input
                                ;       values/addresses in R1, R2, ...
                                ;       and provides output in R0

           LDWA R1 STR1
           CALL GETS

           LDWA R1 STR2
           CALL GETS

           LDWA R1 STR1
           LDWA R2 STR2
           CALL RECURSIVE_STRCMP
           MV R0 R1
           CALL WRITENUM
           HLT

;****************************************************************************


; int recursive_strcmp (char *s, char *t)
; {
;    if (*s != *t)
;       return 0;
;    else if (*s == '\0')
;       return 1;
;    else
;       return recursive_strcmp (s+1, t+1);
; }


RECURSIVE_STRCMP:  LDBR  R11 R1              
                   LDBR  R12 R2              
                   SUB R11 R12
                   JMPZ REC_CMP_L1
                   LDWI R0 0
                   RET

REC_CMP_L1:        MV  R11 R13
                   JMPNZ REC_CMP_L2
                   LDWI R0 1
                   RET

REC_CMP_L2:        INC R1
                   INC R2
                   CALL RECURSIVE_STRCMP
                   RET   ; semplicemente restituisce il valore a sua volta 
                         ; restituito dalla chiamata recursiva

