;PARAM/ASM - LS-DOS 6.2 ; ; Parse a field ; (HL) => command line ; (DE) => FCB area ; (HL) <= 1st byte past non- ; except 13, 3, "(" ; Z <= found valid field ; NZ <= found invalid field ; @PARSER LD B,8 ;Set length @PAR1 LD A,B LD (PAR6+1),A ;Stuff length for test INC B PAR2 LD A,(HL) CP 3 ;ETX? JR Z,PAR5 CP CR ;? JR Z,PAR5 CP '(' ;Begin of parm? JR Z,PAR5 INC HL ;Bump pointer to next CALL TST09AZ ;Test if 0-9,A-Z JR NC,PAR3 ;Go if one of the above CP 'a' ;Check on lower case JR C,PAR5 ;Jump on non-alpha CP 'z'+1 ;Is it a-z? JR NC,PAR5 ;Jump on non-alpha RES 5,A ;Convert lower to upper PAR3 DEC B ;Count down JR Z,PAR4 LD (DE),A ;Xfer the char XOR A ;Show at least 1 valid LD (PAR6+1),A ;Char was detected INC DE ;Bump FCB pointer JR PAR2 ;Loop PAR4 INC B ;Here on max chars ck'd JR PAR2 PAR5 LD C,A ;Save separator IF @BLD631 CP ' ' ;<631> JR NZ,PAR5A ;<631> DB 0FEH ;<631>Single byte skip PAR5B: INC HL ;<631> CP (HL) ;<631> JR Z,PAR5B ;<631> PAR5A: LD A,3 ;<631> LD (DE),A ;<631> ELSE LD A,3 ;Stuff ETX LD (DE),A ; ; Skip over spaces ; LD A,C ;Was separator a space? CP ' ' JR NZ,PAR6 ;Don't skip if not PAR5A CP (HL) ;Next char a space? INC HL JR Z,PAR5A ;Loop until not DEC HL ;Backup to last non-space ENDIF ; ; Return status of field validity ; PAR6 LD A,0 ;Set Z-flag if at least OR A ; 1 valid char detected LD A,C ;Recover separator char RET ; ; Test if 0-9 or A-Z ; TST09AZ CP '0' ;Special character? RET C ;Go if not in range CP '9'+1 ;Jump on digit 0-9 JR C,EXITC ;Go if 0-9 & make NC CP 'A' ;Jump on spec char RET C ;Go if 3B-40 CP 'Z'+1 ;Jump on A-Z EXITC CCF ;Switch flag of result RET ; ; Find parameter in table ; (HL) => pointer to line ; (DE) => pointer to buffer area ; (BC) => pointer to parameter table ; (BC) <= pointer to possible response byte ; (DE) <= parm vector address ; Z <= set if found ; NZ <= if not found in table ; @FNDPRM PUSH HL LD H,B ;Xfer table addr LD L,C LD A,(HL) ;P/u 1st byte of table RLCA ; & test for enhanced PUSH AF ; table format JR NC,FND1 INC HL ;Bump past indicator FND1 POP AF ;Old or enhanced format? PUSH AF LD A,5 ;Init for old lengths LD BC,1<8!2 JR NC,FND1A ;Branch if old format LD A,(HL) ; else get parm length AND 0FH ;Strip flags DEC A ;Adjust for length-1 INC B ;Update offset to address INC HL ;Bump past TYPE byte FND1A LD (FND3A+1),A ;Stuff the lengths ADD A,B LD (FND5A+1),A ADD A,C LD (FND2+1),A LD A,(DE) ;P/u command line byte CP (HL) ;Match 1st char of table? JR Z,FND3 ;Jump if 1st char matches FND2 LD BC,8 ; else bypass that entry ADD HL,BC LD A,(HL) ;Test for table end OR A JR NZ,FND1 ;Loop if more POP HL ;Clean flag from stack POP HL ;Rcvr saved reg & INC A ; set NZ for not found RET FND3 POP AF ;Ck old or new table PUSH AF JR NC,FND3A ;Go if old format table DEC HL ;Ck if type byte permits BIT 4,(HL) ; single-char abbrev INC HL JR Z,FND3A ;Go on no abbrev INC DE ;Make sure the next char LD A,(DE) ; is not in the range DEC DE ; <0-9,A-Z> before CALL TST09AZ ; assuming abbrev JR C,FND5A ;Go on 1-char abbrevs FND3A LD B,5 ;5 more chars to match PUSH HL PUSH DE LD A,B ;Don't if trailing length OR A ; is zero JR Z,FND5 FND4 INC DE INC HL LD A,(DE) CP 3 ;ETX? JR Z,FND7 CP CR ;Jump on JR Z,FND7 CP (HL) ;Match? JR NZ,FND6 ;Jump if not DJNZ FND4 ; else loop FND5 POP DE ;Parm matched POP HL ;Recover begin of parm FND5A LD BC,6 ;Point to address field ADD HL,BC LD C,L ;Save the response-byte LD B,H ; pointer in BC DEC BC LD E,(HL) ;P/u parm table address INC HL LD D,(HL) POP AF ;If not enhanced, change JR C,$+4 ; pointer to bucket LD B,SBUFF$<-8 ; so we don't alter user POP HL ;Recover line position XOR A ;Show found RET FND6 CALL TST09AZ ;Ck if 0-9, A-Z JR NC,FND8 ;Go if in range of above FND7 LD A,(HL) ;Loop if table has CP ' ' ; trailing spaces JR Z,FND5 FND8 POP DE POP HL JR FND2 ; ; PARAM routine ; (HL) => param line ; (DE) => parm table ; (DE) <= table address value ; C <= # of parm ; Z = OK ; NZ = parm error ; PARAM0 INC HL ;Bump the pointer PARAM LD A,(HL) ; and p/u char CP CR RET Z ;Return on enter CP ' ' JR Z,PARAM0 ;Loop on space CP '(' JR NZ,PARAM5 ;Jump if not left paren LD A,(DE) ;Check if enhanced table RLCA JR NC,PARAM1 PUSH DE ;Save pointer to start INC DE ;Point to 1st TYPE byte PUSH HL ;Save this posn ; $?1 LD A,(DE) ;P/u TYPE byte AND 0FH JR Z,$?2 ;Exit on end of table LD L,A ;Point to response byte IF @BLD631 XOR A ;<631> LD H,A ;<631> ELSE LD H,0 ENDIF INC L ADD HL,DE IF @BLD631 LD (HL),A ;<631>Zero the response ELSE LD (HL),0 ;Zero the response ENDIF INC HL ;Bump to the next TYPE INC HL INC HL EX DE,HL ;Table pointer back to DE JR $?1 ;Loop thru all response bytes ; $?2 POP HL ;Rcvr reg POP DE ; & start of parm table PARAM1 PUSH DE LD B,15 ;Max 15-char field LD DE,SBUFF$ ;Point to buffer region INC HL ;Bypass the '(' CALL @PAR1 ;Get the field DEC HL ;Backup to separator POP DE JR NZ,ERROUT ;Return if bad field CP CR ;If separator was a CR, JR NZ,$+3 ; we need to counteract INC HL ; the DEC HL above PUSH DE LD B,D ;Table pointer to BC LD C,E LD DE,SBUFF$ ;Parm in table? CALL @FNDPRM PUSH BC ;Save response pointer JR Z,PARAM3 ;Jump if found in table ; ; Parameter not in table - NZ condition ; PARAM2 POP DE ;Pop response pointer POP DE ;Pop parm table pointer ERROUT LD A,44 ;Set up PARM ERROR RET ; ; Parameter found in table - parse the value ; PARAM3 LD A,(HL) ;Test for assignment CP '=' IF @BLD631 LD BC,0 JR Z,ASSIGN ;<631>Jump if parm=value DEC BC ;<631> ELSE JR Z,ASSIGN ;Jump if parm=value LD BC,-1 ; else set symbol TRUE ENDIF PARMSW EX (SP),HL ;Get response byte SET 6,(HL) ;Turn on FLAG-SWITCH ; ; Valid parm argument parsed into reg BC ; PARAM4 EX DE,HL ;Address pointer to HL LD (HL),C ;Stuff lo-order value INC HL LD (HL),B ;Stuff hi-order value POP HL ;Rcvr parm line pointer POP DE ;Rcvr parm table pointer LD A,(HL) CP ',' ;Comma separator? JR Z,PARAM1 CP CR IF @BLD631 RET Z ;<631> ELSE JR Z,PARAM5 ENDIF CP ')' ;Closing paren? JR NZ,ERROUT ;Leave with ERROR INC HL ;Bump line pointer PARAM5 XOR A ;Show all OK RET ; ; Parameter assignment statement ; ASSIGN INC HL ;Advance token past '=' LD A,(HL) CP '"' ;Double quote string? JR Z,STRING CP 'A' ;Ck on digit or JR C,ASS3 ; special character RES 5,A ;Strip l/c if present CP 'X' ;Hexadecimal? JR Z,ASS1 CALL ONOFF ;Ck on Y, N, ON, OFF JR Z,PARMSW ;Set FLAG-SWITCH if OK JR PARAM2 ; else error exit ASS1 INC HL CALL HEXVAL ;Ck on hex format JR NZ,PARAM2 ;Error if bad format JR ASS3A ; else bypass & set resp ; ; Is the parameter numeric or flag ? ; ASS3 CP '0' ;Parameter=number ? PUSH AF ;CF = 0 if number CALL @DECHEX ;Cvt # @ HL to bin in DE POP AF ASS3A EX (SP),HL ;Get response pointer JR NC,ASS4 ;Show numeric if CF=0 SET 6,(HL) ; otherwise show switch DB LD___A ;Skip next instruction ASS4 SET 7,(HL) ;Set Numeric response bit JR PARAM4 ; ; Parameter string entry ; STRING INC HL ;Bypass '"' LD B,H ;Save starting address LD C,L STR1 LD A,(HL) ;P/u a char CP 20H JR C,PARAM2 ;Exit on control char INC HL ;Bump pointer CP '"' ;Closing double quote JR NZ,STR1 PUSH HL ;Save current pointer SBC HL,BC ;Calc length of string LD A,L DEC A ;Adjust for INC HL CP 32 ;If len > 31, set to 0 JR C,$+3 XOR A POP HL ;Rcvr pointer EX (SP),HL ;Get response byte OR 20H ;Set FLAG-STRING LD (HL),A JR PARAM4 ; ; Check for Yes, No, On, Off ; IF @BLD631 ONOFF: ;<631> ELSE ONOFF LD BC,0 ;Init to FALSE ENDIF SUB 'Y' ;Is it Yes? JR Z,ONO1 ;Jump on yes ADD A,'Y'-'N' ;Is it No? JR Z,ONO2 ;Jump on no DEC A ;Is it 'O'n or 'O'ff? RET NZ ;Return if not on/off INC HL ;Bump pointer to next LD A,(HL) ; character & p/u RES 5,A ;Set lower to upper CP 'F' JR Z,ONO2 ;Jump on off CP 'N' RET NZ ;Return if not on IF @BLD631 ONO1 DEC BC ;<631>Init to true ELSE ONO1 LD BC,-1 ;Init to true ENDIF ONO2 INC HL ;Ignore trailing part LD A,(HL) ; of word until closing CP ')' ; ")" or comma separator RET Z ; or CR CP CR RET Z CP ',' RET Z JR ONO2 ;Loop ; ; Process hexadecimal assignment ; IF @BLD631 HEXVAL: ;<631> ELSE HEXVAL LD BC,0 ;Init value to zero ENDIF LD A,(HL) ;P/u a char CP 27H ;Must be single quote RET NZ ;Ret if not HEX1 INC HL ;Bump past it LD A,(HL) ;P/u possible hex digit SUB 30H ;Begin conversion JR C,HEX2 ;Jump if < "0" CP 10 ;Ck for 0-9 JR C,HEX3 ;Jump if digit is 0-9 RES 5,A ;Strip l/c if present SUB 7 ; else ck A-F CP 16 JR C,HEX3 ;Jump if A-F HEX2 LD A,(HL) ;Test for closing quote CP 27H INC HL ;Bump pointer RET Z ;Ret if closing quote DEC HL ; else backup, set OK, XOR A ; then return RET HEX3 PUSH BC ;Exchange BC & HL EX (SP),HL ; and save HL ADD HL,HL ;Multiply by 16 ADD HL,HL ADD HL,HL ADD HL,HL LD B,H ;Merge new digit ADD A,L LD C,A POP HL ;Recover pointer JR HEX1 ;Loop