/[projet1]/users/dbug/tests/IrqBenchmark/profiler/profile.s
Defence Force logotype

Contents of /users/dbug/tests/IrqBenchmark/profiler/profile.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 938 - (show annotations)
Sun Jun 9 19:22:25 2013 UTC (6 years, 11 months ago) by coco
File size: 14319 byte(s)


1
2 ;CPU USAGE FRAMEWORK
3
4
5 #define PROFILER_ASM
6 #define PROFILER_MAIN
7
8 #define PROFILER_IRQVECTOR $245
9 ;#define PROFILER_IRQVECTOR $FFFC
10
11
12 ; Where the profiler is display on screen.
13 #define PROFILER_SCREEN_BASE $bb80+40*25
14 #define PROFILER_LINE0 PROFILER_SCREEN_BASE+0
15 #define PROFILER_LINE1 PROFILER_SCREEN_BASE+40
16 #define PROFILER_LINE2 PROFILER_SCREEN_BASE+80
17
18
19 ;Based on setting T1 to FFFF and adding to global counter in IRQ for up to 16.5
20 ;Million Clock Cycles.
21
22
23 #define VIA_T1CL $0304
24 #define VIA_T1CH $0305
25
26 #define VIA_T1LL $0306
27 #define VIA_T1LH $0307
28
29
30
31 _ProfilerNames
32 #include "profile.h"
33
34 #ifdef PROFILER_ENABLE
35
36 .zero
37
38 _profiler_temp_0 .dsb 1
39 _profiler_temp_1 .dsb 1
40 _profiler_save_x .dsb 1
41 _profiler_save_y .dsb 1
42 _profiler_function_id .dsb 1 ; 1 byte function counter
43
44 .text
45
46 _ProfilerRoutineCount .dsb PROFILER_ROUTINE_COUNT ; How many times a routine has been called in a frame
47
48 _ProfilerRoutineTimeLow .dsb PROFILER_ROUTINE_COUNT ; 16 bits duration for each routine (low byte)
49 _ProfilerRoutineTimeMid .dsb PROFILER_ROUTINE_COUNT ; 16 bits duration for each routine (mid byte)
50 _ProfilerRoutineTimeHigh .dsb PROFILER_ROUTINE_COUNT ; 16 bits duration for each routine (high byte)
51
52 _ProfilerFrameCount .dsb 2 ; 16 bits frame counter
53 _ProfilerCycleCountLow .dsb 1 ; 24 bits cycle counter (should be in Zero Page, really)
54 _ProfilerCycleCountMid .dsb 1 ; 24 bits cycle counter (should be in Zero Page, really)
55 _ProfilerCycleCountHigh .dsb 1 ; 24 bits cycle counter (should be in Zero Page, really)
56
57 #ifdef PROFILER_USE_NAMES
58 _ProfilerRoutineNameLow .dsb PROFILER_ROUTINE_COUNT ; adress of the name for each routine (low byte)
59 _ProfilerRoutineNameHigh .dsb PROFILER_ROUTINE_COUNT ; adress of the name for each routine (high byte)
60 #endif
61
62
63
64 _ProfilerInitialize
65 .(
66 #ifdef PROFILER_USE_PRINTER
67 lda #<ProfilerMessagePrinterStart
68 ldx #>ProfilerMessagePrinterStart
69 jsr _PrinterSendString
70 jsr _PrinterSendCrlf
71 #endif // PROFILER_USE_PRINTER
72
73 ;bla
74 ; jmp bla
75
76 #ifdef PROFILER_USE_NAMES
77 .(
78 lda #<_ProfilerNames
79 sta tmp0+0
80 lda #>_ProfilerNames
81 sta tmp0+1
82 ldx #0
83 ldy #0
84 loop
85 ; Get the function id
86 lda (tmp0),y
87
88 ; Last one ?
89 cmp #PROFILER_ROUTINE_COUNT
90 beq end
91
92 ; Set the current pointer in the pointer table
93 .(
94 tax
95 inc tmp0+0
96 bne skip
97 inc tmp0+1
98 skip
99 lda tmp0+0
100 sta _ProfilerRoutineNameLow,x
101 lda tmp0+1
102 sta _ProfilerRoutineNameHigh,x
103 .)
104
105 ; Search the null terminator
106 .(
107 search
108 lda (tmp0),y
109 inc tmp0+0
110 bne skip
111 inc tmp0+1
112 skip
113 cmp #0
114 bne search
115 .)
116
117 jmp loop
118 end
119 .)
120 #endif
121
122 ; Initialize the various profiler parameters
123 ; to use sane values.
124 lda #0
125 sta _ProfilerFrameCount+0
126 sta _ProfilerFrameCount+1
127
128 ;
129 ; Install the IRQ vector
130 ;
131 sei
132 lda #<_ProfilerIrqRoutine
133 sta PROFILER_IRQVECTOR+0
134 lda #>_ProfilerIrqRoutine
135 sta PROFILER_IRQVECTOR+1
136
137 lda #$FF
138
139 ; Our main timer starts at $FFFFFF
140 sta _ProfilerCycleCountLow
141 sta _ProfilerCycleCountMid
142 sta _ProfilerCycleCountHigh
143
144 ; Set t1 latch to FFFF
145 ; We don't need to mess around with setting any special T1 mode, Oric boot
146 ; will have already done this.
147 sta VIA_T1LL
148 sta VIA_T1LH
149
150
151 ; Set t1 counter to FFFF so that we can be sure the first count is correct
152 ; As a bonus this will also reset any Interrupt flag the routine up till now may have triggered.
153 sta VIA_T1CL
154 sta VIA_T1CH
155 cli
156
157 rts
158 .)
159
160
161 _ProfilerTerminate
162 .(
163 ; Should probably restore the original IRQ handler
164 rts
165 .)
166
167
168 _ProfilerIrqRoutine
169 .(
170 ; Reset IRQ
171 cmp VIA_T1CL
172
173 ; Decrement the high byte
174 dec _ProfilerCycleCountHigh
175 rti
176 .)
177
178
179
180
181 _ProfilerNextFrame
182 .(
183 ; Increment the totaly number of frames
184 inc _ProfilerFrameCount+0
185 bne end
186 inc _ProfilerFrameCount+1
187 end
188
189 ; Reset the individual routine counters
190 lda #0
191 ldx #PROFILER_ROUTINE_COUNT
192 loop
193 sta _ProfilerRoutineCount-1,x
194 sta _ProfilerRoutineTimeLow-1,x
195 sta _ProfilerRoutineTimeMid-1,x
196 sta _ProfilerRoutineTimeHigh-1,x
197 dex
198 bne loop
199
200 ; Reset the global cycle counter
201 sei
202 lda #$FF
203
204 ; Our main timer starts at $FFFFFF
205 sta _ProfilerCycleCountLow
206 sta _ProfilerCycleCountMid
207 sta _ProfilerCycleCountHigh
208
209 ; Set t1 counter to FFFF so that we can be sure the first count is correct
210 ; As a bonus this will also reset any Interrupt flag the routine up till now may have triggered.
211 sta VIA_T1CL
212 sta VIA_T1CH
213 cli
214
215 rts
216 .)
217
218
219 /*
220 ; That one is a mad function
221 ; Takes as as the function ID,
222 ; Do the normal profile,
223 ; But then it patches the stack frame to call the release function automatically
224 At this point the stack contains:
225
226 */
227 _ProfilerEnterFunctionStack
228 .(
229 rts
230 .)
231
232 _ProfilerLeaveFunctionStack
233 .(
234 rts
235 .)
236
237
238
239 ; A=id of the function to profile
240 _ProfilerEnterFunctionAsm
241 .(
242 stx _profiler_save_x
243 sty _profiler_save_y
244
245 ; One more entry for this function
246 tax
247 inc _ProfilerRoutineCount,x
248
249 ; Store the current profile value in the stack
250 sei
251
252 ;Immediately after capture current T1 (Last count)
253 lda VIA_T1CL
254 ldy VIA_T1CH
255 sty _profiler_temp_0
256
257 ; Add the start value
258 clc
259 adc _ProfilerRoutineTimeLow,x
260 sta _ProfilerRoutineTimeLow,x
261
262 lda _ProfilerRoutineTimeMid,x
263 adc _profiler_temp_0
264 sta _ProfilerRoutineTimeMid,x
265
266 lda _ProfilerRoutineTimeHigh,x
267 adc _ProfilerCycleCountHigh
268 sta _ProfilerRoutineTimeHigh,x
269
270 cli
271
272 ldx _profiler_save_x
273 ldy _profiler_save_y
274
275 rts
276 .)
277
278 _ProfilerEnterFunctionC
279 .(
280 ; One more entry for this function
281 ldx _profiler_function_id
282 inc _ProfilerRoutineCount,x
283
284 ; Store the current profile value in the stack
285 sei
286
287 ;Immediately after capture current T1 (Last count)
288 lda VIA_T1CL
289 ldy VIA_T1CH
290 sty _profiler_temp_0
291
292 ; Add the start value
293 clc
294 adc _ProfilerRoutineTimeLow,x
295 sta _ProfilerRoutineTimeLow,x
296
297 lda _ProfilerRoutineTimeMid,x
298 adc _profiler_temp_0
299 sta _ProfilerRoutineTimeMid,x
300
301 lda _ProfilerRoutineTimeHigh,x
302 adc _ProfilerCycleCountHigh
303 sta _ProfilerRoutineTimeHigh,x
304
305 cli
306
307 rts
308 .)
309
310
311 _ProfilerLeaveFunctionAsm
312 .(
313 stx _profiler_save_x
314 sty _profiler_save_y
315
316 tax
317
318 ; Store the current profile value in the stack
319 sei
320
321 ;Immediately after capture current T1 (Last count)
322 lda VIA_T1CL
323 ldy VIA_T1CH
324 sta _profiler_temp_0
325 sty _profiler_temp_1
326
327 ; Subtract the end value
328 sec
329 lda _ProfilerRoutineTimeLow,x
330 sbc _profiler_temp_0
331 sta _ProfilerRoutineTimeLow,x
332
333 lda _ProfilerRoutineTimeMid,x
334 sbc _profiler_temp_1
335 sta _ProfilerRoutineTimeMid,x
336
337 lda _ProfilerRoutineTimeHigh,x
338 sbc _ProfilerCycleCountHigh
339 sta _ProfilerRoutineTimeHigh,x
340
341 cli
342
343 ldx _profiler_save_x
344 ldy _profiler_save_y
345
346 rts
347 .)
348
349 _ProfilerLeaveFunctionC
350 .(
351 ldx _profiler_function_id
352
353 ; Store the current profile value in the stack
354 sei
355
356 ;Immediately after capture current T1 (Last count)
357 lda VIA_T1CL
358 ldy VIA_T1CH
359 sta _profiler_temp_0
360 sty _profiler_temp_1
361
362 ; Subtract the end value
363 sec
364 lda _ProfilerRoutineTimeLow,x
365 sbc _profiler_temp_0
366 sta _ProfilerRoutineTimeLow,x
367
368 lda _ProfilerRoutineTimeMid,x
369 sbc _profiler_temp_1
370 sta _ProfilerRoutineTimeMid,x
371
372 lda _ProfilerRoutineTimeHigh,x
373 sbc _ProfilerCycleCountHigh
374 sta _ProfilerRoutineTimeHigh,x
375
376 cli
377
378 rts
379 .)
380
381
382
383 _ProfilerDisplay
384 .(
385 sei
386
387 ;Immediately after capture current T1 (Last count)
388 lda VIA_T1CL
389 ldy VIA_T1CH
390
391 ;Now because T1 is counting 65535 down we'll need to invert the value we've sampled
392 sta _ProfilerCycleCountLow
393 sty _ProfilerCycleCountMid
394
395 lda #$FF
396 sec
397 sbc _ProfilerCycleCountLow
398 sta _ProfilerCycleCountLow
399 lda #$FF
400 sbc _ProfilerCycleCountMid
401 sta _ProfilerCycleCountMid
402 lda #$FF
403 sbc _ProfilerCycleCountHigh
404 sta _ProfilerCycleCountHigh
405
406 ;
407 ; Write the frame number in the string
408 ;
409 .(
410 lda _ProfilerFrameCount+1
411 lsr
412 lsr
413 lsr
414 lsr
415 tax
416 lda ProfilerMessageHexDigit,x
417 sta ProfilerMessageFrameCount+0
418
419 lda _ProfilerFrameCount+1
420 and #$0F
421 tax
422 lda ProfilerMessageHexDigit,x
423 sta ProfilerMessageFrameCount+1
424
425 lda _ProfilerFrameCount+0
426 lsr
427 lsr
428 lsr
429 lsr
430 tax
431 lda ProfilerMessageHexDigit,x
432 sta ProfilerMessageFrameCount+2
433
434 lda _ProfilerFrameCount+0
435 and #$0F
436 tax
437 lda ProfilerMessageHexDigit,x
438 sta ProfilerMessageFrameCount+3
439 .)
440
441 ;
442 ; Write the global profiler IRQ counter in the string
443 ;
444 .(
445 lda _ProfilerCycleCountHigh
446 lsr
447 lsr
448 lsr
449 lsr
450 tax
451 lda ProfilerMessageHexDigit,x
452 sta ProfilerMessageFrameTime+0
453
454 lda _ProfilerCycleCountHigh
455 and #$0F
456 tax
457 lda ProfilerMessageHexDigit,x
458 sta ProfilerMessageFrameTime+1
459
460
461 lda _ProfilerCycleCountMid
462 lsr
463 lsr
464 lsr
465 lsr
466 tax
467 lda ProfilerMessageHexDigit,x
468 sta ProfilerMessageFrameTime+2
469
470 lda _ProfilerCycleCountMid
471 and #$0F
472 tax
473 lda ProfilerMessageHexDigit,x
474 sta ProfilerMessageFrameTime+3
475
476
477 lda _ProfilerCycleCountLow
478 lsr
479 lsr
480 lsr
481 lsr
482 tax
483 lda ProfilerMessageHexDigit,x
484 sta ProfilerMessageFrameTime+4
485
486 lda _ProfilerCycleCountLow
487 and #$0F
488 tax
489 lda ProfilerMessageHexDigit,x
490 sta ProfilerMessageFrameTime+5
491 .)
492 cli
493
494 #ifdef PROFILER_USE_PRINTER
495 lda #<ProfilerMessageFrame
496 ldx #>ProfilerMessageFrame
497 jsr _PrinterSendString
498 jsr _PrinterSendCrlf
499 #endif // PROFILER_USE_PRINTER
500
501 ;
502 ; Show the count/time for each routine
503 ;
504 .(
505 ldy #0
506 loop_show_functions
507 jsr ProfilerDisplayFuncCountTime
508 iny
509 cpy #PROFILER_ROUTINE_COUNT
510 bne loop_show_functions
511 .)
512
513 ;
514 ; Show the Frame message
515 ;
516 .(
517 ldx #0
518 loop
519 lda ProfilerMessageFrame,x
520 beq end
521 sta PROFILER_LINE0,x
522 inx
523 bne loop
524 end
525 .)
526
527 #ifdef PROFILER_USE_PRINTER
528 jsr _PrinterSendCrlf
529 #endif // PROFILER_USE_PRINTER
530
531 rts
532 .)
533
534
535 ProfilerDisplayFuncCountTime
536 .(
537 stx _profiler_temp_0
538 sty _profiler_temp_1
539
540 tya
541 asl
542 asl
543 asl
544 tax
545
546 lda _ProfilerRoutineCount,y
547 pha
548 pha
549
550 lda #" "
551 sta PROFILER_LINE1+0,x
552 lda ProfilerMessageHexDigit,y
553 sta PROFILER_LINE1+1,x
554 #ifdef PROFILER_USE_PRINTER
555 jsr _PrinterSendChar
556 #endif // PROFILER_USE_PRINTER
557 lda #"x"
558 sta PROFILER_LINE1+2,x
559 #ifdef PROFILER_USE_PRINTER
560 jsr _PrinterSendChar
561 #endif // PROFILER_USE_PRINTER
562
563 pla
564 lsr
565 lsr
566 lsr
567 lsr
568 tay
569 lda ProfilerMessageHexDigit,y
570 sta PROFILER_LINE1+3,x
571 #ifdef PROFILER_USE_PRINTER
572 jsr _PrinterSendChar
573 #endif // PROFILER_USE_PRINTER
574
575 pla
576 and #$0F
577 tay
578 lda ProfilerMessageHexDigit,y
579 sta PROFILER_LINE1+4,x
580 #ifdef PROFILER_USE_PRINTER
581 jsr _PrinterSendChar
582 #endif // PROFILER_USE_PRINTER
583
584 ldx _profiler_temp_0
585 ldy _profiler_temp_1
586
587 lda _ProfilerRoutineTimeLow,y
588 pha
589 pha
590 lda _ProfilerRoutineTimeMid,y
591 pha
592 pha
593 lda _ProfilerRoutineTimeHigh,y
594 pha
595 pha
596
597 lda #" "
598 sta PROFILER_LINE2+0,x
599 #ifdef PROFILER_USE_PRINTER
600 jsr _PrinterSendChar
601 #endif // PROFILER_USE_PRINTER
602
603 pla
604 lsr
605 lsr
606 lsr
607 lsr
608 tay
609 lda ProfilerMessageHexDigit,y
610 sta PROFILER_LINE2+1,x
611 #ifdef PROFILER_USE_PRINTER
612 jsr _PrinterSendChar
613 #endif // PROFILER_USE_PRINTER
614
615 pla
616 and #$0F
617 tay
618 lda ProfilerMessageHexDigit,y
619 sta PROFILER_LINE2+2,x
620 #ifdef PROFILER_USE_PRINTER
621 jsr _PrinterSendChar
622 #endif // PROFILER_USE_PRINTER
623
624 pla
625 lsr
626 lsr
627 lsr
628 lsr
629 tay
630 lda ProfilerMessageHexDigit,y
631 sta PROFILER_LINE2+3,x
632 #ifdef PROFILER_USE_PRINTER
633 jsr _PrinterSendChar
634 #endif // PROFILER_USE_PRINTER
635
636 pla
637 and #$0F
638 tay
639 lda ProfilerMessageHexDigit,y
640 sta PROFILER_LINE2+4,x
641 #ifdef PROFILER_USE_PRINTER
642 jsr _PrinterSendChar
643 #endif // PROFILER_USE_PRINTER
644
645 pla
646 lsr
647 lsr
648 lsr
649 lsr
650 tay
651 lda ProfilerMessageHexDigit,y
652 sta PROFILER_LINE2+5,x
653 #ifdef PROFILER_USE_PRINTER
654 jsr _PrinterSendChar
655 #endif // PROFILER_USE_PRINTER
656
657 pla
658 and #$0F
659 tay
660 lda ProfilerMessageHexDigit,y
661 sta PROFILER_LINE2+6,x
662 #ifdef PROFILER_USE_PRINTER
663 jsr _PrinterSendChar
664 #endif // PROFILER_USE_PRINTER
665
666
667 #ifdef PROFILER_USE_PRINTER
668 #ifdef PROFILER_USE_NAMES
669 lda #" "
670 jsr _PrinterSendChar
671 ldy _profiler_temp_1
672 lda _ProfilerRoutineNameLow,y
673 ldx _ProfilerRoutineNameHigh,y
674 jsr _PrinterSendString
675 #endif // PROFILER_USE_NAMES
676 #endif // PROFILER_USE_PRINTER
677
678 #ifdef PROFILER_USE_PRINTER
679 jsr _PrinterSendCrlf
680 #endif // PROFILER_USE_PRINTER
681
682 ldx _profiler_temp_0
683 ldy _profiler_temp_1
684
685 rts
686 .)
687
688
689
690 #ifdef PROFILER_USE_PRINTER
691
692
693 ; Call by doing:
694 ; lda #<msg
695 ; ldx #>msg
696 ; jsr _PrinterSendString
697 ;
698 _PrinterSendString
699 .(
700 sta __auto+1
701 stx __auto+2
702
703 ldx #0
704 next_char
705 __auto
706 lda $1234,x
707 beq end_of_line
708 jsr _PrinterSendChar
709 inx
710 jmp next_char
711 end_of_line
712
713 rts
714 .)
715
716 ; A=character to send
717 _PrinterSendChar
718 .(
719 php
720 sei
721 sta $301 ; Send A to port A of 6522
722 lda $300
723 and #$ef ; Set the strobe line low
724 sta $300
725 lda $300
726 ora #$10 ; Set the strobe line high
727 sta $300
728 plp
729 loop_wait ; Wait in a loop until active transition of CA1
730 lda $30d
731 and #2
732 beq loop_wait ; acknowledging the byte
733 lda $30d
734 rts
735 .)
736
737 _PrinterSendCrlf
738 .(
739 lda #10
740 jsr _PrinterSendChar
741 lda #13
742 jsr _PrinterSendChar
743 rts
744 .)
745
746 ; A=value to send
747 _PrinterSendHexByte
748 .(
749 pha
750 lsr
751 lsr
752 lsr
753 lsr
754 tax
755 lda ProfilerMessageHexDigit,x
756 jsr _PrinterSendChar
757
758 pla
759 jsr _PrinterSendChar
760 rts
761 .)
762
763 ProfilerMessagePrinterStart .byte "Profiling started",10,13,0
764
765 #endif // PROFILER_USE_PRINTER
766
767 ProfilerMessageHexDigit .byte "0123456789ABCDEF",0
768 ProfilerMessageFrame .byte "Frame:"
769 ProfilerMessageFrameCount .byte "0000 "
770 .byte "Time="
771 ProfilerMessageFrameTime .byte "000000"
772 .byte 0
773 ProfilerMessage
774
775 #endif // PROFILER_ENABLE
776
777
778 /*
779
780 Profile:
781 08 php ; place holder
782 08 php ; place holder
783 08 php
784 48 pha
785 A9 xx lda #ROUTINE_ASM
786 20 xx xx jsr _ProfilerEnterFunctionStack
787 68 pla
788 28 plp
789
790 Enter:
791 08 php
792 48 pha
793 A9 xx lda #ROUTINE_ASM
794 20 xx xx jsr _ProfilerEnterFunctionAsm
795 68 pla
796 28 plp
797
798 Leave:
799 08 php
800 48 pha
801 A9 xx lda #ROUTINE_ASM
802 20 xx xx jsr _ProfilerLeaveFunctionAsm
803 68 pla
804 28 plp
805
806 */

  ViewVC Help
Powered by ViewVC 1.1.26