Category : Miscellaneous Language Source Code
Archive   : NEC-V20.ZIP
Filename : BENCHB.ASM

 
Output of file : BENCHB.ASM contained in archive : NEC-V20.ZIP
$TITLE(EDN Benchmark B - I/O Kernel with FIFO)

NAME BENCHB

;------------------------------------------------------------------------
; :
; EDN Benchmark B - Nested Interrupt Kernel Response :
; :
; :
;-----------------------------------------------------------------------
$INCLUDE(\SIII\VSERIES.MAC)

DEV80_ID EQU 00H
DEV81_ID EQU 02H
DEV82_ID EQU 04H
DEV83_ID EQU 06H
ON EQU 0FFH


CODE SEGMENT WORD PUBLIC

EXTRN EPILOGUE : NEAR, PROLOGUE : NEAR, PUTS : NEAR

ORG 0100H

ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE

MAIN PROC NEAR

;
; Begin by determining if the processor is a V20/V30 or a 8086/8088.
; In this case, a V20/V30 with set the least significant bit of the CW
; register, while an 8086/8088 will execute a POP CS and a SBC with an
; immediate operand. Since CW is cleared to begin with, if the contents
; of CW are not zero the processor must be a V20/V30.
;

MOV V20_V30, -1 ; Assume a V20/V30 microprocessor

PUSH CS ; Push the PS on stack

XOR CX, CX ; Clear the CW register
SET1 CX, 0 ; Execute the determining instruction

OR CX, CX ; Test if CW has changed value
JNZ VSERIES ; Continue with the V-Series demonstration

MOV V20_V30, 0 ; Set the V-Series flag
JMP UPD8086 ; And continue

VSERIES:
POP AX ; Restore the stack
; No pop was performed by V-Series processor

UPD8086:
MOV DX, OFFSET BENCH_B_STR ; Display the benchmark message
CALL PUTS

CALL PROLOGUE ; Initialize the demo

MOV CX, 20000 ; Do 20000 iterations

MOV AL, 80H ; Select INT Vector 80H
MOV AH, 25H ; Select the set INT Vector function
MOV DX, OFFSET DEV80_INTR ; Get the interrupt vector handler offset
PUSH CS ; Get the current code segment
POP DS ; Set as the interrupt handler code segment
INT 21H ; Install the interrupt handler

MOV AL, 81H ; Select INT Vector 81H
MOV AH, 25H ; Select the set INT Vector function
MOV DX, OFFSET DEV81_INTR ; Get the interrupt vector handler offset
PUSH CS ; Get the current code segment
POP DS ; Set as the interrupt handler code segment
INT 21H ; Install the interrupt handler

MOV AL, 82H ; Select INT Vector 82H
MOV AH, 25H ; Select the set INT Vector function
MOV DX, OFFSET DEV82_INTR ; Get the interrupt vector handler offset
PUSH CS ; Get the current code segment
POP DS ; Set as the interrupt handler code segment
INT 21H ; Install the interrupt handler

MOV AL, 83H ; Select INT Vector 83H
MOV AH, 25H ; Select the set INT Vector function
MOV DX, OFFSET DEV83_INTR ; Get the interrupt vector handler offset
PUSH CS ; Get the current code segment
POP DS ; Set as the interrupt handler code segment
INT 21H ; Install the interrupt handler

MOV CX, 5000 ; Perform 5,000 iterations of the benchmark

NEXT:
MOV QUEUE_IN, OFFSET QUEUE ; Initialize the queue pointer

INT 80H ; Level 0 interrupt
INT 81H ; Level 1 interrupt
INT 82H ; Level 2 interrupt
INT 83H ; Level 3 interrupt

INT 81H ; Level 1 interrupt
INT 81H ; Level 1 interrupt
INT 81H ; Level 1 interrupt

INT 82H ; Level 2 interrupt
INT 82H ; Level 2 interrupt
INT 82H ; Level 2 interrupt
INT 82H ; Level 2 interrupt
INT 82H ; Level 2 interrupt

LOOP NEXT ; Perform the next iteration

CALL EPILOGUE ; Display the results

INT 20H ; Return to DOS

MAIN ENDP

PUBLIC V20_V30

V20_V30 DB ?

BENCH_B_STR DB 'EDN Benchmark B - Interrupt Kernel Benchmark (5,000 Iterations)', 13, '$'

$EJECT
;--------------------------------------------------------------------------------
; :
; EDN Benchmark for the 8086 - Interrupt FIFO Processing Benchmark :
; :
; :
; Inputs :
; :
; None :
; :
; Outputs :
; :
; None :
; :
; Registers Modified :
; :
; None :
; :
;--------------------------------------------------------------------------------

DEV80_INTR PROC FAR

PUSH BX ; Save the working register set
PUSH AX
PUSH DI
PUSH DS

MOV DI, DEV80_ID ; Load the device ID

PUSH CS ; Get the address of the data segment
POP DS ; for the FIFO

MOV AX, QUEUE_IN ; Get the pointer to the next FIFO entry
MOV BX, AX

MOV [BX], DI ; Place the ID into the FIFO
ADD AL, 2 ; Update the FIFO input pointer
MOV QUEUE_IN, AX ; Save the updated queue_in pointer

MOV AL, ON ; Test and Set the RunFlag
XCHG AL, RUNFLAG
TEST AL, ON
JZ SERVICE_NEXT ; Go service this routine if no others
; are in the queue

POP DS ; Restore the registers
POP DI
POP AX
POP BX

IRET ; Exit

DEV80_INTR ENDP


DEV81_INTR PROC FAR

PUSH BX ; Save the working register set
PUSH AX
PUSH DI
PUSH DS

MOV DI, DEV81_ID ; Load the device ID

PUSH CS ; Get the address of the data segment
POP DS ; for the FIFO

MOV AX, QUEUE_IN ; Get the pointer to the next FIFO entry
MOV BX, AX

MOV [BX], DI ; Place the ID into the FIFO
ADD AL, 2 ; Update the FIFO input pointer
MOV QUEUE_IN, AX ; Save the updated queue_in pointer

MOV AL, ON ; Test and Set the RunFlag
XCHG AL, RUNFLAG
TEST AL, ON
JZ SERVICE_NEXT ; Go service this routine if no others
; are in the queue

POP DS ; Restore the registers
POP DI
POP AX
POP BX

IRET ; Exit

DEV81_INTR ENDP


DEV82_INTR PROC FAR

PUSH BX ; Save the working register set
PUSH AX
PUSH DI
PUSH DS

MOV DI, DEV82_ID ; Load the device ID

PUSH CS ; Get the address of the data segment
POP DS ; for the FIFO

MOV AX, QUEUE_IN ; Get the pointer to the next FIFO entry
MOV BX, AX

MOV [BX], DI ; Place the ID into the FIFO
ADD AL, 2 ; Update the FIFO input pointer
MOV QUEUE_IN, AX ; Save the updated queue_in pointer

MOV AL, ON ; Test and Set the RunFlag
XCHG AL, RUNFLAG
TEST AL, ON
JZ SERVICE_NEXT ; Go service this routine if no others
; are in the queue

POP DS ; Restore the registers
POP DI
POP AX
POP BX

IRET ; Exit

DEV82_INTR ENDP


DEV83_INTR PROC FAR

PUSH BX ; Save the working register set
PUSH AX
PUSH DI
PUSH DS

MOV DI, DEV83_ID ; Load the device ID

PUSH CS ; Get the address of the data segment
POP DS ; for the FIFO

MOV AX, QUEUE_IN ; Get the pointer to the next FIFO entry
MOV BX, AX

MOV [BX], DI ; Place the ID into the FIFO
ADD AL, 2 ; Update the FIFO input pointer
MOV QUEUE_IN, AX ; Save the updated queue_in pointer

MOV AL, ON ; Test and Set the RunFlag
XCHG AL, RUNFLAG
TEST AL, ON
JZ SERVICE_NEXT ; Go service this routine if no others
; are in the queue

POP DS ; Restore the registers
POP DI
POP AX
POP BX

IRET ; Exit

DEV83_INTR ENDP


SERVICE_NEXT PROC NEAR

CONTINUE_SERVICING:
MOV DI, [BX] ; Get the I/O ID
STI ; Enable further interrupts

DUMMY_IO_SERVICING:
INC INTR_COUNTERS[DI] ; Service the interrupt

RETURN_FROM_IO_SERVICING:
CLI ; Disable interrupts
ADD BL, 2 ; Remove this interrupt request from the FIFO
CMP BX, QUEUE_IN ; Test if done
JNE CONTINUE_SERVICING ; Get the next I/O request if more

XOR AX, AX ; No further I/O requests
MOV RUNFLAG, AL ; So reset the RunFlag

POP DS ; Restore the machine state
POP DI
POP AX
POP BX

IRET ; Return to the interrupted program

SERVICE_NEXT ENDP

ORG 0500H

QUEUE DW 128 DUP( 0 ) ; I/O FIFO Area
RUNFLAG DB 2 DUP( 0 ) ; RunFlag
QUEUE_IN DW ? ; Pointer to the next queue entry
INTR_COUNTERS DW 4 DUP( 0 ) ; I/O Interrupt counters


CODE ENDS

END MAIN


  3 Responses to “Category : Miscellaneous Language Source Code
Archive   : NEC-V20.ZIP
Filename : BENCHB.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/