TITLE ZCLK ZDOS/MSDOS INTERFACE PROGRAM PAGE ,132 ;************************************************************ ; ZCLK.ASM 10/31/84 Revised 11/27/84 12/07/84 ;************************************************************ ;** Copyright (c) 1984 FBE Research Company, Incorporated ** ;** P.O. Box 68234, Seattle, WA 98168 ** ;************************************************************ ;** This program is yours. There is no license agreement. ** ;** However, the program is copyrighted and you may not ** ;** sell exact copies of it for profit. You may modify ** ;** the program and sell the result as long as you include ** ;** our copyright notice (above). ** ;************************************************************ ; ZCLK for ZDOS or MS-DOS ; ; INVOKE: ZCLK ; ZCLK MM DD YY hh mm ; ZCLK DST ; ; Read date and time from ZCLK and set ZDOS/MSDOS date and ; time. If a command line is present, process it. Skip ; leading spaces. If first character is "D," perform Day- ; light Savings Time command. Else, assume that the command ; line contains ten digits in MM DD YY hh mm format and ; set the date and time. Any error produces comphrehensive ; error message. ; ; The Daylight Savings Time command "springs" forward or ; "falls" back by adding or subtracting an hour according ; to the season. Note that only the hours are affected and ; the command should not be used at a time where a roll-over ; or roll-under of the date would occur. ; ; Access to the ZCLK is via the 6821 Parallel Printer PIA ; (U114) as follows: ; ; PIA Bit Name Function ; ------------------------------------------------ ; PB1 /ERROR Enable access to ZCLK * ; ; PA0 PD1 RD Strobe ; PA1 PD2 WR Strobe ; ; PB2 PD3 Address Counter Clock ; ; PB4 PD5 Data Bus Bit D0 (LSB) ; PB5 PD6 Data Bus Bit D1 ; PB6 PD7 Data Bus Bit D2 ; PB7 PD8 Data Bus Bit D3 ; ; * Installing the ZCLK disconnects PB1 from the /ERROR ; signal from the printer. PB1 is programmed as an input ; by ZDOS/MSDOS but is used here as an output. ; ;************************************************************ ; MSM5832 REGISTER DEFINITIONS ;************************************************************ ; ; Data Bus ; ADDR NAME D3 D2 D1 D0 RANGE NOTES ; ---------------------------------------------------------- ; 0 S1 * * * * 0-9 S1 and S10 are reset to ; 1 S10 * * * 0-5 zero on write to address ; ; 2 MI1 * * * * 0-9 ; 3 MI10 * * * 0-5 ; ; 4 H1 * * * * 0-9 ; 5 H10 A B * * 0-2 A=1 for 24 hour format ; A=0 for 12 hour format ; B=1 for PM B=0 for AM ; 6 W * * * 0-6 ; ; 7 D1 * * * * 0-9 ; 8 D10 C * * 0-3 C=0 for 28 day February ; C=1 for 29 day February ; 9 MO1 * * * * 0-9 ; 10 MO10 * 0-1 ; ; 11 Y1 * * * * 0-9 ; 12 Y10 * * * * ; ; All registers are read/write. * means data valid as "1" ; or "0" bit. Blank means bit does not exist ("0" during ; read and ignored on write). ; ;************************************************************ ; ASSEMBLY INSTRUCTIONS ;************************************************************ ; ; MASM ZCLK; ; LINK ZCLK; ; EXE2BIN ZCLK.EXE.COM ; ERASE ZCLK.EXE ; ERASE ZCLK.OBJ ; ; Since there is not STACK segment, LINK will generate one ; error. Ignore it. ; ;************************************************************ ; DEFINITIONS ;************************************************************ ; BEL EQU 7 ;ASCII CHARACTERS LF EQU 10 CR EQU 13 ; ZPIA EQU 0E0H ;PIA BASE PORT ADATA EQU ZPIA+0 ACTL EQU ZPIA+1 BDATA EQU ZPIA+2 BCTL EQU ZPIA+3 ; ;************************************************************ ; MAIN LINE ;************************************************************ ; CSEG SEGMENT ASSUME CS:CSEG, SS:CSEG, DS:CSEG, ES:NOTHING ; ORG 100H ZCLK: CALL SETTIM ;SET CLOCK IF COMMAND LINE ; CALL RDCLK ;READ THE TIME AND DATE ; MOV SI,OFFSET BUFFER CALL FMTTIM ;MAKE ZDOS/MSDOS TIME FORMAT ; MOV AH,2DH ;SET TIME INT 21H ; CMP AL,255 ;ERROR? JNZ TIMOK ;BRANCH IF NOT ; MOV DX,OFFSET TEMSG ;ISSUE ERROR MESSAGE CALL TYPTX ; TIMOK: INC SI ;SKIP DAY OF WEEK CALL FMTDAT ;MAKE ZDOS/MSDOS DATE FORMAT ; MOV AH,2BH ;SET DATE INT 21H CMP AL,255 ;ERROR? JNZ DATOK ;BRANCH IF NOT ; MOV DX,OFFSET DEMSG ;ISSUE ERROR MESSAGE CALL TYPTX ; DATOK: CALL SHOTIM ;SHOW DATE AND TIME ; MOV AH,0 ;EXIT TO ZDOS/MSDOS INT 21H ; TEMSG: DB BEL,CR,LF DB 'Could not set the system TIME.' DB CR,LF DB 'Reset the ZCLK time and date and try again!' DB CR,LF DB '$' ; DEMSG: DB BEL,CR,LF DB 'Could not set the system DATE.' DB CR,LF DB 'Reset the ZCLK Time and Date and try again!' DB CR,LF DB '$' ; ;************************************************************ ; MAJOR SUBROUTINES ;************************************************************ ; SETTIM - ; If command line not there, exit. Else, process the line. ; If error in line, show error message and exit to system. ; SETTIM: MOV SI,OFFSET 80H ;POINT AT COMMAND LINE MOV BL,[SI] ;GET COUNT BYTE OR BL,BL ;SET FLAGS JNZ STNEXT ;SKIP IF NONZERO ; RET ;ELSE, EXIT ; STNEXT: INC SI ;BUMP POINTER SKSPLP: MOV AL,[SI] ;SKIP LEADING SPACES CMP AL,' ' JNZ NOTSPC ;EXIT IF NON-SPACE ; INC SI ;BUMP POINTER DEC BL ;DONE LINE? JNZ SKSPLP ;LOOP IF NOT ; JMP STMERR ;ELSE IS ERROR ; NOTSPC: CMP AL,'D' ;DAYLIGHT SAVINGS TIME COMMAND? JZ DODSTX ;BRANCH IF SO ; CMP AL,'d' ;LOWER CASE? JNZ NOTDST ;BRANCH IF NOT ; DODSTX: JMP DODST ;ELSE, PROCESS COMMAND ; NOTDST: MOV DI,OFFSET DGTBUF ;SETUP OUTPUT POINTER MOV CL,10 ;DIGIT COUNT SCLOOP: MOV AL,[SI] ;GET POSSIBLE DIGIT INC SI CMP AL,'0' ;LESS THAN ZERO? JL NEXT ;TRY NEXT IF SO ; CMP AL,'9' ;GREATER THAN NINE? JG NEXT ;TRY NEXT IF SO ; MOV [DI],AL ;ELSE, BUFFER THE DIGIT INC DI DEC CL ;DONE TEN? JZ DODOW ;EXIT IF SO ; NEXT: DEC BL ;DONE ALL OF LINE? JNZ SCLOOP ;LOOP IF NOT ; STMERR: MOV DX,OFFSET STMMSG ;SHOW ERROR MESSAGE CALL TYPTX ; MOV AH,0 ;EXIT TO SYSTEM INT 21H ; ;************************************************************ ; DODOW - ; Get day of week. ; DODOW: MOV DX,OFFSET DWMSG ;PROMPT THE OPERATOR CALL TYPTX ; MOV AH,1 ;GET RESPONSE INT 21H ; AND AL,00000111B ;MASK OFF UNUSED BITS SUB AL,1 MOV W,AL ;STORE IN BUFFER ; JMP DODGTS ;PROCESS DIGITS ; DWMSG: DB CR,LF DB 'Specify Day of Week by Number:' DB CR,LF DB ' 1 - Sunday' DB CR,LF DB ' 2 - Monday' DB CR,LF DB ' 3 - Tuesday' DB CR,LF DB ' 4 - Wednesday' DB CR,LF DB ' 5 - Thursday' DB CR,LF DB ' 6 - Friday' DB CR,LF DB ' 7 - Saturday' DB CR,LF DB 'Type Digit ([1] thru [7]): ' DB '$' ; ;************************************************************ ; DODGTS - ; Process contents of digit buffer and set ZCLK. ; DODGTS: MOV SI,OFFSET DGTBUF ;POINT AT DIGITS ; MOV DI,OFFSET MO10 ;MONTH CALL PUTDG ; MOV DI,OFFSET D10 ;DAY MOV DL,[SI] AND DL,00000011B ;MASK OFF UNUSED BITS CALL PUTDGE ; MOV DI,OFFSET Y10 ;YEAR CALL PUTDG ; MOV DI,OFFSET H10 ;HOURS MOV DL,[SI] OR DL,00001000B ;SET 24-HOUR BIT CALL PUTDGE ; MOV DI,OFFSET MI10 ;MINUTES CALL PUTDG ; MOV DX,OFFSET STMSG ;PROMPT OPERATOR CALL TYPTX ; MOV AH,1 ;WAIT FOR RESPONSE INT 21H ; CALL WRCLK ;SET CLOCK MOV DL,LF ;CLEAN UP JMP TYPEC ; STMSG: DB CR,LF,LF DB 'Wait for an "even" minute (00 Seconds) ' DB 'then type [RETURN] to set ZCLK:' DB '$' ; ;************************************************************ ; DODST - ; Process daylight saving time command. Does not check for ; roll over or roll under conditions. Note: Does not mess ; up 24-hour bit in H10. ; DODST: CALL RDCLK ;GET THE ZCLK DATA ; MOV SI,OFFSET MO1 ;GET BINARY MONTH CALL FIX ; MOV SI,OFFSET H1 ;POINT AT HOURS CMP AL,7 ;JULY OR LATER JGE FALL ;BRANCH IF SO ; SPRING: MOV AL,[SI] ;GET HOURS INC SI MOV AH,[SI] INC AL ;ADD ONE AAA ;CORRECT MOV [SI],AH ;PUT BACK IN BUFFER DEC SI MOV [SI],AL JMP WRHRS ;ELSE, SET CLOCK ; FALL: MOV AL,[SI] ;GET HOURS INC SI MOV AH,[SI] DEC AL ;SUBTRACT ONE AAS ;CORRECT MOV [SI],AH ;PUT BACK IN BUFFER DEC SI MOV [SI],AL JMP WRHRS ;UPDATE HOURS ONLY ; ;************************************************************ ; SHOTIM - ; Output date and time to console. ; SHOTIM: MOV DX,OFFSET MSG1 ;PREAMBLE CALL TYPTX ; MOV SI,OFFSET MO10 ;MONTH CALL TYDGT ; MOV DL,'-' CALL TYPEC ; MOV SI,OFFSET D10 ;DAY CALL TYDGTL ; MOV DL,'-' CALL TYPEC ; MOV SI,OFFSET Y10 ;YEAR CALL TYDGT ; MOV AL,W ;DAY OF WEEK CALL SHODOW ; MOV DX,OFFSET MSG2 ;POSTAMBLE CALL TYPTX ; MOV SI,OFFSET H10 ;HOURS CALL TYDGTL ; MOV DL,':' CALL TYPEC ; MOV SI,OFFSET MI10 ;MINUTES CALL TYDGT ; MOV DL,':' CALL TYPEC ; MOV SI,OFFSET S10 ;SECONDS JMP TYDGT ; MSG1: DB CR,LF DB 'FBE ZCLK Date ' DB '$' ; MSG2: DB ' Time ' DB '$' ; ;************************************************************ ; MINOR SUBROUTINES ;************************************************************ ; PUTDG - ; Store two digits from [SI] at [DI]. ; PUTDG: MOV DL,[SI] ;GET DIGIT PUTDGE: CALL PUTBYT ;PUT DIGIT MOV DL,[SI] ;GET DIGIT PUTBYT: MOV [DI],DL ;PUT DIGIT DEC DI ;DECREMENT DESTINATION INC SI ;INCREMENT SOURCE RET ; ;************************************************************ ; TYPTX - ; Output a string at DX to console. ; TYPTX: MOV AH,9 ;ACTIVATE SYSTEM CALL INT 21H RET ; ;************************************************************ ; TYDGTL and TYDGT - ; Output two digits pointed at by SI. TYDGTL masks the MS ; digit to 3. ; TYDGTL: MOV DL,[SI] ;GET DIGIT AND DL,00000011B ;REMOVE EXTRA BITS ADD DL,'0' ;MAKE ASCII JMP SHORT TYDGTE ;SNEAK IN ; TYDGT: MOV DL,[SI] ;GET DIGIT TYDGTE: CALL TYPEC ;OUTPUT IT MOV DL,[SI] ;GET NEXT DIGIT TYPEC: MOV AH,2 ;OUTPUT VIA SYSTEM INT 21H DEC SI ;MOVE POINTER RET ; ;************************************************************ ; SHODOW - ; Display day of week. On entry, AL contains day number. ; SHODOW: MOV BX,OFFSET DOWNDX ;POINT TO ADDRESS TABLE AND AL,00000111B ;MASK OFF FOR SAFETY ADD AL,AL ;DOUBLE THE INDEX MOV AH,0 MOV SI,AX ;INDEX MOV DX,[BX][SI] ;FETCH ADDRESS JMP TYPTX ;DISPLAY TEXT ; DOWNDX: DW OFFSET D0MSG ;MESSAGE ADDRESS TABLE DW OFFSET D1MSG DW OFFSET D2MSG DW OFFSET D3MSG DW OFFSET D4MSG DW OFFSET D5MSG DW OFFSET D6MSG DW OFFSET D7MSG ; D0MSG: DB ' Sunday$' ;MESSAGES D1MSG: DB ' Monday$' D2MSG: DB ' Tuesday$' D3MSG: DB ' Wednesday$' D4MSG: DB ' Thursday$' D5MSG: DB ' Friday$' D6MSG: DB ' Saturday$' D7MSG: DB ' ****> NO ZCLK <****$' ; ;************************************************************ ; ACCESS - ; Access the ZCLK board by taking over the printer PIA. ; Set RD and WR high. Make PB1 and OUTPUT and set it low. ; ACCESS: IN AL,ADATA ;SET RD AND WR HIGH OR AL,00000011B OUT ADATA,AL ; CALL SPBDIR ;SELECT DIRECTION REGISTER ; MOV AL,11111110B ;MAKE PB1 AND OUTPUT OUT BDATA,AL ; CALL SPBDAT ;SELECT DATA REGISTER ; XOR AL,AL ;MAKE PB1 LOW TO ENABLE ZCLK OUT BDATA,AL ; MOV CX,50 ;WAIT FOR ACCESS (150 USEC) ACWAIT: LOOP SHORT ACWAIT RET ; ;************************************************************ ; WRCLK - ; Write contents of data buffer to ZCLK. ; WRCLK: CLI ;NO INTERRIPTS CALL ACCESS ;ENABLE THE ZCLK ; MOV SI,OFFSET BUFFER ;SETUP FOR LOOP MOV BL,13 OULOOP: MOV AL,[SI] ;GET BYTE CALL WRITE ;WRITE TO ZCLK INC SI ;ADVANCE POINTER CALL CLKADR ;ADVANCE ADDRESS COUNTER DEC BL ;DONE ALL? JNZ OULOOP ;LOOP IF NOT ; CALL CLEAR ;DISABLE THE ZCLK STI ;INTERRUPTS OK NOW RET ; ;************************************************************ ; WRITE - ; Write byte in AL to ZCLK register selected by address ; counter. ; WRITE: MOV CL,4 ;POSITION THE DATA ROL AL,CL AND AL,11110000B OUT BDATA,AL ;OUTPUT TO ZCLK ; IN AL,ADATA ;SET WR LOW AND AL,11111101B OUT ADATA,AL ; AND AL,AL ;PAUSE FOR PULSE WIDTH AND AL,AL ; IN AL,ADATA ;SET WR HIGH OR AL,00000010B OUT ADATA,AL RET ; ;************************************************************ ; WRHRS - ; Write only Hours register to ZCLK. ; WRHRS: CLI ;NO INTERRUPTS CALL ACCESS ;ENABLE THE ZCLK ; MOV SI,OFFSET H1 ;POINT AT HOURS DATA MOV BL,2 CALL CLKADR ;ADVANCE TO HOURS REGISTER CALL CLKADR CALL CLKADR CALL CLKADR JMP SHORT OULOOP ;SNEAK IN ; ;************************************************************ ; RDCLK - ; Read time and date from ZCLK. ; RDCLK: CLI ;NO INTERRUPTS CALL ACCESS ;ENABLE THE ZCLK ; CALL SPBDIR ;SELECT DIRECTION REGISTER ; MOV AL,00001110B ;MAKE DB4-DB7 INPUTS OUT BDATA,AL ; CALL SPBDAT ;SELECT DATA REGISTER ; IN AL,ADATA ;SET RD LOW AND AL,11111110B OUT ADATA,AL ; MOV DI,OFFSET BUFFER ;SETUP FOR LOOP MOV BL,13 INLOOP: CALL READ ;READ ZCLK BYTE MOV [DI],CL ;BYTE TO BUFFER INC DI ;ADVANCE POINTER CALL CLKADR ;ADVANCE ADDRESS COUNTER DEC BL ;DONE ALL? JNZ INLOOP ;LOOP IF NOT ; IN AL,ADATA ;SET RD HIGH OR AL,00000001B OUT ADATA,AL ; CALL CLEAR ;DISABLE THE ZCLK STI ;INTERRUPTS OK NOW RET ; ;************************************************************ ; READ - ; Read data from ZCLK register selected by address counter. ; Returns ASCII byte in CL. ; READ: MOV CX,3 ;WAIT FOR ACCESS (6 USEC) RDWAIT: LOOP SHORT RDWAIT ; IN AL,BDATA ;READ ZCLK MOV CL,4 ROR AL,CL ;POSITION THE DATA AND AL,00001111B ;MASK OFF UNWANTED BITS ADD AL,'0' ;MAKE ASCII MOV CL,AL ;SAVE RET ; ;************************************************************ ; CLKADR - ; Advance the address counter. ; CLKADR: IN AL,BDATA OR AL,00000100B ;SET COUNTER CLOCK HIGH OUT BDATA,AL AND AL,11111011B ;SET COUNTER CLOCK LOW. OUT BDATA,AL RET ; ;************************************************************ ; CLEAR - ; Restore printer PIA to normal. Deselect ZCLK. ; CLEAR: CALL SPBDIR ;SELECT DIRECTION REGISTER ; MOV AL,11111100B ;MAKE PB1 AN INPUT OUT BDATA,AL ; JMP SPBDAT ;SELECT DATA REGISTER ; ;************************************************************ ; SPBDIR - ; Select Port B Direction Register. ; SPBDIR: IN AL,BCTL AND AL,11111011B OUT BCTL,AL RET ; ;************************************************************ ; SPBDAT - ; Select Port B Data Register. ; SPBDAT: IN AL,BCTL OR AL,00000100B OUT BCTL,AL RET ; ;************************************************************ ; FMTTIM - ; Transform ZCLK time into ZDOS/MSDOS time. ; FMTTIM: CALL FIX ;DO SECONDS MOV DH,AL MOV DL,AH ; CALL FIX ;DO MINUTES MOV CL,AL ; CALL FIXL ;DO HOURS MOV CH,AL RET ; ;************************************************************ ; FMTDAT - ; Transform ZCLK date into ZDOS/MSDOS date. ; FMTDAT: CALL FIXL ;DO DAY MOV DL,AL ; CALL FIX ;DO MONTH MOV DH,AL ; CALL FIX ;DO YEAR MOV CL,AL MOV CH,AH ADD CX,1900 RET ; ;************************************************************ ; FIXL and FIX - ; Get two BCD bytes via SI and convert to binary. FIXL ; masks MS digit to 3. ; FIXL: MOV AL,[SI] ;DO HOURS INC SI MOV AH,[SI] AND AH,00000011B ;MASK OFF UNUSED BITS JMP SHORT FIXLE ; FIX: MOV AL,[SI] ;GET LOW BYTE INC SI MOV AH,[SI] ;GET HIGH BYTE AND AH,00001111B ;MASK OFF UNUSED BITS FIXLE: AND AL,00001111B INC SI AAD ;MAKE BINARY RET ; ;************************************************************ ; TUTORIAL ERROR MESSAGE - ; STMMSG: DB 'ZCLK ENTRY ERROR Software Copyright (c)' DB ' 1984 FBE Research Company, Inc.' DB CR,LF,LF DB 'To set the system Date and Time, type ZCLK[R' DB 'ETURN].' DB CR,LF,LF DB 'To set the ZCLK Date and Time, type ZC' DB 'LK MM DD YY hh mm[RETURN]. The Date' DB CR,LF DB 'and Time must consist of ten digits, t' DB 'wo digits each for Month (MM), Date,' DB CR,LF DB '(DD), Year (YY), Hours (hh), and Minute' DB 's (mm). Use 24-hour format. That is,' DB CR,LF DB 'after Noon add 12 hours. Seconds will' DB ' be set to zero so enter the time of' DB CR,LF DB 'the next minute. The program will sho' DB 'w a day-of-week menu. Type the digit' DB CR,LF DB 'from the menu which corresponds to the' DB ' actual current day of the week. The' DB CR,LF DB 'program will then pause and wait for t' DB 'he [RETURN] key to be hit before ac-' DB CR,LF DB 'ually setting the ZCLK. This will allow' DB ' the ZCLK seconds to be synchronized' DB CR,LF DB 'to an external clock. As an example, ' DB 'to set September 4, 1984, at 9:14:20,' DB CR,LF DB 'type: ZCLK 09 04 84 09 15[RETURN]. Le' DB 'ading zeroes are required. Non-digits' DB CR,LF DB 'are ignored. Note that 15 was entered' DB ' for "mm" requiring a wait of about 40' DB CR,LF DB 'seconds before hitting [RETURN] to cau' DB 'se the actual setting of the ZCLK.' DB CR,LF,LF DB 'To set Daylight Savings Time, type ZCL' DB 'K DST[RETURN]. If the current date is' DB CR,LF DB 'before July 1st, one hour will be adde' DB 'd to the time. Otherwise, one hour' DB CR,LF DB 'will be subtracted. The change will n' DB 'ot carry over to the Date so use the' DB CR,LF DB '"Spring" command before 2300 hours and' DB ' the "Fall" command after 0100 hours.' DB CR,LF,LF DB '$' ; ;************************************************************ ; STORAGE ; DGTBUF DB 10 DUP(?) ;DIGIT BUFFER FOR SETTING ; BUFFER=THIS BYTE ;ZCLK DATA BUFFER S1 DB ? ;SECONDS S10 DB ? MI1 DB ? ;MINUTES MI10 DB ? H1 DB ? ;HOURS H10 DB ? W DB ? ;DAY OF WEEK D1 DB ? ;DATE D10 DB ? MO1 DB ? ;MONTH MO10 DB ? Y1 DB ? ;YEAR Y10 DB ? ; CSEG ENDS ; END ZCLK ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃ