isr.cod
来自「怎样在win2000下构造驱动程序znsoft_Serial2000_demo.」· COD 代码 · 共 2,049 行 · 第 1/5 页
COD
2,049 行
; 300 :
; 301 : whichPort = 4;
; 302 :
; 303 : } else {
; 304 :
; 305 : whichPort = 5;
; 306 :
; 307 : }
; 308 :
; 309 : } else {
0004a eb 05 jmp SHORT $L14835
$L14831:
; 310 :
; 311 : if (statusRegister & 0x40) {
0004c c1 e8 06 shr eax, 6
0004f 0c 06 or al, 6
$L14835:
; 312 :
; 313 : whichPort = 6;
; 314 :
; 315 : } else {
; 316 :
; 317 : whichPort = 7;
; 318 :
; 319 : }
; 320 :
; 321 : }
; 322 :
; 323 : }
; 324 :
; 325 : if (dispatch->Extensions[whichPort]) {
00051 8b 44 86 04 mov eax, DWORD PTR [esi+eax*4+4]
00055 85 c0 test eax, eax
00057 74 af je SHORT $L14818
; 326 :
; 327 : if (SerialISR(
; 328 : InterruptObject,
; 329 : dispatch->Extensions[whichPort]
; 330 : )) {
00059 50 push eax
0005a ff 74 24 10 push DWORD PTR _InterruptObject$[esp+8]
0005e e8 00 00 00 00 call _SerialISR@8
00063 84 c0 test al, al
00065 74 a1 je SHORT $L14818
; 331 :
; 332 : servicedAnInterrupt = TRUE;
00067 b3 01 mov bl, 1
; 333 :
; 334 : }
; 335 :
; 336 : }
; 337 :
; 338 : }
; 339 :
; 340 : } while (statusRegister);
00069 eb 9d jmp SHORT $L14818
$L15193:
; 341 :
; 342 : return servicedAnInterrupt;
0006b 8a c3 mov al, bl
0006d 5e pop esi
0006e 5b pop ebx
; 343 :
; 344 : }
0006f c2 08 00 ret 8
_SerialBitMappedMultiportIsr@8 ENDP
_TEXT ENDS
PUBLIC _SerialProcessLSR@4
PUBLIC _SerialPutChar@8
EXTRN __imp__WRITE_PORT_BUFFER_UCHAR@12:NEAR
EXTRN __imp_@InterlockedIncrement@4:NEAR
EXTRN __imp_@InterlockedDecrement@4:NEAR
EXTRN _SerialInsertQueueDpc@16:NEAR
EXTRN _SerialSetRTS@4:NEAR
EXTRN _SerialHandleModemUpdate@8:NEAR
EXTRN __imp__KeInsertQueueDpc@12:NEAR
EXTRN __imp__WRITE_PORT_UCHAR@8:NEAR
; Function compile flags: /Ogsy
; COMDAT _SerialISR@8
_TEXT SEGMENT
_Context$ = 12
_ServicedAnInterrupt$ = 12
_ReceivedChar$14879 = -4
_SerialISR@8 PROC NEAR ; COMDAT
; 377 : {
00000 51 push ecx
00001 53 push ebx
00002 55 push ebp
00003 56 push esi
; 378 :
; 379 : //
; 380 : // Holds the information specific to handling this device.
; 381 : //
; 382 : PSERIAL_DEVICE_EXTENSION Extension = Context;
00004 8b 74 24 18 mov esi, DWORD PTR _Context$[esp+12]
00008 57 push edi
; 383 :
; 384 : //
; 385 : // Holds the contents of the interrupt identification record.
; 386 : // A low bit of zero in this register indicates that there is
; 387 : // an interrupt pending on this device.
; 388 : //
; 389 : UCHAR InterruptIdReg;
; 390 :
; 391 : //
; 392 : // Will hold whether we've serviced any interrupt causes in this
; 393 : // routine.
; 394 : //
; 395 : BOOLEAN ServicedAnInterrupt;
; 396 :
; 397 : UCHAR tempLSR;
; 398 :
; 399 : UNREFERENCED_PARAMETER(InterruptObject);
; 400 :
; 401 : //
; 402 : // Make sure we have an interrupt pending. If we do then
; 403 : // we need to make sure that the device is open. If the
; 404 : // device isn't open or powered down then quiet the device. Note that
; 405 : // if the device isn't opened when we enter this routine
; 406 : // it can't open while we're in it.
; 407 : //
; 408 :
; 409 : InterruptIdReg = READ_INTERRUPT_ID_REG(Extension->Controller);
00009 8b 3d 00 00 00
00 mov edi, DWORD PTR __imp__READ_PORT_UCHAR@4
0000f 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
00015 40 inc eax
00016 40 inc eax
00017 50 push eax
00018 ff d7 call edi
; 410 :
; 411 : //
; 412 : // Apply lock so if close happens concurrently we don't miss the DPC
; 413 : // queueing
; 414 : //
; 415 :
; 416 : InterlockedIncrement(&Extension->DpcCount);
0001a 8d 8e 30 06 00
00 lea ecx, DWORD PTR [esi+1584]
00020 8a d8 mov bl, al
00022 ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedIncrement@4
; 417 : LOGENTRY(LOG_CNT, 'DpI3', 0, Extension->DpcCount, 0);
; 418 :
; 419 : if ((InterruptIdReg & SERIAL_IIR_NO_INTERRUPT_PENDING)) {
; 420 :
; 421 : ServicedAnInterrupt = FALSE;
00028 33 ed xor ebp, ebp
0002a f6 c3 01 test bl, 1
0002d 74 0a je SHORT $L14849
0002f 80 64 24 1c 00 and BYTE PTR _ServicedAnInterrupt$[esp+16], 0
; 422 :
; 423 : } else if (!Extension->DeviceIsOpened
00034 e9 b8 05 00 00 jmp $L15226
$L14849:
; 424 : || (Extension->PowerState != PowerDeviceD0)) {
00039 80 be 9d 01 00
00 00 cmp BYTE PTR [esi+413], 0
00040 0f 84 54 05 00
00 je $L14852
00046 83 be a4 04 00
00 01 cmp DWORD PTR [esi+1188], 1
0004d 0f 85 47 05 00
00 jne $L14852
; 489 : } else {
; 490 :
; 491 : ServicedAnInterrupt = TRUE;
00053 c6 44 24 1c 01 mov BYTE PTR _ServicedAnInterrupt$[esp+16], 1
$L15238:
00058 8b 3d 00 00 00
00 mov edi, DWORD PTR __imp__WRITE_PORT_UCHAR@8
; 492 : do {
; 493 :
; 494 : //
; 495 : // We only care about bits that can denote an interrupt.
; 496 : //
; 497 :
; 498 : InterruptIdReg &= SERIAL_IIR_RLS | SERIAL_IIR_RDA |
; 499 : SERIAL_IIR_CTI | SERIAL_IIR_THR |
; 500 : SERIAL_IIR_MS;
0005e 83 e3 0e and ebx, 14 ; 0000000eH
; 501 :
; 502 : //
; 503 : // We have an interrupt. We look for interrupt causes
; 504 : // in priority order. The presence of a higher interrupt
; 505 : // will mask out causes of a lower priority. When we service
; 506 : // and quiet a higher priority interrupt we then need to check
; 507 : // the interrupt causes to see if a new interrupt cause is
; 508 : // present.
; 509 : //
; 510 :
; 511 : switch (InterruptIdReg) {
00061 2b dd sub ebx, ebp
00063 0f 84 68 01 00
00 je $L15016
00069 4b dec ebx
0006a 4b dec ebx
0006b 0f 84 b6 01 00
00 je $doTrasmitStuff$14914
00071 4b dec ebx
00072 4b dec ebx
00073 74 17 je SHORT $L14880
00075 4b dec ebx
00076 4b dec ebx
00077 74 08 je SHORT $L14877
00079 83 eb 06 sub ebx, 6
0007c e9 48 01 00 00 jmp $L15242
$L14877:
; 512 :
; 513 : case SERIAL_IIR_RLS: {
; 514 :
; 515 : SerialProcessLSR(Extension);
00081 56 push esi
00082 e8 00 00 00 00 call _SerialProcessLSR@4
; 516 :
; 517 : break;
00087 e9 4c 01 00 00 jmp $L14871
$L14880:
; 518 :
; 519 : }
; 520 :
; 521 : case SERIAL_IIR_RDA:
; 522 : case SERIAL_IIR_CTI:
; 523 :
; 524 : {
; 525 :
; 526 : //
; 527 : // Reading the receive buffer will quiet this interrupt.
; 528 : //
; 529 : // It may also reveal a new interrupt cause.
; 530 : //
; 531 : UCHAR ReceivedChar;
; 532 :
; 533 : do {
; 534 :
; 535 : ReceivedChar =
; 536 : READ_RECEIVE_BUFFER(Extension->Controller);
0008c ff b6 98 00 00
00 push DWORD PTR [esi+152]
00092 ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
; 537 : Extension->PerfStats.ReceivedCount++;
00098 ff 86 84 01 00
00 inc DWORD PTR [esi+388]
; 538 : Extension->WmiPerfData.ReceivedCount++;
0009e ff 86 18 06 00
00 inc DWORD PTR [esi+1560]
000a4 8a d8 mov bl, al
; 539 :
; 540 : ReceivedChar &= Extension->ValidDataMask;
000a6 22 9e d9 01 00
00 and bl, BYTE PTR [esi+473]
000ac 88 5c 24 10 mov BYTE PTR _ReceivedChar$14879[esp+20], bl
; 541 :
; 542 : if (!ReceivedChar &&
; 543 : (Extension->HandFlow.FlowReplace &
; 544 : SERIAL_NULL_STRIPPING)) {
000b0 75 0d jne SHORT $L14885
000b2 f6 86 78 01 00
00 08 test BYTE PTR [esi+376], 8
000b9 0f 85 f1 00 00
00 jne $ReceiveDoLineStatus$14886
$L14885:
; 545 :
; 546 : //
; 547 : // If what we got is a null character
; 548 : // and we're doing null stripping, then
; 549 : // we simply act as if we didn't see it.
; 550 : //
; 551 :
; 552 : goto ReceiveDoLineStatus;
; 553 :
; 554 : }
; 555 :
; 556 : if ((Extension->HandFlow.FlowReplace &
; 557 : SERIAL_AUTO_TRANSMIT) &&
; 558 : ((ReceivedChar ==
; 559 : Extension->SpecialChars.XonChar) ||
; 560 : (ReceivedChar ==
; 561 : Extension->SpecialChars.XoffChar))) {
000bf 8b 86 78 01 00
00 mov eax, DWORD PTR [esi+376]
000c5 a8 01 test al, 1
000c7 74 66 je SHORT $L14888
000c9 3a 9e 70 01 00
00 cmp bl, BYTE PTR [esi+368]
000cf 74 08 je SHORT $L14889
000d1 3a 9e 71 01 00
00 cmp bl, BYTE PTR [esi+369]
000d7 75 56 jne SHORT $L14888
$L14889:
; 562 :
; 563 : //
; 564 : // No matter what happens this character
; 565 : // will never get seen by the app.
; 566 : //
; 567 :
; 568 : if (ReceivedChar ==
; 569 : Extension->SpecialChars.XoffChar) {
000d9 3a 9e 71 01 00
00 cmp bl, BYTE PTR [esi+369]
000df 75 35 jne SHORT $L14890
; 570 :
; 571 : Extension->TXHolding |= SERIAL_TX_XOFF;
000e1 83 8e 1c 01 00
00 08 or DWORD PTR [esi+284], 8
; 572 :
; 573 : if ((Extension->HandFlow.FlowReplace &
; 574 : SERIAL_RTS_MASK) ==
; 575 : SERIAL_TRANSMIT_TOGGLE) {
000e8 66 25 c0 00 and ax, 192 ; 000000c0H
000ec 3c c0 cmp al, 192 ; 000000c0H
000ee 0f 85 bc 00 00
00 jne $ReceiveDoLineStatus$14886
; 576 :
; 577 : SerialInsertQueueDpc(
; 578 : &Extension->StartTimerLowerRTSDpc,
; 579 : NULL,
; 580 : NULL,
; 581 : Extension
; 582 : )?Extension->CountOfTryingToLowerRTS++:0;
000f4 56 push esi
000f5 55 push ebp
000f6 8d 86 4c 03 00
00 lea eax, DWORD PTR [esi+844]
000fc 55 push ebp
000fd 50 push eax
000fe e8 00 00 00 00 call _SerialInsertQueueDpc@16
00103 84 c0 test al, al
00105 0f 84 a5 00 00
00 je $ReceiveDoLineStatus$14886
0010b ff 86 3c 01 00
00 inc DWORD PTR [esi+316]
; 583 :
; 584 : }
; 585 :
; 586 :
; 587 : } else {
00111 e9 9a 00 00 00 jmp $ReceiveDoLineStatus$14886
$L14890:
; 588 :
; 589 : if (Extension->TXHolding & SERIAL_TX_XOFF) {
00116 8d 8e 1c 01 00
00 lea ecx, DWORD PTR [esi+284]
0011c 8b 01 mov eax, DWORD PTR [ecx]
0011e a8 08 test al, 8
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?