--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CSa32/Debug.S Thu Nov 21 14:55:10 2019 +0100
@@ -0,0 +1,273 @@
+ .include "DS.S"
+#-----------------------------------------------
+# A B S T R A C T S T R U C T U R E S
+#-----------------------------------------------
+#-----------------------------------------------
+# S T A T I C V A R I A B L E S
+#-----------------------------------------------
+ .data
+D.t0: .int 0 # initial timestamp in usecs
+D.semP: .int 0 # -->semaphore for debug output
+ .globl D.prgNameP
+D.prgNameP:
+ .int 0 # -->prog name
+#-----------------------------------------------
+# D E B U G I N I T
+#-----------------------------------------------
+# initialize static debug vars
+ ARGS
+ DS prgP # -->program name
+# returns: nothing
+ PROLOC
+ EPILOC
+#-----------------------------------------------
+ .text
+ .global D.init
+D.init:
+ PROLOG
+ push prgP(bp)
+ call strlen
+ inc a
+ push a
+ call malloc
+ mov a, D.prgNameP # save -->prog name for debugging
+ push prgP(bp)
+ push a
+ call strcpy
+ movl $0, D.t0
+ call D.getTs # get actual time - t0 = actual time
+ mov a, D.t0 # set t0 to actual time
+
+ jmp 3f
+ push $0
+ push $t
+ call gettimeofday # get initial timestamp t0
+ cmp $0, a
+ jz 0f
+ ERR "gettimeofday"
+0: lea t, b # compute (1000000*secs+usecs)
+ mov secs(b), c
+ mov $1000000, a
+ mul c # 1000000*secs
+ add usecs(b), a # 1000000*secs+usecs
+ movl a, D.t0 # save low 32 bits of timestamp in t0
+3:
+ push $0 # allocate semaphore for debug output
+ push $-1
+ push $0x21 # PROT_READ | PROT_WRITE
+ push $0x03 # MAP_SHARED | MAP_ANONYMOUS
+ push $16 # semaphore size
+ push $0
+ call mmap # get shared storage for semaphore
+ cmp $-1, a
+ jne 0f
+ ERR "mmap"
+0: mov a, D.semP # save -->semaphore
+
+ push $1 # initial semaphore value
+ push $1 # semaphore shared between processes
+ pushl D.semP
+ call sem_init # initialize semaphore
+ cmp $0, a
+ jz 0f
+ ERR "sem_init of debug semaphore"
+0:
+ EPILOG
+#-----------------------------------------------
+# S E T D E B U G I D
+#-----------------------------------------------
+# sets debug ID according to format
+ ARGS
+ DS deP # -->Debug instance
+ DS argc # # of values to be put into deb ID
+ DS formP # -->format
+# ... # values
+# returns: nothing
+ PROLOC
+ EPILOC
+#-----------------------------------------------
+ .global D.setId
+D.setId:
+ PROLOG
+# format debug ID
+ mov argc(bp), c # no. of values
+0: mov formP(bp,c,4), a # push values and format
+ push a
+ dec c
+ jns 0b # iterate on values
+ pushl $D.idL # max deb ID len
+ mov deP(bp), b # -->Debug instance
+ lea D.id(b), a # -->DebId
+ push a
+ call snprintf # construct DebId
+ cmp $0, a
+ jnl 0f
+ ERR "DEBID snprintf"
+0:
+ LOG 6, "debid '%s' set", 1
+ EPILOG
+#-----------------------------------------------
+# P R I N T D E B U G M S G
+#-----------------------------------------------
+# outputs to stderr the synchronized debug msg with time diff from program start
+# on appripriate debug level, flushes stderr
+ ARGS
+ ac = 40
+ DS deP # -->Debug instance
+ DS level # msg debug level
+ DS argc # # of values to be used in msg
+ DS form # -->format
+# ... # values
+# returns: nothing
+ PROLOC
+ ac = 0
+ EPILOC
+#-----------------------------------------------
+ .global D.log
+D.log:
+ PROLOG
+
+ mov C.csP, c
+ mov level(bp), a # msg debug level
+ cmp C.debMaxLev(c), a # max debug level >= msg debug level ?
+ jg 3f # nothing to print, leave
+ cmp $7, C.debMaxLev(c) # on max debug level = 7 print level 7 only
+ jne 0f
+ cmp $7, a # msg debug level = 7 ?
+ jne 3f
+# prepare output string of msg
+0: mov argc(bp), c # no. of values
+0: mov form(bp,c,4), a # copy values and format
+ push a
+ dec c
+ jns 0b
+ push $D.msgL # msg buffer len
+ mov deP(bp), b # -->Debug instance
+ lea D.msg(b), a # -->msg buffer
+ push a
+ call snprintf # construct msg in buffer
+ cmp $0, a
+ jnl 0f
+ ERR "LOG snprintf"
+# synchronize with other tasks
+0: pushl D.semP
+ call sem_wait # synchronize
+ cmp $0, a
+ jz 0f
+ ERR "LOG sem_wait"
+# get timestamp
+0: call D.getTs # time from beg of program in usecs
+# print debug msg
+ mov deP(bp), b # -->Debug instance
+ lea D.msg(b), c # -->msg text
+ push c
+ lea D.id(b), c # -->instance debug ID
+ push c
+ push a # tdiff in usecs
+ push $1f
+ push stderr
+ call fprintf
+ jmp 2f
+1: .ascii "%09u %s: %s\n\0"
+# flush stderr
+2: push stderr
+ call fflush # flush stderr
+# free semaphore
+ pushl D.semP
+ call sem_post # free semaphore
+ cmp $0, a
+ jz 3f
+ ERR "LOG sem_post"
+3:
+ EPILOG
+#-----------------------------------------------
+# G E T T I M E S T A M P I N U S E C S
+#-----------------------------------------------
+# returns timestamp in usecs from beg of program
+# returns: int value
+ PROLOC
+ DL t, timevalL # timestamp buffer
+ EPILOC
+#-----------------------------------------------
+ .global D.getTs
+D.getTs:
+ PROLOG
+ push $0
+ lea t(bp), b # -->timeval buffer
+ push b
+ call gettimeofday
+# compute time delta from program start = t-t0 in usecs
+# tdiff = (1000000*ts.secs+ts.usecs)-t0
+ lea t(bp), b # actual timestamp
+ mov secs(b), c # t.secs
+ mov $1000000, a
+ mul c # 1000000*t.secs
+ add usecs(b), a # 1000000*t.secs+t.usecs
+ sub D.t0, a # 1000000*t.secs+t.usecs-t0
+ EPILOG_R
+#-----------------------------------------------
+# S U B R O U T I N E S L I S T
+#-----------------------------------------------
+# print subroutines names and addresses
+# localize address from env ADDR= in subroutine
+ PROLOC
+ DL wAddr # wanted addr
+ EPILOC
+#-----------------------------------------------
+ .global D.subr
+D.subr:
+ PROLOG
+ movl $0, wAddr(bp)
+ pushl $0f
+ call getenv # get env ADDR
+ lea 4(sp), sp
+ jmp 1f
+0: .ascii "ADDR\0"
+1: cmp $0, a
+ jz 0f # no addr wanted
+ pushl $16
+ pushl $0
+ push a
+ call strtol # convert str to hex
+ lea 12(sp), sp
+ mov a, wAddr(bp) # searched addr
+0:
+ pushl $0 # end of list
+ SUBRLIST # print and push list of subroutines
+ cmp $0, wAddr(bp) # address wanted ?
+ je D.subrR
+ mov wAddr(bp), d
+ mov sp, b # -->beg of subr list
+ xor a, a
+ jmp 1f
+0: lea 8(b), b
+1: cmpl $0, (b) # end of list ?
+ je 2f # yes
+ cmp 4(b), d # -->subr > wanted addr ?
+ jb 0b # yes, next
+ cmp 4(b), a # -->subr > last found ?
+ jnb 0b # no, next
+ mov (b), c # get subr name
+ mov 4(b), a # get subr addr
+ jmp 0b # next
+2: test a, a
+ jnz 1f
+ push d
+ push $0f
+ push stderr
+ call fprintf
+ jmp D.subrR
+0: .ascii "addr %p not found in subroutines\n\0"
+1: sub a, d
+ push d # offset in subr
+ push c # subroutine name
+ pushl wAddr(bp) # wanted addr
+ push $0f
+ push stderr
+ call fprintf
+ jmp D.subrR
+0: .ascii "searched addr %p in subroutine %s at offset %x\n\0"
+D.subrR:
+ EPILOG
+#-----------------------------------------------
+ .end