;****************************************************************************
; CxOpcodeGroup
; Handles the stream opcodes within $C0..$CF
;----------------------------------------------------------------------------
; input b ..... opcode
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; continues in the respective handler, then ProcessStreamLoop
;----------------------------------------------------------------------------
; notes: this is located here and not in `stream_process.z80` because all the
; subroutines are close and putting it here lets us use JR instead of JP for
; the jump table (saving some RAM)
;****************************************************************************
CxOpcodeGroup:
PollPcm
ld a, b
and $0F
add a, a
ld (CxOpcodeJump), a
CxOpcodeJump: equ $+1
jr $
jr MoveImmToVar ; SONAOP_VMMOVE_IMM
jr MoveVarToVar ; SONAOP_VMMOVE_VAR
jr AddImmToVar ; SONAOP_VMADD_IMM
jr AddVarToVar ; SONAOP_VMADD_VAR
jr SubImmFromVar ; SONAOP_VMSUB_IMM
jr SubVarFromVar ; SONAOP_VMSUB_VAR
jr AndImmWithVar ; SONAOP_VMAND_IMM
jr AndVarWithVar ; SONAOP_VMAND_VAR
jr OrImmWithVar ; SONAOP_VMOR_IMM
jr OrVarWithVar ; SONAOP_VMOR_VAR
jr XorImmWithVar ; SONAOP_VMXOR_IMM
jr XorVarWithVar ; SONAOP_VMXOR_VAR
jr NegVar ; SONAOP_VMNEG
jr NotVar ; SONAOP_VMNOT
jr IncrVar ; SONAOP_VMINC
jr DecrVar ; SONAOP_VMDEC
;****************************************************************************
; MoveImmToVar [SONAOP_VMMOVE_IMM]
; MoveVarToVar [SONAOP_VMMOVE_VAR]
;
; Copies an immediate value or variable into (another) variable.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
MoveImmToVar:
call FetchImmAndVar ; Fetch the arguments
jr MoveToVar ; Go do the copy
MoveVarToVar:
call FetchVarAndVar ; Fetch the arguments
; fallthrough to MoveToVar... ; Go do the copy
;----------------------------------------------------------------------------
MoveToVar:
ld a, b
ld (de), a
ret
;****************************************************************************
; AddImmToVar [SONAOP_VMADD_IMM]
; AddVarToVar [SONAOP_VMADD_VAR]
;
; Adds an immediate value or variable to (another) variable.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
AddImmToVar:
call FetchImmAndVar ; Fetch the arguments
jr AddToVar ; Go do the addition
AddVarToVar:
call FetchVarAndVar ; Fetch the arguments
; fallthrough to AddToVar... ; Go do the addition
;----------------------------------------------------------------------------
AddToVar:
ld a, (de)
add a, b
ld (de), a
ret
;****************************************************************************
; SubImmFromVar [SONAOP_VMADD_IMM]
; SubVarFromVar [SONAOP_VMADD_VAR]
;
; Substract an immediate value or variable from (another) variable.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
SubImmFromVar:
call FetchImmAndVar ; Fetch the arguments
jr SubFromVar ; Go do the substraction
SubVarFromVar:
call FetchVarAndVar ; Fetch the arguments
; fallthrough to SubFromVar... ; Go do the substraction
;----------------------------------------------------------------------------
SubFromVar:
ld a, (de)
sub b
ld (de), a
ret
;****************************************************************************
; AndImmWithVar [SONAOP_VMAND_IMM]
; AndVarWithVar [SONAOP_VMAND_VAR]
;
; Does a binary AND between an immediate value or variable from (another)
; variable, storing the result in the latter.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
AndImmWithVar:
call FetchImmAndVar ; Fetch the arguments
jr AndWithVar ; Go do the AND operation
AndVarWithVar:
call FetchVarAndVar ; Fetch the arguments
; fallthrough to AndWithVar... ; Go do the AND operation
;----------------------------------------------------------------------------
AndWithVar:
ld a, (de)
and b
ld (de), a
ret
;****************************************************************************
; OrImmWithVar [SONAOP_VMOR_IMM]
; OrVarWithVar [SONAOP_VMOR_VAR]
;
; Does a binary OR between an immediate value or variable from (another)
; variable, storing the result in the latter.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
OrImmWithVar:
call FetchImmAndVar ; Fetch the arguments
jr OrWithVar ; Go do the OR operation
OrVarWithVar:
call FetchVarAndVar ; Fetch the arguments
; fallthrough to OrWithVar... ; Go do the OR operation
;----------------------------------------------------------------------------
OrWithVar:
ld a, (de)
or b
ld (de), a
ret
;****************************************************************************
; XorImmWithVar [SONAOP_VMXOR_IMM]
; XorVarWithVar [SONAOP_VMXOR_VAR]
;
; Does a binary XOR between an immediate value or variable from (another)
; variable, storing the result in the latter.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
XorImmWithVar:
call FetchImmAndVar ; Fetch the arguments
jr XorWithVar ; Go do the XOR operation
XorVarWithVar:
call FetchVarAndVar ; Fetch the arguments
; fallthrough to XorWithVar... ; Go do the XOR operation
;----------------------------------------------------------------------------
XorWithVar:
ld a, (de)
xor b
ld (de), a
ret
;****************************************************************************
; NegVar [SONAOP_VMNEG]
; Flips the sign of a VM variable (two's complement).
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
NegVar:
ReadArgByte ; Fetch variable
ld e, a ; Compute pointer to variable
ld d, VmVarList>>8
ld a, (de) ; Retrieve value and write it back
neg ; with the sign flipped
ld (de), a
ret ; End of subroutine
;****************************************************************************
; IncrVar [SONAOP_VMINC]
; Increments the value of a VM variable by 1.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
IncrVar:
ReadArgByte ; Fetch variable
ld e, a ; Compute pointer to variable
ld d, VmVarList>>8
ex de, hl ; Increment the variable by 1
inc (hl)
ex de, hl
ret ; End of subroutine
;****************************************************************************
; DecrVar [SONAOP_VMDEC]
; Decrements the value of a VM variable by 1.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
DecrVar:
ReadArgByte ; Fetch variable
ld e, a ; Compute pointer to variable
ld d, VmVarList>>8
ex de, hl ; Decrement the variable by 1
dec (hl)
ex de, hl
ret ; End of subroutine
;****************************************************************************
; NotVar [SONAOP_VMNOT]
; Does a binary NOT on a VM variable.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
NotVar:
ReadArgByte ; Fetch variable
ld e, a ; Compute pointer to variable
ld d, VmVarList>>8
ld a, (de) ; Retrieve value and write it back
cpl ; with the bits flipped
ld (de), a
ret ; End of subroutine
;****************************************************************************
; FetchImmAndVar
;
; Fetches the operands for a VM opcode that takes an immediate source and
; a variable as destination.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output b .... value of source
; output de ... pointer to destination
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
FetchImmAndVar:
ReadArgByte ; Fetch destination variable
ld e, b ; Compute pointer to its value so
ld d, VmVarList>>8 ; it can be used by the caller
ReadArgByte ; Fetch source value
ret ; End of subroutine
;****************************************************************************
; FetchVarAndVar
;
; Fetches the operands for a VM opcode that takes a variable as source and
; another variable as destination.
;----------------------------------------------------------------------------
; input c ..... current stream bank
; input hl .... current stream address
;----------------------------------------------------------------------------
; output b .... value of source
; output de ... pointer to destination
; output c .... new stream bank
; output hl ... new stream address
;----------------------------------------------------------------------------
; modifies .... a,b,de,a'
;****************************************************************************
FetchVarAndVar:
ReadArgByte ; Fetch destination variable
ld a, b ; Save it for later
ex af, af'
ReadArgByte ; Fetch source variable
ld e, b ; Get its value
ld d, VmVarList>>8
ld a, (de)
ld b, a
ex af, af' ; Compute pointer to the destination
ld e, a ; variable's value so it can be used
ld d, VmVarList>>8 ; by the caller
PollPcm
ret ; End of subroutine