;*************************** AMUS Program Label ******************************
; Filename: CVTX.M68                                        Date: 05/01/91
; Category: UTIL         Hash Code: 305-560-730-131      Version: 1.0(102)
; Initials:              Name: John Paiement
; Company: Holidair Insurance Services Ltd.        Telephone #: 6044214047
; Related Files: CVTX0.M68, CVTSYM.M68
; Min. Op. Sys.:                               Expertise Level: INT
; Special:  Terminal needs box draw and reverse video capability.
; Description: Full function calculator/ Numeric base translator with memory
; operations.
;
;*****************************************************************************
;*; Updated on 01-May-91 at 4:36 PM by John Paiement; edit time: 0:44:49
;
; NOTE all floats are in standard AM format (48 bit)

    OBJNAM CVTX.LIT
    RADIX  8

    SEARCH SYS
    SEARCH SYSSYM
    SEARCH TRM
       COPY   CVTSYM.M68                               ; Symbols and equates for CVTX


; -------------------------------------------------------------
;
; START OF PROGRAM CODE
;

       PHDR            -1,0,PH$REE!PH$REU      ; Program header

;
; Initialization section
;
    GETIMP     IMPSIZ,A5               ; A5 * to impure area
    MOVB               #0,XITFLG(A5)

       ECHO
    CALL               DRAWSC                  ; Draw calculator

    MOVB               #ADDF,FUNC(A5)             ; Start in ADD function
    CALL               U.FUNC

    MOVB               #DECN,BASE(A5)             ; Start in Decimal base
    CALL               U.BASE

    CALL               MAIN                    ; Call main loop

EXIT:
    PRTTAB     23.,1                   ; Position at 23,1 & end
    EXIT



MAIN:
;
; Main processing loop
;
    CALL      G1CH

    CMPB               XITFLG(A5),#0
    BEQ                MAIN                            ; Loop if not set

    RTN                                                        ; Else exit



; -------------------------------------------------------------
;
; INPUT ROUTINES

G1CH:
;
; Controlling module for processing of user input.
; The first character is processed alone to determine special key handling
; The no-input flag is set on special handling to bypass processing.
;

       CLRBUF
       MOVB            #0,NOINP(A5)              ; Clear no-input flag

       ONEKEY                              ; Get one character
       LEA             A2,BASE(A5)               ; Check base to process
       MOVB            @A2,D1
       CMPB            D1,#RADN
       BNE             G.35
       MOVB            #36.,D2                   ; Rad input at column 36
       JMP             G.36

G.35:
       MOVB            #35.,D2
       CMPB            D1, #PPNN                               ; Ppn input at column 36
       BNE             G.36
       INCB            D2

G.36:
       ROWCOL
       ECHO
       KBD                                                     ; Get 1 character input
       UCS
       CTRLC   SETXIT                          ; Exit on CTRL-C
       CMPB            D1,#ESC                  ; Or ESC
       BNE             GET.IN

       JMP             SETXIT


GET.IN:
;
; Check first character for change of base/function or memory operations
; BYPASS(A5) is set when memory functions selected to avoid placing first
; character in BUFFER
;
       PUSH            D1
       CALL            CK1CH
       CALL            U.FUNC
       POP             D1

       CMPB            BYPASS(A5),#1
       BEQ             NO.BUF

       MOVB            D1,BUFFER(A5)
       JMP             CK10

NO.BUF:
       MOVB            #0,BYPASS(A5)
       JMP             C2FLT         ; Bypass input routine

CK10:
       CMPB            NOINP(A5),#0
       BEQ             PRC.IN            ; Continue as value input

       RTN

PRC.IN:
       LEA             A4,BUFFER(A5)
       CMPB            BASE(A5),#DECN
       BNE             ISIT.H
       CALL            D.IN                ; Call for decimal input validation

       LEA             A2,BUFFER(A5)            ; Point to input buffer
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

C2FLT:
       LEA             A2,INVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT                  ; Display all values
       CALL            AC.VAL
       RTN

ISIT.H:
       CMPB            BASE(A5),#HEXN
       BNE             ISIT.O
       CALL            H.IN                     ; Call for hex input

       SETHEX                             ; Set for hex conversion
       LEA             A2,BUFFER(A5)            ; Point to input buffer
       GTOCT                              ; Place hex in D1
       PUSH            D1
       CLRBUF

       LEA             A2,BUFFER(A5)
       POP             D1
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       JMP             C2FLT

ISIT.O:
       CMPB            BASE(A5),#OCTN
       BNE             ISIT.R
       CALL            O.IN                     ; Call for OCTAL input

       SETOCT                             ; Set for octal conversion
       LEA             A2,BUFFER(A5)            ; Point to input buffer
       GTOCT                              ; Place octal in D1
       PUSH            D1
       CLRBUF

       LEA             A2,BUFFER(A5)
       POP             D1
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       JMP      C2FLT

ISIT.R:
       CMPB            BASE(A5),#RADN
       BEQ             R.CONT
       JMP             ISIT.B

R.CONT:
       CALL            R.IN                     ; Call for RAD input

       LEA             A2,BUFFER(A5)
       MOVB            (A2)+,D1
       MOV             #0,D2
       MOV             #0,D3

RLOOP:
       CMPB            D1,#0
       BEQ             R.OVER

       CMPB            D1,#32.
       BNE             R.10
       MOVB            #0,D1                    ; Set space = 0
       JMP             R.40

R.10:
       CMPB            D1,#36.
       BNE             R.20
       MOVB            #27.,D1                  ; Set $ = 27
       JMP             R.40

R.20:
       CMPB            D1,#64.
       BGE             R.30
       ADDB            #46.,D1                  ; If chr-64 < 0 add 46

R.30:
       SUBB      #64.,D1                  ; Subtract 64 from ascii value
R.40:
       LEA             A4,BUF2(A5)              ; Place mult figure in radin
       CMPW            D2,#0.
       BEQ             R.50
       CMPW            D2,#1600.
       BEQ             R.60
       MOVW            #1,D2
       JMP             R.ADD

R.50:
       MOVW            #1600.,D2
       JMP             R.ADD

R.60:
       MOVW            #40.,D2

R.ADD:
       MOVW            D2,@A4
       MUL             D1,@A4
       ADD             D1,D3

       MOV             #0,D1
       MOVB            (A2)+,D1
       JMP             RLOOP

R.OVER:
       MOV             D3,D1
       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       JMP             C2FLT

ISIT.B:
       CMPB            BASE(A5),#BINN
       BEQ             B.LP
       JMP             ISIT.P

B.LP:
       CALL            B.IN

       MOV             #0,D3
       LEA             A2,BUFFER(A5)
       MOVB            (A2)+,D1

B.LP1:
       CMPB            D1,#0
       BEQ             B.DON
       SUBB            #48.,D1
       ADDB            D1,D3
       MOVB            (A2)+,D1
       CMPB            D1,#0
       BEQ             B.DON
       LSL             D3,#1
       JMP             B.LP1

B.DON:
       CLRBUF
       MOV             D3,D1
       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       JMP             C2FLT

ISIT.P:
       CALL            P.IN                     ; Call for OCTAL input

       SETOCT                             ; Set for octal conversion
       LEA             A2,BUFFER(A5)            ; Point to input buffer
       GTOCT                              ; Place octal in D1
       LSLW            D1,#8.
       PUSH            D1

       CLRBUF
       LEA             A2,BUF2(A5)            ; Point to input buffer
       GTOCT                              ; Place octal in D1
       MOVW            D1,D2
       POP             D1
       ADDW            D2,D1

       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       JMP             C2FLT


D.IN:
;
; input of decimal number
;
       CMP             D1,#CR                  ; Is it CR?
       BEQ             D.DONE

       CMPB            D1,#NINE                  ; > asc(9)?
       BGT             D.BUZZ
       CMPB            D1,#ZERO                  ; < asc(0)?
       BGE             D.OK
       CMP             D1,#PERD                  ; Is it '.'
       BNE             D.BUZZ

D.OK:
       MOVB            D1,(A4)+                 ; Place in buffer
       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       INCB            D2                       ; Inc column
DL2:
       CALL            CHR.IN                          ; Get next char of input
       JMP             D.IN                    ; Validate

D.BUZZ:
       CMP             D1,#RUB                         ; [101] Process the RUBOUT char
       BNE             D.RING
       CMPB            D2,#35.
       BEQ             D.B2
       MOVB            #0,-(A4)
       DECB            D2
D.B2:
       ROWCOL
       MOVB            #32.,D1
       JMP             D.ECH
D.RING:
       MOVB            #BELL,D1                    ; Ring bell
D.ECH:
       TTY
       JMP             DL2                     ; Get again

D.DONE:

       RTN



H.IN:
;
; input of Hex number
;

       CMP             D1,#CR                    ; Is it CR?
       BEQ             H.DONE
       CMPB            D1,#F                     ; > asc(F)?
       BGT             H.BUZZ
       CMPB            D1,#ZERO                  ; < asc(0)?
       BGE             H.OK

       CMP             D1,#NINE                  ; > acs(9)
       BLE             H.OK
       CMP             D1,#A
       BLT             H.BUZZ

H.OK:
       MOVB            D1,(A4)+                 ; Place in buffer
       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       INCB            D2                       ; Inc column
H.LOOP:
       CALL            CHR.IN                          ; Get next
       JMP             H.IN

H.BUZZ:
       CMP             D1,#RUB                         ; [101] Process the RUBOUT char
       BNE             H.RING
       CMPB            D2,#35.
       BEQ             H.B2
       MOVB            #0,-(A4)
       DECB            D2
H.B2:
       ROWCOL
       MOVB            #32.,D1
       JMP             H.ECH
H.RING:
       MOVB            #BELL,D1                    ; Ring bell
H.ECH:
       TTY
       JMP             H.LOOP                   ; Get again

H.DONE:

       RTN

O.IN:
;
; input of Octal number
;

       CMP             D1,#CR                  ; Is it CR?
       BEQ             O.DONE
       CMPB            D1,#SEVN                 ; > asc(7)?
       BGT             O.BUZZ
       CMPB            D1,#ZERO                  ; < asc(0)?
       BLT             O.BUZZ

       MOVB            D1,(A4)+                 ; Place in buffer
       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       INCB            D2                       ; Inc column
O.LOOP:
       CALL            CHR.IN                          ; Get rest of input
       JMP             O.IN                     ; Get next

O.BUZZ:
       CMP             D1,#RUB                         ; [101] Process the RUBOUT char
       BNE             O.RING
       CMPB            D2,#35.
       BEQ             O.B2
       MOVB            #0,-(A4)
       DECB            D2
O.B2:
       ROWCOL
       MOVB            #32.,D1
       JMP             O.ECH
O.RING:
       MOVB            #BELL,D1                    ; Ring bell
O.ECH:
       TTY
       JMP             O.LOOP                   ; Get again

O.DONE:

       RTN


R.IN:
;
; input of Rad50 number
;

       MOVB            #1,D3

       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       MOVB            D1,(A4)+                 ; Place in buffer
       INCB            D2                                      ; Inc column

R.GET:
       CALL            CHR.IN                          ; Get 2nd char
       CMP             D1,#RUB                         ; [101] Process the RUBOUT char
       BNE             R.SAV

       CMPB            D2,#36.
       BEQ             R.G2
       MOVB            #0,-(A4)
       DECB            D2
       CMPB            D3, #1
       BLT             R.G2
       DECB            D3

R.G2:
       ROWCOL
       MOVB            #32.,D1
       TTY
       JMP             R.GET

R.SAV:
       MOVB            D1,(A4)+                 ; Place in buffer
       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       INCB            D2                       ; Inc column
       INCB            D3
       CMP             D3,#3.
       BLT             R.GET

       RTN


B.IN:
;
; input of Binary number
;

       CMP             D1,#CR                  ; Is it CR?
       BEQ             B.DONE
       CMPB            D1,#ONE                  ; > asc(1)?
       BGT             B.BUZZ
       CMPB            D1,#ZERO                  ; < asc(0)?
       BLT             B.BUZZ

       MOVB            D1,(A4)+                 ; Place in buffer
       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       INCB            D2                       ; Inc column
B.LOOP:
       CALL            CHR.IN                          ; Get rest of input
       JMP             B.IN                     ; Get next

B.BUZZ:
       CMP             D1,#RUB                         ; [101] Process the RUBOUT char
       BNE             B.RING
       CMPB            D2,#35.
       BEQ             B.B2
       MOVB            #0,-(A4)
       DECB            D2
B.B2:
       ROWCOL
       MOVB            #32.,D1
       JMP             B.ECH
B.RING:
       MOVB            #BELL,D1                    ; Ring bell
B.ECH:
       TTY
       JMP             B.LOOP                   ; Get again

B.DONE:

       RTN


P.IN:
;
; input of PPN number
;

       CMP             D1,#CR                  ; Is it CR?
       BEQ             P.DONE
       CMPB            D1,#SEVN                 ; > asc(7)?
       BGT             P.BUZZ
       CMPB            D1,#ZERO                  ; < asc(0)?
       BGE             P.CNT
       CMPB            D1,#COMA
       BNE             P.BUZZ
       LEA             A4,BUF2(A5)
       INCB            D2
       JMP             P.LOOP

P.CNT:
       MOVB            D1,(A4)+                 ; Place in buffer
       PUSH            D1
       ROWCOL
       POP             D1
       TTY                                                     ; Echo character
       INCB            D2                       ; Inc column
P.LOOP:
       CALL            CHR.IN                          ; Get rest of input
       JMP             P.IN                     ; Get next

P.BUZZ:
       CMP             D1,#RUB                         ; [101] Process the RUBOUT char
       BNE             P.RING
       CMPB            D2,#36.
       BEQ             P.B2
       MOVB            #0,-(A4)
       DECB            D2
P.B2:
       ROWCOL
       MOVB            #32.,D1
       JMP             P.ECH
P.RING:
       MOVB            #BELL,D1                    ; Ring bell
P.ECH:
       TTY
       JMP             P.LOOP                   ; Get again

P.DONE:

       RTN


CK1CH:
;
; Check first character input for special processing
;
       CMPB            D1,#CR                  ; Display total on CR
       BNE             C10

       LEA             A2,ACCUM(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the ACCUM to be displayed
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
       CALL            N.PROC

       RTN

C10:
       CMPB            D1,#CLRM                 ; Clear memory
       BNE             CLR.D

       LEA             A2,MEMVAL(A5)
       MOV             #0,(A2)+
       MOVW            #0, @A2
       LEA             A2,MEMVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the ACCUM to be displayed
       MOVW            @A2,@A4

       MOVB            #56.,D2
       CALL            SHW.IT
       CALL            N.PROC
       RTN

CLR.D:
       CMPB            D1,#CLRD                 ; Clear display
       BNE             S.ADD

       CLRACC                             ; Clear accumulator
       CLRVAL                             ; Clear input value

       LEA             A2,INVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
       CALL            N.PROC
       RTN

S.ADD:
       CMPB            D1,#PLUS                  ; Set function to ADD
       BNE             S.SUB
       MOVB            #ADDF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.SUB:
       CMPB            D1,#MINS                  ; Set function to Subt
       BNE             S.MUL
       MOVB            #SUBF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.MUL:
       CMPB            D1,#TIMS                  ; Set function to Mult
       BNE             S.DIV
       MOVB            #MULF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.DIV:
       CMPB            D1,#DIVS                  ; Set function to Div
       BNE             S.AND
       MOVB            #DIVF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.AND:
       CMPB            D1,#LAND                 ; Set function to And
       BNE             S.OR
       MOVB            #ANDF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.OR:
       CMPB            D1,#LOR                  ; Set function to Or
       BNE             S.NOT
       MOVB            #ORF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.NOT:
       CMPB            D1,#LNOT                 ; Set function to Not
       BNE             S.XOR
       MOVB            #NOTF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

S.XOR:
       CMPB            D1,#LXOR                 ; Set function to Xor
       BNE             CK.MEM
       MOVB            #XORF,FUNC(A5)
       CALL            N.PROC      ; Set No-processing flag
       RTN

CK.MEM:
       CMPB            D1,#MFNC                 ; Check if memory manipulation CTRL-P
       BEQ             M.ADD
       CMPB            D1,#TAB                  ; Change base
       BEQ             S.BAS
       RTN

S.BAS:
       CALL            SLCT.B
       CALL            N.PROC      ; Set No-processing flag
       RTN

M.ADD:
       KBD                                                     ; Get 2nd half of memory op
       UCS

       CMPB            D1,#PLUS                  ; Add to memory <+>
       BNE             M.SUB

       LEA             A2,DISVAL(A5)
       LEA             A3,MEMVAL(A5)
       FADD            A2, A3

       LEA             A2,MEMVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the ACCUM to be displayed
       MOVW            @A2,@A4

       MOVB            #56.,D2
       CALL            SHW.IT
       CALL            N.PROC      ; Set No-processing flag
       RTN

M.SUB:
       CMPB            D1,#MINS                  ; Subtract from memory <->
       BNE             M.OUT

       LEA             A2,DISVAL(A5)
       LEA             A3,MEMVAL(A5)
       FSUB            A2, A3

       LEA             A2,MEMVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the ACCUM to be displayed
       MOVW            @A2,@A4

       MOVB            #56.,D2
       CALL            SHW.IT
       CALL            N.PROC      ; Set No-processing flag
       RTN

M.OUT:
       CMPB            D1,#CR                  ; Recall memory on <CR>
       BNE             M.IN

       LEA             A2,MEMVAL(A5)            ; Move memval to inval
       LEA             A3,INVAL(A5)
       MOV             (A2)+,(A3)+
       MOVW            @A2,@A3

       LEA             A2,INVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
       MOVB            #1,BYPASS(A5)
       RTN

M.IN:
       CMPB            D1,#EQLS                 ; Memory in <=>
       BNE             CK.DON

       LEA             A2,MEMVAL(A5)            ; Move accum to memval
       LEA             A3,DISVAL(A5)
       MOV             (A3)+,(A2)+
       MOVW            @A3,@A2

       LEA             A2,MEMVAL(A5)
       LEA             A4,DISVAL(A5)
       MOV             (A2)+,(A4)+              ; Set the ACCUM to be displayed
       MOVW            @A2,@A4
       MOVB            #56.,D2
       CALL            SHW.IT
       CALL            N.PROC      ; Set No-processing flag

CK.DON:
       RTN



CHR.IN:
;
; Get the rest of the input from user
;
       ROWCOL
       ECHO
       KBD
       UCS
       RTN


SETXIT:
;
; Set the exit flag
;

       MOVB            #1,XITFLG(A5)            ; Set flag for exit
       RTN



; -------------------------------------------------------------
;
; DISPLAY FUNCTIONS

SHW.IT:
;
; display all values in appropriate window from display value float DISVAL(A5)
;
       CLRBUF

       WINROW  5                        ; Clear decimal line
       TYPE            <                >
       WINROW  5
       LEA             A2,BUFFER(A5)            ; Point to buffer
       GTDEC

       LEA             A2,BUFFER(A5)
       FCVT            DISVAL(A5),0,OT$TRM,0,0  ; Place ascii string in window
       FCVT            DISVAL(A5),0,OT$MEM,0,0  ; Place ascii string in BUFFER

; hex
       INCB            D2
       WINROW  6
       TYPE            <                >
       SETHEX
       LEA             A2,BUFFER(A5)            ; Point to buffer
       BYP

       MOV             #0,D1
       GTDEC
       BMI             DIS.O
       WINROW  6
       LEA             A2,BUFFER(A5)            ; Point to buffer
       OCVT            0,OT$TRM

DIS.O:
       WINROW  7
       TYPE            <                >
       SETOCT
       LEA             A2,BUFFER(A5)            ; Point to buffer
       BYP

       MOV             #0,D1
       GTDEC
       BMI             DIS.R
       WINROW  7
       LEA             A2,BUFFER(A5)            ; Point to buffer
       OCVT            0,OT$TRM

DIS.R:
       MOV             D1,D4
       MOVW            D1,BUF2(A5)
       WINROW  8.
       TYPE            <                >
       EVEN

       MOV             D4,D1
       CMP             D1,#65535.
       BGT             O16B

       CLRBUF
       LEA             A2,BUFFER(A5)
       LEA             A1,BUF2(A5)
       MOVB            #91.,(A2)+
       UNPACK
       MOVB            #93.,(A2)+
       WINROW  8.
       OUTL            BUFFER(A5),OT$TRM
       JMP             DIS.B

O16B:
       WINROW   8.
       TYPE            <[---]>
       EVEN

DIS.B:
       WINROW  9.
       TYPE            <                >
       EVEN

       MOV             D4,D1
       CMP             D1,#65535.
       BGT             DIS.P

       CLRBUF
       MOV             #0,D7
       LEA             A2,BUFFER(A5)
       MOVW            #32768.,D3               ; Bit index at 16th bit

DIS.10:
       MOVW            D4,D1
       ANDW            D3,D1
       CMPW            D1,#0
       BEQ             DIS.20
       MOVB            #49.,(A2)+
       MOVB            #1,D7                    ; Flag first '1' output
       JMP             DIS.40

DIS.20:
       CMPB            D7,#0                    ; Place space until first '1' output
       BEQ             DIS.30
       MOVB            #48.,(A2)+
       JMP             DIS.40

DIS.30:
       MOVB            #32.,(A2)+

DIS.40:
       LSRW            D3,#1
       CMPW            D3,#0
       BEQ             DIS.50
       JMP             DIS.10

DIS.50:
       WINROW  9.
       OUTL            BUFFER(A5),OT$TRM

DIS.P:
       INCB            D2
       WINROW  10.
       TYPE            <                >
       EVEN

       MOV             D4,D1
       CMP             D1,#65535.
       BGT             NO.PD
       CMP             D1,#0
       BEQ             NO.PD

       WINROW  10.
       MOVW            D4, D1
       LSRW            D1, #8.
       AND             #255.,D1                                ; Mask off high bytes

       OCVT            0,OT$TRM
    TYPE               <,>

       MOVW            D4, D1
       ANDW            #255.,D1                 ; Mask off high byte
       OCVT            0,OT$TRM

       TYPE            <]>
       JMP             DS.DON

NO.PD:
       WINROW  10.
       TYPE            <---,---]>
       EVEN

DS.DON:
       RTN



; -------------------------------------------------------------
;
; ACCUMULATOR and MATH/LOGICAL FUNCTIONS


AC.VAL:
;
; perform accumulator functions
;
       CMPB            FUNC(A5),#ADDF
       BNE             AC.SUB

       LEA             A2,INVAL(A5)
       LEA             A3,ACCUM(A5)
       FADD            A2, A3
       RTN

AC.SUB:
       CMPB            FUNC(A5),#SUBF
       BNE             AC.MUL

       LEA             A2,INVAL(A5)
       LEA             A3,ACCUM(A5)
       FSUB            A2, A3
       RTN

AC.MUL:
       CMPB            FUNC(A5),#MULF
       BNE             AC.DIV

       LEA             A2,INVAL(A5)
       LEA             A3,ACCUM(A5)
       FMUL            A2, A3
       RTN

AC.DIV:
       CMPB            FUNC(A5),#DIVF
       BNE             AC.AND

       LEA             A2,INVAL(A5)
       LEA             A3,ACCUM(A5)
       FDIV            A2, A3
       RTN

AC.AND:
       CMPB            FUNC(A5),#ANDF
       BEQ             AC.CNT
       JMP             AC.OR

AC.CNT:
       CALL            CVTACC
       CMPB            BYPASS(A5),#1
       BEQ             ANDOUT

       MOV             D1,D2
       CALL            CVTVAL
       CMPB            BYPASS(A5),#1
       BEQ             ANDOUT

       AND             D2,D1
       CLRBUF
       CLRVAL
       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       LEA             A2,INVAL(A5)
       LEA             A3,DISVAL(A5)
       LEA             A4,ACCUM(A5)
       MOV             (A3)+,@A4
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A3,@A4
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
ANDOUT:
       MOVB            #0,BYPASS(A5)
       RTN

AC.OR:
       CMPB            FUNC(A5),#ORF
       BNE             AC.XOR

       CALL            CVTACC
       CMPB            BYPASS(A5),#1
       BEQ             OROUT

       MOV             D1,D2
       CALL            CVTVAL
       CMPB            BYPASS(A5),#1
       BEQ             OROUT

       OR              D2,D1
       CLRBUF
       CLRVAL
       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       LEA             A2,INVAL(A5)
       LEA             A3,DISVAL(A5)
       LEA             A4,ACCUM(A5)
       MOV             (A3)+,@A4
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A3,@A4
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
OROUT:
       MOVB            #0,BYPASS(A5)
       RTN

AC.XOR:
       CMPB            FUNC(A5),#XORF
       BNE             AC.NOT

       CALL            CVTACC
       CMPB            BYPASS(A5),#1
       BEQ             XOROUT

       MOV             D1,D2
       CALL            CVTVAL
       CMPB            BYPASS(A5),#1
       BEQ             XOROUT

       XOR             D2,D1
       CLRBUF
       CLRVAL
       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       LEA             A2,INVAL(A5)
       LEA             A3,DISVAL(A5)
       LEA             A4,ACCUM(A5)
       MOV             (A3)+,@A4
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A3,@A4
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
XOROUT:
       MOVB            #0,BYPASS(A5)
       RTN

AC.NOT:
       CMPB            FUNC(A5),#NOTF
       BEQ             ACN1
       JMP             AC.WHO

ACN1:
       PUSH            D1
       CALL            CVTACC
       POP             D1
       CMPB            BYPASS(A5),#1
       BEQ             NOTOUT

       NOT             D1
       CLRBUF
       CLRVAL
       LEA             A2,BUFFER(A5)
       DCVT            0,OT$MEM                 ; Place decimal string in buffer
       LEA             A2,BUFFER(A5)
       GTFLT   INVAL(A5)                ; Convert buffer to float at INVAL

       LEA             A2,INVAL(A5)
       LEA             A3,DISVAL(A5)
       LEA             A4,ACCUM(A5)
       MOV             (A3)+,@A4
       MOV             (A2)+,(A4)+              ; Set the INVAL to be displayed
       MOVW            @A3,@A4
       MOVW            @A2,@A4

       MOVB            #34.,D2
       CALL            SHW.IT
NOTOUT:
       MOVB            #0,BYPASS(A5)
       MOVB            #ADDF,FUNC(A5)

AC.WHO:
       RTN


CVTACC:
       CLRBUF
       LEA             A2,BUFFER(A5)
       FCVT            ACCUM(A5),0,OT$MEM,0,0  ; Place ascii string in window
       LEA             A2,BUFFER(A5)            ; Point to buffer
       BYP
       MOV             #0,D1
       GTDEC
       CMP             D1,#^H0FFFFFFFF
       BGE             AC.1
       JMP             NO.GO
AC.1:
       RTN


CVTVAL:
       CLRBUF
       LEA             A2,BUFFER(A5)
       FCVT            INVAL(A5),0,OT$MEM,0,0  ; Place ascii string in window
       LEA             A2,BUFFER(A5)            ; Point to buffer
       BYP

       MOV             #0,D1
       GTDEC
       CMP             D1,#^H0FFFFFFFF
       BGE             AC.2
       JMP             NO.GO
AC.2:
       RTN

NO.GO:
       PRTTAB  24.,1
       TYPE            <No logical operations on values over 2**32>
       EVEN
       MOV             #BELL,D1
       TTY
       KBD
       PRTTAB  24.,1
       TYPE            <                                          >
       EVEN
       MOVB            #1,BYPASS(A5)
       RTN


N.PROC:
;
; Set the no-input-processing flag
;
       MOVB            #1,NOINP(A5)
       RTN


; -------------------------------------------------------------
;
;CHANGE BASE FUNCTIONS
;

SLCT.B:
;
; Controlling module for selection of base
;

       ONEKEY

BAS.10:
       CALL            HILIT
       PRTTAB  -1,29.                   ; Cursor off
       MOVB            #28.,D2
       ROWCOL
       KBD
       UCS
       CALL            UNLIT

       CMPB            D1,#CR                  ; Is it CR
       BNE             NOT.CR
       JMP             ACCEPT

NOT.CR:
       CMPB            D1,#ESC                  ; Is it ESC
       BNE             NO.ESC

ACCEPT:
       PRTTAB  -1,28.                   ; Cursor on
       RTN

NO.ESC:
       CMPB            D1,#11.                  ; Is it CURS UP
       BNE             NOT.UP

       LEA             A2,BASE(A5)
       MOVB            @A2,D1
       CMPB            D1,#DECN
       BEQ             LST.E

       DECB            D1
       JMP             MV.BAR       ; Set base and update

LST.E:
       MOVB            #PPNN,D1

MV.BAR:
       LEA             A2,BASE(A5)
       MOVB            D1,@A2                   ; Store the new base
       CALL            U.BASE
       JMP             BAS.10

NOT.UP:
       CMPB            D1,#10.                  ; Is it CURS DN
       BNE             NOT.DN

       LEA             A2,BASE(A5)
       MOVB            @A2,D1
       INCB            D1
       CMPB            D1,#PPNN
       BLE             MV.BAR
       MOVB            #DECN,D1
       JMP             MV.BAR

NOT.DN:
       CMPB            D1,#68.                  ; Is it D
       BNE             CHK.H
       MOVB            #DECN,BASE(A5)
       PRTTAB  -1,28.                   ; Cursor on
       JMP             SB.END

CHK.H:
       CMPB            D1,#72.                  ; Is it H
       BNE             CHK.O
       MOVB            #HEXN,BASE(A5)
       JMP             SB.END

CHK.O:
       CMPB            D1,#79.                  ; Is it O
       BNE             CHK.R
       MOVB            #OCTN,BASE(A5)
       JMP             SB.END

CHK.R:
       CMPB            D1,#82.                  ; Is it R
       BNE             CHK.B
       MOVB            #RADN,BASE(A5)
       JMP             SB.END

CHK.B:
       CMPB            D1,#66.                  ; Is it B
       BNE             CHK.P
       MOVB            #BINN,BASE(A5)
       JMP             SB.END

CHK.P:
       CMPB            D1,#80.                  ; Is it P
       BEQ             PPN
       JMP             BAS.10

PPN:
       MOVB            #PPNN,BASE(A5)

SB.END:
       CALL            U.BASE
       PRTTAB  -1,28.                   ; Cursor on
       RTN



HILIT:
;
; Hilite the current base for selection
;
       PUSH            D1
       MOVB            #28.,D2
       ROWCOL                             ; At current base row,28
       PRTTAB  -1,32.                   ; Hilite char
       MOVB            #34.,D2
       ROWCOL
       PRTTAB  -1,33.
       POP             D1
       RTN


UNLIT:
;
; Restore normal video on selection
;
       PUSH            D1
       MOVB            #28.,D2
       ROWCOL                             ; At current base row,28
       PRTTAB  -1,33.                   ; End Hilite char
       POP             D1
       RTN



U.BASE:
;
; Update the base in calculator window
;

       MOV             #0,D1
       MOVB            BASE(A5),D1
       LSL             D1,#1
       PRTTAB  3,48.
       LEA             A2,BT1
       ADDW            D1,A2
       MOVW            @A2,D1
       ADDW            D1,A2
       TTYL            @A2

       RTN

U.FUNC:
;
; Update the function in calculator window
;

       MOV             #0,D1
       MOVB            FUNC(A5),D1
       LSL             D1,#1
       PRTTAB  3,36.
       LEA      A2,FT1-2
       ADDW            D1,A2
       MOVW            @A2,D1
       ADDW            D1,A2
       TTYL            @A2

       RTN


DEFINE  OFFTAB A0,A1,A2,A3,A4,A5
       IF NB, A0, WORD A0-.
       IF NB, A1, WORD A1-.
       IF NB, A2, WORD A2-.
       IF NB, A3, WORD A3-.
       IF NB, A4, WORD A4-.
       IF NB, A5, WORD A5-.
ENDM

; Word offset and data table for base/function text placement
;
BT1: OFFTAB BA0,BA1,BA2,BA3,BA4,BA5
FT1: OFFTAB FA1,FA2,FA3,FA4,FA5,FA6
    OFFTAB FA7,FA8

BA0: ASCII      /Dec/
    BYTE      0
BA1: ASCII      /Hex/
    BYTE      0
BA2: ASCII     /Oct/
    BYTE      0
BA3: ASCII     /Rad/
    BYTE      0
BA4: ASCII     /Bin/
    BYTE      0
BA5: ASCII     /Ppn/
    BYTE      0

FA1: ASCII      / Add/
    BYTE      0
FA2: ASCII      /Subt/
    BYTE      0
FA3: ASCII      /Mult/
    BYTE       0
FA4: ASCII      / Div/
    BYTE      0
FA5: ASCII      / And/
    BYTE      0
FA6: ASCII      / Or /
    BYTE      0
FA7: ASCII      / Not/
    BYTE      0
FA8: ASCII      / Xor/
    BYTE      0



; -------------------------------------------------------------
; SCREEN DRAW MODULE

       COPY            CVTX0.M68
END