; ; CONSOLE.A86 ; DBIOS EQU 50 ;Access BIOS through BDOS DCONSTAT EQU 2 ;BIOS console status DCONIN EQU 3 ;BIOS console input DCONOUT EQU 4 ;BIOS console out DLIST EQU 5 ;BIOS list out DLISTST EQU 15 ;BIOS list status ; ;Console I/O routines for MODEM9.xx. ; SHOW: CMP AL,LF JZ CTYPE CMP AL,CR JZ CTYPE CMP AL,9 JZ CTYPE CMP AL,' ' JC SHOWHEX CMP AL,7FH JC CTYPE SHOWHEX: PUSH AX MOV AL,'(' CALL CTYPE POP AX CALL HEXO MOV AL,')' JMP CTYPE ; CTYPE: PUSH CX PUSH DX PUSH BX MOV DL,AL MOV CL,WRCON INT 224 POP BX POP DX POP CX RET ; CRLF: PUSH AX MOV AL,CR CALL TIPE MOV AL,LF CALL TIPE POP AX RET ; TIPE: PUSH SI PUSH CX PUSH DX PUSH BX ; AND AL,07FH MOV Byte Ptr TBLOCK1,AL MOV CL,DBIOS MOV DX,Offset TIPEBLOCK INT 224 POP BX POP DX POP CX POP SI RET ; TIPEBLOCK DB DCONOUT TBLOCK1 DW 0 DW 0 ; STAT: PUSH CX PUSH DX PUSH BX MOV CL,DBIOS MOV DX,Offset STATBLOCK INT 224 POP BX POP DX POP CX OR AL,AL RET ; STATBLOCK: DB DCONSTAT DW 0 DW 0 ; KEYIN: PUSH CX PUSH DX PUSH BX KEYIN1: MOV CL,DBIOS MOV DX,Offset KEYBLOCK INT 224 POP BX POP DX POP CX RET ; KEYBLOCK: DB DCONIN DW 0 DW 0 ; LISTER: PUSH CX PUSH DX PUSH BX MOV CH,0 ; MJM 9.01.05 MOV LBLOCK1,CX ; MJM 9.01.05 MOV DX,Offset LSTBLOCK MOV CL,DBIOS INT 224 POP BX POP DX POP CX RET ; LSTBLOCK DB DLIST LBLOCK1 DW 0 DW 0 ; LSTSTAT: PUSH CX PUSH DX PUSH BX MOV DX, OFFSET LSTSTATBLOCK MOV CL,DBIOS INT 224 POP BX POP DX POP CX OR AL,AL RET LSTSTATBLOCK: DB DLISTST DW 0 DW 0 ; ; UCASE: CMP AL,61H ;CHANGES LOWER CASE CHARACTER.. JC UCASERET ;..IN 'AL' REG TO UPPER CASE. CMP AL,7BH JNC UCASERET AND AL,5FH UCASERET: RET ; DECOUT: PUSH AX PUSH CX PUSH DX PUSH BX MOV CX, -10 MOV DX, -1 DECOU2: ADD BX,CX INC DX JC DECOU2 MOV CX,OFFSET 10 ADD BX,CX XCHG BX,DX MOV AL,BH OR AL,BL JZ DECOU3 CALL DECOUT DECOU3: MOV AL,DL ADD AL,'0' CALL CTYPE POP BX POP DX POP CX POP AX RET ; ;----> DHXOUT: - DOUBLE PRECISION HEX OUTPUT ROUTINE. ; DHXOUT: PUSH BX PUSH AX MOV AL,BH ;GET MS BYTE CALL HEXO ;OUTPUT HIGH ORDER BYTE MOV AL,BL ;GET LS BYTE CALL HEXO ;OUTPUT LOW ORDER BYTE POP AX POP BX RET ; HEXO: PUSH AX RCR AL,1 RCR AL,1 RCR AL,1 RCR AL,1 CALL NIBBL POP AX NIBBL: AND AL,0FH CMP AL,10 JC ISNUM ADD AL,7 ISNUM: ADD AL,'0' JMP TIPE ; SHFTYPE: PUSH AX CALL ILPRT DB 'ctrl-',0 POP AX ADD AL,40H CALL TIPE ; ;WRITE A STRING OF CHARACTERS ; ILPRT: POP SI ILPLP: LODS BYTE PTR [SI] OR AL,AL JZ ILPRET CALL TIPE JMPS ILPLP ILPRET: PUSH SI RET ; ;WRITE A STRING OF CHARACTERS EXCEPT IN QUIET MODE ; ILPRTQ: POP SI ILPLPQ: LODS BYTE PTR [SI] OR AL,AL JZ ILPRETQ TEST QFLG,0FFH JZ ILPLPQ1 CALL TIPE ILPLPQ1: JMPS ILPLPQ ILPRETQ: PUSH SI RET ; ; ;Duplicates 'read buffer' routine same as CP/M function 10, ;but does not use CTL-C (reason for the routine). Does ;allow controls U, R, E and H (backspace). Outputs bell if ;the input is greater than the buffer. ; INBUFF: LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH BX PUSH CX PUSH DX ;'DX' REGISTERS MUST BE PUSHED LAST ISTART: CALL CLEAR ;CLEAR THE BUFFER AREA POP DX ;GET ADDRESS OF BUFFER ON RETRIES PUSH DX ;RESTORE STACK XOR AL,AL LAHF ;ADDRESS COUNT FIELD INC DX SAHF MOV SI,DX ;INITIALIZE WITH A ZERO IN COUNT BYTE MOV [SI],AL LAHF INC DX SAHF XCHG BX,DX ;ADDRESS FIRST BUFFER BYTE WITH 'BX' INBUFA: CALL CONIN CMP AL,CR ;IS IT A RETURN? JNZ INBUFA_1 JMP INBUFR ;IF SO, THEN RETURN INBUFA_1: CMP AL,7FH ;IS IT A DELETE? JZ DELETE CMP AL,8 ;CTL-H WILL BACKSPACE.. JZ DELETE ;..OVER DELETED CHAR. CMP AL,'U'-40H ;IS IT A CTL-U JNZ INBUFA_2 JMP INBUFO ;OUTPUT # CR-LF AND START OVER INBUFA_2: CMP AL,'R'-40H ;CTL-R RETYPES LINE JNZ INBUFA_3 JMP RETYPE INBUFA_3: CMP AL,'E'-40H JNZ INBUFA_4 JMP CRLF INBUFA_4: CMP AL,' ' ;NO CONTROL CHARACTERS OTHER.. JB INBUFA ;..THAN ABOVE ALLOWED. MOV CH,AL ;SAVE INPUTTED CHARACTER XCHG BX,DX ;SAVE 'BX' IN 'DX' POP BX ;GET ADDRESS OF BUFFER IN 'BX' PUSH BX ;RESTORE STACK INC BX ;ADDRESS COUNT BYTE INC Byte Ptr [BX] ;INCREASE COUNT BYTE DEC BX ;ADDRESS MAXIMUM MOV AL,Byte Ptr [BX] ;PUT MAXIMUM IN 'AL' INC BX ;ADDRESS COUNT CMP AL,Byte Ptr [BX] ;COMPARE COUNT TO MAXIMUM JNB INBUFA_5 JMP ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR INBUFA_5: XCHG BX,DX ;RESTORE BUFFER POINTER TO 'BX' MOV Byte Ptr [BX],CH ;PUT INPUTTED CHARACTER IN BUFFER MOV AL,CH ;OUTPUT IT CALL TIPE LAHF ;BUMP POINTER INC BX SAHF JMPS INBUFA ;GET NEXT CHARACTER ; DELETE: XCHG BX,DX ;SAVE BUFFER POINTER IN 'DX' POP BX ;ADDRESS BEGINNING OF BUFFER PUSH BX ;RESTORE STACK INC BX ;ADDRESS COUNT FIELD MOV CH,AL ;SAVE DELETE CHAR - 7FH OR 08H MOV AL,Byte Ptr [BX] SUB AL,1 ;DECREASE COUNT MOV Byte Ptr [BX],AL JB NODEL ;DON'T DELETE PAST BEGINING OF BUFFER. XCHG BX,DX ;RESTORE BUFFER POINTER TO 'BX' DEC BX ;POINT TO LAST BYTE INPUTTED MOV AL,CH ;GET BACK EITHER 7FH OR 08H MOV CH,Byte Ptr [BX] ;GET CHARACTER BEING DELETED MOV Byte Ptr [BX],' ' ;RESTORE BLANK CMP AL,8 JZ BKSPC CMP AL,7FH JZ BKSPC0 JMP INBUFA ;GET NEXT CHARACTER ; NODEL: INC Byte Ptr [BX] ;DON'T LEAVE COUNT NEGATIVE XCHG BX,DX ;RESTORE POINTER TO 'BX' JMP INBUFA ; BKSPC0: MOV AL,08H BKSPC: CALL TIPE ;TRUE ERASE IF 08H MOV AL,' ' CALL TIPE MOV AL,8 CALL TIPE JMP INBUFA ; INBUFO: MOV AL,'#' CALL TIPE CALL CRLF JMP ISTART ; RETYPE: POP DX PUSH DX LAHF ;POINT TO CURRENT NUMBER.. INC DX SAHF MOV SI,DX ;..OF CHARACTERS. MOV AL,[SI] MOV CH,AL MOV AL,'#' CALL TIPE CALL CRLF MOV AL,CH ;TEST IF ZERO INPUT OR AL,AL JNZ CTLRLP JMP INBUFA CTLRLP: LAHF INC DX SAHF MOV SI,DX MOV AL,[SI] CALL TIPE DEC CH JNZ CTLRLP JMP INBUFA ; ALERT: MOV AL,7 CALL TIPE DEC Byte Ptr [BX] XCHG BX,DX JMP INBUFA ; PCRLF: CALL CRLF JMP INBUFA ; INBUFR: CALL CRLF POP DX POP CX POP BX POP AX XCHG AL,AH SAHF RET ; CLEAR: POP DX ;ACCOUNTS FOR CALL POP BX ;ADDRESS BUFFER IN 'BX' PUSH BX ;RESTORE.. PUSH DX ;..STACK MOV CH,Byte Ptr [BX] ;SAVE MAXIMUM IN 'CH' LAHF ;POINT TO FIRST.. INC BX SAHF LAHF ;..BUFFER BYTE. INC BX SAHF MOV AL,' ' CLEARL: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ CLEARL RET ; CONIN: CALL KEYIN CMP AL,61H ;CHANGE TO UPPER.. JB NOUCASE ;..CASE SINCE CP/M.. CMP AL,7BH ;..DOES THE SAME. JNB NOUCASE AND AL,5FH NOUCASE: RET ; ;Parses a CP/M buffer into format same as CP/M command line. ; ;Loads a command line addressed by 'DX' registers (max # characters in ;line in 'DX', number of characters in the line in 'DX'+1, line starts ;in 'DX'+2) into FCB addressed by 'BX' registers. The FCB should be at ;least 33 bytes in length. The command line buffer must have a maximum ;length of at least one more than the greatest number of characters ;that will be needed. ; CPMLINE: PUSH AX PUSH CX PUSH DX PUSH BX CALL CINIT ;FILLS FCBS WITH BLANKS AND NULLS XCHG BX,DX ;GET START OF COMMAND LINE IN 'BX' INC BX ;ADDRESS # BYTES IN CMD LINE MOV DL,BYTE PTR [BX] ;LOAD 'DX' PAIR WITH # BYTES MOV DH,0 INC BX ADD BX,DX ;POINT TO BYTE AFTER LAST CHAR.. MOV BYTE PTR [BX],CR ;..IN CMD LINE AND STORE DELIMITER POP BX ;RESTORE 'BX' AND 'DX' POP DX PUSH DX PUSH BX INC DX ;ADDRESS START OF COMMAND INC DX CALL DRIVE NAME1: MOV CL,8 ;TRANSFER FIRST FILENAME TO FCB CALL TRANS CMP AL,CR JZ CDONE CMP AL,' ' ;IF SPACE, THEN START OF.. JZ NAME2 ;..SECOND FILENAME. TYPE1: POP BX ;FILETYPE MUST BE AFTER.. PUSH BX ;..EIGHTH BYTE OF NAME MOV CX, 9 ADD BX,CX MOV CL,3 ;TRANSFER TYPE OF FIRST FILE CALL TRANS CMP AL,CR JZ CDONE NAME2: XCHG BX,DX MOV AL,BYTE PTR [BX] ;EAT MULTIPLE SPACES.. XCHG BX,DX CMP AL,' ' ;..BETWEEN NAMES JNZ NAME2C INC DX JMP NAME2 NAME2C: POP BX ;SECOND NAME STARTS IN 16TH BYTE PUSH BX ;POINT 'BX' TO THIS BYTE MOV CX, 16 ADD BX,CX CALL DRIVE MOV CL,8 CALL TRANS CMP AL,CR JZ CDONE TYPE2: POP BX ;SECOND TYPE STARTS IN 25TH BYTE. PUSH BX MOV CX,OFFSET 25 ADD BX,CX MOV CL,3 CALL TRANS CDONE: POP BX PUSH BX INC BX ;POINT TO 1ST CHAR OF 1ST NAME IN FCB CALL CSCAN ;CHECK FOR * (AMBIGUOUS NAMES). POP BX PUSH BX MOV CX,OFFSET 17 ;POINT TO 1ST CHAR OF 2ND NAME IN FCB. ADD BX,CX CALL CSCAN POP BX POP DX POP CX POP AX RET ; CINIT: PUSH BX ;INITIALIZES FCB WITH 1 NULL (FOR 1ST DRIVE),.. PUSH CX ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE).. MOV BYTE PTR [BX],0 ;..11 BLANKS, AND 4 NULLS INC BX MOV CH,11 MOV AL,' ' CALL INITFILL MOV CH,5 MOV AL,0 CALL INITFILL MOV CH,11 MOV AL,' ' CALL INITFILL MOV CH,4 MOV AL,0 CALL INITFILL POP CX POP BX RET ; INITFILL: MOV BYTE PTR [BX],AL INC BX DEC CH JNZ INITFILL RET ; DRIVE: INC DX ;CHECK 2ND BYTE OF FILENAME. IF IT.. XCHG BX,DX MOV AL,BYTE PTR [BX] ;..IS A ":", THEN DRIVE WAS SPECIFIED XCHG BX,DX DEC DX CMP AL,':' JNZ DEFDR ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO) XCHG BX,DX MOV AL,BYTE PTR [BX] XCHG BX,DX AND AL,5FH SUB AL,40H ;CALCULATE DRIVE (A=1, B=2,...).. MOV BYTE PTR [BX],AL ;..AND PLACE IT IN FCB INC DX ;ADDRESS FIRST BYTE OF.. INC DX ;..IN CMD LINE.. DEFDR: INC BX ;..AND NAME FIELD IN FCB DEFDRRET: RET ; TRANS: XCHG BX,DX MOV AL,BYTE PTR [BX] XCHG BX,DX ;TRANSFER FROM CMD LINE TO FCB.. INC DX ;..UP TO NUMBER OF CHARS SPECIFIED.. CMP AL,CR ;..BY 'CL' REG. KEEP SCANNING FIELD.. JZ DEFDRRET ;..WITHOUT TRANSFER UNTIL A DELIMITING.. CMP AL,'.' ;..FIELD CHAR SUCH AS '.', BLANK, OR.. JZ DEFDRRET ;..C/R (FOR END OF CMD LINE) CMP AL,' ' JZ DEFDRRET DEC CL JB TRANS ;ONCE 'CL' REG IS LESS THAN '0' KEEP READING MOV BYTE PTR [BX],AL ;..CMD LINE BUT DO NOT TRANSFER TO FCB INC BX JMP TRANS ; CSCAN: MOV CH,8 ;SCAN FILE NAME ADDRESSED BY 'BX' TSTNAM: MOV AL,BYTE PTR [BX] CMP AL,'*' ;IF '*' FOUND, FILL IN REST OF FIELD.. JZ FILL1 ;..WITH '?' FOR AMBIGUOUS NAME INC BX DEC CH JNZ TSTNAM JMP TSTTYP ; FILL1: CALL FILL TSTTYP: MOV CH,3 ;SCAN AND FILL TYPE FIELD FOR NAME.. TSTTYPL: MOV AL,BYTE PTR [BX] ;..SPECIFIED ABOVE CMP AL,'*' JZ FILL2 INC BX DEC CH JZ FILL2RET JMP TSTTYPL ; FILL2: CALL FILL FILL2RET: RET ; FILL: MOV BYTE PTR [BX],'?' ;ROUTINE TRANSFERS '?' INC BX DEC CH JNZ FILL RET ; ; ;In-line compare. Compares string addressed by 'DX' pair to string af- ;the call (ends with '0'). Return with carry set means strings not the ;same. All registers (except 'AL') are unaffected. ; ILCOMP: POP SI ; POINT 'SI' TO 1ST CHARACTER PUSH BX MOV BX,SI PUSH DX ILCOMPL: MOV AL,BYTE PTR [BX] ; 'BX' POINTS TO IN-LINE STRING OR AL,AL ;END OF STRING IF ZERO JZ SAME XCHG BX,DX MOV AL,BYTE PTR [BX] XCHG BX,DX CMP AL,BYTE PTR [BX] JNZ NOTSAME INC BX INC DX JMP ILCOMPL ; NOTSAME: MOV AL,0 ;IF NOT SAME, FINISH THRU.. NSLP: INC BX ;..STRING SO RETURN WILL.. CMP AL,BYTE PTR [BX] ;..GO TO INSTRUCTION AFTER.. JNZ NSLP ;..STRING AND NOT REMAINDER OF STRING STC SAME: POP DX INC BX ;AVOIDS A NOP INSTRUCTION.. MOV SI,BX ;..WHEN RETURNING POP BX PUSH SI RET ;