(***************************************************************************** * * * SAMPLE7.PAS : COUNTER/TIMER * * * * This is a demonstration program to be used with the A/DC card. * * * *****************************************************************************) program sample7; uses crt, dos; const DEFAULT_ADDRESS='340'; COUNTER_OFFSET =$0C; IRQ = 5; base:integer=$340; procedure CtrMode(addr : word; cntr, mode:byte); var ctrl:byte; begin ctrl := (cntr shl 6) or $30 or (mode shl 1); port[addr+3] := ctrl; end; procedure CtrLoad(addr : word; c, val:word); begin port[addr+c] := lo(val); port[addr+c] := hi(val); end; function CtrRead(addr : word; c : integer) : word; var temp : word; begin port[addr+3] := c shl 6; temp := port[addr+c]; CtrRead := temp + (port[addr+c] shl 8); end; (**************************************************************************** * FUNCTION: AskForBaseAddress * ****************************************************************************) function AskForBaseAddress(OldOne : String) : Word; const Msg : string[4] = '0'; var NewOne, Success, Dummy, Error : Word; AddrInputPosX, AddrInputPosY : Word; begin if (OldOne = 'OLD') then OldOne := Msg; WriteLn('Please enter the Base Address (0000-FFFF) for your card (in hex)'); WriteLn('or press ENTER for ', OldOne, '. '); Write('>'); AddrInputPosX := WhereX; AddrInputPosY := WhereY; repeat GotoXY(AddrInputPosX, AddrInputPosY); ClrEol; Readln(Msg); Val('$' + Msg, NewOne, Error); if (Error=0) then begin Success := 1; Dummy := NewOne; end else if (Msg = '') then begin GotoXY(AddrInputPosX, AddrInputPosY); WriteLn(OldOne); Msg := OldOne; Success := 1; Val('$' + Msg, Dummy, Error); end; until (Success = 1); AskForBaseAddress := Dummy; end; { end of AskForBaseAddress } (**************************************************************************** * * * FUNCTION: main program - global routine * * * * INPUT: None. * * * * CALLS: None. * * * * OUTPUT: None. * * * ****************************************************************************) var data:word; IRQGenerated:boolean; chan:word; ch:char; OldIntVec : Procedure; {$F+} procedure NewIntVec; interrupt; var trash:word; begin IRQGenerated := TRUE; trash:=port[base+1]; port[$20] := $20; end; {$F-} BEGIN chan:=0; ClrScr; WriteLn(' Pascal SAMPLE #7: SAMPLE7.PAS '); WriteLn(' '); WriteLn(' This sample will read data from all channels on the A/DC card using'); WriteLn(' timer/counter #2 to time and start conversions.'); WriteLn(' End of conversion will be detected by IRQ generation.'); WriteLn; WriteLn; base:= AskForBaseAddress( DEFAULT_ADDRESS); GetIntVec(IRQ + 8, @OldIntVec); (* save old ISR *) SetIntVec(IRQ + 8, Addr(NewIntVec)); (* set new ISR *) port[$20] := $20; (* reset PIC*) port[$21] := port[$21] AND NOT(1 SHL IRQ); (* enable IRQ *) data := port[base+1]; (* clear previous interrupts *) CtrMode( base+COUNTER_OFFSET, 0, 2); (* all counters in mode 2 *) CtrMode( base+COUNTER_OFFSET, 1, 2); CtrMode( base+COUNTER_OFFSET, 2, 2); (* counter zero without count, it won't increment, cause we don't need it.*) CtrLoad( base+COUNTER_OFFSET, 1, $00FF); CtrLoad( base+COUNTER_OFFSET, 2, $00FF); port[base+2]:=chan; (* setup channel and gain (gain code 0, gain of 1) *) port[base+0]:=$EA; (* allow counter to start conversions *) while not keypressed do begin (* wait for end of conversion *) while ((NOT IRQGenerated) AND (NOT KeyPressed)) do; IRQGenerated:=FALSE; data:=(portw[base+6] SHR 4) AND $0FFF; (* read data from conversion *) gotoxy(10,12+chan); ClrEol; WriteLn('Channel: ',chan,' Data Read: ',data); INC(chan); chan := chan MOD 8; port[base+2]:=chan; (* setup next channel *) END; ch := readkey; gotoxy(1,21); port[$21] := port[$21] OR (1 SHL IRQ); (* disable IRQ *) SetIntVec(IRQ + 8, Addr(OldIntVec)); (* restore old ISR *) END.