;
; Program: MU3
; Author: Richard Conn
; Version: 1.0
; Date: 30 June 84
; Previous Versions: None
;
vers    equ     10
z3env   equ     0f400h

;
;       MU3 is the ZCPR3 Memory Utility.  It allows the user to display
; blocks of memory, edit them, and perform general memory-oriented
; manipulation.  See the file MU3.HLP for usage details.
;

;
;  General Equates
;
bs      equ     08h
cr      equ     0dh
lf      equ     0ah
fcb     equ     5ch
dim     equ     1       ;goto standout mode
bright  equ     2       ;exit standout mode
EOLCH   EQU     0       ;END OF LINE CHAR
SEPCH   EQU     ','     ;SEPARATOR CHAR
EROW    EQU     6       ;FIRST ROW OF EDITOR DISPLAY
ECOL    EQU     4       ;FIRST COL OF EDITOR DISPLAY
ECOLC   EQU     ECOL+16*3+8     ;FIRST COL OF EDITOR CHAR DISPLAY
ECURS   EQU     '>'     ;EDITOR CURSOR
PRROW   EQU     22      ;PROMPT ROW
PRCOL   EQU     10      ;PROMPT COLUMN
PRCOLI  EQU     PRCOL+15        ;PROMPT INPUT COL
ERROW   EQU     23      ;ERROR MESSAGE ROW
ERCOL   EQU     15      ;ERROR MESSAGE COLUMN

;
;  SYSLIB/Z3LIB/VLIB Externals
;
       ext     z3vinit,envptr,codend,putcl
       ext     cls,gotoxy,ereol,at,vprint,stndout
       ext     cout,crlf,cin,caps
       ext     bline,sksp
       ext     phl4hc,pa2hc,phlfdc

;
; Environment Definition
;
       if      z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
       jmp     start
       db      'Z3ENV' ;This is a ZCPR3 Utility
       db      1       ;External Environment Descriptor
z3eadr:
       dw      z3env
start:
       lhld    z3eadr  ;pt to ZCPR3 environment
;
       else
;
; Internal ZCPR3 Environment Descriptor
;
       MACLIB  Z3BASE.LIB
       MACLIB  SYSENV.LIB
z3eadr:
       jmp     start
       SYSENV
start:
       lxi     h,z3eadr        ;pt to ZCPR3 environment
       endif

;
; Start of Program -- Initialize ZCPR3 Environment
;
       call    z3vinit ;initialize the ZCPR3 Env and the VLIB Env
;
; DEFINE FREE SPACE
;
       CALL    CODEND  ;DETERMINE ADDRESS
       MVI     M,126   ;126 CHARS INPUT ALLOWED
       SHLD    BUFFER  ;SET PTR
;
; SET UP ARROW KEYS
;
       LHLD    ENVPTR  ;PT TO ENVIRONMENT DESCRIPTOR
       LXI     D,80H+10H       ;PT TO ARROW KEY INFO
       DAD     D
       LXI     D,EDCURT        ;PT TO CURSOR TABLE
       MVI     B,4     ;4 ARROW KEYS
ARROW:
       MOV     A,M     ;GET CHAR
       STAX    D       ;STORE CHAR
       INX     H       ;PT TO NEXT
       INX     D       ;PT TO NEXT ENTRY
       INX     D
       INX     D
       DCR     B       ;COUNT DOWN
       JNZ     ARROW
;
; Check for Command Line Parameter
;
       lxi     h,fcb+1 ;pt to first char
       mov     a,m     ;get char
       cpi     ' '     ;no param?
       jnz     pcheck
       lhld    envptr  ;pt to environment descriptor
       jmp     mu3
;
; We have a parameter
;
pcheck:
       cpi     '/'     ;help?
       jz      help
       call    hexin   ;convert to binary
       xchg            ;HL=value
       jmp     mu3
;
; Print help message
;
help:
       call    vprint
       db      cr,lf,'Syntax:'
       db      cr,lf,'  MU3            <-- Invoke MU3 at Env Desc'
       db      cr,lf,'  MU3 <hex adr>  <-- Invoke MU3 at Address'
       db      0
       ret
;
; Erase to EOL
;  If fct not supported, send out B spaces and B backspaces
;
vereol:
       call    ereol   ;try erase
       rnz
       push    b       ;save B
       mvi     a,' '   ;send spaces
       call    vereol1
       pop     b       ;get B
       mvi     a,bs    ;send backspaces
vereol1:
       call    cout    ;send char in A
       dcr     b
       jnz     vereol1
       ret
;
; Clear Screen
;  If fct not supported, write 24 CRLFs
;
vcls:
       call    cls     ;try clear
       rnz
       push    b       ;save B
       mvi     b,24    ;count
vcls1:
       call    crlf
       dcr     b
       jnz     vcls1
       pop     b
       ret
;
; Run MU3
;       HL contains starting address
;
mu3:
       SHLD    BLOCK   ;SAVE PTR TO BLOCK
;
; REFRESH EDIT SCREEN
;
EDIT0:
       CALL    VCLS    ;NEW SCREEN
       CALL    AT
       DB      2,26    ;ROW 2, COL 26
       CALL    VPRINT  ;BANNER
       DB      'MU3 Memory Editor, Version '
       DB      (VERS/10)+'0','.',(VERS MOD 10)+'0'
       DB      0
       CALL    AT      ;POSITION FOR VALUE TEXT
       DB      3,67
       CALL    VPRINT
       DB      DIM,'Value',BRIGHT,0
       MVI     H,EROW+9        ;POSITION FOR COMMAND DISPLAY
       MVI     L,1
       CALL    GOTOXY  ;POSITION CURSOR
       CALL    VPRINT  ;PRINT COMMAND SUMMARY
       DB      ' -- Movement --'
       DB      '  -------------- Operation ---------------',CR,LF
       DB      '      ^E          '
       DB      'A',DIM,' Enter Address     ',BRIGHT
       DB      '      +',DIM,' Next Block',BRIGHT,CR,LF
       DB      '       ^          '
       DB      'H',DIM,' Hex Calculator    ',BRIGHT
       DB      '      -',DIM,' Last Block',BRIGHT,CR,LF
       DB      '  ^S <-+-> ^D     '
       DB      'N',DIM,' Enter Hex Numbers ',BRIGHT
       DB      '     ^R',DIM,' Replot Screen',BRIGHT,CR,LF
       DB      '       v          '
       DB      'T',DIM,' Enter Text        ',BRIGHT
       DB      '     ^C',DIM,' Exit MU3',BRIGHT,CR,LF
       DB      '      ^X          '
       DB      'C',DIM,' Enter Command Line',BRIGHT
       DB      0
;
; REENTER MU3 WITH PTRS RESET
;
MU3R:
       XRA     A       ;A=0
       STA     EINDEX  ;SET INDEX TO 0 (FIRST ELEMENT)
       STA     EDERR   ;SET NO PREVIOUS ERROR
       CALL    EDPLOT  ;PLOT BUFFER DATA
;
; INPUT EDITOR COMMAND
;
EDITCMD:
       CALL    EDERCL  ;CLEAR EDITOR INVALID COMMAND MESSAGE
EDITCMD1:
       CALL    PRMSG   ;POSITION AT PROMPT MESSAGE
       DB      DIM,'MU3 Command?',BRIGHT,0
       CALL    PRINP   ;POSITION AT PROMPT INPUT
       DB      0
       CALL    CIN     ;GET CHAR
       CALL    CAPS    ;CAPITALIZE
       MOV     B,A     ;COMMAND IN B
       LXI     H,EDCURT        ;PROCESS CURSOR COMMANDS FIRST
       CALL    CMD     ;PROCESS COMMAND
       LXI     H,ECMDTBL       ;EDITOR COMMAND TABLE
       CALL    CMD     ;PROCESS COMMAND
       MVI     A,0FFH  ;SET ERROR FLAG
       STA     EDERR
       CALL    ERMSG   ;ERROR MESSAGE
       DB      'Invalid Command',0
       JMP     EDITCMD1
;
; Position at Prompt Message and Print it
;
PRMSG:
       CALL    AT      ;POSITION
       DB      PRROW,PRCOL
       JMP     VPRINT  ;PRINT IT
;
; Position at Prompt Input and Print Prompt
;
PRINP:
       CALL    AT      ;POSITION
       DB      PRROW,PRCOLI
       JMP     VPRINT  ;PRINT IT
;
; Position at Error Message and Print It
;
ERMSG:
       CALL    AT      ;POSITION
       DB      ERROW,ERCOL
       JMP     VPRINT  ;PRINT IT
;
;INPUT ERROR
;
WHAT:
       MVI     A,0FFH  ;SET ERROR FLAG
       STA     EDERR
       CALL    ERMSG
       DB      'Value Error',0
       JMP     EDITCMD1
;
;Command Table Search and Execute
;
CMD:
       MOV     A,M     ;CHECK FOR END OF TABLE
       ORA     A
       RZ              ;COMMAND NOT FOUND
       CMP     B       ;MATCH?
       JZ      CMDRUN
       INX     H       ;SKIP TO NEXT ENTRY IN TABLE
       INX     H
       INX     H
       JMP     CMD
;
;RUN COMMAND
;
CMDRUN:
       INX     H       ;PT TO LOW ADDRESS
       MOV     E,M
       INX     H       ;PT TO HIGH ADDRESS
       MOV     D,M
       XCHG
       POP     PSW     ;CLEAR STACK
       PCHL            ;RUN ROUTINE
;
;PLOT BUFFER DATA
;
EDPLOT:
       MVI     H,EROW-1        ;SET ROW
       MVI     L,ECOL  ;SET COLUMN
       CALL    GOTOXY  ;POSITION CURSOR
       CALL    VPRINT
       DB      DIM
       DB      '       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F'
       DB      BRIGHT,0
       INR     H       ;NEXT ROW
       CALL    GOTOXY  ;POSITION CURSOR
       XCHG            ;POSITION IN DE
       LHLD    BLOCK   ;PT TO DATA
       MVI     B,8     ;8 LINES
;
;Print Next Line on Screen
;
EDIT00:
       CALL    STNDOUT ;GO DIM
       MOV     A,H     ;OUTPUT ADDRESS
       CALL    PA2HC
       MOV     A,L
       CALL    PA2HC
       CALL    VPRINT
       DB      ':',BRIGHT,' ',0
       MVI     C,16    ;16 ELEMENTS
EDIT01:
       MOV     A,M     ;GET BYTE
       CALL    PA2HC   ;PRINT AS HEX
       CALL    SPACE   ;PRINT 1 SPACE
       INX     H       ;PT TO NEXT
       DCR     C       ;COUNT DOWN
       JNZ     EDIT01
       XCHG            ;POSITION AGAIN
       INR     H       ;NEXT ROW
       CALL    GOTOXY
       XCHG
       DCR     B       ;COUNT DOWN
       JNZ     EDIT00
       MVI     H,EROW  ;RESET ROW
       MVI     L,ECOLC ;RESET COL
       CALL    GOTOXY  ;POSITION CURSOR
       XCHG            ;POSITION IN DE
       LHLD    BLOCK   ;PT TO DATA
       MVI     B,8     ;8 LINES
EDIT02:
       CALL    BAR     ;PRINT BAR
       MVI     C,16    ;16 ELEMENTS
EDIT03:
       MOV     A,M     ;GET BYTE
       ANI     7FH     ;MASK MSB
       CPI     7FH     ;DON'T PRINT 7FH
       JZ      EDIT7F
       CPI     ' '     ;SPACE OR MORE?
       JNC     EDIT04
EDIT7F:
       MVI     A,'.'   ;PRINT DOT
EDIT04:
       CALL    COUT    ;PRINT BYTE
       INX     H       ;PT TO NEXT
       DCR     C       ;COUNT DOWN
       JNZ     EDIT03
       CALL    BAR     ;PRINT ENDING BAR
       XCHG            ;POSITION AGAIN
       INR     H       ;NEXT ROW
       CALL    GOTOXY
       XCHG
       DCR     B       ;COUNT DOWN
       JNZ     EDIT02
       CALL    EDCUR   ;POSITION CURSOR
       RET
;
;EDITOR COMMAND TABLE
;
ECMDTBL:
       DB      CR      ;NOP
       DW      EDITCMD
       DB      'C'-'@' ;^C = EXIT MU3
       DW      EDCC
       DB      'R'-'@' ;^R = REFRESH
       DW      EDIT0
       DB      'E'-'@' ;^E=UP
       DW      EDUP
       DB      'X'-'@' ;^X=DOWN
       DW      EDDOWN
       DB      'D'-'@' ;^D=RIGHT
       DW      EDRIGHT
       DB      'S'-'@' ;^S=LEFT
       DW      EDLEFT
       DB      ' '     ;NOP
       DW      EDITCMD
       DB      '+'     ;ADVANCE
       DW      EDITPLUS
       DB      '-'     ;BACKUP
       DW      EDITMINUS
       DB      'A'     ;ADDRESS
       DW      EDITADR
       DB      'C'     ;COMMAND LINE
       DW      EDITCL
       DB      'H'     ;HEX CALC
       DW      EDITCALC
       DB      'N'     ;CHANGE NUMBERS
       DW      EDITHEX
       DB      'T'     ;CHANGE TEXT
       DW      EDITALP
       DB      0       ;END OF TABLE
;
;  ARROW KEY DEFINITONS FROM TCAP
;
EDCURT:
       DB      0       ;0 INDICATES NO ARROW KEYS
       DW      EDUP
       DB      0
       DW      EDDOWN
       DB      0
       DW      EDRIGHT
       DB      0
       DW      EDLEFT
       DB      0       ;END OF TABLE
;
;Enter Command Line
;
EDITCL:
       CALL    EDERCL  ;CLEAR ERROR LINE
       CALL    CRLF    ;NEW LINE
       CALL    VPRINT  ;PROMPT INPUT
       DB      DIM,'Command Line? ',BRIGHT,0
       CALL    RDBUF   ;INPUT TEXT
       CALL    PUTCL   ;STORE COMMAND LINE
       JMP     CRLF    ;NEW LINE
;
;Enter ASCII Chars
;
EDITALP:
       CALL    EDERCL  ;CLEAR ERROR LINE
       CALL    PRINP   ;PROMPT INPUT
       DB      DIM,'Enter Text (<hh> for Hex)',BRIGHT
       DB      CR,LF,' --> ',0
       CALL    RDBUF   ;INPUT TEXT WITHOUT PROMPT
       CALL    EDPRCL  ;CLEAR PROMPT LINE
       LDA     EINDEX  ;PT TO POSITION
       XCHG
       LHLD    BLOCK   ;COMPUTE OFFSET
       XCHG
       ADD     E
       MOV     E,A
       MOV     A,D
       ACI     0
       MOV     D,A     ;DE PTS TO BYTE, HL PTS TO TEXT
EDITA1:
       MOV     A,M     ;GET CHAR
       CPI     EOLCH   ;EOL?
       JZ      EDITA2  ;REFRESH SCREEN
       CALL    GETVAL  ;GET ASCII OR <HEX> VALUE
       STAX    D       ;UPDATE BYTE
       INX     H       ;PT TO NEXT INPUT CHAR
       INR     E       ;PT TO NEXT BUFFER BYTE
       JNZ     EDITA1
EDITA2:
       CALL    EDPLOT  ;REPLOT
       JMP     EDITCMD1        ;DONE-REFRESH SCREEN
;
;Calculate Sum and Differences
;
EDITCALC:
       CALL    EDERCL  ;CLEAR ERROR LINE
       CALL    PRINP   ;PROMPT INPUT
       DB      DIM,'Enter Two Hex Numbers - ',BRIGHT,0
       CALL    RDBUF   ;INPUT TEXT
       CALL    EDPRCL  ;CLEAR PROMPT LINE
       CALL    SKSP    ;SKIP TO NON-SPACE
       MOV     A,M     ;ANY INPUT?
       ORA     A       ;0=NO
       JZ      EDITCMD1
       CALL    HEXIN   ;EVALUATE FIRST NUMBER
       CALL    SKSP    ;SKIP TO 2ND NUMBER
       PUSH    D       ;SAVE FIRST NUMBER
       CALL    HEXIN   ;EVALUATE 2ND NUMBER
       POP     H       ;GET FIRST NUMBER
       CALL    ERMSG   ;PRINT ERROR MESSAGE
       DB      0
       CALL    PHL4HC  ;PRINT FIRST NUMBER
       CALL    VPRINT
       DB      DIM,' and ',BRIGHT,0
       XCHG
       CALL    PHL4HC  ;PRINT 2ND NUMBER
       XCHG
       CALL    VPRINT
       DB      '    ',DIM,'Sum = ',BRIGHT,0
       PUSH    H
       DAD     D
       CALL    NUMOUT
       POP     H
       CALL    VPRINT
       DB      '  ',DIM,'Diff = ',BRIGHT,0
       MOV     A,L     ;HL=HL-DE
       SUB     E
       MOV     L,A
       MOV     A,H
       SBB     D
       MOV     H,A
       CALL    NUMOUT
       JMP     EDITCMD1
;
;Output number in HL in Hex and Decimal
;
NUMOUT:
       CALL    PHL4HC  ;HEX
       CALL    VPRINT
       DB      ' (',0
       CALL    PHLFDC  ;DECIMAL FLOATING
       MVI     A,')'   ;CLOSE PAREN
       JMP     COUT
;
;Enter Numbers
;
EDITHEX:
       CALL    EDERCL  ;CLEAR ERROR LINE
       CALL    PRINP   ;PROMPT INPUT
       DB      DIM,'Enter Hex Numbers (#nn for Dec)'
       DB      BRIGHT
       DB      CR,LF,' --> ',0
       CALL    RDBUF   ;INPUT TEXT WITHOUT PROMPT
       CALL    EDPRCL  ;CLEAR PROMPT LINE
       LDA     EINDEX  ;PT TO POSITION
       XCHG
       LHLD    BLOCK   ;COMPUTE OFFSET
       XCHG
       ADD     E
       MOV     E,A
       MOV     A,D
       ACI     0
       MOV     D,A     ;DE PTS TO BYTE, HL PTS TO TEXT
EDITH1:
       MOV     A,M     ;GET HEX DIGIT
       CPI     EOLCH   ;EOL?
       JZ      EDITA2  ;REFRESH SCREEN
       CPI     ' '     ;SKIP SPACES
       JNZ     EDITH2
       INX     H       ;SKIP SPACE
       JMP     EDITH1
EDITH2:
       PUSH    D       ;SAVE PTR
       CALL    HEXIN   ;GET VALUE AND POSITION HL
       MOV     A,E     ;... IN A
       POP     D       ;GET PTR
       STAX    D       ;PUT BYTE
       INR     E       ;ADVANCE TO NEXT BYTE
       JNZ     EDITH1
       JMP     EDITA2  ;DONE-REFRESH
;
;Clear Editor Invalid Command Message
;
EDERCL:
       LDA     EDERR   ;PREVIOUS ERROR?
       ORA     A       ;0=NO
       RZ
       XRA     A       ;CLEAR FLAG
       STA     EDERR
       CALL    ERMSG   ;CLEAR ERROR MESSAGE
       DB      0
       MVI     B,40    ;40 CHARS MAX
       JMP     VEREOL
;
;CLEAR PROMPT LINE
;
EDPRCL:
       CALL    PRINP   ;PROMPT LINE
       DB      0
       MVI     B,40    ;40 POSITIONS
       CALL    VEREOL  ;CLEAR TO EOL OR 40 CHARS
       CALL    AT      ;USER INPUT
       DB      ERROW,1
       MVI     B,79    ;79 POSITIONS
       JMP     VEREOL
;
;Input Address
;
EDITADR:
       CALL    VPRINT
       DB      'Address? ',0
       CALL    RDBUF   ;GET USER INPUT
       CALL    SKSP    ;SKIP LEADING SPACES
       MOV     A,M     ;EMPTY LINE?
       ORA     A
       JZ      MU3R
       CALL    HEXIN   ;CONVERT FROM HEX
       XCHG            ;HL = ADDRESS
       SHLD    BLOCK
       JMP     MU3R    ;REENTER
;
;Advance to Next Block
;
EDITPLUS:
       LHLD    BLOCK   ;ADVANCE TO NEXT BLOCK
       LXI     D,128   ;128 BYTES
       DAD     D
       SHLD    BLOCK
       CALL    EDPLOT  ;REPLOT DATA
       JMP     EDITCMD
;
;Backup to Last Block
;
EDITMINUS:
       LHLD    BLOCK   ;BACKUP TO LAST BLOCK
       LXI     D,-128  ;128 BYTES
       DAD     D
       SHLD    BLOCK
       CALL    EDPLOT  ;REPLOT DATA
       JMP     EDITCMD
;
;Exit MU3
;
EDCC:
       CALL    EDERCL  ;CLEAR ERROR LINE
       JMP     CRLF    ;NEW LINE
;
;EDIT MOVE: UP
;
EDUP:
       CALL    EDCCUR  ;CLEAR CURSOR
       LDA     EINDEX  ;BACKUP INDEX BY 16
       SUI     16
;
;Common EDIT MOVE Routine - on input, A=new index
;
EDMOVE:
       ANI     7FH     ;MOD 128
       STA     EINDEX
       CALL    EDCUR   ;SET CURSOR
       JMP     EDITCMD
;
;EDIT MOVE: DOWN
;
EDDOWN:
       CALL    EDCCUR  ;CLEAR CURSOR
       LDA     EINDEX  ;INCREMENT INDEX BY 16
       ADI     16
       JMP     EDMOVE  ;COMMON ROUTINE
;
;EDIT MOVE: RIGHT
;
EDRIGHT:
       CALL    EDCCUR  ;CLEAR CURSOR
       LDA     EINDEX  ;INCREMENT INDEX BY 1
       INR     A
       JMP     EDMOVE  ;COMMON ROUTINE
;
;EDIT MOVE: LEFT
;
EDLEFT:
       CALL    EDCCUR  ;CLEAR CURSOR
       LDA     EINDEX  ;DECREMENT INDEX BY 1
       DCR     A
       JMP     EDMOVE  ;COMMON ROUTINE
;
;EDIT SUBROUTINE: EDCUR
; Position Editor Cursor at EINDEX
;EDIT SUBROUTINE: EDCCUR
; Clear Editor Cursor at EINDEX
;
EDCUR:
       PUSH    H       ;SAVE HL
       MVI     C,ECURS ;CURSOR CHAR
       CALL    EDSETCUR
       CALL    AT      ;UPDATE DATA
       DB      3,74
       LDA     EINDEX  ;PT TO BYTE AT CURSOR
       LHLD    BLOCK
       ADD     L
       MOV     L,A
       MOV     A,H
       ACI     0
       MOV     H,A     ;HL PTS TO BYTE AT CURSOR
       MOV     A,M     ;GET BYTE
       CALL    PA2HC   ;PRINT AS HEX
       CALL    SPACE
       MOV     A,M     ;GET BYTE
       POP     H       ;RESTORE HL
       ANI     7FH     ;MASK
       CPI     7FH     ;7FH AS DOT
       JZ      EDC7F
       CPI     ' '     ;OUTPUT CHAR OR DOT
       JNC     COUT
EDC7F:
       MVI     A,'.'   ;DOT
       JMP     COUT
EDCCUR:
       MVI     C,' '   ;CLEAR CURSOR
EDSETCUR:
       CALL    EDROW   ;COMPUTE ROW
       ANI     0FH     ;COMPUTE COL MOD 16
       MOV     B,A     ;RESULT IN B
       ADD     A       ;*2
       ADD     B       ;*3
       ADI     ECOL+6  ;ADD IN COL
       DCR     A       ;SUBTRACT 1
       MOV     L,A     ;COL POSITION SET
       CALL    GOTOXY  ;POSITION CURSOR
       MOV     A,C     ;OUTPUT CHAR
       JMP     COUT
;
;Compute Row from EINDEX
;
EDROW:
       LDA     EINDEX  ;GET INDEX
       MOV     B,A     ;SAVE IN B
       RRC             ;DIVIDE BY 16
       RRC
       RRC
       RRC
       ANI     0FH     ;MASK FOR LSB ONLY
       ADI     EROW    ;COMPUTE ROW
       MOV     H,A     ;ROW SET
       MOV     A,B     ;GET INDEX
       RET

;
;PRINT A SPACE
;
SPACE:
       MVI     A,' '
       JMP     COUT
;
;PRINT AN BARISK IN REV VIDEO
;
BAR:
       CALL    VPRINT
       DB      DIM,'|',BRIGHT,0
       RET
;
;Get value from input buffer
;
GETVAL:
       MOV     A,M     ;GET NEXT CHAR
       CPI     '<'     ;HEX ESCAPE?
       RNZ             ;NO, RETURN
;"<<" means one "<"
       INX     H
       MOV     A,M
       CPI     '<'
       RZ
;Got hex
       PUSH    D
       CALL    HEXIN   ;GET VALUE
       CPI     '>'     ;PROPER DELIM?
       MOV     A,E     ;GET VALUE
       POP     D
       RZ
;
;ERROR CONDITION IN SUBROUTINE - CLEAR STACK AND FLAG ERROR
;
SERR:
       POP     PSW     ;CLEAR STACK
       JMP     WHAT    ;ERROR
;
;Input Number from Command Line -- Assume it to be Hex
;  Number returned in DE
;
HEXIN:
       LXI     D,0     ;INIT VALUE
       MOV     A,M
       CPI     '#'     ;DECIMAL?
       JZ      HDIN    ;MAKE DECIMAL
;
HINLP:
       MOV     A,M     ;GET CHAR
       CALL    CAPS    ;CAPITALIZE
       CPI     CR      ;EOL?
       RZ
       CPI     EOLCH   ;EOL?
       RZ
       CPI     SEPCH
       RZ
       CPI     ' '     ;SPACE?
       RZ
       CPI     '-'     ;'THRU'?
       RZ
       CPI     '>'
       RZ
       INX     H       ;PT TO NEXT CHAR
       CPI     '0'     ;RANGE?
       JC      SERR
       CPI     '9'+1   ;RANGE?
       JC      HINNUM
       CPI     'A'     ;RANGE?
       JC      SERR
       CPI     'F'+1   ;RANGE?
       JNC     SERR
       SUI     7       ;ADJUST FROM A-F TO 10-15
;
HINNUM:
       SUI     '0'     ;CONVERT FROM ASCII TO BINARY
       XCHG
       DAD     H       ;MULT PREVIOUS VALUE BY 16
       DAD     H
       DAD     H
       DAD     H
       ADD     L       ;ADD IN NEW DIGIT
       MOV     L,A
       XCHG
       JMP     HINLP
;
HDIN:
       INX     H       ;SKIP '#'
;
;Input Number in Command Line as Decimal
;  Number is returned in DE
;
DECIN:
       LXI     D,0
       MOV     A,M     ; GET 1ST CHAR
       CPI     '#'     ; HEX?
       JNZ     DINLP
       INX     H       ; PT TO DIGIT
       JMP     HINLP   ; DO HEX PROCESSING
;
DINLP:
       MOV     A,M     ;GET DIGIT
       CALL    CAPS    ;CAPITALIZE
       CPI     '0'     ;RANGE?
       RC
       CPI     '9'+1   ;RANGE?
       RNC
       SUI     '0'     ;CONVERT TO BINARY
       INX     H       ;PT TO NEXT
       PUSH    H
       MOV     H,D
       MOV     L,E
       DAD     H       ;X2
       DAD     H       ;X4
       DAD     D       ;X5
       DAD     H       ;X10
       ADD     L       ;ADD IN DIGIT
       MOV     L,A
       MOV     A,H
       ACI     0
       MOV     H,A
       XCHG            ;RESULT IN DE
       POP     H
       JMP     DINLP
;
; READ LINE FROM USER INTO INPUT LINE BUFFER
;
RDBUF:
       LHLD    BUFFER  ;PT TO BUFFER
       XRA     A       ;DON'T CAPITALIZE
       JMP     BLINE   ;INPUT LINE ROUTINE

;
;EDITOR BUFFERS
;
BLOCK:
       DS      2       ;ADDRESS OF CURRENT BLOCK
BUFFER:
       DS      2       ;PTR TO FREE SPACE
EINDEX:
       DS      1       ;INDEX ENTRY
EDERR:
       DS      1       ;ERROR FLAG
EDRUN:
       DS      1       ;FLAG SAYING THAT EDITOR IS RUNNING

       end