; CIS-261
; M08demo.ASM
; @topic W080101 IO.H and IO.ASM usage demo
; @brief Lab M08, <a href="http://www.c-jump.com/bcc/c261c/MLabs/M08console/M08console.html" target="_blank">Console Input/Output</a>, range -128 to 127 validation
; 

.386                ; Tells MASM to use Intel 80386 instruction set.
.MODEL FLAT         ; Flat memory model
option casemap:none ; Treat labels as case-sensitive

INCLUDE IO.H        ; header file for input/output

.CONST              ; Constant data segment
                    ; Literal strings for communication with the user
PROMPT_FIRST_NUMBER       BYTE "Enter a number in range -128 to 127: ", 0
PROMPT_SECOND_NUMBER      BYTE "Enter another number in range 0 to 255: ", 0
PROMPT_BAD_INPUT          BYTE "** Bad input format, please retry...", 0
PROMPT_BAD_SMALL_NUMBER   BYTE "** Error: the number is too small...", 0
PROMPT_BAD_BIG_NUMBER     BYTE "** Error: the number is too big...", 0
PROMPT_BAD_SUM            BYTE "** Error: sum overflow...", 0
ENDL                      BYTE 13, 10, 0

.STACK 100h     ; (default is 1-kilobyte stack)

.DATA           ; Begin initialized data segment
    buffer      BYTE    12 DUP (?)  ; a memeory buffer for input/output
    fst_8bit    BYTE    ?           ; a memory for a byte-size variable
    snd_8bit    BYTE    ?           ; another byte-size variable

.CODE           ; Begin code segment
_main PROC      ; Beginning of code

    ;-----------------------------------------------
    ; Input first number from the user
    ;-----------------------------------------------
enter_first_number:
@@:
    output PROMPT_FIRST_NUMBER  ; prompt the user
    input  buffer, 6            ; input first integer
    atod   buffer               ; convert to number, result in EAX
    jno    @F                   ; if no bad format detected, go on
    output PROMPT_BAD_INPUT     ; display error message
    output ENDL                 ; print new line
    jmp    @B                   ; let them retry
@@:
    ; This is a validation code that works with signed numbers
    ;-----------------------------------------------
    ; check if the number is in range -128 to 127
    ;-----------------------------------------------
    cmp    EAX, -128                  ; if EAX < -128 then bad input
    jge    @F                         ; continue if not
    output PROMPT_BAD_SMALL_NUMBER    ; display error message
    output ENDL                       ; print new line
    jmp    enter_first_number         ; let them retry
@@:
    cmp   EAX, 127                    ; if EAX > 127 then bad input
    jle   @F                          ; continue if not
    output PROMPT_BAD_BIG_NUMBER      ; display error message
    output ENDL                       ; print new line
    jmp    enter_first_number         ; let them retry
@@:
    ;-----------------------------------------------
    ; First 8-bit number is okay
    ;-----------------------------------------------
    mov [fst_8bit], AL                ; store value in memory

    ;-----------------------------------------------
    ; Input another number from the user
    ;-----------------------------------------------
@@:
    output PROMPT_SECOND_NUMBER ; prompt the user
    input  buffer, 6            ; input another integer
    atod   buffer               ; convert to number, result in EAX
    jno    @F                   ; if no bad format detected, go on
    output PROMPT_BAD_INPUT     ; display error message
    output ENDL                 ; print new line
    jmp    @B                   ; let them retry
@@:
    and    EAX, 000000FFh       ; zero out everything except AL
    mov    [snd_8bit], AL       ; store second number in memory
    add    AL, [fst_8bit]       ; compute the sum

    ; NOTE:
    ; if adding signed numbers, the Overflow is indicated by OF
    ; if adding unsigned numbers, the Overflow is indicated by CF
    
    jnc    @F                   ; if no overflow adding unsigned, go on
    output PROMPT_BAD_SUM       ; display error message
    output ENDL                 ; print new line
    jmp    enter_first_number   ; let them retry

@@:
    ; Display the sum
    dtoa buffer, EAX            ; convert EAX to text
    output buffer               ; diplay text
    output ENDL                 ; print new line

    ret                         ; exit program
    
_main ENDP
END _main        ; Marks the end of the module and sets the program entry point label
