;
; Program: REG
; Author: Richard Conn
; Version: 1.0
; Date: 5 Mar 84
;
version equ     10

;
;       REG is used to access the ZCPR3 Registers.  It can set a value,
; display a value or all values, increment, and decrement them.
;

;
; Equates for Key Values
;
z3env   SET     0f400h  ;address of ZCPR3 environment
fcb     equ     5ch
fcb2    equ     6ch
cr      equ     0dh
lf      equ     0ah

;
; External Z3LIB and SYSLIB Routines
;
       ext     z3init,getreg,putreg,getmsg
       ext     eval10,print,cout,crlf,qprint,padc

;
; 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    z3init  ;initialize the ZCPR3 Environment
;
; Print Banner
;
       call    qprint
       db      'REG, Version '
       db      (version/10)+'0','.',(version mod 10)+'0',cr,lf,0
;
; Check for Availability of Registers
;
       call    getmsg
       jz      nomsg
;
; Check for Command
;
       lxi     h,fcb+1 ;pt to first FCB
       mov     a,m     ;get first char
       cpi     ' '     ;check for help
       jz      help
       cpi     '/'     ;also help
       jz      help
       cpi     '#'     ;display all
       jz      dispall
       cpi     'D'     ;display
       jz      display
       cpi     'M'     ;minus (decrement)
       jz      minus
       cpi     'P'     ;plus (increment)
       jz      plus
       cpi     'S'     ;set
       jz      setrg
       cpi     '0'     ;convert to binary
       jc      help
       cpi     '9'+1   ;range?
       jnc     help
       jmp     disp1

;
; Print Error Message
;
nomsg:
       call    print
       db      cr,lf,'No Registers Available',0
       ret

;
; Print Help Message
;
help:
       call    print
       db      cr,lf,'REG - Set/Display/Increment/Decrement Registers'
       db      cr,lf,'REG Syntax:'
       db      cr,lf,' REG Dr or REG r <-- Display Reg r'
       db      cr,lf,' REG Mr          <-- Minus (Decrement) Reg r'
       db      cr,lf,' REG Pr          <-- Plus (Increment) Reg r'
       db      cr,lf,' REG Sr val      <-- Set Reg r to val'
       db      cr,lf,'where "r" may be 0-9 for the regs or'
       db      cr,lf,'# to select all regs'
       db      0
       ret
;
; Display Register
;
display:
       inx     h       ;pt to value
       mov     a,m     ;get it
disp1:
       cpi     '#'     ;display all?
       jz      dispall
;
; Display Particular Register
;
       call    compreg ;compute register number in B
       call    getreg  ;return register value in A
;
; Print Register whose Number is in B and Value in A
;
regprint:
       mov     c,a     ;value in C
       call    print
       db      ' Reg ',0
       mov     a,b
       adi     '0'     ;convert to ASCII
       call    cout
       call    print
       db      ' = ',0
       mov     a,c     ;print value
       jmp     padc
;
; Display All Registers
;
dispall:
       mvi     b,0     ;loop 0 to 9
dispa1:
       call    getreg  ;get register
       call    regprint        ;print register
       call    print
       db      '    ',0
       inr     b       ;increment count
       mov     a,b     ;check for new line
       ani     3
       cz      crlf
       mov     a,b     ;check for done
       cpi     10
       jnz     dispa1
       ret
;
; Convert ASCII Char in A to Register Number in B with error check
;
compreg:
       cpi     '0'     ;convert to binary
       jc      rerr
       cpi     '9'+1
       jnc     rerr
       sui     '0'     ;convert to binary
       mov     b,a     ;return value in B
       ret
rerr:
       mov     b,a     ;save char
       pop     psw     ;clear stack
       call    print
       db      ' Invld Reg ID: ',0
       mov     a,b     ;get char
       jmp     cout
;
; Set Register Value
;
setrg:
       inx     h       ;pt to register
       mov     a,m     ;get char
       cpi     '#'     ;all registers?
       jz      setall
       call    compreg ;get register number in B
       lxi     h,fcb2+1        ;pt to value
       call    eval10  ;evaluate
       mov     c,a     ;save value in C
       call    putreg  ;set register
       jmp     regprint        ;print value
;
; Set All Registers
;
setall:
       lxi     h,fcb2+1        ;pt to value
       call    eval10
       mov     c,a     ;value in C
       mvi     b,0     ;set 10 registers
seta1:
       mov     a,c     ;get value
       call    putreg  ;set value
       inr     b       ;increment reg number
       mov     a,b
       cpi     10
       jnz     seta1
       jmp     dispall ;display all registers
;
; Reg = Reg - 1
;
minus:
       inx     h       ;pt to number
       mov     a,m     ;get it
       cpi     '#'     ;all?
       jz      minall
       call    compreg ;compute register number
       call    getreg  ;get register
       dcr     a       ;-1
       call    putreg  ;restore register
       jmp     regprint        ;print result
;
; All Registers - 1
;
minall:
       mvi     b,0     ;set loop
mina1:
       call    getreg  ;get register
       dcr     a       ;-1
       call    putreg  ;restore register
       inr     b       ;count
       mov     a,b     ;done?
       cpi     10
       jnz     mina1
       jmp     dispall ;display all regs
;
; Reg = Reg + 1
;
plus:
       inx     h       ;pt to register
       mov     a,m     ;get it
       cpi     '#'     ;all?
       jz      plusall
       call    compreg ;compute value
       call    getreg  ;get value
       inr     a       ;+1
       call    putreg  ;put value
       jmp     regprint        ;print value
plusall:
       mvi     b,0     ;set counter
plusa1:
       call    getreg  ;increment value
       inr     a
       call    putreg
       inr     b       ;count
       mov     a,b
       cpi     10
       jnz     plusa1
       jmp     dispall ;print reg values

       end