home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
ucsdappleii.tar.gz
/
ucsdappleii.tar
/
kermacia.text
< prev
next >
Wrap
Text File
|
1986-04-08
|
10KB
|
289 lines
(************* UNIT KERMACIA ********************************************)
(*$S+*)
(*$I-*)
(*$R-*)
(*$V-*)
UNIT KERMACIA; intrinsic code 18 data 19;
INTERFACE
USES kermglob;
PROCEDURE send_break ( adr_comm_reg : integer );
PROCEDURE get_acia_parms( var xpar : parity_type;
var xdbit, xstopbit, xbaud : integer );
PROCEDURE set_acia_parms( xpar : parity_type;
xdbit, xstopbit, xbaud : integer );
IMPLEMENTATION
This unit implements the possibility to change baud rates, parity, number
of databits and stopbits for outgoing characters and the possibility to
send a break signal to the remote host.
This unit is dependent on a special unitstatus call, provided by the
attached driver for remin: ( see file remdriver.text ).
The code below is specific for the 6551 acia on a AP2 serial card from IBS
and for the 6850 acia on a CCS model 7710 ASI1 card, that is probably
similar to the Apple Com Card and the Hayes micromodem card.
On the CCS card it is not possible to change the baud rate by soft command
nor is it possible to set space parity.
If you have a different serial card then this unit should be adapted to
the requirements of that card's acia. If you do not know how to or do not
want to rewrite this unit's implementation, then you can set the value of
'acia_implem' in the kermit.data file to 0 (= unknown). The settable
parameters will then equal the default values , but can no longer be
changed at run time. The procedure send_break will then do nothing.
acia_cntrl_reg = -16209; =$C0AF Specific for a 6551 acia on a
acia_comm_reg = -16210; =$C0AE AP2 serial card in slot 2.
acia_comm_reg = -16224; =$C0A0 Specific for CCS 6850 acia.
The 6850 does not have a
control register.
These 2 adresses are declared in unit kermglob.
If your card also has a 6551 acia then these adresses will
probably be different. They can then be changed in the kermit.data file.
TYPE baud_types = (B16ext, B50, B75, B110, B135, B150, B300, B600,
B1200, B1800, B2400, B3600, B4800, B7200, B9600,
B19200); { 6551 specific }
dbit_types = (dbit8, dbit7, dbit6, dbit5 ); { 6551 specific }
cntrl_6551 = PACKED RECORD
baudr : baud_types;
freq : ( ext, int );
wordlen: dbit_types;
stpbit : ( one, variable );
msb1 : 0..255 ;
END;
comm_6551 = PACKED RECORD
dont_change : 0..31 ;
set_par : BOOLEAN;
par_type : ( p_odd, p_even, p_mark, p_space );
msb2 : 0..255 ;
END;
comm_6850 = PACKED RECORD
filler1 : 0..3 ;
serdata : ( d7pes2, d7pos2, d7pes1, d7pos1,
d8pns2, d8pns1, d8pes1, d8pos1 );
{ d=databits, p=parity, e=even, o=odd, n=none, s=stopbit }
filler2 : 0..7 ;
msb3 : 0..255;
END;
stat_rec1 = RECORD
adres1 : INTEGER;
content1 : cntrl_6551;
END;
stat_rec2 = RECORD
adres2 : INTEGER;
content2 : comm_6551;
END;
stat_rec3 = RECORD
adres3 : INTEGER;
content3 : comm_6850;
END;
VAR baud_rate : ARRAY[ baud_types ] OF INTEGER;
dbits : ARRAY[ dbit_types ] OF INTEGER;
reg_6551_control : stat_rec1;
reg_6551_komm : stat_rec2;
reg_6850_comm : stat_rec3;
cw_status, cw_control : cntrl_word_rec;
PROCEDURE get_6551_parms ( var xpar:parity_type;
var xdbit, xstopbit, xbaud : integer );
BEGIN
reg_6551_control.adres1 := acia_cntrl_reg;
reg_6551_komm.adres2 := acia_comm_reg;
UNITSTATUS( inport, reg_6551_control, cw_status );
UNITSTATUS( inport, reg_6551_komm, cw_status );
WITH reg_6551_komm.content2 DO
BEGIN
IF set_par THEN BEGIN
CASE par_type OF
p_odd : xpar := odd_par;
p_even : xpar := even_par;
p_mark : xpar := mark_par;
p_space : xpar := space_par;
END;
END
ELSE xpar := no_par;
END; { with }
WITH reg_6551_control.content1 DO
BEGIN
xbaud := baud_rate[ baudr ];
xdbit := dbits[ wordlen ];
CASE stpbit OF
one : xstopbit := 1;
variable : BEGIN
xstopbit := 2;
IF ( xpar <> no_par ) and ( word_len = dbit8 )
THEN xstopbit := 1;
IF ( xpar = no_par ) and ( word_len = dbit5 )
THEN xstopbit := 15;
END;
END; { case stpbit }
END; { with }
END; { get_6551_parms }
NOTE : xstopbit = 15 actually means 1.5 stopbit
PROCEDURE get_acia_parms{ var xpar:parity_type;
var xdbit,xstopbit,xbaud : integer};
begin
if acia_implem = A6551 then get_6551_parms( xpar, xdbit, xstopbit, xbaud );
end; { get_acia_parms }
PROCEDURE set_6551_parms ( xpar:parity_type;
xdbit, xstopbit, xbaud : integer );
VAR oldpar : parity_type;
oldbaud, olddbit, oldstopb : INTEGER;
i : baud_types;
j : dbit_types;
BEGIN
get_6551_parms( oldpar, olddbit, oldstopb, oldbaud );
WITH reg_6551_komm.content2 DO
BEGIN
set_par := TRUE;
CASE xpar OF
no_par : set_par := FALSE;
odd_par : par_type := p_odd;
even_par : par_type := p_even;
mark_par : par_type := p_mark;
space_par : par_type := p_space;
END; { case }
END; { with }
UNITSTATUS( inport, reg_6551_komm, cw_control );
WITH reg_6551_control.content1 DO
BEGIN
FOR i := B50 TO B19200 DO IF baud_rate[ i ] = xbaud THEN baudr := i;
FOR j := dbit8 TO dbit5 DO IF dbits[ j ] = xdbit THEN word_len := j;
IF xstopbit = 1 THEN stpbit := one
ELSE stpbit := variable;
END; { with }
UNITSTATUS( inport, reg_6551_control, cw_control );
END; { set_6551_parms }
PROCEDURE set_6850_parms( xpar:parity_type; xdbit,xstop : integer);
BEGIN
WITH reg_6850_comm.content3 DO
BEGIN
IF (xdbit=7) and (xpar=evenpar) and (xstop=1) THEN serdata := d7pes1 ELSE
IF (xdbit=7) and (xpar= oddpar) and (xstop=1) THEN serdata := d7pos1 ELSE
IF (xdbit=7) and (xpar=evenpar) and (xstop=2) THEN serdata := d7pes2 ELSE
IF (xdbit=7) and (xpar= oddpar) and (xstop=2) THEN serdata := d7pos2 ELSE
IF (xdbit=8) and (xpar=markpar) and (xstop=1) THEN serdata := d8pns2 ELSE
IF (xdbit=8) and (xpar= nopar) and (xstop=1) THEN serdata := d8pns1 ELSE
IF (xdbit=8) and (xpar= oddpar) and (xstop=1) THEN serdata := d8pos1 ELSE
IF (xdbit=8) and (xpar=evenpar) and (xstop=1) THEN serdata := d8pes1 ELSE
EXIT( set_6850_parms );
END; { WITH }
reg_6850_comm.content3.filler1 := 3;
reg_6850_comm.content3.filler2 := 0;
reg_6850_comm.adres3 := acia_comm_reg;
UNITSTATUS( inport, reg_6850_comm, cw_control );
{ first give an acia master reset }
reg_6850_comm.content3.filler1 := 1;
UNITSTATUS( inport, reg_6850_comm, cw_control );
{ set acia command register to desired value }
parity := xpar;
stopbit := xstop;
databit := xdbit;
END; { set_6850_parms }
PROCEDURE set_acia_parms { xpar : parity_type;
xdbit, xstopbit, xbaud : integer };
begin
case acia_implem of
A6551 : set_6551_parms( xpar, xdbit, xstopbit, xbaud );
A6850 : set_6850_parms( xpar, xdbit, xstopbit );
end;
end; { set_acia_parms }
PROCEDURE send_6551_break ( adr_comm_reg : INTEGER ); EXTERNAL;
PROCEDURE send_6850_break ( adr_comm_reg : INTEGER ); EXTERNAL;
See file asm.acia.text
PROCEDURE send_break { adr_comm_reg : integer };
sends a break signal to the host. Signal is shut off by typing any key.
The command register is restored to the previous value.
begin
case acia_implem of
A6551 : send_6551_break( adr_comm_reg );
A6850 : begin
send_6850_break( adr_comm_reg );
set_acia_parms( parity, databit, stopbit, baud );
end;
end;
end; { send_break }
BEGIN
baud_rate[ B16ext ] := 0;
baud_rate[ B50 ] := 50;
baud_rate[ B75 ] := 75;
baud_rate[ B110 ] := 110;
baud_rate[ B135 ] := 135;
baud_rate[ B150 ] := 150;
baud_rate[ B300 ] := 300;
baud_rate[ B600 ] := 600;
baud_rate[ B1200 ] := 1200;
baud_rate[ B1800 ] := 1800;
baud_rate[ B2400 ] := 2400;
baud_rate[ B3600 ] := 3600;
baud_rate[ B4800 ] := 4800;
baud_rate[ B7200 ] := 7200;
baud_rate[ B9600 ] := 9600;
baud_rate[ B19200 ] := 19200;
dbits[ dbit8 ] := 8;
dbits[ dbit7 ] := 7;
dbits[ dbit6 ] := 6;
dbits[ dbit5 ] := 5;
WITH cw_status DO
BEGIN
channel := inp;
purpose := status;
special_req := rw_req;
reserved := 0;
filler := 0;
END;
cw_control := cw_status;
cw_control.purpose := control;
{ set serial data for 6850 acia to pascal defaults }
parity := no_par;
stopbit := 1;
databit := 8;
END.