5 * Partition Surprise Team <surprise-dev@lists.sourceforge.net>
7 * $Id: int13sniff.S,v 1.4 2001/02/13 00:47:18 kratochvil Exp $
13 * Sniffer for INT13 calls
15 * Prepare your floppy and reboot from it with 0x80 disk for boot-sniffing:
16 * ANY DATA ON YOUR FLOPPY (/dev/fd0) WILL BE ERASED BY THIS COMMAND!
24 /* !!! All defines below must be COMMENTED-OUT !
25 * !!! Define to value 0 has no effect.
28 /* Enable of normal screen dump output.
29 * You can probably never need to undefine it, only if it severly
30 * harms some needed (fullscreen) application display output.
32 #define SCREEN_PRINT 1
34 /* Enable (if defined) dump output to all serials found
36 #define SERIAL_BAUDRATE 9600
38 /* Enable to refuse dumping output to port without DSR active
39 * - pro: doesn't get slow by dumping to not-connected ports
40 * - con: some cables may not have DSR (DTR<->DSR wiring would be sufficient)
42 #define SERIAL_REQUIRE_DSR
44 /* Enable to dump all messages back to floppy
45 * - con: message output is slowed down a bit
46 * WARNING: some BIOSes fail to report geometry (INT 0x13/AH=0x08) for HDD!
48 #define OUTPUT_STORE_DISK 0x00
50 /* Linear sector offset where to start writing buffer sectors
51 * If undefined, it is calculated to be the last sector of "int13sniff.bin".
52 #define OUTPUT_STORE_ADDRESS -1
55 /* Stack size to reserve in the top-memory area
56 * WARNING: Due to SECTORS_LEN reading, this value MUST be always >=
57 * than the sector size (0x200)!
59 #define STACKSIZE_TOP 0x200
61 /* Maintainers: Disable occupying of any (0x13 & 0x18) interrupt vectors
62 #define DISABLE_SNIFF 1
65 /* Maintainers: Disable .org macroinstructions: ONLY FOR compilation tuning!
66 * - image produced doen't have any functionality!
71 /* Internal defines */
72 #define SERIAL_SENDWAIT 16 /* multiplied by 0x10000, Linux kernel has ~15 (looping 1E6 times) */
73 #define SERIAL_LCR_INIT (UART_LCR_WLEN8) /* 8N1, no DLAB */
74 #define SERIAL_MCR_INIT (UART_MCR_DTR | UART_MCR_RTS) /* we are RTSed! */
75 #define MEM_KBYTES 0x413 /* BIOS variable */
76 #define PORTADDR_BASE 0x400 /* BIOS variable */
77 #define SECTOR2_MAGIC 0xEFBE
78 #define SERIAL_DIVISOR (115200/SERIAL_BAUDRATE)
79 #define OUTPUT_STORE_WRITE_RETRIES 5 /* how many times to try Write16 & ResetDisk sequence */
80 #define OUTPUT_STORE_EOF 26
82 #define DIVIDE_UP(what,by) (((what)+(by)-1)/(by))
83 #define ROUND_UP(what,by) (DIVIDE_UP((what),(by))*(by))
85 #define ALLOC_KB DIVIDE_UP((ALLOC_END-START)+STACKSIZE_TOP,0x400)
86 #define SECTORS_LEN ((SECTORS_END-START)/0x200)
89 #define NIBBLE_TO_HEX1(nibble) ('0'+(nibble)+('A'-('9'+1))*((nibble&8)&&((nibble&2)||(nibble&4))))
90 #define NIBBLE_TO_HEX(nibble) NIBBLE_TO_HEX1((nibble)&0xF)
91 #define BYTE_TO_HEX(byte) NIBBLE_TO_HEX((byte)>>4),NIBBLE_TO_HEX((byte))
93 /* Extract from <linux/serial_reg.h>: */
94 #define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
95 #define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
96 #define UART_IER 1 /* Out: Interrupt Enable Register (DLAB=0) */
97 #define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
98 #define UART_LCR 3 /* Out: Line Control Register */
99 #define UART_MCR 4 /* Out: Modem Control Register */
100 #define UART_LSR 5 /* In: Line Status Register */
101 #define UART_MSR 6 /* In: Modem Status Register */
103 #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
104 #define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
106 #define UART_MCR_RTS 0x02 /* RTS complement */
107 #define UART_MCR_DTR 0x01 /* DTR complement */
109 #define UART_MSR_DSR 0x20 /* Data Set Ready */
111 #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
117 movw $0x0E00 | \char,%ax
131 #define MYORG(offset)
133 #define MYORG(offset) .org (offset) + START /* "+ START" MUST be on the end of line - WHY?!? */
156 #define PUSHALL_SIZE (7*2)
157 #define PUSHALL_SI ((1/*%bp*/+1/*%di*/)*2)
159 .macro CallJumpVector0x13
160 pushf /* create 'lret' stack by this pushf... */
161 pushw %cs /* ...this segment... */
162 call JumpVector0x13 /* ...and this return address */
167 /* Code starts here */
168 /********************/
170 #ifdef HAVE_GAS_ARCH_I8086
180 cli /* just a paranoia, shouldn't be needed */
181 jmp InitRawStack /* We don't want to have 0x90 on offset 2 (one of recognization rules by DOS) */
184 .macro places offset length string
185 .org (\offset) + START
187 .org (\offset) + (\length) + START /* we can't check whether it isn't too short :-( */
189 .macro placex offset length bytes
190 .org (\offset) + START
192 .org (\offset) + (\length) + START /* we can't check whether it isn't too short :-( */
195 /* We rather supply empty (=zeroed) FAT filesystem table
197 places 0x03,8,"I13Sniff" /* OEM ID */
198 placex 0x43,4,"0x5E,0x81,0xA2,0x99" /* Volume Serial Number: 5E81A299 as "SERIAL99" */
199 places 0x47,11,"Int13Sniff\0" /* Volume Label */
200 places 0x52,8,"BootOnly" /* Filesystem ID */
210 ljmp $0x7C0/*segment*/ , $InitContinue7C0-START/*offset*/
215 /* move to top memory */
216 xorw %dx,%dx /* DX=null */
218 movw %ds:MEM_KBYTES,%ax
220 movw %ax,%ds:MEM_KBYTES
224 xorw %bx,%bx /* buffer=ES:BX= topram:0x0000 */
225 movw $0x0200 | SECTORS_LEN,%ax /* READ16 (SECTORS_LEN) sectors */
226 xorw %dx,%dx /* Head 0, Drive 0x00 */
235 movw $InitContinueTop-START,%ax
237 movw $BadCmpMsg-START,%si
239 cmpw $SECTOR2_MAGIC,%es:(Sector2_MagicBuf-START)
252 /* Interface to retry-capable INT13, set everything except CX */
253 /* function may destroy DS value! */
255 movw $0x0001,%cx /* Cylinder 0, Sector 1 */
258 pushw %dx /* save drive for resetting the controller */
259 pushw %ax /* error code in AH */
260 movw $InitMsg-START,%si
262 pushw %bx /* offset... */
263 pushw %es /* and segment of bufffer */
264 pushw %ax /* count */
266 pushw %cx /* CX<sec/cyl> */
267 pushw %dx /* drive */
268 movw $SF13_02_Msg-START,%si
270 movw $SnifferErrTail_MSG-START,%si
271 call PrintString_noPref
272 movb $0x00,%ah /* reset controller - FDC or HDC */
273 popw %dx /* restore the drive */
278 movw $TrailNL_Msg-START,%si
279 jmp PrintString_noPref
281 /* String is given in SI, returns updated SI */
293 movw $PrintString_loop-START,%bx /* from now do just 'ret' to close the loop */
295 testb $0x80,%al /* should be (x&E0==E0) */
304 popw %bx /* discard $PrintString_loop-START */
305 popw %bx /* return address */
306 popw %dx /* value to print */
307 pushw %bx /* return back the return address */
308 movw $PrintString_loop-START,%bx
311 jz PrintString_noHhex
314 call PrintString_Lhex
323 /* One byte to print is in DH */
328 call PrintString_Nhex
331 /* One nibble to print is in the lower one of DH */
336 jc PrintString_charDH
337 addb $'A'-('9'+1),%dh
342 /* Character is given in AL
343 * Preserves: DS, ES, SI, DI
344 * Destroys: AX (even AL!), BX, CX, DX
345 * DS is sometimes left preserved, sometimes set to DS=CS
349 movb $0x0E,%ah /* print character */
355 xorb %bh,%bh /* assumed below */
357 #if defined(SERIAL_BAUDRATE) || defined(OUTPUT_STORE_DISK)
359 popw %ds /* set DS=CS */
360 cmpb %bh,%ds:(SerialEnable-START)
362 #ifdef SERIAL_BAUDRATE
364 #else /* SERIAL_BAUDRATE */
365 jmp OutputStorePrintChar
366 #endif /* SERIAL_BAUDRATE */
367 #else /* defined(SERIAL_BAUDRATE) || defined(OUTPUT_STORE_DISK) */
369 #endif /* defined(SERIAL_BAUDRATE) || defined(OUTPUT_STORE_DISK) */
372 #if defined(SERIAL_BAUDRATE) || defined(OUTPUT_STORE_DISK)
374 .byte 0 /* map of port bits which want to be enabled */
376 #ifdef OUTPUT_STORE_DISK
377 #define OUTPUT_STORE_SerialEnable (0x02) /* FloppyPrintChar enabled */
379 #define OUTPUT_STORE_SerialEnable (0x00)
387 .asciz "Disk 0x00 sector 0 doesn't match myself!"
391 .asciz "16(drv=\xF1,CX<sec/cyl>=\xF3,head=\xF2,count=\xF1,buf=\xF3:\xF3)"
397 /*******************************************************************/
398 /* Storage area - code isn't needed to be primary-sector reachable */
399 /*******************************************************************/
401 /**************************************************************/
402 /* Final primary-sector signature */
403 /**************************************************************/
406 .byte 0xDE,0xAD /* FAT32 defines somehow extended, 32-bit signature (=> 0xDEAD) */
409 /**************************************************************/
410 /* Section run during boot but from the upper half of code */
411 /**************************************************************/
414 /* Main initialization */
415 /***********************/
416 /* DS invalid, ES==CS */
423 movw $ALLOC_KB*1024,%sp
426 #ifdef OUTPUT_STORE_DISK
427 movw $OutputStoreBufSpaceStart-START,%di
428 movw $((OutputStoreBuf+0x200-OutputStoreBufSpaceStart)+1)/2,%cx /* NOTE_1: Buffer may got +1 overfilled */
433 #ifndef SERIAL_BAUDRATE
434 #ifdef OUTPUT_STORE_DISK
435 movb $OUTPUT_STORE_SerialEnable,%cs:(SerialEnable-START)
437 movw $HelloMsg-START,%si
439 #else /* SERIAL_BAUDRATE */
440 movb $0x55|OUTPUT_STORE_SerialEnable,%es:(SerialEnable-START)
441 movw $HelloMsg-START,%si
442 call PrintString /* this string will not have EOL when SERIAL_BAUDRATE is defined */
443 movb %ds:(SerialEnable-START),%cl
444 movw $PORTADDR_BASE,%si
450 jnc SerialHello_skipOne
452 jz SerialHello_skipOne
453 pushw %cx /* push SerialEnable mask, S=1 */
454 pushw %si /* push PORTADDR_BASE+x pointer, S=2 */
455 pushw %ax /* print port base */
456 movw $SerialHelloPort_Msg-START,%si
457 call PrintString_noPref
458 popw %si /* restore PORTADDR_BASE+x pointer, S=1 */
459 popw %cx /* restore SerialEnable mask, S=0 */
461 rorb $1,%cl /* skip unused even bits of SerialEnable mask */
462 cmpw $PORTADDR_BASE+4*2,%si
467 /* now install our SniffFunction0x13 sniffer */
474 movw $OrigVector0x13-START,%di
476 movw $SniffFunction0x13-START,%ax
481 popw %di /* = $0x13*4 */
483 popw %es /* = null */
484 stosw_sniff /* $SniffFunction0x13-START */
488 movw $0x18*4,%di /* ROM basic - failed boot */
489 movw $SniffFunction0x18-START,%ax
495 #ifdef OUTPUT_STORE_DISK
496 incb %cs:(OutputStoreFlushEnable-START) /* we have now functional JumpVector0x13 */
498 /* we WANT DS left with 0x0000 */
499 /* we WANT ES left with 0x0000 */
501 /* and give the system control to disk=0x80/masterboot */
502 movw $0x0201,%ax /* READ16 1 sector */
503 movw $0x7C00,%bx /* buffer=ES:BX= 0x0000:0x7C00 */
505 pushw %bx /* BX/DS on stack for later 'lret', S=2, prepared for far ret */
506 movw $0x0080,%dx /* Head 0, Drive 0x80 */
507 call ReadSectors /* it returns only when successfully read */
508 cmpw $0xAA55,%es:(0x7C00+0x1FE) /* 0x55,0xAA */
509 movw $BadSignatureMsg-START,%si
511 cli /* IMPORTANT: Boot sectors must be run with CLI! */
512 lret /* lret to 0x0000:0x7C00 */
515 movw $Interrupt0x18Msg-START,%si /* %ds gets fixed in PrintFatal */
520 /* SerialPort handling code */
521 /****************************/
523 #ifdef SERIAL_BAUDRATE
527 /* Function assumes DS == CS, it preserves SI, DI, ES but uses ES==0 ! */
528 /* Function expects character to print in AL, preserves it. */
532 movb $0,%ah /* offset from PORTADDR_BASE for port #1 */
533 xorw %bx,%bx /* any register */
534 pushw %es /* push ES, S=1 */
538 movw $PORTADDR_BASE,%bx
542 jz SerialLoop_noport /* now we have port base in BX */
546 testb %ch,%ds:(SerialEnable-START)
547 jz SerialLoop_noport /* disabled port */
548 pushw %ax /* push CHARACTER and AH(port offset), S=2 */
550 jnz SerialLoop_noInit
553 leaw UART_IER(%bx),%dx /* DX=+1, UAT_IER - interrupt enable */
554 xorb %al,%al /* NO interrupts */
557 incw %dx /* DX=+3, UART_LCR - used as divisor enable */
558 movb $SERIAL_LCR_INIT | UART_LCR_DLAB,%al
560 movw %bx,%dx /* DX=+0, UART_DLL - divisor LOW */
561 movb $(SERIAL_DIVISOR & 0xFF),%al
563 incw %dx /* DX=+1, UART_DLM - divisor HIGH */
564 movb $(SERIAL_DIVISOR >> 8),%al
567 incw %dx /* DX=+3, UART_LCR - line control */
568 movb $SERIAL_LCR_INIT,%al
570 incw %dx /* DX=+4, UART_MCR - modem control */
571 movb $SERIAL_MCR_INIT,%al
573 incw %dx /* DX=+5, UART_LSR - line status */
576 jz PrintChar_serial_invalidPort /* LSR port is 0xFF - no device on the bus */
578 #ifdef SERIAL_REQUIRE_DSR
579 incw %dx /* DX=+6, UART_MSR - modem status */
580 xorw %cx,%cx /* Try ~ 60msec for DSR transition delayd by pure wiring after our DTR */
581 PrintChar_serialWaitDSR:
583 andb $UART_MSR_DSR,%al /* we MUST have AL==0 when passing to invalidPort ! */
584 jnz PrintChar_serialSend
585 loop PrintChar_serialWaitDSR
586 jmp PrintChar_serial_invalidPort
587 #endif /* SERIAL_REQUIRE_DSR */
589 SerialLoop_loop_jump1:
592 SerialLoop_noInit: /* still CHARACTER and AH(port offset) on stack, S=2 */
593 PrintChar_serialSend:
594 movb $SERIAL_SENDWAIT,%ah
595 PrintChar_serialSend_wait:
596 leaw UART_LSR(%bx),%dx /* UART_LSR - line status */
598 andb $UART_LSR_THRE,%al /* test transmitter-buffer-empty bit */
599 jnz PrintChar_serialSend_free /* we MUST have AL==0 when passing to invalidPort ! */
600 loop PrintChar_serialSend_wait
601 decb %ah /* out-loop count SERIAL_SENDWAIT */
602 jnz PrintChar_serialSend_wait
603 PrintChar_serial_invalidPort:
604 leaw UART_MCR(%bx),%dx /* UART_LSR - line status */
605 outb %al,%dx /* assumed AL==0: turn off DTR & RTS of the failing port */
606 movb %ds:(SerialEnable-START),%ah
607 pushw %ax /* pushed AH(SerialEnable), S=3 */
608 movb %al,%ds:(SerialEnable-START) /* assumed AL==0; disable temporarily complete serial output */
609 pushw %si /* save SI, S=4 */
610 pushw %bx /* port base to print out */
611 movw $SerialPortError_Msg-START,%si
613 popw %si /* recover SI, S=3 */
614 popw %bx /* restored BH=AH(SerialEnable), S=2 */
615 popw %ax /* restored CHARACTER and AH(port offset), S=1 */
617 movb $0xFE /* ==~1 */,%ch
618 rolb %cl,%ch /* masking-out pattern */
619 andb %ch,%bh /* mask-out the original SerialEnable left in BH */
620 movb %bh,%ds:(SerialEnable-START) /* disable the failed port for futher serial dumping */
621 jmp SerialLoop_noport
623 PrintChar_serialSend_free:
624 movw %bx,%dx /* UART_TX - xmit buffer */
625 popw %ax /* restored CHARACTER and AH(port offset), S=1 */
626 outb %al,%dx /* final character transmit */
630 inc %ah /* skip by two bytes of PORTADDR_BASE entry offset */
632 jne SerialLoop_loop_jump1
633 popw %es /* pop ES, S=0 */
634 #ifndef OUTPUT_STORE_DISK
639 #endif /* SERIAL_BAUDRATE */
641 /* OutputStore handling code */
642 /*****************************/
644 #ifdef OUTPUT_STORE_DISK
646 #if OUTPUT_STORE_DISK!=0x00
647 #error "int13sniff WILL destroy the data on OUTPUT_STORE_DISK!!! Are you sure?"
650 OutputStorePrintChar:
652 /* Function assumes DS == CS, it preserves SI, DI, ES. */
653 /* Function expects character to print in AL. */
655 testb $OUTPUT_STORE_SerialEnable,%ds:(SerialEnable-START)
658 cmp $13,%al /* we completely ignore and filter-out all '\r' */
660 pushw %es /* SAVE %ES */
661 pushw %di /* SAVE %DI */
662 pushw %si /* SAVE %SI */
663 movw %ds:(OutputStoreBufPtr-START),%di
667 OutputStoreTerminate: /* we will terminate the OutputStoreBuf at the given %DI position */
668 movw %di,%ds:(OutputStoreBufPtr-START)
669 movb $OUTPUT_STORE_EOF,%ds:(%di)
670 cmpb $0,%ds:(OutputStoreFlushEnable-START)
671 jz Return2pop_jump1 /* we cannot yet call CallJumpVector0x13 */
673 je OutputStoreFlush /* always flush bufer on message newline */
674 cmpw $(OutputStoreBuf-START)+0x200,%di
683 movw $OUTPUT_STORE_WRITE_RETRIES,%bp
685 mov $0x08,%ah /* %AH=get drive geometry, WARNING: DESTROYS %DI! */
686 mov $OUTPUT_STORE_DISK,%dl
687 CallJumpVector0x13 /* now %DH=maximum heads, %CX=maximum cylinder§or */
693 andb $0x03,%bh /* now %BX==# of cylinders */
694 andb $0x3F,%cl /* now %CL==# of sectors */
695 pushw %cx /* SAVE LOW==# of sectors */
696 inc %dh /* now %DH==# of heads */
698 mulb %cl /* now %AX==# of sectors in cylinder */
700 /* now we have %CX==# of sectors in cylinder, %BX=# of cylinders */
701 movw %cs:(OutputStoreAddress-START+0),%ax
702 movw %cs:(OutputStoreAddress-START+2),%dx /* %DX:%AX==OutputStoreAddress */
703 divw %cx /* now %AX==cylinder, %DX==head§or */
705 popw %bx /* RESTORE ->%BL==# of sectors */
706 jc OS_MediaOver /* cylinders exceeded */
708 divb %bl /* now %AL==head, %AH=0-based sector (and %DX==cylinder) */
709 incb %ah /* now %AL==head, %AH=1-based sector (and %DX==cylinder) */
718 orb %dh,%cl /* now %CX==cylinder§or in BIOS format */
719 movb %al,%dh /* now %DH==head */
722 movb $OUTPUT_STORE_DISK,%dl
723 movw $0x0301,%ax /* %AH=write sectors, %AL=1 sector */
724 movw $(OutputStoreBuf-START),%bx
729 movw %ax,%es /* %ES=Write16 error code */
730 xorb %ah,%ah /* %AH=reset drive */
734 andb $~OUTPUT_STORE_SerialEnable,%ds:(SerialEnable-START) /* OutputStorePrintChar got DISABLED here */
735 pushw %es /* Write16 error code, for secondary "SnifferErrTail_MSG" */
736 /* now parameters for "Common16disk_Msg": */
737 pushw %bx /* buf 2nd */
738 pushw %cs /* buf 1st (%ES has been destroyed by "Write16 error code" */
739 movb $0x01,%al /* "count" has been destroyed by "reset disk" call */
740 pushw %ax /* count */
742 pushw %cx /* CX<sec/cyl> */
743 pushw %dx /* drive */
746 movw $OutputFailedWrite_Msg-START,%si
748 movw $Common16disk_Msg-START,%si
749 call PrintString_noPref /* pops up 6*2 bytes (6 words) */
750 movw $SnifferErrTail_MSG-START,%si
751 call PrintString_noPref /* pops up 1*2 bytes (1 word ) */
753 popw %si /* RESTORE %SI */
754 popw %di /* RESTORE %DI */
755 popw %es /* RESTORE %ES */
759 cmpw $(OutputStoreBuf-START)+0x200,%ds:(OutputStoreBufPtr-START)
760 jc Return2pop /* buffer is not yet filled */
761 incw %ds:(OutputStoreAddress-START+0)
762 jnz OS_IncAddrNotWordCarry
763 incw %ds:(OutputStoreAddress-START+2)
764 OS_IncAddrNotWordCarry:
765 movw $OutputStoreBuf-START,%di
769 rep stosw /* OutputStore got cleared */
771 movb $10,%al /* we want to immediately Flush even the new sector */
772 jmp OutputStoreTerminate
774 #endif /* OUTPUT_STORE_DISK */
776 /**************************************************************/
777 /* Section for INT13 sniffing */
778 /* THIS point may start to be after 0x200 boundary */
779 /**************************************************************/
782 pushw %ax /* trash */
786 cmpb $0x00,%ah /* reset */
788 movw $JumpVector0x13popa-START,%ax
789 pushw %ax /* return address */
790 pushw %dx /* drive */
791 movw $SF13_00_Msg-START,%si
792 JumpVector0x13printStringPopa:
797 cmpb $0x02,%ah /* read16 */
799 pushw %bx /* buf 2nd */
800 pushw %es /* buf 1st */
801 pushw %ax /* count */
803 pushw %cx /* CX<sec/cyl> */
804 pushw %dx /* drive */
805 movw $SF13_02_Msg-START,%si
807 Sniffer13bottomStdHalf:
809 movw $SnifferOKTail_Msg-START,%si
810 jnc SF13_not00_tail /* ...if CY is SET */
811 Sniffer13DumpErrorAH:
812 movw $SnifferErrTail_MSG-START,%si
815 Sniffer13iretPrintStringFinal:
816 call PrintString_noPref
820 incw %sp /* trash discarded */
824 cmpb $0x41,%ah /* presence32 */
828 pushw %dx /* drive */
829 movw $SF13_41_Msg-START,%si
833 jne Sniffer13DumpErrorAH
834 pushw %cx /* supports */
835 pushw %ax /* version */
836 movw $SF13_41_out_Msg-START,%si
837 jmp Sniffer13iretPrintStringFinal
840 popw %ax /* return address */
843 movw %ax,%ss:2/*%bp*/+PUSHALL_SIZE+2/*%ds*/(%bp) /* store %ax to 'trash' */
849 pushALL /* stack is back to normal NOW */
850 pushw %bp /* trash - just to prepare return address16 */
854 movw %ss:2/*%bp*/+2/*%ax*/+2/*return16*/+PUSHALL_SIZE+2/*%ds*/(%bp),%ax
855 movw %ax,%ss:2/*%bp*/+2/*ax*/(%bp)
858 movw %ax,%ss:2/*%bp*/+2/*%ax*/+2/*return16*/+PUSHALL_SIZE+2/*%ds*/+2/*trash*/+4/*ret-seg:offs*/(%bp)
861 ret /* to prepared return16 and now will be stack in normal again */
864 cmpb $0x42,%ah /* read32 */
866 jmp JumpVector0x13popa /* too far for conditional-jump */
869 movb %ds:2(%si),%al /* count */
871 pushw %ds:8(%si) /* LBA32 sector LOWEST */
872 pushw %ds:8+2(%si) /* LBA32 sector LOWER */
873 pushw %ds:8+4(%si) /* LBA32 sector HIGHER */
874 pushw %ds:8+6(%si) /* LBA32 sector HIGHEST */
875 pushw %dx /* drive */
876 movw $SF13_42_Msg-START,%si
877 call PrintString /* first half of the entry-message */
880 movw %ss:PUSHALL_SI(%bp),%si
881 movw %ss:PUSHALL_SIZE(%bp),%ds /* restore DS:SI packet */
883 movw %ds:4(%si),%ax /* buf16 offset */
884 pushw %ax /* buf16 offset */
885 andw %ds:4+2(%si),%ax /* buf16 segment */
886 pushw %ds:4+2(%si) /* buf16 segment */
888 movw $SF13_42_buf16_Msg-START,%si
889 jnz SF13_42_buf16 /* buf16 was NOT 0xFFFF:0xFFFF => jump as OK */
890 addw $4,%sp /* drop buf16 address seg:offs */
891 pushw %ds:0x10(%si) /* 64-bit buffer LOWEST */
892 pushw %ds:0x10+2(%si) /* 64-bit buffer LOWER */
893 pushw %ds:0x10+4(%si) /* 64-bit buffer HIGHER */
894 pushw %ds:0x10+6(%si) /* 64-bit buffer HIGHEST */
895 movw $SF13_42_buf64_Msg-START,%si
897 SF13_42_buf16: /* too far for conditional-jump */
898 call PrintString_noPref
899 jmp Sniffer13bottomStdHalf
905 incw %sp /* trash discarded */
907 .byte 0xEA /* ljmp */
911 /* Serial support upper half initialization messages */
912 /*****************************************************/
914 #ifdef SERIAL_BAUDRATE
917 .asciz "SerialPort \xF3 error: stopping its communication\r\n"
922 #endif /* SERIAL_BAUDRATE */
925 /* Main upper half initialization messages */
926 /*******************************************/
929 .ascii "INT13-Sniff, version ",VERSION,", RCS revision ",REVISION
930 #ifdef OUTPUT_STORE_DISK
931 .ascii ", Output Store on disk 0x"
932 .byte BYTE_TO_HEX(OUTPUT_STORE_DISK)
934 #ifdef SERIAL_BAUDRATE
935 .ascii ", using serial ports:"
941 .asciz "Disk 0x80 has invalid signature!"
944 /* Interrupt sniffing messages */
945 /*******************************/
948 .asciz "Interrupt 0x18 - Failed boot!"
950 .asciz "Reset(drv=\xF1)"
952 .asciz "Presence32(drv=\xF1)"
954 .ascii "=(version=\xF2,supports=\xF3)"
960 .asciz "Read32(drv=\xF1,LBA32=\xF3\xE3\xE3\xE3,count=\xF1,buf="
964 .asciz "\xF3\xE3\xE3\xE3)"
967 /* Output Store messages / variables */
968 /*************************************/
969 #ifdef OUTPUT_STORE_DISK
971 OutputFailedWrite_Msg:
972 .asciz "Output Store error, stopping store: Write"
975 .word OutputStoreBufSpaceStart-START
977 #ifdef OUTPUT_STORE_ADDRESS
978 .long OUTPUT_STORE_ADDRESS
980 .long (OutputStoreBuf-START)/0x200
982 OutputStoreFlushEnable:
983 .byte 0 /* disable calling of JumpVector0x13 as it is not functional yet */
986 /**************************************************************/
987 /* Sectors finalisation */
988 /**************************************************************/
990 #ifndef OUTPUT_STORE_DISK
994 MYORG(ROUND_UP(.+2-START,0x200)-2)
998 #ifdef OUTPUT_STORE_DISK
1001 .ascii "\n<OuTpUt_sToRe>\n"
1002 #ifdef OUTPUT_STORE_DISK
1003 OutputStoreBufSpaceStart:
1004 .ascii "Buffer empty, no data stored yet.\n"
1006 .ascii "OUTPUT_STORE_DISK not defined, Output Store disabled!\n"
1008 .byte OUTPUT_STORE_EOF
1010 MYORG(ROUND_UP(.-START,0x200)) /* WARNING, we may overfull the buffer by +1 bytes, see NOTE_1 */
1012 #ifdef OUTPUT_STORE_DISK
1013 .equ ALLOC_END,.+1 /* we need one 'trash' byte for exceeding OUTPUT_STORE_EOF */