; MODSET v1.0 ; Assemble with M80 ; Z-80 CPU only (unless re-written) ; Set the BYE label to YES if BYExx already loaded when ; setting the time.... ; This way the program will not re-initilaize the modem port ;Command format: ; A>MODSET MM/DD/hh/mmx ;When settimg the time... ; MM = Month number ; DD = Day number ; hh = hour (in 12-hour format...1:00 not 13:00) ; mm = minute ; x = either "P" for PM, or "A" for AM. ;Any puntcuation character may be used to separate ;the values. Although the '/' is easy to remember. ; USE: ; M80 =MODSET ; L80 MODSET,MODSET/N/E ;Written by: ; Ray Kester ; AUG 08, 84 ; Currently set-up for: ; Kaypro-II/IV ;::::::::::::::::::::: ;## Modifications ## ;::::::::::::::::::::: ;If any mods are made to this program, I would appreciate ;knowing the whereabouts of them. Please leave a message ;or uploaded copy to: ; GENERATION-5 RBBS/RCP/M ; 301-495-2932 ; Silver Spring, MD ; v1.0 ; Simple time setting routine for the modem. [RDK] ; Set time on the PROMETHEUS modem. ; Switches should be: ; U U U D D D D D D D U = up ; 1 2 3 4 5 6 7 8 9 0 D = dn ; (Same as BYExxx) .Z80 ASEG ORG 100h YES EQU 0FFH NO EQU 00H ;###### U S E R M O D S ###### ;# # ;# CPU speed in MHz. # MHZ EQU 05 ;# # ;# Number of tries before # ;# aborting... # RETRY EQU 04 ;# # ;# Set to YES if running BYE # ;# at the same time as use. # BYE EQU NO ;# # ;########## END MODS ########## VERS EQU 10 ;Will be displayed as x.x BELL EQU 07 ;Bell CR EQU 0DH ;Return LF EQU 0AH ;Line Feed NULL EQU 0 SPACE EQU 20H CONIN EQU 01 ;Read character from console CONOUT EQU 02 ;Send character to console DEFBUF EQU 80H BDOS EQU 05H ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ;Set up the SP... START: LD (STACK),SP LD SP,STACK ;Print sign-on... CALL ILPRT DB CR,LF DB 'MODSET v',VERS/10 MOD 10+'0' DB '.',VERS MOD 10+'0' DB CR,LF DB 'Set time on the PROMETHEUS modem.' DB CR,LF DB 'Switches should be:' DB CR,LF DB 'U U U D D D D D D D U = up' DB CR,LF DB '1 2 3 4 5 6 7 8 9 0 D = dn' DB CR,LF DB '(Or same as your BYExxx)' DB CR,LF,LF,0 LD HL,DEFBUF+1 ;Point to entered data LD A,(HL) ;Get any OR A ;Set flag JP Z,NONE IF NOT BYE CALL INIT ENDIF ;BYE CALL FINDIT ;Wake up modem CALL CRLF ;Show progress CALL FIXUP ;Mark end of data string LD HL,TIME ;Point to command CALL OUTP ;Send it LD HL,DEFBUF+1 ;Point to user request CALL OUTP ;Send that too LD A,CR CALL MODOUT ;Finish command CALL CRLF ;Show progress CALL READ ;Now show the new settings JP QUIT ;::::::::::::::::::::::::::::: ;## S U B R O U T I N E S ## ;::::::::::::::::::::::::::::: ;Send characters to CRT at SP... ILPRT: EX (SP),HL ;Swap HL=>SP PUSH BC ;Save BC PLOP: LD A,(HL) ;Get byte @HL CALL TYPE ;Print character INC HL ;Bump the pointer LD A,(HL) ;Get another byte OR A ;Zero? JP NZ,PLOP ;No?, then loop POP BC ;Else, get back BC EX (SP),HL ;Put new stack location in RET ;Send single character to CRT... TYPE: PUSH AF ;The rest is obvious PUSH HL PUSH BC PUSH DE LD C,CONOUT LD E,A CALL BDOS POP DE POP BC POP HL POP AF RET ;Check to see if modem is present, if not it will bomb in outp... FINDIT: LD HL,HELLO ;Send this first CALL OUTP LD B,3 ;Loop this many times FL: CALL DELAY DJNZ FL ;Till B=0 LD HL,SETQ ;Set the 'Q' register CALL OUTP RET ;Reset the error count... FIX: XOR A ;Zero A LD (VAL),A ;Reset count RET ;Send a CRLF pair... CRLF: CALL ILPRT DB CR,LF,0 RET ;Mark the end of the data string FIXUP: LD HL,DEFBUF ;Point to string LD A,(DEFBUF) ;Get count LD D,0 LD E,A ;Put into DE ADD HL,DE ;Get end INC HL ;Last byte untouched LD (HL),0 ;Mark it RET ;Send a string to the modem. Check for improperly echoed characters... OUTP: LD (SAVEIT),HL ;Just in case of an error CALL MODIN ;Clear any garbage characters CALL MODIN MOD0: CALL MODOST ;Get modem output status JR Z,MOD0 ;Loop if something there LD A,(HL) ;Else, get a byte @HL CALL MODOUT ;Send byte LD DE,2000*MHZ ;Time for echo to get here MOD1: DEC DE BIT 7,D JR NZ,MOD2 ;We timed out... CALL MODIST ;Get input status JR Z,MOD1 CALL MODIN ;Get the echoed byte CP (HL) ;Same as one sent? JR NZ,MOD2 ;Branch if screw-up INC HL ;Else, bump the pointer XOR A ;Load delimiter CP (HL) ;Same? JP Z,FIX ;Do this first JR MOD0 ;Else loop ;Found an error... MOD2: LD A,CR ;Clear modem's CALL MODOUT ; problem... LD A,(VAL) ;Get count INC A ;Count=count+1 LD (VAL),A ;Save it again CP RETRY ;Equal to retry? JP Z,NONO ;Yep, then leave LD B,2 ;Loop this many times MOD3: CALL DELAY ;Give time for modem to reset DJNZ MOD3 ;Loop til B=0 LD HL,(SAVEIT) ;Else get back the beginning JR OUTP ;Do it again ;Exceeded RETRY value... NONO: CALL ILPRT DB CR,BELL DB 'ERROR-> Can''t complete task...Aborting!' DB CR,LF DB 'Try powering down modem, or check the switches...' DB CR,LF,LF,0 JP QUIT ;Short delay based on constant... DELAY: PUSH AF PUSH HL PUSH BC PUSH DE LD DE,5000*MHZ ;Load constant STALL: DEC DE ;BC=BC-1 BIT 7,D ;Check MSB JP P,STALL ;If positive, loop POP DE POP BC POP HL POP AF RET ;Read present time on modem... READ: LD HL,RTIME ;Message to send to modem CALL OUTP ;Send it CALL ILPRT DB CR,LF DB 'New date is: ',0 LD B,2 READL: CALL DELAY DJNZ READL ;Loop and get date... RAG1: CALL MODIST ;Get status JR Z,RAG1 CALL MODIN ;Get byte CP SPACE ;Space? JR Z,RAG2 ;Then time follows CP CR ;Now trap CR's JR Z,RAG1 CP LF ; and LF's JR Z,RAG1 CALL TYPE ;Else good data, type it JR RAG1 ;Found space, now time follows... RAG2: CALL ILPRT DB CR,LF DB 'New time is: ',0 RAGA: CALL MODIST ;Else, check status JR Z,RAGA ;Nothing, then loop (or time out) CALL MODIN ;Get byte from modem CP CR ;We don't want any JR Z,RAGA ; ...CR's CP LF JR Z,RAGA ; ...LF's CP 'A' ;We want to know the JR Z,RAGB ; end of the CP 'P' ; string too JR Z,RAGB CALL TYPE ;Else type it to CRT JR RAGA ;Loop until we find the end RAGB: CALL TYPE ;Type the last one LD A,'M' ;And then this CALL TYPE RET ;Nothing found on command line... NONE: CALL ILPRT DB BELL DB 'Program used to set the time on the' DB ' PROMETHEUS smartmodem.' DB CR,LF,LF DB 'USE: A>MODSET MM/DD/hh/mmx' DB CR,LF,LF DB 'Where:' DB CR,LF DB 'MM = Month number' DB CR,LF DB 'DD = Day number' DB CR,LF DB 'hh = hour (in 12-hour format...1:00 not 13:00)' DB CR,LF DB 'mm = minute' DB CR,LF DB 'x = either "P" for PM, or "A" for AM.' DB CR,LF,LF,0 ;Quit the program... QUIT: CALL ILPRT DB CR,LF,LF,0 LD SP,(STACK) RET ;Soft return ; ############################################ ; # I N I T # ; ############################################ ; Add a routine that will set-up your ; modem port, if needed... ; These should be the same as BYE configurations.. ; Currently set-up for KAYPRO-II/IV ;Write registers, all not used... REG0 EQU 0 REG1 EQU 1 REG2 EQU 2 REG3 EQU 3 REG4 EQU 4 REG5 EQU 5 REG6 EQU 6 REG7 EQU 7 ;# ;These are the values to send to the proper registers... WRREG0 EQU 18H ;Reset channel WRREG1 EQU 00H ;Null- disable external status WRREG3 EQU 0C1H ;8 bits/char., Rx enable WRREG4 EQU 44H ;16x, 1 stop bit, no parity WRREG5 EQU 0EAH ;DTR on, 8 bits/char., Tx enable ;# ;These values written to SPORT for set-up DB 'TABLE' ;So it can be found in DDT ;# VALUES: DB VALEND-VALUES ;Byte count ;# DB WRREG0 DB REG4 DB WRREG4 DB REG3 DB WRREG3 DB REG5 DB WRREG5 DB REG1 DB WRREG1 VALEND: ;# ;These are the SPORT status masks... ;# TBIT EQU 04H ;Tx buffer empty mask RBIT EQU 01H ;Rx character available mask ;# ;This is the baud rate for BAUDP port... RATE EQU 05H ;300 baud ;# ;This is the baud rate port... BAUDP EQU 00H ;# ;System DATA port DPORT EQU 04H ;# ;System STATUS port SPORT EQU DPORT+2 ;# ;Set-up serial port... INIT: LD C,SPORT ;Port to write LD HL,VALUES ;Point to values LD B,(HL) ;Get byte count INTL: INC HL LD A,(HL) OUT (C),A ;Send to SPORT DJNZ INTL ;Till B=0 ;# ;Set-up baud rate... LD A,RATE OUT (BAUDP),A ;Send rate LD B,1 ;Loop this many times SETL: CALL DELAY ;Make more if needed DJNZ SETL RET ;# ;############################################# ;# # ;# M O D E M P O R T R O U T I N E S # ;# # ;############################################# ;# ;Modem port input status.... ;# MODIST: IN A,(SPORT) ;Get status AND RBIT ;Mask Data available? (01) CP NULL ;Set flags RET Z ;Return if no OR 0FFH ;Else, FF if yes RET ;# ;Modem port output status... ;# MODOST: IN A,(SPORT) ;Get status AND TBIT ;Mask Tx buffer empty (04) CP NULL ;Set flags RET Z ;Return if No OR 0FFH RET ;# ;Get byte at modem data port... ;# MODIN: IN A,(DPORT) AND 7FH ;Mask parity RET ;# ;Send byte to modem port... ;# MODOUT: OUT (DPORT),A RET ;# ;############################ ;Default strings... HELLO: DB 'ATZ',CR,0 ;Modem bed-check SETQ: DB 'ATQ0',CR,0 ;Over ride switch-6 TIME: DB 'AT@T=',0 ;Set time RTIME: DB 'AT@T',CR,0 ;Read time ;:::::::::::::::::::::::::::::: ;## D A T A S T O R A G E ## ;:::::::::::::::::::::::::::::: VAL: DB 0 ;Error count SAVEIT: DS 2 ;Error save place ;Stack stuff... DS 16 ;8 level stack STACK: DS 2 ;Stack's resting place END