; generated by Norcroft RISC OS ARM C vsn 5.06 (Acorn Computers Ltd) [May 25 1995]

; Silly buggery because we want to export fp, sp and pc !
a1      RN 0
a2      RN 1
a3      RN 2
a4      RN 3
v1      RN 4
v2      RN 5
v3      RN 6
v4      RN 7
v5      RN 8
v6      RN 9
sl      RN 10
FP      RN 11
ip      RN 12
SP      RN 13
lr      RN 14
pc      RN 15

	GET	hdr.options

        AREA	|Asm$$code|, CODE, READONLY

        IMPORT  gasp
        IMPORT  load_operand
        IMPORT  z_picture_table
        IMPORT  z_log_shift
        IMPORT  z_art_shift
        IMPORT  z_set_font
        IMPORT  z_draw_picture
        IMPORT  z_picture_data
        IMPORT  z_erase_picture
        IMPORT  z_set_margins
        IMPORT  z_save_undo
        IMPORT  z_restore_undo
        IMPORT  z_print_unicode
        IMPORT  z_check_unicode
        IMPORT  z_move_window
        IMPORT  z_window_size
        IMPORT  z_window_style
        IMPORT  z_get_wind_prop
        IMPORT  z_scroll_window
        IMPORT  z_pop_stack
        IMPORT  z_read_mouse
        IMPORT  z_mouse_window
        IMPORT  z_push_stack
        IMPORT  z_put_wind_prop
        IMPORT  z_print_form
        IMPORT  z_make_menu
        IMPORT  z_check_arg_count
        IMPORT  z_je
        IMPORT  z_jl
        IMPORT  z_jg
        IMPORT  z_dec_chk
        IMPORT  z_inc_chk
        IMPORT  z_jin
        IMPORT  z_test
        IMPORT  z_or
        IMPORT  z_and
        IMPORT  z_test_attr
        IMPORT  z_set_attr
        IMPORT  z_clear_attr
        IMPORT  z_store
        IMPORT  z_insert_obj
        IMPORT  z_loadw
        IMPORT  z_loadb
        IMPORT  z_get_prop
        IMPORT  z_get_prop_addr
        IMPORT  z_get_next_prop
        IMPORT  z_add
        IMPORT  z_sub
        IMPORT  z_mul
        IMPORT  z_div
        IMPORT  z_mod
        IMPORT  z_set_colour
        IMPORT  z_throw
        IMPORT  z_storew
        IMPORT  z_storeb
        IMPORT  z_put_prop
        IMPORT  z_read
        IMPORT  z_print_char
        IMPORT  z_print_num
        IMPORT  z_random
        IMPORT  z_push
        IMPORT  z_pull
        IMPORT  z_split_window
        IMPORT  z_set_window
        IMPORT  z_erase_window
        IMPORT  z_erase_line
        IMPORT  z_set_cursor
        IMPORT  z_get_cursor
        IMPORT  z_set_text_style
        IMPORT  z_buffer_mode
        IMPORT  z_output_stream
        IMPORT  z_input_stream
        IMPORT  z_sound_effect
        IMPORT  z_read_char
        IMPORT  z_scan_table
        IMPORT  z_tokenise
        IMPORT  z_encode_text
        IMPORT  z_copy_table
        IMPORT  z_print_table
        IMPORT  z_not
        IMPORT  z_jz
        IMPORT  z_get_sibling
        IMPORT  z_get_child
        IMPORT  z_get_parent
        IMPORT  z_get_prop_len
        IMPORT  z_inc
        IMPORT  z_dec
        IMPORT  z_print_addr
        IMPORT  z_call
        IMPORT  z_remove_obj
        IMPORT  z_print_obj
        IMPORT  z_jump
        IMPORT  z_print_paddr
        IMPORT  z_load
        IMPORT  z_piracy
        IMPORT  z_print
        IMPORT  z_print_ret
        IMPORT  z_save
        IMPORT  z_restore
        IMPORT  z_restart
        IMPORT  z_ret
        IMPORT  z_catch
        IMPORT  z_new_line
        IMPORT  z_show_status
        IMPORT  z_verify
        IMPORT  fatal
        IMPORT  msgs_lookup

        EXPORT  interpret
interpret
        MOV     ip,SP
        STMDB   SP!,{v1-v6,FP,ip,lr,pc}
        SUB     FP,ip,#4
        SUB     SP,SP,#32
        MOV     v3,#0
        MOV     v6,#4096
01
        LDR     v1,P_pc
        SUBS    v6,v6,#1
        MOVEQ   v6,#4096
	BLEQ	gasp
        LDR     a1,[v1]
        MOV     a2,v1
   [ {FALSE}
	LDR	v2,datap_adcon
	LDR	v2,[v2]
	ADD	v2,v2,#&7100
	ADD	v2,v2,#&007A
	TEQ	a1,v2
	BNE	%FT88
	SWI	&107
	B	%FT88
	IMPORT	datap
datap_adcon
	DCD	datap
88
   ]
        LDRB    v2,[a1],#1
   [ ALLOW_OPCOUNT
	LDR	lr,P_opcount
	LDR	ip,[lr,v2,LSL #2]
	ADD	ip,ip,#1
	STR	ip,[lr,v2,LSL #2]
   ]
        TEQS    v2,#&BE
        STR     a1,[v1]
        BNE     %F02
        LDRB    v2,[a1],#1
   [ ALLOW_OPCOUNT
	ADD	lr,lr,#256*4
	LDR	ip,[lr,v2,LSL #2]
	ADD	ip,ip,#1
	STR	ip,[lr,v2,LSL #2]
   ]
        MOV     v3,#1
        STR     a1,[a2]
02
        MOV     v1,#0
        CMPS    v2,#&80
        BLO     multi_op
        CMPS    v2,#&C0
        BHS     multi_op
        TEQS    v3,#0
        BEQ     single_op
; Multiple operand instructions
multi_op
        CMPS    v2,#&80
        BHS     load_vari_op
        TEQS    v3,#0
        BNE     load_vari_op
load_two_op
; Two operand class, load both operands
        TSTS    v2,#&40
        MOVEQ   a1,#1
        MOVNE   a1,#2
        BL      load_operand
        STR     a1,[SP,#0]
        TSTS    v2,#&20
        MOVEQ   a1,#1
        MOVNE   a1,#2
        BL      load_operand
        MOV     v1,#2
        AND     v2,v2,#&1F
        STR     a1,[SP,#4]
        B       do_two_or_mult_op

P_interrupt_finished
        IMPORT  interrupt_finished
        DCD     interrupt_finished
P_pc
	IMPORT	pc_R
        DCD     pc_R
P_sp
	IMPORT	sp
        DCD     sp

    [ ALLOW_OPCOUNT
P_opcount
	DCD	opcount
    ]

; Variable operand class, load operand specifier
load_vari_op
        LDR     a1,[a2]
        AND     v2,v2,#&3F
        TEQS    v2,#&2C
        TEQNES  v2,#&3A
; Extended CALL instruction
	LDREQB	v4,[a1],#1
	LDRB	v5,[a1],#1
        STR     a1,[a2]
        ORREQ   v5,v5,v4,LSL #8
	MOVNE	v4,#6
        MOVEQ   v4,#14
07
        MOV     a1,v5,LSR v4
        AND     a1,a1,#3
        TEQS    a1,#3
        BEQ     %F10
        BL      load_operand
        STR     a1,[SP,v1,LSL #2]
	ADD	v1,v1,#1
        SUBS    v4,v4,#2
        BPL     %B07
10
        TEQS    v3,#0
        BEQ     do_two_or_mult_op
; Reset "extended" flag
        MOV     v3,#0
        MOV     a1,v1 ; Required to fit all cases into 2 instructions (!)
        ADRL    lr,%98  ; Another instruction wasted, but these are rare opcodes
        CMPS    v2,#&1C
        ADDLS   pc,pc,v2,LSL #3
; Case > &1c: spec says to ignore
        B       %98
; Case 0: save
        MOV     a2,SP
        B       z_save
; Case 1: restore
        MOV     a2,SP
        B       z_restore
; Case 2: log_shift
        LDMIA   SP,{a1,a2}
        B       z_log_shift
; Case 3: art_shift
        LDMIA   SP,{a1,a2}
        B       z_art_shift
; Case 4: set_font
        LDR     a1,[SP,#0]
        B       z_set_font
; Case 5: draw_picture
        MOV     a2,SP
        B       z_draw_picture
; Case 6: picture_data
        LDMIA   SP,{a1,a2}
        B       z_picture_data
; Case 7: erase_picture
        MOV     a2,SP
        B       z_erase_picture
; Case 8: set_margins
        MOV     a2,SP
        B       z_set_margins
; Case 9: save_undo
        B       z_save_undo
        NOP
; Case a: restore_undo
        B       z_restore_undo
        NOP
; Case b: print_unicode
        LDR     a1,[SP,#0]
        B       z_print_unicode
; Case c: check_unicode
        LDR     a1,[SP,#0]
        B       z_check_unicode
; Case d
        B       call_fatal
        NOP
; Case e
        B       call_fatal
        NOP
; Case f
        B       call_fatal
        NOP
; Case 10: move_window
        LDMIA   SP,{a1-a3}
        B       z_move_window
; Case 11: window_size
        LDMIA   SP,{a1-a3}
        B       z_window_size
; Case 12: window_style
        MOV     a2,SP
        B       z_window_style
; Case 13: get_wind_prop
        LDMIA   SP,{a1,a2}
        B       z_get_wind_prop
; Case 14: scroll_window
        LDMIA   SP,{a1,a2}
        B       z_scroll_window
; Case 15: pop_stack
        MOV     a2,SP
        B       z_pop_stack
; Case 16: read_mouse
        LDR     a1,[SP,#0]
        B       z_read_mouse
; Case 17: mouse_window
        LDR     a1,[SP,#0]
        B       z_mouse_window
; Case 18: push_stack
        MOV     a2,SP
        B       z_push_stack
; Case 19: put_wind_prop
        LDMIA   SP,{a1-a3}
        B       z_put_wind_prop
; Case 1a: print_form
        LDR     a1,[SP,#0]
        B       z_print_form
; Case 1b: make_menu
        LDMIA   SP,{a1-a2}
        B       z_make_menu
; Case 1c: picture_table
        LDR     a1,[SP,#0]
        B       z_picture_table

do_two_or_mult_op
        ADR     lr,%98
        MOV     a1,v1 ; Required to fit all cases into 2 instructions (!)
        ADD     pc,pc,v2,LSL #3
        NOP
; Case 0
        B       call_fatal
        NOP
; Case 1
        MOV     a2,SP
        B       z_je
; Case 2
        LDMIA   SP,{a1,a2}
        B       z_jl
; Case 3
        LDMIA   SP,{a1,a2}
        B       z_jg
; Case 4
        LDMIA   SP,{a1,a2}
        B       z_dec_chk
; Case 5
        LDMIA   SP,{a1,a2}
        B       z_inc_chk
; Case 6
        LDMIA   SP,{a1,a2}
        B       z_jin
; Case 7
        LDMIA   SP,{a1,a2}
        B       z_test
; Case 8
        LDMIA   SP,{a1,a2}
        B       z_or
; Case 9
        LDMIA   SP,{a1,a2}
        B       z_and
; Case a
        LDMIA   SP,{a1,a2}
        B       z_test_attr
; Case b
        LDMIA   SP,{a1,a2}
        B       z_set_attr
; Case c
        LDMIA   SP,{a1,a2}
        B       z_clear_attr
; Case d
        LDMIA   SP,{a1,a2}
        B       z_store
; Case e
        LDMIA   SP,{a1,a2}
        B       z_insert_obj
; Case f
        LDMIA   SP,{a1,a2}
        B       z_loadw
; Case 10
        LDMIA   SP,{a1,a2}
        B       z_loadb
; Case 11
        LDMIA   SP,{a1,a2}
        B       z_get_prop
; Case 12
        LDMIA   SP,{a1,a2}
        B       z_get_prop_addr
; Case 13
        LDMIA   SP,{a1,a2}
        B       z_get_next_prop
; Case 14
        LDMIA   SP,{a1,a2}
        B       z_add
; Case 15
        LDMIA   SP,{a1,a2}
        B       z_sub
; Case 16
        LDMIA   SP,{a1,a2}
        B       z_mul
; Case 17
        LDMIA   SP,{a1,a2}
        B       z_div
; Case 18
        LDMIA   SP,{a1,a2}
        B       z_mod
; Case 19
        MOV     a3,#0
        B       do_call_1b
; Case 1a
        MOV     a3,#&100
        B       do_call_1b
; Case 1b
        MOV     a2,SP
        B       z_set_colour
; Case 1c
        LDMIA   SP,{a1,a2}
        B       z_throw
; Case 1d
        B       call_fatal
        NOP
; Case 1e
        B       call_fatal
        NOP
; Case 1f
        B       call_fatal
        NOP
; Case 20
        MOV     a3,#0
        B       do_call_1b
; Case 21
        LDMIA   SP,{a1-a3}
        B       z_storew
; Case 22
        LDMIA   SP,{a1-a3}
        B       z_storeb
; Case 23
        LDMIA   SP,{a1-a3}
        B       z_put_prop
; Case 24
        MOV     a2,SP
        B       z_read
; Case 25
        LDR     a1,[SP]
        B       z_print_char
; Case 26
        LDR     a1,[SP]
        B       z_print_num
; Case 27
        LDR     a1,[SP]
        B       z_random
; Case 28
        LDR     a1,[SP]
        B       z_push
; Case 29
        MOV     a2,SP
        B       z_pull
; Case 2a
        LDR     a1,[SP]
        B       z_split_window
; Case 2b
        LDR     a1,[SP]
        B       z_set_window
; Case 2c
        MOV     a3,#0
        B       do_call_1b
; Case 2d
        LDR     a1,[SP]
        B       z_erase_window
; Case 2e
        LDR     a1,[SP]
        B       z_erase_line
; Case 2f
        MOV     a2,SP
        B       z_set_cursor
; Case 30
        LDR     a1,[SP]
        B       z_get_cursor
; Case 31
        LDR     a1,[SP]
        B       z_set_text_style
; Case 32
        LDR     a1,[SP]
        B       z_buffer_mode
; Case 33
        LDMIA   SP,{a2-a4}
        B       z_output_stream
; Case 34
        LDR     a1,[SP]
        B       z_input_stream
; Case 35
        MOV     a2,SP
        B       z_sound_effect
; Case 36
        MOV     a2,SP
        B       z_read_char
; Case 37
        MOV     a2,SP
        B       z_scan_table
; Case 38
        LDR     a1,[SP]
        B       z_not
; Case 39
        MOV     a3,#&100
        B       do_call_1b
; Case 3a
        MOV     a3,#&100
        B       do_call_1b
; Case 3b
        MOV     a2,SP
        B       z_tokenise
; Case 3c
        LDMIA   SP,{a1-a4}
        B       z_encode_text
; Case 3d
        LDMIA   SP,{a1-a3}
        B       z_copy_table
; Case 3e
        MOV     a2,SP
        B       z_print_table
; Case 3f
        LDR     a1,[SP,#0]
        B       z_check_arg_count

single_op
        CMP     v2,#&B0
        BHS     zero_op
        MOV     a1,#3
        AND     a1,a1,v2,LSR #4
        BL      load_operand
        AND     a2,v2,#&F
        ADR     lr,%98
        ADD     pc,pc,a2,LSL #2
        NOP
; Case 0: jz
        B       z_jz
; Case 1: get_sibling
        B       z_get_sibling
; Case 2: get_child
        B       z_get_child
; Case 3: get_parent
        B       z_get_parent
; Case 4: get_prop_len
        B       z_get_prop_len
; Case 5: inc
        B       z_inc
; Case 6: dec
        B       z_dec
; Case 7: print_addr
        B       z_print_addr
; Case 8: call
        B       do_call_1
; Case 9: remove_obj
        B       z_remove_obj
; Case a: print_obj
        B       z_print_obj
; Case b: ret
        B       z_ret
; Case c: jump
        B       z_jump
; Case d: print_paddr
        B       z_print_paddr
; Case e: load
        B       z_load
; Case f: call or not
        LDR     a2,P_htype
        LDRB    a2,[a2]
        CMPS    a2,#4
        BLE     z_not
        MOV     a3,#&100
        STR     a1,[SP]
        MOV     a1,#1
do_call_1b
        MOV     a2,SP
        B       z_call

do_call_1
        MOV     a3,#0
        MOV     a2,SP
        STR     a1,[SP]
        MOV     a1,#1
        B       z_call

P_htype
        IMPORT  h_type
        DCD     h_type
zero_op
        AND     a1,v2,#&f
        ADR     lr,%98
        ADD     pc,pc,a1,LSL #2
        B       call_fatal
; Case 0
        B       ret_true
; Case 1
        B       ret_false
; Case 2
        B       z_print
; Case 3
        B       z_print_ret
; Case 4
        MOVS    pc,lr ; (!)
; Case 5
        B       do_save
; Case 6
        B       do_restore
; Case 7
        B       z_restart
; Case 8
        B       do_ret_popped
; Case 9
        B       z_catch
; Case a
        LDMDB   FP,{v1-v6,FP,SP,pc}^
; Case b
        B       z_new_line
; Case c
        B       z_show_status
; Case d
        B       z_verify
; Case e
        B       call_fatal
; Case f
        B       z_piracy

ret_true
        MOV     a1,#1
        B       z_ret
ret_false
        MOV     a1,#0
        B       z_ret

do_save
        MOV     a2,#0
        MOV     a1,#0
        B       z_save
do_restore
        MOV     a2,#0
        MOV     a1,#0
        B       z_restore

do_ret_popped
	LDR	a2,P_sp
        LDR     a3,[a2]
        LDR     a1,[a3],#4
        STR     a3,[a2]
        B       z_ret

Illegal_Operation
        = "IllOp", 0
        ALIGN

call_fatal
        ADR     a1,Illegal_Operation
        BL      msgs_lookup
        B       fatal

98
        LDR     a1,P_interrupt_finished
        LDR     a1,[a1]
        TEQS    a1,#0
        BEQ     %B01
        LDMDB   FP,{v1-v6,FP,SP,pc}^

        AREA |Asm$$data|,DATA

|x$dataseg|

    [ ALLOW_OPCOUNT

        AREA	|Asm$$zidata|,DATA,NOINIT

	EXPORT	opcount
opcount
	%	512*4

    ]

        END
