home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / GENASM / EDUCATOR.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  17KB  |  612 lines

  1. ;
  2. ;        EDUCATOR-8080
  3. ;
  4. ;Originally written by the Digital Group
  5. ;Converted to run on CP/M BY Keith Petersen,
  6. ;W8SDZ, July 28, 1980.
  7. ;
  8. BKSPC    EQU    08H    ;BACKSPACE
  9. CR    EQU    0DH    ;CARRIAGE RETURN
  10. LF    EQU    0AH    ;LINE FEED
  11. CLR    EQU    1AH    ;SCREEN CLEAR CHARACTER
  12. DEL    EQU    7FH    ;DELETE (RUBOUT)
  13. ;
  14.     ORG    100H
  15. ;
  16. ;THE CONTROL ROUTINE IS THE TOP OF THE STRUCTURE AND
  17. ;CONTROLS THE OPERATION OF THE ENTIRE PROGRAM.
  18. ;
  19. CNTRL:    LXI    SP,STACK ;SET STACK POINTER
  20.     LHLD    1    ;GET CBIOS POINTER
  21.     LXI    D,3    ;READY FOR DAD
  22.     DAD    D    ;CONSTAT
  23.     DAD    D    ;CONIN
  24.     SHLD    VCONIN+1 ;MODIFY CALL ADDRESS
  25.     DAD    D    ;CONOUT
  26.     SHLD    VCONOUT+1 ;MODIFY CALL ADDRESS
  27. ;
  28. NOTZER:    CALL    DSPLY    ;DISPLAY CONTENTS OF REGISTERS
  29.     CALL    CMDNT    ;ENTER A COMMAND
  30.     CALL     FETCH    ;FETCH THE CORRECT OPCODE
  31.     ORA    A    ;SET ZERO FLAG AS PER CONTENTS
  32.     JNZ    NOTZER    ;JUMP IF NOT ZERO ERROR OCCURED
  33.     CALL    XQTER    ;GO EXECUTE THE CURRENT COMMAND
  34.     JMP    NOTZER    ;LOOP FOREVER
  35. ;
  36. ;THIS DISPLAY ROUTINE CONTROLS THE GENERATION OF THE DYNAMIC
  37. ;DISPLAY.
  38. ;
  39. DSPLY:    LXI    H,TITLS    ;LOAD ADDRESS OF TITLES INTO HL
  40.     CALL    CHEDT    ;DISPLAY TITLES
  41.     LXI    H,BLINE    ;LOAD ADDR OF BLINE TITLE
  42.     LDA    BREG    ;LOAD CONTENTS OF BREG INTO A
  43.     CALL    DSPCV    ;CONVERT AND DISPLAY
  44.     LXI    H,CLINE    ;LOAD ADDR OF CLINE TITLE
  45.     LDA    CREG    ;LOAD CONTENTS OF CREG INTO A
  46.     CALL    DSPCV    ;CONVERT AND DISPLAY
  47.     LXI    H,AFHDR    ;LOAD ADDR OF A FLAGS TITLE
  48.     CALL    CHEDT    ;DISPLAY TITLES
  49.     LHLD    PSWA    ;LOAD FLAGS AND A INTO HL
  50.     MOV    A,L    ;MOVE FLAGS TO A
  51.     ANI    4    ;AND OFF ALL BUT PARITY FLAG
  52.     CALL    DSPFG    ;DISPLAY THE FLAG VALUE
  53.     MOV    A,L    ;MOVE FLAGS TO A
  54.     ANI    40H    ;AND OFF ALL BUT ZERO FLAG
  55.     CALL    DSPFG    ;DISPLAY THE FLAG VALUE
  56.     MOV    A,L    ;MOVE FLAGS TO A
  57.     ANI    80H    ;AND OFF ALL BUT SIGN FLAG
  58.     CALL    DSPFG    ;DISPLAY THE FLAG VALUE
  59.     MOV    A,L    ;MOVE FLAGS TO A
  60.     ANI    10H    ;AND OFF ALL BUT AUX. CARRY FLAG
  61.     CALL    DSPFG    ;DISPLAY THE FLAG VALUE
  62.     MOV    A,L    ;MOVE FLAGS TO A
  63.     ANI    1    ;AND OFF ALL BUT CARRY FLAG
  64.     CALL    DSPFG    ;DISPLAY THE FLAG VALUE
  65.     MOV    A,H    ;MOVE A REGISTER VALUE TO A
  66.     CALL    DSPCN    ;DISPLAY WITH NO TITLE PRINT
  67.     RET        ;RETURN TO THE CNTRL ROUTINE
  68. ;
  69. ;THE DISPLAY CONVERSION ROUTINE PRINTS BINARY,
  70. ;OCTAL AND HEXADECIMAL.
  71. ;
  72. DSPCV:    PUSH    PSW    ;SAVE OUTPUT VALUE FOR CHEDT
  73.     CALL    CHEDT    ;DISPLAY LINE TITLE ADDR IN HL
  74.     POP    PSW    ;RETRIEVE SAVED OUTPUT VALUE
  75. ;
  76. DSPCN:    MVI    E,8    ;MOVE 8 TO E REGISTER
  77. ;
  78. DSPBT:    RLC        ;ROTATE MSB INTO CARRY AND LSB
  79.     PUSH    PSW    ;SAVE CURRENT VALUE
  80.     ANI    1    ;AND OFF ALL BUT LSB
  81.     CALL    DSPFG    ;GO DISPLAY BIT VALUE
  82.     POP    PSW    ;RETRIEVE SAVED CURRENT VALUE
  83.     DCR    E    ;DECREMENT LOOP COUNT
  84.     JNZ    DSPBT    ;JUMP IF LOOP COUNT NOT ZERO
  85.     ORA    A    ;RESET CARRY
  86.     MVI    E,3    ;MOVE 3 TO E REGISTER
  87. ;
  88. DSPQT:    RAL        ;MSB TO CARRY, CARRY TO LSB
  89.     RAL        ;DO IT AGAIN,
  90.     RAL        ; THREE TIMES FOR OCTAL DIGIT
  91.     PUSH    PSW    ;SAVE CURRENT VALUE
  92.     ANI    7    ;AND OFF ALL BUT OCTAL LSD
  93.     ORI    '0'    ;MAKE ASCII
  94.     CALL    CHRPR    ;OUTPUT THE CHARACTER
  95.     POP    PSW    ;RETRIEVE SAVED CURRENT VALUE
  96.     DCR    E    ;DECREMENT LOOP COUNT
  97.     JNZ    DSPQT    ;JUMP IF LOOP COUNT NOT ZERO
  98.     CALL    DSPSP    ;OUTPUT A SPACE
  99.     MVI    E,2    ;MOVE 2 TO E
  100. ;
  101. DSPHT:    RLC        ;ROTATE MSB INTO CARRY AND LSB
  102.     RLC        ;DO IT AGAIN
  103.     RLC        ; FOUR TIMES FOR
  104.     RLC        ;  HEXADECIMAL SHIFT
  105.     PUSH    PSW    ;SAVE CURRENT VALUE
  106.     ANI    0FH    ;AND OFF ALL BUT HEX LSD
  107.     ADI    '0'    ;ADD ON BITS TO MAKE ASCII
  108.     CPI    '9'+1    ;COMPARE RESULT TO ONE MORE THAN 9
  109.     JC    DSPHS    ;IF NUMERIC THEN SKIP ADJUSTMENT
  110.     ADI    7    ;ADD 7 GIVING ASCII A-F CODES
  111. ;
  112. DSPHS:    CALL    CHRPR    ;OUTPUT THE CHARACTER
  113.     POP    PSW    ;RETRIEVE SAVED CURRENT VALUE
  114.     NOP    
  115.     DCR    E    ;DECREMENT LOOP COUNT
  116.     JNZ    DSPHT    ;JUMP IF LOOP COUNT NOT ZERO
  117.     RET        ;RETURN TO CALLING ROUTINE
  118. ;
  119. ;DISPLAY FLAG OR BINARY DIGIT FOLLOWED BY A SPACE.  ALTERNATE
  120. ;ENTRY IS USED TO DISPLAY A SPACE.
  121. ;
  122. DSPFG:    JZ    DSPFZ    ;JUMP IF PASSED VALUE IS A ZERO
  123.     MVI    A,1    ;OTHERWISE MOVE A 1 INTO A
  124. ;
  125. DSPFZ:    ADI    '0'    ;CONVERT INTO ASCII NUMERIC CHAR.
  126.     CALL    CHRPR    ;OUTPUT THE CHARACTER
  127. ;
  128. DSPSP:    PUSH    PSW    ;SAVE THE FLAGS AND VALUE IN A
  129.     MVI    A,' '    ;MOVE SPACE INTO A
  130.     CALL    CHRPR    ;OUTPUT THE SPACE
  131.     POP    PSW    ;RETRIEVE THE SAVED FLAGS AND A
  132.     RET        ;RETURN TO THE CALLING ROUTINE
  133. ;
  134. ;THE CHARACTER STRING OUTPUT EDIT ROUTINE.
  135. ;
  136. CHEDT:    MOV    A,M    ;MOVE NEXT CHARACTER INTO A
  137.     CPI    80H    ;COMPARE IT TO 200 OCTAL
  138.     RZ        ;RETURN IF EQUAL IT'S END OF STRING
  139.     JNC    CHSPA    ;JUMP IF GREATER FOR SPACE ROUTINE
  140.     CALL    CHRPR    ;ELSE GO OUTPUT THE CHARACTER
  141. ;
  142. CHEND:    INX    H    ;INCREMENT THE STRING INDEX
  143.     JMP    CHEDT    ;LOOP FOR NEXT CHARACTER
  144. ;
  145. CHSPA:    SUI    80H    ;SUBTRACT 200 OCTAL FROM VALUE
  146.     MOV    B,A    ;MOVE SPACE COUNT TO B
  147. ;
  148. CHSPL:    MVI    A,' '    ;MOVE SPACE INTO A
  149.     CALL    CHRPR    ;OUTPUT THE SPACE
  150.     DCR    B    ;DECREMENT SPACE COUNT
  151.     JNZ    CHSPL    ;JUMP IF COUNT NOT ZERO TO START OF LOOP
  152.     JMP    CHEND    ;JUMP BACK INTO CHEDT LOOP
  153. ;
  154. ;THE COMMAND ENTRY ROUTINE ACCEPTS INPUT FROM THE KEYBOARD
  155. ;FOR COMMANDS.
  156. ;
  157. CMDNT:    LXI    H,CMDMS    ;MOVE ADDRESS OF COMMAND? INTO HL
  158.     CALL    CHEDT    ;DISPLAY THE MESSAGE
  159.     LXI    H,CMDAR    ;MOVE ADRS OF COMMAND INPUT AREA HL
  160.     MVI    B,22    ;MOVE MAXIMUM LENGTH TO B
  161. ;
  162. CMDKB:    CALL    KEYBD    ;GET AN INPUT CHARACTER
  163.     CPI    'L'-40H    ;IS IT A CONTROL-L LINE DELETE?
  164.     JZ    CNTRL    ;IF SO THEN RESTART PROGRAM
  165.     CPI    CR    ;IS IT A CARRIAGE RETURN?
  166.     JZ    CMDND    ;IF SO THEN GO COMPRESS INPUT
  167.     CPI    DEL    ;IS IT A DELETE CHARACTER?
  168.     JNZ    CMDST    ;IF NOT THEN GO STORE THE CHARACTER
  169.     MVI    A,BKSPC    ;IF SO REPLACE WITH BACKSPACE
  170. ;
  171. CMDST:    MOV    M,A    ;STORE INPUT CHAR. IN COMMAND BUFFER
  172.     CALL    CHRPR    ;DISPLAY THE INPUT CHARACTER
  173.     INX    H    ;INCREMENT COMMAND WORK AREA INDEX
  174.     DCR    B    ;DECREMENT COMMAND LENGTH COUNT
  175.     JNZ    CMDKB    ;IF NOT FULL THEN REITERATE
  176.     MVI    A,1    ;IF BUFFER FULL THEN SELECT ERROR
  177.     CALL    ERROR    ; NUMBER 1 AND PRINT ITS MSG.
  178.     JMP    CNTRL    ;RESTART THE PROGRAM
  179. ;
  180. ;THE COMMAND COMPRESS ROUTINE ELIMINATES ALL BUT LETTERS 
  181. ;AND NUMBERS.
  182. ;
  183. CMDND:    LXI    H,CMDAR    ;LOAD HL WITH ADRS OF WORK AREA
  184.     PUSH    H    ;PUSH & POP MOVE IT TO DE
  185.     POP    D    ; AS THE COMPRESSION POINTER
  186.     MVI    A,22    ;LOAD A WITH MAXIMUM LENGTH
  187.     SUB    B    ;SUBTRACT REMAINING LENGTH FROM B
  188.     MOV    B,A    ;MOVE ACTUAL LENGTH TO B
  189. ;
  190. CMDNX:    MOV    A,M    ;MOVE COMMAND CHARACTER TO A
  191.     CPI    BKSPC    ;IS IT BACKSPACE?
  192.     JNZ    CMDCH    ;IF NOT THEN GO TO OTHER TESTS
  193.     MVI    A,CMDAR AND 0FFH ;LOW ADRS BYTE OF CMDAR TO A
  194.     CMP    E    ;COMPARE TO CURRENT LOW ADRS BYTE
  195.     JNC    CMDNS    ;IF NOT GREATER THEN SKIP SAVE
  196.     DCX    D    ;ELSE BACK UP COMPRESSION POINTER
  197.     JMP    CMDNS    ;SKIP SAVING THE CHARACTER
  198. ;
  199. CMDCH:    CPI    '0'    ;IS THE CHARACTER LESS THAN '0'?
  200.     JC    CMDNS    ;IF SO THEN SKIP SAVING IT
  201.     CPI    '9'+1    ;IS THE CHARACTER LESS THAN '9'+1?
  202.     JC    CMDSV    ;IF SO THEN SAVE NUMERIC VALUE
  203.     CPI    'A'    ;IS THE CHARACTER LESS THAN 'A'?
  204.     JC    CMDNS    ;IF SO THEN SKIP SAVING IT
  205.     CPI    'Z'+1    ;IS THE CHARACTER GREATER THAN 'Z'?
  206.     JNC    CMDNS    ;IF SO THEN SKIP SAVING IT
  207. ;
  208. CMDSV:    STAX    D    ;STORE CHARACTER IN COMPRESSED AREA
  209.     INX    D    ;INCREMENT COMPRESSION POINTER INDEX
  210. ;
  211. CMDNS:    INX    H    ;INCREMENT INPUT STRING POINTER
  212.     DCR    B    ;DECREMENT ACTUAL LENGTH COUNT
  213.     JNZ    CMDNX    ;IF LENGTH IS NOT ZERO THEN REITERATE
  214.     RET        ;ELSE RETURN TO CNTRL CALLING POINT
  215. ;
  216. ;THE FETCH INSTRUCTION/COMMAND ROUTINE VALIDATES AND BUILDS THE
  217. ;OBJECT CODE.
  218. ;
  219. FETCH:    LXI    H,OPTAB    ;LOAD ADDRESS OF OPCODE TABLE HL
  220.     MVI    E,31    ;MOVE TABLE ELEMENT COUNT TO E
  221. ;
  222. FLOOP:    PUSH    H    ;SAVE CURRENT ELEMENT ADDRESS
  223.     LXI    B,CMDAR    ;LOAD ADDRESS OF CMDAR INTO BC
  224.     MVI    D,3    ;MOVE OPCODE LENGTH TO D
  225. ;
  226. FCOMP:    LDAX    B    ;LOAD COMMAND CHARACTER TO A INDEXED BY B
  227.     CMP    M    ;COMPARE IT TO TABLE CHARACTER
  228.     JNZ    FNXEL    ;IF NOT EQUAL THEN GO TO NEXT ELEMENT
  229.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  230.     INX    H    ;INCREMENT TABLE CHARACTER INDEX
  231.     DCR    D    ;DECREMENT OPCODE LENGTH COUNTER
  232.     JNZ    FCOMP    ;IF NOT ZERO CONTINUE TEST LOOP
  233.     XTHL        ;EXCHANGE HL WITH TOP OF STACK
  234.     POP    H    ;POP HL FROM STACK TO CLEAR IT
  235.     MOV    E,M    ;MOVE NAKED OPCODE TO E,D IS ZERO
  236.     PUSH    D    ;SAVE NAKED OPCODE
  237.     INX    H    ;INCREMENT TABLE POINTER
  238.     MOV    E,M    ;DECODE ROUTINE LOW ADDRESS BYTE TO E
  239.     INX    H    ;INCREMENT TABLE POINTER
  240.     MOV    D,M    ;DECODE ROUTINE HIGH ADDRESS BYTE TO D
  241.     XCHG        ;MOVE DECODE ROUTINE ADDRESS TO HL
  242.     POP    D    ;UNSAVE NAKED OPCODE TO DE
  243.     XRA    A    ;CLEAR A, NO ERROR CODE
  244.     PCHL        ;JUMP TO ADDRESS OF DECODE ROUTINE
  245. ;
  246. FNXEL:    LXI    B,6    ;LOAD DOUBLE LENGTH 6 INTO BC
  247.     POP    H    ;UNSAVE CURRENT ELEMENT ADDRESS
  248.     DAD    B    ;ADD 6 TO IT
  249.     DCR    E    ;DECREMENT TABLE ELEMENT COUNT
  250.     JNZ    FLOOP    ;REITERATE TO TEST NEXT ELEMENT
  251.     MVI    A,2    ;MOVE ERROR CODE 2 TO A
  252.     JMP    ERROR    ;GO DISPLAY ERROR 2, OPCODE UNKNOWN
  253.     NOP        ;NO OPERATION FILLER
  254. ;
  255. ;THE INSTRUCTION DECODER ROUTINES FOLLOW
  256. ;INSTRUCTIONS USING THE DIRCT ROUTINE REQUIRE NO DECODING.
  257. ;EXAMPLE: RAL, CMA, ETC.
  258. ;
  259. DIRCT:    RET        ;RETURN TO CNTRL FOR EXECUTION
  260. ;
  261. ;THE MOVRT IS USED ONLY BE THE MOV COMMAND
  262. ;
  263. MOVRT:    CALL    RG543    ;VALIDATE DESTINATION REGISTER
  264.     ORA    A    ;SET FLAGS BASED ON A CONTENTS
  265.     RNZ        ;RETURN NOT ZERO WITH ERROR
  266. ;
  267. ;INSTRUCTIONS USING THE RG210 ROUTINE REQUIRE A SOURCE REGISTER
  268. ;
  269. RG210:    LDAX    B    ;LOAD NEXT COMMAND CHARACTER INTO A
  270.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  271.     CALL    REGAN    ;ANALYZE FOR VALID REGISTER
  272.     JNC    RGERR    ;IF CY=0 THEN REGISTER NOT VALID
  273.     ADD    E    ;ADD NAKED OPCODE TO REGISTER VALUE
  274.     MOV    E,A    ;MOVE RESULT BACK TO E
  275.     XRA    A    ;CLEAR A INDICATING NO ERRORS
  276.     RET        ;RETURN TO CNTRL
  277. ;
  278. ;THE REGISTER ERROR ROUTINE IS USED TO INDICATE REGISTER
  279. ;DESIGNATION ERRORS
  280. ;
  281. RGERR:    MVI    A,3    ;MOV ERROR CODE 3 TO A
  282.     JMP    ERROR    ;GO DISPLAY ERROR 3, INVALID REGISTER
  283. ;
  284. ;THE REGISTER ANALYSIS AND VALIDATION ROUTINE IS USED BY RG543,
  285. ;RG210, AND RG54B
  286. ;
  287. REGAN:    SUI    'A'    ;SUBTRACT AN 'A' FROM THE CHARACTER
  288.     CPI    3    ;COMPARE THE RESULT TO 3
  289.     RNC        ;IF NOT LESS THAN 3 RETURN WITH CY=0
  290.     DCR    A    ;DECREMENT RESULT: A=377,B=000,C=001
  291.     ANI    7    ;AND OFF ALL BUT OCTAL LSD
  292.     STC        ;SET CY=1 INDICATING NO ERROR
  293.     RET        ;RETURN TO CALLING ROUTINE
  294. ;
  295. ;THE MVIRT IS USED ONLY BY THE MVI COMMAND
  296. ;
  297. MVIRT:    CALL    RG543    ;VALIDATE DESTINATION REGISTER
  298.     ORA    A    ;SET FLAGS BASED ON A CONTENTS
  299.     RNZ        ;RETURN NOT ZERO WITH ERROR
  300. ;
  301. ;INSTRUCTIONS REQUIRING AN IMMEDIATE OPERAND USE THE IMMED
  302. ;ROUTINE
  303. ;
  304. IMMED:    LDAX    B    ;LOAD NEXT COMMAND CHARACTER INTO A
  305.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  306.     CPI    'B'    ;IS THE CMND CHAR. A 'B' ?
  307.     JZ    BINRY    ;IF SO THEN PROCESS AS BINARY
  308.     CPI    'Q'    ;IS THE COMMAND CHARACTER A 'Q'?
  309.     JZ    OCTAL    ;IF SO THEN PROCESS AS OCTAL
  310.     CPI    'H'    ;IS THE CMND CHAR. AN 'H' ?
  311.     JZ    HEX    ;IF SO THEN PROCESS AS HEXADECIMAL
  312.     CPI    '8'    ;IS THE COMMAND CHARACTER LESS THAN '8'?
  313.     JC    OCTAD    ;IF SO THEN TREAT AS OCTAL
  314.     MVI    A,5    ;MOVE ERROR CODE 5 TO A
  315.     JMP    ERROR    ;GO DISPLAY ERROR 5, INVALID IMMEDIATE
  316. ;
  317. ;INSTRUCTIONS USING THE RG543 ROUTINE REQUIRE A DESTINATION
  318. ;REGISTER
  319. ;
  320. RG543:    LDAX    B    ;LOAD NEXT COMMAND CHARACTER INTO A
  321.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  322.     CALL    REGAN    ;ANALYZE FOR VALID REGISTER
  323.     JNC    RGERR    ;IF CY=0 THEN REGISTER NOT VALID
  324.     RLC        ;SHIFT OCTAL REGISTER VALUE
  325.     RLC        ;LEFT THREE
  326.     RLC        ; PLACES
  327.     ADD    E    ;ADD NAKED OPCODE TO SHIFTED VALUE
  328.     MOV    E,A    ;MOVE RESULT BACK TO E
  329.     XRA    A    ;CLEAR A INDICATING NO ERRORS
  330.     RET        ;RETURN TO CALLING ROUTINE
  331. ;
  332. ;INSTRUCTIONS USING THE RG54B ROUTINE ARE INX AND DCX
  333. ;
  334. RG54B:    LDAX    B    ;LOAD NEXT COMMAND CHARACTER INTO A
  335.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  336.     CALL    REGAN    ;ANALYZE FOR VALID REGISTER
  337.     CPI    0    ;IS THE REGISTER A ZERO?
  338.     RZ        ;IF SO IT'S 'B' SO RETURN
  339.     MVI    A,4    ;MOVE ERROR CODE 4 TO A
  340.     JMP    ERROR    ;GO DISPLAY ERROR 4, INVALID REGISTER
  341. ;
  342. ;THE BINARY ROUTINE CONVERTS A BINARY IMMEDIATE VALUE INTO
  343. ;USABLE FORM
  344. ;
  345. BINRY:    MVI    H,8    ;MOVE 8 TO H FOR COUNT
  346. ;
  347. BLOOP:    LDAX    B    ;LOAD NEXT COMMAND CHARACTER INTO A
  348.     SUI    '0'    ;SUBTRACT A '0' FROM IT
  349.     CPI    2    ;IS THE RESULT LESS THAN 2?
  350.     JNC    IMMER    ;IF NOT THEN GO DISPLAY IMMEDIATE ERROR
  351.     PUSH    H    ;SAVE THE COUNT
  352.     MOV    L,D    ;MOVE D TO L (IMMEDIATE BYTE)
  353.     DAD    H    ;SHIFT HL LEFT ONE BIT
  354.     ADD    L    ;ADD L TO BIT IN A
  355.     MOV    D,A    ;MOVE THE RESULT BACK TO D
  356.     POP    H    ;UNSAVE THE COUNT
  357.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  358.     DCR    H    ;DECREMENT THE COUNT
  359.     JNZ    BLOOP    ;IF NOT ZERO THEN REITERATE
  360.     XRA    A    ;CLEAR A INDICATING NO ERRORS
  361.     RET        ;RETURN TO CNTRL
  362. ;
  363. ;THE IMMEDIATE ERROR ROUTINE IS USED TO INDICATE IMMEDIATE VALUE 
  364. ;ERRORS
  365. ;
  366. IMMER:    MVI    A,6    ;MOVE ERROR CODE 3 TO A
  367.     JMP    ERROR    ;GO DISPLAY ERROR 3, INVALID IMMEDIATE
  368. ;
  369. ;THE OCTAD ENTRY POINT TO THE OCTAL ROUTINE IS FOR THE DEFAULT
  370. ;CONDITION
  371. ;
  372. OCTAD:    DCX    B    ;DECREMENT COMMAND CHARACTER INDEX
  373. ;
  374. ;THE OCTAL ROUTINE CONVERTS AN OCTAL IMMEDIATE VALUE INTO
  375. ;USABLE FORM
  376. ;
  377. OCTAL:    MVI    H,3    ;MOVE A 3 INTO H FOR COUNT
  378. ;
  379. OLOOP:    LDAX    B    ;LOAD NEXT COMMAND CHARACTER INTO A
  380.     SUI    '0'    ;SUBTRACT A '0' FROM IT
  381.     CPI    8    ;IS CMND LESS THAN 8?
  382.     JNC    IMMER    ;IF NOT GO DISP IMMED ERROR
  383.     PUSH    H    ;SAVE THE COUNT
  384.     MOV    L,D    ;MOVE D TO L IMMED BYTE
  385.     DAD    H    ;SHIFT IMMEDIATE
  386.     DAD    H    ;  BYTE LEFT
  387.     DAD    H    ;    THREE BITS
  388.     ADD    L    ;ADD L TO VALUE IN A
  389.     MOV    D,A    ;MOVE RESULT BACK TO D
  390.     POP    H    ;UNSAVE THE COUNT
  391.     INX    B    ;INCREMENT COMND CHAR INDEX
  392.     DCR    H    ;DECREMENT THE COUNT
  393.     JNZ    OLOOP    ;IF NOT ZERO THEN REITERATE
  394.     XRA    A    ;CLEAR A INDICATING NO ERRORS
  395.     RET        ;RETURN TO CNTRL
  396. ;
  397. ;THE HEX ROUTINE COVERTS A HEXADECIMAL IMMEDIATE VALUE INTO
  398. ;USABLE FORM. 
  399. ;
  400. HEX:    MVI    H,2    ;MOVE A 2 INTO H FOR COUNT
  401. ;
  402. HLOOP:    LDAX    B    ;LOAD NEXT CMND CHAR INTO A
  403.     SUI    '0'    ;SUBTRACT '0' FROM IT
  404.     CPI    9+1    ;IS IT LESS THAN '9'+1?
  405.     JC    HCHOK    ;IF SO THEN NUMERIC CHARACTER IS OK
  406.     SUI    7    ;ELSE CONVERT ALPHABETIC TO NUMERIC
  407.     CPI    15+1    ;IS CHARACTER VALUE GREATER THAN 15?
  408.     JNC    IMMER    ;IF SO THAN INVALID HEXADECIMAL VALUE
  409. ;
  410. HCHOK:    PUSH    H    ;SAVE THE COUNT
  411.     MOV    L,D    ;MOVE D TO L IMMEDIATE BYTE
  412.     DAD    H    ;SHIFT IMMEDIATE
  413.     DAD    H    ; BYTE LEFT
  414.     DAD    H    ;  FOUR
  415.     DAD    H    ;   BITS
  416.     ADD    L    ;ADD L TO VALUE IN A
  417.     MOV    D,A    ;MOVE RESULT BACK TO D
  418.     POP    H    ;UNSAVE THE COUNT
  419.     INX    B    ;INCREMENT COMMAND CHARACTER INDEX
  420.     DCR    H    ;DECREMENT THE COUNT
  421.     JNZ    HLOOP    ;IF NOT ZERO THAN REITERATE
  422.     XRA    A    ;CLEAR A INDICATING NO ERRORS
  423.     RET        ;RETURN TO CNTRL
  424. ;
  425. ;THE XQTER ROUTINE EXECUTES THE GENERATED OBJECT CODE FOR
  426. ;EDUCATOR 8080
  427. ;
  428. XQTER:    XCHG        ;MOVE GENERATED OPCODE TO HL
  429.     SHLD    XQTOP    ;STORE IT AT EXECUTION POINT
  430.     LHLD    PSWA    ;LOAD WORKING PSW & A INTO HL
  431.     PUSH    H    ;PUSH & POP SETS VALUES FOR
  432.     POP    PSW    ; WORKING REGISTER AND FLAGS
  433.     LHLD    BANDC    ;LOAD WORKING B AND C INTO HL
  434.     PUSH    H    ;PUSH & POP SETS VALUES FOR
  435.     POP    B    ; WORKING B AND C REGISTERS
  436. ;
  437. XQTOP:    NOP        ;THE COMMAND TO BE EXECUTED
  438.     NOP        ;IMMEDIATE VALUE OR NOP
  439.     PUSH    B    ;PUSH B AND C WORKING REGISTER VALUES
  440.     POP    H    ;POP THEM INTO HL
  441.     SHLD    BANDC    ;STORE THEM IN SAVE AREA
  442.     PUSH    PSW    ;PUSH PSW AND A WORKING VALUES
  443.     POP    H    ;POP THEM INTO HL
  444.     SHLD    PSWA    ;STORE THEM IN SAVE AREA
  445.     RET        ;RETURN TO CNTRL FOR NEXT COMMAND
  446. ;
  447. ;THE ERROR ROUTINE IS USED TO DISPLAY ERROR MESSAGES
  448. ;
  449. ERROR:    PUSH    PSW    ;SAVE ERROR CODE IN A
  450.     LXI    H,ERRSP    ;LOAD ADDRESS OF ERROR HEADER SPACES
  451.     CALL    CHEDT    ;GO OUTPUT ERROR HEADER SPACES
  452.     POP    PSW    ;UNSAVE ERROR CODE
  453.     LXI    H,ERTAB    ;LOAD ADDRESS OF ERROR MESSAGE TABLE
  454.     ADD    L    ;ADD LOW ADDRESS BYTE TO ERROR CODE
  455.     MOV    L,A    ;MOVE RESULT TO L, POINTS TO OFFSET
  456.     MOV    L,M    ;MOVE OFFSET TO L
  457. ;
  458. ;NOTE: HL NOW CONTAINS THE ADDRESS OR THE ERROR MESSAGE
  459. ;
  460.     CALL    CHEDT    ;OUTPUT THE ERROR MESSAGE
  461. ;
  462. ERTIM:    LXI    D,0    ;LOAD DE WITH TIMING LOOP VALUE
  463.     DCR    E    ;DECREMENT VALUE IN E 256 TIMES
  464.     JNZ    ERTIM+1    ;REITERATE LOOP 256 TIMES
  465. ;
  466. ;THE ABOVE JMP GOES TO THE FIRST 000 IN THE LXI COMMAND WHICH
  467. ;IS AN EFFECTIVE NOP
  468. ;
  469.     DCR    D    ;DECREMENT D
  470.     JNZ    ERTIM+1    ;REITERATE OUTER LOOP 256 TIMES
  471.     MVI    A,0FFH    ;MOVE A 377 TO A INDICATING ERROR
  472.     RET        ;RETURN TO CNTRL
  473. ;
  474. OPTAB:    DB    'ACI',0CEH
  475.     DW    IMMED
  476.     DB    'ADC',88H
  477.     DW    RG210
  478.     DB    'ADD',80H
  479.     DW    RG210
  480.     DB    'ADI',0C6H
  481.     DW    IMMED
  482.     DB    'ANA',0A0H
  483.     DW    RG210
  484.     DB    'ANI',0E6H
  485.     DW    IMMED
  486.     DB    'CMA',2FH
  487.     DW    DIRCT
  488.     DB    'CMC',3FH
  489.     DW    DIRCT
  490.     DB    'CMP',0B8H
  491.     DW    RG210
  492.     DB    'CPI',0FEH
  493.     DW    IMMED
  494.     DB    'DAA',27H
  495.     DW    DIRCT
  496.     DB    'DCR',05H
  497.     DW    RG543
  498.     DB    'DCX',0BH
  499.     DW    RG54B
  500.     DB    'INR',04H
  501.     DW    RG543
  502.     DB    'INX',03H
  503.     DW    RG54B
  504.     DB    'MOV',40H
  505.     DW    MOVRT
  506.     DB    'MVI',06H
  507.     DW    MVIRT
  508.     DB    'NOP',00H
  509.     DW    DIRCT
  510.     DB    'ORA',0B0H
  511.     DW    RG210
  512.     DB    'ORI',0F6H
  513.     DW    IMMED
  514.     DB    'RAL',17H
  515.     DW    DIRCT
  516.     DB    'RAR',1FH
  517.     DW    DIRCT
  518.     DB    'RLC',07H
  519.     DW    DIRCT
  520.     DB    'RRC',0FH
  521.     DW    DIRCT
  522.     DB    'SBB',98H
  523.     DW    RG210
  524.     DB    'SBI',0DEH
  525.     DW    IMMED
  526.     DB    'STC',37H
  527.     DW    DIRCT
  528.     DB    'SUB',90H
  529.     DW    RG210
  530.     DB    'SUI',0D6H
  531.     DW    IMMED
  532.     DB    'XRA',0A8H
  533.     DW    RG210
  534.     DB    'XRI',0EEH
  535.     DW    IMMED
  536. ;
  537. ERTAB:    DB    ERR AND 0FFH,ITL AND 0FFH,ICM AND 0FFH
  538.     DB    IRR AND 0FFH,IRR AND 0FFH,IIT AND 0FFH
  539.     DB    IIV AND 0FFH,ERR AND 0FFH
  540. ;
  541. ITL:    DB    'INPUT TOO LONG',80H
  542. ;
  543. ICM:    DB    'INVALID COMMAND',80H
  544. ;
  545. IRR:    DB    'INVALID REGISTER',80H
  546. ;
  547. IIT:    DB    'INVALID IMMED TYPE',80H
  548. ;
  549. IIV:    DB    'INVALID IMMED VALUE',80H
  550. ;
  551. ERR:    DB    'ERROR!',80H
  552. ;
  553. ERRSP:    DB    CR,LF,90H,80H
  554. ;
  555. TITLS:    DB    CLR,CR,LF
  556.     DB    9BH,'EDUCATOR-8080',CR,LF
  557.     DB    CR,LF,9AH,'<---'
  558.     DB    'BINARY-----'
  559.     DB    ' OCT HX',CR,LF
  560.     DB    9AH,'7 6 5 4 3 2 1 0',80H
  561. ;
  562. BLINE:    DB    CR,LF,CR,LF,90H
  563.     DB    'B-REG >>  ',80H
  564. ;
  565. CLINE:    DB    CR,LF,CR,LF,90H
  566.     DB    'C-REG >>  ',80H
  567. ;
  568. AFHDR:    DB    CR,LF,CR,LF,90H
  569.     DB    'FLAGS & ACC',CR,LF,90H
  570.     DB    'P Z S A C',CR,LF,90H,80H
  571. ;
  572. CMDMS:    DB    CR,LF,CR,LF,90H
  573.     DB    'COMMAND ? ',80H
  574. ;
  575. ;CHARACTER OUTPUT ROUTINE
  576. ;
  577. CHRPR    PUSH    PSW
  578.     PUSH    B
  579.     PUSH    D
  580.     PUSH    H
  581.     MOV    C,A    ;CHARACTER TO C FOR CP/M
  582. VCONOUT    CALL    $-$    ;MODIFIED AT INIT
  583.     POP    H
  584.     POP    D
  585.     POP    B
  586.     POP    PSW
  587.     RET
  588. ;
  589. ;KEYBOARD INPUT ROUTINE
  590. ;
  591. KEYBD    PUSH    B
  592.     PUSH    D
  593.     PUSH    H
  594. VCONIN    CALL    $-$    ;MODIFIED AT INIT
  595.     POP    H
  596.     POP    D
  597.     POP    B
  598.     CPI    'C'-40H    ;CONTROL-C FOR EXIT?
  599.     JZ    0    ;YES, REBOOT CP/M
  600.     RET
  601. ;
  602. ;    DEFINE TEMPORARY STORAGE AREA
  603. ;
  604. BANDC:            ;B AND C REGISTERS
  605. CREG:    DB    0
  606. BREG:    DB    0
  607. PSWA:    DW    0
  608. CMDAR:    DS    40
  609. STACK    EQU    $+60
  610. ;
  611.     END
  612.