Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

;
;Code for accessing variables
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Parse a VAR: instruction into arg1,arg2,arg3,arg4
;
v_arg1: defw    0,0
v_arg2: defw    0,0
v_arg3: defw    0,0
v_arg4: defw    0,0
v_arg5: defw    0,0
v_arg6: defw    0,0
v_arg7: defw    0,0
v_arg8: defw    0,0
v_argc: defb    0
;
g_addr: defw    0       ;Address of global variables
r_offs: defw    0       ;Offset to routines (v6/7)
s_offs: defw    0       ;Offset to strings (v6/7)
;
zapargs:
        push    af      ;SET v_arg1 upto v_argc (inclusive) to zero
        push    bc
        push    de
        push    hl
        ld      hl,v_arg1
        ld      d,h
        ld      e,l
        inc     de
        ld      bc,v_argc-v_arg1
        xor     a
        ld      (hl),b
        ldir
        jp      popd
;
parse_v2:               ;Parse arguments for 8-arg functions. B holds 1st type
                        ;byte, C holds second
        ld      a,b
        push    bc
        call    parse_var
        pop     bc
        ld      a,c
        ld      b,4             ;DE is still set correctly from
        ld      ix,v_arg5       ;last time round the loop
        jr      parlp
;
parse_var:
;
;A = arg type byte
;
        ld      b,4
        ld      e,b
        ld      ix,v_arg1
        push    af
        xor     a
        ld      d,a
        call    zapargs
        ld      (v_argc),a
        pop     af
parlp:  rlca
        rlca
        push    af
        push    de
        push    bc
        and     3
        ld      l,a
        push    hl
        call    parse_type
        pop     hl
        pop     bc
        pop     de
        ld      a,l
        cp      3
        jr      z,endpar
        ld      a,(v_argc)
        inc     a
        ld      (v_argc),a
        pop     af
        add     ix,de
        djnz    parlp
        scf
        ret
;
endpar: pop     af
        scf
        ret
;
parse_type:
        ld      l,a
        ld      h,0     ;HL = 0-3
        add     hl,hl   ;*2
        ld      de,parse_tbl
        add     hl,de
        ld      e,(hl)
        inc     hl
        ld      d,(hl)
        ex      de,hl
        jp      (hl)
;
parse_tbl:
        defw    p_word
        defw    p_byte
        defw    p_var
        defw    p_none
;
;Get byte / word / variable arguments from an instruction.
;
p_none: ret
;
p_byte: push    af
        call    zpcipeek
        ld      (ix+0),a
        ld      (ix+1),0
        pop     af
        ret
;
p_word: push    af
        call    zpcipeek        ;Switch to little-endian
        ld      (ix+1),a
        call    zpcipeek
        ld      (ix+0),a
        pop     af
        ret
;
p_var:  push    af
        call    zpcipeek
        call    get_var
        ld      (ix+0),l
        ld      (ix+1),h
        pop     af
        ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Parse a 2OP instruction.
;
parse_2op:
        ld      ix,v_arg1
        ld      a,(inst)        ;Argument type is part of the instruction
        bit     6,a             ;Type of 1st argument
        call    nz,p_var
        call    z,p_byte
        ld      ix,v_arg2
        bit     5,a
        call    nz,p_var
        call    z,p_byte
        scf
        ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Parse a 1OP instruction.
;
parse_1op:
        ld      ix,v_arg1
        ld      a,(inst)
        cp      0A0h
        call    nc,p_var
        ccf
        ret     c
        cp      90h
        call    nc,p_byte
        ccf
        ret     c
        call    p_word
        scf
        ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Return a value in HL
;
ret_hl:
        call    zpcipeek
        ret     nc
put_var:
        cp      10h             ;Write value in HL to
        jr      nc,put_glb      ;variable number A
        or      a
        jp      nz,put_lcl
zpush:  push    ix
        ld      ix,(rsp)
        dec     ix
        ld      (ix+0),h
        dec     ix
        ld      (ix+0),l
        ld      (rsp),ix
        pop     ix
        scf
        ret
;
put_glb:
        ex      de,hl   ;DE = value to store
        sub     10h
        ld      h,0
        ld      l,a     ;Var no.
        ld      bc,(g_addr)
        add     hl,hl
        add     hl,bc   ;Z-address
        ld      a,d
        call    ZXPOKE  ;IN big-endian format
        call    ZXPK64
        cp      d
        jr      nz,put_g1
        inc     hl
        ld      a,e
        ld      d,a
        call    ZXPOKE
        call    ZXPK64
        cp      d
        scf
        ret     z
put_g1: call    ilprint
        defb    13,10,'Memory write has failed! HL=$'
        call    hexhl
        ld      e,d
        ld      d,0
        call    ilprint
        defb    ' Expected $'
        call    hexde
        call    ilprint
        defb    ' Got $'
        call    hexa
        call    ilprint
        defb    13,10,'$'
        ld      c,1
        call    ZXFDOS
        xor     a
        ld      hl,memerr
        ret
;
put_lcl:
        ex      de,hl   ;DE=value
        ld      hl,(zsp)
        ld      bc,4
        add     hl,bc   ;Start of local vars area
        dec     a
        ld      c,a
        ld      b,0
        add     hl,bc
        add     hl,bc
        ld      (hl),e
        inc     hl
        ld      (hl),d
        scf
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Get the contents of a variable
;
get_var:
        cp      10h
        jr      nc,get_glb
        or      a
        jr      nz,get_lcl
zpop:   push    ix              ;POP the Z-stack
        ld      ix,(rsp)
        ld      l,(ix+0)
        inc     ix
        ld      h,(ix+0)
        inc     ix
        ld      (rsp),ix
        pop     ix
        ret
;
get_glb:
        sub     10h
        ld      h,0
        ld      l,a     ;Var no.
        ld      de,(g_addr)
        add     hl,hl
        add     hl,de   ;Z-address
        ld      e,0
        call    ZXPKWD
        ld      h,b
        ld      l,c
        ret
;
get_lcl:                ;Get a local variable
        ld      hl,(zsp)
        ld      bc,4
        add     hl,bc   ;Start of local vars area
        dec     a
        ld      e,a
        ld      d,0
        add     hl,de
        add     hl,de
        ld      a,(hl)
        inc     hl
        ld      h,(hl)
        ld      l,a
        ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Unpack a packed Z-address (HL -> EHL)
;
upack_table:
        defw    upack0
        defw    upack1, upack2, upack3, upack4
        defw    upack5, upack6, upack7, upack8

upack_addr:
        jp      0
;
upack1:
upack2:
upack3: push    bc
        ld      b,1
        jr      upack_g
;
upack4:
upack5: push    bc
        ld      b,2
        jr      upack_g
;
upack8: push    bc
        ld      b,3
upack_g:
        ld      e,0
upack_l:
        sla     l
        rl      h
        rl      e
        djnz    upack_l
        pop     bc
        ret
;
upack0:
upack6:
upack7: ld      de,ch_
        ld      c,9
        call    ZXFDOS
        ld      c,1
        call    ZXFDOS
        rst     0       ;Must never happen :-)
;
ch_:    defb    'You should never see this message!'
        defb    13,10,36