;
; Program: GOTO
; Author:  Richard Conn
; Version: 1.0
; Date: 8 Mar 84
; Previous Versions:  None
;
version equ     10

;
;       GOTO is a program designed to be run under ZEX which permits
; branching within a ZEX file.  It accepts only one argument, a label,
; which is defined within the ZEX file as a special comment of the
; form:
;       ;=label anytext
; The syntax of GOTO is:
;       GOTO label
;

;
; Basic Equates
;
z3env   SET     0f400h  ;Environment Descriptor
fcb     equ     5ch
cr      equ     0dh
lf      equ     0ah
lflag   equ     '='     ;label flag in comment

;
; Externals
;
       ext     z3init,getzrun,getzfc,putznc,putzrun
       ext     print,cout,caps

;
; 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 Env and the VLIB Env
;
; Check for Valid Label
;
       lda     fcb+1   ;get first char of FCB
       cpi     ' '     ;no label?
       jz      help
       cpi     '/'
       jnz     start1
;
; Print GOTO Help
;
help:
       call    print
       db      'GOTO, Version '
       db      (version/10)+'0','.',(version mod 10)+'0'
       db      cr,lf,'GOTO -- Branch Within a ZEX File'
       db      cr,lf,'Syntax:'
       db      cr,lf,' GOTO label'
       db      cr,lf,'where "label" is defined by a special comment of'
       db      cr,lf,'the form ";',lflag,'label".',0
       ret
;
; Check for Running ZEX
;
start1:
       call    getzrun ;get ZEX run flag
       jnz     start2
       call    print
       db      ' ZEX Not Running',0
       ret
;
; Begin Scan of ZEX Message Buffer
;
start2:
       call    getzfc  ;get ptr to first ZEX char
       lxi     d,fcb+1 ;pt to GOTO label
;
; Scan for Label Comment
;
scanc:
       mov     a,m     ;get char
       cpi     ';'     ;comment?
       jnz     flush   ;advance to next line
       dcx     h       ;pt to next
       mov     a,m
       cpi     lflag   ;label?
       jnz     flush   ;advance to next line if not label
;
; We have a label - check it
;
       push    h       ;save ptrs
       push    d
       dcx     h       ;pt to first char
       mvi     b,8     ;at most 8 chars
label:
       ldax    d       ;get GOTO char
       cpi     ' '     ;done?
       jz      label1
       mov     c,a
       mov     a,m
       call    caps    ;capitalize label in ZEX file
       cmp     c       ;compare
       jnz     label2
       dcx     h       ;advance
       inx     d
       dcr     b
       jnz     label
;
; Label Matches
;
label1:
       mov     a,m     ;must be space or less for match
       cpi     ' '+1
       jnc     label2
       pop     d       ;restore ptrs
       pop     h
;
; Advance to Beginning of Next Line
;
nxtline:
       mov     a,m     ;get char
       dcx     h       ;pt to next
       cpi     cr      ;end of line?
       jz      nxtl1
       cpi     0ffh    ;end of processing?
       jnz     nxtline
nxtl1:
       call    putznc  ;store ptr to next char
       call    print
       db      ' GOTO Label ',0
       jmp     prlabel
;
; No Match on Label
;
label2:
       pop     d       ;restore regs
       pop     h
;
; Flush to Next Line or EOB
;
flush:
       mov     a,m     ;get next char
       cpi     0ffh    ;end of buffer?
       jz      notfnd
       dcx     h       ;pt to next
       cpi     cr      ;end of line?
       jnz     flush
       jmp     scanc   ;resume search
;
; Label Not Found
;
notfnd:
       call    print
       db      ' Label ',0
       call    prlabel ;print label
       call    print
       db      ' Not Found -- Aborting ZEX',0
       xra     a       ;turn off ZEX
       jmp     putzrun

;
; Print Label Name
;
prlabel:
       mvi     b,8
       lxi     h,fcb+1
prl1:
       mov     a,m     ;get next char
       cpi     ' '     ;done?
       rz
       call    cout    ;print char
       inx     h
       dcr     b       ;count down
       jnz     prl1
       ret

       end