;===========================================================
; File:    SelfModify.asm
; Purpose: Using self-modifying code in assembly language
;===========================================================

include 'emu8086.inc'

        org  100h ; set location counter to 100h

        jmp  CodeStart

DataStart:

prompt  db   13, 10, "Number> ", 0 
newline db   13, 10, 0
rsltMsg db   13, 10, "Result: ", 0
opnMsg  db   13, 10,"Type 1 for add, 2 for sub> ", 0
fini    db   13, 10, 13, 10, "Fini", 13, 10, 0
numA    dw   ?
numB    dw   ?
result  dw   ?

AddOpn  dw   0c303h               ; add  ax, bx
SubOpn  dw   0c32bh               ; sub  ax, bx

CodeStart:
        mov  si, offset prompt
        call print_string
        call scan_num             ; get next number
        cmp  cx, 0
        je   EndProg              ; zero indicates quit
        mov  numA, cx

        mov  si, offset prompt    ; prompt for number
        call print_string
        call scan_num             ; get next number
        cmp  cx, 0
        je   EndProg              ; zero indicates quit
        mov  numB, cx
        
OpnPrompt:
        mov  si, offset opnMsg    ; prompt for operation
        call print_string 
        call scan_num             ; get the operation
        cmp  cx, 1
        je   DoAdd
        cmp  cx, 2
        jne  OpnPrompt

DoSub:
        mov  ax, SubOpn           ; copy subtract to Opn
        mov  Opn, ax
        jmp  Doit
       
DoAdd:  
        mov  ax, AddOpn           ; copy add to Opn
        mov  Opn, ax

Doit:
        mov  ax, numA             ; load A
        mov  bx, numB             ; load B
Opn:    dw   0                    ; calculate A +/- B
        mov  result, ax           ; save the result
       
        mov  si, offset rsltMsg   ; display "Result: "
        call print_string

        mov  ax, result           ; display the result
        call print_num
       
        mov  si, offset newline   ; issue newline
        call print_string
       
        jmp  CodeStart            ; go back for more
                     
EndProg:
        mov  si, offset fini      ; display "Fini"
        call print_string

        ret                       ; return to caller

DEFINE_PRINT_STRING
DEFINE_SCAN_NUM
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS
