Difference between revisions of "PM Opc CALL"
From SublabWiki
(CALL Instruction) |
(Inside CALL page) |
||
(7 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
!Hex | !Hex | ||
!Mnemonic | !Mnemonic | ||
− | |||
!Cycles,True | !Cycles,True | ||
!or False | !or False | ||
+ | !Condition | ||
|- | |- | ||
|E0 ss | |E0 ss | ||
− | | | + | |CALLCB #ss<SUP>*1</SUP> |
− | |||
|20 | |20 | ||
|8 | |8 | ||
+ | |Carry=1 | ||
|- | |- | ||
|E1 ss | |E1 ss | ||
− | | | + | |CALLNCB #ss<SUP>*1</SUP> |
− | |||
|20 | |20 | ||
|8 | |8 | ||
+ | |Carry=0 | ||
|- | |- | ||
|E2 ss | |E2 ss | ||
− | | | + | |CALLZB #ss<SUP>*1</SUP> |
− | |||
|20 | |20 | ||
|8 | |8 | ||
+ | |Zero=1 | ||
|- | |- | ||
|E3 ss | |E3 ss | ||
− | | | + | |CALLNZB #ss<SUP>*1</SUP> |
− | |||
|20 | |20 | ||
|8 | |8 | ||
+ | |Zero=0 | ||
|- | |- | ||
|E8 ss ss | |E8 ss ss | ||
− | | | + | |CALLCW #ssss<SUP>*1</SUP> |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Carry=1 | ||
|- | |- | ||
|E9 ss ss | |E9 ss ss | ||
− | | | + | |CALLNCW #ssss<SUP>*1</SUP> |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Carry=0 | ||
|- | |- | ||
|EA ss ss | |EA ss ss | ||
− | | | + | |CALLZW #ssss<SUP>*1</SUP> |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Zero=1 | ||
|- | |- | ||
|EB ss ss | |EB ss ss | ||
− | | | + | |CALLNZW #ssss<SUP>*1</SUP> |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Zero=0 | ||
|- | |- | ||
|F0 ss | |F0 ss | ||
− | | | + | |CALLB #ss<SUP>*1</SUP> |
+ | |20 | ||
|None | |None | ||
− | |||
|None | |None | ||
|- | |- | ||
|F2 ss ss | |F2 ss ss | ||
− | | | + | |CALLW #ssss<SUP>*1</SUP> |
+ | |24 | ||
|None | |None | ||
− | |||
|None | |None | ||
|- | |- | ||
− | |FB | + | |FB nn nn |
|CALL [#nnnn] | |CALL [#nnnn] | ||
+ | |20 | ||
|None | |None | ||
− | |||
|None | |None | ||
|- | |- | ||
− | |FC | + | |FC nn |
|CINT #nn | |CINT #nn | ||
+ | |20 | ||
|None | |None | ||
− | |||
|None | |None | ||
|- | |- | ||
|CE F0 ss | |CE F0 ss | ||
− | |CALLL | + | |CALLL #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |(Overflow=1) != (Sign=1) | ||
|- | |- | ||
|CE F1 ss | |CE F1 ss | ||
− | |CALLLE | + | |CALLLE #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |((Overflow=0) != (Sign=0)) OR (Zero=1) | ||
|- | |- | ||
|CE F2 ss | |CE F2 ss | ||
− | |CALLG | + | |CALLG #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |((Overflow=1) == (Sign=1)) AND (Zero=0) | ||
|- | |- | ||
|CE F3 ss | |CE F3 ss | ||
− | |CALLGE | + | |CALLGE #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |(Overflow=0) == (Sign=0) | ||
|- | |- | ||
|CE F4 ss | |CE F4 ss | ||
− | |CALLO | + | |CALLO #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Overflow=1 | ||
|- | |- | ||
|CE F5 ss | |CE F5 ss | ||
− | |CALLNO | + | |CALLNO #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Overflow=0 | ||
|- | |- | ||
|CE F6 ss | |CE F6 ss | ||
− | | | + | |CALLNS #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Sign=0 | ||
|- | |- | ||
|CE F7 ss | |CE F7 ss | ||
− | | | + | |CALLS #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |Sign=1 | ||
|- | |- | ||
|CE F8 ss | |CE F8 ss | ||
− | |CALLNX0 | + | |CALLNX0 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE F9 ss | |CE F9 ss | ||
− | |CALLNX1 | + | |CALLNX1 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE FA ss | |CE FA ss | ||
− | |CALLNX2 | + | |CALLNX2 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE FB ss | |CE FB ss | ||
− | |CALLNX3 | + | |CALLNX3 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE FC ss | |CE FC ss | ||
− | |CALLX0 | + | |CALLX0 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE FD ss | |CE FD ss | ||
− | |CALLX1 | + | |CALLX1 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE FE ss | |CE FE ss | ||
− | |CALLX2 | + | |CALLX2 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|- | |- | ||
|CE FF ss | |CE FF ss | ||
− | |CALLX3 | + | |CALLX3 #ss |
− | |||
|24 | |24 | ||
|12 | |12 | ||
+ | |?? | ||
|} | |} | ||
+ | |||
+ | '''*1''': CALL, CALLC, CALLNC, CALLZ and CALLNZ can be used in the assembler to auto-detect the appropriate range. | ||
=== Execute === | === Execute === | ||
Line 184: | Line 186: | ||
U/V = Register U or V | U/V = Register U or V | ||
SP = Register SP (Stack Pointer) | SP = Register SP (Stack Pointer) | ||
+ | PC = Register PC (Program Counter) | ||
[#nnnn] = Memory: (I shl 16) or #nnnn | [#nnnn] = Memory: (I shl 16) or #nnnn | ||
− | ; CALL* #ss | + | ; CALL*B #ss |
IF (Condition) THEN | IF (Condition) THEN | ||
Line 197: | Line 200: | ||
ENDIF | ENDIF | ||
− | ; CALL* #ssss | + | ; CALL*W #ssss |
IF (Condition) THEN | IF (Condition) THEN | ||
Line 208: | Line 211: | ||
ENDIF | ENDIF | ||
− | ; | + | ; CALLB #ss |
SP = SP - 3 | SP = SP - 3 | ||
Line 217: | Line 220: | ||
PC = PC + #ss - 1 | PC = PC + #ss - 1 | ||
− | ; | + | ; CALLW #ssss |
SP = SP - 3 | SP = SP - 3 | ||
Line 247: | Line 250: | ||
=== Description === | === Description === | ||
− | Call a subroutine ( | + | Call a subroutine (CALL*) or a interrupt vector (CINT). |
Use [[PM_Opc_RET|RET]] to return from a subroutine and [[PM_Opc_RET|RETI]] from a interrupt. | Use [[PM_Opc_RET|RET]] to return from a subroutine and [[PM_Opc_RET|RETI]] from a interrupt. | ||
− | NOTE: All non-branch instructions does "U = V" causing U to be restored, any branch that require banking needs "MOV U, A" or "MOV U, #nn" before | + | NOTE: All non-branch instructions does "U = V" causing U to be restored, any branch that require banking needs "MOV U, A" or "MOV U, #nn" before CALL... |
=== Conditions === | === Conditions === | ||
Line 261: | Line 264: | ||
; A = 0x10 | ; A = 0x10 | ||
; B = 0x10 | ; B = 0x10 | ||
− | CALL somefunction | + | '''CALL somefunction''' |
; A = 0x11 | ; A = 0x11 | ||
; B = 0x0F | ; B = 0x0F | ||
[[PM_Opc_TST|TST B, #0x10]] | [[PM_Opc_TST|TST B, #0x10]] | ||
; F = (Zero=0):(Sign=0) | ; F = (Zero=0):(Sign=0) | ||
− | CALLZ somefunction ; Condition fail, call not taken | + | '''CALLZ somefunction''' ; Condition fail, call not taken |
; A = 0x11 | ; A = 0x11 | ||
; B = 0x0F | ; B = 0x0F | ||
; F = (Zero=0):(Sign=0) | ; F = (Zero=0):(Sign=0) | ||
− | + | '''CALLNS somefunction''' ; Condition succeed | |
; A = 0x12 | ; A = 0x12 | ||
; B = 0x0E | ; B = 0x0E | ||
Line 277: | Line 280: | ||
somefunction: | somefunction: | ||
− | [[ | + | [[PM_Opc_INC|INC A]] |
− | [[ | + | [[PM_Opc_DEC|DEC B]] |
[[PM_Opc_RET|RET]] ; Return from the call | [[PM_Opc_RET|RET]] ; Return from the call | ||
; Calling a subroutine at different bank | ; Calling a subroutine at different bank | ||
[[PM_Opc_MOV8|MOV U, $0F]] | [[PM_Opc_MOV8|MOV U, $0F]] | ||
− | CALL function_at_bank_16 | + | '''CALL function_at_bank_16''' |
[[PM_InstructionList|'''« Back to Instruction set''']] | [[PM_InstructionList|'''« Back to Instruction set''']] |
Latest revision as of 13:51, 17 October 2010
CALL = Call routine
Hex | Mnemonic | Cycles,True | or False | Condition |
---|---|---|---|---|
E0 ss | CALLCB #ss*1 | 20 | 8 | Carry=1 |
E1 ss | CALLNCB #ss*1 | 20 | 8 | Carry=0 |
E2 ss | CALLZB #ss*1 | 20 | 8 | Zero=1 |
E3 ss | CALLNZB #ss*1 | 20 | 8 | Zero=0 |
E8 ss ss | CALLCW #ssss*1 | 24 | 12 | Carry=1 |
E9 ss ss | CALLNCW #ssss*1 | 24 | 12 | Carry=0 |
EA ss ss | CALLZW #ssss*1 | 24 | 12 | Zero=1 |
EB ss ss | CALLNZW #ssss*1 | 24 | 12 | Zero=0 |
F0 ss | CALLB #ss*1 | 20 | None | None |
F2 ss ss | CALLW #ssss*1 | 24 | None | None |
FB nn nn | CALL [#nnnn] | 20 | None | None |
FC nn | CINT #nn | 20 | None | None |
CE F0 ss | CALLL #ss | 24 | 12 | (Overflow=1) != (Sign=1) |
CE F1 ss | CALLLE #ss | 24 | 12 | ((Overflow=0) != (Sign=0)) OR (Zero=1) |
CE F2 ss | CALLG #ss | 24 | 12 | ((Overflow=1) == (Sign=1)) AND (Zero=0) |
CE F3 ss | CALLGE #ss | 24 | 12 | (Overflow=0) == (Sign=0) |
CE F4 ss | CALLO #ss | 24 | 12 | Overflow=1 |
CE F5 ss | CALLNO #ss | 24 | 12 | Overflow=0 |
CE F6 ss | CALLNS #ss | 24 | 12 | Sign=0 |
CE F7 ss | CALLS #ss | 24 | 12 | Sign=1 |
CE F8 ss | CALLNX0 #ss | 24 | 12 | ?? |
CE F9 ss | CALLNX1 #ss | 24 | 12 | ?? |
CE FA ss | CALLNX2 #ss | 24 | 12 | ?? |
CE FB ss | CALLNX3 #ss | 24 | 12 | ?? |
CE FC ss | CALLX0 #ss | 24 | 12 | ?? |
CE FD ss | CALLX1 #ss | 24 | 12 | ?? |
CE FE ss | CALLX2 #ss | 24 | 12 | ?? |
CE FF ss | CALLX3 #ss | 24 | 12 | ?? |
*1: CALL, CALLC, CALLNC, CALLZ and CALLNZ can be used in the assembler to auto-detect the appropriate range.
Execute
#nn = Immediate unsigned 8-Bits #ss = Immediate signed 8-Bits #ssss = Immediate signed 16-Bits U/V = Register U or V SP = Register SP (Stack Pointer) PC = Register PC (Program Counter) [#nnnn] = Memory: (I shl 16) or #nnnn
; CALL*B #ss IF (Condition) THEN SP = SP - 3 Memory[SP+2] = V Memory[SP+1] = PC SHR 8 Memory[SP] = PC AND 0x00FF V = U PC = PC + #ss - 1 ENDIF
; CALL*W #ssss IF (Condition) THEN SP = SP - 3 Memory[SP+2] = V Memory[SP+1] = PC SHR 8 Memory[SP] = PC AND 0x00FF V = U PC = PC + #ssss - 1 ENDIF
; CALLB #ss SP = SP - 3 Memory[SP+2] = V Memory[SP+1] = PC SHR 8 Memory[SP] = PC AND 0x00FF V = U PC = PC + #ss - 1
; CALLW #ssss SP = SP - 3 Memory[SP+2] = V Memory[SP+1] = PC SHR 8 Memory[SP] = PC AND 0x00FF V = U PC = PC + #ssss - 1
; CALL [#nnnn] SP = SP - 3 Memory[SP+2] = V Memory[SP+1] = PC SHR 8 Memory[SP] = PC AND 0x00FF V = U PC = Memory16[(I SHL 16) + #nnnn]
; CINT #nn (not fully tested) SP = SP - 4 Memory[SP+3] = V Memory[SP+2] = PC SHR 8 Memory[SP+1] = PC AND 0x00FF Memory[SP] = F V = U PC = Memory16[#nn SHL 1]
Description
Call a subroutine (CALL*) or a interrupt vector (CINT).
Use RET to return from a subroutine and RETI from a interrupt.
NOTE: All non-branch instructions does "U = V" causing U to be restored, any branch that require banking needs "MOV U, A" or "MOV U, #nn" before CALL...
Conditions
None
Examples
; A = 0x10 ; B = 0x10 CALL somefunction ; A = 0x11 ; B = 0x0F TST B, #0x10 ; F = (Zero=0):(Sign=0) CALLZ somefunction ; Condition fail, call not taken ; A = 0x11 ; B = 0x0F ; F = (Zero=0):(Sign=0) CALLNS somefunction ; Condition succeed ; A = 0x12 ; B = 0x0E (...) somefunction: INC A DEC B RET ; Return from the call
; Calling a subroutine at different bank MOV U, $0F CALL function_at_bank_16