PAGE ,132 ; SUMMA SKETCH ADI DRIVER FOR AUTOSKETCH ; BY PATRICK SWAYNE 01-FEB-90 ; COPYRIGHT 1990 BY PATRICK SWAYNE. ALL RIGHTS RESERVED. ADIINT EQU 79H ;ADI INTERRUPT USED BY THIS DRIVER JMPF MACRO DB 0EAH ;DEFINE FAR JUMP ENDM BIOS SEGMENT AT 40H ORG 6CH TICCNT LABEL WORD ;PC TIC COUNTER BIOS ENDS CODE SEGMENT ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE ; DEFINE SOME MEMORY LOCATIONS ORG 1 PSPSEG LABEL WORD ;PROGRAM SEGMENT PREFIX SEGMENT ADDR. ORG 3 MCBSIZE LABEL WORD ;MEMORY CONTROL BLOCK SIZE ORG 2CH ENVSEG LABEL WORD ;ENVIRONMENT SEGMENT ORG 5DH FCBARG LABEL BYTE ;FCB ARGUMENT ORG 100H START: JMP SETUP ;GO SET UP PROGRAM EVEN SIG DB 'ADISUM 1.0' ;PROGRAM SIGNATURE XFACT DW 3420 ;X RESOLUTION FACTOR YFACT DW 4956 ;Y RESOLUTION FACTOR M9FLG DB 0 ;MM961 FLAG UNFLG DB 0 ;UNLOAD FLAG ADIVEC DW 0,0 ;ADI INT. VECTOR PORT DW 3D8H ;PORT TEMP DW 0 ;TEMPORARY STORAGE OLDBUT DB 0 ;OLD BUTTON VALUE PAKBUF DB 5 DUP (0) ;TABLET PACKET BUFFER ; ADI INTERRUPT PROCESSOR ADIPROC:CMP AX,1 ;INITIALIZE DRIVER? JNZ NOTINI ;NO JMP INIT ;ELSE, DO INITIALIZATION NOTINI: CMP AX,3 ;SENSE? JZ SENSE ;YES IRET ;ELSE, DON'T PROCESS ; PROCESS SENSE COMMAND SENSE: CLD PUSH DS PUSH CS POP DS ;PUT DS HERE MOV AL,'P' CALL WPORT ;COMMAND TABLET TO SEND REPORT CALL GETPAK ;GET PACKET JNC PAKOK ;GOT IT BADPAK: XOR AX,AX ;BAD TABLET, RETURN NOTHING POP DS IRET PAKOK: MOV BL,PAKBUF ;GET FIRST BYTE OF PACKET XOR BH,BH ;INCLASE BUTTON NO. RETURNED TEST BL,80H ;TEST PHASE BIT JZ BADPAK ;PACKET OUT OF PHASE AND BL,7 ;ISOLATE BUTTON BITS MOV AL,OLDBUT ;GET OLD BUTTON VALUE MOV OLDBUT,BL ;SAVE NEW ONE CMP AL,BL ;HAS BUTTON STATUS CHANGED? JNZ GOTBUT ;YES XOR BL,BL ;ELSE, SAY NO BUTTONS DOWN GOTBUT: MOV AX,2 ;ASSUME TRACKING REPORT OR BL,BL ;ANY BUTTONS PRESSED? JZ GETCOR ;NO, GET COORDINATES INC AL ;ASSUME PICK REPORT CMP BL,1 ;PICK BUTTON PRESSED? JZ GETCOR ;YES, GET COORDINATES MOV AL,5 ;ELSE, MUST BE MENU PICK MOV CL,PAKBUF+3 ;GET Y COORD LOW SHL CL,1 ;SHIFT UP ONE PLACE MOV CH,PAKBUF+4 ;GET Y COORD HIGH CALL CONPAK ;CONVERT TO ADI VALUE MOV DX,CX ;RESULT TO DX MOV CL,PAKBUF+1 ;GET X COORD LOW SHL CL,1 ;SHIFT UP ONE PLACE MOV CH,PAKBUF+2 ;GET X COORD HIGH CALL CONPAK ;CONVERT TO ADI VALUE POP DS IRET GETCOR: MOV CL,PAKBUF+1 ;GET X COORD LOW SHL CL,1 ;SHIFT UP ONE PLACE MOV CH,PAKBUF+2 ;GET X COORD HIGH CALL CONPAK ;CONVERT TO ADI VALUE MOV BX,CX ;RESULT TO BX MOV CL,PAKBUF+3 ;GET Y COORD LOW SHL CL,1 ;SHIFT UP ONE PLACE MOV CH,PAKBUF+4 ;GET Y COORD HIGH CALL CONPAK ;CONVERT TO ADI VALUE POP DS IRET ; INITIALIZE DIGITIZER INIT: PUSH DS PUSH CS POP DS ;PUT DS HERE ; PROGRAM PORT MOV BX,PORT ;GET PORT NO. MOV DX,BX ;PORT TO DX CLI INC DX MOV AL,0 OUT DX,AL ;CLEAR INTERRUPTS ADD DX,3 ;MOVE TO MODEM CONTROL REGISTER MOV AL,13H OUT DX,AL ;SET LOOP-BACK MODE DEC DX ;MOVE TO CONTROL REGISTER MOV AL,80H OUT DX,AL ;SET DIVISOR LATCH MOV DX,BX BAUDL: MOV AL,0CH ;GET 9600 BAUD VALUE OUT DX,AL ;SET UP BAUD RATE INC DX ;MOVE TO HIGH LATCH BAUDH: MOV AL,0 OUT DX,AL ;SET 9600 BAUD ADD DX,2 WORDL: MOV AL,0BH ;8 BITS, ODD PARITY OUT DX,AL ;SET WORD LENGTH, ETC. MOV DX,BX IN AL,DX ;CLEAR PORT IN AL,DX ;AGAIN ADD DX,4 MOV AL,3 OUT DX,AL ;KILL LOOP-BACK MODE STI ; SET UP TABLET MOV AL,0 CALL WPORT ;RESET TABLET MOV AX,40H MOV DS,AX ASSUME DS:BIOS MOV AX,TICCNT ;GET TIC COUNT ADD AX,2 ;ADD TWO TICKS WAITLP: CMP AX,TICCNT JNZ WAITLP ;WAIT TWO TICKS PUSH CS POP DS ;FIX DS ASSUME DS:CODE MOV AL,'w' CALL WPORT ;ASK FOR TEST RESULTS XOR BX,BX ;CLEAR BL CALL RPORT ;GET RESULT JC BADTAB ;BAD TABLET MOV BL,AL ;SAVE RESULT IN BL MOV BH,1 ;INDICATE ABLE TO READ PORT TEST AL,80H ;DID TEST PASS? JNZ TABOK ;TABLET IS OK BADTAB: XOR AX,AX POP DS IRET ;RETURN INDICATING BAD INIT TABOK: MOV AL,'D' CALL WPORT ;SET REQUEST MODE ; MOV AL,'j' ; CALL WPORT ;SET RESOLUTION TO 1000 LPI MOV AL,'r' CALL WPORT ;COMMAND RESOLUTION CHANGE MOV AL,BYTE PTR XFACT CALL WPORT ;SET X RES. LOW MOV AL,BYTE PTR XFACT+1 CALL WPORT ;SET X RES. HIGH MOV AL,BYTE PTR YFACT CALL WPORT ;SET Y RES. LOW MOV AL,BYTE PTR YFACT+1 CALL WPORT ;SET Y RES. HIGH MOV AX,1 ;INDICATE GOOD INITIALIZATION MOV BX,1 ;INDICATE DIGITIZING TABLET MOV CX,0 ;INDICATE CONTINUOUS SAMPLES POP DS IRET ; SUBROUTINES ; GET PORT INPUT STATUS PINST: MOV DX,PORT ;GET PORT ADD DX,5 ;MOVE TO STATUS PORT IN AL,DX ;READ STATUS AND AL,1 ;IS CHARACTER READY? RET ; READ PORT RPORT: PUSH CX PUSH ES MOV CX,40H MOV ES,CX ;POINT TO BIOS RAM ASSUME ES:BIOS MOV CX,ES:TICCNT ;GET TIC COUNTER ADD CX,18*2 ;ADD 2 SECONDS RPORTL: CALL PINST ;GET STATUS JNZ RPORT1 ;WE HAVE SOMETHING CMP CX,ES:TICCNT ;TIMED OUT? JNZ RPORTL ;IF NOT, TRY AGAIN ASSUME ES:CODE POP ES POP CX TIMOUT: MOV AX,0E07H INT 10H ;RING BELL STC RET RPORT1: POP ES POP CX MOV DX,PORT ;GET PORT IN AL,DX ;READ DATA CLC RET ; OUTPUT TO PORT WPORT: PUSH AX ;SAVE DATA MOV DX,PORT ;GET PORT ADD DX,5 ;MOVE TO STATUS PORT POUTST: IN AL,DX ;READ STATUS AND AL,20H ;READY TO TRANSMIT? JZ POUTST ;WAIT UNTIL READY POP AX ;GET CHARACTER SUB DX,5 ;BACK UP TO DATA PORT OUT DX,AL ;TRANSMIT CHARACTER RET ; GET A PACKET FROM THE TABLET. PLACE IN PAKBUF GETPAK: PUSH ES PUSH CS POP ES ;PUT ES HERE MOV DI,OFFSET PAKBUF ;POINT TO BUFFER PUSH DI MOV AL,0 MOV CX,5 REP STOSB ;CLEAR BUFFER POP DI MOV CX,5 GETPLP: CALL RPORT ;READ FROM PORT JC GETPX STOSB ;STORE CHARACTER LOOP GETPLP ;LOOP UNTIL DONE GETPX: POP ES RET ; CONVERT PACKET VALUE INTO ADI VALUE CONPAK: CMP M9FLG,1 ;MM961? JZ CON9 MOV TEMP,CX SHL CX,1 ;* 4 ADD CX,TEMP ;* 6 CONP1: CMP CX,20480 ;SCALE VALUE JBE CXOK MOV CX,20480 CXOK: RET CON9: SHL CX,1 ;* 4 SHL CX,1 ;* 8 JMP CONP1 ; INT 28H PROCESSOR. USED FOR UN-INSTALLING ADISUM. INT28: CMP CS:UNFLG,1 ;UN-INSTALL ADISUM? JZ UNINS ;YES JMPF INT28V DW 0,0 ;ELSE, EXIT UNINS: PUSH CS POP DS ;POINT TO THIS SEGMENT XOR AX,AX MOV ES,AX ;AND TO INT. SEGMENT MOV SI,OFFSET ADIVEC ;POINT TO ADI INT VECTOR MOV DI,ADIINT*4 ;WHERE IT GOES CLD CLI MOVSW ;RESTORE VECTOR MOVSW MOV SI,OFFSET INT28V ;POINT TO INT 28 VECTOR MOV DI,28H*4 ;WHERE IT GOES MOVSW ;RESTORE VECTOR MOVSW PUSH CS POP ES ;PUT ES HERE MOV AH,49H INT 21H ;RELEASE THIS PROGRAM'S MEMORY MOV ES,ENVSEG ;POINT TO ENVIRONMENT SEGMENT MOV AH,49H INT 21H ;RELEASE ENVIRONMENT SEGMENT STI ;ENABLE INTERRUPTS INT 20H ;EXIT ENDRES: ;END OF RESIDENT CODE ; SET UP KEYBOARD INTERRUPT PROCESSOR SETUP: MOV DX,OFFSET SIGNON MOV AH,9 INT 21H ;PRINT SIGN-ON CLD MOV AH,52H INT 21H ;GET MEMORY CONTROL BLOCK ADDR. MOV AX,ES:[BX-2] ;GET FIRST MCB SEGMENT MOV DS,AX ;POINT TO IT FNDLP: MOV AX,PSPSEG ;GET PSP SEGMENT MOV DX,CS CMP AX,DX ;IN THIS SEGMENT? JAE CHKFND ;IF SO, CHECK IF ADISUM FOUND MOV ES,AX ;ELSE, PSP SEGMENT TO ES MOV SI,OFFSET SIG MOV DI,SI PUSH DS ;SAVE MCB SEGMENT PUSH CS POP DS ;PUT DS HERE MOV CX,5 ;6 WORDS IN SIGNATURE REPZ CMPSW ;IS ADISUM HERE? JZ GOTCC ;WE FOUND ADISUM MOV LSTSEG,ES ;SAVE PSP SEGMENT FNDNXT: POP DS ;RESTORE MCB SEGMENT MOV AX,MCBSIZE ;GET MCB SIZE INC AX ;CORRECT IT MOV BX,DS ADD AX,BX ;CALCULATE NEXT MCB SEGMENT MOV DS,AX ;POINT TO IT JMP FNDLP ;TRY AGAIN GOTCC: MOV FNDSEG,ES ;SAVE SEGMENT WHERE FOUND MOV BYTE PTR FNDFLG,1 ;MARK PROGRAM FOUND JMP FNDNXT CHKFND: PUSH CS POP DS ;FIX DS CMP BYTE PTR FNDFLG,1 ;WAS ADISUM FOUND? JNZ NOTFND ;NO MOV ES,FNDSEG ;GET SEGMENT WHERE FOUND CMP FCBARG,'U' ;UNINSTALL? JZ DOUNIN MOV DX,OFFSET ALMSG MOV AH,9 INT 21H ;SAY "ADISUM ALREADY IN" INT 20H DOUNIN: MOV BX,FNDSEG ;GET SEGMENT WHERE FOUND CMP BX,LSTSEG ;COMPARE WITH LAST PSP FOUND JNC UNLOK ;OK TO UNLOAD MOV DX,OFFSET NOUNMSG MOV AH,9 INT 21H ;ELSE, SAY "CAN'T UNLOAD" INT 20H UNLOK: MOV DX,OFFSET UNMSG MOV AH,9 INT 21H ;PRINT UNLOAD MESSAGE MOV ES:UNFLG,1 ;FLAG UNLOAD DESIRED INT 20H ;AND EXIT NOTFND: CMP FCBARG,'U' ;UNINSTALL? JNZ DOINS ;NO MOV DX,OFFSET NINMSG MOV AH,9 INT 21H ;ELSE, SAY "ALREADY UNLOADED" INT 20H ;AND EXIT DOINS: PUSH CS POP ES ;FIX ES CMP FCBARG,' ' ;ANY ARGUMENT JNZ GOTARG ;YES MOV AL,0 ;ELSE, USE COM1 JMP PORTOK GOTARG: MOV AL,FCBARG ;ELSE, GET SPECIFIED PORT SUB AL,'1' ;REMOVE ASCII JB BADPORT CMP AL,3 JBE PORTOK BADPORT:MOV DX,OFFSET BPMSG MOV AH,9 INT 21H ;SAY "BAD PORT" INT 20H ;AND EXIT PORTOK: MOV BX,40H MOV DS,BX ;POINT TO BIOS RAM SHL AL,1 ;DOUBLE IT CBW ;MAKE IT A WORD XOR SI,SI ;POINT TO COM PORTS ADD SI,AX ;POINT TO THE ONE USED MOV BX,[SI] ;GET IT PUSH CS POP DS ;FIX DS OR BX,BX JNZ SETPRT ;SET UP PORT OR SI,SI ;TESTING COM1? JZ BADPORT ;BAD PORT XOR AL,AL ;ELSE, TRY COM1 JMP PORTOK SETPRT: MOV PORT,BX ;STORE PORT NUMBER PUSH DS ;SAVE DS XOR AX,AX MOV DS,AX ;DS AT 0 MOV SI,OFFSET ADIINT*4 ;POINT TO ADI INTERRUPT MOV DI,OFFSET ADIVEC ;PUT OLD VECTOR HERE PUSH SI CLI ;TURN OFF INTERRUPTS CLD MOVSW ;MOVE VECTOR MOVSW POP SI MOV WORD PTR [SI],OFFSET ADIPROC ;PUT IN MY VECTOR MOV 2[SI],CS ;AND THIS SEGMENT MOV SI,OFFSET 28H*4 ;POINT TO INT 28 VECTOR MOV DI,OFFSET INT28V PUSH SI MOVSW ;COPY INT 28 VECTOR MOVSW POP SI MOV WORD PTR [SI],OFFSET INT28 ;SET NEW ONE MOV 2[SI],CS STI POP DS MOV DX,OFFSET INMSG MOV AH,9 INT 21H ;SAY "ADISUM INSTALLED" MOV DX,OFFSET ENDRES ;POINT TO END OF RES. CODE INT 27H ;EXIT, LEAVE PROGRAM HERE LSTSEG DW 0 ;LAST PSP SEGMENT (SHOULD BE < PSPSEG) FNDSEG DW 0 ;SEGMENT WHERE FOUND FNDFLG DB 0 ;PROGRAM FOUND FLAG SIGNON DB 13,10,'ADI SummaSketch (MM series) Driver, v. 1.0',13,10 DB 'By Patrick Swayne, HUG Software Engineer',13,10 DB "Copyright (C) 1990 by Heath/Zenith Users' Group",13,10,10,'$' INMSG DB 'ADISUM is now installed.',13,10 DB 'To uninstall, type ADISUM U.',13,10,'$' ALMSG DB 'ADISUM is already installed.',13,10,'$' UNMSG DB 'ADISUM is now uninstalled.',13,10,'$' NOUNMSG DB "ADISUM is not the last TSR. Can't uninstall.",13,10,'$' NINMSG DB "ADISUM is already not installed.",13,10,'$' BPMSG DB 'Bad port specified.',13,10,'$' CODE ENDS END START