;=======================================================
; File:    PrimeTest.asm
; Purpose: Repeatedly see if a number entered by the
;          user is a prime. Stop when zero is entered.
;          Show how to call a PROC.
;=======================================================

include 'emu8086.inc'

       org  100h ; set location counter to 100h

       jmp  CodeStart

DataStart:

prompt    db   13, 10, "Enter a number> ", 0
prime     db   "That number is a prime", 13, 10, 0
composite db   "That number is composite", 13, 10, 0
endMsg:   db   13, 10, "End of Prime Test", 13, 10, 0
newline   db   13, 10, 0
num       dw   ?

CodeStart:
       mov  si, offset prompt    ; prompt for a number
       call print_string

       call scan_num             ; read the number
       mov  num, cx

       mov  si, offset newline   ; issue a newline
       call print_string

       cmp  cx, 0                ; check for <= 0
       jle  EndProg

       mov  bx, num              ; call IsPrime to determine
       call IsPrime              ; if this number is prime

       cmp  dx, 0                ; check dx - returned by IsPrime
       jne  IsPrimeNum

       mov  si, offset composite ; the number was composite
       call print_string
       jmp  CodeStart            ; go back for more...

IsPrimeNum:                      ; the number was prime
       mov  si, offset prime
       call print_string
       jmp  CodeStart            ; go back for more

EndProg:                         ; issue final message
       mov  si, offset endMsg
       call print_string
       ret                       ; return to caller


; ---------------------------------------------------------------------
; this is EXACTLY the code from Week 4's iLab

IsPrime PROC
       ; uses a loop to determine if number in bx is prime
       ; upon return if bx not prime dx will be 0, otherwise dx > 0

       ; we only have to test divisors from 2 to bx/2
       
       ; prepare to divide dx:ax / 2         
       mov ax, bx
       mov dx, 0 
       mov cx, 2  
       div cx
       
       ; move result into si for loop
       mov si, ax
       
       ; assume the value is prime
       mov dx, 1
       
       ; start loop at 2
       mov cx, 2
       
       PrimeLoop:
       
           ; compare loop count(in cx) and max loop value (in si)
           cmp cx, si
           
           ; jump out of loop if count(cx) > si
           ja StopLabel
       
           ; divide test value (in bx) by loop count (in cx)
           mov ax, bx
           mov dx, 0            
           div cx
           
           ; check remainder (in dx), if zero then we found a divisor
           ; and the number cannot be prime
           cmp dx, 0
           
           ; if dx = 0 then we found a divisor and can stop looking
           je StopLabel
           
           ; increment count
           add cx, 1
       
        jmp PrimeLoop
       
      StopLabel:
       
        ret
IsPrime ENDP
   
DEFINE_PRINT_STRING
DEFINE_SCAN_NUM
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS
