Login

Subversion Repositories NedoOS

Rev

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;A lot of the code in this file has been hand-crafted from the
;C routines in JZIP 2.0.1g
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
obj_addr:
        defw    0       ;Object table address
objlen: defw    0       ;Length of 1 object
ptlen:  defw    0       ;Length of default property table

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Get address of object DE into HL.
;
objadd: push    de      ;get_object_address()
        push    bc
        push    af
        ld      a,d     ;<< v1.01 Check for Vile 0 Error. It should have been
        or      e       ;        caught earlier but this is the last defence.
        call    z,v0efh ;>> v1.01
        ld      hl,(obj_addr)
        ld      bc,(ptlen)      ;Default property table length
        add     hl,bc           ;HL -> start of objects
        push    hl
        ld      bc,(objlen)     ;BC = object length, DE = object number
        dec     de              ;DE was 1 based
        call    umult16         ;DE:= offset to object
        pop     hl
        add     hl,de
        pop     af
        pop     bc
        pop     de
        ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Locate attribute BC in object DE.
;
attradd:
        push    bc
        call    objadd  ;HL:=object address
        pop     bc
        ld      a,c     ;A=attribute number
        rrca
        rrca
        rrca            ;Divide by 8, giving offset in bytes
        and     7       ;Remove the bits which went round to the top
        ld      e,a
        ld      d,0
        add     hl,de
;
;CREATE a bitmask
;
mkmask: ld      a,c
        and     7       ;Attribute number
        ld      b,80h
mkms1:  ret     z
        srl     b
        dec     a
        jr      mkms1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;For HL->object, read/write its parent, child, siblings
;
read_child:
        push    bc
        ld      bc,060Ah        ;B=offset for v1-v3; C=offset for v4-v8
        jr      oread
;
write_child:
        push    bc
        ld      bc,060Ah
        jr      owrite
;
read_sibling:
        push    bc
        ld      bc,0508h
        jr      oread
;
write_sibling:
        push    bc
        ld      bc,0508h
        jr      owrite
;
read_parent:
        push    bc
        ld      bc,0406h
oread:  ld      a,(zver)
        cp      4
        jr      c,oreadb
        ld      b,0
        add     hl,bc
        ld      e,0
        call    ZXPKWI
        ld      d,b
        ld      e,c
        pop     bc
        ret
;
oreadb: ld      c,b
        ld      b,0
        add     hl,bc
        call    peek64
        ld      e,a
        ld      d,0
        pop     bc
        ret
;
write_parent:
        push    bc
        ld      bc,0406h
owrite: ld      a,(zver)
        cp      4
        jr      c,owriteb
        ld      b,0
        add     hl,bc
        ld      a,d
        call    ZXPOKE
        inc     hl
        jr      owritee
;
owriteb:
        ld      c,b
        ld      b,0
        add     hl,bc
owritee:
        ld      a,e
        call    ZXPOKE
        pop     bc
        ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Remove object DE from its container
;
obj_remove:
        push    bc
        push    hl
        push    de
        call    objadd
        ld      a,d             ;<< v1.01 Vile 0 Error?
        or      e
        jp      z,remret        ;>> v1.01

        ld      (objptr),hl
        call    read_parent
        ld      a,d
        or      e
        jp      z,remret        ;Object already removed
        call    objadd
        ld      (objpar),hl     ;HL -> parent
        call    read_child      ;DE = no. of 1st child
        pop     bc
        push    bc              ;BC = no. to remove
        call    cpdebc          ;Are they the same?

        jr      nz,remv1
        ld      hl,(objptr)
        call    read_sibling    ;DE = object's sibling

        ld      hl,(objpar)
        call    write_child
        jr      remv2
;
;DE = number of current child object. BC = number to delete.
;
remv1:  call    objadd          ;HL -> current child
        push    hl              ;<< v0.02 bug fix >>
        call    read_sibling    ;DE = sibling of current child
        pop     hl              ;<< v0.02 bug fix >>

        call    cpdebc          ;Is this object's sibling the one to remove?
        jr      nz,remv1
        push    hl
        ld      hl,(objptr)
        call    read_sibling

        pop     hl
        call    write_sibling
remv2:  ld      hl,(objptr)
        ld      de,0
        push    hl
        call    write_sibling
        pop     hl
        call    write_parent
remret: pop     de
        pop     hl
        pop     bc
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;INSERT object DE in object HL.
;
objptr: defw    0       ;Points to object being removed or inserted
objpar: defw    0       ;Parent of object being removed or inserted
objpno: defw    0       ;Number of new parent object

obj_insert:
        ld      (objpno),hl     ;Number of new parent
        call    obj_remove      ;Remove object DE from where it was

        ld      a,d             ;<< v1.01 Vile 0 Error?
        or      e
        scf
        ret     z               ;>> v1.01

        push    de              ;Sets objptr but not objpar
        ex      de,hl
        call    objadd
        ld      (objpar),hl     ;so set objpar here
;
;Get number of new parent's 1st child, set it to current object's sibling
;
        push    hl
        call    read_child      ;New parent's 1st child
        ld      hl,(objptr)
        push    hl
        call    write_sibling
        pop     hl
;
;Tell the object about its new parent
;
        ld      de,(objpno)
        call    write_parent
        pop     hl
;
;SET new parent's child to new object
;
        pop     de
        jp      write_child
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;<< v0.02
;
;Print data for object DE (debugging code)
;
obtree: push    af
        push    bc
        push    de
        push    hl
        call    ilprint
        defb    'Object $'
        call    hexde

        call    objadd  ;HL -> the object
obtr0:  push    hl

        call    ilprint
        defb    ' @ $'
        call    hexhl

        call    ilprint
        defb    13,10,'Siblings: $'

siblp:  call    read_sibling
        call    hexde
        ld      a,d
        or      e
        jr      z,obtr1
        call    objadd
        call    ilprint
        defb    '[$'
        call    hexhl
        call    ilprint
        defb    '] $'
        jr      siblp

obtr1:  call    ilprint
        defb    13,10,'Children: $'
        pop     hl
        call    read_child
chlp:   call    hexde
        ld      a,d
        or      e
        jr      z,obtr2
        call    objadd
        call    ilprint
        defb    '[$'
        call    hexhl
        call    ilprint
        defb    '] $'
        call    read_sibling
        jr      chlp

obtr2:  call    ilprint
        defb    13,10,'$'
        jp      popd
;
; >> v0.02
; << v1.01
;
v0efh:  nop
        call    ilprint
        defb    'WARNING: This story file has attempted to access object 0.'
        defb    13,10
        defb    'The story file may behave unpredictably, or you may need '
        defb    13,10
        defb    'an updated version of the story file.'
        defb    13,10,'$'

        push    af
        push    de
        ld      a,(zpc+2)
        call    hexa
        ld      de,(zpc)
        call    hexde

        ld      a,0C9h  ;RET - only show the message once.
        ld      (v0efh),a
        pop     de
        pop     af
        ret
;
; >> v1.01
;