; Silly buggery because we want to export fp, sp and pc !
a1	RN 0
a2	RN 1
a3	RN 2
a4	RN 3
ip	RN 12
lr	RN 14
pc	RN 15

        AREA |C$$code|, CODE, READONLY

        IMPORT	load_variable
        EXPORT  load_operand
load_operand
        LDR     a2,P_pc_R       ; a2=&pc
        LDR     a4,[a2]         ; a4=pc
	TEQS	a1,#0
	BEQ	read_code_word  ; if (type==0)...

	TEQS	a1,#2
        LDRB    a1,[a4],#1      ; a1 = next byte
        STR     a4,[a2]         ; write back pc
	MOVNES	pc,lr           ; if type != 2, return that byte

        TEQS    a1,#0           ; if byte!=0, get that var and return it
        BNE     load_variable

        LDR     a2,P_sp         ; var 0 => pop stack
        LDR     a3,[a2]
        LDR     a1,[a3],#4
        STR     a3,[a2]
	MOVS	pc,lr

P_pc_R
        IMPORT  pc_R
        DCD     pc_R
P_sp
        IMPORT  sp
        DCD     sp

; Type = 0: a two-byte literal.
read_code_word
	LDRB	a1,[a4],#1     ; get next two bytes
	LDRB	a3,[a4],#1
        STR     a4,[a2]        ; write back pc
        ORR     a1,a3,a1,LSL #8
	MOVS	pc,lr

	IMPORT	z_store
        EXPORT  store_operand
store_operand
        MOV     ip,a1,LSL #16
        LDR     a2,P_pc_R
        LDR     a4,[a2]
        LDRB    a1,[a4],#1
        TEQS    a1,#0
        STR     a4,[a2]
        MOVNE   a2,ip,LSR #16
        BNE     z_store
        LDR     a2,P_sp
        LDR     a3,[a2]
        MOV     a1,ip,LSR #16
	STR	a1,[a3,#-4]!
        STR     a3,[a2]
        MOVS    pc,lr

	EXPORT	z_push
z_push
	MOV	a3,a1,LSL #16
	MOV	a3,a3,LSR #16
	LDR	a1,P_sp
	LDR	a2,[a1]
	STR	a3,[a2,#-4]!
	STR	a2,[a1]
	MOVS	pc,lr

        END
