;       Aquest arxiu conté els subprogrames
;       STRINP:far, STRLON:far, INTASTR:far, STRAINT:far
;
;    Macrodefinició per a la interrupció de serveis del DOS
DosCall MACRO   Serv
        MOV     AH, Serv
        INT     21h
        ENDM
;
data    SEGMENT PARA PUBLIC 'DATA'
;   Dades per a STRINP, STRLON
Tec_CR  DB      0Dh
LonMax  DW      255
msgerr  DB      13,10,"Cadena massa llarga",13,10,"$"
;   Dades per a INTASTR, STRAINT
MIN_NUM EQU   byte PTR '0'
DIEZ    DW      10
;
data    ENDS
;
CODE    SEGMENT PARA PUBLIC 'CODE'
        PUBLIC  STRINP, STRLON, INTASTR, STRAINT
        ASSUME  CS:CODE
        ASSUME  DS:data
;
;  DEFINICIO DELS SUBPROGRAMES
;
;  STRINP       Subprograma que entra una cadena de fins a 255 caracters
;               des del teclat i hi afegeix un terminador
;               1er. paràmetre: caràcter de terminació
;               2ón. paràmetre: adreça (offset) de la cadena
;       Retorna a AX la longitud de la cadena llegida
;
STRINP  PROC    FAR
        PUSH    BP
        MOV     BP,SP
        MOV     BX,[BP+8]   ;Agafa adreça cadena
        MOV     SI,0
MOV CX,LonMax
EntCar:                     ;Entra caracters fins a <CR>
        DosCall 01h
        MOV     [BX+SI],AL
        INC     SI
        SUB     AL, Tec_CR           ;Comprovar si és el <CR>
        LOOPNZ  EntCar
        DEC     SI
        MOV     AL,BYTE PTR [BP+6]   ;Afegeix el terminador
        MOV     [BX+SI],AL
        MOV     AX,SI                ;Retorna a AX la longitud
;
        POP     BP
        RET
STRINP  ENDP
;
;  STRLON       Subprograma que retorna a AX la longitud d'una cadena
;               1er. paràmetre: caràcter de terminació de la cadena
;               2ón. paràmetre: adreça (offset) de la cadena
;
STRLON  PROC    FAR
        PUSH    BP
        MOV     BP,SP
        MOV     AX,[BP+6]      ;Agafa el terminador
        MOV     DI,[BP+8]      ;Agafa adreça cadena
        MOV     CX,LonMax
        REPNE SCASB
        JCXZ    LonExc
        INC     CX
        MOV     AX,LonMax
        SUB     AX,CX
        JMP     SL_Ret
;
LonExc:
        MOV     DX, OFFSET msgerr
        DosCall 09h
        DosCall 08h
;
SL_Ret:
        POP     BP
        RET
STRLON  ENDP

;  INTASTR      Subprograma per a convertir un nombre enter d'un byte
;               a una cadena de caracters imprimibles i hi afegeix
;               un carácter de terminació.
;               1er. paràmetre: nombre enter
;               2ón. paràmetre: caràcter de terminació
;               3er. paràmetre: adreça (offset) de la cadena
;               Retorna a AL la longitud de la cadena resultant
;
INTASTR PROC    FAR
        PUSH    BP
        MOV     BP,SP
        MOV     AX,[BP+6]    
        MOV     BX,[BP+10]   
        MOV     SI,0
base_10:
        MOV   DX,0
        DIV     DIEZ
        ADD    DL,MIN_NUM
        MOV   [BX+SI],DL
        INC      SI
        CMP    AX, DIEZ
        JNS     base_10
;
        ADD     AL,MIN_NUM
        MOV    [BX+SI],AL
        MOV    DI,0
        MOV    CX,SI
        INC      CX
        MOV    DX,CX           
        SHR     CX,1
invert:
        MOV    AL,[BYTE PTR (BX+DI)]
        MOV    AH,[BYTE PTR (BX+SI)]
        MOV   [BYTE PTR (BX+DI)],AH
        MOV   [BYTE PTR (BX+SI)],AL
        INC     DI
        DEC    SI
        LOOP   invert
;
        MOV    DI,DX            
        MOV     AL,[BP+8]
        MOV     [BYTE PTR (BX+DI)],AL
        MOV     AX,DI     
        MOV     AH,0
        POP     BP
        RET
INTASTR ENDP
;  STRAINT      Subprograma per a convertir una cadena de caracters
;               amb un cert caràcter de terminació en un nombre enter
;               1er. paràmetre: caràcter de terminació
;               2ón. paràmetre: adreça (offset) de la cadena
;               Retorna a AX el nombre enter resultant
;
STRAINT PROC    FAR
        PUSH    BP
        MOV     BP,SP
        MOV     AX,[BP+6]
        MOV     BX,[BP+8]
        PUSH    BX          ;Calcula longitud de la cadena
        PUSH    AX
        CALL    STRLON
        ADD     SP,4
        CMP     AX,0        ;Comprovar si la cadena és buida
        JE      Cad_Nula
        MOV     CX,AX       ;Inicialitza comptador
        DEC     CX
        MOV     AL,[BYTE PTR BX]  ;Inicialitza acumulador
        MOV     AH,0
        SUB     AX,MIN_NUM
        MOV     SI,1
        JCXZ    StrAInt_Ret
b10poli:
        MUL     DIEZ
        MOV     DH,0
        MOV     DL,[BYTE PTR (BX+SI)]
        SUB     DX,MIN_NUM
        ADD     AX,DX
        INC     SI
        LOOP    b10poli
;
        JMP     StrAInt_Ret
;
Cad_Nula:
        MOV     AX,0           ;Retornar 0 si la cadena és nul.la
;
StrAInt_Ret:
;
        POP     BP
        RET
STRAINT ENDP
;
CODE    ENDS
        END
