; This source code in this file is licensed to You by Castle Technology
; Limited ("Castle") and its licensors on contractual terms and conditions
; ("Licence") which entitle you freely to modify and/or to distribute this
; source code subject to Your compliance with the terms of the Licence.
;
; This source code has been made available to You without any warranties
; whatsoever. Consequently, Your use, modification and distribution of this
; source code is entirely at Your own risk and neither Castle, its licensors
; nor any other person who has contributed to this source code shall be
; liable to You for any loss or damage which You may suffer as a result of
; Your use, modification or distribution of this source code.
;
; Full details of Your rights and obligations are set out in the Licence.
; You should have received a copy of the Licence with this source code file.
; If You have not received a copy, the text of the Licence is available
; online at www.castle-technology.co.uk/riscosbaselicence.htm
;
SUBT Macros for Econet debugging
OldOpt SETA {OPT}
OPT OptNoList+OptNoP1List
; ***********************************
; *** C h a n g e L i s t ***
; ***********************************
;
; Date Name Description
; ---- ---- -----------
; 01-Jul-93 BCockburn Created from Hdr:EcoMacros
; 29-Mar-94 BCockburn Moved all Econet specific macros in from Hdr:EcoMacros
ARM_config_cp CP 15 ; coprocessor number for configuration control
ARM_ID_reg CN 0 ; processor ID
ARM8A_cache_reg CN 7 ; cache operations, ARM 8 or StrongARM
C0 CN 0
C5 CN 5
C10 CN 10
MACRO
FIQStr $s
STR r4, [ r0, -r0 ] ; Save in a known place
LDR r4, =DebugTraceRegs ; Work area
STMIA r4!, { r0-r3 }
LDMIA r4!, { r1, r2 }
STMIA r4!, { r5 }
MOV r5, psr ; Preserve mode
TEQP psr, #( FFlag + IFlag + SVC_mode ) ; Set FIQ flag and goto SVC mode
CMP r2, #50
BLT %FT30
ADR r3, %FT20
10
LDRB r0, [ r3 ], #1
STRB r0, [ r1, #0 ]
TEQ r0, #0
SUBNE r2, r2, #1
ADDNE r1, r1, #1
BNE %BT10
B %FT30
20
DCB $s, 0
ALIGN
30
TEQP r5, #0 ; Return to Correct mode
LDMDB r4!, { r5 }
STMDB r4!, { r1, r2 }
LDMDB r4!, { r0-r3 }
LDR r4, [ r0, -r0 ]
MEND
MACRO
FIQReg $r
STR r4, [ r0, -r0 ] ; Save in a known place
LDR r4, =DebugTraceRegs ; Work area
STMIA r4!, { r0-r3 }
MOV r3, psr ; Preserve mode
[ $r = r4
LDR r0, [ r0, -r0 ]
|
MOV r0, $r
]
TEQP psr, #( FFlag + IFlag + SVC_mode ) ; Set FIQ flag and goto SVC mode
LDMIA r4!, { r1, r2 }
STMIA r4!, { r14 } ; Preserve SVC r14
SWI XOS_ConvertHex8
LDMDB r4!, { r14 }
STMDB r4!, { r1, r2 }
TEQP r3, #0 ; Return to Correct mode
LDMDB r4!, { r0-r3 }
LDR r4, [ r0, -r0 ]
MEND
MACRO
Str $s
Push "r0-r4"
MOV r4, psr ; Preserve mode
TEQP psr, #( FFlag + IFlag + SVC_mode ) ; Set FIQ flag and goto SVC mode
LDR r0, =DebugTraceAddr ; Work area
LDMIA r0, { r1, r2 }
CMP r2, #50
BLT %FT30
ADR r3, %FT20
10
LDRB r0, [ r3 ], #1
STRB r0, [ r1, #0 ]
TEQ r0, #0
SUBNE r2, r2, #1
ADDNE r1, r1, #1
BNE %BT10
B %FT30
20
DCB $s, 0
ALIGN
30
LDR r0, =DebugTraceAddr ; Work area
STMIA r0, { r1, r2 }
TEQP r4, #0 ; Return to Correct mode
Pull "r0-r4"
MEND
MACRO
Reg $r
Push "r0-r4"
MOV r4, psr ; Preserve mode
TEQP psr, #( FFlag + IFlag + SVC_mode ) ; Set FIQ flag and goto SVC mode
LDR r0, =DebugTraceAddr ; Work area
LDMIA r0, { r1, r2 }
CMP r2, #50
BLT %FT30
[ $r = r0
LDR r0, [ sp, #0 ]
|
[ $r = r1
LDR r0, [ sp, #4 ]
|
[ $r = r2
LDR r0, [ sp, #8 ]
|
[ $r = r3
LDR r0, [ sp, #12 ]
|
[ $r = r4
LDR r0, [ sp, #16 ]
|
MOV r0, $r
]
]
]
]
]
Push "lr"
SWI XOS_ConvertHex8
Pull "lr"
30
LDR r0, =DebugTraceAddr ; Work area
STMIA r0, { r1, r2 }
TEQP r4, #0 ; Return to Correct mode
Pull "r0-r4"
MEND
MACRO
DebugStats $Reg,$Id
STR r0, [ r0, -r0 ]
LDR r0, =DebugRegs
STMIA r0, { r1, r2, r3 }
LDR r1, =DebugPtr
LDR r2, [ r1, #0 ]
LDR r3, [ r1, #DebugLimit-DebugPtr ]
CMP r3, r2
ORR r3, $Reg, #($Id :SHL: 16)
STMLTDB r2!, { r3 }
STRLT r2, [ r1, #0 ]
LDMIA r0, { r1, r2, r3 }
LDR r0, [ r0, -r0 ]
MEND
MACRO
Load $reg,$identifier,$c
; If the global variable with the same name as "$identifier"
; is null then it is assumed that a variable exists and can be
; LD'd from, otherwise the global variable is assumed to contain
; the text of the value that can be LDR ='d.
[ $identifier = ""
LD $reg, $identifier.Var, $c
|
LDR$c $reg, =$$$identifier
]
MEND
MACRO
Stor $reg,$identifier,$cond
; If the global variable with the same name as the identifier
; is null then it is assumed that a variable exists and can be
; ST'd to, otherwise an error is raised
[ $identifier = ""
ST $reg, $identifier.Var, $cond
|
! 0, "Storing to constant value"
]
MEND
MACRO
$a SetFIQ $dest,$rega,$regb,$style,$init,$regc
; $dest is the label of the code to jump to
; $rega is the register to use for the pointer
; $regb is the register to use for the instruction
; $regc is an extra register required to preserve the mode during initialisation
[ "$rega" = "" :LOR: "$regb" = "" :LOR: ("$init" = "Init" :LAND: "$regc" = "")
! 1,"Syntax is: SetFIQ dest, rega, regb [, long [, init, regc]]"
]
[ "$init" = "Init"
$a
[ {TRUE} ; ; Cope with 32bit CPUs
mrs AL, $regc, CPSR_all ; Switch to _32 mode with IRQs and FIQs off
ORR $regb, $regc, #I32_bit :OR: F32_bit ; Has to be done in two stages because RISC OS
msr AL, CPSR_all, $regb ; can't return to a 32bit mode and interrupts
ORR $regb, $regb, #2_10000 ; can occur after the MSR but before the following
msr AL, CPSR_all, $regb ; instruction.
]
ADR $rega, FIQVector
LDR $regb, =&E51FF004 ; LDR pc, .+4 = LDR pc, [ pc, #-4 ]
STR $regb, [ $rega ], #4
[ {TRUE} ; ; Cope with 32bit CPUs
; And switch back
msr AL, CPSR_all, $regc
]
[ StrongARM
; Local version of OS_SynchroniseCodeAreas, because it's far too much hassle
; calling a SWI in these circumstances
MRC ARM_config_cp, 0, $regc, ARM_ID_reg, C0, 0
AND $regc,$regc,#&F000
TEQS $regc,#&A000
BNE %FT01 ; not StrongARM
; We want to clean the (32-byte) data cache line containing
; the FIQVector word.
ADR $regc, FIQVector
MCR ARM_config_cp, 0, $regc, ARM8A_cache_reg, C10, 1 ; clean DC entry
MCR ARM_config_cp, 0, $regc, ARM8A_cache_reg, C10, 4 ; drain WB
MCR ARM_config_cp, 0, $regc, ARM8A_cache_reg, C5, 0 ; flush IC
; Normally 4 NOPs could be required to make sure the
; modified instruction wasn't in the pipeline. Fortunately
; we know that the FIQ vector can't be called within 3
; instructions of here (and if an FIQ were to go off, the
; pipeline would be flushed anyway).
1
[ ARM810support
SUB PC,PC,#4 ; flushes branch predict on ARM810 (local equivalent of OS_SynchroniseCodeAreas)
]
]
|
$a ADR $rega, FIQVector + 4
]
[ "$style" = "Long"
ADRL $regb, $dest
|
ADR $regb, $dest
]
STR $regb, [ $rega, #0 ]
MEND
MACRO
$a SetJump $dest,$rega,$regb,$style
; $dest is the label of the code to jump to
; $rega is the register to use for the instruction
; $regb is the register to use for the pointer
[ "$rega" = "" :LOR: "$regb" = ""
! 1,"Syntax is: SetJump dest, temp, address [, long]"
]
[ "$style" = "Long"
$a ADRL $rega, $dest
|
$a ADR $rega, $dest
]
ADR $regb, NextJump
STR $rega, [ $regb, #0 ]
MEND
MACRO
$a PutFIQ $rega,$regb,$init
; $rega is the register with the instruction in it
; $regb is the register to use for the pointer
[ "$rega" = "" :LOR: "$regb" = ""
! 1,"Syntax is: PutFIQ instruction, address [, init]"
]
[ "$init" = "Init"
[ StrongARM
! 1,"PutFIQ Init won't work on StrongARM!"
]
$a ADR $rega, FIQVector
LDR $regb, =&E51FF004 ; LDR pc, .+4 = LDR pc, [ pc, #-4 ]
STR $regb, [ $rega ], #4
|
$a ADR $rega, FIQVector + 4
]
ADR $regb, NextJump
LDR $regb, [ $regb, #0 ]
STR $regb, [ $rega, #0 ]
MEND
MACRO
$a RTFIQ
$a SUBS pc, lr, #4
MEND
MACRO
$a WaitForFIQ $rega,$regb
; rega is the register to use for the instruction
; regb is the register to use for the pointer
[ "$rega" = "" :LOR: "$regb" = ""
! 1,"Syntax is: WaitForFIQ rega, regb"
]
$a ADR $rega, FIQVector + 4
ADR $regb, %FT10
STR $regb, [ $rega, #0 ]
SUBS pc, lr, #4
ALIGN $Alignment
10
MEND
MACRO
MakeNetError $cond
[ Debug
MOV$cond r8, pc ; Goes into Offset_NetError
]
B$cond NetError
MEND
MACRO
MakeNetError1 $cond
[ Debug
MOV$cond r8, pc ; Goes into Offset_NetError
]
B$cond NetErrorWithSReg1
MEND
MACRO
MakeNetError2 $cond
[ Debug
MOV$cond r8, pc ; Goes into Offset_NetError
]
B$cond NetErrorWithSReg2
MEND
MACRO
MakeReceptionError $cond
[ Debug
MOV$cond r8, pc ; Goes into Offset_NetError
]
B$cond ReceptionError
MEND
MACRO
MakeReceptionError2 $cond
[ Debug
MOV$cond r8, pc ; Goes into Offset_NetError
]
B$cond ReceptionErrorWithSReg2
MEND
MACRO
TurnAroundDelay $reg1,$reg2,$reg3,$delay
ADR r10, IOC
[ "$delay" = "" ; Default case is 40 microseconds
MOV $reg1, #80
| ; Delay value in microseconds
MOV $reg1, #(($delay)*2)
]
STRB $reg1, [ r10, #Timer0LR ] ; Copies counter to output latch
LDRB $reg2, [ r10, #Timer0CL ] ; Reg2 = low output latch
10 ; loop waiting for 2MHz counter to change
STRB $reg1, [ r10, #Timer0LR ] ; Copies counter to output latch
LDRB $reg3, [ r10, #Timer0CL ] ; Reg3 = low output latch
TEQS $reg2, $reg3 ; Has counter changed?
BEQ %BT10 ; Else wait for it to change
; counter has changed, decrement our count of ticks
MOV $reg2, $reg3 ; Update copy of counter
SUBS $reg1, $reg1, #1 ; Decrement ticks
BNE %BT10 ; Then continue if not done
; delay has expired
[ PoduleCapable
LDR r10, HardwareAddress
|
LDR r10, =EconetController
]
MEND
MACRO
Err $name
ALIGN
Error$name
DCD ErrorNumber_$name
DCB ErrorString_$name
DCB 0
ALIGN
MEND
OPT OldOpt
END