; Sample solution to Project 4
; - prompt for a loop start value and a decrement value
; - run the loop from the start down to zero (not below)
; - print a singular/plural termination message
;-------------------------------------------------------------------
P4      segment
        assume  CS:P4,DS:P4
        org     100h            ; .COM requires this
;-------------------------------------------------------------------
start:
        mov     dx,offset pstart ; prompt for loop start value
	call    outstr

        call    getnum          ; read loop start value
        jc      error           ; non-numeric?
        mov     loopst,ax       ; save the first number

        call    newline         ; output CR+LF

        mov     dx,offset pdecr ; prompt for loop decrement value
        call    outstr

        call    getnum          ; read loop decrement value
        jc      error           ; non-numeric?
        mov     loopdec,ax      ; save the second number

        call    newline         ; output CR+LF

        ; start of FOR loop
        mov     ax,loopst       ; start loop variable i=loopst
        mov     i,ax
        mov     count,0         ; counts the loop iterations
while:
        cmp     i,0             ; while ( i >= 0 )
        jl      endwhile        ; break loop when i < 0

        mov     ax,i            ; display the current loop value
        call    shownum

        mov     dx,offset space ; put out a space
        call    outstr

        mov     ax,loopdec      ; i -= loopdec
        sub     i,ax

        inc     count           ; ++count
        jmp     while
endwhile:
        call    newline         ; output CR+LF

        mov     dx,offset term1 ; print termination message first half
        call    outstr

        mov     ax,count        ; display number of iterations of loop
        call    shownum

	; output singular or plural "iteration(s)" message
	;
	cmp     count,1         ; if ( count == 1 )
	jne     plural
        mov     dx,offset term2s ; singular termination message closing half
	jmp     term
plural: 
        mov     dx,offset term2p ; plural termination message closing half
term:
        call    outstr

        ; Quit the program (return to the O/S).
        ;
        mov     al,0h           ; load a successful return status
goexit:
        mov     ah,4Ch          ; 4C means "terminate program"
        int     21h             ; DOS service routine

error:
        mov     dx,offset errmsg ; display an error message
        call    outstr

        mov     al,1h           ; load a failure non-zero return status
        jmp     goexit          ; take the regular program exit

loopst  dw      ?               ; the first number - loop start value
loopdec dw      ?               ; the second number - loop decrement value
i       dw      ?               ; loop variable
count   dw      ?               ; count of loop iterations

pstart  db      "Please enter loop start value: "
        db      "$"             ; end of ASCII$ string
pdecr   db      "Please enter loop decrement value: "
        db      "$"             ; end of ASCII$ string
term1   db      "Program done after "
        db      "$"             ; end of ASCII$ string
term2s  db      " iteration."
        db      0Dh,0Ah         ; CR, LF
        db      "$"             ; end of ASCII$ string
term2p  db      " iterations."
        db      0Dh,0Ah         ; CR, LF
        db      "$"             ; end of ASCII$ string
errmsg  db      0Dh,0Ah         ; CR, LF
        db      "This program encountered non-numeric input.  Goodbye."
        db      0Dh,0Ah         ; CR, LF
        db      "$"             ; end of ASCII$ string
crlf    db      0Dh,0Ah         ; CR, LF
        db      "$"             ; end of ASCII$ string
space   db      " "             ; SP
        db      "$"             ; end of ASCII$ string

; Outputs CR+LF
newline proc    near
        push    dx              ; save registers used
        mov     dx,offset crlf  ; put out CR+LF
        call    outstr
        pop     dx              ; restore registers
        ret
newline endp

; Output the string pointed to by DX
outstr  proc    near
        push    ax              ; save registers used
        mov     ah,09h          ; 09 means "output string at address in DX"
        int     21h
        pop     ax              ; restore registers
	ret
outstr  endp
;-------------------------------------------------------------------
        INCLUDE getshow.asm     ; a modified version of Alan's dec_io.pkg
;-------------------------------------------------------------------
P4      ends
        end start               ; "start" is the label on the first instruction

