{ ROSMAC.INC for the OSBORNE EXEC and Hayes Smart Modem 1200 } (* THIS IS NOT A FINISHED OVERLAY. Fix me! fix me! rename to rosmac.inc and compile with ros32a. It will answer the phone the first time because I places the ATS0=1 which it shouldn't need but it doesn't reset properly and just hangs when somebody hangs up. I took addresses from the Osborne Exec Mex overlay which seems to initialize the port properly. It seems like the problem is in the hangup routine. I have noticed that if I pull the rs232 plug out of the machine the program resets like it is ready for another call but it won't answer a second call. The date routine works fine to get the date but not to set the date. I have not removed some of the kaypro stuff that this file was based on. If you can fix this overlay please upload to george's board or my board george 1-717-657-8699 my POWER board 1-608-251-3494 thanks maurice thaler voice 608-244-8517 *) YEAR,HOUR,MINUTE,SECOND,DAY,MONTH : BYTE; {CPM+TIME STUFF} JULDATE : INTEGER; {** Time and date routines } PROCEDURE JulToDay(Year : Byte; JulDate : INTEGER; VAR Month, Day : Byte); CONST DaysInMonth = ' 312831303130313130313031'; VAR DayInMon, ResCode : INTEGER; Finished : BOOLEAN; BEGIN Month := 1; Finished := false; WHILE NOT Finished DO BEGIN VAL(COPY(DaysInMonth, 2*Month, 2), DayInMon, ResCode); IF (Month = 2) THEN BEGIN IF ((Year MOD 4) = 0) THEN DayInMon := DayInMon + 1 END; IF (JulDate <= DayInMon) THEN Finished := true ELSE BEGIN JulDate := JulDate - DayInMon; Month := Month + 1 END END; Day := JulDate END; PROCEDURE CPMtoJulian(CPMdate : INTEGER; VAR Year : Byte; VAR JulDate : INTEGER); CONST BaseYear = 78; BEGIN Year := CPMdate DIV 365; JulDate := (CPMdate MOD 365) - ((Year+1) DIV 4); Year := Year + BaseYear END; PROCEDURE GetTimeAndDate(VAR Year : Byte; VAR JulDate : INTEGER; VAR Hour, Minute, Second : Byte); CONST TimeAndDate = 105; VAR TimeDate : RECORD DateInt : INTEGER; HourByte : Byte; MinByte : Byte END; FUNCTION BCDtoBIN(BCD : Byte) : Byte; BEGIN BCdtoBIN := 10 * (BCD DIV 16) + (BCD MOD 16) END; BEGIN Second := BCDtoBIN(BDos(105, Addr(TimeDate))); WITH TimeDate DO BEGIN Minute := BCDtoBIN(MinByte); Hour := BCDtoBIN(HourByte); CPMtoJulian(DateInt, Year, JulDate) END END; procedure GetTAD(var t: tad_array); { Return a 6 element integer array of the current system time in seconds, minutes, hours, day, month, and year. } begin gettimeanddate (year,juldate,hour,minute,second); jultoday (year,juldate,month,day); t[0] := second; t[1] := minute; t[2] := hour; t[3] := day; t[4] := month; t[5] := year end; (* procedure GetTAD(var t: tad_array); { Return a 6 element byte array of the current system time in seconds, minutes, hours, day, month, and year. } var i : integer; Time : array [0..12] of byte; { Array filled in from Z-Clock } begin for i := 0 to 12 do { This section reads the Z-Clock } Time[i] := port[BasePort + i]; t[0] := Time[1] * 10 + Time[0]; if Time[5] < 4 then t[2] := Time[5] * 10 + Time[4] else if Time[5] >= 8 then t[2] := (Time[5] - 8) * 10 + Time[4] else t[2] := (Time[5] - 4) * 10 + Time[4]; t[1] := Time[3] * 10 + Time[2]; if Time[8] >= 4 then Time[8] := Time[8] - 4; t[3] := Time[8] * 10 + Time[7]; t[4] := Time[10] * 10 + Time[9]; t[5] := Time[12] * 10 + Time[11] end; *) procedure SetTAD(var t: tad_array); { Set the system time using a 6 element byte array } var i : integer; Time : array [0..12] of byte; { Array filled in from Z-Clock } begin Time[0] := 0; Time[1] := 0; Time[2] := t[1] mod 10; Time[3] := t[1] div 10; Time[4] := t[2] mod 10; Time[5] := t[2] div 10; Time[6] := 0; { Day of week computed in ROS } Time[7] := t[3] mod 10; Time[8] := t[3] div 10; Time[9] := t[4] mod 10; Time[10]:= t[4] div 10; Time[11]:= t[5] mod 10; Time[12]:= t[5] div 10; For i := 0 to 12 do { port[BasePort + i] := Time[i] } end; procedure SpecialBell(bell_on: boolean); { Signal sysop from chat with special bell (if available) } begin if bell_on then port[$C8] := $0F else port[$C8] := $07 end; const { Machine specific constants } DataPort = $0C; { Data port } StatusPort = $0D; { Status port } RatePort = $04; { Data rate (bps) port } RESCHN = $18; { reset channel } RESSTA = $14; { reset ext/status } WRREG1 = $00; { value to write to register 1 } WRREG3 = $C1; { 8 bits/char, rx enable } WRREG4 = $44; { 16x, 1 stop bit, no parity } DTROFF = $68; { dtr off, rts off } DTRON = $EA; { dtr on, 8 bits/char, tx enable, rts on } ONINS = $30; { error reset } { StatusPort status masks } DAV = $01; { data available } TRDY = $04; { transmit buffer empty } DCD = $20; { data carrier detect } PE = $10; { parity error } OE = $20; { overrun error } FE = $40; { framing error } ERR = $60; { parity, overrun and framing error } { Smartmodem result codes } OKAY = '0'; { Command executed with no errors } CONNECT300 = '1'; { Carrier detect at 300 bps } RING = '2'; { Ring signal detected } NOCARRIER = '3'; { Carrier lost or never heard } ERROR = '4'; { Error in command execution } CONNECT1200 = '5'; { Carrier detect at 1200 bps } { Rate setting commands } BDSET1200 = $47; BDSET300 = $1; BD300 = $80; { 300 bps } BD1200 = $60; { 1200 bps } procedure putstat(st: StrStd); { Put 'st' on status line and return to normal display } const status_line = 1; { Line used for system status } last_line = 24; { Last line on screen } begin GotoXY(1, status_line); ClrEol; LowVideo; write(st); HighVideo; GotoXY(1, last_line) end; procedure mdout(b: byte); { Output a byte to modem - wait until ready } begin repeat until ((TRDY and port[StatusPort]) <> 0); port[DataPort] := b end; function mdinp: byte; { Input a byte from modem - no wait - assumed ready } const NOPAR = $7F; var bt: byte; begin bt := port[DataPort]; 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) end; bt := ord(CR); mdout(bt); delay(2000); end; procedure mdinit; { Initialize the sio channel and the Hayes Smartmodem 1200 } const sio_init: array[1..9] of byte = (RESCHN, 4, WRREG4, 1, WRREG1, 3, WRREG3, 5, DTROFF); var i: integer; mdmstr : StrStd; bt : byte; begin for i := 1 to 9 do port[StatusPort] := sio_init[i]; { initialize the SIO channel } port[StatusPort] := 5; { pull DTR high } port[StatusPort] := DTRON; { port[RatePort] := BDSET1200;} port[RatePort] := BD1200; {set the ZSIO to 1200 baud} delay (500); {let the modem settle for a bit} mdmstr := 'ATZ'; mdsend(mdmstr,3); mdmstr := 'AT'; mdsend(mdmstr,2); {force the modem to 1200 baud} mdmstr := 'ATE0Q0V0M0X1 S0=1 S2=3 S4=255 S5=255'; mdsend(mdmstr,41); bt := mdinp; { clear any previous rings } bt := mdinp end; function mdinprdy: boolean; { Check for ready to input from modem } var bt: byte; begin if ((DAV and port[StatusPort]) <> 0) then begin port[StatusPort] := 1; if ((ERR and port[StatusPort]) <> 0) then begin port[StatusPort] := ONINS; bt := port[DataPort]; mdinprdy := FALSE end else mdinprdy := TRUE end else mdinprdy := FALSE end; function mdring: boolean; { Determine if the phone is ringing } var code: char; begin if mdinprdy then begin code := chr(mdinp); if code = RING then mdring := TRUE else mdring := FALSE end else mdring := FALSE end; function mdcarck: boolean; { Check to see if carrier is present } begin port[StatusPort] := RESSTA; mdcarck := ((DCD and port[StatusPort]) <> 0) end; procedure mdhangup; { Hangup modem } var mdmstr : StrStd; begin { repeat } port[StatusPort] := 5; { setup to write register 5 } port[StatusPort] := DTROFF; { clear DTR, causing hangup } delay(2000); port[StatusPort] := 5; port[StatusPort] := DTRON; if mdcarck then begin mdmstr := chr(3)+chr(3)+chr(3); mdsend(mdmstr,3); { get modems attention } mdmstr := 'ATH0'; mdsend(mdmstr,4); { hang up phone } 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 repeat until mdinprdy; bt := mdinp; mdmstr := 'ATA'; mdsend(mdmstr,3); repeat until mdinprdy; code := chr(mdinp); if code = CONNECT1200 then begin port[RatePort] := BDSET1200; port[RatePort] := BD1200; rate := {50;}$60; delay(500); bt := mdinp; bt := mdinp end; if code = CONNECT300 then begin port[RatePort] := BDSET300; port[RatePort] := BD300; rate :={ 200;} $180; delay(500); bt := mdinp; bt := mdinp end; if code = NOCARRIER then mdhangup end; procedure system_init; { System particular initialization to be done once (when ROS first starts) } begin 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;