;
; Program: ERROR4
; Author: Richard Conn
; Version: 1.0
; Date: 5 Mar 84
;
version equ     10

;
;       This error handler prints the name of the COM file which was not
; found and then advances to the next entry (assuming a multiple command
; line) and resumes with the next command in the line.
;
;       This program is transportable from one ZCPR3 system to another
; provided it is reassembled with the correct address for the ZCPR3
; Environment Descriptor (Z3ENV) or DDT is used to patch this address
; (which is the first two bytes after the opening JMP).  If an external
; ZCPR3 Environment Descriptor is not available, one will have to be
; provided by setting the Z3ENV equate to 0 and providing SYSENV.LIB in
; the current directory at assembly time.
;

;
; Equates for Key Values
;
z3env   SET     0f400h  ;address of ZCPR3 environment
cmtch   equ     ';'     ;comment character
cr      equ     0dh
lf      equ     0ah

;
; External Z3LIB and SYSLIB Routines
;
       ext     z3init
       ext     print,pstr,codend,moveb
       ext     erradr,puter1,puterc            ;Error Handler Routines
       ext     getefcb,getcl1,qerror           ;Z3 Messages et al

;
; Environment Definition
;
       if      z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
       jmp     start
       db      'Z3ENV' ;This is a ZCPR3 Utility
       db      1       ;External Environment Descriptor
z3eadr:
       dw      z3env
start:
       lhld    z3eadr  ;pt to ZCPR3 environment
;
       else
;
; Internal ZCPR3 Environment Descriptor
;
       MACLIB  Z3BASE.LIB
       MACLIB  SYSENV.LIB
z3eadr:
       jmp     start
       SYSENV
start:
       lxi     h,z3eadr        ;pt to ZCPR3 environment
       endif

;
; Start of Program -- Initialize ZCPR3 Environment
;
       call    z3init  ;initialize the ZCPR3 Environment
;
; Determine if Program Invoked as an Error Handler or By the User
;
       call    qerror  ;error?
       jz      handler ;handle error
;
; Invoked by the User, so Install as an Error Handler
;
       call    getefcb         ;pt to external FCB
       jz      start1          ;proceed if external FCB not available
;
; Make Name Invoked by User the Name of the Error Handler
;
       inx     h               ;pt to first char
       lxi     d,ername        ;pt to name of error handler message
       mvi     b,8             ;at most 8 bytes
       call    moveb           ;copy into buffer
;
; Make Command Line in Buffer the Error Handler
;
start1:
       lxi     h,ername        ;make name in buffer the error handler
       call    puterc          ;set command
       mvi     a,0ffh          ;set error code
       call    puter1          ;set message
       call    print
       db      'ERROR4, Version '
       db      (version/10)+'0','.',(version mod 10)+'0'
       db      cr,lf,' Error Handler Installed',0
       ret
;
; Handle Error
;
handler:
       call    erradr          ;get address of error line
       xchg                    ;HL pts to free area, DE pts to error line
       call    codend          ;get ptr to free area
;
; Extract Bad Command and Store It in Memory Starting at CODEND
;       DE pts to bad command, HL pts to location to store it at
;
savebad:
       ldax    d               ;get next char
       mov     m,a             ;put it
       ora     a               ;done?
       jz      sbad1
       cpi     cmtch           ;check for comment
       jz      sbad1
       cpi     ' '             ;check for space
       jz      sbad1
       inx     h               ;pt to next
       inx     d
       jmp     savebad
;
; Set ending 0 in bad command buffer and print error message and command
;
sbad1:
       mvi     m,0             ;store ending zero
       call    print
       db      ' File ',0
       call    codend          ;pt to name
       call    pstr
       call    print
       db      '.COM Not Found',0
;
; Advance to Next Entry in Error Line
;
       call    erradr          ;pt to error
sbad2:
       mov     a,m             ;skip to comment or eol
       ora     a               ;eol?
       jz      sbad3
       inx     h               ;pt to next
       cpi     cmtch           ;comment?
       jnz     sbad2
;
; Set Up Command Line Pointer
;
sbad3:
       push    h               ;save ptr to error text
       call    getcl1          ;pt to command line buffer
       lxi     d,4             ;pt to first char position
       xchg
       dad     d
       xchg                    ;DE pts to command line
       mov     m,e             ;store address
       inx     h
       mov     m,d
       pop     h               ;HL pts to next command, DE pts to cmd line
;
; Set Up Command Line Contents
;
sbad4:
       mov     a,m             ;copy
       stax    d
       inx     h               ;pt to next
       inx     d
       ora     a               ;done?
       jnz     sbad4
       ret

;
; Buffers
;
ername:
       db      'ERROR4  ',0    ;name of error handler

       end