M EQU Byte Ptr 0[BX] ;******************************************************** ;* * ;* TEST ROUTINES FOR THE COMPPRO SYSTEM * ;* SUPPORT 1 BOARD REAL TIME CLOCK * ;* * ;******************************************************** ; ; Verion 1.0 From System Support manual ; 8/1/82 Keyed in by Bill Bolton. ; ; Version 1.10 Modified for Australian date ; 8/1/82 format by Bill Bolton. ; ; Version 1.11 Placed version number in signon ; 11/1/82 and added version number equates ; Bill Bolton ; ; Version 1.12 XLT86 translation to CP/M-86 ; Bill Bolton ; BASE EQU 50H ;BASE PORT ADDRESS CLKCMD EQU BASE+10 ;CLOCK COMMAND PORT CLKDATA EQU BASE+11 ;CLOCK DATA PORT WBOOT EQU 0 ;BIOS WBOOT ENTRY BDOS EQU 00005H ;BDOS ENTRY POINT READ EQU 10H ;READ BIT PATTERN WRITE EQU 20H ;WRITE BIT PATTERN HOLD EQU 40H ;HOLD BIT PATTERN ALF EQU 0AH ;ASCII LINE FEED ACR EQU 0DH ;ASCII CARRIAGE RETURN ; VERS EQU 1 ;MAJOR VERSION NUMBER REV EQU 12 ;MINOR REVISION NUMBER ; ORG 100H ; ;******************************************************** ;* THIS IS THE MAIN LOOP THAT PRINTS THE * ;* SIGNON MESSAGE, DECIDES WHAT COMMAND * ;* HAS BEEN ENTERED AND EXECUTES THAT ROUTINE * ;******************************************************** START: MOV DX,(Offset SIGNON) ;INITIAL SIGNON MESSAGE CALL PMSG ;DISPLAY IT CALL GETCHAR ;GET COMMAND CHARACTER CMP AL,'X' ;EXIT TO CP/M ? JNZ L_1 MOV CL,0 ;YES MOV DL,0 INT 224 L_1: CMP AL,'S' ;SET TIME ? JZ SETTIME ;YES CMP AL,'D' ;DISPLAY TIME ? JNZ L_2 JMP PTIME ;YES L_2: CMP AL,'C' ;CONTIUOUS DISPLAY ? JNZ L_3 JMP FOREVER ;YES L_3: MOV DX,(Offset ERROR) ;CANT RECOGNIZE COMMAND CALL PMSG ;SO COMPLAIN ABOUT IT JMPS START ;TRY AGAIN ; ;******************************************************** ;* THIS ROUTINE SETS UP HL TO POINT TO A TABLE * ;* TO RECEIVE THE DIGITS TO BE WRITTEN TO THE CLOCK* ;* DE CONTAINS THE POINTER TO THE TABLE OF ADDRESS * ;* VALUES THAT CORRESPOND TO THE DESIRED DIGIT. * ;* THE TABLE IS ORGANISED IN THE PROPER ORDER FOR * ;* READING AND WRITING. THE ROUTINE GETS THE * ;* DIGITS FROM THE CONSOLE AND PUTS THEM INTO * ;* MEMORY AND THEN WRITES THEM TO THE CLOCK. * ;******************************************************** SETTIME: CALL GETTIME ;GET THE DATE AND TIME DATA MOV BX,(Offset DTABLE) ;HL <---- DIGIT TABLE ADDRESS MOV DX,(Offset ATABLE) ;DE <---- ADDRESS TABLE MOV CH,13 ;NUMBER OF DIGITS TO WRITE +1 MOV AL,HOLD ;SET HOLD BIT OUT CLKCMD,AL ;SEND COMMAND SET1: DEC CH ;DONE LAST DIGIT ? JNZ HERE ;NO MOV AL,0 ;YES, CLEAR HOLD BIT OUT CLKCMD,AL ;SEND COMMAND MOV DX,(Offset TIMEIS) ;"TIME IS" MESSAGE CALL PMSG CALL CLKPRNT ;DISPLAY THE TIME JMPS START ;NEXT COMMAND ; HERE: MOV AL,M ;A <---- DIGIT MOV CL,AL ;C <---- DIGIT MOV SI,DX ;A <---- COMMAND MOV AL,[SI] CALL WRTDGT ;WRITE THE DIGIT LAHF ;BUMP POINTERS INC BX SAHF LAHF INC DX SAHF JMPS SET1 ;NEXT DIGIT ;******************************************************** ;* THIS ROUTINE GETS THE DIGITS FROM THE CONSOLE * ;* AND STORES THEM INTO MEMORY AT THE ADDRESS * ;* POINTED TO BY HL. * ;******************************************************** GETTIME: MOV DX,(Offset ASKTIME) ;PROMPT FOR TIME INPUT CALL PMSG MOV BX,(Offset DTABLE) ;HL <---- ADDRESS TO PUT DIGITS GET1: CALL GETNUMB ;GET A DIGIT CMP AL,ACR ;FINISHED TIME ? JZ GETDATE ;YES AND AL,0FH ;NO, CONVERT TO BCD FORMAT MOV M,AL ;PUT DIGIT INTO MEMORY INC BX ;POINT TO NEXT TABLE ADDRESS JMPS GET1 ; GETDATE: MOV DX,(Offset ASKDATE) ;PROMPT FOR TIME INPUT CALL PMSG GET2: CALL GETNUMB ;GET A DIGIT CMP AL,ACR ;FINISHED DATE ? JNZ L_4 RET ;YES L_4: AND AL,0FH ;NO, CONVERT TO BCD MOV M,AL ;PUT DIGIT INTO MEMORY INC BX ;POINT TO NEXT TABLE ADDRESS JMPS GET2 ;******************************************************** ;* THIS ROUTINE GETS A CHARACTER FROM THE CONSOLE * ;* AND CHECKS THE INPUT FOR EITHER A CARRIAGE * ;* RETURN OR A VALID DIGIT BETWEEN 0-9 WILL NOT * ;* RETURN UNTIL A CR OR VALID DIGIT IS TYPED * ;******************************************************** GETNUMB: CALL GETCHAR CMP AL,ACR ;CARRIAGE RETURN ? JNZ L_5 RET ;YES L_5: CMP AL,'0' JB GETNUMB CMP AL,'9'+1 JNB GETNUMB RET ;******************************************************** ;* THIS ROUTINE WRITES THE DIGIT TO THE CLOCK * ;* AND CHECKS TO SEE IF THE HOURS OR DAYS 10 * ;* DIGIT AND SETS THE 24 HOUR AND LEAP YEAR BITS * ;* ACCORDINGLY. THIS ROUTINE IS CALEED WITH DIGIT * ;* ADDRESS IN A AND THE DIGIT TO BE WRITTEN IN C. * ;******************************************************** WRTDGT: LAHF ;SAVE THE COMMAND XCHG AL,AH PUSH AX XCHG AL,AH ADD AL,HOLD ;ADD IN THE HOLD BIT OUT CLKCMD,AL ;SEND COMMAND CMP AL,HOLD+5 ;HOURS TEN DIGIT ? JNZ WRT1 ;NO MOV AL,CL ;YES, GET DIGIT ADD AL,08H ;SET 24 HOUR MODE JMPS WRT3 ; WRT1: CMP AL,8+HOLD ;DAYS 10 DIGIT ? JNZ WRT2 ;NO MOV AL,CL ;YES, GET THE DIGIT AND AL,03H ;SET NON-LEAP YEAR MODE JMPS WRT3 ; WRT2: MOV AL,CL ;A <---- DIGIT WRT3: OUT CLKDATA,AL ;SEND DIGIT POP AX ;GET COMMAND BACK XCHG AL,AH ADD AL,WRITE+HOLD ;ADD THE WRITE + HOLD BITS OUT CLKCMD,AL ;SEND COMMAND SUB AL,WRITE ;CLEAR THE WRITE BIT OUT CLKCMD,AL ;SEND COMMAND RET ;******************************************************** ;* THIS ROUTINE READS A DIGIT FROM THE CLOCK AND * ;* MASKS THE LEAP YEAR AND AND AM/PM/24 HOUR MODE * ;* BITS. THIS ROUTINE IS CALLED WITH THE DIGIT * ;* ADDRESS IN A AND RTURNS WITH THE DIGIT VALUE * ;* IN A. * ;******************************************************** RDDGT: ADD AL,READ ;ADD IN THE READ BIT OUT CLKCMD,AL ;SEND COMMAND CMP AL,5+READ ;TENS HOURS DIGIT ? IN AL,CLKDATA ;GET THE DIGIT JZ L_6 RET ;NO, FINISHED L_6: SUB AL,08H ;YES, TURN OFF 24 HOUR BIT RET ;******************************************************** ;* THIS ROUTINE PRINTS THE CURRENT TIME AND DATE * ;* ONCE , COMPLETE WITH COLONS AND SLASHES * ;******************************************************** CLKPRNT: MOV BX,(Offset ATABLE) ;HL <---- TABLE ADDRESS CALL PRINTWO ;DISPLAY THE FIRST TWO DIGITS MOV AL,':' CALL PCHAR ;DISPLAY THE SEPERATOR CALL PRINTWO ;DISPLAY THE NEXT TWO DIGITS MOV AL,':' CALL PCHAR ;DISPLAY THE SEPERATOR CALL PRINTWO ;DISPLAY THE NEXT TWO DIGITS MOV AL,' ' CALL PCHAR MOV AL,' ' ;TWO SPACES CALL PCHAR CALL PRINTWO ;TWO MORE DIGITS MOV AL,'/' ;DISPLAY A SLASH CALL PCHAR CALL PRINTWO MOV AL,'/' CALL PCHAR CALL PRINTWO ;PRINT LAST TWO DIGITS RET ;******************************************************** ;* THIS ROUTINE PRINTS TWO DIGITS FROM THE CLOCK. * ;* IT IS CALLED WITH THE DIGIT ADDRESS OF THE * ;* DIGIT IN HL. EXITS WITH HL POINTING TO THE * ;* ADDRESS OF THE NEXT TWO DIGITS. * ;******************************************************** PRINTWO: MOV AL,M ;A <---- ADDRESS (FROM TABLE) CALL RDDGT ;READ THE DIGIT ADD AL,30H ;CONVERT TO ASCII CALL PCHAR ;DISPLAY IT INC BX ;ADJUST POINTER MOV AL,M ;A <---- ADDRESS CALL RDDGT ADD AL,30H CALL PCHAR LAHF INC BX SAHF RET ;******************************************************** ;* THIS ROUTINE DISPLAYS THE TIME ONCE AND JUMPS * ;* BACK TO THE MAIN LOOP * ;******************************************************** PTIME: MOV DX,(Offset TIMEIS) CALL PMSG CALL CLKPRNT JMP START ;******************************************************** ;* THIS ROUTINE DISPLAYS THE TIME CONTINUOUSLY * ;* UNTIL A CONTROL C IS TYPED. IT CONTINUALLY * ;* READS THE SECONDS 1 DIGIT AND WAITS FOR IT TO * ;* CHANGE BEFORE DISPLAYING THE TIME. * ;******************************************************** FOREVER: MOV AL,ALF ;LINE FEED CALL PCHAR FOR1: MOV AL,ACR ;CR CALL PCHAR CALL CLKPRNT ;DISPLAY THE TIME MOV AL,0 ;ADDRESS OF SECONDS DIGIT CALL RDDGT ;READ DIGIT MOV CH,AL ;B <---- DIGIT FOR2: MOV AL,0 CALL RDDGT ;READ IT AGAIN CMP AL,CH ;CHANGED ? JZ FOR2 ;NO JMPS FOREVER ;YES ;******************************************************** ;* CP/M CALLS AND UTILITY ROUTINES * ;* * ;* THIS ROUTINE GETS A CHARACTER FORM THE CONSOLE * ;* AND CONVERTS IT TO UPPERCASE, STRIPS OF PARITY * ;* AND CHECKS FOR CONTROL C. * ;******************************************************** GETCHAR: PUSH BX MOV CL,1 ;BDOS CONSOLE IN INT 224 POP BX CMP AL,'a' ;RANGE CHECK FOR UPPER CASE JB SKIP CMP AL,'z'+1 ;DITTO JNB SKIP AND AL,5FH ;CONVERT TO UPPER CASE SKIP: AND AL,7FH ;STRIP PARITY BIT CMP AL,03H ;CONTROL C ? JNZ L_7 MOV CL,0 ;YES, EXIT TO CP/M MOV DL,0 INT 224 L_7: RET ;NO ;******************************************************** ;* THIS ROUTINE PRINTS A CHARACTER ON THE CONSOLE * ;* AND CHECKS TO SEE IF ANY WERE ENTERED WHILE * ;* PRINTING. * ;******************************************************** PCHAR: PUSH DX MOV DL,AL ;E <---- CHARCATER MOV CL,2 ;BDOS CONSOLE OUT PUSH BX INT 224 MOV CL,0BH ;BDOS CONSOLE STATUS CHECK INT 224 POP BX POP DX OR AL,AL ;CHARACTER READY ? JZ L_8 CALL GETCHAR ;YES, GET IT L_8: RET ;NO ;******************************************************** ;* THIS ROUTINE DISPLAYS THE STRING POINTED TO * ;* BY DE UNTIL $ IS FOUND. * ;******************************************************** PMSG: PUSH BX MOV CL,9 ;BDOS DISPLAY STRING INT 224 POP BX RET L_9 EQU $ ; DSEG ; ORG Offset L_9 ;******************************************************** ;* MESSAGES * ;******************************************************** SIGNON RS 0 DB ACR,ALF,ACR,ALF DB 'Time and Date Test Routines for System Support 1' DB ACR,ALF DB 'Version ',VERS + '0','.',REV/10 + '0',REV mod 10 +'0' DB ACR,ALF,ACR,ALF DB 'Please type one of the following Commands:' DB ACR,ALF DB 'S - Set the Time and Date',ACR,ALF DB 'D - Display the Time and Date Once',ACR,ALF DB 'C - Continuously Display the Time and Date' DB ACR,ALF DB 'X - Exit to Operating System' DB ACR,ALF,ACR,ALF DB 'Command: $' ; ERROR RS 0 DB ACR,ALF DB 'That was not one of the above commands' DB ACR,ALF DB 'Please try again.$' ; ASKTIME RS 0 DB ACR,ALF DB 'What is the time? (24 hour format - HH:MM:SS) $' ; ASKDATE RS 0 DB ACR,ALF DB 'What is the date? (DD/MM/YY) $' ; TIMEIS RS 0 DB ACR,ALF DB 'The Time and Date are: $' ;******************************************************** ;* TABLES * ;* * ;* THIS TABLE CONTAINS THE 'ADDRESS' VALUES * ;* THAT ARE SENT IN THE COMMAND BYTE IN THE * ;* FOLLOWING ORDER - HOURS 10, HOURS 1, MIN 10 * ;* MIN 1, SEC 10, SEC 1, DAYS 10, DAYS 1 * ;* MONTHS 10, MONTHS 1, YEARS 10, YEARS 1. * ;******************************************************** ATABLE RS 0 DB 5,4,3,2,1,0,8,7,0AH,9,0CH,0BH ;******************************************************** ;* THIS IS THE AREA WHICH GETS THE DIGITS AS THEY * ;* ARE ENTERED FROM THE CONSOLE. * ;******************************************************** DTABLE RS 0 DB 0,0,0,0,0,0,0,0,0,0,0,0 ; END