;************************************************************** ;Put internal routines outside of CODE SEGMENT ;************************************************************** CWAIT MACRO ;Wait for bit 2 to set before writing to the COMMAND PORT LOCAL CWAIT_LOOP MOV DX,ADPORT1 CWAIT_LOOP: IN AL,DX ;Look at the ADPORT ROR AL,1 ;Rotate right 3 times to get bit 2 off ROR AL,1 ROR AL,1 JNC CWAIT_LOOP ;Loop if not set ENDM ;************************************************************** WWAIT MACRO ;Wait for bit 1 to become 0 before writing to the DATA PORT LOCAL WWAIT_LOOP MOV DX,ADPORT1 WWAIT_LOOP: IN AL,DX ;Look at the ADPORT ROR AL,1 ;Rotate right 2 times to get bit 1 off ROR AL,1 JC WWAIT_LOOP ;Loop if not reset MOV DX,ADPORT0 ENDM ;************************************************************** RWAIT MACRO ;Wait for bit 0 to set before reading from the DATA PORT LOCAL RWAIT_LOOP MOV DX,ADPORT1 RWAIT_LOOP: IN AL,DX ;Look at the ADPORT ROR AL,1 ;Rotate right 1 time to get bit 2 off JNC RWAIT_LOOP ;Loop if not set MOV DX,ADPORT0 ENDM ;************************************************************** ACODE SEGMENT PUBLIC 'CODE' ASSUME CS:ACODE ;************************************************************** ;Reserve spaces for data ;************************************************************** ADPORT0 DW 2ECH ;Address of (DATA REGISTER) port ADPORT1 DW 2EDH ;Address of (COMMAND/STATUS) port ADGAIN DB 0 ;Temporary storage of GAIN STORE1 DW 16 DUP(0) ;Lo-word used in ADIN04 & ADINC4 STORE2 DW 16 DUP(0) ;Hi-word used in ADIN04 & ADINC4 AD_BUF1 DW 0 AD_BUF2 DW 0 AD_BUF3 DW 0 LNGTH DW 2 DUP(0) ;************************************************************** PUBLIC ADIN00 ;ADIN00(CHAN,GAIN,VALUE) ADIN00 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV CL,ES:[BX] ;GAIN --> CL MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV CH,ES:[BX] ;CHAN --> CH ; CWAIT MOV AL,0CH ;-----------------------------------------------+ OUT DX,AL ;Function 0CH --> Read A/D Immediate I WWAIT ; I MOV AL,CL ; I OUT DX,AL ;Write GAIN to Data Port I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Write CHAN to Data Port I RWAIT ; I IN AL,DX ;Read the low byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the high byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ ; MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV ES:[BX],AX ;AX --> VALUE POP BP RET 12 ADIN00 ENDP ;************************************************************** PUBLIC ADIN01 ;ADIN01(NUM,CHAN,GAIN,VALUE) ;TAKE NUM OF SAMPLES AND ADD THEM ADIN01 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV AL,ES:[BX] ;GAIN --> AL MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV AH,ES:[BX] ;CHAN --> AH MOV BX,SS:[BP+12] MOV ES,SS:[BP+14] MOV CX,ES:[BX] ;NUM --> CX MOV BX,AX ;Now, GAIN --> BL; CHAN --> BH MOV SI,0 ;Reset DI*SI, which are used as the accumulator MOV DI,0 ADIN01_LOOP: CWAIT MOV AL,0CH ;-----------------------------------------------+ OUT DX,AL ;Function 0CH --> Read A/D Immediate I WWAIT ; I MOV AL,BL ; I OUT DX,AL ;Write GAIN to Data Port I WWAIT ; I MOV AL,BH ; I OUT DX,AL ;Write CHAN to Data Port I RWAIT ; I IN AL,DX ;Read the low byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the high byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ ADD SI,AX ;Add the data to DI SI JNC ADIN01A INC DI ADIN01A: JCXZ ADIN01_EXIT LOOP ADIN01_LOOP ;Loop back and read more times (CX = counter) ; MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV ES:[BX],SI ;Move the lo-word of VALUE MOV ES:[BX+2],DI ;Move the hi-word of VALUE ADIN01_EXIT: POP BP RET 16 ADIN01 ENDP ;************************************************************** PUBLIC ADIN02 ;ADIN02(CHAN1,CHAN2,GAIN,VALUE) ADIN02 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV SI,ES:[BX] ;GAIN --> SI MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV CL,ES:[BX] ;CHAN2 --> CL MOV BX,SS:[BP+12] MOV ES,SS:[BP+14] MOV CH,ES:[BX] ;CHAN1 --> CH MOV BX,SS:[BP] MOV ES,SS:[BP+2] ;get ready for the address of VALUE MOV DI,0 ;Pointer of INTEGER*2 VALUE(*) CMP CH,CL ;Make sure that CH (CHAN1) is =< CL (CHAN2) JLE ADIN02A MOV CL,CH ADIN02A: INC CL ;CL contains CHAN2+1 ADIN02_LOOP: CWAIT MOV AL,0CH ;-----------------------------------------------+ OUT DX,AL ;Function 0CH --> Read A/D Immediate I WWAIT ; I MOV AX,SI ; I OUT DX,AL ;Write GAIN to Data Port I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Write CHAN to Data Port I RWAIT ; I IN AL,DX ;Read the low byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the high byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ MOV ES:[BX][DI],AX ;AX --> VALUE ARRAY of 2-bytes INC DI ;Increment the value of pointer by 2 INC DI INC CH ;Next channel CMP CH,CL JNZ ADIN02_LOOP ;Loop if the current channel <> CHAN2+1 ; POP BP RET 16 ADIN02 ENDP ;************************************************************** PUBLIC RESADC ;RESADC ;RESET THE D/A BOARD RESADC PROC FAR PUSH BP MOV BP,SP MOV DX,ADPORT1 ;Do not wait before issuing the following command MOV AL,0FH OUT DX,AL ;Function 0FH --> Stop Command MOV CX,200H ;Loop 200H times to kill time RESADC_LOOP: DEC CX JNZ RESADC_LOOP IN AL,DX ;ADPORT1 --> AL AND AL,01 JZ RESADCB ;Jump over if bit 1 of STATUS is cleared MOV DX,ADPORT0 IN AL,DX ;Read Data Port so that it can be cleared RESADCB: CWAIT MOV AL,1H ;-----------------------------------------------+ OUT DX,AL ;Function 1 --> Clear Error CWAIT MOV AL,5H ;-----------------------------------------------+ OUT DX,AL ;Function 5 --> Set digital port for output I WWAIT ; I MOV AL,0H ; I OUT DX,AL ;00000000 --> Digital Port ---------------------+ POP BP RET RESADC ENDP ;************************************************************** PUBLIC DAOUT0 ;DAOUT0(CHAN,VALUE) DAOUT0 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV CH,ES:[BX] ;CHAN --> CH CMP CH,1 ;Make sure that CHAN is 0 or 1 JG DAOUT0_EXIT MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV AX,ES:[BX] MOV BX,AX ;VALUE --> BX ; CWAIT MOV AL,8 ;-----------------------------------------------+ OUT DX,AL ;Function 8 --> Write Immediate I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Write channel I WWAIT ; I MOV AL,BL ; I OUT DX,AL ;Write the lo byte to Data Port I WWAIT ; I MOV AL,BH ; I OUT DX,AL ;Write the hi byte to Data Port ----------------+ DAOUT0_EXIT: POP BP RET 8 DAOUT0 ENDP ;************************************************************** PUBLIC DAOUT1 ;DAOUT1(VALUE0,VALUE1) DAOUT1 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV CX,ES:[BX] ;VALUE1 --> CX MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV AX,ES:[BX] MOV BX,AX ;VALUE0 --> BX ; CWAIT MOV AL,8 ;-----------------------------------------------+ OUT DX,AL ;Function 8 --> Write Immediate I WWAIT ; I MOV AL,2 ; I OUT DX,AL ;Write channel (both) I WWAIT ; I MOV AL,BL ; I OUT DX,AL ;Write the lo byte (channel 0) to Data Port I WWAIT ; I MOV AL,BH ; I OUT DX,AL ;Write the hi byte (channel 0) to Data Port I WWAIT ; I MOV AL,CL ; I OUT DX,AL ;Write the lo byte (channel 1) to Data Port I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Write the hi byte (channel 1) to Data Port ----+ ; POP BP RET 8 DAOUT1 ENDP ;************************************************************** ;************************************************************** ;************************************************************** PUBLIC SETCLK SETCLK PROC FAR ;SETCLK(NUM) PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV CX,ES:[BX] ;NUM --> CX ; CWAIT MOV AL,3 ;-----------------------------------------------+ OUT DX,AL ;Function 3 --> Set Internal Clock Period I WWAIT ; I MOV AL,CL ; I OUT DX,AL ;Write the lo byte of period I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Write the hi byte of period -------------------+ ; POP BP RET 4 SETCLK ENDP ;************************************************************** PUBLIC SETAD0 SETAD0 PROC FAR ;SETAD0(NUM,CHAN1,CHAN2,GAIN) PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV SI,ES:[BX] ;GAIN --> SI MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV CL,ES:[BX] ;CHAN2 --> CL MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV CH,ES:[BX] ;CHAN1 --> CH MOV BX,SS:[BP+12] MOV ES,SS:[BP+14] MOV DX,ES:[BX] MOV BX,DX ;NUM --> BX ; CWAIT CMP BX,0 ;Continuous & DMA Operation JNE SETAD0A MOV BX,0FFFFH ;Dummy NUM MOV AL,3DH OUT DX,AL ;Function 3DH --> Set A/D Parameters (Block) JMP SETAD0_CONT SETAD0A: CMP BX,1 ;DMA JNE SETAD0B MOV BX,0FFFFH ;Dummy NUM MOV AL,1DH OUT DX,AL ;Function 1DH --> Set A/D Parameters (Block) JMP SETAD0_CONT SETAD0B: CMP BX,2 ;Continuous JNE SETAD0C MOV BX,0FFFFH ;Dummy NUM MOV AL,2DH OUT DX,AL ;Function 1DH --> Set A/D Parameters (Block) JMP SETAD0_CONT SETAD0C: MOV AL,0DH OUT DX,AL ;Function 0DH --> Set A/D Parameters (Block) ---+ ; SETAD0_CONT: WWAIT ; I MOV AX,SI ; I OUT DX,AL ;Write GAIN to Data Port I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Write CHAN1 to Data Port I WWAIT ; I MOV AL,CL ; I OUT DX,AL ;Write CHAN2 to Data Port I WWAIT ; I MOV AL,BL ; I OUT DX,AL ;Write the lo byte of NUM to Data Port I WWAIT ; I MOV AL,BH ; I OUT DX,AL ;Write the hi byte of NUM to Data Port ---------+ ; POP BP RET 16 SETAD0 ENDP ;************************************************************** PUBLIC ADIN03 ADIN03 PROC FAR ;ADIN03(NUM1,NUM2,VALUES) PUSH BP MOV BP,SP ADD BP,6 MOV AD_BUF1,SP ;Save the Stack Pointer in memory MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV SI,ES:[BX] ;NUM2 --> SI (Number of conversions in one cycle) MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV SP,ES:[BX] ;NUM1 --> SP (Number of channels to scan) DEC SP ;NUM1-1 --> SP MOV BX,SS:[BP] MOV ES,SS:[BP+2] ;get ready for the address of VALUE MOV DI,0 ;Pointer of INTEGER*2 VALUE(*) MOV CX,0 ;Reset the counter ; CWAIT MOV AL,0EH ;-----------------------------------------------+ OUT DX,AL ;Function 0EH --> Read A/D in Block Mode I JMP ADIN03A ADIN03_LOOP: INC CX ;CX = CX+1 CMP CX,SI JNZ ADIN03A MOV CX,0 ;IF CX = SI, THEN CX = 0 (i.e. start a new cycle) ADIN03A: MOV DX,ADPORT1 ADIN03_WAIT: ;This wait section is the same for all block modes IN AL,DX ;Read from the Status Register ROL AL,1 JC ADIN03_EXIT ;Check Bit 7: Composite Error; Exit if set ROR AL,1 ROR AL,1 JC ADIN03_READ ;Check Bit 0: Ready to read if set --> goto READ ROR AL,1 ROR AL,1 JC ADIN03_EXIT ;Check Bit 2: Ready to issue new command; --> Exit JMP ADIN03_WAIT ;Not ready --> Loop back & wait until ready ADIN03_READ: MOV DX,ADPORT0 ; I IN AL,DX ;Read the lo byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the hi byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ ; CMP CX,SP JA ADIN03_LOOP ;IF counter <= # channel to scan, THEN ;save result MOV ES:[BX][DI],AX ;AX --> VALUE ARRAY of 2-bytes INC DI ;Increment the value of memory pointer by 2 INC DI JMP ADIN03_LOOP ;Loop back to take more data ADIN03_EXIT: MOV SP,AD_BUF1 ;Restore the Stack Pointer from memory POP BP RET 12 ADIN03 ENDP ;************************************************************** PUBLIC ADIN04 ADIN04 PROC FAR ;ADIN04(NUM1,NUM2,VALUES) PUSH BP MOV BP,SP ADD BP,6 MOV AD_BUF1,SP ;Save the Stack Pointer in memory MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV SI,ES:[BX] ;NUM2 --> (SI temporarily) MOV AD_BUF2,SI ;NUM2 --> BUF2 (i.e. # conversions per cycle) MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV SP,ES:[BX] ;NUM1 --> (SP temporarily) MOV AX,SP ADD AX,SP MOV AD_BUF3,AX ;2*NUM1 --> BUF3 (i.e. twice of # channels to scan) SUB SI,SP MOV SP,SI ;NUM2 - NUM1 --> SP MOV BX,SS:[BP] MOV ES,SS:[BP+2] ;get ready for the address of VALUE ;Initialize STORE1 and STORE0 to 0 MOV SI,32 ;# bytes of temporary storage for STORE1 or STORE2 ADIN04_INIT: MOV STORE1[SI-2],0 MOV STORE2[SI-2],0 DEC SI DEC SI JNZ ADIN04_INIT MOV SI,0FFFEH ;Set SI=-2 (SI points to offset in STORE) ; MOV DI,0 ;Pointer of INTEGER*2 VALUE(*) MOV CX,0 ;Reset the counter ; CWAIT MOV AL,0EH ;-----------------------------------------------+ OUT DX,AL ;Function 0EH --> Read A/D in Block Mode I JMP ADIN04A ADIN04_LOOP: INC CX ;CX = CX+1 CMP CX,AD_BUF2 JNZ ADIN04A MOV CX,0 ;IF CX = BUF2, THEN CX = 0 (i.e. start a new cycle) ADIN04A: MOV DX,ADPORT1 ADIN04_WAIT: ;This wait section is the same for all block modes IN AL,DX ;Read from the Status Register ROL AL,1 JC ADIN04_EXIT ;Check Bit 7: Composite Error; Exit if set ROR AL,1 ROR AL,1 JC ADIN04_READ ;Check Bit 0: Ready to read if set --> goto READ ROR AL,1 ROR AL,1 JC ADIN04_EXIT ;Check Bit 2: Ready to issue new command; --> Exit JMP ADIN04_WAIT ;Not ready --> Loop back & wait until ready ADIN04_READ: MOV DX,ADPORT0 ; I IN AL,DX ;Read the lo byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the hi byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ ; ;Add new value to stored ones: INC SI ;Calculate index INC SI CMP SI,AD_BUF3 JNZ ADIN04B MOV SI,0 ;If SI = 2*NUM1, THEN SI=0 (i.e. start a new cycle) ADIN04B: ADD STORE1[SI],AX ;Add the current result to the lo-word JNC NOCARRY1 INC STORE2[SI] ;Add the carry to the hi-word NOCARRY1: CMP CX,SP JB ADIN04_LOOP ;IF counter <= # channel to scan, THEN ;add the accumulated result and zero fields MOV AX,STORE1[SI] MOV ES:[BX][DI],AX ;Lo-word of result --> INTEGER*4 VALUE(*) MOV STORE1[SI],0 ;Reset the temporary memory INC DI ;Increment the value of memory pointer by 2 INC DI MOV AX,STORE2[SI] MOV ES:[BX][DI],AX ;Hi-word of result --> INTEGER*4 VALUE(*) MOV STORE2[SI],0 ;Reset the temporary memory INC DI ;Increment the value of memory pointer by 2 INC DI JMP ADIN04_LOOP ;Loop back to take more data ADIN04_EXIT: MOV SP,AD_BUF1 POP BP RET 12 ADIN04 ENDP ;************************************************************** PUBLIC ADINC3 ADINC3 PROC FAR ;ADINC3(LENGTH,NUM1,NUM2,VALUES) PUSH BP MOV BP,SP ADD BP,6 MOV AD_BUF1,SP ;Save the Stack Pointer in memory MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV SI,ES:[BX] ;NUM2 --> SI (Number of conversions in one cycle) MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV SP,ES:[BX] ;NUM1 --> SP (Number of channels to scan) DEC SP ;NUM1-1 --> SP MOV BX,SS:[BP+12] MOV ES,SS:[BP+14] MOV AX,ES:[BX] MOV LNGTH[0],AX ;Lo-word of LENGTH --> LNGTH[0] MOV AX,ES:[BX+2] MOV LNGTH[2],AX ;Hi-word of LENGTH --> LNGTH[0] MOV BX,SS:[BP] MOV ES,SS:[BP+2] ;get ready for the address of VALUE MOV DI,0 ;Pointer of INTEGER*2 VALUE(*) MOV CX,0 ;Reset the counter ; CWAIT MOV AL,0EH ;-----------------------------------------------+ OUT DX,AL ;Function 0EH --> Read A/D in Block Mode I JMP ADINC3A ADINC3_LOOP: INC CX ;CX = CX+1 CMP CX,SI JNZ ADINC3A MOV CX,0 ;IF CX = SI, THEN CX = 0 (i.e. start a new cycle) ADINC3A: DEC LNGTH[0] ;LENGTH = LENGTH - 1 JNC ADINC3B DEC LNGTH[2] ;Subtract the carry from the hi-word JC ADINC3_EXIT ;IF LENGTH < 0, THEN exit ADINC3B: MOV DX,ADPORT1 ADINC3_WAIT: ;This wait section is the same for all block modes IN AL,DX ;Read from the Status Register ROL AL,1 JC ADINC3_EXIT ;Check Bit 7: Composite Error; Exit if set ROR AL,1 ROR AL,1 JC ADINC3_READ ;Check Bit 0: Ready to read if set --> goto READ ROR AL,1 ROR AL,1 JC ADINC3_EXIT ;Check Bit 2: Ready to issue new command; --> Exit JMP ADINC3_WAIT ;Not ready --> Loop back & wait until ready ADINC3_READ: MOV DX,ADPORT0 ; I IN AL,DX ;Read the lo byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the hi byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ ; CMP CX,SP JA ADINC3_LOOP ;IF counter <= # channel to scan, THEN ;save result MOV ES:[BX][DI],AX ;AX --> VALUE ARRAY of 2-bytes INC DI ;Increment the value of memory pointer by 2 INC DI JMP ADINC3_LOOP ;Loop back to take more data ADINC3_EXIT: MOV SP,AD_BUF1 ;Restore the Stack Pointer from memory POP BP RET 16 ADINC3 ENDP ;************************************************************** PUBLIC ADINC4 ADINC4 PROC FAR ;ADINC4(LENGTH,NUM1,NUM2,VALUES) PUSH BP MOV BP,SP ADD BP,6 MOV AD_BUF1,SP ;Save the Stack Pointer in memory MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV SI,ES:[BX] ;NUM2 --> (SI temporarily) MOV AD_BUF2,SI ;NUM2 --> BUF2 (i.e. # conversions per cycle) MOV BX,SS:[BP+8] MOV ES,SS:[BP+10] MOV SP,ES:[BX] ;NUM1 --> (SP temporarily) MOV AX,SP ADD AX,SP MOV AD_BUF3,AX ;2*NUM1 --> BUF3 (i.e. twice of # channels to scan) SUB SI,SP MOV SP,SI ;NUM2 - NUM1 --> SP MOV BX,SS:[BP+12] MOV ES,SS:[BP+14] MOV AX,ES:[BX] MOV LNGTH[0],AX ;Lo-word of LENGTH --> LNGTH[0] MOV AX,ES:[BX+2] MOV LNGTH[2],AX ;Hi-word of LENGTH --> LNGTH[0] MOV BX,SS:[BP] MOV ES,SS:[BP+2] ;get ready for the address of VALUE ;Initialize STORE1 and STORE0 to 0 MOV SI,32 ;# bytes of temporary storage for STORE1 or STORE2 ADINC4_INIT: MOV STORE1[SI-2],0 MOV STORE2[SI-2],0 DEC SI DEC SI JNZ ADINC4_INIT MOV SI,0FFFEH ;Set SI=-2 (SI points to offset in STORE) ; MOV DI,0 ;Pointer of INTEGER*2 VALUE(*) MOV CX,0 ;Reset the counter ; CWAIT MOV AL,0EH ;-----------------------------------------------+ OUT DX,AL ;Function 0EH --> Read A/D in Block Mode I JMP ADINC4A ADINC4_LOOP: INC CX ;CX = CX+1 CMP CX,AD_BUF2 JNZ ADINC4A MOV CX,0 ;IF CX = BUF2, THEN CX = 0 (i.e. start a new cycle) ADINC4A: DEC LNGTH[0] JNC ADINC4B DEC LNGTH[2] JC ADINC4_EXIT ADINC4B: MOV DX,ADPORT1 ADINC4_WAIT: ;This wait section is the same for all block modes IN AL,DX ;Read from the Status Register ROL AL,1 JC ADINC4_EXIT ;Check Bit 7: Composite Error; Exit if set ROR AL,1 ROR AL,1 JC ADINC4_READ ;Check Bit 0: Ready to read if set --> goto READ ROR AL,1 ROR AL,1 JC ADINC4_EXIT ;Check Bit 2: Ready to issue new command; --> Exit JMP ADINC4_WAIT ;Not ready --> Loop back & wait until ready ADINC4_READ: MOV DX,ADPORT0 ; I IN AL,DX ;Read the lo byte from Data Port I MOV AH,AL ; I RWAIT ; I IN AL,DX ;Read the hi byte from Data Port I XCHG AH,AL ;-----------------------------------------------+ ; ;Add new value to stored ones: INC SI ;Calculate index INC SI CMP SI,AD_BUF3 JNZ ADINC4C MOV SI,0 ADINC4C: ADD STORE1[SI],AX JNC NOCARRY2 INC STORE2[SI] ;Add the carry to the hi-word NOCARRY2: CMP CX,SP JB ADINC4_LOOP ;IF counter <= # channel to scan, THEN ;add the accumulated result and zero fields MOV AX,STORE1[SI] MOV ES:[BX][DI],AX ;Lo-word of result --> INTEGER*4 VALUE(*) MOV STORE1[SI],0 ;Reset the temporary memory INC DI ;Increment the value of memory pointer by 2 INC DI MOV AX,STORE2[SI] MOV ES:[BX][DI],AX ;Hi-word of result --> INTEGER*4 VALUE(*) MOV STORE2[SI],0 ;Reset the temporary memory INC DI ;Increment the value of memory pointer by 2 INC DI JMP ADINC4_LOOP ;Loop back to take more data ADINC4_EXIT: MOV SP,AD_BUF1 POP BP RET 16 ADINC4 ENDP ;************************************************************** PUBLIC DDOUT0 ;DDOUT0(IPORT) ;Reset digital I/O ports as output; IPORT=0,1,2 DDOUT0 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV CH,ES:[BX] ;IPORT --> CH ; CWAIT ;-----------------------------------------------+ MOV AL,5 ; I OUT DX,AL ;Function 5 --> Set Digital Port for Output I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Enable IPORT I CWAIT ; I MOV AL,7 ; I OUT DX,AL ;Function 7 --> Write Digital Port Immediate I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Get ready to write to IPORT I WWAIT ; I MOV AL,0 ; I OUT DX,AL ;Reset all channels in port 0 or 1 I CMP CH,2 ;See if additional port needs to be reset I JL DDOUT0_EXIT ; I WWAIT ; I MOV AL,0 ; I OUT DX,AL ;Reset all channels in port 1 ------------------+ DDOUT0_EXIT: POP BP RET 4 DDOUT0 ENDP ;************************************************************** PUBLIC DDOUT1 ;DDOUT1(IPORT,IVALUE) ;Output digital information through I/O ports as output; IPORT=0,1,2 DDOUT1 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV CH,ES:[BX] ;IPORT --> CH MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV AX,ES:[BX] MOV BX,AX ;IVALUE --> BX ; CWAIT ;-----------------------------------------------+ MOV AL,7 ; I OUT DX,AL ;Function 7 --> Write Digital Port Immediate I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Get ready to write to IPORT I WWAIT ; I MOV AL,BL ; I OUT DX,AL ;Write to channels in port 0 or 1 I CMP CH,2 ;See if additional port needs information I JL DDOUT1_EXIT ; I WWAIT ; I MOV AL,BH ; I OUT DX,AL ;Write to next set of channels -----------------+ DDOUT1_EXIT: POP BP RET 8 DDOUT1 ENDP ;************************************************************** PUBLIC DDIN00 ;DDIN00(IPORT) ;Reset digital I/O ports as input; IPORT=0,1,2 DDIN00 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV CH,ES:[BX] ;IPORT --> CH ; CWAIT ;-----------------------------------------------+ MOV AL,4 ; I OUT DX,AL ;Function 4 --> Set Digital Port for Input I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Enable IPORT ----------------------------------+ DDIN00_EXIT: POP BP RET 4 DDIN00 ENDP ;************************************************************** PUBLIC DDIN01 ;DDIN01(IPORT,IVALUE) ;Output digital information through I/O ports as output; IPORT=0,1,2 DDIN01 PROC FAR PUSH BP MOV BP,SP ADD BP,6 MOV BX,SS:[BP+4] MOV ES,SS:[BP+6] MOV CH,ES:[BX] ;IPORT --> CH ; CWAIT ;-----------------------------------------------+ MOV AL,6 ; I OUT DX,AL ;Function 6 --> Read Digital Port Immediate I WWAIT ; I MOV AL,CH ; I OUT DX,AL ;Get ready to read from IPORT I RWAIT ; I IN AL,DX ;Read from channels in port 0 or 1 I MOV AH,AL ; I CMP CH,2 ;See if additional port needs to be read I JL DDIN01_EXIT ; I RWAIT ; I IN AL,DX ;Read from the next set of channels ------------+ DDIN01_EXIT: XCHG AH,AL MOV BX,SS:[BP] MOV ES,SS:[BP+2] MOV ES:[BX],AX ;AX --> IVALUE POP BP RET 8 DDIN01 ENDP ;************************************************************** ACODE ENDS END