; TYP3HDR.Z80, Version 1.1

; This code has been modified as suggested by Charles Irvine so that it will
; function correctly with interrupts enabled.

; This is header code that can be used at the beginning of a type-3-environment
; program so that it will abort with an error message when not loaded to the
; correct address (such as when a user tries to run it under CP/M or Z30).

entry:
       jr      start0          ; Must use relative jump
       defb    0               ; Filler
       db      'Z3ENV',3       ; Type-3 environment
z3env:  dw      0               ; Filled in by Z33
       dw      entry           ; Intended load address

start0:
       ld      hl,0            ; Point to warmboot entry
       ld      a,(hl)          ; Save the byte there
       di                      ; Protect against interrupts
       ld      (hl),0c9h       ; Replace warmboot with a return opcode
       rst     0               ; Call address 0, pushing RETADDR onto stack
retaddr:
       ld      (hl),a          ; Restore byte at 0
       dec     sp              ; Get stack pointer to point
       dec     sp              ; ..to the value of RETADDR
       pop     hl              ; Get it into HL and restore stack
       ei                      ; We can allow interrupts again
       ld      de,retaddr      ; This is where we should be
       xor     a               ; Clear carry flag
       push    hl              ; Save address again
       sbc     hl,de           ; Subtract -- we should have 0 now
       pop     hl              ; Restore value of RETADDR
       jr      z,start         ; If addresses matched, begin real code

       ld      de,notz33msg-retaddr ; Offset to message
       add     hl,de
       ex      de,hl           ; Switch pointer to message into DE
       ld      c,9
       jp      0005h           ; Return via BDOS print string function

notz33msg:
       defb    'Not Z33+$'     ; Abort message if not Z33-compatible

start:
       ret                     ; Replace with real code

       end