Blame | Last modification | View Log | Download | RSS feed
; CPU_TIME.INC;*************************************************************************;* *;* Author...: Oli(ver Sellke) D-65199 Wiesbaden *;* auf AS umgestellt von Alfred Arnold, Oktober 1993 *;* die Low-Level-Ausgaberoutinen sind nach CONOUT.INC verlagert *;* Date.....: 14 Okt 1993 Version..: 1.0 *;* Target...: TLCS900-Family (TOSHIBA) Compiler.: AS V1.39p1 *;* Project..: General Purpose / e.g. TMP96C141F / Watt Ihr Volt *;* *;* Function.: Mit dieser Routine kann man die Ausfuehrungszeit die *;* ein Programm(teil) benoetigt ermitteln. *;* Die Zeit wird mit Timer4 und CAP1 davon gemessen, d.h. *;* dieser darf innerhalb des gemessenen Programm(teil)s *;* nicht (!) benutzt werden. *;* !!! Alle Zeiten beziehen sich auf einen 14,7456MHz Quarz!! *;* Zur Ausgabe des Messwertes werden Monitor-Routinen benutzt,*;* deshalb kann es auch nur unter Anwendung von diesem zur *;* Ausfuehrung gebracht werden. *;* Wenn ein Programm(teil) getestet wird, dessen Ausfuehrungs-*;* zeit unbekannt ist, sollte man die 8,681us Aufloesung waehlen *;* um einen Overrun des Counters zu verhindern. Wenn der Wert *;* entsprechend klein ist ( <0FFF ), kann man die 0,543us Auf-*;* loesung waehlen um genauere Werte zu bekommen. *;* Ausserdem ist die Ermittlung der 16 groessten und 16 kleinsten *;* Werte die bei mehreren Durchlaeufen erzielt wurden moeglich! *;* Man kann so einige 1000 Durchlaeufe fahren mit immer unter- *;* schiedlichen Randbedingungen auf die der zu testende Pro- *;* teil entsprechend reagiert und auch Zeit benoetigt. *;* So hat man sicher die minimale und maximale Laufzeit. *;* *;* Bei allgemeiner Verwendung: *;* Max.Meсwert=0FFFFH = 35.585us bei 0,543us Aufloesung *;* Max.Meсwert=0FFFFH = 568.909us bei 8,681us Aufloesung *;* *;* Hardware.: getested auf Micro-ICE TLCS900 mit 14,7456MHz Quarz !!!! *;* *;* Routine Funktion Ausgabe Stack *;* *;* CPU_TI_INI Initialisierung ------ 6 Byte *;* CPU_TIME Uhr starten ------ 0 Byte *;* CPU_STOP Uhr stoppen Zeit+Statistik 8 Byte *;* *;* - Der Prozessor muss sich im Maximum-Modus befinden *;* - Symbol BigTime definieren fuer groessere Aufloesung *;* - Da die Routinen lokale Labels verwenden, ist mindestens AS 1.39 *;* erforderlich *;* - MACROS.INC muss vorher, CONOUT.INC irgendwo eingebunden werden *;*************************************************************************;-------------------------------------------------------------------------; gemeinsamer Anfang, Definitionensection TimerTRUN EQU 020HCAP1L EQU 034HCAP1H EQU 035HT4MOD EQU 038HCR EQU 0DHLF EQU 0AHifdef BigTimeOverhead equ 1 ; Eigenverbrauch Start/StopelseifOverhead equ 9endifCPU_TI_FAA db 40h dup (?) ; FeldAnfangsAdresse, ab hier wer-; den 40H (64) RAM-Zellen benoetigt; gleich 2 * 16 WorteCPU_TI_CR dd ? ; CPU_TIME-Control-Register,; wird noch nicht benoetigt!!!;*************************************************************************;Dieser Aufruf gehoert in den Initialisierungsbereich des zu testenden;Programmabschnittes!!proc CPU_TI_INI;Hier werden die Feldwerte initialisiert..PUSH XDE ;Wird gleich benutztPUSH BC ;Wird gleich benutztLD B,10H ;16 Woerter fuer Max.Werte werden gebrauchtLD XDE,CPU_TI_FAA ;FeldAnfangsAdresse ladenCPU_TI_INI1: LDW (XDE),00000H ;Feldzelle fuer Max.Werte initalisierenINC 2,XDE ;naechste Max.Wert-Feldzelle;adressierenDJNZ CPU_TI_INI1 ;Alle Max.Werte initialisiert?LD B,10H ;16 Woerter fuer Min.Werte werden gebrauchtCPU_TI_INI2: LDW (XDE),0FFFFH ;Feldzelle fuer Min.Werte initalisierenINC 2,XDE ;naechste Max.Wert-Feldzelle;adressierenDJNZ CPU_TI_INI2 ;Alle Min.Werte initialisiert?POP BC ;Und wieder restaurierenPOP XDE ;hier auch...RET ;Zurueck zum Aufruf!endp;*************************************************************************; Uhr startenproc CPU_TIME;Timer4 CPU-Time-Messung vorbereitenRES 4,(TRUN) ;Timer4 stop and clear !ifdef BigTimeLD (T4MOD),00100011B ;Bit 0+1:Source-Clock: 8,681цselseifLD (T4MOD),00100001B ;Bit 0+1:Source-Clock: 0,543цsendif;Bit 2 :clear from TREG5 disabled;Bit 3+4:INT-Capture disabled;Bit 5 :No Sw. capture nowSET 4,(TRUN) ;Timer4 start and count !RETendp;*************************************************************************proc CPU_STOPRES 5,(T4MOD) ;Capture1 grabs countCALL CPU_TI_SOUT ;Einzelausgabe des gemessenen WertesCALL CPU_TI_SOR ;gemessenen Wert ins Feld sortierenRET ;Zurueck zum Aufruf!endp;*************************************************************************;Hier wird der gerade gemessene Wert ausgegeben. Diese Ausgabe ist;ausreichend um Laufzeitwerte von statischen Programmabschnitten;zu ermitteln (keine Verzweigungen im Programmabschnitt).CPU_TI_SOUT: PUSH A ; needed little laterPUSH F ; needed little laterpush bc ; needed little laterld wa,(cap1l) ; gemessener Wertcall WriteTimepop bc ; back to the roots ...POP FPOP ARET ; Zurueck zum Aufruf!;*************************************************************************;Hier werden die ermittelten Werte sortiert abgelegt!;Jeweils am Feldanfang steht der groesste und der kleinste Wert.;Falls ein Wert einem anderen im Feld entspricht (gleicher Messwert);wird dieser nicht nochmal eingetragen!!!!;!!Achtung diese Routine benoetigt max. 145цs (14,7456MHz Quarz); im worst case!! Aber nur wenn Daten und Code 16Bit breit sind; und keine Waitstates zugeschaltet sind (Micro-ICE TLCS900 default RAM)!CPU_TI_SOR: PUSH HL ;Wird gleich benutztPUSH BC ;Wird gleich benutztPUSH XDE ;Wird gleich benutzt;Max.Werte sortiert ablegen!!!LD B,10H ;16 Woerter enthaelt Max.Wert-FeldLD HL,(CAP1L) ;gemessenen Wert aus Capture-Reg. holenLD XDE,CPU_TI_FAA ;erste Max.Wert-Feldzelle adressierenCPU_TI_SOR1: CP HL,(XDE) ;Wert mit Feldinhalt vergleichenJR ULT,CPU_TI_SOR2 ;Ist Wert kleiner als Feldinhalt?JR Z,CPU_TI_SOR3 ;Ist Wert gleich Feldinhalt? Abbrechen!EX (XDE),HL ;Nein-->Wert mit Feldinhalt tauschen!CPU_TI_SOR2: INC 2,XDE ;naechste Feldzelle adressierenDJNZ B,CPU_TI_SOR1 ;Alle 16 Max.Werte kontrolliert?;Min.Werte sortiert ablegen!!!CPU_TI_SOR3: LD B,10H ;16 Woerter enthaelt Min.Wert-FeldLD HL,(CAP1L) ;gemessenen Wert aus Capture-Reg. holenLD XDE,CPU_TI_FAA+20H ;erste Min.Wert-Feldzelle adressierenCPU_TI_SOR4: CP HL,(XDE) ;Wert mit Feldinhalt vergleichenJR UGT,CPU_TI_SOR5 ;Ist Wert groesser als Feldinhalt?JR Z,CPU_TI_SOR6 ;Ist Wert gleich Feldinhalt? Abbrechen!EX (XDE),HL ;Nein-->Wert mit Feldinhalt tauschen!CPU_TI_SOR5: INC 2,XDE ;naechste Feldzelle adressierenDJNZ B,CPU_TI_SOR4 ;Alle 16 Min.Werte kontrolliert?CPU_TI_SOR6: POP XDE ;Und wieder restaurierenPOP BC ;wieder restaurierenPOP HL ;hier auch...RET ;Zurueck zum Aufruf!;*************************************************************************;Hier werden die im Feld abgelegten Werte ausgeben.CPU_TI_MOUT: ;Muss noch geschrieben werden!RET ;Zurueck zum Aufruf!;*************************************************************************; eine Zeitdifferenz in WA umrechnen und ausgeben; wegen der Aufloesung der Timer ist die letzte Stelle hinter dem Komma; bei hoher Aufloesung mit Vorsicht zu geniessenWriteTime: push xwa ; Register rettenpush bcsub wa,Overhead ; Zeit korrigierenifdef BigTime ; Fall 1: niedrige Aufloesungmul xwa,8681 ; -->Nanos in XWAadd xwa,5000 ; !!Rundung!!div xwa,10000 ; Nanos , einzelne Mikros wegschmeiсenextz xwadiv xwa,100 ; Millisekunden in WAld bc,2003h ; ausgebencall WriteDecld a,'.'call CONOUTld wa,qwa ; auf 10 us genau ausgebenld bc,3002hcall WriteDeccall PSTRdb " Milli",StrTermelseif ; Fall 2: hohe Aufloesungmul xwa,543 ; -->Nanosekunden in XWAdiv xwa,1000 ; -->Nanos in QWA, Mikros in WAld bc,2005h ; Mikros 5-stellig mit Blankscall WriteDecld a,'.'call CONOUTld wa,qwa ; Nanos einstelligadd wa,50 ; Rundungextz xwadiv xwa,100 ; Ergebnis 0..9cp wa,10jr ne,NoErrld wa,9NoErr: ld bc,3001h ; einstellig ausgebencall WriteDeccall PSTRdb " Mikro",StrTermendifcall PSTRdb "sekunden",StrTerm ; gemeinsamer Restpop bc ; Register zurueckpop xwaret;*************************************************************************; gemeinsames Endeendsection