home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / debug / tracker / !Tracker / AsmLib / s / Debug next >
Encoding:
Text File  |  1994-12-07  |  28.9 KB  |  881 lines

  1. ; Linkable debugging routines
  2.  
  3.                 GET             Asm:s.regs
  4.                 GET             Asm:s.xswis
  5.                 GET             Asm:s.general
  6.                 GET             Asm:s.DebugHdr
  7.  
  8.                 ^               &C9840 :OR: XOS_Bit
  9. XRAMPod_Read    #               1
  10. XRAMPod_Write   #               1
  11. XRAMPod_LEDs    #               1
  12. XRAMPod_Clear   #               1
  13. XRAMPod_WriteS  #               1
  14. XRAMPod_WriteN  #               1
  15. XRAMPod_SaveBuffer #            1
  16.  
  17.                 ^               &CF000 :OR: XOS_Bit
  18. ;XTracker_Open   #               1
  19. ;XTracker_Close  #               1
  20. ;XTracker_SetPos #               1
  21. ;XTracker_WriteS #               1
  22. ;XTracker_CLS    #               1
  23. ;XTracker_Simple #               1
  24.  
  25.                 ^               &40500 :OR: XOS_Bit
  26. XIO_Podule      #               1
  27.  
  28. ; Write registers
  29.  
  30. ORB             *               4 * 0
  31. ORA             *               4 * 1
  32. DDRB            *               4 * 2
  33. DDRA            *               4 * 3
  34. T1CL            *               4 * 4
  35. T1CH            *               4 * 5
  36. T1LL            *               4 * 6
  37. T1LH            *               4 * 7
  38. T2CL            *               4 * 8
  39. T2CH            *               4 * 9
  40. SR              *               4 * 10
  41. ACR             *               4 * 11
  42. PCR             *               4 * 12
  43. IFR             *               4 * 13
  44. IER             *               4 * 14
  45. ORAns           *               4 * 15
  46.  
  47. ; Read registers
  48.  
  49. IRA             *               ORA
  50. IRB             *               ORB
  51. IRAns           *               ORAns
  52.  
  53.                 AREA            |Debug$$code|, PIC, CODE
  54.  
  55.                 EXPORT          DebugF, DebugFlags, DebugTrapOn, DebugTrapOff
  56.                 EXPORT          DebugBacktrace
  57.  
  58. ; Static data
  59.  
  60. Flags           &               DebugOn :OR: UseTracker
  61. VIA             &               0               ; 0 means not tried, -1 means not available
  62. BaseTime        &               0               ; Relative to OS_MonotonicTime
  63.  
  64. ; General purpose ASCII output.
  65. ;
  66. ; R0  ==> Char to output
  67.  
  68. DBChar          STMFD           sp!, {r0-r1, lr}
  69.                 LDR             r1, Flags
  70.                 TST             r1, #DebugOn
  71.                 LDMEQFD         sp!, {r0-r1, pc}^
  72.  
  73.                 TST             r1, #UseVDU
  74.                 BLNE            VDUSend
  75.  
  76.                 TST             r1, #UseTracker
  77.                 MOVNE           r0, sp
  78.                 SWINE           XTracker_Simple
  79.                 LDRNE           r0, [sp]
  80.  
  81.                 TST             r1, #UseBeeb
  82.                 BLNE            UserSend
  83.  
  84.                 TST             r1, #UseRAM
  85.                 BLNE            RAMSend
  86.                 LDMFD           sp!, {r0-r1, pc}^
  87.  
  88. RAMSendBuf      %               80
  89. RAMSendBP       =               0
  90.                 ALIGN
  91.  
  92. RAMSend         STMFD           sp!, {r0-r2, lr}
  93.                 TEQ             r0, #&0c
  94.                 BNE             RAMSend1
  95.                 SWI             XRAMPod_Clear
  96.                 MOV             r1, #0
  97.                 STRB            r1, RAMSendBP
  98.                 LDMFD           sp!, {r0-r2, pc}^
  99.  
  100. RAMSend1        LDRB            r1, RAMSendBP
  101.                 ADR             r2, RAMSendBuf
  102.                 STRB            r0, [r2, r1]
  103.                 ADD             r1, r1, #1
  104.                 TEQ             r0, #&0a
  105.                 TEQNE           r0, #&0d
  106.                 TEQNE           r1, #80
  107.                 BLEQ            RAMSendFlush
  108.                 STRB            r1, RAMSendBP
  109.                 LDMFD           sp!, {r0-r2, pc}^
  110.  
  111. RAMSendFlush    STMFD           sp!, {lr}
  112.                 ADR             r0, RAMSendBuf
  113.                 SWI             XRAMPod_WriteN
  114.                 MOV             r1, #0
  115.                 LDMFD           sp!, {pc}^ 
  116.  
  117. VDUSend         STMFD           sp!, {lr}
  118.                 TEQ             r0, #&0a
  119.                 TEQNE           r0, #&0d
  120.                 SWIEQ           XOS_WriteI + &0a
  121.                 SWIEQ           XOS_WriteI + &0d
  122.                 SWINE           XOS_WriteC
  123.                 LDMFD           sp!, {pc}^
  124.  
  125. UserSend        STMFD           sp!, {r0-r1, lr}
  126.                 LDR             r1, VIA
  127.                 CMP             r1, #-1
  128.                 LDMEQFD         sp!, {r0-r1, pc}^
  129.  
  130. ; Send character
  131.  
  132.                 STRB            r0, [r1, #ORB]
  133. UserSend1       LDRB            r0, [r1, #IFR]
  134.                 TST             r0, #2_00010000
  135.                 BEQ             UserSend1
  136.                 MOV             r0, #&FF
  137.                 STRB            r0, [r1, #IFR]
  138.                 LDMFD           sp, {r0-r1, pc}^
  139.  
  140. BinError
  141. DecError
  142. HexError        ADD             r1, r1, #4
  143.  
  144. BinString
  145. DecString
  146. HexString       STMFD           sp!, {lr}
  147. String1         LDRB            r0, [r1], #1
  148.                 TEQ             r0, #0
  149.                 BLNE            OutChar
  150.                 BNE             String1
  151.                 LDMFD           sp!, {pc}^
  152.  
  153. BinCharacter
  154. DecCharacter
  155. HexCharacter    MOV             r0, r1
  156.  
  157. OutChar         STMFD           sp!, {r0-r1, lr}
  158.                 AND             r1, r0, #&FF
  159.                 CMPS            r1, #&7F
  160.                 MOVHS           r0, #"|"
  161.                 BLHS            DBChar
  162.                 MOVEQ           r0, #"?"
  163.                 BLEQ            DBChar
  164.                 LDMEQFD         sp!, {r0-r1, pc}^
  165.                 MOVHI           r0, #"!"
  166.                 BLHI            DBChar
  167.                 ANDHI           r1, r1, #&7F
  168.                 CMPS            r1, #&20
  169.                 MOVLO           r0, #"|"
  170.                 BLLO            DBChar
  171.                 ADDLO           r0, r1, #&40
  172.                 MOVHS           r0, r1
  173.                 BL              DBChar
  174.                 LDMFD           sp!, {r0-r1, pc}^
  175.  
  176. NewLine         STMFD           sp!, {r0, lr}
  177.                 MOV             r0, #&0A
  178.                 BL              DBChar
  179.                 MOV             r0, #&0D
  180.                 BL              DBChar
  181.                 LDMFD           sp!, {r0, pc}^
  182.  
  183. ; DebugF output formatted debugging information.
  184. ;
  185. ; In order to output accurate information about the contents of R14 DebugF
  186. ; must be called like this
  187. ;
  188. ;               STMFD           sp!, {lr, pc}
  189. ;               BL              DebugF
  190. ;               =               "Hello"
  191. ;               LDR             lr, [sp], #8
  192. ;
  193. ;    % introduces a conversion
  194. ;    \ introduces an escape
  195. ;
  196. ; The general format of conversions is
  197. ;
  198. ;    %<register>[<radix specifier>]<conversion>
  199. ;
  200. ;    register is 0..F, or (5.4.93, AA) R|r0..R|r15 | SP | sp | LR | lr | PC | pc
  201. ;
  202. ;    radix specifier is
  203. ;
  204. ;       %       binary
  205. ;       #       decimal
  206. ;
  207. ;    conversion is
  208. ;
  209. ;       s       string
  210. ;       w       word
  211. ;       h       halfword
  212. ;       b       byte
  213. ;       c       character
  214.  
  215. DebugF          STMFD           sp!, {lr}
  216.                 STMFD           sp!, {r0-r15}
  217.  
  218. ; r3 will address inline argument string
  219.  
  220.                 BIC             r3, lr, #&FC000003
  221.  
  222. ; Copy lr and pc from outside invocation
  223.  
  224.                 LDR             lr, [sp, #17 * 4]  ; Get lr
  225.                 STR             lr, [sp, #14 * 4]
  226.                 LDR             lr, [sp, #18 * 4]  ; and pc
  227.                 SUB             lr, lr, #8      ; Adjust
  228.                 STR             lr, [sp, #15 * 4]
  229.  
  230. ; Keep a copy of the entry mode stack pointer
  231.  
  232.                 MOV             r4, sp
  233.  
  234. ; Force supervisor mode
  235.  
  236.                 MOV             r5, pc
  237.                 TST             r5, #3          ; USR mode?
  238.                 SWIEQ           XOS_EnterOS
  239.                 ORR             r6, r5, #S0_bit :OR: S1_bit :OR: I_bit
  240.                 TEQP            r6, #0
  241.                 MOV             r6, r6
  242.                 STMFD           sp!, {r8, lr}
  243.  
  244. ; Do it
  245.  
  246. DebugF1         LDRB            r0, [r3], #1
  247.                 TEQ             r0, #"%"
  248.                 BNE             DebugF6
  249.  
  250. ; Handle possible conversion
  251.  
  252.                 LDRB            r0, [r3], #1
  253.                 CMP             r0, #"0"
  254.                 RSBHSS          lr, r0, #"9"
  255.                 SUBHS           r1, r0, #"0"
  256.                 BHS             DebugF2
  257.  
  258.                 CMP             r0, #"A"
  259.                 RSBHSS          lr, r0, #"F"
  260.                 SUBHS           r1, r0, #"A"-10
  261.                 BHS             DebugF2
  262.  
  263.                 CMP             r0, #"a"
  264.                 RSBHSS          lr, r0, #"f"
  265.                 SUBHS           r1, r0, #"a"-10
  266.                 BHS             DebugF2
  267.  
  268. ; Handle register name without corrupting R0 if not found
  269.  
  270.                 BL              WhichReg
  271.                 BCS             DebugF5
  272.  
  273. ; Get the value to print (from the caller's stack)
  274.  
  275. DebugF2         LDR             r1, [r4, r1, LSL #2]
  276.  
  277. ; Get possible radix indicator
  278.  
  279.                 LDRB            r0, [r3], #1
  280.                 MOV             r2, #2          ; == Hex
  281.                 TEQ             r0, #0
  282.                 BEQ             DebugF7
  283.  
  284.                 TEQ             r0, #"%"        ; Binary
  285.                 MOVEQ           r2, #0
  286.                 LDREQB          r0, [r3], #1
  287.                 BEQ             DebugF3
  288.  
  289.                 TEQNE           r0, #"#"        ; Decimal
  290.                 MOVEQ           r2, #1
  291.                 LDREQB          r0, [r3], #1
  292.  
  293. ; Value in R1, radix in R2, conversion character in R0
  294.  
  295. DebugF3         ADR             r6, Converts
  296. DebugF4         LDRB            r7, [r6], #4
  297.                 TEQ             r7, #0
  298.                 BEQ             DebugF7
  299.                 TEQ             r7, r0
  300.                 ADDNE           r6, r6, #12
  301.                 BNE             DebugF4
  302.  
  303.                 MOV             r8, pc
  304.                 AND             r8, r8, #&FC000003
  305.                 ORR             r6, r6, r8
  306.                 MOV             lr, pc
  307.                 ADD             pc, r6, r2, LSL #2
  308.                 B               DebugF1
  309.  
  310. ; Check for %t or %z
  311.  
  312. DebugF5         MOV             r2, r0
  313.                 TEQ             r2, #"t"
  314.                 TEQNE           r2, #"T"
  315.                 TEQNE           r2, #"z"
  316.                 TEQNE           r2, #"Z"
  317.                 BNE             DebugF7
  318.                 SWI             XOS_ReadMonotonicTime
  319.                 MOV             r1, r0
  320.                 TEQ             r2, #"z"
  321.                 TEQNE           r2, #"Z"
  322.                 STREQ           r0, BaseTime
  323.                 LDRNE           r0, BaseTime
  324.                 SUB             r1, r1, r0
  325.                 BL              DecWord
  326.                 B               DebugF1
  327.  
  328. DebugF6         TEQ             r0, #"\\"
  329.                 BNE             DebugF7
  330.  
  331.                 LDRB            r0, [r3], #1
  332.  
  333. ; Carriage return
  334.  
  335.                 TEQ             r0, #"n"
  336.                 BLEQ            NewLine
  337.                 BEQ             DebugF1
  338.  
  339. ; BELL
  340.  
  341.                 TEQ             r0, #"b"
  342.                 MOVEQ           r0, #&07
  343.                 BEQ             DebugF7
  344.  
  345. ; Formfeed (CLS)
  346.  
  347.                 TEQ             r0, #"f"
  348.                 MOVEQ           r0, #&0C
  349.  
  350. DebugF7         TEQ             r0, #0
  351.                 BLNE            DBChar
  352.                 BNE             DebugF1
  353.  
  354.                 LDMFD           sp!, {r8, lr}
  355.                 TEQP            r5, #0
  356.                 MOV             r5, r5
  357.  
  358.                 LDR             r2, [sp, #16 * 4]
  359.                 AND             r2, r2, #&FC000003
  360.                 ADD             r3, r3, #3
  361.                 BIC             r3, r3, #3
  362.                 ORR             r3, r3, r2
  363.                 STR             r3, [sp, #16 * 4]
  364.  
  365.                 LDMFD           sp!, {r0-r12}   ; Don't bother with sp, lr, pc
  366.                 ADD             sp, sp, #4 * 3
  367.                 LDMFD           sp!, {pc}^
  368.  
  369. ; Match a register name, first character in R0, remainder at R3, don't
  370. ; corrupt either unless a match is found
  371.  
  372. WhichReg        STMFD           sp!, {r0, r2-r3, lr}
  373.  
  374.                 ADR             r2, RegTab
  375.  
  376. WhichReg1       LDR             r3, [sp, #4 * 2]
  377.                 LDR             r0, [sp, #4 * 0]
  378.  
  379. WhichReg2       LDRB            r1, [r2], #1
  380.                 CMP             r1, #" "
  381.                 BLO             WhichReg4
  382.  
  383.                 CMP             r0, #"a"
  384.                 RSBHSS          lr, r0, #"z"
  385.                 SUBHS           r0, r0, #"a"-"A"
  386.                 TEQ             r0, r1
  387.                 LDREQB          r0, [r3], #1
  388.                 BEQ             WhichReg2
  389.  
  390. WhichReg3       LDRB            r1, [r2], #1
  391.                 CMP             r1, #" "
  392.                 BHS             WhichReg3
  393.                 LDRB            r1, [r2]
  394.                 TEQ             r1, #0
  395.                 BNE             WhichReg1
  396.  
  397.                 LDMFD           sp!, {r0, r2-r3, lr}
  398.                 ORRS            pc, lr, #C_bit
  399.  
  400. WhichReg4       SUB             r3, r3, #1
  401.                 STR             r3, [sp, #4 * 2]
  402.                 LDMFD           sp!, {r0, r2-r3, lr}
  403.                 BICS            pc, lr, #C_bit
  404.  
  405.  
  406. RegTab          =               "R8", 8, "R9", 9, "R10", 10, "R11", 11
  407.                 =               "R12", 12, "WS", 12, "R13", 13, "SP", 13
  408.                 =               "R14", 14, "LR", 14, "R15", 15, "PC", 15
  409.                 =               "R0", 0, "R1", 1, "R2", 2, "R3", 3
  410.                 =               "R4", 4, "R5", 5, "R6", 6, "R7", 7
  411.                 =               0
  412.                 ALIGN
  413.  
  414.                 MACRO
  415. $label          CVRT            $char, $routine
  416. $label          =               "$char", 0, 0, 0
  417.                 B               Bin$routine
  418.                 B               Dec$routine
  419.                 B               Hex$routine
  420.                 MEND
  421.  
  422. Converts        CVRT            "s", String
  423.                 CVRT            "e", Error
  424.                 CVRT            "c", Character
  425.                 CVRT            "w", Word
  426.                 CVRT            "h", HalfWord
  427.                 CVRT            "b", Byte
  428.                 CVRT            "p", PC
  429.                 =               0
  430.                 ALIGN
  431.  
  432.                 MACRO
  433. $label          Converter       $swiname
  434. $label          STMFD           sp!, {r0-r2, lr}
  435.                 SUB             sp, sp, #40
  436.                 MOV             r0, r1
  437.                 MOV             r1, sp
  438.                 MOV             r2, #40
  439.                 SWI             $swiname
  440.                 BL              OutS
  441.                 ADD             sp, sp, #40
  442.                 LDMFD           sp!, {r0-r2, pc}^
  443.                 MEND
  444.  
  445. OutS            STMFD           sp!, {r0-r1, lr}
  446.                 MOV             r1, r0
  447. OutS1           LDRB            r0, [r1], #1
  448.                 TEQ             r0, #0
  449.                 BLNE            DBChar
  450.                 BNE             OutS1
  451.                 LDMFD           sp!, {r0-r1, pc}^
  452.  
  453. DecHalfWord     MOV             r1, r1, LSL #16
  454.                 MOV             r1, r1, ASR #16
  455.                 B               DecWord
  456.  
  457. DecByte         MOV             r1, r1, LSL #24
  458.                 MOV             r1, r1, ASR #24
  459.  
  460. DecWord         Converter       XOS_ConvertInteger4
  461.  
  462. BinWord         Converter       XOS_ConvertBinary4
  463. BinHalfWord     Converter       XOS_ConvertBinary2
  464. BinByte         Converter       XOS_ConvertBinary1
  465.  
  466. HexWord         Converter       XOS_ConvertHex8
  467. HexHalfWord     Converter       XOS_ConvertHex4
  468. HexByte         Converter       XOS_ConvertHex2
  469.  
  470. PModes          =               "USR", 0, "FIQ", 0, "IRQ", 0, "SVC", 0
  471. PFlags          =               "NZCVIF", 0
  472.  
  473.                 ALIGN
  474.  
  475. BinPC
  476. DecPC
  477. HexPC           STMFD           sp!, {r0-r2, lr}
  478.                 MOV             r2, r1
  479.                 BIC             r1, r1, #&FC000003
  480.                 BL              HexWord
  481.  
  482.                 MOV             r0, #" "
  483.                 BL              DBChar
  484.  
  485.                 AND             r1, r2, #3
  486.                 ADR             r0, PModes
  487.                 ADD             r0, r0, r1, LSL #2
  488.                 BL              OutS
  489.  
  490.                 MOV             r0, #" "
  491.                 BL              DBChar
  492.  
  493.                 ADR             r1, PFlags
  494.  
  495. HexPC1          LDRB            r0, [r1], #1
  496.                 TEQ             r0, #0
  497.                 LDMEQFD         sp!, {r0-r2, pc}^
  498.                 TST             r2, #1 :SHL: 31
  499.                 ADDEQ           r0, r0, #"a"-"A"
  500.                 BL              DBChar
  501.                 MOV             r2, r2, LSL #1
  502.                 B               HexPC1
  503.  
  504. ; flags := (flags AND R1) EOR R0
  505.  
  506. DebugFlags      STMFD           sp!, {r0-r4, lr}
  507.  
  508.                 MOV             r3, pc
  509.                 TST             r3, #3
  510.                 SWIEQ           XOS_EnterOS
  511.                 ORR             r4, r3, #S0_bit :OR: S1_bit :OR: I_bit
  512.                 TEQP            r4, #0
  513.                 MOV             r4, r4
  514.                 STMFD           sp!, {lr}
  515.  
  516. ; Set the flags
  517.  
  518.                 LDR             r2, Flags
  519.                 AND             r1, r1, r2
  520.                 EOR             r0, r0, r1
  521.                 STR             r0, Flags
  522.  
  523. ; Check for a VIA
  524.  
  525.                 LDR             r1, VIA
  526.                 TEQ             r1, #0
  527.                 BNE             DebugFlags1
  528.                 SWI             XIO_Podule
  529.                 MOVVS           r1, #-1
  530.                 ADDVC           r1, r1, #&2000
  531.                 STR             r1, VIA
  532.  
  533. ; Initialise VIA for our use
  534.  
  535.                 MOVVC           r0, #&FF
  536.                 STRVCB          r0, [r1, #DDRB]
  537.                 MOVVC           r0, #&40
  538.                 STRVCB          r0, [r1, #IER]
  539.                 LDRVCB          r0, [r1, #PCR]
  540.                 ANDVC           r0, r0, #&0F
  541.                 ORRVC           r0, r0, #&80
  542.                 STRVCB          r0, [r1, #PCR]
  543.  
  544. DebugFlags1     LDMFD           sp!, {lr}
  545.                 TEQP            r3, #0
  546.                 MOV             r3, r3
  547.                 LDMFD           sp!, {r0-r4, pc}^
  548.  
  549. ; Static variable which is the most recent stack pointer known to us. 0 is a
  550. ; special case which means we haven't been entered properly, and should not
  551. ; attempt a stack backtrace. A backtrace will also not be attempted if the
  552. ; current stack pointer is either a) above this value, or b) more than 64k
  553. ; below it.
  554.  
  555. DebugMaxSP      &               0, 0, 0, 0
  556.  
  557. ; Old exception handler values
  558.  
  559. OldUDI          &               0
  560. OldPrAb         &               0
  561. OldDaAb         &               0
  562. OldAdEx         &               0
  563.  
  564. DebugTrapOn     STMFD           sp!, {r0-r7, lr}
  565.  
  566.                 ADR             lr, DebugMaxSP
  567.                 LDMIA           lr, {r1-r3}
  568.                 ADD             r0, sp, #4 * 9
  569.                 STMIA           lr, {r0-r3}
  570.  
  571.                 TEQ             r1, #0
  572.  
  573. ; Install handlers
  574.  
  575.                 MOVEQ           r0, #0
  576.                 MOVEQ           r1, #0
  577.                 ADREQ           r4, BadInst
  578.                 ADREQ           r5, PrefetchAbt
  579.                 ADREQ           r6, DataAbt
  580.                 ADREQ           r7, AddrExcp
  581.                 SWIEQ           XOS_SetEnv
  582.                 ADREQ           lr, OldUDI
  583.                 STMEQIA         lr, {r4-r7}
  584.  
  585. DebugTrapOnX    LDMFD           sp!, {r0-r7, pc}^
  586.  
  587. DebugTrapOff    STMFD           sp!, {r0-r7, lr}
  588.  
  589.                 ADR             lr, DebugMaxSP
  590.                 LDMIB           lr, {r0-r2}
  591.                 MOV             r3, #0
  592.                 STMIA           lr, {r0-r3}
  593.  
  594.                 TEQ             r0, #0
  595.                 ADREQ           lr, OldUDI
  596.                 LDMEQIA         lr, {r4-r7}
  597.                 MOVEQ           r0, #0
  598.                 MOVEQ           r1, #0
  599.                 SWIEQ           XOS_SetEnv
  600.  
  601.                 LDMFD           sp!, {r0-r7, pc}^
  602.  
  603. ; Alternative backtrace entry, used by exception handlers
  604.  
  605. AltBacktrace    STMFD           sp!, {r0-r9, lr}
  606.                 LDR             r5, RegSave + 13 * 4
  607.                 B               Backtrace1
  608.  
  609. ; Stack unwinding and profiling stuff
  610.  
  611. DebugBacktrace  STMFD           sp!, {r0-r9, lr}
  612.                 MOV             r5, sp
  613. Backtrace1      MOV             r3, pc
  614.  
  615.                 TST             r3, #3
  616.                 SWIEQ           XOS_EnterOS
  617.                 ORR             r4, r3, #S0_bit :OR: S1_bit :OR: I_bit
  618.                 TEQP            r4, #0
  619.                 MOV             r4, r4
  620.                 STMFD           sp!, {r3, lr}
  621.  
  622. ; Now work up the stack, from r5 + 4 * 6
  623.  
  624.                 LDR             r4, DebugMaxSP
  625.                 TEQ             r4, #0
  626.                 BEQ             BacktraceX
  627.  
  628.                 SUBS            lr, r4, r5
  629.                 BLO             BacktraceX
  630.                 CMP             lr, #64 * 1024
  631.                 BHI             BacktraceX
  632.  
  633. ; Now get down to it
  634.  
  635.                 LDR             r3, BackWord
  636. Backtrace2      CMP             r5, r4
  637.                 BHI             BacktraceX
  638.  
  639.                 LDR             r0, [r5], #4
  640.                 TEQ             r0, r3
  641.                 BNE             Backtrace2
  642.  
  643. ; Next word is pointer to function name
  644.  
  645.                 LDR             r0, [r5, #4 * 0]
  646.                 TST             r0, #&FC000003
  647.                 BNE             Backtrace2
  648.                 ADD             r1, r0, #32
  649.                 SWI             XOS_ValidateAddress
  650.                 BCS             Backtrace2
  651.  
  652. Backtrace3      CMP             r0, r1
  653.                 BHS             Backtrace2
  654.                 LDRB            r2, [r0], #1
  655.                 CMP             r2, #" "
  656.                 RSBHSS          lr, r2, #126
  657.                 BHS             Backtrace3
  658.                 TEQ             r2, #0
  659.                 BNE             Backtrace2
  660.  
  661. ; Things are looking OK, so check for STMFD sp!, {...} instruction
  662.  
  663.                 LDR             r6, [r5, #4 * 1]
  664.                 LDR             r1, STMFDWord
  665.                 LDR             r2, STMFDMask
  666.                 AND             r2, r2, r6
  667.                 TEQ             r2, r1
  668.                 BNE             Backtrace2
  669.  
  670. ; Got bit mask of stacked registers in R6 now, so do a bit of output
  671.  
  672.                 LDR             r1, [r5, #4 * 0]
  673.                 BL              BinString       ; Function name
  674.  
  675. ; Now output a dump of the registers
  676.  
  677.                 ADD             r5, r5, #4 * 2  ; Start of stacked registers
  678.                 BL              ShowRegs
  679.                 ADD             r5, r5, #4 * 16
  680.                 B               Backtrace2
  681.  
  682. BacktraceX      LDMFD           sp!, {r3, lr}
  683.                 TEQP            r3, #0
  684.                 MOV             r3, r3
  685.                 LDMFD           sp!, {r0-r9, pc}^
  686.  
  687. ; Dump a set of registers, stored at R5. The lower 16 bits in R6 represent
  688. ; registers 0 to 15 respectively and control whether the name is capitalized
  689. ; (as in 'R') or not. If R6 is a STM instruction the register dump will
  690. ; reflect the registers which it stacked.
  691.  
  692. ShowRegs        STMFD           sp!, {r0-r8, lr}
  693.  
  694.                 ADR             r7, RegNames
  695.                 MOV             r8, #0          ; Reg. no
  696.  
  697. ShowRegs1       MOV             r1, #4          ; ccount
  698. ShowRegs2       LDRB            r0, [r7], #1
  699.                 TEQ             r0, #"\\"
  700.                 BLEQ            NewLine
  701.                 MOVEQ           r0, #" "
  702.                 CMP             r0, #"A"
  703.                 RSBHSS          lr, r0, #"Z"
  704.                 BLO             ShowRegs3
  705.                 TST             r6, #1
  706.                 ADDEQ           r0, r0, #"a"-"A"
  707. ShowRegs3       BL              DBChar
  708.                 SUBS            r1, r1, #1
  709.                 BNE             ShowRegs2
  710.  
  711.                 ADR             r1, Equals
  712.                 BL              BinString
  713.                 LDR             r1, [r5, r8, LSL #2]
  714.                 CMP             r8, #14
  715.                 BLLO            HexWord
  716.                 BLHS            HexPC
  717.                 MOV             r6, r6, LSR #1
  718.                 ADD             r8, r8, #1
  719.                 CMP             r8, #16
  720.                 BLO             ShowRegs1
  721.  
  722.                 BL              NewLine
  723.                 BL              NewLine
  724.  
  725.                 LDMFD           sp!, {r0-r8, pc}^
  726.  
  727. BackWord        =               "BACK"
  728. STMFDWord       &               &092D0000
  729. STMFDMask       &               &0FFF0000
  730.  
  731. Equals          =               " = ", 0
  732.  
  733. RegNames        =               "\\ R0  R1  R2  R3"
  734.                 =               "\\ R4  R5  R6  R7"
  735.                 =               "\\ R8  R9 R10 R11"
  736.                 =               "\\R12  SP\\ LR  PC"
  737.  
  738. InitSP2         &               &01F0136C
  739. InitSP          &               &01C02000
  740.  
  741. ; Exception handlers and workspace
  742.  
  743. SaveLR          &               0
  744. RegSave         %               16 * 4
  745.  
  746. BadInst         TEQP            pc, #I_bit :OR: F_bit :OR: S0_bit :OR: S1_bit
  747.                 STR             lr, SaveLR
  748.                 ADR             lr, RegSave
  749.                 STMIA           lr!, {r0-r7}
  750.                 MOV             r0, lr
  751.                 BL              Report
  752.  
  753.                 &               &80000000
  754.                 =               "Undefined instruction", 0
  755.                 ALIGN
  756.  
  757. PrefetchAbt     TEQP            pc, #I_bit :OR: F_bit :OR: S0_bit :OR: S1_bit
  758.                 STR             lr, SaveLR
  759.                 ADR             lr, RegSave
  760.                 STMIA           lr!, {r0-r7}
  761.                 MOV             r0, lr
  762.                 BL              Report
  763.  
  764.                 &               &80000001
  765.                 =               "Abort on instruction fetch", 0
  766.                 ALIGN
  767.  
  768. DataAbt         TEQP            pc, #I_bit :OR: F_bit :OR: S0_bit :OR: S1_bit
  769.                 STR             lr, SaveLR
  770.                 ADR             lr, RegSave
  771.                 STMIA           lr!, {r0-r7}
  772.                 MOV             r0, lr
  773.                 BL              Report
  774.  
  775.                 &               &80000002
  776.                 =               "Abort on data transfer", 0
  777.                 ALIGN
  778.  
  779. ; Save lr (the exception address) at 0
  780.  
  781. AddrExcp        TEQP            pc, #I_bit :OR: F_bit :OR: S0_bit :OR: S1_bit
  782.                 STR             lr, SaveLR
  783.                 ADR             lr, RegSave
  784.                 STMIA           lr!, {r0-r7}
  785.                 MOV             r0, lr
  786.                 BL              Report
  787.  
  788.                 &               &80000003
  789.                 =               "Address exception", 0
  790.                 ALIGN
  791.  
  792. ; Report an exception. On entry, location 0 holds a copy of lr pointing to
  793. ; the faulted instruction.
  794. ;
  795. ; R0  ==> Register save area address for R8-PC (R0-R7 are already saved)
  796. ; LR  ==> Return address points to a string describing the problem, (e.g.
  797. ;         Address exception)
  798.  
  799. Report          LDR             r1, SaveLR      ; Get exception LR
  800.                 STR             r1, [r0, #4 * 7]  ; Save it as the PC
  801.                 TST             r1, #3          ; Was it a non-USR mode?
  802.                 STMEQIA         r0, {r8-lr}^    ; If not, save the USR mode registers
  803.                 BEQ             Report1
  804.  
  805. ; Exception happened in a non-USR mode
  806.  
  807.                 TST             r1, #1
  808.                 TSTNE           r1, #2
  809.                 STMNEIA         r0, {r8-lr}
  810.                 BNE             Report1
  811.  
  812. ; Exception was in either IRQ or FIQ mode, so go into that mode, save the
  813. ; registers then return to SVC mode
  814.  
  815.                 TEQP            r1, #0
  816.                 NOP
  817.  
  818.                 STMIA           r0, {r8-lr}
  819.                 TEQP            pc, #S0_bit :OR: S1_bit
  820.  
  821. ; Do some funny stuff with IOC
  822.  
  823.                 AND             r1, r1, #3
  824.                 EORS            r2, r1, #1
  825.                 MOVEQ           r3, #&03200000
  826.                 STREQB          r2, [r3, #56]
  827.  
  828. Report1         LDR             sp, InitSP      ; Need a stack, this one will do
  829.  
  830.                 ADR             r1, RegSave + 10 * 4
  831.                 LDMIA           r1, {r10-r12}
  832.                 STMFD           sp!, {r10-r12}
  833.  
  834.                 LDR             r1, RegSave + 15 * 4  ; PC
  835.                 STMFD           sp!, {r1}
  836.  
  837. ; Address of message
  838.  
  839.                 BIC             r10, lr, #&FC000003
  840.  
  841. ; Put VDU back to screen
  842.  
  843.                 MOV             r0, #&3C
  844.                 MOV             r1, #0
  845.                 MOV             r2, #0
  846.                 MOV             r1, #1
  847.                 SWI             XOS_SpriteOp
  848.  
  849. ;                MOV             r0, #DebugOn :OR: UseVDU
  850. ;                MOV             r1, #0
  851. ;                BL              DebugFlags
  852. ;                SWI             XOS_WriteI + 22
  853. ;                SWI             XOS_WriteI + 31
  854. ;                SWI             XOS_WriteI + "N" - 64
  855.  
  856.                 ADD             r1, r10, #4
  857.                 BL              BinString
  858.                 ADR             r1, AtStr
  859.                 BL              BinString
  860.                 LDR             r1, RegSave + 15 * 4
  861.                 BL              HexPC
  862.  
  863.                 ADR             r5, RegSave
  864.                 MOV             r6, #0
  865.                 BL              ShowRegs
  866.                 BL              AltBacktrace
  867.  
  868. ; This is just borrowed from the OS; I don't know what is at location 264
  869.  
  870.                 TEQP            pc, #&08000002
  871.                 MOV             r1, #0
  872.                 STR             r1, [r1, #264]
  873.                 LDR             sp, InitSP2
  874.                 MOV             r0, r10
  875.                 SWI             XOS_GenerateError :AND: (:NOT: XOS_Bit)
  876.  
  877. AtStr           =               " at &", 0
  878.                 ALIGN
  879.  
  880.                 END
  881.