; Sept. 16, 1997: 
; No operation is performed.  
;*****************************************************************************
TITLE         MAIN PROGRAM TEMPLATE
	      PAGE           57,80
;-----------------------------------------------------------------------------
; AUTHOR: M.S. ALAM
; Revised: Dec 17, 1996
;    This the main program template.  This demonstrates how two 16 bit 
; decimal numbers can be entered from the keyboard and saved at 
; INPUT1 and INPUT2 in the data segment. The program also shows how 16-bit 
; data stored as hexadecimal in the datasegment can be displayed 
; on the monitor.
;    Then the program shows how to setup calls for addition, subtraction, 
; multiplication and division.  A menu is presented but no operation is 
; is performed
;-----------------------------------------------------------------------------
; PARAMETER PASSING FOR THE CONVERSION PROGRAMS
; DECIN16  --> Converted binary number availabe in DX
; DECIN32  --> ................................... DX
; DECOUT16  <-- Output1 offset is passed to it with LEA SI,OUTPUT1
; DECOUT32  <-- Output1 offset is passed to it with LEA SI,OUTPUT1
;               Note only the beginning location offset needs to be passed.
;               It expects to read two words starting at this location.
; DECOUT64  <-- Output1 offset is passed to it with LEA SI, OUTPUT1.
;               It expects to read 4 words starting at this location.
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Here are some binary multiplication examples that can be used to test the
; program:
; FFFFh x 10h = FFFF0h, FFFFh x 100h = FFFF00h, FFFFh x 1000h = FFFF000h 
; FFFFh x  Fh = EFFF1h, FFFFh x  FFh = FEFF01h, FFFFh x  FFFh = FFEF001h
; FFFFh x  FFFFh = FFFE0001
; FFFF0h/FFFFh = 10h
; FEFF01h/FFh  = FFFFh
;*****************************************************************************
	     ;Include Macros for reading from the keyboard and outputing
	     ;to the video monitor
	     IF1
		  INCLUDE \PHY353\MACLIB\STRING.MAC                         
	     ENDIF
;******************************************************************************

SSEG          SEGMENT        PARA STACK  'STACK' ; Start of Stack Segment
	      DB             64 DUP('STACK')     ; Reserve 64 bytes
SSEG          ENDS                               ; End of Stack Segment

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

DSEG          SEGMENT        PARA PUBLIC 'DATA'  ; Start of data segment

INTMSG        DB '********************************************',0DH,0AH
	      DB '.........16-bit Calculator Program..........',0DH,0AH
	      DB '********************************************',0DH,0AH
	      DB 0DH,0AH,'$'
MENUMSG       DB 0DH,0AH,' Choose: + - * / <cr> for add, sub, mul,'
	      DB 'div or all....  ','$'
	      ;DB 0DH,0AH,'$'
CONFIRM       DB '                             Number inputted is =','$'
	      DB 0DH,0AH,'$'
ADDMSG        DB '            You have selected addition', '$'
SUBMSG        DB '            You have selected subtraction', '$'
MULMSG        DB '            You have selected multiplication', '$'
DIVMSG        DB '            You have selected division', '$'
ALLMSG        DB ' You have selected all four',0DH,0AH, '$'
QMSG          DB 'Type q/Q for quit or <cr>',0DH,0AH,'$' 

QINP          DB 2,2 DUP(?)
MENUINP       DB 2,2 DUP(?)

	      ; This declaration allows these variables to be accessed by
	      ; any procedure call
	      PUBLIC INPUT1,INPUT2,DIFF,SUM,PRODL,PRODH,QUOT,REM
MARKER        DB 'INPUT DATA INPUT DATA INPUT DATA FOLLOWS','$'
INPUT1        DW             0257              ; Store multiplier 101H
INPUT2        DW             0255              ; Store multiplicand FFH
DIFF          DW             02                ; Difference stored here 02h
SUM           DW             0512              ; Sum stored here  200h
PRODL         DW             065535            ; Low word of product FFFFh
PRODH         DW             00000H            ; High word of product
QUOT          DW             01                ; Quotient stored here 01h
REM           DW             02                ; Remainder stored here 02h

DSEG          ENDS                             ; End of data segment
	       
;*****************************************************************************

CSEG          SEGMENT        PARA PUBLIC 'CODE'  ; Start of Code Segment
	      ASSUME         CS:CSEG, DS:DSEG, SS:SSEG
	      ;
	      ; This decleration defines these as external procdures supplied
	      ; as seprate OBJ modules or as a library
	      EXTRN  DECIN16:NEAR,DECOUT16:NEAR,DECOUT32:NEAR
;              EXTRN  ADD16:NEAR,SUB16:NEAR,MUL16:NEAR,DIV16:NEAR
	      ;
MAIN          PROC           FAR
;             Set up the Stack  with proper values to return to DOS or DEBUG
	      DOS_RET_SETUP   
;             Initialize data segment
	      INIT_DATA_SEG DSEG
	      DISP_STRING INTMSG
;----------------------------------------------------------------------------
;             Here we read in the first ASCII decimal from the keyboard, which
;             is less than 65535 and has a maximum of 5 digits. The ASCII
;             decimal is converted into a binary number stored in REG DX
;
AGAIN:        
	      ; Get multiplier from keyboard
GET1:         CALL DECIN16        ; Get first 16-bit ASCII decimal
	      JNC STORE1          ; CF=0, good number
	      JMP GET1            ; CF=1, go back and try again
STORE1:       MOV INPUT1,DX       ; Store in memory at location MPLIER
	      DO_CR_LF
       
	      ; Get multiplicand from keyboard                       
GET2:         CALL DECIN16        ; Get second 16-bit ASCII decimal
	      JNC STORE2          ; CF=0, good number
	      JMP GET2            ; CF=1, go back and try again
STORE2:       MOV INPUT2,DX       ; Store in memory at location MCAND
	      DO_CR_LF
	      ;----------------------------------------------------------
	      ; Confirm both inputs by falshing the stored values

	      DISP_STRING CONFIRM ; Confirm value of number inputed
	      LEA SI,INPUT1
	      CALL DECOUT16       ; Print out number just input
	      DISP_STRING CONFIRM ; Confirm value of number inputed
	      LEA SI,INPUT2
	      CALL DECOUT16       ; Print out number just input
	      DO_CR_LF
	      ;----------------------------------------------------------
	      ; Start checking menu selected
	      DISP_STRING MENUMSG ; Display menu choices
	      READ_STRING MENUINP ; Store the operator input choice
	      DO_CR_LF
	      DO_CR_LF

CHKADD:       CMP MENUINP+2,'+'   ; 02BH is ascii code for +
	      JNE CHKSUB
	      JMP DOADD
CHKSUB:       CMP MENUINP+2,'-'   ; 02DH is ascii code for -
	      JNE CHKMUL
	      JMP DOSUB
CHKMUL:       CMP MENUINP+2,'*'   ; 02AH is ascii code for *
	      JNE CHKDIV
	      JMP DOMUL
CHKDIV:       CMP MENUINP+2,'/'   ; 02F is the ascii code for /
	      JNE CHKALL
	      JMP DODIV
CHKALL:       CMP MENUINP+2,0DH   ; 0DH is ascii code for <cr>
	      JNE NXTOP           ; Not selected
	      JMP DOALL           ; Do all operations
NXTOP:        JMP NXTREQ

DOALL:        ;Come here to perform all operations
	      DISP_STRING ALLMSG
	      ;---------------------------------------------------------
	      ; Note a conditional jump using JC or JNC for example has
	      ; limited range (128 bytes) so I have used both JMP and JNC
	      ; to avoid this problem.
	      ;---------------------------------------------------------
DOADD:        ;Come here to add
	      DISP_STRING ADDMSG
	      DO_CR_LF            ; Do CR-LF for next request
	      CMP MENUINP+2,0DH   ; For all operations, go to next op           
	      JE DOSUB            ;
	      JMP NXTREQ
	      ;---------------------------------------------------------
DOSUB:        ;Come here to subtract
	      DISP_STRING SUBMSG
	      DO_CR_LF            ; Do CR-LF for next request
	      CMP MENUINP+2,0DH   ; For all operations, go to next op           
	      JE DOMUL            ;
	      JMP NXTREQ
	      ;---------------------------------------------------------
DOMUL:        ;Come here to multiply
	      DISP_STRING DIVMSG
	      DO_CR_LF            ; Do CR-LF for next request
	      CMP MENUINP+2,0DH   ; For all operations, go to next op           
	      JE DODIV            ; For all operations, go to next op
	      JMP NXTREQ
	      ;---------------------------------------------------------
DODIV:        ;Come here to divide
	      DISP_STRING DIVMSG
	      DO_CR_LF            ; Do CR-LF for next request
	      JMP NXTREQ
	      ;---------------------------------------------------------
NXTREQ:       ;Ask whether we want to try any pair of numbers or quit
	      DISP_STRING QMSG         ;; Do you want to quit
	      READ_STRING QINP         ;; y = Quit n = TRY AGAIN
	      CMP QINP+2,71H           ;; ASCII Code for q = 79H
	      JE  QUIT
	      CMP QINP+2,51h           ;; ASCII Code for Q = 59H
	      JE  QUIT
	      JMP AGAIN                ;; Go back and request new numbers
QUIT:         RET
MAIN          ENDP
CSEG          ENDS
	      END            MAIN
;************************************************************************      

