; M4H19S/ASM *GET M4H19/EQU *GET M4H19/MAC VS EQU 15 ;Offset in header for visual cursor VE EQU 16 ;Offset in header for line mode cursor DEF_LEN EQU 17 ;Default length of audible bell BELLFLAG EQU 18 ;Audible or visual bell flag DEF_FREQ EQU 19 ;Frequency value for bell tone OLDLOW EQU 21 ;Set up address used for removing *HP OLDHIGH EQU 23 ;Ditto BIT_MASK EQU 29 ;Offset to bit mask ; ; Load in low memory to avoid user programs, and KERMIT in ; particular ; ORG 2500H START: LD DE,ARGBUFF+1 ;Copy the arguments LD BC,255 ;Pick a number suffiently large LD (PARMS),DE ;Save the dest for later use LDIR ;Move the command line GETH19: LD DE,H19_NAME ;Check to see if $HEATH is there SSVC @GTMOD ;Try to find it JP NZ,NOH19 ;Not there, so go put it in PUSH HL ;Put the header address into IX POP IX LD DE,PARAM_TABLE ;Get the parameter table LD HL,(PARMS) ;Get the command line ; ; We look for a '(' to know whether or not to display the usage ; message. If we do not find one, then we give the user help. ; LOOP1: LD A,(HL) ;See if there is anything there CP 13 ;End of command line JP Z,SHOW_VALS ;If so, then give help CP '(' ;Start of argument list? JR Z,LOOP2 ;Jump if it is INC HL ;Point to next JR LOOP1 ;Loop on LOOP2: DEC HL ;Back up before the '(' SSVC @PARAM ;Parse the parameter list JP NZ,SHOW_VALS ;On failure, give help LD A,(RESP_VS) ;Was a BLOCK cursor value given? OR A JR Z,CHK_VE ;Jump if not AND 60H ;Verify only numeric. JP NZ,BAD_PARAM ;Jump if not LD HL,(VS_VAL) ;Get the value given LD A,H ;Make sure it is only a byte OR A JP NZ,TOO_BIG ;Print a message if too big LD A,L ;Get the byte value from L LD (IX+VS),A ;Save it into the $HEATH header CHK_VE: LD A,(RESP_VE) ;Was there a line mode cursor OR A ;Jump if not JR Z,CHK_REM AND 60H ;Verify it is only numeric JP NZ,BAD_PARAM ;Jump if bad LD HL,(VE_VAL) ;Get the value LD A,H ;Make sure it is a byte value OR A JP NZ,TOO_BIG ;Jump if too big. LD A,L ;Get the byte value from L LD (IX+VE),A ;Store it CHK_REM: LD A,(RESP_REMOVE) ;Is this a remove request? OR A JR Z,CHK_FREQ ;If not go check bell frequency AND 0A0H ;Must be boolean JP NZ,BAD_PARAM LD B,0 ;Get the current HIGH$ value LD HL,0 SSVC @HIGH$ JP NZ,ERROR LD A,(IX+OLDHIGH) ;Get the OLD HIGH$ from header LD C,A LD A,(IX+OLDHIGH+1) LD B,A ;See if they are still the same OR A ;Reset the carry SBC HL,BC ;Compute the difference JP NZ,CANT_REMOVE ;If not equal, then can't remove LD A,(IX+OLDLOW) ;Get the previous HIGH$ that was LD L,A ;in effect before $HEATH was LD A,(IX+OLDLOW+1) ;installed LD H,A LD B,0 ;removing the module SSVC @HIGH$ JP NZ,ERROR ; ; The code here make several RASH assumptions about what devices ; $HEATH is mated to. It assumes that the following commands were ; used to install the $HEATH module: ; ; set *hp h19 ; filter *so *hp ; ; With these in mind, it does the following commands ; ; reset *so ; reset *hp ; remove *hp ; route *so *do ; ; This should restore the system to a reasonable state, given the ; fact that the filter should be in by itself anyway. ; REMOVE_FILTER: LD HL,CMD1 ;Do "reset *so" command SSVC @CMNDR LD HL,CMD2 ;Do "reset *hp" command SSVC @CMNDR LD HL,CMD3 ;Do "remove *hp" command SSVC @CMNDR LD HL,CMD4 ;Do "route *so *do" command SSVC @CMNDR JP SET_EXIT ;Nothing else is reasonable, quit CHK_FREQ: LD A,(RESP_FREQ) ;Check for a frequency given OR A JR Z,CHK_DUR ;Jump if none there AND 60H ;Verify that it is numeric JP NZ,BAD_PARAM ;Jump if not just numeric LD HL,(FREQ_VAL) ;Get the value LD (IX+DEF_FREQ),L ;Use all 16 bits worth LD (IX+DEF_FREQ+1),H CHK_DUR: LD A,(RESP_DURA) ;Is there a duration given? OR A JR Z,CHK_BELL ;Jump if there is isn't AND 60H ;Verify that it is numeric JP NZ,BAD_PARAM ;Jump if it is not LD HL,(DUR_VAL) ;Get the value LD A,H ;Make sure there is only a byte OR A JP NZ,TOO_BIG ;Jump if MSB not zero LD A,L ;Get the byte value from L LD (IX+DEF_LEN),A ;Save the tone length CHK_BELL: LD A,(RESP_BELL) ;Are they setting bell flag? OR A JP Z,CHK_STRIP8 ;Check if strip8 parameter given AND 0A0H ;Is it boolean? JP NZ,BAD_PARAM ;Jump if not LD A,(BELL_VAL) ;Get the value LD (IX+BELLFLAG),A ;Save it CHK_STRIP8: LD A,(RESP_STRIP8) ;Get the parameter present flag OR A JP Z,CHK_SHOW ;Go check show parameter AND 0A0H ;Check if boolean JP NZ,BAD_PARAM LD C,(IX+BIT_MASK) LD B,(IX+BIT_MASK+1) PUSH IX POP HL ADD HL,BC ;Compute the offset LD C,0FFH ;Get the off mask LD A,(STRIP8_VAL) OR A JR Z,STRIP8_OFF ;Option is off so jump LD C,07FH ;Load on mask STRIP8_OFF: LD (HL),C ;Patch AND instruction CHK_SHOW: LD A,(RESP_SHOW) ;Check if show given OR A JR Z,CHK_HELP ;Check for help AND 0A0H ;Is it boolean JP NZ,BAD_PARAM ;Error if not LD A,(SHOW_VAL) ;Get the value OR A ;Make sure not (SHOW=NO) CALL NZ,SHOW_VALS CHK_HELP: LD A,(RESP_HELP) ;Check if HELP given OR A JR Z,SET_EXIT AND 0A0H ;Is it boolean? JP NZ,BAD_PARAM LD A,(HELP_VAL) ;Get the value OR A ;Make sure not (HELP=NO) JP Z,SET_EXIT LD HL,HELP_STR SSVC @DSPLY SET_EXIT: LD HL,0 ;Set normal exit code RET ;Return, DON'T @EXIT HERE ; ; Show the values of the currently set options ; SHOW_VALS: LD HL,LINE_STR ;Get the line mode cursor descr SSVC @DSPLY ;Display it LD L,(IX+VE) ;Get the value LD H,0 ;Make it only a byte CALL NUMOUT ;Print it on the screen LD HL,BLK_STR ;Print the block mode descr SSVC @DSPLY LD L,(IX+VS) ;Get the value LD H,0 ;Make it a byte CALL NUMOUT ;Print the number on the display LD C,13 ;Get a new line SSVC @DSP LD HL,BELL_STR ;Print the BELL descr SSVC @DSPLY LD HL,ON_STR ;Get the ON string LD A,(IX+BELLFLAG) ;Get the value OR A ;Check if it is on JR NZ,SHOW_1 ;Jump if it is LD HL,OFF_STR ;Get the off string SHOW_1 SSVC @DSPLY ;Display ON or OFF LD HL,DURA_STR ;Get the duration descr SSVC @DSPLY LD L,(IX+DEF_LEN) ;Get the duration LD H,0 ;Make it a byte in HL CALL NUMOUT ;Print the number on the screen LD HL,FREQ_STR ;Print the frequency descr SSVC @DSPLY LD L,(IX+DEF_FREQ) ;Get the LSB of FREQ LD H,(IX+DEF_FREQ+1);Get the MSB CALL NUMOUT ;Print the number out LD HL,STRIP_STR ;Get the STRIP8 message SSVC @DSPLY LD C,(IX+BIT_MASK) LD B,(IX+BIT_MASK+1) PUSH IX POP HL ADD HL,BC ;Compute the offset LD A,(HL) LD HL,ONSTR CP 0FFH ;Check for off JR NZ,ISON LD HL,OFFSTR ISON: SSVC @DSPLY RET ;Return to caller ; NUMOUT LD DE,STRBUF PUSH DE SSVC @HEXDEC EX DE,HL LD (HL),3 POP HL LD A,' ' NUM_1 CP (HL) JR NZ,NUM_2 INC HL JR NUM_1 NUM_2 SSVC @DSPLY RET ; CANT_REMOVE: LD HL,NO_REMOVE ;Print the Can't remove message SSVC @DSPLY JP REMOVE_FILTER ;Finish unlinking the devices ; TOO_BIG: LD HL,TOO_BIG_STR ;Get the TOO BIG message DB 0DDH ;Hide LD HL instruction ; NOH19MESS: LD HL,NOFLT_STR ;Print error message, No H19/FLT DB 0DDH ;Hide LD HL ; BAD_PARAM LD HL,BAD_PARAM_STR;Print Bad paramter message ; PRINT_EXIT: SSVC @DSPLY ;Print it EXIT: LD HL,-1 ;Get error exit code RET ;Return from caller ; ERROR: OR 0C0H LD C,A SSVC @ERROR JR EXIT ; NOH19: LD A,(ONCE) ;Check if we have been here once OR A JR NZ,NOH19MESS ;If so, then issue a message INC A ;Set the flag LD (ONCE),A LD HL,SETH19 ;Do the "set *hp h19" command SSVC @CMNDR LD HL,FILTER ;Do the "filter *so *hp" command SSVC @CMNDR JP GETH19 ;Try to load it again ; H19_NAME DB '$HEATH',0 NO_REMOVE DB 'Can not reclaim used memory!',13 STRIP_STR DB 10,'Strip 8th bit: ',3 ONSTR DB 'YES',13 OFFSTR DB 'NO',13 NOFLT_STR DB 'Can not find H19 filter',13 BAD_PARAM_STR DB 'Bad parameter value',13 TOO_BIG_STR DB 'Value too large',13 LINE_STR DB 'Normal cursor: ',3 BLK_STR DB ', Block cursor: ',3 DURA_STR DB ', Duration: ',3 FREQ_STR DB ', Frequency: ',3 BELL_STR DB 'Bell: ',3 ON_STR DB 'ON',3 OFF_STR DB 'OFF',3 ; HELP_STR DB 'Recognized parameters:',10 DB 'CURSOR - Normal cursor character',10 DB 'BLOCK - Block cursor character',10 DB 'BELL - Turn bell ON or OFF',10 DB 'FREQUENCY - Frequency of bell (inverse of ' DB 'real freq)',10 DB 'DURATION - Length of tone (255 MAX)',10 DB 'STRIP8 - Remove 8th bit from characters ' DB '(default=ON)',10 DB 'REMOVE - Remove the filter from memory' DB 10,'SHOW - Show all values',10 DB 'HELP - This message',10,13 ; VE_VAL DW 0 VS_VAL DW 0 RM_FLAG DW 0 DUR_VAL DW 0 FREQ_VAL DW 0 BELL_VAL DW 0 SHOW_VAL DW 0 HELP_VAL DW 0 STRIP8_VAL DW 0 ; CMD1 DB 'reset *so',13 CMD2 DB 'reset *hp',13 CMD3 DB 'remove *hp',13 CMD4 DB 'route *so *do',13 SETH19 DB 'set *hp h19',13 FILTER DB 'filter *so *hp' PARMS DW 0 ONCE DB 0 ARGBUFF DB ' ' DS 255 STRBUF DS 20 ; PARAM_TABLE: DB 80H ; DB 80H+5 DB 'BLOCK' RESP_VS DB 0 DW VS_VAL ; DB 80H+6 DB 'CURSOR' RESP_VE DB 0 DW VE_VAL ; DB 40H+6 DB 'REMOVE' RESP_REMOVE DB 0 DW RM_FLAG ; DB 90H+9 DB 'FREQUENCY' RESP_FREQ DB 0 DW FREQ_VAL ; DB 90H+8 DB 'DURATION' RESP_DURA DB 0 DW DUR_VAL ; DB 40H+4 DB 'BELL' RESP_BELL DB 0 DW BELL_VAL ; DB 40H+4 DB 'SHOW' RESP_SHOW DB 0 DW SHOW_VAL ; DB 40H+4 DB 'HELP' RESP_HELP DB 0 DW HELP_VAL ; DB 46H DB 'STRIP8' RESP_STRIP8 DB 0 DW STRIP8_VAL ; TABLE_END DB 0 END START