cs161agc@sdcc10.ucsd.EDU (John Schultz) (12/29/88)
Ok, here's what I've got so far: IMPLEMENTATION MODULE CIATimer; FROM SYSTEM IMPORT ADDRESS,ADR,BYTE,INLINE; FROM InOut IMPORT WriteString; FROM CIAHardware IMPORT ciaa,CIABITS,CIAicrTB; FROM CIAResource IMPORT AbleICR,AddICRVector,RemICRVector,SetICR, CIAAName; FROM Resources IMPORT OpenResource,ResourcePtr; FROM Interrupts IMPORT Interrupt,InterruptPtr; FROM Nodes IMPORT NTInterrupt; CONST TIMERON = CIABITS(1); TIMEROFF = CIABITS(0); LATCHLOW = CIABITS(0CCH); (* 2CCH = 716, for 1000hz *) LATCHHIGH = CIABITS(002H); VAR CIAResource : ResourcePtr; timer : Interrupt; oldint : InterruptPtr; oldciacrb, (* So we can restore them later *) oldciatblo, oldciatbhi : CIABITS; PROCEDURE ResetTimer; BEGIN CIATime := 0D; END ResetTimer; PROCEDURE Wait(msec : LONGCARD); BEGIN CIATime := 0D; REPEAT UNTIL CIATime >= msec; END Wait; PROCEDURE IncTimer(): LONGCARD; (* Private: Not exported *) BEGIN INC(CIATime); RETURN 0D; END IncTimer; PROCEDURE CreateTimer(): BOOLEAN; BEGIN WITH timer DO isNode.lnType := NTInterrupt; isNode.lnPri := BYTE(0); isNode.lnName := ADR("PrivateCIATimerCIAicrTB"); isData := ADR(CIATime); isCode := ADR(IncTimer); END; (* WITH *) CIAResource := OpenResource(ADR(CIAAName)); IF CIAResource = NIL THEN WriteString("OpenCIAResource Failed.\n"); RETURN FALSE; END; oldint := AddICRVector(CIAicrTB,timer,CIAResource^); IF oldint # NIL THEN (* Not available? Take it by force! *) RemICRVector(CIAicrTB,oldint^,CIAResource^); IF AddICRVector(CIAicrTB,timer,CIAResource^) # NIL THEN (* Install ours *) WriteString("AddICRVector Failed.\n");(*What?! This should never happen*) oldint := AddICRVector(CIAicrTB,oldint^,CIAResource^); CIAResource := NIL; (* So DeleteTimer will do nothing. *) RETURN FALSE; END; (* IF *) END; (* IF *) WITH ciaa^ DO (* Using Timer B *) oldciacrb := ciacrb; (* Save the old so we can restore later *) oldciatblo := ciatblo; oldciatbhi := ciatbhi; ciacrb := TIMEROFF; (* Turn off Timer B *) ciatblo := LATCHLOW; (* Set timer latch to 0x2CC (716) *) ciatbhi := LATCHHIGH; (* to give us 1000hz resolution *) ciacrb := TIMERON; (* Turn on Timer B *) END; (* WITH ciaa^ *) RETURN TRUE; END CreateTimer; PROCEDURE DeleteTimer; BEGIN IF CIAResource # NIL THEN ciaa^.ciacrb := TIMEROFF; (* Turn off Timer B *) RemICRVector(CIAicrTB,timer,CIAResource^); (* Remove our timer interrupt *) WITH ciaa^ DO (* Restore old cia values so the disk drives *) ciatblo := oldciatblo; (* will work [nice feature]. *) ciatbhi := oldciatbhi; ciacrb := oldciacrb; END; (* WITH *) (* Put back the old interrupt, this also sets the ICR bit and enAbles the corresponding bit interrupt, in this case Timer B [bit 1]. *) IF AddICRVector(CIAicrTB,oldint^,CIAResource^) # NIL THEN WriteString("DANGER: Couldn't restore old CIAicrTB Vector!\n"); WriteString(" Disk drives will now no longer function until\n"); WriteString(" REBOOT!\n"); END; END; END DeleteTimer; BEGIN CIAResource := NIL; END CIATimer. Here's what I'm trying to do: Wait with millisecond accuracy (has to be _accurate_), measure response times with millisecond accuracy. This is being used for a research project, so I'm not worried about multitasking, etc., but I'd like it to be "legal" if possible [possibly just read system timers for stamps? Can I get high-res accuracy (1ms), reliably?]. The above works fine, >> as long as there are disks in all of the drives and no disk access takes place <<. What's the scoop? What is the bottom line on these timers? Am I reading the docs wrong, or is the documentation inaccurate? Timer B on ciaa *should* be available. I can't use timer A because we need the serial port at the same time. I'd love to be enlightened on all of this...Any help appreciated. Thanks, John Schultz
riley@batcomputer.tn.cornell.edu (Daniel S. Riley) (12/29/88)
In article <38@sdcc10.ucsd.EDU> cs161agc@sdcc10.ucsd.edu.UUCP (John Schultz) writes: [...code and other stuff deleted...] > Timer B on ciaa *should* be available. I can't use timer A >because we need the serial port at the same time. Is this really true? I know the hardware reference says "Commodore Serial Communications", but SP and CNT for that CIA are connected to paper out and busy on the parallel interface. Those lines can be used for serial communciation, but they have nothing to do with the serial port, as far as I can tell. Have you actually tried using timer A and failed, or are you just trusting the somewhat misleading remarks in the hardware reference? Am I reading the Hardware reference right? Is time A actually used for anything? -Dan Riley (dsr@lns61.tn.cornell.edu, cornell!batcomputer!riley) -Wilson Lab, Cornell U.
dan@cbmvax.UUCP (Dan Baker CATS) (12/30/88)
In article <38@sdcc10.ucsd.EDU> cs161agc@sdcc10.ucsd.edu.UUCP (John Schultz) writes: > > [Long CIA timer program deleted....] > > What's the scoop? What is the bottom line on these timers? Am I >reading the docs wrong, or is the documentation inaccurate? > Timer B on ciaa *should* be available. CIA-A timer B is reserved for system use. CIA-B timer B is available for applications. The Hardware Manual is WRONG on this point. Timers are allocated as follows: ----- CIA A timer A Used for keyboard handshake. timer B Used for uSec timer.device. TOD Used for 60 Hz timer.device. CIA B timer A Commodore 8-bit serial bus communication. timer B Not used. TOD Used for graphics.library beam counter. Use CIA-B timer B for your applications. CIA-B timer A could also be used although this is reserved for a "1541-style" interface for products like the 64-Emulator. For more on this see Bob Burns' article in the Jan/Feb '89 issue of Amiga Mail coming soon. Also see Paul Higginbottom's example CIA timer porgram in the Sept/Oct '88 issue of Amiga Mail. -- Dan Baker, CATS
kodiak@amiga.UUCP (Robert R. Burns) (12/31/88)
In article ... (John Schultz) writes: 1) oldint := AddICRVector(CIAicrTB,timer,CIAResource^); 2) IF oldint # NIL THEN (* Not available? Take it by force! *) 3) RemICRVector(CIAicrTB,oldint^,CIAResource^); 4) IF AddICRVector(CIAicrTB,timer,CIAResource^) # NIL THEN (* Install ours *) 5) WriteString("AddICRVector Failed.\n");(*What?! This should never happen*) Unfortunately, there was no smiley face to calm me down. Who is served in a multitasking environment by this kind of holier-than-thou, stab-them-in-the-back programming mentality? Certainly not the user! The Amiga has a few hardware resources which can be allocated by applications that need them. If they're already in use, do one of several things: 1. Steal them, as above. *No!* 2. Die mysteriously. *No!* 3. Take the ln_Name of the oldint and present it to the user as an indication of what program precludes you from running. *Yeah!* a. *That's* why oldint was returned. b. *That's* why filling in the ln_Name field of structures is useful. c. *That way* the user is not mystified why one or the other of his applications went bust. Remember multitasking! See what happens when, between line 3 & line 4 above, another task gets cycles and follows the rules? Why *shouldn't* it happen? Remember multitasking! It imbues a special responsibility on Amiga programmers to think harder and code better, so that one's goofs do not cause another's application to appear buggy -- soiling the wrong reputation. - Kodiak -- Bob Burns, amiga!kodiak _ | /_ _|. _ | Commodore __ |_) _ |_ _ )' |<(_)(_)|(_\|< /\ | ||| _` /\ |_)(_\| )(_\ | | \ Software ___/..\|\/|||__|/..\___ Faith
cs161agc@sdcc10.ucsd.EDU (John Schultz) (12/31/88)
In article <3227@amiga.UUCP> kodiak@tooter.UUCP (Robert Burns) writes: >In article ... (John Schultz) writes: [stuff I wrote deleted] [100% USDA Certified Flames from Bob deleted] >Unfortunately, there was no smiley face to calm me down. Ok, here's one now :-). But seriously, that code was written to be used in a *research* experiment, by *no one else*. More specifically, I was forced to steal the timer because I had no other choice. If I can't have a millisecond timer, then we can't run the experiment. I had to do whatever necessary to get that timer. Why did I steal it anyway? The hardware manual was erroneous on the system's use of the timers. Thanks to Dan Baker of CATS, I have the correct information as to which timers are available. Sorry I got you (Bob) all flustered, I should have made the intended use clearer and stated what I was doing was *totally illegal* for normal use. But by golly I needed a timer and took the one the documentation said was available. Anyway, I rewrote the code using CIA-B timer B and ran the experiment [an Amiga talking to an HP which is controling a Neuromagnetometer, making Magneto EncephaloGrams (MEG's) of human brains [live, attached to people]]. Works wonderful. And the code is now fully *legal* and multitaskable. This makes the Doctors happy, which makes Me happy. I wonder what systems programmer's brain wave's look like when they see code examples that "stab's them in the back"? Better not chance it, the temperature increase might cause the superconductors to heat up and blow out the MEG, spewing helium everywhere. We'd all talk funny for a week. Thanks Dan, Bob, for your interest, John Schultz