; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; > &.Hdr.NdrDebug ; OldOpt SETA {OPT} OPT OptNoList+OptNoP1List ; *********************************** ; *** C h a n g e L i s t *** ; *********************************** ; Date Name Description ; ---- ---- ----------- ; ; 25-Sep-89 NDR First version written ; 3-May-90 NDR File debugging added ; 30-Aug-90 NDR Changed so if file can't be opened, no debugging is output ; 1-Nov-90 NDR Neil_NewLine flushes data to file ; 6-Nov-90 NDR Neil_NewLine also puts out end-of-file marker and resets PTR ; 2-Jan-91 NDR Ensure Debug macro still works if V set on entry ; 3-Jan-91 NDR Ensure debug_flush deals correctly when no debug output ; 4-Jan-91 NDR Preserve R2 in Neil_Write0 and Neil_Newline ; 10-Apr-91 OSS Changed all macros, particularly InsertNDRDebugRoutines, ; to not put any code in if the debug flag is not set. This ; is because too many modules are messing things up and ; are putting debugging code into the ROM! ; 10-Feb-93 BC Restored OPT correctly ; 27-Apr-93 AMG Changed the macros to use HostFS SWIs instead of OS_CLI. ; This stops scratchspace corruption which was affecting ; Colourtrans_SelectTable debug calls. Added logic flag ; to allow assembling ColourTrans with the previous version ; to raise an error. ; 14-Jul-93 SAH Print *NULL* if DebugS is given a 0 pointer. ; 2-Aug-93 SAH Increased number of parameters to 10 ; 2-Aug-93 SAH Added conditional versions (DebugIf, DebugaIf, DebugSIf) ; 13-Oct-93 AMG Merge the two copies of NdrDebug together, and remove ; the one from hdr - ATTENTION: NdrDebug lives in hdr2 !!! ; 20-Sep-94 SMC Added support for DebugIt module (set debug_module to true, ; hostvdu should be false). ; 17-Apr-97 JRC If debug_file is set, it is a file name which is opened, ; written to and closed in each call to Debug. Even better ; than debug_flush! ; 15-Jan-98 KJB Added support for PDebug module (set pdebug_module to true, ; hostvdu should be false). ; 21-May-99 BJGA Added support for debugging null-terminated strings: ; top-bit-clear characters (other than CR and LF) are effectively ; reverse-GSTrans'd (set debug_nullterminatedstrings to true). ; Also added support for DADebug module (set daddebug_module true). ; hostvdu is now defined, and set false, if not yet defined. ; Debug_Open and Debug_Close only generate code in cases where the ; output mechanism needs it, so they no longer need to be ; bracketed conditionally in the source code. ; 28-May-99 BJGA Added debug_irqsafe option, which converts a 32-bit number to a ; string itself, without calling OS_ConvertHex8 ; 04-Apr-00 KJB Made 32-bit compatible (except a few options, which will generate ; warnings) ; 05-Apr-00 BJGA debug_nullterminatedstrings also made 32-bit compatible; ; 32-bit compatibility now complete ; 14-Aug-00 BJGA Now outputs the value of r13 correctly; No32BitCode-unset variant ; now objasm-compatible (uses mymrs macros rather than mrs macros) GBLL debug GBLL debug_flush GBLS debug_file GBLL true GBLL false ; New logical variable for use in sources which suffer from scratchspace ; corruption caused by older version of this header calling OS_CLI instead ; of HostFS by SWI directly. Set it to {FALSE} before incorporating this ; header file to ensure that the new header file is in use. You may also ; need to add a GET for hdr:HostFS GBLL debug_noscratchspace debug_noscratchspace SETL {TRUE} [ :LNOT: :DEF: hostvdu GBLL hostvdu ; Use HostFS hostvdu SETL {FALSE} ] GBLL debug_module ; Use DebugIt module debug_module SETL {FALSE} GBLL pdebug_module ; Use PDebug module pdebug_module SETL {FALSE} GBLL dadebug_module ; Use DADebug module dadebug_module SETL {FALSE} GBLL debug_nullterminatedstrings ; Print control characters in strings debug_nullterminatedstrings SETL {FALSE} GBLL debug_irqsafe ; Emulate SWI OS_ConvertHex8 debug_irqsafe SETL {FALSE} true SETL 1=1 false SETL 1=0 debug_flush SETL false ; default - can be altered before InsertNDRDebugRoutines debug_file SETS "" ; default - can be altered before InsertNDRDebugRoutines ; NB: All s preserve the flags and all registers. ; However, they do require the stack to be set up. MACRO $lab Debug_Open $filename $lab [ debug :LAND: :LNOT: hostvdu :LAND: :LNOT: debug_module :LAND: :LNOT: pdebug_module [ dadebug_module ; this doesn't use $filename Push "R0, LR" SWI &731C0 ; XDADebug_GetWriteCAddress MOVVS R0, #0 ADRL LR, dadebug_writec STR R0, [LR] CLRV Pull "R0, LR" | [ debug_file = "" Push "R1, LR" ADR R1, %FT00 BL Neil_OpenFile B %FT01 00 DCB "$filename", 0 ALIGN 01 Pull "R1, LR" | Debug "", "------------------------------------------------------------" ] ] ] MEND MACRO $lab Debug_Close $lab [ debug :LAND: :LNOT: hostvdu :LAND: :LNOT: debug_module :LAND: :LNOT: pdebug_module [ dadebug_module Push "LR" MOV LR, #0 STR LR, dadebug_writec Pull "LR" | [ debug_file = "" Push "LR" BL Neil_CloseFile Pull "LR" ] ] ] MEND MACRO Debug1 $dbg, $string [ debug$dbg Debug $dbg, "$string" ] MEND MACRO Debug2 $dbg, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 [ debug$dbg Debug $dbg, "", $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 ] MEND MACRO Debug2a $dbg, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 [ debug$dbg Debuga $dbg, "", $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 ] MEND MACRO DebugS $dbg, $string, $reg, $max [ debug:LAND:debug$dbg Push "R0-R12, LR, PC" [ :LNOT:No32bitCode mymrs ,LR, CPSR STR LR, [sp, #14*4] ] [ debug_file <> "" ADR R1, %FT10 BL Neil_OpenFile B %FT11 10 DCB "$debug_file", 0 ALIGN 11 ] [ hostvdu BL Neil_HostVdu ] MOV r0, pc BL Neil_ConvertHex8 ADR R0, %FT00 BL Neil_Write0 B %FT01 00 DCB ": $dbg, $string", 0 02 DCB "*NULL*", 0 ALIGN 01 MOV R0, #" " BL Neil_WriteC MOV R0, #"'" BL Neil_WriteC [ $reg > sp LDR R0, [sp, #:INDEX:$reg * 4 - 4] ; R13 is not stacked | LDR R0, [sp, #:INDEX:$reg * 4] ] TEQ R0, #0 ADREQ R0, %BT02 [ "$max"="" BL Neil_Write0 | MOV R2, #$max BL Neil_Write0_R2max ] MOV R0, #"'" BL Neil_WriteC BL Neil_NewLine [ hostvdu BL Neil_TubeVdu ] [ debug_file <> "" BL Neil_CloseFile ] Pull "R0-R12" LDR LR, [sp, #4] RestPSR LR,,f ; restore flags LDR LR, [sp], #8 ; correct stack ] MEND MACRO Debug $dbg, $string, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 [ debug:LAND:debug$dbg Push "R0-R12, LR, PC" [ :LNOT:No32bitCode mymrs ,LR, CPSR STR LR, [sp, #14*4] ] [ debug_file <> "" ADR R1, %FT10 BL Neil_OpenFile B %FT11 10 DCB "$debug_file", 0 ALIGN 11 ] [ hostvdu BL Neil_HostVdu ] MOV r0, pc BL Neil_ConvertHex8 ADR R0, %FT00 BL Neil_Write0 B %FT01 00 DCB ": $dbg, $string", 0 ALIGN 01 [ "$p1"<>"" Dreg $p1 ] [ "$p2"<>"" Dreg $p2 ] [ "$p3"<>"" Dreg $p3 ] [ "$p4"<>"" Dreg $p4 ] [ "$p5"<>"" Dreg $p5 ] [ "$p6"<>"" Dreg $p6 ] [ "$p7"<>"" Dreg $p7 ] [ "$p8"<>"" Dreg $p8 ] [ "$p9"<>"" Dreg $p9 ] [ "$p10"<>"" Dreg $p10 ] BL Neil_NewLine [ hostvdu BL Neil_TubeVdu ] [ debug_file <> "" BL Neil_CloseFile ] Pull "R0-R12" LDR LR, [sp, #4] RestPSR LR,,f ; restore flags LDR LR, [sp], #8 ; correct stack ] MEND MACRO Debuga $dbg, $string, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 [ debug:LAND:debug$dbg Push "R0-R12, LR, PC" [ :LNOT:No32bitCode mymrs ,LR, CPSR STR LR, [sp, #14*4] ] [ hostvdu BL Neil_HostVdu ] ADR R0, %FT00 BL Neil_Write0 B %FT01 00 DCB "$string", 0 ALIGN 01 [ "$p1"<>"" Dreg $p1 ] [ "$p2"<>"" Dreg $p2 ] [ "$p3"<>"" Dreg $p3 ] [ "$p4"<>"" Dreg $p4 ] [ "$p5"<>"" Dreg $p5 ] [ "$p6"<>"" Dreg $p6 ] [ "$p7"<>"" Dreg $p7 ] [ "$p8"<>"" Dreg $p8 ] [ "$p9"<>"" Dreg $p9 ] [ "$p10"<>"" Dreg $p10 ] [ hostvdu BL Neil_TubeVdu ] Pull "R0-R12" LDR LR, [sp, #4] RestPSR LR,,f ; restore flags LDR LR, [sp], #8 ; correct stack ] MEND MACRO Dreg $reg [ debug [ "$reg":LEFT:1 = "#" LCLS locn locn SETS "$reg":RIGHT:(:LEN:"$reg"-1) [ :BASE:($locn) = sp LDR R0, $locn + 15*4 ; allow for 15 stacked registers | LDR R0, $locn ] | [ $reg > sp LDR R0, [sp, #:INDEX:$reg * 4 - 4] ; R13 is not stacked | [ $reg = sp ADD R0, sp, #15*4 | LDR R0, [sp, #:INDEX:$reg * 4] ] ] ] BL Neil_ConvertHex8 ] ; End debug MEND MACRO $lab DebugE $dbg, $mess [ debug:LAND:debug$dbg $lab BVC %ft0 ADD R0, R0, #4 DebugS $dbg, "$mess", R0 SUB R0, R0, #4 0 ] MEND ; Conditional versions of some of the above macros MACRO $lab DebugSIf $cond, $dbg, $string, $reg, $max [ debug:LAND:debug$dbg $lab B$cond %FT99 B %FT98 99 DebugS $dbg, "$string", "$reg", "$max" 98 ] MEND MACRO $lab DebugaIf $cond, $dbg, $string, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 [ debug:LAND:debug$dbg $lab B$cond %FT99 B %FT98 99 Debuga $dbg, "$string", $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 ] MEND MACRO $lab DebugIf $cond, $dbg, $string, $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 [ debug:LAND:debug$dbg $lab B$cond %FT99 B %FT98 99 Debug $dbg, "$string", $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10 98 ] MEND MACRO InsertNDRDebugRoutines [ debug Neil_ConvertHex8 ; prints number in R0 Push "R0, LR" ; MOV R0, #" " BL Neil_WriteC [ debug_irqsafe Pull "R1" MOV R2, #8 01 MOV R0, R1, LSR#28 CMP R0, #10 ADDCC R0, R0, #48 ADDCS R0, R0, #55 BL Neil_WriteC MOV R1, R1, LSL#4 SUBS R2, R2, #1 BNE %BT01 | Pull "R0" SUB sp, sp, #12 MOV R1, sp MOV R2, #9 ; includes room for terminator SWI XOS_ConvertHex8 ADDVS R0, R0, #4 ; print error message if there was one BL Neil_Write0 ADD sp, sp, #12 ] ; Pull "PC" [ hostvdu Neil_HostVdu EntryS SWI XHostFS_HostVdu SWI XOS_WriteI+4 ; VDU 4 mode in case no HostVdu EXITS Neil_TubeVdu EntryS SWI XHostFS_TubeVdu EXITS ] Neil_Write0 EntryS "R2" MOV R2, #&10000000 ; no limit on string length BL Neil_Write0_R2max EXITS Neil_Write0_R2max EntryS "R0" MOV R1, R0 ; R1 -> string, R2 = max length (unsigned) 01 LDRB R0, [R1], #1 [ debug_nullterminatedstrings CMP R0, #1 | CMP R0, #32 ; terminate on any ctrl-char ] SUBCSS R2, R2, #1 BLCS Neil_WriteC BCS %BT01 02 EXITS Neil_WriteC [ pdebug_module EntryS "R0-R2" | EntryS "R0, R1" ] [ debug_nullterminatedstrings CMN R0, #0 ; clear C TEQ R0, #"""" ; TEQ without shift preserves C TEQNE R0, #"|" TEQNE R0, #"<" EOREQ R0, R0, #"@" ; these characters don't need converting when prefixed by "|" TEQNE R0, #127 CMPNE R0, #32 ; CS if >= Space, except ", |, < and Delete TEQ R0, #0 TEQNE R0, #10 TEQNE R0, #13 CMPEQ R0, #0 ; now also CS if R0 was 0, 10 or 13 EORCC R1, R0, #"@" ; if non line-end control character, generate escaped character MOVCC R0, #"|" ; and prefix with "|" BLCC %FT01 ; preserves flags, fortunately MOVCC R0, R1 B %FT02 01 ALTENTRY 02 ] LDR R1, Neil_FileHandle CMP R1, #0 ; 0 => writec, -1 => none, >0 => file [ debug_module SWIEQ XDebugIt_WriteC | [ pdebug_module MOVEQ R0,#0 ADDEQ R1,R13,#Proc_RegOffset ; yuck :) MOVEQ R2,#1 SWIEQ &6F900 ; XPDebugM_Send | [ dadebug_module BGT %FT01 LDR LR, dadebug_writec CMP LR, #0 ; undefined? BEQ %FT01 MOV LR, PC LDR PC, dadebug_writec CMP R0, R0 ; ensure not GT 01 | SWIEQ XOS_WriteC ] ] ] SWIGT XOS_BPut EXITS Neil_NewLine ROUT EntryS "R0-R2" LDR R14, Neil_FileHandle CMP R14, #0 MOVEQ R0, #13 ; only write CR if not to a file BLEQ Neil_WriteC MOV R0, #10 BL Neil_WriteC [ debug_flush LDR R1, Neil_FileHandle ; ensure bytes to the media after each line CMP R1, #0 BLE %FT00 MOV R0, #"E" BL Neil_WriteC MOV R0, #"O" BL Neil_WriteC MOV R0, #"F" BL Neil_WriteC MOV R0, #255 ; ensure bytes to media SWI XOS_Args MOV R0, #0 ; read PTR in R2 SWI XOS_Args SUB R2, R2, #3 MOV R0, #1 ; write PTR in R2 SWI XOS_Args 00 ] EXITS Neil_OpenFile ROUT Entry "R0-R2" MOV r0, #-1 STR r0, Neil_FileHandle ; -1 => no file debugging MOV r0, #&C7 ; open for update SWI XOS_Find EXIT VS TEQ r0, #0 ; object exists? BEQ %20 ;File found---get the extent MOV r1, r0 ; file handle MOV r0, #2 ; read extent SWI XOS_Args EXIT VS ;r2 = extent ;Set the pointer to the extent MOV r0, #1 ; write ptr ;r1 still has file handle ;r2 still has extent SWI XOS_Args EXIT VS B %30 20 ;File not found---open a new one for output MOV r0, #&87 ; open for output SWI XOS_Find EXIT VS ;r0 = file handle ;r1 -> file name ;Make it a text file Push "r0" MOV r0, #18 MOV r2, #&FF ORR r2, r2, #&F00 ; file type text SWI XOS_File Pull "r1" EXIT VS 30 STR r1, Neil_FileHandle EXIT Neil_CloseFile ROUT EntryS "R0-R1" MOV R0, #0 ; close file LDR R1, Neil_FileHandle CMP R1, #0 STRGT R0, Neil_FileHandle ; back to writec debugging SWIGT XOS_Find EXITS Neil_FileHandle DCD 0 ; default state => writec debugging [ dadebug_module dadebug_writec DCD 0 ; workspace to hold routine pointer ] ] ; End debug MEND OPT OldOpt END