Listing of file='FIELDS.SRC;01' on disk='vmedia/chip_53-sector.ccvf'
;FIELD HANDLING ROUTINE WHICH ;ENABLES BASIC TO CREATE ;'PROTECTED' & 'UNPROTECTED' FIELDS ;ON THE SCREEN. ; ;AUTHOR. BERNIE RAFFE ; HARROW ; ENGLAND ;FEBRUARY 1981 ; ; ; DATA AREA USED TO PASS PARAMETERS ; COUNT: DB 0 ;CHARACTER COUNT NA: DS 1 ;NUMERIC OR ALPHA;SET BY BASIC CHARIN: DS 1 ;TEMPORARY CHARACTER STORE FLDADR: DS 1 ;START OF FIELD;SET BY BASIC MAXBAS EQU 32940 ;POINTER TO END OF BASIC RAM VCALL EQU 33282 ;CALL VECTOR ; SUBROUTINE TO SET UP LINKAGES WHEN RUN FROM FCS ; START: PUSH H ;SAVE SOME REGS PUSH D PUSH PSW LXI H,COUNT-1 ;SET END OF BASIC RAM POINTER SHLD MAXBAS ;TO 1 BYTE IN FRONT OF PGM MVI A,(JMP) ;SET UP JUMP TO OUR RTN IN CALL VECT. LXI H,CIINIT ;SO CALL WILL GO TO CIINIT STA VCALL SHLD VCALL+1 ;STORE ADDRESS LXI H,1C78H ;ASSUME LO ADDRESS IS IN V879 LDA 0001H ;CHECK CPI 6CH ;IS IT? JNZ STUFF ;YES LXI H,3392H ;NO, CHANGE TO V678 ADDRESS STUFF: SHLD LO+1 ;PUT PROPER ADDR. INTO INSTRUCTION POP PSW ;PREPARE TO EXIT POP D POP H MVI B,0 ;CLEAR B TO INDIC. NO ERR. TO FCS RET ;RETURN TO FCS ; LO LINKAGE ; VERSIONIZED BY START ROUTINE LO: JMP 0FFFFH ;JUMP TO LO ROUTINE IN MONITOR ;ACTUAL ADDRESS FILLED IN BY START PAGE CR EQU 13 ;CARRIAGE RETURN DELINE EQU 04 ;DELETE LINE KEY INSERT EQU 05 ;INSERT KEY DELETE EQU 127 ;DELETE KEY HT EQU 9 ;HORIZONTAL TAB RIGHT EQU 25 ;MOVE CURSOR RIGHT LEFT EQU 26 ;MOVE CURSOR LEFT SPACE EQU 32 ;SPACE CHRACTER SLASH EQU 47 INPCRT EQU 81C5H ;JUMP VECTOR #31 KBDFL EQU 81DFH ;HOLD NO. OF JUMP KBRDY EQU 81FFH ;KEYBOARD READY FLAG ;VECTOR FOR KEYBOARD NUMMIN EQU 45 ;NUMERIC MINIMUM NUMMAX EQU 58 ;NUMERIC MAXIMUM ALPHMIN EQU 32 ;ALPHANUMERIC MINIMUM ALPHMAX EQU 91 ;ALPHANUMERIC MAXIMUM ;THIS CHARACTER INPUT INITIALISATION ;ROUTINE SETS UP THE PARAMETERS ;NECESSARY FOR THE 'CHRINT' AND ;'CI' ROUTINES. CIINIT: PUSH PSW ;SAVE REGISTERS REQ'STD BY BASIC PUSH H LDA KBDFL ;SAVE BASIC'S JUMP VECTOR # PUSH PSW MVI A,31 ;SETUP NEW JUMP VECTOR # STA KBDFL MVI A,0C3H ;PLACE 'JMP' AT VECTOR LOCATION STA INPCRT LXI H,CHRINT ;GET ADDRESS OF 'CHRINT' ROUTN SHLD INPCRT+1 ;PLACE ADDRESS AFTER 'JMP' XRA A MOV B,A STA KBRDY STA CHARIN STA COUNT ;RESET CHARACTER COUNT JMP GETNXT ;CHRINT - THIS CHARACTER INPUT ROUTINE IS ;VECTORED TO FROM THE KEYBOARD INPUT ;ROUTINE THROUGH THE JUMP VECTOR (#31). ;THE CHARACTER FROM THE KEYBOARD ;ROUTINE IS IN REGISTER 'E'. CHRINT: LXI H,CHARIN ;GET ADDRESS OF TEMP ;CHARACTER STORAGE. XRA A ;CLEAR ACCUMULATOR CMP M ;TEST FOR 'CHARIN' FOR ZERO JNZ CFIN ;IF NOT ZERO THEN IGNORE INPUT MOV A,E ;GET CHAR FROM 'E' ANI 127 ;STRIP UPPER BIT FOR ASCII MOV M,A ;PUT CHAR IN 'CHARIN' CFIN: EI ;ENABLE INTERRUPTS RET ;RETURN FROM INTERRUPT ;CI - THIS CHARACTER INPUT ROUTINE GETS A CHARACTER ; FROM THE TEMPORARY STORAGE LOCATION 'CHARIN' ; CLEARS THE KEYBOARD READY FLAG ; AND RETURNS WITH THE CHARACTER IN 'A'. ; IF THERE IS NO CHARACTER IN 'CHARIN', ; THEN 'CI' WILL HANG AND WAIT FOR ONE. CI: EI ;ENABLE INTERRUPTS CI10: LDA CHARIN ;GET CHARACTER CPI 0 ;HAVE A CHAR? JZ CI10 ;IF NOT,HANG FOR ONE PUSH PSW ;GOT ONE,NOW SAVE IT XRA A STA KBRDY ;CLEAR KEYBOARD READY FLAG STA CHARIN ;CLEAR TEMP STORAGE FOR NEXT CHAR POP PSW ;RESTORE CHAR RET GETNXT: CALL CI ;GET NEXT KEYBOARD CHARACTER MOV D,A ;STORE IN 'D' CPI LEFT ;BACKSPACE? JZ LEFTKEY ;JUMP TO BACKSPACE ROUTINE CPI HT ;TAB? JZ MAINFIN ;YES-JUMP TO END ROUTINE CPI CR ;RETURN? JZ MAINFIN ;YES - JUMP TO END ROUTINE CPI RIGHT ;CURSOR RIGHT JZ RGHTKEY ;PUT IT ON SCREEN CPI INSERT ;INSERT A NEW CHARACTER JZ INS10 CPI DELETE ;DELETE A CHARACTER JZ DEL10 CPI DELINE ;DELETE LINE CHAR JZ DLIN10 MOV A,B ;FIELD FULL? CMP E JZ GETNXT ;YES SO IGNORE LDA NA ;NUMERIC OR ALPHANUMERIC FIELD CPI 65 ;A=ALPHA JZ ALPHA NUMERIC:MOV A,D ;NUMERIC VALIDATION CPI NUMMAX ;RANGE TEST-MAXIMUM VALUE JNC GETNXT ;IGNORE CPI NUMMIN ; MINIMUM VALUE JC GETNXT ;IGNORE CPI SLASH ;= '/' JZ GETNXT ;IGNORE JMP KEYOK ;ACCEPT KEY ALPHA: MOV A,D ;ALPHANUMERIC VALIDATION CPI ALPHMAX ;RANGE TEST - MAXIMUM VALUE JNC GETNXT ;IGNORE CPI ALPHMIN ; MINIMUM VALUE JC GETNXT ;IGNORE KEYOK: CALL LO ;PUT IT ON SCREEN INR B ;INCREMENT FINAL COUNT JMP GETNXT ;GET NEXT CHAR MAINFIN: MVI A,3 ;PUT CURSOR OFF SCREEN CALL LO MVI A,64 CALL LO XRA A CALL LO CALL CNT10 ;SETUP FIELD COUNT FOR BASIC STA COUNT MOV E,D ;PUT LAST CHAR IN 'E' XRA A MOV D,A POP PSW ;RSTORE BASIC JUMP VECTOR # STA KBDFL POP H ;RESTORE USED REGISTERS POP PSW RET LEFTKEY: MOV A,B ;BACKSPACE SUBROUTINE CPI 0 ;IF ON FIRST CHAR JZ GETNXT ;THEN IGNORE DCR B ;DECREMENT CHAR COUNT MVI A,LEFT ;BACKSPACE CURSOR CALL LO JMP GETNXT RGHTKEY: MOV A,B ;RIGHT CURSOR FUNCTION CMP E ;CHECK IF FIELD FULL MOV A,D ;RESTORE CHARACTER JNZ KEYOK ;NO SO O.K. JMP GETNXT ;IGNORE ;INSERT A CHARACTER ROUTINE.... ;REGISTER USAGE:- ; A=NO OF CHARS ALREADY IN FIELD ; B=POSITION WITHIN FIELD ; C=NO OF CHARS TO SHUFFLE ; E=MAX NO OF CHARS IN FIELD INS10: CALL CNT10 ;DETERMINE SIZE OF FIELD RTN CPI 0 ;IGNORE IF NO CHARS IN FIELD JZ GETNXT PUSH D LHLD FLDADR ;SET UP HL DCX H DCX H SUB B ;CALCULATE NO OF CHARS JM INS55 ;RETURN IF PAST LAST CHAR (NAUGHTY!) JZ INS55 MOV C,A ;PUT IN C ADD B ;RESTORE A CMP E ;IS FIELD FULL JNZ INS20 ;NO DCX H ;YES - SO ARRANGE FOR LAST CHAR DCX H ;TO DISAPPEAR FROM FACE OF EARTH DCR C JZ INS55 ;IGNORE IF SITTING ON LAST CHAR INS20: MVI D,0 ;POSITION HL TO LAST CHAR MOV E,A DAD D DAD D LXI D,0FFFCH ;TO SUBTRACT 4 LATER ON INS30: MOV A,M ;GET CHAR FROM FIELD INX H INX H MOV M,A ;AND SHIFT UP INS40: DCR C ;ANY MORE? JZ INS50 ;NO DAD D ;YES POINT TO PREVIOUS CHAR JMP INS30 INS50: DCX H ;PUT A SPACE AT CURSOR POSITION DCX H MVI M,SPACE INS55: POP D JMP GETNXT ;RETURN ;DELETE A CHARACTER ROUTINE..... ;REGISTER USAGE:- ; A=NO OF CHARACTERS ALREADY IN FIELD (AFTER CNT10 CALL) ; B=POSITION WITHIN FIELD ; C=NO OF CHARACTERS TO SHUFFLE DEL10: CALL CNT10 ;DETERMINE SIZE OF FIELD CPI 0 ;IGNORE IF NOTHING IN IT JZ GETNXT PUSH D LHLD FLDADR ;SETUP HL INX H INX H SUB B ;CALCULATE NO OF CHARS MOV C,A ;TO SHUFFLE & PUT IN C DEL20: MOV E,B ;POSITION HL TO FIRST CHAR TO SHUFFLE MVI D,0 DAD D DAD D LXI D,4 ;TO ADD 4 LATER ON DEL25: DCR C JM DEL55 ;RETURN IF PAST LAST CHAR JNZ DEL30 ;SPECIAL TEST FOR LAST CHAR DCX H DCX H JMP DEL53 DEL30: MOV A,M ;GET CHAR FROM FIELD DCX H DCX H MOV M,A ;AND SHIFT UP DEL40: DCR C ;ANY MORE? JZ DEL50 ;NO DAD D ;YES - POINT TO NEXT ONE JMP DEL30 DEL50: INX H ;PUT A SPACE AT LAST INX H ;CHARACTER POSITION DEL53: MVI M,SPACE DEL55: POP D JMP GETNXT ;RETURN ;ROUTINE TO DELETE ALL THE REMAINING ;CHARACTERS IN THE FIELD DLIN10: CALL CNT10 ;GET NO OF CHARS IN FIELD PUSH D LHLD FLDADR ;START OF FIELD SUB B ;CALCULATE NO.OF CHARS TO DELETE JM DLIN40 ;IGNORE IF AT END JZ DLIN40 MOV C,A DLIN20: MVI D,0 ;SET H&L TO 1ST CHAR TO DELETE MOV E,B DAD D DAD D MVI A,SPACE DLIN30: MOV M,A ;DELETE CHARS DCR C ;ANY MORE? JZ DLIN40 ;NO INX H INX H JMP DLIN30 DLIN40: POP D JMP GETNXT ;ROUTINE TO DETERMINE THE EXACT LENGTH ;OF A FIELD ON THE SCREEN. ;FINAL COUNT IS PUT IN 'A'. CNT10: PUSH B ;SAVE IT LHLD FLDADR ;START OF FIELD DCX H DCX H MVI B,0 CNT20: MVI C,0 ;C WILL CONTAIN NO OF SPACES ;PAST THE END OF THE FIELD CNT30: MOV A,B ;B CONTAINS THE FIELD COUNT CMP E ;ARE WE AT MAXIMUM JZ CNT40 ;YES - FINISHED INX H ;GET TO NEXT CHAR INX H INR B ;ADD 1 TO COUNT MOV A,M CPI SPACE ;IS IT A SPACE JNZ CNT20 ;NOPE INR C ;INCREMENT SPACE COUNT JMP CNT30 ;BACK & SHUFFLE NEXT ONE CNT40: MOV A,B ;CALCULATE EXACT COUNT SUB C POP B ;RESTORE USED REGISTER RET END START