; ARUNZ-1.Z80 Initialization and Main Code Loop ; Initialization Code Section ; TYP3HDR.Z80, Version 1.1, safety header ENTRY: jr START00 ; Must use relative jump db 0 ; Filler db 'Z3ENV' TYPE: db ENVTYP ; Type-3 or -4 environment Z3EADR: dw 0fe00h ; Filled in by Z33 if ENVTYP lt 4 dw ENTRY ; Intended load address else dw ldaddr ; Type 4 load address word endif ; ENVTYP lt 4 CONFIG ; Macro with configuration flags IOFCB: ds 1 ; Initialized by FXIO db 'ALIAS ' ; File name db 'CMD' ; File type ds 24 ; Initialized by FXIO START00: if ENVTYP eq 3 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: db 'Bad load address',BELL,'$' endif ; ENVTYP eq 3 START: ; Initialize ld hl,(Z3EADR) ; Pt to ZCPR3 environment call ZSYSCHK ; Print msg if program not properly installed ret nz ; ..and exit call Z3INIT ; Initialize ZCPR3 environment IF Z33ONLY call Z33CHK ; Require Z33 or later jr z,STARTA call PRINT db CR,LF,'Z33 or later required',BELL,0 ret STARTA: ENDIF ;Z33ONLY ld (STACK),sp ; Save system stack pointer ld sp,STACK ; Set up local stack call RETUD ; Save user/disk information ld (dusave),bc ld a,(REGF) ; See if user register is setting configuration cp 20h ; If not 00..1FH, use hard-coded options jr nc,START0 ld b,a ; Get value of register call GETREG ld hl,PATHF ; Set up PATHF from user register bit 0,a ; ..based on bit 0 call INITFLAG ld hl,ROOTF ; Set up ROOTF based bit 1,a ; ..on bit 1 call INITFLAG ld hl,SCANCUR ; Set up SCANCUR based bit 2,a ; ..on bit 2 call INITFLAG START0: xor a ; Set rflag for non-recursive script ld (RFLAG),a IF PINPUT ld a,2 ; Set ZEX input redirection flag off ld (ZEXFL),a ENDIF ;PINPUT call GETCST ; Get command status flag and 100b ; See if ECP invocation jr z,START1 ; If not, skip on ld a,(QUIETECP) ; If so, substitute flag quietecp ld (QUIETF),a ld a,0ffh START1: ld (NLFLAG),a ; Set "new line" flag non-zero ; ..zero if prgram not invoked as ECP DSEG NLFLAG: ds 1 CSEG ;--------------------------------------------------------------------------- ; This section of the code defines and allocates space for the various ; buffers that are needed. ; Define data buffer areas if ENVTYP eq 4 ld hl,(CODESIZ) ; Size of code, including lib routines ld de,ENTRY add hl,de ; HL now has address of end of code else call CODEND ; Use CODEND value for type-3 endif ; ENVTYP eq 4 ld (CLBUF),hl ; Command line will be first after code DSEG CLBUF ds 2 CSEG ; Allocate buffer for the new command line if XMCL ld de,(mclsiz) ; Get extended MCL size ld a,d ; See if bigger than 100h or a jr z,START2 ; If so, use this value for the extended MCL add hl,de ld (HIGHLIMIT),hl ; Save in PUTCH code for overflow test jr START3 endif ; XMCL start2: ex de,hl ; Move buffer pointer to DE call getcl1 or a ; Check for zero size jp z,QUIT ; If MCL length is 0, quit ld c,a ; Save MCL size in C ld a,h ; Check for no MCL or l jp z,QUIT ; If none, quit ld l,c ; Get CL length into HL ld h,0 add hl,de ld (HIGHLIMIT),hl ; Save this as buffer filling limit address ld hl,CLSIZE ; Use oversize standard buffer add hl,de START3: inc hl ; Room for final null if ENVTYP eq 4 BUFFER DEFL CLSIZE + 1 ; Keep track of buffer allocations endif ; ENVTYP eq 4 if XMCL AND (high MCLSIZE ne 0) if ENVTYP eq 4 BUFFER DEFL MCLSIZE + 1 ; Use extended mcl length if option enabled endif ; ENVTYP eq 4 endif ; XMCL and (high MCLSIZE ne 0) ld (TAILBUF),hl ; Command tail buffer will be here ld de,80h ; Allow 128 bytes add hl,de if ENVTYP eq 4 BUFFER DEFL BUFFER + 80h ; Tally buffer allocations endif ; ENVTYP eq 4 DSEG TAILBUF: ds 2 CSEG IF PINPUT ; Allow space for user responses to prompts ld (PROMPTBUF),hl ld de,NPROMPTS*80h add hl,de if ENVTYP eq 4 BUFFER DEFL BUFFER + ( NPROMPTS * 80h ) endif ; ENVTYP eq 4 xor a ; Initialize prompt count ld (PROMPTCNT),a DSEG PROMPTBUF: ds 2 PROMPTCNT: ds 1 ; Number of prompts CSEG ENDIF ;PINPUT ld a,l or a ; Are we already on a page boundary jr z,START4 ; Skip ahead if so inc h ld l,0 ; Get to a page boundary START4: ld (BUFADR),hl ; File buffer will be here ld de,FBUFSIZE*100h add hl,de if ENVTYP eq 4 BUFFER DEFL BUFFER + ( FBUFSIZE * 100h ) + 255 LDADDR DEFL CODESIZE + 100h + BUFFER endif ; ENVTYP eq 4 ex de,hl ; Ending address into DE call GZMTOP ; Get top of free memory (page) in HL xor a ; Make sure carry is clear sbc hl,de jr nc,FINDEND1 ; If no carry, we have enough room call PRINT db CR,LF,'Insufficient TPA',BELL,0 jp ERRQUIT FINDEND1: call SAVETAIL ; Save the command tail in tailbuf call HELPCHK ; See if built-in help requested call FINDFILE ; Find the ALIAS.CMD file call FINDALIAS ; Find the named alias script call PRTALIAS ; Display alias-running message ; Process the alias script ld de,(CLBUF) ; Point to buffer for new command line ;--------------------------------------------------------------------------- ; This is the main character-processing loop. ; Strip leading spaces and tabs STRIP: call GETCH ; Get next character from ALIAS.CMD jr z,NXTCHAR1 ; Skip ahead if end of line or file cp ' ' ; If space, skip over it jr z,STRIP cp TAB ; Ditto if tab jr z,STRIP jr NXTCHAR1 ; Otherwise, process the character NXTCHAR: call GETCH ; Get next character from ALIAS.CMD NXTCHAR1: jr z,DONE ; Jump if end of characters cp '$' ; Parameter lead-in char? jp z,PARAM cp '^' ; Control-char lead-in? jr z,CTRLCH call PUTCH ; Store the character jr NXTCHAR ;--------------------------------------------------------------------------- ; We get here when the alias script has been fully expanded and is ready for ; insertion into the command line buffer. ; Done -- Buffer is Loaded DONE: ld hl,(CLBUF) ; Point to expanded alias ld a,(hl) ; Skip if empty line or a jr z,QUIT ; Test flag for recursive script. If set, ignore pending commands. ld a,(RFLAG) ; Get recursion flag inc a ; Set flag and accumulator 0 if flag set jr z,DONE3 ; Recursive script, put final null in buffer ; Get pointer to pending commands call GETCL2 ; Set HL to pending commands, A to ; ..first character in commands ; Append any commands pending in MCL. At this point, DE points to end of ; expanded alias script, and HL points to the next command in the MCL. DONE2: or a ; Test character jr z,DONE3 ; Jump if at end of commands call PUTCH ; Add character to buffer at DE inc hl ; Get next pending character ld a,(hl) jr DONE2 DONE3: call XPUTCH ; Add the ending null (there's always ; ..room for one more character) ; Calculate actual length of new command line and load into BC ld hl,(CLBUF) push hl ex de,hl xor a sbc hl,de ld b,h ld c,l ; Initialize command line pointer in MCL call GETCL1 ; HL points to start of MCL buffer ex de,hl ; Put into DE ld hl,4 ; Offset to beginning of command line add hl,de ; HL -> MCL command line, DE -> MCL buffer ex de,hl ; DE -> MCL command line, HL -> MCL buffer ld (hl),e inc hl ld (hl),d ; Now move the new command line to the MCL pop hl ; HL -> (CLBUF): source for move ldir ; Work complete; return to system QUIT: ld sp,(STACK) ; Get old stack value ret ; Back to ZCPR3 ; Report MCL overflow error OVFLERR: call PRINT db cr,lf,lf,'***> MCL Overflow <***',cr,lf,0 jp ERRQUIT ; Add character to buffer at DE with limit checking against the address ; in HIGHLIMIT. If the carry flag is set on return, then there is room for ; only one more character. At standard entry point PUTCH, the code branches ; on overflow to an alias-overflow-error exit. At the entry point XPUTCH, ; the overflow flag is returned to the caller for action. NOTE: this routine ; uses self-modifying code. PUTCH: call XPUTCH jr c,OVFLERR ret XPUTCH: push hl ld (de),a ; Save the character inc de ; Advance pointer HIGHLIMIT EQU $ + 1 ld hl,0 ; Filled in by code or a ; Clear carry but leave character alone sbc hl,de ; Carry set if overflow pop hl ret ; End of ARUNZ-1.Z80