;    FILE APUTST.SRC      VER.1.0
;    CREATED 9-16-80
;    LAST UPDATE 9-25-80  WRITTEN BY D.A. STEELE

;    THIS PROCEDURE WILL DO A FEW TESTS TO ASSURE THAT THE APU
;    IS FUNCTIONING.  THE TESTS ARE NOT CONCLUSIVE HOWEVER
;    AND THE USER SHOULD NOT ASSUME THAT ALL OPERATIONS OF THE
;    APU HAVE BEEN CHECKED.

;    THIS MODULE SHOULD BE DECLARED EXTERNAL IN THE PASCAL
;    MONITOR PROGRAM
;
;    FUNCTION APUT : INTEGER; EXTERNAL

;    THIS MODULE WILL RETURN TRUE OF FALSE DEPENDING WHETHER
;    OR NOT THE TEST PASSED OR FAILED.  TRUE = FAILED.


         NAME APUT
         ENTRY APUT


APUDAT:   EQU       0AAH
APUSTAT:  EQU       0ABH
SADD:     EQU       6CH
SSUB:     EQU       6DH  ;SUBTRACT TOS FROM NOS
SMUL:     EQU       6EH  ;I6 BIT MULTIPLY
SMUU:     EQU       76H  ;16 BIT MILTIPLY
SDIV:     EQU       6FH  ;16 BIT DIVIDE
DADD:     EQU       2CH  ;23 BIT ADD
DSUB:     EQU       2DH  ;32 BIT SUBTRACT
DMUL:     EQU       2EH  ;32 BIT MULTIPLY LOWER
DDIV:     EQU       2FH  ;32 BIT DIVIDE
FADD:     EQU       10H  ;32 BIT FLOATING ADD
FSUB:     EQU       11H  ;32 BIT FLOATING SUBTRACT
FMUL:     EQU       12H  ;32 BIT FLOATINNG MULTIPLY
FDIV:     EQU       13H  ;32 BIT FLOATING DIVIDE
SQRT:     EQU       1    ;SQUARE ROOT
PWR:      EQU       0BH  ;RAISE TO A POWER
FIXD:     EQU       1EH  ;FLOAT => FIX
FLTD:     EQU       1CH  ;FIX => FLOAT
CHSD      EQU       34H  ;FIXED SIGN CHANGE
CHSF      EQU       15H  ;FLOAT SIGN CHANGE
XCHD      EQU       26H  ;EXCHANGE TOS W/ NOS

ATEST1:   EQU       1    ;APU BUS ERROR TEST
ATEST2:   EQU       2    ;APU STACK TEST
ATEST3:   EQU       4    ;DADD TEST
ATEST4:   EQU       8    ;DSUB TEST
ATEST5:   EQU       10H  ;DMUL & DDIV TEST
ATEST6:   EQU       20H  ;UNUSED
ATEST7:   EQU       40H  ;16 BIT ARITHMATIC TEST
ATEST8    EQU       80H  ;MISC TEST

APUSTOR:  DS        16   ;STORAGE AREA FOR RESULTS �APUERR:   DS        2    ;THE MODULE ARROR FLAG
ATEST:    DS        1    ;THE TEST BEING DONE
STATUS:   DS        1    ;STORAGE FOR THE STATUS BYTE


;========================================================
;THIS ROUTINE WILL SEND THE COMMAND IN A TO THE APU
;AND THEN MONITOR THE STATUS BYTE UNTIL IT GOES NOT
;BUSY OR UNTIL 64K MACHINE CYCLES HAVE PASSED
;IF A NOT BUSY IS NOT RECEIVED THEN THE ERROR FLAG IS SET TO
;ALL ONES
;
OUTIT:    PUSH      B
         OUT       APUSTAT   ;OUTPUT THE COMMAND
         LXI       B,0FFFFH  ;SET THE TIMER
OUTIT1:   DCX       B
         IN        APUSTAT   ;GET THE STATUS BIT
         ANI       80H       ;SEE IF THE BUSY BIT IS 1
         JNZ       OUTXIT

         MOV       A,B       ;START CHECKING THE B REGISTER
         ORA       C         ;DON'T FORGET THE BOTTOM HALF
         CPI       0
         JNZ       OUTIT1    ;IF ISN'T 0 THEN GO ANOTHER ROUND
         LXI       H,APUERR+1;IF IT IS ZERRO THEN THE APU IS BAD
         MVI       M,2       ;SET THE ERROR FLAG

OUTXIT:   POP       B
         RET                 ;AND RETURN

;=============================================================
;ERROR ROUTIME TO OR IN THE NEW ERROR
ERROR:    PUSH      B
         LDA       APUERR    ;GET THE ERROR FLAG
         MOV       B,A
         LDA       ATEST     ;GET TEST TYPE
         ORA       B
         STA       APUERR    ;STORE THE ERROR FLAG
         POP       B
         RET
;===========================================================
;    THIS IS A COMPARE ROUTINE TO CPMPARE A STRING OF BITS
;    THE LENGTH OF WHICH IS IN BC AND IS POINTED TO BY HL
;    WITH ANOTHER STRING POINTED TO BY DE.

COMPX:
COMPX1:   MOV       A,M       ;GET ONE OF THE FIRST BYTES
         XCHG
         CCI                 ;COMPAIR A WITH MEMORY. INX HL
                             ;AND DCX BC.
         CNZ       ERROR     ;IF THE BYTES ARE NOT EQUAL ERROR
         XCHG
         INX       H         ;INCREMENT THE OTHER POINTER
         MOV       A,B       ;IS IT THE END OF THE STRING
         ORA       C �          NOP                 ;MAINTAIN CODE SIZE
         JNZ       COMPX1    ;IF NOT END DO IT AGAIN
         RET

;===========================================================
;THIS WILL TEST THE BUS LINES TO THE APU

REGTST:   MVI       C,APUDAT       ;PUT PORT NUMBER IN C FOR MOVE
         MVI       B,16           ;GOING TO MOVE 16 BYTES
APU1:     OUTP      D              ;OUTPUT THE PATTERN 16 TIMES
         DCR       B              ;COUNT THE OUTPUTS
         JNZ       APU1

         ; NOW READ THE 16 BYTES BACK
         MVI       B,16           ;THERE'S 16 OF THEM
APU11:    INP       A              ;GET THE TOS
         CMP       D              ;IT SHOULD NOT HAVE CHANGED
         CNZ       ERROR          ;IF IT HAS CHANGED THEN ERROR
         DCR       B
         JNZ       APU11
         RET                      ;END OF BUS TEST


APUT1:  MVI       D,01010101B    ;FILL D WITH A PATTERN
         CALL      REGTST
         MVI       D,10101010B
         CALL      REGTST         ;DI FINAL BUS TEST
         RET


;===========================================================
;    NEXT IS A TST OF ALL APU REGISTERS. ALL 256 BIT PATTERNS
;    WILL BE TESTED IN EACH REGISTER

APUT2:    MVI       D,0

APUT21: CALL      REGTST
         OUTP      D         ;SLIDE THE APU REGISTER WINDOW
         INR       D         ;GET THE NEXT BIT PATTERN
         JNZ       APUT21  ;IF WE HAVN'T DONE THEM ALL THEN CONTINUE
         RET

;===========================================================
;    THE NEXT TEST WILL TEST THE DOUBBLE ADD INSTRUCTION OF
;    THE APU

RES:      DB        0,0FFH,0FFH,0FFH
APUT3:  MVI       C,APUDAT
APUT31: MVI       D,55H     ;OUTPUT THE FIRST OPERAND
         OUTP      D
         OUTP      D
         OUTP      D
         MVI       D,0
         OUTP      D
�          MVI       D,0AAH     ;OUTPUT THE SECOND OPERAND
         OUTP      D
         OUTP      D
         OUTP      D
         MVI       D,0
         OUTP      D

         MVI       A,DADD
         CALL      OUTIT     ;OUTPUT THE OPCODE

         MVI       C,APUDAT  ;TIME TO GET THE RESULT
         LXI       H,APUSTOR ;STRING TO PUT IT IN
         MVI       B,4       ;THE LENGTH
         INIR                ;MOVE IT IN

         LXI       B,4       ;COMPAIR THE RESULTS
         LXI       H,RES
         LXI       D,APUSTOR
         CALL      COMPX
         RET

;============================================================
;    THIS WILL TEST DADD AND DSUB BY TAKING A NUMBER-ADDING A
;    SECOND NUMBER TO IT AND THEN SUBTRACTING THE FIRST NUMBER
;    FROM THE SECOND.  THE RESULT SHOULD BE THE SECOND NUMBER
;
NUM1      DB   0,0AAH,55H,0AAH
NUM2      DB   1,55H,0AAH,55H

APUT4:  MVI       C,APUDAT  ;DATAPORT IN C
         MVI       B,8       ;MOVING 8 BYTES
         LXI       H,NUM2+3  ;START W/ LSB
         OUTDR               ;LOAD THE APU

         MVI       A,DADD
         CALL      OUTIT     ;ADD THE TWO NUMBERS

         MVI       B,4       ;MOVING 4 BYTES
         LXI       H,NUM2-1  ;START W/ LSB
         OUTDR               ;LOAD APU WITH FORST NUMBER AGAIN

         MVI       A,DSUB
         CALL      OUTIT     ;SUBTRACT THE FIRST FROM THE SECOND

         LXI       H,APUSTOR
         MVI       B,4
         INIR                ;GET THE 4 BYTE RESULT

         LXI       H,APUSTOR
         LXI       D,NUM2
         LXI       B,4       ;COMPAIR 4 BYTES
         CALL      COMPX
         RET

;============================================================ �;    THIS TEST WILL TEST MULTIPLY AND DIVIDE BY TAKING A NUMBER
;    AND MULTIPLYING IT BY A SECOND NUMBER AND THEN DIVIDING
;    THE RESULT BY THE FIRST NUMBER.  THE FINAL RESULT SHOULD
;    BE THE SECOND NUMBER.


NUMA:     DB   0,0,5,3
NUMB:     DB   0,0,1,2
APUT5:

         MVI       C,APUDAT
         MVI       B,8
         LXI       H,NUMB+3
         OUTDR               ;LOAD THE APU

         MVI       A,DMUL
         CALL      OUTIT     ;DO THE MULTIPLY

         MVI       B,4       ;GETTING 4 BYTES
         LXI       H,NUMB-1  ;GET THE FIRST NUMBER AGAIN
         OUTDR               ;PUT IT IN THE APU
         MVI       A,DDIV
         CALL      OUTIT     ;DO THE DIVIDE

         LXI       H,APUSTOR ;GET READY TO STORE THE DATA
         MVI       B,4       ;4 BYTES
         INIR                ;GET THE RESULTS

         LXI       H,NUMB    ;COMPAIR THE ANSWER
         LXI       D,APUSTOR
         LXI       B,4
         CALL      COMPX
         RET

;============================================================
;    THIS TEST WILL CHECK TO SEE IF THE CORRECT RESULTS ARE
;    RETURNED IF THE BUSY BIT IF THE APU IS NOT CHECKED.
;
;
IX        DB        0,0,0,5
IY        DB        0,0,0,0FH
IR        DB        0,0BH,96H,4FH

APUT6:
         MVI       C,APUDAT
         MVI       B,4
         LXI       H,IY+3
         OUTDR               ;LOAD THE OPERANDS IN THE APU
         MVI       A,FLTD
         CALL      OUTIT     ;CONVERT TO FLOATING POINT

         MVI       B,4
         LXI       H,IX+3
         OUTDR               ;LOAD SECOND OPERAND
         MVI       A,FLTD �          CALL      OUTIT     ;CONVERT TO FLOATING POINT

         MVI       A,PWR
         OUT       APUSTAT   ;RAISE IT TO THE POWER

         MVI       A,FIXD
         CALL      OUTIT     ;CONVERT TO FIXED POINT

         LXI       H,APUSTOR
         MVI       B,4
         INIR                ;GET THE RESULT

         LXI       H,IR
         LXI       D,APUSTOR
         LXI       B,3       ;JUST CHCK HIGH 3 BYTES - LOW PRECISION
         CALL      COMPX     ;COMPAIR THE RESULT

         RET                 ;AND RETURN


;============================================================
;    THIS TEST WILL CHECK THE FOUR 16 BIT FUNCTIONS
;    BY ADDING A NUMBER TO ITSELF- THEN SUBTRACTING ITSELF-
;    THEN MULTIPLYING AND DIVIDING.  THE RESULT SHOULD BE THE
;    ORIGIONAL NUMBER

NUM       DB        0,0FH,0,0FH

APUT7:
         MVI       C,APUDAT
         MVI       B,4       ;MOVING 4 BYTES
         LXI       H,NUM+3   ;START WITH THE LOW BIT
         OUTDR               ;LOAD THE APU
         MVI       A,SADD    ;GET READY TO ADD
         CALL      OUTIT     ;DO THE ADD

         MVI       B,2       ;READY TO LOAD ANOTHER OPERAND
         LXI       H,NUM+1
         OUTDR               ;LOAD THE APU
         MVI       A,SSUB    ;GET READY TO SUBTRACT
         CALL      OUTIT     ;DO THE SUBTRACT

         MVI       B,2       ;READY TO LOAD NEXT OPERAND
         LXI       H,NUM+1
         OUTDR               ;LOAD THE APU
         MVI       A,SMUL    ;GET READY TO MULTIPLY
         CALL      OUTIT     ;DO THE MULTIPLY


         MVI       B,2       ;READY TO LOAD NEXT OPERAND
         LXI       H,NUM+1
         OUTDR               ;LOAD THE APU
         MVI       A,SDIV
         CALL      OUTIT     ;DI THE DIVIDE
�          LXI       H,APUSTOR ;GET READY TO STORE THE RESULTS
         MVI       B,2       ;IT WILL BE 2 BYTES LONG
         INIR                ;MOVE IT INTO MEMORY

         LXI       H,NUM     ;GET THE ADDRESS OF THE NUMBER
         LXI       D,APUSTOR ;GET THE ADDRESS OF THE RESULT
         LXI       B,2       ;ITS TWO BYTES LONG
         CALL      COMPX     ;COMPAIR THE RESULTS

         RET                 ;TO THE BACKGROUND


;============================================================
;    THIS TEST WILL DO A TEST OF THE FOLLOWING FUNCTIONS
;    SQRT, PWR, FIXD, FLTD, CHSF
;
NUMX      DB        0,0,0FH,0FFH
NUMY      DB        0,0,0,2
RES1      DB        0,0FFH,0E0H,01
RES2      DB        0,0FFH,0DFH
APOP4:    LXI       H,APUSTOR ;GET READY TO STORE THE RESULTS
         MVI       B,4       ;4 BYTES OF DATA 32 BITS
         INIR                ;MOVE IT INTO MEMORY
         RET

APUSH4:   MVI       B,4       ;PUSHING IN 4 BYTES
         LXI       H,APUSTOR+3 ;USE THE LAST ANSWER
         OUTDR
         RET

GOCOMP:   LXI       D,APUSTOR ;THE ADDRESS OF THE RESULT
         LXI       B,3       ;TESTING 3 BYTES
         CALL      COMPX     ;DO THE COMPAIR
         RET

APUT8:    MVI       C,APUDAT  ;GET THE OUTPUT PORT
         MVI       B,4       ;GOING TO PUSH IN 4 BYTES
         LXI       H,NUMX+3
         OUTDR               ;LOAD THE APU

         MVI       A,FLTD    ;CONVERT TO FLOATING POINT
         CALL      OUTIT

         MVI       A,FIXD    ;CONVERT TO FIXED
         CALL      OUTIT

         CALL      APOP4     ;GET THE TOS
         LXI       H,NUMX    ;RESULT SHOULD BE WHAT WAS PUT IN
         CALL      GOCOMP

APWR:     MVI       C,APUDAT
         CALL      APUSH4    ;GET THE NUMBER BACK
         MVI       A,FLTD    ;CONVERT TO F.P
         CALL      OUTIT
�          MVI       B,4
         LXI       H,NUMY+3  ;PUSH IN TO POWER OF TEN
         OUTDR
         MVI       A,FLTD    ;FLOAT IT
         CALL      OUTIT

         MVI       A,PWR     ;RAISE TO THE PWR OF NUMY
         CALL      OUTIT

         MVI       A,FIXD    ;CONVERT TO FIXED
         CALL      OUTIT

         CALL      APOP4     ;GET THE RESULT
         LXI       H,RES2    ;SHOULD BE RESULT 2
         CALL      GOCOMP    ;GO DO THE COMPAIR

SQRTT:    MVI       C,APUDAT
         MVI       B,4
         LXI       H,RES1+3
         OUTDR

         MVI       A,FLTD    ;CONVERT TO F.P
         CALL      OUTIT

         MVI       A,SQRT    ;TAKE THE SQUARE ROOT
         CALL      OUTIT

         MVI       A,FIXD    ;CONVERT TO FIXED POINT
         CALL      OUTIT

         CALL      APOP4
         LXI       H,NUMX    ;THE RESULT SHOULD BE NUMX
         CALL      GOCOMP


         RET                 ;FROM TEST 8


;============================================================
;THIS IS THE MAIN DRIVER FOR THIS MODULE
;============================================================
;
APUT:                  ;SAVE THE REGISTERS FOR PASCAL
         PUSH      H

         XRA       A
         STA       APUERR    ;ZERO THE ERROR FLAG
         STA       APUERR+1

INIT:     MVI       A,1AH     ;TO INITIALIZE , PUSH PI
         CALL      OUTIT     ;ONTO STACK
         MVI       B,16      ;WE WILL POP NO MORE THAN 16
INIT1:    IN        APUDAT    ;READ THE DATA PORT
         CPI       0DAH      ;THIS IS WHAT IT SHOULD BE
         JZ        T1        ;CHECK THE WHOLE STACK �          DCR       B         ;COUNT IT
         JNZ       INIT1
         LXI       H,APUERR+1
         MVI       M,01H
         JMP       XIT

T1:       MVI       A,ATEST1  ;SET THE TEST BEING DONE
         STA       ATEST
         CALL      APUT1   ;CALL THE TEST

T2:       MVI       A,ATEST2
         STA       ATEST
         CALL      APUT2

T3:       MVI       A,ATEST3
         STA       ATEST
         CALL      APUT3


T4:       MVI       A,ATEST4
         STA       ATEST
         CALL      APUT4

T5:       MVI       A,ATEST5
         STA       ATEST
         CALL      APUT5

T6:       MVI       A,ATEST6
         STA       ATEST
         CALL      APUT6

T7:       MVI       A,ATEST7
         STA       ATEST
         CALL      APUT7

T8:       MVI       A,ATEST8
         STA       ATEST
         CALL      APUT8

XIT:      XRA       A         ;GET READY TO RETURN TO PASCAL
         LXI       H,APUERR  ;THE ADDRESS OF THE ERROR FLAG
         MOV       E,M       ;PUT THE ERROR FLAG IN E
         INX       H
         MOV       D,M       ;ZERO D
         POP       H
         RET                 ;RETURN TO PASCAL