;*****************************************************************************
TITLE         MAIN PROGRAM TEMPLATE
              PAGE           57,80
;-----------------------------------------------------------------------------
; AUTHOR: M.S. ALAM
; Revised: Dec 16, 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 
; and 32-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 and the operation is 
; performed according to the menu.  
;-----------------------------------------------------------------------------
; 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: + - * / for add, sub, mul and div: ','$'
              ;DB 0DH,0AH,'$'
CONFIRM       DB '                             Number inputted is =','$'
              DB 0DH,0AH,'$'
DIFFMSG       DB '                             The differenc is   =','$'
NOOPMSG       DB 'Operation not valid. Try again',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
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

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
              CALL DECIN16        ; Get first 16-bit ASCII decimal
              MOV INPUT1,DX       ; Store in memory at location MPLIER
              DO_CR_LF
       
              ; Get multiplicand from keyboard                       
              CALL DECIN16        ; Get second 16-bit ASCII decimal
              MOV INPUT2,DX       ; Store in memory at location MCAND
              DO_CR_LF
              ;----------------------------------------------------------
              DISP_STRING MENUMSG
              READ_STRING MENUINP
              DO_CR_LF
              DO_CR_LF

              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

CHKSUB:       CMP MENUINP+2,'-'   ; 02DH is ascii code for -
              JNE NXTOP
              JMP DOSUB
NXTOP:        JMP NXTREQ
              ;---------------------------------------------------------
              ; 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.
              ;---------------------------------------------------------
DOSUB:        ;The difference of the two words is located at  
              ;DIFF from where we can read them at display
              ;them on the screen
	      CALL SUB16
              JNC DIFFM           ; Subtract is valid
              JMP NOOP            ; A borrow was necessary
DIFFM:        DISP_STRING DIFFMSG ; Display DIFF message
              LEA SI,DIFF
              CALL DECOUT16       ; Convert difference to ASCII and flash
              DO_CR_LF            ; Do CR-LF for next request
              JMP NXTREQ

NOOP:         DISP_STRING NOOPMSG
              ;---------------------------------------------------------
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
;************************************************************************      

