{ ROS.MCH - Remote Operating System Machine Dependent Routines } { File: TV803.MCH Description: This driver set is designed to support the Televideo 803. Date: 4/27/87 Author: Darrell Pittman } {** System routines **} procedure putstat(st: StrStd); { Display 'st' on status line } const status_line = 25; last_line = 24; begin GotoXY( 1, status_line ); LowVideo; writeln( st ); HighVideo; GotoXY( 1, last_line ); end; {** Remote channel routines **} const BASE = $20; {base address of Z80 STI} DATA = $2F; {data register} RSTAT = $2D; {receiver status register} TSTAT = $2E; {transmitter status register} CTRL = $2C; {control register} GPIP = $21; {general purpose I/O interrupt} PVR = $28; {pointer vector register} IDR = $20; {indirect data register} IMRB = $26; {interrupt mask} IMRA = $25; {interrupt mask a} TABCR = $29; {timer A and B data register} TBDR = $2A; {timer B data register} TADR = $2B; {timer A data register} { masks for GPIP port } GPIP_NOCARRIER = $01; { bit 0 set if no carrier } GPIP_DTRHI = $00; { set DTR high } GPIP_DTRLOW = $20; { set DTR low } { masks for TSTAT port} TSTAT_TRDY= $80; {bit 7 set if transmitter ready} { masks for RSTAT port} RSTAT_RRDY= $80; {bit 7 set if receiver ready} IERB = $04; {interrupt enable register B} IERA = $05; {interrupt enable register A} DDR = $06; {data direction register} EOS = '$'; {end of string} {baud rate constants } { ...clock tick counters for the TADR register} BD75 = $80; BD150 = $40; BD300 = $20; BD600 = $10; BD1200 = $08; BD2400 = $04; BD4800 = $02; BD9600 = $01; var cr3 : byte; {byte to save bits-parity-stop. } mask : byte; {masks input chars according to parity } procedure cr3on( mask : byte ); begin cr3 := cr3 or mask; port[CTRL] := cr3; end; procedure cr3off( mask : byte ); begin cr3 := cr3 and (not mask); port[CTRL] := cr3; end; procedure ch_setparity( code : byte ); { set parity. "code" must be either 0 (no parity), 1 (odd), or 2 (even)} begin case code of 0: cr3off( $04 ); 1: begin cr3off( $02 ); cr3on( $04 ); end; 2: begin cr3on( $02 ); cr3on( $04 ); end; else writeln('ch_setparity> Attempt to assign ', code, ' parity. Ignored.'); end; end; procedure ch_setwordlength( bits : byte ); { set number of data bits. "bits" must be 7 or 8} begin case bits of 7: begin cr3off( $40 ); cr3on( $20 ); mask := $7F; end; 8: begin cr3off( $60 ); mask := $FF; end; else writeln('ch_setwordlength> Attempt to assign ', bits, ' data bits. Ignored.'); end; end; procedure ch_setstopbits( bits : byte ); { set number of stop bits. "bits" must be either 1 or 2 } begin case bits of 1: cr3off( $10 ); 2: cr3on( $10 ); else writeln( 'ch_setstopbits> Attempt to assign ', bits, 'stop bits. Ignored.'); end; end; procedure ch_init; { Initialize the remote channel } begin port[PVR] := ( IERB or $60 ); {clear interrupt enables} port[IDR] := $10; {send through indirect register} port[PVR] := ( IERA or $60 ); port[IDR] := $00; {clear second set} port[IMRA] := $DE; {permit only timer A interrupt} port[IMRB] := $30; {permit only timers C & D} port[PVR] := ( DDR or $60 ); {set data direction register} port[IDR] := $24; {set direction 0=in 1=out} cr3 := $AE; {save in "cr3". Will be overridden} port[CTRL] := cr3; {set x16 clock, and other unneeded stuff} ch_setwordlength( 8 ); {set to 8-bit data length} ch_setparity( 0 ); {set to no parity} ch_setstopbits( 1 ); {set number of stop bits) port[RSTAT] := $01; {enable receiver} port[TSTAT] := $01; {enable transmitter} port[GPIP] := $84; {set RTS} end; procedure ch_on; { Turn on remote channel (usually by enabling DTR) } begin port[GPIP] := GPIP_DTRHI; delay(250); end; procedure ch_off; { Turn off remote channel (usually by disabling DTR) } begin port[GPIP] := GPIP_DTRLOW; delay(250) end; function ch_carck: boolean; { Check to see if carrier is present } begin ch_carck := (port[GPIP] and GPIP_NOCARRIER) = 0; end; function ch_inprdy: boolean; { Check for ready to input from port } begin ch_inprdy := ( port[RSTAT] and RSTAT_RRDY ) <> 0; end; function ch_inp: byte; { Input a byte from port - no wait - assumed ready } begin ch_inp := port[DATA] and mask; end; function ch_outrdy : boolean; { Check for ready to output to port} begin ch_outrdy := ( port[TSTAT] and TSTAT_TRDY ) <> 0; end; procedure ch_out(bt: byte); { Output a byte to port - wait until ready } begin repeat until ch_outrdy; {wait until transmitter is ready} port[DATA] := bt; {...then output} end; procedure ch_set(r: integer); { Set the bps rate } procedure setbrx( r : integer; code : byte ); {called when supportability of requested baud rate establised} {sets global baud rate indicator "rate" } begin rate := r; {save new baud rate setting} port[RSTAT] := $00; {off receiver} port[TSTAT] := $00; {off transmitter} port[TABCR] := $00; {off counters A & B} port[TADR] := code; {set channel A data register} port[TABCR] := $11; { ... on both counters} port[RSTAT] := $01; {on receiver} port[TSTAT] := $01; {on transmitter} end; begin case r of 75: setbrx( r, BD75 ); 150: setbrx( r, BD150 ); 300: setbrx( r, BD300 ); 600: setbrx( r, BD600 ); 1200: setbrx( r, BD1200 ); 2400: setbrx( r, BD2400 ); 4800: setbrx( r, BD4800 ); 9600: setbrx( r, BD9600 ); else writeln( 'ch_set> Unsupported baud rate ', r, ' ignored.' + BEL); end; end; procedure system_init; { Initialization to be done once when ROS first starts } begin ch_off; {drop DTR} delay(1000); ch_on; {raise DTR} delay(1000); end; procedure system_de_init; { De-initialization to be done once when ROS terminates } begin ch_off; {drop DTR} delay(1000); ch_on; {raise DTR} putstat(''); {clear status line} end;