{ ROSMAC.INC for the Heath/Zenith H-89 and SmarTeam 1200 Modem } { NOTES: Required delay of 100ms when calling mdans, otherwise it would miss the connect code. Maybe the wait for output/input ready are not working correctly. UART 8250 BAUD RATE CONTROL NONE Ring Detect NONE MODEM SmarTeam 1200 CLOCK MSM 5832 Written by: John P. Hohensee (714) 884-0825 SYSOP (714) 381-2887 10 July 1985 } (* SmarTeam 1200/Hayes Smart Moden switch settings : UP UP DN UP DN UP UP DN *) {** Time and date routines } procedure GetTAD( var t : tad_array ); { Setup for Ray Albrekson's Real-Time sound/clock board for the H/Z-89 computer. Uses the MSM5832 clock chip. NOTE: This is the only way this code would run! } { Return a 6 element integer array of the current system time in seconds, minutes, hours, day, month, and year. } var Time : array[ 0..13 ] of integer; i, RegAddr : integer; begin port[ 208 ] := ord( #$07 ); { PORT 0D0H, middle serial port } port[ 210 ] := ord( #$80 ); { Port B for Output, Port A for Input } for i := 0 to 13 do begin RegAddr := 132 + i * 8; port[ 208 ] := ord( #$0F ); { Port B } port[ 210 ] := RegAddr; port[ 208 ] := ord( #$0E ); { Port A } Time[ i ] := port[ 209 ] - 240; { drop d7 thru d4 } end; t[ 0 ] := ( Time[ 1 ] and ord( #07 ) ) * 10 + Time[ 0 ]; { seconds } t[ 1 ] := ( Time[ 3 ] and ord( #07 ) ) * 10 + Time[ 2 ]; { minutes } t[ 2 ] := ( Time[ 5 ] and ord( #03 ) ) * 10 + Time[ 4 ]; { hours } t[ 3 ] := ( Time[ 8 ] and ord( #07 ) ) * 10 + Time[ 7 ]; { day } t[ 4 ] := ( Time[ 10 ] and ord( #01 ) ) * 10 + Time[ 9 ]; { month } t[ 5 ] := Time[ 12 ] * 10 + Time[ 11 ]; { year } end; procedure SetTAD( var t : tad_array ); { Set the system time using a 6 element integer array which contains seconds, minutes, hours, day, month, and year. } begin { HAVE NOT CODED THE SET FEATURE YET } end; { System Special Functions } procedure SpecialBell(bell_on: boolean); { Signal sysop from chat with special bell (if available) } begin if bell_on then write( BEL ); end; procedure system_init; { System particular initialization to be done once (when ROS first starts) } var mdmstr : StrStd; bt : byte; begin Write( ESC,'x1' ); end; procedure putstat(st: StrStd); { Put 'st' on status line and return to normal display } const status_line = 25; { Line used for system status } last_line = 24; { Last line on screen } begin GotoXY( 1, status_line ); ClrEol; { Clear garbage from line } LowVideo; write( st ); { Write message } HighVideo; GotoXY( 1, last_line ) { Return to main screen } end; { Machine specific constants } const Data_Port = $D8; { Data port } Line_Control = $DB; { Selects Baud Rate Register } Modem_Control = $DC; { DTR and RTS bits } Line_Status = $DD; { Line Status port } Status_Port = $DE; { Modem Status port } { UART specific constants } Word_Len = $03; { 8 Data, No Parity, 1 Stop } DTR_OFF = $00; { dtr off, rts off } DTR_ON = $03; { dtr on, rts on } DLAB = $83; { Rate setting commands } Set_300 = 1; BDL300 = $80; { 300 baud } BDH300 = $01; Set_1200 = 2; BDL1200 = $60; { 1200 baud } BDH1200 = $00; { StatusPort status masks } DAV = $01; { data available } TRDY = $20; { transmit buffer empty } DCD = $80; { data carrier detect } PE = $04; { parity error } OE = $02; { overrun error } FE = $08; { framing error } ERR = $0E; { parity, overrun and framing error } RDET = $40; { Ring detect - NOT USED } RLST = $02; { Ring Last - NOT USED } { Smartmodem result codes } OKAY = '0'; { Command executed with no errors } CONNECT_300 = '1'; { Carrier detect at 300 bps } RING = '2'; { Ring signal detected } NO_CARRIER = '3'; { Carrier lost or never heard } ERROR = '4'; { Error in command execution } CONNECT_1200 = '5'; { Carrier detect at 1200 bps } { Common Routines - called by ROSMAC and ROS } procedure mdout( b : byte ); { Output a byte to modem - wait until ready } var bt : byte; begin repeat bt := port[ Line_Status ]; until ( ( TRDY and bt ) <> 0 ); port[ Data_Port ] := b end; function mdinp : byte; { Input a byte from modem - no wait - assumed ready } const NOPAR = $7F; var bt : byte; begin bt := port[ Data_Port ]; mdinp := NOPAR and bt end; procedure mdsend( mstr : StrStd; lstr : Integer ); { Send a command string to the modem w/ CR and delay } var i : integer; bt : byte; begin for i := 1 to lstr do begin bt := ord( mstr[ i ] ); mdout( bt ); delay( 50 ); { Required by SmarTEAM 1200 } end; bt := ord( CR ); mdout( bt ); delay( 2000 ); end; procedure Baud( Rate : integer ); { Set Baud rate for 8250 UART - makes baud changes easier } var bt : byte; begin port[ Line_Control ] := DLAB; { Set DLAB, Select for BAUD RATE } case Rate of Set_300 : begin port[ Data_Port ] := BDL300; port[ Data_Port + 1 ] := BDH300; end; Set_1200 : begin port[ Data_Port ] := BDL1200; port[ Data_Port + 1 ] := BDH1200; end; end; port[ Line_Control ] := Word_Len; { 8 Data, 1 Stop, No Parity } delay( 500 ); bt := mdinp; bt := mdinp; end; { routines - Called by ROS } procedure mdinit; { Initialize the sio channel and the Hayes Smartmodem 1200 } var mdmstr : StrStd; bt : byte; i : integer; begin port[ Modem_Control ] := DTR_OFF; { Drop DTR & RTS } delay( 500 ); port[ Modem_Control ] := DTR_ON; { Raise DTR & RTS } baud( Set_1200 ); mdmstr := 'ATZ'; mdsend( mdmstr, 3 ); { Reset Modem } mdmstr := 'AT'; mdsend( mdmstr, 2 ); { Get Modem's Attention } mdmstr := 'ATE0Q0V0M0X1 S0=0 S2=3 S4=255 S5=255'; mdsend( mdmstr, 41 ); { Initialize Modem } bt := mdinp; { Clear Garbage } bt := mdinp end; function mdinprdy : boolean; { Check for ready to input from modem } var bt : byte; code : char; begin bt := port[ Line_Status ]; mdinprdy := ( ( DAV and bt ) <> 0 ); end; function mdring : boolean; { Determine if the phone is ringing } { NO HARDWARE RING DETECT AVAILABLE } var code : char; begin mdring := FALSE; if mdinprdy then begin code := chr( mdinp ); if code = RING then mdring := TRUE end; end; function mdcarck : boolean; { Check to see if carrier is present } var bt : byte; begin mdcarck := ( ( DCD and port[ Status_Port ] ) <> 0 ); end; procedure mdhangup; { Hangup modem } var mdmstr : StrStd; begin repeat port[ Modem_Control ] := DTR_OFF; { drop DTR, causing hangup } delay( 2000 ); port[ Modem_Control ] := DTR_ON; { Raise DTR } if mdcarck then begin mdmstr := chr( 3 ) + chr( 3 ) + chr( 3 ); mdsend( mdmstr, 3 ); mdmstr := 'ATH0'; mdsend( mdmstr, 4 ); end; until not mdcarck end; procedure mdans; { Detect and set system to rate at which modem answered phone } var mdmstr : StrStd; code : char; bt : byte; begin delay( 100 ); { Required at least for SmarTeam } repeat until mdinprdy; bt := mdinp; { Dump Garbage char } mdmstr := 'ATA'; mdsend( mdmstr, 3 ); repeat until mdinprdy; code := chr( mdinp ); case code of { OKAY : ** MAKES TESTING EASY **} { WRITELN( 'OKAY' ); TEST } CONNECT_300 : begin baud( Set_300 ); rate := 0.083; { WRITELN( 'CONNECT 300' ); TEST } end; { RING : } { WRITELN( 'RING' ); TEST } NO_CARRIER : { begin } mdhangup; { WRITELN( 'NO CARRIER' ); TEST } { end; } { ERROR : } { WRITELN( 'ERROR' ); TEST } CONNECT_1200 : begin baud( Set_1200 ); rate := 0.02075; { WRITELN( 'CONNECT 1200' ); TEST } end; { else } { WRITELN( 'NOT CODED code = ', code ); } end; end; procedure mdbusy; { Take modem off hook to present a busy signal to incoming callers } var mdmstr : String[ 4 ]; begin mdmstr := 'ATH1'; { take modem off hook to give busy signal } mdsend( mdmstr, 4 ); end; { - - - - - ROSMAC.INC H89 - - - - - }